@optifye/dashboard-core 6.11.39 → 6.11.41

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.mjs CHANGED
@@ -1,10 +1,10 @@
1
+ import { format, addDays, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, parseISO, subDays, differenceInMinutes, addMinutes, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
2
+ import { formatInTimeZone, fromZonedTime, toZonedTime } from 'date-fns-tz';
1
3
  import * as React143 from 'react';
2
4
  import React143__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, forwardRef, useImperativeHandle, useLayoutEffect, memo as memo$1, useContext, useSyncExternalStore, useId, Children, isValidElement, useInsertionEffect, startTransition, Fragment as Fragment$1, createElement, Component } from 'react';
3
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
6
  import { useRouter } from 'next/router';
5
7
  import { toast } from 'sonner';
6
- import { formatInTimeZone, fromZonedTime, toZonedTime } from 'date-fns-tz';
7
- import { format, addDays, subMonths, endOfMonth, startOfMonth, endOfDay, eachDayOfInterval, getDay, isSameDay, isWithinInterval, startOfDay, parseISO, subDays, differenceInMinutes, addMinutes, addMonths, isValid, formatDistanceToNow, isToday, isFuture, isBefore } from 'date-fns';
8
8
  import mixpanel from 'mixpanel-browser';
9
9
  import { EventEmitter } from 'events';
10
10
  import { createClient, REALTIME_SUBSCRIBE_STATES } from '@supabase/supabase-js';
@@ -1632,6 +1632,149 @@ function isValidPrefetchParams(params) {
1632
1632
  function isValidPrefetchStatus(status) {
1633
1633
  return typeof status === "string" && Object.values(PrefetchStatus).includes(status);
1634
1634
  }
1635
+ var getOperationalDate = (timezone, date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
1636
+ const zonedDate = toZonedTime(date, timezone);
1637
+ const hours = zonedDate.getHours();
1638
+ const minutes = zonedDate.getMinutes();
1639
+ const [startHourRaw, startMinuteRaw] = shiftStartTime.split(":").map(Number);
1640
+ const startHour = Number.isFinite(startHourRaw) ? startHourRaw : 6;
1641
+ const startMinute = Number.isFinite(startMinuteRaw) ? startMinuteRaw : 0;
1642
+ const currentTotalMinutes = hours * 60 + minutes;
1643
+ const shiftStartTotalMinutes = startHour * 60 + startMinute;
1644
+ const operationalDate = currentTotalMinutes < shiftStartTotalMinutes ? subDays(zonedDate, 1) : zonedDate;
1645
+ return format(operationalDate, "yyyy-MM-dd");
1646
+ };
1647
+ function formatTimeInZone(time2, timezone, formatString = "HH:mm:ss") {
1648
+ const dateObj = typeof time2 === "string" ? parseISO(time2) : time2;
1649
+ if (!isValid(dateObj)) return "Invalid Date";
1650
+ return formatInTimeZone(dateObj, timezone, formatString);
1651
+ }
1652
+ function getCurrentTimeInZone(timezone, formatString) {
1653
+ const now4 = /* @__PURE__ */ new Date();
1654
+ if (formatString) {
1655
+ if (!isValid(now4)) return "Invalid Date";
1656
+ return formatInTimeZone(now4, timezone, formatString);
1657
+ }
1658
+ return now4;
1659
+ }
1660
+ var pad2 = (value) => String(value).padStart(2, "0");
1661
+ var DATE_KEY_PREFIX_PATTERN = /^(\d{4}-\d{2}-\d{2})/;
1662
+ var buildDateKey = (year, monthIndex, day) => {
1663
+ return `${year}-${pad2(monthIndex + 1)}-${pad2(day)}`;
1664
+ };
1665
+ var getDateKeyFromDate = (date) => {
1666
+ return buildDateKey(date.getFullYear(), date.getMonth(), date.getDate());
1667
+ };
1668
+ var parseDateKeyToDate = (dateKey) => {
1669
+ const [year, month, day] = dateKey.split("-").map(Number);
1670
+ return new Date(year, month - 1, day, 12, 0, 0, 0);
1671
+ };
1672
+ var getDateKeyFromValue = (value) => {
1673
+ if (typeof value === "string") {
1674
+ const keyMatch = value.match(DATE_KEY_PREFIX_PATTERN);
1675
+ if (keyMatch?.[1]) {
1676
+ return keyMatch[1];
1677
+ }
1678
+ const parsed = parseISO(value);
1679
+ if (isValid(parsed)) {
1680
+ return getDateKeyFromDate(parsed);
1681
+ }
1682
+ return value;
1683
+ }
1684
+ return getDateKeyFromDate(value);
1685
+ };
1686
+ var formatDateKeyForDisplay = (dateKey, formatStr = "MMM d, yyyy") => {
1687
+ return format(parseDateKeyToDate(dateKey), formatStr);
1688
+ };
1689
+ var getMonthKeyBounds = (year, monthIndex) => {
1690
+ const startKey = buildDateKey(year, monthIndex, 1);
1691
+ const lastDay = new Date(year, monthIndex + 1, 0).getDate();
1692
+ const endKey = buildDateKey(year, monthIndex, lastDay);
1693
+ return { startKey, endKey };
1694
+ };
1695
+ var getCurrentWeekToDateRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
1696
+ const todayKey = formatInTimeZone(now4, timezone || "UTC", "yyyy-MM-dd");
1697
+ const todayDate = parseISO(`${todayKey}T00:00:00`);
1698
+ const dayOfWeek = getDay(todayDate);
1699
+ const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
1700
+ const weekStart = subDays(todayDate, daysSinceMonday);
1701
+ return {
1702
+ startKey: format(weekStart, "yyyy-MM-dd"),
1703
+ endKey: format(todayDate, "yyyy-MM-dd")
1704
+ };
1705
+ };
1706
+ var getCurrentWeekFullRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
1707
+ const currentWeekToDateRange = getCurrentWeekToDateRange(timezone, now4);
1708
+ const weekStart = parseDateKeyToDate(currentWeekToDateRange.startKey);
1709
+ return {
1710
+ startKey: currentWeekToDateRange.startKey,
1711
+ endKey: format(addDays(weekStart, 6), "yyyy-MM-dd")
1712
+ };
1713
+ };
1714
+ var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
1715
+ const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
1716
+ const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
1717
+ if (clampedStart <= clampedEnd) {
1718
+ return { startKey: clampedStart, endKey: clampedEnd };
1719
+ }
1720
+ return { startKey: clampedEnd, endKey: clampedStart };
1721
+ };
1722
+ var isFullMonthRange = (range, year, monthIndex) => {
1723
+ const bounds = getMonthKeyBounds(year, monthIndex);
1724
+ return range.startKey === bounds.startKey && range.endKey === bounds.endKey;
1725
+ };
1726
+ var getMonthlyTrendComparisonLabel = (range, year, monthIndex) => {
1727
+ if (isFullMonthRange(range, year, monthIndex)) {
1728
+ return "last month";
1729
+ }
1730
+ return range.startKey === range.endKey ? "previous day" : "previous range";
1731
+ };
1732
+ var getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
1733
+ const totalDays = new Date(year, monthIndex + 1, 0).getDate();
1734
+ const ranges = [];
1735
+ let currentStartDay = 1;
1736
+ for (let day = 1; day <= totalDays; day += 1) {
1737
+ const zonedDate = toZonedTime(new Date(year, monthIndex, day), timezone);
1738
+ const dayOfWeek = zonedDate.getDay();
1739
+ const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
1740
+ if (isEndOfWeek) {
1741
+ const startKey = buildDateKey(year, monthIndex, currentStartDay);
1742
+ const endKey = buildDateKey(year, monthIndex, day);
1743
+ if (maxKey && startKey > maxKey) {
1744
+ break;
1745
+ }
1746
+ const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
1747
+ if (clampedEndKey < startKey) {
1748
+ break;
1749
+ }
1750
+ const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
1751
+ const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
1752
+ ranges.push({
1753
+ startKey,
1754
+ endKey: clampedEndKey,
1755
+ label: `Week of ${labelStart} - ${labelEnd}`
1756
+ });
1757
+ currentStartDay = day + 1;
1758
+ }
1759
+ }
1760
+ return ranges;
1761
+ };
1762
+ var formatRangeLabel = (range, fullMonthLabel) => {
1763
+ if (!range.startKey || !range.endKey) return fullMonthLabel;
1764
+ if (range.startKey === range.endKey) {
1765
+ return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
1766
+ }
1767
+ const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
1768
+ const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
1769
+ return `${startLabel} - ${endLabel}`;
1770
+ };
1771
+ var filterDataByDateKeyRange = (data, range) => {
1772
+ if (!range.startKey || !range.endKey) return data;
1773
+ return (data || []).filter((item) => {
1774
+ const dateKey = item.dateKey || getDateKeyFromValue(item.date);
1775
+ return dateKey >= range.startKey && dateKey <= range.endKey;
1776
+ });
1777
+ };
1635
1778
 
