@optifye/dashboard-core 6.11.39 → 6.11.40
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 +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +224 -189
- package/dist/index.mjs +223 -190
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var dateFns = require('date-fns');
|
|
4
|
+
var dateFnsTz = require('date-fns-tz');
|
|
3
5
|
var React143 = require('react');
|
|
4
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
7
|
var router = require('next/router');
|
|
6
8
|
var sonner = require('sonner');
|
|
7
|
-
var dateFnsTz = require('date-fns-tz');
|
|
8
|
-
var dateFns = require('date-fns');
|
|
9
9
|
var mixpanel = require('mixpanel-browser');
|
|
10
10
|
var events = require('events');
|
|
11
11
|
var supabaseJs = require('@supabase/supabase-js');
|
|
@@ -1661,6 +1661,149 @@ function isValidPrefetchParams(params) {
|
|
|
1661
1661
|
function isValidPrefetchStatus(status) {
|
|
1662
1662
|
return typeof status === "string" && Object.values(PrefetchStatus).includes(status);
|
|
1663
1663
|
}
|
|
1664
|
+
var getOperationalDate = (timezone, date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
|
|
1665
|
+
const zonedDate = dateFnsTz.toZonedTime(date, timezone);
|
|
1666
|
+
const hours = zonedDate.getHours();
|
|
1667
|
+
const minutes = zonedDate.getMinutes();
|
|
1668
|
+
const [startHourRaw, startMinuteRaw] = shiftStartTime.split(":").map(Number);
|
|
1669
|
+
const startHour = Number.isFinite(startHourRaw) ? startHourRaw : 6;
|
|
1670
|
+
const startMinute = Number.isFinite(startMinuteRaw) ? startMinuteRaw : 0;
|
|
1671
|
+
const currentTotalMinutes = hours * 60 + minutes;
|
|
1672
|
+
const shiftStartTotalMinutes = startHour * 60 + startMinute;
|
|
1673
|
+
const operationalDate = currentTotalMinutes < shiftStartTotalMinutes ? dateFns.subDays(zonedDate, 1) : zonedDate;
|
|
1674
|
+
return dateFns.format(operationalDate, "yyyy-MM-dd");
|
|
1675
|
+
};
|
|
1676
|
+
function formatTimeInZone(time2, timezone, formatString = "HH:mm:ss") {
|
|
1677
|
+
const dateObj = typeof time2 === "string" ? dateFns.parseISO(time2) : time2;
|
|
1678
|
+
if (!dateFns.isValid(dateObj)) return "Invalid Date";
|
|
1679
|
+
return dateFnsTz.formatInTimeZone(dateObj, timezone, formatString);
|
|
1680
|
+
}
|
|
1681
|
+
function getCurrentTimeInZone(timezone, formatString) {
|
|
1682
|
+
const now4 = /* @__PURE__ */ new Date();
|
|
1683
|
+
if (formatString) {
|
|
1684
|
+
if (!dateFns.isValid(now4)) return "Invalid Date";
|
|
1685
|
+
return dateFnsTz.formatInTimeZone(now4, timezone, formatString);
|
|
1686
|
+
}
|
|
1687
|
+
return now4;
|
|
1688
|
+
}
|
|
1689
|
+
var pad2 = (value) => String(value).padStart(2, "0");
|
|
1690
|
+
var DATE_KEY_PREFIX_PATTERN = /^(\d{4}-\d{2}-\d{2})/;
|
|
1691
|
+
var buildDateKey = (year, monthIndex, day) => {
|
|
1692
|
+
return `${year}-${pad2(monthIndex + 1)}-${pad2(day)}`;
|
|
1693
|
+
};
|
|
1694
|
+
var getDateKeyFromDate = (date) => {
|
|
1695
|
+
return buildDateKey(date.getFullYear(), date.getMonth(), date.getDate());
|
|
1696
|
+
};
|
|
1697
|
+
var parseDateKeyToDate = (dateKey) => {
|
|
1698
|
+
const [year, month, day] = dateKey.split("-").map(Number);
|
|
1699
|
+
return new Date(year, month - 1, day, 12, 0, 0, 0);
|
|
1700
|
+
};
|
|
1701
|
+
var getDateKeyFromValue = (value) => {
|
|
1702
|
+
if (typeof value === "string") {
|
|
1703
|
+
const keyMatch = value.match(DATE_KEY_PREFIX_PATTERN);
|
|
1704
|
+
if (keyMatch?.[1]) {
|
|
1705
|
+
return keyMatch[1];
|
|
1706
|
+
}
|
|
1707
|
+
const parsed = dateFns.parseISO(value);
|
|
1708
|
+
if (dateFns.isValid(parsed)) {
|
|
1709
|
+
return getDateKeyFromDate(parsed);
|
|
1710
|
+
}
|
|
1711
|
+
return value;
|
|
1712
|
+
}
|
|
1713
|
+
return getDateKeyFromDate(value);
|
|
1714
|
+
};
|
|
1715
|
+
var formatDateKeyForDisplay = (dateKey, formatStr = "MMM d, yyyy") => {
|
|
1716
|
+
return dateFns.format(parseDateKeyToDate(dateKey), formatStr);
|
|
1717
|
+
};
|
|
1718
|
+
var getMonthKeyBounds = (year, monthIndex) => {
|
|
1719
|
+
const startKey = buildDateKey(year, monthIndex, 1);
|
|
1720
|
+
const lastDay = new Date(year, monthIndex + 1, 0).getDate();
|
|
1721
|
+
const endKey = buildDateKey(year, monthIndex, lastDay);
|
|
1722
|
+
return { startKey, endKey };
|
|
1723
|
+
};
|
|
1724
|
+
var getCurrentWeekToDateRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
|
|
1725
|
+
const todayKey = dateFnsTz.formatInTimeZone(now4, timezone || "UTC", "yyyy-MM-dd");
|
|
1726
|
+
const todayDate = dateFns.parseISO(`${todayKey}T00:00:00`);
|
|
1727
|
+
const dayOfWeek = dateFns.getDay(todayDate);
|
|
1728
|
+
const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
|
1729
|
+
const weekStart = dateFns.subDays(todayDate, daysSinceMonday);
|
|
1730
|
+
return {
|
|
1731
|
+
startKey: dateFns.format(weekStart, "yyyy-MM-dd"),
|
|
1732
|
+
endKey: dateFns.format(todayDate, "yyyy-MM-dd")
|
|
1733
|
+
};
|
|
1734
|
+
};
|
|
1735
|
+
var getCurrentWeekFullRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
|
|
1736
|
+
const currentWeekToDateRange = getCurrentWeekToDateRange(timezone, now4);
|
|
1737
|
+
const weekStart = parseDateKeyToDate(currentWeekToDateRange.startKey);
|
|
1738
|
+
return {
|
|
1739
|
+
startKey: currentWeekToDateRange.startKey,
|
|
1740
|
+
endKey: dateFns.format(dateFns.addDays(weekStart, 6), "yyyy-MM-dd")
|
|
1741
|
+
};
|
|
1742
|
+
};
|
|
1743
|
+
var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
|
|
1744
|
+
const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
|
|
1745
|
+
const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
|
|
1746
|
+
if (clampedStart <= clampedEnd) {
|
|
1747
|
+
return { startKey: clampedStart, endKey: clampedEnd };
|
|
1748
|
+
}
|
|
1749
|
+
return { startKey: clampedEnd, endKey: clampedStart };
|
|
1750
|
+
};
|
|
1751
|
+
var isFullMonthRange = (range, year, monthIndex) => {
|
|
1752
|
+
const bounds = getMonthKeyBounds(year, monthIndex);
|
|
1753
|
+
return range.startKey === bounds.startKey && range.endKey === bounds.endKey;
|
|
1754
|
+
};
|
|
1755
|
+
var getMonthlyTrendComparisonLabel = (range, year, monthIndex) => {
|
|
1756
|
+
if (isFullMonthRange(range, year, monthIndex)) {
|
|
1757
|
+
return "last month";
|
|
1758
|
+
}
|
|
1759
|
+
return range.startKey === range.endKey ? "previous day" : "previous range";
|
|
1760
|
+
};
|
|
1761
|
+
var getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
|
|
1762
|
+
const totalDays = new Date(year, monthIndex + 1, 0).getDate();
|
|
1763
|
+
const ranges = [];
|
|
1764
|
+
let currentStartDay = 1;
|
|
1765
|
+
for (let day = 1; day <= totalDays; day += 1) {
|
|
1766
|
+
const zonedDate = dateFnsTz.toZonedTime(new Date(year, monthIndex, day), timezone);
|
|
1767
|
+
const dayOfWeek = zonedDate.getDay();
|
|
1768
|
+
const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
|
|
1769
|
+
if (isEndOfWeek) {
|
|
1770
|
+
const startKey = buildDateKey(year, monthIndex, currentStartDay);
|
|
1771
|
+
const endKey = buildDateKey(year, monthIndex, day);
|
|
1772
|
+
if (maxKey && startKey > maxKey) {
|
|
1773
|
+
break;
|
|
1774
|
+
}
|
|
1775
|
+
const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
|
|
1776
|
+
if (clampedEndKey < startKey) {
|
|
1777
|
+
break;
|
|
1778
|
+
}
|
|
1779
|
+
const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
|
|
1780
|
+
const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
|
|
1781
|
+
ranges.push({
|
|
1782
|
+
startKey,
|
|
1783
|
+
endKey: clampedEndKey,
|
|
1784
|
+
label: `Week of ${labelStart} - ${labelEnd}`
|
|
1785
|
+
});
|
|
1786
|
+
currentStartDay = day + 1;
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
return ranges;
|
|
1790
|
+
};
|
|
1791
|
+
var formatRangeLabel = (range, fullMonthLabel) => {
|
|
1792
|
+
if (!range.startKey || !range.endKey) return fullMonthLabel;
|
|
1793
|
+
if (range.startKey === range.endKey) {
|
|
1794
|
+
return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
|
|
1795
|
+
}
|
|
1796
|
+
const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
|
|
1797
|
+
const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
|
|
1798
|
+
return `${startLabel} - ${endLabel}`;
|
|
1799
|
+
};
|
|
1800
|
+
var filterDataByDateKeyRange = (data, range) => {
|
|
1801
|
+
if (!range.startKey || !range.endKey) return data;
|
|
1802
|
+
return (data || []).filter((item) => {
|
|
1803
|
+
const dateKey = item.dateKey || getDateKeyFromValue(item.date);
|
|
1804
|
+
return dateKey >= range.startKey && dateKey <= range.endKey;
|
|
1805
|
+
});
|
|
1806
|
+
};
|
|
1664
1807
|
|
|
1665
1808
|
// src/lib/types/calendar.ts
|
|
1666
1809
|
var DEFAULT_SHIFT_DATA = {
|
|
@@ -1692,6 +1835,9 @@ var hasAnyShiftData = (day) => {
|
|
|
1692
1835
|
var getAvailableShiftIds = (day) => {
|
|
1693
1836
|
return Object.keys(day.shifts).map(Number).sort((a, b) => a - b);
|
|
1694
1837
|
};
|
|
1838
|
+
var getDayDateKey = (day) => {
|
|
1839
|
+
return day.dateKey || getDateKeyFromDate(day.date);
|
|
1840
|
+
};
|
|
1695
1841
|
|
|
1696
1842
|
// src/components/dashboard/grid/workspace_grid_constants.ts
|
|
1697
1843
|
var DEFAULT_WORKSPACE_POSITIONS = [
|
|
@@ -3347,136 +3493,6 @@ var memoizedOutputArrayAggregation = createMemoizedFunction(
|
|
|
3347
3493
|
},
|
|
3348
3494
|
(arrays) => arrays.map((arr) => arr.length).join("-")
|
|
3349
3495
|
);
|
|
3350
|
-
var getOperationalDate = (timezone, date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
|
|
3351
|
-
const zonedDate = dateFnsTz.toZonedTime(date, timezone);
|
|
3352
|
-
const hours = zonedDate.getHours();
|
|
3353
|
-
const minutes = zonedDate.getMinutes();
|
|
3354
|
-
const [startHourRaw, startMinuteRaw] = shiftStartTime.split(":").map(Number);
|
|
3355
|
-
const startHour = Number.isFinite(startHourRaw) ? startHourRaw : 6;
|
|
3356
|
-
const startMinute = Number.isFinite(startMinuteRaw) ? startMinuteRaw : 0;
|
|
3357
|
-
const currentTotalMinutes = hours * 60 + minutes;
|
|
3358
|
-
const shiftStartTotalMinutes = startHour * 60 + startMinute;
|
|
3359
|
-
const operationalDate = currentTotalMinutes < shiftStartTotalMinutes ? dateFns.subDays(zonedDate, 1) : zonedDate;
|
|
3360
|
-
return dateFns.format(operationalDate, "yyyy-MM-dd");
|
|
3361
|
-
};
|
|
3362
|
-
function formatTimeInZone(time2, timezone, formatString = "HH:mm:ss") {
|
|
3363
|
-
const dateObj = typeof time2 === "string" ? dateFns.parseISO(time2) : time2;
|
|
3364
|
-
if (!dateFns.isValid(dateObj)) return "Invalid Date";
|
|
3365
|
-
return dateFnsTz.formatInTimeZone(dateObj, timezone, formatString);
|
|
3366
|
-
}
|
|
3367
|
-
function getCurrentTimeInZone(timezone, formatString) {
|
|
3368
|
-
const now4 = /* @__PURE__ */ new Date();
|
|
3369
|
-
if (formatString) {
|
|
3370
|
-
if (!dateFns.isValid(now4)) return "Invalid Date";
|
|
3371
|
-
return dateFnsTz.formatInTimeZone(now4, timezone, formatString);
|
|
3372
|
-
}
|
|
3373
|
-
return now4;
|
|
3374
|
-
}
|
|
3375
|
-
var pad2 = (value) => String(value).padStart(2, "0");
|
|
3376
|
-
var buildDateKey = (year, monthIndex, day) => {
|
|
3377
|
-
return `${year}-${pad2(monthIndex + 1)}-${pad2(day)}`;
|
|
3378
|
-
};
|
|
3379
|
-
var getDateKeyFromDate = (date) => {
|
|
3380
|
-
return date.toISOString().split("T")[0];
|
|
3381
|
-
};
|
|
3382
|
-
var parseDateKeyToDate = (dateKey) => {
|
|
3383
|
-
const [year, month, day] = dateKey.split("-").map(Number);
|
|
3384
|
-
return new Date(year, month - 1, day);
|
|
3385
|
-
};
|
|
3386
|
-
var formatDateKeyForDisplay = (dateKey, formatStr = "MMM d, yyyy") => {
|
|
3387
|
-
return dateFns.format(parseDateKeyToDate(dateKey), formatStr);
|
|
3388
|
-
};
|
|
3389
|
-
var getMonthKeyBounds = (year, monthIndex) => {
|
|
3390
|
-
const startKey = buildDateKey(year, monthIndex, 1);
|
|
3391
|
-
const lastDay = new Date(year, monthIndex + 1, 0).getDate();
|
|
3392
|
-
const endKey = buildDateKey(year, monthIndex, lastDay);
|
|
3393
|
-
return { startKey, endKey };
|
|
3394
|
-
};
|
|
3395
|
-
var getCurrentWeekToDateRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
|
|
3396
|
-
const todayKey = dateFnsTz.formatInTimeZone(now4, timezone || "UTC", "yyyy-MM-dd");
|
|
3397
|
-
const todayDate = dateFns.parseISO(`${todayKey}T00:00:00`);
|
|
3398
|
-
const dayOfWeek = dateFns.getDay(todayDate);
|
|
3399
|
-
const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
|
3400
|
-
const weekStart = dateFns.subDays(todayDate, daysSinceMonday);
|
|
3401
|
-
return {
|
|
3402
|
-
startKey: dateFns.format(weekStart, "yyyy-MM-dd"),
|
|
3403
|
-
endKey: dateFns.format(todayDate, "yyyy-MM-dd")
|
|
3404
|
-
};
|
|
3405
|
-
};
|
|
3406
|
-
var getCurrentWeekFullRange = (timezone, now4 = /* @__PURE__ */ new Date()) => {
|
|
3407
|
-
const currentWeekToDateRange = getCurrentWeekToDateRange(timezone, now4);
|
|
3408
|
-
const weekStart = parseDateKeyToDate(currentWeekToDateRange.startKey);
|
|
3409
|
-
return {
|
|
3410
|
-
startKey: currentWeekToDateRange.startKey,
|
|
3411
|
-
endKey: dateFns.format(dateFns.addDays(weekStart, 6), "yyyy-MM-dd")
|
|
3412
|
-
};
|
|
3413
|
-
};
|
|
3414
|
-
var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
|
|
3415
|
-
const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
|
|
3416
|
-
const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
|
|
3417
|
-
if (clampedStart <= clampedEnd) {
|
|
3418
|
-
return { startKey: clampedStart, endKey: clampedEnd };
|
|
3419
|
-
}
|
|
3420
|
-
return { startKey: clampedEnd, endKey: clampedStart };
|
|
3421
|
-
};
|
|
3422
|
-
var isFullMonthRange = (range, year, monthIndex) => {
|
|
3423
|
-
const bounds = getMonthKeyBounds(year, monthIndex);
|
|
3424
|
-
return range.startKey === bounds.startKey && range.endKey === bounds.endKey;
|
|
3425
|
-
};
|
|
3426
|
-
var getMonthlyTrendComparisonLabel = (range, year, monthIndex) => {
|
|
3427
|
-
if (isFullMonthRange(range, year, monthIndex)) {
|
|
3428
|
-
return "last month";
|
|
3429
|
-
}
|
|
3430
|
-
return range.startKey === range.endKey ? "previous day" : "previous range";
|
|
3431
|
-
};
|
|
3432
|
-
var getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
|
|
3433
|
-
const totalDays = new Date(year, monthIndex + 1, 0).getDate();
|
|
3434
|
-
const ranges = [];
|
|
3435
|
-
let currentStartDay = 1;
|
|
3436
|
-
for (let day = 1; day <= totalDays; day += 1) {
|
|
3437
|
-
const zonedDate = dateFnsTz.toZonedTime(new Date(year, monthIndex, day), timezone);
|
|
3438
|
-
const dayOfWeek = zonedDate.getDay();
|
|
3439
|
-
const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
|
|
3440
|
-
if (isEndOfWeek) {
|
|
3441
|
-
const startKey = buildDateKey(year, monthIndex, currentStartDay);
|
|
3442
|
-
const endKey = buildDateKey(year, monthIndex, day);
|
|
3443
|
-
if (maxKey && startKey > maxKey) {
|
|
3444
|
-
break;
|
|
3445
|
-
}
|
|
3446
|
-
const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
|
|
3447
|
-
if (clampedEndKey < startKey) {
|
|
3448
|
-
break;
|
|
3449
|
-
}
|
|
3450
|
-
const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
|
|
3451
|
-
const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
|
|
3452
|
-
ranges.push({
|
|
3453
|
-
startKey,
|
|
3454
|
-
endKey: clampedEndKey,
|
|
3455
|
-
label: `Week of ${labelStart} - ${labelEnd}`
|
|
3456
|
-
});
|
|
3457
|
-
currentStartDay = day + 1;
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
return ranges;
|
|
3461
|
-
};
|
|
3462
|
-
var formatRangeLabel = (range, fullMonthLabel) => {
|
|
3463
|
-
if (!range.startKey || !range.endKey) return fullMonthLabel;
|
|
3464
|
-
if (range.startKey === range.endKey) {
|
|
3465
|
-
return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
|
|
3466
|
-
}
|
|
3467
|
-
const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
|
|
3468
|
-
const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
|
|
3469
|
-
return `${startLabel} - ${endLabel}`;
|
|
3470
|
-
};
|
|
3471
|
-
var filterDataByDateKeyRange = (data, range) => {
|
|
3472
|
-
if (!range.startKey || !range.endKey) return data;
|
|
3473
|
-
return (data || []).filter((item) => {
|
|
3474
|
-
const dateKey = typeof item.date === "string" ? item.date : getDateKeyFromDate(item.date);
|
|
3475
|
-
return dateKey >= range.startKey && dateKey <= range.endKey;
|
|
3476
|
-
});
|
|
3477
|
-
};
|
|
3478
|
-
|
|
3479
|
-
// src/lib/utils/shifts.ts
|
|
3480
3496
|
var DEFAULT_DAY_SHIFT_START = "06:00";
|
|
3481
3497
|
var DEFAULT_NIGHT_SHIFT_START = "18:00";
|
|
3482
3498
|
var DEFAULT_TRANSITION_MINUTES = 15;
|
|
@@ -49910,6 +49926,7 @@ var formatHours = (value) => {
|
|
|
49910
49926
|
if (Math.abs(rounded) < 0.05) return "0h";
|
|
49911
49927
|
return Number.isInteger(rounded) ? `${rounded}h` : `${rounded.toFixed(1)}h`;
|
|
49912
49928
|
};
|
|
49929
|
+
var roundToSingleDecimal = (value) => Math.round(value * 10) / 10;
|
|
49913
49930
|
var formatCycleSeconds = (value) => {
|
|
49914
49931
|
if (!Number.isFinite(value)) return "0.0s";
|
|
49915
49932
|
return `${value.toFixed(1)}s`;
|
|
@@ -50035,21 +50052,30 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50035
50052
|
if (!shiftConfig) return null;
|
|
50036
50053
|
return getShiftWorkDurationSeconds(shiftConfig, selectedShiftId);
|
|
50037
50054
|
}, [shiftConfig, selectedShiftId]);
|
|
50038
|
-
const
|
|
50055
|
+
const analysisMonthlyDataByKey = React143.useMemo(
|
|
50056
|
+
() => new Map(analysisMonthlyData.map((day) => [getDayDateKey(day), day])),
|
|
50057
|
+
[analysisMonthlyData]
|
|
50058
|
+
);
|
|
50059
|
+
const monthlyDataByKey = React143.useMemo(
|
|
50060
|
+
() => new Map(data.map((day) => [getDayDateKey(day), day])),
|
|
50061
|
+
[data]
|
|
50062
|
+
);
|
|
50063
|
+
const rangeDateKeys = React143.useMemo(() => {
|
|
50039
50064
|
const rangeStartDate = parseDateKeyToDate(normalizedRange.startKey);
|
|
50040
50065
|
const rangeEndDate = parseDateKeyToDate(normalizedRange.endKey);
|
|
50041
|
-
const
|
|
50066
|
+
const keys = [];
|
|
50042
50067
|
for (let d = new Date(rangeStartDate); d <= rangeEndDate; d.setDate(d.getDate() + 1)) {
|
|
50043
|
-
|
|
50068
|
+
keys.push(buildDateKey(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
50044
50069
|
}
|
|
50070
|
+
return keys;
|
|
50071
|
+
}, [normalizedRange.endKey, normalizedRange.startKey]);
|
|
50072
|
+
const chartData = React143.useMemo(() => {
|
|
50045
50073
|
const dailyData = [];
|
|
50046
50074
|
if (isUptimeMode) {
|
|
50047
50075
|
let maxHours = 0;
|
|
50048
|
-
for (const
|
|
50049
|
-
const dayData =
|
|
50050
|
-
|
|
50051
|
-
return date.getDate() === day;
|
|
50052
|
-
});
|
|
50076
|
+
for (const dateKey of rangeDateKeys) {
|
|
50077
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50078
|
+
const dayNumber = Number(dateKey.slice(-2));
|
|
50053
50079
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50054
50080
|
const hasShiftData = Boolean(shiftData && hasRealData(shiftData));
|
|
50055
50081
|
const availableSeconds = hasShiftData ? shiftData.availableTimeSeconds ?? shiftWorkSeconds ?? 0 : 0;
|
|
@@ -50076,8 +50102,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50076
50102
|
}
|
|
50077
50103
|
maxHours = Math.max(maxHours, idleHours + productiveHours);
|
|
50078
50104
|
dailyData.push({
|
|
50079
|
-
hour: getOrdinal2(
|
|
50080
|
-
timeRange: `Day ${
|
|
50105
|
+
hour: getOrdinal2(dayNumber),
|
|
50106
|
+
timeRange: `Day ${dayNumber}`,
|
|
50081
50107
|
productiveHours,
|
|
50082
50108
|
idleHours,
|
|
50083
50109
|
utilization
|
|
@@ -50088,12 +50114,9 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50088
50114
|
}
|
|
50089
50115
|
let maxOutput = 0;
|
|
50090
50116
|
let lastSetTarget = 0;
|
|
50091
|
-
for (let i =
|
|
50092
|
-
const
|
|
50093
|
-
const dayData =
|
|
50094
|
-
const date = new Date(d.date);
|
|
50095
|
-
return date.getDate() === day;
|
|
50096
|
-
});
|
|
50117
|
+
for (let i = rangeDateKeys.length - 1; i >= 0; i--) {
|
|
50118
|
+
const dateKey = rangeDateKeys[i];
|
|
50119
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50097
50120
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50098
50121
|
const idealOutput = shiftData ? shiftData.idealOutput : 0;
|
|
50099
50122
|
if (idealOutput > 0) {
|
|
@@ -50101,20 +50124,18 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50101
50124
|
break;
|
|
50102
50125
|
}
|
|
50103
50126
|
}
|
|
50104
|
-
for (const
|
|
50105
|
-
const dayData =
|
|
50106
|
-
|
|
50107
|
-
return date.getDate() === day;
|
|
50108
|
-
});
|
|
50127
|
+
for (const dateKey of rangeDateKeys) {
|
|
50128
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50129
|
+
const dayNumber = Number(dateKey.slice(-2));
|
|
50109
50130
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50110
50131
|
const output = shiftData && hasRealData(shiftData) ? shiftData.output : 0;
|
|
50111
50132
|
const idealOutput = shiftData ? shiftData.idealOutput : 0;
|
|
50112
50133
|
if (output > maxOutput) maxOutput = output;
|
|
50113
50134
|
const color2 = output >= lastSetTarget ? "#00AB45" : "#E34329";
|
|
50114
50135
|
dailyData.push({
|
|
50115
|
-
hour: getOrdinal2(
|
|
50136
|
+
hour: getOrdinal2(dayNumber),
|
|
50116
50137
|
// Using ordinal format (1st, 2nd, 3rd, etc.)
|
|
50117
|
-
timeRange: `Day ${
|
|
50138
|
+
timeRange: `Day ${dayNumber}`,
|
|
50118
50139
|
output,
|
|
50119
50140
|
originalOutput: output,
|
|
50120
50141
|
// For label display
|
|
@@ -50128,7 +50149,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50128
50149
|
const calculatedMax = Math.max(maxOutput, lastSetTarget);
|
|
50129
50150
|
const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
|
|
50130
50151
|
return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
|
|
50131
|
-
}, [
|
|
50152
|
+
}, [analysisMonthlyDataByKey, rangeDateKeys, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
|
|
50132
50153
|
const yAxisTicks = React143.useMemo(() => {
|
|
50133
50154
|
if (isUptimeMode) return void 0;
|
|
50134
50155
|
const max = chartData.yAxisMax;
|
|
@@ -50213,7 +50234,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50213
50234
|
}
|
|
50214
50235
|
const avgEfficiency = Math.round(totalEfficiency / filteredShifts.length);
|
|
50215
50236
|
const avgDailyOutput = Math.round(totalOutput / filteredShifts.length);
|
|
50216
|
-
const avgCycleTime =
|
|
50237
|
+
const avgCycleTime = roundToSingleDecimal(totalCycleTime / filteredShifts.length);
|
|
50217
50238
|
const avgRank = ranks.length > 0 ? Math.round(ranks.reduce((a, b) => a + b, 0) / ranks.length) : null;
|
|
50218
50239
|
return {
|
|
50219
50240
|
avgEfficiency,
|
|
@@ -50233,7 +50254,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50233
50254
|
const assemblyRangeCycleTime = React143.useMemo(() => {
|
|
50234
50255
|
const trendCycleTime = Number(trendSummary?.avg_cycle_time?.current);
|
|
50235
50256
|
if (Number.isFinite(trendCycleTime) && trendCycleTime > 0) {
|
|
50236
|
-
return
|
|
50257
|
+
return trendCycleTime;
|
|
50237
50258
|
}
|
|
50238
50259
|
return metrics2?.avgCycleTime ?? 0;
|
|
50239
50260
|
}, [trendSummary?.avg_cycle_time?.current, metrics2?.avgCycleTime]);
|
|
@@ -50262,20 +50283,15 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50262
50283
|
if (startOffset === -1) startOffset = 6;
|
|
50263
50284
|
const calendar = Array(startOffset).fill(null);
|
|
50264
50285
|
for (let day = 1; day <= totalDays; day++) {
|
|
50265
|
-
const
|
|
50266
|
-
|
|
50267
|
-
return date.getDate() === day;
|
|
50268
|
-
});
|
|
50286
|
+
const dateKey = buildDateKey(year, month, day);
|
|
50287
|
+
const dayData = monthlyDataByKey.get(dateKey);
|
|
50269
50288
|
calendar.push(dayData || null);
|
|
50270
50289
|
}
|
|
50271
50290
|
return { calendar, startOffset };
|
|
50272
|
-
}, [
|
|
50291
|
+
}, [monthlyDataByKey, month, year]);
|
|
50273
50292
|
const handleDayClick = React143.useCallback((day) => {
|
|
50274
50293
|
if (!day) return;
|
|
50275
|
-
const
|
|
50276
|
-
const month2 = String(day.date.getMonth() + 1).padStart(2, "0");
|
|
50277
|
-
const dayOfMonth = String(day.date.getDate()).padStart(2, "0");
|
|
50278
|
-
const formattedDate = `${year2}-${month2}-${dayOfMonth}`;
|
|
50294
|
+
const formattedDate = getDayDateKey(day);
|
|
50279
50295
|
trackCoreEvent("Workspace Monthly History Day Clicked", {
|
|
50280
50296
|
source: "monthly_history",
|
|
50281
50297
|
workspace_id: workspaceId,
|
|
@@ -51221,13 +51237,20 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51221
51237
|
startKey: rangeStart || monthBounds.startKey,
|
|
51222
51238
|
endKey: rangeEnd || monthBounds.endKey
|
|
51223
51239
|
};
|
|
51240
|
+
const boundsSourceKey = rangeStart || rangeEnd || monthBounds.startKey;
|
|
51241
|
+
const boundsSourceDate = parseDateKeyToDate(boundsSourceKey);
|
|
51242
|
+
const effectiveBounds = getMonthKeyBounds(boundsSourceDate.getFullYear(), boundsSourceDate.getMonth());
|
|
51224
51243
|
const normalizedRange = normalizeDateKeyRange(
|
|
51225
51244
|
requestedRange.startKey,
|
|
51226
51245
|
requestedRange.endKey,
|
|
51227
|
-
|
|
51228
|
-
|
|
51246
|
+
effectiveBounds.startKey,
|
|
51247
|
+
effectiveBounds.endKey
|
|
51248
|
+
);
|
|
51249
|
+
const fullRange = isFullMonthRange(
|
|
51250
|
+
normalizedRange,
|
|
51251
|
+
boundsSourceDate.getFullYear(),
|
|
51252
|
+
boundsSourceDate.getMonth()
|
|
51229
51253
|
);
|
|
51230
|
-
const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
|
|
51231
51254
|
const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
|
|
51232
51255
|
const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
|
|
51233
51256
|
const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
|
|
@@ -51249,12 +51272,17 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51249
51272
|
const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
|
|
51250
51273
|
const resolvedLineName = lineName?.trim() || "Line";
|
|
51251
51274
|
const dailySectionTitle = isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary";
|
|
51275
|
+
const monthName = reportStartDate.toLocaleDateString("en-IN", {
|
|
51276
|
+
month: "long",
|
|
51277
|
+
year: "numeric",
|
|
51278
|
+
timeZone: "Asia/Kolkata"
|
|
51279
|
+
});
|
|
51252
51280
|
trackCoreEvent("Workspace Monthly PDF Export Clicked", {
|
|
51253
51281
|
workspace_id: workspaceId,
|
|
51254
51282
|
workspace_name: workspaceName,
|
|
51255
51283
|
line_name: resolvedLineName,
|
|
51256
|
-
month:
|
|
51257
|
-
year:
|
|
51284
|
+
month: reportStartDate.getMonth(),
|
|
51285
|
+
year: reportStartDate.getFullYear(),
|
|
51258
51286
|
shift_id: selectedShiftId,
|
|
51259
51287
|
range_start: normalizedRange.startKey,
|
|
51260
51288
|
range_end: normalizedRange.endKey,
|
|
@@ -51295,11 +51323,6 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51295
51323
|
doc.setFontSize(13);
|
|
51296
51324
|
doc.setFont("helvetica", "normal");
|
|
51297
51325
|
doc.setTextColor(60, 60, 60);
|
|
51298
|
-
const monthName = new Date(selectedYear, selectedMonth).toLocaleDateString("en-IN", {
|
|
51299
|
-
month: "long",
|
|
51300
|
-
year: "numeric",
|
|
51301
|
-
timeZone: "Asia/Kolkata"
|
|
51302
|
-
});
|
|
51303
51326
|
const shiftType = getShiftDisplayName2(selectedShiftId, availableShifts);
|
|
51304
51327
|
doc.text(`${monthName}`, 20, 65);
|
|
51305
51328
|
doc.text(`${shiftType}`, 20, 73);
|
|
@@ -51311,15 +51334,12 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51311
51334
|
doc.setLineWidth(0.8);
|
|
51312
51335
|
doc.line(20, 90, 190, 90);
|
|
51313
51336
|
const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
|
|
51314
|
-
const validDays = reportData
|
|
51315
|
-
const date = new Date(day.date);
|
|
51316
|
-
return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
|
|
51317
|
-
});
|
|
51337
|
+
const validDays = reportData;
|
|
51318
51338
|
const validShifts = validDays.map((day) => getShiftData(day, selectedShiftId)).filter(hasShiftData);
|
|
51319
51339
|
const dailyEntries = validDays.map((dayData) => {
|
|
51320
51340
|
const shift = getShiftData(dayData, selectedShiftId);
|
|
51321
51341
|
return { dayData, shift };
|
|
51322
|
-
}).filter(({ shift }) => hasShiftData(shift)).sort((left, right) =>
|
|
51342
|
+
}).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => getDayDateKey(right.dayData).localeCompare(getDayDateKey(left.dayData)));
|
|
51323
51343
|
const filteredShifts = isUptimeMode ? validShifts : validShifts.filter((shift) => (shift.efficiency ?? 0) >= 5);
|
|
51324
51344
|
const monthlyMetrics = filteredShifts.length > 0 ? isUptimeMode ? (() => {
|
|
51325
51345
|
const totalIdleTime = filteredShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
|
|
@@ -71152,15 +71172,26 @@ var WorkspaceDetailView = ({
|
|
|
71152
71172
|
const range = React143.useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
|
|
71153
71173
|
const isFullRange = React143.useMemo(() => isFullMonthRange(range, selectedYear, selectedMonth), [range, selectedYear, selectedMonth]);
|
|
71154
71174
|
React143.useEffect(() => {
|
|
71175
|
+
const hasExternalRange = typeof urlRangeStart === "string" || typeof urlRangeEnd === "string";
|
|
71176
|
+
if (!hasExternalRange) {
|
|
71177
|
+
return;
|
|
71178
|
+
}
|
|
71179
|
+
const targetStartKey = typeof urlRangeStart === "string" ? urlRangeStart : typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.startKey;
|
|
71180
|
+
const targetStartDate = parseDateKeyToDate(targetStartKey);
|
|
71181
|
+
const targetMonth = targetStartDate.getMonth();
|
|
71182
|
+
const targetYear = targetStartDate.getFullYear();
|
|
71183
|
+
const targetBounds = getMonthKeyBounds(targetYear, targetMonth);
|
|
71155
71184
|
const normalized = normalizeDateKeyRange(
|
|
71156
|
-
typeof urlRangeStart === "string" ? urlRangeStart :
|
|
71157
|
-
typeof urlRangeEnd === "string" ? urlRangeEnd :
|
|
71158
|
-
|
|
71159
|
-
|
|
71185
|
+
typeof urlRangeStart === "string" ? urlRangeStart : targetBounds.startKey,
|
|
71186
|
+
typeof urlRangeEnd === "string" ? urlRangeEnd : targetBounds.endKey,
|
|
71187
|
+
targetBounds.startKey,
|
|
71188
|
+
targetBounds.endKey
|
|
71160
71189
|
);
|
|
71190
|
+
setSelectedMonth(targetMonth);
|
|
71191
|
+
setSelectedYear(targetYear);
|
|
71161
71192
|
setRangeStart(normalized.startKey);
|
|
71162
71193
|
setRangeEnd(normalized.endKey);
|
|
71163
|
-
}, [urlRangeStart, urlRangeEnd, monthBounds.startKey
|
|
71194
|
+
}, [urlRangeStart, urlRangeEnd, monthBounds.startKey]);
|
|
71164
71195
|
const isHistoricView = Boolean(date && parsedShiftId !== void 0);
|
|
71165
71196
|
const initialTab = getInitialTab(sourceType, defaultTab, fromMonthly, date);
|
|
71166
71197
|
const [activeTab, setActiveTab] = React143.useState(initialTab);
|
|
@@ -71682,12 +71713,13 @@ var WorkspaceDetailView = ({
|
|
|
71682
71713
|
console.warn("Skipping invalid metric:", metric);
|
|
71683
71714
|
return;
|
|
71684
71715
|
}
|
|
71685
|
-
const
|
|
71686
|
-
const
|
|
71716
|
+
const dateKey = getDateKeyFromValue(metric.date);
|
|
71717
|
+
const dateObj = parseDateKeyToDate(dateKey);
|
|
71687
71718
|
let dayEntry = dayDataMap.get(dateKey);
|
|
71688
71719
|
if (!dayEntry) {
|
|
71689
71720
|
dayEntry = {
|
|
71690
71721
|
date: dateObj,
|
|
71722
|
+
dateKey,
|
|
71691
71723
|
shifts: {}
|
|
71692
71724
|
// Multi-shift structure: Record<number, CalendarShiftData>
|
|
71693
71725
|
};
|
|
@@ -71732,6 +71764,7 @@ var WorkspaceDetailView = ({
|
|
|
71732
71764
|
});
|
|
71733
71765
|
const processedData = Array.from(dayDataMap.values()).filter((entry) => Object.keys(entry.shifts).length > 0).map((entry) => ({
|
|
71734
71766
|
date: entry.date,
|
|
71767
|
+
dateKey: entry.dateKey,
|
|
71735
71768
|
shifts: entry.shifts
|
|
71736
71769
|
}));
|
|
71737
71770
|
console.log(`[handleMonthlyDataLoaded] Transformed data for calendar:`, {
|
|
@@ -81949,6 +81982,8 @@ exports.getCurrentWeekFullRange = getCurrentWeekFullRange;
|
|
|
81949
81982
|
exports.getCurrentWeekToDateRange = getCurrentWeekToDateRange;
|
|
81950
81983
|
exports.getDashboardHeaderTimeInZone = getDashboardHeaderTimeInZone;
|
|
81951
81984
|
exports.getDateKeyFromDate = getDateKeyFromDate;
|
|
81985
|
+
exports.getDateKeyFromValue = getDateKeyFromValue;
|
|
81986
|
+
exports.getDayDateKey = getDayDateKey;
|
|
81952
81987
|
exports.getDaysDifferenceInZone = getDaysDifferenceInZone;
|
|
81953
81988
|
exports.getDefaultCameraStreamUrl = getDefaultCameraStreamUrl;
|
|
81954
81989
|
exports.getDefaultLineId = getDefaultLineId;
|