@cwellt_software/cwellt-reactjs-lib 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +468 -207
- package/dist/index.css +3 -1
- package/dist/index.d.ts +48 -5
- package/dist/index.es.js +468 -208
- package/dist/src/common/functions/colorManipulation.d.ts.map +1 -1
- package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts +6 -0
- package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts.map +1 -1
- package/dist/src/components/control/input/date-picker/CwInputDatePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/date-picker/datePickerUtils.d.ts +38 -0
- package/dist/src/components/control/input/date-picker/datePickerUtils.d.ts.map +1 -0
- package/dist/src/components/control/input/date-text/CwInputDateText.d.ts +4 -4
- package/dist/src/components/control/input/date-text/CwInputDateText.d.ts.map +1 -1
- package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts +16 -0
- package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts +10 -1
- package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateTimePicker.d.ts +6 -1
- package/dist/src/components/control/input/new-dates/CwDateTimePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateTimePickerCompact.d.ts +8 -1
- package/dist/src/components/control/input/new-dates/CwDateTimePickerCompact.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/utils/timezoneHelpers.d.ts +16 -0
- package/dist/src/components/control/input/new-dates/utils/timezoneHelpers.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler/components/day_headers/MyDaysHeader.d.ts +0 -3
- package/dist/src/components/custom/scheduler/components/day_headers/MyDaysHeader.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler/components/scheduler_content_area/SchedulerContentArea.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler/logic/dates/getFormatedTimeForHeader.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler/logic/dates/listOfDatesToWeeks.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler/logic/filtering/filterResources.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/NewScheduler.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/components/header/HeaderDivision.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/components/header/SchedulerHeader.d.ts +6 -1
- package/dist/src/components/custom/scheduler-new/presentation/components/header/SchedulerHeader.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/helpers.d.ts +0 -9
- package/dist/src/components/custom/scheduler-new/presentation/helpers.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/logic/dateFromPercentage.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/logic/eventIsVisible.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/logic/filterVisibleEvents.d.ts +3 -0
- package/dist/src/components/custom/scheduler-new/presentation/logic/filterVisibleEvents.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-new/presentation/logic/getDefaultDivisions.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/logic/getDivisions.d.ts.map +1 -1
- package/dist/src/components/custom/scheduler-new/presentation/logic/isToday.d.ts +2 -0
- package/dist/src/components/custom/scheduler-new/presentation/logic/isToday.d.ts.map +1 -0
- package/dist/src/components/custom/super-scheduler/SuperSchedulerPresenter.d.ts.map +1 -1
- package/dist/src/components/display/data/table/CwTable.d.ts +2 -1
- package/dist/src/components/display/data/table/CwTable.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/main.d.ts +0 -1
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/playground/PlaygroundApp.d.ts +4 -0
- package/dist/src/playground/PlaygroundApp.d.ts.map +1 -0
- package/dist/src/playground/pages/ColorContrastPage.d.ts +3 -0
- package/dist/src/playground/pages/ColorContrastPage.d.ts.map +1 -0
- package/dist/src/playground/pages/DatePickerLocalePage.d.ts +3 -0
- package/dist/src/playground/pages/DatePickerLocalePage.d.ts.map +1 -0
- package/dist/src/playground/pages/TablePaginationPage.d.ts +3 -0
- package/dist/src/playground/pages/TablePaginationPage.d.ts.map +1 -0
- package/dist/test/components/control/input/date-picker/datePickerUtils.test.d.ts +2 -0
- package/dist/test/components/control/input/date-picker/datePickerUtils.test.d.ts.map +1 -0
- package/dist/test/components/custom/new-scheduler/presentation/header/getStartEnd.test.d.ts +2 -0
- package/dist/test/components/custom/new-scheduler/presentation/header/getStartEnd.test.d.ts.map +1 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/dateFromPercentage.test.d.ts +2 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/dateFromPercentage.test.d.ts.map +1 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/eventIsVisible.test.d.ts +2 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/eventIsVisible.test.d.ts.map +1 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/filterVisibleEvents.test.d.ts +2 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/filterVisibleEvents.test.d.ts.map +1 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/isToday.test.d.ts +2 -0
- package/dist/test/components/custom/new-scheduler/presentation/logic/isToday.test.d.ts.map +1 -0
- package/dist/test/components/custom/scheduler/getFormattedTimeForHeader.test.d.ts +2 -0
- package/dist/test/components/custom/scheduler/getFormattedTimeForHeader.test.d.ts.map +1 -0
- package/package.json +19 -17
package/dist/index.es.js
CHANGED
|
@@ -4,12 +4,10 @@ import React__default, { cloneElement, useEffect, useState, useCallback, useRef,
|
|
|
4
4
|
import { createRoot } from 'react-dom/client';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
6
6
|
import Draggable from 'react-draggable';
|
|
7
|
-
import moment from 'moment';
|
|
8
7
|
import { format } from 'date-fns';
|
|
9
8
|
import { enGB } from 'date-fns/locale';
|
|
10
9
|
import { DayPicker } from 'react-day-picker';
|
|
11
10
|
import 'react-day-picker/dist/style.css';
|
|
12
|
-
import moment$1 from 'moment-timezone';
|
|
13
11
|
import { VariableSizeList } from 'react-window';
|
|
14
12
|
|
|
15
13
|
class CwSelectList {
|
|
@@ -107,36 +105,60 @@ function getHSLColor(color, alpha = 1) {
|
|
|
107
105
|
const hsl = colorToHSL(color);
|
|
108
106
|
return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha})`;
|
|
109
107
|
}
|
|
108
|
+
function hslToLinearRgb(h, s, l) {
|
|
109
|
+
const sNorm = s / 100;
|
|
110
|
+
const lNorm = l / 100;
|
|
111
|
+
const a = sNorm * Math.min(lNorm, 1 - lNorm);
|
|
112
|
+
const f = (n) => {
|
|
113
|
+
const k = (n + h / 30) % 12;
|
|
114
|
+
return lNorm - a * Math.max(-1, Math.min(k - 3, Math.min(9 - k, 1)));
|
|
115
|
+
};
|
|
116
|
+
return [f(0), f(8), f(4)];
|
|
117
|
+
}
|
|
118
|
+
function srgbLuminance(r, g, b) {
|
|
119
|
+
const lin = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
120
|
+
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
121
|
+
}
|
|
122
|
+
function wcagContrastRatio(lum1, lum2) {
|
|
123
|
+
const lighter = Math.max(lum1, lum2);
|
|
124
|
+
const darker = Math.min(lum1, lum2);
|
|
125
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
126
|
+
}
|
|
110
127
|
function getContrastColor(color) {
|
|
111
|
-
if (color === null)
|
|
128
|
+
if (color === null)
|
|
112
129
|
return '#000000';
|
|
113
|
-
}
|
|
114
130
|
const hsl = colorToHSL(color);
|
|
115
|
-
// Saturated greenyellow and cyan tones need lower luminance threshold (40-35)
|
|
116
|
-
// Saturated mediumblue and blueviolet tones need higher luminance threshold (55-60)
|
|
117
|
-
// Saturated orangered tones need lower luminance threshold (45)
|
|
118
|
-
const isYellowGreen = (hsl.h >= 45 && hsl.h <= 180);
|
|
119
|
-
const isBlueViolet = (hsl.h >= 210 && hsl.h <= 300);
|
|
120
|
-
const isRedOrange = (hsl.h >= 0 && hsl.h <= 30) || (hsl.h >= 330 && hsl.h <= 360);
|
|
121
|
-
let threshold = 50;
|
|
122
|
-
if (isYellowGreen) {
|
|
123
|
-
threshold = 40;
|
|
124
|
-
if (hsl.s >= 70) {
|
|
125
|
-
threshold = 35;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else if (isBlueViolet) {
|
|
129
|
-
threshold = 55;
|
|
130
|
-
if (hsl.s >= 70) {
|
|
131
|
-
threshold = 60;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
else if (isRedOrange && hsl.s >= 80) {
|
|
135
|
-
threshold = 45;
|
|
136
|
-
}
|
|
137
|
-
const contrastL = hsl.l >= threshold ? 20 : 90;
|
|
138
131
|
const contrastS = Math.min(hsl.s, 90);
|
|
139
|
-
|
|
132
|
+
const bgRgb = hslToLinearRgb(hsl.h, hsl.s, hsl.l);
|
|
133
|
+
const bgLum = srgbLuminance(...bgRgb);
|
|
134
|
+
const darkL = 15;
|
|
135
|
+
const lightL = 90;
|
|
136
|
+
const darkLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, darkL));
|
|
137
|
+
const lightLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, lightL));
|
|
138
|
+
const darkRatio = wcagContrastRatio(bgLum, darkLum);
|
|
139
|
+
const lightRatio = wcagContrastRatio(bgLum, lightLum);
|
|
140
|
+
// On saturated backgrounds, dark-tinted text blends visually with the
|
|
141
|
+
// vibrant color even when math says it has better contrast.
|
|
142
|
+
// Prefer light text unless dark has an overwhelmingly higher ratio.
|
|
143
|
+
const saturatedBias = hsl.s >= 30 && bgLum < 0.4;
|
|
144
|
+
// Mid-grays (#777–#999): dark text "sinks" into the background while
|
|
145
|
+
// white text pops, even though dark wins on WCAG ratio.
|
|
146
|
+
const midGrayBias = hsl.s < 15 && bgLum >= 0.18 && bgLum <= 0.35;
|
|
147
|
+
const goLight = saturatedBias
|
|
148
|
+
? darkRatio < lightRatio * 3
|
|
149
|
+
: midGrayBias || lightRatio >= darkRatio;
|
|
150
|
+
let targetL = goLight ? lightL : darkL;
|
|
151
|
+
let bestRatio = goLight ? lightRatio : darkRatio;
|
|
152
|
+
if (bestRatio < 4.5) {
|
|
153
|
+
const step = goLight ? 5 : -5;
|
|
154
|
+
const limit = goLight ? 95 : 0;
|
|
155
|
+
while (bestRatio < 4.5 && targetL !== limit) {
|
|
156
|
+
targetL = goLight ? Math.min(targetL + step, limit) : Math.max(targetL + step, limit);
|
|
157
|
+
const candidateLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, targetL));
|
|
158
|
+
bestRatio = wcagContrastRatio(bgLum, candidateLum);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
const SVG_ICONS = {
|
|
@@ -607,11 +629,7 @@ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPositio
|
|
|
607
629
|
* <CwLoading size="small" />
|
|
608
630
|
*/
|
|
609
631
|
function CwLoadingSmall(CwelltLoadingAppointements) {
|
|
610
|
-
return (jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (
|
|
611
|
-
// * Show loading appointment
|
|
612
|
-
jsx("div", { className: "cw-loading-container", children: jsx("div", { className: "cw-loading" }) })) : (
|
|
613
|
-
// Show empty div
|
|
614
|
-
jsx("div", {})) }));
|
|
632
|
+
return (jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (jsx("div", { className: "cw-loading-container", children: jsx("div", { className: "cw-loading" }) })) : (jsx("div", {})) }));
|
|
615
633
|
}
|
|
616
634
|
|
|
617
635
|
var styles$p = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
|
|
@@ -1093,11 +1111,7 @@ function CwModal(custModalProps) {
|
|
|
1093
1111
|
width: custModalProps.widthModal
|
|
1094
1112
|
}
|
|
1095
1113
|
};
|
|
1096
|
-
return (jsx("div", { children: custModalProps.modalState && (jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsx("span", { className: "cwelltCloseIcon" }) })] }), jsx("div", { className: "cwelltModalBody", children: jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (
|
|
1097
|
-
// [ false : show modal ]
|
|
1098
|
-
jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (
|
|
1099
|
-
// true [ do not show the modal ]
|
|
1100
|
-
jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1114
|
+
return (jsx("div", { children: custModalProps.modalState && (jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsx("span", { className: "cwelltCloseIcon" }) })] }), jsx("div", { className: "cwelltModalBody", children: jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1101
1115
|
}
|
|
1102
1116
|
|
|
1103
1117
|
var styles$n = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
|
|
@@ -1450,12 +1464,10 @@ const CwDialog = props => {
|
|
|
1450
1464
|
const footer = useMemo(() => (jsx("footer", { children: customFooter || (jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave })) })), [customFooter, onSave, disableSave]);
|
|
1451
1465
|
const resizeHandles = useMemo(() => size.autoHeight
|
|
1452
1466
|
? [
|
|
1453
|
-
// Only horizontal handles if autoHeight is true
|
|
1454
1467
|
jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
|
|
1455
1468
|
jsx("div", { "data-handle-w": true, onMouseDown: handleResizeMouseDown("w") }, "handle-w")
|
|
1456
1469
|
]
|
|
1457
1470
|
: [
|
|
1458
|
-
// All handles if autoHeight is false
|
|
1459
1471
|
jsx("div", { "data-handle-n": true, onMouseDown: handleResizeMouseDown("n") }, "handle-n"),
|
|
1460
1472
|
jsx("div", { "data-handle-s": true, onMouseDown: handleResizeMouseDown("s") }, "handle-s"),
|
|
1461
1473
|
jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
|
|
@@ -1856,7 +1868,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
|
|
|
1856
1868
|
*
|
|
1857
1869
|
* @returns React component
|
|
1858
1870
|
*/
|
|
1859
|
-
function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, rowSelection }) {
|
|
1871
|
+
function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, pageLabel = "page", rowSelection }) {
|
|
1860
1872
|
const [currentPage, setCurrentPage] = useState(1);
|
|
1861
1873
|
const [expandedRowKey, setExpandedRowKey] = useState(null);
|
|
1862
1874
|
const [sortConfig, setSortConfig] = useState({
|
|
@@ -2041,16 +2053,16 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2041
2053
|
? "sortable"
|
|
2042
2054
|
: sortConfig.direction === "asc"
|
|
2043
2055
|
? "sortable-asc"
|
|
2044
|
-
: "sortable-desc" }))] }), jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsx("tbody", { children: renderTableBody() })] }) }), pagination && data.length > pageSizeOptions[0] && (jsxs("footer", { className: "cw-table-pagination", children: [jsx("
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2056
|
+
: "sortable-desc" }))] }), jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsx("tbody", { children: renderTableBody() })] }) }), pagination && data.length > pageSizeOptions[0] && (jsxs("footer", { className: "cw-table-pagination", children: [jsxs("div", { className: "cw-table-pagination-size", children: [jsx(CwIcon, { iconId: "list" }), jsx("select", { value: localItemsPerPage, onChange: handleItemsPerPageChange, children: pageSizeOptions.map(size => (jsx("option", { value: size, children: pageLabel ? `${size} / ${pageLabel}` : size }, size))) })] }), jsxs("div", { className: "cw-table-pagination-nav", children: [jsx(CwButton, { onClick: () => handlePageChange(1), disabled: currentPage === 1 || totalPages === 1, variant: "icon", icon: "chevron-left-double" }), jsx(CwButton, { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1 || totalPages === 1, variant: "icon", icon: "chevron-left" }), jsx("input", { type: "text", inputMode: "numeric", value: currentPage, onChange: (e) => {
|
|
2057
|
+
const value = parseInt(e.target.value, 10);
|
|
2058
|
+
if (!isNaN(value))
|
|
2059
|
+
handlePageChange(value);
|
|
2060
|
+
}, onBlur: (e) => {
|
|
2061
|
+
const value = parseInt(e.target.value, 10);
|
|
2062
|
+
if (isNaN(value) || value < 1 || value > totalPages) {
|
|
2063
|
+
handlePageChange(1);
|
|
2064
|
+
}
|
|
2065
|
+
}, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages === 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages === 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2054
2066
|
}
|
|
2055
2067
|
|
|
2056
2068
|
var styles$i = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","skeletonRow":"cw-sortable-table-module__skeletonRow__vyD0M","skeleton":"cw-sortable-table-module__skeleton__QGXAD","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
|
|
@@ -2807,10 +2819,26 @@ function CwFileUpload(fileUploadProps) {
|
|
|
2807
2819
|
|
|
2808
2820
|
var styles$e = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
|
|
2809
2821
|
|
|
2822
|
+
const DEFAULT_LABELS = {
|
|
2823
|
+
uploadDisabled: 'Upload disabled',
|
|
2824
|
+
clickToUpload: 'Click to upload or drag and drop',
|
|
2825
|
+
acceptedFiles: (accept) => `Accepted files: ${accept}`,
|
|
2826
|
+
singleFileOnly: '(Single file only)',
|
|
2827
|
+
allTypesAccepted: 'All file types accepted',
|
|
2828
|
+
changeFile: 'Change File',
|
|
2829
|
+
clearAll: 'Clear all',
|
|
2830
|
+
addMoreFiles: 'Add More Files',
|
|
2831
|
+
filesSelected: (count) => `${count} file${count !== 1 ? 's' : ''} selected`,
|
|
2832
|
+
fileTooLarge: (name, maxSize) => `File "${name}" is too large. Maximum size allowed is ${maxSize}MB.`,
|
|
2833
|
+
invalidFormat: (name, accepted) => `File "${name}" has an invalid format. Allowed formats: ${accepted}`,
|
|
2834
|
+
invalidMimeType: (name, types) => `File "${name}" has an invalid MIME type. Allowed types: ${types}`,
|
|
2835
|
+
alreadySelected: (name) => `File "${name}" is already selected.`,
|
|
2836
|
+
};
|
|
2810
2837
|
function CwFileUploadMultiple(fileUploadProps) {
|
|
2811
2838
|
const fileInputRef = useRef(null);
|
|
2812
2839
|
const [selectedFiles, setSelectedFiles] = useState([]);
|
|
2813
2840
|
const [existingFile, setExistingFile] = useState(fileUploadProps.initialFileName);
|
|
2841
|
+
const labels = { ...DEFAULT_LABELS, ...fileUploadProps.labels };
|
|
2814
2842
|
React__default.useEffect(() => {
|
|
2815
2843
|
setExistingFile(fileUploadProps.initialFileName);
|
|
2816
2844
|
}, [fileUploadProps.initialFileName]);
|
|
@@ -2824,7 +2852,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2824
2852
|
if (fileSizeInMB > fileUploadProps.maxFileSize) {
|
|
2825
2853
|
return {
|
|
2826
2854
|
isValid: false,
|
|
2827
|
-
error:
|
|
2855
|
+
error: labels.fileTooLarge(file.name, fileUploadProps.maxFileSize)
|
|
2828
2856
|
};
|
|
2829
2857
|
}
|
|
2830
2858
|
}
|
|
@@ -2841,7 +2869,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2841
2869
|
if (!isExtensionValid) {
|
|
2842
2870
|
return {
|
|
2843
2871
|
isValid: false,
|
|
2844
|
-
error:
|
|
2872
|
+
error: labels.invalidFormat(file.name, fileUploadProps.accept)
|
|
2845
2873
|
};
|
|
2846
2874
|
}
|
|
2847
2875
|
}
|
|
@@ -2851,7 +2879,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2851
2879
|
if (!isMimeTypeValid) {
|
|
2852
2880
|
return {
|
|
2853
2881
|
isValid: false,
|
|
2854
|
-
error:
|
|
2882
|
+
error: labels.invalidMimeType(file.name, fileUploadProps.allowedTypes.join(', '))
|
|
2855
2883
|
};
|
|
2856
2884
|
}
|
|
2857
2885
|
}
|
|
@@ -2865,7 +2893,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2865
2893
|
// Check if the file already exists (by name and size)
|
|
2866
2894
|
const isDuplicate = existingFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
|
|
2867
2895
|
if (isDuplicate) {
|
|
2868
|
-
errors.push(
|
|
2896
|
+
errors.push(labels.alreadySelected(file.name));
|
|
2869
2897
|
continue;
|
|
2870
2898
|
}
|
|
2871
2899
|
const validation = validateFile(file);
|
|
@@ -2956,12 +2984,12 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2956
2984
|
}
|
|
2957
2985
|
}
|
|
2958
2986
|
};
|
|
2959
|
-
return (jsxs("div", { className: `${styles$e.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$e.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$e.uploadArea} ${fileUploadProps.disabled ? styles$e.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$e.uploadTitle}`, children: fileUploadProps.disabled ?
|
|
2987
|
+
return (jsxs("div", { className: `${styles$e.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$e.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$e.uploadArea} ${fileUploadProps.disabled ? styles$e.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$e.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$e.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$e.filesContainer, children: [jsxs("div", { className: styles$e.fileItem, children: [jsxs("div", { className: styles$e.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$e.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$e.fileInfo, children: jsx("p", { className: styles$e.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
|
|
2960
2988
|
setExistingFile(undefined);
|
|
2961
2989
|
if (fileUploadProps.onSelect) {
|
|
2962
2990
|
fileUploadProps.onSelect(null);
|
|
2963
2991
|
}
|
|
2964
|
-
}, disabled: fileUploadProps.disabled, className: styles$e.smallButton })] }), jsx(CwButton, { text:
|
|
2992
|
+
}, disabled: fileUploadProps.disabled, className: styles$e.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$e.filesContainer, children: [jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsx("small", { className: styles$e.filesCount, children: labels.filesSelected(selectedFiles.length) }), jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll })] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$e.fileItem, children: [jsxs("div", { className: styles$e.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$e.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$e.fileInfo, children: [jsx("p", { className: styles$e.fileName, children: file.name }), jsxs("p", { className: styles$e.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$e.smallButton })] }, index))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
|
|
2965
2993
|
}
|
|
2966
2994
|
|
|
2967
2995
|
function CwInput(CwInputProps) {
|
|
@@ -2975,9 +3003,7 @@ function CwInput(CwInputProps) {
|
|
|
2975
3003
|
? "cw-flex-column"
|
|
2976
3004
|
: "cw-flex-row ", children: [jsx("label", { className: CwInputProps.disabled === true
|
|
2977
3005
|
? CwInputProps.labelClassName + " " + "cw_label_text cw_label_text_disabled"
|
|
2978
|
-
: CwInputProps.labelClassName + " " + "cw_label_text", children: CwInputProps.labelName }), jsx("input", { id: CwInputProps.id, type: "text", value: CwInputProps.value, onChange: e => handleChange(e), className: CwInputProps.className + " " + "cw_input", placeholder: CwInputProps.placeholder === undefined ? "Write a text please" : CwInputProps.placeholder, style: CwInputProps.style, disabled: CwInputProps.disabled, required: CwInputProps.required }), CwInputProps.value && (
|
|
2979
|
-
// if the component is disabled do not show clear button
|
|
2980
|
-
jsx("button", { className: "cw_button_clear cwellt_flex cwellt_justify_center cwellt_align_items_center", onClick: handleClearClick }))] }));
|
|
3006
|
+
: CwInputProps.labelClassName + " " + "cw_label_text", children: CwInputProps.labelName }), jsx("input", { id: CwInputProps.id, type: "text", value: CwInputProps.value, onChange: e => handleChange(e), className: CwInputProps.className + " " + "cw_input", placeholder: CwInputProps.placeholder === undefined ? "Write a text please" : CwInputProps.placeholder, style: CwInputProps.style, disabled: CwInputProps.disabled, required: CwInputProps.required }), CwInputProps.value && (jsx("button", { className: "cw_button_clear cwellt_flex cwellt_justify_center cwellt_align_items_center", onClick: handleClearClick }))] }));
|
|
2981
3007
|
}
|
|
2982
3008
|
|
|
2983
3009
|
/**
|
|
@@ -3453,6 +3479,114 @@ function CwInputDate(props) {
|
|
|
3453
3479
|
|
|
3454
3480
|
var classes = {"datePicker":"cw-input-date-picker-module__datePicker__jogOq","input":"cw-input-date-picker-module__input__uQshH","calendar":"cw-input-date-picker-module__calendar__q39ic","calendarHeader":"cw-input-date-picker-module__calendarHeader__1btPK","arrowButton":"cw-input-date-picker-module__arrowButton__23tNc","calendarTitle":"cw-input-date-picker-module__calendarTitle__oOODw","calendarBody":"cw-input-date-picker-module__calendarBody__-711a","calendarDay":"cw-input-date-picker-module__calendarDay__z-Mmv","selected":"cw-input-date-picker-module__selected__XQgR7","todayButton":"cw-input-date-picker-module__todayButton__oYamC","emptyDay":"cw-input-date-picker-module__emptyDay__lbI5B"};
|
|
3455
3481
|
|
|
3482
|
+
/**
|
|
3483
|
+
* Converts a Date or ISO string to a Temporal.PlainDate.
|
|
3484
|
+
*/
|
|
3485
|
+
function toPlainDate$1(dateString) {
|
|
3486
|
+
if (dateString instanceof Date) {
|
|
3487
|
+
return Temporal.PlainDate.from({
|
|
3488
|
+
year: dateString.getFullYear(),
|
|
3489
|
+
month: dateString.getMonth() + 1,
|
|
3490
|
+
day: dateString.getDate(),
|
|
3491
|
+
});
|
|
3492
|
+
}
|
|
3493
|
+
// ISO "YYYY-MM-DD" → direct parse
|
|
3494
|
+
return Temporal.PlainDate.from(dateString);
|
|
3495
|
+
}
|
|
3496
|
+
/**
|
|
3497
|
+
* Formats a date as DD.MM.YYYY (German locale).
|
|
3498
|
+
*/
|
|
3499
|
+
function toGermanDate(dateString) {
|
|
3500
|
+
const pd = toPlainDate$1(dateString);
|
|
3501
|
+
const day = String(pd.day).padStart(2, "0");
|
|
3502
|
+
const month = String(pd.month).padStart(2, "0");
|
|
3503
|
+
return `${day}.${month}.${pd.year}`;
|
|
3504
|
+
}
|
|
3505
|
+
/**
|
|
3506
|
+
* Formats a date as YYYY-MM-DD (ISO).
|
|
3507
|
+
*/
|
|
3508
|
+
function toISODate(dateString) {
|
|
3509
|
+
return toPlainDate$1(dateString).toString();
|
|
3510
|
+
}
|
|
3511
|
+
/**
|
|
3512
|
+
* Validates whether a string is a valid DD.MM.YYYY date.
|
|
3513
|
+
*/
|
|
3514
|
+
function isValidGermanDate(textDate) {
|
|
3515
|
+
return parseGermanDate(textDate) !== null;
|
|
3516
|
+
}
|
|
3517
|
+
/**
|
|
3518
|
+
* Converts a DD.MM.YYYY string to YYYY-MM-DD, or null if invalid.
|
|
3519
|
+
*/
|
|
3520
|
+
function germanDateToISO(textDate) {
|
|
3521
|
+
const pd = parseGermanDate(textDate);
|
|
3522
|
+
return pd ? pd.toString() : null;
|
|
3523
|
+
}
|
|
3524
|
+
/**
|
|
3525
|
+
* Converts a DD.MM.YYYY string to a Date object, or null if invalid.
|
|
3526
|
+
*/
|
|
3527
|
+
function germanDateToDate(textDate) {
|
|
3528
|
+
const pd = parseGermanDate(textDate);
|
|
3529
|
+
if (!pd)
|
|
3530
|
+
return null;
|
|
3531
|
+
return new Date(pd.year, pd.month - 1, pd.day);
|
|
3532
|
+
}
|
|
3533
|
+
/**
|
|
3534
|
+
* Returns the number of days in the month and the Monday-based
|
|
3535
|
+
* weekday offset (0 = Monday) for the 1st of the month.
|
|
3536
|
+
*/
|
|
3537
|
+
function computeCalendarGrid(internalDate) {
|
|
3538
|
+
const pd = Temporal.PlainDate.from({
|
|
3539
|
+
year: internalDate.getFullYear(),
|
|
3540
|
+
month: internalDate.getMonth() + 1,
|
|
3541
|
+
day: 1,
|
|
3542
|
+
});
|
|
3543
|
+
const daysInMonth = pd.daysInMonth;
|
|
3544
|
+
const startDay = pd.dayOfWeek - 1; // Temporal: 1=Mon … 7=Sun → 0-based Mon
|
|
3545
|
+
return { daysInMonth, startDay };
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* Returns true when the given day in the internalDate's month/year
|
|
3549
|
+
* matches the selected ISO value string.
|
|
3550
|
+
*/
|
|
3551
|
+
function isSelectedDay(internalDate, day, value) {
|
|
3552
|
+
const pd = Temporal.PlainDate.from({
|
|
3553
|
+
year: internalDate.getFullYear(),
|
|
3554
|
+
month: internalDate.getMonth() + 1,
|
|
3555
|
+
day,
|
|
3556
|
+
});
|
|
3557
|
+
return pd.toString() === value;
|
|
3558
|
+
}
|
|
3559
|
+
/**
|
|
3560
|
+
* Returns a new Date set to the 1st of the month offset by `direction` months.
|
|
3561
|
+
*/
|
|
3562
|
+
function computeNextMonthDate(currentDate, direction) {
|
|
3563
|
+
const pd = Temporal.PlainDate.from({
|
|
3564
|
+
year: currentDate.getFullYear(),
|
|
3565
|
+
month: currentDate.getMonth() + 1,
|
|
3566
|
+
day: 1,
|
|
3567
|
+
});
|
|
3568
|
+
const moved = pd.add({ months: direction });
|
|
3569
|
+
return new Date(moved.year, moved.month - 1, moved.day);
|
|
3570
|
+
}
|
|
3571
|
+
// ── internal helper ────────────────────────────────────────────────────
|
|
3572
|
+
/**
|
|
3573
|
+
* Strictly parses a DD.MM.YYYY string into a Temporal.PlainDate, or null.
|
|
3574
|
+
*/
|
|
3575
|
+
function parseGermanDate(text) {
|
|
3576
|
+
const match = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(text);
|
|
3577
|
+
if (!match)
|
|
3578
|
+
return null;
|
|
3579
|
+
const day = Number(match[1]);
|
|
3580
|
+
const month = Number(match[2]);
|
|
3581
|
+
const year = Number(match[3]);
|
|
3582
|
+
try {
|
|
3583
|
+
return Temporal.PlainDate.from({ year, month, day }, { overflow: "reject" });
|
|
3584
|
+
}
|
|
3585
|
+
catch {
|
|
3586
|
+
return null;
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3456
3590
|
const CwInputDatePicker = ({ value, onChange }) => {
|
|
3457
3591
|
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
|
3458
3592
|
const [internalDate, setInternalDate] = useState(new Date(value || new Date().toISOString()));
|
|
@@ -3476,21 +3610,13 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3476
3610
|
useEffect(() => {
|
|
3477
3611
|
setTextDate(toGermanDate(value));
|
|
3478
3612
|
}, [value]);
|
|
3479
|
-
function toGermanDate(dateString) {
|
|
3480
|
-
return moment(dateString).format("DD.MM.YYYY");
|
|
3481
|
-
}
|
|
3482
|
-
function toISODate(dateString) {
|
|
3483
|
-
return moment(dateString).format("YYYY-MM-DD");
|
|
3484
|
-
}
|
|
3485
3613
|
const submitInput = () => {
|
|
3486
|
-
if (
|
|
3487
|
-
const
|
|
3488
|
-
const
|
|
3489
|
-
if (
|
|
3490
|
-
const newDateString = momentDate.format("YYYY-MM-DD");
|
|
3614
|
+
if (isValidGermanDate(textDate)) {
|
|
3615
|
+
const newDateString = germanDateToISO(textDate);
|
|
3616
|
+
const newDate = germanDateToDate(textDate);
|
|
3617
|
+
if (newDateString && newDate) {
|
|
3491
3618
|
if (newDateString !== value) {
|
|
3492
|
-
|
|
3493
|
-
setInternalDate(momentDate.toDate());
|
|
3619
|
+
setInternalDate(newDate);
|
|
3494
3620
|
onChange?.(newDateString);
|
|
3495
3621
|
}
|
|
3496
3622
|
setIsCalendarOpen(false);
|
|
@@ -3527,7 +3653,7 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3527
3653
|
setIsCalendarOpen(false);
|
|
3528
3654
|
};
|
|
3529
3655
|
const handleClickMonthArrow = (direction) => {
|
|
3530
|
-
setInternalDate(prevDate =>
|
|
3656
|
+
setInternalDate(prevDate => computeNextMonthDate(prevDate, direction));
|
|
3531
3657
|
};
|
|
3532
3658
|
const handlePressEnter = (event) => {
|
|
3533
3659
|
if (event.key === "Enter" && submitInput()) {
|
|
@@ -3540,23 +3666,21 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3540
3666
|
}
|
|
3541
3667
|
};
|
|
3542
3668
|
const generateCalendarDays = () => {
|
|
3543
|
-
const daysInMonth
|
|
3544
|
-
const startDay = new Date(internalDate.getFullYear(), internalDate.getMonth(), 1).getDay() - 1;
|
|
3669
|
+
const { daysInMonth, startDay } = computeCalendarGrid(internalDate);
|
|
3545
3670
|
const calendarDays = new Array;
|
|
3546
3671
|
for (let i = 0; i < startDay; i++) {
|
|
3547
3672
|
calendarDays.push(jsx("div", { className: classes.emptyDay }, `empty-${i}`));
|
|
3548
3673
|
}
|
|
3549
3674
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
3550
|
-
const
|
|
3551
|
-
|
|
3552
|
-
calendarDays.push(jsx("div", { className: `${classes.calendarDay}${isSelected ? ` ${classes.selected}` : ""}`, onClick: () => handleClickDay(day), children: day }, day));
|
|
3675
|
+
const selected = isSelectedDay(internalDate, day, value);
|
|
3676
|
+
calendarDays.push(jsx("div", { className: `${classes.calendarDay}${selected ? ` ${classes.selected}` : ""}`, onClick: () => handleClickDay(day), children: day }, day));
|
|
3553
3677
|
}
|
|
3554
3678
|
return calendarDays;
|
|
3555
3679
|
};
|
|
3556
3680
|
return (jsxs("div", { className: classes.datePicker, children: [jsx("input", { type: "text", value: textDate, onChange: e => setTextDate(e.currentTarget.value), onFocus: () => {
|
|
3557
3681
|
setInternalDate(new Date(value));
|
|
3558
3682
|
setIsCalendarOpen(true);
|
|
3559
|
-
}, onBlur: handleBlurInput, onKeyDown: handlePressEnter, "data-valid":
|
|
3683
|
+
}, onBlur: handleBlurInput, onKeyDown: handlePressEnter, "data-valid": isValidGermanDate(textDate), ref: inputRef, className: classes.input }), isCalendarOpen && (jsxs("div", { className: classes.calendar, ref: calendarRef, children: [jsxs("div", { className: classes.calendarHeader, children: [jsx("button", { className: classes.arrowButton, onClick: () => handleClickMonthArrow(-1), children: "<" }), jsxs("span", { className: classes.calendarTitle, children: [internalDate.toLocaleString("default", { month: "long" }), " ", internalDate.getFullYear()] }), jsx("button", { className: classes.arrowButton, onClick: () => handleClickMonthArrow(1), children: ">" })] }), jsx("div", { className: classes.calendarBody, children: generateCalendarDays() }), jsx("button", { className: classes.todayButton, onClick: handleClickToday, children: "Today" })] }))] }));
|
|
3560
3684
|
};
|
|
3561
3685
|
|
|
3562
3686
|
/**
|
|
@@ -3609,6 +3733,47 @@ function CwTime(props) {
|
|
|
3609
3733
|
return (jsx("div", { className: "cw-input-date", children: jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsx("input", { type: "time", ...inputProps }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
|
|
3610
3734
|
}
|
|
3611
3735
|
|
|
3736
|
+
function parseDateParts(dateStr, format) {
|
|
3737
|
+
const parts = dateStr.split(/[.\-\/]/);
|
|
3738
|
+
if (parts.length !== 3)
|
|
3739
|
+
return null;
|
|
3740
|
+
let year, month, day;
|
|
3741
|
+
switch (format) {
|
|
3742
|
+
case "DD.MM.YYYY":
|
|
3743
|
+
case "DD/MM/YYYY":
|
|
3744
|
+
day = Number(parts[0]);
|
|
3745
|
+
month = Number(parts[1]);
|
|
3746
|
+
year = Number(parts[2]);
|
|
3747
|
+
break;
|
|
3748
|
+
case "MM/DD/YYYY":
|
|
3749
|
+
month = Number(parts[0]);
|
|
3750
|
+
day = Number(parts[1]);
|
|
3751
|
+
year = Number(parts[2]);
|
|
3752
|
+
break;
|
|
3753
|
+
case "YYYY-MM-DD":
|
|
3754
|
+
year = Number(parts[0]);
|
|
3755
|
+
month = Number(parts[1]);
|
|
3756
|
+
day = Number(parts[2]);
|
|
3757
|
+
break;
|
|
3758
|
+
}
|
|
3759
|
+
try {
|
|
3760
|
+
return Temporal.PlainDate.from({ year, month, day });
|
|
3761
|
+
}
|
|
3762
|
+
catch {
|
|
3763
|
+
return null;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
function formatPlainDate(pd, format) {
|
|
3767
|
+
const dd = pd.day.toString().padStart(2, "0");
|
|
3768
|
+
const mm = pd.month.toString().padStart(2, "0");
|
|
3769
|
+
const yyyy = pd.year.toString().padStart(4, "0");
|
|
3770
|
+
switch (format) {
|
|
3771
|
+
case "DD.MM.YYYY": return `${dd}.${mm}.${yyyy}`;
|
|
3772
|
+
case "DD/MM/YYYY": return `${dd}/${mm}/${yyyy}`;
|
|
3773
|
+
case "MM/DD/YYYY": return `${mm}/${dd}/${yyyy}`;
|
|
3774
|
+
case "YYYY-MM-DD": return `${yyyy}-${mm}-${dd}`;
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3612
3777
|
/**
|
|
3613
3778
|
* Input for entering a string of text as a date
|
|
3614
3779
|
* @remarks
|
|
@@ -3638,11 +3803,8 @@ function CwInputDateText(props) {
|
|
|
3638
3803
|
const format = dateFormat ?? displayFormat;
|
|
3639
3804
|
const width = size ?? 12;
|
|
3640
3805
|
const formattedDate = (date, inFormat, outFormat) => {
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
}
|
|
3644
|
-
else
|
|
3645
|
-
return "";
|
|
3806
|
+
const pd = parseDateParts(date, inFormat);
|
|
3807
|
+
return pd ? formatPlainDate(pd, outFormat) : "";
|
|
3646
3808
|
};
|
|
3647
3809
|
const [date, setDate] = useState("");
|
|
3648
3810
|
const [displayedDate, setDisplayedDate] = useState("");
|
|
@@ -3661,8 +3823,9 @@ function CwInputDateText(props) {
|
|
|
3661
3823
|
const onChangeInputText = (e) => {
|
|
3662
3824
|
const newDate = e.target.value;
|
|
3663
3825
|
setDisplayedDate(newDate);
|
|
3664
|
-
|
|
3665
|
-
|
|
3826
|
+
const pd = parseDateParts(newDate, format);
|
|
3827
|
+
if (pd) {
|
|
3828
|
+
setDate(formatPlainDate(pd, internalFormat));
|
|
3666
3829
|
}
|
|
3667
3830
|
else {
|
|
3668
3831
|
setDate("");
|
|
@@ -3671,8 +3834,9 @@ function CwInputDateText(props) {
|
|
|
3671
3834
|
const onChangeInputDate = (e) => {
|
|
3672
3835
|
const newDate = e.target.value;
|
|
3673
3836
|
setDate(newDate);
|
|
3674
|
-
|
|
3675
|
-
|
|
3837
|
+
const pd = parseDateParts(newDate, internalFormat);
|
|
3838
|
+
if (pd)
|
|
3839
|
+
setDisplayedDate(formatPlainDate(pd, format));
|
|
3676
3840
|
else
|
|
3677
3841
|
setDisplayedDate("");
|
|
3678
3842
|
};
|
|
@@ -4185,7 +4349,7 @@ const CwMultiFilterTag = props => {
|
|
|
4185
4349
|
} : undefined }) }));
|
|
4186
4350
|
};
|
|
4187
4351
|
|
|
4188
|
-
var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0"};
|
|
4352
|
+
var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0"};
|
|
4189
4353
|
|
|
4190
4354
|
/**
|
|
4191
4355
|
* A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
|
|
@@ -4326,7 +4490,7 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-
|
|
|
4326
4490
|
* @param {CwMultiFilterProps} props
|
|
4327
4491
|
* @returns Set the `onChange` callback to a function to check for changes in the selected filters
|
|
4328
4492
|
*/
|
|
4329
|
-
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style }) => {
|
|
4493
|
+
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style }) => {
|
|
4330
4494
|
const [filteredTags, setFilteredTags] = useState(new Set());
|
|
4331
4495
|
const [inputTextValue, setInputTextValue] = useState("");
|
|
4332
4496
|
const [isPanelOpen, setIsPanelOpen] = useState(false);
|
|
@@ -4428,9 +4592,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
|
|
|
4428
4592
|
inputRef.current?.focus();
|
|
4429
4593
|
}
|
|
4430
4594
|
};
|
|
4431
|
-
return (jsxs("form", { ref: componentRef, id: id, className: styles$7["cw-multi-filter"]
|
|
4595
|
+
return (jsxs("form", { ref: componentRef, id: id, className: `${styles$7["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
4432
4596
|
e.preventDefault();
|
|
4433
|
-
}, children: [jsxs("div", { onClick: handleDivClick, className: styles$7["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.target.value), autoComplete: "off", placeholder:
|
|
4597
|
+
}, children: [jsxs("div", { onClick: handleDivClick, className: styles$7["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.target.value), autoComplete: "off", placeholder: placeholder, onKeyDown: e => {
|
|
4434
4598
|
switch (e.key) {
|
|
4435
4599
|
case "Enter":
|
|
4436
4600
|
case "Tab": {
|
|
@@ -4460,15 +4624,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
|
|
|
4460
4624
|
} })] }), selectedTags.size > 0 ? (jsx("input", { type: "reset", value: "\u00D7", onClick: e => {
|
|
4461
4625
|
e.preventDefault();
|
|
4462
4626
|
onChangeSelectedTags(new Set());
|
|
4463
|
-
} })) : null] }), jsxs("section", { className: styles$7["cw-multi-filter-catalog-container"], "data-display-none": !isPanelOpen, children: [jsxs("nav", { children: [jsx("button", {
|
|
4464
|
-
? {
|
|
4465
|
-
backgroundColor: "var(--cw-color-primary-container)",
|
|
4466
|
-
color: "var(--cw-color-primary)",
|
|
4467
|
-
outline: "2px solid var(--cw-color-primary)",
|
|
4468
|
-
outlineOffset: "-2px",
|
|
4469
|
-
fontWeight: 400
|
|
4470
|
-
}
|
|
4471
|
-
: {}, onClick: () => handleClickCategory("All"), children: "SEARCH IN ALL CATEGORIES" }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { style: selectedCategory === category
|
|
4627
|
+
} })) : null] }), jsxs("section", { className: styles$7["cw-multi-filter-catalog-container"], "data-display-none": !isPanelOpen, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$7["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { style: selectedCategory === category
|
|
4472
4628
|
? {
|
|
4473
4629
|
backgroundColor: getColor(category).primary,
|
|
4474
4630
|
color: getColor(category).onPrimary,
|
|
@@ -5018,10 +5174,13 @@ function usePickerPopup({ anchorRef, isOpen, onClose, position = "left-bottom" }
|
|
|
5018
5174
|
return { popupRef, popupStyle: style, renderPopup };
|
|
5019
5175
|
}
|
|
5020
5176
|
|
|
5021
|
-
function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, defaultMonth, labelProps, alignProps, placeholder = "Select a date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, }) {
|
|
5177
|
+
function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, defaultMonth, labelProps, alignProps, placeholder = "Select a date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, locale = enGB, todayLabel = "Today", feedback, }) {
|
|
5022
5178
|
const [isOpen, setIsOpen] = useState(false);
|
|
5023
5179
|
const [inputValue, setInputValue] = useState("");
|
|
5024
5180
|
const containerRef = useRef(null);
|
|
5181
|
+
const feedbackMessages = feedback
|
|
5182
|
+
? Array.isArray(feedback) ? feedback : [feedback]
|
|
5183
|
+
: [];
|
|
5025
5184
|
const wrapperRef = useRef(null);
|
|
5026
5185
|
const inputRef = useRef(null);
|
|
5027
5186
|
const prevValueRef = useRef(undefined);
|
|
@@ -5189,11 +5348,11 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
5189
5348
|
...(maxDate ? [{ after: maxDate }] : []),
|
|
5190
5349
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
5191
5350
|
], [disabledDates, minDate, maxDate, disabledMatcher]);
|
|
5192
|
-
return (
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5351
|
+
return (jsxs("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsx(DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, modifiers: {
|
|
5352
|
+
today: new Date(),
|
|
5353
|
+
}, modifiersClassNames: {
|
|
5354
|
+
today: "rdp-day-today",
|
|
5355
|
+
} }), showTodayButton && (jsx("footer", { className: "cw-flex-row cw-align-right-center", children: jsx(CwButton, { type: "button", variant: "outline", onClick: handleTodayClick, text: todayLabel }) }))] }))] })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
5197
5356
|
}
|
|
5198
5357
|
|
|
5199
5358
|
var rangeStyles = {"rangeWrapper":"cw-range-picker-module__rangeWrapper__1nIVs","rangePopup":"cw-range-picker-module__rangePopup__E5jd1","presetList":"cw-range-picker-module__presetList__INiLo"};
|
|
@@ -5984,6 +6143,17 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
5984
6143
|
}) }) }))] })] }) }));
|
|
5985
6144
|
}
|
|
5986
6145
|
|
|
6146
|
+
/**
|
|
6147
|
+
* Converts a numeric offset in hours (e.g. 0, 1, -5, 5.5) to a
|
|
6148
|
+
* Temporal-compatible offset string like "+00:00", "+01:00", "-05:00", "+05:30".
|
|
6149
|
+
*/
|
|
6150
|
+
function offsetHoursToString(offset) {
|
|
6151
|
+
const sign = offset >= 0 ? "+" : "-";
|
|
6152
|
+
const abs = Math.abs(offset);
|
|
6153
|
+
const hours = Math.floor(abs);
|
|
6154
|
+
const minutes = Math.round((abs - hours) * 60);
|
|
6155
|
+
return `${sign}${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
|
|
6156
|
+
}
|
|
5987
6157
|
/**
|
|
5988
6158
|
* Converts a Date to a new Date whose local year/month/day
|
|
5989
6159
|
* reflect the date in the given UTC offset.
|
|
@@ -5997,8 +6167,9 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
5997
6167
|
* @returns A new Date with local fields matching the target timezone's date
|
|
5998
6168
|
*/
|
|
5999
6169
|
function getDateInOffset(date, timezoneOffset) {
|
|
6000
|
-
const
|
|
6001
|
-
|
|
6170
|
+
const instant = Temporal.Instant.fromEpochMilliseconds(date.getTime());
|
|
6171
|
+
const zdt = instant.toZonedDateTimeISO(offsetHoursToString(timezoneOffset));
|
|
6172
|
+
return new Date(zdt.year, zdt.month - 1, zdt.day);
|
|
6002
6173
|
}
|
|
6003
6174
|
/**
|
|
6004
6175
|
* Gets the time string (HH:mm) for a Date in the given UTC offset.
|
|
@@ -6008,10 +6179,28 @@ function getDateInOffset(date, timezoneOffset) {
|
|
|
6008
6179
|
* @returns Time string in "HH:mm" format for the given offset
|
|
6009
6180
|
*/
|
|
6010
6181
|
function getTimeInOffset(date, timezoneOffset) {
|
|
6011
|
-
|
|
6182
|
+
const instant = Temporal.Instant.fromEpochMilliseconds(date.getTime());
|
|
6183
|
+
const zdt = instant.toZonedDateTimeISO(offsetHoursToString(timezoneOffset));
|
|
6184
|
+
return `${String(zdt.hour).padStart(2, "0")}:${String(zdt.minute).padStart(2, "0")}`;
|
|
6185
|
+
}
|
|
6186
|
+
/**
|
|
6187
|
+
* Combines a display date (local fields) and time components into a real Date
|
|
6188
|
+
* by interpreting them in the given UTC offset.
|
|
6189
|
+
*
|
|
6190
|
+
* @param date - Date whose local year/month/day are the "display" values
|
|
6191
|
+
* @param hours - Hour component (0-23)
|
|
6192
|
+
* @param minutes - Minute component (0-59)
|
|
6193
|
+
* @param timezoneOffset - Numeric offset in hours
|
|
6194
|
+
* @returns A Date representing the UTC instant of that date+time in the given offset
|
|
6195
|
+
*/
|
|
6196
|
+
function combineDateTimeInOffset(date, hours, minutes, timezoneOffset) {
|
|
6197
|
+
const offsetStr = offsetHoursToString(timezoneOffset);
|
|
6198
|
+
const pdt = new Temporal.PlainDateTime(date.getFullYear(), date.getMonth() + 1, date.getDate(), hours, minutes);
|
|
6199
|
+
const zdt = pdt.toZonedDateTime(offsetStr);
|
|
6200
|
+
return new Date(zdt.epochMilliseconds);
|
|
6012
6201
|
}
|
|
6013
6202
|
|
|
6014
|
-
function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledDates, disabledMatcher, timeInterval = 15, minTime, maxTime, labelProps, alignProps, datePlaceholder = "dd.MM.yyyy", timePlaceholder = "HH:mm", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showNowButton = false, timezoneOffset, }) {
|
|
6203
|
+
function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledDates, disabledMatcher, timeInterval = 15, minTime, maxTime, labelProps, alignProps, datePlaceholder = "dd.MM.yyyy", timePlaceholder = "HH:mm", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showNowButton = false, nowLabel = "Now", locale = enGB, timezoneOffset, }) {
|
|
6015
6204
|
// ========================================
|
|
6016
6205
|
// PROPS NORMALIZATION
|
|
6017
6206
|
// ========================================
|
|
@@ -6084,16 +6273,14 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6084
6273
|
if (!date)
|
|
6085
6274
|
return undefined;
|
|
6086
6275
|
const [hours, minutes] = (time ?? "00:00").split(':').map(Number);
|
|
6087
|
-
let
|
|
6276
|
+
let combined;
|
|
6088
6277
|
if (timezoneOffset !== undefined) {
|
|
6089
|
-
//
|
|
6090
|
-
|
|
6091
|
-
m.utcOffset(timezoneOffset * 60, true);
|
|
6278
|
+
// Interpret the display date+time as belonging to the specified offset
|
|
6279
|
+
combined = combineDateTimeInOffset(date, hours, minutes, timezoneOffset);
|
|
6092
6280
|
}
|
|
6093
6281
|
else {
|
|
6094
|
-
|
|
6282
|
+
combined = new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, minutes, 0, 0);
|
|
6095
6283
|
}
|
|
6096
|
-
const combined = m.toDate();
|
|
6097
6284
|
// Validate against min/max datetime
|
|
6098
6285
|
if (normalizedMinDateTime && combined < normalizedMinDateTime)
|
|
6099
6286
|
return undefined;
|
|
@@ -6114,31 +6301,32 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6114
6301
|
const calculateTimeRestrictions = useCallback((selectedDate) => {
|
|
6115
6302
|
if (!selectedDate)
|
|
6116
6303
|
return { minTime, maxTime };
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6304
|
+
const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() &&
|
|
6305
|
+
a.getMonth() === b.getMonth() &&
|
|
6306
|
+
a.getDate() === b.getDate();
|
|
6307
|
+
const formatLocalTime = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
6120
6308
|
let calculatedMinTime = minTime;
|
|
6121
6309
|
let calculatedMaxTime = maxTime;
|
|
6122
6310
|
// If selected date matches minDateTime date, restrict minimum time
|
|
6123
6311
|
if (normalizedMinDateTime) {
|
|
6124
|
-
const
|
|
6125
|
-
?
|
|
6126
|
-
:
|
|
6127
|
-
if (
|
|
6312
|
+
const minDisplay = timezoneOffset !== undefined
|
|
6313
|
+
? getDateInOffset(normalizedMinDateTime, timezoneOffset)
|
|
6314
|
+
: normalizedMinDateTime;
|
|
6315
|
+
if (isSameDay(selectedDate, minDisplay)) {
|
|
6128
6316
|
calculatedMinTime = timezoneOffset !== undefined
|
|
6129
6317
|
? getTimeInOffset(normalizedMinDateTime, timezoneOffset)
|
|
6130
|
-
:
|
|
6318
|
+
: formatLocalTime(normalizedMinDateTime);
|
|
6131
6319
|
}
|
|
6132
6320
|
}
|
|
6133
6321
|
// If selected date matches maxDateTime date, restrict maximum time
|
|
6134
6322
|
if (normalizedMaxDateTime) {
|
|
6135
|
-
const
|
|
6136
|
-
?
|
|
6137
|
-
:
|
|
6138
|
-
if (
|
|
6323
|
+
const maxDisplay = timezoneOffset !== undefined
|
|
6324
|
+
? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6325
|
+
: normalizedMaxDateTime;
|
|
6326
|
+
if (isSameDay(selectedDate, maxDisplay)) {
|
|
6139
6327
|
calculatedMaxTime = timezoneOffset !== undefined
|
|
6140
6328
|
? getTimeInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6141
|
-
:
|
|
6329
|
+
: formatLocalTime(normalizedMaxDateTime);
|
|
6142
6330
|
}
|
|
6143
6331
|
}
|
|
6144
6332
|
return {
|
|
@@ -6252,12 +6440,12 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6252
6440
|
const displayMaxDate = useMemo(() => normalizedMaxDateTime && timezoneOffset !== undefined
|
|
6253
6441
|
? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6254
6442
|
: normalizedMaxDateTime, [normalizedMaxDateTime, timezoneOffset]);
|
|
6255
|
-
return jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition }), jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled,
|
|
6443
|
+
return jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale }), jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] })] }) });
|
|
6256
6444
|
}
|
|
6257
6445
|
|
|
6258
6446
|
var compactStyles = {"compactPopup":"cw-datetime-compact-module__compactPopup__GiuNY","calendarWrapper":"cw-datetime-compact-module__calendarWrapper__P4Nlq","timeWrapper":"cw-datetime-compact-module__timeWrapper__uMe-A","compactTimeList":"cw-datetime-compact-module__compactTimeList__MzSQT"};
|
|
6259
6447
|
|
|
6260
|
-
function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, disabledDates, disabledMatcher, timeInterval = 15, minTime, maxTime, labelProps, alignProps, placeholder = "dd.mm.yyyy HH:mm", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, }) {
|
|
6448
|
+
function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, disabledDates, disabledMatcher, timeInterval = 15, minTime, maxTime, labelProps, alignProps, placeholder = "dd.mm.yyyy HH:mm", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, nowLabel = "Now", timeLabel = "Time", locale = enGB, }) {
|
|
6261
6449
|
const [isOpen, setIsOpen] = useState(false);
|
|
6262
6450
|
const [inputValue, setInputValue] = useState("");
|
|
6263
6451
|
const [selectedDate, setSelectedDate] = useState(value);
|
|
@@ -6488,11 +6676,11 @@ function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, di
|
|
|
6488
6676
|
...(maxDateTime ? [{ after: maxDateTime }] : []),
|
|
6489
6677
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
6490
6678
|
], [disabledDates, minDateTime, maxDateTime, disabledMatcher]);
|
|
6491
|
-
return (jsx("div", { ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 16
|
|
6679
|
+
return (jsx("div", { ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 16 }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxs("div", { className: compactStyles.calendarWrapper, children: [jsx(DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, modifiers: {
|
|
6492
6680
|
today: new Date(),
|
|
6493
6681
|
}, modifiersClassNames: {
|
|
6494
6682
|
today: "rdp-day-today",
|
|
6495
|
-
} }), showTodayButton && (jsx("footer", { className: "cw-flex-row cw-align-center-center", children: jsx(CwButton, { type: "button", variant: "outline", icon: "check-big", onClick: handleNowClick, text:
|
|
6683
|
+
} }), showTodayButton && (jsx("footer", { className: "cw-flex-row cw-align-center-center", children: jsx(CwButton, { type: "button", variant: "outline", icon: "check-big", onClick: handleNowClick, text: nowLabel }) }))] }), jsxs("div", { className: compactStyles.timeWrapper, children: [jsxs("header", { children: [jsx(CwIcon, { iconId: "clock", size: "medium" }), jsx("span", { children: timeLabel })] }), jsx("div", { ref: timeListRef, className: `${timeStyles.timePickerList} ${compactStyles.compactTimeList}`, children: timeOptions.map((time) => {
|
|
6496
6684
|
const isSelected = time === selectedTime;
|
|
6497
6685
|
return (jsx("button", { type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
|
|
6498
6686
|
}) })] })] }))] })] }) }));
|
|
@@ -6829,7 +7017,10 @@ const SchedulerContentArea = ({ now, showTimeline, timeLineLeftPx, timeSeparator
|
|
|
6829
7017
|
if (reference) {
|
|
6830
7018
|
setContentArea(reference);
|
|
6831
7019
|
}
|
|
6832
|
-
}, children: [showTimeline && (jsx(TimeLine$1, { id: scheduler.props.id + "_timeline", marginLeft: timeLineLeftPx, zIndex: 8, toolTipTitle:
|
|
7020
|
+
}, children: [showTimeline && (jsx(TimeLine$1, { id: scheduler.props.id + "_timeline", marginLeft: timeLineLeftPx, zIndex: 8, toolTipTitle: Temporal.PlainTime.from({
|
|
7021
|
+
hour: now.getHours(),
|
|
7022
|
+
minute: now.getMinutes(),
|
|
7023
|
+
}).toString({ smallestUnit: "minute" }) })), timeSeparatorLeftPx.map((pixels) => {
|
|
6833
7024
|
return jsx(TimeLine$1, { marginLeft: pixels, color: "rgba(255,255,255,0.7)" });
|
|
6834
7025
|
}), jsx("span", { onClick: () => {
|
|
6835
7026
|
if (onEmptyClick) {
|
|
@@ -7043,6 +7234,11 @@ const DaysHeader = ({ days, divisionType, maxWidth, headerType }) => {
|
|
|
7043
7234
|
return jsx("tr", { className: "cwelltSchRowDate", children: headerToDraw });
|
|
7044
7235
|
};
|
|
7045
7236
|
|
|
7237
|
+
function formatHHmm(date) {
|
|
7238
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7239
|
+
const zdt = Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTimeISO(timeZone);
|
|
7240
|
+
return `${zdt.hour.toString().padStart(2, "0")}:${zdt.minute.toString().padStart(2, "0")}`;
|
|
7241
|
+
}
|
|
7046
7242
|
const getFormattedTimeForHeader = (calculatedDivType, calculatedDivision, timeHeader) => {
|
|
7047
7243
|
let showDate = "";
|
|
7048
7244
|
switch (calculatedDivType) {
|
|
@@ -7058,18 +7254,18 @@ const getFormattedTimeForHeader = (calculatedDivType, calculatedDivision, timeHe
|
|
|
7058
7254
|
timeHeader.getHours() === 15 ||
|
|
7059
7255
|
timeHeader.getHours() === 18 ||
|
|
7060
7256
|
timeHeader.getHours() === 21
|
|
7061
|
-
?
|
|
7257
|
+
? formatHHmm(timeHeader)
|
|
7062
7258
|
: "";
|
|
7063
7259
|
break;
|
|
7064
7260
|
case 3:
|
|
7065
7261
|
showDate =
|
|
7066
7262
|
timeHeader.getHours() === 0 || timeHeader.getHours() === 8 || timeHeader.getHours() === 16
|
|
7067
|
-
?
|
|
7263
|
+
? formatHHmm(timeHeader)
|
|
7068
7264
|
: "";
|
|
7069
7265
|
break;
|
|
7070
7266
|
case 2:
|
|
7071
7267
|
showDate =
|
|
7072
|
-
timeHeader.getHours() === 0 || timeHeader.getHours() === 12 ?
|
|
7268
|
+
timeHeader.getHours() === 0 || timeHeader.getHours() === 12 ? formatHHmm(timeHeader) : "";
|
|
7073
7269
|
break;
|
|
7074
7270
|
}
|
|
7075
7271
|
break;
|
|
@@ -7221,8 +7417,7 @@ const compareStrings = (str1, str2) => {
|
|
|
7221
7417
|
const filterResources = (module, resourceName, resources, groupByFunction, endDate, startDate, scheduleName) => {
|
|
7222
7418
|
if ((module === "CrewControl" || module === "CrewScheduling" || module === "CrewSchedulingVacations") &&
|
|
7223
7419
|
resourceName === "Employees") {
|
|
7224
|
-
resources = resources.filter(c => (c.data.Eintritt === null || (c.data.Eintritt
|
|
7225
|
-
(c.data.Austritt === null || (c.data.Austritt !== null && moment(c.data.Austritt).toDate() >= startDate)));
|
|
7420
|
+
resources = resources.filter(c => (c.data.Eintritt === null || (new Date(c.data.Eintritt) <= endDate)) && (c.data.Austritt === null || (new Date(c.data.Austritt) >= startDate)));
|
|
7226
7421
|
}
|
|
7227
7422
|
if (scheduleName === "crewPinnedScheduler" || (module === "CrewControl" || module === "CrewScheduling") && resourceName === "Employees") {
|
|
7228
7423
|
const sortKey = (groupByFunction || scheduleName === "crewPinnedScheduler") ? "mainFunction" : "C3_LC";
|
|
@@ -7416,8 +7611,8 @@ class CwScheduler extends Component {
|
|
|
7416
7611
|
arraysEqual = (a1, a2) => a1.length === a2.length && a1.every((o, idx) => this.objectsEqualDeep(o, a2[idx]));
|
|
7417
7612
|
componentWillReceiveProps(_nextProps) {
|
|
7418
7613
|
if (this.state.showConsoleLogs) {
|
|
7419
|
-
console.log("Schedule - componentWillReceiveProps, start: ",
|
|
7420
|
-
console.log("Schedule - componentWillReceiveProps - has changes, start: ",
|
|
7614
|
+
console.log("Schedule - componentWillReceiveProps, start: ", new Date());
|
|
7615
|
+
console.log("Schedule - componentWillReceiveProps - has changes, start: ", new Date());
|
|
7421
7616
|
}
|
|
7422
7617
|
const dateChange = _nextProps.startDate.toISOString() !== this.props.startDate.toISOString() ||
|
|
7423
7618
|
_nextProps.endDate.toISOString() !== this.props.endDate.toISOString();
|
|
@@ -7458,8 +7653,8 @@ class CwScheduler extends Component {
|
|
|
7458
7653
|
pinnedResources: this.props.pinnedResources ?? [],
|
|
7459
7654
|
});
|
|
7460
7655
|
if (this.state.showConsoleLogs) {
|
|
7461
|
-
console.log("Schedule - componentWillReceiveProps - print on schedule, end: ",
|
|
7462
|
-
console.log("Schedule - componentWillReceiveProps, end: ",
|
|
7656
|
+
console.log("Schedule - componentWillReceiveProps - print on schedule, end: ", new Date());
|
|
7657
|
+
console.log("Schedule - componentWillReceiveProps, end: ", new Date());
|
|
7463
7658
|
}
|
|
7464
7659
|
return;
|
|
7465
7660
|
}
|
|
@@ -7552,10 +7747,11 @@ class CwScheduler extends Component {
|
|
|
7552
7747
|
}
|
|
7553
7748
|
|
|
7554
7749
|
function dateFromPercentage(startDate, visibleDays, percentage) {
|
|
7555
|
-
const
|
|
7556
|
-
const
|
|
7557
|
-
const
|
|
7558
|
-
|
|
7750
|
+
const start = Temporal.Instant.fromEpochMilliseconds(startDate.getTime());
|
|
7751
|
+
const spanMs = Math.round(visibleDays) * 24 * 60 * 60 * 1000;
|
|
7752
|
+
const offsetMs = Math.round(spanMs * percentage);
|
|
7753
|
+
const result = start.add({ milliseconds: offsetMs });
|
|
7754
|
+
return new Date(result.epochMilliseconds);
|
|
7559
7755
|
}
|
|
7560
7756
|
|
|
7561
7757
|
function getPercentageFromMouseEvent(event) {
|
|
@@ -7726,20 +7922,27 @@ const TimeLine = ({ left, top = "0px", height, color, width = "2px", zIndexNumbe
|
|
|
7726
7922
|
}, className: styles$3["scheduler-timeline-label"], children: timeString })) }));
|
|
7727
7923
|
};
|
|
7728
7924
|
|
|
7925
|
+
function isToday(startDate, endDate) {
|
|
7926
|
+
if (!startDate)
|
|
7927
|
+
return false;
|
|
7928
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7929
|
+
const today = Temporal.Now.plainDateISO();
|
|
7930
|
+
const start = Temporal.Instant.fromEpochMilliseconds(startDate.getTime())
|
|
7931
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
7932
|
+
if (endDate) {
|
|
7933
|
+
const end = Temporal.Instant.fromEpochMilliseconds(endDate.getTime())
|
|
7934
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
7935
|
+
return Temporal.PlainDate.compare(today, start) >= 0
|
|
7936
|
+
&& Temporal.PlainDate.compare(today, end) <= 0;
|
|
7937
|
+
}
|
|
7938
|
+
return today.equals(start);
|
|
7939
|
+
}
|
|
7940
|
+
|
|
7729
7941
|
const SchedulerHeaderDivision = ({ topDivisions, bottomDivisions, classification, topWidth, startDate, endDate }) => {
|
|
7730
|
-
const isToday = () => {
|
|
7731
|
-
if (!startDate)
|
|
7732
|
-
return false;
|
|
7733
|
-
const today = moment();
|
|
7734
|
-
if (endDate) {
|
|
7735
|
-
return today.isBetween(startDate, endDate, 'day', '[]');
|
|
7736
|
-
}
|
|
7737
|
-
return today.isSame(startDate, 'day');
|
|
7738
|
-
};
|
|
7739
7942
|
return (jsxs("div", { style: {
|
|
7740
7943
|
width: topWidth,
|
|
7741
7944
|
cursor: "pointer"
|
|
7742
|
-
}, children: [jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday() ? styles$3["current-day"] : ""}`, children: jsx("span", { children: topDivisions }) }), jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsx("div", { className: styles$3["scheduler-hours"], children: jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
|
|
7945
|
+
}, children: [jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$3["current-day"] : ""}`, children: jsx("span", { children: topDivisions }) }), jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsx("div", { className: styles$3["scheduler-hours"], children: jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
|
|
7743
7946
|
};
|
|
7744
7947
|
|
|
7745
7948
|
const HeaderTitle = ({ title, dividerText, width }) => {
|
|
@@ -7763,12 +7966,23 @@ const SchedulerHeader = ({ content, divisions, visibleDays, selectedDate, width,
|
|
|
7763
7966
|
const thisTopWidth = visibleDays > 15
|
|
7764
7967
|
? topWidth * day.bottom.length
|
|
7765
7968
|
: topWidth;
|
|
7766
|
-
const
|
|
7767
|
-
|
|
7768
|
-
const endDate = day.endDate ? moment(day.endDate).toDate() : undefined;
|
|
7769
|
-
return (jsx(SchedulerHeaderDivision, { topDivisions: day.top, bottomDivisions: day.bottom, classification: classification, topWidth: thisTopWidth + "%", startDate: startDate, endDate: endDate }, day.top + classification));
|
|
7969
|
+
const { start, end } = getStartEnd(day);
|
|
7970
|
+
return (jsx(SchedulerHeaderDivision, { topDivisions: day.top, bottomDivisions: day.bottom, classification: classification, topWidth: thisTopWidth + "%", startDate: start, endDate: end }, day.top + classification));
|
|
7770
7971
|
}), !(timeLinePercentage < 0 || timeLinePercentage > 100) && (jsx(TimeLine, { color: "red", left: `${timeLinePercentage}%`, top: "50%", height: "50%", isHeader: true, isUtc: isUtc }))] })] }));
|
|
7771
7972
|
};
|
|
7973
|
+
function getStartEnd(day) {
|
|
7974
|
+
const startDate = day.startDate
|
|
7975
|
+
? new Date(day.startDate)
|
|
7976
|
+
: (() => {
|
|
7977
|
+
const [dd, mm, yyyy] = day.top.split(".");
|
|
7978
|
+
return new Date(Number(yyyy), Number(mm) - 1, Number(dd));
|
|
7979
|
+
})();
|
|
7980
|
+
const endDate = day.endDate ? new Date(day.endDate) : undefined;
|
|
7981
|
+
return {
|
|
7982
|
+
start: startDate,
|
|
7983
|
+
end: endDate
|
|
7984
|
+
};
|
|
7985
|
+
}
|
|
7772
7986
|
|
|
7773
7987
|
var styles$2 = {"hide-scrollbar":"new-scheduler-module__hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module__scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module__scheduler-event-container__-h1xm","time-marker":"new-scheduler-module__time-marker__2BejU","scheduler-event-text":"new-scheduler-module__scheduler-event-text__zjvd7"};
|
|
7774
7988
|
|
|
@@ -8090,6 +8304,16 @@ const SchedulerRow = memo((props) => {
|
|
|
8090
8304
|
return true;
|
|
8091
8305
|
});
|
|
8092
8306
|
|
|
8307
|
+
const filterVisibleEvents = (events, selectedDate, visibleDays) => {
|
|
8308
|
+
const schedulerEnd = Temporal.PlainDate.from({
|
|
8309
|
+
year: selectedDate.getFullYear(),
|
|
8310
|
+
month: selectedDate.getMonth() + 1,
|
|
8311
|
+
day: selectedDate.getDate(),
|
|
8312
|
+
}).add({ days: visibleDays });
|
|
8313
|
+
const lastDayOfScheduler = new Date(schedulerEnd.year, schedulerEnd.month - 1, schedulerEnd.day);
|
|
8314
|
+
return events.filter((event) => event.endDate > selectedDate && event.startDate < lastDayOfScheduler);
|
|
8315
|
+
};
|
|
8316
|
+
|
|
8093
8317
|
const DIVISION_RULES = [
|
|
8094
8318
|
{ maxDays: 2, divisions: 24 },
|
|
8095
8319
|
{ maxDays: 3, divisions: 12 },
|
|
@@ -8104,17 +8328,52 @@ const calculateDivisionsByDays = (days) => {
|
|
|
8104
8328
|
};
|
|
8105
8329
|
const getHoursFromDivisions = (divisions, useCompactHourFormat = false) => {
|
|
8106
8330
|
const hoursInterval = 24 / divisions;
|
|
8107
|
-
const hourFormat = useCompactHourFormat ? "HH[h]" : "HH:mm";
|
|
8108
8331
|
const array = [];
|
|
8109
8332
|
for (let i = 0; i < divisions; i++) {
|
|
8110
|
-
const
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8333
|
+
const totalMinutes = Math.round(hoursInterval * i * 60);
|
|
8334
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
8335
|
+
const minutes = totalMinutes % 60;
|
|
8336
|
+
const hh = hours.toString().padStart(2, "0");
|
|
8337
|
+
const mm = minutes.toString().padStart(2, "0");
|
|
8338
|
+
array.push(useCompactHourFormat ? `${hh}h` : `${hh}:${mm}`);
|
|
8114
8339
|
}
|
|
8115
8340
|
return array;
|
|
8116
8341
|
};
|
|
8117
8342
|
|
|
8343
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
8344
|
+
function toPlainDate(date) {
|
|
8345
|
+
return Temporal.Instant.fromEpochMilliseconds(date.getTime())
|
|
8346
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
8347
|
+
}
|
|
8348
|
+
function addDays(date, days) {
|
|
8349
|
+
const result = new Date(date);
|
|
8350
|
+
result.setDate(result.getDate() + days);
|
|
8351
|
+
return result;
|
|
8352
|
+
}
|
|
8353
|
+
function formatDD_MM(date) {
|
|
8354
|
+
const pd = toPlainDate(date);
|
|
8355
|
+
return `${pd.day.toString().padStart(2, "0")}.${pd.month.toString().padStart(2, "0")}`;
|
|
8356
|
+
}
|
|
8357
|
+
function formatDD_MM_YYYY(date) {
|
|
8358
|
+
const pd = toPlainDate(date);
|
|
8359
|
+
return `${pd.day.toString().padStart(2, "0")}.${pd.month.toString().padStart(2, "0")}.${pd.year}`;
|
|
8360
|
+
}
|
|
8361
|
+
function formatMM_YYYY(date) {
|
|
8362
|
+
const pd = toPlainDate(date);
|
|
8363
|
+
return `${pd.month.toString().padStart(2, "0")}.${pd.year}`;
|
|
8364
|
+
}
|
|
8365
|
+
function getShortWeekday(date) {
|
|
8366
|
+
return date.toLocaleDateString("en-US", { weekday: "short" });
|
|
8367
|
+
}
|
|
8368
|
+
function daysBetween(a, b) {
|
|
8369
|
+
const aPlain = toPlainDate(a);
|
|
8370
|
+
const bPlain = toPlainDate(b);
|
|
8371
|
+
return Math.abs(aPlain.until(bPlain).days);
|
|
8372
|
+
}
|
|
8373
|
+
function daysInMonth(date) {
|
|
8374
|
+
const pd = toPlainDate(date);
|
|
8375
|
+
return pd.daysInMonth;
|
|
8376
|
+
}
|
|
8118
8377
|
const getDefaultDivisions = (visibleDays, selectedDate) => {
|
|
8119
8378
|
if (visibleDays <= 15) {
|
|
8120
8379
|
return getDayDivisions(visibleDays, selectedDate);
|
|
@@ -8130,16 +8389,16 @@ const getDayDivisions = (visibleDays, selectedDate) => {
|
|
|
8130
8389
|
const divisions = getHoursFromDivisions(divisionsNumber, visibleDays < 3);
|
|
8131
8390
|
const calculatedDivision = [];
|
|
8132
8391
|
for (let i = 0; i < visibleDays; i++) {
|
|
8133
|
-
const currentDate =
|
|
8134
|
-
const weekdayShort = currentDate
|
|
8392
|
+
const currentDate = addDays(selectedDate, i);
|
|
8393
|
+
const weekdayShort = getShortWeekday(currentDate);
|
|
8135
8394
|
const weekdayLabel = visibleDays < 8
|
|
8136
8395
|
? weekdayShort
|
|
8137
8396
|
: weekdayShort.charAt(0).toUpperCase();
|
|
8138
8397
|
calculatedDivision.push({
|
|
8139
|
-
top: `${weekdayLabel} ${currentDate
|
|
8398
|
+
top: `${weekdayLabel} ${formatDD_MM(currentDate)}`,
|
|
8140
8399
|
bottom: divisions,
|
|
8141
|
-
startDate: currentDate
|
|
8142
|
-
endDate: currentDate
|
|
8400
|
+
startDate: currentDate,
|
|
8401
|
+
endDate: currentDate
|
|
8143
8402
|
});
|
|
8144
8403
|
}
|
|
8145
8404
|
return calculatedDivision;
|
|
@@ -8147,16 +8406,16 @@ const getDayDivisions = (visibleDays, selectedDate) => {
|
|
|
8147
8406
|
const getWeekDivisions = (visibleDays, selectedDate) => {
|
|
8148
8407
|
const weeks = getWeeksByDays(visibleDays, selectedDate);
|
|
8149
8408
|
const divisions = weeks.map((week) => {
|
|
8150
|
-
const days = Array.from({ length: week.days }, (_, i) =>
|
|
8151
|
-
const weekEnd =
|
|
8409
|
+
const days = Array.from({ length: week.days }, (_, i) => addDays(week.start, i).getDate().toString());
|
|
8410
|
+
const weekEnd = addDays(week.start, week.days - 1);
|
|
8152
8411
|
const top = days.length > 2
|
|
8153
|
-
?
|
|
8154
|
-
:
|
|
8412
|
+
? formatDD_MM_YYYY(week.start) + " - " + formatDD_MM_YYYY(weekEnd)
|
|
8413
|
+
: formatDD_MM_YYYY(week.start);
|
|
8155
8414
|
const division = {
|
|
8156
8415
|
top: top,
|
|
8157
8416
|
bottom: days,
|
|
8158
|
-
startDate:
|
|
8159
|
-
endDate: weekEnd
|
|
8417
|
+
startDate: new Date(week.start),
|
|
8418
|
+
endDate: weekEnd
|
|
8160
8419
|
};
|
|
8161
8420
|
return division;
|
|
8162
8421
|
});
|
|
@@ -8165,13 +8424,13 @@ const getWeekDivisions = (visibleDays, selectedDate) => {
|
|
|
8165
8424
|
const getMonthDivisions = (visibleDays, selectedDate) => {
|
|
8166
8425
|
const months = getMonthsByDays(visibleDays, selectedDate);
|
|
8167
8426
|
const divisions = months.map((month) => {
|
|
8168
|
-
const days = Array.from({ length: month.days }, (_, i) =>
|
|
8169
|
-
const monthEnd =
|
|
8427
|
+
const days = Array.from({ length: month.days }, (_, i) => addDays(month.start, i).getDate().toString());
|
|
8428
|
+
const monthEnd = addDays(month.start, month.days - 1);
|
|
8170
8429
|
const division = {
|
|
8171
|
-
top:
|
|
8430
|
+
top: formatMM_YYYY(month.start),
|
|
8172
8431
|
bottom: days,
|
|
8173
|
-
startDate:
|
|
8174
|
-
endDate: monthEnd
|
|
8432
|
+
startDate: new Date(month.start),
|
|
8433
|
+
endDate: monthEnd
|
|
8175
8434
|
};
|
|
8176
8435
|
return division;
|
|
8177
8436
|
});
|
|
@@ -8182,23 +8441,23 @@ const getMonthsByDays = (visibleDays, selectedDate) => {
|
|
|
8182
8441
|
return [];
|
|
8183
8442
|
}
|
|
8184
8443
|
const month = [];
|
|
8185
|
-
let
|
|
8444
|
+
let rangeStart = new Date(selectedDate);
|
|
8186
8445
|
for (let i = 0; i < visibleDays; i++) {
|
|
8187
|
-
const currentDay =
|
|
8446
|
+
const currentDay = addDays(selectedDate, i);
|
|
8188
8447
|
const isLastLoop = i + 1 === visibleDays;
|
|
8189
8448
|
if (isLastLoop) {
|
|
8190
8449
|
month.push({
|
|
8191
|
-
start:
|
|
8192
|
-
days:
|
|
8450
|
+
start: rangeStart,
|
|
8451
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8193
8452
|
});
|
|
8194
8453
|
break;
|
|
8195
8454
|
}
|
|
8196
|
-
if (currentDay.
|
|
8455
|
+
if (currentDay.getDate() === daysInMonth(currentDay)) {
|
|
8197
8456
|
month.push({
|
|
8198
|
-
start:
|
|
8199
|
-
days:
|
|
8457
|
+
start: rangeStart,
|
|
8458
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8200
8459
|
});
|
|
8201
|
-
|
|
8460
|
+
rangeStart = addDays(currentDay, 1);
|
|
8202
8461
|
}
|
|
8203
8462
|
}
|
|
8204
8463
|
return month;
|
|
@@ -8209,32 +8468,37 @@ const getWeeksByDays = (visibleDays, selectedDate) => {
|
|
|
8209
8468
|
return [];
|
|
8210
8469
|
}
|
|
8211
8470
|
const weeks = [];
|
|
8212
|
-
let
|
|
8471
|
+
let rangeStart = new Date(selectedDate);
|
|
8213
8472
|
for (let i = 0; i < visibleDays; i++) {
|
|
8214
|
-
const currentDay =
|
|
8473
|
+
const currentDay = addDays(selectedDate, i);
|
|
8215
8474
|
const isLastLoop = i + 1 === visibleDays;
|
|
8216
8475
|
if (isLastLoop) {
|
|
8217
8476
|
weeks.push({
|
|
8218
|
-
start:
|
|
8219
|
-
days:
|
|
8477
|
+
start: rangeStart,
|
|
8478
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8220
8479
|
});
|
|
8221
8480
|
break;
|
|
8222
8481
|
}
|
|
8223
|
-
if (currentDay.
|
|
8482
|
+
if (currentDay.getDay() === SUNDAY) {
|
|
8224
8483
|
weeks.push({
|
|
8225
|
-
start:
|
|
8226
|
-
days:
|
|
8484
|
+
start: rangeStart,
|
|
8485
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8227
8486
|
});
|
|
8228
|
-
|
|
8487
|
+
rangeStart = addDays(currentDay, 1);
|
|
8229
8488
|
}
|
|
8230
8489
|
}
|
|
8231
8490
|
return weeks;
|
|
8232
8491
|
};
|
|
8233
8492
|
|
|
8234
8493
|
const eventIsVisible = (startDate, endDate, selectedDate, visibleDays) => {
|
|
8235
|
-
const schedulerEnd =
|
|
8494
|
+
const schedulerEnd = Temporal.PlainDate.from({
|
|
8495
|
+
year: selectedDate.getFullYear(),
|
|
8496
|
+
month: selectedDate.getMonth() + 1,
|
|
8497
|
+
day: selectedDate.getDate(),
|
|
8498
|
+
}).add({ days: visibleDays });
|
|
8499
|
+
const schedulerEndDate = new Date(schedulerEnd.year, schedulerEnd.month - 1, schedulerEnd.day);
|
|
8236
8500
|
const isBefore = selectedDate > startDate && selectedDate > endDate;
|
|
8237
|
-
const isAfter =
|
|
8501
|
+
const isAfter = schedulerEndDate < startDate && schedulerEndDate < endDate;
|
|
8238
8502
|
return !isBefore && !isAfter;
|
|
8239
8503
|
};
|
|
8240
8504
|
|
|
@@ -8335,11 +8599,7 @@ const Scheduler = (props) => {
|
|
|
8335
8599
|
const instanceRef = useRef(null);
|
|
8336
8600
|
// const rowHeaderWidth = "180px";
|
|
8337
8601
|
const { selectedDate, visibleDays, isUtc, isHeaderVisible, visibleRows: stateVisibleRows } = props.state;
|
|
8338
|
-
const events = eventsState
|
|
8339
|
-
const lastDayOfScheduler = moment(selectedDate).add(visibleDays, "days");
|
|
8340
|
-
return (moment(event.endDate).isAfter(selectedDate) &&
|
|
8341
|
-
moment(event.startDate).isBefore(lastDayOfScheduler));
|
|
8342
|
-
});
|
|
8602
|
+
const events = filterVisibleEvents(eventsState, selectedDate, visibleDays);
|
|
8343
8603
|
useEffect(() => {
|
|
8344
8604
|
instanceRef.current?.resetAfterIndex(0);
|
|
8345
8605
|
}, [orderCategories, props.rows.length, events]);
|
|
@@ -9193,4 +9453,4 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
|
|
|
9193
9453
|
}, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected crewmember", variant: "icon", icon: "close", color: "neutral" })) : (jsx(CwIcon, { iconId: "person" })) })] })] }), showDropdown && options.length > 0 && (jsx("div", { ref: dropdownRef, className: "cw-input-search-dropdown", role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { className: index === highlightedIndex ? "highlighted" : "", onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
|
|
9194
9454
|
};
|
|
9195
9455
|
|
|
9196
|
-
export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDateRangePicker, CwDateTimePicker, CwDateTimePickerCompact, CwDialog, CwDialogManager, CwDigit, CwDisplayMessage, CwDropdownFilter, CwExpandable, CwFileUpload, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDate, CwInputDatePicker, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwLoadingSmall, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNote, CwOption, CwPopoverButton, CwReportModal, CwScheduler, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSortableList, CwSortableTable, CwSuperScheduler, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PinRowHeader, Resource, Scheduler, SchedulerEvent, SuperScheduler, UiEvent, Weekdays, cblEvent, eventIsVisible, getDefaultDivisions, getEventSizes, itemsToMultiFilterTags, useCwMessage, useSortableList, useSortableTable };
|
|
9456
|
+
export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDateRangePicker, CwDateTimePicker, CwDateTimePickerCompact, CwDialog, CwDialogManager, CwDigit, CwDisplayMessage, CwDropdownFilter, CwExpandable, CwFileUpload, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDate, CwInputDatePicker, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwLoadingSmall, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNote, CwOption, CwPopoverButton, CwReportModal, CwScheduler, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSortableList, CwSortableTable, CwSuperScheduler, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PinRowHeader, Resource, Scheduler, SchedulerEvent, SuperScheduler, UiEvent, Weekdays, cblEvent, eventIsVisible, filterVisibleEvents, getDefaultDivisions, getEventSizes, itemsToMultiFilterTags, useCwMessage, useSortableList, useSortableTable };
|