@j3m-quantum/ui 1.12.1 → 2.1.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/README.md +72 -7
- package/cursor-rules-for-consumers.md +24 -15
- package/dist/cli/index.js +670 -0
- package/dist/cli/postinstall.js +25 -0
- package/dist/index.cjs +1041 -450
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -11
- package/dist/index.d.ts +112 -11
- package/dist/index.js +968 -380
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React27 = require('react');
|
|
4
4
|
var reactSlot = require('@radix-ui/react-slot');
|
|
5
5
|
var classVarianceAuthority = require('class-variance-authority');
|
|
6
6
|
var clsx = require('clsx');
|
|
@@ -73,7 +73,7 @@ function _interopNamespace(e) {
|
|
|
73
73
|
return Object.freeze(n);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
var
|
|
76
|
+
var React27__namespace = /*#__PURE__*/_interopNamespace(React27);
|
|
77
77
|
var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
|
|
78
78
|
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
79
79
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
@@ -108,8 +108,8 @@ var tunnel__default = /*#__PURE__*/_interopDefault(tunnel);
|
|
|
108
108
|
// src/hooks/use-mobile.ts
|
|
109
109
|
var MOBILE_BREAKPOINT = 768;
|
|
110
110
|
function useIsMobile() {
|
|
111
|
-
const [isMobile, setIsMobile] =
|
|
112
|
-
|
|
111
|
+
const [isMobile, setIsMobile] = React27__namespace.useState(void 0);
|
|
112
|
+
React27__namespace.useEffect(() => {
|
|
113
113
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
114
114
|
const onChange = () => {
|
|
115
115
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
@@ -123,6 +123,53 @@ function useIsMobile() {
|
|
|
123
123
|
function cn(...inputs) {
|
|
124
124
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
125
125
|
}
|
|
126
|
+
var statusCellFillClasses = {
|
|
127
|
+
// Green - complete/valid/ready state
|
|
128
|
+
complete: {
|
|
129
|
+
bg: "bg-green-50/50 dark:bg-green-950/30"},
|
|
130
|
+
ready: {
|
|
131
|
+
combined: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30"
|
|
132
|
+
},
|
|
133
|
+
// Amber - warning/attention state
|
|
134
|
+
warning: {
|
|
135
|
+
bg: "bg-amber-50/50 dark:bg-amber-950/30"},
|
|
136
|
+
// Red - critical/risk state
|
|
137
|
+
critical: {
|
|
138
|
+
bg: "bg-red-50/50 dark:bg-red-950/30"},
|
|
139
|
+
risk: {
|
|
140
|
+
combined: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30"
|
|
141
|
+
},
|
|
142
|
+
// Grey - normal/pending/neutral state (on track but not complete)
|
|
143
|
+
normal: {
|
|
144
|
+
combined: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20"
|
|
145
|
+
},
|
|
146
|
+
// Shipped - distinct muted state with green accent (greyed out + check)
|
|
147
|
+
shipped: {
|
|
148
|
+
combined: "border-l-[3px] border-l-green-500/50 bg-muted/50 dark:bg-muted/30"
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
var statusCellTextClasses = {
|
|
152
|
+
ready: {
|
|
153
|
+
title: "text-foreground",
|
|
154
|
+
subtitle: "text-green-700/80 dark:text-green-300/80",
|
|
155
|
+
icon: "text-green-600 dark:text-green-400"
|
|
156
|
+
},
|
|
157
|
+
risk: {
|
|
158
|
+
title: "text-foreground",
|
|
159
|
+
subtitle: "text-red-700/80 dark:text-red-300/80",
|
|
160
|
+
icon: "text-red-600 dark:text-red-400"
|
|
161
|
+
},
|
|
162
|
+
normal: {
|
|
163
|
+
title: "text-foreground",
|
|
164
|
+
subtitle: "text-muted-foreground",
|
|
165
|
+
icon: "text-muted-foreground"
|
|
166
|
+
},
|
|
167
|
+
shipped: {
|
|
168
|
+
title: "text-muted-foreground",
|
|
169
|
+
subtitle: "text-muted-foreground/70",
|
|
170
|
+
icon: "text-green-600/70 dark:text-green-400/70"
|
|
171
|
+
}
|
|
172
|
+
};
|
|
126
173
|
var buttonVariants = classVarianceAuthority.cva(
|
|
127
174
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
128
175
|
{
|
|
@@ -150,7 +197,7 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
150
197
|
}
|
|
151
198
|
}
|
|
152
199
|
);
|
|
153
|
-
var Button =
|
|
200
|
+
var Button = React27__namespace.forwardRef(
|
|
154
201
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
155
202
|
const Comp = asChild ? reactSlot.Slot : "button";
|
|
156
203
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -514,7 +561,7 @@ function Slider({
|
|
|
514
561
|
max = 100,
|
|
515
562
|
...props
|
|
516
563
|
}) {
|
|
517
|
-
const _values =
|
|
564
|
+
const _values = React27__namespace.useMemo(
|
|
518
565
|
() => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
|
|
519
566
|
[value, defaultValue, min, max]
|
|
520
567
|
);
|
|
@@ -800,7 +847,7 @@ function Toggle({
|
|
|
800
847
|
}
|
|
801
848
|
);
|
|
802
849
|
}
|
|
803
|
-
var ToggleGroupContext =
|
|
850
|
+
var ToggleGroupContext = React27__namespace.createContext({
|
|
804
851
|
size: "default",
|
|
805
852
|
variant: "default",
|
|
806
853
|
spacing: 0
|
|
@@ -837,7 +884,7 @@ function ToggleGroupItem({
|
|
|
837
884
|
size,
|
|
838
885
|
...props
|
|
839
886
|
}) {
|
|
840
|
-
const context =
|
|
887
|
+
const context = React27__namespace.useContext(ToggleGroupContext);
|
|
841
888
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
842
889
|
ToggleGroupPrimitive__namespace.Item,
|
|
843
890
|
{
|
|
@@ -867,7 +914,7 @@ function ThemeSwitch({
|
|
|
867
914
|
className,
|
|
868
915
|
size = "default"
|
|
869
916
|
}) {
|
|
870
|
-
const [isChecked, setIsChecked] =
|
|
917
|
+
const [isChecked, setIsChecked] = React27__namespace.useState(defaultChecked);
|
|
871
918
|
const isControlled = checked !== void 0;
|
|
872
919
|
const currentChecked = isControlled ? checked : isChecked;
|
|
873
920
|
const handleClick = () => {
|
|
@@ -1287,7 +1334,7 @@ function Label2({
|
|
|
1287
1334
|
);
|
|
1288
1335
|
}
|
|
1289
1336
|
var Form = reactHookForm.FormProvider;
|
|
1290
|
-
var FormFieldContext =
|
|
1337
|
+
var FormFieldContext = React27__namespace.createContext(
|
|
1291
1338
|
{}
|
|
1292
1339
|
);
|
|
1293
1340
|
var FormField = ({
|
|
@@ -1296,8 +1343,8 @@ var FormField = ({
|
|
|
1296
1343
|
return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.Controller, { ...props }) });
|
|
1297
1344
|
};
|
|
1298
1345
|
var useFormField = () => {
|
|
1299
|
-
const fieldContext =
|
|
1300
|
-
const itemContext =
|
|
1346
|
+
const fieldContext = React27__namespace.useContext(FormFieldContext);
|
|
1347
|
+
const itemContext = React27__namespace.useContext(FormItemContext);
|
|
1301
1348
|
const { getFieldState } = reactHookForm.useFormContext();
|
|
1302
1349
|
const formState = reactHookForm.useFormState({ name: fieldContext.name });
|
|
1303
1350
|
const fieldState = getFieldState(fieldContext.name, formState);
|
|
@@ -1314,11 +1361,11 @@ var useFormField = () => {
|
|
|
1314
1361
|
...fieldState
|
|
1315
1362
|
};
|
|
1316
1363
|
};
|
|
1317
|
-
var FormItemContext =
|
|
1364
|
+
var FormItemContext = React27__namespace.createContext(
|
|
1318
1365
|
{}
|
|
1319
1366
|
);
|
|
1320
1367
|
function FormItem({ className, ...props }) {
|
|
1321
|
-
const id =
|
|
1368
|
+
const id = React27__namespace.useId();
|
|
1322
1369
|
return /* @__PURE__ */ jsxRuntime.jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1323
1370
|
"div",
|
|
1324
1371
|
{
|
|
@@ -1566,7 +1613,7 @@ function FieldError({
|
|
|
1566
1613
|
errors,
|
|
1567
1614
|
...props
|
|
1568
1615
|
}) {
|
|
1569
|
-
const content =
|
|
1616
|
+
const content = React27.useMemo(() => {
|
|
1570
1617
|
if (children) {
|
|
1571
1618
|
return children;
|
|
1572
1619
|
}
|
|
@@ -1597,6 +1644,166 @@ function FieldError({
|
|
|
1597
1644
|
}
|
|
1598
1645
|
);
|
|
1599
1646
|
}
|
|
1647
|
+
var iconMap = {
|
|
1648
|
+
factory: lucideReact.Factory,
|
|
1649
|
+
truck: lucideReact.Truck,
|
|
1650
|
+
check: lucideReact.Check,
|
|
1651
|
+
alert: lucideReact.AlertTriangle,
|
|
1652
|
+
trending: lucideReact.TrendingUp
|
|
1653
|
+
};
|
|
1654
|
+
var statusColorMap = {
|
|
1655
|
+
normal: "text-muted-foreground",
|
|
1656
|
+
success: "text-green-600 dark:text-green-400",
|
|
1657
|
+
warning: "text-amber-600 dark:text-amber-400",
|
|
1658
|
+
critical: "text-red-600 dark:text-red-400"
|
|
1659
|
+
};
|
|
1660
|
+
function InsightBar({ metrics, className }) {
|
|
1661
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
"data-slot": "insight-bar",
|
|
1665
|
+
className: cn(
|
|
1666
|
+
"flex flex-wrap items-center gap-6 px-4 py-3",
|
|
1667
|
+
"border-b border-border bg-muted/20",
|
|
1668
|
+
className
|
|
1669
|
+
),
|
|
1670
|
+
children: metrics.map((metric) => {
|
|
1671
|
+
const Icon2 = metric.icon ? iconMap[metric.icon] : null;
|
|
1672
|
+
const statusColor = metric.status ? statusColorMap[metric.status] : "text-foreground";
|
|
1673
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1674
|
+
"div",
|
|
1675
|
+
{
|
|
1676
|
+
className: "flex items-center gap-2",
|
|
1677
|
+
children: [
|
|
1678
|
+
Icon2 && /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: cn("h-4 w-4", statusColor) }),
|
|
1679
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
1680
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
1681
|
+
"text-lg font-semibold tabular-nums",
|
|
1682
|
+
statusColor
|
|
1683
|
+
), children: metric.isPercentage ? `${Math.round(metric.value)}%` : metric.value.toLocaleString(void 0, { maximumFractionDigits: 1 }) }),
|
|
1684
|
+
metric.unit && !metric.isPercentage && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: metric.unit }),
|
|
1685
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: metric.label })
|
|
1686
|
+
] })
|
|
1687
|
+
]
|
|
1688
|
+
},
|
|
1689
|
+
metric.key
|
|
1690
|
+
);
|
|
1691
|
+
})
|
|
1692
|
+
}
|
|
1693
|
+
);
|
|
1694
|
+
}
|
|
1695
|
+
var iconMap2 = {
|
|
1696
|
+
factory: lucideReact.Factory,
|
|
1697
|
+
truck: lucideReact.Truck,
|
|
1698
|
+
check: lucideReact.Check
|
|
1699
|
+
};
|
|
1700
|
+
var statusBgMap = {
|
|
1701
|
+
normal: "bg-muted/30",
|
|
1702
|
+
complete: statusCellFillClasses.complete.bg,
|
|
1703
|
+
warning: statusCellFillClasses.warning.bg,
|
|
1704
|
+
critical: statusCellFillClasses.critical.bg
|
|
1705
|
+
};
|
|
1706
|
+
var statusTextMap = {
|
|
1707
|
+
normal: "text-muted-foreground",
|
|
1708
|
+
complete: "text-green-700 dark:text-green-300",
|
|
1709
|
+
warning: "text-amber-700 dark:text-amber-300",
|
|
1710
|
+
critical: "text-red-700 dark:text-red-300"
|
|
1711
|
+
};
|
|
1712
|
+
function ColumnSummaryCell({
|
|
1713
|
+
data,
|
|
1714
|
+
widthClass = "min-w-[120px]",
|
|
1715
|
+
className
|
|
1716
|
+
}) {
|
|
1717
|
+
const status = data.status || "normal";
|
|
1718
|
+
const bgClass = statusBgMap[status];
|
|
1719
|
+
const textClass = statusTextMap[status];
|
|
1720
|
+
const isClickable = !!data.onClick;
|
|
1721
|
+
const PrimaryIcon = data.primary?.icon ? iconMap2[data.primary.icon] : null;
|
|
1722
|
+
const SecondaryIcon = data.secondary?.icon ? iconMap2[data.secondary.icon] : null;
|
|
1723
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1724
|
+
"div",
|
|
1725
|
+
{
|
|
1726
|
+
role: isClickable ? "button" : void 0,
|
|
1727
|
+
tabIndex: isClickable ? 0 : void 0,
|
|
1728
|
+
onClick: data.onClick,
|
|
1729
|
+
onKeyDown: (e) => {
|
|
1730
|
+
if (isClickable && (e.key === "Enter" || e.key === " ")) {
|
|
1731
|
+
e.preventDefault();
|
|
1732
|
+
data.onClick?.();
|
|
1733
|
+
}
|
|
1734
|
+
},
|
|
1735
|
+
className: cn(
|
|
1736
|
+
// Base sizing
|
|
1737
|
+
widthClass,
|
|
1738
|
+
"flex flex-col gap-0.5 px-2 py-1.5",
|
|
1739
|
+
// Background based on status
|
|
1740
|
+
bgClass,
|
|
1741
|
+
// Clickable styles
|
|
1742
|
+
isClickable && "cursor-pointer hover:brightness-95 transition-all",
|
|
1743
|
+
isClickable && "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
1744
|
+
className
|
|
1745
|
+
),
|
|
1746
|
+
children: [
|
|
1747
|
+
data.primary && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1748
|
+
PrimaryIcon && /* @__PURE__ */ jsxRuntime.jsx(PrimaryIcon, { className: cn("h-3 w-3", textClass) }),
|
|
1749
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium tabular-nums", textClass), children: data.primary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }) }),
|
|
1750
|
+
data.primary.unit && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: data.primary.unit })
|
|
1751
|
+
] }),
|
|
1752
|
+
data.secondary && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1753
|
+
SecondaryIcon && /* @__PURE__ */ jsxRuntime.jsx(SecondaryIcon, { className: cn("h-3 w-3 text-muted-foreground") }),
|
|
1754
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
1755
|
+
data.secondary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
1756
|
+
data.secondary.unit && ` ${data.secondary.unit}`
|
|
1757
|
+
] })
|
|
1758
|
+
] }),
|
|
1759
|
+
data.tertiary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground/70 tabular-nums", children: [
|
|
1760
|
+
data.tertiary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
1761
|
+
data.tertiary.unit && ` ${data.tertiary.unit}`
|
|
1762
|
+
] }) })
|
|
1763
|
+
]
|
|
1764
|
+
}
|
|
1765
|
+
);
|
|
1766
|
+
}
|
|
1767
|
+
function ColumnSummaryStrip({
|
|
1768
|
+
columns,
|
|
1769
|
+
columnWidthClass = "min-w-[120px]",
|
|
1770
|
+
rowHeaderLabel,
|
|
1771
|
+
rowHeaderWidthClass = "min-w-[200px] w-[200px]",
|
|
1772
|
+
className
|
|
1773
|
+
}) {
|
|
1774
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1775
|
+
"div",
|
|
1776
|
+
{
|
|
1777
|
+
"data-slot": "column-summary-strip",
|
|
1778
|
+
className: cn(
|
|
1779
|
+
"flex border-b border-border",
|
|
1780
|
+
className
|
|
1781
|
+
),
|
|
1782
|
+
children: [
|
|
1783
|
+
rowHeaderLabel !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1784
|
+
"div",
|
|
1785
|
+
{
|
|
1786
|
+
className: cn(
|
|
1787
|
+
"flex items-center px-3 py-1.5",
|
|
1788
|
+
"bg-muted/30 border-r border-border",
|
|
1789
|
+
"sticky left-0 z-10",
|
|
1790
|
+
rowHeaderWidthClass
|
|
1791
|
+
),
|
|
1792
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: rowHeaderLabel })
|
|
1793
|
+
}
|
|
1794
|
+
),
|
|
1795
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1796
|
+
ColumnSummaryCell,
|
|
1797
|
+
{
|
|
1798
|
+
data: column,
|
|
1799
|
+
widthClass: columnWidthClass
|
|
1800
|
+
},
|
|
1801
|
+
column.columnKey
|
|
1802
|
+
)) })
|
|
1803
|
+
]
|
|
1804
|
+
}
|
|
1805
|
+
);
|
|
1806
|
+
}
|
|
1600
1807
|
var cardVariants = classVarianceAuthority.cva(
|
|
1601
1808
|
"rounded-xl text-card-foreground",
|
|
1602
1809
|
{
|
|
@@ -2420,8 +2627,8 @@ function CalendarDayButton({
|
|
|
2420
2627
|
modifiers,
|
|
2421
2628
|
...props
|
|
2422
2629
|
}) {
|
|
2423
|
-
const ref =
|
|
2424
|
-
|
|
2630
|
+
const ref = React27__namespace.useRef(null);
|
|
2631
|
+
React27__namespace.useEffect(() => {
|
|
2425
2632
|
if (modifiers.focused) ref.current?.focus();
|
|
2426
2633
|
}, [modifiers.focused]);
|
|
2427
2634
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2442,9 +2649,9 @@ function CalendarDayButton({
|
|
|
2442
2649
|
}
|
|
2443
2650
|
);
|
|
2444
2651
|
}
|
|
2445
|
-
var CarouselContext =
|
|
2652
|
+
var CarouselContext = React27__namespace.createContext(null);
|
|
2446
2653
|
function useCarousel() {
|
|
2447
|
-
const context =
|
|
2654
|
+
const context = React27__namespace.useContext(CarouselContext);
|
|
2448
2655
|
if (!context) {
|
|
2449
2656
|
throw new Error("useCarousel must be used within a <Carousel />");
|
|
2450
2657
|
}
|
|
@@ -2466,20 +2673,20 @@ function Carousel({
|
|
|
2466
2673
|
},
|
|
2467
2674
|
plugins
|
|
2468
2675
|
);
|
|
2469
|
-
const [canScrollPrev, setCanScrollPrev] =
|
|
2470
|
-
const [canScrollNext, setCanScrollNext] =
|
|
2471
|
-
const onSelect =
|
|
2676
|
+
const [canScrollPrev, setCanScrollPrev] = React27__namespace.useState(false);
|
|
2677
|
+
const [canScrollNext, setCanScrollNext] = React27__namespace.useState(false);
|
|
2678
|
+
const onSelect = React27__namespace.useCallback((api2) => {
|
|
2472
2679
|
if (!api2) return;
|
|
2473
2680
|
setCanScrollPrev(api2.canScrollPrev());
|
|
2474
2681
|
setCanScrollNext(api2.canScrollNext());
|
|
2475
2682
|
}, []);
|
|
2476
|
-
const scrollPrev =
|
|
2683
|
+
const scrollPrev = React27__namespace.useCallback(() => {
|
|
2477
2684
|
api?.scrollPrev();
|
|
2478
2685
|
}, [api]);
|
|
2479
|
-
const scrollNext =
|
|
2686
|
+
const scrollNext = React27__namespace.useCallback(() => {
|
|
2480
2687
|
api?.scrollNext();
|
|
2481
2688
|
}, [api]);
|
|
2482
|
-
const handleKeyDown =
|
|
2689
|
+
const handleKeyDown = React27__namespace.useCallback(
|
|
2483
2690
|
(event) => {
|
|
2484
2691
|
if (event.key === "ArrowLeft") {
|
|
2485
2692
|
event.preventDefault();
|
|
@@ -2491,11 +2698,11 @@ function Carousel({
|
|
|
2491
2698
|
},
|
|
2492
2699
|
[scrollPrev, scrollNext]
|
|
2493
2700
|
);
|
|
2494
|
-
|
|
2701
|
+
React27__namespace.useEffect(() => {
|
|
2495
2702
|
if (!api || !setApi) return;
|
|
2496
2703
|
setApi(api);
|
|
2497
2704
|
}, [api, setApi]);
|
|
2498
|
-
|
|
2705
|
+
React27__namespace.useEffect(() => {
|
|
2499
2706
|
if (!api) return;
|
|
2500
2707
|
onSelect(api);
|
|
2501
2708
|
api.on("reInit", onSelect);
|
|
@@ -2628,9 +2835,9 @@ function CarouselNext({
|
|
|
2628
2835
|
);
|
|
2629
2836
|
}
|
|
2630
2837
|
var THEMES = { light: "", dark: ".dark" };
|
|
2631
|
-
var ChartContext =
|
|
2838
|
+
var ChartContext = React27__namespace.createContext(null);
|
|
2632
2839
|
function useChart() {
|
|
2633
|
-
const context =
|
|
2840
|
+
const context = React27__namespace.useContext(ChartContext);
|
|
2634
2841
|
if (!context) {
|
|
2635
2842
|
throw new Error("useChart must be used within a <ChartContainer />");
|
|
2636
2843
|
}
|
|
@@ -2643,7 +2850,7 @@ function ChartContainer({
|
|
|
2643
2850
|
config,
|
|
2644
2851
|
...props
|
|
2645
2852
|
}) {
|
|
2646
|
-
const uniqueId =
|
|
2853
|
+
const uniqueId = React27__namespace.useId();
|
|
2647
2854
|
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
|
|
2648
2855
|
return /* @__PURE__ */ jsxRuntime.jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2649
2856
|
"div",
|
|
@@ -2704,7 +2911,7 @@ function ChartTooltipContent({
|
|
|
2704
2911
|
labelKey
|
|
2705
2912
|
}) {
|
|
2706
2913
|
const { config } = useChart();
|
|
2707
|
-
const tooltipLabel =
|
|
2914
|
+
const tooltipLabel = React27__namespace.useMemo(() => {
|
|
2708
2915
|
if (hideLabel || !payload?.length) {
|
|
2709
2916
|
return null;
|
|
2710
2917
|
}
|
|
@@ -3539,7 +3746,7 @@ function StatusProgress({
|
|
|
3539
3746
|
const resolvedVariant = variant ?? getVariantFromProgress(clampedValue);
|
|
3540
3747
|
const colors = getStatusColors(resolvedVariant);
|
|
3541
3748
|
const sizes = getSizeClasses(size);
|
|
3542
|
-
const labelText =
|
|
3749
|
+
const labelText = React27__namespace.useMemo(() => {
|
|
3543
3750
|
if (currentCount !== void 0 && totalCount !== void 0) {
|
|
3544
3751
|
return `${currentCount} / ${totalCount} ${unitLabel}`;
|
|
3545
3752
|
}
|
|
@@ -3644,8 +3851,8 @@ function TooltipContent({
|
|
|
3644
3851
|
) });
|
|
3645
3852
|
}
|
|
3646
3853
|
function useDetectTheme() {
|
|
3647
|
-
const [theme, setTheme] =
|
|
3648
|
-
|
|
3854
|
+
const [theme, setTheme] = React27__namespace.useState("light");
|
|
3855
|
+
React27__namespace.useEffect(() => {
|
|
3649
3856
|
const isDark = document.documentElement.classList.contains("dark");
|
|
3650
3857
|
setTheme(isDark ? "dark" : "light");
|
|
3651
3858
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -4294,7 +4501,7 @@ function CommandShortcut({
|
|
|
4294
4501
|
}
|
|
4295
4502
|
);
|
|
4296
4503
|
}
|
|
4297
|
-
var SearchTrigger =
|
|
4504
|
+
var SearchTrigger = React27__namespace.forwardRef(
|
|
4298
4505
|
({
|
|
4299
4506
|
className,
|
|
4300
4507
|
placeholder = "Search...",
|
|
@@ -4330,7 +4537,7 @@ var SearchTrigger = React29__namespace.forwardRef(
|
|
|
4330
4537
|
);
|
|
4331
4538
|
SearchTrigger.displayName = "SearchTrigger";
|
|
4332
4539
|
function useSearchShortcut(onOpen, key = "k") {
|
|
4333
|
-
|
|
4540
|
+
React27__namespace.useEffect(() => {
|
|
4334
4541
|
const down = (e) => {
|
|
4335
4542
|
if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
|
|
4336
4543
|
e.preventDefault();
|
|
@@ -5305,9 +5512,9 @@ var SIDEBAR_WIDTH = "16rem";
|
|
|
5305
5512
|
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
5306
5513
|
var SIDEBAR_WIDTH_ICON = "3rem";
|
|
5307
5514
|
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
5308
|
-
var SidebarContext =
|
|
5515
|
+
var SidebarContext = React27__namespace.createContext(null);
|
|
5309
5516
|
function useSidebar() {
|
|
5310
|
-
const context =
|
|
5517
|
+
const context = React27__namespace.useContext(SidebarContext);
|
|
5311
5518
|
if (!context) {
|
|
5312
5519
|
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
5313
5520
|
}
|
|
@@ -5323,10 +5530,10 @@ function SidebarProvider({
|
|
|
5323
5530
|
...props
|
|
5324
5531
|
}) {
|
|
5325
5532
|
const isMobile = useIsMobile();
|
|
5326
|
-
const [openMobile, setOpenMobile] =
|
|
5327
|
-
const [_open, _setOpen] =
|
|
5533
|
+
const [openMobile, setOpenMobile] = React27__namespace.useState(false);
|
|
5534
|
+
const [_open, _setOpen] = React27__namespace.useState(defaultOpen);
|
|
5328
5535
|
const open = openProp ?? _open;
|
|
5329
|
-
const setOpen =
|
|
5536
|
+
const setOpen = React27__namespace.useCallback(
|
|
5330
5537
|
(value) => {
|
|
5331
5538
|
const openState = typeof value === "function" ? value(open) : value;
|
|
5332
5539
|
if (setOpenProp) {
|
|
@@ -5338,10 +5545,10 @@ function SidebarProvider({
|
|
|
5338
5545
|
},
|
|
5339
5546
|
[setOpenProp, open]
|
|
5340
5547
|
);
|
|
5341
|
-
const toggleSidebar =
|
|
5548
|
+
const toggleSidebar = React27__namespace.useCallback(() => {
|
|
5342
5549
|
return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
|
|
5343
5550
|
}, [isMobile, setOpen, setOpenMobile]);
|
|
5344
|
-
|
|
5551
|
+
React27__namespace.useEffect(() => {
|
|
5345
5552
|
const handleKeyDown = (event) => {
|
|
5346
5553
|
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
5347
5554
|
event.preventDefault();
|
|
@@ -5352,7 +5559,7 @@ function SidebarProvider({
|
|
|
5352
5559
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5353
5560
|
}, [toggleSidebar]);
|
|
5354
5561
|
const state = open ? "expanded" : "collapsed";
|
|
5355
|
-
const contextValue =
|
|
5562
|
+
const contextValue = React27__namespace.useMemo(
|
|
5356
5563
|
() => ({
|
|
5357
5564
|
state,
|
|
5358
5565
|
open,
|
|
@@ -5810,7 +6017,7 @@ function SidebarMenuSkeleton({
|
|
|
5810
6017
|
showIcon = false,
|
|
5811
6018
|
...props
|
|
5812
6019
|
}) {
|
|
5813
|
-
const width =
|
|
6020
|
+
const width = React27__namespace.useMemo(() => {
|
|
5814
6021
|
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
5815
6022
|
}, []);
|
|
5816
6023
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -5953,7 +6160,7 @@ var sectionVariants = classVarianceAuthority.cva(
|
|
|
5953
6160
|
}
|
|
5954
6161
|
);
|
|
5955
6162
|
var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
|
|
5956
|
-
var Section =
|
|
6163
|
+
var Section = React27__namespace.forwardRef(
|
|
5957
6164
|
({ className, variant, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5958
6165
|
"section",
|
|
5959
6166
|
{
|
|
@@ -5965,7 +6172,7 @@ var Section = React29__namespace.forwardRef(
|
|
|
5965
6172
|
)
|
|
5966
6173
|
);
|
|
5967
6174
|
Section.displayName = "Section";
|
|
5968
|
-
var SectionHeader =
|
|
6175
|
+
var SectionHeader = React27__namespace.forwardRef(
|
|
5969
6176
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5970
6177
|
"div",
|
|
5971
6178
|
{
|
|
@@ -5980,7 +6187,7 @@ var SectionHeader = React29__namespace.forwardRef(
|
|
|
5980
6187
|
)
|
|
5981
6188
|
);
|
|
5982
6189
|
SectionHeader.displayName = "SectionHeader";
|
|
5983
|
-
var SectionTitle =
|
|
6190
|
+
var SectionTitle = React27__namespace.forwardRef(
|
|
5984
6191
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5985
6192
|
"h2",
|
|
5986
6193
|
{
|
|
@@ -5994,7 +6201,7 @@ var SectionTitle = React29__namespace.forwardRef(
|
|
|
5994
6201
|
)
|
|
5995
6202
|
);
|
|
5996
6203
|
SectionTitle.displayName = "SectionTitle";
|
|
5997
|
-
var SectionDescription =
|
|
6204
|
+
var SectionDescription = React27__namespace.forwardRef(
|
|
5998
6205
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5999
6206
|
"p",
|
|
6000
6207
|
{
|
|
@@ -6008,7 +6215,7 @@ var SectionDescription = React29__namespace.forwardRef(
|
|
|
6008
6215
|
)
|
|
6009
6216
|
);
|
|
6010
6217
|
SectionDescription.displayName = "SectionDescription";
|
|
6011
|
-
var SectionContent =
|
|
6218
|
+
var SectionContent = React27__namespace.forwardRef(
|
|
6012
6219
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6013
6220
|
"div",
|
|
6014
6221
|
{
|
|
@@ -6022,7 +6229,7 @@ var SectionContent = React29__namespace.forwardRef(
|
|
|
6022
6229
|
)
|
|
6023
6230
|
);
|
|
6024
6231
|
SectionContent.displayName = "SectionContent";
|
|
6025
|
-
var SectionFooter =
|
|
6232
|
+
var SectionFooter = React27__namespace.forwardRef(
|
|
6026
6233
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6027
6234
|
"div",
|
|
6028
6235
|
{
|
|
@@ -6330,7 +6537,7 @@ function SiteHeader({
|
|
|
6330
6537
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-[var(--header-height,3.5rem)] w-full items-center gap-[var(--j3m-spacing-s)] px-[var(--j3m-spacing-m)]", children: [
|
|
6331
6538
|
trigger,
|
|
6332
6539
|
trigger && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
|
|
6333
|
-
/* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6540
|
+
/* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React27__namespace.Fragment, { children: [
|
|
6334
6541
|
index > 0 && /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbSeparator, {}),
|
|
6335
6542
|
/* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbPage, { children: item.label }) })
|
|
6336
6543
|
] }, index)) }) }),
|
|
@@ -6951,11 +7158,11 @@ function PlanningWeekCommentPopover({
|
|
|
6951
7158
|
open,
|
|
6952
7159
|
onOpenChange
|
|
6953
7160
|
}) {
|
|
6954
|
-
const [newCommentText, setNewCommentText] =
|
|
6955
|
-
const [selectedLocationId, setSelectedLocationId] =
|
|
6956
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
6957
|
-
const [showAddForm, setShowAddForm] =
|
|
6958
|
-
const selectedLocation =
|
|
7161
|
+
const [newCommentText, setNewCommentText] = React27__namespace.useState("");
|
|
7162
|
+
const [selectedLocationId, setSelectedLocationId] = React27__namespace.useState("");
|
|
7163
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
|
|
7164
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
7165
|
+
const selectedLocation = React27__namespace.useMemo(() => {
|
|
6959
7166
|
return locationOptions.find((opt) => opt.id === selectedLocationId);
|
|
6960
7167
|
}, [locationOptions, selectedLocationId]);
|
|
6961
7168
|
const handleSubmit = () => {
|
|
@@ -6999,8 +7206,8 @@ function PlanningWeekCommentPopover({
|
|
|
6999
7206
|
minute: "2-digit"
|
|
7000
7207
|
}).format(date);
|
|
7001
7208
|
};
|
|
7002
|
-
const prevOpenRef =
|
|
7003
|
-
|
|
7209
|
+
const prevOpenRef = React27__namespace.useRef(open);
|
|
7210
|
+
React27__namespace.useEffect(() => {
|
|
7004
7211
|
const wasOpen = prevOpenRef.current;
|
|
7005
7212
|
prevOpenRef.current = open;
|
|
7006
7213
|
if (wasOpen && !open) {
|
|
@@ -7354,22 +7561,22 @@ function PlanningTable({
|
|
|
7354
7561
|
stickySupplierColumn = true,
|
|
7355
7562
|
maxHeight = "600px"
|
|
7356
7563
|
} = config;
|
|
7357
|
-
const weeks =
|
|
7564
|
+
const weeks = React27__namespace.useMemo(
|
|
7358
7565
|
() => generateWeeks(startDate, weekCount),
|
|
7359
7566
|
[startDate, weekCount]
|
|
7360
7567
|
);
|
|
7361
|
-
const currentWeekKey =
|
|
7568
|
+
const currentWeekKey = React27__namespace.useMemo(() => {
|
|
7362
7569
|
const currentWeek = weeks.find((w) => w.isCurrentWeek);
|
|
7363
7570
|
return currentWeek ? getWeekKey(currentWeek.startDate) : null;
|
|
7364
7571
|
}, [weeks]);
|
|
7365
|
-
const columns =
|
|
7572
|
+
const columns = React27__namespace.useMemo(
|
|
7366
7573
|
() => generateColumns(weeks, config, suppliers),
|
|
7367
7574
|
[weeks, config, suppliers]
|
|
7368
7575
|
);
|
|
7369
|
-
const [sorting, setSorting] =
|
|
7370
|
-
const [columnFilters, setColumnFilters] =
|
|
7371
|
-
const [columnVisibility, setColumnVisibility] =
|
|
7372
|
-
const [rowSelection, setRowSelection] =
|
|
7576
|
+
const [sorting, setSorting] = React27__namespace.useState([]);
|
|
7577
|
+
const [columnFilters, setColumnFilters] = React27__namespace.useState([]);
|
|
7578
|
+
const [columnVisibility, setColumnVisibility] = React27__namespace.useState({});
|
|
7579
|
+
const [rowSelection, setRowSelection] = React27__namespace.useState({});
|
|
7373
7580
|
const table = reactTable.useReactTable({
|
|
7374
7581
|
data: suppliers,
|
|
7375
7582
|
columns,
|
|
@@ -7393,12 +7600,95 @@ function PlanningTable({
|
|
|
7393
7600
|
}
|
|
7394
7601
|
}
|
|
7395
7602
|
});
|
|
7603
|
+
const insightMetrics = React27__namespace.useMemo(() => {
|
|
7604
|
+
let totalProduced = 0;
|
|
7605
|
+
let totalRequired = 0;
|
|
7606
|
+
let totalDeliveries = 0;
|
|
7607
|
+
for (const supplier of suppliers) {
|
|
7608
|
+
for (const weekKey in supplier.weeks) {
|
|
7609
|
+
const weekData = supplier.weeks[weekKey];
|
|
7610
|
+
if (weekData.production) {
|
|
7611
|
+
totalProduced += weekData.production.produced;
|
|
7612
|
+
totalRequired += weekData.production.target;
|
|
7613
|
+
}
|
|
7614
|
+
totalDeliveries += weekData.deliveries?.length ?? 0;
|
|
7615
|
+
}
|
|
7616
|
+
}
|
|
7617
|
+
const productionPercent = totalRequired > 0 ? totalProduced / totalRequired * 100 : 0;
|
|
7618
|
+
return [
|
|
7619
|
+
{
|
|
7620
|
+
key: "produced",
|
|
7621
|
+
label: "produced",
|
|
7622
|
+
value: totalProduced,
|
|
7623
|
+
unit: "tons",
|
|
7624
|
+
icon: "factory",
|
|
7625
|
+
status: productionPercent >= 100 ? "success" : "normal"
|
|
7626
|
+
},
|
|
7627
|
+
{
|
|
7628
|
+
key: "deliveries",
|
|
7629
|
+
label: "planned deliveries",
|
|
7630
|
+
value: totalDeliveries,
|
|
7631
|
+
icon: "truck",
|
|
7632
|
+
status: "normal"
|
|
7633
|
+
},
|
|
7634
|
+
{
|
|
7635
|
+
key: "progress",
|
|
7636
|
+
label: "produced vs required",
|
|
7637
|
+
value: productionPercent,
|
|
7638
|
+
isPercentage: true,
|
|
7639
|
+
icon: "trending",
|
|
7640
|
+
status: productionPercent >= 100 ? "success" : productionPercent >= 50 ? "normal" : "warning"
|
|
7641
|
+
}
|
|
7642
|
+
];
|
|
7643
|
+
}, [suppliers]);
|
|
7644
|
+
const columnSummaryData = React27__namespace.useMemo(() => {
|
|
7645
|
+
return weeks.map((week) => {
|
|
7646
|
+
const weekKey = getWeekKey(week.startDate);
|
|
7647
|
+
let producedTons = 0;
|
|
7648
|
+
let plannedDeliveries = 0;
|
|
7649
|
+
let sentDeliveries = 0;
|
|
7650
|
+
let hasWarning = false;
|
|
7651
|
+
let hasCritical = false;
|
|
7652
|
+
let allComplete = true;
|
|
7653
|
+
for (const supplier of suppliers) {
|
|
7654
|
+
const weekData = supplier.weeks[weekKey];
|
|
7655
|
+
if (weekData) {
|
|
7656
|
+
if (weekData.production) {
|
|
7657
|
+
producedTons += weekData.production.produced;
|
|
7658
|
+
if (weekData.production.progress !== void 0 && weekData.production.progress < 100) {
|
|
7659
|
+
allComplete = false;
|
|
7660
|
+
}
|
|
7661
|
+
}
|
|
7662
|
+
if (weekData.deliveries) {
|
|
7663
|
+
plannedDeliveries += weekData.deliveries.length;
|
|
7664
|
+
sentDeliveries += weekData.deliveries.filter(
|
|
7665
|
+
(d) => d.status === "on-time" && (d.progress ?? 0) >= 100
|
|
7666
|
+
).length;
|
|
7667
|
+
}
|
|
7668
|
+
if (weekData.hasWarning) hasWarning = true;
|
|
7669
|
+
if (weekData.deliveries?.some((d) => d.status === "critical")) hasCritical = true;
|
|
7670
|
+
}
|
|
7671
|
+
}
|
|
7672
|
+
let status = "normal";
|
|
7673
|
+
if (hasCritical) status = "critical";
|
|
7674
|
+
else if (hasWarning) status = "warning";
|
|
7675
|
+
else if (allComplete && producedTons > 0) status = "complete";
|
|
7676
|
+
return {
|
|
7677
|
+
weekKey,
|
|
7678
|
+
producedTons,
|
|
7679
|
+
plannedDeliveries,
|
|
7680
|
+
sentDeliveries,
|
|
7681
|
+
status
|
|
7682
|
+
};
|
|
7683
|
+
});
|
|
7684
|
+
}, [weeks, suppliers]);
|
|
7396
7685
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7397
7686
|
"div",
|
|
7398
7687
|
{
|
|
7399
7688
|
"data-slot": "planning-table",
|
|
7400
7689
|
className: cn("flex flex-col gap-4", className),
|
|
7401
7690
|
children: [
|
|
7691
|
+
/* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics }),
|
|
7402
7692
|
showToolbar && /* @__PURE__ */ jsxRuntime.jsx(PlanningTableToolbar, { table }),
|
|
7403
7693
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border bg-background shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7404
7694
|
ScrollArea,
|
|
@@ -7407,37 +7697,80 @@ function PlanningTable({
|
|
|
7407
7697
|
style: { maxHeight },
|
|
7408
7698
|
children: [
|
|
7409
7699
|
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
|
|
7410
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7700
|
+
/* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "sticky top-0 z-20", children: [
|
|
7701
|
+
table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7702
|
+
"tr",
|
|
7703
|
+
{
|
|
7704
|
+
children: headerGroup.headers.map((header, index) => {
|
|
7705
|
+
const isCurrentWeekColumn = header.id === currentWeekKey;
|
|
7706
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7707
|
+
"th",
|
|
7708
|
+
{
|
|
7709
|
+
className: cn(
|
|
7710
|
+
"h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
|
|
7711
|
+
"border-r border-b border-border last:border-r-0 bg-sidebar",
|
|
7712
|
+
// First column: sticky with right-edge shadow (Quantum token)
|
|
7713
|
+
index === 0 && stickySupplierColumn && [
|
|
7714
|
+
"sticky left-0 z-30 min-w-[200px]",
|
|
7715
|
+
"shadow-[var(--j3m-shadow-sticky-edge)]"
|
|
7716
|
+
],
|
|
7717
|
+
index > 0 && "min-w-[140px]",
|
|
7718
|
+
// Current week: only highlight text/dot, not full background
|
|
7719
|
+
isCurrentWeekColumn && highlightCurrentWeek && "text-primary"
|
|
7720
|
+
),
|
|
7721
|
+
children: header.isPlaceholder ? null : reactTable.flexRender(
|
|
7722
|
+
header.column.columnDef.header,
|
|
7723
|
+
header.getContext()
|
|
7724
|
+
)
|
|
7725
|
+
},
|
|
7726
|
+
header.id
|
|
7727
|
+
);
|
|
7728
|
+
})
|
|
7729
|
+
},
|
|
7730
|
+
headerGroup.id
|
|
7731
|
+
)),
|
|
7732
|
+
/* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
7733
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
|
|
7734
|
+
"h-auto px-3 py-1.5 text-left align-middle",
|
|
7735
|
+
"border-r border-b border-border bg-muted/30",
|
|
7736
|
+
stickySupplierColumn && "sticky left-0 z-30 min-w-[200px]",
|
|
7737
|
+
stickySupplierColumn && "shadow-[var(--j3m-shadow-sticky-edge)]"
|
|
7738
|
+
), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Summary" }) }),
|
|
7739
|
+
columnSummaryData.map((summary) => {
|
|
7740
|
+
const statusBg = summary.status === "complete" ? "bg-green-50/50 dark:bg-green-950/30" : summary.status === "critical" ? "bg-red-50/50 dark:bg-red-950/30" : summary.status === "warning" ? "bg-amber-50/50 dark:bg-amber-950/30" : "bg-muted/30";
|
|
7741
|
+
const statusText = summary.status === "complete" ? "text-green-700 dark:text-green-300" : summary.status === "critical" ? "text-red-700 dark:text-red-300" : summary.status === "warning" ? "text-amber-700 dark:text-amber-300" : "text-muted-foreground";
|
|
7415
7742
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7416
7743
|
"th",
|
|
7417
7744
|
{
|
|
7418
7745
|
className: cn(
|
|
7419
|
-
"h-
|
|
7420
|
-
"border-r border-b border-border last:border-r-0
|
|
7421
|
-
|
|
7422
|
-
index === 0 && stickySupplierColumn && [
|
|
7423
|
-
"sticky left-0 z-30 min-w-[200px]",
|
|
7424
|
-
"shadow-[var(--j3m-shadow-sticky-edge)]"
|
|
7425
|
-
],
|
|
7426
|
-
index > 0 && "min-w-[140px]",
|
|
7427
|
-
// Current week: only highlight text/dot, not full background
|
|
7428
|
-
isCurrentWeekColumn && highlightCurrentWeek && "text-primary"
|
|
7746
|
+
"h-auto px-2 py-1.5 text-left align-middle",
|
|
7747
|
+
"border-r border-b border-border last:border-r-0 min-w-[140px]",
|
|
7748
|
+
statusBg
|
|
7429
7749
|
),
|
|
7430
|
-
children:
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7750
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
7751
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7752
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3", statusText) }),
|
|
7753
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-xs font-medium tabular-nums", statusText), children: [
|
|
7754
|
+
summary.producedTons.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
7755
|
+
" t"
|
|
7756
|
+
] })
|
|
7757
|
+
] }),
|
|
7758
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7759
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3 w-3 text-muted-foreground" }),
|
|
7760
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
7761
|
+
summary.sentDeliveries,
|
|
7762
|
+
"/",
|
|
7763
|
+
summary.plannedDeliveries,
|
|
7764
|
+
" sent"
|
|
7765
|
+
] })
|
|
7766
|
+
] })
|
|
7767
|
+
] })
|
|
7434
7768
|
},
|
|
7435
|
-
|
|
7769
|
+
summary.weekKey
|
|
7436
7770
|
);
|
|
7437
7771
|
})
|
|
7438
|
-
}
|
|
7439
|
-
|
|
7440
|
-
)) }),
|
|
7772
|
+
] })
|
|
7773
|
+
] }),
|
|
7441
7774
|
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7442
7775
|
"tr",
|
|
7443
7776
|
{
|
|
@@ -7585,10 +7918,10 @@ function DeliveryCommentPopover({
|
|
|
7585
7918
|
onAddComment,
|
|
7586
7919
|
deliveryLabel
|
|
7587
7920
|
}) {
|
|
7588
|
-
const [open, setOpen] =
|
|
7589
|
-
const [newCommentText, setNewCommentText] =
|
|
7590
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
7591
|
-
const [showAddForm, setShowAddForm] =
|
|
7921
|
+
const [open, setOpen] = React27__namespace.useState(false);
|
|
7922
|
+
const [newCommentText, setNewCommentText] = React27__namespace.useState("");
|
|
7923
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
|
|
7924
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
7592
7925
|
const handleSubmit = () => {
|
|
7593
7926
|
if (newCommentText.trim() && onAddComment) {
|
|
7594
7927
|
onAddComment(newCommentText.trim());
|
|
@@ -7615,8 +7948,8 @@ function DeliveryCommentPopover({
|
|
|
7615
7948
|
minute: "2-digit"
|
|
7616
7949
|
}).format(date);
|
|
7617
7950
|
};
|
|
7618
|
-
const prevOpenRef =
|
|
7619
|
-
|
|
7951
|
+
const prevOpenRef = React27__namespace.useRef(open);
|
|
7952
|
+
React27__namespace.useEffect(() => {
|
|
7620
7953
|
const wasOpen = prevOpenRef.current;
|
|
7621
7954
|
prevOpenRef.current = open;
|
|
7622
7955
|
if (wasOpen && !open) {
|
|
@@ -7728,8 +8061,8 @@ function ProductionCommentSection({
|
|
|
7728
8061
|
comments = [],
|
|
7729
8062
|
onAddComment
|
|
7730
8063
|
}) {
|
|
7731
|
-
const [showAddForm, setShowAddForm] =
|
|
7732
|
-
const [newComment, setNewComment] =
|
|
8064
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
8065
|
+
const [newComment, setNewComment] = React27__namespace.useState("");
|
|
7733
8066
|
const handleSubmit = () => {
|
|
7734
8067
|
if (newComment.trim() && onAddComment) {
|
|
7735
8068
|
onAddComment(newComment.trim());
|
|
@@ -7828,43 +8161,65 @@ function DeliveryListItem({
|
|
|
7828
8161
|
}) {
|
|
7829
8162
|
const hasComments = (delivery.comments?.length ?? 0) > 0;
|
|
7830
8163
|
const isComplete = (delivery.progress ?? 0) >= 100;
|
|
7831
|
-
const
|
|
8164
|
+
const getCardStyles3 = () => {
|
|
7832
8165
|
if (delivery.status === "critical") {
|
|
7833
|
-
return {
|
|
8166
|
+
return {
|
|
8167
|
+
card: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30",
|
|
8168
|
+
icon: "text-red-600 dark:text-red-400",
|
|
8169
|
+
title: "text-foreground",
|
|
8170
|
+
subtitle: "text-red-700/70 dark:text-red-300/70",
|
|
8171
|
+
chevron: "text-red-600/60 dark:text-red-400/60"
|
|
8172
|
+
};
|
|
7834
8173
|
}
|
|
7835
8174
|
if (delivery.status === "delayed") {
|
|
7836
|
-
return {
|
|
8175
|
+
return {
|
|
8176
|
+
card: "border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30",
|
|
8177
|
+
icon: "text-amber-600 dark:text-amber-400",
|
|
8178
|
+
title: "text-foreground",
|
|
8179
|
+
subtitle: "text-amber-700/70 dark:text-amber-300/70",
|
|
8180
|
+
chevron: "text-amber-600/60 dark:text-amber-400/60"
|
|
8181
|
+
};
|
|
7837
8182
|
}
|
|
7838
8183
|
if (isComplete) {
|
|
7839
|
-
return {
|
|
8184
|
+
return {
|
|
8185
|
+
card: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30",
|
|
8186
|
+
icon: "text-green-600 dark:text-green-400",
|
|
8187
|
+
title: "text-foreground",
|
|
8188
|
+
subtitle: "text-green-700/70 dark:text-green-300/70",
|
|
8189
|
+
chevron: "text-green-600/60 dark:text-green-400/60"
|
|
8190
|
+
};
|
|
7840
8191
|
}
|
|
7841
|
-
return {
|
|
8192
|
+
return {
|
|
8193
|
+
card: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20",
|
|
8194
|
+
icon: "text-muted-foreground",
|
|
8195
|
+
title: "text-foreground",
|
|
8196
|
+
subtitle: "text-muted-foreground",
|
|
8197
|
+
chevron: "text-muted-foreground/60"
|
|
8198
|
+
};
|
|
7842
8199
|
};
|
|
7843
|
-
const
|
|
8200
|
+
const styles = getCardStyles3();
|
|
7844
8201
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7845
8202
|
"button",
|
|
7846
8203
|
{
|
|
7847
8204
|
onClick,
|
|
7848
8205
|
className: cn(
|
|
7849
8206
|
"w-full flex items-center justify-between p-3 rounded-lg",
|
|
7850
|
-
"
|
|
7851
|
-
"
|
|
8207
|
+
"transition-all duration-200 ease-out cursor-pointer text-left",
|
|
8208
|
+
"hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
|
|
8209
|
+
styles.card
|
|
7852
8210
|
),
|
|
7853
8211
|
children: [
|
|
7854
8212
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7855
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7856
|
-
"flex items-center justify-center h-8 w-8 rounded-lg",
|
|
7857
|
-
iconStyles.bg
|
|
7858
|
-
), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
|
|
8213
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-5 w-5 shrink-0", styles.icon) }),
|
|
7859
8214
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7860
8215
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7861
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
|
|
8216
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", styles.title), children: delivery.label || `Delivery ${index + 1}` }),
|
|
7862
8217
|
hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
7863
8218
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
|
|
7864
8219
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
|
|
7865
8220
|
] })
|
|
7866
8221
|
] }),
|
|
7867
|
-
delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs
|
|
8222
|
+
delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs", styles.subtitle), children: [
|
|
7868
8223
|
"\u2192 ",
|
|
7869
8224
|
delivery.destination
|
|
7870
8225
|
] })
|
|
@@ -7879,7 +8234,7 @@ function DeliveryListItem({
|
|
|
7879
8234
|
children: getStatusLabel(delivery.status, isComplete)
|
|
7880
8235
|
}
|
|
7881
8236
|
),
|
|
7882
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4
|
|
8237
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4", styles.chevron) })
|
|
7883
8238
|
] })
|
|
7884
8239
|
]
|
|
7885
8240
|
}
|
|
@@ -7892,7 +8247,7 @@ function DeliveryDetailsView({
|
|
|
7892
8247
|
onAddComment
|
|
7893
8248
|
}) {
|
|
7894
8249
|
const elements = delivery.elements ?? [];
|
|
7895
|
-
const categorizedElements =
|
|
8250
|
+
const categorizedElements = React27__namespace.useMemo(() => {
|
|
7896
8251
|
const sent = [];
|
|
7897
8252
|
const notSent = [];
|
|
7898
8253
|
const moved = [];
|
|
@@ -8260,15 +8615,15 @@ function WeekDetailDialog({
|
|
|
8260
8615
|
}) {
|
|
8261
8616
|
const production = data?.production;
|
|
8262
8617
|
const initialProduced = production?.produced ?? 0;
|
|
8263
|
-
const [producedValue, setProducedValue] =
|
|
8264
|
-
const [hasChanges, setHasChanges] =
|
|
8265
|
-
const [selectedDelivery, setSelectedDelivery] =
|
|
8266
|
-
|
|
8618
|
+
const [producedValue, setProducedValue] = React27__namespace.useState(initialProduced.toString());
|
|
8619
|
+
const [hasChanges, setHasChanges] = React27__namespace.useState(false);
|
|
8620
|
+
const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
|
|
8621
|
+
React27__namespace.useEffect(() => {
|
|
8267
8622
|
const newProduced = data?.production?.produced ?? 0;
|
|
8268
8623
|
setProducedValue(newProduced.toString());
|
|
8269
8624
|
setHasChanges(false);
|
|
8270
8625
|
}, [data]);
|
|
8271
|
-
|
|
8626
|
+
React27__namespace.useEffect(() => {
|
|
8272
8627
|
if (!open) {
|
|
8273
8628
|
setSelectedDelivery(null);
|
|
8274
8629
|
}
|
|
@@ -8399,24 +8754,24 @@ function ElementProductionDialog({
|
|
|
8399
8754
|
elements,
|
|
8400
8755
|
onSave
|
|
8401
8756
|
}) {
|
|
8402
|
-
const [searchQuery, setSearchQuery] =
|
|
8403
|
-
const [selectedIds, setSelectedIds] =
|
|
8757
|
+
const [searchQuery, setSearchQuery] = React27__namespace.useState("");
|
|
8758
|
+
const [selectedIds, setSelectedIds] = React27__namespace.useState(
|
|
8404
8759
|
new Set(elements.filter((e) => e.isProduced).map((e) => e.id))
|
|
8405
8760
|
);
|
|
8406
|
-
|
|
8761
|
+
React27__namespace.useEffect(() => {
|
|
8407
8762
|
if (open) {
|
|
8408
8763
|
setSelectedIds(new Set(elements.filter((e) => e.isProduced).map((e) => e.id)));
|
|
8409
8764
|
setSearchQuery("");
|
|
8410
8765
|
}
|
|
8411
8766
|
}, [open, elements]);
|
|
8412
|
-
const filteredElements =
|
|
8767
|
+
const filteredElements = React27__namespace.useMemo(() => {
|
|
8413
8768
|
if (!searchQuery.trim()) return elements;
|
|
8414
8769
|
const query = searchQuery.toLowerCase();
|
|
8415
8770
|
return elements.filter(
|
|
8416
8771
|
(e) => e.name.toLowerCase().includes(query) || e.prefix?.toLowerCase().includes(query) || e.type?.toLowerCase().includes(query)
|
|
8417
8772
|
);
|
|
8418
8773
|
}, [elements, searchQuery]);
|
|
8419
|
-
|
|
8774
|
+
React27__namespace.useMemo(() => {
|
|
8420
8775
|
const prefixes = /* @__PURE__ */ new Set();
|
|
8421
8776
|
elements.forEach((e) => {
|
|
8422
8777
|
if (e.prefix) prefixes.add(e.prefix);
|
|
@@ -8602,10 +8957,10 @@ function DeliveryCommentPopover2({
|
|
|
8602
8957
|
onAddComment,
|
|
8603
8958
|
deliveryLabel
|
|
8604
8959
|
}) {
|
|
8605
|
-
const [open, setOpen] =
|
|
8606
|
-
const [newCommentText, setNewCommentText] =
|
|
8607
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
8608
|
-
const [showAddForm, setShowAddForm] =
|
|
8960
|
+
const [open, setOpen] = React27__namespace.useState(false);
|
|
8961
|
+
const [newCommentText, setNewCommentText] = React27__namespace.useState("");
|
|
8962
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
|
|
8963
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
8609
8964
|
const handleSubmit = () => {
|
|
8610
8965
|
if (newCommentText.trim() && onAddComment) {
|
|
8611
8966
|
onAddComment(newCommentText.trim());
|
|
@@ -8632,7 +8987,7 @@ function DeliveryCommentPopover2({
|
|
|
8632
8987
|
minute: "2-digit"
|
|
8633
8988
|
}).format(date);
|
|
8634
8989
|
};
|
|
8635
|
-
|
|
8990
|
+
React27__namespace.useEffect(() => {
|
|
8636
8991
|
if (!open) {
|
|
8637
8992
|
setShowAddForm(false);
|
|
8638
8993
|
setNewCommentText("");
|
|
@@ -8742,8 +9097,8 @@ function ProductionCommentSection2({
|
|
|
8742
9097
|
comments = [],
|
|
8743
9098
|
onAddComment
|
|
8744
9099
|
}) {
|
|
8745
|
-
const [showAddForm, setShowAddForm] =
|
|
8746
|
-
const [newComment, setNewComment] =
|
|
9100
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
9101
|
+
const [newComment, setNewComment] = React27__namespace.useState("");
|
|
8747
9102
|
const handleSubmit = () => {
|
|
8748
9103
|
if (newComment.trim() && onAddComment) {
|
|
8749
9104
|
onAddComment(newComment.trim());
|
|
@@ -8842,43 +9197,65 @@ function DeliveryListItem2({
|
|
|
8842
9197
|
}) {
|
|
8843
9198
|
const hasComments = (delivery.comments?.length ?? 0) > 0;
|
|
8844
9199
|
const isComplete = (delivery.progress ?? 0) >= 100;
|
|
8845
|
-
const
|
|
9200
|
+
const getCardStyles3 = () => {
|
|
8846
9201
|
if (delivery.status === "critical") {
|
|
8847
|
-
return {
|
|
9202
|
+
return {
|
|
9203
|
+
card: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30",
|
|
9204
|
+
icon: "text-red-600 dark:text-red-400",
|
|
9205
|
+
title: "text-foreground",
|
|
9206
|
+
subtitle: "text-red-700/70 dark:text-red-300/70",
|
|
9207
|
+
chevron: "text-red-600/60 dark:text-red-400/60"
|
|
9208
|
+
};
|
|
8848
9209
|
}
|
|
8849
9210
|
if (delivery.status === "delayed") {
|
|
8850
|
-
return {
|
|
9211
|
+
return {
|
|
9212
|
+
card: "border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30",
|
|
9213
|
+
icon: "text-amber-600 dark:text-amber-400",
|
|
9214
|
+
title: "text-foreground",
|
|
9215
|
+
subtitle: "text-amber-700/70 dark:text-amber-300/70",
|
|
9216
|
+
chevron: "text-amber-600/60 dark:text-amber-400/60"
|
|
9217
|
+
};
|
|
8851
9218
|
}
|
|
8852
9219
|
if (isComplete) {
|
|
8853
|
-
return {
|
|
9220
|
+
return {
|
|
9221
|
+
card: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30",
|
|
9222
|
+
icon: "text-green-600 dark:text-green-400",
|
|
9223
|
+
title: "text-foreground",
|
|
9224
|
+
subtitle: "text-green-700/70 dark:text-green-300/70",
|
|
9225
|
+
chevron: "text-green-600/60 dark:text-green-400/60"
|
|
9226
|
+
};
|
|
8854
9227
|
}
|
|
8855
|
-
return {
|
|
9228
|
+
return {
|
|
9229
|
+
card: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20",
|
|
9230
|
+
icon: "text-muted-foreground",
|
|
9231
|
+
title: "text-foreground",
|
|
9232
|
+
subtitle: "text-muted-foreground",
|
|
9233
|
+
chevron: "text-muted-foreground/60"
|
|
9234
|
+
};
|
|
8856
9235
|
};
|
|
8857
|
-
const
|
|
9236
|
+
const styles = getCardStyles3();
|
|
8858
9237
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8859
9238
|
"button",
|
|
8860
9239
|
{
|
|
8861
9240
|
onClick,
|
|
8862
9241
|
className: cn(
|
|
8863
9242
|
"w-full flex items-center justify-between p-3 rounded-lg",
|
|
8864
|
-
"
|
|
8865
|
-
"
|
|
9243
|
+
"transition-all duration-200 ease-out cursor-pointer text-left",
|
|
9244
|
+
"hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
|
|
9245
|
+
styles.card
|
|
8866
9246
|
),
|
|
8867
9247
|
children: [
|
|
8868
9248
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
8869
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8870
|
-
"flex items-center justify-center h-8 w-8 rounded-lg",
|
|
8871
|
-
iconStyles.bg
|
|
8872
|
-
), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
|
|
9249
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-5 w-5 shrink-0", styles.icon) }),
|
|
8873
9250
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8874
9251
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8875
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
|
|
9252
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", styles.title), children: delivery.label || `Delivery ${index + 1}` }),
|
|
8876
9253
|
hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
8877
9254
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
|
|
8878
9255
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
|
|
8879
9256
|
] })
|
|
8880
9257
|
] }),
|
|
8881
|
-
delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs
|
|
9258
|
+
delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs", styles.subtitle), children: [
|
|
8882
9259
|
"\u2192 ",
|
|
8883
9260
|
delivery.destination
|
|
8884
9261
|
] })
|
|
@@ -8893,7 +9270,7 @@ function DeliveryListItem2({
|
|
|
8893
9270
|
children: getStatusLabel2(delivery.status, isComplete)
|
|
8894
9271
|
}
|
|
8895
9272
|
),
|
|
8896
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4
|
|
9273
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4", styles.chevron) })
|
|
8897
9274
|
] })
|
|
8898
9275
|
]
|
|
8899
9276
|
}
|
|
@@ -8906,7 +9283,7 @@ function DeliveryDetailsView2({
|
|
|
8906
9283
|
onAddComment
|
|
8907
9284
|
}) {
|
|
8908
9285
|
const elements = delivery.elements ?? [];
|
|
8909
|
-
const categorizedElements =
|
|
9286
|
+
const categorizedElements = React27__namespace.useMemo(() => {
|
|
8910
9287
|
const sent = [];
|
|
8911
9288
|
const notSent = [];
|
|
8912
9289
|
const moved = [];
|
|
@@ -9240,10 +9617,10 @@ function WeekDetailSheet({
|
|
|
9240
9617
|
onAddProductionComment,
|
|
9241
9618
|
onAddDeliveryComment
|
|
9242
9619
|
}) {
|
|
9243
|
-
const [selectedDelivery, setSelectedDelivery] =
|
|
9244
|
-
const [productionDialogOpen, setProductionDialogOpen] =
|
|
9245
|
-
const [previousProducedCount, setPreviousProducedCount] =
|
|
9246
|
-
const productionElements =
|
|
9620
|
+
const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
|
|
9621
|
+
const [productionDialogOpen, setProductionDialogOpen] = React27__namespace.useState(false);
|
|
9622
|
+
const [previousProducedCount, setPreviousProducedCount] = React27__namespace.useState(void 0);
|
|
9623
|
+
const productionElements = React27__namespace.useMemo(() => {
|
|
9247
9624
|
if (!data?.deliveries) return [];
|
|
9248
9625
|
const elements = [];
|
|
9249
9626
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -9267,12 +9644,12 @@ function WeekDetailSheet({
|
|
|
9267
9644
|
return elements;
|
|
9268
9645
|
}, [data?.deliveries]);
|
|
9269
9646
|
const currentProducedCount = productionElements.filter((e) => e.isProduced).length;
|
|
9270
|
-
|
|
9647
|
+
React27__namespace.useEffect(() => {
|
|
9271
9648
|
if (open && data?.deliveries) {
|
|
9272
9649
|
setPreviousProducedCount(currentProducedCount);
|
|
9273
9650
|
}
|
|
9274
9651
|
}, [open]);
|
|
9275
|
-
|
|
9652
|
+
React27__namespace.useEffect(() => {
|
|
9276
9653
|
if (!open) {
|
|
9277
9654
|
setSelectedDelivery(null);
|
|
9278
9655
|
setProductionDialogOpen(false);
|
|
@@ -9505,13 +9882,13 @@ function CalibrationWeekCell({
|
|
|
9505
9882
|
onAddClick,
|
|
9506
9883
|
...props
|
|
9507
9884
|
}) {
|
|
9508
|
-
const inputRef =
|
|
9509
|
-
const [localValue, setLocalValue] =
|
|
9885
|
+
const inputRef = React27__namespace.useRef(null);
|
|
9886
|
+
const [localValue, setLocalValue] = React27__namespace.useState(
|
|
9510
9887
|
data.entered !== null ? String(data.entered) : ""
|
|
9511
9888
|
);
|
|
9512
|
-
const [isHovered, setIsHovered] =
|
|
9513
|
-
const [isEditing, setIsEditing] =
|
|
9514
|
-
|
|
9889
|
+
const [isHovered, setIsHovered] = React27__namespace.useState(false);
|
|
9890
|
+
const [isEditing, setIsEditing] = React27__namespace.useState(false);
|
|
9891
|
+
React27__namespace.useEffect(() => {
|
|
9515
9892
|
setLocalValue(data.entered !== null ? String(data.entered) : "");
|
|
9516
9893
|
}, [data.entered]);
|
|
9517
9894
|
const unitLabel = formatCalibrationUnit(unit);
|
|
@@ -9697,11 +10074,11 @@ function CommentPopover({
|
|
|
9697
10074
|
open,
|
|
9698
10075
|
onOpenChange
|
|
9699
10076
|
}) {
|
|
9700
|
-
const [newCommentText, setNewCommentText] =
|
|
9701
|
-
const [selectedPrefixId, setSelectedPrefixId] =
|
|
9702
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
9703
|
-
const [showAddForm, setShowAddForm] =
|
|
9704
|
-
const selectedPrefixName =
|
|
10077
|
+
const [newCommentText, setNewCommentText] = React27__namespace.useState("");
|
|
10078
|
+
const [selectedPrefixId, setSelectedPrefixId] = React27__namespace.useState("");
|
|
10079
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
|
|
10080
|
+
const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
|
|
10081
|
+
const selectedPrefixName = React27__namespace.useMemo(() => {
|
|
9705
10082
|
const prefix = availablePrefixes.find((p) => p.id === selectedPrefixId);
|
|
9706
10083
|
return prefix?.name ?? "";
|
|
9707
10084
|
}, [availablePrefixes, selectedPrefixId]);
|
|
@@ -9733,8 +10110,8 @@ function CommentPopover({
|
|
|
9733
10110
|
minute: "2-digit"
|
|
9734
10111
|
}).format(date);
|
|
9735
10112
|
};
|
|
9736
|
-
const prevOpenRef =
|
|
9737
|
-
|
|
10113
|
+
const prevOpenRef = React27__namespace.useRef(open);
|
|
10114
|
+
React27__namespace.useEffect(() => {
|
|
9738
10115
|
const wasOpen = prevOpenRef.current;
|
|
9739
10116
|
prevOpenRef.current = open;
|
|
9740
10117
|
if (wasOpen && !open) {
|
|
@@ -9963,7 +10340,7 @@ function CalibrationTable({
|
|
|
9963
10340
|
onAddComment,
|
|
9964
10341
|
onAddEarlierWeek
|
|
9965
10342
|
} = config;
|
|
9966
|
-
const calculatedStartDate =
|
|
10343
|
+
const calculatedStartDate = React27__namespace.useMemo(() => {
|
|
9967
10344
|
if (startDate) return startDate;
|
|
9968
10345
|
let earliest = null;
|
|
9969
10346
|
for (const prefix of prefixes) {
|
|
@@ -9984,31 +10361,31 @@ function CalibrationTable({
|
|
|
9984
10361
|
}
|
|
9985
10362
|
return earliest ?? /* @__PURE__ */ new Date();
|
|
9986
10363
|
}, [startDate, prefixes]);
|
|
9987
|
-
const [additionalWeeks, setAdditionalWeeks] =
|
|
9988
|
-
const weeks =
|
|
10364
|
+
const [additionalWeeks, setAdditionalWeeks] = React27__namespace.useState(0);
|
|
10365
|
+
const weeks = React27__namespace.useMemo(() => {
|
|
9989
10366
|
const start = new Date(calculatedStartDate);
|
|
9990
10367
|
start.setDate(start.getDate() - additionalWeeks * 7);
|
|
9991
10368
|
return generateWeeks(start, weekCount + additionalWeeks);
|
|
9992
10369
|
}, [calculatedStartDate, weekCount, additionalWeeks]);
|
|
9993
|
-
|
|
10370
|
+
React27__namespace.useMemo(() => {
|
|
9994
10371
|
const currentWeek = weeks.find((w) => w.isCurrentWeek);
|
|
9995
10372
|
return currentWeek ? getWeekKey(currentWeek.startDate) : null;
|
|
9996
10373
|
}, [weeks]);
|
|
9997
|
-
const [currentPage, setCurrentPage] =
|
|
9998
|
-
const [pageSize, setPageSize] =
|
|
9999
|
-
const [searchQuery, setSearchQuery] =
|
|
10000
|
-
const filteredPrefixes =
|
|
10374
|
+
const [currentPage, setCurrentPage] = React27__namespace.useState(0);
|
|
10375
|
+
const [pageSize, setPageSize] = React27__namespace.useState(defaultPageSize);
|
|
10376
|
+
const [searchQuery, setSearchQuery] = React27__namespace.useState("");
|
|
10377
|
+
const filteredPrefixes = React27__namespace.useMemo(() => {
|
|
10001
10378
|
if (!searchQuery) return prefixes;
|
|
10002
10379
|
const query = searchQuery.toLowerCase();
|
|
10003
10380
|
return prefixes.filter(
|
|
10004
10381
|
(p) => p.name.toLowerCase().includes(query) || p.typeCode.toLowerCase().includes(query)
|
|
10005
10382
|
);
|
|
10006
10383
|
}, [prefixes, searchQuery]);
|
|
10007
|
-
const paginatedPrefixes =
|
|
10384
|
+
const paginatedPrefixes = React27__namespace.useMemo(() => {
|
|
10008
10385
|
const start = currentPage * pageSize;
|
|
10009
10386
|
return filteredPrefixes.slice(start, start + pageSize);
|
|
10010
10387
|
}, [filteredPrefixes, currentPage, pageSize]);
|
|
10011
|
-
|
|
10388
|
+
React27__namespace.useMemo(
|
|
10012
10389
|
() => canSubmitCalibration(prefixes),
|
|
10013
10390
|
[prefixes]
|
|
10014
10391
|
);
|
|
@@ -10032,10 +10409,88 @@ function CalibrationTable({
|
|
|
10032
10409
|
}
|
|
10033
10410
|
return allComments;
|
|
10034
10411
|
};
|
|
10035
|
-
const availablePrefixes =
|
|
10412
|
+
const availablePrefixes = React27__namespace.useMemo(
|
|
10036
10413
|
() => prefixes.map((p) => ({ id: p.id, name: p.name })),
|
|
10037
10414
|
[prefixes]
|
|
10038
10415
|
);
|
|
10416
|
+
const insightMetrics = React27__namespace.useMemo(() => {
|
|
10417
|
+
let totalCalibrated = 0;
|
|
10418
|
+
let totalRequired = 0;
|
|
10419
|
+
for (const prefix of prefixes) {
|
|
10420
|
+
for (const weekKey in prefix.weeks) {
|
|
10421
|
+
const cell = prefix.weeks[weekKey];
|
|
10422
|
+
if (cell.planned > 0) {
|
|
10423
|
+
totalRequired += cell.planned;
|
|
10424
|
+
totalCalibrated += cell.entered ?? 0;
|
|
10425
|
+
}
|
|
10426
|
+
}
|
|
10427
|
+
}
|
|
10428
|
+
const completeness = totalRequired > 0 ? totalCalibrated / totalRequired * 100 : 0;
|
|
10429
|
+
const remaining = Math.max(0, totalRequired - totalCalibrated);
|
|
10430
|
+
return [
|
|
10431
|
+
{
|
|
10432
|
+
key: "calibrated",
|
|
10433
|
+
label: "calibrated",
|
|
10434
|
+
value: totalCalibrated,
|
|
10435
|
+
unit: "tons",
|
|
10436
|
+
icon: "factory",
|
|
10437
|
+
status: completeness >= 100 ? "success" : "normal"
|
|
10438
|
+
},
|
|
10439
|
+
{
|
|
10440
|
+
key: "remaining",
|
|
10441
|
+
label: "remaining",
|
|
10442
|
+
value: remaining,
|
|
10443
|
+
unit: "tons",
|
|
10444
|
+
icon: "factory",
|
|
10445
|
+
status: remaining > 0 ? "warning" : "success"
|
|
10446
|
+
},
|
|
10447
|
+
{
|
|
10448
|
+
key: "completeness",
|
|
10449
|
+
label: "complete",
|
|
10450
|
+
value: completeness,
|
|
10451
|
+
isPercentage: true,
|
|
10452
|
+
icon: "trending",
|
|
10453
|
+
status: completeness >= 100 ? "success" : completeness >= 50 ? "normal" : "warning"
|
|
10454
|
+
}
|
|
10455
|
+
];
|
|
10456
|
+
}, [prefixes]);
|
|
10457
|
+
const columnSummaryData = React27__namespace.useMemo(() => {
|
|
10458
|
+
return weeks.map((week) => {
|
|
10459
|
+
const weekKey = getWeekKey(week.startDate);
|
|
10460
|
+
let calibratedTons = 0;
|
|
10461
|
+
let requiredTons = 0;
|
|
10462
|
+
let hasShortfall = false;
|
|
10463
|
+
let allValid = true;
|
|
10464
|
+
for (const prefix of prefixes) {
|
|
10465
|
+
const cell = prefix.weeks[weekKey];
|
|
10466
|
+
if (cell) {
|
|
10467
|
+
requiredTons += cell.planned;
|
|
10468
|
+
calibratedTons += cell.entered ?? 0;
|
|
10469
|
+
if (cell.status === "shortfall") hasShortfall = true;
|
|
10470
|
+
if (cell.status !== "valid" && cell.planned > 0) allValid = false;
|
|
10471
|
+
}
|
|
10472
|
+
}
|
|
10473
|
+
let status2 = "normal";
|
|
10474
|
+
if (hasShortfall) {
|
|
10475
|
+
status2 = "critical";
|
|
10476
|
+
} else if (allValid && requiredTons > 0) {
|
|
10477
|
+
status2 = "complete";
|
|
10478
|
+
}
|
|
10479
|
+
return {
|
|
10480
|
+
columnKey: weekKey,
|
|
10481
|
+
primary: {
|
|
10482
|
+
value: calibratedTons,
|
|
10483
|
+
unit: "t",
|
|
10484
|
+
icon: "factory"
|
|
10485
|
+
},
|
|
10486
|
+
secondary: {
|
|
10487
|
+
value: requiredTons,
|
|
10488
|
+
unit: "t req"
|
|
10489
|
+
},
|
|
10490
|
+
status: status2
|
|
10491
|
+
};
|
|
10492
|
+
});
|
|
10493
|
+
}, [weeks, prefixes]);
|
|
10039
10494
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10040
10495
|
"div",
|
|
10041
10496
|
{
|
|
@@ -10046,6 +10501,7 @@ function CalibrationTable({
|
|
|
10046
10501
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: "Weekly Production Calibration" }),
|
|
10047
10502
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Review required weekly production and confirm achievable output at the selected checkpoint." })
|
|
10048
10503
|
] }) }),
|
|
10504
|
+
/* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics }),
|
|
10049
10505
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
10050
10506
|
showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
10051
10507
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10078,36 +10534,74 @@ function CalibrationTable({
|
|
|
10078
10534
|
style: { maxHeight },
|
|
10079
10535
|
children: [
|
|
10080
10536
|
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
|
|
10081
|
-
/* @__PURE__ */ jsxRuntime.
|
|
10082
|
-
/* @__PURE__ */ jsxRuntime.
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10537
|
+
/* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "sticky top-0 z-20", children: [
|
|
10538
|
+
/* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
10539
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
|
|
10540
|
+
"h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
|
|
10541
|
+
"border-r border-b border-border bg-sidebar",
|
|
10542
|
+
stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
|
|
10543
|
+
// Right shadow using Quantum token
|
|
10544
|
+
stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
|
|
10545
|
+
), children: "Supplier / Scope" }),
|
|
10546
|
+
weeks.map((week) => {
|
|
10547
|
+
const weekKey = getWeekKey(week.startDate);
|
|
10548
|
+
const weekComments = getWeekComments(weekKey);
|
|
10549
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10550
|
+
"th",
|
|
10551
|
+
{
|
|
10552
|
+
className: "h-14 px-2 text-left align-middle border-r border-b border-border last:border-r-0 min-w-[220px] bg-sidebar",
|
|
10553
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10554
|
+
CalibrationWeekHeader,
|
|
10555
|
+
{
|
|
10556
|
+
week,
|
|
10557
|
+
comments: weekComments,
|
|
10558
|
+
showCommentButton: true,
|
|
10559
|
+
availablePrefixes,
|
|
10560
|
+
onAddComment: (text, prefixId, prefixName) => handleAddWeekComment(weekKey, text, prefixId)
|
|
10561
|
+
}
|
|
10562
|
+
)
|
|
10563
|
+
},
|
|
10564
|
+
weekKey
|
|
10565
|
+
);
|
|
10566
|
+
})
|
|
10567
|
+
] }),
|
|
10568
|
+
/* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
10569
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
|
|
10570
|
+
"h-auto px-3 py-1.5 text-left align-middle",
|
|
10571
|
+
"border-r border-b border-border bg-muted/30",
|
|
10572
|
+
stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
|
|
10573
|
+
stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
|
|
10574
|
+
), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Summary" }) }),
|
|
10575
|
+
columnSummaryData.map((summary) => {
|
|
10576
|
+
const statusBg = summary.status === "complete" ? "bg-green-50/50 dark:bg-green-950/30" : summary.status === "critical" ? "bg-red-50/50 dark:bg-red-950/30" : "bg-muted/30";
|
|
10577
|
+
const statusText = summary.status === "complete" ? "text-green-700 dark:text-green-300" : summary.status === "critical" ? "text-red-700 dark:text-red-300" : "text-muted-foreground";
|
|
10578
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10579
|
+
"th",
|
|
10580
|
+
{
|
|
10581
|
+
className: cn(
|
|
10582
|
+
"h-auto px-2 py-1.5 text-left align-middle",
|
|
10583
|
+
"border-r border-b border-border last:border-r-0 min-w-[220px]",
|
|
10584
|
+
statusBg
|
|
10585
|
+
),
|
|
10586
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
10587
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
10588
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3", statusText) }),
|
|
10589
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-xs font-medium tabular-nums", statusText), children: [
|
|
10590
|
+
summary.primary?.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
10591
|
+
" t"
|
|
10592
|
+
] })
|
|
10593
|
+
] }),
|
|
10594
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
10595
|
+
summary.secondary?.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
10596
|
+
" t req"
|
|
10597
|
+
] })
|
|
10598
|
+
] })
|
|
10599
|
+
},
|
|
10600
|
+
summary.columnKey
|
|
10601
|
+
);
|
|
10602
|
+
})
|
|
10603
|
+
] })
|
|
10604
|
+
] }),
|
|
10111
10605
|
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: paginatedPrefixes.length > 0 ? paginatedPrefixes.map((prefix) => {
|
|
10112
10606
|
const sortedWeekKeys = weeks.map((w) => getWeekKey(w.startDate));
|
|
10113
10607
|
let hasDeficit = false;
|
|
@@ -10269,14 +10763,14 @@ function CommentDialog({
|
|
|
10269
10763
|
open,
|
|
10270
10764
|
onOpenChange
|
|
10271
10765
|
}) {
|
|
10272
|
-
const [selectedPrefixId, setSelectedPrefixId] =
|
|
10273
|
-
const [selectedWeekKey, setSelectedWeekKey] =
|
|
10274
|
-
const [commentText, setCommentText] =
|
|
10275
|
-
const currentWeek =
|
|
10766
|
+
const [selectedPrefixId, setSelectedPrefixId] = React27__namespace.useState("");
|
|
10767
|
+
const [selectedWeekKey, setSelectedWeekKey] = React27__namespace.useState("");
|
|
10768
|
+
const [commentText, setCommentText] = React27__namespace.useState("");
|
|
10769
|
+
const currentWeek = React27__namespace.useMemo(
|
|
10276
10770
|
() => weeks.find((w) => w.isCurrentWeek),
|
|
10277
10771
|
[weeks]
|
|
10278
10772
|
);
|
|
10279
|
-
|
|
10773
|
+
React27__namespace.useEffect(() => {
|
|
10280
10774
|
if (open) {
|
|
10281
10775
|
setSelectedPrefixId(prefixes[0]?.id ?? "");
|
|
10282
10776
|
setSelectedWeekKey(currentWeek ? getWeekKey(currentWeek.startDate) : weeks[0] ? getWeekKey(weeks[0].startDate) : "");
|
|
@@ -10606,35 +11100,39 @@ function groupDeliveriesByPrefixAndDay(deliveries) {
|
|
|
10606
11100
|
}
|
|
10607
11101
|
return grouped;
|
|
10608
11102
|
}
|
|
10609
|
-
function getCardStyles(state, hasRisk
|
|
11103
|
+
function getCardStyles(state, hasRisk) {
|
|
10610
11104
|
if (hasRisk) {
|
|
10611
11105
|
return {
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
|
|
11106
|
+
fill: statusCellFillClasses.risk.combined,
|
|
11107
|
+
titleColor: statusCellTextClasses.risk.title,
|
|
11108
|
+
subtitleColor: statusCellTextClasses.risk.subtitle,
|
|
11109
|
+
iconColor: statusCellTextClasses.risk.icon,
|
|
10615
11110
|
opacity: ""
|
|
10616
11111
|
};
|
|
10617
11112
|
}
|
|
10618
11113
|
switch (state) {
|
|
10619
11114
|
case "sent":
|
|
10620
11115
|
return {
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
11116
|
+
fill: statusCellFillClasses.shipped.combined,
|
|
11117
|
+
titleColor: statusCellTextClasses.shipped.title,
|
|
11118
|
+
subtitleColor: statusCellTextClasses.shipped.subtitle,
|
|
11119
|
+
iconColor: statusCellTextClasses.shipped.icon,
|
|
11120
|
+
opacity: "opacity-75"
|
|
10625
11121
|
};
|
|
10626
11122
|
case "ready":
|
|
10627
11123
|
return {
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
11124
|
+
fill: statusCellFillClasses.ready.combined,
|
|
11125
|
+
titleColor: statusCellTextClasses.ready.title,
|
|
11126
|
+
subtitleColor: statusCellTextClasses.ready.subtitle,
|
|
11127
|
+
iconColor: statusCellTextClasses.ready.icon,
|
|
10631
11128
|
opacity: ""
|
|
10632
11129
|
};
|
|
10633
11130
|
default:
|
|
10634
11131
|
return {
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
11132
|
+
fill: statusCellFillClasses.normal.combined,
|
|
11133
|
+
titleColor: statusCellTextClasses.normal.title,
|
|
11134
|
+
subtitleColor: statusCellTextClasses.normal.subtitle,
|
|
11135
|
+
iconColor: statusCellTextClasses.normal.icon,
|
|
10638
11136
|
opacity: ""
|
|
10639
11137
|
};
|
|
10640
11138
|
}
|
|
@@ -10645,10 +11143,9 @@ function DeliveryBadge({
|
|
|
10645
11143
|
onCommentClick,
|
|
10646
11144
|
className
|
|
10647
11145
|
}) {
|
|
10648
|
-
const [isHovered, setIsHovered] = React29__namespace.useState(false);
|
|
10649
11146
|
const hasComments = delivery.comments.length > 0;
|
|
10650
11147
|
const visualState = getDeliveryVisualState(delivery);
|
|
10651
|
-
const styles = getCardStyles(visualState, delivery.hasProductionRisk ?? false
|
|
11148
|
+
const styles = getCardStyles(visualState, delivery.hasProductionRisk ?? false);
|
|
10652
11149
|
const projectName = delivery.destination || delivery.label;
|
|
10653
11150
|
const handleClick = (e) => {
|
|
10654
11151
|
e.stopPropagation();
|
|
@@ -10671,16 +11168,14 @@ function DeliveryBadge({
|
|
|
10671
11168
|
className: cn(
|
|
10672
11169
|
// Position relative for comment button
|
|
10673
11170
|
"relative",
|
|
10674
|
-
// Full-width in cell,
|
|
10675
|
-
"w-full rounded-
|
|
11171
|
+
// Full-width in cell, small radius (matching planning cards)
|
|
11172
|
+
"w-full rounded-lg",
|
|
10676
11173
|
// Compact sizing - min-h-[72px], p-4 (j3m.spacing.m)
|
|
10677
11174
|
"min-h-[72px] p-4",
|
|
10678
|
-
//
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
//
|
|
10682
|
-
styles.stroke,
|
|
10683
|
-
// Opacity for shipped state only
|
|
11175
|
+
// FULL-CARD STATUS FILL - uses shared calibration/planning tokens
|
|
11176
|
+
// This is the key change: status fill on outermost container
|
|
11177
|
+
styles.fill,
|
|
11178
|
+
// Opacity for shipped state
|
|
10684
11179
|
styles.opacity,
|
|
10685
11180
|
// Interactive states (disabled hover lift for shipped)
|
|
10686
11181
|
"transition-all duration-200 ease-out",
|
|
@@ -10699,6 +11194,8 @@ function DeliveryBadge({
|
|
|
10699
11194
|
// 44px touch target for accessibility
|
|
10700
11195
|
"h-11 w-11",
|
|
10701
11196
|
"rounded-full",
|
|
11197
|
+
// Subtle background for visibility on colored fills
|
|
11198
|
+
"bg-background/50 hover:bg-background/80",
|
|
10702
11199
|
hasComments && "text-primary"
|
|
10703
11200
|
),
|
|
10704
11201
|
onClick: handleCommentClick,
|
|
@@ -10721,8 +11218,6 @@ function DeliveryBadge({
|
|
|
10721
11218
|
type: "button",
|
|
10722
11219
|
onClick: handleClick,
|
|
10723
11220
|
onKeyDown: handleKeyDown,
|
|
10724
|
-
onMouseEnter: () => setIsHovered(true),
|
|
10725
|
-
onMouseLeave: () => setIsHovered(false),
|
|
10726
11221
|
className: cn(
|
|
10727
11222
|
// Full width, no background (inherits from parent)
|
|
10728
11223
|
"w-full bg-transparent text-left",
|
|
@@ -10740,14 +11235,15 @@ function DeliveryBadge({
|
|
|
10740
11235
|
"text-sm font-semibold leading-tight line-clamp-2",
|
|
10741
11236
|
styles.titleColor
|
|
10742
11237
|
), children: projectName }),
|
|
10743
|
-
delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4
|
|
11238
|
+
delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: cn("h-4 w-4 shrink-0 mt-0.5", styles.iconColor) })
|
|
10744
11239
|
] }),
|
|
10745
11240
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
|
|
10746
11241
|
visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10747
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5
|
|
10748
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium
|
|
11242
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
|
|
11243
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-medium uppercase tracking-wide", styles.subtitleColor), children: "Shipped" })
|
|
10749
11244
|
] }),
|
|
10750
|
-
visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold
|
|
11245
|
+
visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "Ready" }),
|
|
11246
|
+
delivery.hasProductionRisk && visualState !== "sent" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "At Risk" })
|
|
10751
11247
|
] })
|
|
10752
11248
|
]
|
|
10753
11249
|
}
|
|
@@ -10821,7 +11317,7 @@ function WeeklyLoadingView({
|
|
|
10821
11317
|
showNavigation = true,
|
|
10822
11318
|
className
|
|
10823
11319
|
}) {
|
|
10824
|
-
const [shippedOpenState, setShippedOpenState] =
|
|
11320
|
+
const [shippedOpenState, setShippedOpenState] = React27__namespace.useState({
|
|
10825
11321
|
1: false,
|
|
10826
11322
|
// Monday
|
|
10827
11323
|
2: false,
|
|
@@ -10839,7 +11335,7 @@ function WeeklyLoadingView({
|
|
|
10839
11335
|
[dayOfWeek]: !prev[dayOfWeek]
|
|
10840
11336
|
}));
|
|
10841
11337
|
};
|
|
10842
|
-
const weekDays =
|
|
11338
|
+
const weekDays = React27__namespace.useMemo(() => {
|
|
10843
11339
|
const days = [];
|
|
10844
11340
|
for (let i = 0; i < 5; i++) {
|
|
10845
11341
|
const date = dateFns.addDays(week.startDate, i);
|
|
@@ -10851,7 +11347,7 @@ function WeeklyLoadingView({
|
|
|
10851
11347
|
}
|
|
10852
11348
|
return days;
|
|
10853
11349
|
}, [week.startDate]);
|
|
10854
|
-
const deliveriesByDay =
|
|
11350
|
+
const deliveriesByDay = React27__namespace.useMemo(() => {
|
|
10855
11351
|
const grouped = /* @__PURE__ */ new Map();
|
|
10856
11352
|
for (let i = 1; i <= 5; i++) {
|
|
10857
11353
|
grouped.set(i, { pending: [], shipped: [] });
|
|
@@ -10871,6 +11367,19 @@ function WeeklyLoadingView({
|
|
|
10871
11367
|
}, [deliveries]);
|
|
10872
11368
|
const totalPendingDeliveries = deliveries.filter((d) => !isShippedDelivery(d)).length;
|
|
10873
11369
|
const totalShippedDeliveries = deliveries.filter((d) => isShippedDelivery(d)).length;
|
|
11370
|
+
const daySummaryData = React27__namespace.useMemo(() => {
|
|
11371
|
+
const summaries = /* @__PURE__ */ new Map();
|
|
11372
|
+
for (let i = 1; i <= 5; i++) {
|
|
11373
|
+
const dayData = deliveriesByDay.get(i) ?? { pending: [], shipped: [] };
|
|
11374
|
+
const allDayDeliveries = [...dayData.pending, ...dayData.shipped];
|
|
11375
|
+
summaries.set(i, {
|
|
11376
|
+
deliveries: allDayDeliveries.length,
|
|
11377
|
+
tonsRequired: allDayDeliveries.reduce((sum, d) => sum + (d.totalTons ?? 0), 0),
|
|
11378
|
+
tonsProduced: allDayDeliveries.reduce((sum, d) => sum + (d.producedTons ?? 0), 0)
|
|
11379
|
+
});
|
|
11380
|
+
}
|
|
11381
|
+
return summaries;
|
|
11382
|
+
}, [deliveriesByDay]);
|
|
10874
11383
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [
|
|
10875
11384
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between", children: [
|
|
10876
11385
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
@@ -10955,6 +11464,42 @@ function WeeklyLoadingView({
|
|
|
10955
11464
|
},
|
|
10956
11465
|
dayOfWeek
|
|
10957
11466
|
)) }),
|
|
11467
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 border-b border-border", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
|
|
11468
|
+
const summary = daySummaryData.get(dayOfWeek) ?? { deliveries: 0, tonsRequired: 0, tonsProduced: 0 };
|
|
11469
|
+
const productionComplete = summary.tonsRequired > 0 && summary.tonsProduced >= summary.tonsRequired;
|
|
11470
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11471
|
+
"div",
|
|
11472
|
+
{
|
|
11473
|
+
className: cn(
|
|
11474
|
+
"flex flex-col gap-0.5 py-1.5 px-2",
|
|
11475
|
+
productionComplete ? "bg-green-50/50 dark:bg-green-950/30" : "bg-muted/20",
|
|
11476
|
+
dayIsToday && "bg-primary/5"
|
|
11477
|
+
),
|
|
11478
|
+
children: [
|
|
11479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
11480
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3 w-3 text-muted-foreground" }),
|
|
11481
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium tabular-nums text-muted-foreground", children: summary.deliveries })
|
|
11482
|
+
] }),
|
|
11483
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
11484
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn(
|
|
11485
|
+
"h-3 w-3",
|
|
11486
|
+
productionComplete ? "text-green-600 dark:text-green-400" : "text-muted-foreground"
|
|
11487
|
+
) }),
|
|
11488
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
|
|
11489
|
+
"text-[10px] tabular-nums",
|
|
11490
|
+
productionComplete ? "text-green-700 dark:text-green-300" : "text-muted-foreground"
|
|
11491
|
+
), children: [
|
|
11492
|
+
summary.tonsProduced.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
11493
|
+
"/",
|
|
11494
|
+
summary.tonsRequired.toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
11495
|
+
" t"
|
|
11496
|
+
] })
|
|
11497
|
+
] })
|
|
11498
|
+
]
|
|
11499
|
+
},
|
|
11500
|
+
dayOfWeek
|
|
11501
|
+
);
|
|
11502
|
+
}) }),
|
|
10958
11503
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
|
|
10959
11504
|
const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
|
|
10960
11505
|
const hasPending = dayData.pending.length > 0;
|
|
@@ -11176,7 +11721,7 @@ function DeliveryTimeline({ timelineState }) {
|
|
|
11176
11721
|
const state = getStateForStep(step.id);
|
|
11177
11722
|
const styles = getStepStyles(state);
|
|
11178
11723
|
const isLast = index === TIMELINE_STEPS.length - 1;
|
|
11179
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11724
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React27__namespace.Fragment, { children: [
|
|
11180
11725
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
11181
11726
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11182
11727
|
"div",
|
|
@@ -11311,7 +11856,7 @@ function AddCommentDialog({
|
|
|
11311
11856
|
weekId,
|
|
11312
11857
|
onAddComment
|
|
11313
11858
|
}) {
|
|
11314
|
-
const [commentText, setCommentText] =
|
|
11859
|
+
const [commentText, setCommentText] = React27__namespace.useState("");
|
|
11315
11860
|
const handleSubmit = () => {
|
|
11316
11861
|
if (commentText.trim() && onAddComment) {
|
|
11317
11862
|
onAddComment({
|
|
@@ -11336,7 +11881,7 @@ function AddCommentDialog({
|
|
|
11336
11881
|
handleSubmit();
|
|
11337
11882
|
}
|
|
11338
11883
|
};
|
|
11339
|
-
|
|
11884
|
+
React27__namespace.useEffect(() => {
|
|
11340
11885
|
if (!open) {
|
|
11341
11886
|
setCommentText("");
|
|
11342
11887
|
}
|
|
@@ -11399,8 +11944,8 @@ function CommentsSection({
|
|
|
11399
11944
|
weekId,
|
|
11400
11945
|
onAddComment
|
|
11401
11946
|
}) {
|
|
11402
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
11403
|
-
const [addDialogOpen, setAddDialogOpen] =
|
|
11947
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
|
|
11948
|
+
const [addDialogOpen, setAddDialogOpen] = React27__namespace.useState(false);
|
|
11404
11949
|
const formatDate3 = (date) => {
|
|
11405
11950
|
return new Intl.DateTimeFormat("en-US", {
|
|
11406
11951
|
month: "short",
|
|
@@ -11474,7 +12019,7 @@ function DeliveryDetailPage({
|
|
|
11474
12019
|
onConfirmLoad
|
|
11475
12020
|
}) {
|
|
11476
12021
|
const timelineState = getTimelineState(delivery);
|
|
11477
|
-
const elementsByStatus =
|
|
12022
|
+
const elementsByStatus = React27__namespace.useMemo(() => {
|
|
11478
12023
|
const loaded = delivery.elements.filter((e) => e.status === "loaded");
|
|
11479
12024
|
const missing = delivery.elements.filter((e) => e.status === "missing");
|
|
11480
12025
|
const moved = delivery.elements.filter((e) => e.status === "moved");
|
|
@@ -11661,11 +12206,11 @@ function SupplierWeeklyLoading({
|
|
|
11661
12206
|
bordered = true,
|
|
11662
12207
|
className
|
|
11663
12208
|
}) {
|
|
11664
|
-
const [selectedDelivery, setSelectedDelivery] =
|
|
11665
|
-
const [sheetOpen, setSheetOpen] =
|
|
11666
|
-
const [commentDelivery, setCommentDelivery] =
|
|
11667
|
-
const [commentDialogOpen, setCommentDialogOpen] =
|
|
11668
|
-
const [commentText, setCommentText] =
|
|
12209
|
+
const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
|
|
12210
|
+
const [sheetOpen, setSheetOpen] = React27__namespace.useState(false);
|
|
12211
|
+
const [commentDelivery, setCommentDelivery] = React27__namespace.useState(null);
|
|
12212
|
+
const [commentDialogOpen, setCommentDialogOpen] = React27__namespace.useState(false);
|
|
12213
|
+
const [commentText, setCommentText] = React27__namespace.useState("");
|
|
11669
12214
|
const handleDeliveryClick = (delivery) => {
|
|
11670
12215
|
setSelectedDelivery(delivery);
|
|
11671
12216
|
setSheetOpen(true);
|
|
@@ -11708,31 +12253,74 @@ function SupplierWeeklyLoading({
|
|
|
11708
12253
|
handleCommentSubmit();
|
|
11709
12254
|
}
|
|
11710
12255
|
};
|
|
12256
|
+
const insightMetrics = React27__namespace.useMemo(() => {
|
|
12257
|
+
const totalDeliveries = deliveries.length;
|
|
12258
|
+
const readyDeliveries = deliveries.filter((d) => d.isReadyToUnload).length;
|
|
12259
|
+
deliveries.filter(
|
|
12260
|
+
(d) => d.status === "shipped" || d.status === "delivered"
|
|
12261
|
+
).length;
|
|
12262
|
+
const totalTonsRequired = deliveries.reduce((sum, d) => sum + (d.totalTons ?? 0), 0);
|
|
12263
|
+
const producedTons = deliveries.reduce((sum, d) => sum + (d.producedTons ?? 0), 0);
|
|
12264
|
+
return [
|
|
12265
|
+
{
|
|
12266
|
+
key: "deliveries",
|
|
12267
|
+
label: "deliveries",
|
|
12268
|
+
value: totalDeliveries,
|
|
12269
|
+
icon: "truck",
|
|
12270
|
+
status: "normal"
|
|
12271
|
+
},
|
|
12272
|
+
{
|
|
12273
|
+
key: "ready",
|
|
12274
|
+
label: "ready",
|
|
12275
|
+
value: readyDeliveries,
|
|
12276
|
+
icon: "check",
|
|
12277
|
+
status: readyDeliveries > 0 ? "success" : "normal"
|
|
12278
|
+
},
|
|
12279
|
+
{
|
|
12280
|
+
key: "required",
|
|
12281
|
+
label: "tons required",
|
|
12282
|
+
value: totalTonsRequired,
|
|
12283
|
+
unit: "t",
|
|
12284
|
+
icon: "factory",
|
|
12285
|
+
status: "normal"
|
|
12286
|
+
},
|
|
12287
|
+
{
|
|
12288
|
+
key: "produced",
|
|
12289
|
+
label: "tons produced",
|
|
12290
|
+
value: producedTons,
|
|
12291
|
+
unit: "t",
|
|
12292
|
+
icon: "factory",
|
|
12293
|
+
status: producedTons >= totalTonsRequired ? "success" : producedTons >= totalTonsRequired * 0.5 ? "normal" : "warning"
|
|
12294
|
+
}
|
|
12295
|
+
];
|
|
12296
|
+
}, [deliveries]);
|
|
11711
12297
|
const Wrapper = bordered ? Card : "div";
|
|
11712
12298
|
const Content14 = bordered ? CardContent : "div";
|
|
11713
12299
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11714
|
-
/* @__PURE__ */ jsxRuntime.
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
12300
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-0", className), children: [
|
|
12301
|
+
/* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics, className: "rounded-t-lg border border-b-0" }),
|
|
12302
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12303
|
+
Wrapper,
|
|
12304
|
+
{
|
|
12305
|
+
className: cn(
|
|
12306
|
+
"flex flex-col overflow-hidden rounded-t-none",
|
|
12307
|
+
// Removed fixed min-height - content-driven sizing
|
|
12308
|
+
!bordered && "border border-border bg-card rounded-lg rounded-t-none"
|
|
12309
|
+
),
|
|
12310
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Content14, { className: cn("flex-1 overflow-hidden p-0", !bordered && ""), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12311
|
+
WeeklyLoadingView,
|
|
12312
|
+
{
|
|
12313
|
+
week,
|
|
12314
|
+
deliveries,
|
|
12315
|
+
onDeliveryClick: handleDeliveryClick,
|
|
12316
|
+
onDeliveryCommentClick: handleDeliveryCommentClick,
|
|
12317
|
+
onWeekChange,
|
|
12318
|
+
showNavigation
|
|
12319
|
+
}
|
|
12320
|
+
) })
|
|
12321
|
+
}
|
|
12322
|
+
)
|
|
12323
|
+
] }),
|
|
11736
12324
|
/* @__PURE__ */ jsxRuntime.jsx(Sheet, { open: sheetOpen, onOpenChange: (open) => !open && handleSheetClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11737
12325
|
SheetContent,
|
|
11738
12326
|
{
|
|
@@ -11809,35 +12397,39 @@ function SupplierWeeklyLoading({
|
|
|
11809
12397
|
] }) })
|
|
11810
12398
|
] });
|
|
11811
12399
|
}
|
|
11812
|
-
function getCardStyles2(state, hasRisk
|
|
12400
|
+
function getCardStyles2(state, hasRisk) {
|
|
11813
12401
|
if (hasRisk) {
|
|
11814
12402
|
return {
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
12403
|
+
fill: statusCellFillClasses.risk.combined,
|
|
12404
|
+
titleColor: statusCellTextClasses.risk.title,
|
|
12405
|
+
subtitleColor: statusCellTextClasses.risk.subtitle,
|
|
12406
|
+
iconColor: statusCellTextClasses.risk.icon,
|
|
11818
12407
|
opacity: ""
|
|
11819
12408
|
};
|
|
11820
12409
|
}
|
|
11821
12410
|
switch (state) {
|
|
11822
12411
|
case "sent":
|
|
11823
12412
|
return {
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
12413
|
+
fill: statusCellFillClasses.shipped.combined,
|
|
12414
|
+
titleColor: statusCellTextClasses.shipped.title,
|
|
12415
|
+
subtitleColor: statusCellTextClasses.shipped.subtitle,
|
|
12416
|
+
iconColor: statusCellTextClasses.shipped.icon,
|
|
12417
|
+
opacity: "opacity-75"
|
|
11828
12418
|
};
|
|
11829
12419
|
case "ready":
|
|
11830
12420
|
return {
|
|
11831
|
-
|
|
11832
|
-
|
|
11833
|
-
|
|
12421
|
+
fill: statusCellFillClasses.ready.combined,
|
|
12422
|
+
titleColor: statusCellTextClasses.ready.title,
|
|
12423
|
+
subtitleColor: statusCellTextClasses.ready.subtitle,
|
|
12424
|
+
iconColor: statusCellTextClasses.ready.icon,
|
|
11834
12425
|
opacity: ""
|
|
11835
12426
|
};
|
|
11836
12427
|
default:
|
|
11837
12428
|
return {
|
|
11838
|
-
|
|
11839
|
-
|
|
11840
|
-
|
|
12429
|
+
fill: statusCellFillClasses.normal.combined,
|
|
12430
|
+
titleColor: statusCellTextClasses.normal.title,
|
|
12431
|
+
subtitleColor: statusCellTextClasses.normal.subtitle,
|
|
12432
|
+
iconColor: statusCellTextClasses.normal.icon,
|
|
11841
12433
|
opacity: ""
|
|
11842
12434
|
};
|
|
11843
12435
|
}
|
|
@@ -11847,10 +12439,9 @@ function DeliveryCard({
|
|
|
11847
12439
|
onTap,
|
|
11848
12440
|
className
|
|
11849
12441
|
}) {
|
|
11850
|
-
const [isHovered, setIsHovered] = React29__namespace.useState(false);
|
|
11851
12442
|
const hasComments = delivery.comments.length > 0;
|
|
11852
12443
|
const visualState = getDeliveryVisualState(delivery);
|
|
11853
|
-
const styles = getCardStyles2(visualState, delivery.hasProductionRisk ?? false
|
|
12444
|
+
const styles = getCardStyles2(visualState, delivery.hasProductionRisk ?? false);
|
|
11854
12445
|
const projectName = delivery.destination || delivery.label;
|
|
11855
12446
|
const handleClick = () => {
|
|
11856
12447
|
onTap?.();
|
|
@@ -11868,19 +12459,15 @@ function DeliveryCard({
|
|
|
11868
12459
|
tabIndex: 0,
|
|
11869
12460
|
onClick: handleClick,
|
|
11870
12461
|
onKeyDown: handleKeyDown,
|
|
11871
|
-
onMouseEnter: () => setIsHovered(true),
|
|
11872
|
-
onMouseLeave: () => setIsHovered(false),
|
|
11873
12462
|
className: cn(
|
|
11874
|
-
// Full-width,
|
|
11875
|
-
"w-full rounded-
|
|
12463
|
+
// Full-width, small radius (matching planning table cards)
|
|
12464
|
+
"w-full rounded-lg",
|
|
11876
12465
|
// Touch-friendly sizing - 56px min-height for iPad
|
|
11877
12466
|
"min-h-[56px] p-4",
|
|
11878
|
-
//
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
//
|
|
11882
|
-
styles.stroke,
|
|
11883
|
-
// Opacity for shipped state only
|
|
12467
|
+
// FULL-CARD STATUS FILL - uses shared calibration/planning tokens
|
|
12468
|
+
// This is the key change: status fill on outermost container
|
|
12469
|
+
styles.fill,
|
|
12470
|
+
// Opacity for shipped state
|
|
11884
12471
|
styles.opacity,
|
|
11885
12472
|
// Hover/tap state - lift effect (disabled for shipped)
|
|
11886
12473
|
"cursor-pointer transition-all duration-200 ease-out",
|
|
@@ -11897,21 +12484,22 @@ function DeliveryCard({
|
|
|
11897
12484
|
"text-sm font-semibold truncate",
|
|
11898
12485
|
styles.titleColor
|
|
11899
12486
|
), children: projectName }),
|
|
11900
|
-
delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4
|
|
11901
|
-
hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
|
|
12487
|
+
delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: cn("h-4 w-4 shrink-0", styles.iconColor) }),
|
|
12488
|
+
hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0 p-0.5 rounded bg-background/50", children: [
|
|
11902
12489
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
11903
12490
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
|
|
11904
12491
|
] })
|
|
11905
12492
|
] }),
|
|
11906
12493
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
11907
12494
|
visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11908
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5
|
|
11909
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium
|
|
12495
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
|
|
12496
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-medium uppercase tracking-wide", styles.subtitleColor), children: "Shipped" })
|
|
11910
12497
|
] }),
|
|
11911
|
-
visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold
|
|
12498
|
+
visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "Ready" }),
|
|
12499
|
+
delivery.hasProductionRisk && visualState !== "sent" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "At Risk" })
|
|
11912
12500
|
] })
|
|
11913
12501
|
] }),
|
|
11914
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4
|
|
12502
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4 shrink-0", styles.iconColor) })
|
|
11915
12503
|
] })
|
|
11916
12504
|
}
|
|
11917
12505
|
);
|
|
@@ -11979,7 +12567,7 @@ var BADGE_VARIANT_LABELS = {
|
|
|
11979
12567
|
colored: "Colored",
|
|
11980
12568
|
mixed: "Mixed"
|
|
11981
12569
|
};
|
|
11982
|
-
var CalendarContext =
|
|
12570
|
+
var CalendarContext = React27__namespace.createContext(null);
|
|
11983
12571
|
function EventCalendarProvider({
|
|
11984
12572
|
children,
|
|
11985
12573
|
events: initialEvents = [],
|
|
@@ -11994,38 +12582,38 @@ function EventCalendarProvider({
|
|
|
11994
12582
|
onEventUpdate,
|
|
11995
12583
|
onEventDelete
|
|
11996
12584
|
}) {
|
|
11997
|
-
const [selectedDate, setSelectedDate] =
|
|
11998
|
-
const [selectedUserId, setSelectedUserId] =
|
|
11999
|
-
const [events, setEventsState] =
|
|
12000
|
-
const [users] =
|
|
12001
|
-
const [badgeVariant, setBadgeVariant] =
|
|
12002
|
-
const [view, setView] =
|
|
12003
|
-
const [workingHours, setWorkingHours] =
|
|
12004
|
-
const [visibleHours, setVisibleHours] =
|
|
12005
|
-
|
|
12585
|
+
const [selectedDate, setSelectedDate] = React27__namespace.useState(defaultDate);
|
|
12586
|
+
const [selectedUserId, setSelectedUserId] = React27__namespace.useState(defaultUserId);
|
|
12587
|
+
const [events, setEventsState] = React27__namespace.useState(initialEvents);
|
|
12588
|
+
const [users] = React27__namespace.useState(initialUsers);
|
|
12589
|
+
const [badgeVariant, setBadgeVariant] = React27__namespace.useState(defaultBadgeVariant);
|
|
12590
|
+
const [view, setView] = React27__namespace.useState(defaultView);
|
|
12591
|
+
const [workingHours, setWorkingHours] = React27__namespace.useState(defaultWorkingHours);
|
|
12592
|
+
const [visibleHours, setVisibleHours] = React27__namespace.useState(defaultVisibleHours);
|
|
12593
|
+
React27__namespace.useEffect(() => {
|
|
12006
12594
|
setEventsState(initialEvents);
|
|
12007
12595
|
}, [initialEvents]);
|
|
12008
|
-
const setEvents =
|
|
12596
|
+
const setEvents = React27__namespace.useCallback((newEvents) => {
|
|
12009
12597
|
setEventsState(newEvents);
|
|
12010
12598
|
}, []);
|
|
12011
|
-
const addEvent =
|
|
12599
|
+
const addEvent = React27__namespace.useCallback((event) => {
|
|
12012
12600
|
setEventsState((prev) => [...prev, event]);
|
|
12013
12601
|
onEventAdd?.(event);
|
|
12014
12602
|
}, [onEventAdd]);
|
|
12015
|
-
const updateEvent =
|
|
12603
|
+
const updateEvent = React27__namespace.useCallback((event) => {
|
|
12016
12604
|
setEventsState(
|
|
12017
12605
|
(prev) => prev.map((e) => e.id === event.id ? event : e)
|
|
12018
12606
|
);
|
|
12019
12607
|
onEventUpdate?.(event);
|
|
12020
12608
|
}, [onEventUpdate]);
|
|
12021
|
-
const deleteEvent =
|
|
12609
|
+
const deleteEvent = React27__namespace.useCallback((eventId) => {
|
|
12022
12610
|
setEventsState((prev) => prev.filter((e) => e.id !== eventId));
|
|
12023
12611
|
onEventDelete?.(eventId);
|
|
12024
12612
|
}, [onEventDelete]);
|
|
12025
|
-
const goToToday =
|
|
12613
|
+
const goToToday = React27__namespace.useCallback(() => {
|
|
12026
12614
|
setSelectedDate(/* @__PURE__ */ new Date());
|
|
12027
12615
|
}, []);
|
|
12028
|
-
const goToPrevious =
|
|
12616
|
+
const goToPrevious = React27__namespace.useCallback(() => {
|
|
12029
12617
|
setSelectedDate((current) => {
|
|
12030
12618
|
switch (view) {
|
|
12031
12619
|
case "day":
|
|
@@ -12043,7 +12631,7 @@ function EventCalendarProvider({
|
|
|
12043
12631
|
}
|
|
12044
12632
|
});
|
|
12045
12633
|
}, [view]);
|
|
12046
|
-
const goToNext =
|
|
12634
|
+
const goToNext = React27__namespace.useCallback(() => {
|
|
12047
12635
|
setSelectedDate((current) => {
|
|
12048
12636
|
switch (view) {
|
|
12049
12637
|
case "day":
|
|
@@ -12061,7 +12649,7 @@ function EventCalendarProvider({
|
|
|
12061
12649
|
}
|
|
12062
12650
|
});
|
|
12063
12651
|
}, [view]);
|
|
12064
|
-
const contextValue =
|
|
12652
|
+
const contextValue = React27__namespace.useMemo(
|
|
12065
12653
|
() => ({
|
|
12066
12654
|
// State
|
|
12067
12655
|
selectedDate,
|
|
@@ -12108,7 +12696,7 @@ function EventCalendarProvider({
|
|
|
12108
12696
|
return /* @__PURE__ */ jsxRuntime.jsx(CalendarContext.Provider, { value: contextValue, children });
|
|
12109
12697
|
}
|
|
12110
12698
|
function useEventCalendar() {
|
|
12111
|
-
const context =
|
|
12699
|
+
const context = React27__namespace.useContext(CalendarContext);
|
|
12112
12700
|
if (!context) {
|
|
12113
12701
|
throw new Error("useEventCalendar must be used within an EventCalendarProvider");
|
|
12114
12702
|
}
|
|
@@ -12116,14 +12704,14 @@ function useEventCalendar() {
|
|
|
12116
12704
|
}
|
|
12117
12705
|
function useFilteredEvents() {
|
|
12118
12706
|
const { events, selectedUserId } = useEventCalendar();
|
|
12119
|
-
return
|
|
12707
|
+
return React27__namespace.useMemo(() => {
|
|
12120
12708
|
if (!selectedUserId) return events;
|
|
12121
12709
|
return events.filter((event) => event.user.id === selectedUserId);
|
|
12122
12710
|
}, [events, selectedUserId]);
|
|
12123
12711
|
}
|
|
12124
12712
|
function useEventsInRange(startDate, endDate) {
|
|
12125
12713
|
const filteredEvents = useFilteredEvents();
|
|
12126
|
-
return
|
|
12714
|
+
return React27__namespace.useMemo(() => {
|
|
12127
12715
|
return filteredEvents.filter((event) => {
|
|
12128
12716
|
const eventStart = new Date(event.startDate);
|
|
12129
12717
|
const eventEnd = new Date(event.endDate);
|
|
@@ -12681,8 +13269,8 @@ function MoreEvents({ count, onClick, className }) {
|
|
|
12681
13269
|
);
|
|
12682
13270
|
}
|
|
12683
13271
|
function TimeIndicator({ className }) {
|
|
12684
|
-
const [now, setNow] =
|
|
12685
|
-
|
|
13272
|
+
const [now, setNow] = React27__namespace.useState(/* @__PURE__ */ new Date());
|
|
13273
|
+
React27__namespace.useEffect(() => {
|
|
12686
13274
|
const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
|
|
12687
13275
|
return () => clearInterval(interval);
|
|
12688
13276
|
}, []);
|
|
@@ -12719,24 +13307,24 @@ function DateBadge({ date, className }) {
|
|
|
12719
13307
|
}
|
|
12720
13308
|
);
|
|
12721
13309
|
}
|
|
12722
|
-
var DragContext =
|
|
13310
|
+
var DragContext = React27__namespace.createContext(null);
|
|
12723
13311
|
function DragProvider({
|
|
12724
13312
|
children,
|
|
12725
13313
|
snapMinutes = 15,
|
|
12726
13314
|
onDragStart,
|
|
12727
13315
|
onDragEnd
|
|
12728
13316
|
}) {
|
|
12729
|
-
const [draggedEvent, setDraggedEventState] =
|
|
12730
|
-
const [isDragging, setIsDragging] =
|
|
13317
|
+
const [draggedEvent, setDraggedEventState] = React27__namespace.useState(null);
|
|
13318
|
+
const [isDragging, setIsDragging] = React27__namespace.useState(false);
|
|
12731
13319
|
const { updateEvent } = useEventCalendar();
|
|
12732
|
-
const setDraggedEvent =
|
|
13320
|
+
const setDraggedEvent = React27__namespace.useCallback((event) => {
|
|
12733
13321
|
setDraggedEventState(event);
|
|
12734
13322
|
setIsDragging(!!event);
|
|
12735
13323
|
if (event) {
|
|
12736
13324
|
onDragStart?.(event);
|
|
12737
13325
|
}
|
|
12738
13326
|
}, [onDragStart]);
|
|
12739
|
-
const handleDrop =
|
|
13327
|
+
const handleDrop = React27__namespace.useCallback((newStartDate) => {
|
|
12740
13328
|
if (!draggedEvent) return;
|
|
12741
13329
|
const snappedDate = snapToInterval(newStartDate, snapMinutes);
|
|
12742
13330
|
const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
|
|
@@ -12749,7 +13337,7 @@ function DragProvider({
|
|
|
12749
13337
|
onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
|
|
12750
13338
|
setDraggedEvent(null);
|
|
12751
13339
|
}, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
|
|
12752
|
-
const contextValue =
|
|
13340
|
+
const contextValue = React27__namespace.useMemo(
|
|
12753
13341
|
() => ({
|
|
12754
13342
|
draggedEvent,
|
|
12755
13343
|
setDraggedEvent,
|
|
@@ -12760,7 +13348,7 @@ function DragProvider({
|
|
|
12760
13348
|
return /* @__PURE__ */ jsxRuntime.jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DragDropHandler, { onDrop: handleDrop, children }) });
|
|
12761
13349
|
}
|
|
12762
13350
|
function useDrag() {
|
|
12763
|
-
const context =
|
|
13351
|
+
const context = React27__namespace.useContext(DragContext);
|
|
12764
13352
|
if (!context) {
|
|
12765
13353
|
throw new Error("useDrag must be used within a DragProvider");
|
|
12766
13354
|
}
|
|
@@ -12805,7 +13393,7 @@ function DroppableZone({
|
|
|
12805
13393
|
}) {
|
|
12806
13394
|
const { draggedEvent, setDraggedEvent } = useDrag();
|
|
12807
13395
|
const { updateEvent } = useEventCalendar();
|
|
12808
|
-
const [isOver, setIsOver] =
|
|
13396
|
+
const [isOver, setIsOver] = React27__namespace.useState(false);
|
|
12809
13397
|
const handleDragOver = (e) => {
|
|
12810
13398
|
e.preventDefault();
|
|
12811
13399
|
e.dataTransfer.dropEffect = "move";
|
|
@@ -12843,23 +13431,23 @@ function DroppableZone({
|
|
|
12843
13431
|
function useDroppable({ date, hour, minute = 0, onDrop }) {
|
|
12844
13432
|
const { draggedEvent, setDraggedEvent } = useDrag();
|
|
12845
13433
|
const { updateEvent } = useEventCalendar();
|
|
12846
|
-
const [isOver, setIsOver] =
|
|
12847
|
-
const dropTargetDate =
|
|
13434
|
+
const [isOver, setIsOver] = React27__namespace.useState(false);
|
|
13435
|
+
const dropTargetDate = React27__namespace.useMemo(() => {
|
|
12848
13436
|
const targetDate = new Date(date);
|
|
12849
13437
|
if (hour !== void 0) {
|
|
12850
13438
|
targetDate.setHours(hour, minute, 0, 0);
|
|
12851
13439
|
}
|
|
12852
13440
|
return targetDate;
|
|
12853
13441
|
}, [date, hour, minute]);
|
|
12854
|
-
const handleDragOver =
|
|
13442
|
+
const handleDragOver = React27__namespace.useCallback((e) => {
|
|
12855
13443
|
e.preventDefault();
|
|
12856
13444
|
e.dataTransfer.dropEffect = "move";
|
|
12857
13445
|
if (!isOver) setIsOver(true);
|
|
12858
13446
|
}, [isOver]);
|
|
12859
|
-
const handleDragLeave =
|
|
13447
|
+
const handleDragLeave = React27__namespace.useCallback(() => {
|
|
12860
13448
|
setIsOver(false);
|
|
12861
13449
|
}, []);
|
|
12862
|
-
const handleDrop =
|
|
13450
|
+
const handleDrop = React27__namespace.useCallback((e) => {
|
|
12863
13451
|
e.preventDefault();
|
|
12864
13452
|
setIsOver(false);
|
|
12865
13453
|
if (!draggedEvent) return;
|
|
@@ -12886,13 +13474,13 @@ function useDroppable({ date, hour, minute = 0, onDrop }) {
|
|
|
12886
13474
|
function useDraggable(event, disabled = false) {
|
|
12887
13475
|
const { setDraggedEvent, draggedEvent } = useDrag();
|
|
12888
13476
|
const isDragged = draggedEvent?.id === event.id;
|
|
12889
|
-
const handleDragStart =
|
|
13477
|
+
const handleDragStart = React27__namespace.useCallback((e) => {
|
|
12890
13478
|
if (disabled) return;
|
|
12891
13479
|
e.dataTransfer.effectAllowed = "move";
|
|
12892
13480
|
e.dataTransfer.setData("text/plain", event.id);
|
|
12893
13481
|
setDraggedEvent(event);
|
|
12894
13482
|
}, [disabled, event, setDraggedEvent]);
|
|
12895
|
-
const handleDragEnd =
|
|
13483
|
+
const handleDragEnd = React27__namespace.useCallback(() => {
|
|
12896
13484
|
setDraggedEvent(null);
|
|
12897
13485
|
}, [setDraggedEvent]);
|
|
12898
13486
|
return {
|
|
@@ -12933,15 +13521,15 @@ function MonthView({
|
|
|
12933
13521
|
}) {
|
|
12934
13522
|
const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
|
|
12935
13523
|
const filteredEvents = useFilteredEvents();
|
|
12936
|
-
const { singleDayEvents, multiDayEvents } =
|
|
13524
|
+
const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
|
|
12937
13525
|
() => splitEventsByDuration(filteredEvents),
|
|
12938
13526
|
[filteredEvents]
|
|
12939
13527
|
);
|
|
12940
|
-
const cells =
|
|
13528
|
+
const cells = React27__namespace.useMemo(
|
|
12941
13529
|
() => getCalendarCells(selectedDate),
|
|
12942
13530
|
[selectedDate]
|
|
12943
13531
|
);
|
|
12944
|
-
const eventPositions =
|
|
13532
|
+
const eventPositions = React27__namespace.useMemo(
|
|
12945
13533
|
() => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
|
|
12946
13534
|
[multiDayEvents, singleDayEvents, selectedDate]
|
|
12947
13535
|
);
|
|
@@ -13123,7 +13711,7 @@ function WeekView({
|
|
|
13123
13711
|
visibleHours
|
|
13124
13712
|
} = useEventCalendar();
|
|
13125
13713
|
const filteredEvents = useFilteredEvents();
|
|
13126
|
-
const { singleDayEvents, multiDayEvents } =
|
|
13714
|
+
const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
|
|
13127
13715
|
() => splitEventsByDuration(filteredEvents),
|
|
13128
13716
|
[filteredEvents]
|
|
13129
13717
|
);
|
|
@@ -13329,8 +13917,8 @@ function CalendarTimeline({
|
|
|
13329
13917
|
firstVisibleHour,
|
|
13330
13918
|
lastVisibleHour
|
|
13331
13919
|
}) {
|
|
13332
|
-
const [currentTime, setCurrentTime] =
|
|
13333
|
-
|
|
13920
|
+
const [currentTime, setCurrentTime] = React27__namespace.useState(/* @__PURE__ */ new Date());
|
|
13921
|
+
React27__namespace.useEffect(() => {
|
|
13334
13922
|
const interval = setInterval(() => {
|
|
13335
13923
|
setCurrentTime(/* @__PURE__ */ new Date());
|
|
13336
13924
|
}, 6e4);
|
|
@@ -13413,7 +14001,7 @@ function DayView({
|
|
|
13413
14001
|
visibleHours
|
|
13414
14002
|
} = useEventCalendar();
|
|
13415
14003
|
const filteredEvents = useFilteredEvents();
|
|
13416
|
-
const { singleDayEvents, multiDayEvents } =
|
|
14004
|
+
const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
|
|
13417
14005
|
() => splitEventsByDuration(filteredEvents),
|
|
13418
14006
|
[filteredEvents]
|
|
13419
14007
|
);
|
|
@@ -13421,7 +14009,7 @@ function DayView({
|
|
|
13421
14009
|
visibleHours,
|
|
13422
14010
|
singleDayEvents
|
|
13423
14011
|
);
|
|
13424
|
-
const currentEvents =
|
|
14012
|
+
const currentEvents = React27__namespace.useMemo(() => {
|
|
13425
14013
|
if (!dateFns.isToday(selectedDate)) return [];
|
|
13426
14014
|
return getCurrentEvents(singleDayEvents);
|
|
13427
14015
|
}, [singleDayEvents, selectedDate]);
|
|
@@ -13645,8 +14233,8 @@ function CalendarTimeline2({
|
|
|
13645
14233
|
firstVisibleHour,
|
|
13646
14234
|
lastVisibleHour
|
|
13647
14235
|
}) {
|
|
13648
|
-
const [currentTime, setCurrentTime] =
|
|
13649
|
-
|
|
14236
|
+
const [currentTime, setCurrentTime] = React27__namespace.useState(/* @__PURE__ */ new Date());
|
|
14237
|
+
React27__namespace.useEffect(() => {
|
|
13650
14238
|
const interval = setInterval(() => {
|
|
13651
14239
|
setCurrentTime(/* @__PURE__ */ new Date());
|
|
13652
14240
|
}, 6e4);
|
|
@@ -13680,7 +14268,7 @@ function YearView({
|
|
|
13680
14268
|
}) {
|
|
13681
14269
|
const { selectedDate, setSelectedDate, setView } = useEventCalendar();
|
|
13682
14270
|
const filteredEvents = useFilteredEvents();
|
|
13683
|
-
const months =
|
|
14271
|
+
const months = React27__namespace.useMemo(() => {
|
|
13684
14272
|
const yearStart = dateFns.startOfYear(selectedDate);
|
|
13685
14273
|
return Array.from({ length: 12 }, (_, i) => dateFns.addMonths(yearStart, i));
|
|
13686
14274
|
}, [selectedDate]);
|
|
@@ -13803,11 +14391,11 @@ function AgendaView({
|
|
|
13803
14391
|
}) {
|
|
13804
14392
|
const { selectedDate, setSelectedDate, setView } = useEventCalendar();
|
|
13805
14393
|
const filteredEvents = useFilteredEvents();
|
|
13806
|
-
const { singleDayEvents, multiDayEvents } =
|
|
14394
|
+
const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
|
|
13807
14395
|
() => splitEventsByDuration(filteredEvents),
|
|
13808
14396
|
[filteredEvents]
|
|
13809
14397
|
);
|
|
13810
|
-
const eventsByDay =
|
|
14398
|
+
const eventsByDay = React27__namespace.useMemo(() => {
|
|
13811
14399
|
const allDates = /* @__PURE__ */ new Map();
|
|
13812
14400
|
singleDayEvents.forEach((event) => {
|
|
13813
14401
|
const eventDate = dateFns.parseISO(event.startDate);
|
|
@@ -14272,16 +14860,16 @@ function EventDialog({
|
|
|
14272
14860
|
defaultUserId
|
|
14273
14861
|
}) {
|
|
14274
14862
|
const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
|
|
14275
|
-
const [title, setTitle] =
|
|
14276
|
-
const [description, setDescription] =
|
|
14277
|
-
const [startDate, setStartDate] =
|
|
14278
|
-
const [startTime, setStartTime] =
|
|
14279
|
-
const [endDate, setEndDate] =
|
|
14280
|
-
const [endTime, setEndTime] =
|
|
14281
|
-
const [color, setColor] =
|
|
14282
|
-
const [userId, setUserId] =
|
|
14283
|
-
const [isSubmitting, setIsSubmitting] =
|
|
14284
|
-
|
|
14863
|
+
const [title, setTitle] = React27__namespace.useState("");
|
|
14864
|
+
const [description, setDescription] = React27__namespace.useState("");
|
|
14865
|
+
const [startDate, setStartDate] = React27__namespace.useState("");
|
|
14866
|
+
const [startTime, setStartTime] = React27__namespace.useState("");
|
|
14867
|
+
const [endDate, setEndDate] = React27__namespace.useState("");
|
|
14868
|
+
const [endTime, setEndTime] = React27__namespace.useState("");
|
|
14869
|
+
const [color, setColor] = React27__namespace.useState("blue");
|
|
14870
|
+
const [userId, setUserId] = React27__namespace.useState("");
|
|
14871
|
+
const [isSubmitting, setIsSubmitting] = React27__namespace.useState(false);
|
|
14872
|
+
React27__namespace.useEffect(() => {
|
|
14285
14873
|
if (open) {
|
|
14286
14874
|
if (mode === "edit" && event) {
|
|
14287
14875
|
const start = dateFns.parseISO(event.startDate);
|
|
@@ -14504,7 +15092,7 @@ function QuickAddEvent({
|
|
|
14504
15092
|
onOpenDialog,
|
|
14505
15093
|
onClose
|
|
14506
15094
|
}) {
|
|
14507
|
-
const [title, setTitle] =
|
|
15095
|
+
const [title, setTitle] = React27__namespace.useState("");
|
|
14508
15096
|
const { users } = useEventCalendar();
|
|
14509
15097
|
const handleSubmit = (e) => {
|
|
14510
15098
|
e.preventDefault();
|
|
@@ -14571,8 +15159,8 @@ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
|
|
|
14571
15159
|
});
|
|
14572
15160
|
function ChangeVisibleHoursInput() {
|
|
14573
15161
|
const { visibleHours, setVisibleHours } = useEventCalendar();
|
|
14574
|
-
const [from, setFrom] =
|
|
14575
|
-
const [to, setTo] =
|
|
15162
|
+
const [from, setFrom] = React27__namespace.useState(visibleHours.from);
|
|
15163
|
+
const [to, setTo] = React27__namespace.useState(visibleHours.to);
|
|
14576
15164
|
const handleApply = () => {
|
|
14577
15165
|
const toHour = to === 0 ? 24 : to;
|
|
14578
15166
|
setVisibleHours({ from, to: toHour });
|
|
@@ -14618,7 +15206,7 @@ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
|
|
|
14618
15206
|
});
|
|
14619
15207
|
function ChangeWorkingHoursInput() {
|
|
14620
15208
|
const { workingHours, setWorkingHours } = useEventCalendar();
|
|
14621
|
-
const [localWorkingHours, setLocalWorkingHours] =
|
|
15209
|
+
const [localWorkingHours, setLocalWorkingHours] = React27__namespace.useState({
|
|
14622
15210
|
...workingHours
|
|
14623
15211
|
});
|
|
14624
15212
|
const handleToggleDay = (dayId) => {
|
|
@@ -14767,8 +15355,8 @@ function CalendarSettingsButton({
|
|
|
14767
15355
|
);
|
|
14768
15356
|
}
|
|
14769
15357
|
function useMediaQuery(query) {
|
|
14770
|
-
const [matches, setMatches] =
|
|
14771
|
-
|
|
15358
|
+
const [matches, setMatches] = React27__namespace.useState(false);
|
|
15359
|
+
React27__namespace.useEffect(() => {
|
|
14772
15360
|
const media = window.matchMedia(query);
|
|
14773
15361
|
setMatches(media.matches);
|
|
14774
15362
|
const listener = (event) => {
|
|
@@ -14820,11 +15408,11 @@ function BigCalendarInner({
|
|
|
14820
15408
|
maxEventsPerDay
|
|
14821
15409
|
}) {
|
|
14822
15410
|
const { view, setView } = useEventCalendar();
|
|
14823
|
-
const [dialogOpen, setDialogOpen] =
|
|
14824
|
-
const [settingsDialogOpen, setSettingsDialogOpen] =
|
|
14825
|
-
const [selectedEvent, setSelectedEvent] =
|
|
14826
|
-
const [dialogMode, setDialogMode] =
|
|
14827
|
-
const [defaultDate, setDefaultDate] =
|
|
15411
|
+
const [dialogOpen, setDialogOpen] = React27__namespace.useState(false);
|
|
15412
|
+
const [settingsDialogOpen, setSettingsDialogOpen] = React27__namespace.useState(false);
|
|
15413
|
+
const [selectedEvent, setSelectedEvent] = React27__namespace.useState(null);
|
|
15414
|
+
const [dialogMode, setDialogMode] = React27__namespace.useState("add");
|
|
15415
|
+
const [defaultDate, setDefaultDate] = React27__namespace.useState(/* @__PURE__ */ new Date());
|
|
14828
15416
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
14829
15417
|
const isCompact = compact === "auto" ? isMobile : compact;
|
|
14830
15418
|
const handleAddClick = () => {
|
|
@@ -15111,7 +15699,7 @@ var calculateInnerOffset = (date, range, columnWidth) => {
|
|
|
15111
15699
|
const dayOfMonth = date.getDate();
|
|
15112
15700
|
return dayOfMonth / totalRangeDays * columnWidth;
|
|
15113
15701
|
};
|
|
15114
|
-
var GanttContext =
|
|
15702
|
+
var GanttContext = React27.createContext({
|
|
15115
15703
|
zoom: 100,
|
|
15116
15704
|
range: "monthly",
|
|
15117
15705
|
columnWidth: 50,
|
|
@@ -15132,7 +15720,7 @@ var GanttContentHeader = ({
|
|
|
15132
15720
|
columns,
|
|
15133
15721
|
renderHeaderItem
|
|
15134
15722
|
}) => {
|
|
15135
|
-
const id =
|
|
15723
|
+
const id = React27.useId();
|
|
15136
15724
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15137
15725
|
"div",
|
|
15138
15726
|
{
|
|
@@ -15180,8 +15768,8 @@ var getWeekStartDate = (year, weekNumber) => {
|
|
|
15180
15768
|
return dateFns.addWeeks(week1Start, weekNumber - 1);
|
|
15181
15769
|
};
|
|
15182
15770
|
var WeeklyHeader = () => {
|
|
15183
|
-
const gantt =
|
|
15184
|
-
const weeklyData =
|
|
15771
|
+
const gantt = React27.useContext(GanttContext);
|
|
15772
|
+
const weeklyData = React27.useMemo(() => {
|
|
15185
15773
|
const result = [];
|
|
15186
15774
|
for (const yearData of gantt.timelineData) {
|
|
15187
15775
|
const year = yearData.year;
|
|
@@ -15216,7 +15804,7 @@ var WeeklyHeader = () => {
|
|
|
15216
15804
|
] }, yearData.year));
|
|
15217
15805
|
};
|
|
15218
15806
|
var MonthlyHeader = () => {
|
|
15219
|
-
const gantt =
|
|
15807
|
+
const gantt = React27.useContext(GanttContext);
|
|
15220
15808
|
return gantt.timelineData.map((year) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col", children: [
|
|
15221
15809
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15222
15810
|
GanttContentHeader,
|
|
@@ -15235,7 +15823,7 @@ var MonthlyHeader = () => {
|
|
|
15235
15823
|
] }, year.year));
|
|
15236
15824
|
};
|
|
15237
15825
|
var QuarterlyHeader = () => {
|
|
15238
|
-
const gantt =
|
|
15826
|
+
const gantt = React27.useContext(GanttContext);
|
|
15239
15827
|
return gantt.timelineData.map(
|
|
15240
15828
|
(year) => year.quarters.map((quarter, quarterIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15241
15829
|
"div",
|
|
@@ -15263,7 +15851,7 @@ var headers = {
|
|
|
15263
15851
|
quarterly: QuarterlyHeader
|
|
15264
15852
|
};
|
|
15265
15853
|
var GanttHeader = ({ className }) => {
|
|
15266
|
-
const gantt =
|
|
15854
|
+
const gantt = React27.useContext(GanttContext);
|
|
15267
15855
|
const Header2 = headers[gantt.range];
|
|
15268
15856
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15269
15857
|
"div",
|
|
@@ -15281,7 +15869,7 @@ var GanttSidebarItem = ({
|
|
|
15281
15869
|
onSelectItem,
|
|
15282
15870
|
className
|
|
15283
15871
|
}) => {
|
|
15284
|
-
const gantt =
|
|
15872
|
+
const gantt = React27.useContext(GanttContext);
|
|
15285
15873
|
const tempEndAt = feature.endAt && dateFns.isSameDay(feature.startAt, feature.endAt) ? dateFns.addDays(feature.endAt, 1) : feature.endAt;
|
|
15286
15874
|
const duration = tempEndAt ? dateFns.formatDistance(feature.startAt, tempEndAt) : `${dateFns.formatDistance(feature.startAt, /* @__PURE__ */ new Date())} so far`;
|
|
15287
15875
|
const handleClick = (event) => {
|
|
@@ -15357,24 +15945,24 @@ function computeGroupRange(features) {
|
|
|
15357
15945
|
}
|
|
15358
15946
|
return { start: minStart, end: maxEnd };
|
|
15359
15947
|
}
|
|
15360
|
-
var GanttGroupSummaryBar =
|
|
15948
|
+
var GanttGroupSummaryBar = React27.memo(({
|
|
15361
15949
|
group,
|
|
15362
15950
|
className
|
|
15363
15951
|
}) => {
|
|
15364
|
-
const gantt =
|
|
15365
|
-
const timelineStartDate =
|
|
15952
|
+
const gantt = React27.useContext(GanttContext);
|
|
15953
|
+
const timelineStartDate = React27.useMemo(
|
|
15366
15954
|
() => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
|
|
15367
15955
|
[gantt.timelineData]
|
|
15368
15956
|
);
|
|
15369
|
-
const { start: groupStart, end: groupEnd } =
|
|
15957
|
+
const { start: groupStart, end: groupEnd } = React27.useMemo(
|
|
15370
15958
|
() => computeGroupRange(group.features),
|
|
15371
15959
|
[group.features]
|
|
15372
15960
|
);
|
|
15373
|
-
const offset =
|
|
15961
|
+
const offset = React27.useMemo(() => {
|
|
15374
15962
|
if (!groupStart) return 0;
|
|
15375
15963
|
return Math.round(getOffset(groupStart, timelineStartDate, gantt));
|
|
15376
15964
|
}, [groupStart, timelineStartDate, gantt]);
|
|
15377
|
-
const width =
|
|
15965
|
+
const width = React27.useMemo(() => {
|
|
15378
15966
|
if (!groupStart || !groupEnd) return 0;
|
|
15379
15967
|
return Math.round(getWidth(groupStart, groupEnd, gantt));
|
|
15380
15968
|
}, [groupStart, groupEnd, gantt]);
|
|
@@ -15414,13 +16002,13 @@ var GanttCollapsibleSidebarGroup = ({
|
|
|
15414
16002
|
children,
|
|
15415
16003
|
className
|
|
15416
16004
|
}) => {
|
|
15417
|
-
const gantt =
|
|
16005
|
+
const gantt = React27.useContext(GanttContext);
|
|
15418
16006
|
const isExpanded = gantt.expandedGroups[group.id] ?? true;
|
|
15419
|
-
const { start: groupStart, end: groupEnd } =
|
|
16007
|
+
const { start: groupStart, end: groupEnd } = React27.useMemo(
|
|
15420
16008
|
() => computeGroupRange(group.features),
|
|
15421
16009
|
[group.features]
|
|
15422
16010
|
);
|
|
15423
|
-
const duration =
|
|
16011
|
+
const duration = React27.useMemo(() => {
|
|
15424
16012
|
if (!groupStart || !groupEnd) return null;
|
|
15425
16013
|
return dateFns.formatDistance(groupStart, groupEnd);
|
|
15426
16014
|
}, [groupStart, groupEnd]);
|
|
@@ -15464,7 +16052,7 @@ var GanttCollapsibleTimelineGroup = ({
|
|
|
15464
16052
|
children,
|
|
15465
16053
|
className
|
|
15466
16054
|
}) => {
|
|
15467
|
-
const gantt =
|
|
16055
|
+
const gantt = React27.useContext(GanttContext);
|
|
15468
16056
|
const isExpanded = gantt.expandedGroups[group.id] ?? true;
|
|
15469
16057
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15470
16058
|
Collapsible,
|
|
@@ -15524,7 +16112,7 @@ var GanttAddFeatureHelper = ({
|
|
|
15524
16112
|
className
|
|
15525
16113
|
}) => {
|
|
15526
16114
|
const [scrollX] = useGanttScrollX();
|
|
15527
|
-
const gantt =
|
|
16115
|
+
const gantt = React27.useContext(GanttContext);
|
|
15528
16116
|
const [mousePosition, mouseRef] = usehooks.useMouse();
|
|
15529
16117
|
const handleClick = () => {
|
|
15530
16118
|
const ganttRect = gantt.ref?.current?.getBoundingClientRect();
|
|
@@ -15563,10 +16151,10 @@ var GanttColumn = ({
|
|
|
15563
16151
|
index,
|
|
15564
16152
|
isColumnSecondary
|
|
15565
16153
|
}) => {
|
|
15566
|
-
const gantt =
|
|
16154
|
+
const gantt = React27.useContext(GanttContext);
|
|
15567
16155
|
const [dragging] = useGanttDragging();
|
|
15568
16156
|
const [mousePosition, mouseRef] = usehooks.useMouse();
|
|
15569
|
-
const [hovering, setHovering] =
|
|
16157
|
+
const [hovering, setHovering] = React27.useState(false);
|
|
15570
16158
|
const [windowScroll] = usehooks.useWindowScroll();
|
|
15571
16159
|
const handleMouseEnter = () => setHovering(true);
|
|
15572
16160
|
const handleMouseLeave = () => setHovering(false);
|
|
@@ -15596,7 +16184,7 @@ var GanttColumns = ({
|
|
|
15596
16184
|
columns,
|
|
15597
16185
|
isColumnSecondary
|
|
15598
16186
|
}) => {
|
|
15599
|
-
const id =
|
|
16187
|
+
const id = React27.useId();
|
|
15600
16188
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15601
16189
|
"div",
|
|
15602
16190
|
{
|
|
@@ -15615,12 +16203,12 @@ var GanttColumns = ({
|
|
|
15615
16203
|
}
|
|
15616
16204
|
);
|
|
15617
16205
|
};
|
|
15618
|
-
var GanttGridLines =
|
|
16206
|
+
var GanttGridLines = React27.memo(({
|
|
15619
16207
|
className
|
|
15620
16208
|
}) => {
|
|
15621
|
-
const gantt =
|
|
15622
|
-
const id =
|
|
15623
|
-
const { columns, monthBoundaryIndices } =
|
|
16209
|
+
const gantt = React27.useContext(GanttContext);
|
|
16210
|
+
const id = React27.useId();
|
|
16211
|
+
const { columns, monthBoundaryIndices } = React27.useMemo(() => {
|
|
15624
16212
|
let totalColumns = 0;
|
|
15625
16213
|
const monthIndices = [];
|
|
15626
16214
|
if (gantt.range === "weekly") {
|
|
@@ -15684,7 +16272,7 @@ var GanttCreateMarkerTrigger = ({
|
|
|
15684
16272
|
onCreateMarker,
|
|
15685
16273
|
className
|
|
15686
16274
|
}) => {
|
|
15687
|
-
const gantt =
|
|
16275
|
+
const gantt = React27.useContext(GanttContext);
|
|
15688
16276
|
const [mousePosition, mouseRef] = usehooks.useMouse();
|
|
15689
16277
|
const [windowScroll] = usehooks.useWindowScroll();
|
|
15690
16278
|
const x = usehooks.useThrottle(
|
|
@@ -15733,7 +16321,7 @@ var GanttFeatureDragHelper = ({
|
|
|
15733
16321
|
id: `feature-drag-helper-${featureId}`
|
|
15734
16322
|
});
|
|
15735
16323
|
const isPressed = Boolean(attributes["aria-pressed"]);
|
|
15736
|
-
|
|
16324
|
+
React27.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
|
|
15737
16325
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15738
16326
|
"div",
|
|
15739
16327
|
{
|
|
@@ -15779,7 +16367,7 @@ var GanttFeatureItemCard = ({
|
|
|
15779
16367
|
const [, setDragging] = useGanttDragging();
|
|
15780
16368
|
const { attributes, listeners, setNodeRef } = core.useDraggable({ id });
|
|
15781
16369
|
const isPressed = Boolean(attributes["aria-pressed"]);
|
|
15782
|
-
|
|
16370
|
+
React27.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
|
|
15783
16371
|
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "h-full w-full rounded-sm border bg-background px-2 py-1.5 text-xs shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15784
16372
|
"div",
|
|
15785
16373
|
{
|
|
@@ -15805,37 +16393,37 @@ var GanttFeatureItem = ({
|
|
|
15805
16393
|
...feature
|
|
15806
16394
|
}) => {
|
|
15807
16395
|
const [scrollX] = useGanttScrollX();
|
|
15808
|
-
const gantt =
|
|
15809
|
-
const timelineStartDate =
|
|
16396
|
+
const gantt = React27.useContext(GanttContext);
|
|
16397
|
+
const timelineStartDate = React27.useMemo(
|
|
15810
16398
|
() => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
|
|
15811
16399
|
[gantt.timelineData]
|
|
15812
16400
|
);
|
|
15813
|
-
const [startAt, setStartAt] =
|
|
15814
|
-
const [endAt, setEndAt] =
|
|
15815
|
-
const width =
|
|
16401
|
+
const [startAt, setStartAt] = React27.useState(feature.startAt);
|
|
16402
|
+
const [endAt, setEndAt] = React27.useState(feature.endAt);
|
|
16403
|
+
const width = React27.useMemo(
|
|
15816
16404
|
() => Math.round(getWidth(startAt, endAt, gantt)),
|
|
15817
16405
|
[startAt, endAt, gantt]
|
|
15818
16406
|
);
|
|
15819
|
-
const offset =
|
|
16407
|
+
const offset = React27.useMemo(
|
|
15820
16408
|
() => Math.round(getOffset(startAt, timelineStartDate, gantt)),
|
|
15821
16409
|
[startAt, timelineStartDate, gantt]
|
|
15822
16410
|
);
|
|
15823
|
-
const addRange =
|
|
16411
|
+
const addRange = React27.useMemo(() => getAddRange(gantt.range), [gantt.range]);
|
|
15824
16412
|
const [mousePosition] = usehooks.useMouse();
|
|
15825
|
-
const [previousMouseX, setPreviousMouseX] =
|
|
15826
|
-
const [previousStartAt, setPreviousStartAt] =
|
|
15827
|
-
const [previousEndAt, setPreviousEndAt] =
|
|
16413
|
+
const [previousMouseX, setPreviousMouseX] = React27.useState(0);
|
|
16414
|
+
const [previousStartAt, setPreviousStartAt] = React27.useState(startAt);
|
|
16415
|
+
const [previousEndAt, setPreviousEndAt] = React27.useState(endAt);
|
|
15828
16416
|
const mouseSensor = core.useSensor(core.MouseSensor, {
|
|
15829
16417
|
activationConstraint: {
|
|
15830
16418
|
distance: 10
|
|
15831
16419
|
}
|
|
15832
16420
|
});
|
|
15833
|
-
const handleItemDragStart =
|
|
16421
|
+
const handleItemDragStart = React27.useCallback(() => {
|
|
15834
16422
|
setPreviousMouseX(mousePosition.x);
|
|
15835
16423
|
setPreviousStartAt(startAt);
|
|
15836
16424
|
setPreviousEndAt(endAt);
|
|
15837
16425
|
}, [mousePosition.x, startAt, endAt]);
|
|
15838
|
-
const handleItemDragMove =
|
|
16426
|
+
const handleItemDragMove = React27.useCallback(() => {
|
|
15839
16427
|
const currentDate = getDateByMousePosition(gantt, mousePosition.x);
|
|
15840
16428
|
const originalDate = getDateByMousePosition(gantt, previousMouseX);
|
|
15841
16429
|
const delta = gantt.range === "weekly" ? dateFns.differenceInDays(currentDate, originalDate) : getInnerDifferenceIn(gantt.range)(currentDate, originalDate);
|
|
@@ -15844,17 +16432,17 @@ var GanttFeatureItem = ({
|
|
|
15844
16432
|
setStartAt(newStartDate);
|
|
15845
16433
|
setEndAt(newEndDate);
|
|
15846
16434
|
}, [gantt, mousePosition.x, previousMouseX, previousStartAt, previousEndAt]);
|
|
15847
|
-
const onDragEnd =
|
|
16435
|
+
const onDragEnd = React27.useCallback(
|
|
15848
16436
|
() => onMove?.(feature.id, startAt, endAt),
|
|
15849
16437
|
[onMove, feature.id, startAt, endAt]
|
|
15850
16438
|
);
|
|
15851
|
-
const handleLeftDragMove =
|
|
16439
|
+
const handleLeftDragMove = React27.useCallback(() => {
|
|
15852
16440
|
const ganttRect = gantt.ref?.current?.getBoundingClientRect();
|
|
15853
16441
|
const x = mousePosition.x - (ganttRect?.left ?? 0) + scrollX - gantt.sidebarWidth;
|
|
15854
16442
|
const newStartAt = getDateByMousePosition(gantt, x);
|
|
15855
16443
|
setStartAt(newStartAt);
|
|
15856
16444
|
}, [gantt, mousePosition.x, scrollX]);
|
|
15857
|
-
const handleRightDragMove =
|
|
16445
|
+
const handleRightDragMove = React27.useCallback(() => {
|
|
15858
16446
|
const ganttRect = gantt.ref?.current?.getBoundingClientRect();
|
|
15859
16447
|
const x = mousePosition.x - (ganttRect?.left ?? 0) + scrollX - gantt.sidebarWidth;
|
|
15860
16448
|
const newEndAt = getDateByMousePosition(gantt, x);
|
|
@@ -16050,21 +16638,21 @@ var GanttFeatureList = ({
|
|
|
16050
16638
|
children
|
|
16051
16639
|
}
|
|
16052
16640
|
);
|
|
16053
|
-
var GanttMarker =
|
|
16054
|
-
const gantt =
|
|
16055
|
-
const differenceIn =
|
|
16641
|
+
var GanttMarker = React27.memo(({ label, date, id, onRemove, className }) => {
|
|
16642
|
+
const gantt = React27.useContext(GanttContext);
|
|
16643
|
+
const differenceIn = React27.useMemo(
|
|
16056
16644
|
() => getDifferenceIn(gantt.range),
|
|
16057
16645
|
[gantt.range]
|
|
16058
16646
|
);
|
|
16059
|
-
const timelineStartDate =
|
|
16647
|
+
const timelineStartDate = React27.useMemo(
|
|
16060
16648
|
() => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
|
|
16061
16649
|
[gantt.timelineData]
|
|
16062
16650
|
);
|
|
16063
|
-
const offset =
|
|
16651
|
+
const offset = React27.useMemo(
|
|
16064
16652
|
() => differenceIn(date, timelineStartDate),
|
|
16065
16653
|
[differenceIn, date, timelineStartDate]
|
|
16066
16654
|
);
|
|
16067
|
-
const innerOffset =
|
|
16655
|
+
const innerOffset = React27.useMemo(
|
|
16068
16656
|
() => calculateInnerOffset(
|
|
16069
16657
|
date,
|
|
16070
16658
|
gantt.range,
|
|
@@ -16072,7 +16660,7 @@ var GanttMarker = React29.memo(({ label, date, id, onRemove, className }) => {
|
|
|
16072
16660
|
),
|
|
16073
16661
|
[date, gantt.range, gantt.columnWidth, gantt.zoom]
|
|
16074
16662
|
);
|
|
16075
|
-
const handleRemove =
|
|
16663
|
+
const handleRemove = React27.useCallback(() => onRemove?.(id), [onRemove, id]);
|
|
16076
16664
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
16077
16665
|
"div",
|
|
16078
16666
|
{
|
|
@@ -16122,14 +16710,14 @@ var GanttProvider = ({
|
|
|
16122
16710
|
className,
|
|
16123
16711
|
defaultExpandedGroups = {}
|
|
16124
16712
|
}) => {
|
|
16125
|
-
const scrollRef =
|
|
16126
|
-
const [timelineData, setTimelineData] =
|
|
16713
|
+
const scrollRef = React27.useRef(null);
|
|
16714
|
+
const [timelineData, setTimelineData] = React27.useState(
|
|
16127
16715
|
createInitialTimelineData(/* @__PURE__ */ new Date())
|
|
16128
16716
|
);
|
|
16129
16717
|
const [, setScrollX] = useGanttScrollX();
|
|
16130
16718
|
const sidebarWidth = 280;
|
|
16131
|
-
const [expandedGroups, setExpandedGroups] =
|
|
16132
|
-
const setGroupExpanded =
|
|
16719
|
+
const [expandedGroups, setExpandedGroups] = React27.useState(defaultExpandedGroups);
|
|
16720
|
+
const setGroupExpanded = React27.useCallback((groupId, expanded) => {
|
|
16133
16721
|
setExpandedGroups((prev) => ({ ...prev, [groupId]: expanded }));
|
|
16134
16722
|
}, []);
|
|
16135
16723
|
const headerHeight = 60;
|
|
@@ -16140,7 +16728,7 @@ var GanttProvider = ({
|
|
|
16140
16728
|
} else if (range === "quarterly") {
|
|
16141
16729
|
columnWidth = 100;
|
|
16142
16730
|
}
|
|
16143
|
-
const cssVariables =
|
|
16731
|
+
const cssVariables = React27.useMemo(
|
|
16144
16732
|
() => ({
|
|
16145
16733
|
"--gantt-zoom": `${zoom}`,
|
|
16146
16734
|
"--gantt-column-width": `${zoom / 100 * columnWidth}px`,
|
|
@@ -16150,13 +16738,13 @@ var GanttProvider = ({
|
|
|
16150
16738
|
}),
|
|
16151
16739
|
[zoom, columnWidth, sidebarWidth]
|
|
16152
16740
|
);
|
|
16153
|
-
|
|
16741
|
+
React27.useEffect(() => {
|
|
16154
16742
|
if (scrollRef.current) {
|
|
16155
16743
|
scrollRef.current.scrollLeft = scrollRef.current.scrollWidth / 2 - scrollRef.current.clientWidth / 2;
|
|
16156
16744
|
setScrollX(scrollRef.current.scrollLeft);
|
|
16157
16745
|
}
|
|
16158
16746
|
}, [setScrollX]);
|
|
16159
|
-
const handleScroll =
|
|
16747
|
+
const handleScroll = React27.useCallback(
|
|
16160
16748
|
throttle__default.default(() => {
|
|
16161
16749
|
const scrollElement = scrollRef.current;
|
|
16162
16750
|
if (!scrollElement) {
|
|
@@ -16208,7 +16796,7 @@ var GanttProvider = ({
|
|
|
16208
16796
|
}, 100),
|
|
16209
16797
|
[]
|
|
16210
16798
|
);
|
|
16211
|
-
|
|
16799
|
+
React27.useEffect(() => {
|
|
16212
16800
|
const scrollElement = scrollRef.current;
|
|
16213
16801
|
if (scrollElement) {
|
|
16214
16802
|
scrollElement.addEventListener("scroll", handleScroll);
|
|
@@ -16219,7 +16807,7 @@ var GanttProvider = ({
|
|
|
16219
16807
|
}
|
|
16220
16808
|
};
|
|
16221
16809
|
}, [handleScroll]);
|
|
16222
|
-
const scrollToFeature =
|
|
16810
|
+
const scrollToFeature = React27.useCallback(
|
|
16223
16811
|
(feature) => {
|
|
16224
16812
|
const scrollElement = scrollRef.current;
|
|
16225
16813
|
if (!scrollElement) {
|
|
@@ -16299,21 +16887,21 @@ var GanttTimeline = ({
|
|
|
16299
16887
|
);
|
|
16300
16888
|
var GanttToday = ({ className }) => {
|
|
16301
16889
|
const label = "Today";
|
|
16302
|
-
const date =
|
|
16303
|
-
const gantt =
|
|
16304
|
-
const differenceIn =
|
|
16890
|
+
const date = React27.useMemo(() => /* @__PURE__ */ new Date(), []);
|
|
16891
|
+
const gantt = React27.useContext(GanttContext);
|
|
16892
|
+
const differenceIn = React27.useMemo(
|
|
16305
16893
|
() => getDifferenceIn(gantt.range),
|
|
16306
16894
|
[gantt.range]
|
|
16307
16895
|
);
|
|
16308
|
-
const timelineStartDate =
|
|
16896
|
+
const timelineStartDate = React27.useMemo(
|
|
16309
16897
|
() => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
|
|
16310
16898
|
[gantt.timelineData]
|
|
16311
16899
|
);
|
|
16312
|
-
const offset =
|
|
16900
|
+
const offset = React27.useMemo(
|
|
16313
16901
|
() => differenceIn(date, timelineStartDate),
|
|
16314
16902
|
[differenceIn, date, timelineStartDate]
|
|
16315
16903
|
);
|
|
16316
|
-
const innerOffset =
|
|
16904
|
+
const innerOffset = React27.useMemo(
|
|
16317
16905
|
() => Math.round(calculateInnerOffset(
|
|
16318
16906
|
date,
|
|
16319
16907
|
gantt.range,
|
|
@@ -16349,7 +16937,7 @@ var GanttToday = ({ className }) => {
|
|
|
16349
16937
|
);
|
|
16350
16938
|
};
|
|
16351
16939
|
var t = tunnel__default.default();
|
|
16352
|
-
var KanbanContext =
|
|
16940
|
+
var KanbanContext = React27.createContext({
|
|
16353
16941
|
columns: [],
|
|
16354
16942
|
data: [],
|
|
16355
16943
|
activeCardId: null
|
|
@@ -16387,7 +16975,7 @@ var KanbanCard = ({
|
|
|
16387
16975
|
} = sortable.useSortable({
|
|
16388
16976
|
id
|
|
16389
16977
|
});
|
|
16390
|
-
const { activeCardId } =
|
|
16978
|
+
const { activeCardId } = React27.useContext(KanbanContext);
|
|
16391
16979
|
const style = {
|
|
16392
16980
|
transition,
|
|
16393
16981
|
transform: utilities.CSS.Transform.toString(transform)
|
|
@@ -16422,7 +17010,7 @@ var KanbanCards = ({
|
|
|
16422
17010
|
className,
|
|
16423
17011
|
...props
|
|
16424
17012
|
}) => {
|
|
16425
|
-
const { data } =
|
|
17013
|
+
const { data } = React27.useContext(KanbanContext);
|
|
16426
17014
|
const filteredData = data.filter((item) => item.column === props.id);
|
|
16427
17015
|
const items = filteredData.map((item) => item.id);
|
|
16428
17016
|
return /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "overflow-hidden", children: [
|
|
@@ -16449,7 +17037,7 @@ var KanbanProvider = ({
|
|
|
16449
17037
|
onDataChange,
|
|
16450
17038
|
...props
|
|
16451
17039
|
}) => {
|
|
16452
|
-
const [activeCardId, setActiveCardId] =
|
|
17040
|
+
const [activeCardId, setActiveCardId] = React27.useState(null);
|
|
16453
17041
|
const sensors = core.useSensors(
|
|
16454
17042
|
core.useSensor(core.MouseSensor),
|
|
16455
17043
|
core.useSensor(core.TouchSensor),
|
|
@@ -16672,6 +17260,8 @@ exports.CircularProgress = CircularProgress;
|
|
|
16672
17260
|
exports.Collapsible = Collapsible;
|
|
16673
17261
|
exports.CollapsibleContent = CollapsibleContent2;
|
|
16674
17262
|
exports.CollapsibleTrigger = CollapsibleTrigger2;
|
|
17263
|
+
exports.ColumnSummaryCell = ColumnSummaryCell;
|
|
17264
|
+
exports.ColumnSummaryStrip = ColumnSummaryStrip;
|
|
16675
17265
|
exports.Command = Command;
|
|
16676
17266
|
exports.CommandDialog = CommandDialog;
|
|
16677
17267
|
exports.CommandEmpty = CommandEmpty;
|
|
@@ -16811,6 +17401,7 @@ exports.InputGroupButton = InputGroupButton;
|
|
|
16811
17401
|
exports.InputGroupInput = InputGroupInput;
|
|
16812
17402
|
exports.InputGroupText = InputGroupText;
|
|
16813
17403
|
exports.InputGroupTextarea = InputGroupTextarea;
|
|
17404
|
+
exports.InsightBar = InsightBar;
|
|
16814
17405
|
exports.Item = Item6;
|
|
16815
17406
|
exports.ItemActions = ItemActions;
|
|
16816
17407
|
exports.ItemContent = ItemContent;
|