1636
1779
  // src/lib/types/calendar.ts
1637
1780
  var DEFAULT_SHIFT_DATA = {
@@ -1663,6 +1806,9 @@ var hasAnyShiftData = (day) => {
1663
1806
  var getAvailableShiftIds = (day) => {
1664
1807
  return Object.keys(day.shifts).map(Number).sort((a, b) => a - b);
1665
1808
  };
1809
+ var getDayDateKey = (day) => {
1810
+ return day.dateKey || getDateKeyFromDate(day.date);
1811
+ };
1666
1812
 
1667
1813
  // src/components/dashboard/grid/workspace_grid_constants.ts
1668
1814
  var DEFAULT_WORKSPACE_POSITIONS = [
@@ -3318,136 +3464,6 @@ var memoizedOutputArrayAggregation = createMemoizedFunction(
3318
3464
  },
3319
3465
  (arrays) => arrays.map((arr) => arr.length).join("-")
3320
3466
  );
3321
- var getOperationalDate = (timezone, date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
3322
- const zonedDate = toZonedTime(date, timezone);
3323
- const hours = zonedDate.getHours();
3324
- const minutes = zonedDate.getMinutes();
3325
- const [startHourRaw, startMinuteRaw] = shiftStartTime.split(":").map(Number);
3326
- const startHour = Number.isFinite(startHourRaw) ? startHourRaw : 6;
3327
- const startMinute = Number.isFinite(startMinuteRaw) ? startMinuteRaw : 0;
3328
- const currentTotalMinutes = hours * 60 + minutes;
3329
- const shiftStartTotalMinutes = startHour * 60 + startMinute;
3330
- const operationalDate = currentTotalMinutes < shiftStartTotalMinutes ? subDays(zonedDate, 1) : zonedDate;
3331
- return format(operationalDate, "yyyy-MM-dd");
3332
- };
3333
- function formatTimeInZone(time2, timezone, formatString = "HH:mm:ss") {
3334
- const dateObj = typeof time2 === "string" ? parseISO(time2) : time2;
3335
- if (!isValid(dateObj)) return "Invalid Date";
3336
- return formatInTimeZone(dateObj, timezone, formatString);
3337
- }
3338
- function getCurrentTimeInZone(timezone, formatString) {
3339
- const now4 = /* @__PURE__ */ new Date();
3340
- if (formatString) {
3341
- if (!isValid(now4)) return "Invalid Date";
3342
- return formatInTimeZone(now4, timezone, formatString);
3343
- }
3344
- return now4;
3345
- }
3346
- var pad2 = (value) => String(value).padStart(2, "0");
3347
- var buildDateKey = (year, monthIndex, day) => {
3348
- return `${year}-${pad2(monthIndex + 1)}-${pad2(day)}`;
3349
- };
3350
- var getDateKeyFromDate = (date) => {
3351
- return date.toISOString().split("T")[0];
3352
- };
3353
- var parseDateKeyToDate = (dateKey) => {
3354
- const [year, month, day] = dateKey.split("-").map(Number);
3355
- return new Date(year, month - 1, day);
3356
- };
3357
- var formatDateKeyForDisplay = (dateKey, formatStr = "MMM d, yyyy") => {
3358
- return format(parseDateKeyToDate(dateKey), formatStr);
3359
- };
3360
- var getMonthKeyBounds = (year, monthIndex) => {
3361
- const startKey = buildDateKey(year, monthIndex, 1);
3362
- const lastDay = new Date(year, monthIndex + 1, 0).getDate();
3363
- const endKey = buildDateKey(year, monthIndex, lastDay);
3364
- return { startKey, endKey };
3365
- };
3366
- var getCurrentWeekToDateRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
3367
- const todayKey = formatInTimeZone(now4, timezone || "UTC", "yyyy-MM-dd");
3368
- const todayDate = parseISO(`${todayKey}T00:00:00`);
3369
- const dayOfWeek = getDay(todayDate);
3370
- const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
3371
- const weekStart = subDays(todayDate, daysSinceMonday);
3372
- return {
3373
- startKey: format(weekStart, "yyyy-MM-dd"),
3374
- endKey: format(todayDate, "yyyy-MM-dd")
3375
- };
3376
- };
3377
- var getCurrentWeekFullRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
3378
- const currentWeekToDateRange = getCurrentWeekToDateRange(timezone, now4);
3379
- const weekStart = parseDateKeyToDate(currentWeekToDateRange.startKey);
3380
- return {
3381
- startKey: currentWeekToDateRange.startKey,
3382
- endKey: format(addDays(weekStart, 6), "yyyy-MM-dd")
3383
- };
3384
- };
3385
- var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
3386
- const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
3387
- const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
3388
- if (clampedStart <= clampedEnd) {
3389
- return { startKey: clampedStart, endKey: clampedEnd };
3390
- }
3391
- return { startKey: clampedEnd, endKey: clampedStart };
3392
- };
3393
- var isFullMonthRange = (range, year, monthIndex) => {
3394
- const bounds = getMonthKeyBounds(year, monthIndex);
3395
- return range.startKey === bounds.startKey && range.endKey === bounds.endKey;
3396
- };
3397
- var getMonthlyTrendComparisonLabel = (range, year, monthIndex) => {
3398
- if (isFullMonthRange(range, year, monthIndex)) {
3399
- return "last month";
3400
- }
3401
- return range.startKey === range.endKey ? "previous day" : "previous range";
3402
- };
3403
- var getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
3404
- const totalDays = new Date(year, monthIndex + 1, 0).getDate();
3405
- const ranges = [];
3406
- let currentStartDay = 1;
3407
- for (let day = 1; day <= totalDays; day += 1) {
3408
- const zonedDate = toZonedTime(new Date(year, monthIndex, day), timezone);
3409
- const dayOfWeek = zonedDate.getDay();
3410
- const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
3411
- if (isEndOfWeek) {
3412
- const startKey = buildDateKey(year, monthIndex, currentStartDay);
3413
- const endKey = buildDateKey(year, monthIndex, day);
3414
- if (maxKey && startKey > maxKey) {
3415
- break;
3416
- }
3417
- const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
3418
- if (clampedEndKey < startKey) {
3419
- break;
3420
- }
3421
- const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
3422
- const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
3423
- ranges.push({
3424
- startKey,
3425
- endKey: clampedEndKey,
3426
- label: `Week of ${labelStart} - ${labelEnd}`
3427
- });
3428
- currentStartDay = day + 1;
3429
- }
3430
- }
3431
- return ranges;
3432
- };
3433
- var formatRangeLabel = (range, fullMonthLabel) => {
3434
- if (!range.startKey || !range.endKey) return fullMonthLabel;
3435
- if (range.startKey === range.endKey) {
3436
- return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
3437
- }
3438
- const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
3439
- const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
3440
- return `${startLabel} - ${endLabel}`;
3441
- };
3442
- var filterDataByDateKeyRange = (data, range) => {
3443
- if (!range.startKey || !range.endKey) return data;
3444
- return (data || []).filter((item) => {
3445
- const dateKey = typeof item.date === "string" ? item.date : getDateKeyFromDate(item.date);
3446
- return dateKey >= range.startKey && dateKey <= range.endKey;
3447
- });
3448
- };
3449
-
3450
- // src/lib/utils/shifts.ts
3451
3467
  var DEFAULT_DAY_SHIFT_START = "06:00";
