GanttInteractionConfig
차트 전체 상호작용 플래그와 권한 우선순위, 요약 행 마스크
GanttInteractionConfig는 상호작용 설정 중 차트 전체에 적용되는 쪽이에요. 권한 플래그 7개와
readOnly 1개, 드래그 경계 2개로 이루어져요. 타입은 패키지 루트에서 내보내지만 차트는 이 10개
필드를 각각 prop으로 받아 객체를 직접 만들어요. 그래서 interaction prop은 없어요.
import type { GanttInteractionConfig } from '@jaeungkim/gantt-chart';GanttInteractionConfig
/** 차트 전체에 걸리는 상호작용 설정 - 기본으로 모든 제스처가 허용되고(작업 생성은 `onTaskCreate`도 필요해요), 같은 이름의 작업 필드가 이 값을 이겨요. */
export interface GanttInteractionConfig {
readOnly?: boolean;
allowMove?: boolean;
allowResize?: boolean;
allowProgressChange?: boolean;
allowLinkCreate?: boolean;
allowLinkDelete?: boolean;
allowTaskCreate?: boolean;
/** 행 순서 바꾸기를 켜요 - opt-in이에요(기본값 false). */
allowReorder?: boolean;
minDate?: string;
maxDate?: string;
}| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
readOnly | boolean | undefined | 모든 작업의 모든 제스처를 막고 상세 패널의 기본 필드도 일반 텍스트로 렌더링해요. 어느 쪽에서든 권한 플래그를 설정하면 그 플래그가 우선이지만 패널의 Name은 readOnly만 읽어서 일반 텍스트로 남아요. |
allowMove | boolean | undefined | 타임라인을 따라 막대를 끌어 옮기는 동작이에요. |
allowResize | boolean | undefined | 막대의 양쪽 끝 중 한쪽을 끌어 크기를 조절하는 동작이에요. 상세 패널의 Start와 End가 편집할 수 있는 날짜 입력란이 되는지도 이 플래그가 정해요. |
allowProgressChange | boolean | undefined | 진행률 핸들을 끄는 동작이에요. 상세 패널의 Progress가 편집할 수 있는 숫자 입력란이 되는지도 이 플래그가 정해요. |
allowLinkCreate | boolean | undefined | 막대의 핸들에서 의존성 드래그를 시작하는 동작이에요. |
allowLinkDelete | boolean | undefined | 의존성 화살표를 선택해서 지우는 동작이에요. |
allowTaskCreate | boolean | undefined | Add task 버튼과 addTask(), 그린 범위로 onTaskCreate에 초안을 보내는 동작이에요. 차트 전체 설정만 있어요. |
allowReorder | boolean | undefined | 작업 목록 행을 끌어 다른 자리나 다른 부모로 옮기는 동작이에요. 같은 일을 하는 키보드 바인딩도 여기에 포함돼요. |
minDate | string | undefined | 막대를 끌어 옮길 수 있는 가장 이른 날짜를 UTC ISO 문자열로 넘겨요. 상세 패널에 입력한 날짜도 이 경계로 범위가 제한돼요. |
maxDate | string | undefined | 막대를 끌어 옮길 수 있는 가장 늦은 날짜를 UTC ISO 문자열로 넘겨요. 상세 패널에 입력한 날짜도 이 경계로 범위가 제한돼요. |
모든 필드를 비워 두면 모든 제스처가 허용되고 드래그 경계도 없어요. 예외는 2개예요.
allowTaskCreate는 onTaskCreate 콜백도 있어야 해요. 아래 작업 생성을 참고하세요.
allowReorder는 설정하기 전까지 꺼져 있어요. canReorder를 참고하세요.
같은 이름의 GanttProps prop 10개가 이 객체를 채워요. GanttProps를 참고하세요. 이 값을
덮어쓰는 작업별 필드는 Task와 작업 타입에 있어요.
권한 해석
작업별 권한 6가지는 내부 함수 resolveTaskInteraction이 해석해요. 이 함수는 패키지 루트에서
내보내지 않아요. 차트 동작을 결정하는 우선순위라서 여기에 적어요.
// 우선순위: `task.allowX` > `task.readOnly` > `config.allowX` > `config.readOnly` > 허용.
// 요약 행은 크기를 바꿀 수 없고 진행률도 끌 수 없어요 - 둘 다 자식에서 집계돼요.
// 순서 바꾸기만 예외예요: 바닥이 `false`라서, 명시적인 플래그만 이것을 켜요.
export function resolveTaskInteraction(
task: Pick<
Task,
| 'readOnly'
| 'allowMove'
| 'allowResize'
| 'allowProgressChange'
| 'allowLinkCreate'
| 'allowLinkDelete'
| 'allowReorder'
| 'minDate'
| 'maxDate'
> & { isSummary?: boolean },
config: GanttInteractionConfig = NO_INTERACTION_CONFIG
): ResolvedTaskInteraction {
const resolve = (
taskFlag: boolean | undefined,
configFlag: boolean | undefined
): boolean => {
if (taskFlag !== undefined) return taskFlag;
if (task.readOnly !== undefined) return !task.readOnly;
if (configFlag !== undefined) return configFlag;
return !config.readOnly;
};
const canReorder =
task.allowReorder ??
(task.readOnly === true ? false : (config.allowReorder ?? false));
const derived = task.isSummary === true;
return {
canMove: resolve(task.allowMove, config.allowMove),
canResize:
!derived &&
resolve(task.allowResize, config.allowResize),
canChangeProgress:
!derived &&
resolve(task.allowProgressChange, config.allowProgressChange),
canCreateLink: resolve(task.allowLinkCreate, config.allowLinkCreate),
canDeleteLink: resolve(task.allowLinkDelete, config.allowLinkDelete),
canReorder,
minDate: task.minDate ?? config.minDate,
maxDate: task.maxDate ?? config.maxDate,
};
}6가지 중 5가지는 아래 우선순위를 따라요. canReorder는 더 짧은 우선순위를 따르는데
canReorder에서 설명해요.
우선순위는 다음과 같아요. 구체적인 값부터 차례로 확인해요.
task.allowX가 설정돼 있으면 그 값을 그대로 써요.task.readOnly가 설정돼 있으면 그 값을 뒤집어요.config.allowX가 설정돼 있으면 그 값을 써요.- 그렇지 않으면
config.readOnly를 뒤집어요. 비어 있으면false로 읽혀서 아무것도 설정하지 않은 차트는 제스처를 허용해요.
아래 표에서 없음은 그 필드가 undefined라는 뜻이에요.
task.allowX | task.readOnly | config.allowX | config.readOnly | 결과 | 결정 단계 |
|---|---|---|---|---|---|
true | 무엇이든 | 무엇이든 | 무엇이든 | 허용 | 1 |
false | 무엇이든 | 무엇이든 | 무엇이든 | 차단 | 1 |
| 없음 | true | 무엇이든 | 무엇이든 | 차단 | 2 |
| 없음 | false | 무엇이든 | 무엇이든 | 허용 | 2 |
| 없음 | 없음 | true | 무엇이든 | 허용 | 3 |
| 없음 | 없음 | false | 무엇이든 | 차단 | 3 |
| 없음 | 없음 | 없음 | true | 차단 | 4 |
| 없음 | 없음 | 없음 | false | 허용 | 4 |
| 없음 | 없음 | 없음 | 없음 | 허용 | 4 |
차트에 readOnly를 두고 한 작업에만 allowProgressChange: true를 주면, 그 작업은 1단계에서
결정되고 나머지는 모두 4단계로 내려가요. 작업 편집을 참고하세요.
권한 6가지
6가지 중 5가지는 위 우선순위로 필드 한 쌍을 읽어요. 그다음 마지막 열의 구조 마스크가 결과 앞에
&&로 붙어요. canReorder는 다음 절에서 설명하는 더 짧은 우선순위를 따라요.
| 해석된 권한 | Task 필드 | GanttInteractionConfig 필드 | 구조 마스크 |
|---|---|---|---|
canMove | allowMove | allowMove | 없음 |
canResize | allowResize | allowResize | !isSummary |
canChangeProgress | allowProgressChange | allowProgressChange | !isSummary |
canCreateLink | allowLinkCreate | allowLinkCreate | 없음 |
canDeleteLink | allowLinkDelete | allowLinkDelete | 없음 |
canReorder | allowReorder | allowReorder | 없음 |
해석기는 이 값을 ResolvedTaskInteraction으로 반환해요. 이 타입도 패키지 루트에서 내보내지
않아요. 필드 이름이 소스와 위 표에 나오기 때문에 여기 옮겨 적었어요.
interface ResolvedTaskInteraction {
canMove: boolean;
canResize: boolean;
canChangeProgress: boolean;
canCreateLink: boolean;
canDeleteLink: boolean;
canReorder: boolean;
minDate?: string;
maxDate?: string;
}canReorder
순서 바꾸기는 옵트인이라 우선순위의 마지막이 !config.readOnly가 아니라 false예요.
const canReorder =
task.allowReorder ??
(task.readOnly === true ? false : (config.allowReorder ?? false));여기서는 config.readOnly를 건너뛰어요. 읽기 전용 차트도 아무것도 설정하지 않은 차트도 순서
바꾸기를 막아요. 어느 쪽에서든 allowReorder를 명시해야 켜져요. 위의 두 단계는 그대로예요. 작업
자신의 플래그가 우선이고 readOnly를 true로 설정한 작업은 차트 전체 플래그로도 순서를 바꿀 수
없어요.
task.allowReorder | task.readOnly | config.allowReorder | 결과 |
|---|---|---|---|
true | 무엇이든 | 무엇이든 | 허용 |
false | 무엇이든 | 무엇이든 | 차단 |
| 없음 | true | 무엇이든 | 차단 |
| 없음 | false 또는 없음 | true | 허용 |
| 없음 | false 또는 없음 | false | 차단 |
| 없음 | false 또는 없음 | 없음 | 차단 |
드래그 경계
minDate와 maxDate는 이 우선순위를 쓰지 않아요. 각각 ?? 병합 한 단계로 정해요.
minDate: task.minDate ?? config.minDate,
maxDate: task.maxDate ?? config.maxDate,작업 자신의 경계가 차트의 경계를 대신해요. readOnly와 권한 플래그는 두 경계에 영향을 주지
않아요. 드래그 중에 이 경계가 무엇을 제한하는지는 작업 편집에서 다뤄요.
작업 생성
작업 생성은 차트 전체 설정만 있어서 두 단계짜리 해석기를 따로 써요. 이 함수도 내부용이고 내보내지 않아요.
// 차트 전체 설정만 있어요 - 어느 입구도 작업에서 시작하지 않으니 작업별 단계가 없어요
export function canCreateTasks(
config: GanttInteractionConfig = NO_INTERACTION_CONFIG
): boolean {
return config.allowTaskCreate ?? !config.readOnly;
}config.allowTaskCreate | config.readOnly | 결과 |
|---|---|---|
true | 무엇이든 | 허용 |
false | 무엇이든 | 차단 |
| 없음 | true | 차단 |
| 없음 | false | 허용 |
| 없음 | 없음 | 허용 |
Task에는 allowTaskCreate 필드가 없어서 작업별 단계도 없어요. 차트는 여기에 onTaskCreate가
있는지까지 함께 확인해요.
const canCreateTask = onTaskCreate !== undefined && canCreateTasks(interaction);이 값 하나가 진입점 3개를 모두 결정해요. 값이 없으면 Add task 버튼이 렌더링되지 않고 그리기
제스처도 꺼지고 addTask()도 아무 일도 하지 않아요. 그래서 onTaskCreate가 없으면 플래그와
상관없이 작업을 만들 수 없어요. 작업 생성을 참고하세요.
제약
요약 행은 크기를 조절할 수 없고 진행률도 끌 수 없어요. 이 규칙은 해석기 결과 앞에 &&로 붙어서
어느 쪽 플래그로도 다시 켤 수 없어요.
isSummary가 true면 canResize와 canChangeProgress가 둘 다 false예요. 작업에
allowResize: true와 allowProgressChange: true를 줘도 마찬가지예요. canMove는 영향을 받지 않아요. 요약 행 이동은
허용되고 하위 트리 전체가 함께 옮겨져요.
두 값 모두 파생값이에요. rollUpTasks가 렌더링할 때마다 요약 행의 시작과 끝을 자식에서 다시
계산하고 진행률도 요약 행에 직접 값이 없으면 자식에서 롤업해요. 여기서 고친 값은 다음 렌더링에서
버려지거나 파생값을 고정해 버려요.
isSummary는 hierarchy prop이 켜져 있을 때만 설정돼요. 그래서 계층 없는 차트에는 이 규칙이
적용되지 않아요. readOnly는 요약 행의 모든 제스처를 여전히 막아요.
참고
패키지 루트에서 내보내는 것은 GanttInteractionConfig 타입뿐이에요.
resolveTaskInteraction, canCreateTasks, ResolvedTaskInteraction, NO_INTERACTION_CONFIG는
내보내지 않아요. 차트의 동작을 설명하려고 이 페이지에서만 이름을 썼어요. 가져오지 마세요.
이 플래그가 다루는 제스처는 작업 편집과 의존성에서 설명해요. 이 플래그가 결정하는 패널 필드는 상세 패널에서 다뤄요.