@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.cjs.js
CHANGED
|
@@ -5,12 +5,10 @@ var React = require('react');
|
|
|
5
5
|
var client = require('react-dom/client');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var Draggable = require('react-draggable');
|
|
8
|
-
var moment = require('moment');
|
|
9
8
|
var dateFns = require('date-fns');
|
|
10
9
|
var locale = require('date-fns/locale');
|
|
11
10
|
var reactDayPicker = require('react-day-picker');
|
|
12
11
|
require('react-day-picker/dist/style.css');
|
|
13
|
-
var moment$1 = require('moment-timezone');
|
|
14
12
|
var reactWindow = require('react-window');
|
|
15
13
|
|
|
16
14
|
function _interopNamespaceDefault(e) {
|
|
@@ -127,36 +125,60 @@ function getHSLColor(color, alpha = 1) {
|
|
|
127
125
|
const hsl = colorToHSL(color);
|
|
128
126
|
return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha})`;
|
|
129
127
|
}
|
|
128
|
+
function hslToLinearRgb(h, s, l) {
|
|
129
|
+
const sNorm = s / 100;
|
|
130
|
+
const lNorm = l / 100;
|
|
131
|
+
const a = sNorm * Math.min(lNorm, 1 - lNorm);
|
|
132
|
+
const f = (n) => {
|
|
133
|
+
const k = (n + h / 30) % 12;
|
|
134
|
+
return lNorm - a * Math.max(-1, Math.min(k - 3, Math.min(9 - k, 1)));
|
|
135
|
+
};
|
|
136
|
+
return [f(0), f(8), f(4)];
|
|
137
|
+
}
|
|
138
|
+
function srgbLuminance(r, g, b) {
|
|
139
|
+
const lin = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
140
|
+
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
141
|
+
}
|
|
142
|
+
function wcagContrastRatio(lum1, lum2) {
|
|
143
|
+
const lighter = Math.max(lum1, lum2);
|
|
144
|
+
const darker = Math.min(lum1, lum2);
|
|
145
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
146
|
+
}
|
|
130
147
|
function getContrastColor(color) {
|
|
131
|
-
if (color === null)
|
|
148
|
+
if (color === null)
|
|
132
149
|
return '#000000';
|
|
133
|
-
}
|
|
134
150
|
const hsl = colorToHSL(color);
|
|
135
|
-
// Saturated greenyellow and cyan tones need lower luminance threshold (40-35)
|
|
136
|
-
// Saturated mediumblue and blueviolet tones need higher luminance threshold (55-60)
|
|
137
|
-
// Saturated orangered tones need lower luminance threshold (45)
|
|
138
|
-
const isYellowGreen = (hsl.h >= 45 && hsl.h <= 180);
|
|
139
|
-
const isBlueViolet = (hsl.h >= 210 && hsl.h <= 300);
|
|
140
|
-
const isRedOrange = (hsl.h >= 0 && hsl.h <= 30) || (hsl.h >= 330 && hsl.h <= 360);
|
|
141
|
-
let threshold = 50;
|
|
142
|
-
if (isYellowGreen) {
|
|
143
|
-
threshold = 40;
|
|
144
|
-
if (hsl.s >= 70) {
|
|
145
|
-
threshold = 35;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
else if (isBlueViolet) {
|
|
149
|
-
threshold = 55;
|
|
150
|
-
if (hsl.s >= 70) {
|
|
151
|
-
threshold = 60;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
else if (isRedOrange && hsl.s >= 80) {
|
|
155
|
-
threshold = 45;
|
|
156
|
-
}
|
|
157
|
-
const contrastL = hsl.l >= threshold ? 20 : 90;
|
|
158
151
|
const contrastS = Math.min(hsl.s, 90);
|
|
159
|
-
|
|
152
|
+
const bgRgb = hslToLinearRgb(hsl.h, hsl.s, hsl.l);
|
|
153
|
+
const bgLum = srgbLuminance(...bgRgb);
|
|
154
|
+
const darkL = 15;
|
|
155
|
+
const lightL = 90;
|
|
156
|
+
const darkLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, darkL));
|
|
157
|
+
const lightLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, lightL));
|
|
158
|
+
const darkRatio = wcagContrastRatio(bgLum, darkLum);
|
|
159
|
+
const lightRatio = wcagContrastRatio(bgLum, lightLum);
|
|
160
|
+
// On saturated backgrounds, dark-tinted text blends visually with the
|
|
161
|
+
// vibrant color even when math says it has better contrast.
|
|
162
|
+
// Prefer light text unless dark has an overwhelmingly higher ratio.
|
|
163
|
+
const saturatedBias = hsl.s >= 30 && bgLum < 0.4;
|
|
164
|
+
// Mid-grays (#777–#999): dark text "sinks" into the background while
|
|
165
|
+
// white text pops, even though dark wins on WCAG ratio.
|
|
166
|
+
const midGrayBias = hsl.s < 15 && bgLum >= 0.18 && bgLum <= 0.35;
|
|
167
|
+
const goLight = saturatedBias
|
|
168
|
+
? darkRatio < lightRatio * 3
|
|
169
|
+
: midGrayBias || lightRatio >= darkRatio;
|
|
170
|
+
let targetL = goLight ? lightL : darkL;
|
|
171
|
+
let bestRatio = goLight ? lightRatio : darkRatio;
|
|
172
|
+
if (bestRatio < 4.5) {
|
|
173
|
+
const step = goLight ? 5 : -5;
|
|
174
|
+
const limit = goLight ? 95 : 0;
|
|
175
|
+
while (bestRatio < 4.5 && targetL !== limit) {
|
|
176
|
+
targetL = goLight ? Math.min(targetL + step, limit) : Math.max(targetL + step, limit);
|
|
177
|
+
const candidateLum = srgbLuminance(...hslToLinearRgb(hsl.h, contrastS, targetL));
|
|
178
|
+
bestRatio = wcagContrastRatio(bgLum, candidateLum);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
160
182
|
}
|
|
161
183
|
|
|
162
184
|
const SVG_ICONS = {
|
|
@@ -627,11 +649,7 @@ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPositio
|
|
|
627
649
|
* <CwLoading size="small" />
|
|
628
650
|
*/
|
|
629
651
|
function CwLoadingSmall(CwelltLoadingAppointements) {
|
|
630
|
-
return (jsxRuntime.jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (
|
|
631
|
-
// * Show loading appointment
|
|
632
|
-
jsxRuntime.jsx("div", { className: "cw-loading-container", children: jsxRuntime.jsx("div", { className: "cw-loading" }) })) : (
|
|
633
|
-
// Show empty div
|
|
634
|
-
jsxRuntime.jsx("div", {})) }));
|
|
652
|
+
return (jsxRuntime.jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (jsxRuntime.jsx("div", { className: "cw-loading-container", children: jsxRuntime.jsx("div", { className: "cw-loading" }) })) : (jsxRuntime.jsx("div", {})) }));
|
|
635
653
|
}
|
|
636
654
|
|
|
637
655
|
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"};
|
|
@@ -1113,11 +1131,7 @@ function CwModal(custModalProps) {
|
|
|
1113
1131
|
width: custModalProps.widthModal
|
|
1114
1132
|
}
|
|
1115
1133
|
};
|
|
1116
|
-
return (jsxRuntime.jsx("div", { children: custModalProps.modalState && (jsxRuntime.jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsxRuntime.jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsxRuntime.jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxRuntime.jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (
|
|
1117
|
-
// [ false : show modal ]
|
|
1118
|
-
jsxRuntime.jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (
|
|
1119
|
-
// true [ do not show the modal ]
|
|
1120
|
-
jsxRuntime.jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1134
|
+
return (jsxRuntime.jsx("div", { children: custModalProps.modalState && (jsxRuntime.jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsxRuntime.jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsxRuntime.jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxRuntime.jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsxRuntime.jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsxRuntime.jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1121
1135
|
}
|
|
1122
1136
|
|
|
1123
1137
|
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"};
|
|
@@ -1470,12 +1484,10 @@ const CwDialog = props => {
|
|
|
1470
1484
|
const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave })) })), [customFooter, onSave, disableSave]);
|
|
1471
1485
|
const resizeHandles = React.useMemo(() => size.autoHeight
|
|
1472
1486
|
? [
|
|
1473
|
-
// Only horizontal handles if autoHeight is true
|
|
1474
1487
|
jsxRuntime.jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
|
|
1475
1488
|
jsxRuntime.jsx("div", { "data-handle-w": true, onMouseDown: handleResizeMouseDown("w") }, "handle-w")
|
|
1476
1489
|
]
|
|
1477
1490
|
: [
|
|
1478
|
-
// All handles if autoHeight is false
|
|
1479
1491
|
jsxRuntime.jsx("div", { "data-handle-n": true, onMouseDown: handleResizeMouseDown("n") }, "handle-n"),
|
|
1480
1492
|
jsxRuntime.jsx("div", { "data-handle-s": true, onMouseDown: handleResizeMouseDown("s") }, "handle-s"),
|
|
1481
1493
|
jsxRuntime.jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
|
|
@@ -1876,7 +1888,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
|
|
|
1876
1888
|
*
|
|
1877
1889
|
* @returns React component
|
|
1878
1890
|
*/
|
|
1879
|
-
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 }) {
|
|
1891
|
+
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 }) {
|
|
1880
1892
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
1881
1893
|
const [expandedRowKey, setExpandedRowKey] = React.useState(null);
|
|
1882
1894
|
const [sortConfig, setSortConfig] = React.useState({
|
|
@@ -2061,16 +2073,16 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2061
2073
|
? "sortable"
|
|
2062
2074
|
: sortConfig.direction === "asc"
|
|
2063
2075
|
? "sortable-asc"
|
|
2064
|
-
: "sortable-desc" }))] }), jsxRuntime.jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderTableBody() })] }) }), pagination && data.length > pageSizeOptions[0] && (jsxRuntime.jsxs("footer", { className: "cw-table-pagination", children: [jsxRuntime.jsx("
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2076
|
+
: "sortable-desc" }))] }), jsxRuntime.jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderTableBody() })] }) }), pagination && data.length > pageSizeOptions[0] && (jsxRuntime.jsxs("footer", { className: "cw-table-pagination", children: [jsxRuntime.jsxs("div", { className: "cw-table-pagination-size", children: [jsxRuntime.jsx(CwIcon, { iconId: "list" }), jsxRuntime.jsx("select", { value: localItemsPerPage, onChange: handleItemsPerPageChange, children: pageSizeOptions.map(size => (jsxRuntime.jsx("option", { value: size, children: pageLabel ? `${size} / ${pageLabel}` : size }, size))) })] }), jsxRuntime.jsxs("div", { className: "cw-table-pagination-nav", children: [jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(1), disabled: currentPage === 1 || totalPages === 1, variant: "icon", icon: "chevron-left-double" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1 || totalPages === 1, variant: "icon", icon: "chevron-left" }), jsxRuntime.jsx("input", { type: "text", inputMode: "numeric", value: currentPage, onChange: (e) => {
|
|
2077
|
+
const value = parseInt(e.target.value, 10);
|
|
2078
|
+
if (!isNaN(value))
|
|
2079
|
+
handlePageChange(value);
|
|
2080
|
+
}, onBlur: (e) => {
|
|
2081
|
+
const value = parseInt(e.target.value, 10);
|
|
2082
|
+
if (isNaN(value) || value < 1 || value > totalPages) {
|
|
2083
|
+
handlePageChange(1);
|
|
2084
|
+
}
|
|
2085
|
+
}, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages === 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages === 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2074
2086
|
}
|
|
2075
2087
|
|
|
2076
2088
|
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"};
|
|
@@ -2827,10 +2839,26 @@ function CwFileUpload(fileUploadProps) {
|
|
|
2827
2839
|
|
|
2828
2840
|
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"};
|
|
2829
2841
|
|
|
2842
|
+
const DEFAULT_LABELS = {
|
|
2843
|
+
uploadDisabled: 'Upload disabled',
|
|
2844
|
+
clickToUpload: 'Click to upload or drag and drop',
|
|
2845
|
+
acceptedFiles: (accept) => `Accepted files: ${accept}`,
|
|
2846
|
+
singleFileOnly: '(Single file only)',
|
|
2847
|
+
allTypesAccepted: 'All file types accepted',
|
|
2848
|
+
changeFile: 'Change File',
|
|
2849
|
+
clearAll: 'Clear all',
|
|
2850
|
+
addMoreFiles: 'Add More Files',
|
|
2851
|
+
filesSelected: (count) => `${count} file${count !== 1 ? 's' : ''} selected`,
|
|
2852
|
+
fileTooLarge: (name, maxSize) => `File "${name}" is too large. Maximum size allowed is ${maxSize}MB.`,
|
|
2853
|
+
invalidFormat: (name, accepted) => `File "${name}" has an invalid format. Allowed formats: ${accepted}`,
|
|
2854
|
+
invalidMimeType: (name, types) => `File "${name}" has an invalid MIME type. Allowed types: ${types}`,
|
|
2855
|
+
alreadySelected: (name) => `File "${name}" is already selected.`,
|
|
2856
|
+
};
|
|
2830
2857
|
function CwFileUploadMultiple(fileUploadProps) {
|
|
2831
2858
|
const fileInputRef = React.useRef(null);
|
|
2832
2859
|
const [selectedFiles, setSelectedFiles] = React.useState([]);
|
|
2833
2860
|
const [existingFile, setExistingFile] = React.useState(fileUploadProps.initialFileName);
|
|
2861
|
+
const labels = { ...DEFAULT_LABELS, ...fileUploadProps.labels };
|
|
2834
2862
|
React.useEffect(() => {
|
|
2835
2863
|
setExistingFile(fileUploadProps.initialFileName);
|
|
2836
2864
|
}, [fileUploadProps.initialFileName]);
|
|
@@ -2844,7 +2872,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2844
2872
|
if (fileSizeInMB > fileUploadProps.maxFileSize) {
|
|
2845
2873
|
return {
|
|
2846
2874
|
isValid: false,
|
|
2847
|
-
error:
|
|
2875
|
+
error: labels.fileTooLarge(file.name, fileUploadProps.maxFileSize)
|
|
2848
2876
|
};
|
|
2849
2877
|
}
|
|
2850
2878
|
}
|
|
@@ -2861,7 +2889,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2861
2889
|
if (!isExtensionValid) {
|
|
2862
2890
|
return {
|
|
2863
2891
|
isValid: false,
|
|
2864
|
-
error:
|
|
2892
|
+
error: labels.invalidFormat(file.name, fileUploadProps.accept)
|
|
2865
2893
|
};
|
|
2866
2894
|
}
|
|
2867
2895
|
}
|
|
@@ -2871,7 +2899,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2871
2899
|
if (!isMimeTypeValid) {
|
|
2872
2900
|
return {
|
|
2873
2901
|
isValid: false,
|
|
2874
|
-
error:
|
|
2902
|
+
error: labels.invalidMimeType(file.name, fileUploadProps.allowedTypes.join(', '))
|
|
2875
2903
|
};
|
|
2876
2904
|
}
|
|
2877
2905
|
}
|
|
@@ -2885,7 +2913,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2885
2913
|
// Check if the file already exists (by name and size)
|
|
2886
2914
|
const isDuplicate = existingFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
|
|
2887
2915
|
if (isDuplicate) {
|
|
2888
|
-
errors.push(
|
|
2916
|
+
errors.push(labels.alreadySelected(file.name));
|
|
2889
2917
|
continue;
|
|
2890
2918
|
}
|
|
2891
2919
|
const validation = validateFile(file);
|
|
@@ -2976,12 +3004,12 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2976
3004
|
}
|
|
2977
3005
|
}
|
|
2978
3006
|
};
|
|
2979
|
-
return (jsxRuntime.jsxs("div", { className: `${styles$e.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: `${styles$e.uploadArea} ${fileUploadProps.disabled ? styles$e.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$e.uploadTitle}`, children: fileUploadProps.disabled ?
|
|
3007
|
+
return (jsxRuntime.jsxs("div", { className: `${styles$e.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: `${styles$e.uploadArea} ${fileUploadProps.disabled ? styles$e.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$e.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxRuntime.jsxs("p", { className: `${styles$e.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxRuntime.jsxs("div", { className: styles$e.filesContainer, children: [jsxRuntime.jsxs("div", { className: styles$e.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$e.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$e.fileExtension, children: getFileExtension(existingFile) })] }), jsxRuntime.jsx("div", { className: styles$e.fileInfo, children: jsxRuntime.jsx("p", { className: styles$e.fileName, children: existingFile }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
|
|
2980
3008
|
setExistingFile(undefined);
|
|
2981
3009
|
if (fileUploadProps.onSelect) {
|
|
2982
3010
|
fileUploadProps.onSelect(null);
|
|
2983
3011
|
}
|
|
2984
|
-
}, disabled: fileUploadProps.disabled, className: styles$e.smallButton })] }), jsxRuntime.jsx(CwButton, { text:
|
|
3012
|
+
}, disabled: fileUploadProps.disabled, className: styles$e.smallButton })] }), jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxRuntime.jsxs("div", { className: styles$e.filesContainer, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsxRuntime.jsx("small", { className: styles$e.filesCount, children: labels.filesSelected(selectedFiles.length) }), jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$e.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$e.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$e.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$e.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$e.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$e.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$e.smallButton })] }, index))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
|
|
2985
3013
|
}
|
|
2986
3014
|
|
|
2987
3015
|
function CwInput(CwInputProps) {
|
|
@@ -2995,9 +3023,7 @@ function CwInput(CwInputProps) {
|
|
|
2995
3023
|
? "cw-flex-column"
|
|
2996
3024
|
: "cw-flex-row ", children: [jsxRuntime.jsx("label", { className: CwInputProps.disabled === true
|
|
2997
3025
|
? CwInputProps.labelClassName + " " + "cw_label_text cw_label_text_disabled"
|
|
2998
|
-
: CwInputProps.labelClassName + " " + "cw_label_text", children: CwInputProps.labelName }), jsxRuntime.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 && (
|
|
2999
|
-
// if the component is disabled do not show clear button
|
|
3000
|
-
jsxRuntime.jsx("button", { className: "cw_button_clear cwellt_flex cwellt_justify_center cwellt_align_items_center", onClick: handleClearClick }))] }));
|
|
3026
|
+
: CwInputProps.labelClassName + " " + "cw_label_text", children: CwInputProps.labelName }), jsxRuntime.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 && (jsxRuntime.jsx("button", { className: "cw_button_clear cwellt_flex cwellt_justify_center cwellt_align_items_center", onClick: handleClearClick }))] }));
|
|
3001
3027
|
}
|
|
3002
3028
|
|
|
3003
3029
|
/**
|
|
@@ -3473,6 +3499,114 @@ function CwInputDate(props) {
|
|
|
3473
3499
|
|
|
3474
3500
|
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"};
|
|
3475
3501
|
|
|
3502
|
+
/**
|
|
3503
|
+
* Converts a Date or ISO string to a Temporal.PlainDate.
|
|
3504
|
+
*/
|
|
3505
|
+
function toPlainDate$1(dateString) {
|
|
3506
|
+
if (dateString instanceof Date) {
|
|
3507
|
+
return Temporal.PlainDate.from({
|
|
3508
|
+
year: dateString.getFullYear(),
|
|
3509
|
+
month: dateString.getMonth() + 1,
|
|
3510
|
+
day: dateString.getDate(),
|
|
3511
|
+
});
|
|
3512
|
+
}
|
|
3513
|
+
// ISO "YYYY-MM-DD" → direct parse
|
|
3514
|
+
return Temporal.PlainDate.from(dateString);
|
|
3515
|
+
}
|
|
3516
|
+
/**
|
|
3517
|
+
* Formats a date as DD.MM.YYYY (German locale).
|
|
3518
|
+
*/
|
|
3519
|
+
function toGermanDate(dateString) {
|
|
3520
|
+
const pd = toPlainDate$1(dateString);
|
|
3521
|
+
const day = String(pd.day).padStart(2, "0");
|
|
3522
|
+
const month = String(pd.month).padStart(2, "0");
|
|
3523
|
+
return `${day}.${month}.${pd.year}`;
|
|
3524
|
+
}
|
|
3525
|
+
/**
|
|
3526
|
+
* Formats a date as YYYY-MM-DD (ISO).
|
|
3527
|
+
*/
|
|
3528
|
+
function toISODate(dateString) {
|
|
3529
|
+
return toPlainDate$1(dateString).toString();
|
|
3530
|
+
}
|
|
3531
|
+
/**
|
|
3532
|
+
* Validates whether a string is a valid DD.MM.YYYY date.
|
|
3533
|
+
*/
|
|
3534
|
+
function isValidGermanDate(textDate) {
|
|
3535
|
+
return parseGermanDate(textDate) !== null;
|
|
3536
|
+
}
|
|
3537
|
+
/**
|
|
3538
|
+
* Converts a DD.MM.YYYY string to YYYY-MM-DD, or null if invalid.
|
|
3539
|
+
*/
|
|
3540
|
+
function germanDateToISO(textDate) {
|
|
3541
|
+
const pd = parseGermanDate(textDate);
|
|
3542
|
+
return pd ? pd.toString() : null;
|
|
3543
|
+
}
|
|
3544
|
+
/**
|
|
3545
|
+
* Converts a DD.MM.YYYY string to a Date object, or null if invalid.
|
|
3546
|
+
*/
|
|
3547
|
+
function germanDateToDate(textDate) {
|
|
3548
|
+
const pd = parseGermanDate(textDate);
|
|
3549
|
+
if (!pd)
|
|
3550
|
+
return null;
|
|
3551
|
+
return new Date(pd.year, pd.month - 1, pd.day);
|
|
3552
|
+
}
|
|
3553
|
+
/**
|
|
3554
|
+
* Returns the number of days in the month and the Monday-based
|
|
3555
|
+
* weekday offset (0 = Monday) for the 1st of the month.
|
|
3556
|
+
*/
|
|
3557
|
+
function computeCalendarGrid(internalDate) {
|
|
3558
|
+
const pd = Temporal.PlainDate.from({
|
|
3559
|
+
year: internalDate.getFullYear(),
|
|
3560
|
+
month: internalDate.getMonth() + 1,
|
|
3561
|
+
day: 1,
|
|
3562
|
+
});
|
|
3563
|
+
const daysInMonth = pd.daysInMonth;
|
|
3564
|
+
const startDay = pd.dayOfWeek - 1; // Temporal: 1=Mon … 7=Sun → 0-based Mon
|
|
3565
|
+
return { daysInMonth, startDay };
|
|
3566
|
+
}
|
|
3567
|
+
/**
|
|
3568
|
+
* Returns true when the given day in the internalDate's month/year
|
|
3569
|
+
* matches the selected ISO value string.
|
|
3570
|
+
*/
|
|
3571
|
+
function isSelectedDay(internalDate, day, value) {
|
|
3572
|
+
const pd = Temporal.PlainDate.from({
|
|
3573
|
+
year: internalDate.getFullYear(),
|
|
3574
|
+
month: internalDate.getMonth() + 1,
|
|
3575
|
+
day,
|
|
3576
|
+
});
|
|
3577
|
+
return pd.toString() === value;
|
|
3578
|
+
}
|
|
3579
|
+
/**
|
|
3580
|
+
* Returns a new Date set to the 1st of the month offset by `direction` months.
|
|
3581
|
+
*/
|
|
3582
|
+
function computeNextMonthDate(currentDate, direction) {
|
|
3583
|
+
const pd = Temporal.PlainDate.from({
|
|
3584
|
+
year: currentDate.getFullYear(),
|
|
3585
|
+
month: currentDate.getMonth() + 1,
|
|
3586
|
+
day: 1,
|
|
3587
|
+
});
|
|
3588
|
+
const moved = pd.add({ months: direction });
|
|
3589
|
+
return new Date(moved.year, moved.month - 1, moved.day);
|
|
3590
|
+
}
|
|
3591
|
+
// ── internal helper ────────────────────────────────────────────────────
|
|
3592
|
+
/**
|
|
3593
|
+
* Strictly parses a DD.MM.YYYY string into a Temporal.PlainDate, or null.
|
|
3594
|
+
*/
|
|
3595
|
+
function parseGermanDate(text) {
|
|
3596
|
+
const match = /^(\d{2})\.(\d{2})\.(\d{4})$/.exec(text);
|
|
3597
|
+
if (!match)
|
|
3598
|
+
return null;
|
|
3599
|
+
const day = Number(match[1]);
|
|
3600
|
+
const month = Number(match[2]);
|
|
3601
|
+
const year = Number(match[3]);
|
|
3602
|
+
try {
|
|
3603
|
+
return Temporal.PlainDate.from({ year, month, day }, { overflow: "reject" });
|
|
3604
|
+
}
|
|
3605
|
+
catch {
|
|
3606
|
+
return null;
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
|
|
3476
3610
|
const CwInputDatePicker = ({ value, onChange }) => {
|
|
3477
3611
|
const [isCalendarOpen, setIsCalendarOpen] = React.useState(false);
|
|
3478
3612
|
const [internalDate, setInternalDate] = React.useState(new Date(value || new Date().toISOString()));
|
|
@@ -3496,21 +3630,13 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3496
3630
|
React.useEffect(() => {
|
|
3497
3631
|
setTextDate(toGermanDate(value));
|
|
3498
3632
|
}, [value]);
|
|
3499
|
-
function toGermanDate(dateString) {
|
|
3500
|
-
return moment(dateString).format("DD.MM.YYYY");
|
|
3501
|
-
}
|
|
3502
|
-
function toISODate(dateString) {
|
|
3503
|
-
return moment(dateString).format("YYYY-MM-DD");
|
|
3504
|
-
}
|
|
3505
3633
|
const submitInput = () => {
|
|
3506
|
-
if (
|
|
3507
|
-
const
|
|
3508
|
-
const
|
|
3509
|
-
if (
|
|
3510
|
-
const newDateString = momentDate.format("YYYY-MM-DD");
|
|
3634
|
+
if (isValidGermanDate(textDate)) {
|
|
3635
|
+
const newDateString = germanDateToISO(textDate);
|
|
3636
|
+
const newDate = germanDateToDate(textDate);
|
|
3637
|
+
if (newDateString && newDate) {
|
|
3511
3638
|
if (newDateString !== value) {
|
|
3512
|
-
|
|
3513
|
-
setInternalDate(momentDate.toDate());
|
|
3639
|
+
setInternalDate(newDate);
|
|
3514
3640
|
onChange?.(newDateString);
|
|
3515
3641
|
}
|
|
3516
3642
|
setIsCalendarOpen(false);
|
|
@@ -3547,7 +3673,7 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3547
3673
|
setIsCalendarOpen(false);
|
|
3548
3674
|
};
|
|
3549
3675
|
const handleClickMonthArrow = (direction) => {
|
|
3550
|
-
setInternalDate(prevDate =>
|
|
3676
|
+
setInternalDate(prevDate => computeNextMonthDate(prevDate, direction));
|
|
3551
3677
|
};
|
|
3552
3678
|
const handlePressEnter = (event) => {
|
|
3553
3679
|
if (event.key === "Enter" && submitInput()) {
|
|
@@ -3560,23 +3686,21 @@ const CwInputDatePicker = ({ value, onChange }) => {
|
|
|
3560
3686
|
}
|
|
3561
3687
|
};
|
|
3562
3688
|
const generateCalendarDays = () => {
|
|
3563
|
-
const daysInMonth
|
|
3564
|
-
const startDay = new Date(internalDate.getFullYear(), internalDate.getMonth(), 1).getDay() - 1;
|
|
3689
|
+
const { daysInMonth, startDay } = computeCalendarGrid(internalDate);
|
|
3565
3690
|
const calendarDays = new Array;
|
|
3566
3691
|
for (let i = 0; i < startDay; i++) {
|
|
3567
3692
|
calendarDays.push(jsxRuntime.jsx("div", { className: classes.emptyDay }, `empty-${i}`));
|
|
3568
3693
|
}
|
|
3569
3694
|
for (let day = 1; day <= daysInMonth; day++) {
|
|
3570
|
-
const
|
|
3571
|
-
|
|
3572
|
-
calendarDays.push(jsxRuntime.jsx("div", { className: `${classes.calendarDay}${isSelected ? ` ${classes.selected}` : ""}`, onClick: () => handleClickDay(day), children: day }, day));
|
|
3695
|
+
const selected = isSelectedDay(internalDate, day, value);
|
|
3696
|
+
calendarDays.push(jsxRuntime.jsx("div", { className: `${classes.calendarDay}${selected ? ` ${classes.selected}` : ""}`, onClick: () => handleClickDay(day), children: day }, day));
|
|
3573
3697
|
}
|
|
3574
3698
|
return calendarDays;
|
|
3575
3699
|
};
|
|
3576
3700
|
return (jsxRuntime.jsxs("div", { className: classes.datePicker, children: [jsxRuntime.jsx("input", { type: "text", value: textDate, onChange: e => setTextDate(e.currentTarget.value), onFocus: () => {
|
|
3577
3701
|
setInternalDate(new Date(value));
|
|
3578
3702
|
setIsCalendarOpen(true);
|
|
3579
|
-
}, onBlur: handleBlurInput, onKeyDown: handlePressEnter, "data-valid":
|
|
3703
|
+
}, onBlur: handleBlurInput, onKeyDown: handlePressEnter, "data-valid": isValidGermanDate(textDate), ref: inputRef, className: classes.input }), isCalendarOpen && (jsxRuntime.jsxs("div", { className: classes.calendar, ref: calendarRef, children: [jsxRuntime.jsxs("div", { className: classes.calendarHeader, children: [jsxRuntime.jsx("button", { className: classes.arrowButton, onClick: () => handleClickMonthArrow(-1), children: "<" }), jsxRuntime.jsxs("span", { className: classes.calendarTitle, children: [internalDate.toLocaleString("default", { month: "long" }), " ", internalDate.getFullYear()] }), jsxRuntime.jsx("button", { className: classes.arrowButton, onClick: () => handleClickMonthArrow(1), children: ">" })] }), jsxRuntime.jsx("div", { className: classes.calendarBody, children: generateCalendarDays() }), jsxRuntime.jsx("button", { className: classes.todayButton, onClick: handleClickToday, children: "Today" })] }))] }));
|
|
3580
3704
|
};
|
|
3581
3705
|
|
|
3582
3706
|
/**
|
|
@@ -3629,6 +3753,47 @@ function CwTime(props) {
|
|
|
3629
3753
|
return (jsxRuntime.jsx("div", { className: "cw-input-date", children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsx("input", { type: "time", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
|
|
3630
3754
|
}
|
|
3631
3755
|
|
|
3756
|
+
function parseDateParts(dateStr, format) {
|
|
3757
|
+
const parts = dateStr.split(/[.\-\/]/);
|
|
3758
|
+
if (parts.length !== 3)
|
|
3759
|
+
return null;
|
|
3760
|
+
let year, month, day;
|
|
3761
|
+
switch (format) {
|
|
3762
|
+
case "DD.MM.YYYY":
|
|
3763
|
+
case "DD/MM/YYYY":
|
|
3764
|
+
day = Number(parts[0]);
|
|
3765
|
+
month = Number(parts[1]);
|
|
3766
|
+
year = Number(parts[2]);
|
|
3767
|
+
break;
|
|
3768
|
+
case "MM/DD/YYYY":
|
|
3769
|
+
month = Number(parts[0]);
|
|
3770
|
+
day = Number(parts[1]);
|
|
3771
|
+
year = Number(parts[2]);
|
|
3772
|
+
break;
|
|
3773
|
+
case "YYYY-MM-DD":
|
|
3774
|
+
year = Number(parts[0]);
|
|
3775
|
+
month = Number(parts[1]);
|
|
3776
|
+
day = Number(parts[2]);
|
|
3777
|
+
break;
|
|
3778
|
+
}
|
|
3779
|
+
try {
|
|
3780
|
+
return Temporal.PlainDate.from({ year, month, day });
|
|
3781
|
+
}
|
|
3782
|
+
catch {
|
|
3783
|
+
return null;
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
function formatPlainDate(pd, format) {
|
|
3787
|
+
const dd = pd.day.toString().padStart(2, "0");
|
|
3788
|
+
const mm = pd.month.toString().padStart(2, "0");
|
|
3789
|
+
const yyyy = pd.year.toString().padStart(4, "0");
|
|
3790
|
+
switch (format) {
|
|
3791
|
+
case "DD.MM.YYYY": return `${dd}.${mm}.${yyyy}`;
|
|
3792
|
+
case "DD/MM/YYYY": return `${dd}/${mm}/${yyyy}`;
|
|
3793
|
+
case "MM/DD/YYYY": return `${mm}/${dd}/${yyyy}`;
|
|
3794
|
+
case "YYYY-MM-DD": return `${yyyy}-${mm}-${dd}`;
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3632
3797
|
/**
|
|
3633
3798
|
* Input for entering a string of text as a date
|
|
3634
3799
|
* @remarks
|
|
@@ -3658,11 +3823,8 @@ function CwInputDateText(props) {
|
|
|
3658
3823
|
const format = dateFormat ?? displayFormat;
|
|
3659
3824
|
const width = size ?? 12;
|
|
3660
3825
|
const formattedDate = (date, inFormat, outFormat) => {
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
}
|
|
3664
|
-
else
|
|
3665
|
-
return "";
|
|
3826
|
+
const pd = parseDateParts(date, inFormat);
|
|
3827
|
+
return pd ? formatPlainDate(pd, outFormat) : "";
|
|
3666
3828
|
};
|
|
3667
3829
|
const [date, setDate] = React.useState("");
|
|
3668
3830
|
const [displayedDate, setDisplayedDate] = React.useState("");
|
|
@@ -3681,8 +3843,9 @@ function CwInputDateText(props) {
|
|
|
3681
3843
|
const onChangeInputText = (e) => {
|
|
3682
3844
|
const newDate = e.target.value;
|
|
3683
3845
|
setDisplayedDate(newDate);
|
|
3684
|
-
|
|
3685
|
-
|
|
3846
|
+
const pd = parseDateParts(newDate, format);
|
|
3847
|
+
if (pd) {
|
|
3848
|
+
setDate(formatPlainDate(pd, internalFormat));
|
|
3686
3849
|
}
|
|
3687
3850
|
else {
|
|
3688
3851
|
setDate("");
|
|
@@ -3691,8 +3854,9 @@ function CwInputDateText(props) {
|
|
|
3691
3854
|
const onChangeInputDate = (e) => {
|
|
3692
3855
|
const newDate = e.target.value;
|
|
3693
3856
|
setDate(newDate);
|
|
3694
|
-
|
|
3695
|
-
|
|
3857
|
+
const pd = parseDateParts(newDate, internalFormat);
|
|
3858
|
+
if (pd)
|
|
3859
|
+
setDisplayedDate(formatPlainDate(pd, format));
|
|
3696
3860
|
else
|
|
3697
3861
|
setDisplayedDate("");
|
|
3698
3862
|
};
|
|
@@ -4205,7 +4369,7 @@ const CwMultiFilterTag = props => {
|
|
|
4205
4369
|
} : undefined }) }));
|
|
4206
4370
|
};
|
|
4207
4371
|
|
|
4208
|
-
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"};
|
|
4372
|
+
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"};
|
|
4209
4373
|
|
|
4210
4374
|
/**
|
|
4211
4375
|
* A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
|
|
@@ -4346,7 +4510,7 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-
|
|
|
4346
4510
|
* @param {CwMultiFilterProps} props
|
|
4347
4511
|
* @returns Set the `onChange` callback to a function to check for changes in the selected filters
|
|
4348
4512
|
*/
|
|
4349
|
-
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style }) => {
|
|
4513
|
+
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style }) => {
|
|
4350
4514
|
const [filteredTags, setFilteredTags] = React.useState(new Set());
|
|
4351
4515
|
const [inputTextValue, setInputTextValue] = React.useState("");
|
|
4352
4516
|
const [isPanelOpen, setIsPanelOpen] = React.useState(false);
|
|
@@ -4448,9 +4612,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
|
|
|
4448
4612
|
inputRef.current?.focus();
|
|
4449
4613
|
}
|
|
4450
4614
|
};
|
|
4451
|
-
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: styles$7["cw-multi-filter"]
|
|
4615
|
+
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: `${styles$7["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
4452
4616
|
e.preventDefault();
|
|
4453
|
-
}, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, className: styles$7["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.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:
|
|
4617
|
+
}, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, className: styles$7["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.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 => {
|
|
4454
4618
|
switch (e.key) {
|
|
4455
4619
|
case "Enter":
|
|
4456
4620
|
case "Tab": {
|
|
@@ -4480,15 +4644,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
|
|
|
4480
4644
|
} })] }), selectedTags.size > 0 ? (jsxRuntime.jsx("input", { type: "reset", value: "\u00D7", onClick: e => {
|
|
4481
4645
|
e.preventDefault();
|
|
4482
4646
|
onChangeSelectedTags(new Set());
|
|
4483
|
-
} })) : null] }), jsxRuntime.jsxs("section", { className: styles$7["cw-multi-filter-catalog-container"], "data-display-none": !isPanelOpen, children: [jsxRuntime.jsxs("nav", { children: [jsxRuntime.jsx("button", {
|
|
4484
|
-
? {
|
|
4485
|
-
backgroundColor: "var(--cw-color-primary-container)",
|
|
4486
|
-
color: "var(--cw-color-primary)",
|
|
4487
|
-
outline: "2px solid var(--cw-color-primary)",
|
|
4488
|
-
outlineOffset: "-2px",
|
|
4489
|
-
fontWeight: 400
|
|
4490
|
-
}
|
|
4491
|
-
: {}, onClick: () => handleClickCategory("All"), children: "SEARCH IN ALL CATEGORIES" }), Array.from(categoriesMappedToTags().keys()).map(category => (jsxRuntime.jsx("button", { style: selectedCategory === category
|
|
4647
|
+
} })) : null] }), jsxRuntime.jsxs("section", { className: styles$7["cw-multi-filter-catalog-container"], "data-display-none": !isPanelOpen, children: [jsxRuntime.jsxs("nav", { children: [jsxRuntime.jsx("button", { className: selectedCategory === "All" ? styles$7["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsxRuntime.jsx("button", { style: selectedCategory === category
|
|
4492
4648
|
? {
|
|
4493
4649
|
backgroundColor: getColor(category).primary,
|
|
4494
4650
|
color: getColor(category).onPrimary,
|
|
@@ -5038,10 +5194,13 @@ function usePickerPopup({ anchorRef, isOpen, onClose, position = "left-bottom" }
|
|
|
5038
5194
|
return { popupRef, popupStyle: style, renderPopup };
|
|
5039
5195
|
}
|
|
5040
5196
|
|
|
5041
|
-
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, }) {
|
|
5197
|
+
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: locale$1 = locale.enGB, todayLabel = "Today", feedback, }) {
|
|
5042
5198
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
5043
5199
|
const [inputValue, setInputValue] = React.useState("");
|
|
5044
5200
|
const containerRef = React.useRef(null);
|
|
5201
|
+
const feedbackMessages = feedback
|
|
5202
|
+
? Array.isArray(feedback) ? feedback : [feedback]
|
|
5203
|
+
: [];
|
|
5045
5204
|
const wrapperRef = React.useRef(null);
|
|
5046
5205
|
const inputRef = React.useRef(null);
|
|
5047
5206
|
const prevValueRef = React.useRef(undefined);
|
|
@@ -5209,11 +5368,11 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
5209
5368
|
...(maxDate ? [{ after: maxDate }] : []),
|
|
5210
5369
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
5211
5370
|
], [disabledDates, minDate, maxDate, disabledMatcher]);
|
|
5212
|
-
return (jsxRuntime.
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5371
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, modifiers: {
|
|
5372
|
+
today: new Date(),
|
|
5373
|
+
}, modifiersClassNames: {
|
|
5374
|
+
today: "rdp-day-today",
|
|
5375
|
+
} }), showTodayButton && (jsxRuntime.jsx("footer", { className: "cw-flex-row cw-align-right-center", children: jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleTodayClick, text: todayLabel }) }))] }))] })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
5217
5376
|
}
|
|
5218
5377
|
|
|
5219
5378
|
var rangeStyles = {"rangeWrapper":"cw-range-picker-module__rangeWrapper__1nIVs","rangePopup":"cw-range-picker-module__rangePopup__E5jd1","presetList":"cw-range-picker-module__presetList__INiLo"};
|
|
@@ -6004,6 +6163,17 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
6004
6163
|
}) }) }))] })] }) }));
|
|
6005
6164
|
}
|
|
6006
6165
|
|
|
6166
|
+
/**
|
|
6167
|
+
* Converts a numeric offset in hours (e.g. 0, 1, -5, 5.5) to a
|
|
6168
|
+
* Temporal-compatible offset string like "+00:00", "+01:00", "-05:00", "+05:30".
|
|
6169
|
+
*/
|
|
6170
|
+
function offsetHoursToString(offset) {
|
|
6171
|
+
const sign = offset >= 0 ? "+" : "-";
|
|
6172
|
+
const abs = Math.abs(offset);
|
|
6173
|
+
const hours = Math.floor(abs);
|
|
6174
|
+
const minutes = Math.round((abs - hours) * 60);
|
|
6175
|
+
return `${sign}${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
|
|
6176
|
+
}
|
|
6007
6177
|
/**
|
|
6008
6178
|
* Converts a Date to a new Date whose local year/month/day
|
|
6009
6179
|
* reflect the date in the given UTC offset.
|
|
@@ -6017,8 +6187,9 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
6017
6187
|
* @returns A new Date with local fields matching the target timezone's date
|
|
6018
6188
|
*/
|
|
6019
6189
|
function getDateInOffset(date, timezoneOffset) {
|
|
6020
|
-
const
|
|
6021
|
-
|
|
6190
|
+
const instant = Temporal.Instant.fromEpochMilliseconds(date.getTime());
|
|
6191
|
+
const zdt = instant.toZonedDateTimeISO(offsetHoursToString(timezoneOffset));
|
|
6192
|
+
return new Date(zdt.year, zdt.month - 1, zdt.day);
|
|
6022
6193
|
}
|
|
6023
6194
|
/**
|
|
6024
6195
|
* Gets the time string (HH:mm) for a Date in the given UTC offset.
|
|
@@ -6028,10 +6199,28 @@ function getDateInOffset(date, timezoneOffset) {
|
|
|
6028
6199
|
* @returns Time string in "HH:mm" format for the given offset
|
|
6029
6200
|
*/
|
|
6030
6201
|
function getTimeInOffset(date, timezoneOffset) {
|
|
6031
|
-
|
|
6202
|
+
const instant = Temporal.Instant.fromEpochMilliseconds(date.getTime());
|
|
6203
|
+
const zdt = instant.toZonedDateTimeISO(offsetHoursToString(timezoneOffset));
|
|
6204
|
+
return `${String(zdt.hour).padStart(2, "0")}:${String(zdt.minute).padStart(2, "0")}`;
|
|
6205
|
+
}
|
|
6206
|
+
/**
|
|
6207
|
+
* Combines a display date (local fields) and time components into a real Date
|
|
6208
|
+
* by interpreting them in the given UTC offset.
|
|
6209
|
+
*
|
|
6210
|
+
* @param date - Date whose local year/month/day are the "display" values
|
|
6211
|
+
* @param hours - Hour component (0-23)
|
|
6212
|
+
* @param minutes - Minute component (0-59)
|
|
6213
|
+
* @param timezoneOffset - Numeric offset in hours
|
|
6214
|
+
* @returns A Date representing the UTC instant of that date+time in the given offset
|
|
6215
|
+
*/
|
|
6216
|
+
function combineDateTimeInOffset(date, hours, minutes, timezoneOffset) {
|
|
6217
|
+
const offsetStr = offsetHoursToString(timezoneOffset);
|
|
6218
|
+
const pdt = new Temporal.PlainDateTime(date.getFullYear(), date.getMonth() + 1, date.getDate(), hours, minutes);
|
|
6219
|
+
const zdt = pdt.toZonedDateTime(offsetStr);
|
|
6220
|
+
return new Date(zdt.epochMilliseconds);
|
|
6032
6221
|
}
|
|
6033
6222
|
|
|
6034
|
-
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, }) {
|
|
6223
|
+
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: locale$1 = locale.enGB, timezoneOffset, }) {
|
|
6035
6224
|
// ========================================
|
|
6036
6225
|
// PROPS NORMALIZATION
|
|
6037
6226
|
// ========================================
|
|
@@ -6104,16 +6293,14 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6104
6293
|
if (!date)
|
|
6105
6294
|
return undefined;
|
|
6106
6295
|
const [hours, minutes] = (time ?? "00:00").split(':').map(Number);
|
|
6107
|
-
let
|
|
6296
|
+
let combined;
|
|
6108
6297
|
if (timezoneOffset !== undefined) {
|
|
6109
|
-
//
|
|
6110
|
-
|
|
6111
|
-
m.utcOffset(timezoneOffset * 60, true);
|
|
6298
|
+
// Interpret the display date+time as belonging to the specified offset
|
|
6299
|
+
combined = combineDateTimeInOffset(date, hours, minutes, timezoneOffset);
|
|
6112
6300
|
}
|
|
6113
6301
|
else {
|
|
6114
|
-
|
|
6302
|
+
combined = new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, minutes, 0, 0);
|
|
6115
6303
|
}
|
|
6116
|
-
const combined = m.toDate();
|
|
6117
6304
|
// Validate against min/max datetime
|
|
6118
6305
|
if (normalizedMinDateTime && combined < normalizedMinDateTime)
|
|
6119
6306
|
return undefined;
|
|
@@ -6134,31 +6321,32 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6134
6321
|
const calculateTimeRestrictions = React.useCallback((selectedDate) => {
|
|
6135
6322
|
if (!selectedDate)
|
|
6136
6323
|
return { minTime, maxTime };
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6324
|
+
const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() &&
|
|
6325
|
+
a.getMonth() === b.getMonth() &&
|
|
6326
|
+
a.getDate() === b.getDate();
|
|
6327
|
+
const formatLocalTime = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
6140
6328
|
let calculatedMinTime = minTime;
|
|
6141
6329
|
let calculatedMaxTime = maxTime;
|
|
6142
6330
|
// If selected date matches minDateTime date, restrict minimum time
|
|
6143
6331
|
if (normalizedMinDateTime) {
|
|
6144
|
-
const
|
|
6145
|
-
?
|
|
6146
|
-
:
|
|
6147
|
-
if (
|
|
6332
|
+
const minDisplay = timezoneOffset !== undefined
|
|
6333
|
+
? getDateInOffset(normalizedMinDateTime, timezoneOffset)
|
|
6334
|
+
: normalizedMinDateTime;
|
|
6335
|
+
if (isSameDay(selectedDate, minDisplay)) {
|
|
6148
6336
|
calculatedMinTime = timezoneOffset !== undefined
|
|
6149
6337
|
? getTimeInOffset(normalizedMinDateTime, timezoneOffset)
|
|
6150
|
-
:
|
|
6338
|
+
: formatLocalTime(normalizedMinDateTime);
|
|
6151
6339
|
}
|
|
6152
6340
|
}
|
|
6153
6341
|
// If selected date matches maxDateTime date, restrict maximum time
|
|
6154
6342
|
if (normalizedMaxDateTime) {
|
|
6155
|
-
const
|
|
6156
|
-
?
|
|
6157
|
-
:
|
|
6158
|
-
if (
|
|
6343
|
+
const maxDisplay = timezoneOffset !== undefined
|
|
6344
|
+
? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6345
|
+
: normalizedMaxDateTime;
|
|
6346
|
+
if (isSameDay(selectedDate, maxDisplay)) {
|
|
6159
6347
|
calculatedMaxTime = timezoneOffset !== undefined
|
|
6160
6348
|
? getTimeInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6161
|
-
:
|
|
6349
|
+
: formatLocalTime(normalizedMaxDateTime);
|
|
6162
6350
|
}
|
|
6163
6351
|
}
|
|
6164
6352
|
return {
|
|
@@ -6272,12 +6460,12 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
|
|
|
6272
6460
|
const displayMaxDate = React.useMemo(() => normalizedMaxDateTime && timezoneOffset !== undefined
|
|
6273
6461
|
? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
|
|
6274
6462
|
: normalizedMaxDateTime, [normalizedMaxDateTime, timezoneOffset]);
|
|
6275
|
-
return jsxRuntime.jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.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 }), jsxRuntime.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 && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled,
|
|
6463
|
+
return jsxRuntime.jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.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$1 }), jsxRuntime.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 && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] })] }) });
|
|
6276
6464
|
}
|
|
6277
6465
|
|
|
6278
6466
|
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"};
|
|
6279
6467
|
|
|
6280
|
-
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, }) {
|
|
6468
|
+
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: locale$1 = locale.enGB, }) {
|
|
6281
6469
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
6282
6470
|
const [inputValue, setInputValue] = React.useState("");
|
|
6283
6471
|
const [selectedDate, setSelectedDate] = React.useState(value);
|
|
@@ -6508,11 +6696,11 @@ function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, di
|
|
|
6508
6696
|
...(maxDateTime ? [{ after: maxDateTime }] : []),
|
|
6509
6697
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
6510
6698
|
], [disabledDates, minDateTime, maxDateTime, disabledMatcher]);
|
|
6511
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 16
|
|
6699
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 16 }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: compactStyles.calendarWrapper, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, modifiers: {
|
|
6512
6700
|
today: new Date(),
|
|
6513
6701
|
}, modifiersClassNames: {
|
|
6514
6702
|
today: "rdp-day-today",
|
|
6515
|
-
} }), showTodayButton && (jsxRuntime.jsx("footer", { className: "cw-flex-row cw-align-center-center", children: jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", icon: "check-big", onClick: handleNowClick, text:
|
|
6703
|
+
} }), showTodayButton && (jsxRuntime.jsx("footer", { className: "cw-flex-row cw-align-center-center", children: jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", icon: "check-big", onClick: handleNowClick, text: nowLabel }) }))] }), jsxRuntime.jsxs("div", { className: compactStyles.timeWrapper, children: [jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx(CwIcon, { iconId: "clock", size: "medium" }), jsxRuntime.jsx("span", { children: timeLabel })] }), jsxRuntime.jsx("div", { ref: timeListRef, className: `${timeStyles.timePickerList} ${compactStyles.compactTimeList}`, children: timeOptions.map((time) => {
|
|
6516
6704
|
const isSelected = time === selectedTime;
|
|
6517
6705
|
return (jsxRuntime.jsx("button", { type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
|
|
6518
6706
|
}) })] })] }))] })] }) }));
|
|
@@ -6849,7 +7037,10 @@ const SchedulerContentArea = ({ now, showTimeline, timeLineLeftPx, timeSeparator
|
|
|
6849
7037
|
if (reference) {
|
|
6850
7038
|
setContentArea(reference);
|
|
6851
7039
|
}
|
|
6852
|
-
}, children: [showTimeline && (jsxRuntime.jsx(TimeLine$1, { id: scheduler.props.id + "_timeline", marginLeft: timeLineLeftPx, zIndex: 8, toolTipTitle:
|
|
7040
|
+
}, children: [showTimeline && (jsxRuntime.jsx(TimeLine$1, { id: scheduler.props.id + "_timeline", marginLeft: timeLineLeftPx, zIndex: 8, toolTipTitle: Temporal.PlainTime.from({
|
|
7041
|
+
hour: now.getHours(),
|
|
7042
|
+
minute: now.getMinutes(),
|
|
7043
|
+
}).toString({ smallestUnit: "minute" }) })), timeSeparatorLeftPx.map((pixels) => {
|
|
6853
7044
|
return jsxRuntime.jsx(TimeLine$1, { marginLeft: pixels, color: "rgba(255,255,255,0.7)" });
|
|
6854
7045
|
}), jsxRuntime.jsx("span", { onClick: () => {
|
|
6855
7046
|
if (onEmptyClick) {
|
|
@@ -7063,6 +7254,11 @@ const DaysHeader = ({ days, divisionType, maxWidth, headerType }) => {
|
|
|
7063
7254
|
return jsxRuntime.jsx("tr", { className: "cwelltSchRowDate", children: headerToDraw });
|
|
7064
7255
|
};
|
|
7065
7256
|
|
|
7257
|
+
function formatHHmm(date) {
|
|
7258
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7259
|
+
const zdt = Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTimeISO(timeZone);
|
|
7260
|
+
return `${zdt.hour.toString().padStart(2, "0")}:${zdt.minute.toString().padStart(2, "0")}`;
|
|
7261
|
+
}
|
|
7066
7262
|
const getFormattedTimeForHeader = (calculatedDivType, calculatedDivision, timeHeader) => {
|
|
7067
7263
|
let showDate = "";
|
|
7068
7264
|
switch (calculatedDivType) {
|
|
@@ -7078,18 +7274,18 @@ const getFormattedTimeForHeader = (calculatedDivType, calculatedDivision, timeHe
|
|
|
7078
7274
|
timeHeader.getHours() === 15 ||
|
|
7079
7275
|
timeHeader.getHours() === 18 ||
|
|
7080
7276
|
timeHeader.getHours() === 21
|
|
7081
|
-
?
|
|
7277
|
+
? formatHHmm(timeHeader)
|
|
7082
7278
|
: "";
|
|
7083
7279
|
break;
|
|
7084
7280
|
case 3:
|
|
7085
7281
|
showDate =
|
|
7086
7282
|
timeHeader.getHours() === 0 || timeHeader.getHours() === 8 || timeHeader.getHours() === 16
|
|
7087
|
-
?
|
|
7283
|
+
? formatHHmm(timeHeader)
|
|
7088
7284
|
: "";
|
|
7089
7285
|
break;
|
|
7090
7286
|
case 2:
|
|
7091
7287
|
showDate =
|
|
7092
|
-
timeHeader.getHours() === 0 || timeHeader.getHours() === 12 ?
|
|
7288
|
+
timeHeader.getHours() === 0 || timeHeader.getHours() === 12 ? formatHHmm(timeHeader) : "";
|
|
7093
7289
|
break;
|
|
7094
7290
|
}
|
|
7095
7291
|
break;
|
|
@@ -7241,8 +7437,7 @@ const compareStrings = (str1, str2) => {
|
|
|
7241
7437
|
const filterResources = (module, resourceName, resources, groupByFunction, endDate, startDate, scheduleName) => {
|
|
7242
7438
|
if ((module === "CrewControl" || module === "CrewScheduling" || module === "CrewSchedulingVacations") &&
|
|
7243
7439
|
resourceName === "Employees") {
|
|
7244
|
-
resources = resources.filter(c => (c.data.Eintritt === null || (c.data.Eintritt
|
|
7245
|
-
(c.data.Austritt === null || (c.data.Austritt !== null && moment(c.data.Austritt).toDate() >= startDate)));
|
|
7440
|
+
resources = resources.filter(c => (c.data.Eintritt === null || (new Date(c.data.Eintritt) <= endDate)) && (c.data.Austritt === null || (new Date(c.data.Austritt) >= startDate)));
|
|
7246
7441
|
}
|
|
7247
7442
|
if (scheduleName === "crewPinnedScheduler" || (module === "CrewControl" || module === "CrewScheduling") && resourceName === "Employees") {
|
|
7248
7443
|
const sortKey = (groupByFunction || scheduleName === "crewPinnedScheduler") ? "mainFunction" : "C3_LC";
|
|
@@ -7436,8 +7631,8 @@ class CwScheduler extends React.Component {
|
|
|
7436
7631
|
arraysEqual = (a1, a2) => a1.length === a2.length && a1.every((o, idx) => this.objectsEqualDeep(o, a2[idx]));
|
|
7437
7632
|
componentWillReceiveProps(_nextProps) {
|
|
7438
7633
|
if (this.state.showConsoleLogs) {
|
|
7439
|
-
console.log("Schedule - componentWillReceiveProps, start: ",
|
|
7440
|
-
console.log("Schedule - componentWillReceiveProps - has changes, start: ",
|
|
7634
|
+
console.log("Schedule - componentWillReceiveProps, start: ", new Date());
|
|
7635
|
+
console.log("Schedule - componentWillReceiveProps - has changes, start: ", new Date());
|
|
7441
7636
|
}
|
|
7442
7637
|
const dateChange = _nextProps.startDate.toISOString() !== this.props.startDate.toISOString() ||
|
|
7443
7638
|
_nextProps.endDate.toISOString() !== this.props.endDate.toISOString();
|
|
@@ -7478,8 +7673,8 @@ class CwScheduler extends React.Component {
|
|
|
7478
7673
|
pinnedResources: this.props.pinnedResources ?? [],
|
|
7479
7674
|
});
|
|
7480
7675
|
if (this.state.showConsoleLogs) {
|
|
7481
|
-
console.log("Schedule - componentWillReceiveProps - print on schedule, end: ",
|
|
7482
|
-
console.log("Schedule - componentWillReceiveProps, end: ",
|
|
7676
|
+
console.log("Schedule - componentWillReceiveProps - print on schedule, end: ", new Date());
|
|
7677
|
+
console.log("Schedule - componentWillReceiveProps, end: ", new Date());
|
|
7483
7678
|
}
|
|
7484
7679
|
return;
|
|
7485
7680
|
}
|
|
@@ -7572,10 +7767,11 @@ class CwScheduler extends React.Component {
|
|
|
7572
7767
|
}
|
|
7573
7768
|
|
|
7574
7769
|
function dateFromPercentage(startDate, visibleDays, percentage) {
|
|
7575
|
-
const
|
|
7576
|
-
const
|
|
7577
|
-
const
|
|
7578
|
-
|
|
7770
|
+
const start = Temporal.Instant.fromEpochMilliseconds(startDate.getTime());
|
|
7771
|
+
const spanMs = Math.round(visibleDays) * 24 * 60 * 60 * 1000;
|
|
7772
|
+
const offsetMs = Math.round(spanMs * percentage);
|
|
7773
|
+
const result = start.add({ milliseconds: offsetMs });
|
|
7774
|
+
return new Date(result.epochMilliseconds);
|
|
7579
7775
|
}
|
|
7580
7776
|
|
|
7581
7777
|
function getPercentageFromMouseEvent(event) {
|
|
@@ -7746,20 +7942,27 @@ const TimeLine = ({ left, top = "0px", height, color, width = "2px", zIndexNumbe
|
|
|
7746
7942
|
}, className: styles$3["scheduler-timeline-label"], children: timeString })) }));
|
|
7747
7943
|
};
|
|
7748
7944
|
|
|
7945
|
+
function isToday(startDate, endDate) {
|
|
7946
|
+
if (!startDate)
|
|
7947
|
+
return false;
|
|
7948
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7949
|
+
const today = Temporal.Now.plainDateISO();
|
|
7950
|
+
const start = Temporal.Instant.fromEpochMilliseconds(startDate.getTime())
|
|
7951
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
7952
|
+
if (endDate) {
|
|
7953
|
+
const end = Temporal.Instant.fromEpochMilliseconds(endDate.getTime())
|
|
7954
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
7955
|
+
return Temporal.PlainDate.compare(today, start) >= 0
|
|
7956
|
+
&& Temporal.PlainDate.compare(today, end) <= 0;
|
|
7957
|
+
}
|
|
7958
|
+
return today.equals(start);
|
|
7959
|
+
}
|
|
7960
|
+
|
|
7749
7961
|
const SchedulerHeaderDivision = ({ topDivisions, bottomDivisions, classification, topWidth, startDate, endDate }) => {
|
|
7750
|
-
const isToday = () => {
|
|
7751
|
-
if (!startDate)
|
|
7752
|
-
return false;
|
|
7753
|
-
const today = moment();
|
|
7754
|
-
if (endDate) {
|
|
7755
|
-
return today.isBetween(startDate, endDate, 'day', '[]');
|
|
7756
|
-
}
|
|
7757
|
-
return today.isSame(startDate, 'day');
|
|
7758
|
-
};
|
|
7759
7962
|
return (jsxRuntime.jsxs("div", { style: {
|
|
7760
7963
|
width: topWidth,
|
|
7761
7964
|
cursor: "pointer"
|
|
7762
|
-
}, children: [jsxRuntime.jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday() ? styles$3["current-day"] : ""}`, children: jsxRuntime.jsx("span", { children: topDivisions }) }), jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsxRuntime.jsx("div", { className: styles$3["scheduler-hours"], children: jsxRuntime.jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
|
|
7965
|
+
}, children: [jsxRuntime.jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$3["current-day"] : ""}`, children: jsxRuntime.jsx("span", { children: topDivisions }) }), jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsxRuntime.jsx("div", { className: styles$3["scheduler-hours"], children: jsxRuntime.jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
|
|
7763
7966
|
};
|
|
7764
7967
|
|
|
7765
7968
|
const HeaderTitle = ({ title, dividerText, width }) => {
|
|
@@ -7783,12 +7986,23 @@ const SchedulerHeader = ({ content, divisions, visibleDays, selectedDate, width,
|
|
|
7783
7986
|
const thisTopWidth = visibleDays > 15
|
|
7784
7987
|
? topWidth * day.bottom.length
|
|
7785
7988
|
: topWidth;
|
|
7786
|
-
const
|
|
7787
|
-
|
|
7788
|
-
const endDate = day.endDate ? moment(day.endDate).toDate() : undefined;
|
|
7789
|
-
return (jsxRuntime.jsx(SchedulerHeaderDivision, { topDivisions: day.top, bottomDivisions: day.bottom, classification: classification, topWidth: thisTopWidth + "%", startDate: startDate, endDate: endDate }, day.top + classification));
|
|
7989
|
+
const { start, end } = getStartEnd(day);
|
|
7990
|
+
return (jsxRuntime.jsx(SchedulerHeaderDivision, { topDivisions: day.top, bottomDivisions: day.bottom, classification: classification, topWidth: thisTopWidth + "%", startDate: start, endDate: end }, day.top + classification));
|
|
7790
7991
|
}), !(timeLinePercentage < 0 || timeLinePercentage > 100) && (jsxRuntime.jsx(TimeLine, { color: "red", left: `${timeLinePercentage}%`, top: "50%", height: "50%", isHeader: true, isUtc: isUtc }))] })] }));
|
|
7791
7992
|
};
|
|
7993
|
+
function getStartEnd(day) {
|
|
7994
|
+
const startDate = day.startDate
|
|
7995
|
+
? new Date(day.startDate)
|
|
7996
|
+
: (() => {
|
|
7997
|
+
const [dd, mm, yyyy] = day.top.split(".");
|
|
7998
|
+
return new Date(Number(yyyy), Number(mm) - 1, Number(dd));
|
|
7999
|
+
})();
|
|
8000
|
+
const endDate = day.endDate ? new Date(day.endDate) : undefined;
|
|
8001
|
+
return {
|
|
8002
|
+
start: startDate,
|
|
8003
|
+
end: endDate
|
|
8004
|
+
};
|
|
8005
|
+
}
|
|
7792
8006
|
|
|
7793
8007
|
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"};
|
|
7794
8008
|
|
|
@@ -8110,6 +8324,16 @@ const SchedulerRow = React.memo((props) => {
|
|
|
8110
8324
|
return true;
|
|
8111
8325
|
});
|
|
8112
8326
|
|
|
8327
|
+
const filterVisibleEvents = (events, selectedDate, visibleDays) => {
|
|
8328
|
+
const schedulerEnd = Temporal.PlainDate.from({
|
|
8329
|
+
year: selectedDate.getFullYear(),
|
|
8330
|
+
month: selectedDate.getMonth() + 1,
|
|
8331
|
+
day: selectedDate.getDate(),
|
|
8332
|
+
}).add({ days: visibleDays });
|
|
8333
|
+
const lastDayOfScheduler = new Date(schedulerEnd.year, schedulerEnd.month - 1, schedulerEnd.day);
|
|
8334
|
+
return events.filter((event) => event.endDate > selectedDate && event.startDate < lastDayOfScheduler);
|
|
8335
|
+
};
|
|
8336
|
+
|
|
8113
8337
|
const DIVISION_RULES = [
|
|
8114
8338
|
{ maxDays: 2, divisions: 24 },
|
|
8115
8339
|
{ maxDays: 3, divisions: 12 },
|
|
@@ -8124,17 +8348,52 @@ const calculateDivisionsByDays = (days) => {
|
|
|
8124
8348
|
};
|
|
8125
8349
|
const getHoursFromDivisions = (divisions, useCompactHourFormat = false) => {
|
|
8126
8350
|
const hoursInterval = 24 / divisions;
|
|
8127
|
-
const hourFormat = useCompactHourFormat ? "HH[h]" : "HH:mm";
|
|
8128
8351
|
const array = [];
|
|
8129
8352
|
for (let i = 0; i < divisions; i++) {
|
|
8130
|
-
const
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8353
|
+
const totalMinutes = Math.round(hoursInterval * i * 60);
|
|
8354
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
8355
|
+
const minutes = totalMinutes % 60;
|
|
8356
|
+
const hh = hours.toString().padStart(2, "0");
|
|
8357
|
+
const mm = minutes.toString().padStart(2, "0");
|
|
8358
|
+
array.push(useCompactHourFormat ? `${hh}h` : `${hh}:${mm}`);
|
|
8134
8359
|
}
|
|
8135
8360
|
return array;
|
|
8136
8361
|
};
|
|
8137
8362
|
|
|
8363
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
8364
|
+
function toPlainDate(date) {
|
|
8365
|
+
return Temporal.Instant.fromEpochMilliseconds(date.getTime())
|
|
8366
|
+
.toZonedDateTimeISO(timeZone).toPlainDate();
|
|
8367
|
+
}
|
|
8368
|
+
function addDays(date, days) {
|
|
8369
|
+
const result = new Date(date);
|
|
8370
|
+
result.setDate(result.getDate() + days);
|
|
8371
|
+
return result;
|
|
8372
|
+
}
|
|
8373
|
+
function formatDD_MM(date) {
|
|
8374
|
+
const pd = toPlainDate(date);
|
|
8375
|
+
return `${pd.day.toString().padStart(2, "0")}.${pd.month.toString().padStart(2, "0")}`;
|
|
8376
|
+
}
|
|
8377
|
+
function formatDD_MM_YYYY(date) {
|
|
8378
|
+
const pd = toPlainDate(date);
|
|
8379
|
+
return `${pd.day.toString().padStart(2, "0")}.${pd.month.toString().padStart(2, "0")}.${pd.year}`;
|
|
8380
|
+
}
|
|
8381
|
+
function formatMM_YYYY(date) {
|
|
8382
|
+
const pd = toPlainDate(date);
|
|
8383
|
+
return `${pd.month.toString().padStart(2, "0")}.${pd.year}`;
|
|
8384
|
+
}
|
|
8385
|
+
function getShortWeekday(date) {
|
|
8386
|
+
return date.toLocaleDateString("en-US", { weekday: "short" });
|
|
8387
|
+
}
|
|
8388
|
+
function daysBetween(a, b) {
|
|
8389
|
+
const aPlain = toPlainDate(a);
|
|
8390
|
+
const bPlain = toPlainDate(b);
|
|
8391
|
+
return Math.abs(aPlain.until(bPlain).days);
|
|
8392
|
+
}
|
|
8393
|
+
function daysInMonth(date) {
|
|
8394
|
+
const pd = toPlainDate(date);
|
|
8395
|
+
return pd.daysInMonth;
|
|
8396
|
+
}
|
|
8138
8397
|
const getDefaultDivisions = (visibleDays, selectedDate) => {
|
|
8139
8398
|
if (visibleDays <= 15) {
|
|
8140
8399
|
return getDayDivisions(visibleDays, selectedDate);
|
|
@@ -8150,16 +8409,16 @@ const getDayDivisions = (visibleDays, selectedDate) => {
|
|
|
8150
8409
|
const divisions = getHoursFromDivisions(divisionsNumber, visibleDays < 3);
|
|
8151
8410
|
const calculatedDivision = [];
|
|
8152
8411
|
for (let i = 0; i < visibleDays; i++) {
|
|
8153
|
-
const currentDate =
|
|
8154
|
-
const weekdayShort = currentDate
|
|
8412
|
+
const currentDate = addDays(selectedDate, i);
|
|
8413
|
+
const weekdayShort = getShortWeekday(currentDate);
|
|
8155
8414
|
const weekdayLabel = visibleDays < 8
|
|
8156
8415
|
? weekdayShort
|
|
8157
8416
|
: weekdayShort.charAt(0).toUpperCase();
|
|
8158
8417
|
calculatedDivision.push({
|
|
8159
|
-
top: `${weekdayLabel} ${currentDate
|
|
8418
|
+
top: `${weekdayLabel} ${formatDD_MM(currentDate)}`,
|
|
8160
8419
|
bottom: divisions,
|
|
8161
|
-
startDate: currentDate
|
|
8162
|
-
endDate: currentDate
|
|
8420
|
+
startDate: currentDate,
|
|
8421
|
+
endDate: currentDate
|
|
8163
8422
|
});
|
|
8164
8423
|
}
|
|
8165
8424
|
return calculatedDivision;
|
|
@@ -8167,16 +8426,16 @@ const getDayDivisions = (visibleDays, selectedDate) => {
|
|
|
8167
8426
|
const getWeekDivisions = (visibleDays, selectedDate) => {
|
|
8168
8427
|
const weeks = getWeeksByDays(visibleDays, selectedDate);
|
|
8169
8428
|
const divisions = weeks.map((week) => {
|
|
8170
|
-
const days = Array.from({ length: week.days }, (_, i) =>
|
|
8171
|
-
const weekEnd =
|
|
8429
|
+
const days = Array.from({ length: week.days }, (_, i) => addDays(week.start, i).getDate().toString());
|
|
8430
|
+
const weekEnd = addDays(week.start, week.days - 1);
|
|
8172
8431
|
const top = days.length > 2
|
|
8173
|
-
?
|
|
8174
|
-
:
|
|
8432
|
+
? formatDD_MM_YYYY(week.start) + " - " + formatDD_MM_YYYY(weekEnd)
|
|
8433
|
+
: formatDD_MM_YYYY(week.start);
|
|
8175
8434
|
const division = {
|
|
8176
8435
|
top: top,
|
|
8177
8436
|
bottom: days,
|
|
8178
|
-
startDate:
|
|
8179
|
-
endDate: weekEnd
|
|
8437
|
+
startDate: new Date(week.start),
|
|
8438
|
+
endDate: weekEnd
|
|
8180
8439
|
};
|
|
8181
8440
|
return division;
|
|
8182
8441
|
});
|
|
@@ -8185,13 +8444,13 @@ const getWeekDivisions = (visibleDays, selectedDate) => {
|
|
|
8185
8444
|
const getMonthDivisions = (visibleDays, selectedDate) => {
|
|
8186
8445
|
const months = getMonthsByDays(visibleDays, selectedDate);
|
|
8187
8446
|
const divisions = months.map((month) => {
|
|
8188
|
-
const days = Array.from({ length: month.days }, (_, i) =>
|
|
8189
|
-
const monthEnd =
|
|
8447
|
+
const days = Array.from({ length: month.days }, (_, i) => addDays(month.start, i).getDate().toString());
|
|
8448
|
+
const monthEnd = addDays(month.start, month.days - 1);
|
|
8190
8449
|
const division = {
|
|
8191
|
-
top:
|
|
8450
|
+
top: formatMM_YYYY(month.start),
|
|
8192
8451
|
bottom: days,
|
|
8193
|
-
startDate:
|
|
8194
|
-
endDate: monthEnd
|
|
8452
|
+
startDate: new Date(month.start),
|
|
8453
|
+
endDate: monthEnd
|
|
8195
8454
|
};
|
|
8196
8455
|
return division;
|
|
8197
8456
|
});
|
|
@@ -8202,23 +8461,23 @@ const getMonthsByDays = (visibleDays, selectedDate) => {
|
|
|
8202
8461
|
return [];
|
|
8203
8462
|
}
|
|
8204
8463
|
const month = [];
|
|
8205
|
-
let
|
|
8464
|
+
let rangeStart = new Date(selectedDate);
|
|
8206
8465
|
for (let i = 0; i < visibleDays; i++) {
|
|
8207
|
-
const currentDay =
|
|
8466
|
+
const currentDay = addDays(selectedDate, i);
|
|
8208
8467
|
const isLastLoop = i + 1 === visibleDays;
|
|
8209
8468
|
if (isLastLoop) {
|
|
8210
8469
|
month.push({
|
|
8211
|
-
start:
|
|
8212
|
-
days:
|
|
8470
|
+
start: rangeStart,
|
|
8471
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8213
8472
|
});
|
|
8214
8473
|
break;
|
|
8215
8474
|
}
|
|
8216
|
-
if (currentDay.
|
|
8475
|
+
if (currentDay.getDate() === daysInMonth(currentDay)) {
|
|
8217
8476
|
month.push({
|
|
8218
|
-
start:
|
|
8219
|
-
days:
|
|
8477
|
+
start: rangeStart,
|
|
8478
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8220
8479
|
});
|
|
8221
|
-
|
|
8480
|
+
rangeStart = addDays(currentDay, 1);
|
|
8222
8481
|
}
|
|
8223
8482
|
}
|
|
8224
8483
|
return month;
|
|
@@ -8229,32 +8488,37 @@ const getWeeksByDays = (visibleDays, selectedDate) => {
|
|
|
8229
8488
|
return [];
|
|
8230
8489
|
}
|
|
8231
8490
|
const weeks = [];
|
|
8232
|
-
let
|
|
8491
|
+
let rangeStart = new Date(selectedDate);
|
|
8233
8492
|
for (let i = 0; i < visibleDays; i++) {
|
|
8234
|
-
const currentDay =
|
|
8493
|
+
const currentDay = addDays(selectedDate, i);
|
|
8235
8494
|
const isLastLoop = i + 1 === visibleDays;
|
|
8236
8495
|
if (isLastLoop) {
|
|
8237
8496
|
weeks.push({
|
|
8238
|
-
start:
|
|
8239
|
-
days:
|
|
8497
|
+
start: rangeStart,
|
|
8498
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8240
8499
|
});
|
|
8241
8500
|
break;
|
|
8242
8501
|
}
|
|
8243
|
-
if (currentDay.
|
|
8502
|
+
if (currentDay.getDay() === SUNDAY) {
|
|
8244
8503
|
weeks.push({
|
|
8245
|
-
start:
|
|
8246
|
-
days:
|
|
8504
|
+
start: rangeStart,
|
|
8505
|
+
days: daysBetween(rangeStart, currentDay) + 1,
|
|
8247
8506
|
});
|
|
8248
|
-
|
|
8507
|
+
rangeStart = addDays(currentDay, 1);
|
|
8249
8508
|
}
|
|
8250
8509
|
}
|
|
8251
8510
|
return weeks;
|
|
8252
8511
|
};
|
|
8253
8512
|
|
|
8254
8513
|
const eventIsVisible = (startDate, endDate, selectedDate, visibleDays) => {
|
|
8255
|
-
const schedulerEnd =
|
|
8514
|
+
const schedulerEnd = Temporal.PlainDate.from({
|
|
8515
|
+
year: selectedDate.getFullYear(),
|
|
8516
|
+
month: selectedDate.getMonth() + 1,
|
|
8517
|
+
day: selectedDate.getDate(),
|
|
8518
|
+
}).add({ days: visibleDays });
|
|
8519
|
+
const schedulerEndDate = new Date(schedulerEnd.year, schedulerEnd.month - 1, schedulerEnd.day);
|
|
8256
8520
|
const isBefore = selectedDate > startDate && selectedDate > endDate;
|
|
8257
|
-
const isAfter =
|
|
8521
|
+
const isAfter = schedulerEndDate < startDate && schedulerEndDate < endDate;
|
|
8258
8522
|
return !isBefore && !isAfter;
|
|
8259
8523
|
};
|
|
8260
8524
|
|
|
@@ -8355,11 +8619,7 @@ const Scheduler = (props) => {
|
|
|
8355
8619
|
const instanceRef = React.useRef(null);
|
|
8356
8620
|
// const rowHeaderWidth = "180px";
|
|
8357
8621
|
const { selectedDate, visibleDays, isUtc, isHeaderVisible, visibleRows: stateVisibleRows } = props.state;
|
|
8358
|
-
const events = eventsState
|
|
8359
|
-
const lastDayOfScheduler = moment(selectedDate).add(visibleDays, "days");
|
|
8360
|
-
return (moment(event.endDate).isAfter(selectedDate) &&
|
|
8361
|
-
moment(event.startDate).isBefore(lastDayOfScheduler));
|
|
8362
|
-
});
|
|
8622
|
+
const events = filterVisibleEvents(eventsState, selectedDate, visibleDays);
|
|
8363
8623
|
React.useEffect(() => {
|
|
8364
8624
|
instanceRef.current?.resetAfterIndex(0);
|
|
8365
8625
|
}, [orderCategories, props.rows.length, events]);
|
|
@@ -9328,6 +9588,7 @@ exports.UiEvent = UiEvent;
|
|
|
9328
9588
|
exports.Weekdays = Weekdays;
|
|
9329
9589
|
exports.cblEvent = cblEvent;
|
|
9330
9590
|
exports.eventIsVisible = eventIsVisible;
|
|
9591
|
+
exports.filterVisibleEvents = filterVisibleEvents;
|
|
9331
9592
|
exports.getDefaultDivisions = getDefaultDivisions;
|
|
9332
9593
|
exports.getEventSizes = getEventSizes;
|
|
9333
9594
|
exports.itemsToMultiFilterTags = itemsToMultiFilterTags;
|