3452
3468
  var DEFAULT_NIGHT_SHIFT_START = "18:00";
3453
3469
  var DEFAULT_TRANSITION_MINUTES = 15;
@@ -46530,6 +46546,7 @@ var getLineShiftData = (day, shiftId) => {
46530
46546
  }
46531
46547
  return { ...DEFAULT_LINE_SHIFT_DATA };
46532
46548
  };
46549
+ var getLineDayDateKey = (day) => day.dateKey || getDateKeyFromValue(day.date);
46533
46550
  var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
46534
46551
  var LineHistoryCalendar = ({
46535
46552
  data,
@@ -46564,20 +46581,16 @@ var LineHistoryCalendar = ({
46564
46581
  for (let day = 1; day <= totalDays; day++) {
46565
46582
  const currentDate = toZonedTime(new Date(year, month, day), configuredTimezone);
46566
46583
  const currentDateString = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(2, "0")}-${String(currentDate.getDate()).padStart(2, "0")}`;
46567
- const existingData = data.find((d) => {
46568
- if (!d.date) return false;
46569
- const dDate = typeof d.date === "string" ? new Date(d.date) : d.date;
46570
- const dDateIST = toZonedTime(dDate, configuredTimezone);
46571
- const dDateString = `${dDateIST.getFullYear()}-${String(dDateIST.getMonth() + 1).padStart(2, "0")}-${String(dDateIST.getDate()).padStart(2, "0")}`;
46572
- return dDateString === currentDateString;
46573
- });
46584
+ const existingData = data.find((d) => d && getLineDayDateKey(d) === currentDateString);
46574
46585
  if (existingData) {
46575
46586
  calendar.push({
46576
46587
  ...existingData,
46588
+ dateKey: getLineDayDateKey(existingData),
46577
46589
  date: currentDate
46578
46590
  });
46579
46591
  } else {
46580
46592
  calendar.push({
46593
+ dateKey: currentDateString,
46581
46594
  date: currentDate,
46582
46595
  shifts: {}
46583
46596
  });
@@ -46649,7 +46662,7 @@ var LineHistoryCalendar = ({
46649
46662
  const isFuture = isFutureDate(day.date instanceof Date ? day.date : new Date(day.date));
46650
46663
  const hasData = hasRealData(shiftData);
46651
46664
  const dateObj = day.date instanceof Date ? day.date : new Date(day.date);
46652
- const dateKey = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, "0")}-${String(dateObj.getDate()).padStart(2, "0")}`;
46665
+ const dateKey = getLineDayDateKey(day);
46653
46666
  const showRange = rangeStart && rangeEnd ? !(rangeStart === monthBounds.startKey && rangeEnd === monthBounds.endKey) : false;
46654
46667
  const inRange = showRange ? dateKey >= rangeStart && dateKey <= rangeEnd : false;
46655
46668
  const isRangeEdge = inRange && (dateKey === rangeStart || dateKey === rangeEnd);
@@ -46660,11 +46673,7 @@ var LineHistoryCalendar = ({
46660
46673
  className: `group h-full ${isFuture || !hasData || isFilteredOut ? "cursor-not-allowed" : "cursor-pointer hover:opacity-90"}`,
46661
46674
  onClick: () => {
46662
46675
  if (!isFuture && hasData && !isFilteredOut) {
46663
- const dateObj2 = day.date instanceof Date ? day.date : new Date(day.date);
46664
- const year2 = dateObj2.getFullYear();
46665
- const month2 = String(dateObj2.getMonth() + 1).padStart(2, "0");
46666
- const dayOfMonth = String(dateObj2.getDate()).padStart(2, "0");
46667
- const date = `${year2}-${month2}-${dayOfMonth}`;
46676
+ const date = getLineDayDateKey(day);
46668
46677
  trackCoreEvent("Line Monthly History Day Clicked", {
46669
46678
  source: "line_kpi",
46670
46679
  line_id: lineId,
@@ -46676,8 +46685,8 @@ var LineHistoryCalendar = ({
46676
46685
  });
46677
46686
  const params = new URLSearchParams();
46678
46687
  params.set("tab", "monthly_history");
46679
- params.set("month", month2.toString());
46680
- params.set("year", year2.toString());
46688
+ params.set("month", month.toString());
46689
+ params.set("year", year.toString());
46681
46690
  if (rangeStart && rangeEnd && !(rangeStart === monthBounds.startKey && rangeEnd === monthBounds.endKey)) {
46682
46691
  params.set("rangeStart", rangeStart);
46683
46692
  params.set("rangeEnd", rangeEnd);
@@ -47146,6 +47155,7 @@ var getShiftData2 = (day, shiftId) => {
47146
47155
  }
47147
47156
  return { ...DEFAULT_PERFORMANCE_DATA };
47148
47157
  };
47158
+ var getLineDayDateKey2 = (day) => day.dateKey || getDateKeyFromValue(day.date);
47149
47159
  var getUptimeTotals = (shift, hasShiftData) => {
47150
47160
  if (!shift) {
47151
47161
  return { availableSeconds: 0, productiveSeconds: 0, idleSeconds: 0 };
@@ -47203,6 +47213,10 @@ var LineMonthlyHistory = ({
47203
47213
  }
47204
47214
  return filterDataByDateKeyRange(monthlyData, normalizedRange);
47205
47215
  }, [analysisData, monthlyData, normalizedRange]);
47216
+ const analysisMonthlyDataByKey = useMemo(
47217
+ () => new Map((analysisMonthlyData || []).map((day) => [getLineDayDateKey2(day), day])),
47218
+ [analysisMonthlyData]
47219
+ );
47206
47220
  const startDate = normalizedRange.startKey;
47207
47221
  const endDate = normalizedRange.endKey;
47208
47222
  const {
@@ -47309,9 +47323,9 @@ var LineMonthlyHistory = ({
47309
47323
  const chartData = useMemo(() => {
47310
47324
  const rangeStartDate = parseDateKeyToDate(normalizedRange.startKey);
47311
47325
  const rangeEndDate = parseDateKeyToDate(normalizedRange.endKey);
47312
- const dayNumbers = [];
47326
+ const rangeDateKeys = [];
47313
47327
  for (let d = new Date(rangeStartDate); d <= rangeEndDate; d.setDate(d.getDate() + 1)) {
47314
- dayNumbers.push(d.getDate());
47328
+ rangeDateKeys.push(buildDateKey(d.getFullYear(), d.getMonth(), d.getDate()));
47315
47329
  }
47316
47330
  if (isUptimeMode) {
47317
47331
  const dailyData2 = [];
@@ -47319,13 +47333,10 @@ var LineMonthlyHistory = ({
47319
47333
  const todayInZone = getCurrentTimeInZone(timezone);
47320
47334
  const todayDate = typeof todayInZone === "string" ? new Date(todayInZone) : todayInZone;
47321
47335
  const todayKey = `${todayDate.getFullYear()}-${String(todayDate.getMonth() + 1).padStart(2, "0")}-${String(todayDate.getDate()).padStart(2, "0")}`;
47322
- for (const day of dayNumbers) {
47323
- const dayKey = `${rangeStartDate.getFullYear()}-${String(rangeStartDate.getMonth() + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
47336
+ for (const dayKey of rangeDateKeys) {
47337
+ const day = Number(dayKey.slice(-2));
47324
47338
  const isFutureDay = dayKey > todayKey;
47325
- const dayData = analysisMonthlyData.find((d) => {
47326
- const date = new Date(d.date);
47327
- return date.getDate() === day;
47328
- });
47339
+ const dayData = analysisMonthlyDataByKey.get(dayKey);
47329
47340
  const shiftData = dayData ? getShiftData2(dayData, selectedShiftId) : null;
47330
47341
  const hasShiftData = Boolean(shiftData && hasRealData(shiftData));
47331
47342
  const efficiencyValue = hasShiftData && Number.isFinite(shiftData?.avg_efficiency) ? Number(shiftData?.avg_efficiency) : 0;
@@ -47347,12 +47358,9 @@ var LineMonthlyHistory = ({
47347
47358
  const dailyData = [];
47348
47359
  let maxOutput = 0;
47349
47360
  let lastSetTarget = 0;
47350
- for (let i = dayNumbers.length - 1; i >= 0; i--) {
47351
- const day = dayNumbers[i];
47352
- const dayData = analysisMonthlyData.find((d) => {
47353
- const date = new Date(d.date);
47354
- return date.getDate() === day;
47355
- });
47361
+ for (let i = rangeDateKeys.length - 1; i >= 0; i--) {
47362
+ const dayKey = rangeDateKeys[i];
47363
+ const dayData = analysisMonthlyDataByKey.get(dayKey);
47356
47364
  const shiftData = dayData ? getShiftData2(dayData, selectedShiftId) : null;
47357
47365
  const idealOutput = shiftData ? shiftData.idealOutput || 0 : 0;
47358
47366
  if (idealOutput > 0) {
@@ -47360,11 +47368,9 @@ var LineMonthlyHistory = ({
47360
47368
  break;
47361
47369
  }
47362
47370
  }
47363
- for (const day of dayNumbers) {
47364
- const dayData = analysisMonthlyData.find((d) => {
47365
- const date = new Date(d.date);
47366
- return date.getDate() === day;
47367
- });
47371
+ for (const dayKey of rangeDateKeys) {
47372
+ const day = Number(dayKey.slice(-2));
47373
+ const dayData = analysisMonthlyDataByKey.get(dayKey);
47368
47374
  const shiftData = dayData ? getShiftData2(dayData, selectedShiftId) : null;
47369
47375
  const output = shiftData && hasRealData(shiftData) ? shiftData.output || 0 : 0;
47370
47376
  const idealOutput = shiftData ? shiftData.idealOutput || 0 : 0;
@@ -47384,7 +47390,7 @@ var LineMonthlyHistory = ({
47384
47390
  const calculatedMax = Math.max(maxOutput, lastSetTarget);
47385
47391
  const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
47386
47392
  return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
47387
- }, [analysisMonthlyData, normalizedRange.startKey, normalizedRange.endKey, selectedShiftId, isUptimeMode, timezone]);
47393
+ }, [analysisMonthlyDataByKey, normalizedRange.endKey, normalizedRange.startKey, selectedShiftId, isUptimeMode, timezone]);
47388
47394
  const yAxisTicks = useMemo(() => {
47389
47395
  const max = chartData.yAxisMax;
47390
47396
  const target = chartData.lastSetTarget;
@@ -47872,6 +47878,7 @@ var getShiftDisplayName = (shiftId, availableShifts) => {
47872
47878
  if (shiftId === 1) return "Night Shift";
47873
47879
  return `Shift ${shiftId}`;
47874
47880
  };
47881
+ var getLineDayDateKey3 = (day) => day.dateKey || getDateKeyFromValue(day.date);
47875
47882
  var LineMonthlyPdfGenerator = ({
47876
47883
  lineId,
47877
47884
  lineName,
@@ -47901,13 +47908,20 @@ var LineMonthlyPdfGenerator = ({
47901
47908
  startKey: rangeStart || monthBounds.startKey,
47902
47909
  endKey: rangeEnd || monthBounds.endKey
47903
47910
  };
47911
+ const boundsSourceKey = rangeStart || rangeEnd || monthBounds.startKey;
47912
+ const boundsSourceDate = parseDateKeyToDate(boundsSourceKey);
47913
+ const effectiveBounds = getMonthKeyBounds(boundsSourceDate.getFullYear(), boundsSourceDate.getMonth());
47904
47914
  const normalizedRange = normalizeDateKeyRange(
47905
47915
  requestedRange.startKey,
47906
47916
  requestedRange.endKey,
47907
- monthBounds.startKey,
47908
- monthBounds.endKey
47917
+ effectiveBounds.startKey,
47918
+ effectiveBounds.endKey
47919
+ );
47920
+ const fullRange = isFullMonthRange(
47921
+ normalizedRange,
47922
+ boundsSourceDate.getFullYear(),
47923
+ boundsSourceDate.getMonth()
47909
47924
  );
47910
- const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
47911
47925
  const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
47912
47926
  const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
47913
47927
  const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
@@ -47925,8 +47939,8 @@ var LineMonthlyPdfGenerator = ({
47925
47939
  trackCoreEvent("Line Monthly PDF Export Clicked", {
47926
47940
  line_id: lineId,
47927
47941
  line_name: lineName,
47928
- month: selectedMonth,
47929
- year: selectedYear,
47942
+ month: reportStartDate.getMonth(),
47943
+ year: reportStartDate.getFullYear(),
47930
47944
  shift_id: selectedShiftId,
47931
47945
  range_start: normalizedRange.startKey,
47932
47946
  range_end: normalizedRange.endKey,
@@ -47938,6 +47952,11 @@ var LineMonthlyPdfGenerator = ({
47938
47952
  const maxContentY = footerY - 10;
47939
47953
  const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
47940
47954
  const dailySectionTitle = isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary";
47955
+ const monthName = reportStartDate.toLocaleDateString("en-IN", {
47956
+ month: "long",
47957
+ year: "numeric",
47958
+ timeZone: "Asia/Kolkata"
47959
+ });
47941
47960
  const drawPageChrome = () => {
47942
47961
  doc.setFontSize(14);
47943
47962
  doc.setFont("helvetica", "bold");
@@ -47969,11 +47988,6 @@ var LineMonthlyPdfGenerator = ({
47969
47988
  doc.setFontSize(13);
47970
47989
  doc.setFont("helvetica", "normal");
47971
47990
  doc.setTextColor(60, 60, 60);
47972
- const monthName = new Date(selectedYear, selectedMonth).toLocaleDateString("en-IN", {
47973
- month: "long",
47974
- year: "numeric",
47975
- timeZone: "Asia/Kolkata"
47976
- });
47977
47991
  const shiftType = getShiftDisplayName(selectedShiftId, availableShifts);
47978
47992
  doc.text(`${monthName}`, 20, 55);
47979
47993
  doc.text(`${shiftType}`, 20, 63);
@@ -47986,10 +48000,7 @@ var LineMonthlyPdfGenerator = ({
47986
48000
  const mainSeparatorY = isUptimeMode ? 90 : 85;
47987
48001
  doc.line(20, mainSeparatorY, 190, mainSeparatorY);
47988
48002
  const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
47989
- const validDays = reportData.filter((day) => {
47990
- const date = new Date(day.date);
47991
- return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
47992
- });
48003
+ const validDays = reportData;
47993
48004
  const hasShiftData = (shift) => {
47994
48005
  if (shift.hasData !== void 0) return shift.hasData;
47995
48006
  return shift.total_workspaces > 0 || shift.avg_efficiency > 0 || shift.underperforming_workspaces > 0 || (shift.available_time_seconds ?? 0) > 0 || (shift.idle_time_seconds ?? 0) > 0 || (shift.output ?? 0) > 0;
@@ -47997,7 +48008,7 @@ var LineMonthlyPdfGenerator = ({
47997
48008
  const dailyEntries = validDays.map((dayData) => {
47998
48009
  const shift = getLineShiftData2(dayData, selectedShiftId);
47999
48010
  return { dayData, shift };
48000
- }).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => new Date(right.dayData.date).getTime() - new Date(left.dayData.date).getTime());
48011
+ }).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => getLineDayDateKey3(right.dayData).localeCompare(getLineDayDateKey3(left.dayData)));
48001
48012
  const getUptimeTotals2 = (shift, hasData) => {
48002
48013
  if (!hasData || !shift) {
48003
48014
  return { availableSeconds: 0, productiveSeconds: 0, idleSeconds: 0 };
@@ -49881,6 +49892,7 @@ var formatHours = (value) => {
49881
49892
  if (Math.abs(rounded) < 0.05) return "0h";
49882
49893
  return Number.isInteger(rounded) ? `${rounded}h` : `${rounded.toFixed(1)}h`;
49883
49894
  };
49895
+ var roundToSingleDecimal = (value) => Math.round(value * 10) / 10;
49884
49896
  var formatCycleSeconds = (value) => {
49885
49897
  if (!Number.isFinite(value)) return "0.0s";
49886
49898
  return `${value.toFixed(1)}s`;
@@ -50006,21 +50018,30 @@ var WorkspaceMonthlyHistory = ({
50006
50018
  if (!shiftConfig) return null;
50007
50019
  return getShiftWorkDurationSeconds(shiftConfig, selectedShiftId);
50008
50020
  }, [shiftConfig, selectedShiftId]);
50009
- const chartData = useMemo(() => {
50021
+ const analysisMonthlyDataByKey = useMemo(
50022
+ () => new Map(analysisMonthlyData.map((day) => [getDayDateKey(day), day])),
50023
+ [analysisMonthlyData]
50024
+ );
50025
+ const monthlyDataByKey = useMemo(
50026
+ () => new Map(data.map((day) => [getDayDateKey(day), day])),
50027
+ [data]
50028
+ );
50029
+ const rangeDateKeys = useMemo(() => {
50010
50030
  const rangeStartDate = parseDateKeyToDate(normalizedRange.startKey);
50011
50031
  const rangeEndDate = parseDateKeyToDate(normalizedRange.endKey);
50012
- const dayNumbers = [];
50032
+ const keys = [];
50013
50033
  for (let d = new Date(rangeStartDate); d <= rangeEndDate; d.setDate(d.getDate() + 1)) {
50014
- dayNumbers.push(d.getDate());
50034
+ keys.push(buildDateKey(d.getFullYear(), d.getMonth(), d.getDate()));
50015
50035
  }
50036
+ return keys;
50037
+ }, [normalizedRange.endKey, normalizedRange.startKey]);
50038
+ const chartData = useMemo(() => {
50016
50039
  const dailyData = [];
50017
50040
  if (isUptimeMode) {
50018
50041
  let maxHours = 0;
50019
- for (const day of dayNumbers) {
50020
- const dayData = analysisMonthlyData.find((d) => {
50021
- const date = new Date(d.date);
50022
- return date.getDate() === day;
50023
- });
50042
+ for (const dateKey of rangeDateKeys) {
50043
+ const dayData = analysisMonthlyDataByKey.get(dateKey);
50044
+ const dayNumber = Number(dateKey.slice(-2));
50024
50045
  const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
50025
50046
  const hasShiftData = Boolean(shiftData && hasRealData(shiftData));
50026
50047
  const availableSeconds = hasShiftData ? shiftData.availableTimeSeconds ?? shiftWorkSeconds ?? 0 : 0;
@@ -50047,8 +50068,8 @@ var WorkspaceMonthlyHistory = ({
50047
50068
  }
50048
50069
  maxHours = Math.max(maxHours, idleHours + productiveHours);
50049
50070
  dailyData.push({
50050
- hour: getOrdinal2(day),
50051
- timeRange: `Day ${day}`,
50071
+ hour: getOrdinal2(dayNumber),
50072
+ timeRange: `Day ${dayNumber}`,
50052
50073
  productiveHours,
50053
50074
  idleHours,
50054
50075
  utilization
@@ -50059,12 +50080,9 @@ var WorkspaceMonthlyHistory = ({
50059
50080
  }
50060
50081
  let maxOutput = 0;
50061
50082
  let lastSetTarget = 0;
50062
- for (let i = dayNumbers.length - 1; i >= 0; i--) {
50063
- const day = dayNumbers[i];
50064
- const dayData = analysisMonthlyData.find((d) => {
50065
- const date = new Date(d.date);
50066
- return date.getDate() === day;
50067
- });
50083
+ for (let i = rangeDateKeys.length - 1; i >= 0; i--) {
50084
+ const dateKey = rangeDateKeys[i];
50085
+ const dayData = analysisMonthlyDataByKey.get(dateKey);
50068
50086
  const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
50069
50087
  const idealOutput = shiftData ? shiftData.idealOutput : 0;
50070
50088
  if (idealOutput > 0) {
@@ -50072,20 +50090,18 @@ var WorkspaceMonthlyHistory = ({
50072
50090
  break;
50073
50091
  }
50074
50092
  }
50075
- for (const day of dayNumbers) {
50076
- const dayData = analysisMonthlyData.find((d) => {
50077
- const date = new Date(d.date);
50078
- return date.getDate() === day;
50079
- });
50093
+ for (const dateKey of rangeDateKeys) {
50094
+ const dayData = analysisMonthlyDataByKey.get(dateKey);
50095
+ const dayNumber = Number(dateKey.slice(-2));
50080
50096
  const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
50081
50097
  const output = shiftData && hasRealData(shiftData) ? shiftData.output : 0;
50082
50098
  const idealOutput = shiftData ? shiftData.idealOutput : 0;
50083
50099
  if (output > maxOutput) maxOutput = output;
50084
50100
  const color2 = output >= lastSetTarget ? "#00AB45" : "#E34329";
50085
50101
  dailyData.push({
50086
- hour: getOrdinal2(day),
50102
+ hour: getOrdinal2(dayNumber),
50087
50103
  // Using ordinal format (1st, 2nd, 3rd, etc.)
50088
- timeRange: `Day ${day}`,
50104
+ timeRange: `Day ${dayNumber}`,
50089
50105
  output,
50090
50106
  originalOutput: output,
50091
50107
  // For label display
@@ -50099,7 +50115,7 @@ var WorkspaceMonthlyHistory = ({
50099
50115
  const calculatedMax = Math.max(maxOutput, lastSetTarget);
50100
50116
  const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
50101
50117
  return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
50102
- }, [analysisMonthlyData, normalizedRange.startKey, normalizedRange.endKey, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
50118
+ }, [analysisMonthlyDataByKey, rangeDateKeys, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
50103
50119
  const yAxisTicks = useMemo(() => {
50104
50120
  if (isUptimeMode) return void 0;
50105
50121
  const max = chartData.yAxisMax;
@@ -50184,7 +50200,7 @@ var WorkspaceMonthlyHistory = ({
50184
50200
  }
50185
50201
  const avgEfficiency = Math.round(totalEfficiency / filteredShifts.length);
50186
50202
  const avgDailyOutput = Math.round(totalOutput / filteredShifts.length);
50187
- const avgCycleTime = Math.round(totalCycleTime / filteredShifts.length);
50203
+ const avgCycleTime = roundToSingleDecimal(totalCycleTime / filteredShifts.length);
50188
50204
  const avgRank = ranks.length > 0 ? Math.round(ranks.reduce((a, b) => a + b, 0) / ranks.length) : null;
50189
50205
  return {
50190
50206
  avgEfficiency,
@@ -50204,7 +50220,7 @@ var WorkspaceMonthlyHistory = ({
50204
50220
  const assemblyRangeCycleTime = useMemo(() => {
50205
50221
  const trendCycleTime = Number(trendSummary?.avg_cycle_time?.current);
50206
50222
  if (Number.isFinite(trendCycleTime) && trendCycleTime > 0) {
50207
- return Math.round(trendCycleTime);
50223
+ return trendCycleTime;
50208
50224
  }
50209
50225
  return metrics2?.avgCycleTime ?? 0;
50210
50226
  }, [trendSummary?.avg_cycle_time?.current, metrics2?.avgCycleTime]);
@@ -50233,20 +50249,15 @@ var WorkspaceMonthlyHistory = ({
50233
50249
  if (startOffset === -1) startOffset = 6;
50234
50250
  const calendar = Array(startOffset).fill(null);
50235
50251
  for (let day = 1; day <= totalDays; day++) {
50236
- const dayData = data.find((d) => {
50237
- const date = new Date(d.date);
50238
- return date.getDate() === day;
50239
- });
50252
+ const dateKey = buildDateKey(year, month, day);
50253
+ const dayData = monthlyDataByKey.get(dateKey);
50240
50254
  calendar.push(dayData || null);
50241
50255
  }
50242
50256
  return { calendar, startOffset };
50243
- }, [data, month, year]);
50257
+ }, [monthlyDataByKey, month, year]);
50244
50258
  const handleDayClick = useCallback((day) => {
50245
50259
  if (!day) return;
50246
- const year2 = day.date.getFullYear();
50247
- const month2 = String(day.date.getMonth() + 1).padStart(2, "0");
50248
- const dayOfMonth = String(day.date.getDate()).padStart(2, "0");
50249
- const formattedDate = `${year2}-${month2}-${dayOfMonth}`;
50260
+ const formattedDate = getDayDateKey(day);
50250
50261
  trackCoreEvent("Workspace Monthly History Day Clicked", {
50251
50262
  source: "monthly_history",
50252
50263
  workspace_id: workspaceId,
@@ -51192,13 +51203,20 @@ var WorkspaceMonthlyPdfGenerator = ({
51192
51203
  startKey: rangeStart || monthBounds.startKey,
51193
51204
  endKey: rangeEnd || monthBounds.endKey
51194
51205
  };
51206
+ const boundsSourceKey = rangeStart || rangeEnd || monthBounds.startKey;
51207
+ const boundsSourceDate = parseDateKeyToDate(boundsSourceKey);
51208
+ const effectiveBounds = getMonthKeyBounds(boundsSourceDate.getFullYear(), boundsSourceDate.getMonth());
51195
51209
  const normalizedRange = normalizeDateKeyRange(
51196
51210
  requestedRange.startKey,
51197
51211
  requestedRange.endKey,
51198
- monthBounds.startKey,
51199
- monthBounds.endKey
51212
+ effectiveBounds.startKey,
51213
+ effectiveBounds.endKey
51214
+ );
51215
+ const fullRange = isFullMonthRange(
51216
+ normalizedRange,
51217
+ boundsSourceDate.getFullYear(),
51218
+ boundsSourceDate.getMonth()
51200
51219
  );
51201
- const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
51202
51220
  const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
51203
51221
  const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
51204
51222
  const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
@@ -51220,12 +51238,17 @@ var WorkspaceMonthlyPdfGenerator = ({
51220
51238
  const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
51221
51239
  const resolvedLineName = lineName?.trim() || "Line";
51222
51240
  const dailySectionTitle = isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary";
51241
+ const monthName = reportStartDate.toLocaleDateString("en-IN", {
51242
+ month: "long",
51243
+ year: "numeric",
51244
+ timeZone: "Asia/Kolkata"
51245
+ });
51223
51246
  trackCoreEvent("Workspace Monthly PDF Export Clicked", {
51224
51247
  workspace_id: workspaceId,
51225
51248
  workspace_name: workspaceName,
51226
51249
  line_name: resolvedLineName,
51227
- month: selectedMonth,
51228
- year: selectedYear,
51250
+ month: reportStartDate.getMonth(),
51251
+ year: reportStartDate.getFullYear(),
51229
51252
  shift_id: selectedShiftId,
51230
51253
  range_start: normalizedRange.startKey,
51231
51254
  range_end: normalizedRange.endKey,
@@ -51266,11 +51289,6 @@ var WorkspaceMonthlyPdfGenerator = ({
51266
51289
  doc.setFontSize(13);
51267
51290
  doc.setFont("helvetica", "normal");
51268
51291
  doc.setTextColor(60, 60, 60);
51269
- const monthName = new Date(selectedYear, selectedMonth).toLocaleDateString("en-IN", {
51270
- month: "long",
51271
- year: "numeric",
51272
- timeZone: "Asia/Kolkata"
51273
- });
51274
51292
  const shiftType = getShiftDisplayName2(selectedShiftId, availableShifts);
51275
51293
  doc.text(`${monthName}`, 20, 65);
51276
51294
  doc.text(`${shiftType}`, 20, 73);
@@ -51282,15 +51300,12 @@ var WorkspaceMonthlyPdfGenerator = ({
51282
51300
  doc.setLineWidth(0.8);
51283
51301
  doc.line(20, 90, 190, 90);
51284
51302
  const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
51285
- const validDays = reportData.filter((day) => {
51286
- const date = new Date(day.date);
51287
- return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
51288
- });
51303
+ const validDays = reportData;
51289
51304
  const validShifts = validDays.map((day) => getShiftData(day, selectedShiftId)).filter(hasShiftData);
51290
51305
  const dailyEntries = validDays.map((dayData) => {
51291
51306
  const shift = getShiftData(dayData, selectedShiftId);
51292
51307
  return { dayData, shift };
51293
- }).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => new Date(right.dayData.date).getTime() - new Date(left.dayData.date).getTime());
51308
+ }).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => getDayDateKey(right.dayData).localeCompare(getDayDateKey(left.dayData)));
51294
51309
  const filteredShifts = isUptimeMode ? validShifts : validShifts.filter((shift) => (shift.efficiency ?? 0) >= 5);
51295
51310
  const monthlyMetrics = filteredShifts.length > 0 ? isUptimeMode ? (() => {
51296
51311
  const totalIdleTime = filteredShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
@@ -63606,6 +63621,7 @@ var KPIDetailView = ({
63606
63621
  const monthBounds = useMemo(() => getMonthKeyBounds(currentYear, currentMonth), [currentYear, currentMonth]);
63607
63622
  const [rangeStart, setRangeStart] = useState(monthBounds.startKey);
63608
63623
  const [rangeEnd, setRangeEnd] = useState(monthBounds.endKey);
63624
+ const appliedExternalRangeKeyRef = useRef(null);
63609
63625
  const [monthlyData, setMonthlyData] = useState([]);
63610
63626
  const [underperformingWorkspaces, setUnderperformingWorkspaces] = useState({});
63611
63627
  const [selectedShiftId, setSelectedShiftId] = useState(0);
@@ -63648,12 +63664,29 @@ var KPIDetailView = ({
63648
63664
  const range = useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
63649
63665
  const isFullRange = useMemo(() => isFullMonthRange(range, currentYear, currentMonth), [range, currentYear, currentMonth]);
63650
63666
  useEffect(() => {
63667
+ const hasExternalRange = typeof urlRangeStart === "string" || typeof urlRangeEnd === "string";
63668
+ if (!hasExternalRange) {
63669
+ appliedExternalRangeKeyRef.current = null;
63670
+ return;
63671
+ }
63672
+ const externalRangeKey = `${urlRangeStart ?? ""}|${urlRangeEnd ?? ""}`;
63673
+ if (appliedExternalRangeKeyRef.current === externalRangeKey) {
63674
+ return;
63675
+ }
63676
+ appliedExternalRangeKeyRef.current = externalRangeKey;
63677
+ const targetStartKey = typeof urlRangeStart === "string" ? urlRangeStart : typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.startKey;
63678
+ const targetStartDate = parseDateKeyToDate(targetStartKey);
63679
+ const targetMonth = targetStartDate.getMonth();
63680
+ const targetYear = targetStartDate.getFullYear();
63681
+ const targetBounds = getMonthKeyBounds(targetYear, targetMonth);
63651
63682
  const normalized = normalizeDateKeyRange(
63652
- typeof urlRangeStart === "string" ? urlRangeStart : monthBounds.startKey,
63653
- typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.endKey,
63654
- monthBounds.startKey,
63655
- monthBounds.endKey
63683
+ typeof urlRangeStart === "string" ? urlRangeStart : targetBounds.startKey,
63684
+ typeof urlRangeEnd === "string" ? urlRangeEnd : targetBounds.endKey,
63685
+ targetBounds.startKey,
63686
+ targetBounds.endKey
63656
63687
  );
63688
+ setCurrentMonth(targetMonth);
63689
+ setCurrentYear(targetYear);
63657
63690
  setRangeStart(normalized.startKey);
63658
63691
  setRangeEnd(normalized.endKey);
63659
63692
  }, [urlRangeStart, urlRangeEnd, monthBounds.startKey, monthBounds.endKey]);
@@ -63821,12 +63854,13 @@ var KPIDetailView = ({
63821
63854
  const dayDataMap = /* @__PURE__ */ new Map();
63822
63855
  const resolveMonthlyShiftTimes = (metricShiftId) => resolveShiftTimes(metricShiftId);
63823
63856
  monthlyMetrics.forEach((metric) => {
63824
- const date = new Date(metric.date);
63825
- const dateKey = date.toISOString().split("T")[0];
63857
+ const dateKey = getDateKeyFromValue(metric.date);
63858
+ const date = parseDateKeyToDate(dateKey);
63826
63859
  let dayData = dayDataMap.get(dateKey);
63827
63860
  if (!dayData) {
63828
63861
  dayData = {
63829
63862
  date,
63863
+ dateKey,
63830
63864
  shifts: {}
63831
63865
  // Multi-shift structure: Record<number, ShiftData>
63832
63866
  };
@@ -63873,7 +63907,11 @@ var KPIDetailView = ({
63873
63907
  };
63874
63908
  dayData.shifts[metric.shift_id] = shiftData;
63875
63909
  });
63876
- const transformedMonthlyData = Array.from(dayDataMap.values());
63910
+ const transformedMonthlyData = Array.from(dayDataMap.values()).map((dayData) => ({
63911
+ date: dayData.date,
63912
+ dateKey: dayData.dateKey,
63913
+ shifts: dayData.shifts
63914
+ }));
63877
63915
  console.log("Transformed monthly data for calendar:", transformedMonthlyData);
63878
63916
  setMonthlyData(transformedMonthlyData);
63879
63917
  const mapWorkspaces = (workspaces2) => (workspaces2 || []).map((ws) => ({
@@ -71114,6 +71152,7 @@ var WorkspaceDetailView = ({
71114
71152
  const monthBounds = useMemo(() => getMonthKeyBounds(selectedYear, selectedMonth), [selectedYear, selectedMonth]);
71115
71153
  const [rangeStart, setRangeStart] = useState(monthBounds.startKey);
71116
71154
  const [rangeEnd, setRangeEnd] = useState(monthBounds.endKey);
71155
+ const appliedExternalRangeKeyRef = useRef(null);
71117
71156
  const [selectedShift, setSelectedShift] = useState(0);
71118
71157
  useEffect(() => {
71119
71158
  if (parsedShiftId !== void 0) {
@@ -71123,15 +71162,32 @@ var WorkspaceDetailView = ({
71123
71162
  const range = useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
71124
71163
  const isFullRange = useMemo(() => isFullMonthRange(range, selectedYear, selectedMonth), [range, selectedYear, selectedMonth]);
71125
71164
  useEffect(() => {
71165
+ const hasExternalRange = typeof urlRangeStart === "string" || typeof urlRangeEnd === "string";
71166
+ if (!hasExternalRange) {
71167
+ appliedExternalRangeKeyRef.current = null;
71168
+ return;
71169
+ }
71170
+ const externalRangeKey = `${urlRangeStart ?? ""}|${urlRangeEnd ?? ""}`;
71171
+ if (appliedExternalRangeKeyRef.current === externalRangeKey) {
71172
+ return;
71173
+ }
71174
+ appliedExternalRangeKeyRef.current = externalRangeKey;
71175
+ const targetStartKey = typeof urlRangeStart === "string" ? urlRangeStart : typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.startKey;
71176
+ const targetStartDate = parseDateKeyToDate(targetStartKey);
71177
+ const targetMonth = targetStartDate.getMonth();
71178
+ const targetYear = targetStartDate.getFullYear();
71179
+ const targetBounds = getMonthKeyBounds(targetYear, targetMonth);
71126
71180
  const normalized = normalizeDateKeyRange(
71127
- typeof urlRangeStart === "string" ? urlRangeStart : monthBounds.startKey,
71128
- typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.endKey,
71129
- monthBounds.startKey,
71130
- monthBounds.endKey
71181
+ typeof urlRangeStart === "string" ? urlRangeStart : targetBounds.startKey,
71182
+ typeof urlRangeEnd === "string" ? urlRangeEnd : targetBounds.endKey,
71183
+ targetBounds.startKey,
71184
+ targetBounds.endKey
71131
71185
  );
71186
+ setSelectedMonth(targetMonth);
71187
+ setSelectedYear(targetYear);
71132
71188
  setRangeStart(normalized.startKey);
71133
71189
  setRangeEnd(normalized.endKey);
71134
- }, [urlRangeStart, urlRangeEnd, monthBounds.startKey, monthBounds.endKey]);
71190
+ }, [urlRangeStart, urlRangeEnd, monthBounds.startKey]);
71135
71191
  const isHistoricView = Boolean(date && parsedShiftId !== void 0);
71136
71192
  const initialTab = getInitialTab(sourceType, defaultTab, fromMonthly, date);
71137
71193
  const [activeTab, setActiveTab] = useState(initialTab);
@@ -71653,12 +71709,13 @@ var WorkspaceDetailView = ({
71653
71709
  console.warn("Skipping invalid metric:", metric);
71654
71710
  return;
71655
71711
  }
71656
- const dateObj = new Date(metric.date);
71657
- const dateKey = dateObj.toISOString().split("T")[0];
71712
+ const dateKey = getDateKeyFromValue(metric.date);
71713
+ const dateObj = parseDateKeyToDate(dateKey);
71658
71714
  let dayEntry = dayDataMap.get(dateKey);
71659
71715
  if (!dayEntry) {
71660
71716
  dayEntry = {
71661
71717
  date: dateObj,
71718
+ dateKey,
71662
71719
  shifts: {}
71663
71720
  // Multi-shift structure: Record<number, CalendarShiftData>
71664
71721
  };
@@ -71703,6 +71760,7 @@ var WorkspaceDetailView = ({
71703
71760
  });
71704
71761
  const processedData = Array.from(dayDataMap.values()).filter((entry) => Object.keys(entry.shifts).length > 0).map((entry) => ({
71705
71762
  date: entry.date,
71763
+ dateKey: entry.dateKey,
71706
71764
  shifts: entry.shifts
71707
71765
  }));
71708
71766
  console.log(`[handleMonthlyDataLoaded] Transformed data for calendar:`, {
@@ -71735,7 +71793,7 @@ var WorkspaceDetailView = ({
71735
71793
  const analysisMonthlyData = useMemo(() => {
71736
71794
  return filterDataByDateKeyRange(monthlyData, range);
71737
71795
  }, [monthlyData, range]);
71738
- const formattedWorkspaceName = displayName || workspace?.workspace_display_name || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
71796
+ const formattedWorkspaceName = workspace?.workspace_display_name || displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
71739
71797
  const resolvedLineName = useMemo(() => {
71740
71798
  const workspaceLineName = workspace?.line_name?.trim();
71741
71799
  if (workspaceLineName) {
@@ -72281,6 +72339,9 @@ var WorkspaceDetailView = ({
72281
72339
  onMonthNavigate: (newMonth, newYear) => {
72282
72340
  setSelectedMonth(newMonth);
72283
72341
  setSelectedYear(newYear);
72342
+ const nextBounds = getMonthKeyBounds(newYear, newMonth);
72343
+ setRangeStart(nextBounds.startKey);
72344
+ setRangeEnd(nextBounds.endKey);
72284
72345
  },
72285
72346
  showLabel: false
72286
72347
  }
@@ -81595,4 +81656,4 @@ var streamProxyConfig = {
81595
81656
  }
81596
81657
  };
81597
81658
 
81598
- export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, 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, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getMonthlyTrendComparisonLabel, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
81659
+ export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, 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, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDateKeyFromValue, getDayDateKey, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getMonthlyTrendComparisonLabel, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };