@optifye/dashboard-core 6.10.9 → 6.10.10

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.js CHANGED
@@ -37421,50 +37421,61 @@ var LinePdfGenerator = ({
37421
37421
  doc.setLineWidth(0.8);
37422
37422
  doc.line(20, 118, 190, 118);
37423
37423
  const hourlyOverviewStartY = 123;
37424
+ const parseTimeToMinutes2 = (timeStr) => {
37425
+ const [hours, minutes] = timeStr.split(":");
37426
+ const hour = parseInt(hours, 10);
37427
+ const minute = parseInt(minutes || "0", 10);
37428
+ if (Number.isNaN(hour) || Number.isNaN(minute)) {
37429
+ return NaN;
37430
+ }
37431
+ return (hour * 60 + minute) % (24 * 60);
37432
+ };
37433
+ const formatMinutesLabel = (totalMinutes) => {
37434
+ const normalized = (totalMinutes % (24 * 60) + 24 * 60) % (24 * 60);
37435
+ const hour = Math.floor(normalized / 60);
37436
+ const minute = normalized % 60;
37437
+ const time2 = /* @__PURE__ */ new Date();
37438
+ time2.setHours(hour);
37439
+ time2.setMinutes(minute);
37440
+ time2.setSeconds(0);
37441
+ time2.setMilliseconds(0);
37442
+ return time2.toLocaleTimeString("en-IN", {
37443
+ hour: "2-digit",
37444
+ minute: "2-digit",
37445
+ hour12: true,
37446
+ timeZone: "Asia/Kolkata"
37447
+ });
37448
+ };
37449
+ const buildRange = (startMinutes, minutes) => {
37450
+ const endMinutes = startMinutes + minutes;
37451
+ return {
37452
+ label: `${formatMinutesLabel(startMinutes)} - ${formatMinutesLabel(endMinutes)}`,
37453
+ minutes
37454
+ };
37455
+ };
37424
37456
  const getHourlyTimeRanges = (startTimeStr, endTimeStr) => {
37425
- const [hours, minutes] = startTimeStr.split(":");
37426
- const startHour = parseInt(hours);
37427
- const startMinute = parseInt(minutes || "0");
37428
- let SHIFT_DURATION = 11;
37429
- let endHour = startHour + 11;
37430
- let endMinute = startMinute;
37431
- if (endTimeStr) {
37432
- const [endHours, endMinutes] = endTimeStr.split(":");
37433
- endHour = parseInt(endHours);
37434
- endMinute = parseInt(endMinutes || "0");
37435
- let duration = endHour - startHour;
37436
- if (duration <= 0) {
37437
- duration += 24;
37438
- }
37439
- const hasPartialLastHour = endMinute > 0 && endMinute < 60;
37440
- SHIFT_DURATION = hasPartialLastHour ? Math.ceil(duration) : Math.round(duration);
37441
- }
37442
- return Array.from({ length: SHIFT_DURATION }, (_, i) => {
37443
- const isLastHour = i === SHIFT_DURATION - 1;
37444
- const hourStartTime = /* @__PURE__ */ new Date();
37445
- hourStartTime.setHours((startHour + i) % 24);
37446
- hourStartTime.setMinutes(startMinute);
37447
- hourStartTime.setSeconds(0);
37448
- hourStartTime.setMilliseconds(0);
37449
- let hourEndTime = /* @__PURE__ */ new Date();
37450
- if (isLastHour && endTimeStr) {
37451
- hourEndTime.setHours(endHour % 24);
37452
- hourEndTime.setMinutes(endMinute);
37453
- } else {
37454
- hourEndTime.setHours((startHour + i + 1) % 24);
37455
- hourEndTime.setMinutes(startMinute);
37456
- }
37457
- hourEndTime.setSeconds(0);
37458
- hourEndTime.setMilliseconds(0);
37459
- const formatTime5 = (date2) => {
37460
- return date2.toLocaleTimeString("en-IN", {
37461
- hour: "2-digit",
37462
- minute: "2-digit",
37463
- hour12: true,
37464
- timeZone: "Asia/Kolkata"
37465
- });
37466
- };
37467
- return `${formatTime5(hourStartTime)} - ${formatTime5(hourEndTime)}`;
37457
+ const startMinutes = parseTimeToMinutes2(startTimeStr);
37458
+ if (Number.isNaN(startMinutes)) {
37459
+ return [];
37460
+ }
37461
+ if (!endTimeStr) {
37462
+ const defaultHours = 11;
37463
+ return Array.from({ length: defaultHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
37464
+ }
37465
+ const endMinutes = parseTimeToMinutes2(endTimeStr);
37466
+ if (Number.isNaN(endMinutes)) {
37467
+ const fallbackHours = 11;
37468
+ return Array.from({ length: fallbackHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
37469
+ }
37470
+ let durationMinutes = endMinutes - startMinutes;
37471
+ if (durationMinutes <= 0) {
37472
+ durationMinutes += 24 * 60;
37473
+ }
37474
+ const rangeCount = Math.max(1, Math.ceil(durationMinutes / 60));
37475
+ return Array.from({ length: rangeCount }, (_, i) => {
37476
+ const remainingMinutes = durationMinutes - i * 60;
37477
+ const rangeMinutes = remainingMinutes >= 60 ? 60 : remainingMinutes;
37478
+ return buildRange(startMinutes + i * 60, rangeMinutes);
37468
37479
  });
37469
37480
  };
37470
37481
  const hourlyTimeRanges = lineInfo.metrics.shift_start ? getHourlyTimeRanges(lineInfo.metrics.shift_start, lineInfo.metrics.shift_end) : [];
@@ -37476,8 +37487,13 @@ var LinePdfGenerator = ({
37476
37487
  const startHour = parseInt(startHourStr);
37477
37488
  const startMinute = parseInt(startMinuteStr || "0");
37478
37489
  const [endHourStr, endMinuteStr] = (lineInfo.metrics.shift_end || "18:00").split(":");
37490
+ const endHour = parseInt(endHourStr);
37479
37491
  const endMinute = parseInt(endMinuteStr || "0");
37480
- const hasPartialLastHour = endMinute > 0 && endMinute < 60;
37492
+ let durationMinutes = endHour * 60 + endMinute - (startHour * 60 + startMinute);
37493
+ if (durationMinutes <= 0) {
37494
+ durationMinutes += 24 * 60;
37495
+ }
37496
+ const hasPartialLastHour = durationMinutes % 60 !== 0;
37481
37497
  const expectedHours = [];
37482
37498
  for (let i = 0; i < shiftDuration; i++) {
37483
37499
  expectedHours.push((startHour + i) % 24);
@@ -37668,19 +37684,21 @@ var LinePdfGenerator = ({
37668
37684
  const hourNumber = (startHour + index) % 24;
37669
37685
  const dataCollected = !isTodayForTable || hourNumber < currentHour;
37670
37686
  const outputStr = dataCollected ? actualOutput.toString() : "TBD";
37671
- const targetStr = targetOutputPerHour.toString();
37672
37687
  if (index < totalRows - 1) {
37673
37688
  const rowBottomY = headerBottomY + (index + 1) * rowSpacing;
37674
37689
  doc.setDrawColor(200, 200, 200);
37675
37690
  doc.line(20, rowBottomY, 190, rowBottomY);
37676
37691
  }
37677
- doc.text(timeRange, 25, yPos);
37692
+ const rangeMinutes = timeRange.minutes || 60;
37693
+ const targetForRange = targetOutputPerHour * (rangeMinutes / 60);
37694
+ const targetStr = rangeMinutes === 60 ? targetOutputPerHour.toString() : targetForRange.toFixed(1).replace(/\.0$/, "");
37695
+ doc.text(timeRange.label, 25, yPos);
37678
37696
  doc.text(outputStr, 75, yPos);
37679
37697
  doc.text(targetStr, 105, yPos);
37680
37698
  if (!dataCollected) {
37681
37699
  doc.setTextColor(100, 100, 100);
37682
37700
  doc.text("-", 135, yPos);
37683
- } else if (actualOutput >= targetOutputPerHour) {
37701
+ } else if (actualOutput >= targetForRange) {
37684
37702
  doc.setTextColor(0, 171, 69);
37685
37703
  doc.setFont("ZapfDingbats", "normal");
37686
37704
  doc.text("4", 135, yPos);
@@ -39091,23 +39109,29 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons }) => {
39091
39109
  const colBoundaries = [20, 70, 100, 130, 155, 190];
39092
39110
  const totalRows = hourlyData.length;
39093
39111
  const gridBottomY = headerBottomY + totalRows * rowHeight;
39112
+ const tableHeight = gridBottomY - gridTopY;
39113
+ doc.setFillColor(255, 255, 255);
39114
+ doc.roundedRect(20, gridTopY, 170, tableHeight, 2, 2, "F");
39115
+ doc.setDrawColor(230, 230, 230);
39116
+ doc.setLineWidth(0.2);
39117
+ doc.roundedRect(20, gridTopY, 170, tableHeight, 2, 2, "S");
39094
39118
  doc.setDrawColor(200, 200, 200);
39095
39119
  doc.setLineWidth(0.3);
39096
- doc.line(20, gridTopY, 190, gridTopY);
39097
39120
  doc.line(20, headerBottomY, 190, headerBottomY);
39098
- colBoundaries.forEach((x) => {
39121
+ colBoundaries.slice(1, -1).forEach((x) => {
39099
39122
  doc.line(x, gridTopY, x, gridBottomY);
39100
39123
  });
39101
39124
  doc.setFontSize(headerFontSize);
39102
39125
  doc.setFont("helvetica", "bold");
39103
- doc.text("Time Range", 25, headerY);
39104
- doc.text("Output", 75, headerY);
39105
- doc.text("Target", 105, headerY);
39106
- doc.text("Status", 135, headerY);
39107
- doc.text("Remarks", 160, headerY);
39126
+ const headerTextY = gridTopY + 5.5;
39127
+ doc.text("Time Range", 25, headerTextY);
39128
+ doc.text("Output", 75, headerTextY);
39129
+ doc.text("Target", 105, headerTextY);
39130
+ doc.text("Status", 135, headerTextY);
39131
+ doc.text("Remarks", 160, headerTextY);
39108
39132
  doc.setFontSize(contentFontSize);
39109
39133
  doc.setFont("helvetica", "normal");
39110
- let yPos = tableStartY;
39134
+ let yPos = headerBottomY + 5.5;
39111
39135
  const workspaceDate = new Date(workspace.date);
39112
39136
  const today = /* @__PURE__ */ new Date();
39113
39137
  today.setHours(0, 0, 0, 0);
@@ -39135,9 +39159,11 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons }) => {
39135
39159
  const dataCollected = !isToday2 || hourNumber < currentHour;
39136
39160
  const outputStr = dataCollected ? output.toString() : "TBD";
39137
39161
  const targetStr = hourlyTarget.toString();
39138
- const rowBottomY = headerBottomY + (index + 1) * rowHeight;
39139
- doc.setDrawColor(200, 200, 200);
39140
- doc.line(20, rowBottomY, 190, rowBottomY);
39162
+ if (index < totalRows - 1) {
39163
+ const rowBottomY = headerBottomY + (index + 1) * rowHeight;
39164
+ doc.setDrawColor(200, 200, 200);
39165
+ doc.line(20, rowBottomY, 190, rowBottomY);
39166
+ }
39141
39167
  doc.text(timeRange, 25, yPos);
39142
39168
  doc.text(outputStr, 75, yPos);
39143
39169
  doc.text(targetStr, 105, yPos);
package/dist/index.mjs CHANGED
@@ -37392,50 +37392,61 @@ var LinePdfGenerator = ({
37392
37392
  doc.setLineWidth(0.8);
37393
37393
  doc.line(20, 118, 190, 118);
37394
37394
  const hourlyOverviewStartY = 123;
37395
+ const parseTimeToMinutes2 = (timeStr) => {
37396
+ const [hours, minutes] = timeStr.split(":");
37397
+ const hour = parseInt(hours, 10);
37398
+ const minute = parseInt(minutes || "0", 10);
37399
+ if (Number.isNaN(hour) || Number.isNaN(minute)) {
37400
+ return NaN;
37401
+ }
37402
+ return (hour * 60 + minute) % (24 * 60);
37403
+ };
37404
+ const formatMinutesLabel = (totalMinutes) => {
37405
+ const normalized = (totalMinutes % (24 * 60) + 24 * 60) % (24 * 60);
37406
+ const hour = Math.floor(normalized / 60);
37407
+ const minute = normalized % 60;
37408
+ const time2 = /* @__PURE__ */ new Date();
37409
+ time2.setHours(hour);
37410
+ time2.setMinutes(minute);
37411
+ time2.setSeconds(0);
37412
+ time2.setMilliseconds(0);
37413
+ return time2.toLocaleTimeString("en-IN", {
37414
+ hour: "2-digit",
37415
+ minute: "2-digit",
37416
+ hour12: true,
37417
+ timeZone: "Asia/Kolkata"
37418
+ });
37419
+ };
37420
+ const buildRange = (startMinutes, minutes) => {
37421
+ const endMinutes = startMinutes + minutes;
37422
+ return {
37423
+ label: `${formatMinutesLabel(startMinutes)} - ${formatMinutesLabel(endMinutes)}`,
37424
+ minutes
37425
+ };
37426
+ };
37395
37427
  const getHourlyTimeRanges = (startTimeStr, endTimeStr) => {
37396
- const [hours, minutes] = startTimeStr.split(":");
37397
- const startHour = parseInt(hours);
37398
- const startMinute = parseInt(minutes || "0");
37399
- let SHIFT_DURATION = 11;
37400
- let endHour = startHour + 11;
37401
- let endMinute = startMinute;
37402
- if (endTimeStr) {
37403
- const [endHours, endMinutes] = endTimeStr.split(":");
37404
- endHour = parseInt(endHours);
37405
- endMinute = parseInt(endMinutes || "0");
37406
- let duration = endHour - startHour;
37407
- if (duration <= 0) {
37408
- duration += 24;
37409
- }
37410
- const hasPartialLastHour = endMinute > 0 && endMinute < 60;
37411
- SHIFT_DURATION = hasPartialLastHour ? Math.ceil(duration) : Math.round(duration);
37412
- }
37413
- return Array.from({ length: SHIFT_DURATION }, (_, i) => {
37414
- const isLastHour = i === SHIFT_DURATION - 1;
37415
- const hourStartTime = /* @__PURE__ */ new Date();
37416
- hourStartTime.setHours((startHour + i) % 24);
37417
- hourStartTime.setMinutes(startMinute);
37418
- hourStartTime.setSeconds(0);
37419
- hourStartTime.setMilliseconds(0);
37420
- let hourEndTime = /* @__PURE__ */ new Date();
37421
- if (isLastHour && endTimeStr) {
37422
- hourEndTime.setHours(endHour % 24);
37423
- hourEndTime.setMinutes(endMinute);
37424
- } else {
37425
- hourEndTime.setHours((startHour + i + 1) % 24);
37426
- hourEndTime.setMinutes(startMinute);
37427
- }
37428
- hourEndTime.setSeconds(0);
37429
- hourEndTime.setMilliseconds(0);
37430
- const formatTime5 = (date2) => {
37431
- return date2.toLocaleTimeString("en-IN", {
37432
- hour: "2-digit",
37433
- minute: "2-digit",
37434
- hour12: true,
37435
- timeZone: "Asia/Kolkata"
37436
- });
37437
- };
37438
- return `${formatTime5(hourStartTime)} - ${formatTime5(hourEndTime)}`;
37428
+ const startMinutes = parseTimeToMinutes2(startTimeStr);
37429
+ if (Number.isNaN(startMinutes)) {
37430
+ return [];
37431
+ }
37432
+ if (!endTimeStr) {
37433
+ const defaultHours = 11;
37434
+ return Array.from({ length: defaultHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
37435
+ }
37436
+ const endMinutes = parseTimeToMinutes2(endTimeStr);
37437
+ if (Number.isNaN(endMinutes)) {
37438
+ const fallbackHours = 11;
37439
+ return Array.from({ length: fallbackHours }, (_, i) => buildRange(startMinutes + i * 60, 60));
37440
+ }
37441
+ let durationMinutes = endMinutes - startMinutes;
37442
+ if (durationMinutes <= 0) {
37443
+ durationMinutes += 24 * 60;
37444
+ }
37445
+ const rangeCount = Math.max(1, Math.ceil(durationMinutes / 60));
37446
+ return Array.from({ length: rangeCount }, (_, i) => {
37447
+ const remainingMinutes = durationMinutes - i * 60;
37448
+ const rangeMinutes = remainingMinutes >= 60 ? 60 : remainingMinutes;
37449
+ return buildRange(startMinutes + i * 60, rangeMinutes);
37439
37450
  });
37440
37451
  };
37441
37452
  const hourlyTimeRanges = lineInfo.metrics.shift_start ? getHourlyTimeRanges(lineInfo.metrics.shift_start, lineInfo.metrics.shift_end) : [];
@@ -37447,8 +37458,13 @@ var LinePdfGenerator = ({
37447
37458
  const startHour = parseInt(startHourStr);
37448
37459
  const startMinute = parseInt(startMinuteStr || "0");
37449
37460
  const [endHourStr, endMinuteStr] = (lineInfo.metrics.shift_end || "18:00").split(":");
37461
+ const endHour = parseInt(endHourStr);
37450
37462
  const endMinute = parseInt(endMinuteStr || "0");
37451
- const hasPartialLastHour = endMinute > 0 && endMinute < 60;
37463
+ let durationMinutes = endHour * 60 + endMinute - (startHour * 60 + startMinute);
37464
+ if (durationMinutes <= 0) {
37465
+ durationMinutes += 24 * 60;
37466
+ }
37467
+ const hasPartialLastHour = durationMinutes % 60 !== 0;
37452
37468
  const expectedHours = [];
37453
37469
  for (let i = 0; i < shiftDuration; i++) {
37454
37470
  expectedHours.push((startHour + i) % 24);
@@ -37639,19 +37655,21 @@ var LinePdfGenerator = ({
37639
37655
  const hourNumber = (startHour + index) % 24;
37640
37656
  const dataCollected = !isTodayForTable || hourNumber < currentHour;
37641
37657
  const outputStr = dataCollected ? actualOutput.toString() : "TBD";
37642
- const targetStr = targetOutputPerHour.toString();
37643
37658
  if (index < totalRows - 1) {
37644
37659
  const rowBottomY = headerBottomY + (index + 1) * rowSpacing;
37645
37660
  doc.setDrawColor(200, 200, 200);
37646
37661
  doc.line(20, rowBottomY, 190, rowBottomY);
37647
37662
  }
37648
- doc.text(timeRange, 25, yPos);
37663
+ const rangeMinutes = timeRange.minutes || 60;
37664
+ const targetForRange = targetOutputPerHour * (rangeMinutes / 60);
37665
+ const targetStr = rangeMinutes === 60 ? targetOutputPerHour.toString() : targetForRange.toFixed(1).replace(/\.0$/, "");
37666
+ doc.text(timeRange.label, 25, yPos);
37649
37667
  doc.text(outputStr, 75, yPos);
37650
37668
  doc.text(targetStr, 105, yPos);
37651
37669
  if (!dataCollected) {
37652
37670
  doc.setTextColor(100, 100, 100);
37653
37671
  doc.text("-", 135, yPos);
37654
- } else if (actualOutput >= targetOutputPerHour) {
37672
+ } else if (actualOutput >= targetForRange) {
37655
37673
  doc.setTextColor(0, 171, 69);
37656
37674
  doc.setFont("ZapfDingbats", "normal");
37657
37675
  doc.text("4", 135, yPos);
@@ -39062,23 +39080,29 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons }) => {
39062
39080
  const colBoundaries = [20, 70, 100, 130, 155, 190];
39063
39081
  const totalRows = hourlyData.length;
39064
39082
  const gridBottomY = headerBottomY + totalRows * rowHeight;
39083
+ const tableHeight = gridBottomY - gridTopY;
39084
+ doc.setFillColor(255, 255, 255);
39085
+ doc.roundedRect(20, gridTopY, 170, tableHeight, 2, 2, "F");
39086
+ doc.setDrawColor(230, 230, 230);
39087
+ doc.setLineWidth(0.2);
39088
+ doc.roundedRect(20, gridTopY, 170, tableHeight, 2, 2, "S");
39065
39089
  doc.setDrawColor(200, 200, 200);
39066
39090
  doc.setLineWidth(0.3);
39067
- doc.line(20, gridTopY, 190, gridTopY);
39068
39091
  doc.line(20, headerBottomY, 190, headerBottomY);
39069
- colBoundaries.forEach((x) => {
39092
+ colBoundaries.slice(1, -1).forEach((x) => {
39070
39093
  doc.line(x, gridTopY, x, gridBottomY);
39071
39094
  });
39072
39095
  doc.setFontSize(headerFontSize);
39073
39096
  doc.setFont("helvetica", "bold");
39074
- doc.text("Time Range", 25, headerY);
39075
- doc.text("Output", 75, headerY);
39076
- doc.text("Target", 105, headerY);
39077
- doc.text("Status", 135, headerY);
39078
- doc.text("Remarks", 160, headerY);
39097
+ const headerTextY = gridTopY + 5.5;
39098
+ doc.text("Time Range", 25, headerTextY);
39099
+ doc.text("Output", 75, headerTextY);
39100
+ doc.text("Target", 105, headerTextY);
39101
+ doc.text("Status", 135, headerTextY);
39102
+ doc.text("Remarks", 160, headerTextY);
39079
39103
  doc.setFontSize(contentFontSize);
39080
39104
  doc.setFont("helvetica", "normal");
39081
- let yPos = tableStartY;
39105
+ let yPos = headerBottomY + 5.5;
39082
39106
  const workspaceDate = new Date(workspace.date);
39083
39107
  const today = /* @__PURE__ */ new Date();
39084
39108
  today.setHours(0, 0, 0, 0);
@@ -39106,9 +39130,11 @@ var WorkspacePdfGenerator = ({ workspace, className, idleTimeReasons }) => {
39106
39130
  const dataCollected = !isToday2 || hourNumber < currentHour;
39107
39131
  const outputStr = dataCollected ? output.toString() : "TBD";
39108
39132
  const targetStr = hourlyTarget.toString();
39109
- const rowBottomY = headerBottomY + (index + 1) * rowHeight;
39110
- doc.setDrawColor(200, 200, 200);
39111
- doc.line(20, rowBottomY, 190, rowBottomY);
39133
+ if (index < totalRows - 1) {
39134
+ const rowBottomY = headerBottomY + (index + 1) * rowHeight;
39135
+ doc.setDrawColor(200, 200, 200);
39136
+ doc.line(20, rowBottomY, 190, rowBottomY);
39137
+ }
39112
39138
  doc.text(timeRange, 25, yPos);
39113
39139
  doc.text(outputStr, 75, yPos);
39114
39140
  doc.text(targetStr, 105, yPos);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optifye/dashboard-core",
3
- "version": "6.10.9",
3
+ "version": "6.10.10",
4
4
  "description": "Reusable UI & logic for Optifye dashboard",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",