@optifye/dashboard-core 6.11.38 → 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 +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +451 -315
- package/dist/index.mjs +449 -316
- 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,130 +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 getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
|
|
3427
|
-
const totalDays = new Date(year, monthIndex + 1, 0).getDate();
|
|
3428
|
-
const ranges = [];
|
|
3429
|
-
let currentStartDay = 1;
|
|
3430
|
-
for (let day = 1; day <= totalDays; day += 1) {
|
|
3431
|
-
const zonedDate = dateFnsTz.toZonedTime(new Date(year, monthIndex, day), timezone);
|
|
3432
|
-
const dayOfWeek = zonedDate.getDay();
|
|
3433
|
-
const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
|
|
3434
|
-
if (isEndOfWeek) {
|
|
3435
|
-
const startKey = buildDateKey(year, monthIndex, currentStartDay);
|
|
3436
|
-
const endKey = buildDateKey(year, monthIndex, day);
|
|
3437
|
-
if (maxKey && startKey > maxKey) {
|
|
3438
|
-
break;
|
|
3439
|
-
}
|
|
3440
|
-
const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
|
|
3441
|
-
if (clampedEndKey < startKey) {
|
|
3442
|
-
break;
|
|
3443
|
-
}
|
|
3444
|
-
const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
|
|
3445
|
-
const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
|
|
3446
|
-
ranges.push({
|
|
3447
|
-
startKey,
|
|
3448
|
-
endKey: clampedEndKey,
|
|
3449
|
-
label: `Week of ${labelStart} - ${labelEnd}`
|
|
3450
|
-
});
|
|
3451
|
-
currentStartDay = day + 1;
|
|
3452
|
-
}
|
|
3453
|
-
}
|
|
3454
|
-
return ranges;
|
|
3455
|
-
};
|
|
3456
|
-
var formatRangeLabel = (range, fullMonthLabel) => {
|
|
3457
|
-
if (!range.startKey || !range.endKey) return fullMonthLabel;
|
|
3458
|
-
if (range.startKey === range.endKey) {
|
|
3459
|
-
return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
|
|
3460
|
-
}
|
|
3461
|
-
const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
|
|
3462
|
-
const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
|
|
3463
|
-
return `${startLabel} - ${endLabel}`;
|
|
3464
|
-
};
|
|
3465
|
-
var filterDataByDateKeyRange = (data, range) => {
|
|
3466
|
-
if (!range.startKey || !range.endKey) return data;
|
|
3467
|
-
return (data || []).filter((item) => {
|
|
3468
|
-
const dateKey = typeof item.date === "string" ? item.date : getDateKeyFromDate(item.date);
|
|
3469
|
-
return dateKey >= range.startKey && dateKey <= range.endKey;
|
|
3470
|
-
});
|
|
3471
|
-
};
|
|
3472
|
-
|
|
3473
|
-
// src/lib/utils/shifts.ts
|
|
3474
3496
|
var DEFAULT_DAY_SHIFT_START = "06:00";
|
|
3475
3497
|
var DEFAULT_NIGHT_SHIFT_START = "18:00";
|
|
3476
3498
|
var DEFAULT_TRANSITION_MINUTES = 15;
|
|
@@ -12290,6 +12312,7 @@ var toWorkspaceDetailedMetrics = ({
|
|
|
12290
12312
|
return {
|
|
12291
12313
|
workspace_id: data.workspace_id,
|
|
12292
12314
|
workspace_name: data.workspace_name,
|
|
12315
|
+
workspace_display_name: typeof data.workspace_display_name === "string" ? data.workspace_display_name : typeof data.display_name === "string" ? data.display_name : null,
|
|
12293
12316
|
line_id: data.line_id,
|
|
12294
12317
|
line_name: data.line_name || "",
|
|
12295
12318
|
line_assembly_enabled: data.line_assembly_enabled === true || data.assembly_enabled === true,
|
|
@@ -18438,13 +18461,27 @@ var useMonthlyTrend = (params) => {
|
|
|
18438
18461
|
if (typeof params.shiftId === "number") {
|
|
18439
18462
|
searchParams.append("shift_id", params.shiftId.toString());
|
|
18440
18463
|
}
|
|
18464
|
+
if (params.startDate && params.endDate) {
|
|
18465
|
+
searchParams.append("start_date", params.startDate);
|
|
18466
|
+
searchParams.append("end_date", params.endDate);
|
|
18467
|
+
}
|
|
18441
18468
|
if (params.entityType === "line") {
|
|
18442
18469
|
searchParams.append("line_id", params.entityId);
|
|
18443
18470
|
} else {
|
|
18444
18471
|
searchParams.append("workspace_id", params.entityId);
|
|
18445
18472
|
}
|
|
18446
18473
|
return searchParams.toString();
|
|
18447
|
-
}, [
|
|
18474
|
+
}, [
|
|
18475
|
+
params.companyId,
|
|
18476
|
+
params.endDate,
|
|
18477
|
+
params.entityId,
|
|
18478
|
+
params.entityType,
|
|
18479
|
+
params.month,
|
|
18480
|
+
params.shiftId,
|
|
18481
|
+
params.startDate,
|
|
18482
|
+
params.year,
|
|
18483
|
+
entityConfig?.companyId
|
|
18484
|
+
]);
|
|
18448
18485
|
React143.useEffect(() => {
|
|
18449
18486
|
let isMounted = true;
|
|
18450
18487
|
if (!queryString || !supabase) {
|
|
@@ -47290,6 +47327,10 @@ var LineMonthlyHistory = ({
|
|
|
47290
47327
|
const efficiencyImproved = efficiencyDelta >= 0;
|
|
47291
47328
|
const EfficiencyTrendIcon = efficiencyImproved ? lucideReact.ArrowUp : lucideReact.ArrowDown;
|
|
47292
47329
|
const efficiencyTrendText = `${Math.abs(efficiencyDelta).toFixed(1)}%`;
|
|
47330
|
+
const trendComparisonLabel = React143.useMemo(
|
|
47331
|
+
() => getMonthlyTrendComparisonLabel(normalizedRange, year, month),
|
|
47332
|
+
[month, normalizedRange, year]
|
|
47333
|
+
);
|
|
47293
47334
|
const outputDelta = trendSummary?.avg_daily_output?.delta_pp ?? 0;
|
|
47294
47335
|
const outputImproved = outputDelta >= 0;
|
|
47295
47336
|
const OutputTrendIcon = outputImproved ? lucideReact.ArrowUp : lucideReact.ArrowDown;
|
|
@@ -47540,10 +47581,7 @@ var LineMonthlyHistory = ({
|
|
|
47540
47581
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-bold text-gray-900 whitespace-nowrap", children: uptimeSummary?.avgDailyStoppages ?? 0 }),
|
|
47541
47582
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${stoppagesImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
47542
47583
|
/* @__PURE__ */ jsxRuntime.jsx(StoppagesTrendIcon, { className: "w-3 h-3" }),
|
|
47543
|
-
/* @__PURE__ */ jsxRuntime.
|
|
47544
|
-
stoppagesTrendText,
|
|
47545
|
-
" vs last month"
|
|
47546
|
-
] })
|
|
47584
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${stoppagesTrendText} vs ${trendComparisonLabel}` })
|
|
47547
47585
|
] })
|
|
47548
47586
|
] })
|
|
47549
47587
|
] }),
|
|
@@ -47553,10 +47591,7 @@ var LineMonthlyHistory = ({
|
|
|
47553
47591
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base font-bold text-gray-900 whitespace-nowrap", children: formatIdleTime(uptimeSummary?.avgIdleTime ?? 0) }),
|
|
47554
47592
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${idleImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
47555
47593
|
/* @__PURE__ */ jsxRuntime.jsx(IdleTrendIcon, { className: "w-3 h-3" }),
|
|
47556
|
-
/* @__PURE__ */ jsxRuntime.
|
|
47557
|
-
idleTrendText,
|
|
47558
|
-
" vs last month"
|
|
47559
|
-
] })
|
|
47594
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${idleTrendText} vs ${trendComparisonLabel}` })
|
|
47560
47595
|
] })
|
|
47561
47596
|
] })
|
|
47562
47597
|
] })
|
|
@@ -47570,10 +47605,7 @@ var LineMonthlyHistory = ({
|
|
|
47570
47605
|
] }),
|
|
47571
47606
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${efficiencyImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
47572
47607
|
/* @__PURE__ */ jsxRuntime.jsx(EfficiencyTrendIcon, { className: "w-3 h-3" }),
|
|
47573
|
-
/* @__PURE__ */ jsxRuntime.
|
|
47574
|
-
efficiencyTrendText,
|
|
47575
|
-
" vs last month"
|
|
47576
|
-
] })
|
|
47608
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${efficiencyTrendText} vs ${trendComparisonLabel}` })
|
|
47577
47609
|
] })
|
|
47578
47610
|
] })
|
|
47579
47611
|
] }),
|
|
@@ -47583,10 +47615,7 @@ var LineMonthlyHistory = ({
|
|
|
47583
47615
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xl font-bold text-gray-900", children: Math.round(avgOutput).toLocaleString() }),
|
|
47584
47616
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${outputImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
47585
47617
|
/* @__PURE__ */ jsxRuntime.jsx(OutputTrendIcon, { className: "w-3 h-3" }),
|
|
47586
|
-
/* @__PURE__ */ jsxRuntime.
|
|
47587
|
-
outputTrendText,
|
|
47588
|
-
" vs last month"
|
|
47589
|
-
] })
|
|
47618
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${outputTrendText} vs ${trendComparisonLabel}` })
|
|
47590
47619
|
] })
|
|
47591
47620
|
] })
|
|
47592
47621
|
] })
|
|
@@ -47597,10 +47626,7 @@ var LineMonthlyHistory = ({
|
|
|
47597
47626
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs sm:text-sm font-bold text-gray-700 text-left", children: "Utilization" }),
|
|
47598
47627
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${utilizationImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-1.5 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
47599
47628
|
/* @__PURE__ */ jsxRuntime.jsx(UtilizationTrendIcon, { className: "w-3 h-3" }),
|
|
47600
|
-
/* @__PURE__ */ jsxRuntime.
|
|
47601
|
-
utilizationTrendText,
|
|
47602
|
-
" vs last month"
|
|
47603
|
-
] })
|
|
47629
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${utilizationTrendText} vs ${trendComparisonLabel}` })
|
|
47604
47630
|
] })
|
|
47605
47631
|
] }),
|
|
47606
47632
|
pieChartData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-[140px] sm:h-[160px] flex items-center overflow-hidden", children: [
|
|
@@ -47952,19 +47978,33 @@ var LineMonthlyPdfGenerator = ({
|
|
|
47952
47978
|
is_full_month: fullRange
|
|
47953
47979
|
});
|
|
47954
47980
|
const doc = new jsPDF.jsPDF();
|
|
47955
|
-
doc.
|
|
47956
|
-
|
|
47957
|
-
|
|
47958
|
-
|
|
47959
|
-
|
|
47960
|
-
|
|
47961
|
-
|
|
47962
|
-
|
|
47963
|
-
|
|
47964
|
-
|
|
47965
|
-
|
|
47966
|
-
|
|
47967
|
-
|
|
47981
|
+
const pageHeight = typeof doc.internal.pageSize.height === "number" ? Number(doc.internal.pageSize.height) : 297;
|
|
47982
|
+
const footerY = pageHeight - 17;
|
|
47983
|
+
const maxContentY = footerY - 10;
|
|
47984
|
+
const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
|
|
47985
|
+
const dailySectionTitle = isUptimeMode ? "Daily Utilization Summary" : "Daily Performance Summary";
|
|
47986
|
+
const drawPageChrome = () => {
|
|
47987
|
+
doc.setFontSize(14);
|
|
47988
|
+
doc.setFont("helvetica", "bold");
|
|
47989
|
+
doc.setTextColor(50, 50, 50);
|
|
47990
|
+
doc.text("OPTIFYE.AI", 20, 15);
|
|
47991
|
+
doc.setFontSize(11);
|
|
47992
|
+
doc.setFont("helvetica", "normal");
|
|
47993
|
+
doc.setTextColor(80, 80, 80);
|
|
47994
|
+
const reportText = isUptimeMode ? "MONTHLY UTILIZATION REPORT" : "MONTHLY PERFORMANCE REPORT";
|
|
47995
|
+
const reportTextWidth = doc.getStringUnitWidth(reportText) * 11 / doc.internal.scaleFactor;
|
|
47996
|
+
doc.text(reportText, doc.internal.pageSize.width - 20 - reportTextWidth, 15);
|
|
47997
|
+
doc.setDrawColor(200, 200, 200);
|
|
47998
|
+
doc.setLineWidth(0.5);
|
|
47999
|
+
doc.line(20, 20, 190, 20);
|
|
48000
|
+
};
|
|
48001
|
+
const drawFooter = () => {
|
|
48002
|
+
doc.setFontSize(9);
|
|
48003
|
+
doc.setTextColor(130, 130, 130);
|
|
48004
|
+
doc.text(generatedText, 20, footerY);
|
|
48005
|
+
doc.setTextColor(0, 0, 0);
|
|
48006
|
+
};
|
|
48007
|
+
drawPageChrome();
|
|
47968
48008
|
doc.setFillColor(250, 250, 250);
|
|
47969
48009
|
doc.roundedRect(15, 25, 180, 55, 3, 3, "F");
|
|
47970
48010
|
doc.setFontSize(32);
|
|
@@ -47999,6 +48039,10 @@ var LineMonthlyPdfGenerator = ({
|
|
|
47999
48039
|
if (shift.hasData !== void 0) return shift.hasData;
|
|
48000
48040
|
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;
|
|
48001
48041
|
};
|
|
48042
|
+
const dailyEntries = validDays.map((dayData) => {
|
|
48043
|
+
const shift = getLineShiftData2(dayData, selectedShiftId);
|
|
48044
|
+
return { dayData, shift };
|
|
48045
|
+
}).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => new Date(right.dayData.date).getTime() - new Date(left.dayData.date).getTime());
|
|
48002
48046
|
const getUptimeTotals2 = (shift, hasData) => {
|
|
48003
48047
|
if (!hasData || !shift) {
|
|
48004
48048
|
return { availableSeconds: 0, productiveSeconds: 0, idleSeconds: 0 };
|
|
@@ -48125,46 +48169,45 @@ var LineMonthlyPdfGenerator = ({
|
|
|
48125
48169
|
}
|
|
48126
48170
|
const dailySeparatorY = isUptimeMode ? 180 : 165;
|
|
48127
48171
|
const dailySectionStartY = isUptimeMode ? 185 : 170;
|
|
48128
|
-
const dailyTitleY = isUptimeMode ? 195 : 180;
|
|
48129
|
-
const dailyHeaderY = isUptimeMode ? 200 : 185;
|
|
48130
|
-
const dailyHeaderTextY = isUptimeMode ? 205 : 190;
|
|
48131
|
-
const dailyHeaderLineY = isUptimeMode ? 208 : 193;
|
|
48132
48172
|
const dailyContentStartY = isUptimeMode ? 215 : 200;
|
|
48133
|
-
const dailyMaxY = isUptimeMode ? 260 : 245;
|
|
48134
48173
|
doc.setDrawColor(180, 180, 180);
|
|
48135
48174
|
doc.setLineWidth(0.8);
|
|
48136
48175
|
doc.line(20, dailySeparatorY, 190, dailySeparatorY);
|
|
48137
|
-
|
|
48138
|
-
|
|
48139
|
-
|
|
48140
|
-
|
|
48141
|
-
|
|
48142
|
-
|
|
48143
|
-
|
|
48144
|
-
|
|
48176
|
+
const renderDailyTablePage = (startIndex, sectionY, title) => {
|
|
48177
|
+
const rowHeight = 8;
|
|
48178
|
+
const tableHeaderY = sectionY + 15;
|
|
48179
|
+
const headerTextY = tableHeaderY + 5;
|
|
48180
|
+
const firstRowY = headerTextY + 10;
|
|
48181
|
+
const rowsPerPage = Math.max(1, Math.floor((maxContentY - firstRowY) / rowHeight));
|
|
48182
|
+
const pageEntries = dailyEntries.slice(startIndex, startIndex + rowsPerPage);
|
|
48183
|
+
const endY = firstRowY + pageEntries.length * rowHeight;
|
|
48184
|
+
const sectionHeight = Math.max(40, endY - sectionY + 5);
|
|
48185
|
+
doc.setFillColor(245, 245, 245);
|
|
48186
|
+
doc.roundedRect(15, sectionY, 180, sectionHeight, 3, 3, "F");
|
|
48187
|
+
doc.setFontSize(18);
|
|
48188
|
+
doc.setFont("helvetica", "bold");
|
|
48189
|
+
doc.setTextColor(40, 40, 40);
|
|
48190
|
+
doc.text(title, 20, sectionY + 10);
|
|
48191
|
+
doc.setTextColor(0, 0, 0);
|
|
48145
48192
|
doc.setFontSize(10);
|
|
48146
48193
|
doc.setFont("helvetica", "bold");
|
|
48147
48194
|
doc.setFillColor(240, 240, 240);
|
|
48148
|
-
doc.roundedRect(20,
|
|
48149
|
-
doc.text("Date", 25,
|
|
48195
|
+
doc.roundedRect(20, tableHeaderY, 170, 7, 1, 1, "F");
|
|
48196
|
+
doc.text("Date", 25, headerTextY);
|
|
48150
48197
|
if (isUptimeMode) {
|
|
48151
|
-
doc.text("Utilization", 95,
|
|
48198
|
+
doc.text("Utilization", 95, headerTextY);
|
|
48152
48199
|
} else {
|
|
48153
|
-
doc.text("Actual", 60,
|
|
48154
|
-
doc.text("Standard", 95,
|
|
48155
|
-
doc.text("Efficiency", 135,
|
|
48156
|
-
doc.text("Status", 170,
|
|
48200
|
+
doc.text("Actual", 60, headerTextY);
|
|
48201
|
+
doc.text("Standard", 95, headerTextY);
|
|
48202
|
+
doc.text("Efficiency", 135, headerTextY);
|
|
48203
|
+
doc.text("Status", 170, headerTextY);
|
|
48157
48204
|
}
|
|
48158
48205
|
doc.setLineWidth(0.2);
|
|
48159
48206
|
doc.setDrawColor(220, 220, 220);
|
|
48160
|
-
doc.line(20,
|
|
48207
|
+
doc.line(20, headerTextY + 3, 190, headerTextY + 3);
|
|
48161
48208
|
doc.setFont("helvetica", "normal");
|
|
48162
|
-
let yPos =
|
|
48163
|
-
|
|
48164
|
-
recentDays.forEach((dayData, index) => {
|
|
48165
|
-
if (yPos > dailyMaxY) return;
|
|
48166
|
-
const shift = getLineShiftData2(dayData, selectedShiftId);
|
|
48167
|
-
if (!hasShiftData(shift)) return;
|
|
48209
|
+
let yPos = firstRowY;
|
|
48210
|
+
pageEntries.forEach(({ dayData, shift }, index) => {
|
|
48168
48211
|
if (isUptimeMode) {
|
|
48169
48212
|
doc.setDrawColor(200, 200, 200);
|
|
48170
48213
|
doc.setLineWidth(0.1);
|
|
@@ -48205,12 +48248,34 @@ var LineMonthlyPdfGenerator = ({
|
|
|
48205
48248
|
}
|
|
48206
48249
|
doc.setTextColor(0, 0, 0);
|
|
48207
48250
|
}
|
|
48208
|
-
yPos +=
|
|
48251
|
+
yPos += rowHeight;
|
|
48209
48252
|
});
|
|
48210
48253
|
if (!isUptimeMode) {
|
|
48211
48254
|
doc.setLineWidth(0.2);
|
|
48212
48255
|
doc.setDrawColor(220, 220, 220);
|
|
48213
|
-
doc.roundedRect(20,
|
|
48256
|
+
doc.roundedRect(20, tableHeaderY, 170, yPos - tableHeaderY - 3, 1, 1, "S");
|
|
48257
|
+
}
|
|
48258
|
+
return startIndex + pageEntries.length;
|
|
48259
|
+
};
|
|
48260
|
+
if (dailyEntries.length > 0) {
|
|
48261
|
+
let renderedEntries = renderDailyTablePage(0, dailySectionStartY, dailySectionTitle);
|
|
48262
|
+
while (renderedEntries < dailyEntries.length) {
|
|
48263
|
+
drawFooter();
|
|
48264
|
+
doc.addPage();
|
|
48265
|
+
drawPageChrome();
|
|
48266
|
+
doc.setFontSize(12);
|
|
48267
|
+
doc.setFont("helvetica", "bold");
|
|
48268
|
+
doc.setTextColor(40, 40, 40);
|
|
48269
|
+
doc.text(lineName || "Line", 20, 32);
|
|
48270
|
+
doc.setFont("helvetica", "normal");
|
|
48271
|
+
doc.setTextColor(90, 90, 90);
|
|
48272
|
+
doc.text(`${monthName} \u2022 ${shiftType} \u2022 ${reportStartStr} - ${reportEndStr}`, 20, 40);
|
|
48273
|
+
doc.setTextColor(0, 0, 0);
|
|
48274
|
+
renderedEntries = renderDailyTablePage(
|
|
48275
|
+
renderedEntries,
|
|
48276
|
+
48,
|
|
48277
|
+
`${dailySectionTitle} (cont.)`
|
|
48278
|
+
);
|
|
48214
48279
|
}
|
|
48215
48280
|
} else {
|
|
48216
48281
|
doc.setFontSize(12);
|
|
@@ -48223,20 +48288,9 @@ var LineMonthlyPdfGenerator = ({
|
|
|
48223
48288
|
const isCycleTimeWorkspace = (workspace) => workspace.metric_mode === "cycle_time" || lineAssembly && (workspace.avg_cycle_time !== void 0 || workspace.ideal_cycle_time !== void 0 || workspace.cycle_ratio !== void 0);
|
|
48224
48289
|
const showCycleTimePoorestPerformers = !isUptimeMode && poorestWorkspaces.some(isCycleTimeWorkspace);
|
|
48225
48290
|
if (poorestWorkspaces && poorestWorkspaces.length > 0) {
|
|
48291
|
+
drawFooter();
|
|
48226
48292
|
doc.addPage();
|
|
48227
|
-
|
|
48228
|
-
doc.setFont("helvetica", "bold");
|
|
48229
|
-
doc.setTextColor(50, 50, 50);
|
|
48230
|
-
doc.text("OPTIFYE.AI", 20, 15);
|
|
48231
|
-
doc.setFontSize(11);
|
|
48232
|
-
doc.setFont("helvetica", "normal");
|
|
48233
|
-
doc.setTextColor(80, 80, 80);
|
|
48234
|
-
const reportText2 = isUptimeMode ? "MONTHLY UTILIZATION REPORT" : "MONTHLY PERFORMANCE REPORT";
|
|
48235
|
-
const reportTextWidth2 = doc.getStringUnitWidth(reportText2) * 11 / doc.internal.scaleFactor;
|
|
48236
|
-
doc.text(reportText2, doc.internal.pageSize.width - 20 - reportTextWidth2, 15);
|
|
48237
|
-
doc.setDrawColor(200, 200, 200);
|
|
48238
|
-
doc.setLineWidth(0.5);
|
|
48239
|
-
doc.line(20, 20, 190, 20);
|
|
48293
|
+
drawPageChrome();
|
|
48240
48294
|
doc.setFontSize(18);
|
|
48241
48295
|
doc.setFont("helvetica", "bold");
|
|
48242
48296
|
doc.setTextColor(40, 40, 40);
|
|
@@ -48302,10 +48356,7 @@ var LineMonthlyPdfGenerator = ({
|
|
|
48302
48356
|
doc.setDrawColor(220, 220, 220);
|
|
48303
48357
|
doc.roundedRect(20, 45, 170, yPos2 - 45 - 5, 1, 1, "S");
|
|
48304
48358
|
}
|
|
48305
|
-
|
|
48306
|
-
doc.setTextColor(130, 130, 130);
|
|
48307
|
-
const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
|
|
48308
|
-
doc.text(generatedText, 20, 280);
|
|
48359
|
+
drawFooter();
|
|
48309
48360
|
const fileName = `${lineName || "Line"}_${monthName.replace(" ", "_")}_${shiftType.replace(" ", "_")}.pdf`;
|
|
48310
48361
|
doc.save(fileName);
|
|
48311
48362
|
} catch (error) {
|
|
@@ -49875,6 +49926,11 @@ var formatHours = (value) => {
|
|
|
49875
49926
|
if (Math.abs(rounded) < 0.05) return "0h";
|
|
49876
49927
|
return Number.isInteger(rounded) ? `${rounded}h` : `${rounded.toFixed(1)}h`;
|
|
49877
49928
|
};
|
|
49929
|
+
var roundToSingleDecimal = (value) => Math.round(value * 10) / 10;
|
|
49930
|
+
var formatCycleSeconds = (value) => {
|
|
49931
|
+
if (!Number.isFinite(value)) return "0.0s";
|
|
49932
|
+
return `${value.toFixed(1)}s`;
|
|
49933
|
+
};
|
|
49878
49934
|
var CustomTooltip3 = ({ active, payload, label, isUptimeMode }) => {
|
|
49879
49935
|
if (!active || !payload || payload.length === 0) return null;
|
|
49880
49936
|
if (isUptimeMode) {
|
|
@@ -49996,21 +50052,30 @@ var WorkspaceMonthlyHistory = ({
|
|
|
49996
50052
|
if (!shiftConfig) return null;
|
|
49997
50053
|
return getShiftWorkDurationSeconds(shiftConfig, selectedShiftId);
|
|
49998
50054
|
}, [shiftConfig, selectedShiftId]);
|
|
49999
|
-
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(() => {
|
|
50000
50064
|
const rangeStartDate = parseDateKeyToDate(normalizedRange.startKey);
|
|
50001
50065
|
const rangeEndDate = parseDateKeyToDate(normalizedRange.endKey);
|
|
50002
|
-
const
|
|
50066
|
+
const keys = [];
|
|
50003
50067
|
for (let d = new Date(rangeStartDate); d <= rangeEndDate; d.setDate(d.getDate() + 1)) {
|
|
50004
|
-
|
|
50068
|
+
keys.push(buildDateKey(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
50005
50069
|
}
|
|
50070
|
+
return keys;
|
|
50071
|
+
}, [normalizedRange.endKey, normalizedRange.startKey]);
|
|
50072
|
+
const chartData = React143.useMemo(() => {
|
|
50006
50073
|
const dailyData = [];
|
|
50007
50074
|
if (isUptimeMode) {
|
|
50008
50075
|
let maxHours = 0;
|
|
50009
|
-
for (const
|
|
50010
|
-
const dayData =
|
|
50011
|
-
|
|
50012
|
-
return date.getDate() === day;
|
|
50013
|
-
});
|
|
50076
|
+
for (const dateKey of rangeDateKeys) {
|
|
50077
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50078
|
+
const dayNumber = Number(dateKey.slice(-2));
|
|
50014
50079
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50015
50080
|
const hasShiftData = Boolean(shiftData && hasRealData(shiftData));
|
|
50016
50081
|
const availableSeconds = hasShiftData ? shiftData.availableTimeSeconds ?? shiftWorkSeconds ?? 0 : 0;
|
|
@@ -50037,8 +50102,8 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50037
50102
|
}
|
|
50038
50103
|
maxHours = Math.max(maxHours, idleHours + productiveHours);
|
|
50039
50104
|
dailyData.push({
|
|
50040
|
-
hour: getOrdinal2(
|
|
50041
|
-
timeRange: `Day ${
|
|
50105
|
+
hour: getOrdinal2(dayNumber),
|
|
50106
|
+
timeRange: `Day ${dayNumber}`,
|
|
50042
50107
|
productiveHours,
|
|
50043
50108
|
idleHours,
|
|
50044
50109
|
utilization
|
|
@@ -50049,12 +50114,9 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50049
50114
|
}
|
|
50050
50115
|
let maxOutput = 0;
|
|
50051
50116
|
let lastSetTarget = 0;
|
|
50052
|
-
for (let i =
|
|
50053
|
-
const
|
|
50054
|
-
const dayData =
|
|
50055
|
-
const date = new Date(d.date);
|
|
50056
|
-
return date.getDate() === day;
|
|
50057
|
-
});
|
|
50117
|
+
for (let i = rangeDateKeys.length - 1; i >= 0; i--) {
|
|
50118
|
+
const dateKey = rangeDateKeys[i];
|
|
50119
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50058
50120
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50059
50121
|
const idealOutput = shiftData ? shiftData.idealOutput : 0;
|
|
50060
50122
|
if (idealOutput > 0) {
|
|
@@ -50062,20 +50124,18 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50062
50124
|
break;
|
|
50063
50125
|
}
|
|
50064
50126
|
}
|
|
50065
|
-
for (const
|
|
50066
|
-
const dayData =
|
|
50067
|
-
|
|
50068
|
-
return date.getDate() === day;
|
|
50069
|
-
});
|
|
50127
|
+
for (const dateKey of rangeDateKeys) {
|
|
50128
|
+
const dayData = analysisMonthlyDataByKey.get(dateKey);
|
|
50129
|
+
const dayNumber = Number(dateKey.slice(-2));
|
|
50070
50130
|
const shiftData = dayData ? getShiftData(dayData, selectedShiftId) : null;
|
|
50071
50131
|
const output = shiftData && hasRealData(shiftData) ? shiftData.output : 0;
|
|
50072
50132
|
const idealOutput = shiftData ? shiftData.idealOutput : 0;
|
|
50073
50133
|
if (output > maxOutput) maxOutput = output;
|
|
50074
50134
|
const color2 = output >= lastSetTarget ? "#00AB45" : "#E34329";
|
|
50075
50135
|
dailyData.push({
|
|
50076
|
-
hour: getOrdinal2(
|
|
50136
|
+
hour: getOrdinal2(dayNumber),
|
|
50077
50137
|
// Using ordinal format (1st, 2nd, 3rd, etc.)
|
|
50078
|
-
timeRange: `Day ${
|
|
50138
|
+
timeRange: `Day ${dayNumber}`,
|
|
50079
50139
|
output,
|
|
50080
50140
|
originalOutput: output,
|
|
50081
50141
|
// For label display
|
|
@@ -50089,7 +50149,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50089
50149
|
const calculatedMax = Math.max(maxOutput, lastSetTarget);
|
|
50090
50150
|
const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
|
|
50091
50151
|
return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
|
|
50092
|
-
}, [
|
|
50152
|
+
}, [analysisMonthlyDataByKey, rangeDateKeys, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
|
|
50093
50153
|
const yAxisTicks = React143.useMemo(() => {
|
|
50094
50154
|
if (isUptimeMode) return void 0;
|
|
50095
50155
|
const max = chartData.yAxisMax;
|
|
@@ -50174,7 +50234,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50174
50234
|
}
|
|
50175
50235
|
const avgEfficiency = Math.round(totalEfficiency / filteredShifts.length);
|
|
50176
50236
|
const avgDailyOutput = Math.round(totalOutput / filteredShifts.length);
|
|
50177
|
-
const avgCycleTime =
|
|
50237
|
+
const avgCycleTime = roundToSingleDecimal(totalCycleTime / filteredShifts.length);
|
|
50178
50238
|
const avgRank = ranks.length > 0 ? Math.round(ranks.reduce((a, b) => a + b, 0) / ranks.length) : null;
|
|
50179
50239
|
return {
|
|
50180
50240
|
avgEfficiency,
|
|
@@ -50185,12 +50245,16 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50185
50245
|
avgIdleTime: Math.round(totalIdleTime / filteredShifts.length)
|
|
50186
50246
|
};
|
|
50187
50247
|
}, [analysisMonthlyData, selectedShiftId, isUptimeMode, shiftWorkSeconds]);
|
|
50248
|
+
const trendComparisonLabel = React143.useMemo(
|
|
50249
|
+
() => getMonthlyTrendComparisonLabel(normalizedRange, year, month),
|
|
50250
|
+
[month, normalizedRange, year]
|
|
50251
|
+
);
|
|
50188
50252
|
const efficiencyDelta = trendSummary?.avg_efficiency?.delta_pp ?? 0;
|
|
50189
50253
|
const efficiencyImproved = efficiencyDelta >= 0;
|
|
50190
50254
|
const assemblyRangeCycleTime = React143.useMemo(() => {
|
|
50191
50255
|
const trendCycleTime = Number(trendSummary?.avg_cycle_time?.current);
|
|
50192
50256
|
if (Number.isFinite(trendCycleTime) && trendCycleTime > 0) {
|
|
50193
|
-
return
|
|
50257
|
+
return trendCycleTime;
|
|
50194
50258
|
}
|
|
50195
50259
|
return metrics2?.avgCycleTime ?? 0;
|
|
50196
50260
|
}, [trendSummary?.avg_cycle_time?.current, metrics2?.avgCycleTime]);
|
|
@@ -50200,17 +50264,17 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50200
50264
|
const cycleWorsened = cycleDelta > 0;
|
|
50201
50265
|
const utilizationDelta = efficiencyDelta;
|
|
50202
50266
|
const utilizationImproved = utilizationDelta >= 0;
|
|
50203
|
-
const utilizationTrendText = `${Math.abs(utilizationDelta).toFixed(1)}
|
|
50267
|
+
const utilizationTrendText = `${Math.abs(utilizationDelta).toFixed(1)}%`;
|
|
50204
50268
|
const idleDeltaRaw = trendSummary?.avg_idle_time?.delta_seconds ?? 0;
|
|
50205
50269
|
const idlePrev = trendSummary?.avg_idle_time?.previous ?? 0;
|
|
50206
50270
|
const idleDelta = idlePrev ? idleDeltaRaw / idlePrev * 100 : 0;
|
|
50207
50271
|
const idleImproved = idleDelta <= 0;
|
|
50208
|
-
const idleTrendText = `${Math.abs(idleDelta).toFixed(1)}
|
|
50272
|
+
const idleTrendText = `${Math.abs(idleDelta).toFixed(1)}%`;
|
|
50209
50273
|
const stoppagesDeltaRaw = trendSummary?.avg_daily_stoppages?.delta_count ?? 0;
|
|
50210
50274
|
const stoppagesPrev = trendSummary?.avg_daily_stoppages?.previous ?? 0;
|
|
50211
50275
|
const stoppagesDelta = stoppagesPrev ? stoppagesDeltaRaw / stoppagesPrev * 100 : 0;
|
|
50212
50276
|
const stoppagesImproved = stoppagesDelta <= 0;
|
|
50213
|
-
const stoppagesTrendText = `${Math.abs(stoppagesDelta).toFixed(1)}
|
|
50277
|
+
const stoppagesTrendText = `${Math.abs(stoppagesDelta).toFixed(1)}%`;
|
|
50214
50278
|
const calendarData = React143.useMemo(() => {
|
|
50215
50279
|
const startOfMonth2 = new Date(year, month, 1);
|
|
50216
50280
|
const endOfMonth2 = new Date(year, month + 1, 0);
|
|
@@ -50219,20 +50283,15 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50219
50283
|
if (startOffset === -1) startOffset = 6;
|
|
50220
50284
|
const calendar = Array(startOffset).fill(null);
|
|
50221
50285
|
for (let day = 1; day <= totalDays; day++) {
|
|
50222
|
-
const
|
|
50223
|
-
|
|
50224
|
-
return date.getDate() === day;
|
|
50225
|
-
});
|
|
50286
|
+
const dateKey = buildDateKey(year, month, day);
|
|
50287
|
+
const dayData = monthlyDataByKey.get(dateKey);
|
|
50226
50288
|
calendar.push(dayData || null);
|
|
50227
50289
|
}
|
|
50228
50290
|
return { calendar, startOffset };
|
|
50229
|
-
}, [
|
|
50291
|
+
}, [monthlyDataByKey, month, year]);
|
|
50230
50292
|
const handleDayClick = React143.useCallback((day) => {
|
|
50231
50293
|
if (!day) return;
|
|
50232
|
-
const
|
|
50233
|
-
const month2 = String(day.date.getMonth() + 1).padStart(2, "0");
|
|
50234
|
-
const dayOfMonth = String(day.date.getDate()).padStart(2, "0");
|
|
50235
|
-
const formattedDate = `${year2}-${month2}-${dayOfMonth}`;
|
|
50294
|
+
const formattedDate = getDayDateKey(day);
|
|
50236
50295
|
trackCoreEvent("Workspace Monthly History Day Clicked", {
|
|
50237
50296
|
source: "monthly_history",
|
|
50238
50297
|
workspace_id: workspaceId,
|
|
@@ -50371,20 +50430,17 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50371
50430
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold text-gray-900", children: formatIdleTime(metrics2?.avgIdleTime ?? 0) }),
|
|
50372
50431
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${idleImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50373
50432
|
idleImproved ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }),
|
|
50374
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: idleTrendText })
|
|
50433
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${idleTrendText} vs ${trendComparisonLabel}` })
|
|
50375
50434
|
] })
|
|
50376
50435
|
] })
|
|
50377
50436
|
] }),
|
|
50378
50437
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-sm border border-gray-100 p-4 flex flex-col justify-between", children: [
|
|
50379
50438
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-gray-600 mb-1", children: "Avg Cycle Time" }),
|
|
50380
50439
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-nowrap", children: [
|
|
50381
|
-
/* @__PURE__ */ jsxRuntime.
|
|
50382
|
-
assemblyRangeCycleTime,
|
|
50383
|
-
"s"
|
|
50384
|
-
] }),
|
|
50440
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold text-gray-900", children: formatCycleSeconds(assemblyRangeCycleTime) }),
|
|
50385
50441
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${cycleWorsened ? "bg-red-50 text-red-600" : "bg-emerald-50 text-emerald-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50386
50442
|
cycleWorsened ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }),
|
|
50387
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(cycleDelta).toFixed(1)}% vs
|
|
50443
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(cycleDelta).toFixed(1)}% vs ${trendComparisonLabel}` })
|
|
50388
50444
|
] })
|
|
50389
50445
|
] })
|
|
50390
50446
|
] })
|
|
@@ -50395,10 +50451,10 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50395
50451
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold text-gray-900", children: isUptimeMode ? `${metrics2?.avgUtilization ?? 0}%` : `${metrics2?.avgEfficiency ?? 0}%` }),
|
|
50396
50452
|
isUptimeMode ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${utilizationImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50397
50453
|
utilizationImproved ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }),
|
|
50398
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: utilizationTrendText })
|
|
50454
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${utilizationTrendText} vs ${trendComparisonLabel}` })
|
|
50399
50455
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${efficiencyImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50400
50456
|
efficiencyImproved ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }),
|
|
50401
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(efficiencyDelta).toFixed(1)}% vs
|
|
50457
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(efficiencyDelta).toFixed(1)}% vs ${trendComparisonLabel}` })
|
|
50402
50458
|
] })
|
|
50403
50459
|
] })
|
|
50404
50460
|
] }),
|
|
@@ -50408,7 +50464,7 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50408
50464
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-2xl font-bold text-gray-900", children: formatIdleTime(metrics2?.avgIdleTime ?? 0) }),
|
|
50409
50465
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${idleImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50410
50466
|
idleImproved ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }),
|
|
50411
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: idleTrendText })
|
|
50467
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${idleTrendText} vs ${trendComparisonLabel}` })
|
|
50412
50468
|
] })
|
|
50413
50469
|
] })
|
|
50414
50470
|
] }),
|
|
@@ -50421,10 +50477,10 @@ var WorkspaceMonthlyHistory = ({
|
|
|
50421
50477
|
] }),
|
|
50422
50478
|
isUptimeMode ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${stoppagesImproved ? "bg-emerald-50 text-emerald-600" : "bg-red-50 text-red-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50423
50479
|
stoppagesImproved ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }),
|
|
50424
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: stoppagesTrendText })
|
|
50480
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${stoppagesTrendText} vs ${trendComparisonLabel}` })
|
|
50425
50481
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-1 ${cycleWorsened ? "bg-red-50 text-red-600" : "bg-emerald-50 text-emerald-600"} px-2 py-0.5 rounded-full text-[10px] font-medium whitespace-nowrap flex-shrink-0`, children: [
|
|
50426
50482
|
cycleWorsened ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-3 h-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "w-3 h-3" }),
|
|
50427
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(cycleDelta).toFixed(1)}% vs
|
|
50483
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: `${Math.abs(cycleDelta).toFixed(1)}% vs ${trendComparisonLabel}` })
|
|
50428
50484
|
] })
|
|
50429
50485
|
] })
|
|
50430
50486
|
] })
|
|
@@ -51136,6 +51192,7 @@ var getShiftDisplayName2 = (shiftId, availableShifts) => {
|
|
|
51136
51192
|
var WorkspaceMonthlyPdfGenerator = ({
|
|
51137
51193
|
workspaceId,
|
|
51138
51194
|
workspaceName,
|
|
51195
|
+
lineName,
|
|
51139
51196
|
monthlyData,
|
|
51140
51197
|
analysisData,
|
|
51141
51198
|
selectedMonth,
|
|
@@ -51180,13 +51237,20 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51180
51237
|
startKey: rangeStart || monthBounds.startKey,
|
|
51181
51238
|
endKey: rangeEnd || monthBounds.endKey
|
|
51182
51239
|
};
|
|
51240
|
+
const boundsSourceKey = rangeStart || rangeEnd || monthBounds.startKey;
|
|
51241
|
+
const boundsSourceDate = parseDateKeyToDate(boundsSourceKey);
|
|
51242
|
+
const effectiveBounds = getMonthKeyBounds(boundsSourceDate.getFullYear(), boundsSourceDate.getMonth());
|
|
51183
51243
|
const normalizedRange = normalizeDateKeyRange(
|
|
51184
51244
|
requestedRange.startKey,
|
|
51185
51245
|
requestedRange.endKey,
|
|
51186
|
-
|
|
51187
|
-
|
|
51246
|
+
effectiveBounds.startKey,
|
|
51247
|
+
effectiveBounds.endKey
|
|
51248
|
+
);
|
|
51249
|
+
const fullRange = isFullMonthRange(
|
|
51250
|
+
normalizedRange,
|
|
51251
|
+
boundsSourceDate.getFullYear(),
|
|
51252
|
+
boundsSourceDate.getMonth()
|
|
51188
51253
|
);
|
|
51189
|
-
const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
|
|
51190
51254
|
const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
|
|
51191
51255
|
const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
|
|
51192
51256
|
const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
|
|
@@ -51201,36 +51265,57 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51201
51265
|
year: "numeric",
|
|
51202
51266
|
timeZone: "Asia/Kolkata"
|
|
51203
51267
|
});
|
|
51268
|
+
const doc = new jsPDF.jsPDF();
|
|
51269
|
+
const pageHeight = typeof doc.internal.pageSize.height === "number" ? Number(doc.internal.pageSize.height) : 297;
|
|
51270
|
+
const footerY = pageHeight - 17;
|
|
51271
|
+
const maxContentY = footerY - 10;
|
|
51272
|
+
const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
|
|
51273
|
+
const resolvedLineName = lineName?.trim() || "Line";
|
|
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
|
+
});
|
|
51204
51280
|
trackCoreEvent("Workspace Monthly PDF Export Clicked", {
|
|
51205
51281
|
workspace_id: workspaceId,
|
|
51206
51282
|
workspace_name: workspaceName,
|
|
51207
|
-
|
|
51208
|
-
|
|
51283
|
+
line_name: resolvedLineName,
|
|
51284
|
+
month: reportStartDate.getMonth(),
|
|
51285
|
+
year: reportStartDate.getFullYear(),
|
|
51209
51286
|
shift_id: selectedShiftId,
|
|
51210
51287
|
range_start: normalizedRange.startKey,
|
|
51211
51288
|
range_end: normalizedRange.endKey,
|
|
51212
51289
|
is_full_month: fullRange
|
|
51213
51290
|
});
|
|
51214
|
-
const
|
|
51215
|
-
|
|
51216
|
-
|
|
51217
|
-
|
|
51218
|
-
|
|
51219
|
-
|
|
51220
|
-
|
|
51221
|
-
|
|
51222
|
-
|
|
51223
|
-
|
|
51224
|
-
|
|
51225
|
-
|
|
51226
|
-
|
|
51227
|
-
|
|
51291
|
+
const drawPageChrome = () => {
|
|
51292
|
+
doc.setFontSize(14);
|
|
51293
|
+
doc.setFont("helvetica", "bold");
|
|
51294
|
+
doc.setTextColor(50, 50, 50);
|
|
51295
|
+
doc.text("OPTIFYE.AI", 20, 15);
|
|
51296
|
+
doc.setFontSize(11);
|
|
51297
|
+
doc.setFont("helvetica", "normal");
|
|
51298
|
+
doc.setTextColor(80, 80, 80);
|
|
51299
|
+
const reportText = isUptimeMode ? "MONTHLY UTILIZATION REPORT" : "MONTHLY PERFORMANCE REPORT";
|
|
51300
|
+
const reportTextWidth = doc.getStringUnitWidth(reportText) * 11 / doc.internal.scaleFactor;
|
|
51301
|
+
doc.text(reportText, doc.internal.pageSize.width - 20 - reportTextWidth, 15);
|
|
51302
|
+
doc.setDrawColor(200, 200, 200);
|
|
51303
|
+
doc.setLineWidth(0.5);
|
|
51304
|
+
doc.line(20, 20, 190, 20);
|
|
51305
|
+
};
|
|
51306
|
+
const drawFooter = () => {
|
|
51307
|
+
doc.setFontSize(9);
|
|
51308
|
+
doc.setTextColor(130, 130, 130);
|
|
51309
|
+
doc.text(generatedText, 20, footerY);
|
|
51310
|
+
doc.setTextColor(0, 0, 0);
|
|
51311
|
+
};
|
|
51312
|
+
drawPageChrome();
|
|
51228
51313
|
doc.setFillColor(250, 250, 250);
|
|
51229
51314
|
doc.roundedRect(15, 25, 180, 55, 3, 3, "F");
|
|
51230
51315
|
doc.setFontSize(32);
|
|
51231
51316
|
doc.setFont("helvetica", "bold");
|
|
51232
51317
|
doc.setTextColor(0, 0, 0);
|
|
51233
|
-
doc.text(
|
|
51318
|
+
doc.text(resolvedLineName, 20, 40);
|
|
51234
51319
|
doc.setFontSize(22);
|
|
51235
51320
|
doc.setFont("helvetica", "normal");
|
|
51236
51321
|
doc.setTextColor(40, 40, 40);
|
|
@@ -51238,11 +51323,6 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51238
51323
|
doc.setFontSize(13);
|
|
51239
51324
|
doc.setFont("helvetica", "normal");
|
|
51240
51325
|
doc.setTextColor(60, 60, 60);
|
|
51241
|
-
const monthName = new Date(selectedYear, selectedMonth).toLocaleDateString("en-IN", {
|
|
51242
|
-
month: "long",
|
|
51243
|
-
year: "numeric",
|
|
51244
|
-
timeZone: "Asia/Kolkata"
|
|
51245
|
-
});
|
|
51246
51326
|
const shiftType = getShiftDisplayName2(selectedShiftId, availableShifts);
|
|
51247
51327
|
doc.text(`${monthName}`, 20, 65);
|
|
51248
51328
|
doc.text(`${shiftType}`, 20, 73);
|
|
@@ -51254,11 +51334,12 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51254
51334
|
doc.setLineWidth(0.8);
|
|
51255
51335
|
doc.line(20, 90, 190, 90);
|
|
51256
51336
|
const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
|
|
51257
|
-
const validDays = reportData
|
|
51258
|
-
const date = new Date(day.date);
|
|
51259
|
-
return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
|
|
51260
|
-
});
|
|
51337
|
+
const validDays = reportData;
|
|
51261
51338
|
const validShifts = validDays.map((day) => getShiftData(day, selectedShiftId)).filter(hasShiftData);
|
|
51339
|
+
const dailyEntries = validDays.map((dayData) => {
|
|
51340
|
+
const shift = getShiftData(dayData, selectedShiftId);
|
|
51341
|
+
return { dayData, shift };
|
|
51342
|
+
}).filter(({ shift }) => hasShiftData(shift)).sort((left, right) => getDayDateKey(right.dayData).localeCompare(getDayDateKey(left.dayData)));
|
|
51262
51343
|
const filteredShifts = isUptimeMode ? validShifts : validShifts.filter((shift) => (shift.efficiency ?? 0) >= 5);
|
|
51263
51344
|
const monthlyMetrics = filteredShifts.length > 0 ? isUptimeMode ? (() => {
|
|
51264
51345
|
const totalIdleTime = filteredShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
|
|
@@ -51385,21 +51466,27 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51385
51466
|
doc.setLineWidth(0.8);
|
|
51386
51467
|
const separatorY = isAssemblyWorkspaceAndNotUptime ? 150 : 180;
|
|
51387
51468
|
doc.line(20, separatorY, 190, separatorY);
|
|
51388
|
-
doc.setFillColor(245, 245, 245);
|
|
51389
51469
|
const dailySectionY = isAssemblyWorkspaceAndNotUptime ? 155 : 185;
|
|
51390
|
-
|
|
51391
|
-
|
|
51392
|
-
|
|
51393
|
-
|
|
51394
|
-
|
|
51395
|
-
|
|
51396
|
-
|
|
51470
|
+
const renderDailyTablePage = (startIndex, sectionY, title) => {
|
|
51471
|
+
const rowHeight = 8;
|
|
51472
|
+
const tableHeaderY = sectionY + 15;
|
|
51473
|
+
const textY = tableHeaderY + 5;
|
|
51474
|
+
const firstRowY = textY + 10;
|
|
51475
|
+
const rowsPerPage = Math.max(1, Math.floor((maxContentY - firstRowY) / rowHeight));
|
|
51476
|
+
const pageEntries = dailyEntries.slice(startIndex, startIndex + rowsPerPage);
|
|
51477
|
+
const endY = firstRowY + pageEntries.length * rowHeight;
|
|
51478
|
+
const sectionHeight = Math.max(40, endY - sectionY + 5);
|
|
51479
|
+
doc.setFillColor(245, 245, 245);
|
|
51480
|
+
doc.roundedRect(15, sectionY, 180, sectionHeight, 3, 3, "F");
|
|
51481
|
+
doc.setFontSize(18);
|
|
51482
|
+
doc.setFont("helvetica", "bold");
|
|
51483
|
+
doc.setTextColor(40, 40, 40);
|
|
51484
|
+
doc.text(title, 20, sectionY + 10);
|
|
51485
|
+
doc.setTextColor(0, 0, 0);
|
|
51397
51486
|
doc.setFontSize(10);
|
|
51398
51487
|
doc.setFont("helvetica", "bold");
|
|
51399
51488
|
doc.setFillColor(240, 240, 240);
|
|
51400
|
-
const tableHeaderY = dailySectionY + 15;
|
|
51401
51489
|
doc.roundedRect(20, tableHeaderY, 170, 7, 1, 1, "F");
|
|
51402
|
-
const textY = tableHeaderY + 5;
|
|
51403
51490
|
doc.text("Date", 25, textY);
|
|
51404
51491
|
doc.text(isUptimeMode ? "Productive" : isAssemblyWorkspace ? "Actual Cycle Time" : "Actual", 60, textY);
|
|
51405
51492
|
doc.text(isUptimeMode ? "Idle" : isAssemblyWorkspace ? "Standard Cycle Time" : "Standard", 95, textY);
|
|
@@ -51409,12 +51496,8 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51409
51496
|
doc.setDrawColor(220, 220, 220);
|
|
51410
51497
|
doc.line(20, textY + 3, 190, textY + 3);
|
|
51411
51498
|
doc.setFont("helvetica", "normal");
|
|
51412
|
-
let yPos =
|
|
51413
|
-
|
|
51414
|
-
recentDays.forEach((dayData, index) => {
|
|
51415
|
-
if (yPos > 260) return;
|
|
51416
|
-
const shift = getShiftData(dayData, selectedShiftId);
|
|
51417
|
-
if (!hasShiftData(shift)) return;
|
|
51499
|
+
let yPos = firstRowY;
|
|
51500
|
+
pageEntries.forEach(({ dayData, shift }, index) => {
|
|
51418
51501
|
if (index % 2 === 0) {
|
|
51419
51502
|
doc.setFillColor(252, 252, 252);
|
|
51420
51503
|
doc.roundedRect(20, yPos - 4, 170, 7, 1, 1, "F");
|
|
@@ -51447,11 +51530,35 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51447
51530
|
doc.text(`${shift.efficiency.toFixed(1)}%`, 135, yPos);
|
|
51448
51531
|
drawStatusMark(doc, 171, yPos - 0.3, shift.efficiency >= effectiveLegend.green_min);
|
|
51449
51532
|
}
|
|
51450
|
-
yPos +=
|
|
51533
|
+
yPos += rowHeight;
|
|
51451
51534
|
});
|
|
51452
51535
|
doc.setLineWidth(0.2);
|
|
51453
51536
|
doc.setDrawColor(220, 220, 220);
|
|
51454
51537
|
doc.roundedRect(20, tableHeaderY, 170, yPos - tableHeaderY - 3, 1, 1, "S");
|
|
51538
|
+
return startIndex + pageEntries.length;
|
|
51539
|
+
};
|
|
51540
|
+
if (dailyEntries.length > 0) {
|
|
51541
|
+
let renderedEntries = renderDailyTablePage(0, dailySectionY, dailySectionTitle);
|
|
51542
|
+
while (renderedEntries < dailyEntries.length) {
|
|
51543
|
+
drawFooter();
|
|
51544
|
+
doc.addPage();
|
|
51545
|
+
drawPageChrome();
|
|
51546
|
+
doc.setFontSize(12);
|
|
51547
|
+
doc.setFont("helvetica", "bold");
|
|
51548
|
+
doc.setTextColor(40, 40, 40);
|
|
51549
|
+
doc.text(resolvedLineName, 20, 32);
|
|
51550
|
+
doc.setFont("helvetica", "normal");
|
|
51551
|
+
doc.text(getWorkspaceDisplayName(workspaceName), 20, 40);
|
|
51552
|
+
doc.setFontSize(10);
|
|
51553
|
+
doc.setTextColor(90, 90, 90);
|
|
51554
|
+
doc.text(`${monthName} \u2022 ${shiftType} \u2022 ${reportStartStr} - ${reportEndStr}`, 20, 48);
|
|
51555
|
+
doc.setTextColor(0, 0, 0);
|
|
51556
|
+
renderedEntries = renderDailyTablePage(
|
|
51557
|
+
renderedEntries,
|
|
51558
|
+
56,
|
|
51559
|
+
`${dailySectionTitle} (cont.)`
|
|
51560
|
+
);
|
|
51561
|
+
}
|
|
51455
51562
|
} else {
|
|
51456
51563
|
doc.setFontSize(12);
|
|
51457
51564
|
doc.setFont("helvetica", "normal");
|
|
@@ -51459,10 +51566,7 @@ var WorkspaceMonthlyPdfGenerator = ({
|
|
|
51459
51566
|
doc.text("No daily data available for this month", 25, dailySectionY + 30);
|
|
51460
51567
|
doc.setTextColor(0, 0, 0);
|
|
51461
51568
|
}
|
|
51462
|
-
|
|
51463
|
-
doc.setTextColor(130, 130, 130);
|
|
51464
|
-
const generatedText = `Generated on ${(/* @__PURE__ */ new Date()).toLocaleString("en-IN", { timeZone: "Asia/Kolkata" })}`;
|
|
51465
|
-
doc.text(generatedText, 20, 280);
|
|
51569
|
+
drawFooter();
|
|
51466
51570
|
const fileName = `${getWorkspaceDisplayName(workspaceName)}_${monthName.replace(" ", "_")}_${shiftType.replace(" ", "_")}.pdf`;
|
|
51467
51571
|
doc.save(fileName);
|
|
51468
51572
|
} catch (error) {
|
|
@@ -63611,7 +63715,9 @@ var KPIDetailView = ({
|
|
|
63611
63715
|
month: currentMonth,
|
|
63612
63716
|
year: currentYear,
|
|
63613
63717
|
shiftId: selectedShiftId,
|
|
63614
|
-
companyId: resolvedCompanyId
|
|
63718
|
+
companyId: resolvedCompanyId,
|
|
63719
|
+
startDate: isFullRange ? void 0 : rangeStart,
|
|
63720
|
+
endDate: isFullRange ? void 0 : rangeEnd
|
|
63615
63721
|
});
|
|
63616
63722
|
const configuredTimezone = timezone || dashboardConfig.dateTimeConfig?.defaultTimezone || "UTC";
|
|
63617
63723
|
React143.useMemo(() => getCurrentTimeInZone(configuredTimezone), [configuredTimezone]);
|
|
@@ -71066,15 +71172,26 @@ var WorkspaceDetailView = ({
|
|
|
71066
71172
|
const range = React143.useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
|
|
71067
71173
|
const isFullRange = React143.useMemo(() => isFullMonthRange(range, selectedYear, selectedMonth), [range, selectedYear, selectedMonth]);
|
|
71068
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);
|
|
71069
71184
|
const normalized = normalizeDateKeyRange(
|
|
71070
|
-
typeof urlRangeStart === "string" ? urlRangeStart :
|
|
71071
|
-
typeof urlRangeEnd === "string" ? urlRangeEnd :
|
|
71072
|
-
|
|
71073
|
-
|
|
71185
|
+
typeof urlRangeStart === "string" ? urlRangeStart : targetBounds.startKey,
|
|
71186
|
+
typeof urlRangeEnd === "string" ? urlRangeEnd : targetBounds.endKey,
|
|
71187
|
+
targetBounds.startKey,
|
|
71188
|
+
targetBounds.endKey
|
|
71074
71189
|
);
|
|
71190
|
+
setSelectedMonth(targetMonth);
|
|
71191
|
+
setSelectedYear(targetYear);
|
|
71075
71192
|
setRangeStart(normalized.startKey);
|
|
71076
71193
|
setRangeEnd(normalized.endKey);
|
|
71077
|
-
}, [urlRangeStart, urlRangeEnd, monthBounds.startKey
|
|
71194
|
+
}, [urlRangeStart, urlRangeEnd, monthBounds.startKey]);
|
|
71078
71195
|
const isHistoricView = Boolean(date && parsedShiftId !== void 0);
|
|
71079
71196
|
const initialTab = getInitialTab(sourceType, defaultTab, fromMonthly, date);
|
|
71080
71197
|
const [activeTab, setActiveTab] = React143.useState(initialTab);
|
|
@@ -71094,7 +71211,9 @@ var WorkspaceDetailView = ({
|
|
|
71094
71211
|
month: selectedMonth,
|
|
71095
71212
|
year: selectedYear,
|
|
71096
71213
|
shiftId: selectedShift,
|
|
71097
|
-
companyId: dashboardConfig?.entityConfig?.companyId
|
|
71214
|
+
companyId: dashboardConfig?.entityConfig?.companyId,
|
|
71215
|
+
startDate: isFullRange ? void 0 : rangeStart,
|
|
71216
|
+
endDate: isFullRange ? void 0 : rangeEnd
|
|
71098
71217
|
});
|
|
71099
71218
|
const {
|
|
71100
71219
|
isFastSlowClipFiltersEnabled,
|
|
@@ -71361,6 +71480,7 @@ var WorkspaceDetailView = ({
|
|
|
71361
71480
|
line_name: "",
|
|
71362
71481
|
line_assembly_enabled: cachedOverviewMetrics.assembly_enabled === true,
|
|
71363
71482
|
workspace_name: cachedOverviewMetrics.workspace_name,
|
|
71483
|
+
workspace_display_name: cachedOverviewMetrics.displayName ?? null,
|
|
71364
71484
|
workspace_id: cachedOverviewMetrics.workspace_uuid || "",
|
|
71365
71485
|
company_id: cachedOverviewMetrics.company_id,
|
|
71366
71486
|
company_name: "",
|
|
@@ -71593,12 +71713,13 @@ var WorkspaceDetailView = ({
|
|
|
71593
71713
|
console.warn("Skipping invalid metric:", metric);
|
|
71594
71714
|
return;
|
|
71595
71715
|
}
|
|
71596
|
-
const
|
|
71597
|
-
const
|
|
71716
|
+
const dateKey = getDateKeyFromValue(metric.date);
|
|
71717
|
+
const dateObj = parseDateKeyToDate(dateKey);
|
|
71598
71718
|
let dayEntry = dayDataMap.get(dateKey);
|
|
71599
71719
|
if (!dayEntry) {
|
|
71600
71720
|
dayEntry = {
|
|
71601
71721
|
date: dateObj,
|
|
71722
|
+
dateKey,
|
|
71602
71723
|
shifts: {}
|
|
71603
71724
|
// Multi-shift structure: Record<number, CalendarShiftData>
|
|
71604
71725
|
};
|
|
@@ -71643,6 +71764,7 @@ var WorkspaceDetailView = ({
|
|
|
71643
71764
|
});
|
|
71644
71765
|
const processedData = Array.from(dayDataMap.values()).filter((entry) => Object.keys(entry.shifts).length > 0).map((entry) => ({
|
|
71645
71766
|
date: entry.date,
|
|
71767
|
+
dateKey: entry.dateKey,
|
|
71646
71768
|
shifts: entry.shifts
|
|
71647
71769
|
}));
|
|
71648
71770
|
console.log(`[handleMonthlyDataLoaded] Transformed data for calendar:`, {
|
|
@@ -71675,7 +71797,17 @@ var WorkspaceDetailView = ({
|
|
|
71675
71797
|
const analysisMonthlyData = React143.useMemo(() => {
|
|
71676
71798
|
return filterDataByDateKeyRange(monthlyData, range);
|
|
71677
71799
|
}, [monthlyData, range]);
|
|
71678
|
-
const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
|
|
71800
|
+
const formattedWorkspaceName = displayName || workspace?.workspace_display_name || formatWorkspaceName3(workspace?.workspace_name || "", resolvedLineId);
|
|
71801
|
+
const resolvedLineName = React143.useMemo(() => {
|
|
71802
|
+
const workspaceLineName = workspace?.line_name?.trim();
|
|
71803
|
+
if (workspaceLineName) {
|
|
71804
|
+
return workspaceLineName;
|
|
71805
|
+
}
|
|
71806
|
+
if (resolvedLineId && dashboardConfig?.entityConfig) {
|
|
71807
|
+
return getLineDisplayName(dashboardConfig.entityConfig, resolvedLineId);
|
|
71808
|
+
}
|
|
71809
|
+
return "Line";
|
|
71810
|
+
}, [dashboardConfig?.entityConfig, resolvedLineId, workspace?.line_name]);
|
|
71679
71811
|
const workspaceCycleTimeEligibility = workspace ? {
|
|
71680
71812
|
line_assembly_enabled: workspace.line_assembly_enabled,
|
|
71681
71813
|
action_family: workspace.action_family,
|
|
@@ -72220,6 +72352,7 @@ var WorkspaceDetailView = ({
|
|
|
72220
72352
|
{
|
|
72221
72353
|
workspaceId,
|
|
72222
72354
|
workspaceName: formattedWorkspaceName,
|
|
72355
|
+
lineName: resolvedLineName,
|
|
72223
72356
|
monthlyData,
|
|
72224
72357
|
analysisData: analysisMonthlyData,
|
|
72225
72358
|
selectedMonth,
|
|
@@ -81849,6 +81982,8 @@ exports.getCurrentWeekFullRange = getCurrentWeekFullRange;
|
|
|
81849
81982
|
exports.getCurrentWeekToDateRange = getCurrentWeekToDateRange;
|
|
81850
81983
|
exports.getDashboardHeaderTimeInZone = getDashboardHeaderTimeInZone;
|
|
81851
81984
|
exports.getDateKeyFromDate = getDateKeyFromDate;
|
|
81985
|
+
exports.getDateKeyFromValue = getDateKeyFromValue;
|
|
81986
|
+
exports.getDayDateKey = getDayDateKey;
|
|
81852
81987
|
exports.getDaysDifferenceInZone = getDaysDifferenceInZone;
|
|
81853
81988
|
exports.getDefaultCameraStreamUrl = getDefaultCameraStreamUrl;
|
|
81854
81989
|
exports.getDefaultLineId = getDefaultLineId;
|
|
@@ -81859,6 +81994,7 @@ exports.getManufacturingInsights = getManufacturingInsights;
|
|
|
81859
81994
|
exports.getMetricsTablePrefix = getMetricsTablePrefix;
|
|
81860
81995
|
exports.getMonthKeyBounds = getMonthKeyBounds;
|
|
81861
81996
|
exports.getMonthWeekRanges = getMonthWeekRanges;
|
|
81997
|
+
exports.getMonthlyTrendComparisonLabel = getMonthlyTrendComparisonLabel;
|
|
81862
81998
|
exports.getNextUpdateInterval = getNextUpdateInterval;
|
|
81863
81999
|
exports.getOperationalDate = getOperationalDate;
|
|
81864
82000
|
exports.getRoleAssignmentKind = getRoleAssignmentKind;
|