@dou-ui/gantt 0.0.0-stage → 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/dist/collaboration/index.js +323 -0
- package/dist/collaboration/index.js.map +1 -0
- package/dist/collaboration/peers.js +78 -0
- package/dist/collaboration/peers.js.map +1 -0
- package/dist/components/cell-editor.js +6 -0
- package/dist/components/cell-editor.js.map +1 -0
- package/dist/components/cell-editor.vue_vue_type_script_setup_true_lang.js +114 -0
- package/dist/components/cell-editor.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/gantt-menu.js +6 -0
- package/dist/components/gantt-menu.js.map +1 -0
- package/dist/components/gantt-menu.vue_vue_type_script_setup_true_lang.js +40 -0
- package/dist/components/gantt-menu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/time-grid.js +6 -0
- package/dist/components/time-grid.js.map +1 -0
- package/dist/components/time-grid.vue_vue_type_script_setup_true_lang.js +32 -0
- package/dist/components/time-grid.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/time-header.js +6 -0
- package/dist/components/time-header.js.map +1 -0
- package/dist/components/time-header.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/time-header.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/context.js +12 -0
- package/dist/context.js.map +1 -0
- package/dist/core/baseline.js +48 -0
- package/dist/core/baseline.js.map +1 -0
- package/dist/core/calendar.js +191 -0
- package/dist/core/calendar.js.map +1 -0
- package/dist/core/csv.js +424 -0
- package/dist/core/csv.js.map +1 -0
- package/dist/core/document.js +231 -0
- package/dist/core/document.js.map +1 -0
- package/dist/core/extension.js +42 -0
- package/dist/core/extension.js.map +1 -0
- package/dist/core/geometry.js +112 -0
- package/dist/core/geometry.js.map +1 -0
- package/dist/core/history.js +70 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/links.js +72 -0
- package/dist/core/links.js.map +1 -0
- package/dist/core/model.js +52 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/order.js +34 -0
- package/dist/core/order.js.map +1 -0
- package/dist/core/scale.js +118 -0
- package/dist/core/scale.js.map +1 -0
- package/dist/core/schedule.js +235 -0
- package/dist/core/schedule.js.map +1 -0
- package/dist/core/time.js +81 -0
- package/dist/core/time.js.map +1 -0
- package/dist/core/transaction.js +371 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/tree.js +114 -0
- package/dist/core/tree.js.map +1 -0
- package/dist/export/draw.js +214 -0
- package/dist/export/draw.js.map +1 -0
- package/dist/export/theme.js +131 -0
- package/dist/export/theme.js.map +1 -0
- package/dist/gantt.js +6 -0
- package/dist/gantt.js.map +1 -0
- package/dist/gantt.vue_vue_type_script_setup_true_lang.js +2774 -0
- package/dist/gantt.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/labels.js +87 -0
- package/dist/labels.js.map +1 -0
- package/dist/locale.js +355 -0
- package/dist/locale.js.map +1 -0
- package/dist/scheduler/index.js +8 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/layout.js +97 -0
- package/dist/scheduler/layout.js.map +1 -0
- package/dist/scheduler/scheduler.js +6 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/scheduler.vue_vue_type_script_setup_true_lang.js +1359 -0
- package/dist/scheduler/scheduler.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/scheduler/style.d.ts +1 -0
- package/dist/scheduler/style.js +2 -0
- package/dist/style.css +1 -0
- package/dist/style.d.ts +1 -0
- package/dist/style.js +4 -0
- package/dist/time-axis.js +337 -0
- package/dist/time-axis.js.map +1 -0
- package/dist/types/collaboration/index.d.ts +39 -0
- package/dist/types/collaboration/peers.d.ts +22 -0
- package/dist/types/components/cell-editor.vue.d.ts +21 -0
- package/dist/types/components/gantt-menu.vue.d.ts +18 -0
- package/dist/types/components/time-grid.vue.d.ts +12 -0
- package/dist/types/components/time-header.vue.d.ts +23 -0
- package/dist/types/context.d.ts +64 -0
- package/dist/types/core/baseline.d.ts +14 -0
- package/dist/types/core/calendar.d.ts +75 -0
- package/dist/types/core/csv.d.ts +77 -0
- package/dist/types/core/document.d.ts +51 -0
- package/dist/types/core/extension.d.ts +88 -0
- package/dist/types/core/geometry.d.ts +33 -0
- package/dist/types/core/history.d.ts +19 -0
- package/dist/types/core/links.d.ts +20 -0
- package/dist/types/core/menu.d.ts +27 -0
- package/dist/types/core/model.d.ts +72 -0
- package/dist/types/core/order.d.ts +9 -0
- package/dist/types/core/scale.d.ts +33 -0
- package/dist/types/core/schedule.d.ts +44 -0
- package/dist/types/core/time.d.ts +39 -0
- package/dist/types/core/transaction.d.ts +134 -0
- package/dist/types/core/tree.d.ts +30 -0
- package/dist/types/export/draw.d.ts +76 -0
- package/dist/types/export/theme.d.ts +49 -0
- package/dist/types/gantt.vue.d.ts +54 -0
- package/dist/types/index.d.ts +148 -0
- package/dist/types/labels.d.ts +24 -0
- package/dist/types/locale.d.ts +161 -0
- package/dist/types/scheduler/index.d.ts +102 -0
- package/dist/types/scheduler/layout.d.ts +58 -0
- package/dist/types/scheduler/scheduler.vue.d.ts +46 -0
- package/dist/types/scheduler/types.d.ts +109 -0
- package/dist/types/time-axis.d.ts +80 -0
- package/dist/types/types.d.ts +305 -0
- package/package.json +79 -4
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GanttLink, GanttTask } from './model';
|
|
2
|
+
/** A point on the timeline, in px from its start and from the top of the rows. */
|
|
3
|
+
export interface GanttPoint {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* What a context menu was opened on: a task (bar or row), a link, or an
|
|
9
|
+
* empty part of the timeline. `point` is where, in timeline coordinates,
|
|
10
|
+
* and `time` the moment under it, in minutes; from the table or the
|
|
11
|
+
* keyboard they are at the task's start.
|
|
12
|
+
*/
|
|
13
|
+
export type GanttMenuTarget = {
|
|
14
|
+
kind: 'task';
|
|
15
|
+
task: GanttTask;
|
|
16
|
+
point: GanttPoint;
|
|
17
|
+
time: number;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'link';
|
|
20
|
+
link: GanttLink;
|
|
21
|
+
point: GanttPoint;
|
|
22
|
+
time: number;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'canvas';
|
|
25
|
+
point: GanttPoint;
|
|
26
|
+
time: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Tone } from 'dou-ui';
|
|
2
|
+
export type GanttData = Record<string, unknown>;
|
|
3
|
+
export interface GanttTask<Data extends GanttData = GanttData> {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
/** The parent task's id. A task with children is a summary task. */
|
|
7
|
+
parent?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Sort key among siblings, compared as a string. Siblings without one
|
|
10
|
+
* keep their order in the array.
|
|
11
|
+
*/
|
|
12
|
+
order?: string;
|
|
13
|
+
/** A milestone is a point in time: it only reads `start`. */
|
|
14
|
+
type?: 'task' | 'milestone';
|
|
15
|
+
/** `YYYY-MM-DD` or `YYYY-MM-DD HH:mm`. Without it the task is not scheduled yet. */
|
|
16
|
+
start?: string;
|
|
17
|
+
/**
|
|
18
|
+
* `YYYY-MM-DD` for the last day of the task, or `YYYY-MM-DD HH:mm` for the
|
|
19
|
+
* moment it ends. Defaults to one day, or one hour after a timed `start`.
|
|
20
|
+
*/
|
|
21
|
+
end?: string;
|
|
22
|
+
/** From `0` to `1`. */
|
|
23
|
+
progress?: number;
|
|
24
|
+
tone?: Tone;
|
|
25
|
+
/** Hide the children. */
|
|
26
|
+
collapsed?: boolean;
|
|
27
|
+
/** Can't be moved or resized. */
|
|
28
|
+
locked?: boolean;
|
|
29
|
+
/** The id of the resource it is assigned to, for `DouScheduler`. */
|
|
30
|
+
resource?: string;
|
|
31
|
+
/** Your own fields, e.g. for columns. */
|
|
32
|
+
data?: Data;
|
|
33
|
+
}
|
|
34
|
+
export type GanttLinkType = 'fs' | 'ss' | 'ff' | 'sf';
|
|
35
|
+
/** A dependency: `to` waits for `from`. */
|
|
36
|
+
export interface GanttLink {
|
|
37
|
+
id: string;
|
|
38
|
+
from: string;
|
|
39
|
+
to: string;
|
|
40
|
+
/**
|
|
41
|
+
* `fs` finish to start (the default): `to` starts after `from` finishes;
|
|
42
|
+
* `ss` start to start; `ff` finish to finish; `sf` start to finish.
|
|
43
|
+
*/
|
|
44
|
+
type?: GanttLinkType;
|
|
45
|
+
/**
|
|
46
|
+
* Working time between the two ends; may be negative. A number counts
|
|
47
|
+
* working days; a string gives a unit: `'2d'` working days, `'4h'`
|
|
48
|
+
* working hours, `'30m'` working minutes.
|
|
49
|
+
*/
|
|
50
|
+
lag?: number | string;
|
|
51
|
+
}
|
|
52
|
+
/** Where a task sits in time, in minutes since the epoch. `end` is exclusive. */
|
|
53
|
+
export interface TaskSpan {
|
|
54
|
+
start: number;
|
|
55
|
+
end: number;
|
|
56
|
+
/** Both ends are whole days, written without a time. */
|
|
57
|
+
dateOnly: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Reads a task's dates. A date-only `end` covers its whole day; a missing or
|
|
61
|
+
* early one makes the task one day (or one hour) long. A milestone's span
|
|
62
|
+
* is empty: `start` and `end` are the same moment, the middle of its day
|
|
63
|
+
* when it has no time.
|
|
64
|
+
*/
|
|
65
|
+
export declare function spanOf(task: GanttTask): TaskSpan | null;
|
|
66
|
+
/**
|
|
67
|
+
* The `start` and `end` strings for a span, in the task's own style: whole
|
|
68
|
+
* days stay date-only, anything else is written with times.
|
|
69
|
+
*/
|
|
70
|
+
export declare function writeSpan(task: GanttTask, start: number, end: number): Pick<GanttTask, 'start' | 'end'>;
|
|
71
|
+
export declare const clampProgress: (value: number | undefined) => number;
|
|
72
|
+
export declare const createId: () => string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Whether a key is made of the characters `orderBetween` uses. */
|
|
2
|
+
export declare const isOrderKey: (key: string) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* A key that sorts after `before` and before `after`; leave either out for
|
|
5
|
+
* the start or the end. `before` must sort before `after`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function orderBetween(before?: string, after?: string): string;
|
|
8
|
+
/** `count` keys in order, spread out so that later insertions stay short. */
|
|
9
|
+
export declare function orderKeys(count: number): string[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type GanttScale = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
|
|
2
|
+
/** A step of the time header. */
|
|
3
|
+
export type TimeUnit = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'half' | 'year';
|
|
4
|
+
export interface ScaleLevel {
|
|
5
|
+
name: GanttScale;
|
|
6
|
+
/** The narrowest a day gets at this level, in px; below it the next level takes over. */
|
|
7
|
+
min: number;
|
|
8
|
+
/** How wide a day is when the level is picked, in px. */
|
|
9
|
+
base: number;
|
|
10
|
+
/** The two rows of the header. */
|
|
11
|
+
top: TimeUnit;
|
|
12
|
+
bottom: TimeUnit;
|
|
13
|
+
}
|
|
14
|
+
/** From the widest days to the narrowest. */
|
|
15
|
+
export declare const scaleLevels: readonly ScaleLevel[];
|
|
16
|
+
/** The widest and narrowest a day may be, in px. */
|
|
17
|
+
export declare const DAY_WIDTH_RANGE: [number, number];
|
|
18
|
+
export declare const levelByName: (name: GanttScale) => ScaleLevel;
|
|
19
|
+
/** The level that shows days `dayWidth` px wide. */
|
|
20
|
+
export declare const levelOf: (dayWidth: number) => ScaleLevel;
|
|
21
|
+
/** Hours per header cell, so that labels have room. */
|
|
22
|
+
export declare function hourStep(dayWidth: number): number;
|
|
23
|
+
/** The step that drags and new dates snap to, in minutes. */
|
|
24
|
+
export declare function snapStep(dayWidth: number): 60 | 1440 | 15 | 30;
|
|
25
|
+
/** The start of the `unit` that holds `at`. */
|
|
26
|
+
export declare function unitStart(unit: TimeUnit, at: number, weekStart?: 0 | 1, step?: number): number;
|
|
27
|
+
/** The start of the `unit` after the one that starts at `at`. */
|
|
28
|
+
export declare function nextUnit(unit: TimeUnit, at: number, step?: number): number;
|
|
29
|
+
/** The units that overlap `[from, to)`, as their start and end. */
|
|
30
|
+
export declare function unitsBetween(unit: TimeUnit, from: number, to: number, weekStart?: 0 | 1, step?: number): {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
}[];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type GanttCalendar, type WorkCalendar } from './calendar';
|
|
2
|
+
import { type GanttTask } from './model';
|
|
3
|
+
import type { GanttDocument } from './transaction';
|
|
4
|
+
export interface GanttScheduleOptions {
|
|
5
|
+
/** Which days and hours are worked; the chart's `calendar`. */
|
|
6
|
+
calendar?: GanttCalendar | WorkCalendar;
|
|
7
|
+
/** Also bring tasks earlier, to the earliest their links allow. Only tasks with links in move. */
|
|
8
|
+
pull?: boolean;
|
|
9
|
+
/** Tasks to leave where they are, e.g. the ones just moved by hand; `locked` tasks always stay. */
|
|
10
|
+
fixed?: Iterable<string>;
|
|
11
|
+
}
|
|
12
|
+
export interface GanttSchedule {
|
|
13
|
+
/** The new dates of the tasks that move, written in each task's own style. */
|
|
14
|
+
moves: Map<string, Pick<GanttTask, 'start' | 'end'>>;
|
|
15
|
+
/** Links still not kept afterwards: into a locked or fixed task, or on a loop. */
|
|
16
|
+
violated: Set<string>;
|
|
17
|
+
/** Tasks on a loop of links, or after one; they are left where they are. */
|
|
18
|
+
cycle: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface GanttCriticalPath {
|
|
21
|
+
/** Tasks with no slack: any delay to them delays the end of the plan. */
|
|
22
|
+
tasks: Set<string>;
|
|
23
|
+
/** Links between critical tasks that drive the later one. */
|
|
24
|
+
links: Set<string>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Moves tasks so that every link is kept: each task starts no earlier than
|
|
28
|
+
* its links allow, keeping its working time. By default tasks are only
|
|
29
|
+
* pushed later; `pull` also brings linked tasks earlier. Locked and fixed
|
|
30
|
+
* tasks stay, and links into them may stay broken.
|
|
31
|
+
*
|
|
32
|
+
* Takes time in proportion to the tasks and links. Nothing is changed:
|
|
33
|
+
* apply `moves` in a transaction, or call the chart's `schedule()`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function computeSchedule(doc: GanttDocument, options?: GanttScheduleOptions): GanttSchedule;
|
|
36
|
+
/** Links whose `to` side starts (or ends) before the link allows; for manual scheduling. */
|
|
37
|
+
export declare function findBrokenLinks(doc: GanttDocument, options?: Pick<GanttScheduleOptions, 'calendar'>): Set<string>;
|
|
38
|
+
/**
|
|
39
|
+
* The tasks that decide when the plan ends: working back from the last
|
|
40
|
+
* end, each task gets the latest end its successors allow, and the ones
|
|
41
|
+
* with no working time to spare are critical. Reads the dates as they
|
|
42
|
+
* are; tasks on a loop of links are left out.
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeCriticalPath(doc: GanttDocument, options?: Pick<GanttScheduleOptions, 'calendar'>): GanttCriticalPath;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const MINUTES_PER_HOUR = 60;
|
|
2
|
+
export declare const MINUTES_PER_DAY = 1440;
|
|
3
|
+
export interface ParsedTime {
|
|
4
|
+
/** Minutes since the epoch. */
|
|
5
|
+
at: number;
|
|
6
|
+
/** The string had no time of day. */
|
|
7
|
+
dateOnly: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Reads `YYYY-MM-DD` or `YYYY-MM-DD HH:mm`; seconds (`HH:mm:ss`) are
|
|
11
|
+
* accepted and dropped. `null` for anything else.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseTime(text: string | undefined | null): Readonly<ParsedTime> | null;
|
|
14
|
+
/** Minutes since the epoch for a wall-clock date; `month` counts from 1. */
|
|
15
|
+
export declare function fromParts(year: number, month: number, day: number, hour?: number, minute?: number): number;
|
|
16
|
+
export interface TimeParts {
|
|
17
|
+
year: number;
|
|
18
|
+
/** From 1. */
|
|
19
|
+
month: number;
|
|
20
|
+
day: number;
|
|
21
|
+
/** `0` is Sunday. */
|
|
22
|
+
weekday: number;
|
|
23
|
+
hour: number;
|
|
24
|
+
minute: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function partsOf(at: number): TimeParts;
|
|
27
|
+
/** `YYYY-MM-DD`. */
|
|
28
|
+
export declare function formatDate(at: number): string;
|
|
29
|
+
/** `YYYY-MM-DD HH:mm`, or `YYYY-MM-DD` when `dateOnly`. */
|
|
30
|
+
export declare function formatTime(at: number, dateOnly?: boolean): string;
|
|
31
|
+
/** `HH:mm` as minutes since midnight, or `null`. */
|
|
32
|
+
export declare function parseClock(text: string | undefined): number | null;
|
|
33
|
+
/** The midnight that starts the day of `at`. */
|
|
34
|
+
export declare const dayStart: (at: number) => number;
|
|
35
|
+
/** Days since the epoch. */
|
|
36
|
+
export declare const dayIndex: (at: number) => number;
|
|
37
|
+
export declare const isMidnight: (at: number) => boolean;
|
|
38
|
+
/** The current wall-clock time, in minutes since the epoch. */
|
|
39
|
+
export declare function wallClockNow(now?: Date): number;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { type GanttLink, type GanttTask } from './model';
|
|
2
|
+
/** An empty document, the chart's `v-model` when none is bound. */
|
|
3
|
+
export declare const emptyDocument: () => GanttDocument;
|
|
4
|
+
type Patch<T> = {
|
|
5
|
+
[K in keyof T]?: T[K] | undefined;
|
|
6
|
+
};
|
|
7
|
+
/** The tasks and links together, as a transaction sees them. */
|
|
8
|
+
export interface GanttDocument {
|
|
9
|
+
/** The version of the format; see `migrateDocument`. */
|
|
10
|
+
version: 1;
|
|
11
|
+
tasks: GanttTask[];
|
|
12
|
+
links: GanttLink[];
|
|
13
|
+
}
|
|
14
|
+
export type GanttStep = {
|
|
15
|
+
type: 'addTask';
|
|
16
|
+
task: GanttTask;
|
|
17
|
+
index?: number;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'removeTask';
|
|
20
|
+
id: string;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'updateTask';
|
|
23
|
+
id: string;
|
|
24
|
+
patch: Patch<GanttTask>;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'addLink';
|
|
27
|
+
link: GanttLink;
|
|
28
|
+
index?: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'removeLink';
|
|
31
|
+
id: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'updateLink';
|
|
34
|
+
id: string;
|
|
35
|
+
patch: Patch<GanttLink>;
|
|
36
|
+
};
|
|
37
|
+
export interface GanttTransactionMeta {
|
|
38
|
+
/** Keep out of the undo history, e.g. folding a summary or a change from another client. */
|
|
39
|
+
history?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Consecutive transactions in the same group within a second undo as
|
|
42
|
+
* one, e.g. repeated arrow key nudges.
|
|
43
|
+
*/
|
|
44
|
+
group?: string;
|
|
45
|
+
/**
|
|
46
|
+
* With `scheduling="auto"`, set to `false` to leave the waiting tasks
|
|
47
|
+
* where they are, e.g. for a change from another client.
|
|
48
|
+
*/
|
|
49
|
+
schedule?: boolean;
|
|
50
|
+
/** Who made the change, passed on to the `transaction` event. */
|
|
51
|
+
origin?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A batch of changes. Steps apply as they are added, so later calls see
|
|
55
|
+
* earlier ones; `doc` is the result.
|
|
56
|
+
*/
|
|
57
|
+
export declare class GanttTransaction {
|
|
58
|
+
readonly before: GanttDocument;
|
|
59
|
+
readonly steps: GanttStep[];
|
|
60
|
+
/** The steps that undo this transaction, in the order to apply them. */
|
|
61
|
+
readonly inverse: GanttStep[];
|
|
62
|
+
meta: GanttTransactionMeta;
|
|
63
|
+
private tasks;
|
|
64
|
+
private links;
|
|
65
|
+
private copied;
|
|
66
|
+
/** Where each task and link is in its list; built on first use, dropped when a list changes length. */
|
|
67
|
+
private at;
|
|
68
|
+
constructor(before: GanttDocument);
|
|
69
|
+
get doc(): GanttDocument;
|
|
70
|
+
/** Whether the change makes any change: it has steps and wasn't cancelled. */
|
|
71
|
+
get changed(): boolean;
|
|
72
|
+
private stopped;
|
|
73
|
+
/**
|
|
74
|
+
* Stops the change: none of it is applied or kept for undo, and the
|
|
75
|
+
* editor fires `transactionCancel` and says why. For an extension's `transaction`
|
|
76
|
+
* hook, e.g. to keep people from changing what they may not; hooks after
|
|
77
|
+
* it don't run. A change kept out of the history (`meta.history: false`),
|
|
78
|
+
* such as undo, redo or another person's, can't be cancelled and goes ahead.
|
|
79
|
+
*/
|
|
80
|
+
cancel(reason?: string): this;
|
|
81
|
+
/** Whether `cancel` stopped it. */
|
|
82
|
+
get cancelled(): boolean;
|
|
83
|
+
/** What `cancel` was given, to tell people why. */
|
|
84
|
+
get cancelReason(): string | undefined;
|
|
85
|
+
/** Whether the tasks, or the links, changed. */
|
|
86
|
+
touches(kind: 'tasks' | 'links'): boolean;
|
|
87
|
+
getTask(id: string): GanttTask<import("./model").GanttData> | undefined;
|
|
88
|
+
getLink(id: string): GanttLink | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* A task's or link's position in its list, `-1` when there is none. The
|
|
91
|
+
* positions are kept as tasks and links come and go, and checked when
|
|
92
|
+
* read: one that moved since is found again with the rest.
|
|
93
|
+
*/
|
|
94
|
+
private indexOf;
|
|
95
|
+
/** Links into or out of a task. */
|
|
96
|
+
linksOf(id: string): GanttLink[];
|
|
97
|
+
setMeta(meta: GanttTransactionMeta): this;
|
|
98
|
+
step(step: GanttStep): this;
|
|
99
|
+
addTask(task: GanttTask, index?: number): this;
|
|
100
|
+
/** Removes a task with its subtasks and every link attached to them. */
|
|
101
|
+
removeTask(id: string): this;
|
|
102
|
+
updateTask(id: string, patch: Patch<GanttTask>): this;
|
|
103
|
+
/**
|
|
104
|
+
* Sets a task's dates, written back in the task's own style. Takes
|
|
105
|
+
* minutes, or strings read like the task's own: a date-only `end` is the
|
|
106
|
+
* last day of the task.
|
|
107
|
+
*/
|
|
108
|
+
setSpan(id: string, start: number | string, end: number | string): this;
|
|
109
|
+
/**
|
|
110
|
+
* Moves a task, with its subtasks, under `parent` (or to the top level)
|
|
111
|
+
* at `index` among its new siblings, the end by default. Only the task's
|
|
112
|
+
* `parent` and `order` change, unless its new siblings have no room
|
|
113
|
+
* between them: then they all get new `order` keys. Links between the
|
|
114
|
+
* task's subtasks and its new parents go, since a task can't depend on
|
|
115
|
+
* its own parent. A move into the task itself is ignored.
|
|
116
|
+
*/
|
|
117
|
+
moveTask(id: string, parent: string | undefined, index?: number): this;
|
|
118
|
+
/** Merges `patch` into the task's `data`. */
|
|
119
|
+
updateData(id: string, patch: Record<string, unknown>): this;
|
|
120
|
+
addLink(link: GanttLink, index?: number): this;
|
|
121
|
+
removeLink(id: string): this;
|
|
122
|
+
updateLink(id: string, patch: Patch<GanttLink>): this;
|
|
123
|
+
private writable;
|
|
124
|
+
/** Applies a step and returns its inverse, or `null` when it changes nothing. */
|
|
125
|
+
private apply;
|
|
126
|
+
}
|
|
127
|
+
/** Applies steps to a document; steps that no longer apply are skipped. */
|
|
128
|
+
export declare function applyGanttSteps(doc: GanttDocument, steps: readonly GanttStep[]): GanttTransaction;
|
|
129
|
+
/**
|
|
130
|
+
* Folds updates of the same task or link into one, as long as nothing
|
|
131
|
+
* adds or removes it in between.
|
|
132
|
+
*/
|
|
133
|
+
export declare function compactSteps(steps: readonly GanttStep[]): GanttStep[];
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type GanttTask, type TaskSpan } from './model';
|
|
2
|
+
export interface GanttRow {
|
|
3
|
+
task: GanttTask;
|
|
4
|
+
/** Nesting level, from 0. */
|
|
5
|
+
depth: number;
|
|
6
|
+
/** Position among the shown rows; `-1` when a collapsed parent hides it. */
|
|
7
|
+
index: number;
|
|
8
|
+
/** Number of direct children. */
|
|
9
|
+
children: number;
|
|
10
|
+
/** Has children, so its dates and progress come from them. */
|
|
11
|
+
summary: boolean;
|
|
12
|
+
milestone: boolean;
|
|
13
|
+
/** Its own dates, or for a summary the dates its children cover. */
|
|
14
|
+
span: TaskSpan | null;
|
|
15
|
+
progress: number;
|
|
16
|
+
}
|
|
17
|
+
export interface GanttTree {
|
|
18
|
+
/** The rows to show, top to bottom. */
|
|
19
|
+
rows: GanttRow[];
|
|
20
|
+
/** Every task's row, shown or not. */
|
|
21
|
+
byId: Map<string, GanttRow>;
|
|
22
|
+
/** Children in display order; roots under `undefined`. */
|
|
23
|
+
childrenOf: Map<string | undefined, GanttTask[]>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Lays the flat task list out as a tree: rows in display order, summaries
|
|
27
|
+
* worked out from their children. A `parent` that doesn't exist, or that
|
|
28
|
+
* would make a loop, is ignored and the task becomes a root.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildTree(tasks: readonly GanttTask[]): GanttTree;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Tone } from 'dou-ui';
|
|
2
|
+
import { type WorkCalendar } from '../core/calendar';
|
|
3
|
+
import type { GanttLink, TaskSpan } from '../core/model';
|
|
4
|
+
import type { GanttRow } from '../core/tree';
|
|
5
|
+
import type { GanttMessages } from '../locale';
|
|
6
|
+
import type { GanttBarLabel } from '../types';
|
|
7
|
+
import type { ExportTheme } from './theme';
|
|
8
|
+
/** Height of the time header, in px, as on screen. */
|
|
9
|
+
export declare const HEADER = 56;
|
|
10
|
+
/** More room before a side title where a link leaves the bar's end, in px. */
|
|
11
|
+
export declare const LINKED_END_ROOM = 14;
|
|
12
|
+
export interface ExportColumn {
|
|
13
|
+
title: string;
|
|
14
|
+
width: number;
|
|
15
|
+
align: 'start' | 'center' | 'end';
|
|
16
|
+
/** The title column: indented by depth, summaries in medium weight. */
|
|
17
|
+
isTitle: boolean;
|
|
18
|
+
text: (row: GanttRow) => string;
|
|
19
|
+
}
|
|
20
|
+
export interface DrawInput {
|
|
21
|
+
/** The rows to draw, top to bottom. */
|
|
22
|
+
rows: readonly GanttRow[];
|
|
23
|
+
links: readonly GanttLink[];
|
|
24
|
+
/** Columns of the table; none to leave the table out. */
|
|
25
|
+
columns: readonly ExportColumn[];
|
|
26
|
+
rowHeight: number;
|
|
27
|
+
dayWidth: number;
|
|
28
|
+
/** The time drawn, in minutes. */
|
|
29
|
+
start: number;
|
|
30
|
+
end: number;
|
|
31
|
+
calendar: WorkCalendar;
|
|
32
|
+
messages: GanttMessages;
|
|
33
|
+
weekStart: 0 | 1;
|
|
34
|
+
/** The current time, or `null` to leave the today line out. */
|
|
35
|
+
now: number | null;
|
|
36
|
+
markers: readonly {
|
|
37
|
+
at: number;
|
|
38
|
+
label?: string;
|
|
39
|
+
tone?: Tone;
|
|
40
|
+
}[];
|
|
41
|
+
critical: {
|
|
42
|
+
tasks: ReadonlySet<string>;
|
|
43
|
+
links: ReadonlySet<string>;
|
|
44
|
+
} | null;
|
|
45
|
+
broken: ReadonlySet<string>;
|
|
46
|
+
baseline: ReadonlyMap<string, TaskSpan> | null;
|
|
47
|
+
barLabel: GanttBarLabel;
|
|
48
|
+
/** Fill the header and the rows with the page colors; `false` leaves them transparent. */
|
|
49
|
+
background: boolean;
|
|
50
|
+
/** Tasks with a link at their end, whose side titles start further out. */
|
|
51
|
+
linkedEnds: ReadonlySet<string>;
|
|
52
|
+
/** Width of a text in px, at the given weight. */
|
|
53
|
+
textWidth: (text: string, bold?: boolean) => number;
|
|
54
|
+
}
|
|
55
|
+
/** The chart drawn as SVG markup, in two parts so the header can repeat on every printed page. */
|
|
56
|
+
export interface GanttDrawing {
|
|
57
|
+
width: number;
|
|
58
|
+
/** Height of the rows, below the header. */
|
|
59
|
+
bodyHeight: number;
|
|
60
|
+
header: string;
|
|
61
|
+
body: string;
|
|
62
|
+
}
|
|
63
|
+
/** The time the content covers, widened to whole header cells with one more on either side. */
|
|
64
|
+
export declare function paddedRange(start: number, end: number, dayWidth: number, weekStart: 0 | 1): {
|
|
65
|
+
start: number;
|
|
66
|
+
end: number;
|
|
67
|
+
};
|
|
68
|
+
export declare function drawGantt(input: DrawInput, theme: ExportTheme): GanttDrawing;
|
|
69
|
+
/**
|
|
70
|
+
* A whole SVG document: the header, then the rows; `window` keeps only
|
|
71
|
+
* some of the rows, for a printed page.
|
|
72
|
+
*/
|
|
73
|
+
export declare function svgDocument(drawing: GanttDrawing, window?: {
|
|
74
|
+
top: number;
|
|
75
|
+
height: number;
|
|
76
|
+
}): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Tone } from 'dou-ui';
|
|
2
|
+
export type BarTone = Tone | 'default' | 'critical';
|
|
3
|
+
export interface BarColors {
|
|
4
|
+
fill: string;
|
|
5
|
+
stroke: string;
|
|
6
|
+
progress: string;
|
|
7
|
+
}
|
|
8
|
+
/** The chart's colors and font, read from the page, for drawing it elsewhere. */
|
|
9
|
+
export interface ExportTheme {
|
|
10
|
+
fontFamily: string;
|
|
11
|
+
/** Size of the header, bar and cell text, in px. */
|
|
12
|
+
fontSize: number;
|
|
13
|
+
fontWeight: string;
|
|
14
|
+
surface: string;
|
|
15
|
+
headerBg: string;
|
|
16
|
+
line: string;
|
|
17
|
+
lineStrong: string;
|
|
18
|
+
off: string;
|
|
19
|
+
text: string;
|
|
20
|
+
textSecondary: string;
|
|
21
|
+
textTertiary: string;
|
|
22
|
+
today: string;
|
|
23
|
+
link: string;
|
|
24
|
+
linkCritical: string;
|
|
25
|
+
linkBroken: string;
|
|
26
|
+
baseline: string;
|
|
27
|
+
bar: Record<BarTone, BarColors>;
|
|
28
|
+
summary: Record<BarTone, string>;
|
|
29
|
+
milestone: Record<BarTone, {
|
|
30
|
+
fill: string;
|
|
31
|
+
stroke: string;
|
|
32
|
+
}>;
|
|
33
|
+
marker: Record<Tone, {
|
|
34
|
+
line: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A computed color as `#rrggbb` or `rgba(…)`, which every SVG reader
|
|
40
|
+
* understands. A canvas converts most colors as it parses them; colors
|
|
41
|
+
* it keeps in another space (`oklab(…)`, `color(…)`) are painted on a
|
|
42
|
+
* pixel and read back.
|
|
43
|
+
*/
|
|
44
|
+
export declare function plain(color: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Reads the colors from elements made like the chart's own, inside `root`
|
|
47
|
+
* so its theme and tokens apply, and removes them after.
|
|
48
|
+
*/
|
|
49
|
+
export declare function readTheme(root: HTMLElement): ExportTheme;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type GanttLink, type GanttTask } from './core/model';
|
|
2
|
+
import { GanttTransaction, type GanttDocument } from './core/transaction';
|
|
3
|
+
import { type GanttScale } from './core/scale';
|
|
4
|
+
import type { GanttExpose, GanttProps, GanttSlots } from './types';
|
|
5
|
+
type __VLS_Props = GanttProps;
|
|
6
|
+
type __VLS_Slots = GanttSlots;
|
|
7
|
+
type __VLS_ModelProps = {
|
|
8
|
+
modelValue?: GanttDocument;
|
|
9
|
+
'selection'?: string[];
|
|
10
|
+
'scale'?: GanttScale;
|
|
11
|
+
};
|
|
12
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
13
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, GanttExpose, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
link: (link: GanttLink) => any;
|
|
15
|
+
transaction: (tr: GanttTransaction) => any;
|
|
16
|
+
"update:modelValue": (value: GanttDocument) => any;
|
|
17
|
+
transactionCancel: (tr: GanttTransaction) => any;
|
|
18
|
+
taskClick: (task: GanttTask<import(".").GanttData>, event: MouseEvent) => any;
|
|
19
|
+
taskDblclick: (task: GanttTask<import(".").GanttData>, event: MouseEvent) => any;
|
|
20
|
+
taskContextmenu: (task: GanttTask<import(".").GanttData>, event: MouseEvent) => any;
|
|
21
|
+
linkClick: (link: GanttLink, event: MouseEvent) => any;
|
|
22
|
+
linkContextmenu: (link: GanttLink, event: MouseEvent) => any;
|
|
23
|
+
"update:selection": (value: string[]) => any;
|
|
24
|
+
"update:scale": (value: GanttScale | undefined) => any;
|
|
25
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
26
|
+
onLink?: ((link: GanttLink) => any) | undefined;
|
|
27
|
+
onTransaction?: ((tr: GanttTransaction) => any) | undefined;
|
|
28
|
+
"onUpdate:modelValue"?: ((value: GanttDocument) => any) | undefined;
|
|
29
|
+
onTransactionCancel?: ((tr: GanttTransaction) => any) | undefined;
|
|
30
|
+
onTaskClick?: ((task: GanttTask<import(".").GanttData>, event: MouseEvent) => any) | undefined;
|
|
31
|
+
onTaskDblclick?: ((task: GanttTask<import(".").GanttData>, event: MouseEvent) => any) | undefined;
|
|
32
|
+
onTaskContextmenu?: ((task: GanttTask<import(".").GanttData>, event: MouseEvent) => any) | undefined;
|
|
33
|
+
onLinkClick?: ((link: GanttLink, event: MouseEvent) => any) | undefined;
|
|
34
|
+
onLinkContextmenu?: ((link: GanttLink, event: MouseEvent) => any) | undefined;
|
|
35
|
+
"onUpdate:selection"?: ((value: string[]) => any) | undefined;
|
|
36
|
+
"onUpdate:scale"?: ((value: GanttScale | undefined) => any) | undefined;
|
|
37
|
+
}>, {
|
|
38
|
+
today: boolean;
|
|
39
|
+
addRow: boolean;
|
|
40
|
+
menu: boolean;
|
|
41
|
+
table: boolean;
|
|
42
|
+
rowHeight: number;
|
|
43
|
+
tableWidth: number;
|
|
44
|
+
barLabel: import("./types").GanttBarLabel;
|
|
45
|
+
scheduling: "auto" | "manual";
|
|
46
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
47
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
48
|
+
declare const _default: typeof __VLS_export;
|
|
49
|
+
export default _default;
|
|
50
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
51
|
+
new (): {
|
|
52
|
+
$slots: S;
|
|
53
|
+
};
|
|
54
|
+
};
|