@almadar/ui 6.25.0 → 6.27.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/dist/avl/index.cjs +249 -2
- package/dist/avl/index.js +249 -2
- package/dist/components/index.cjs +247 -2
- package/dist/components/index.d.cts +72 -1
- package/dist/components/index.d.ts +72 -1
- package/dist/components/index.js +246 -2
- package/dist/providers/index.cjs +243 -0
- package/dist/providers/index.js +243 -0
- package/dist/runtime/index.cjs +249 -2
- package/dist/runtime/index.js +249 -2
- package/package.json +5 -5
package/dist/avl/index.cjs
CHANGED
|
@@ -34818,6 +34818,247 @@ var init_WizardNavigation = __esm({
|
|
|
34818
34818
|
WizardNavigation.displayName = "WizardNavigation";
|
|
34819
34819
|
}
|
|
34820
34820
|
});
|
|
34821
|
+
function parseDay(value) {
|
|
34822
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
34823
|
+
const d = value instanceof Date ? new Date(value.getTime()) : new Date(value);
|
|
34824
|
+
if (Number.isNaN(d.getTime())) return null;
|
|
34825
|
+
d.setHours(0, 0, 0, 0);
|
|
34826
|
+
return d;
|
|
34827
|
+
}
|
|
34828
|
+
function Gantt({
|
|
34829
|
+
tasks = [],
|
|
34830
|
+
links = [],
|
|
34831
|
+
titleField = "title",
|
|
34832
|
+
startField = "start",
|
|
34833
|
+
endField = "end",
|
|
34834
|
+
durationField,
|
|
34835
|
+
statusField = "status",
|
|
34836
|
+
groupField = "",
|
|
34837
|
+
rangeStart,
|
|
34838
|
+
rangeEnd,
|
|
34839
|
+
showToday = true,
|
|
34840
|
+
dayWidth = 28,
|
|
34841
|
+
barClickEvent,
|
|
34842
|
+
className,
|
|
34843
|
+
isLoading = false,
|
|
34844
|
+
error = null
|
|
34845
|
+
}) {
|
|
34846
|
+
const { t } = hooks.useTranslate();
|
|
34847
|
+
const placed = React96.useMemo(() => {
|
|
34848
|
+
const rows = Array.isArray(tasks) ? tasks : tasks ? [tasks] : [];
|
|
34849
|
+
const out = [];
|
|
34850
|
+
rows.forEach((row, idx) => {
|
|
34851
|
+
const start = parseDay(core.getNestedValue(row, startField));
|
|
34852
|
+
if (!start) return;
|
|
34853
|
+
let end = parseDay(core.getNestedValue(row, endField));
|
|
34854
|
+
if (!end && durationField) {
|
|
34855
|
+
const days2 = Number(core.getNestedValue(row, durationField));
|
|
34856
|
+
if (Number.isFinite(days2) && days2 > 0) {
|
|
34857
|
+
end = new Date(start.getTime() + days2 * DAY_MS);
|
|
34858
|
+
}
|
|
34859
|
+
}
|
|
34860
|
+
if (!end || end.getTime() < start.getTime()) end = new Date(start.getTime() + DAY_MS);
|
|
34861
|
+
out.push({
|
|
34862
|
+
row,
|
|
34863
|
+
id: String(row.id ?? idx),
|
|
34864
|
+
label: String(core.getNestedValue(row, titleField) ?? ""),
|
|
34865
|
+
status: String(core.getNestedValue(row, statusField) ?? "").toLowerCase(),
|
|
34866
|
+
group: groupField ? String(core.getNestedValue(row, groupField) ?? "") : "",
|
|
34867
|
+
start,
|
|
34868
|
+
end
|
|
34869
|
+
});
|
|
34870
|
+
});
|
|
34871
|
+
return out;
|
|
34872
|
+
}, [tasks, titleField, startField, endField, durationField, statusField, groupField]);
|
|
34873
|
+
const [axisStart, axisEnd] = React96.useMemo(() => {
|
|
34874
|
+
const lo = parseDay(rangeStart) ?? (placed.length ? new Date(Math.min(...placed.map((p) => p.start.getTime())) - 2 * DAY_MS) : new Date((/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0)));
|
|
34875
|
+
const hi = parseDay(rangeEnd) ?? (placed.length ? new Date(Math.max(...placed.map((p) => p.end.getTime())) + 2 * DAY_MS) : new Date(lo.getTime() + 30 * DAY_MS));
|
|
34876
|
+
return hi.getTime() > lo.getTime() ? [lo, hi] : [lo, new Date(lo.getTime() + DAY_MS)];
|
|
34877
|
+
}, [rangeStart, rangeEnd, placed]);
|
|
34878
|
+
const totalDays = Math.round((axisEnd.getTime() - axisStart.getTime()) / DAY_MS);
|
|
34879
|
+
const chartWidth = totalDays * dayWidth;
|
|
34880
|
+
const dayOffset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34881
|
+
const displayItems = React96.useMemo(() => {
|
|
34882
|
+
if (!groupField) return placed.map((task) => ({ kind: "task", task }));
|
|
34883
|
+
const items = [];
|
|
34884
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34885
|
+
for (const task of placed) {
|
|
34886
|
+
if (!seen.has(task.group)) {
|
|
34887
|
+
seen.add(task.group);
|
|
34888
|
+
items.push({ kind: "group", label: task.group || "\u2014" });
|
|
34889
|
+
}
|
|
34890
|
+
items.push({ kind: "task", task });
|
|
34891
|
+
}
|
|
34892
|
+
return items;
|
|
34893
|
+
}, [placed, groupField]);
|
|
34894
|
+
const barGeometry = React96.useMemo(() => {
|
|
34895
|
+
const offset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34896
|
+
const map = /* @__PURE__ */ new Map();
|
|
34897
|
+
displayItems.forEach((item, idx) => {
|
|
34898
|
+
if (item.kind !== "task") return;
|
|
34899
|
+
const x0 = offset(item.task.start);
|
|
34900
|
+
const x1 = Math.max(offset(item.task.end), x0 + dayWidth / 2);
|
|
34901
|
+
map.set(item.task.id, { x0, x1, y: HEADER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2 });
|
|
34902
|
+
});
|
|
34903
|
+
return map;
|
|
34904
|
+
}, [displayItems, axisStart, dayWidth]);
|
|
34905
|
+
const days = React96.useMemo(() => {
|
|
34906
|
+
const out = [];
|
|
34907
|
+
for (let i = 0; i < totalDays; i++) out.push(new Date(axisStart.getTime() + i * DAY_MS));
|
|
34908
|
+
return out;
|
|
34909
|
+
}, [axisStart, totalDays]);
|
|
34910
|
+
const todayOffset = React96.useMemo(() => {
|
|
34911
|
+
const today = parseDay(/* @__PURE__ */ new Date());
|
|
34912
|
+
if (!today || today < axisStart || today > axisEnd) return null;
|
|
34913
|
+
return (today.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34914
|
+
}, [axisStart, axisEnd, dayWidth]);
|
|
34915
|
+
if (isLoading) {
|
|
34916
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
|
|
34917
|
+
}
|
|
34918
|
+
if (error) {
|
|
34919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("p-4", className), children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
34920
|
+
}
|
|
34921
|
+
if (placed.length === 0) {
|
|
34922
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
34923
|
+
EmptyState,
|
|
34924
|
+
{
|
|
34925
|
+
title: t("empty.noData"),
|
|
34926
|
+
className
|
|
34927
|
+
}
|
|
34928
|
+
);
|
|
34929
|
+
}
|
|
34930
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
34931
|
+
Box,
|
|
34932
|
+
{
|
|
34933
|
+
className: cn("w-full overflow-auto rounded-md border border-border bg-card", className),
|
|
34934
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", style: { width: LABEL_WIDTH + chartWidth, minWidth: "100%" }, children: [
|
|
34935
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "none", className: "sticky top-0 z-20 bg-card border-b border-border", style: { height: HEADER_HEIGHT }, children: [
|
|
34936
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card border-r border-border", style: { width: LABEL_WIDTH, height: HEADER_HEIGHT } }),
|
|
34937
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "relative", style: { width: chartWidth, height: HEADER_HEIGHT }, children: days.map((day, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
34938
|
+
Box,
|
|
34939
|
+
{
|
|
34940
|
+
className: cn(
|
|
34941
|
+
"absolute top-0 bottom-0 border-l border-border/50 flex items-end justify-center pb-1",
|
|
34942
|
+
day.getDay() === 0 || day.getDay() === 6 ? "bg-muted/40" : void 0
|
|
34943
|
+
),
|
|
34944
|
+
style: { left: i * dayWidth, width: dayWidth },
|
|
34945
|
+
children: dayWidth >= 20 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: day.getDate() })
|
|
34946
|
+
},
|
|
34947
|
+
i
|
|
34948
|
+
)) })
|
|
34949
|
+
] }),
|
|
34950
|
+
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "none", className: "relative", children: [
|
|
34951
|
+
displayItems.map(
|
|
34952
|
+
(item, idx) => item.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
34953
|
+
HStack,
|
|
34954
|
+
{
|
|
34955
|
+
gap: "none",
|
|
34956
|
+
className: "border-b border-border bg-muted/30",
|
|
34957
|
+
style: { height: ROW_HEIGHT },
|
|
34958
|
+
children: [
|
|
34959
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-muted/30 px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", weight: "semibold", children: item.label }) }),
|
|
34960
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { style: { width: chartWidth, height: ROW_HEIGHT } })
|
|
34961
|
+
]
|
|
34962
|
+
},
|
|
34963
|
+
`g-${idx}`
|
|
34964
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
34965
|
+
HStack,
|
|
34966
|
+
{
|
|
34967
|
+
gap: "none",
|
|
34968
|
+
className: "border-b border-border/50",
|
|
34969
|
+
style: { height: ROW_HEIGHT },
|
|
34970
|
+
children: [
|
|
34971
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "truncate", children: item.task.label }) }),
|
|
34972
|
+
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "relative", style: { width: chartWidth, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
34973
|
+
Box,
|
|
34974
|
+
{
|
|
34975
|
+
className: cn(
|
|
34976
|
+
"absolute top-1/2 -translate-y-1/2 h-4 rounded-sm transition-colors",
|
|
34977
|
+
STATUS_BAR[item.task.status] ?? "bg-primary/80 hover:bg-primary",
|
|
34978
|
+
barClickEvent ? "cursor-pointer" : void 0
|
|
34979
|
+
),
|
|
34980
|
+
style: {
|
|
34981
|
+
left: dayOffset(item.task.start),
|
|
34982
|
+
width: Math.max(dayOffset(item.task.end) - dayOffset(item.task.start), dayWidth / 2)
|
|
34983
|
+
},
|
|
34984
|
+
action: barClickEvent,
|
|
34985
|
+
actionPayload: { id: item.task.id }
|
|
34986
|
+
}
|
|
34987
|
+
) })
|
|
34988
|
+
]
|
|
34989
|
+
},
|
|
34990
|
+
item.task.id
|
|
34991
|
+
)
|
|
34992
|
+
),
|
|
34993
|
+
links.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
34994
|
+
"svg",
|
|
34995
|
+
{
|
|
34996
|
+
className: "absolute pointer-events-none",
|
|
34997
|
+
style: { left: LABEL_WIDTH, top: 0 },
|
|
34998
|
+
width: chartWidth,
|
|
34999
|
+
height: HEADER_HEIGHT + displayItems.length * ROW_HEIGHT,
|
|
35000
|
+
children: [
|
|
35001
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "gantt-arrow", markerWidth: "8", markerHeight: "8", refX: "7", refY: "4", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,4 L0,8 z", fill: "var(--muted-foreground, currentColor)" }) }) }),
|
|
35002
|
+
links.map((link, i) => {
|
|
35003
|
+
const from = barGeometry.get(link.from);
|
|
35004
|
+
const to = barGeometry.get(link.to);
|
|
35005
|
+
if (!from || !to) return null;
|
|
35006
|
+
const midX = from.x1 + Math.max(8, (to.x0 - from.x1) / 2);
|
|
35007
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35008
|
+
"path",
|
|
35009
|
+
{
|
|
35010
|
+
d: `M ${from.x1} ${from.y} L ${midX} ${from.y} L ${midX} ${to.y} L ${to.x0} ${to.y}`,
|
|
35011
|
+
fill: "none",
|
|
35012
|
+
stroke: "var(--muted-foreground, currentColor)",
|
|
35013
|
+
strokeWidth: 1.5,
|
|
35014
|
+
markerEnd: "url(#gantt-arrow)"
|
|
35015
|
+
},
|
|
35016
|
+
i
|
|
35017
|
+
);
|
|
35018
|
+
})
|
|
35019
|
+
]
|
|
35020
|
+
}
|
|
35021
|
+
),
|
|
35022
|
+
showToday && todayOffset !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
35023
|
+
Box,
|
|
35024
|
+
{
|
|
35025
|
+
className: "absolute top-0 bottom-0 w-0.5 bg-error/70 pointer-events-none",
|
|
35026
|
+
style: { left: LABEL_WIDTH + todayOffset }
|
|
35027
|
+
}
|
|
35028
|
+
)
|
|
35029
|
+
] })
|
|
35030
|
+
] })
|
|
35031
|
+
}
|
|
35032
|
+
);
|
|
35033
|
+
}
|
|
35034
|
+
var DAY_MS, ROW_HEIGHT, HEADER_HEIGHT, LABEL_WIDTH, STATUS_BAR;
|
|
35035
|
+
var init_Gantt = __esm({
|
|
35036
|
+
"components/core/molecules/Gantt.tsx"() {
|
|
35037
|
+
"use client";
|
|
35038
|
+
init_cn();
|
|
35039
|
+
init_getNestedValue();
|
|
35040
|
+
init_Box();
|
|
35041
|
+
init_Stack();
|
|
35042
|
+
init_Typography();
|
|
35043
|
+
init_LoadingState();
|
|
35044
|
+
init_EmptyState();
|
|
35045
|
+
DAY_MS = 24 * 60 * 60 * 1e3;
|
|
35046
|
+
ROW_HEIGHT = 36;
|
|
35047
|
+
HEADER_HEIGHT = 44;
|
|
35048
|
+
LABEL_WIDTH = 192;
|
|
35049
|
+
STATUS_BAR = {
|
|
35050
|
+
complete: "bg-success/80 hover:bg-success",
|
|
35051
|
+
done: "bg-success/80 hover:bg-success",
|
|
35052
|
+
active: "bg-primary/80 hover:bg-primary",
|
|
35053
|
+
"in-progress": "bg-primary/80 hover:bg-primary",
|
|
35054
|
+
blocked: "bg-error/80 hover:bg-error",
|
|
35055
|
+
error: "bg-error/80 hover:bg-error",
|
|
35056
|
+
"at-risk": "bg-warning/80 hover:bg-warning",
|
|
35057
|
+
pending: "bg-muted-foreground/50 hover:bg-muted-foreground/70"
|
|
35058
|
+
};
|
|
35059
|
+
Gantt.displayName = "Gantt";
|
|
35060
|
+
}
|
|
35061
|
+
});
|
|
34821
35062
|
var RepeatableFormSection;
|
|
34822
35063
|
var init_RepeatableFormSection = __esm({
|
|
34823
35064
|
"components/core/molecules/RepeatableFormSection.tsx"() {
|
|
@@ -53975,6 +54216,7 @@ var init_component_registry_generated = __esm({
|
|
|
53975
54216
|
init_GameIcon();
|
|
53976
54217
|
init_GameMenu();
|
|
53977
54218
|
init_GameShell();
|
|
54219
|
+
init_Gantt();
|
|
53978
54220
|
init_GenericAppTemplate();
|
|
53979
54221
|
init_GeometricPattern();
|
|
53980
54222
|
init_GradientDivider();
|
|
@@ -54254,6 +54496,7 @@ var init_component_registry_generated = __esm({
|
|
|
54254
54496
|
"GameIcon": GameIcon,
|
|
54255
54497
|
"GameMenu": GameMenu,
|
|
54256
54498
|
"GameShell": GameShell,
|
|
54499
|
+
"Gantt": Gantt,
|
|
54257
54500
|
"GenericAppTemplate": GenericAppTemplate,
|
|
54258
54501
|
"GeometricPattern": GeometricPattern,
|
|
54259
54502
|
"GradientDivider": GradientDivider,
|
|
@@ -60598,6 +60841,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60598
60841
|
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
60599
60842
|
[traits2]
|
|
60600
60843
|
);
|
|
60844
|
+
const activeTraitNamesRef = React96.useRef(activeTraitNames);
|
|
60845
|
+
React96.useEffect(() => {
|
|
60846
|
+
activeTraitNamesRef.current = activeTraitNames;
|
|
60847
|
+
}, [activeTraitNames]);
|
|
60601
60848
|
const withActiveTraits = React96.useCallback(
|
|
60602
60849
|
(payload) => {
|
|
60603
60850
|
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
@@ -60622,7 +60869,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60622
60869
|
}
|
|
60623
60870
|
void bridge.sendEvent(name, event, withActiveTraits(payload), void 0, void 0, locallyEmitted, results, entityByTrait).then(({ effects, meta }) => {
|
|
60624
60871
|
recordServerResponse(name, event, { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
|
|
60625
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits,
|
|
60872
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
|
|
60626
60873
|
});
|
|
60627
60874
|
}
|
|
60628
60875
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
@@ -60685,7 +60932,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60685
60932
|
effects: effectTraces,
|
|
60686
60933
|
timestamp: Date.now()
|
|
60687
60934
|
});
|
|
60688
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits,
|
|
60935
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
|
|
60689
60936
|
}
|
|
60690
60937
|
})();
|
|
60691
60938
|
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|
package/dist/avl/index.js
CHANGED
|
@@ -34742,6 +34742,247 @@ var init_WizardNavigation = __esm({
|
|
|
34742
34742
|
WizardNavigation.displayName = "WizardNavigation";
|
|
34743
34743
|
}
|
|
34744
34744
|
});
|
|
34745
|
+
function parseDay(value) {
|
|
34746
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
34747
|
+
const d = value instanceof Date ? new Date(value.getTime()) : new Date(value);
|
|
34748
|
+
if (Number.isNaN(d.getTime())) return null;
|
|
34749
|
+
d.setHours(0, 0, 0, 0);
|
|
34750
|
+
return d;
|
|
34751
|
+
}
|
|
34752
|
+
function Gantt({
|
|
34753
|
+
tasks = [],
|
|
34754
|
+
links = [],
|
|
34755
|
+
titleField = "title",
|
|
34756
|
+
startField = "start",
|
|
34757
|
+
endField = "end",
|
|
34758
|
+
durationField,
|
|
34759
|
+
statusField = "status",
|
|
34760
|
+
groupField = "",
|
|
34761
|
+
rangeStart,
|
|
34762
|
+
rangeEnd,
|
|
34763
|
+
showToday = true,
|
|
34764
|
+
dayWidth = 28,
|
|
34765
|
+
barClickEvent,
|
|
34766
|
+
className,
|
|
34767
|
+
isLoading = false,
|
|
34768
|
+
error = null
|
|
34769
|
+
}) {
|
|
34770
|
+
const { t } = useTranslate();
|
|
34771
|
+
const placed = useMemo(() => {
|
|
34772
|
+
const rows = Array.isArray(tasks) ? tasks : tasks ? [tasks] : [];
|
|
34773
|
+
const out = [];
|
|
34774
|
+
rows.forEach((row, idx) => {
|
|
34775
|
+
const start = parseDay(getNestedValue(row, startField));
|
|
34776
|
+
if (!start) return;
|
|
34777
|
+
let end = parseDay(getNestedValue(row, endField));
|
|
34778
|
+
if (!end && durationField) {
|
|
34779
|
+
const days2 = Number(getNestedValue(row, durationField));
|
|
34780
|
+
if (Number.isFinite(days2) && days2 > 0) {
|
|
34781
|
+
end = new Date(start.getTime() + days2 * DAY_MS);
|
|
34782
|
+
}
|
|
34783
|
+
}
|
|
34784
|
+
if (!end || end.getTime() < start.getTime()) end = new Date(start.getTime() + DAY_MS);
|
|
34785
|
+
out.push({
|
|
34786
|
+
row,
|
|
34787
|
+
id: String(row.id ?? idx),
|
|
34788
|
+
label: String(getNestedValue(row, titleField) ?? ""),
|
|
34789
|
+
status: String(getNestedValue(row, statusField) ?? "").toLowerCase(),
|
|
34790
|
+
group: groupField ? String(getNestedValue(row, groupField) ?? "") : "",
|
|
34791
|
+
start,
|
|
34792
|
+
end
|
|
34793
|
+
});
|
|
34794
|
+
});
|
|
34795
|
+
return out;
|
|
34796
|
+
}, [tasks, titleField, startField, endField, durationField, statusField, groupField]);
|
|
34797
|
+
const [axisStart, axisEnd] = useMemo(() => {
|
|
34798
|
+
const lo = parseDay(rangeStart) ?? (placed.length ? new Date(Math.min(...placed.map((p) => p.start.getTime())) - 2 * DAY_MS) : new Date((/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0)));
|
|
34799
|
+
const hi = parseDay(rangeEnd) ?? (placed.length ? new Date(Math.max(...placed.map((p) => p.end.getTime())) + 2 * DAY_MS) : new Date(lo.getTime() + 30 * DAY_MS));
|
|
34800
|
+
return hi.getTime() > lo.getTime() ? [lo, hi] : [lo, new Date(lo.getTime() + DAY_MS)];
|
|
34801
|
+
}, [rangeStart, rangeEnd, placed]);
|
|
34802
|
+
const totalDays = Math.round((axisEnd.getTime() - axisStart.getTime()) / DAY_MS);
|
|
34803
|
+
const chartWidth = totalDays * dayWidth;
|
|
34804
|
+
const dayOffset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34805
|
+
const displayItems = useMemo(() => {
|
|
34806
|
+
if (!groupField) return placed.map((task) => ({ kind: "task", task }));
|
|
34807
|
+
const items = [];
|
|
34808
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34809
|
+
for (const task of placed) {
|
|
34810
|
+
if (!seen.has(task.group)) {
|
|
34811
|
+
seen.add(task.group);
|
|
34812
|
+
items.push({ kind: "group", label: task.group || "\u2014" });
|
|
34813
|
+
}
|
|
34814
|
+
items.push({ kind: "task", task });
|
|
34815
|
+
}
|
|
34816
|
+
return items;
|
|
34817
|
+
}, [placed, groupField]);
|
|
34818
|
+
const barGeometry = useMemo(() => {
|
|
34819
|
+
const offset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34820
|
+
const map = /* @__PURE__ */ new Map();
|
|
34821
|
+
displayItems.forEach((item, idx) => {
|
|
34822
|
+
if (item.kind !== "task") return;
|
|
34823
|
+
const x0 = offset(item.task.start);
|
|
34824
|
+
const x1 = Math.max(offset(item.task.end), x0 + dayWidth / 2);
|
|
34825
|
+
map.set(item.task.id, { x0, x1, y: HEADER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2 });
|
|
34826
|
+
});
|
|
34827
|
+
return map;
|
|
34828
|
+
}, [displayItems, axisStart, dayWidth]);
|
|
34829
|
+
const days = useMemo(() => {
|
|
34830
|
+
const out = [];
|
|
34831
|
+
for (let i = 0; i < totalDays; i++) out.push(new Date(axisStart.getTime() + i * DAY_MS));
|
|
34832
|
+
return out;
|
|
34833
|
+
}, [axisStart, totalDays]);
|
|
34834
|
+
const todayOffset = useMemo(() => {
|
|
34835
|
+
const today = parseDay(/* @__PURE__ */ new Date());
|
|
34836
|
+
if (!today || today < axisStart || today > axisEnd) return null;
|
|
34837
|
+
return (today.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
|
|
34838
|
+
}, [axisStart, axisEnd, dayWidth]);
|
|
34839
|
+
if (isLoading) {
|
|
34840
|
+
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
34841
|
+
}
|
|
34842
|
+
if (error) {
|
|
34843
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("p-4", className), children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
34844
|
+
}
|
|
34845
|
+
if (placed.length === 0) {
|
|
34846
|
+
return /* @__PURE__ */ jsx(
|
|
34847
|
+
EmptyState,
|
|
34848
|
+
{
|
|
34849
|
+
title: t("empty.noData"),
|
|
34850
|
+
className
|
|
34851
|
+
}
|
|
34852
|
+
);
|
|
34853
|
+
}
|
|
34854
|
+
return /* @__PURE__ */ jsx(
|
|
34855
|
+
Box,
|
|
34856
|
+
{
|
|
34857
|
+
className: cn("w-full overflow-auto rounded-md border border-border bg-card", className),
|
|
34858
|
+
children: /* @__PURE__ */ jsxs(Box, { className: "relative", style: { width: LABEL_WIDTH + chartWidth, minWidth: "100%" }, children: [
|
|
34859
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "none", className: "sticky top-0 z-20 bg-card border-b border-border", style: { height: HEADER_HEIGHT }, children: [
|
|
34860
|
+
/* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card border-r border-border", style: { width: LABEL_WIDTH, height: HEADER_HEIGHT } }),
|
|
34861
|
+
/* @__PURE__ */ jsx(Box, { className: "relative", style: { width: chartWidth, height: HEADER_HEIGHT }, children: days.map((day, i) => /* @__PURE__ */ jsx(
|
|
34862
|
+
Box,
|
|
34863
|
+
{
|
|
34864
|
+
className: cn(
|
|
34865
|
+
"absolute top-0 bottom-0 border-l border-border/50 flex items-end justify-center pb-1",
|
|
34866
|
+
day.getDay() === 0 || day.getDay() === 6 ? "bg-muted/40" : void 0
|
|
34867
|
+
),
|
|
34868
|
+
style: { left: i * dayWidth, width: dayWidth },
|
|
34869
|
+
children: dayWidth >= 20 && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: day.getDate() })
|
|
34870
|
+
},
|
|
34871
|
+
i
|
|
34872
|
+
)) })
|
|
34873
|
+
] }),
|
|
34874
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "none", className: "relative", children: [
|
|
34875
|
+
displayItems.map(
|
|
34876
|
+
(item, idx) => item.kind === "group" ? /* @__PURE__ */ jsxs(
|
|
34877
|
+
HStack,
|
|
34878
|
+
{
|
|
34879
|
+
gap: "none",
|
|
34880
|
+
className: "border-b border-border bg-muted/30",
|
|
34881
|
+
style: { height: ROW_HEIGHT },
|
|
34882
|
+
children: [
|
|
34883
|
+
/* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-muted/30 px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", weight: "semibold", children: item.label }) }),
|
|
34884
|
+
/* @__PURE__ */ jsx(Box, { style: { width: chartWidth, height: ROW_HEIGHT } })
|
|
34885
|
+
]
|
|
34886
|
+
},
|
|
34887
|
+
`g-${idx}`
|
|
34888
|
+
) : /* @__PURE__ */ jsxs(
|
|
34889
|
+
HStack,
|
|
34890
|
+
{
|
|
34891
|
+
gap: "none",
|
|
34892
|
+
className: "border-b border-border/50",
|
|
34893
|
+
style: { height: ROW_HEIGHT },
|
|
34894
|
+
children: [
|
|
34895
|
+
/* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate", children: item.task.label }) }),
|
|
34896
|
+
/* @__PURE__ */ jsx(Box, { className: "relative", style: { width: chartWidth, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(
|
|
34897
|
+
Box,
|
|
34898
|
+
{
|
|
34899
|
+
className: cn(
|
|
34900
|
+
"absolute top-1/2 -translate-y-1/2 h-4 rounded-sm transition-colors",
|
|
34901
|
+
STATUS_BAR[item.task.status] ?? "bg-primary/80 hover:bg-primary",
|
|
34902
|
+
barClickEvent ? "cursor-pointer" : void 0
|
|
34903
|
+
),
|
|
34904
|
+
style: {
|
|
34905
|
+
left: dayOffset(item.task.start),
|
|
34906
|
+
width: Math.max(dayOffset(item.task.end) - dayOffset(item.task.start), dayWidth / 2)
|
|
34907
|
+
},
|
|
34908
|
+
action: barClickEvent,
|
|
34909
|
+
actionPayload: { id: item.task.id }
|
|
34910
|
+
}
|
|
34911
|
+
) })
|
|
34912
|
+
]
|
|
34913
|
+
},
|
|
34914
|
+
item.task.id
|
|
34915
|
+
)
|
|
34916
|
+
),
|
|
34917
|
+
links.length > 0 && /* @__PURE__ */ jsxs(
|
|
34918
|
+
"svg",
|
|
34919
|
+
{
|
|
34920
|
+
className: "absolute pointer-events-none",
|
|
34921
|
+
style: { left: LABEL_WIDTH, top: 0 },
|
|
34922
|
+
width: chartWidth,
|
|
34923
|
+
height: HEADER_HEIGHT + displayItems.length * ROW_HEIGHT,
|
|
34924
|
+
children: [
|
|
34925
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", { id: "gantt-arrow", markerWidth: "8", markerHeight: "8", refX: "7", refY: "4", orient: "auto", children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,4 L0,8 z", fill: "var(--muted-foreground, currentColor)" }) }) }),
|
|
34926
|
+
links.map((link, i) => {
|
|
34927
|
+
const from = barGeometry.get(link.from);
|
|
34928
|
+
const to = barGeometry.get(link.to);
|
|
34929
|
+
if (!from || !to) return null;
|
|
34930
|
+
const midX = from.x1 + Math.max(8, (to.x0 - from.x1) / 2);
|
|
34931
|
+
return /* @__PURE__ */ jsx(
|
|
34932
|
+
"path",
|
|
34933
|
+
{
|
|
34934
|
+
d: `M ${from.x1} ${from.y} L ${midX} ${from.y} L ${midX} ${to.y} L ${to.x0} ${to.y}`,
|
|
34935
|
+
fill: "none",
|
|
34936
|
+
stroke: "var(--muted-foreground, currentColor)",
|
|
34937
|
+
strokeWidth: 1.5,
|
|
34938
|
+
markerEnd: "url(#gantt-arrow)"
|
|
34939
|
+
},
|
|
34940
|
+
i
|
|
34941
|
+
);
|
|
34942
|
+
})
|
|
34943
|
+
]
|
|
34944
|
+
}
|
|
34945
|
+
),
|
|
34946
|
+
showToday && todayOffset !== null && /* @__PURE__ */ jsx(
|
|
34947
|
+
Box,
|
|
34948
|
+
{
|
|
34949
|
+
className: "absolute top-0 bottom-0 w-0.5 bg-error/70 pointer-events-none",
|
|
34950
|
+
style: { left: LABEL_WIDTH + todayOffset }
|
|
34951
|
+
}
|
|
34952
|
+
)
|
|
34953
|
+
] })
|
|
34954
|
+
] })
|
|
34955
|
+
}
|
|
34956
|
+
);
|
|
34957
|
+
}
|
|
34958
|
+
var DAY_MS, ROW_HEIGHT, HEADER_HEIGHT, LABEL_WIDTH, STATUS_BAR;
|
|
34959
|
+
var init_Gantt = __esm({
|
|
34960
|
+
"components/core/molecules/Gantt.tsx"() {
|
|
34961
|
+
"use client";
|
|
34962
|
+
init_cn();
|
|
34963
|
+
init_getNestedValue();
|
|
34964
|
+
init_Box();
|
|
34965
|
+
init_Stack();
|
|
34966
|
+
init_Typography();
|
|
34967
|
+
init_LoadingState();
|
|
34968
|
+
init_EmptyState();
|
|
34969
|
+
DAY_MS = 24 * 60 * 60 * 1e3;
|
|
34970
|
+
ROW_HEIGHT = 36;
|
|
34971
|
+
HEADER_HEIGHT = 44;
|
|
34972
|
+
LABEL_WIDTH = 192;
|
|
34973
|
+
STATUS_BAR = {
|
|
34974
|
+
complete: "bg-success/80 hover:bg-success",
|
|
34975
|
+
done: "bg-success/80 hover:bg-success",
|
|
34976
|
+
active: "bg-primary/80 hover:bg-primary",
|
|
34977
|
+
"in-progress": "bg-primary/80 hover:bg-primary",
|
|
34978
|
+
blocked: "bg-error/80 hover:bg-error",
|
|
34979
|
+
error: "bg-error/80 hover:bg-error",
|
|
34980
|
+
"at-risk": "bg-warning/80 hover:bg-warning",
|
|
34981
|
+
pending: "bg-muted-foreground/50 hover:bg-muted-foreground/70"
|
|
34982
|
+
};
|
|
34983
|
+
Gantt.displayName = "Gantt";
|
|
34984
|
+
}
|
|
34985
|
+
});
|
|
34745
34986
|
var RepeatableFormSection;
|
|
34746
34987
|
var init_RepeatableFormSection = __esm({
|
|
34747
34988
|
"components/core/molecules/RepeatableFormSection.tsx"() {
|
|
@@ -53899,6 +54140,7 @@ var init_component_registry_generated = __esm({
|
|
|
53899
54140
|
init_GameIcon();
|
|
53900
54141
|
init_GameMenu();
|
|
53901
54142
|
init_GameShell();
|
|
54143
|
+
init_Gantt();
|
|
53902
54144
|
init_GenericAppTemplate();
|
|
53903
54145
|
init_GeometricPattern();
|
|
53904
54146
|
init_GradientDivider();
|
|
@@ -54178,6 +54420,7 @@ var init_component_registry_generated = __esm({
|
|
|
54178
54420
|
"GameIcon": GameIcon,
|
|
54179
54421
|
"GameMenu": GameMenu,
|
|
54180
54422
|
"GameShell": GameShell,
|
|
54423
|
+
"Gantt": Gantt,
|
|
54181
54424
|
"GenericAppTemplate": GenericAppTemplate,
|
|
54182
54425
|
"GeometricPattern": GeometricPattern,
|
|
54183
54426
|
"GradientDivider": GradientDivider,
|
|
@@ -60522,6 +60765,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60522
60765
|
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
60523
60766
|
[traits2]
|
|
60524
60767
|
);
|
|
60768
|
+
const activeTraitNamesRef = useRef(activeTraitNames);
|
|
60769
|
+
useEffect(() => {
|
|
60770
|
+
activeTraitNamesRef.current = activeTraitNames;
|
|
60771
|
+
}, [activeTraitNames]);
|
|
60525
60772
|
const withActiveTraits = useCallback(
|
|
60526
60773
|
(payload) => {
|
|
60527
60774
|
if (!serverActiveTraits || serverActiveTraits.size === 0) return payload;
|
|
@@ -60546,7 +60793,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60546
60793
|
}
|
|
60547
60794
|
void bridge.sendEvent(name, event, withActiveTraits(payload), void 0, void 0, locallyEmitted, results, entityByTrait).then(({ effects, meta }) => {
|
|
60548
60795
|
recordServerResponse(name, event, { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
|
|
60549
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits,
|
|
60796
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
|
|
60550
60797
|
});
|
|
60551
60798
|
}
|
|
60552
60799
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
@@ -60609,7 +60856,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60609
60856
|
effects: effectTraces,
|
|
60610
60857
|
timestamp: Date.now()
|
|
60611
60858
|
});
|
|
60612
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits,
|
|
60859
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNamesRef.current, onNavigateBack);
|
|
60613
60860
|
}
|
|
60614
60861
|
})();
|
|
60615
60862
|
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|