@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.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import Hls2 from 'hls.js';
|
|
|
10
10
|
import useSWR from 'swr';
|
|
11
11
|
import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
|
|
12
12
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
13
|
-
import { ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, ReferenceLine,
|
|
13
|
+
import { Bar, LabelList, ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, ReferenceLine, Cell, PieChart, Pie, Legend, LineChart as LineChart$1, Line } from 'recharts';
|
|
14
14
|
import { Slot } from '@radix-ui/react-slot';
|
|
15
15
|
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Settings, LifeBuoy, Loader2, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
16
16
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
@@ -991,7 +991,7 @@ var dashboardService = {
|
|
|
991
991
|
const formattedStartDate = formatDate(startDate);
|
|
992
992
|
const formattedEndDate = formatDate(endDate);
|
|
993
993
|
try {
|
|
994
|
-
const { data, error } = await supabase.from(metricsTable).select("date, shift_id, efficiency, total_output, avg_cycle_time,
|
|
994
|
+
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 });
|
|
995
995
|
if (error) throw error;
|
|
996
996
|
if (!data) return [];
|
|
997
997
|
const transformedData = data.map((item) => ({
|
|
@@ -1004,8 +1004,7 @@ var dashboardService = {
|
|
|
1004
1004
|
ideal_output: item.ideal_output || 0,
|
|
1005
1005
|
avg_pph: item.avg_pph || 0,
|
|
1006
1006
|
pph_threshold: item.pph_threshold || 0,
|
|
1007
|
-
workspace_rank: item.workspace_rank || 0
|
|
1008
|
-
idle_time: item.idle_time || 0
|
|
1007
|
+
workspace_rank: item.workspace_rank || 0
|
|
1009
1008
|
}));
|
|
1010
1009
|
return transformedData;
|
|
1011
1010
|
} catch (err) {
|
|
@@ -2081,28 +2080,42 @@ var AuthProvider = ({ children }) => {
|
|
|
2081
2080
|
id: supabaseUser.id,
|
|
2082
2081
|
email: supabaseUser.email
|
|
2083
2082
|
};
|
|
2084
|
-
if (!
|
|
2083
|
+
if (!supabase) return basicUser;
|
|
2085
2084
|
try {
|
|
2086
2085
|
const timeoutPromise = new Promise(
|
|
2087
2086
|
(_, reject) => setTimeout(() => reject(new Error("Profile fetch timeout")), 5e3)
|
|
2088
2087
|
);
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2088
|
+
const rolePromise = supabase.from("user_roles").select("role_level").eq("user_id", supabaseUser.id).single();
|
|
2089
|
+
let profilePromise = null;
|
|
2090
|
+
if (userProfileTable) {
|
|
2091
|
+
profilePromise = supabase.from(userProfileTable).select(roleColumn).eq("id", supabaseUser.id).single();
|
|
2092
|
+
}
|
|
2093
|
+
const [roleResult, profileResult] = await Promise.race([
|
|
2094
|
+
Promise.all([
|
|
2095
|
+
rolePromise,
|
|
2096
|
+
profilePromise || Promise.resolve(null)
|
|
2097
|
+
]),
|
|
2098
|
+
timeoutPromise.then(() => {
|
|
2099
|
+
throw new Error("Timeout");
|
|
2100
|
+
})
|
|
2093
2101
|
]);
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2102
|
+
let roleLevel = void 0;
|
|
2103
|
+
if (roleResult && !roleResult.error && roleResult.data) {
|
|
2104
|
+
roleLevel = roleResult.data.role_level;
|
|
2105
|
+
} else if (roleResult?.error) {
|
|
2106
|
+
console.log("Error fetching role_level:", roleResult.error.message);
|
|
2107
|
+
}
|
|
2108
|
+
let roleValue = void 0;
|
|
2109
|
+
if (profileResult && !profileResult.error && profileResult.data) {
|
|
2110
|
+
roleValue = profileResult.data[roleColumn];
|
|
2101
2111
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2112
|
+
return {
|
|
2113
|
+
...basicUser,
|
|
2114
|
+
role: roleValue,
|
|
2115
|
+
role_level: roleLevel
|
|
2116
|
+
};
|
|
2104
2117
|
} catch (err) {
|
|
2105
|
-
console.error("Error fetching user
|
|
2118
|
+
console.error("Error fetching user details:", err);
|
|
2106
2119
|
return basicUser;
|
|
2107
2120
|
}
|
|
2108
2121
|
}, [supabase, userProfileTable, roleColumn]);
|
|
@@ -2137,7 +2150,8 @@ var AuthProvider = ({ children }) => {
|
|
|
2137
2150
|
email: userDetails.email,
|
|
2138
2151
|
name: userDetails.email,
|
|
2139
2152
|
// using email as the display name for now
|
|
2140
|
-
role: userDetails.role
|
|
2153
|
+
role: userDetails.role,
|
|
2154
|
+
role_level: userDetails.role_level
|
|
2141
2155
|
});
|
|
2142
2156
|
}
|
|
2143
2157
|
}
|
|
@@ -2175,7 +2189,8 @@ var AuthProvider = ({ children }) => {
|
|
|
2175
2189
|
identifyCoreUser(userDetails.id, {
|
|
2176
2190
|
email: userDetails.email,
|
|
2177
2191
|
name: userDetails.email,
|
|
2178
|
-
role: userDetails.role
|
|
2192
|
+
role: userDetails.role,
|
|
2193
|
+
role_level: userDetails.role_level
|
|
2179
2194
|
});
|
|
2180
2195
|
}
|
|
2181
2196
|
}
|
|
@@ -14702,16 +14717,16 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14702
14717
|
if (!this.isVisible) {
|
|
14703
14718
|
return hiddenVisibility;
|
|
14704
14719
|
}
|
|
14705
|
-
const
|
|
14720
|
+
const styles2 = {
|
|
14706
14721
|
visibility: ""
|
|
14707
14722
|
};
|
|
14708
14723
|
const transformTemplate = this.getTransformTemplate();
|
|
14709
14724
|
if (this.needsReset) {
|
|
14710
14725
|
this.needsReset = false;
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
return
|
|
14726
|
+
styles2.opacity = "";
|
|
14727
|
+
styles2.pointerEvents = resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "";
|
|
14728
|
+
styles2.transform = transformTemplate ? transformTemplate(this.latestValues, "") : "none";
|
|
14729
|
+
return styles2;
|
|
14715
14730
|
}
|
|
14716
14731
|
const lead = this.getLead();
|
|
14717
14732
|
if (!this.projectionDelta || !this.layout || !lead.target) {
|
|
@@ -14728,35 +14743,35 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14728
14743
|
}
|
|
14729
14744
|
const valuesToRender = lead.animationValues || lead.latestValues;
|
|
14730
14745
|
this.applyTransformsToTarget();
|
|
14731
|
-
|
|
14746
|
+
styles2.transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
|
|
14732
14747
|
if (transformTemplate) {
|
|
14733
|
-
|
|
14748
|
+
styles2.transform = transformTemplate(valuesToRender, styles2.transform);
|
|
14734
14749
|
}
|
|
14735
14750
|
const { x, y } = this.projectionDelta;
|
|
14736
|
-
|
|
14751
|
+
styles2.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
|
|
14737
14752
|
if (lead.animationValues) {
|
|
14738
|
-
|
|
14753
|
+
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;
|
|
14739
14754
|
} else {
|
|
14740
|
-
|
|
14755
|
+
styles2.opacity = lead === this ? valuesToRender.opacity !== void 0 ? valuesToRender.opacity : "" : valuesToRender.opacityExit !== void 0 ? valuesToRender.opacityExit : 0;
|
|
14741
14756
|
}
|
|
14742
14757
|
for (const key in scaleCorrectors) {
|
|
14743
14758
|
if (valuesToRender[key] === void 0)
|
|
14744
14759
|
continue;
|
|
14745
14760
|
const { correct, applyTo } = scaleCorrectors[key];
|
|
14746
|
-
const corrected =
|
|
14761
|
+
const corrected = styles2.transform === "none" ? valuesToRender[key] : correct(valuesToRender[key], lead);
|
|
14747
14762
|
if (applyTo) {
|
|
14748
14763
|
const num = applyTo.length;
|
|
14749
14764
|
for (let i = 0; i < num; i++) {
|
|
14750
|
-
|
|
14765
|
+
styles2[applyTo[i]] = corrected;
|
|
14751
14766
|
}
|
|
14752
14767
|
} else {
|
|
14753
|
-
|
|
14768
|
+
styles2[key] = corrected;
|
|
14754
14769
|
}
|
|
14755
14770
|
}
|
|
14756
14771
|
if (this.options.layoutId) {
|
|
14757
|
-
|
|
14772
|
+
styles2.pointerEvents = lead === this ? resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "" : "none";
|
|
14758
14773
|
}
|
|
14759
|
-
return
|
|
14774
|
+
return styles2;
|
|
14760
14775
|
}
|
|
14761
14776
|
clearSnapshot() {
|
|
14762
14777
|
this.resumeFrom = this.snapshot = void 0;
|
|
@@ -16863,23 +16878,35 @@ var HourlyOutputChart = ({
|
|
|
16863
16878
|
const [animatedData, setAnimatedData] = React14__default.useState(Array(SHIFT_DURATION).fill(0));
|
|
16864
16879
|
const prevDataRef = React14__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
16865
16880
|
const animationFrameRef = React14__default.useRef(null);
|
|
16866
|
-
const [
|
|
16881
|
+
const [idleBarState, setIdleBarState] = React14__default.useState({
|
|
16882
|
+
visible: showIdleTime,
|
|
16883
|
+
key: 0,
|
|
16884
|
+
shouldAnimate: false
|
|
16885
|
+
});
|
|
16867
16886
|
const prevShowIdleTimeRef = React14__default.useRef(showIdleTime);
|
|
16868
|
-
const
|
|
16887
|
+
const stateUpdateTimeoutRef = React14__default.useRef(null);
|
|
16869
16888
|
React14__default.useEffect(() => {
|
|
16889
|
+
if (stateUpdateTimeoutRef.current) {
|
|
16890
|
+
clearTimeout(stateUpdateTimeoutRef.current);
|
|
16891
|
+
}
|
|
16870
16892
|
if (showIdleTime && !prevShowIdleTimeRef.current) {
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
16877
|
-
|
|
16893
|
+
requestAnimationFrame(() => {
|
|
16894
|
+
setIdleBarState({
|
|
16895
|
+
visible: true,
|
|
16896
|
+
key: Date.now(),
|
|
16897
|
+
shouldAnimate: true
|
|
16898
|
+
});
|
|
16899
|
+
stateUpdateTimeoutRef.current = setTimeout(() => {
|
|
16900
|
+
setIdleBarState((prev) => ({ ...prev, shouldAnimate: false }));
|
|
16901
|
+
}, 1100);
|
|
16902
|
+
});
|
|
16903
|
+
} else if (!showIdleTime && prevShowIdleTimeRef.current) {
|
|
16904
|
+
setIdleBarState((prev) => ({ ...prev, visible: false }));
|
|
16878
16905
|
}
|
|
16879
16906
|
prevShowIdleTimeRef.current = showIdleTime;
|
|
16880
16907
|
return () => {
|
|
16881
|
-
if (
|
|
16882
|
-
clearTimeout(
|
|
16908
|
+
if (stateUpdateTimeoutRef.current) {
|
|
16909
|
+
clearTimeout(stateUpdateTimeoutRef.current);
|
|
16883
16910
|
}
|
|
16884
16911
|
};
|
|
16885
16912
|
}, [showIdleTime]);
|
|
@@ -16972,6 +16999,55 @@ var HourlyOutputChart = ({
|
|
|
16972
16999
|
};
|
|
16973
17000
|
});
|
|
16974
17001
|
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
17002
|
+
const IdleBar = React14__default.useMemo(() => {
|
|
17003
|
+
if (!idleBarState.visible) return null;
|
|
17004
|
+
return /* @__PURE__ */ jsx(
|
|
17005
|
+
Bar,
|
|
17006
|
+
{
|
|
17007
|
+
dataKey: "idleMinutes",
|
|
17008
|
+
yAxisId: "idle",
|
|
17009
|
+
maxBarSize: 35,
|
|
17010
|
+
radius: [10, 10, 0, 0],
|
|
17011
|
+
fill: "url(#idlePattern)",
|
|
17012
|
+
opacity: 0.7,
|
|
17013
|
+
isAnimationActive: idleBarState.shouldAnimate,
|
|
17014
|
+
animationBegin: 0,
|
|
17015
|
+
animationDuration: 1e3,
|
|
17016
|
+
animationEasing: "ease-out",
|
|
17017
|
+
children: /* @__PURE__ */ jsx(
|
|
17018
|
+
LabelList,
|
|
17019
|
+
{
|
|
17020
|
+
dataKey: "idleMinutes",
|
|
17021
|
+
position: "top",
|
|
17022
|
+
content: (props) => {
|
|
17023
|
+
const { x, y, width, value } = props;
|
|
17024
|
+
if (!value || value === 0) return null;
|
|
17025
|
+
return /* @__PURE__ */ jsxs(
|
|
17026
|
+
"text",
|
|
17027
|
+
{
|
|
17028
|
+
x: x + width / 2,
|
|
17029
|
+
y: y - 2,
|
|
17030
|
+
textAnchor: "middle",
|
|
17031
|
+
fontSize: "9",
|
|
17032
|
+
fontWeight: "600",
|
|
17033
|
+
fill: "#6b7280",
|
|
17034
|
+
style: {
|
|
17035
|
+
opacity: 1,
|
|
17036
|
+
pointerEvents: "none"
|
|
17037
|
+
},
|
|
17038
|
+
children: [
|
|
17039
|
+
value,
|
|
17040
|
+
"m"
|
|
17041
|
+
]
|
|
17042
|
+
}
|
|
17043
|
+
);
|
|
17044
|
+
}
|
|
17045
|
+
}
|
|
17046
|
+
)
|
|
17047
|
+
},
|
|
17048
|
+
`idle-bar-${idleBarState.key}`
|
|
17049
|
+
);
|
|
17050
|
+
}, [idleBarState.visible, idleBarState.key, idleBarState.shouldAnimate]);
|
|
16975
17051
|
const maxYValue = Math.ceil(pphThreshold * 1.5);
|
|
16976
17052
|
const generateYAxisTicks = () => {
|
|
16977
17053
|
const targetValue = Math.round(pphThreshold);
|
|
@@ -17229,51 +17305,7 @@ var HourlyOutputChart = ({
|
|
|
17229
17305
|
]
|
|
17230
17306
|
}
|
|
17231
17307
|
),
|
|
17232
|
-
|
|
17233
|
-
Bar,
|
|
17234
|
-
{
|
|
17235
|
-
dataKey: "idleMinutes",
|
|
17236
|
-
yAxisId: "idle",
|
|
17237
|
-
maxBarSize: 35,
|
|
17238
|
-
radius: [10, 10, 0, 0],
|
|
17239
|
-
fill: "url(#idlePattern)",
|
|
17240
|
-
opacity: 0.7,
|
|
17241
|
-
isAnimationActive: shouldAnimateIdle,
|
|
17242
|
-
animationBegin: shouldAnimateIdle ? 200 : 0,
|
|
17243
|
-
animationDuration: shouldAnimateIdle ? 800 : 0,
|
|
17244
|
-
animationEasing: "ease-out",
|
|
17245
|
-
children: /* @__PURE__ */ jsx(
|
|
17246
|
-
LabelList,
|
|
17247
|
-
{
|
|
17248
|
-
dataKey: "idleMinutes",
|
|
17249
|
-
position: "top",
|
|
17250
|
-
content: (props) => {
|
|
17251
|
-
const { x, y, width, value } = props;
|
|
17252
|
-
if (!value || value === 0) return null;
|
|
17253
|
-
return /* @__PURE__ */ jsxs(
|
|
17254
|
-
"text",
|
|
17255
|
-
{
|
|
17256
|
-
x: x + width / 2,
|
|
17257
|
-
y: y - 2,
|
|
17258
|
-
textAnchor: "middle",
|
|
17259
|
-
fontSize: "9",
|
|
17260
|
-
fontWeight: "600",
|
|
17261
|
-
fill: "#6b7280",
|
|
17262
|
-
style: {
|
|
17263
|
-
opacity: 1,
|
|
17264
|
-
pointerEvents: "none"
|
|
17265
|
-
},
|
|
17266
|
-
children: [
|
|
17267
|
-
value,
|
|
17268
|
-
"m"
|
|
17269
|
-
]
|
|
17270
|
-
}
|
|
17271
|
-
);
|
|
17272
|
-
}
|
|
17273
|
-
}
|
|
17274
|
-
)
|
|
17275
|
-
}
|
|
17276
|
-
),
|
|
17308
|
+
IdleBar,
|
|
17277
17309
|
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("pattern", { id: "idlePattern", patternUnits: "userSpaceOnUse", width: "4", height: "4", children: [
|
|
17278
17310
|
/* @__PURE__ */ jsx("rect", { width: "4", height: "4", fill: "#9ca3af", opacity: "0.2" }),
|
|
17279
17311
|
/* @__PURE__ */ 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" })
|
|
@@ -17944,6 +17976,187 @@ var SOPComplianceChart = ({
|
|
|
17944
17976
|
renderLegend()
|
|
17945
17977
|
] });
|
|
17946
17978
|
};
|
|
17979
|
+
var GaugeChart = ({
|
|
17980
|
+
value,
|
|
17981
|
+
min,
|
|
17982
|
+
max,
|
|
17983
|
+
target,
|
|
17984
|
+
label,
|
|
17985
|
+
unit = "",
|
|
17986
|
+
thresholds,
|
|
17987
|
+
className = ""
|
|
17988
|
+
}) => {
|
|
17989
|
+
const normalizedValue = (value - min) / (max - min) * 100;
|
|
17990
|
+
const clampedValue = Math.max(0, Math.min(100, normalizedValue));
|
|
17991
|
+
const data = [
|
|
17992
|
+
{ name: "value", value: clampedValue },
|
|
17993
|
+
{ name: "empty", value: 100 - clampedValue }
|
|
17994
|
+
];
|
|
17995
|
+
const getColor = () => {
|
|
17996
|
+
if (thresholds && thresholds.length > 0) {
|
|
17997
|
+
const sortedThresholds = [...thresholds].sort((a, b) => a.value - b.value);
|
|
17998
|
+
for (let i = sortedThresholds.length - 1; i >= 0; i--) {
|
|
17999
|
+
if (value >= sortedThresholds[i].value) {
|
|
18000
|
+
return sortedThresholds[i].color;
|
|
18001
|
+
}
|
|
18002
|
+
}
|
|
18003
|
+
return sortedThresholds[0].color;
|
|
18004
|
+
}
|
|
18005
|
+
if (clampedValue < 33) return "#ef4444";
|
|
18006
|
+
if (clampedValue < 66) return "#f59e0b";
|
|
18007
|
+
return "#10b981";
|
|
18008
|
+
};
|
|
18009
|
+
const gaugeColor = getColor();
|
|
18010
|
+
const targetAngle = target !== void 0 ? 180 - (target - min) / (max - min) * 180 : null;
|
|
18011
|
+
return /* @__PURE__ */ jsx("div", { className: `relative w-full h-full flex flex-col items-center justify-center ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "relative w-full max-w-[280px] aspect-square", children: [
|
|
18012
|
+
/* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsx(PieChart, { children: /* @__PURE__ */ jsxs(
|
|
18013
|
+
Pie,
|
|
18014
|
+
{
|
|
18015
|
+
data,
|
|
18016
|
+
cx: "50%",
|
|
18017
|
+
cy: "50%",
|
|
18018
|
+
startAngle: 180,
|
|
18019
|
+
endAngle: 0,
|
|
18020
|
+
innerRadius: "65%",
|
|
18021
|
+
outerRadius: "85%",
|
|
18022
|
+
paddingAngle: 0,
|
|
18023
|
+
dataKey: "value",
|
|
18024
|
+
animationBegin: 0,
|
|
18025
|
+
animationDuration: 1e3,
|
|
18026
|
+
animationEasing: "ease-out",
|
|
18027
|
+
children: [
|
|
18028
|
+
/* @__PURE__ */ jsx(Cell, { fill: gaugeColor }),
|
|
18029
|
+
/* @__PURE__ */ jsx(Cell, { fill: "#f3f4f6" })
|
|
18030
|
+
]
|
|
18031
|
+
}
|
|
18032
|
+
) }) }),
|
|
18033
|
+
targetAngle !== null && /* @__PURE__ */ jsx(
|
|
18034
|
+
"div",
|
|
18035
|
+
{
|
|
18036
|
+
className: "absolute top-1/2 left-1/2 w-1 h-[42%] bg-gray-800 origin-bottom",
|
|
18037
|
+
style: {
|
|
18038
|
+
transform: `translate(-50%, -100%) rotate(${targetAngle}deg)`,
|
|
18039
|
+
transition: "transform 0.3s ease-out"
|
|
18040
|
+
},
|
|
18041
|
+
children: /* @__PURE__ */ jsx("div", { className: "absolute -top-1 -left-1.5 w-3 h-3 bg-gray-800 rounded-full" })
|
|
18042
|
+
}
|
|
18043
|
+
),
|
|
18044
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
18045
|
+
/* @__PURE__ */ jsxs("div", { className: "text-3xl font-bold text-gray-800", children: [
|
|
18046
|
+
value.toFixed(unit === "%" ? 1 : 0),
|
|
18047
|
+
unit
|
|
18048
|
+
] }),
|
|
18049
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-gray-600 mt-1 font-medium", children: label }),
|
|
18050
|
+
target !== void 0 && /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500 mt-1", children: [
|
|
18051
|
+
"Target: ",
|
|
18052
|
+
target,
|
|
18053
|
+
unit
|
|
18054
|
+
] })
|
|
18055
|
+
] }) }),
|
|
18056
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-[15%] left-[15%] text-xs text-gray-500", children: [
|
|
18057
|
+
min,
|
|
18058
|
+
unit
|
|
18059
|
+
] }),
|
|
18060
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-[15%] right-[15%] text-xs text-gray-500", children: [
|
|
18061
|
+
max,
|
|
18062
|
+
unit
|
|
18063
|
+
] })
|
|
18064
|
+
] }) });
|
|
18065
|
+
};
|
|
18066
|
+
var DEFAULT_COLORS = [
|
|
18067
|
+
"#3b82f6",
|
|
18068
|
+
// blue-500
|
|
18069
|
+
"#10b981",
|
|
18070
|
+
// green-500
|
|
18071
|
+
"#f59e0b",
|
|
18072
|
+
// amber-500
|
|
18073
|
+
"#ef4444",
|
|
18074
|
+
// red-500
|
|
18075
|
+
"#8b5cf6",
|
|
18076
|
+
// violet-500
|
|
18077
|
+
"#06b6d4",
|
|
18078
|
+
// cyan-500
|
|
18079
|
+
"#f97316",
|
|
18080
|
+
// orange-500
|
|
18081
|
+
"#6366f1"
|
|
18082
|
+
// indigo-500
|
|
18083
|
+
];
|
|
18084
|
+
var PieChart4 = ({
|
|
18085
|
+
data,
|
|
18086
|
+
className = "",
|
|
18087
|
+
showPercentages = false,
|
|
18088
|
+
colors = DEFAULT_COLORS
|
|
18089
|
+
}) => {
|
|
18090
|
+
const total = data.reduce((sum, entry) => sum + entry.value, 0);
|
|
18091
|
+
const dataWithPercentage = data.map((entry) => ({
|
|
18092
|
+
...entry,
|
|
18093
|
+
percentage: (entry.value / total * 100).toFixed(1)
|
|
18094
|
+
}));
|
|
18095
|
+
const renderCustomLabel = (props) => {
|
|
18096
|
+
if (!showPercentages) return null;
|
|
18097
|
+
const { cx: cx2, cy, midAngle, innerRadius, outerRadius, percentage } = props;
|
|
18098
|
+
const RADIAN = Math.PI / 180;
|
|
18099
|
+
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
|
|
18100
|
+
const x = cx2 + radius * Math.cos(-midAngle * RADIAN);
|
|
18101
|
+
const y = cy + radius * Math.sin(-midAngle * RADIAN);
|
|
18102
|
+
return /* @__PURE__ */ jsxs(
|
|
18103
|
+
"text",
|
|
18104
|
+
{
|
|
18105
|
+
x,
|
|
18106
|
+
y,
|
|
18107
|
+
fill: "white",
|
|
18108
|
+
textAnchor: x > cx2 ? "start" : "end",
|
|
18109
|
+
dominantBaseline: "central",
|
|
18110
|
+
className: "text-xs font-medium",
|
|
18111
|
+
children: [
|
|
18112
|
+
percentage,
|
|
18113
|
+
"%"
|
|
18114
|
+
]
|
|
18115
|
+
}
|
|
18116
|
+
);
|
|
18117
|
+
};
|
|
18118
|
+
const CustomTooltip = ({ active, payload }) => {
|
|
18119
|
+
if (active && payload && payload.length) {
|
|
18120
|
+
const data2 = payload[0];
|
|
18121
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white px-3 py-2 shadow-lg rounded-lg border border-gray-200", children: [
|
|
18122
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: data2.name }),
|
|
18123
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-600", children: [
|
|
18124
|
+
"Value: ",
|
|
18125
|
+
data2.value,
|
|
18126
|
+
showPercentages && ` (${data2.payload.percentage}%)`
|
|
18127
|
+
] })
|
|
18128
|
+
] });
|
|
18129
|
+
}
|
|
18130
|
+
return null;
|
|
18131
|
+
};
|
|
18132
|
+
return /* @__PURE__ */ jsx("div", { className: `w-full h-full ${className}`, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { children: [
|
|
18133
|
+
/* @__PURE__ */ jsx(
|
|
18134
|
+
Pie,
|
|
18135
|
+
{
|
|
18136
|
+
data: dataWithPercentage,
|
|
18137
|
+
cx: "50%",
|
|
18138
|
+
cy: "50%",
|
|
18139
|
+
labelLine: false,
|
|
18140
|
+
label: showPercentages ? renderCustomLabel : void 0,
|
|
18141
|
+
outerRadius: "80%",
|
|
18142
|
+
fill: "#8884d8",
|
|
18143
|
+
dataKey: "value",
|
|
18144
|
+
animationBegin: 0,
|
|
18145
|
+
animationDuration: 800,
|
|
18146
|
+
children: dataWithPercentage.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: colors[index % colors.length] }, `cell-${index}`))
|
|
18147
|
+
}
|
|
18148
|
+
),
|
|
18149
|
+
/* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(CustomTooltip, {}) }),
|
|
18150
|
+
/* @__PURE__ */ jsx(
|
|
18151
|
+
Legend,
|
|
18152
|
+
{
|
|
18153
|
+
verticalAlign: "bottom",
|
|
18154
|
+
height: 36,
|
|
18155
|
+
formatter: (value) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: value })
|
|
18156
|
+
}
|
|
18157
|
+
)
|
|
18158
|
+
] }) }) });
|
|
18159
|
+
};
|
|
17947
18160
|
var TrendIcon = ({ trend }) => {
|
|
17948
18161
|
if (trend === "up") {
|
|
17949
18162
|
return /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4 text-green-500" });
|
|
@@ -19746,6 +19959,32 @@ var WorkspaceCard = ({
|
|
|
19746
19959
|
}
|
|
19747
19960
|
);
|
|
19748
19961
|
};
|
|
19962
|
+
var styles = `
|
|
19963
|
+
@keyframes fadeIn {
|
|
19964
|
+
from {
|
|
19965
|
+
opacity: 0;
|
|
19966
|
+
transform: translateY(-10px);
|
|
19967
|
+
}
|
|
19968
|
+
to {
|
|
19969
|
+
opacity: 1;
|
|
19970
|
+
transform: translateY(0);
|
|
19971
|
+
}
|
|
19972
|
+
}
|
|
19973
|
+
|
|
19974
|
+
.calendar-container {
|
|
19975
|
+
will-change: transform, opacity;
|
|
19976
|
+
animation: fadeIn 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
|
19977
|
+
}
|
|
19978
|
+
|
|
19979
|
+
.calendar-wrapper:not(.animation-complete) * {
|
|
19980
|
+
transition: none !important;
|
|
19981
|
+
}
|
|
19982
|
+
|
|
19983
|
+
.calendar-wrapper:not(.animation-complete) .group:hover {
|
|
19984
|
+
opacity: 1 !important;
|
|
19985
|
+
transform: scale(1) !important;
|
|
19986
|
+
}
|
|
19987
|
+
`;
|
|
19749
19988
|
var WEEKDAYS2 = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
19750
19989
|
var getTimeInZoneAsDate = (timezone) => {
|
|
19751
19990
|
const time2 = getCurrentTimeInZone(timezone);
|
|
@@ -19764,20 +20003,20 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19764
20003
|
}) => {
|
|
19765
20004
|
const { dateTimeConfig } = useDashboardConfig();
|
|
19766
20005
|
const configuredTimezone = dateTimeConfig?.defaultTimezone || "Asia/Kolkata";
|
|
20006
|
+
const [animationComplete, setAnimationComplete] = useState(false);
|
|
20007
|
+
useEffect(() => {
|
|
20008
|
+
setAnimationComplete(false);
|
|
20009
|
+
const timer = setTimeout(() => {
|
|
20010
|
+
setAnimationComplete(true);
|
|
20011
|
+
}, 600);
|
|
20012
|
+
return () => clearTimeout(timer);
|
|
20013
|
+
}, [month, year]);
|
|
19767
20014
|
const calendarData = useMemo(() => {
|
|
19768
20015
|
const startOfMonth = toZonedTime(new Date(year, month, 1), configuredTimezone);
|
|
19769
20016
|
const endOfMonth = toZonedTime(new Date(year, month + 1, 0), configuredTimezone);
|
|
19770
20017
|
const totalDays = endOfMonth.getDate();
|
|
19771
20018
|
let startOffset = startOfMonth.getDay() - 1;
|
|
19772
20019
|
if (startOffset === -1) startOffset = 6;
|
|
19773
|
-
console.log("Calendar generation for:", {
|
|
19774
|
-
month: month + 1,
|
|
19775
|
-
year,
|
|
19776
|
-
startOffset,
|
|
19777
|
-
totalDays,
|
|
19778
|
-
configuredTimezone
|
|
19779
|
-
});
|
|
19780
|
-
console.log("Data points received:", data);
|
|
19781
20020
|
const calendar = Array(startOffset).fill(null);
|
|
19782
20021
|
for (let day = 1; day <= totalDays; day++) {
|
|
19783
20022
|
const currentDate = new Date(year, month, day);
|
|
@@ -19791,15 +20030,6 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19791
20030
|
const dataDate = new Date(d.date);
|
|
19792
20031
|
const dataDateStr = dataDate.toISOString().split("T")[0];
|
|
19793
20032
|
const matches = dataDateStr === dateToMatch;
|
|
19794
|
-
if (day <= 3 && matches) {
|
|
19795
|
-
console.log(`Found data match for day ${day}:`, {
|
|
19796
|
-
dataDate: dataDate.toISOString(),
|
|
19797
|
-
currentDate: currentTimezoneDate.toISOString(),
|
|
19798
|
-
dataDateStr,
|
|
19799
|
-
dateToMatch,
|
|
19800
|
-
data: d
|
|
19801
|
-
});
|
|
19802
|
-
}
|
|
19803
20033
|
return matches;
|
|
19804
20034
|
});
|
|
19805
20035
|
if (matchingData.length > 0) {
|
|
@@ -19810,32 +20040,10 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19810
20040
|
// Use the timezone-adjusted date for display
|
|
19811
20041
|
});
|
|
19812
20042
|
} else {
|
|
19813
|
-
calendar.push(
|
|
19814
|
-
date: currentTimezoneDate,
|
|
19815
|
-
dayShift: {
|
|
19816
|
-
efficiency: 0,
|
|
19817
|
-
output: 0,
|
|
19818
|
-
cycleTime: 0,
|
|
19819
|
-
pph: 0,
|
|
19820
|
-
pphThreshold: 0,
|
|
19821
|
-
idealOutput: 0,
|
|
19822
|
-
rank: 0,
|
|
19823
|
-
idleTime: 0
|
|
19824
|
-
},
|
|
19825
|
-
nightShift: {
|
|
19826
|
-
efficiency: 0,
|
|
19827
|
-
output: 0,
|
|
19828
|
-
cycleTime: 0,
|
|
19829
|
-
pph: 0,
|
|
19830
|
-
pphThreshold: 0,
|
|
19831
|
-
idealOutput: 0,
|
|
19832
|
-
rank: 0,
|
|
19833
|
-
idleTime: 0
|
|
19834
|
-
}
|
|
19835
|
-
});
|
|
20043
|
+
calendar.push(null);
|
|
19836
20044
|
}
|
|
19837
20045
|
}
|
|
19838
|
-
return calendar;
|
|
20046
|
+
return { calendar, startOffset };
|
|
19839
20047
|
}, [data, month, year, configuredTimezone]);
|
|
19840
20048
|
const monthlyMetrics = useMemo(() => {
|
|
19841
20049
|
const validDays = data.filter((day) => {
|
|
@@ -19852,15 +20060,17 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19852
20060
|
return [];
|
|
19853
20061
|
}
|
|
19854
20062
|
return [day.dayShift, day.nightShift];
|
|
19855
|
-
})
|
|
20063
|
+
});
|
|
19856
20064
|
if (validShifts.length === 0) return null;
|
|
19857
20065
|
const badShiftsCount = validShifts.filter((shift) => shift.efficiency < 75).length;
|
|
20066
|
+
const totalIdleTime = validShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
|
|
20067
|
+
const avgIdleTime = Math.round(totalIdleTime / validShifts.length);
|
|
19858
20068
|
return {
|
|
19859
20069
|
avgEfficiency: Math.round(validShifts.reduce((sum, shift) => sum + shift.efficiency, 0) / validShifts.length),
|
|
19860
20070
|
avgCycleTime: Math.round(validShifts.reduce((sum, shift) => sum + shift.cycleTime, 0) / validShifts.length),
|
|
20071
|
+
avgIdleTime,
|
|
19861
20072
|
badDaysCount: badShiftsCount,
|
|
19862
|
-
totalDays: validShifts.length
|
|
19863
|
-
avgIdleTime: Math.round(validShifts.reduce((sum, shift) => sum + (shift.idleTime || 0), 0) / validShifts.length)
|
|
20073
|
+
totalDays: validShifts.length
|
|
19864
20074
|
};
|
|
19865
20075
|
}, [data, month, year, configuredTimezone]);
|
|
19866
20076
|
const handleDayClick = useCallback((day, shift) => {
|
|
@@ -19908,7 +20118,6 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19908
20118
|
compareDate.setHours(0, 0, 0, 0);
|
|
19909
20119
|
if (compareDate.getDay() === 0) return "bg-gray-300";
|
|
19910
20120
|
if (compareDate > istNow) return "bg-gray-200";
|
|
19911
|
-
if (efficiency < 10) return "bg-gray-300";
|
|
19912
20121
|
if (efficiency >= 80) return "bg-[#00AB45]/90";
|
|
19913
20122
|
if (efficiency >= 70) return "bg-[#FFB020]/90";
|
|
19914
20123
|
return "bg-[#E34329]/90";
|
|
@@ -19947,38 +20156,55 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19947
20156
|
] })
|
|
19948
20157
|
] }) });
|
|
19949
20158
|
};
|
|
19950
|
-
const renderDayCell = useCallback((day) => {
|
|
19951
|
-
if (
|
|
20159
|
+
const renderDayCell = useCallback((day, dayNumber, index) => {
|
|
20160
|
+
if (dayNumber === null) {
|
|
20161
|
+
return /* @__PURE__ */ jsx("div", { className: "h-full" });
|
|
20162
|
+
}
|
|
20163
|
+
const cellDate = toZonedTime(new Date(year, month, dayNumber), configuredTimezone);
|
|
20164
|
+
const isToday = isCurrentDate(cellDate);
|
|
20165
|
+
const isFuture = isFutureDate(cellDate);
|
|
20166
|
+
const isSunday = cellDate.getDay() === 0;
|
|
20167
|
+
if (!day) {
|
|
20168
|
+
let bgColor = "bg-gray-100";
|
|
20169
|
+
let textColor = "text-gray-400";
|
|
20170
|
+
if (isSunday) {
|
|
20171
|
+
bgColor = "bg-gray-200";
|
|
20172
|
+
textColor = "text-gray-500";
|
|
20173
|
+
}
|
|
20174
|
+
if (isFuture) {
|
|
20175
|
+
bgColor = "bg-gray-50";
|
|
20176
|
+
textColor = "text-gray-300";
|
|
20177
|
+
}
|
|
20178
|
+
return /* @__PURE__ */ 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__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx("div", { className: `text-base font-medium ${textColor} ${isToday ? "text-blue-500" : ""}`, children: dayNumber }) }) });
|
|
20179
|
+
}
|
|
19952
20180
|
const shiftData = selectedShift === "day" ? day.dayShift : day.nightShift;
|
|
19953
|
-
const isToday = isCurrentDate(day.date);
|
|
19954
|
-
const isFuture = isFutureDate(day.date);
|
|
19955
|
-
const isInactive = shiftData.efficiency < 10;
|
|
19956
20181
|
return /* @__PURE__ */ jsx(
|
|
19957
20182
|
"div",
|
|
19958
20183
|
{
|
|
19959
|
-
className: `group h-full transition-all duration-
|
|
19960
|
-
onClick: () => !isFuture &&
|
|
20184
|
+
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"}`,
|
|
20185
|
+
onClick: () => !isFuture && handleDayClick(day, selectedShift),
|
|
19961
20186
|
children: /* @__PURE__ */ jsxs("div", { className: `
|
|
19962
20187
|
${getPerformanceColor(shiftData.efficiency, day.date)}
|
|
19963
|
-
rounded-lg h-full p-2 relative transition-all duration-
|
|
20188
|
+
rounded-lg h-full p-2 relative ${animationComplete ? "transition-all duration-300 ease-in-out" : ""} shadow-sm
|
|
19964
20189
|
${isToday ? "ring-2 ring-blue-500 ring-offset-2 shadow-md" : ""}
|
|
19965
20190
|
`, children: [
|
|
19966
20191
|
/* @__PURE__ */ jsx("div", { className: `
|
|
19967
|
-
text-base font-medium text-white flex items-center transition-all duration-
|
|
20192
|
+
text-base font-medium text-white flex items-center ${animationComplete ? "transition-all duration-300 ease-in-out" : ""}
|
|
19968
20193
|
${isToday ? "bg-blue-500 rounded-full w-7 h-7 justify-center" : ""}
|
|
19969
20194
|
`, children: day.date.getDate() }),
|
|
19970
|
-
!isFuture &&
|
|
20195
|
+
!isFuture && animationComplete && renderStats(shiftData, day.date)
|
|
19971
20196
|
] })
|
|
19972
20197
|
}
|
|
19973
20198
|
);
|
|
19974
|
-
}, [selectedShift, isCurrentDate, isFutureDate, getPerformanceColor, handleDayClick]);
|
|
19975
|
-
return /* @__PURE__ */ jsxs("div", { className: `space-y-6 ${className || ""}`, children: [
|
|
20199
|
+
}, [selectedShift, isCurrentDate, isFutureDate, getPerformanceColor, handleDayClick, year, month, configuredTimezone, animationComplete]);
|
|
20200
|
+
return /* @__PURE__ */ jsxs("div", { className: `calendar-wrapper space-y-6 ${className || ""} ${animationComplete ? "animation-complete" : ""}`, children: [
|
|
20201
|
+
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: styles } }),
|
|
19976
20202
|
/* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: [
|
|
19977
20203
|
/* @__PURE__ */ jsx(
|
|
19978
20204
|
"button",
|
|
19979
20205
|
{
|
|
19980
20206
|
onClick: () => handleShiftChange("day"),
|
|
19981
|
-
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" :
|
|
20207
|
+
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" : ""}`}`,
|
|
19982
20208
|
children: "Day Shift"
|
|
19983
20209
|
}
|
|
19984
20210
|
),
|
|
@@ -19986,23 +20212,27 @@ var WorkspaceHistoryCalendar = ({
|
|
|
19986
20212
|
"button",
|
|
19987
20213
|
{
|
|
19988
20214
|
onClick: () => handleShiftChange("night"),
|
|
19989
|
-
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" :
|
|
20215
|
+
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" : ""}`}`,
|
|
19990
20216
|
children: "Night Shift"
|
|
19991
20217
|
}
|
|
19992
20218
|
)
|
|
19993
20219
|
] }) }),
|
|
19994
20220
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-8", children: [
|
|
19995
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20221
|
+
/* @__PURE__ */ 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: [
|
|
19996
20222
|
/* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
19997
20223
|
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-gray-900 text-lg", children: selectedShift === "day" ? "Day Shifts" : "Night Shifts" }),
|
|
19998
20224
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Calendar view of daily performance" })
|
|
19999
20225
|
] }),
|
|
20000
20226
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-6", children: [
|
|
20001
20227
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: WEEKDAYS2.map((day) => /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-gray-600 text-center", children: day }, day)) }),
|
|
20002
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: calendarData.map((day, index) =>
|
|
20228
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: calendarData.calendar.map((day, index) => {
|
|
20229
|
+
const startOffset = calendarData.startOffset;
|
|
20230
|
+
const dayNumber = index >= startOffset ? index - startOffset + 1 : null;
|
|
20231
|
+
return /* @__PURE__ */ 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);
|
|
20232
|
+
}) })
|
|
20003
20233
|
] })
|
|
20004
20234
|
] }),
|
|
20005
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 transition-all duration-200 ease-in-out", children: [
|
|
20235
|
+
/* @__PURE__ */ 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: [
|
|
20006
20236
|
/* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
20007
20237
|
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-gray-900 text-lg", children: "Monthly Summary" }),
|
|
20008
20238
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1", children: "Overview of monthly performance metrics" })
|
|
@@ -22525,7 +22755,7 @@ var getWorkspaceStyles = (position, isPlaceholder = false) => {
|
|
|
22525
22755
|
${additionalStyles}
|
|
22526
22756
|
${isPlaceholder ? "cursor-default" : ""}`;
|
|
22527
22757
|
};
|
|
22528
|
-
var
|
|
22758
|
+
var Legend6 = () => /* @__PURE__ */ 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: [
|
|
22529
22759
|
/* @__PURE__ */ jsx("div", { className: "font-medium text-gray-700 hidden sm:block", children: "Efficiency:" }),
|
|
22530
22760
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-4", children: [
|
|
22531
22761
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 sm:gap-2", children: [
|
|
@@ -22573,7 +22803,7 @@ var WorkspaceGridItem = React14__default.memo(({
|
|
|
22573
22803
|
}, [data.efficiency, isInactive, position.size, position.orientation]);
|
|
22574
22804
|
const { arrow, color: arrowColor } = useMemo(() => getTrendArrowAndColor2(data.trend_score), [data.trend_score]);
|
|
22575
22805
|
const workspaceNumber = useMemo(() => getWorkspaceNumber(data.workspace_name), [data.workspace_name]);
|
|
22576
|
-
const
|
|
22806
|
+
const styles2 = useMemo(() => getWorkspaceStyles(position, isInactive), [position, isInactive]);
|
|
22577
22807
|
const arrowPosition = useMemo(() => getArrowPositionClass(position), [position]);
|
|
22578
22808
|
const handleClick = useCallback((e) => {
|
|
22579
22809
|
e.preventDefault();
|
|
@@ -22624,7 +22854,7 @@ var WorkspaceGridItem = React14__default.memo(({
|
|
|
22624
22854
|
"button",
|
|
22625
22855
|
{
|
|
22626
22856
|
onClick: handleClick,
|
|
22627
|
-
className: `${
|
|
22857
|
+
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
|
|
22628
22858
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
22629
22859
|
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name)}` : getWorkspaceDisplayName(data.workspace_name),
|
|
22630
22860
|
children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
|
|
@@ -22663,8 +22893,8 @@ var WorkspaceGrid = React14__default.memo(({
|
|
|
22663
22893
|
const { VideoGridView: VideoGridViewComponent } = useRegistry();
|
|
22664
22894
|
return /* @__PURE__ */ jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
|
|
22665
22895
|
/* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-2 sm:left-4 right-2 sm:right-8 z-20", children: [
|
|
22666
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(
|
|
22667
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1", children: /* @__PURE__ */ jsx(
|
|
22896
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(Legend6, {}) }) }),
|
|
22897
|
+
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1", children: /* @__PURE__ */ jsx(Legend6, {}) })
|
|
22668
22898
|
] }),
|
|
22669
22899
|
/* @__PURE__ */ jsx("div", { className: "absolute top-10 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsx(
|
|
22670
22900
|
VideoGridViewComponent,
|
|
@@ -23267,6 +23497,78 @@ var WorkspaceMonthlyDataFetcher = ({
|
|
|
23267
23497
|
}, [workspaceId, selectedMonth, selectedYear, supabase, onDataLoaded, onLoadingChange]);
|
|
23268
23498
|
return null;
|
|
23269
23499
|
};
|
|
23500
|
+
var WorkspaceDisplayNameExample = () => {
|
|
23501
|
+
const { displayNames, loading, error } = useWorkspaceDisplayNames();
|
|
23502
|
+
const { displayName: singleWorkspaceName, loading: singleLoading } = useWorkspaceDisplayName("WS01");
|
|
23503
|
+
const { displayNames: displayNamesMap, loading: mapLoading } = useWorkspaceDisplayNamesMap(["WS01", "WS02", "WS03"]);
|
|
23504
|
+
if (loading) {
|
|
23505
|
+
return /* @__PURE__ */ jsx("div", { className: "p-4", children: "Loading workspace display names..." });
|
|
23506
|
+
}
|
|
23507
|
+
if (error) {
|
|
23508
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 text-red-600", children: [
|
|
23509
|
+
"Error loading workspace display names: ",
|
|
23510
|
+
error.message
|
|
23511
|
+
] });
|
|
23512
|
+
}
|
|
23513
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-6 max-w-4xl mx-auto", children: [
|
|
23514
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold mb-6", children: "Workspace Display Names Examples" }),
|
|
23515
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
23516
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-4", children: "1. All Workspace Display Names" }),
|
|
23517
|
+
/* @__PURE__ */ 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__ */ jsxs("div", { className: "p-3 border rounded-lg", children: [
|
|
23518
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: workspaceId }),
|
|
23519
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-gray-600", children: displayName })
|
|
23520
|
+
] }, workspaceId)) }),
|
|
23521
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-gray-50 rounded-lg", children: /* @__PURE__ */ jsxs("p", { className: "text-sm", children: [
|
|
23522
|
+
/* @__PURE__ */ jsx("strong", { children: "Using utility function:" }),
|
|
23523
|
+
` getWorkspaceDisplayName('WS01') = "`,
|
|
23524
|
+
getWorkspaceDisplayName("WS01"),
|
|
23525
|
+
'"'
|
|
23526
|
+
] }) })
|
|
23527
|
+
] }),
|
|
23528
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
23529
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-4", children: "2. Single Workspace Display Name" }),
|
|
23530
|
+
/* @__PURE__ */ jsx("div", { className: "p-3 border rounded-lg", children: singleLoading ? /* @__PURE__ */ jsx("div", { children: "Loading WS01..." }) : /* @__PURE__ */ jsxs("div", { children: [
|
|
23531
|
+
/* @__PURE__ */ jsx("strong", { children: "WS01:" }),
|
|
23532
|
+
" ",
|
|
23533
|
+
singleWorkspaceName
|
|
23534
|
+
] }) })
|
|
23535
|
+
] }),
|
|
23536
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
23537
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-4", children: "3. Specific Workspaces Map" }),
|
|
23538
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: mapLoading ? /* @__PURE__ */ jsx("div", { children: "Loading specific workspaces..." }) : Object.entries(displayNamesMap).map(([workspaceId, displayName]) => /* @__PURE__ */ jsxs("div", { className: "p-3 border rounded-lg", children: [
|
|
23539
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: workspaceId }),
|
|
23540
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-gray-600", children: displayName })
|
|
23541
|
+
] }, workspaceId)) })
|
|
23542
|
+
] }),
|
|
23543
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-8 p-4 bg-blue-50 rounded-lg", children: [
|
|
23544
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "Migration Guide" }),
|
|
23545
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm space-y-2", children: [
|
|
23546
|
+
/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: "Before (hardcoded):" }) }),
|
|
23547
|
+
/* @__PURE__ */ jsxs("code", { className: "block p-2 bg-gray-100 rounded", children: [
|
|
23548
|
+
"import ",
|
|
23549
|
+
`{getWorkspaceDisplayName}`,
|
|
23550
|
+
" from '@optifye/dashboard-core';",
|
|
23551
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
23552
|
+
"const name = getWorkspaceDisplayName('WS01'); // Synchronous, hardcoded"
|
|
23553
|
+
] }),
|
|
23554
|
+
/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: "After (from Supabase):" }) }),
|
|
23555
|
+
/* @__PURE__ */ jsxs("code", { className: "block p-2 bg-gray-100 rounded", children: [
|
|
23556
|
+
"import ",
|
|
23557
|
+
`{useWorkspaceDisplayName}`,
|
|
23558
|
+
" from '@optifye/dashboard-core';",
|
|
23559
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
23560
|
+
"const ",
|
|
23561
|
+
`{displayName, loading}`,
|
|
23562
|
+
" = useWorkspaceDisplayName('WS01'); // Async, from database"
|
|
23563
|
+
] }),
|
|
23564
|
+
/* @__PURE__ */ jsxs("p", { className: "text-blue-700", children: [
|
|
23565
|
+
/* @__PURE__ */ jsx("strong", { children: "Note:" }),
|
|
23566
|
+
" The old synchronous functions are still available as fallbacks and for backward compatibility."
|
|
23567
|
+
] })
|
|
23568
|
+
] })
|
|
23569
|
+
] })
|
|
23570
|
+
] });
|
|
23571
|
+
};
|
|
23270
23572
|
var Breadcrumbs = ({ items }) => {
|
|
23271
23573
|
const navigation = useNavigation();
|
|
23272
23574
|
if (!items || items.length === 0) return null;
|
|
@@ -24712,6 +25014,234 @@ var AIAgentView = () => {
|
|
|
24712
25014
|
});
|
|
24713
25015
|
}
|
|
24714
25016
|
const renderAssistantContent = (content) => {
|
|
25017
|
+
const parseChartPatterns = (text) => {
|
|
25018
|
+
const chartElements = [];
|
|
25019
|
+
let lastIndex = 0;
|
|
25020
|
+
const chartRegex = /\[\s*(?:Calling\s+|CALL\s+)?(create_[a-z_]+)\s*\(([\s\S]*?)\)\s*\]/g;
|
|
25021
|
+
let match;
|
|
25022
|
+
const processedIndices = /* @__PURE__ */ new Set();
|
|
25023
|
+
while ((match = chartRegex.exec(text)) !== null) {
|
|
25024
|
+
const startIndex = match.index;
|
|
25025
|
+
const endIndex = startIndex + match[0].length;
|
|
25026
|
+
if (!processedIndices.has(startIndex)) {
|
|
25027
|
+
processedIndices.add(startIndex);
|
|
25028
|
+
if (startIndex > lastIndex) {
|
|
25029
|
+
const beforeText = text.substring(lastIndex, startIndex);
|
|
25030
|
+
chartElements.push(
|
|
25031
|
+
/* @__PURE__ */ jsx(
|
|
25032
|
+
"div",
|
|
25033
|
+
{
|
|
25034
|
+
dangerouslySetInnerHTML: { __html: formatMessage(beforeText) }
|
|
25035
|
+
},
|
|
25036
|
+
`text-${lastIndex}`
|
|
25037
|
+
)
|
|
25038
|
+
);
|
|
25039
|
+
}
|
|
25040
|
+
const chartType = match[1];
|
|
25041
|
+
const argsString = match[2];
|
|
25042
|
+
try {
|
|
25043
|
+
const args = parseChartArguments(argsString);
|
|
25044
|
+
const chartElement = renderChart(chartType, args, startIndex);
|
|
25045
|
+
if (chartElement) {
|
|
25046
|
+
chartElements.push(chartElement);
|
|
25047
|
+
}
|
|
25048
|
+
} catch (error) {
|
|
25049
|
+
console.error(`Failed to parse chart ${chartType}:`, error);
|
|
25050
|
+
chartElements.push(
|
|
25051
|
+
/* @__PURE__ */ jsxs(
|
|
25052
|
+
"div",
|
|
25053
|
+
{
|
|
25054
|
+
className: "text-red-500 text-sm",
|
|
25055
|
+
children: [
|
|
25056
|
+
"Error rendering chart: ",
|
|
25057
|
+
match[0]
|
|
25058
|
+
]
|
|
25059
|
+
},
|
|
25060
|
+
`error-${startIndex}`
|
|
25061
|
+
)
|
|
25062
|
+
);
|
|
25063
|
+
}
|
|
25064
|
+
lastIndex = endIndex;
|
|
25065
|
+
}
|
|
25066
|
+
}
|
|
25067
|
+
if (lastIndex < text.length) {
|
|
25068
|
+
const remainingText = text.substring(lastIndex);
|
|
25069
|
+
chartElements.push(
|
|
25070
|
+
/* @__PURE__ */ jsx(
|
|
25071
|
+
"div",
|
|
25072
|
+
{
|
|
25073
|
+
dangerouslySetInnerHTML: { __html: formatMessage(remainingText) }
|
|
25074
|
+
},
|
|
25075
|
+
`text-${lastIndex}`
|
|
25076
|
+
)
|
|
25077
|
+
);
|
|
25078
|
+
}
|
|
25079
|
+
if (chartElements.length === 1 && lastIndex === 0) {
|
|
25080
|
+
return null;
|
|
25081
|
+
}
|
|
25082
|
+
return chartElements;
|
|
25083
|
+
};
|
|
25084
|
+
const parseChartArguments = (argsString) => {
|
|
25085
|
+
const args = {};
|
|
25086
|
+
const jsonParamRegex = /(\w+)\s*=\s*(\[[\s\S]*?\](?=\s*(?:,|\s*\)|\s*$))|\{[\s\S]*?\}(?=\s*(?:,|\s*\)|\s*$)))/g;
|
|
25087
|
+
let jsonMatch;
|
|
25088
|
+
while ((jsonMatch = jsonParamRegex.exec(argsString)) !== null) {
|
|
25089
|
+
const paramName = jsonMatch[1];
|
|
25090
|
+
const jsonValue = jsonMatch[2];
|
|
25091
|
+
try {
|
|
25092
|
+
args[paramName] = JSON.parse(jsonValue);
|
|
25093
|
+
argsString = argsString.replace(jsonMatch[0], "");
|
|
25094
|
+
} catch (e) {
|
|
25095
|
+
console.error(`Failed to parse ${paramName} JSON:`, e);
|
|
25096
|
+
}
|
|
25097
|
+
}
|
|
25098
|
+
const argRegex = /(\w+)\s*=\s*("([^"]*)"|'([^']*)'|([^,\s\)]+))/g;
|
|
25099
|
+
let argMatch;
|
|
25100
|
+
while ((argMatch = argRegex.exec(argsString)) !== null) {
|
|
25101
|
+
const key = argMatch[1];
|
|
25102
|
+
const value = argMatch[3] || argMatch[4] || argMatch[5];
|
|
25103
|
+
if (key === "data") continue;
|
|
25104
|
+
if (value === "true" || value === "True") {
|
|
25105
|
+
args[key] = true;
|
|
25106
|
+
} else if (value === "false" || value === "False") {
|
|
25107
|
+
args[key] = false;
|
|
25108
|
+
} else if (value === "null" || value === "None") {
|
|
25109
|
+
args[key] = null;
|
|
25110
|
+
} else if (!isNaN(Number(value)) && value !== "") {
|
|
25111
|
+
args[key] = Number(value);
|
|
25112
|
+
} else {
|
|
25113
|
+
args[key] = value;
|
|
25114
|
+
}
|
|
25115
|
+
}
|
|
25116
|
+
return args;
|
|
25117
|
+
};
|
|
25118
|
+
const renderChart = (chartType, args, key) => {
|
|
25119
|
+
switch (chartType) {
|
|
25120
|
+
case "create_gauge_chart":
|
|
25121
|
+
return /* @__PURE__ */ jsx("div", { className: "my-6 h-64 w-full flex justify-center", children: /* @__PURE__ */ jsx(
|
|
25122
|
+
GaugeChart,
|
|
25123
|
+
{
|
|
25124
|
+
value: args.value || 0,
|
|
25125
|
+
min: args.min_value || 0,
|
|
25126
|
+
max: args.max_value || 100,
|
|
25127
|
+
target: args.target,
|
|
25128
|
+
label: args.title || "",
|
|
25129
|
+
unit: args.unit || "",
|
|
25130
|
+
thresholds: args.thresholds,
|
|
25131
|
+
className: "w-full max-w-sm"
|
|
25132
|
+
}
|
|
25133
|
+
) }, `gauge-${key}`);
|
|
25134
|
+
case "create_bar_chart":
|
|
25135
|
+
if (!args.data || !args.x_field || !args.y_field) {
|
|
25136
|
+
console.error("Bar chart missing required parameters");
|
|
25137
|
+
return null;
|
|
25138
|
+
}
|
|
25139
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-6 w-full", style: { maxWidth: args.max_width || "100%" }, children: [
|
|
25140
|
+
/* @__PURE__ */ jsx(
|
|
25141
|
+
BarChart,
|
|
25142
|
+
{
|
|
25143
|
+
data: args.data,
|
|
25144
|
+
bars: [{
|
|
25145
|
+
dataKey: args.y_field,
|
|
25146
|
+
fill: args.color || "#3b82f6",
|
|
25147
|
+
labelList: args.show_values
|
|
25148
|
+
}],
|
|
25149
|
+
xAxisDataKey: args.x_field,
|
|
25150
|
+
className: "h-64",
|
|
25151
|
+
showLegend: false
|
|
25152
|
+
}
|
|
25153
|
+
),
|
|
25154
|
+
args.title && /* @__PURE__ */ jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
|
|
25155
|
+
] }, `bar-${key}`);
|
|
25156
|
+
case "create_line_chart":
|
|
25157
|
+
if (!args.data || !args.x_field || !args.y_field) {
|
|
25158
|
+
console.error("Line chart missing required parameters");
|
|
25159
|
+
return null;
|
|
25160
|
+
}
|
|
25161
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-6 w-full", style: {
|
|
25162
|
+
height: args.height || 256,
|
|
25163
|
+
width: args.width || "100%"
|
|
25164
|
+
}, children: [
|
|
25165
|
+
/* @__PURE__ */ jsx(
|
|
25166
|
+
LineChart,
|
|
25167
|
+
{
|
|
25168
|
+
data: args.data,
|
|
25169
|
+
lines: [{
|
|
25170
|
+
dataKey: args.y_field,
|
|
25171
|
+
stroke: "#3b82f6",
|
|
25172
|
+
strokeWidth: 2
|
|
25173
|
+
}],
|
|
25174
|
+
xAxisDataKey: args.x_field,
|
|
25175
|
+
className: "h-full",
|
|
25176
|
+
showLegend: false
|
|
25177
|
+
}
|
|
25178
|
+
),
|
|
25179
|
+
args.title && /* @__PURE__ */ jsx("p", { className: "text-center text-sm text-gray-600 mt-2", children: args.title })
|
|
25180
|
+
] }, `line-${key}`);
|
|
25181
|
+
case "create_pie_chart":
|
|
25182
|
+
if (!args.data || !args.label_field || !args.value_field) {
|
|
25183
|
+
console.error("Pie chart missing required parameters");
|
|
25184
|
+
return null;
|
|
25185
|
+
}
|
|
25186
|
+
const pieData = args.data.map((item) => ({
|
|
25187
|
+
name: item[args.label_field],
|
|
25188
|
+
value: item[args.value_field]
|
|
25189
|
+
}));
|
|
25190
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-6 w-full flex flex-col items-center", children: [
|
|
25191
|
+
args.title && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
|
|
25192
|
+
/* @__PURE__ */ jsx("div", { className: "h-64 w-full max-w-md", children: /* @__PURE__ */ jsx(
|
|
25193
|
+
PieChart4,
|
|
25194
|
+
{
|
|
25195
|
+
data: pieData,
|
|
25196
|
+
showPercentages: args.show_percentages || false
|
|
25197
|
+
}
|
|
25198
|
+
) })
|
|
25199
|
+
] }, `pie-${key}`);
|
|
25200
|
+
case "create_comparison_table":
|
|
25201
|
+
if (!args.data) {
|
|
25202
|
+
console.error("Comparison table missing required data");
|
|
25203
|
+
return null;
|
|
25204
|
+
}
|
|
25205
|
+
const columns = args.columns || Object.keys(args.data[0] || {});
|
|
25206
|
+
let sortedData = [...args.data];
|
|
25207
|
+
if (args.sort_by && columns.includes(args.sort_by)) {
|
|
25208
|
+
sortedData.sort((a, b) => {
|
|
25209
|
+
const aVal = a[args.sort_by];
|
|
25210
|
+
const bVal = b[args.sort_by];
|
|
25211
|
+
const comparison = aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
25212
|
+
return args.sort_descending === false ? comparison : -comparison;
|
|
25213
|
+
});
|
|
25214
|
+
}
|
|
25215
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-6 w-full overflow-x-auto", children: [
|
|
25216
|
+
args.title && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-700 mb-2", children: args.title }),
|
|
25217
|
+
/* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
|
|
25218
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
25219
|
+
"th",
|
|
25220
|
+
{
|
|
25221
|
+
className: `px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${col === args.highlight_column ? "bg-blue-50" : ""}`,
|
|
25222
|
+
children: col
|
|
25223
|
+
},
|
|
25224
|
+
col
|
|
25225
|
+
)) }) }),
|
|
25226
|
+
/* @__PURE__ */ jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: sortedData.map((row, rowIdx) => /* @__PURE__ */ jsx("tr", { className: rowIdx % 2 === 0 ? "bg-white" : "bg-gray-50", children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
25227
|
+
"td",
|
|
25228
|
+
{
|
|
25229
|
+
className: `px-4 py-2 whitespace-nowrap text-sm ${col === args.highlight_column ? "font-medium text-blue-600 bg-blue-50" : "text-gray-900"}`,
|
|
25230
|
+
children: row[col]
|
|
25231
|
+
},
|
|
25232
|
+
col
|
|
25233
|
+
)) }, rowIdx)) })
|
|
25234
|
+
] })
|
|
25235
|
+
] }, `table-${key}`);
|
|
25236
|
+
default:
|
|
25237
|
+
console.warn(`Unknown chart type: ${chartType}`);
|
|
25238
|
+
return null;
|
|
25239
|
+
}
|
|
25240
|
+
};
|
|
25241
|
+
const chartContent = parseChartPatterns(content);
|
|
25242
|
+
if (chartContent) {
|
|
25243
|
+
return /* @__PURE__ */ jsx("div", { className: "formatted-content", children: chartContent });
|
|
25244
|
+
}
|
|
24715
25245
|
return /* @__PURE__ */ jsx(
|
|
24716
25246
|
"div",
|
|
24717
25247
|
{
|
|
@@ -30135,6 +30665,11 @@ var WorkspaceDetailView = ({
|
|
|
30135
30665
|
return getOperationalDate();
|
|
30136
30666
|
}, [isHistoricView, date]);
|
|
30137
30667
|
const handleMonthlyDataLoaded = useCallback((data) => {
|
|
30668
|
+
console.log("[handleMonthlyDataLoaded] Received data:", {
|
|
30669
|
+
dataLength: data?.length,
|
|
30670
|
+
isArray: Array.isArray(data),
|
|
30671
|
+
sample: data?.[0]
|
|
30672
|
+
});
|
|
30138
30673
|
if (!data || !Array.isArray(data)) {
|
|
30139
30674
|
console.error("Invalid monthly metrics data received:", data);
|
|
30140
30675
|
setMonthlyData([]);
|
|
@@ -30152,22 +30687,35 @@ var WorkspaceDetailView = ({
|
|
|
30152
30687
|
if (!dayEntry) {
|
|
30153
30688
|
dayEntry = {
|
|
30154
30689
|
date: dateObj,
|
|
30155
|
-
dayShift:
|
|
30156
|
-
|
|
30690
|
+
dayShift: null,
|
|
30691
|
+
// Start with null instead of zeros
|
|
30692
|
+
nightShift: null
|
|
30693
|
+
// Start with null instead of zeros
|
|
30157
30694
|
};
|
|
30158
30695
|
dayDataMap.set(dateKey, dayEntry);
|
|
30159
30696
|
}
|
|
30160
|
-
const
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
|
|
30166
|
-
|
|
30167
|
-
|
|
30168
|
-
|
|
30697
|
+
const shiftData = {
|
|
30698
|
+
efficiency: metric.avg_efficiency || 0,
|
|
30699
|
+
output: metric.total_output || 0,
|
|
30700
|
+
cycleTime: metric.avg_cycle_time || 0,
|
|
30701
|
+
pph: metric.avg_pph || 0,
|
|
30702
|
+
pphThreshold: metric.pph_threshold || 0,
|
|
30703
|
+
idealOutput: metric.ideal_output || 0,
|
|
30704
|
+
rank: metric.workspace_rank || 0,
|
|
30705
|
+
idleTime: metric.idle_time || 0
|
|
30706
|
+
};
|
|
30707
|
+
if (metric.shift_id === 0) {
|
|
30708
|
+
dayEntry.dayShift = shiftData;
|
|
30709
|
+
} else {
|
|
30710
|
+
dayEntry.nightShift = shiftData;
|
|
30711
|
+
}
|
|
30169
30712
|
});
|
|
30170
|
-
const processedData = Array.from(dayDataMap.values())
|
|
30713
|
+
const processedData = Array.from(dayDataMap.values()).filter((entry) => entry.dayShift !== null || entry.nightShift !== null).map((entry) => ({
|
|
30714
|
+
date: entry.date,
|
|
30715
|
+
// If a shift is null (no data), provide zeros for compatibility
|
|
30716
|
+
dayShift: entry.dayShift || { efficiency: 0, output: 0, cycleTime: 0, pph: 0, pphThreshold: 0, idealOutput: 0, rank: 0, idleTime: 0 },
|
|
30717
|
+
nightShift: entry.nightShift || { efficiency: 0, output: 0, cycleTime: 0, pph: 0, pphThreshold: 0, idealOutput: 0, rank: 0, idleTime: 0 }
|
|
30718
|
+
}));
|
|
30171
30719
|
console.log(`[handleMonthlyDataLoaded] Transformed data for calendar:`, {
|
|
30172
30720
|
count: processedData.length,
|
|
30173
30721
|
sample: processedData.slice(0, 1)
|
|
@@ -30627,7 +31175,7 @@ var WorkspaceDetailView = ({
|
|
|
30627
31175
|
}
|
|
30628
31176
|
)
|
|
30629
31177
|
] }),
|
|
30630
|
-
|
|
31178
|
+
/* @__PURE__ */ jsx(
|
|
30631
31179
|
WorkspaceHistoryCalendar,
|
|
30632
31180
|
{
|
|
30633
31181
|
data: monthlyData,
|
|
@@ -30906,4 +31454,4 @@ var S3Service = class {
|
|
|
30906
31454
|
}
|
|
30907
31455
|
};
|
|
30908
31456
|
|
|
30909
|
-
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView,
|
|
31457
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSpinner_default as LoadingSpinner, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, PieChart4 as PieChart, ProfileView_default as ProfileView, RegistryProvider, S3Service, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, s3VideoPreloader, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useShiftConfig, useShifts, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|