construction-gantt 0.1.0 → 0.2.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/CHANGELOG.md +14 -0
- package/LICENSE.md +27 -0
- package/dist/index.cjs +164 -47
- package/dist/index.d.cts +23 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +164 -47
- package/dist/{pdf-CBaoJRTI.js → pdf-BsFqo2UW.js} +1 -1
- package/dist/{pdf-CAQDrX0w.cjs → pdf-N2LwD-_F.cjs} +1 -1
- package/dist/{png-C8t74695.cjs → png-BloW1DDl.cjs} +1 -0
- package/dist/{png-DKZeKnRh.js → png-C2poOLQo.js} +1 -0
- package/package.json +2 -2
- package/src/Gantt.css +39 -0
- package/src/Gantt.tsx +201 -42
- package/src/export/offscreen.tsx +2 -0
- package/src/export/pdf.ts +1 -0
- package/src/export/png.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# construction-gantt
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b59d1fe: Multi-baseline UI: render multiple captured baselines simultaneously for variation-claim delay analysis under NZS 3910 / AS 4000.
|
|
8
|
+
|
|
9
|
+
- New `baselineIndices: ReadonlyArray<BaselineIndex>` prop on `<Gantt>` overlays one phantom ghost row per selected baseline.
|
|
10
|
+
- Existing `baselineIndex` prop continues to work; deprecated, removed at v1.0.
|
|
11
|
+
- Each phantom row in multi-baseline mode carries its own variance pill; single-baseline mode keeps the pill on the live bar (existing behaviour).
|
|
12
|
+
- Per-baseline CSS class `bode-baseline-${N}` for indices 0–10 ships with a default palette; consumers override via higher-specificity rules.
|
|
13
|
+
- Phantom row label includes `baseline.name` (or `Baseline N` fallback) and formatted `capturedAt`.
|
|
14
|
+
|
|
15
|
+
No engine changes (ADR-005 preserved). Render-layer only. Test infrastructure additions: canvas 2D context stub at `vitest.setup.ts` so SVAR mounts under happy-dom.
|
|
16
|
+
|
|
3
17
|
## 0.1.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rips Cassels
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This software wraps and depends on free SVAR React Gantt (also MIT-licensed). Consumers
|
|
26
|
+
must also accept that license. See https://github.com/svar-widgets/gantt for SVAR's
|
|
27
|
+
terms.
|
package/dist/index.cjs
CHANGED
|
@@ -1907,7 +1907,7 @@ function reducer(state, action) {
|
|
|
1907
1907
|
};
|
|
1908
1908
|
}
|
|
1909
1909
|
|
|
1910
|
-
__insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.construction-gantt-marker-today{background:#ef4444;color:#fff;font-weight:600}.construction-gantt-marker-milestone{background:#2563eb;color:#fff;font-weight:500}");
|
|
1910
|
+
__insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.construction-gantt-marker-today{background:#ef4444;color:#fff;font-weight:600}.construction-gantt-marker-milestone{background:#2563eb;color:#fff;font-weight:500}.bode-baseline-ghost{display:flex;align-items:center;gap:6px;height:60%;margin-top:15%;padding:0 8px;border-radius:3px;font-size:9px;font-style:italic;color:#fff;opacity:.85;white-space:nowrap}.bode-baseline-0{background:#6b7280}.bode-baseline-1{background:#3b82f6}.bode-baseline-2{background:#8b5cf6}.bode-baseline-3{background:#14b8a6;color:#0f172a}.bode-baseline-4{background:#f59e0b;color:#0f172a}.bode-baseline-5{background:#ec4899}.bode-baseline-6{background:#06b6d4;color:#0f172a}.bode-baseline-7{background:#84cc16;color:#0f172a}.bode-baseline-8{background:#f97316;color:#0f172a}.bode-baseline-9{background:#a855f7}.bode-baseline-10{background:#dc2626}");
|
|
1911
1911
|
|
|
1912
1912
|
// Render-only visibility filter for <Gantt> tasks.
|
|
1913
1913
|
//
|
|
@@ -1938,8 +1938,12 @@ __insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.c
|
|
|
1938
1938
|
return tasks.filter((t)=>visibleTaskIds.has(t.id));
|
|
1939
1939
|
}
|
|
1940
1940
|
|
|
1941
|
-
const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height = 500, cellWidth = 48, cellHeight = 42, preScheduled = false, markers, baselineIndex, showBaselineBars, columns, visibleTaskIds }, ref) {
|
|
1941
|
+
const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height = 500, cellWidth = 48, cellHeight = 42, preScheduled = false, markers, baselineIndex, baselineIndices, showBaselineBars, columns, visibleTaskIds }, ref) {
|
|
1942
1942
|
const containerRef = react.useRef(null);
|
|
1943
|
+
const effectiveBaselineIndices = react.useMemo(()=>resolveEffectiveBaselineIndices(baselineIndices, baselineIndex), [
|
|
1944
|
+
baselineIndices,
|
|
1945
|
+
baselineIndex
|
|
1946
|
+
]);
|
|
1943
1947
|
const scheduled = react.useMemo(()=>preScheduled ? project : schedule(project), [
|
|
1944
1948
|
project,
|
|
1945
1949
|
preScheduled
|
|
@@ -1954,32 +1958,17 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
1954
1958
|
scheduled.calendars,
|
|
1955
1959
|
scheduled.defaultCalendarId
|
|
1956
1960
|
]);
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
+
// Resolve effective indices → actual Baseline records, dropping any that
|
|
1962
|
+
// don't exist on the project. Preserves caller order so phantom rows
|
|
1963
|
+
// render in the array order the consumer passed.
|
|
1964
|
+
const resolvedBaselines = react.useMemo(()=>resolveBaselines(scheduled.baselines, effectiveBaselineIndices), [
|
|
1961
1965
|
scheduled.baselines,
|
|
1962
|
-
|
|
1966
|
+
effectiveBaselineIndices
|
|
1963
1967
|
]);
|
|
1964
|
-
const ghostBarsEnabled =
|
|
1965
|
-
const svarTasks = react.useMemo(()=>
|
|
1966
|
-
if (!ghostBarsEnabled || !baseline) {
|
|
1967
|
-
return renderableTasks.map((t)=>toSvarTask(t, baseline, calendar));
|
|
1968
|
-
}
|
|
1969
|
-
// Interleave each real task with its baseline-snapshot ghost row.
|
|
1970
|
-
// Phantoms share the real task's `parent` so they stay grouped under
|
|
1971
|
-
// the same summary in hierarchy views.
|
|
1972
|
-
const out = [];
|
|
1973
|
-
for (const t of renderableTasks){
|
|
1974
|
-
out.push(toSvarTask(t, baseline, calendar));
|
|
1975
|
-
if (t.type === 'summary') continue;
|
|
1976
|
-
const phantom = makeBaselinePhantom(t, baseline);
|
|
1977
|
-
if (phantom) out.push(phantom);
|
|
1978
|
-
}
|
|
1979
|
-
return out;
|
|
1980
|
-
}, [
|
|
1968
|
+
const ghostBarsEnabled = resolvedBaselines.length > 0 && (showBaselineBars ?? true);
|
|
1969
|
+
const svarTasks = react.useMemo(()=>buildSvarTasks(renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled), [
|
|
1981
1970
|
renderableTasks,
|
|
1982
|
-
|
|
1971
|
+
resolvedBaselines,
|
|
1983
1972
|
calendar,
|
|
1984
1973
|
ghostBarsEnabled
|
|
1985
1974
|
]);
|
|
@@ -2010,7 +1999,7 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2010
1999
|
]);
|
|
2011
2000
|
react.useImperativeHandle(ref, ()=>({
|
|
2012
2001
|
async exportPNG (options) {
|
|
2013
|
-
const { exportPNG } = await Promise.resolve().then(function () { return require('./png-
|
|
2002
|
+
const { exportPNG } = await Promise.resolve().then(function () { return require('./png-BloW1DDl.cjs'); });
|
|
2014
2003
|
return exportPNG({
|
|
2015
2004
|
scheduled,
|
|
2016
2005
|
ganttProps: {
|
|
@@ -2018,6 +2007,7 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2018
2007
|
cellHeight,
|
|
2019
2008
|
markers,
|
|
2020
2009
|
baselineIndex,
|
|
2010
|
+
baselineIndices,
|
|
2021
2011
|
showBaselineBars,
|
|
2022
2012
|
columns,
|
|
2023
2013
|
height,
|
|
@@ -2027,7 +2017,7 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2027
2017
|
});
|
|
2028
2018
|
},
|
|
2029
2019
|
async exportPDF (options) {
|
|
2030
|
-
const { exportPDF } = await Promise.resolve().then(function () { return require('./pdf-
|
|
2020
|
+
const { exportPDF } = await Promise.resolve().then(function () { return require('./pdf-N2LwD-_F.cjs'); });
|
|
2031
2021
|
return exportPDF({
|
|
2032
2022
|
scheduled,
|
|
2033
2023
|
ganttProps: {
|
|
@@ -2035,6 +2025,7 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2035
2025
|
cellHeight,
|
|
2036
2026
|
markers,
|
|
2037
2027
|
baselineIndex,
|
|
2028
|
+
baselineIndices,
|
|
2038
2029
|
showBaselineBars,
|
|
2039
2030
|
columns,
|
|
2040
2031
|
height,
|
|
@@ -2056,6 +2047,7 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2056
2047
|
cellHeight,
|
|
2057
2048
|
markers,
|
|
2058
2049
|
baselineIndex,
|
|
2050
|
+
baselineIndices,
|
|
2059
2051
|
showBaselineBars,
|
|
2060
2052
|
columns,
|
|
2061
2053
|
height,
|
|
@@ -2085,23 +2077,56 @@ const Gantt = /*#__PURE__*/ react.forwardRef(function Gantt({ project, height =
|
|
|
2085
2077
|
const ConstructionBar = ({ data })=>{
|
|
2086
2078
|
// Phantom baseline row — render a slim outlined ghost bar.
|
|
2087
2079
|
if (data.is_baseline_ghost) {
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
background: 'transparent',
|
|
2094
|
-
borderRadius: 3,
|
|
2095
|
-
fontSize: 9,
|
|
2096
|
-
color: '#64748b',
|
|
2097
|
-
display: 'flex',
|
|
2098
|
-
alignItems: 'center',
|
|
2099
|
-
padding: '0 6px',
|
|
2100
|
-
fontStyle: 'italic',
|
|
2101
|
-
whiteSpace: 'nowrap'
|
|
2102
|
-
},
|
|
2080
|
+
const baselineIdx = data.baseline_index ?? 0;
|
|
2081
|
+
const phantomSlipped = data.is_slipped ?? false;
|
|
2082
|
+
const phantomAhead = data.is_ahead ?? false;
|
|
2083
|
+
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
2084
|
+
className: `bode-baseline-ghost bode-baseline-${baselineIdx}`,
|
|
2103
2085
|
title: "Baseline position — where this task was when the baseline was captured",
|
|
2104
|
-
children:
|
|
2086
|
+
children: [
|
|
2087
|
+
/*#__PURE__*/ jsxRuntime.jsx("span", {
|
|
2088
|
+
style: {
|
|
2089
|
+
flex: 1,
|
|
2090
|
+
overflow: 'hidden',
|
|
2091
|
+
textOverflow: 'ellipsis'
|
|
2092
|
+
},
|
|
2093
|
+
children: data.text
|
|
2094
|
+
}),
|
|
2095
|
+
phantomSlipped && /*#__PURE__*/ jsxRuntime.jsxs("span", {
|
|
2096
|
+
style: {
|
|
2097
|
+
padding: '0 6px',
|
|
2098
|
+
background: '#fed7aa',
|
|
2099
|
+
color: '#7c2d12',
|
|
2100
|
+
borderRadius: 3,
|
|
2101
|
+
fontSize: 10,
|
|
2102
|
+
fontWeight: 700,
|
|
2103
|
+
lineHeight: '16px',
|
|
2104
|
+
whiteSpace: 'nowrap'
|
|
2105
|
+
},
|
|
2106
|
+
title: "Drifted later than the baseline",
|
|
2107
|
+
children: [
|
|
2108
|
+
"+",
|
|
2109
|
+
workingMinutesToShortLabel(data.start_variance ?? 0)
|
|
2110
|
+
]
|
|
2111
|
+
}),
|
|
2112
|
+
phantomAhead && /*#__PURE__*/ jsxRuntime.jsxs("span", {
|
|
2113
|
+
style: {
|
|
2114
|
+
padding: '0 6px',
|
|
2115
|
+
background: '#bbf7d0',
|
|
2116
|
+
color: '#14532d',
|
|
2117
|
+
borderRadius: 3,
|
|
2118
|
+
fontSize: 10,
|
|
2119
|
+
fontWeight: 700,
|
|
2120
|
+
lineHeight: '16px',
|
|
2121
|
+
whiteSpace: 'nowrap'
|
|
2122
|
+
},
|
|
2123
|
+
title: "Ahead of the baseline",
|
|
2124
|
+
children: [
|
|
2125
|
+
"−",
|
|
2126
|
+
workingMinutesToShortLabel(data.start_variance ?? 0)
|
|
2127
|
+
]
|
|
2128
|
+
})
|
|
2129
|
+
]
|
|
2105
2130
|
});
|
|
2106
2131
|
}
|
|
2107
2132
|
const isCritical = data.is_critical ?? false;
|
|
@@ -2252,19 +2277,25 @@ function toSvarTask(t, baseline, calendar) {
|
|
|
2252
2277
|
if (t.type === 'summary') base.open = t.open ?? true;
|
|
2253
2278
|
return base;
|
|
2254
2279
|
}
|
|
2255
|
-
function makeBaselinePhantom(t, baseline) {
|
|
2280
|
+
function makeBaselinePhantom(t, baseline, calendar) {
|
|
2256
2281
|
const snap = baseline.tasks.get(t.id);
|
|
2257
2282
|
if (!snap) return null;
|
|
2283
|
+
const variance = calendar ? getTaskBaselineVariance(t, baseline, calendar) : undefined;
|
|
2284
|
+
const startVariance = variance?.startVariance ?? 0;
|
|
2258
2285
|
return {
|
|
2259
|
-
id: `${t.id}
|
|
2260
|
-
text:
|
|
2286
|
+
id: `${t.id}__baseline_${baseline.index}`,
|
|
2287
|
+
text: formatBaselineLabel(baseline),
|
|
2261
2288
|
start: snap.start,
|
|
2262
2289
|
end: snap.end,
|
|
2263
2290
|
duration: snap.duration,
|
|
2264
2291
|
progress: 0,
|
|
2265
2292
|
type: 'task',
|
|
2266
2293
|
parent: t.parent,
|
|
2267
|
-
is_baseline_ghost: true
|
|
2294
|
+
is_baseline_ghost: true,
|
|
2295
|
+
baseline_index: baseline.index,
|
|
2296
|
+
start_variance: startVariance,
|
|
2297
|
+
is_slipped: startVariance >= 30,
|
|
2298
|
+
is_ahead: startVariance <= -30
|
|
2268
2299
|
};
|
|
2269
2300
|
}
|
|
2270
2301
|
function toSvarLink(l) {
|
|
@@ -2288,6 +2319,26 @@ function dependencyTypeToSvar(t) {
|
|
|
2288
2319
|
return 's2e';
|
|
2289
2320
|
}
|
|
2290
2321
|
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Format a baseline's metadata for display in the phantom row's label.
|
|
2324
|
+
* Returns "${name ?? `Baseline ${index}`} — captured ${formatShortDate(capturedAt)}".
|
|
2325
|
+
*
|
|
2326
|
+
* Exported for testing. Not part of the public surface.
|
|
2327
|
+
*/ function formatBaselineLabel(baseline) {
|
|
2328
|
+
const name = baseline.name ?? `Baseline ${baseline.index}`;
|
|
2329
|
+
return `${name} — captured ${formatShortDate(baseline.capturedAt)}`;
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Format a Date as YYYY-MM-DD using local-time components. Deterministic
|
|
2333
|
+
* across locales (no Intl.DateTimeFormat — those vary by host locale).
|
|
2334
|
+
*
|
|
2335
|
+
* Exported for testing. Not part of the public surface.
|
|
2336
|
+
*/ function formatShortDate(d) {
|
|
2337
|
+
const year = d.getFullYear();
|
|
2338
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
2339
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
2340
|
+
return `${year}-${month}-${day}`;
|
|
2341
|
+
}
|
|
2291
2342
|
function getProjectEnd(p) {
|
|
2292
2343
|
if (p.end) return p.end;
|
|
2293
2344
|
let latestMs = Number.NEGATIVE_INFINITY;
|
|
@@ -2298,6 +2349,72 @@ function getProjectEnd(p) {
|
|
|
2298
2349
|
const cushion = 24 * 60 * 60 * 1000; // 1 day
|
|
2299
2350
|
return Number.isFinite(latestMs) ? new Date(latestMs + cushion) : new Date(p.start);
|
|
2300
2351
|
}
|
|
2352
|
+
/**
|
|
2353
|
+
* Resolve the effective baseline indices from the two GanttProps inputs.
|
|
2354
|
+
*
|
|
2355
|
+
* - `baselineIndices` takes precedence when set (including when empty —
|
|
2356
|
+
* passing `[]` is an explicit opt-out signal).
|
|
2357
|
+
* - When `baselineIndices` is undefined, fall back to wrapping `baselineIndex`
|
|
2358
|
+
* in a single-element array.
|
|
2359
|
+
* - When both are undefined, return an empty array.
|
|
2360
|
+
*
|
|
2361
|
+
* Exported for testing. Not part of the public surface; consumers don't
|
|
2362
|
+
* call this directly.
|
|
2363
|
+
*/ function resolveEffectiveBaselineIndices(baselineIndices, baselineIndex) {
|
|
2364
|
+
return baselineIndices ?? (baselineIndex !== undefined ? [
|
|
2365
|
+
baselineIndex
|
|
2366
|
+
] : []);
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* Map effective baseline indices to actual Baseline records on a project,
|
|
2370
|
+
* preserving caller order. Indices not present on the project are silently
|
|
2371
|
+
* dropped (per spec — consumers can pass a fixed shape across projects
|
|
2372
|
+
* with varying baseline counts).
|
|
2373
|
+
*
|
|
2374
|
+
* Exported for testing. Not part of the public surface.
|
|
2375
|
+
*/ function resolveBaselines(allBaselines, effectiveIndices) {
|
|
2376
|
+
if (effectiveIndices.length === 0) return [];
|
|
2377
|
+
const byIndex = new Map(allBaselines.map((b)=>[
|
|
2378
|
+
b.index,
|
|
2379
|
+
b
|
|
2380
|
+
]));
|
|
2381
|
+
const out = [];
|
|
2382
|
+
for (const idx of effectiveIndices){
|
|
2383
|
+
const b = byIndex.get(idx);
|
|
2384
|
+
if (b) out.push(b);
|
|
2385
|
+
}
|
|
2386
|
+
return out;
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Convert the rendered tasks + resolved baselines into the SVAR ITask[]
|
|
2390
|
+
* shape, including phantom ghost rows for each (task × baseline) pair
|
|
2391
|
+
* when ghost bars are enabled.
|
|
2392
|
+
*
|
|
2393
|
+
* In single-baseline mode (resolvedBaselines.length === 1), the live row
|
|
2394
|
+
* carries the variance pill (`start_variance` / `is_slipped` / `is_ahead`
|
|
2395
|
+
* are populated relative to that one baseline). In multi-baseline mode
|
|
2396
|
+
* (length > 1), the live row gets no variance fields (would require a
|
|
2397
|
+
* "primary" baseline concept that the spec rejects); each phantom row
|
|
2398
|
+
* gets its own.
|
|
2399
|
+
*
|
|
2400
|
+
* Exported for testing. Not part of the public surface.
|
|
2401
|
+
*/ function buildSvarTasks(renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled) {
|
|
2402
|
+
if (!ghostBarsEnabled || resolvedBaselines.length === 0) {
|
|
2403
|
+
const primary = resolvedBaselines[0];
|
|
2404
|
+
return renderableTasks.map((t)=>toSvarTask(t, primary, calendar));
|
|
2405
|
+
}
|
|
2406
|
+
const out = [];
|
|
2407
|
+
for (const t of renderableTasks){
|
|
2408
|
+
const liveBarBaseline = resolvedBaselines.length === 1 ? resolvedBaselines[0] : undefined;
|
|
2409
|
+
out.push(toSvarTask(t, liveBarBaseline, calendar));
|
|
2410
|
+
if (t.type === 'summary') continue;
|
|
2411
|
+
for (const b of resolvedBaselines){
|
|
2412
|
+
const phantom = makeBaselinePhantom(t, b, calendar);
|
|
2413
|
+
if (phantom) out.push(phantom);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
return out;
|
|
2417
|
+
}
|
|
2301
2418
|
function resolveMarkers(userMarkers, projectStart, projectEnd) {
|
|
2302
2419
|
if (userMarkers) return userMarkers.map(toSvarMarker);
|
|
2303
2420
|
// Default: today line, only if today falls within the project window.
|
package/dist/index.d.cts
CHANGED
|
@@ -476,6 +476,26 @@ interface GanttProps {
|
|
|
476
476
|
*/
|
|
477
477
|
markers?: GanttMarker[];
|
|
478
478
|
/**
|
|
479
|
+
* Baselines to overlay as phantom ghost rows beneath each live task.
|
|
480
|
+
*
|
|
481
|
+
* - Single-baseline mode (length 1): the live bar carries the variance pill,
|
|
482
|
+
* matching the existing single-baseline behaviour.
|
|
483
|
+
* - Multi-baseline mode (length > 1): each phantom row carries its own
|
|
484
|
+
* variance pill against the live task; the live bar has no pill.
|
|
485
|
+
* - Indices not present on `project.baselines` are silently skipped (no
|
|
486
|
+
* throw) so consumers can pass a fixed shape regardless of how many
|
|
487
|
+
* baselines a particular project has captured.
|
|
488
|
+
*
|
|
489
|
+
* Phantom rows render in array order — consumers wanting chronological
|
|
490
|
+
* order should sort by `baseline.capturedAt` before passing.
|
|
491
|
+
*/
|
|
492
|
+
baselineIndices?: ReadonlyArray<BaselineIndex>;
|
|
493
|
+
/**
|
|
494
|
+
* @deprecated Use `baselineIndices: [N]`. Single-index convenience prop
|
|
495
|
+
* kept as a no-friction alias for v0.x consumers. Removed at v1.0.
|
|
496
|
+
* If both `baselineIndex` and `baselineIndices` are set, `baselineIndices`
|
|
497
|
+
* takes precedence.
|
|
498
|
+
*
|
|
479
499
|
* Show variance against this baseline index. If unset (or no matching
|
|
480
500
|
* baseline exists on `project.baselines`), bars render without variance
|
|
481
501
|
* pills. Construction-vertical use case (ADR-003): comparing the live
|
|
@@ -486,8 +506,9 @@ interface GanttProps {
|
|
|
486
506
|
/**
|
|
487
507
|
* Render the baseline as a separate "ghost" bar beneath each live task.
|
|
488
508
|
* Matches the MS Project baseline-view idiom construction PMs expect
|
|
489
|
-
* when reviewing variation claims. Default true when
|
|
490
|
-
* is set; pass `false` to keep
|
|
509
|
+
* when reviewing variation claims. Default true when either
|
|
510
|
+
* `baselineIndex` or `baselineIndices` is set; pass `false` to keep
|
|
511
|
+
* variance shown only as in-bar pills.
|
|
491
512
|
*/
|
|
492
513
|
showBaselineBars?: boolean;
|
|
493
514
|
/**
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/analysis.ts","../src/baseline.ts","../src/calendars/nz-holidays.ts","../src/editing/commands.ts","../src/editing/errors.ts","../src/editing/factories.ts","../src/editing/use-editable-project.ts","../src/export/types.ts","../src/Gantt.tsx","../src/mspdi/types.ts","../src/mspdi/parse.ts","../src/mspdi/serialize.ts","../src/SpikeGantt.tsx","../src/schedule.ts","../src/topological-sort.ts","../src/working-time.ts"],"mappings":";;;AAAA,KAAK,MAAM;AACX,KAAK,MAAM;AACX,KAAK,UAAU;AACf,KAAK,UAAU;AACf,KAAK,YAAY;AACjB,KAAK,QAAQ;AACb,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,UAAU;AACpB,UAAU,cAAc;AACxB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,QAAQ,MAAM;AACd;AACA;AACA,aAAa,MAAM;AACnB,UAAU,QAAQ;AAClB,kBAAkB,YAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,kBAAkB,UAAU;AAC5B;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB,gBAAgB,IAAI;AACpB,iBAAiB,IAAI;AACrB,eAAe,IAAI;AACnB,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,IAAI;AACd,QAAQ,MAAM;AACd,YAAY,MAAM;AAClB,YAAY,MAAM;AAClB,UAAU,cAAc;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA,KAAK,SAAS;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA,cAAc,YAAY;AAC1B,gBAAgB,iBAAiB;AACjC,qBAAqB,UAAU;AAC/B;AACA,UAAU,iBAAiB;AAC3B,UAAU,IAAI;AACd;AACA;AACA,gBAAgB,YAAY;AAC5B;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB,QAAQ,YAAY;AACpB,YAAY,MAAM;AAClB,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB,UAAU,QAAQ;AAClB,WAAW,aAAa;AACxB;AACA;AACA,gBAAgB,IAAI;AACpB;AACA,WAAW,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC3C;AACA,UAAU,oBAAoB;AAC9B,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,UAAU,OAAO;AACjB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,uBAAuB,UAAU;AACjC,WAAW,IAAI;AACf,WAAW,IAAI;AACf,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,UAAU;AAC3B;;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,IAAI;AACxD,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,YAAY;;AC3BhE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,SAAS,aAAa;AACvE;AACA,iBAAiB,IAAI;AACrB,IAAI,OAAO;AACX,UAAU,oBAAoB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B,UAAU,OAAO,iBAAiB,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC7H;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,YAAY,QAAQ,GAAG,oBAAoB;;ACtClH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,QAAQ;AACb,UAAU,wBAAwB;AAClC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA,SAAS,UAAU;AACnB;AACA;AACA;AACA,iBAAiB,gBAAgB,oCAAoC,QAAQ,GAAG,iBAAiB;AACjG,iBAAiB,iBAAiB,UAAU,wBAAwB,GAAG,QAAQ;;ACvB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,GAAG,OAAO;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO,GAAG,WAAW;AAC1C;;AC9BA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,SAAS,KAAK;AACrC;AACA;AACA;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU,KAAK,MAAM,iBAAiB,WAAW;AAClE,iBAAiB,YAAY,KAAK,MAAM,SAAS,IAAI,GAAG,WAAW;AACnE,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,OAAO,IAAI,YAAY,MAAM,iBAAiB,MAAM,GAAG,WAAW;AAC7F,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,SAAS,MAAM,UAAU,MAAM,SAAS,cAAc,iBAAiB,WAAW;AAC5G,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;;AC3BpD;AACA;AACA;AACA;AACA,UAAU,eAAe;AACzB,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB,UAAU,OAAO,GAAG,eAAe;;ACxBtE,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB;AACA;AACA,iBAAiB,IAAI,WAAW,IAAI,uBAAuB,IAAI;AAC/D;AACA,UAAU,iBAAiB;AAC3B;AACA;AACA;AACA,cAAc,UAAU;AACxB;AACA,UAAU,WAAW;AACrB,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,yBAAyB,iBAAiB,GAAG,OAAO,CAAC,IAAI;AACzD;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/analysis.ts","../src/baseline.ts","../src/calendars/nz-holidays.ts","../src/editing/commands.ts","../src/editing/errors.ts","../src/editing/factories.ts","../src/editing/use-editable-project.ts","../src/export/types.ts","../src/Gantt.tsx","../src/mspdi/types.ts","../src/mspdi/parse.ts","../src/mspdi/serialize.ts","../src/SpikeGantt.tsx","../src/schedule.ts","../src/topological-sort.ts","../src/working-time.ts"],"mappings":";;;AAAA,KAAK,MAAM;AACX,KAAK,MAAM;AACX,KAAK,UAAU;AACf,KAAK,UAAU;AACf,KAAK,YAAY;AACjB,KAAK,QAAQ;AACb,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,UAAU;AACpB,UAAU,cAAc;AACxB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,QAAQ,MAAM;AACd;AACA;AACA,aAAa,MAAM;AACnB,UAAU,QAAQ;AAClB,kBAAkB,YAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,kBAAkB,UAAU;AAC5B;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB,gBAAgB,IAAI;AACpB,iBAAiB,IAAI;AACrB,eAAe,IAAI;AACnB,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,IAAI;AACd,QAAQ,MAAM;AACd,YAAY,MAAM;AAClB,YAAY,MAAM;AAClB,UAAU,cAAc;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA,KAAK,SAAS;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA,cAAc,YAAY;AAC1B,gBAAgB,iBAAiB;AACjC,qBAAqB,UAAU;AAC/B;AACA,UAAU,iBAAiB;AAC3B,UAAU,IAAI;AACd;AACA;AACA,gBAAgB,YAAY;AAC5B;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB,QAAQ,YAAY;AACpB,YAAY,MAAM;AAClB,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB,UAAU,QAAQ;AAClB,WAAW,aAAa;AACxB;AACA;AACA,gBAAgB,IAAI;AACpB;AACA,WAAW,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC3C;AACA,UAAU,oBAAoB;AAC9B,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,UAAU,OAAO;AACjB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,uBAAuB,UAAU;AACjC,WAAW,IAAI;AACf,WAAW,IAAI;AACf,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,UAAU;AAC3B;;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,IAAI;AACxD,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,YAAY;;AC3BhE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,SAAS,aAAa;AACvE;AACA,iBAAiB,IAAI;AACrB,IAAI,OAAO;AACX,UAAU,oBAAoB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B,UAAU,OAAO,iBAAiB,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC7H;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,YAAY,QAAQ,GAAG,oBAAoB;;ACtClH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,QAAQ;AACb,UAAU,wBAAwB;AAClC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA,SAAS,UAAU;AACnB;AACA;AACA;AACA,iBAAiB,gBAAgB,oCAAoC,QAAQ,GAAG,iBAAiB;AACjG,iBAAiB,iBAAiB,UAAU,wBAAwB,GAAG,QAAQ;;ACvB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,GAAG,OAAO;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO,GAAG,WAAW;AAC1C;;AC9BA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,SAAS,KAAK;AACrC;AACA;AACA;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU,KAAK,MAAM,iBAAiB,WAAW;AAClE,iBAAiB,YAAY,KAAK,MAAM,SAAS,IAAI,GAAG,WAAW;AACnE,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,OAAO,IAAI,YAAY,MAAM,iBAAiB,MAAM,GAAG,WAAW;AAC7F,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,SAAS,MAAM,UAAU,MAAM,SAAS,cAAc,iBAAiB,WAAW;AAC5G,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;;AC3BpD;AACA;AACA;AACA;AACA,UAAU,eAAe;AACzB,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB,UAAU,OAAO,GAAG,eAAe;;ACxBtE,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB;AACA;AACA,iBAAiB,IAAI,WAAW,IAAI,uBAAuB,IAAI;AAC/D;AACA,UAAU,iBAAiB;AAC3B;AACA;AACA;AACA,cAAc,UAAU;AACxB;AACA,UAAU,WAAW;AACrB,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,yBAAyB,iBAAiB,GAAG,OAAO,CAAC,IAAI;AACzD;;ACzBA,UAAU,WAAW;AACrB,WAAW,IAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW,SAAS,IAAI;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,cAAc,IAAI;AAClB;AACA;AACA,UAAU,UAAU;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,aAAa,CAAC,aAAa;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,aAAa;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW,CAAC,MAAM;AACvC;AAgBA,cAAc,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,WAAW;;ACpJjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B,aAAa,OAAO;AACpB,mBAAmB,YAAY;AAC/B;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qBAAqB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrCA,iBAAiB,UAAU,eAAe,gBAAgB;;ACA1D,iBAAiB,cAAc,UAAU,OAAO,YAAY,qBAAqB;;ACAjF,iBAAiB,UAAU,IAAI,YAAY;;ACD3C,iBAAiB,QAAQ,UAAU,OAAO,GAAG,OAAO;;ACApD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,QAAQ,IAAI,WAAW,IAAI,KAAK,IAAI;;ACVpE,iBAAiB,YAAY,OAAO,IAAI,YAAY,QAAQ;AAC5D,iBAAiB,oBAAoB,OAAO,IAAI,YAAY,QAAQ;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB,QAAQ,IAAI,6BAA6B,QAAQ,GAAG,IAAI;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB,MAAM,IAAI,6BAA6B,QAAQ,GAAG,IAAI;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,GAAG,IAAI;AAC9E;AACA;AACA;AACA;AACA,iBAAiB,2BAA2B,OAAO,IAAI,YAAY,QAAQ,GAAG,IAAI;AAClF;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB,IAAI,IAAI,KAAK,IAAI,YAAY,QAAQ;;;;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -476,6 +476,26 @@ interface GanttProps {
|
|
|
476
476
|
*/
|
|
477
477
|
markers?: GanttMarker[];
|
|
478
478
|
/**
|
|
479
|
+
* Baselines to overlay as phantom ghost rows beneath each live task.
|
|
480
|
+
*
|
|
481
|
+
* - Single-baseline mode (length 1): the live bar carries the variance pill,
|
|
482
|
+
* matching the existing single-baseline behaviour.
|
|
483
|
+
* - Multi-baseline mode (length > 1): each phantom row carries its own
|
|
484
|
+
* variance pill against the live task; the live bar has no pill.
|
|
485
|
+
* - Indices not present on `project.baselines` are silently skipped (no
|
|
486
|
+
* throw) so consumers can pass a fixed shape regardless of how many
|
|
487
|
+
* baselines a particular project has captured.
|
|
488
|
+
*
|
|
489
|
+
* Phantom rows render in array order — consumers wanting chronological
|
|
490
|
+
* order should sort by `baseline.capturedAt` before passing.
|
|
491
|
+
*/
|
|
492
|
+
baselineIndices?: ReadonlyArray<BaselineIndex>;
|
|
493
|
+
/**
|
|
494
|
+
* @deprecated Use `baselineIndices: [N]`. Single-index convenience prop
|
|
495
|
+
* kept as a no-friction alias for v0.x consumers. Removed at v1.0.
|
|
496
|
+
* If both `baselineIndex` and `baselineIndices` are set, `baselineIndices`
|
|
497
|
+
* takes precedence.
|
|
498
|
+
*
|
|
479
499
|
* Show variance against this baseline index. If unset (or no matching
|
|
480
500
|
* baseline exists on `project.baselines`), bars render without variance
|
|
481
501
|
* pills. Construction-vertical use case (ADR-003): comparing the live
|
|
@@ -486,8 +506,9 @@ interface GanttProps {
|
|
|
486
506
|
/**
|
|
487
507
|
* Render the baseline as a separate "ghost" bar beneath each live task.
|
|
488
508
|
* Matches the MS Project baseline-view idiom construction PMs expect
|
|
489
|
-
* when reviewing variation claims. Default true when
|
|
490
|
-
* is set; pass `false` to keep
|
|
509
|
+
* when reviewing variation claims. Default true when either
|
|
510
|
+
* `baselineIndex` or `baselineIndices` is set; pass `false` to keep
|
|
511
|
+
* variance shown only as in-bar pills.
|
|
491
512
|
*/
|
|
492
513
|
showBaselineBars?: boolean;
|
|
493
514
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sources":["../src/types.ts","../src/analysis.ts","../src/baseline.ts","../src/calendars/nz-holidays.ts","../src/editing/commands.ts","../src/editing/errors.ts","../src/editing/factories.ts","../src/editing/use-editable-project.ts","../src/export/types.ts","../src/Gantt.tsx","../src/mspdi/types.ts","../src/mspdi/parse.ts","../src/mspdi/serialize.ts","../src/SpikeGantt.tsx","../src/schedule.ts","../src/topological-sort.ts","../src/working-time.ts"],"mappings":";;;AAAA,KAAK,MAAM;AACX,KAAK,MAAM;AACX,KAAK,UAAU;AACf,KAAK,UAAU;AACf,KAAK,YAAY;AACjB,KAAK,QAAQ;AACb,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,UAAU;AACpB,UAAU,cAAc;AACxB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,QAAQ,MAAM;AACd;AACA;AACA,aAAa,MAAM;AACnB,UAAU,QAAQ;AAClB,kBAAkB,YAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,kBAAkB,UAAU;AAC5B;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB,gBAAgB,IAAI;AACpB,iBAAiB,IAAI;AACrB,eAAe,IAAI;AACnB,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,IAAI;AACd,QAAQ,MAAM;AACd,YAAY,MAAM;AAClB,YAAY,MAAM;AAClB,UAAU,cAAc;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA,KAAK,SAAS;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA,cAAc,YAAY;AAC1B,gBAAgB,iBAAiB;AACjC,qBAAqB,UAAU;AAC/B;AACA,UAAU,iBAAiB;AAC3B,UAAU,IAAI;AACd;AACA;AACA,gBAAgB,YAAY;AAC5B;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB,QAAQ,YAAY;AACpB,YAAY,MAAM;AAClB,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB,UAAU,QAAQ;AAClB,WAAW,aAAa;AACxB;AACA;AACA,gBAAgB,IAAI;AACpB;AACA,WAAW,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC3C;AACA,UAAU,oBAAoB;AAC9B,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,UAAU,OAAO;AACjB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,uBAAuB,UAAU;AACjC,WAAW,IAAI;AACf,WAAW,IAAI;AACf,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,UAAU;AAC3B;;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,IAAI;AACxD,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,YAAY;;AC3BhE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,SAAS,aAAa;AACvE;AACA,iBAAiB,IAAI;AACrB,IAAI,OAAO;AACX,UAAU,oBAAoB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B,UAAU,OAAO,iBAAiB,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC7H;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,YAAY,QAAQ,GAAG,oBAAoB;;ACtClH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,QAAQ;AACb,UAAU,wBAAwB;AAClC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA,SAAS,UAAU;AACnB;AACA;AACA;AACA,iBAAiB,gBAAgB,oCAAoC,QAAQ,GAAG,iBAAiB;AACjG,iBAAiB,iBAAiB,UAAU,wBAAwB,GAAG,QAAQ;;ACvB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,GAAG,OAAO;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO,GAAG,WAAW;AAC1C;;AC9BA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,SAAS,KAAK;AACrC;AACA;AACA;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU,KAAK,MAAM,iBAAiB,WAAW;AAClE,iBAAiB,YAAY,KAAK,MAAM,SAAS,IAAI,GAAG,WAAW;AACnE,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,OAAO,IAAI,YAAY,MAAM,iBAAiB,MAAM,GAAG,WAAW;AAC7F,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,SAAS,MAAM,UAAU,MAAM,SAAS,cAAc,iBAAiB,WAAW;AAC5G,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;;AC3BpD;AACA;AACA;AACA;AACA,UAAU,eAAe;AACzB,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB,UAAU,OAAO,GAAG,eAAe;;ACxBtE,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB;AACA;AACA,iBAAiB,IAAI,WAAW,IAAI,uBAAuB,IAAI;AAC/D;AACA,UAAU,iBAAiB;AAC3B;AACA;AACA;AACA,cAAc,UAAU;AACxB;AACA,UAAU,WAAW;AACrB,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,yBAAyB,iBAAiB,GAAG,OAAO,CAAC,IAAI;AACzD;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/types.ts","../src/analysis.ts","../src/baseline.ts","../src/calendars/nz-holidays.ts","../src/editing/commands.ts","../src/editing/errors.ts","../src/editing/factories.ts","../src/editing/use-editable-project.ts","../src/export/types.ts","../src/Gantt.tsx","../src/mspdi/types.ts","../src/mspdi/parse.ts","../src/mspdi/serialize.ts","../src/SpikeGantt.tsx","../src/schedule.ts","../src/topological-sort.ts","../src/working-time.ts"],"mappings":";;;AAAA,KAAK,MAAM;AACX,KAAK,MAAM;AACX,KAAK,UAAU;AACf,KAAK,UAAU;AACf,KAAK,YAAY;AACjB,KAAK,QAAQ;AACb,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,UAAU;AACpB,UAAU,cAAc;AACxB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,QAAQ,MAAM;AACd;AACA;AACA,aAAa,MAAM;AACnB,UAAU,QAAQ;AAClB,kBAAkB,YAAY;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,kBAAkB,UAAU;AAC5B;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB,gBAAgB,IAAI;AACpB,iBAAiB,IAAI;AACrB,eAAe,IAAI;AACnB,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB,UAAU,IAAI;AACd,QAAQ,MAAM;AACd,YAAY,MAAM;AAClB,YAAY,MAAM;AAClB,UAAU,cAAc;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA,KAAK,SAAS;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA,cAAc,YAAY;AAC1B,gBAAgB,iBAAiB;AACjC,qBAAqB,UAAU;AAC/B;AACA,UAAU,iBAAiB;AAC3B,UAAU,IAAI;AACd;AACA;AACA,gBAAgB,YAAY;AAC5B;AACA;AACA;AACA,UAAU,QAAQ;AAClB,QAAQ,UAAU;AAClB;AACA;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB,QAAQ,YAAY;AACpB,YAAY,MAAM;AAClB,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB,UAAU,QAAQ;AAClB,WAAW,aAAa;AACxB;AACA;AACA,gBAAgB,IAAI;AACpB;AACA,WAAW,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC3C;AACA,UAAU,oBAAoB;AAC9B,WAAW,IAAI;AACf,SAAS,IAAI;AACb;AACA;AACA,UAAU,OAAO;AACjB;AACA,WAAW,IAAI;AACf;AACA,UAAU,IAAI;AACd,uBAAuB,UAAU;AACjC,WAAW,IAAI;AACf,WAAW,IAAI;AACf,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,UAAU;AAC3B;;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,IAAI;AACxD,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,GAAG,YAAY;;AC3BhE;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,UAAU,OAAO,SAAS,aAAa;AACvE;AACA,iBAAiB,IAAI;AACrB,IAAI,OAAO;AACX,UAAU,oBAAoB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B,UAAU,OAAO,iBAAiB,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB;AAC7H;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,YAAY,QAAQ,GAAG,oBAAoB;;ACtClH;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,QAAQ;AACb,UAAU,wBAAwB;AAClC;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,eAAe,YAAY;AAC3B;AACA,SAAS,UAAU;AACnB;AACA;AACA;AACA,iBAAiB,gBAAgB,oCAAoC,QAAQ,GAAG,iBAAiB;AACjG,iBAAiB,iBAAiB,UAAU,wBAAwB,GAAG,QAAQ;;ACvB/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW;AACrB;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,GAAG,OAAO;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO,GAAG,WAAW;AAC1C;;AC9BA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,SAAS,KAAK;AACrC;AACA;AACA;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,UAAU,KAAK,MAAM,iBAAiB,WAAW;AAClE,iBAAiB,YAAY,KAAK,MAAM,SAAS,IAAI,GAAG,WAAW;AACnE,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,eAAe,KAAK,MAAM,oBAAoB,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,OAAO,IAAI,YAAY,MAAM,iBAAiB,MAAM,GAAG,WAAW;AAC7F,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,SAAS,SAAS,MAAM,UAAU,MAAM,SAAS,cAAc,iBAAiB,WAAW;AAC5G,iBAAiB,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC,IAAI,IAAI,WAAW;AAC1E,iBAAiB,UAAU,KAAK,MAAM,GAAG,WAAW;;AC3BpD;AACA;AACA;AACA;AACA,UAAU,eAAe;AACzB,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAkB,UAAU,OAAO,GAAG,eAAe;;ACxBtE,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,UAAU;AACpB;AACA;AACA,iBAAiB,IAAI,WAAW,IAAI,uBAAuB,IAAI;AAC/D;AACA,UAAU,iBAAiB;AAC3B;AACA;AACA;AACA,cAAc,UAAU;AACxB;AACA,UAAU,WAAW;AACrB,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,wBAAwB,gBAAgB,GAAG,OAAO,CAAC,IAAI;AACvD,yBAAyB,iBAAiB,GAAG,OAAO,CAAC,IAAI;AACzD;;ACzBA,UAAU,WAAW;AACrB,WAAW,IAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,WAAW,SAAS,IAAI;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,EAAE;AACf,cAAc,IAAI;AAClB;AACA;AACA,UAAU,UAAU;AACpB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,aAAa,CAAC,aAAa;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,aAAa;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW,CAAC,MAAM;AACvC;AAgBA,cAAc,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,WAAW;;ACpJjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,gBAAgB;AAC1B,aAAa,OAAO;AACpB,mBAAmB,YAAY;AAC/B;AACA,UAAU,YAAY;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,qBAAqB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrCA,iBAAiB,UAAU,eAAe,gBAAgB;;ACA1D,iBAAiB,cAAc,UAAU,OAAO,YAAY,qBAAqB;;ACAjF,iBAAiB,UAAU,IAAI,YAAY;;ACD3C,iBAAiB,QAAQ,UAAU,OAAO,GAAG,OAAO;;ACApD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,eAAe,QAAQ,IAAI,WAAW,IAAI,KAAK,IAAI;;ACVpE,iBAAiB,YAAY,OAAO,IAAI,YAAY,QAAQ;AAC5D,iBAAiB,oBAAoB,OAAO,IAAI,YAAY,QAAQ;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,iBAAiB,QAAQ,IAAI,6BAA6B,QAAQ,GAAG,IAAI;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB,MAAM,IAAI,6BAA6B,QAAQ,GAAG,IAAI;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB,OAAO,IAAI,YAAY,QAAQ,GAAG,IAAI;AAC9E;AACA;AACA;AACA;AACA,iBAAiB,2BAA2B,OAAO,IAAI,YAAY,QAAQ,GAAG,IAAI;AAClF;AACA;AACA;AACA;AACA;AACA,iBAAiB,qBAAqB,IAAI,IAAI,KAAK,IAAI,YAAY,QAAQ;;;;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1907,7 +1907,7 @@ function reducer(state, action) {
|
|
|
1907
1907
|
};
|
|
1908
1908
|
}
|
|
1909
1909
|
|
|
1910
|
-
__insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.construction-gantt-marker-today{background:#ef4444;color:#fff;font-weight:600}.construction-gantt-marker-milestone{background:#2563eb;color:#fff;font-weight:500}");
|
|
1910
|
+
__insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.construction-gantt-marker-today{background:#ef4444;color:#fff;font-weight:600}.construction-gantt-marker-milestone{background:#2563eb;color:#fff;font-weight:500}.bode-baseline-ghost{display:flex;align-items:center;gap:6px;height:60%;margin-top:15%;padding:0 8px;border-radius:3px;font-size:9px;font-style:italic;color:#fff;opacity:.85;white-space:nowrap}.bode-baseline-0{background:#6b7280}.bode-baseline-1{background:#3b82f6}.bode-baseline-2{background:#8b5cf6}.bode-baseline-3{background:#14b8a6;color:#0f172a}.bode-baseline-4{background:#f59e0b;color:#0f172a}.bode-baseline-5{background:#ec4899}.bode-baseline-6{background:#06b6d4;color:#0f172a}.bode-baseline-7{background:#84cc16;color:#0f172a}.bode-baseline-8{background:#f97316;color:#0f172a}.bode-baseline-9{background:#a855f7}.bode-baseline-10{background:#dc2626}");
|
|
1911
1911
|
|
|
1912
1912
|
// Render-only visibility filter for <Gantt> tasks.
|
|
1913
1913
|
//
|
|
@@ -1938,8 +1938,12 @@ __insertCSS(".construction-gantt-non-working{background:rgba(241,245,249,.65)}.c
|
|
|
1938
1938
|
return tasks.filter((t)=>visibleTaskIds.has(t.id));
|
|
1939
1939
|
}
|
|
1940
1940
|
|
|
1941
|
-
const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, cellWidth = 48, cellHeight = 42, preScheduled = false, markers, baselineIndex, showBaselineBars, columns, visibleTaskIds }, ref) {
|
|
1941
|
+
const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, cellWidth = 48, cellHeight = 42, preScheduled = false, markers, baselineIndex, baselineIndices, showBaselineBars, columns, visibleTaskIds }, ref) {
|
|
1942
1942
|
const containerRef = useRef(null);
|
|
1943
|
+
const effectiveBaselineIndices = useMemo(()=>resolveEffectiveBaselineIndices(baselineIndices, baselineIndex), [
|
|
1944
|
+
baselineIndices,
|
|
1945
|
+
baselineIndex
|
|
1946
|
+
]);
|
|
1943
1947
|
const scheduled = useMemo(()=>preScheduled ? project : schedule(project), [
|
|
1944
1948
|
project,
|
|
1945
1949
|
preScheduled
|
|
@@ -1954,32 +1958,17 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
1954
1958
|
scheduled.calendars,
|
|
1955
1959
|
scheduled.defaultCalendarId
|
|
1956
1960
|
]);
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
+
// Resolve effective indices → actual Baseline records, dropping any that
|
|
1962
|
+
// don't exist on the project. Preserves caller order so phantom rows
|
|
1963
|
+
// render in the array order the consumer passed.
|
|
1964
|
+
const resolvedBaselines = useMemo(()=>resolveBaselines(scheduled.baselines, effectiveBaselineIndices), [
|
|
1961
1965
|
scheduled.baselines,
|
|
1962
|
-
|
|
1966
|
+
effectiveBaselineIndices
|
|
1963
1967
|
]);
|
|
1964
|
-
const ghostBarsEnabled =
|
|
1965
|
-
const svarTasks = useMemo(()=>
|
|
1966
|
-
if (!ghostBarsEnabled || !baseline) {
|
|
1967
|
-
return renderableTasks.map((t)=>toSvarTask(t, baseline, calendar));
|
|
1968
|
-
}
|
|
1969
|
-
// Interleave each real task with its baseline-snapshot ghost row.
|
|
1970
|
-
// Phantoms share the real task's `parent` so they stay grouped under
|
|
1971
|
-
// the same summary in hierarchy views.
|
|
1972
|
-
const out = [];
|
|
1973
|
-
for (const t of renderableTasks){
|
|
1974
|
-
out.push(toSvarTask(t, baseline, calendar));
|
|
1975
|
-
if (t.type === 'summary') continue;
|
|
1976
|
-
const phantom = makeBaselinePhantom(t, baseline);
|
|
1977
|
-
if (phantom) out.push(phantom);
|
|
1978
|
-
}
|
|
1979
|
-
return out;
|
|
1980
|
-
}, [
|
|
1968
|
+
const ghostBarsEnabled = resolvedBaselines.length > 0 && (showBaselineBars ?? true);
|
|
1969
|
+
const svarTasks = useMemo(()=>buildSvarTasks(renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled), [
|
|
1981
1970
|
renderableTasks,
|
|
1982
|
-
|
|
1971
|
+
resolvedBaselines,
|
|
1983
1972
|
calendar,
|
|
1984
1973
|
ghostBarsEnabled
|
|
1985
1974
|
]);
|
|
@@ -2010,7 +1999,7 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2010
1999
|
]);
|
|
2011
2000
|
useImperativeHandle(ref, ()=>({
|
|
2012
2001
|
async exportPNG (options) {
|
|
2013
|
-
const { exportPNG } = await import('./png-
|
|
2002
|
+
const { exportPNG } = await import('./png-C2poOLQo.js');
|
|
2014
2003
|
return exportPNG({
|
|
2015
2004
|
scheduled,
|
|
2016
2005
|
ganttProps: {
|
|
@@ -2018,6 +2007,7 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2018
2007
|
cellHeight,
|
|
2019
2008
|
markers,
|
|
2020
2009
|
baselineIndex,
|
|
2010
|
+
baselineIndices,
|
|
2021
2011
|
showBaselineBars,
|
|
2022
2012
|
columns,
|
|
2023
2013
|
height,
|
|
@@ -2027,7 +2017,7 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2027
2017
|
});
|
|
2028
2018
|
},
|
|
2029
2019
|
async exportPDF (options) {
|
|
2030
|
-
const { exportPDF } = await import('./pdf-
|
|
2020
|
+
const { exportPDF } = await import('./pdf-BsFqo2UW.js');
|
|
2031
2021
|
return exportPDF({
|
|
2032
2022
|
scheduled,
|
|
2033
2023
|
ganttProps: {
|
|
@@ -2035,6 +2025,7 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2035
2025
|
cellHeight,
|
|
2036
2026
|
markers,
|
|
2037
2027
|
baselineIndex,
|
|
2028
|
+
baselineIndices,
|
|
2038
2029
|
showBaselineBars,
|
|
2039
2030
|
columns,
|
|
2040
2031
|
height,
|
|
@@ -2056,6 +2047,7 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2056
2047
|
cellHeight,
|
|
2057
2048
|
markers,
|
|
2058
2049
|
baselineIndex,
|
|
2050
|
+
baselineIndices,
|
|
2059
2051
|
showBaselineBars,
|
|
2060
2052
|
columns,
|
|
2061
2053
|
height,
|
|
@@ -2085,23 +2077,56 @@ const Gantt = /*#__PURE__*/ forwardRef(function Gantt({ project, height = 500, c
|
|
|
2085
2077
|
const ConstructionBar = ({ data })=>{
|
|
2086
2078
|
// Phantom baseline row — render a slim outlined ghost bar.
|
|
2087
2079
|
if (data.is_baseline_ghost) {
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
background: 'transparent',
|
|
2094
|
-
borderRadius: 3,
|
|
2095
|
-
fontSize: 9,
|
|
2096
|
-
color: '#64748b',
|
|
2097
|
-
display: 'flex',
|
|
2098
|
-
alignItems: 'center',
|
|
2099
|
-
padding: '0 6px',
|
|
2100
|
-
fontStyle: 'italic',
|
|
2101
|
-
whiteSpace: 'nowrap'
|
|
2102
|
-
},
|
|
2080
|
+
const baselineIdx = data.baseline_index ?? 0;
|
|
2081
|
+
const phantomSlipped = data.is_slipped ?? false;
|
|
2082
|
+
const phantomAhead = data.is_ahead ?? false;
|
|
2083
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
2084
|
+
className: `bode-baseline-ghost bode-baseline-${baselineIdx}`,
|
|
2103
2085
|
title: "Baseline position — where this task was when the baseline was captured",
|
|
2104
|
-
children:
|
|
2086
|
+
children: [
|
|
2087
|
+
/*#__PURE__*/ jsx("span", {
|
|
2088
|
+
style: {
|
|
2089
|
+
flex: 1,
|
|
2090
|
+
overflow: 'hidden',
|
|
2091
|
+
textOverflow: 'ellipsis'
|
|
2092
|
+
},
|
|
2093
|
+
children: data.text
|
|
2094
|
+
}),
|
|
2095
|
+
phantomSlipped && /*#__PURE__*/ jsxs("span", {
|
|
2096
|
+
style: {
|
|
2097
|
+
padding: '0 6px',
|
|
2098
|
+
background: '#fed7aa',
|
|
2099
|
+
color: '#7c2d12',
|
|
2100
|
+
borderRadius: 3,
|
|
2101
|
+
fontSize: 10,
|
|
2102
|
+
fontWeight: 700,
|
|
2103
|
+
lineHeight: '16px',
|
|
2104
|
+
whiteSpace: 'nowrap'
|
|
2105
|
+
},
|
|
2106
|
+
title: "Drifted later than the baseline",
|
|
2107
|
+
children: [
|
|
2108
|
+
"+",
|
|
2109
|
+
workingMinutesToShortLabel(data.start_variance ?? 0)
|
|
2110
|
+
]
|
|
2111
|
+
}),
|
|
2112
|
+
phantomAhead && /*#__PURE__*/ jsxs("span", {
|
|
2113
|
+
style: {
|
|
2114
|
+
padding: '0 6px',
|
|
2115
|
+
background: '#bbf7d0',
|
|
2116
|
+
color: '#14532d',
|
|
2117
|
+
borderRadius: 3,
|
|
2118
|
+
fontSize: 10,
|
|
2119
|
+
fontWeight: 700,
|
|
2120
|
+
lineHeight: '16px',
|
|
2121
|
+
whiteSpace: 'nowrap'
|
|
2122
|
+
},
|
|
2123
|
+
title: "Ahead of the baseline",
|
|
2124
|
+
children: [
|
|
2125
|
+
"−",
|
|
2126
|
+
workingMinutesToShortLabel(data.start_variance ?? 0)
|
|
2127
|
+
]
|
|
2128
|
+
})
|
|
2129
|
+
]
|
|
2105
2130
|
});
|
|
2106
2131
|
}
|
|
2107
2132
|
const isCritical = data.is_critical ?? false;
|
|
@@ -2252,19 +2277,25 @@ function toSvarTask(t, baseline, calendar) {
|
|
|
2252
2277
|
if (t.type === 'summary') base.open = t.open ?? true;
|
|
2253
2278
|
return base;
|
|
2254
2279
|
}
|
|
2255
|
-
function makeBaselinePhantom(t, baseline) {
|
|
2280
|
+
function makeBaselinePhantom(t, baseline, calendar) {
|
|
2256
2281
|
const snap = baseline.tasks.get(t.id);
|
|
2257
2282
|
if (!snap) return null;
|
|
2283
|
+
const variance = calendar ? getTaskBaselineVariance(t, baseline, calendar) : undefined;
|
|
2284
|
+
const startVariance = variance?.startVariance ?? 0;
|
|
2258
2285
|
return {
|
|
2259
|
-
id: `${t.id}
|
|
2260
|
-
text:
|
|
2286
|
+
id: `${t.id}__baseline_${baseline.index}`,
|
|
2287
|
+
text: formatBaselineLabel(baseline),
|
|
2261
2288
|
start: snap.start,
|
|
2262
2289
|
end: snap.end,
|
|
2263
2290
|
duration: snap.duration,
|
|
2264
2291
|
progress: 0,
|
|
2265
2292
|
type: 'task',
|
|
2266
2293
|
parent: t.parent,
|
|
2267
|
-
is_baseline_ghost: true
|
|
2294
|
+
is_baseline_ghost: true,
|
|
2295
|
+
baseline_index: baseline.index,
|
|
2296
|
+
start_variance: startVariance,
|
|
2297
|
+
is_slipped: startVariance >= 30,
|
|
2298
|
+
is_ahead: startVariance <= -30
|
|
2268
2299
|
};
|
|
2269
2300
|
}
|
|
2270
2301
|
function toSvarLink(l) {
|
|
@@ -2288,6 +2319,26 @@ function dependencyTypeToSvar(t) {
|
|
|
2288
2319
|
return 's2e';
|
|
2289
2320
|
}
|
|
2290
2321
|
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Format a baseline's metadata for display in the phantom row's label.
|
|
2324
|
+
* Returns "${name ?? `Baseline ${index}`} — captured ${formatShortDate(capturedAt)}".
|
|
2325
|
+
*
|
|
2326
|
+
* Exported for testing. Not part of the public surface.
|
|
2327
|
+
*/ function formatBaselineLabel(baseline) {
|
|
2328
|
+
const name = baseline.name ?? `Baseline ${baseline.index}`;
|
|
2329
|
+
return `${name} — captured ${formatShortDate(baseline.capturedAt)}`;
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Format a Date as YYYY-MM-DD using local-time components. Deterministic
|
|
2333
|
+
* across locales (no Intl.DateTimeFormat — those vary by host locale).
|
|
2334
|
+
*
|
|
2335
|
+
* Exported for testing. Not part of the public surface.
|
|
2336
|
+
*/ function formatShortDate(d) {
|
|
2337
|
+
const year = d.getFullYear();
|
|
2338
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
2339
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
2340
|
+
return `${year}-${month}-${day}`;
|
|
2341
|
+
}
|
|
2291
2342
|
function getProjectEnd(p) {
|
|
2292
2343
|
if (p.end) return p.end;
|
|
2293
2344
|
let latestMs = Number.NEGATIVE_INFINITY;
|
|
@@ -2298,6 +2349,72 @@ function getProjectEnd(p) {
|
|
|
2298
2349
|
const cushion = 24 * 60 * 60 * 1000; // 1 day
|
|
2299
2350
|
return Number.isFinite(latestMs) ? new Date(latestMs + cushion) : new Date(p.start);
|
|
2300
2351
|
}
|
|
2352
|
+
/**
|
|
2353
|
+
* Resolve the effective baseline indices from the two GanttProps inputs.
|
|
2354
|
+
*
|
|
2355
|
+
* - `baselineIndices` takes precedence when set (including when empty —
|
|
2356
|
+
* passing `[]` is an explicit opt-out signal).
|
|
2357
|
+
* - When `baselineIndices` is undefined, fall back to wrapping `baselineIndex`
|
|
2358
|
+
* in a single-element array.
|
|
2359
|
+
* - When both are undefined, return an empty array.
|
|
2360
|
+
*
|
|
2361
|
+
* Exported for testing. Not part of the public surface; consumers don't
|
|
2362
|
+
* call this directly.
|
|
2363
|
+
*/ function resolveEffectiveBaselineIndices(baselineIndices, baselineIndex) {
|
|
2364
|
+
return baselineIndices ?? (baselineIndex !== undefined ? [
|
|
2365
|
+
baselineIndex
|
|
2366
|
+
] : []);
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* Map effective baseline indices to actual Baseline records on a project,
|
|
2370
|
+
* preserving caller order. Indices not present on the project are silently
|
|
2371
|
+
* dropped (per spec — consumers can pass a fixed shape across projects
|
|
2372
|
+
* with varying baseline counts).
|
|
2373
|
+
*
|
|
2374
|
+
* Exported for testing. Not part of the public surface.
|
|
2375
|
+
*/ function resolveBaselines(allBaselines, effectiveIndices) {
|
|
2376
|
+
if (effectiveIndices.length === 0) return [];
|
|
2377
|
+
const byIndex = new Map(allBaselines.map((b)=>[
|
|
2378
|
+
b.index,
|
|
2379
|
+
b
|
|
2380
|
+
]));
|
|
2381
|
+
const out = [];
|
|
2382
|
+
for (const idx of effectiveIndices){
|
|
2383
|
+
const b = byIndex.get(idx);
|
|
2384
|
+
if (b) out.push(b);
|
|
2385
|
+
}
|
|
2386
|
+
return out;
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Convert the rendered tasks + resolved baselines into the SVAR ITask[]
|
|
2390
|
+
* shape, including phantom ghost rows for each (task × baseline) pair
|
|
2391
|
+
* when ghost bars are enabled.
|
|
2392
|
+
*
|
|
2393
|
+
* In single-baseline mode (resolvedBaselines.length === 1), the live row
|
|
2394
|
+
* carries the variance pill (`start_variance` / `is_slipped` / `is_ahead`
|
|
2395
|
+
* are populated relative to that one baseline). In multi-baseline mode
|
|
2396
|
+
* (length > 1), the live row gets no variance fields (would require a
|
|
2397
|
+
* "primary" baseline concept that the spec rejects); each phantom row
|
|
2398
|
+
* gets its own.
|
|
2399
|
+
*
|
|
2400
|
+
* Exported for testing. Not part of the public surface.
|
|
2401
|
+
*/ function buildSvarTasks(renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled) {
|
|
2402
|
+
if (!ghostBarsEnabled || resolvedBaselines.length === 0) {
|
|
2403
|
+
const primary = resolvedBaselines[0];
|
|
2404
|
+
return renderableTasks.map((t)=>toSvarTask(t, primary, calendar));
|
|
2405
|
+
}
|
|
2406
|
+
const out = [];
|
|
2407
|
+
for (const t of renderableTasks){
|
|
2408
|
+
const liveBarBaseline = resolvedBaselines.length === 1 ? resolvedBaselines[0] : undefined;
|
|
2409
|
+
out.push(toSvarTask(t, liveBarBaseline, calendar));
|
|
2410
|
+
if (t.type === 'summary') continue;
|
|
2411
|
+
for (const b of resolvedBaselines){
|
|
2412
|
+
const phantom = makeBaselinePhantom(t, b, calendar);
|
|
2413
|
+
if (phantom) out.push(phantom);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
return out;
|
|
2417
|
+
}
|
|
2301
2418
|
function resolveMarkers(userMarkers, projectStart, projectEnd) {
|
|
2302
2419
|
if (userMarkers) return userMarkers.map(toSvarMarker);
|
|
2303
2420
|
// Default: today line, only if today falls within the project window.
|
|
@@ -8,7 +8,7 @@ function __insertCSS(code) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
import { jsPDF } from 'jspdf';
|
|
11
|
-
import { exportPNG } from './png-
|
|
11
|
+
import { exportPNG } from './png-C2poOLQo.js';
|
|
12
12
|
|
|
13
13
|
// Pure-function image-fit math. Used by the PDF exporter to scale the
|
|
14
14
|
// captured PNG onto a chosen page format with a uniform margin while
|
|
@@ -8,7 +8,7 @@ function __insertCSS(code) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
var jspdf = require('jspdf');
|
|
11
|
-
var png = require('./png-
|
|
11
|
+
var png = require('./png-BloW1DDl.cjs');
|
|
12
12
|
|
|
13
13
|
// Pure-function image-fit math. Used by the PDF exporter to scale the
|
|
14
14
|
// captured PNG onto a chosen page format with a uniform margin while
|
|
@@ -29,6 +29,7 @@ async function renderOffscreen(args) {
|
|
|
29
29
|
cellHeight: ganttProps.cellHeight,
|
|
30
30
|
markers: ganttProps.markers,
|
|
31
31
|
baselineIndex: ganttProps.baselineIndex,
|
|
32
|
+
baselineIndices: ganttProps.baselineIndices,
|
|
32
33
|
showBaselineBars: ganttProps.showBaselineBars,
|
|
33
34
|
columns: ganttProps.columns,
|
|
34
35
|
visibleTaskIds: ganttProps.visibleTaskIds,
|
|
@@ -29,6 +29,7 @@ async function renderOffscreen(args) {
|
|
|
29
29
|
cellHeight: ganttProps.cellHeight,
|
|
30
30
|
markers: ganttProps.markers,
|
|
31
31
|
baselineIndex: ganttProps.baselineIndex,
|
|
32
|
+
baselineIndices: ganttProps.baselineIndices,
|
|
32
33
|
showBaselineBars: ganttProps.showBaselineBars,
|
|
33
34
|
columns: ganttProps.columns,
|
|
34
35
|
visibleTaskIds: ganttProps.visibleTaskIds,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "construction-gantt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "MIT React Gantt for construction project management — PRO-equivalent scheduling engine + construction-vertical extensions on free SVAR React Gantt",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,4 +83,4 @@
|
|
|
83
83
|
"typecheck": "tsc --noEmit",
|
|
84
84
|
"test": "vitest run --project=unit"
|
|
85
85
|
}
|
|
86
|
-
}
|
|
86
|
+
}
|
package/src/Gantt.css
CHANGED
|
@@ -21,3 +21,42 @@
|
|
|
21
21
|
color: #ffffff;
|
|
22
22
|
font-weight: 500;
|
|
23
23
|
}
|
|
24
|
+
|
|
25
|
+
/* Phantom baseline-row styling. Each row gets `.bode-baseline-ghost`
|
|
26
|
+
* plus a `.bode-baseline-${N}` class identifying WHICH baseline.
|
|
27
|
+
* Consumers override colours by re-declaring `.bode-baseline-N` with
|
|
28
|
+
* higher specificity or `!important`. */
|
|
29
|
+
.bode-baseline-ghost {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: 6px;
|
|
33
|
+
height: 60%;
|
|
34
|
+
margin-top: 15%;
|
|
35
|
+
padding: 0 8px;
|
|
36
|
+
border-radius: 3px;
|
|
37
|
+
font-size: 9px;
|
|
38
|
+
font-style: italic;
|
|
39
|
+
color: #ffffff;
|
|
40
|
+
opacity: 0.85;
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Per-baseline palette. Picked for distinguishability + colourblind-
|
|
45
|
+
* friendly ordering: greys → cool blues → warm reds for higher indices.
|
|
46
|
+
* Consumers override by re-declaring with higher specificity or `!important`.
|
|
47
|
+
*
|
|
48
|
+
* Lighter backgrounds (amber, lime, cyan, teal, orange) override the default
|
|
49
|
+
* white text to slate `#0f172a` so the small italic label remains legible
|
|
50
|
+
* (WCAG AA 4.5:1 for small text). Darker backgrounds keep the ghost rule's
|
|
51
|
+
* white text. */
|
|
52
|
+
.bode-baseline-0 { background: #6b7280; } /* gray */
|
|
53
|
+
.bode-baseline-1 { background: #3b82f6; } /* blue */
|
|
54
|
+
.bode-baseline-2 { background: #8b5cf6; } /* violet */
|
|
55
|
+
.bode-baseline-3 { background: #14b8a6; color: #0f172a; } /* teal */
|
|
56
|
+
.bode-baseline-4 { background: #f59e0b; color: #0f172a; } /* amber */
|
|
57
|
+
.bode-baseline-5 { background: #ec4899; } /* pink */
|
|
58
|
+
.bode-baseline-6 { background: #06b6d4; color: #0f172a; } /* cyan */
|
|
59
|
+
.bode-baseline-7 { background: #84cc16; color: #0f172a; } /* lime */
|
|
60
|
+
.bode-baseline-8 { background: #f97316; color: #0f172a; } /* orange */
|
|
61
|
+
.bode-baseline-9 { background: #a855f7; } /* purple */
|
|
62
|
+
.bode-baseline-10 { background: #dc2626; } /* red */
|
package/src/Gantt.tsx
CHANGED
|
@@ -98,6 +98,26 @@ export interface GanttProps {
|
|
|
98
98
|
*/
|
|
99
99
|
markers?: GanttMarker[];
|
|
100
100
|
/**
|
|
101
|
+
* Baselines to overlay as phantom ghost rows beneath each live task.
|
|
102
|
+
*
|
|
103
|
+
* - Single-baseline mode (length 1): the live bar carries the variance pill,
|
|
104
|
+
* matching the existing single-baseline behaviour.
|
|
105
|
+
* - Multi-baseline mode (length > 1): each phantom row carries its own
|
|
106
|
+
* variance pill against the live task; the live bar has no pill.
|
|
107
|
+
* - Indices not present on `project.baselines` are silently skipped (no
|
|
108
|
+
* throw) so consumers can pass a fixed shape regardless of how many
|
|
109
|
+
* baselines a particular project has captured.
|
|
110
|
+
*
|
|
111
|
+
* Phantom rows render in array order — consumers wanting chronological
|
|
112
|
+
* order should sort by `baseline.capturedAt` before passing.
|
|
113
|
+
*/
|
|
114
|
+
baselineIndices?: ReadonlyArray<BaselineIndex>;
|
|
115
|
+
/**
|
|
116
|
+
* @deprecated Use `baselineIndices: [N]`. Single-index convenience prop
|
|
117
|
+
* kept as a no-friction alias for v0.x consumers. Removed at v1.0.
|
|
118
|
+
* If both `baselineIndex` and `baselineIndices` are set, `baselineIndices`
|
|
119
|
+
* takes precedence.
|
|
120
|
+
*
|
|
101
121
|
* Show variance against this baseline index. If unset (or no matching
|
|
102
122
|
* baseline exists on `project.baselines`), bars render without variance
|
|
103
123
|
* pills. Construction-vertical use case (ADR-003): comparing the live
|
|
@@ -108,8 +128,9 @@ export interface GanttProps {
|
|
|
108
128
|
/**
|
|
109
129
|
* Render the baseline as a separate "ghost" bar beneath each live task.
|
|
110
130
|
* Matches the MS Project baseline-view idiom construction PMs expect
|
|
111
|
-
* when reviewing variation claims. Default true when
|
|
112
|
-
* is set; pass `false` to keep
|
|
131
|
+
* when reviewing variation claims. Default true when either
|
|
132
|
+
* `baselineIndex` or `baselineIndices` is set; pass `false` to keep
|
|
133
|
+
* variance shown only as in-bar pills.
|
|
113
134
|
*/
|
|
114
135
|
showBaselineBars?: boolean;
|
|
115
136
|
/**
|
|
@@ -155,6 +176,8 @@ interface SvarTaskWithComputed extends ITask {
|
|
|
155
176
|
is_ahead?: boolean;
|
|
156
177
|
/** True for phantom rows representing a baseline snapshot's position. */
|
|
157
178
|
is_baseline_ghost?: boolean;
|
|
179
|
+
/** When set, identifies which baseline (0..10) this phantom row mirrors. */
|
|
180
|
+
baseline_index?: BaselineIndex;
|
|
158
181
|
}
|
|
159
182
|
|
|
160
183
|
interface SvarMarker {
|
|
@@ -172,6 +195,7 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
172
195
|
preScheduled = false,
|
|
173
196
|
markers,
|
|
174
197
|
baselineIndex,
|
|
198
|
+
baselineIndices,
|
|
175
199
|
showBaselineBars,
|
|
176
200
|
columns,
|
|
177
201
|
visibleTaskIds,
|
|
@@ -180,6 +204,11 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
180
204
|
) {
|
|
181
205
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
182
206
|
|
|
207
|
+
const effectiveBaselineIndices = useMemo<ReadonlyArray<BaselineIndex>>(
|
|
208
|
+
() => resolveEffectiveBaselineIndices(baselineIndices, baselineIndex),
|
|
209
|
+
[baselineIndices, baselineIndex],
|
|
210
|
+
);
|
|
211
|
+
|
|
183
212
|
const scheduled = useMemo(
|
|
184
213
|
() => (preScheduled ? project : schedule(project)),
|
|
185
214
|
[project, preScheduled],
|
|
@@ -197,29 +226,20 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
197
226
|
[scheduled.calendars, scheduled.defaultCalendarId],
|
|
198
227
|
);
|
|
199
228
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
229
|
+
// Resolve effective indices → actual Baseline records, dropping any that
|
|
230
|
+
// don't exist on the project. Preserves caller order so phantom rows
|
|
231
|
+
// render in the array order the consumer passed.
|
|
232
|
+
const resolvedBaselines = useMemo<Baseline[]>(
|
|
233
|
+
() => resolveBaselines(scheduled.baselines, effectiveBaselineIndices),
|
|
234
|
+
[scheduled.baselines, effectiveBaselineIndices],
|
|
235
|
+
);
|
|
204
236
|
|
|
205
|
-
const ghostBarsEnabled =
|
|
237
|
+
const ghostBarsEnabled = resolvedBaselines.length > 0 && (showBaselineBars ?? true);
|
|
206
238
|
|
|
207
|
-
const svarTasks: ITask[] = useMemo(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
// Interleave each real task with its baseline-snapshot ghost row.
|
|
212
|
-
// Phantoms share the real task's `parent` so they stay grouped under
|
|
213
|
-
// the same summary in hierarchy views.
|
|
214
|
-
const out: SvarTaskWithComputed[] = [];
|
|
215
|
-
for (const t of renderableTasks) {
|
|
216
|
-
out.push(toSvarTask(t, baseline, calendar));
|
|
217
|
-
if (t.type === 'summary') continue;
|
|
218
|
-
const phantom = makeBaselinePhantom(t, baseline);
|
|
219
|
-
if (phantom) out.push(phantom);
|
|
220
|
-
}
|
|
221
|
-
return out;
|
|
222
|
-
}, [renderableTasks, baseline, calendar, ghostBarsEnabled]);
|
|
239
|
+
const svarTasks: ITask[] = useMemo(
|
|
240
|
+
() => buildSvarTasks(renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled),
|
|
241
|
+
[renderableTasks, resolvedBaselines, calendar, ghostBarsEnabled],
|
|
242
|
+
);
|
|
223
243
|
const svarLinks: ILink[] = useMemo(() => scheduled.links.map(toSvarLink), [scheduled.links]);
|
|
224
244
|
|
|
225
245
|
const projectEnd = useMemo(() => getProjectEnd(scheduled), [scheduled]);
|
|
@@ -255,6 +275,7 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
255
275
|
cellHeight,
|
|
256
276
|
markers,
|
|
257
277
|
baselineIndex,
|
|
278
|
+
baselineIndices,
|
|
258
279
|
showBaselineBars,
|
|
259
280
|
columns,
|
|
260
281
|
height,
|
|
@@ -272,6 +293,7 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
272
293
|
cellHeight,
|
|
273
294
|
markers,
|
|
274
295
|
baselineIndex,
|
|
296
|
+
baselineIndices,
|
|
275
297
|
showBaselineBars,
|
|
276
298
|
columns,
|
|
277
299
|
height,
|
|
@@ -291,6 +313,7 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
291
313
|
cellHeight,
|
|
292
314
|
markers,
|
|
293
315
|
baselineIndex,
|
|
316
|
+
baselineIndices,
|
|
294
317
|
showBaselineBars,
|
|
295
318
|
columns,
|
|
296
319
|
height,
|
|
@@ -316,28 +339,52 @@ export const Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(
|
|
|
316
339
|
);
|
|
317
340
|
});
|
|
318
341
|
|
|
319
|
-
const ConstructionBar: FC<{ data: SvarTaskWithComputed }> = ({ data }) => {
|
|
342
|
+
export const ConstructionBar: FC<{ data: SvarTaskWithComputed }> = ({ data }) => {
|
|
320
343
|
// Phantom baseline row — render a slim outlined ghost bar.
|
|
321
344
|
if (data.is_baseline_ghost) {
|
|
345
|
+
const baselineIdx = data.baseline_index ?? 0;
|
|
346
|
+
const phantomSlipped = data.is_slipped ?? false;
|
|
347
|
+
const phantomAhead = data.is_ahead ?? false;
|
|
322
348
|
return (
|
|
323
349
|
<div
|
|
324
|
-
|
|
325
|
-
height: '60%',
|
|
326
|
-
marginTop: '15%',
|
|
327
|
-
border: '1.5px dashed #94a3b8',
|
|
328
|
-
background: 'transparent',
|
|
329
|
-
borderRadius: 3,
|
|
330
|
-
fontSize: 9,
|
|
331
|
-
color: '#64748b',
|
|
332
|
-
display: 'flex',
|
|
333
|
-
alignItems: 'center',
|
|
334
|
-
padding: '0 6px',
|
|
335
|
-
fontStyle: 'italic',
|
|
336
|
-
whiteSpace: 'nowrap',
|
|
337
|
-
}}
|
|
350
|
+
className={`bode-baseline-ghost bode-baseline-${baselineIdx}`}
|
|
338
351
|
title="Baseline position — where this task was when the baseline was captured"
|
|
339
352
|
>
|
|
340
|
-
|
|
353
|
+
<span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis' }}>{data.text}</span>
|
|
354
|
+
{phantomSlipped && (
|
|
355
|
+
<span
|
|
356
|
+
style={{
|
|
357
|
+
padding: '0 6px',
|
|
358
|
+
background: '#fed7aa',
|
|
359
|
+
color: '#7c2d12',
|
|
360
|
+
borderRadius: 3,
|
|
361
|
+
fontSize: 10,
|
|
362
|
+
fontWeight: 700,
|
|
363
|
+
lineHeight: '16px',
|
|
364
|
+
whiteSpace: 'nowrap',
|
|
365
|
+
}}
|
|
366
|
+
title="Drifted later than the baseline"
|
|
367
|
+
>
|
|
368
|
+
+{workingMinutesToShortLabel(data.start_variance ?? 0)}
|
|
369
|
+
</span>
|
|
370
|
+
)}
|
|
371
|
+
{phantomAhead && (
|
|
372
|
+
<span
|
|
373
|
+
style={{
|
|
374
|
+
padding: '0 6px',
|
|
375
|
+
background: '#bbf7d0',
|
|
376
|
+
color: '#14532d',
|
|
377
|
+
borderRadius: 3,
|
|
378
|
+
fontSize: 10,
|
|
379
|
+
fontWeight: 700,
|
|
380
|
+
lineHeight: '16px',
|
|
381
|
+
whiteSpace: 'nowrap',
|
|
382
|
+
}}
|
|
383
|
+
title="Ahead of the baseline"
|
|
384
|
+
>
|
|
385
|
+
−{workingMinutesToShortLabel(data.start_variance ?? 0)}
|
|
386
|
+
</span>
|
|
387
|
+
)}
|
|
341
388
|
</div>
|
|
342
389
|
);
|
|
343
390
|
}
|
|
@@ -496,12 +543,18 @@ function toSvarTask(
|
|
|
496
543
|
return base;
|
|
497
544
|
}
|
|
498
545
|
|
|
499
|
-
function makeBaselinePhantom(
|
|
546
|
+
function makeBaselinePhantom(
|
|
547
|
+
t: Task,
|
|
548
|
+
baseline: Baseline,
|
|
549
|
+
calendar: Calendar | undefined,
|
|
550
|
+
): SvarTaskWithComputed | null {
|
|
500
551
|
const snap = baseline.tasks.get(t.id);
|
|
501
552
|
if (!snap) return null;
|
|
553
|
+
const variance = calendar ? getTaskBaselineVariance(t, baseline, calendar) : undefined;
|
|
554
|
+
const startVariance = variance?.startVariance ?? 0;
|
|
502
555
|
return {
|
|
503
|
-
id: `${t.id}
|
|
504
|
-
text:
|
|
556
|
+
id: `${t.id}__baseline_${baseline.index}`,
|
|
557
|
+
text: formatBaselineLabel(baseline),
|
|
505
558
|
start: snap.start,
|
|
506
559
|
end: snap.end,
|
|
507
560
|
duration: snap.duration,
|
|
@@ -509,6 +562,10 @@ function makeBaselinePhantom(t: Task, baseline: Baseline): SvarTaskWithComputed
|
|
|
509
562
|
type: 'task',
|
|
510
563
|
parent: t.parent,
|
|
511
564
|
is_baseline_ghost: true,
|
|
565
|
+
baseline_index: baseline.index,
|
|
566
|
+
start_variance: startVariance,
|
|
567
|
+
is_slipped: startVariance >= 30,
|
|
568
|
+
is_ahead: startVariance <= -30,
|
|
512
569
|
};
|
|
513
570
|
}
|
|
514
571
|
|
|
@@ -535,6 +592,30 @@ function dependencyTypeToSvar(t: DependencyType): ILink['type'] {
|
|
|
535
592
|
}
|
|
536
593
|
}
|
|
537
594
|
|
|
595
|
+
/**
|
|
596
|
+
* Format a baseline's metadata for display in the phantom row's label.
|
|
597
|
+
* Returns "${name ?? `Baseline ${index}`} — captured ${formatShortDate(capturedAt)}".
|
|
598
|
+
*
|
|
599
|
+
* Exported for testing. Not part of the public surface.
|
|
600
|
+
*/
|
|
601
|
+
export function formatBaselineLabel(baseline: Baseline): string {
|
|
602
|
+
const name = baseline.name ?? `Baseline ${baseline.index}`;
|
|
603
|
+
return `${name} — captured ${formatShortDate(baseline.capturedAt)}`;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Format a Date as YYYY-MM-DD using local-time components. Deterministic
|
|
608
|
+
* across locales (no Intl.DateTimeFormat — those vary by host locale).
|
|
609
|
+
*
|
|
610
|
+
* Exported for testing. Not part of the public surface.
|
|
611
|
+
*/
|
|
612
|
+
export function formatShortDate(d: Date): string {
|
|
613
|
+
const year = d.getFullYear();
|
|
614
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
615
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
616
|
+
return `${year}-${month}-${day}`;
|
|
617
|
+
}
|
|
618
|
+
|
|
538
619
|
function getProjectEnd(p: Project): Date {
|
|
539
620
|
if (p.end) return p.end;
|
|
540
621
|
let latestMs = Number.NEGATIVE_INFINITY;
|
|
@@ -546,6 +627,84 @@ function getProjectEnd(p: Project): Date {
|
|
|
546
627
|
return Number.isFinite(latestMs) ? new Date(latestMs + cushion) : new Date(p.start);
|
|
547
628
|
}
|
|
548
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Resolve the effective baseline indices from the two GanttProps inputs.
|
|
632
|
+
*
|
|
633
|
+
* - `baselineIndices` takes precedence when set (including when empty —
|
|
634
|
+
* passing `[]` is an explicit opt-out signal).
|
|
635
|
+
* - When `baselineIndices` is undefined, fall back to wrapping `baselineIndex`
|
|
636
|
+
* in a single-element array.
|
|
637
|
+
* - When both are undefined, return an empty array.
|
|
638
|
+
*
|
|
639
|
+
* Exported for testing. Not part of the public surface; consumers don't
|
|
640
|
+
* call this directly.
|
|
641
|
+
*/
|
|
642
|
+
export function resolveEffectiveBaselineIndices(
|
|
643
|
+
baselineIndices: ReadonlyArray<BaselineIndex> | undefined,
|
|
644
|
+
baselineIndex: BaselineIndex | undefined,
|
|
645
|
+
): ReadonlyArray<BaselineIndex> {
|
|
646
|
+
return baselineIndices ?? (baselineIndex !== undefined ? [baselineIndex] : []);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Map effective baseline indices to actual Baseline records on a project,
|
|
651
|
+
* preserving caller order. Indices not present on the project are silently
|
|
652
|
+
* dropped (per spec — consumers can pass a fixed shape across projects
|
|
653
|
+
* with varying baseline counts).
|
|
654
|
+
*
|
|
655
|
+
* Exported for testing. Not part of the public surface.
|
|
656
|
+
*/
|
|
657
|
+
export function resolveBaselines(
|
|
658
|
+
allBaselines: Baseline[],
|
|
659
|
+
effectiveIndices: ReadonlyArray<BaselineIndex>,
|
|
660
|
+
): Baseline[] {
|
|
661
|
+
if (effectiveIndices.length === 0) return [];
|
|
662
|
+
const byIndex = new Map(allBaselines.map((b) => [b.index, b]));
|
|
663
|
+
const out: Baseline[] = [];
|
|
664
|
+
for (const idx of effectiveIndices) {
|
|
665
|
+
const b = byIndex.get(idx);
|
|
666
|
+
if (b) out.push(b);
|
|
667
|
+
}
|
|
668
|
+
return out;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Convert the rendered tasks + resolved baselines into the SVAR ITask[]
|
|
673
|
+
* shape, including phantom ghost rows for each (task × baseline) pair
|
|
674
|
+
* when ghost bars are enabled.
|
|
675
|
+
*
|
|
676
|
+
* In single-baseline mode (resolvedBaselines.length === 1), the live row
|
|
677
|
+
* carries the variance pill (`start_variance` / `is_slipped` / `is_ahead`
|
|
678
|
+
* are populated relative to that one baseline). In multi-baseline mode
|
|
679
|
+
* (length > 1), the live row gets no variance fields (would require a
|
|
680
|
+
* "primary" baseline concept that the spec rejects); each phantom row
|
|
681
|
+
* gets its own.
|
|
682
|
+
*
|
|
683
|
+
* Exported for testing. Not part of the public surface.
|
|
684
|
+
*/
|
|
685
|
+
export function buildSvarTasks(
|
|
686
|
+
renderableTasks: Task[],
|
|
687
|
+
resolvedBaselines: Baseline[],
|
|
688
|
+
calendar: Calendar | undefined,
|
|
689
|
+
ghostBarsEnabled: boolean,
|
|
690
|
+
): SvarTaskWithComputed[] {
|
|
691
|
+
if (!ghostBarsEnabled || resolvedBaselines.length === 0) {
|
|
692
|
+
const primary = resolvedBaselines[0];
|
|
693
|
+
return renderableTasks.map((t) => toSvarTask(t, primary, calendar));
|
|
694
|
+
}
|
|
695
|
+
const out: SvarTaskWithComputed[] = [];
|
|
696
|
+
for (const t of renderableTasks) {
|
|
697
|
+
const liveBarBaseline = resolvedBaselines.length === 1 ? resolvedBaselines[0] : undefined;
|
|
698
|
+
out.push(toSvarTask(t, liveBarBaseline, calendar));
|
|
699
|
+
if (t.type === 'summary') continue;
|
|
700
|
+
for (const b of resolvedBaselines) {
|
|
701
|
+
const phantom = makeBaselinePhantom(t, b, calendar);
|
|
702
|
+
if (phantom) out.push(phantom);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return out;
|
|
706
|
+
}
|
|
707
|
+
|
|
549
708
|
function resolveMarkers(
|
|
550
709
|
userMarkers: GanttMarker[] | undefined,
|
|
551
710
|
projectStart: Date,
|
package/src/export/offscreen.tsx
CHANGED
|
@@ -14,6 +14,7 @@ export type OffscreenGanttProps = Pick<
|
|
|
14
14
|
| 'cellHeight'
|
|
15
15
|
| 'markers'
|
|
16
16
|
| 'baselineIndex'
|
|
17
|
+
| 'baselineIndices'
|
|
17
18
|
| 'showBaselineBars'
|
|
18
19
|
| 'columns'
|
|
19
20
|
| 'height'
|
|
@@ -50,6 +51,7 @@ export async function renderOffscreen(args: {
|
|
|
50
51
|
cellHeight={ganttProps.cellHeight}
|
|
51
52
|
markers={ganttProps.markers}
|
|
52
53
|
baselineIndex={ganttProps.baselineIndex}
|
|
54
|
+
baselineIndices={ganttProps.baselineIndices}
|
|
53
55
|
showBaselineBars={ganttProps.showBaselineBars}
|
|
54
56
|
columns={ganttProps.columns}
|
|
55
57
|
visibleTaskIds={ganttProps.visibleTaskIds}
|
package/src/export/pdf.ts
CHANGED