@optifye/dashboard-core 4.2.8 → 4.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +39 -5
- package/dist/index.d.ts +39 -5
- package/dist/index.js +723 -172
- package/dist/index.mjs +721 -173
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1020,7 +1020,7 @@ var dashboardService = {
|
|
|
1020
1020
|
const formattedStartDate = formatDate(startDate);
|
|
1021
1021
|
const formattedEndDate = formatDate(endDate);
|
|
1022
1022
|
try {
|
|
1023
|
-
const { data, error } = await supabase.from(metricsTable).select("date, shift_id, efficiency, total_output, avg_cycle_time,
|
|
1023
|
+
const { data, error } = await supabase.from(metricsTable).select("date, shift_id, efficiency, total_output, avg_cycle_time, ideal_output, avg_pph, pph_threshold, workspace_rank").eq("workspace_id", workspaceUuid).gte("date", formattedStartDate).lte("date", formattedEndDate).order("date", { ascending: true }).order("shift_id", { ascending: true });
|
|
1024
1024
|
if (error) throw error;
|
|
1025
1025
|
if (!data) return [];
|
|
1026
1026
|
const transformedData = data.map((item) => ({
|
|
@@ -1033,8 +1033,7 @@ var dashboardService = {
|
|
|
1033
1033
|
ideal_output: item.ideal_output || 0,
|
|
1034
1034
|
avg_pph: item.avg_pph || 0,
|
|
1035
1035
|
pph_threshold: item.pph_threshold || 0,
|
|
1036
|
-
workspace_rank: item.workspace_rank || 0
|
|
1037
|
-
idle_time: item.idle_time || 0
|
|
1036
|
+
workspace_rank: item.workspace_rank || 0
|
|
1038
1037
|
}));
|
|
1039
1038
|
return transformedData;
|
|
1040
1039
|
} catch (err) {
|
|
@@ -2110,28 +2109,42 @@ var AuthProvider = ({ children }) => {
|
|
|
2110
2109
|
id: supabaseUser.id,
|
|
2111
2110
|
email: supabaseUser.email
|
|
2112
2111
|
};
|
|
2113
|
-
if (!
|
|
2112
|
+
if (!supabase) return basicUser;
|
|
2114
2113
|
try {
|
|
2115
2114
|
const timeoutPromise = new Promise(
|
|
2116
2115
|
(_, reject) => setTimeout(() => reject(new Error("Profile fetch timeout")), 5e3)
|
|
2117
2116
|
);
|
|
2118
|
-
const
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2117
|
+
const rolePromise = supabase.from("user_roles").select("role_level").eq("user_id", supabaseUser.id).single();
|
|
2118
|
+
let profilePromise = null;
|
|
2119
|
+
if (userProfileTable) {
|
|
2120
|
+
profilePromise = supabase.from(userProfileTable).select(roleColumn).eq("id", supabaseUser.id).single();
|
|
2121
|
+
}
|
|
2122
|
+
const [roleResult, profileResult] = await Promise.race([
|
|
2123
|
+
Promise.all([
|
|
2124
|
+
rolePromise,
|
|
2125
|
+
profilePromise || Promise.resolve(null)
|
|
2126
|
+
]),
|
|
2127
|
+
timeoutPromise.then(() => {
|
|
2128
|
+
throw new Error("Timeout");
|
|
2129
|
+
})
|
|
2122
2130
|
]);
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2131
|
+
let roleLevel = void 0;
|
|
2132
|
+
if (roleResult && !roleResult.error && roleResult.data) {
|
|
2133
|
+
roleLevel = roleResult.data.role_level;
|
|
2134
|
+
} else if (roleResult?.error) {
|
|
2135
|
+
console.log("Error fetching role_level:", roleResult.error.message);
|
|
2136
|
+
}
|
|
2137
|
+
let roleValue = void 0;
|
|
2138
|
+
if (profileResult && !profileResult.error && profileResult.data) {
|
|
2139
|
+
roleValue = profileResult.data[roleColumn];
|
|
2130
2140
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
2141
|
+
return {
|
|
2142
|
+
...basicUser,
|
|
2143
|
+
role: roleValue,
|
|
2144
|
+
role_level: roleLevel
|
|
2145
|
+
};
|
|
2133
2146
|
} catch (err) {
|
|
2134
|
-
console.error("Error fetching user
|
|
2147
|
+
console.error("Error fetching user details:", err);
|
|
2135
2148
|
return basicUser;
|
|
2136
2149
|
}
|
|
2137
2150
|
}, [supabase, userProfileTable, roleColumn]);
|
|
@@ -2166,7 +2179,8 @@ var AuthProvider = ({ children }) => {
|
|
|
2166
2179
|
email: userDetails.email,
|
|
2167
2180
|
name: userDetails.email,
|
|
2168
2181
|
// using email as the display name for now
|
|
2169
|
-
role: userDetails.role
|
|
2182
|
+
role: userDetails.role,
|
|
2183
|
+
role_level: userDetails.role_level
|
|
2170
2184
|
});
|
|
2171
2185
|
}
|
|
2172
2186
|
}
|
|
@@ -2204,7 +2218,8 @@ var AuthProvider = ({ children }) => {
|
|
|
2204
2218
|
identifyCoreUser(userDetails.id, {
|
|
2205
2219
|
email: userDetails.email,
|
|
2206
2220
|
name: userDetails.email,
|
|
2207
|
-
role: userDetails.role
|
|
2221
|
+
role: userDetails.role,
|
|
2222
|
+
role_level: userDetails.role_level
|
|
2208
2223
|
});
|
|
2209
2224
|
}
|
|
2210
2225
|
}
|
|
@@ -14731,16 +14746,16 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14731
14746
|
if (!this.isVisible) {
|
|
14732
14747
|
return hiddenVisibility;
|
|
14733
14748
|
}
|
|
14734
|
-
const
|
|
14749
|
+
const styles2 = {
|
|
14735
14750
|
visibility: ""
|
|
14736
14751
|
};
|
|
14737
14752
|
const transformTemplate = this.getTransformTemplate();
|
|
14738
14753
|
if (this.needsReset) {
|
|
14739
14754
|
this.needsReset = false;
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
return
|
|
14755
|
+
styles2.opacity = "";
|
|
14756
|
+
styles2.pointerEvents = resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "";
|
|
14757
|
+
styles2.transform = transformTemplate ? transformTemplate(this.latestValues, "") : "none";
|
|
14758
|
+
return styles2;
|
|
14744
14759
|
}
|
|
14745
14760
|
const lead = this.getLead();
|
|
14746
14761
|
if (!this.projectionDelta || !this.layout || !lead.target) {
|
|
@@ -14757,35 +14772,35 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14757
14772
|
}
|
|
14758
14773
|
const valuesToRender = lead.animationValues || lead.latestValues;
|
|
14759
14774
|
this.applyTransformsToTarget();
|
|
14760
|
-
|
|
14775
|
+
styles2.transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
|
|
14761
14776
|
if (transformTemplate) {
|
|
14762
|
-
|
|
14777
|
+
styles2.transform = transformTemplate(valuesToRender, styles2.transform);
|
|
14763
14778
|
}
|
|
14764
14779
|
const { x, y } = this.projectionDelta;
|
|
14765
|
-
|
|
14780
|
+
styles2.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
|
|
14766
14781
|
if (lead.animationValues) {
|
|
14767
|
-
|
|
14782
|
+
styles2.opacity = lead === this ? (_b = (_a = valuesToRender.opacity) !== null && _a !== void 0 ? _a : this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1 : this.preserveOpacity ? this.latestValues.opacity : valuesToRender.opacityExit;
|
|
14768
14783
|
} else {
|
|
14769
|
-
|
|
14784
|
+
styles2.opacity = lead === this ? valuesToRender.opacity !== void 0 ? valuesToRender.opacity : "" : valuesToRender.opacityExit !== void 0 ? valuesToRender.opacityExit : 0;
|
|
14770
14785
|
}
|
|
14771
14786
|
for (const key in scaleCorrectors) {
|
|
14772
14787
|
if (valuesToRender[key] === void 0)
|
|
14773
14788
|
continue;
|
|
14774
14789
|
const { correct, applyTo } = scaleCorrectors[key];
|
|
14775
|
-
const corrected =
|
|
14790
|
+
const corrected = styles2.transform === "none" ? valuesToRender[key] : correct(valuesToRender[key], lead);
|
|
14776
14791
|
if (applyTo) {
|
|
14777
14792
|
const num = applyTo.length;
|
|
14778
14793
|
for (let i = 0; i < num; i++) {
|
|
14779
|
-
|
|
14794
|
+
styles2[applyTo[i]] = corrected;
|
|
14780
14795
|
}
|
|
14781
14796
|
} else {
|
|
14782
|
-
|
|
14797
|
+
styles2[key] = corrected;
|
|
14783
14798
|
}
|
|
14784
14799
|
}
|
|
14785
14800
|
if (this.options.layoutId) {
|
|
14786
|
-
|
|
14801
|
+
styles2.pointerEvents = lead === this ? resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "" : "none";
|
|
14787
14802
|
}
|
|
14788
|
-
return
|
|
14803
|
+
return styles2;
|
|
14789
14804
|
}
|
|
14790
14805
|
clearSnapshot() {
|
|
14791
14806
|
this.resumeFrom = this.snapshot = void 0;
|
|
@@ -16892,23 +16907,35 @@ var HourlyOutputChart = ({
|
|
|
16892
16907
|
const [animatedData, setAnimatedData] = React14__namespace.default.useState(Array(SHIFT_DURATION).fill(0));
|
|
16893
16908
|
const prevDataRef = React14__namespace.default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
16894
16909
|
const animationFrameRef = React14__namespace.default.useRef(null);
|
|
16895
|
-
const [
|
|
16910
|
+
const [idleBarState, setIdleBarState] = React14__namespace.default.useState({
|
|
16911
|
+
visible: showIdleTime,
|
|
16912
|
+
key: 0,
|
|
16913
|
+
shouldAnimate: false
|
|
16914
|
+
});
|
|
16896
16915
|
const prevShowIdleTimeRef = React14__namespace.default.useRef(showIdleTime);
|
|
16897
|
-
const
|
|
16916
|
+
const stateUpdateTimeoutRef = React14__namespace.default.useRef(null);
|
|
16898
16917
|
React14__namespace.default.useEffect(() => {
|
|
16918
|
+
if (stateUpdateTimeoutRef.current) {
|
|
16919
|
+
clearTimeout(stateUpdateTimeoutRef.current);
|
|
16920
|
+
}
|
|
16899
16921
|
if (showIdleTime && !prevShowIdleTimeRef.current) {
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16922
|
+
requestAnimationFrame(() => {
|
|
16923
|
+
setIdleBarState({
|
|
16924
|
+
visible: true,
|
|
16925
|
+
key: Date.now(),
|
|
16926
|
+
shouldAnimate: true
|
|
16927
|
+
});
|
|
16928
|
+
stateUpdateTimeoutRef.current = setTimeout(() => {
|
|
16929
|
+
setIdleBarState((prev) => ({ ...prev, shouldAnimate: false }));
|
|
16930
|
+
}, 1100);
|
|
16931
|
+
});
|
|
16932
|
+
} else if (!showIdleTime && prevShowIdleTimeRef.current) {
|
|
16933
|
+
setIdleBarState((prev) => ({ ...prev, visible: false }));
|
|
16907
16934
|
}
|
|
16908
16935
|
prevShowIdleTimeRef.current = showIdleTime;
|
|
16909
16936
|
return () => {
|
|
16910
|
-
if (
|
|
16911
|
-
clearTimeout(
|
|
16937
|
+
if (stateUpdateTimeoutRef.current) {
|
|
16938
|
+
clearTimeout(stateUpdateTimeoutRef.current);
|
|
16912
16939
|
}
|
|
16913
16940
|
};
|
|
16914
16941
|
}, [showIdleTime]);
|
|
@@ -17001,6 +17028,55 @@ var HourlyOutputChart = ({
|
|
|
17001
17028
|
};
|
|
17002
17029
|
});
|
|
17003
17030
|
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
17031
|
+
const IdleBar = React14__namespace.default.useMemo(() => {
|
|
17032
|
+
if (!idleBarState.visible) return null;
|
|
17033
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17034
|
+
recharts.Bar,
|
|
17035
|
+
{
|
|
17036
|
+
dataKey: "idleMinutes",
|
|
17037
|
+
yAxisId: "idle",
|
|
17038
|
+
maxBarSize: 35,
|
|
17039
|
+
radius: [10, 10, 0, 0],
|
|
17040
|
+
fill: "url(#idlePattern)",
|
|
17041
|
+
opacity: 0.7,
|
|
17042
|
+
isAnimationActive: idleBarState.shouldAnimate,
|
|
17043
|
+
animationBegin: 0,
|
|
17044
|
+
animationDuration: 1e3,
|
|
17045
|
+
animationEasing: "ease-out",
|
|
17046
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17047
|
+
recharts.LabelList,
|
|
17048
|
+
{
|
|
17049
|
+
dataKey: "idleMinutes",
|
|
17050
|
+
position: "top",
|
|
17051
|
+
content: (props) => {
|
|
17052
|
+
const { x, y, width, value } = props;
|
|
17053
|
+
if (!value || value === 0) return null;
|
|
17054
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17055
|
+
"text",
|
|
17056
|
+
{
|
|
17057
|
+
x: x + width / 2,
|
|
17058
|
+
y: y - 2,
|
|
17059
|
+
textAnchor: "middle",
|
|
17060
|
+
fontSize: "9",
|
|
17061
|
+
fontWeight: "600",
|
|
17062
|
+
fill: "#6b7280",
|
|
17063
|
+
style: {
|
|
17064
|
+
opacity: 1,
|
|
17065
|
+
pointerEvents: "none"
|
|
17066
|
+
},
|
|
17067
|
+
children: [
|
|
17068
|
+
value,
|
|
17069
|
+
"m"
|
|
17070
|
+
]
|
|
17071
|
+
}
|
|
17072
|
+
);
|
|
17073
|
+
}
|
|
17074
|
+
}
|
|
17075
|
+
)
|
|
17076
|
+
},
|
|
17077
|
+
`idle-bar-${idleBarState.key}`
|
|
17078
|
+
);
|
|
17079
|
+
}, [idleBarState.visible, idleBarState.key, idleBarState.shouldAnimate]);
|
|
17004
17080
|
const maxYValue = Math.ceil(pphThreshold * 1.5);
|
|
17005
17081
|
const generateYAxisTicks = () => {
|
|
17006
17082
|
const targetValue = Math.round(pphThreshold);
|
|
@@ -17258,51 +17334,7 @@ var HourlyOutputChart = ({
|
|
|
17258
17334
|
]
|
|
17259
17335
|
}
|
|
17260
17336
|
),
|
|
17261
|
-
|
|
17262
|
-
recharts.Bar,
|
|
17263
|
-
{
|
|
17264
|
-
dataKey: "idleMinutes",
|
|
17265
|
-
yAxisId: "idle",
|
|
17266
|
-
maxBarSize: 35,
|
|
17267
|
-
radius: [10, 10, 0, 0],
|
|
17268
|
-
fill: "url(#idlePattern)",
|
|
17269
|
-
opacity: 0.7,
|
|
17270
|
-
isAnimationActive: shouldAnimateIdle,
|
|
17271
|
-
animationBegin: shouldAnimateIdle ? 200 : 0,
|
|
17272
|
-
animationDuration: shouldAnimateIdle ? 800 : 0,
|
|
17273
|
-
animationEasing: "ease-out",
|
|
17274
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17275
|
-
recharts.LabelList,
|
|
17276
|
-
{
|
|
17277
|
-
dataKey: "idleMinutes",
|
|
17278
|
-
position: "top",
|
|
17279
|
-
content: (props) => {
|
|
17280
|
-
const { x, y, width, value } = props;
|
|
17281
|
-
if (!value || value === 0) return null;
|
|
17282
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17283
|
-
"text",
|
|
17284
|
-
{
|
|
17285
|
-
x: x + width / 2,
|
|
17286
|
-
y: y - 2,
|
|
17287
|
-
textAnchor: "middle",
|
|
17288
|
-
fontSize: "9",
|
|
17289
|
-
fontWeight: "600",
|
|
17290
|
-
fill: "#6b7280",
|
|
17291
|
-
style: {
|
|
17292
|
-
opacity: 1,
|
|
17293
|
-
pointerEvents: "none"
|
|
17294
|
-
},
|
|
17295
|
-
children: [
|
|
17296
|
-
value,
|
|
17297
|
-
"m"
|
|
17298
|
-
]
|
|
17299
|
-
}
|
|
17300
|
-
);
|
|
17301
|
-
}
|
|
17302
|
-
}
|
|
17303
|
-
)
|
|
17304
|
-
}
|
|
17305
|
-
),
|
|
17337
|
+
IdleBar,
|
|
17306
17338
|
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("pattern", { id: "idlePattern", patternUnits: "userSpaceOnUse", width: "4", height: "4", children: [
|
|
17307
17339
|
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "4", height: "4", fill: "#9ca3af", opacity: "0.2" }),
|
|
17308
17340
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 0,4 l 4,-4 M -1,1 l 2,-2 M 3,5 l 2,-2", stroke: "#6b7280", strokeWidth: "0.5", opacity: "0.3" })
|
|
@@ -17973,6 +18005,187 @@ var SOPComplianceChart = ({
|
|
|
17973
18005
|
renderLegend()
|
|
17974
18006
|
] });
|
|
17975
18007
|
};
|
|
18008
|
+
var GaugeChart = ({
|
|
18009
|
+
value,
|
|
18010
|
+
min,
|
|
18011
|
+
max,
|
|
18012
|
+
target,
|
|
18013
|
+
label,
|
|
18014
|
+
unit = "",
|
|
18015
|
+
thresholds,
|
|
18016
|
+
className = ""
|
|
18017
|
+
}) => {
|
|
18018
|
+
const normalizedValue = (value - min) / (max - min) * 100;
|
|
18019
|
+
const clampedValue = Math.max(0, Math.min(100, normalizedValue));
|
|
18020
|
+
const data = [
|
|
18021
|
+
{ name: "value", value: clampedValue },
|
|
18022
|
+
{ name: "empty", value: 100 - clampedValue }
|
|
18023
|
+
];
|
|
18024
|
+
const getColor = () => {
|
|
18025
|
+
if (thresholds && thresholds.length > 0) {
|
|
18026
|
+
const sortedThresholds = [...thresholds].sort((a, b) => a.value - b.value);
|
|
18027
|
+
for (let i = sortedThresholds.length - 1; i >= 0; i--) {
|
|
18028
|
+
if (value >= sortedThresholds[i].value) {
|
|
18029
|
+
return sortedThresholds[i].color;
|
|
18030
|
+
}
|
|
18031
|
+
}
|
|
18032
|
+
return sortedThresholds[0].color;
|
|
18033
|
+
}
|
|
18034
|
+
if (clampedValue < 33) return "#ef4444";
|
|
18035
|
+
if (clampedValue < 66) return "#f59e0b";
|
|
18036
|
+
return "#10b981";
|
|
18037
|
+
};
|
|
18038
|
+
const gaugeColor = getColor();
|
|
18039
|
+
const targetAngle = target !== void 0 ? 180 - (target - min) / (max - min) * 180 : null;
|
|
18040
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative w-full h-full flex flex-col items-center justify-center ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-[280px] aspect-square", children: [
|
|
18041
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.PieChart, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18042
|
+
recharts.Pie,
|
|
18043
|
+
{
|
|
18044
|
+
data,
|
|
18045
|
+
cx: "50%",
|
|
18046
|
+
cy: "50%",
|
|
18047
|
+
startAngle: 180,
|
|
18048
|
+
endAngle: 0,
|
|
18049
|
+
innerRadius: "65%",
|
|
18050
|
+
outerRadius: "85%",
|
|
18051
|
+
paddingAngle: 0,
|
|
18052
|
+
dataKey: "value",
|
|
18053
|
+
animationBegin: 0,
|
|
18054
|
+
animationDuration: 1e3,
|
|
18055
|
+
animationEasing: "ease-out",
|
|
18056
|
+
children: [
|
|
18057
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: gaugeColor }),
|
|
18058
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: "#f3f4f6" })
|
|
18059
|
+
]
|
|
18060
|
+
}
|
|
18061
|
+
) }) }),
|
|
18062
|
+
targetAngle !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18063
|
+
"div",
|
|
18064
|
+
{
|
|
18065
|
+
className: "absolute top-1/2 left-1/2 w-1 h-[42%] bg-gray-800 origin-bottom",
|
|
18066
|
+
style: {
|
|
18067
|
+
transform: `translate(-50%, -100%) rotate(${targetAngle}deg)`,
|
|
18068
|
+
transition: "transform 0.3s ease-out"
|
|
18069
|
+
},
|
|
18070
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -left-1.5 w-3 h-3 bg-gray-800 rounded-full" })
|
|
18071
|
+
}
|
|
18072
|
+
),
|
|
18073
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
18074
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-3xl font-bold text-gray-800", children: [
|
|
18075
|
+
value.toFixed(unit === "%" ? 1 : 0),
|
|
18076
|
+
unit
|
|
18077
|
+
] }),
|
|
18078
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-600 mt-1 font-medium", children: label }),
|
|
18079
|
+
target !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 mt-1", children: [
|
|
18080
|
+
"Target: ",
|
|
18081
|
+
target,
|
|
18082
|
+
unit
|
|
18083
|
+
] })
|
|
18084
|
+
] }) }),
|
|
18085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-[15%] left-[15%] text-xs text-gray-500", children: [
|
|
18086
|
+
min,
|
|
18087
|
+
unit
|
|
18088
|
+
] }),
|
|
18089
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-[15%] right-[15%] text-xs text-gray-500", children: [
|
|
18090
|
+
max,
|
|
18091
|
+
unit
|
|
18092
|
+
] })
|
|
18093
|
+
] }) });
|
|
18094
|
+
};
|
|
18095
|
+
var DEFAULT_COLORS = [
|
|
18096
|
+
"#3b82f6",
|
|
18097
|
+
// blue-500
|
|
18098
|
+
"#10b981",
|
|
18099
|
+
// green-500
|
|
18100
|
+
"#f59e0b",
|
|
18101
|
+
// amber-500
|
|
18102
|
+
"#ef4444",
|
|
18103
|
+
// red-500
|
|
18104
|
+
"#8b5cf6",
|
|
18105
|
+
// violet-500
|
|
18106
|
+
"#06b6d4",
|
|
18107
|
+
// cyan-500
|
|
18108
|
+
"#f97316",
|
|
18109
|
+
// orange-500
|
|
18110
|
+
"#6366f1"
|
|
18111
|
+
// indigo-500
|
|
18112
|
+
];
|
|
18113
|
+
var PieChart4 = ({
|
|
18114
|
+
data,
|
|
18115
|
+
className = "",
|
|
18116
|
+
showPercentages = false,
|
|
18117
|
+
colors = DEFAULT_COLORS
|
|
18118
|
+
}) => {
|
|
18119
|
+
const total = data.reduce((sum, entry) => sum + entry.value, 0);
|
|
18120
|
+
const dataWithPercentage = data.map((entry) => ({
|
|
18121
|
+
...entry,
|
|
18122
|
+
percentage: (entry.value / total * 100).toFixed(1)
|
|
18123
|
+
}));
|
|
18124
|
+
const renderCustomLabel = (props) => {
|
|
18125
|
+
if (!showPercentages) return null;
|
|
18126
|
+
const { cx: cx2, cy, midAngle, innerRadius, outerRadius, percentage } = props;
|
|
18127
|
+
const RADIAN = Math.PI / 180;
|
|
18128
|
+
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
|
|
18129
|
+
const x = cx2 + radius * Math.cos(-midAngle * RADIAN);
|
|
18130
|
+
const y = cy + radius * Math.sin(-midAngle * RADIAN);
|
|
18131
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18132
|
+
"text",
|
|
18133
|
+
{
|
|
18134
|
+
x,
|
|
18135
|
+
y,
|
|
18136
|
+
fill: "white",
|
|
18137
|
+
textAnchor: x > cx2 ? "start" : "end",
|
|
18138
|
+
dominantBaseline: "central",
|
|
18139
|
+
className: "text-xs font-medium",
|
|
18140
|
+
children: [
|
|
18141
|
+
percentage,
|
|
18142
|
+
"%"
|
|
18143
|
+
]
|
|
18144
|
+
}
|
|
18145
|
+
);
|
|
18146
|
+
};
|
|
18147
|
+
const CustomTooltip = ({ active, payload }) => {
|
|
18148
|
+
if (active && payload && payload.length) {
|
|
18149
|
+
const data2 = payload[0];
|
|
18150
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white px-3 py-2 shadow-lg rounded-lg border border-gray-200", children: [
|
|
18151
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900", children: data2.name }),
|
|
18152
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-600", children: [
|
|
18153
|
+
"Value: ",
|
|
18154
|
+
data2.value,
|
|
18155
|
+
showPercentages && ` (${data2.payload.percentage}%)`
|
|
18156
|
+
] })
|
|
18157
|
+
] });
|
|
18158
|
+
}
|
|
18159
|
+
return null;
|
|
18160
|
+
};
|
|
18161
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full h-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
|
|
18162
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18163
|
+
recharts.Pie,
|
|
18164
|
+
{
|
|
18165
|
+
data: dataWithPercentage,
|
|
18166
|
+
cx: "50%",
|
|
18167
|
+
cy: "50%",
|
|
18168
|
+
labelLine: false,
|
|
18169
|
+
label: showPercentages ? renderCustomLabel : void 0,
|
|
18170
|
+
outerRadius: "80%",
|
|
18171
|
+
fill: "#8884d8",
|
|
18172
|
+
dataKey: "value",
|
|
18173
|
+
animationBegin: 0,
|
|
18174
|
+
animationDuration: 800,
|
|
18175
|
+
children: dataWithPercentage.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: colors[index % colors.length] }, `cell-${index}`))
|
|
18176
|
+
}
|
|
18177
|
+
),
|
|
18178
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}) }),
|
|
18179
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18180
|
+
recharts.Legend,
|
|
18181
|
+
{
|
|
18182
|
+
verticalAlign: "bottom",
|
|
18183
|
+
height: 36,
|
|
18184
|
+
formatter: (value) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: value })
|
|
18185
|
+
}
|
|
18186
|
+
)
|
|
18187
|
+
] }) }) });
|
|
18188
|
+
};
|
|
17976
18189
|
var TrendIcon = ({ trend }) => {
|
|
17977
18190
|
if (trend === "up") {
|
|
17978
18191
|
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-4 w-4 text-green-500" });
|
|
@@ -19775,6 +19988,32 @@ var WorkspaceCard = ({
|
|
|
19775
19988
|
}
|
|
19776
19989
|
);
|
|
19777
19990
|
};
|
|
19991
|
+
var styles = `
|
|
19992
|
+
@keyframes fadeIn {
|
|
19993
|
+
from {
|
|
19994
|
+
opacity: 0;
|
|
19995
|
+
transform: translateY(-10px);
|
|
19996
|
+
}
|
|
19997
|
+
to {
|
|
19998
|
+
opacity: 1;
|
|
19999
|
+
transform: translateY(0);
|
|
20000
|
+
}
|
|
20001
|
+
}
|
|
20002
|
+
|
|
20003
|
+
.calendar-container {
|
|
20004
|
+
will-change: transform, opacity;
|
|
20005
|
+
animation: fadeIn 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
|
20006
|
+
}
|
|
20007
|
+
|
|
20008
|
+
.calendar-wrapper:not(.animation-complete) * {
|
|
20009
|
+
transition: none !important;
|
|
20010
|
+
}
|
|
20011
|
+
|
|
20012
|
+
.calendar-wrapper:not(.animation-complete) .group:hover {
|
|
20013
|
+
opacity: 1 !important;
|
|
20014
|
+
transform: scale(1) !important;
|
|
20015
|
+
}
|
|
20016
|
+
`;
|
|
19778
20017
|
var WEEKDAYS2 = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
19779
20018
|
var getTimeInZoneAsDate = (timezone) => {
|
|
19780
20019
|
const time2 = getCurrentTimeInZone(timezone);
|
|
@@ -19793,20 +20032,20 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19793
20032
|
}) => {
|
|
19794
20033
|
const { dateTimeConfig } = useDashboardConfig();
|
|
19795
20034
|
const configuredTimezone = dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
20035
|
+
const [animationComplete, setAnimationComplete] = React14.useState(false);
|
|
20036
|
+
React14.useEffect(() => {
|
|
20037
|
+
setAnimationComplete(false);
|
|
20038
|
+
const timer = setTimeout(() => {
|
|
20039
|
+
setAnimationComplete(true);
|
|
20040
|
+
}, 600);
|
|
20041
|
+
return () => clearTimeout(timer);
|
|
20042
|
+
}, [month, year]);
|
|
19796
20043
|
const calendarData = React14.useMemo(() => {
|
|
19797
20044
|
const startOfMonth = dateFnsTz.toZonedTime(new Date(year, month, 1), configuredTimezone);
|
|
19798
20045
|
const endOfMonth = dateFnsTz.toZonedTime(new Date(year, month + 1, 0), configuredTimezone);
|
|
19799
20046
|
const totalDays = endOfMonth.getDate();
|
|
19800
20047
|
let startOffset = startOfMonth.getDay() - 1;
|
|
19801
20048
|
if (startOffset === -1) startOffset = 6;
|
|
19802
|
-
console.log("Calendar generation for:", {
|
|
19803
|
-
month: month + 1,
|
|
19804
|
-
year,
|
|
19805
|
-
startOffset,
|
|
19806
|
-
totalDays,
|
|
19807
|
-
configuredTimezone
|
|
19808
|
-
});
|
|
19809
|
-
console.log("Data points received:", data);
|
|
19810
20049
|
const calendar = Array(startOffset).fill(null);
|
|
19811
20050
|
for (let day = 1; day <= totalDays; day++) {
|
|
19812
20051
|
const currentDate = new Date(year, month, day);
|
|
@@ -19820,15 +20059,6 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19820
20059
|
const dataDate = new Date(d.date);
|
|
19821
20060
|
const dataDateStr = dataDate.toISOString().split("T")[0];
|
|
19822
20061
|
const matches = dataDateStr === dateToMatch;
|
|
19823
|
-
if (day <= 3 && matches) {
|
|
19824
|
-
console.log(`Found data match for day ${day}:`, {
|
|
19825
|
-
dataDate: dataDate.toISOString(),
|
|
19826
|
-
currentDate: currentTimezoneDate.toISOString(),
|
|
19827
|
-
dataDateStr,
|
|
19828
|
-
dateToMatch,
|
|
19829
|
-
data: d
|
|
19830
|
-
});
|
|
19831
|
-
}
|
|
19832
20062
|
return matches;
|
|
19833
20063
|
});
|
|
19834
20064
|
if (matchingData.length > 0) {
|
|
@@ -19839,32 +20069,10 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19839
20069
|
// Use the timezone-adjusted date for display
|
|
19840
20070
|
});
|
|
19841
20071
|
} else {
|
|
19842
|
-
calendar.push(
|
|
19843
|
-
date: currentTimezoneDate,
|
|
19844
|
-
dayShift: {
|
|
19845
|
-
efficiency: 0,
|
|
19846
|
-
output: 0,
|
|
19847
|
-
cycleTime: 0,
|
|
19848
|
-
pph: 0,
|
|
19849
|
-
pphThreshold: 0,
|
|
19850
|
-
idealOutput: 0,
|
|
19851
|
-
rank: 0,
|
|
19852
|
-
idleTime: 0
|
|
19853
|
-
},
|
|
19854
|
-
nightShift: {
|
|
19855
|
-
efficiency: 0,
|
|
19856
|
-
output: 0,
|
|
19857
|
-
cycleTime: 0,
|
|
19858
|
-
pph: 0,
|
|
19859
|
-
pphThreshold: 0,
|
|
19860
|
-
idealOutput: 0,
|
|
19861
|
-
rank: 0,
|
|
19862
|
-
idleTime: 0
|
|
19863
|
-
}
|
|
19864
|
-
});
|
|
20072
|
+
calendar.push(null);
|
|
19865
20073
|
}
|
|
19866
20074
|
}
|
|
19867
|
-
return calendar;
|
|
20075
|
+
return { calendar, startOffset };
|
|
19868
20076
|
}, [data, month, year, configuredTimezone]);
|
|
19869
20077
|
const monthlyMetrics = React14.useMemo(() => {
|
|
19870
20078
|
const validDays = data.filter((day) => {
|
|
@@ -19881,15 +20089,17 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19881
20089
|
return [];
|
|
19882
20090
|
}
|
|
19883
20091
|
return [day.dayShift, day.nightShift];
|
|
19884
|
-
})
|
|
20092
|
+
});
|
|
19885
20093
|
if (validShifts.length === 0) return null;
|
|
19886
20094
|
const badShiftsCount = validShifts.filter((shift) => shift.efficiency < 75).length;
|
|
20095
|
+
const totalIdleTime = validShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
|
|
20096
|
+
const avgIdleTime = Math.round(totalIdleTime / validShifts.length);
|
|
19887
20097
|
return {
|
|
19888
20098
|
avgEfficiency: Math.round(validShifts.reduce((sum, shift) => sum + shift.efficiency, 0) / validShifts.length),
|
|
19889
20099
|
avgCycleTime: Math.round(validShifts.reduce((sum, shift) => sum + shift.cycleTime, 0) / validShifts.length),
|
|
20100
|
+
avgIdleTime,
|
|
19890
20101
|
badDaysCount: badShiftsCount,
|
|
19891
|
-
totalDays: validShifts.length
|
|
19892
|
-
avgIdleTime: Math.round(validShifts.reduce((sum, shift) => sum + (shift.idleTime || 0), 0) / validShifts.length)
|
|
20102
|
+
totalDays: validShifts.length
|
|
19893
20103
|
};
|
|
19894
20104
|
}, [data, month, year, configuredTimezone]);
|
|
19895
20105
|
const handleDayClick = React14.useCallback((day, shift) => {
|
|
@@ -19937,7 +20147,6 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19937
20147
|
compareDate.setHours(0, 0, 0, 0);
|
|
19938
20148
|
if (compareDate.getDay() === 0) return "bg-gray-300";
|
|
19939
20149
|
if (compareDate > istNow) return "bg-gray-200";
|
|
19940
|
-
if (efficiency < 10) return "bg-gray-300";
|
|
19941
20150
|
if (efficiency >= 80) return "bg-[#00AB45]/90";
|
|
19942
20151
|
if (efficiency >= 70) return "bg-[#FFB020]/90";
|
|
19943
20152
|
return "bg-[#E34329]/90";
|
|
@@ -19976,38 +20185,55 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19976
20185
|
] })
|
|
19977
20186
|
] }) });
|
|
19978
20187
|
};
|
|
19979
|
-
const renderDayCell = React14.useCallback((day) => {
|
|
19980
|
-
if (
|
|
20188
|
+
const renderDayCell = React14.useCallback((day, dayNumber, index) => {
|
|
20189
|
+
if (dayNumber === null) {
|
|
20190
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full" });
|
|
20191
|
+
}
|
|
20192
|
+
const cellDate = dateFnsTz.toZonedTime(new Date(year, month, dayNumber), configuredTimezone);
|
|
20193
|
+
const isToday = isCurrentDate(cellDate);
|
|
20194
|
+
const isFuture = isFutureDate(cellDate);
|
|
20195
|
+
const isSunday = cellDate.getDay() === 0;
|
|
20196
|
+
if (!day) {
|
|
20197
|
+
let bgColor = "bg-gray-100";
|
|
20198
|
+
let textColor = "text-gray-400";
|
|
20199
|
+
if (isSunday) {
|
|
20200
|
+
bgColor = "bg-gray-200";
|
|
20201
|
+
textColor = "text-gray-500";
|
|
20202
|
+
}
|
|
20203
|
+
if (isFuture) {
|
|
20204
|
+
bgColor = "bg-gray-50";
|
|
20205
|
+
textColor = "text-gray-300";
|
|
20206
|
+
}
|
|
20207
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-full border border-gray-200 rounded-lg ${bgColor} ${animationComplete ? "transition-all duration-300 ease-in-out" : ""} cursor-not-allowed opacity-60`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `text-base font-medium ${textColor} ${isToday ? "text-blue-500" : ""}`, children: dayNumber }) }) });
|
|
20208
|
+
}
|
|
19981
20209
|
const shiftData = selectedShift === "day" ? day.dayShift : day.nightShift;
|
|
19982
|
-
const isToday = isCurrentDate(day.date);
|
|
19983
|
-
const isFuture = isFutureDate(day.date);
|
|
19984
|
-
const isInactive = shiftData.efficiency < 10;
|
|
19985
20210
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19986
20211
|
"div",
|
|
19987
20212
|
{
|
|
19988
|
-
className: `group h-full transition-all duration-
|
|
19989
|
-
onClick: () => !isFuture &&
|
|
20213
|
+
className: `group h-full ${animationComplete ? "transition-all duration-300 ease-in-out" : ""} ${!isFuture && animationComplete ? "cursor-pointer hover:opacity-90 hover:scale-105" : "cursor-not-allowed"}`,
|
|
20214
|
+
onClick: () => !isFuture && handleDayClick(day, selectedShift),
|
|
19990
20215
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `
|
|
19991
20216
|
${getPerformanceColor(shiftData.efficiency, day.date)}
|
|
19992
|
-
rounded-lg h-full p-2 relative transition-all duration-
|
|
20217
|
+
rounded-lg h-full p-2 relative ${animationComplete ? "transition-all duration-300 ease-in-out" : ""} shadow-sm
|
|
19993
20218
|
${isToday ? "ring-2 ring-blue-500 ring-offset-2 shadow-md" : ""}
|
|
19994
20219
|
`, children: [
|
|
19995
20220
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `
|
|
19996
|
-
text-base font-medium text-white flex items-center transition-all duration-
|
|
20221
|
+
text-base font-medium text-white flex items-center ${animationComplete ? "transition-all duration-300 ease-in-out" : ""}
|
|
19997
20222
|
${isToday ? "bg-blue-500 rounded-full w-7 h-7 justify-center" : ""}
|
|
19998
20223
|
`, children: day.date.getDate() }),
|
|
19999
|
-
!isFuture &&
|
|
20224
|
+
!isFuture && animationComplete && renderStats(shiftData, day.date)
|
|
20000
20225
|
] })
|
|
20001
20226
|
}
|
|
20002
20227
|
);
|
|
20003
|
-
}, [selectedShift, isCurrentDate, isFutureDate, getPerformanceColor, handleDayClick]);
|
|
20004
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `space-y-6 ${className || ""}`, children: [
|
|
20228
|
+
}, [selectedShift, isCurrentDate, isFutureDate, getPerformanceColor, handleDayClick, year, month, configuredTimezone, animationComplete]);
|
|
20229
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `calendar-wrapper space-y-6 ${className || ""} ${animationComplete ? "animation-complete" : ""}`, children: [
|
|
20230
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: styles } }),
|
|
20005
20231
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: [
|
|
20006
20232
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20007
20233
|
"button",
|
|
20008
20234
|
{
|
|
20009
20235
|
onClick: () => handleShiftChange("day"),
|
|
20010
|
-
className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShift === "day" ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" :
|
|
20236
|
+
className: `px-4 py-2 text-sm font-medium rounded-md ${animationComplete ? "transition-all duration-200" : ""} ${selectedShift === "day" ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : `text-gray-600 ${animationComplete ? "hover:text-gray-900 hover:bg-gray-100" : ""}`}`,
|
|
20011
20237
|
children: "Day Shift"
|
|
20012
20238
|
}
|
|
20013
20239
|
),
|
|
@@ -20015,23 +20241,27 @@ var WorkspaceHistoryCalendar = ({
|
|
|
20015
20241
|
"button",
|
|
20016
20242
|
{
|
|
20017
20243
|
onClick: () => handleShiftChange("night"),
|
|
20018
|
-
className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShift === "night" ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" :
|
|
20244
|
+
className: `px-4 py-2 text-sm font-medium rounded-md ${animationComplete ? "transition-all duration-200" : ""} ${selectedShift === "night" ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : `text-gray-600 ${animationComplete ? "hover:text-gray-900 hover:bg-gray-100" : ""}`}`,
|
|
20019
20245
|
children: "Night Shift"
|
|
20020
20246
|
}
|
|
20021
20247
|
)
|
|
20022
20248
|
] }) }),
|
|
20023
20249
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-8", children: [
|
|
20024
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20250
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "calendar-container bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20025
20251
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
|
|
20026
20252
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-gray-900 text-lg", children: selectedShift === "day" ? "Day Shifts" : "Night Shifts" }),
|
|
20027
20253
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Calendar view of daily performance" })
|
|
20028
20254
|
] }),
|
|
20029
20255
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6", children: [
|
|
20030
20256
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-2", children: WEEKDAYS2.map((day) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-600 text-center", children: day }, day)) }),
|
|
20031
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-2", children: calendarData.map((day, index) =>
|
|
20257
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-2", children: calendarData.calendar.map((day, index) => {
|
|
20258
|
+
const startOffset = calendarData.startOffset;
|
|
20259
|
+
const dayNumber = index >= startOffset ? index - startOffset + 1 : null;
|
|
20260
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-square relative transition-all duration-200 ease-in-out", children: renderDayCell(day, dayNumber && dayNumber <= new Date(year, month + 1, 0).getDate() ? dayNumber : null, index) }, index);
|
|
20261
|
+
}) })
|
|
20032
20262
|
] })
|
|
20033
20263
|
] }),
|
|
20034
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20264
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "calendar-container bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20035
20265
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
|
|
20036
20266
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-gray-900 text-lg", children: "Monthly Summary" }),
|
|
20037
20267
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Overview of monthly performance metrics" })
|
|
@@ -22554,7 +22784,7 @@ var getWorkspaceStyles = (position, isPlaceholder = false) => {
|
|
|
22554
22784
|
${additionalStyles}
|
|
22555
22785
|
${isPlaceholder ? "cursor-default" : ""}`;
|
|
22556
22786
|
};
|
|
22557
|
-
var
|
|
22787
|
+
var Legend6 = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3 bg-white/95 rounded-lg shadow-sm px-2 sm:px-4 py-1 sm:py-1.5 border border-gray-200/60 backdrop-blur-sm text-xs sm:text-sm", children: [
|
|
22558
22788
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-gray-700 hidden sm:block", children: "Efficiency:" }),
|
|
22559
22789
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-4", children: [
|
|
22560
22790
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-2", children: [
|
|
@@ -22602,7 +22832,7 @@ var WorkspaceGridItem = React14__namespace.default.memo(({
|
|
|
22602
22832
|
}, [data.efficiency, isInactive, position.size, position.orientation]);
|
|
22603
22833
|
const { arrow, color: arrowColor } = React14.useMemo(() => getTrendArrowAndColor2(data.trend_score), [data.trend_score]);
|
|
22604
22834
|
const workspaceNumber = React14.useMemo(() => getWorkspaceNumber(data.workspace_name), [data.workspace_name]);
|
|
22605
|
-
const
|
|
22835
|
+
const styles2 = React14.useMemo(() => getWorkspaceStyles(position, isInactive), [position, isInactive]);
|
|
22606
22836
|
const arrowPosition = React14.useMemo(() => getArrowPositionClass(position), [position]);
|
|
22607
22837
|
const handleClick = React14.useCallback((e) => {
|
|
22608
22838
|
e.preventDefault();
|
|
@@ -22653,7 +22883,7 @@ var WorkspaceGridItem = React14__namespace.default.memo(({
|
|
|
22653
22883
|
"button",
|
|
22654
22884
|
{
|
|
22655
22885
|
onClick: handleClick,
|
|
22656
|
-
className: `${
|
|
22886
|
+
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
|
|
22657
22887
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
22658
22888
|
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name)}` : getWorkspaceDisplayName(data.workspace_name),
|
|
22659
22889
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `font-semibold tracking-wide text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
|
|
@@ -22692,8 +22922,8 @@ var WorkspaceGrid = React14__namespace.default.memo(({
|
|
|
22692
22922
|
const { VideoGridView: VideoGridViewComponent } = useRegistry();
|
|
22693
22923
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
|
|
22694
22924
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 left-2 sm:left-4 right-2 sm:right-8 z-20", children: [
|
|
22695
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22696
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22925
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(Legend6, {}) }) }),
|
|
22926
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(Legend6, {}) })
|
|
22697
22927
|
] }),
|
|
22698
22928
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-10 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22699
22929
|
VideoGridViewComponent,
|
|
@@ -23296,6 +23526,78 @@ var WorkspaceMonthlyDataFetcher = ({
|
|
|
23296
23526
|
}, [workspaceId, selectedMonth, selectedYear, supabase, onDataLoaded, onLoadingChange]);
|
|
23297
23527
|
return null;
|
|
23298
23528
|
};
|
|
23529
|
+
var WorkspaceDisplayNameExample = () => {
|
|
23530
|
+
const { displayNames, loading, error } = useWorkspaceDisplayNames();
|
|
23531
|
+
const { displayName: singleWorkspaceName, loading: singleLoading } = useWorkspaceDisplayName("WS01");
|
|
23532
|
+
const { displayNames: displayNamesMap, loading: mapLoading } = useWorkspaceDisplayNamesMap(["WS01", "WS02", "WS03"]);
|
|
23533
|
+
if (loading) {
|
|
23534
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: "Loading workspace display names..." });
|
|
23535
|
+
}
|
|
23536
|
+
if (error) {
|
|
23537
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 text-red-600", children: [
|
|
23538
|
+
"Error loading workspace display names: ",
|
|
23539
|
+
error.message
|
|
23540
|
+
] });
|
|
23541
|
+
}
|
|
23542
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 max-w-4xl mx-auto", children: [
|
|
23543
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold mb-6", children: "Workspace Display Names Examples" }),
|
|
23544
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8", children: [
|
|
23545
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-4", children: "1. All Workspace Display Names" }),
|
|
23546
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: Object.entries(displayNames).map(([workspaceId, displayName]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 border rounded-lg", children: [
|
|
23547
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: workspaceId }),
|
|
23548
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-600", children: displayName })
|
|
23549
|
+
] }, workspaceId)) }),
|
|
23550
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 p-3 bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm", children: [
|
|
23551
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Using utility function:" }),
|
|
23552
|
+
` getWorkspaceDisplayName('WS01') = "`,
|
|
23553
|
+
getWorkspaceDisplayName("WS01"),
|
|
23554
|
+
'"'
|
|
23555
|
+
] }) })
|
|
23556
|
+
] }),
|
|
23557
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8", children: [
|
|
23558
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-4", children: "2. Single Workspace Display Name" }),
|
|
23559
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border rounded-lg", children: singleLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading WS01..." }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
23560
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "WS01:" }),
|
|
23561
|
+
" ",
|
|
23562
|
+
singleWorkspaceName
|
|
23563
|
+
] }) })
|
|
23564
|
+
] }),
|
|
23565
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8", children: [
|
|
23566
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-4", children: "3. Specific Workspaces Map" }),
|
|
23567
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: mapLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading specific workspaces..." }) : Object.entries(displayNamesMap).map(([workspaceId, displayName]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 border rounded-lg", children: [
|
|
23568
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: workspaceId }),
|
|
23569
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-600", children: displayName })
|
|
23570
|
+
] }, workspaceId)) })
|
|
23571
|
+
] }),
|
|
23572
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 p-4 bg-blue-50 rounded-lg", children: [
|
|
23573
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "Migration Guide" }),
|
|
23574
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm space-y-2", children: [
|
|
23575
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Before (hardcoded):" }) }),
|
|
23576
|
+
/* @__PURE__ */ jsxRuntime.jsxs("code", { className: "block p-2 bg-gray-100 rounded", children: [
|
|
23577
|
+
"import ",
|
|
23578
|
+
`{getWorkspaceDisplayName}`,
|
|
23579
|
+
" from '@optifye/dashboard-core';",
|
|
23580
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
23581
|
+
"const name = getWorkspaceDisplayName('WS01'); // Synchronous, hardcoded"
|
|
23582
|
+
] }),
|
|
23583
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "After (from Supabase):" }) }),
|
|
23584
|
+
/* @__PURE__ */ jsxRuntime.jsxs("code", { className: "block p-2 bg-gray-100 rounded", children: [
|
|
23585
|
+
"import ",
|
|
23586
|
+
`{useWorkspaceDisplayName}`,
|
|
23587
|
+
" from '@optifye/dashboard-core';",
|
|
23588
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
23589
|
+
"const ",
|
|
23590
|
+
`{displayName, loading}`,
|
|
23591
|
+
" = useWorkspaceDisplayName('WS01'); // Async, from database"
|
|
23592
|
+
] }),
|
|
23593
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-blue-700", children: [
|
|
23594
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Note:" }),
|
|
23595
|
+
" The old synchronous functions are still available as fallbacks and for backward compatibility."
|
|
23596
|
+
] })
|
|
23597
|
+
] })
|
|
23598
|
+
] })
|
|
23599
|
+
] });
|
|
23600
|
+
};
|
|
23299
23601
|
var Breadcrumbs = ({ items }) => {
|
|
23300
23602
|
const navigation = useNavigation();
|
|
23301
23603
|
if (!items || items.length === 0) return null;
|
|
@@ -24741,6 +25043,234 @@ var AIAgentView = () => {
|
|
|
24741
25043
|
});
|
|
24742
25044
|
}
|
|
24743
25045
|
const renderAssistantContent = (content) => {
|
|
25046
|
+
const parseChartPatterns = (text) => {
|
|
25047
|
+
const chartElements = [];
|
|
25048
|
+
let lastIndex = 0;
|
|
25049
|
+
const chartRegex = /\[\s*(?:Calling\s+|CALL\s+)?(create_[a-z_]+)\s*\(([\s\S]*?)\)\s*\]/g;
|
|
25050
|
+
let match;
|
|
25051
|
+
const processedIndices = /* @__PURE__ */ new Set();
|
|
25052
|
+
while ((match = chartRegex.exec(text)) !== null) {
|
|
25053
|
+
const startIndex = match.index;
|
|
25054
|
+
const endIndex = startIndex + match[0].length;
|
|
25055
|
+
if (!processedIndices.has(startIndex)) {
|
|
25056
|
+
processedIndices.add(startIndex);
|
|
25057
|
+
if (startIndex > lastIndex) {
|
|
25058
|
+
const beforeText = text.substring(lastIndex, startIndex);
|
|
25059
|
+
chartElements.push(
|
|
25060
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25061
|
+
"div",
|
|
25062
|
+
{
|
|
25063
|
+
dangerouslySetInnerHTML: { __html: formatMessage(beforeText) }
|
|
25064
|
+
},
|
|
25065
|
+
`text-${lastIndex}`
|
|
25066
|
+
)
|
|
25067
|
+
);
|
|
25068
|
+
}
|
|
25069
|
+
const chartType = match[1];
|
|
25070
|
+
const argsString = match[2];
|
|
25071
|
+
try {
|
|
25072
|
+
const args = parseChartArguments(argsString);
|
|
25073
|
+
const chartElement = renderChart(chartType, args, startIndex);
|
|
25074
|
+
if (chartElement) {
|
|
25075
|
+
chartElements.push(chartElement);
|
|
25076
|
+
}
|
|
25077
|
+
} catch (error) {
|
|
25078
|
+
console.error(`Failed to parse chart ${chartType}:`, error);
|
|
25079
|
+
chartElements.push(
|
|
25080
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
25081
|
+
"div",
|
|
25082
|
+
{
|
|
25083
|
+
className: "text-red-500 text-sm",
|
|
25084
|
+
children: [
|
|
25085
|
+
"Error rendering chart: ",
|
|
25086
|
+
match[0]
|
|
25087
|
+
]
|
|
25088
|
+
},
|
|
25089
|
+
`error-${startIndex}`
|
|
25090
|
+
)
|
|
25091
|
+
);
|
|
25092
|
+
}
|
|
25093
|
+
lastIndex = endIndex;
|
|
25094
|
+
}
|
|
25095
|
+
}
|
|
25096
|
+
if (lastIndex < text.length) {
|
|
25097
|
+
const remainingText = text.substring(lastIndex);
|
|
25098
|
+
chartElements.push(
|
|
25099
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25100
|
+
"div",
|
|
25101
|
+
{
|
|
25102
|
+
dangerouslySetInnerHTML: { __html: formatMessage(remainingText) }
|
|
25103
|
+
},
|
|
25104
|
+
`text-${lastIndex}`
|
|
25105
|
+
)
|
|
25106
|
+
);
|
|
25107
|
+
}
|
|
25108
|
+
if (chartElements.length === 1 && lastIndex === 0) {
|
|
25109
|
+
return null;
|
|
25110
|
+
}
|
|
25111
|
+
return chartElements;
|
|
25112
|
+
};
|
|
25113
|
+
const parseChartArguments = (argsString) => {
|
|
25114
|
+
const args = {};
|
|
25115
|
+
const jsonParamRegex = /(\w+)\s*=\s*(\[[\s\S]*?\](?=\s*(?:,|\s*\)|\s*$))|\{[\s\S]*?\}(?=\s*(?:,|\s*\)|\s*$)))/g;
|
|
25116
|
+
let jsonMatch;
|
|
25117
|
+
while ((jsonMatch = jsonParamRegex.exec(argsString)) !== null) {
|
|
25118
|
+
const paramName = jsonMatch[1];
|
|
25119
|
+
const jsonValue = jsonMatch[2];
|
|
25120
|
+
try {
|
|
25121
|
+
args[paramName] = JSON.parse(jsonValue);
|
|
25122
|
+
argsString = argsString.replace(jsonMatch[0], "");
|
|
25123
|
+
} catch (e) {
|
|
25124
|
+
console.error(`Failed to parse ${paramName} JSON:`, e);
|
|
25125
|
+
}
|
|
25126
|
+
}
|
|
25127
|
+
const argRegex = /(\w+)\s*=\s*("([^"]*)"|'([^']*)'|([^,\s\)]+))/g;
|
|
25128
|
+
let argMatch;
|
|
25129
|
+
while ((argMatch = argRegex.exec(argsString)) !== null) {
|
|
25130
|
+
const key = argMatch[1];
|
|
25131
|
+
const value = argMatch[3] || argMatch[4] || argMatch[5];
|
|
25132
|
+
if (key === "data") continue;
|
|
25133
|
+
if (value === "true" || value === "True") {
|
|
25134
|
+
args[key] = true;
|
|
25135
|
+
} else if (value === "false" || value === "False") {
|
|
25136
|
+
args[key] = false;
|
|
25137
|
+
} else if (value === "null" || value === "None") {
|
|
25138
|
+
args[key] = null;
|
|
25139
|
+
} else if (!isNaN(Number(value)) && value !== "") {
|
|
25140
|
+
args[key] = Number(value);
|
|
25141
|
+
} else {
|
|
25142
|
+
args[key] = value;
|
|
25143
|
+
}
|
|
25144
|
+
}
|
|
25145
|
+
return args;
|
|
25146
|
+
};
|
|
25147
|
+
const renderChart = (chartType, args, key) => {
|
|
25148
|
+
switch (chartType) {
|
|
25149
|
+
case "create_gauge_chart":
|
|
25150
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-6 h-64 w-full flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
25151
|
+
GaugeChart,
|
|
25152
|
+
{
|
|
25153
|
+
value: args.value || 0,
|
|
25154
|
+
min: args.min_value || 0,
|
|
25155
|
+
max: args.max_value || 100,
|
|
25156
|
+
target: args.target,
|
|
25157
|
+
label: args.title || "",
|
|
25158
|
+
unit: args.unit || "",
|
|
25159
|
+
thresholds: args.thresholds,
|
|
25160
|
+
className: "w-full max-w-sm"
|
|
25161
|
+
}
|
|
25162
|
+
) }, `gauge-${key}`);
|
|
25163
|
+
case "create_bar_chart":
|
|
25164
|
+
if (!args.data || !args.x_field || !args.y_field) {
|
|
25165
|
+
console.error("Bar chart missing required parameters");
|
|
25166
|
+
return null;
|
|
25167
|
+
}
|
|
25168
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", style: { maxWidth: args.max_width || "100%" }, children: [
|
|
25169
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25170
|
+
BarChart,
|
|
25171
|
+
{
|
|
25172
|
+
data: args.data,
|
|
25173
|
+
bars: [{
|
|
25174
|
+
dataKey: args.y_field,
|
|
25175
|
+
fill: args.color || "#3b82f6",
|
|
25176
|
+
labelList: args.show_values
|
|
25177
|
+
}],
|
|
25178
|
+
xAxisDataKey: args.x_field,
|
|
25179
|
+
className: "h-64",
|
|
25180
|
+
showLegend: false
|
|
25181
|
+
}
|
|
25182
|
+
),
|
|
25183
|
+
args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
|
|
25184
|
+
] }, `bar-${key}`);
|
|
25185
|
+
case "create_line_chart":
|
|
25186
|
+
if (!args.data || !args.x_field || !args.y_field) {
|
|
25187
|
+
console.error("Line chart missing required parameters");
|
|
25188
|
+
return null;
|
|
25189
|
+
}
|
|
25190
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full", style: {
|
|
25191
|
+
height: args.height || 256,
|
|
25192
|
+
width: args.width || "100%"
|
|
25193
|
+
}, children: [
|
|
25194
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25195
|
+
LineChart,
|
|
25196
|
+
{
|
|
25197
|
+
data: args.data,
|
|
25198
|
+
lines: [{
|
|
25199
|
+
dataKey: args.y_field,
|
|
25200
|
+
stroke: "#3b82f6",
|
|
25201
|
+
strokeWidth: 2
|
|
25202
|
+
}],
|
|
25203
|
+
xAxisDataKey: args.x_field,
|
|
25204
|
+
className: "h-full",
|
|
25205
|
+
showLegend: false
|
|
25206
|
+
}
|
|
25207
|
+
),
|
|
25208
|
+
args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
|
|
25209
|
+
] }, `line-${key}`);
|
|
25210
|
+
case "create_pie_chart":
|
|
25211
|
+
if (!args.data || !args.label_field || !args.value_field) {
|
|
25212
|
+
console.error("Pie chart missing required parameters");
|
|
25213
|
+
return null;
|
|
25214
|
+
}
|
|
25215
|
+
const pieData = args.data.map((item) => ({
|
|
25216
|
+
name: item[args.label_field],
|
|
25217
|
+
value: item[args.value_field]
|
|
25218
|
+
}));
|
|
25219
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full flex flex-col items-center", children: [
|
|
25220
|
+
args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
|
|
25221
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-64 w-full max-w-md", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
25222
|
+
PieChart4,
|
|
25223
|
+
{
|
|
25224
|
+
data: pieData,
|
|
25225
|
+
showPercentages: args.show_percentages || false
|
|
25226
|
+
}
|
|
25227
|
+
) })
|
|
25228
|
+
] }, `pie-${key}`);
|
|
25229
|
+
case "create_comparison_table":
|
|
25230
|
+
if (!args.data) {
|
|
25231
|
+
console.error("Comparison table missing required data");
|
|
25232
|
+
return null;
|
|
25233
|
+
}
|
|
25234
|
+
const columns = args.columns || Object.keys(args.data[0] || {});
|
|
25235
|
+
let sortedData = [...args.data];
|
|
25236
|
+
if (args.sort_by && columns.includes(args.sort_by)) {
|
|
25237
|
+
sortedData.sort((a, b) => {
|
|
25238
|
+
const aVal = a[args.sort_by];
|
|
25239
|
+
const bVal = b[args.sort_by];
|
|
25240
|
+
const comparison = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
25241
|
+
return args.sort_descending === false ? comparison : -comparison;
|
|
25242
|
+
});
|
|
25243
|
+
}
|
|
25244
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-6 w-full overflow-x-auto", children: [
|
|
25245
|
+
args.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
|
|
25246
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
|
|
25247
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
25248
|
+
"th",
|
|
25249
|
+
{
|
|
25250
|
+
className: `px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
|
|
25251
|
+
children: col
|
|
25252
|
+
},
|
|
25253
|
+
col
|
|
25254
|
+
)) }) }),
|
|
25255
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
25256
|
+
"td",
|
|
25257
|
+
{
|
|
25258
|
+
className: `px-4 py-2 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
|
|
25259
|
+
children: row[col]
|
|
25260
|
+
},
|
|
25261
|
+
col
|
|
25262
|
+
)) }, rowIdx)) })
|
|
25263
|
+
] })
|
|
25264
|
+
] }, `table-${key}`);
|
|
25265
|
+
default:
|
|
25266
|
+
console.warn(`Unknown chart type: ${chartType}`);
|
|
25267
|
+
return null;
|
|
25268
|
+
}
|
|
25269
|
+
};
|
|
25270
|
+
const chartContent = parseChartPatterns(content);
|
|
25271
|
+
if (chartContent) {
|
|
25272
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "formatted-content", children: chartContent });
|
|
25273
|
+
}
|
|
24744
25274
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24745
25275
|
"div",
|
|
24746
25276
|
{
|
|
@@ -30164,6 +30694,11 @@ var WorkspaceDetailView = ({
|
|
|
30164
30694
|
return getOperationalDate();
|
|
30165
30695
|
}, [isHistoricView, date]);
|
|
30166
30696
|
const handleMonthlyDataLoaded = React14.useCallback((data) => {
|
|
30697
|
+
console.log("[handleMonthlyDataLoaded] Received data:", {
|
|
30698
|
+
dataLength: data?.length,
|
|
30699
|
+
isArray: Array.isArray(data),
|
|
30700
|
+
sample: data?.[0]
|
|
30701
|
+
});
|
|
30167
30702
|
if (!data || !Array.isArray(data)) {
|
|
30168
30703
|
console.error("Invalid monthly metrics data received:", data);
|
|
30169
30704
|
setMonthlyData([]);
|
|
@@ -30181,22 +30716,35 @@ var WorkspaceDetailView = ({
|
|
|
30181
30716
|
if (!dayEntry) {
|
|
30182
30717
|
dayEntry = {
|
|
30183
30718
|
date: dateObj,
|
|
30184
|
-
dayShift:
|
|
30185
|
-
|
|
30719
|
+
dayShift: null,
|
|
30720
|
+
// Start with null instead of zeros
|
|
30721
|
+
nightShift: null
|
|
30722
|
+
// Start with null instead of zeros
|
|
30186
30723
|
};
|
|
30187
30724
|
dayDataMap.set(dateKey, dayEntry);
|
|
30188
30725
|
}
|
|
30189
|
-
const
|
|
30190
|
-
|
|
30191
|
-
|
|
30192
|
-
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
|
|
30726
|
+
const shiftData = {
|
|
30727
|
+
efficiency: metric.avg_efficiency || 0,
|
|
30728
|
+
output: metric.total_output || 0,
|
|
30729
|
+
cycleTime: metric.avg_cycle_time || 0,
|
|
30730
|
+
pph: metric.avg_pph || 0,
|
|
30731
|
+
pphThreshold: metric.pph_threshold || 0,
|
|
30732
|
+
idealOutput: metric.ideal_output || 0,
|
|
30733
|
+
rank: metric.workspace_rank || 0,
|
|
30734
|
+
idleTime: metric.idle_time || 0
|
|
30735
|
+
};
|
|
30736
|
+
if (metric.shift_id === 0) {
|
|
30737
|
+
dayEntry.dayShift = shiftData;
|
|
30738
|
+
} else {
|
|
30739
|
+
dayEntry.nightShift = shiftData;
|
|
30740
|
+
}
|
|
30198
30741
|
});
|
|
30199
|
-
const processedData = Array.from(dayDataMap.values())
|
|
30742
|
+
const processedData = Array.from(dayDataMap.values()).filter((entry) => entry.dayShift !== null || entry.nightShift !== null).map((entry) => ({
|
|
30743
|
+
date: entry.date,
|
|
30744
|
+
// If a shift is null (no data), provide zeros for compatibility
|
|
30745
|
+
dayShift: entry.dayShift || { efficiency: 0, output: 0, cycleTime: 0, pph: 0, pphThreshold: 0, idealOutput: 0, rank: 0, idleTime: 0 },
|
|
30746
|
+
nightShift: entry.nightShift || { efficiency: 0, output: 0, cycleTime: 0, pph: 0, pphThreshold: 0, idealOutput: 0, rank: 0, idleTime: 0 }
|
|
30747
|
+
}));
|
|
30200
30748
|
console.log(`[handleMonthlyDataLoaded] Transformed data for calendar:`, {
|
|
30201
30749
|
count: processedData.length,
|
|
30202
30750
|
sample: processedData.slice(0, 1)
|
|
@@ -30656,7 +31204,7 @@ var WorkspaceDetailView = ({
|
|
|
30656
31204
|
}
|
|
30657
31205
|
)
|
|
30658
31206
|
] }),
|
|
30659
|
-
|
|
31207
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
30660
31208
|
WorkspaceHistoryCalendar,
|
|
30661
31209
|
{
|
|
30662
31210
|
data: monthlyData,
|
|
@@ -30978,6 +31526,7 @@ exports.DebugAuth = DebugAuth;
|
|
|
30978
31526
|
exports.DebugAuthView = DebugAuthView_default;
|
|
30979
31527
|
exports.EmptyStateMessage = EmptyStateMessage;
|
|
30980
31528
|
exports.FactoryView = FactoryView_default;
|
|
31529
|
+
exports.GaugeChart = GaugeChart;
|
|
30981
31530
|
exports.GridComponentsPlaceholder = GridComponentsPlaceholder;
|
|
30982
31531
|
exports.Header = Header;
|
|
30983
31532
|
exports.HelpView = HelpView_default;
|
|
@@ -30993,7 +31542,7 @@ exports.KPIsOverviewView = KPIsOverviewView_default;
|
|
|
30993
31542
|
exports.LINE_1_UUID = LINE_1_UUID;
|
|
30994
31543
|
exports.LargeOutputProgressChart = LargeOutputProgressChart;
|
|
30995
31544
|
exports.LeaderboardDetailView = LeaderboardDetailView_default;
|
|
30996
|
-
exports.Legend =
|
|
31545
|
+
exports.Legend = Legend6;
|
|
30997
31546
|
exports.LineChart = LineChart;
|
|
30998
31547
|
exports.LineHistoryCalendar = LineHistoryCalendar;
|
|
30999
31548
|
exports.LineMonthlyHistory = LineMonthlyHistory;
|
|
@@ -31013,6 +31562,7 @@ exports.NoWorkspaceData = NoWorkspaceData;
|
|
|
31013
31562
|
exports.OptifyeAgentClient = OptifyeAgentClient;
|
|
31014
31563
|
exports.OutputProgressChart = OutputProgressChart;
|
|
31015
31564
|
exports.PageHeader = PageHeader;
|
|
31565
|
+
exports.PieChart = PieChart4;
|
|
31016
31566
|
exports.ProfileView = ProfileView_default;
|
|
31017
31567
|
exports.RegistryProvider = RegistryProvider;
|
|
31018
31568
|
exports.S3Service = S3Service;
|
|
@@ -31047,6 +31597,7 @@ exports.WORKSPACE_POSITIONS = WORKSPACE_POSITIONS;
|
|
|
31047
31597
|
exports.WhatsAppShareButton = WhatsAppShareButton;
|
|
31048
31598
|
exports.WorkspaceCard = WorkspaceCard;
|
|
31049
31599
|
exports.WorkspaceDetailView = WorkspaceDetailView_default;
|
|
31600
|
+
exports.WorkspaceDisplayNameExample = WorkspaceDisplayNameExample;
|
|
31050
31601
|
exports.WorkspaceGrid = WorkspaceGrid;
|
|
31051
31602
|
exports.WorkspaceGridItem = WorkspaceGridItem;
|
|
31052
31603
|
exports.WorkspaceHistoryCalendar = WorkspaceHistoryCalendar;
|