@cwellt_software/cwellt-reactjs-lib 1.5.1 → 1.5.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/content/fonts/roboto-mono/LICENSE +93 -93
- package/dist/content/fonts/roboto-mono/RobotoMono.css +43 -43
- package/dist/content/icons/new-cw-icons/css/new-cw-icons.css +6 -0
- package/dist/index.cjs.js +268 -1471
- package/dist/index.css +2 -2
- package/dist/index.d.ts +137 -230
- package/dist/index.es.js +269 -1468
- package/dist/src/components/control/action/button/CwButton.d.ts +5 -0
- package/dist/src/components/control/action/button/CwButton.d.ts.map +1 -1
- package/dist/src/components/control/action/button/CwButtonBadge.d.ts +63 -0
- package/dist/src/components/control/action/button/CwButtonBadge.d.ts.map +1 -0
- package/dist/src/components/control/choice/checkbox/CwCheckboxGroup.d.ts.map +1 -1
- package/dist/src/components/control/choice/checkbox/CwRadioGroup.d.ts.map +1 -1
- package/dist/src/components/control/choice/select/CwDropdown.d.ts.map +1 -1
- package/dist/src/components/control/choice/tag-selector/CwTagSelector.d.ts.map +1 -1
- package/dist/src/components/control/input/color/CwInputColor.d.ts +2 -0
- package/dist/src/components/control/input/color/CwInputColor.d.ts.map +1 -1
- package/dist/src/components/control/input/digit/CwDigit.d.ts +12 -0
- package/dist/src/components/control/input/digit/CwDigit.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDatePickerTemporal.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateRangePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateRangePickerTemporal.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwTimePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/weekday/CwWeekdaySelector.d.ts +16 -44
- package/dist/src/components/control/input/weekday/CwWeekdaySelector.d.ts.map +1 -1
- package/dist/src/components/control/input/weekday/weekdayNames.d.ts +14 -0
- package/dist/src/components/control/input/weekday/weekdayNames.d.ts.map +1 -0
- package/dist/src/components/control/input/weekday/weekdays.d.ts +65 -0
- package/dist/src/components/control/input/weekday/weekdays.d.ts.map +1 -0
- package/dist/src/components/display/graphics/progress/CwProgress.d.ts +3 -1
- package/dist/src/components/display/graphics/progress/CwProgress.d.ts.map +1 -1
- package/dist/src/components/display/text/badge/CwBadge.d.ts +48 -0
- package/dist/src/components/display/text/badge/CwBadge.d.ts.map +1 -0
- package/dist/src/components/display/text/badge/badgeContent.d.ts +33 -0
- package/dist/src/components/display/text/badge/badgeContent.d.ts.map +1 -0
- package/dist/src/components/display/text/tag/CwChip.d.ts +16 -8
- package/dist/src/components/display/text/tag/CwChip.d.ts.map +1 -1
- package/dist/src/components/layout/tabs/CwTabs.d.ts +7 -1
- package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -9
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
- package/dist/src/playground/pages/CwBadgePage.d.ts +3 -0
- package/dist/src/playground/pages/CwBadgePage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwChipPage.d.ts +3 -0
- package/dist/src/playground/pages/CwChipPage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwDigitPage.d.ts +3 -0
- package/dist/src/playground/pages/CwDigitPage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwWeekdaySelectorPage.d.ts +3 -0
- package/dist/src/playground/pages/CwWeekdaySelectorPage.d.ts.map +1 -0
- package/dist/src/playground/pages/FormControlLayoutsPage.d.ts +3 -0
- package/dist/src/playground/pages/FormControlLayoutsPage.d.ts.map +1 -0
- package/dist/src/playground/pages/ProgressPage.d.ts.map +1 -1
- package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
- package/dist/test/components/control/input/weekday/weekdayNames.test.d.ts +2 -0
- package/dist/test/components/control/input/weekday/weekdayNames.test.d.ts.map +1 -0
- package/dist/test/components/control/input/weekday/weekdays.test.d.ts +2 -0
- package/dist/test/components/control/input/weekday/weekdays.test.d.ts.map +1 -0
- package/dist/test/components/display/text/badge/badgeContent.test.d.ts +2 -0
- package/dist/test/components/display/text/badge/badgeContent.test.d.ts.map +1 -0
- package/package.json +3 -3
- package/dist/content/fonts/roboto/LICENSE.txt +0 -202
- package/dist/content/fonts/roboto/Roboto-Black.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-BlackItalic.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Bold.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-BoldItalic.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Italic.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Light.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-LightItalic.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Medium.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-MediumItalic.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Regular.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-Thin.ttf +0 -0
- package/dist/content/fonts/roboto/Roboto-ThinItalic.ttf +0 -0
- package/dist/content/fonts/roboto/RobotoFontFamily.css +0 -109
- package/dist/content/fonts/roboto-flex/README.md +0 -24
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-grad-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-opsz-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-slnt-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-standard-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-wdth-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-wght-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-xopq-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-xtra-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-yopq-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-ytas-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-ytde-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-ytfi-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-ytlc-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ext-ytuc-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-grad-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-opsz-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-slnt-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-standard-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-wdth-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-wght-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-xopq-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-xtra-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-yopq-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ytas-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ytde-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ytfi-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ytlc-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/files/roboto-flex-latin-ytuc-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-flex/grad.css +0 -19
- package/dist/content/fonts/roboto-flex/index.css +0 -19
- package/dist/content/fonts/roboto-flex/metadata.json +0 -33
- package/dist/content/fonts/roboto-flex/opsz.css +0 -19
- package/dist/content/fonts/roboto-flex/slnt.css +0 -19
- package/dist/content/fonts/roboto-flex/standard.css +0 -21
- package/dist/content/fonts/roboto-flex/unicode.json +0 -4
- package/dist/content/fonts/roboto-flex/wdth.css +0 -21
- package/dist/content/fonts/roboto-flex/wght.css +0 -20
- package/dist/content/fonts/roboto-flex/xopq.css +0 -20
- package/dist/content/fonts/roboto-flex/xtra.css +0 -19
- package/dist/content/fonts/roboto-flex/yopq.css +0 -19
- package/dist/content/fonts/roboto-flex/ytas.css +0 -19
- package/dist/content/fonts/roboto-flex/ytde.css +0 -20
- package/dist/content/fonts/roboto-flex/ytfi.css +0 -20
- package/dist/content/fonts/roboto-flex/ytlc.css +0 -19
- package/dist/content/fonts/roboto-flex/ytuc.css +0 -20
- package/dist/content/icons/new-cw-icons/NewCwIcons.html +0 -415
package/dist/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { useState, useRef, useEffect, useCallback, useLayoutEffect, createContext, useContext, cloneElement, useMemo, forwardRef,
|
|
3
|
+
import React__default, { useState, useRef, useEffect, useCallback, useLayoutEffect, createContext, useContext, cloneElement, useMemo, forwardRef, useId, useImperativeHandle, createElement, memo } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import { createRoot } from 'react-dom/client';
|
|
6
6
|
import Draggable from 'react-draggable';
|
|
@@ -161,7 +161,7 @@ function getContrastColor(color) {
|
|
|
161
161
|
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
var styles$
|
|
164
|
+
var styles$y = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
165
165
|
|
|
166
166
|
// Constants
|
|
167
167
|
const margin$1 = 16;
|
|
@@ -451,7 +451,7 @@ const CwTooltipManager = () => {
|
|
|
451
451
|
if (!state.isVisible || !state.content) {
|
|
452
452
|
return null;
|
|
453
453
|
}
|
|
454
|
-
return createPortal(jsx("div", { ref: tooltipRef, className: styles$
|
|
454
|
+
return createPortal(jsx("div", { ref: tooltipRef, className: styles$y["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
|
|
455
455
|
top: `${tooltipPosition.top}px`,
|
|
456
456
|
left: `${tooltipPosition.left}px`,
|
|
457
457
|
opacity: (isPositioned && !isMeasuring) ? 1 : 0,
|
|
@@ -532,7 +532,7 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
|
|
|
532
532
|
useEffect(() => {
|
|
533
533
|
ensureTooltipManager();
|
|
534
534
|
}, []);
|
|
535
|
-
return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$
|
|
535
|
+
return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$y["cw-tooltip"], children: children }));
|
|
536
536
|
};
|
|
537
537
|
|
|
538
538
|
const SVG_ICONS = {
|
|
@@ -567,25 +567,31 @@ function CwIcon(props) {
|
|
|
567
567
|
/**
|
|
568
568
|
* CwChip - A simple chip/tag component for displaying labels or categories
|
|
569
569
|
*
|
|
570
|
+
* The colour comes from `color`; the older `colorScheme` spelling is deprecated but still
|
|
571
|
+
* honoured, and `color` wins when both are passed.
|
|
572
|
+
*
|
|
570
573
|
* @example
|
|
571
|
-
* <CwChip label="Active"
|
|
572
|
-
* <CwChip label="High Priority"
|
|
573
|
-
* <CwChip label="Custom"
|
|
574
|
-
* <CwChip label="Outlined"
|
|
574
|
+
* <CwChip label="Active" color="success" />
|
|
575
|
+
* <CwChip label="High Priority" color="danger" variant="solid" />
|
|
576
|
+
* <CwChip label="Custom" color="custom" customColor="#8a2be2" />
|
|
577
|
+
* <CwChip label="Outlined" color="info" variant="outline" />
|
|
575
578
|
* <CwChip label="Removable" closable onClose={() => console.log('closed')} />
|
|
576
579
|
**/
|
|
577
|
-
const CwChip = ({ label, colorScheme
|
|
580
|
+
const CwChip = ({ label, color, colorScheme, customColor, variant = 'soft', className = '', closable = false, onClose, icon, style = {}, }) => {
|
|
581
|
+
const resolvedColor = color ?? colorScheme ?? 'info';
|
|
578
582
|
// Basic validation
|
|
579
583
|
if (closable && !onClose) {
|
|
580
584
|
console.warn('CwChip: onClose prop is required when closable is true');
|
|
581
585
|
}
|
|
582
|
-
//
|
|
586
|
+
// One arbitrary colour can only fill two of the four roles, so soft and solid look alike here.
|
|
583
587
|
const chipStyle = React__default.useMemo(() => {
|
|
584
588
|
if (customColor) {
|
|
585
|
-
|
|
589
|
+
const contrast = getContrastColor(customColor);
|
|
586
590
|
return {
|
|
587
|
-
'--
|
|
588
|
-
'--
|
|
591
|
+
'--accent-light': customColor,
|
|
592
|
+
'--accent-main': customColor,
|
|
593
|
+
'--accent-dark': contrast,
|
|
594
|
+
'--accent-on-main': contrast,
|
|
589
595
|
...style
|
|
590
596
|
};
|
|
591
597
|
}
|
|
@@ -604,7 +610,79 @@ const CwChip = ({ label, colorScheme = 'info', customColor, variant = 'soft', cl
|
|
|
604
610
|
className,
|
|
605
611
|
closable ? 'cw-chip-closable' : '',
|
|
606
612
|
].filter(Boolean).join(' ');
|
|
607
|
-
return (jsxs("span", { className: chipClassNames, "data-color
|
|
613
|
+
return (jsxs("span", { className: chipClassNames, "data-color": resolvedColor, "data-variant": variant, "data-icon-only": (Boolean(icon) && !label) || undefined, style: chipStyle, children: [icon && jsx(CwIcon, { iconId: icon }), label && jsx("span", { children: label }), closable && (jsx("button", { className: "cw-chip-close-button", onClick: handleClose, "aria-label": "Remove", type: "button", children: jsx("span", { className: "cwi-icons cwi-close" }) }))] }));
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Normalises a raw count into the integer the badge represents: a non-negative whole number.
|
|
618
|
+
* Both the display string and the `showZero` decision derive from this.
|
|
619
|
+
*/
|
|
620
|
+
function normalizeBadgeCount(count) {
|
|
621
|
+
return Number.isFinite(count) ? Math.max(0, Math.trunc(count)) : 0;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Formats a badge count into its display string. Both arguments are normalised, `max` with a
|
|
625
|
+
* floor of 1 - below that every non-zero count would overflow.
|
|
626
|
+
*
|
|
627
|
+
* @param count Raw count to display.
|
|
628
|
+
* @param max Highest value shown as a number; anything above renders `"{max}+"`.
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* formatBadgeCount(7, 99); // "7"
|
|
632
|
+
* formatBadgeCount(100, 99); // "99+"
|
|
633
|
+
* formatBadgeCount(12, 9); // "9+"
|
|
634
|
+
*/
|
|
635
|
+
function formatBadgeCount(count, max) {
|
|
636
|
+
const safeCount = normalizeBadgeCount(count);
|
|
637
|
+
const safeMax = Number.isFinite(max) ? Math.max(1, Math.trunc(max)) : 1;
|
|
638
|
+
return safeCount > safeMax ? `${safeMax}+` : `${safeCount}`;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Resolves the badge's accessibility attributes. A text-less badge with no label is hidden rather
|
|
642
|
+
* than announced as an empty element; the button or tab around it usually names the thing.
|
|
643
|
+
*
|
|
644
|
+
* @param label Caller-supplied accessible name.
|
|
645
|
+
* @param loading Whether the badge is showing its spinner.
|
|
646
|
+
* @param hasText Whether the badge renders a count or content.
|
|
647
|
+
*/
|
|
648
|
+
function resolveBadgeAria(label, loading, hasText) {
|
|
649
|
+
if (label) {
|
|
650
|
+
return { role: loading ? 'status' : 'img', 'aria-label': label };
|
|
651
|
+
}
|
|
652
|
+
return hasText ? {} : { 'aria-hidden': 'true' };
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
var styles$x = {"badge":"cw-badge-module__badge__PKlak"};
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* CwBadge - the small coloured circle with a number, used for alert and notification counts.
|
|
659
|
+
*
|
|
660
|
+
* Always **in flow** (`inline-flex`); it never positions itself, so overlaying it on an icon
|
|
661
|
+
* button is the caller's job. One digit stays a circle, wider content such as `"99+"` grows into
|
|
662
|
+
* a pill. With neither `count` nor `content` it renders as a dot.
|
|
663
|
+
*
|
|
664
|
+
* Precedence: `loading` > `content` > `count` > dot. While loading the badge renders regardless
|
|
665
|
+
* of `showZero`, and the spinner replaces it - circle, background and padding come off.
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* <CwBadge count={3} color="danger" />
|
|
669
|
+
* <CwBadge count={0} showZero={false} />
|
|
670
|
+
* <CwBadge count={128} max={99} color="warning" variant="soft" />
|
|
671
|
+
* <CwBadge color="warning" label="Unresolved findings" />
|
|
672
|
+
* <CwBadge count={0} loading />
|
|
673
|
+
*/
|
|
674
|
+
const CwBadge = ({ count, content, color = 'info', variant = 'solid', size = 'small', showZero = true, loading = false, max = 99, label, className = '', style, }) => {
|
|
675
|
+
// null counts as absent, so `content={null}` still renders a dot rather than an empty pill.
|
|
676
|
+
const hasContent = content !== undefined && content !== null;
|
|
677
|
+
if (!loading && !hasContent && count !== undefined && !showZero && normalizeBadgeCount(count) === 0) {
|
|
678
|
+
return null;
|
|
679
|
+
}
|
|
680
|
+
const countText = !hasContent && count !== undefined
|
|
681
|
+
? formatBadgeCount(count, max)
|
|
682
|
+
: undefined;
|
|
683
|
+
const isDot = !loading && !hasContent && count === undefined;
|
|
684
|
+
const badgeClassNames = ['cw-badge', styles$x.badge, className].filter(Boolean).join(' ');
|
|
685
|
+
return (jsx("span", { className: badgeClassNames, "data-color": color, "data-variant": variant, "data-size": size, "data-loading": loading ? 'true' : undefined, "data-dot": isDot ? 'true' : undefined, ...resolveBadgeAria(label, loading, !loading && (hasContent || countText !== undefined)), style: style, children: loading ? jsx(CwIcon, { iconId: "spinner", size: "small" }) : hasContent ? content : countText }));
|
|
608
686
|
};
|
|
609
687
|
|
|
610
688
|
const CW_DEFAULT_MESSAGE_DURATION = 2000;
|
|
@@ -1058,7 +1136,7 @@ var styles$v = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-pro
|
|
|
1058
1136
|
* <CwProgress value={62} label="Import" color="success" />
|
|
1059
1137
|
* <CwProgress indeterminate label="Uploading" />
|
|
1060
1138
|
*/
|
|
1061
|
-
function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false }) {
|
|
1139
|
+
function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false, className }) {
|
|
1062
1140
|
const labelId = React__default.useId();
|
|
1063
1141
|
// Determinate: a missing or non-finite value is treated as 0 (never NaN), then
|
|
1064
1142
|
// clamped to [0,100] for aria-valuenow and the fill width. Indeterminate has no value.
|
|
@@ -1070,7 +1148,7 @@ function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'r
|
|
|
1070
1148
|
const valueText = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
|
|
1071
1149
|
// The un-hashed cw-progress class carries no styles in the library - a stable
|
|
1072
1150
|
// public hook for exceptional external overrides only.
|
|
1073
|
-
const rootClassName = ['cw-progress', styles$v.progress].filter(Boolean).join(' ');
|
|
1151
|
+
const rootClassName = ['cw-progress', styles$v.progress, className].filter(Boolean).join(' ');
|
|
1074
1152
|
const labelSpan = label ? jsx("span", { className: styles$v.label, id: labelId, children: label }) : null;
|
|
1075
1153
|
const valueLabel = showValue ? (jsx("span", { className: styles$v.value, "data-mono": monoValue || undefined, children: valueText })) : null;
|
|
1076
1154
|
return (jsxs("div", { className: rootClassName, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxs("header", { className: styles$v.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsx("div", { className: styles$v.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
|
|
@@ -1226,7 +1304,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1226
1304
|
return (jsxs("div", { ref: containerRef, className: styles$u["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
|
|
1227
1305
|
};
|
|
1228
1306
|
|
|
1229
|
-
const CwButton = React__default.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }, ref) {
|
|
1307
|
+
const CwButton = React__default.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", badge, children, ...buttonProps }, ref) {
|
|
1230
1308
|
// Build CSS classes based on variant and props
|
|
1231
1309
|
let buttonClass = `cw-button-${variant}`;
|
|
1232
1310
|
// Add icon class only for icon variant without children
|
|
@@ -1239,13 +1317,19 @@ const CwButton = React__default.forwardRef(function CwButton({ text, variant = '
|
|
|
1239
1317
|
const tooltipContent = title || (variant === 'icon' && text ? text : undefined);
|
|
1240
1318
|
const iconElement = icon ? jsx(CwIcon, { iconId: icon }) : null;
|
|
1241
1319
|
const textElement = text ? jsx("strong", { children: text }) : null;
|
|
1320
|
+
// Overlaid, not content: the `cwi-` condition above deliberately ignores it, so a badge
|
|
1321
|
+
// never suppresses the button's own icon. Size defaulted explicitly, not by spread order,
|
|
1322
|
+
// so `size: undefined` in the object cannot clobber it.
|
|
1323
|
+
const badgeElement = badge
|
|
1324
|
+
? jsx(CwBadge, { ...badge, size: badge.size ?? (variant === 'icon' ? 'small' : size) })
|
|
1325
|
+
: null;
|
|
1242
1326
|
// Only emit toggle attributes when `pressed` is defined; otherwise output stays identical to a normal button.
|
|
1243
1327
|
const pressedProps = pressed !== undefined
|
|
1244
1328
|
? { "aria-pressed": pressed, "data-pressed": pressed ? "true" : undefined }
|
|
1245
1329
|
: {};
|
|
1246
|
-
const buttonElement = (jsx("button", { ref: ref, type: "button", className: buttonClass, ...buttonProps, "data-color": color, "data-size": size, ...pressedProps, "aria-label":
|
|
1247
|
-
|
|
1248
|
-
|
|
1330
|
+
const buttonElement = (jsx("button", { ref: ref, type: "button", className: buttonClass, ...buttonProps, "data-color": color, "data-size": size, "data-has-badge": badge ? "true" : undefined, ...pressedProps, "aria-label": buttonProps["aria-label"] ?? tooltipContent, children: variant === 'icon' ? badgeElement : (jsxs(Fragment, { children: [children ?? (iconPosition === 'right'
|
|
1331
|
+
? jsxs(Fragment, { children: [textElement, iconElement] })
|
|
1332
|
+
: jsxs(Fragment, { children: [iconElement, textElement] })), badgeElement] })) }));
|
|
1249
1333
|
return tooltipContent ? (jsx(CwTooltipNew, { content: tooltipContent, position: tooltipPosition, displayInline: true, children: buttonElement })) : (buttonElement);
|
|
1250
1334
|
});
|
|
1251
1335
|
CwButton.displayName = "CwButton";
|
|
@@ -2634,8 +2718,12 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2634
2718
|
}, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2635
2719
|
}
|
|
2636
2720
|
|
|
2637
|
-
var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","
|
|
2721
|
+
var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
|
|
2638
2722
|
|
|
2723
|
+
const BADGE_COLOR_SCHEMES = ['primary', 'danger', 'warning', 'success', 'info', 'neutral'];
|
|
2724
|
+
function isBadgeColorScheme(value) {
|
|
2725
|
+
return BADGE_COLOR_SCHEMES.includes(value);
|
|
2726
|
+
}
|
|
2639
2727
|
const TabIcon = ({ icon }) => {
|
|
2640
2728
|
if (!icon)
|
|
2641
2729
|
return null;
|
|
@@ -2684,7 +2772,11 @@ function CwTabs(CwTabsProps) {
|
|
|
2684
2772
|
const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
|
|
2685
2773
|
? { minWidth: CwTabsProps.tabsListWidth }
|
|
2686
2774
|
: undefined;
|
|
2687
|
-
return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab =>
|
|
2775
|
+
return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
|
|
2776
|
+
const badgeScheme = tab.badgeColor && isBadgeColorScheme(tab.badgeColor) ? tab.badgeColor : undefined;
|
|
2777
|
+
const rawBadgeColor = tab.badgeColor && !badgeScheme ? tab.badgeColor : undefined;
|
|
2778
|
+
return (jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, "data-badge-themed": tab.badgeColor ? "true" : undefined, children: [jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsx(CwBadge, { count: typeof tab.badge === 'number' ? tab.badge : undefined, content: typeof tab.badge === 'string' ? tab.badge : undefined, size: "medium", color: badgeScheme ?? 'primary', variant: badgeScheme ? 'solid' : 'soft', style: rawBadgeColor ? { backgroundColor: rawBadgeColor, color: getContrastColor(rawBadgeColor) } : undefined }))] }, tab.key));
|
|
2779
|
+
}) }), jsx("div", { className: styles$n['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
|
|
2688
2780
|
}
|
|
2689
2781
|
|
|
2690
2782
|
/**
|
|
@@ -3233,8 +3325,16 @@ function CwInput(CwInputProps) {
|
|
|
3233
3325
|
* ```
|
|
3234
3326
|
*/
|
|
3235
3327
|
function CwDigit(props) {
|
|
3236
|
-
const { alignProps, buttonProps, iconProps, labelProps, ...inputProps } = props;
|
|
3237
|
-
|
|
3328
|
+
const { alignProps, buttonProps, iconProps, labelProps, feedback, feedbackPosition, ...inputProps } = props;
|
|
3329
|
+
const feedbackMessages = feedback
|
|
3330
|
+
? Array.isArray(feedback) ? feedback : [feedback]
|
|
3331
|
+
: [];
|
|
3332
|
+
const feedbackId = useId();
|
|
3333
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
3334
|
+
const describedBy = [inputProps["aria-describedby"], ...feedbackIds].filter(Boolean).join(" ") || undefined;
|
|
3335
|
+
// data-direction drives the feedback indent, which only makes sense under a label column.
|
|
3336
|
+
const flexDirection = alignProps?.flexDirection ?? "row";
|
|
3337
|
+
return (jsxs("div", { className: "cw-input-text", "data-direction": labelProps ? flexDirection : "column", "data-feedback-position": feedbackPosition, children: [jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: "cw-input-button", children: [jsx("input", { type: "number", ...inputProps, "aria-describedby": describedBy }), buttonProps && jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-info", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
3238
3338
|
}
|
|
3239
3339
|
|
|
3240
3340
|
var styles$j = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
|
|
@@ -3448,7 +3548,7 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
|
|
|
3448
3548
|
|
|
3449
3549
|
var styles$i = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
|
|
3450
3550
|
|
|
3451
|
-
const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, }) => {
|
|
3551
|
+
const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, className, style, }) => {
|
|
3452
3552
|
const [isOpen, setIsOpen] = useState(false);
|
|
3453
3553
|
const containerRef = useRef(null);
|
|
3454
3554
|
const dropdownRef = useRef(null);
|
|
@@ -3579,7 +3679,7 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
|
|
|
3579
3679
|
break;
|
|
3580
3680
|
}
|
|
3581
3681
|
};
|
|
3582
|
-
return (jsxs("div", { className: `cw-input-color ${styles$i.container}`, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$i.selectColor} ${disabled ? styles$i.disabled : ''} ${readOnly ? styles$i.readOnly : ''}`, style: {
|
|
3682
|
+
return (jsxs("div", { className: `cw-input-color ${styles$i.container}${className ? ` ${className}` : ''}`, style: style, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$i.selectColor} ${disabled ? styles$i.disabled : ''} ${readOnly ? styles$i.readOnly : ''}`, style: {
|
|
3583
3683
|
width,
|
|
3584
3684
|
height,
|
|
3585
3685
|
backgroundColor: value,
|
|
@@ -4044,15 +4144,37 @@ const CwImageArea = forwardRef((props, ref) => {
|
|
|
4044
4144
|
});
|
|
4045
4145
|
CwImageArea.displayName = "CwImageArea";
|
|
4046
4146
|
|
|
4047
|
-
var styles$g = {"cw-weekday-selector":"cw-weekday-selector-
|
|
4147
|
+
var styles$g = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
|
|
4148
|
+
|
|
4149
|
+
/* 2024-01-01 was a Monday. Formatted in UTC so a negative browser offset cannot shift a day. */
|
|
4150
|
+
const MONDAY_UTC = Date.UTC(2024, 0, 1);
|
|
4151
|
+
const DAY_IN_MS = 86_400_000;
|
|
4152
|
+
const DAY_CODES = ["M", "T", "W", "R", "F", "S", "U"];
|
|
4153
|
+
/**
|
|
4154
|
+
* Day names in the fixed MTWRFSU order the selector renders, resolved through Intl so every
|
|
4155
|
+
* locale gets its own letters (es -> LMXJVSD, de -> MDMDFSS) with no table to maintain.
|
|
4156
|
+
*
|
|
4157
|
+
* @param localeCode BCP-47 tag, e.g. "en-GB" | "es" | "de"
|
|
4158
|
+
*/
|
|
4159
|
+
function getWeekdayNames(localeCode) {
|
|
4160
|
+
const narrow = new Intl.DateTimeFormat(localeCode, { weekday: "narrow", timeZone: "UTC" });
|
|
4161
|
+
const full = new Intl.DateTimeFormat(localeCode, { weekday: "long", timeZone: "UTC" });
|
|
4162
|
+
const names = {};
|
|
4163
|
+
DAY_CODES.forEach((code, index) => {
|
|
4164
|
+
const date = new Date(MONDAY_UTC + index * DAY_IN_MS);
|
|
4165
|
+
names[code] = { letter: narrow.format(date), full: full.format(date) };
|
|
4166
|
+
});
|
|
4167
|
+
return names;
|
|
4168
|
+
}
|
|
4048
4169
|
|
|
4170
|
+
/* The week model behind CwWeekdaySelector, kept apart from the rendering. */
|
|
4049
4171
|
/**
|
|
4050
4172
|
* This class represents a week where days can be selected or unselected
|
|
4051
4173
|
* @remark Selected days are in UPPERCASE, unselected days are in lowercase
|
|
4052
4174
|
* ```
|
|
4053
4175
|
* Monday = "M" | "m"
|
|
4054
4176
|
* Tuesday = "T" | "t"
|
|
4055
|
-
*
|
|
4177
|
+
* Wednesday = "W" | "w"
|
|
4056
4178
|
* thuRsday = "R" | "r"
|
|
4057
4179
|
* Friday = "F" | "f"
|
|
4058
4180
|
* Saturday = "S" | "s"
|
|
@@ -4064,15 +4186,6 @@ class Weekdays {
|
|
|
4064
4186
|
static WEEKDAYS_STANDARD_ARRAY_EMPTY = ["m", "t", "w", "r", "f", "s", "u"];
|
|
4065
4187
|
static WEEKDAYS_STANDARD_STRING_FULL = "MTWRFSU";
|
|
4066
4188
|
static WEEKDAYS_STANDARD_STRING_EMPTY = "mtwrfsu";
|
|
4067
|
-
static WEEKDAYS_TO_USA_LETTER_FORMAT = new Map([
|
|
4068
|
-
["M", "M"],
|
|
4069
|
-
["T", "T"],
|
|
4070
|
-
["W", "W"],
|
|
4071
|
-
["R", "T"],
|
|
4072
|
-
["F", "F"],
|
|
4073
|
-
["S", "S"],
|
|
4074
|
-
["U", "S"]
|
|
4075
|
-
]);
|
|
4076
4189
|
static WEEKDAYS_TO_USA_SHORT_FORMAT = new Map([
|
|
4077
4190
|
["M", "Mon"],
|
|
4078
4191
|
["T", "Tue"],
|
|
@@ -4091,6 +4204,7 @@ class Weekdays {
|
|
|
4091
4204
|
5: "F",
|
|
4092
4205
|
6: "S"
|
|
4093
4206
|
};
|
|
4207
|
+
static DAY_NUMBER_BY_CODE = Object.fromEntries(Object.entries(Weekdays.WEEKDAY_MAP).map(([dayNumber, code]) => [code, Number(dayNumber)]));
|
|
4094
4208
|
days;
|
|
4095
4209
|
constructor(days = Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL) {
|
|
4096
4210
|
if (typeof days === "string")
|
|
@@ -4134,11 +4248,11 @@ class Weekdays {
|
|
|
4134
4248
|
toString() {
|
|
4135
4249
|
return this.days.join("").trim();
|
|
4136
4250
|
}
|
|
4137
|
-
toStringFormatted(limiters = { startExistingDay: "{",
|
|
4251
|
+
toStringFormatted(limiters = { startExistingDay: "{", endExistingDay: "}", startMissingDay: "(", endMissingDay: ")", separator: " " }, format = Weekdays.WEEKDAYS_TO_USA_SHORT_FORMAT) {
|
|
4138
4252
|
const result = new Array();
|
|
4139
4253
|
[...this.days].forEach((letter, index) => {
|
|
4140
4254
|
if (letter === letter.toUpperCase()) {
|
|
4141
|
-
result.push(limiters.startExistingDay + format.get(letter) + limiters.
|
|
4255
|
+
result.push(limiters.startExistingDay + format.get(letter) + limiters.endExistingDay);
|
|
4142
4256
|
}
|
|
4143
4257
|
else if (letter === letter.toLowerCase()) {
|
|
4144
4258
|
result.push(limiters.startMissingDay +
|
|
@@ -4158,33 +4272,77 @@ class Weekdays {
|
|
|
4158
4272
|
return this.toString() === Weekdays.WEEKDAYS_STANDARD_STRING_FULL;
|
|
4159
4273
|
}
|
|
4160
4274
|
static getFullWeek() {
|
|
4161
|
-
return Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL;
|
|
4275
|
+
return [...Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL];
|
|
4162
4276
|
}
|
|
4163
4277
|
static getEmptyWeek() {
|
|
4164
|
-
return Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY;
|
|
4278
|
+
return [...Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY];
|
|
4165
4279
|
}
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
if (
|
|
4176
|
-
|
|
4177
|
-
|
|
4280
|
+
/** A week with nothing selected. */
|
|
4281
|
+
static empty() {
|
|
4282
|
+
return new Weekdays(Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY);
|
|
4283
|
+
}
|
|
4284
|
+
/**
|
|
4285
|
+
* Like {@link fromString}, but yields an empty week instead of throwing on anything invalid.
|
|
4286
|
+
* For UI fed straight from a backend field that can arrive null, empty or partial.
|
|
4287
|
+
*/
|
|
4288
|
+
static tryFromString(value) {
|
|
4289
|
+
if (!value)
|
|
4290
|
+
return Weekdays.empty();
|
|
4291
|
+
try {
|
|
4292
|
+
return Weekdays.fromString(value);
|
|
4178
4293
|
}
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
updated.push(day.toLowerCase());
|
|
4294
|
+
catch {
|
|
4295
|
+
return Weekdays.empty();
|
|
4182
4296
|
}
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4297
|
+
}
|
|
4298
|
+
/** Selected flags in MTWRFSU order (Monday first). */
|
|
4299
|
+
toBooleans() {
|
|
4300
|
+
return this.days.map(day => day === day.toUpperCase());
|
|
4301
|
+
}
|
|
4302
|
+
/** @param flags selected flags in MTWRFSU order; missing entries count as unselected */
|
|
4303
|
+
static fromBooleans(flags) {
|
|
4304
|
+
return new Weekdays(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map((day, index) => flags[index] ? day : day.toLowerCase()));
|
|
4305
|
+
}
|
|
4306
|
+
/** 7-character mask in MTWRFSU order where "1" means selected, e.g. "1100100". */
|
|
4307
|
+
toMask() {
|
|
4308
|
+
return this.toBooleans().map(selected => (selected ? "1" : "0")).join("");
|
|
4309
|
+
}
|
|
4310
|
+
/** @param mask 7-character mask in MTWRFSU order where "1" means selected; a shorter, empty or
|
|
4311
|
+
* missing mask counts the absent days as unselected */
|
|
4312
|
+
static fromMask(mask) {
|
|
4313
|
+
return Weekdays.fromBooleans(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map((_, index) => mask?.[index] === "1"));
|
|
4314
|
+
}
|
|
4315
|
+
/** Selected days as Date.getDay() numbers (0 = Sunday), in MTWRFSU order. */
|
|
4316
|
+
toDayNumbers() {
|
|
4317
|
+
return this.days
|
|
4318
|
+
.filter(day => day === day.toUpperCase())
|
|
4319
|
+
.map(day => Weekdays.DAY_NUMBER_BY_CODE[day]);
|
|
4320
|
+
}
|
|
4321
|
+
/** @param days Date.getDay() numbers (0 = Sunday) */
|
|
4322
|
+
static fromDayNumbers(days) {
|
|
4323
|
+
const selected = new Set(days);
|
|
4324
|
+
return Weekdays.fromBooleans(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map(day => selected.has(Weekdays.DAY_NUMBER_BY_CODE[day])));
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
const CwWeekdaySelector = ({ value = "mtwrfsu", onChange, disabled = false, labelProps, layout, feedback, locale = "en-GB", className }) => {
|
|
4329
|
+
const selectedDays = Weekdays.tryFromString(value).toArray();
|
|
4330
|
+
const dayNames = useMemo(() => getWeekdayNames(locale), [locale]);
|
|
4331
|
+
const handleChange = (day, checked) => {
|
|
4332
|
+
const updated = selectedDays.filter(d => d !== day && d !== day.toLowerCase());
|
|
4333
|
+
updated.push(checked ? day : day.toLowerCase());
|
|
4334
|
+
onChange?.(new Weekdays(updated).toString());
|
|
4186
4335
|
};
|
|
4187
|
-
|
|
4336
|
+
const feedbackMessages = feedback
|
|
4337
|
+
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4338
|
+
: [];
|
|
4339
|
+
const feedbackId = useId();
|
|
4340
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4341
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4342
|
+
// Points at the label element rather than copying its text, which also covers a labelProps that
|
|
4343
|
+
// carries children instead of `text`.
|
|
4344
|
+
const labelId = labelProps?.id ?? `${feedbackId}-label`;
|
|
4345
|
+
return (jsxs("div", { className: `cw-weekday-selector ${styles$g.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsx("div", { role: "group", className: styles$g.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4188
4346
|
};
|
|
4189
4347
|
|
|
4190
4348
|
var styles$f = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
|
|
@@ -4232,6 +4390,9 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4232
4390
|
const feedbackMessages = feedback
|
|
4233
4391
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4234
4392
|
: [];
|
|
4393
|
+
const feedbackId = useId();
|
|
4394
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4395
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4235
4396
|
// Effective layout — precedence: new `groupLayout`/`itemLayout` > legacy-derived > default.
|
|
4236
4397
|
// Legacy `alignProps.flexDirection` drove the label-vs-options axis (default "row" = label
|
|
4237
4398
|
// beside the options); map it to `groupLayout.direction`.
|
|
@@ -4244,7 +4405,7 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4244
4405
|
?? (optionsAlignment === "column" ? "row" : "column");
|
|
4245
4406
|
// Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
|
|
4246
4407
|
const checkDirection = itemDirection === "row" ? "column" : "row";
|
|
4247
|
-
return (jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-
|
|
4408
|
+
return (jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4248
4409
|
}
|
|
4249
4410
|
|
|
4250
4411
|
var styles$e = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
|
|
@@ -4271,11 +4432,14 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
|
|
|
4271
4432
|
const feedbackMessages = feedback
|
|
4272
4433
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4273
4434
|
: [];
|
|
4435
|
+
const feedbackId = useId();
|
|
4436
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4437
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4274
4438
|
// Each radio's circle-to-text layout is the opposite of the options flow: a stacked list
|
|
4275
4439
|
// (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
|
|
4276
4440
|
// best with the circle above the text.
|
|
4277
4441
|
const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
|
|
4278
|
-
return (jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$e.options, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-
|
|
4442
|
+
return (jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$e.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4279
4443
|
}
|
|
4280
4444
|
|
|
4281
4445
|
function CwToggle(props) {
|
|
@@ -4455,6 +4619,13 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
|
|
|
4455
4619
|
const feedbackMessages = feedback
|
|
4456
4620
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4457
4621
|
: [];
|
|
4622
|
+
const feedbackId = useId();
|
|
4623
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4624
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4625
|
+
// The trigger is named by reference - the label for the field, the content for the current
|
|
4626
|
+
// value - so neither has to be copied into a string.
|
|
4627
|
+
const labelId = labelProps?.id ?? `${feedbackId}-label`;
|
|
4628
|
+
const valueId = `${feedbackId}-value`;
|
|
4458
4629
|
// Scroll highlighted item into view
|
|
4459
4630
|
useEffect(() => {
|
|
4460
4631
|
if (isOpen && highlightedItemRef.current) {
|
|
@@ -4523,12 +4694,12 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
|
|
|
4523
4694
|
}
|
|
4524
4695
|
}, [isOpen, highlightedIndex, filteredOptions, handleOptionSelect]);
|
|
4525
4696
|
const flexDirection = alignProps?.flexDirection ?? "row";
|
|
4526
|
-
return (
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4697
|
+
return (jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsxs("div", { className: dropdownStyles.value, children: [jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxs(Fragment, { children: [selectedOption.color && (jsx("span", { className: dropdownStyles.colorCircle, style: { backgroundColor: selectedOption.color } })), jsx("span", { children: selectedOption.label })] })) : (jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxs("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsx("div", { className: dropdownStyles.searchBox, children: jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: dropdownStyles.searchInput, autoComplete: "off" }) })), jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
|
|
4698
|
+
dropdownStyles.option,
|
|
4699
|
+
value === option.value ? dropdownStyles.optionSelected : "",
|
|
4700
|
+
highlightedIndex === index ? dropdownStyles.optionFocused : "",
|
|
4701
|
+
option.disabled ? dropdownStyles.optionDisabled : "",
|
|
4702
|
+
].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsx("span", { className: dropdownStyles.colorCircle, style: { backgroundColor: option.color } })), jsx("span", { children: option.label })] }, option.value)))) : (jsx("li", { className: dropdownStyles.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
|
|
4532
4703
|
}
|
|
4533
4704
|
|
|
4534
4705
|
function CwDropdownFilter(props) {
|
|
@@ -4936,7 +5107,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4936
5107
|
} }, props.ID))) })] }))] }));
|
|
4937
5108
|
};
|
|
4938
5109
|
|
|
4939
|
-
var styles$a = {"container":"cw-tag-selector-module__container__-do8i","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
|
|
5110
|
+
var styles$a = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
|
|
4940
5111
|
|
|
4941
5112
|
/**
|
|
4942
5113
|
* Multi-select input with chip tags and searchable dropdown.
|
|
@@ -5071,8 +5242,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
|
|
|
5071
5242
|
// Keeping containerRef for any other potential use
|
|
5072
5243
|
const direction = alignProps?.flexDirection ?? "row";
|
|
5073
5244
|
const feedbackMessages = feedback ? (Array.isArray(feedback) ? feedback : [feedback]) : [];
|
|
5074
|
-
|
|
5075
|
-
|
|
5245
|
+
const feedbackId = useId();
|
|
5246
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
5247
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
5248
|
+
return (jsxs("div", { ref: containerRef, className: `${styles$a.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: styles$a.value, children: [jsxs("div", { className: `${styles$a.inputBox}${disabled ? ` ${styles$a.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
|
|
5249
|
+
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$a.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$a.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxs("li", { className: `${styles$a.option}${idx === focusedIndex ? ` ${styles$a.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsx("span", { className: styles$a.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
|
|
5076
5250
|
}
|
|
5077
5251
|
|
|
5078
5252
|
var styles$9 = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
|
|
@@ -6083,7 +6257,7 @@ function CwBtnCancel({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...res
|
|
|
6083
6257
|
return (jsx(CwButton, { ...rest, variant: "icon", icon: "cancel", color: "danger", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled, title: "Cancel" }));
|
|
6084
6258
|
}
|
|
6085
6259
|
|
|
6086
|
-
var styles$4 = {"pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
|
|
6260
|
+
var styles$4 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
|
|
6087
6261
|
|
|
6088
6262
|
/**
|
|
6089
6263
|
* Renders a picker popup in a portal so it escapes overflow containers.
|
|
@@ -6140,6 +6314,9 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
6140
6314
|
const feedbackMessages = feedback
|
|
6141
6315
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
6142
6316
|
: [];
|
|
6317
|
+
const feedbackId = useId();
|
|
6318
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
6319
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
6143
6320
|
const wrapperRef = useRef(null);
|
|
6144
6321
|
const inputRef = useRef(null);
|
|
6145
6322
|
const prevValueRef = useRef(undefined);
|
|
@@ -6320,11 +6497,11 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
6320
6497
|
...(maxDate ? [{ after: maxDate }] : []),
|
|
6321
6498
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
6322
6499
|
], [disabledDates, minDate, maxDate, disabledMatcher]);
|
|
6323
|
-
return (
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6500
|
+
return (jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [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, "aria-describedby": describedBy, required: required, size: displayFormat.length }), 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, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
6501
|
+
today: new Date(),
|
|
6502
|
+
}, modifiersClassNames: {
|
|
6503
|
+
today: "rdp-day-today",
|
|
6504
|
+
} }), 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", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) }));
|
|
6328
6505
|
}
|
|
6329
6506
|
|
|
6330
6507
|
var rangeStyles = {"rangeWrapper":"cw-range-picker-module__rangeWrapper__1nIVs","rangePopup":"cw-range-picker-module__rangePopup__E5jd1","rangeCalendarRow":"cw-range-picker-module__rangeCalendarRow__VTxi0","presetList":"cw-range-picker-module__presetList__INiLo","rangeError":"cw-range-picker-module__rangeError__qHMdi"};
|
|
@@ -6963,14 +7140,14 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
|
|
|
6963
7140
|
}
|
|
6964
7141
|
return undefined;
|
|
6965
7142
|
}, [value]);
|
|
6966
|
-
return (jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
|
|
7143
|
+
return (jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
|
|
6967
7144
|
today: new Date(),
|
|
6968
7145
|
}, modifiersClassNames: {
|
|
6969
7146
|
today: "rdp-day-today",
|
|
6970
7147
|
} })] }), jsx("div", { role: "alert", "aria-live": "polite", className: rangeStyles.rangeError, children: rangeErrorMessage })] }))] })] }) }));
|
|
6971
7148
|
}
|
|
6972
7149
|
|
|
6973
|
-
var timeStyles = {"timePickerPopup":"cw-time-picker-module__timePickerPopup__BN63t","timePickerList":"cw-time-picker-module__timePickerList__E88pr","selected":"cw-time-picker-module__selected__qVnfL","
|
|
7150
|
+
var timeStyles = {"timePickerPopup":"cw-time-picker-module__timePickerPopup__BN63t","timePickerList":"cw-time-picker-module__timePickerList__E88pr","selected":"cw-time-picker-module__selected__qVnfL","field":"cw-time-picker-module__field__kPvGN","narrow":"cw-time-picker-module__narrow__Z7lCI"};
|
|
6974
7151
|
|
|
6975
7152
|
const isMobileDevice = () => {
|
|
6976
7153
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
@@ -7132,7 +7309,7 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
7132
7309
|
return (jsx("div", { className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$4.pickerWrapper, children: jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, className: "cw-timepicker-native" }) })] }) }));
|
|
7133
7310
|
}
|
|
7134
7311
|
// Custom time picker
|
|
7135
|
-
return (jsx("div", { ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper
|
|
7312
|
+
return (jsx("div", { ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: `${styles$4.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 5 }), showClear && (jsx("div", { className: styles$4.pickerIcons, children: value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsx("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
|
|
7136
7313
|
const isSelected = time === value;
|
|
7137
7314
|
return (jsx("button", { ref: isSelected ? selectedItemRef : null, type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
|
|
7138
7315
|
}) }) }))] })] }) }));
|
|
@@ -7798,6 +7975,9 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
|
|
|
7798
7975
|
const feedbackMessages = feedback
|
|
7799
7976
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
7800
7977
|
: [];
|
|
7978
|
+
const feedbackId = useId();
|
|
7979
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
7980
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
7801
7981
|
const wrapperRef = useRef(null);
|
|
7802
7982
|
const inputRef = useRef(null);
|
|
7803
7983
|
const prevValueRef = useRef(undefined);
|
|
@@ -7904,11 +8084,11 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
|
|
|
7904
8084
|
const defaultMonthJsDate = defaultMonth
|
|
7905
8085
|
? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
|
|
7906
8086
|
: selectedJsDate;
|
|
7907
|
-
return (
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
8087
|
+
return (jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [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, "aria-describedby": describedBy, required: required, size: displayFormat.length }), 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: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8088
|
+
today: new Date(),
|
|
8089
|
+
}, modifiersClassNames: {
|
|
8090
|
+
today: "rdp-day-today",
|
|
8091
|
+
} }), 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", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) }));
|
|
7912
8092
|
}
|
|
7913
8093
|
|
|
7914
8094
|
// DateTimePickerState - immutable domain model for the Temporal date-time picker.
|
|
@@ -8646,1073 +8826,13 @@ function CwDateRangePickerTemporal({ value, onChange, minDate, maxDate, disabled
|
|
|
8646
8826
|
const defaultMonthJsDate = defaultMonth
|
|
8647
8827
|
? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
|
|
8648
8828
|
: (value?.from ? plainDateToJsDate(value.from) : undefined);
|
|
8649
|
-
return (jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8829
|
+
return (jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8650
8830
|
today: new Date(),
|
|
8651
8831
|
}, modifiersClassNames: {
|
|
8652
8832
|
today: "rdp-day-today",
|
|
8653
8833
|
} })] }), jsx("div", { role: "alert", "aria-live": "polite", className: rangeStyles.rangeError, children: rangeErrorMessage })] }))] })] }) }));
|
|
8654
8834
|
}
|
|
8655
8835
|
|
|
8656
|
-
const ResourcesTitleList = ({ resources, canBePinned, includesPinned, onCrewPinning, onClickResourceContextMenu, ResourceTitleComponent, }) => {
|
|
8657
|
-
const onClickContextMenu = useCallback((key, resource) => {
|
|
8658
|
-
if (onClickResourceContextMenu) {
|
|
8659
|
-
onClickResourceContextMenu(key, resource);
|
|
8660
|
-
}
|
|
8661
|
-
}, []);
|
|
8662
|
-
return (jsx("td", { className: "resourceArea", style: { width: "100px" }, children: resources.map((r, _i) => (jsxs("div", { className: "resource CwelltFunctionDescription", style: { height: r.maxTop }, children: [(canBePinned || includesPinned) && (jsx(PinButton, { canBePinned: canBePinned, resource: r, onCrewPinning: onCrewPinning })), jsx(ResourceTitleComponent, { resource: r, handleOnClickResourceContextMenu: onClickContextMenu })] }, r.id.toString()))) }));
|
|
8663
|
-
};
|
|
8664
|
-
const PinButton = ({ canBePinned, resource, onCrewPinning }) => {
|
|
8665
|
-
const buttonProps = canBePinned
|
|
8666
|
-
? {
|
|
8667
|
-
id: "cbl_pinL",
|
|
8668
|
-
onClick: () => onCrewPinning(resource, ""),
|
|
8669
|
-
children: jsx("span", { className: "cwi-pin", style: { visibility: "visible" } }),
|
|
8670
|
-
}
|
|
8671
|
-
: {
|
|
8672
|
-
id: "cbl_pinLess45deg",
|
|
8673
|
-
onClick: () => onCrewPinning(resource, "remove"),
|
|
8674
|
-
children: jsx("span", { className: "cwi-pinned cwi-pin", style: { visibility: "visible" } }),
|
|
8675
|
-
};
|
|
8676
|
-
return jsx("button", { className: "cw-button-icon cw-icon-pin", ...buttonProps });
|
|
8677
|
-
};
|
|
8678
|
-
|
|
8679
|
-
const addMinutesToDateFromPx = (originalDate, leftPx, minutesPerPx) => {
|
|
8680
|
-
const minutes = leftPx / minutesPerPx;
|
|
8681
|
-
const datePlusMinutes = new Date(originalDate.getTime() + minutes * 60000);
|
|
8682
|
-
return datePlusMinutes;
|
|
8683
|
-
};
|
|
8684
|
-
|
|
8685
|
-
const doubleClickOnResource = (props, resource) => {
|
|
8686
|
-
if (props.scheduler_handleDblClickOnResourceInScheduler) {
|
|
8687
|
-
props.scheduler_handleDblClickOnResourceInScheduler(resource);
|
|
8688
|
-
}
|
|
8689
|
-
};
|
|
8690
|
-
|
|
8691
|
-
let CblDragAndDrop$1 = class CblDragAndDrop {
|
|
8692
|
-
fromId;
|
|
8693
|
-
toId;
|
|
8694
|
-
data;
|
|
8695
|
-
droppedOnDate;
|
|
8696
|
-
resizeFromStart;
|
|
8697
|
-
resizeFromEnd;
|
|
8698
|
-
isCtrlKey;
|
|
8699
|
-
constructor(fromId, toId, data, droppedOnDate = null, resizeFromStart = null, resizeFromEnd = null, isCtrlKey = null) {
|
|
8700
|
-
this.fromId = fromId;
|
|
8701
|
-
this.toId = toId;
|
|
8702
|
-
this.data = data;
|
|
8703
|
-
this.droppedOnDate = droppedOnDate;
|
|
8704
|
-
this.resizeFromStart = resizeFromStart;
|
|
8705
|
-
this.resizeFromEnd = resizeFromEnd;
|
|
8706
|
-
this.isCtrlKey = isCtrlKey;
|
|
8707
|
-
}
|
|
8708
|
-
};
|
|
8709
|
-
|
|
8710
|
-
const BIRTHDATE = 15;
|
|
8711
|
-
const NOT_WORKING = 16;
|
|
8712
|
-
const REST_TIME = 10;
|
|
8713
|
-
const MAX_FLIGHT_DUTY_PERIOD = 11;
|
|
8714
|
-
const DUTY_REGULATION = 20;
|
|
8715
|
-
const unHandleableEvents = [REST_TIME, MAX_FLIGHT_DUTY_PERIOD, NOT_WORKING, DUTY_REGULATION];
|
|
8716
|
-
const getEventStyle = (event, reslTime) => {
|
|
8717
|
-
const baseStyle = {
|
|
8718
|
-
left: event.leftPx,
|
|
8719
|
-
width: event.width,
|
|
8720
|
-
top: event.top,
|
|
8721
|
-
overflow: "hidden",
|
|
8722
|
-
zIndex: event.isFullHeight ? 4 : 5,
|
|
8723
|
-
};
|
|
8724
|
-
if (event.data.eventType === BIRTHDATE) {
|
|
8725
|
-
return {
|
|
8726
|
-
...baseStyle,
|
|
8727
|
-
height: event.isFullHeight ? "100%" : "auto",
|
|
8728
|
-
marginTop: event.isFullHeight ? -1 * event.top : 0,
|
|
8729
|
-
pointerEvents: "none",
|
|
8730
|
-
borderBottom: "solid 1px rgba(0, 0, 0, 0.4)",
|
|
8731
|
-
backgroundColor: event.data.category.color || "orange",
|
|
8732
|
-
display: "flex",
|
|
8733
|
-
opacity: 0.3,
|
|
8734
|
-
alignItems: "flex-end",
|
|
8735
|
-
};
|
|
8736
|
-
}
|
|
8737
|
-
if ([REST_TIME, MAX_FLIGHT_DUTY_PERIOD, DUTY_REGULATION].includes(event.data.eventType)) {
|
|
8738
|
-
return {
|
|
8739
|
-
...baseStyle,
|
|
8740
|
-
zIndex: event.isFullHeight ? 4 : 6,
|
|
8741
|
-
marginTop: event.isFullHeight ? -1 * event.top : 0,
|
|
8742
|
-
borderRadius: "0px",
|
|
8743
|
-
backgroundColor: event.data.category.color || "grey",
|
|
8744
|
-
opacity: 0.3,
|
|
8745
|
-
borderBottom: event.data.eventType === DUTY_REGULATION ? "solid 1px rgba(0, 0, 0, 0.4)" : "",
|
|
8746
|
-
};
|
|
8747
|
-
}
|
|
8748
|
-
return {
|
|
8749
|
-
...baseStyle,
|
|
8750
|
-
height: event.isFullHeight ? "100%" : "auto",
|
|
8751
|
-
marginTop: event.isFullHeight ? -1 * event.top : 0,
|
|
8752
|
-
borderRadius: reslTime <= 0.99 ? "3px" : "5px",
|
|
8753
|
-
minWidth: reslTime <= 1.5 ? "5px" : "",
|
|
8754
|
-
maxWidth: reslTime <= 1.5 ? "25px" : "",
|
|
8755
|
-
};
|
|
8756
|
-
};
|
|
8757
|
-
const EventRender = ({ event, schedulerProps }) => {
|
|
8758
|
-
const dateStart = new Date(event.data.start);
|
|
8759
|
-
const dateEnd = new Date(event.data.end);
|
|
8760
|
-
const reslTime = (dateEnd.getTime() - dateStart.getTime()) / 3600000;
|
|
8761
|
-
const eventStyle = getEventStyle(event, reslTime);
|
|
8762
|
-
const onClickEvent = (e) => {
|
|
8763
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8764
|
-
e.stopPropagation();
|
|
8765
|
-
const props = schedulerProps;
|
|
8766
|
-
props.scheduler_handleCblEventClick.call(props.parent, event, schedulerProps.id);
|
|
8767
|
-
}
|
|
8768
|
-
};
|
|
8769
|
-
const onRightClickEvent = (e) => {
|
|
8770
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8771
|
-
e.stopPropagation();
|
|
8772
|
-
const props = schedulerProps;
|
|
8773
|
-
if (props.scheduler_handleCblEventClickRight) {
|
|
8774
|
-
props.scheduler_handleCblEventClickRight.call(props.parent, event, schedulerProps.id);
|
|
8775
|
-
}
|
|
8776
|
-
}
|
|
8777
|
-
};
|
|
8778
|
-
const safeHandleDragStart = (e, isLeft, isRight) => {
|
|
8779
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8780
|
-
handleDragStart(e, isLeft, isRight);
|
|
8781
|
-
}
|
|
8782
|
-
};
|
|
8783
|
-
const handleDragStart = (e, isResizeFromStart, isResizeFromEnd) => {
|
|
8784
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8785
|
-
[].forEach.call(document.querySelectorAll(".ant-tooltip"), function (el) {
|
|
8786
|
-
el.style.visibility = "hidden";
|
|
8787
|
-
});
|
|
8788
|
-
// We don't know in which case is necessary
|
|
8789
|
-
if (e.target !== e.currentTarget) {
|
|
8790
|
-
// e.preventDefault();
|
|
8791
|
-
return;
|
|
8792
|
-
}
|
|
8793
|
-
const isResize = isResizeFromStart || isResizeFromEnd;
|
|
8794
|
-
const isAllowed = !event.isReadOnly && (isResize ? event.isResizable : event.isDraggable);
|
|
8795
|
-
if (!isAllowed) {
|
|
8796
|
-
e.preventDefault();
|
|
8797
|
-
return;
|
|
8798
|
-
}
|
|
8799
|
-
const cblDragNDrop = new CblDragAndDrop$1(schedulerProps.id, null, [event], null, isResizeFromStart, isResizeFromEnd);
|
|
8800
|
-
if (!isResize) {
|
|
8801
|
-
e.dataTransfer.dropEffect = e.ctrlKey ? "copy" : "link";
|
|
8802
|
-
}
|
|
8803
|
-
e.dataTransfer.setData("data", JSON.stringify(cblDragNDrop));
|
|
8804
|
-
}
|
|
8805
|
-
};
|
|
8806
|
-
const handleDoubleClick = (e) => {
|
|
8807
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8808
|
-
e.preventDefault();
|
|
8809
|
-
e.stopPropagation();
|
|
8810
|
-
const props = schedulerProps;
|
|
8811
|
-
props.scheduler_handleCblEventDoubleClick.call(props.parent, event, schedulerProps.id);
|
|
8812
|
-
}
|
|
8813
|
-
};
|
|
8814
|
-
const onClickContextMenu = (e) => {
|
|
8815
|
-
if (!unHandleableEvents.includes(event.data.eventType)) {
|
|
8816
|
-
const props = schedulerProps;
|
|
8817
|
-
if (props.scheduler_handleOnClickEventContextMenu) {
|
|
8818
|
-
props.scheduler_handleOnClickEventContextMenu(e, event);
|
|
8819
|
-
}
|
|
8820
|
-
}
|
|
8821
|
-
};
|
|
8822
|
-
const renderBirthdayEvent = () => (jsxs("div", { className: `fc-timeline-event cwellt_timeline_event cwellt_event_bday ${event.selected ? "cblEventSelected" : ""}`, style: eventStyle, children: [jsx("span", { className: "cwi-icons cwi-birthday", style: { visibility: "visible" } }), event.data.subject && jsx("span", { style: { lineHeight: "1em" }, children: event.data.subject })] }, event.id));
|
|
8823
|
-
const renderRegularEvent = () => (jsxs("div", { draggable: ![10, 11, 16, 20, 21].includes(event.data.eventType), className: "fc-timeline-event cwellt_timeline_event " +
|
|
8824
|
-
(event.selected === true ? "cblEventSelected " : "") +
|
|
8825
|
-
(event.data.eventType === REST_TIME ||
|
|
8826
|
-
event.data.eventType === MAX_FLIGHT_DUTY_PERIOD ||
|
|
8827
|
-
event.data.eventType === DUTY_REGULATION
|
|
8828
|
-
? " cwellt_event_bhnd_appt "
|
|
8829
|
-
: " "), style: eventStyle, onClick: onClickEvent, onContextMenu: onRightClickEvent, onDragStart: (e) => safeHandleDragStart(e, false, false), onDoubleClick: handleDoubleClick, children: [schedulerProps.scheduler_handleCblEventResize &&
|
|
8830
|
-
!event.isReadOnly &&
|
|
8831
|
-
!unHandleableEvents.includes(event.data.eventType) && (jsx("span", { draggable: true, onDragStart: (e) => handleDragStart(e, true, false), style: {
|
|
8832
|
-
position: "absolute",
|
|
8833
|
-
cursor: "e-resize",
|
|
8834
|
-
zIndex: 10,
|
|
8835
|
-
left: "0",
|
|
8836
|
-
border: "solid 1px rgba(46,49,49,0.5)",
|
|
8837
|
-
}, children: "\u200B" })), jsx(schedulerProps.cblEventComp, { cblEvent: event, handleOnClickEventContextMenu: onClickContextMenu }, event.id), schedulerProps.scheduler_handleCblEventResize &&
|
|
8838
|
-
!event.isReadOnly &&
|
|
8839
|
-
!unHandleableEvents.includes(event.data.eventType) && (jsx("span", { draggable: true, onDragStart: (e) => handleDragStart(e, false, true), style: {
|
|
8840
|
-
position: "absolute",
|
|
8841
|
-
right: "0",
|
|
8842
|
-
cursor: "e-resize",
|
|
8843
|
-
zIndex: 10,
|
|
8844
|
-
border: "solid 1px rgba(46,49,49,0.5)",
|
|
8845
|
-
marginTop: "-25px",
|
|
8846
|
-
}, children: "\u200B" }))] }, event.id));
|
|
8847
|
-
const render = event.data.eventType === BIRTHDATE ? renderBirthdayEvent() : renderRegularEvent();
|
|
8848
|
-
return render;
|
|
8849
|
-
};
|
|
8850
|
-
|
|
8851
|
-
const onDropEventToResource = (props, cblDragNDrop, resource) => {
|
|
8852
|
-
props.scheduler_handleOnDropCblEventsOnResource.call(props.parent, cblDragNDrop, resource);
|
|
8853
|
-
};
|
|
8854
|
-
|
|
8855
|
-
const isAllowedToMove = (data, resData, cblDragNDrop) => {
|
|
8856
|
-
if (data?.eventType !== 1) {
|
|
8857
|
-
return true;
|
|
8858
|
-
}
|
|
8859
|
-
const allowedMoves = [
|
|
8860
|
-
{ from: "acftsScheduler", to: "flightsPairingsScheduler" },
|
|
8861
|
-
{ from: "flightsScheduler", to: "crewAssignmentsScheduler" },
|
|
8862
|
-
{ from: "opstoolScheduler", to: "opstoolScheduler" },
|
|
8863
|
-
{ from: "opstoolScheduler", to: "opstoolSchedulerVirtual" },
|
|
8864
|
-
{ from: "opstoolSchedulerVirtual", to: "opstoolScheduler" },
|
|
8865
|
-
{ from: "opstoolSchedulerVirtual", to: "opstoolSchedulerVirtual" },
|
|
8866
|
-
{ from: "vacationsScheduler", to: "vacationsScheduler" }
|
|
8867
|
-
];
|
|
8868
|
-
const crewControllAllowedMove = allowedMoves.some(move => move.from === cblDragNDrop.fromId && move.to === cblDragNDrop.toId);
|
|
8869
|
-
if (crewControllAllowedMove) {
|
|
8870
|
-
return true;
|
|
8871
|
-
}
|
|
8872
|
-
return data.Crew !== resData.Crewmember_Id;
|
|
8873
|
-
};
|
|
8874
|
-
|
|
8875
|
-
const OnDrop = ({ e, resource, id, contentArea, state, schedulerProps }) => {
|
|
8876
|
-
e.dataTransfer.dropEffect = "move";
|
|
8877
|
-
const cblDragNDrop = JSON.parse(e.dataTransfer.getData("data"));
|
|
8878
|
-
if (!cblDragNDrop.data || !cblDragNDrop.data[0]) {
|
|
8879
|
-
return;
|
|
8880
|
-
}
|
|
8881
|
-
cblDragNDrop.toId = id;
|
|
8882
|
-
const obj = cblDragNDrop.data[0];
|
|
8883
|
-
cblDragNDrop.isCtrlKey = e.ctrlKey;
|
|
8884
|
-
const isResizeEvent = cblDragNDrop.resizeFromStart === true || cblDragNDrop.resizeFromEnd === true;
|
|
8885
|
-
if (isResizeEvent) {
|
|
8886
|
-
// Resize
|
|
8887
|
-
if (obj.data === undefined || obj.data.eventType === 1) {
|
|
8888
|
-
return;
|
|
8889
|
-
}
|
|
8890
|
-
const _eventX = e.clientX;
|
|
8891
|
-
const _caLeft = contentArea?.getBoundingClientRect()?.left ?? 0;
|
|
8892
|
-
const leftPos = _eventX - _caLeft;
|
|
8893
|
-
let droppedDate = addMinutesToDateFromPx(schedulerProps.startDate, leftPos, state.minutePx);
|
|
8894
|
-
if (cblDragNDrop.resizeFromEnd === true) {
|
|
8895
|
-
const eventStart = new Date(Date.parse(obj.start));
|
|
8896
|
-
droppedDate = droppedDate < eventStart ? eventStart : droppedDate;
|
|
8897
|
-
}
|
|
8898
|
-
if (cblDragNDrop.resizeFromStart === true) {
|
|
8899
|
-
const eventEnd = new Date(Date.parse(obj.end));
|
|
8900
|
-
// 3 hours before is the minimun size in the backend
|
|
8901
|
-
eventEnd.setHours(eventEnd.getHours() - 3);
|
|
8902
|
-
droppedDate = droppedDate > eventEnd ? eventEnd : droppedDate;
|
|
8903
|
-
}
|
|
8904
|
-
cblDragNDrop.droppedOnDate = droppedDate;
|
|
8905
|
-
schedulerProps.scheduler_handleCblEventResize?.call(schedulerProps.parent, cblDragNDrop);
|
|
8906
|
-
return;
|
|
8907
|
-
}
|
|
8908
|
-
// Drag & Drop
|
|
8909
|
-
if (!isAllowedToMove(obj.data, resource.data, cblDragNDrop)) {
|
|
8910
|
-
return;
|
|
8911
|
-
}
|
|
8912
|
-
const d = e.clientX - (contentArea?.getBoundingClientRect()?.left ?? 0);
|
|
8913
|
-
const date = new Date(schedulerProps.startDate.getTime() + (d / state.minutePx) * 60000);
|
|
8914
|
-
cblDragNDrop.droppedOnDate = date;
|
|
8915
|
-
onDropEventToResource(schedulerProps, cblDragNDrop, resource);
|
|
8916
|
-
};
|
|
8917
|
-
|
|
8918
|
-
const onDragOver = (e) => {
|
|
8919
|
-
if (e.ctrlKey === true) {
|
|
8920
|
-
e.dataTransfer.dropEffect = "copy";
|
|
8921
|
-
}
|
|
8922
|
-
else {
|
|
8923
|
-
e.dataTransfer.dropEffect = "link";
|
|
8924
|
-
}
|
|
8925
|
-
e.preventDefault();
|
|
8926
|
-
};
|
|
8927
|
-
|
|
8928
|
-
const arePropsEqual = (prevProps, nextProps) => {
|
|
8929
|
-
return prevProps.res.events === nextProps.res.events && prevProps.isInViewport === nextProps.isInViewport;
|
|
8930
|
-
};
|
|
8931
|
-
const ResourceRender = memo(({ res, schedulerProps, contentArea, state }) => {
|
|
8932
|
-
return (jsx("div", { style: {
|
|
8933
|
-
backgroundColor: "#F9F8F8",
|
|
8934
|
-
height: res.maxTop,
|
|
8935
|
-
width: "100%",
|
|
8936
|
-
position: "relative",
|
|
8937
|
-
borderBottom: "1px solid rgb(255,255,255)",
|
|
8938
|
-
}, onDragOver: (e) => onDragOver(e), onDrop: (e) => {
|
|
8939
|
-
OnDrop({
|
|
8940
|
-
e,
|
|
8941
|
-
resource: res,
|
|
8942
|
-
id: schedulerProps.id,
|
|
8943
|
-
contentArea,
|
|
8944
|
-
state,
|
|
8945
|
-
schedulerProps,
|
|
8946
|
-
});
|
|
8947
|
-
}, className: "cwellt_divRow_schContent", children: res.events.map((evnt) => (jsx(EventRender, { event: evnt, schedulerProps: schedulerProps }, evnt.id))) }, res.id));
|
|
8948
|
-
}, arePropsEqual);
|
|
8949
|
-
|
|
8950
|
-
const ResourceListRender = ({ resources, schedulerProps, state, contentArea,
|
|
8951
|
-
// onClickContextMenu,
|
|
8952
|
-
crewAssignmentSchedulerContextMenu, }) => {
|
|
8953
|
-
return (jsx(Fragment$1, { children: resources.map((r, _i) => (jsx(CwAnchoredMenu, { placement: "bottom", onContextMenu: (e) => {
|
|
8954
|
-
// Dirty temporal solution to remove ANT design, this can be killed when this scheduler is deprecated
|
|
8955
|
-
const leftPos = e.currentTarget.getBoundingClientRect().left -
|
|
8956
|
-
(contentArea?.getBoundingClientRect()?.left ?? 0) -
|
|
8957
|
-
window.scrollX;
|
|
8958
|
-
const calculatedDatetime = addMinutesToDateFromPx(schedulerProps.startDate, leftPos, state.minutePx);
|
|
8959
|
-
r.__contextMenuDatetime = calculatedDatetime;
|
|
8960
|
-
}, options: crewAssignmentSchedulerContextMenu?.map(m => ({
|
|
8961
|
-
key: m.key,
|
|
8962
|
-
label: (jsxs(Fragment, { children: [jsx("span", { className: m.icon, style: { color: m.color } }), jsx("span", { children: m.text })] }))
|
|
8963
|
-
})) ?? [], onSelect: (key) => {
|
|
8964
|
-
const datetime = r.__contextMenuDatetime ?? new Date();
|
|
8965
|
-
if (schedulerProps.scheduler_handleOnClickContextMenuResource) {
|
|
8966
|
-
schedulerProps.scheduler_handleOnClickContextMenuResource(datetime, r, key, schedulerProps.id);
|
|
8967
|
-
}
|
|
8968
|
-
}, children: jsx("span", { onDoubleClick: () => doubleClickOnResource(schedulerProps, r), id: schedulerProps.id + "_" + r.id, children: jsx(ResourceRender, { res: r, schedulerProps: schedulerProps, contentArea: contentArea, state: state, isInViewport: r.isInViewport }, r.id) }) }, r.id))) }));
|
|
8969
|
-
};
|
|
8970
|
-
|
|
8971
|
-
const TimeLine$1 = ({ id, toolTipTitle, marginLeft, color = "rgba(255,0,0,.6)", pixels = 2, height = "100%", zIndex = 1, }) => {
|
|
8972
|
-
return (jsx(CwTooltipNew, { content: toolTipTitle, position: "top", children: jsx("div", { id: id, style: {
|
|
8973
|
-
borderLeft: `${pixels}px solid ${color}`,
|
|
8974
|
-
marginLeft: marginLeft,
|
|
8975
|
-
width: "0px",
|
|
8976
|
-
height: height,
|
|
8977
|
-
position: "absolute",
|
|
8978
|
-
zIndex: zIndex,
|
|
8979
|
-
} }) }));
|
|
8980
|
-
};
|
|
8981
|
-
|
|
8982
|
-
const SchedulerContentArea = ({ now, showTimeline, timeLineLeftPx, timeSeparatorLeftPx, resources, scheduler, contextMenuContents, onEmptyClick, setContentArea, onClickContextMenu, }) => {
|
|
8983
|
-
return (jsxs("td", { className: "contentArea", style: { width: "100%", overflow: "hidden", position: "relative" }, ref: (reference) => {
|
|
8984
|
-
if (reference) {
|
|
8985
|
-
setContentArea(reference);
|
|
8986
|
-
}
|
|
8987
|
-
}, children: [showTimeline && (jsx(TimeLine$1, { id: scheduler.props.id + "_timeline", marginLeft: timeLineLeftPx, zIndex: 8, toolTipTitle: Temporal.PlainTime.from({
|
|
8988
|
-
hour: now.getHours(),
|
|
8989
|
-
minute: now.getMinutes(),
|
|
8990
|
-
}).toString({ smallestUnit: "minute" }) })), timeSeparatorLeftPx.map((pixels) => {
|
|
8991
|
-
return jsx(TimeLine$1, { marginLeft: pixels, color: "rgba(255,255,255,0.7)" });
|
|
8992
|
-
}), jsx("span", { onClick: () => {
|
|
8993
|
-
if (onEmptyClick) {
|
|
8994
|
-
onEmptyClick(scheduler.props.id);
|
|
8995
|
-
}
|
|
8996
|
-
}, children: jsx(ResourceListRender, { resources: resources, state: scheduler.state, schedulerProps: scheduler.props, contentArea: scheduler.contentArea, onClickContextMenu: onClickContextMenu, crewAssignmentSchedulerContextMenu: contextMenuContents }) })] }));
|
|
8997
|
-
};
|
|
8998
|
-
|
|
8999
|
-
const daysBetweenTwoDates = (date1, date2) => {
|
|
9000
|
-
const diff = Math.abs(date1.getTime() - date2.getTime());
|
|
9001
|
-
let diffDays = 0;
|
|
9002
|
-
const startOffset = Math.abs(date1.getTimezoneOffset());
|
|
9003
|
-
const endOffset = Math.abs(date2.getTimezoneOffset());
|
|
9004
|
-
// Summer: +1 -> +2, true
|
|
9005
|
-
// Winter: +2 -> -1, false
|
|
9006
|
-
if (startOffset > endOffset) {
|
|
9007
|
-
diffDays = Math.floor(diff / (1000 * 3600 * 24));
|
|
9008
|
-
}
|
|
9009
|
-
else {
|
|
9010
|
-
diffDays = Math.ceil(diff / (1000 * 3600 * 24));
|
|
9011
|
-
}
|
|
9012
|
-
return diffDays;
|
|
9013
|
-
};
|
|
9014
|
-
|
|
9015
|
-
const calculateDivisionType = (start, end) => {
|
|
9016
|
-
const diffDays = daysBetweenTwoDates(start, end);
|
|
9017
|
-
if (diffDays <= 15) {
|
|
9018
|
-
return "d";
|
|
9019
|
-
}
|
|
9020
|
-
else if (diffDays <= 30) {
|
|
9021
|
-
return "w";
|
|
9022
|
-
}
|
|
9023
|
-
else {
|
|
9024
|
-
return "m";
|
|
9025
|
-
}
|
|
9026
|
-
};
|
|
9027
|
-
|
|
9028
|
-
const getMonthHeaderData = (dates, maxWidth) => {
|
|
9029
|
-
if (dates.length === 0)
|
|
9030
|
-
return [];
|
|
9031
|
-
const dayWidth = maxWidth / dates.length;
|
|
9032
|
-
const ranges = getMonthRanges(dates);
|
|
9033
|
-
return ranges.map((range) => {
|
|
9034
|
-
return {
|
|
9035
|
-
monthFormatted: range.start.getMonth() + 1 + "." + range.start.getFullYear(),
|
|
9036
|
-
width: dayWidth * range.daysLong,
|
|
9037
|
-
};
|
|
9038
|
-
});
|
|
9039
|
-
};
|
|
9040
|
-
const getMonthRanges = (dates) => {
|
|
9041
|
-
const firstDay = dates[0];
|
|
9042
|
-
const lastDay = dates[dates.length - 1];
|
|
9043
|
-
let currentDate = new Date(firstDay);
|
|
9044
|
-
const ranges = [];
|
|
9045
|
-
while (currentDate <= lastDay) {
|
|
9046
|
-
const rangeStart = new Date(currentDate);
|
|
9047
|
-
let rangeEnd = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
|
|
9048
|
-
if (rangeEnd >= lastDay) {
|
|
9049
|
-
rangeEnd = lastDay;
|
|
9050
|
-
}
|
|
9051
|
-
ranges.push({
|
|
9052
|
-
start: rangeStart,
|
|
9053
|
-
daysLong: getDaysBetweenDates(rangeStart, rangeEnd),
|
|
9054
|
-
});
|
|
9055
|
-
currentDate = new Date(rangeEnd.getFullYear(), rangeEnd.getMonth() + 1, 1);
|
|
9056
|
-
}
|
|
9057
|
-
return ranges;
|
|
9058
|
-
};
|
|
9059
|
-
const getDaysBetweenDates = (startDate, endDate) => {
|
|
9060
|
-
const timeDifference = endDate.getTime() - startDate.getTime();
|
|
9061
|
-
return Math.floor(timeDifference / (1000 * 60 * 60 * 24)) + 1;
|
|
9062
|
-
};
|
|
9063
|
-
|
|
9064
|
-
const getWeekHeaderDataFromWeekRange = (weekRange, maxWidth, dateFormatter) => weekRange.map(week => {
|
|
9065
|
-
const numberOfDaysInScheduler = weekRange
|
|
9066
|
-
.flatMap(element => {
|
|
9067
|
-
return element.days;
|
|
9068
|
-
})
|
|
9069
|
-
.reduce((el1, el2) => {
|
|
9070
|
-
return el1 + el2;
|
|
9071
|
-
});
|
|
9072
|
-
return {
|
|
9073
|
-
formattedString: getStringForWeekRange(week, dateFormatter),
|
|
9074
|
-
width: getWidthForWeekRange(maxWidth, week.days, numberOfDaysInScheduler)
|
|
9075
|
-
};
|
|
9076
|
-
});
|
|
9077
|
-
const getStringForWeekRange = (weekRange, dateFormatter) => weekRange.days == 1
|
|
9078
|
-
? dateFormatter(weekRange.start)
|
|
9079
|
-
: `${dateFormatter(weekRange.start)} - ${dateFormatter(weekRange.end)}`;
|
|
9080
|
-
const getWidthForWeekRange = (maxWidth, weekDays, monthDays) => {
|
|
9081
|
-
const dayWidth = maxWidth / monthDays;
|
|
9082
|
-
return dayWidth * weekDays;
|
|
9083
|
-
};
|
|
9084
|
-
|
|
9085
|
-
// stringRange: `${formatter(date)} - ${formatter(end)}`,
|
|
9086
|
-
const listOfDatesToWeekRangeList = (dates) => {
|
|
9087
|
-
if (dates.length === 0) {
|
|
9088
|
-
return [];
|
|
9089
|
-
}
|
|
9090
|
-
const datesToReturn = [];
|
|
9091
|
-
dates.forEach((date, index) => {
|
|
9092
|
-
const dayOfWeek = date.getDay();
|
|
9093
|
-
const isFirstDay = index === 0;
|
|
9094
|
-
const isLastDay = index === dates.length - 1;
|
|
9095
|
-
const isSunday = dayOfWeek === 0;
|
|
9096
|
-
const isMonday = dayOfWeek === 1;
|
|
9097
|
-
if (isFirstDay && !isSunday) {
|
|
9098
|
-
datesToReturn.push(createWeekRange(date, 8 - dayOfWeek));
|
|
9099
|
-
return;
|
|
9100
|
-
}
|
|
9101
|
-
if (isLastDay && !isSunday) {
|
|
9102
|
-
if (!isMonday) {
|
|
9103
|
-
datesToReturn.pop();
|
|
9104
|
-
}
|
|
9105
|
-
const firstOfWeek = getFirstDayOfWeek(date);
|
|
9106
|
-
datesToReturn.push(createWeekRange(firstOfWeek, dayOfWeek));
|
|
9107
|
-
return;
|
|
9108
|
-
}
|
|
9109
|
-
if (isMonday) {
|
|
9110
|
-
datesToReturn.push(createWeekRange(date, 7));
|
|
9111
|
-
return;
|
|
9112
|
-
}
|
|
9113
|
-
// this is because sunday is 0
|
|
9114
|
-
if (isFirstDay && isSunday) {
|
|
9115
|
-
datesToReturn.push(createWeekRange(date, 1));
|
|
9116
|
-
return;
|
|
9117
|
-
}
|
|
9118
|
-
});
|
|
9119
|
-
return datesToReturn;
|
|
9120
|
-
};
|
|
9121
|
-
const createWeekRange = (start, days) => {
|
|
9122
|
-
const end = new Date(start);
|
|
9123
|
-
end.setDate(end.getDate() + days - 1);
|
|
9124
|
-
return {
|
|
9125
|
-
days,
|
|
9126
|
-
start,
|
|
9127
|
-
end,
|
|
9128
|
-
isShortWeek: days < 7
|
|
9129
|
-
};
|
|
9130
|
-
};
|
|
9131
|
-
const getFirstDayOfWeek = (date) => {
|
|
9132
|
-
const currentDate = new Date(date);
|
|
9133
|
-
const dayOfWeek = currentDate.getDay();
|
|
9134
|
-
// dayOfWeek 0 == (Sunday)
|
|
9135
|
-
const diffToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
|
9136
|
-
// Set the date to the first day of the week
|
|
9137
|
-
currentDate.setDate(currentDate.getDate() - diffToMonday);
|
|
9138
|
-
return currentDate;
|
|
9139
|
-
};
|
|
9140
|
-
|
|
9141
|
-
const DayHeader = ({ index, text, width, headerType }) => {
|
|
9142
|
-
const isFirstDay = index == 0;
|
|
9143
|
-
return (jsx("td", { style: {
|
|
9144
|
-
display: "inline-block",
|
|
9145
|
-
fontSize: "10px",
|
|
9146
|
-
width: width,
|
|
9147
|
-
maxWidth: width,
|
|
9148
|
-
}, id: headerType + index, children: jsx("span", { className: isFirstDay ? "cwelltFirstDate_desc" : "", children: text }) }));
|
|
9149
|
-
};
|
|
9150
|
-
|
|
9151
|
-
const MonthHeader = ({ index, text, width, headerType }) => {
|
|
9152
|
-
return (jsx("td", { style: {
|
|
9153
|
-
display: "inline-block",
|
|
9154
|
-
fontSize: "10px",
|
|
9155
|
-
width: width,
|
|
9156
|
-
maxWidth: width,
|
|
9157
|
-
}, id: headerType + index, children: jsx("span", { children: text }) }));
|
|
9158
|
-
};
|
|
9159
|
-
|
|
9160
|
-
const WeekHeader = ({ index, text, width, headerType }) => {
|
|
9161
|
-
const isFirstDay = index == 0;
|
|
9162
|
-
return (jsx("td", { style: {
|
|
9163
|
-
display: "inline-block",
|
|
9164
|
-
fontSize: "10px",
|
|
9165
|
-
width: width,
|
|
9166
|
-
maxWidth: width,
|
|
9167
|
-
}, id: headerType + index, children: jsx("span", { className: isFirstDay ? "cwelltFirstDate_desc" : "", style: { whiteSpace: "nowrap" }, children: text }) }));
|
|
9168
|
-
};
|
|
9169
|
-
|
|
9170
|
-
const DaysHeader = ({ days, divisionType, maxWidth, headerType }) => {
|
|
9171
|
-
let headerToDraw = [];
|
|
9172
|
-
const filteredDays = days.filter((date) => {
|
|
9173
|
-
return date.getHours() === 0;
|
|
9174
|
-
});
|
|
9175
|
-
const dateFormatter = (date) => {
|
|
9176
|
-
return `${date.getDate()}.${date.getMonth() + 1}.${date.getFullYear()}`;
|
|
9177
|
-
};
|
|
9178
|
-
switch (divisionType) {
|
|
9179
|
-
case "d":
|
|
9180
|
-
{
|
|
9181
|
-
headerToDraw = filteredDays.map((date, index) => {
|
|
9182
|
-
return (jsx(DayHeader, { text: dateFormatter(date), index: index, width: maxWidth / filteredDays.length, headerType: headerType }, index));
|
|
9183
|
-
});
|
|
9184
|
-
}
|
|
9185
|
-
break;
|
|
9186
|
-
case "w":
|
|
9187
|
-
{
|
|
9188
|
-
const weekRanges = listOfDatesToWeekRangeList(filteredDays);
|
|
9189
|
-
headerToDraw = getWeekHeaderDataFromWeekRange(weekRanges, maxWidth, dateFormatter).map((week, index) => {
|
|
9190
|
-
return (jsx(WeekHeader, { index: index, text: week.formattedString, width: week.width, headerType: headerType }, index));
|
|
9191
|
-
});
|
|
9192
|
-
}
|
|
9193
|
-
break;
|
|
9194
|
-
case "m":
|
|
9195
|
-
{
|
|
9196
|
-
const monthData = getMonthHeaderData(filteredDays, maxWidth);
|
|
9197
|
-
headerToDraw = monthData.map(({ monthFormatted, width }, index) => (jsx(MonthHeader, { index: index, text: monthFormatted, width: width, headerType: headerType }, index)));
|
|
9198
|
-
}
|
|
9199
|
-
break;
|
|
9200
|
-
}
|
|
9201
|
-
return jsx("tr", { className: "cwelltSchRowDate", children: headerToDraw });
|
|
9202
|
-
};
|
|
9203
|
-
|
|
9204
|
-
function formatHHmm(date) {
|
|
9205
|
-
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
9206
|
-
const zdt = Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTimeISO(timeZone);
|
|
9207
|
-
return `${zdt.hour.toString().padStart(2, "0")}:${zdt.minute.toString().padStart(2, "0")}`;
|
|
9208
|
-
}
|
|
9209
|
-
const getFormattedTimeForHeader = (calculatedDivType, calculatedDivision, timeHeader) => {
|
|
9210
|
-
let showDate = "";
|
|
9211
|
-
switch (calculatedDivType) {
|
|
9212
|
-
case "d":
|
|
9213
|
-
switch (calculatedDivision) {
|
|
9214
|
-
case 8:
|
|
9215
|
-
showDate =
|
|
9216
|
-
timeHeader.getHours() === 0 ||
|
|
9217
|
-
timeHeader.getHours() === 3 ||
|
|
9218
|
-
timeHeader.getHours() === 6 ||
|
|
9219
|
-
timeHeader.getHours() === 9 ||
|
|
9220
|
-
timeHeader.getHours() === 12 ||
|
|
9221
|
-
timeHeader.getHours() === 15 ||
|
|
9222
|
-
timeHeader.getHours() === 18 ||
|
|
9223
|
-
timeHeader.getHours() === 21
|
|
9224
|
-
? formatHHmm(timeHeader)
|
|
9225
|
-
: "";
|
|
9226
|
-
break;
|
|
9227
|
-
case 3:
|
|
9228
|
-
showDate =
|
|
9229
|
-
timeHeader.getHours() === 0 || timeHeader.getHours() === 8 || timeHeader.getHours() === 16
|
|
9230
|
-
? formatHHmm(timeHeader)
|
|
9231
|
-
: "";
|
|
9232
|
-
break;
|
|
9233
|
-
case 2:
|
|
9234
|
-
showDate =
|
|
9235
|
-
timeHeader.getHours() === 0 || timeHeader.getHours() === 12 ? formatHHmm(timeHeader) : "";
|
|
9236
|
-
break;
|
|
9237
|
-
}
|
|
9238
|
-
break;
|
|
9239
|
-
case "m":
|
|
9240
|
-
showDate = timeHeader.getHours() === 0 ? timeHeader.getDate().toString() : "";
|
|
9241
|
-
break;
|
|
9242
|
-
case "w":
|
|
9243
|
-
showDate = timeHeader.getHours() === 0 ? timeHeader.getDate().toString() : "";
|
|
9244
|
-
break;
|
|
9245
|
-
}
|
|
9246
|
-
return {
|
|
9247
|
-
text: showDate,
|
|
9248
|
-
isWeekend: timeHeader.getDay() === 6 || timeHeader.getDay() === 0,
|
|
9249
|
-
};
|
|
9250
|
-
};
|
|
9251
|
-
|
|
9252
|
-
const calculateDivisions = (start, end) => {
|
|
9253
|
-
const diffDays = daysBetweenTwoDates(start, end);
|
|
9254
|
-
if (diffDays <= 3) {
|
|
9255
|
-
return 8;
|
|
9256
|
-
}
|
|
9257
|
-
else if (diffDays < 8) {
|
|
9258
|
-
return 3;
|
|
9259
|
-
}
|
|
9260
|
-
else if (diffDays <= 15) {
|
|
9261
|
-
return 2;
|
|
9262
|
-
}
|
|
9263
|
-
else {
|
|
9264
|
-
return 1;
|
|
9265
|
-
}
|
|
9266
|
-
};
|
|
9267
|
-
|
|
9268
|
-
const TimeHeader = ({ isWeekend, index, text, width, header }) => {
|
|
9269
|
-
if (text === "") {
|
|
9270
|
-
return;
|
|
9271
|
-
}
|
|
9272
|
-
const commonStyles = {
|
|
9273
|
-
display: "flex",
|
|
9274
|
-
alignItems: "center",
|
|
9275
|
-
justifyContent: "left",
|
|
9276
|
-
fontSize: "10px",
|
|
9277
|
-
width: width,
|
|
9278
|
-
maxWidth: width,
|
|
9279
|
-
height: "30px",
|
|
9280
|
-
borderLeft: "1px solid white",
|
|
9281
|
-
background: isWeekend ? "#cbc9c9" : "",
|
|
9282
|
-
color: "#000000d9",
|
|
9283
|
-
fontWeight: 700,
|
|
9284
|
-
};
|
|
9285
|
-
return (jsx("td", { style: commonStyles, id: `${header}Time${index}`, children: jsx("span", { style: { paddingLeft: "8px" }, children: text }) }, `t${index}`));
|
|
9286
|
-
};
|
|
9287
|
-
|
|
9288
|
-
const TimeHeaderRow = ({ timeHeaders, startDate, endDate, maxWidth, header }) => {
|
|
9289
|
-
const calculatedDivision = calculateDivisions(startDate, endDate);
|
|
9290
|
-
const calculatedDivType = calculateDivisionType(startDate, endDate);
|
|
9291
|
-
const formattedHeaders = timeHeaders.map((th) => {
|
|
9292
|
-
return getFormattedTimeForHeader(calculatedDivType, calculatedDivision, th);
|
|
9293
|
-
});
|
|
9294
|
-
const filteredHeaders = formattedHeaders.filter((element) => element.text !== "");
|
|
9295
|
-
return (jsx("tr", { className: "cwelltSchRowTime", style: { height: "30px" }, children: filteredHeaders.map(({ text, isWeekend }, index) => {
|
|
9296
|
-
return (jsx(TimeHeader, { isWeekend: isWeekend, index: index, text: text, width: maxWidth / filteredHeaders.length, header: header }, index));
|
|
9297
|
-
}) }));
|
|
9298
|
-
};
|
|
9299
|
-
|
|
9300
|
-
const SchedulerTimeLine = ({ maxPx, hoursList, startDate, endDate, pxPerHour, headerName, }) => {
|
|
9301
|
-
return (jsx("table", { className: "content-area cwelltSchTable", style: { width: maxPx }, children: jsxs("tbody", { style: { width: "100%", borderSpacing: 0 }, className: "content-area cwelltSchTbody", children: [jsx(DaysHeader, { days: hoursList, divisionType: calculateDivisionType(startDate, endDate), maxWidth: pxPerHour * hoursList.length, headerType: headerName ?? "schedulerDateHeader" }), jsx(TimeHeaderRow, { timeHeaders: hoursList, startDate: startDate, endDate: endDate, maxWidth: pxPerHour * hoursList.length, header: headerName ?? "schedulerTimeHeader" })] }) }));
|
|
9302
|
-
};
|
|
9303
|
-
|
|
9304
|
-
const SchedulerHeader$1 = ({ timelineProps, descriptionColumn }) => {
|
|
9305
|
-
const { maxPx, hoursList, startDate, endDate, pxPerHour, headerName } = timelineProps;
|
|
9306
|
-
return (jsx("thead", { className: "cwellt_fc_header_scheduler", style: { position: "sticky", zIndex: 9 }, children: jsxs("tr", { className: "cwellt_fc_header_row", children: [jsxs("td", { className: "border", style: {
|
|
9307
|
-
position: "sticky",
|
|
9308
|
-
top: 0,
|
|
9309
|
-
backgroundColor: "white",
|
|
9310
|
-
width: "100px",
|
|
9311
|
-
}, children: [jsx("div", { style: {
|
|
9312
|
-
display: "flex",
|
|
9313
|
-
height: "30px",
|
|
9314
|
-
alignItems: "center",
|
|
9315
|
-
width: "150px",
|
|
9316
|
-
}, children: jsx("label", { children: headerName }) }), jsx("div", { style: {
|
|
9317
|
-
display: "flex",
|
|
9318
|
-
height: "30px",
|
|
9319
|
-
alignItems: "center",
|
|
9320
|
-
background: "rgba(0, 0, 0, 0.04)",
|
|
9321
|
-
}, children: jsx("span", { children: descriptionColumn }) })] }), jsx("td", { style: {
|
|
9322
|
-
position: "sticky",
|
|
9323
|
-
top: 0,
|
|
9324
|
-
zIndex: 6,
|
|
9325
|
-
backgroundColor: "white",
|
|
9326
|
-
}, children: jsx(SchedulerTimeLine, { maxPx: maxPx, hoursList: hoursList, pxPerHour: pxPerHour, startDate: startDate, endDate: endDate, headerName: headerName }) })] }) }));
|
|
9327
|
-
};
|
|
9328
|
-
|
|
9329
|
-
const daysBetweenTwoDatesIncludingBoth = (date1, date2) => {
|
|
9330
|
-
const diff = Math.abs(date1.getTime() - date2.getTime());
|
|
9331
|
-
const diffDays = diff / (1000 * 3600 * 24);
|
|
9332
|
-
return diffDays;
|
|
9333
|
-
};
|
|
9334
|
-
|
|
9335
|
-
const getUtcToday = () => {
|
|
9336
|
-
const now = new Date();
|
|
9337
|
-
const userTimezoneOffset = now.getTimezoneOffset() * 60000;
|
|
9338
|
-
const nowUtc = new Date(now.getTime() + userTimezoneOffset);
|
|
9339
|
-
return nowUtc;
|
|
9340
|
-
};
|
|
9341
|
-
|
|
9342
|
-
const filterEvents = (events, start, end, id, module = undefined) => {
|
|
9343
|
-
const datesCollide = (event) => event.start <= end && event.end >= start;
|
|
9344
|
-
let eventsFiltered = events.filter(event => datesCollide(event));
|
|
9345
|
-
if (id !== "flightWatchScheduler") {
|
|
9346
|
-
eventsFiltered = sortByDate(eventsFiltered);
|
|
9347
|
-
}
|
|
9348
|
-
if (id !== "crewAssignmentsScheduler" && id !== "vacationsScheduler") {
|
|
9349
|
-
return eventsFiltered;
|
|
9350
|
-
}
|
|
9351
|
-
eventsFiltered = setNotFullHeightEventsFirst(eventsFiltered);
|
|
9352
|
-
if (module === "CrewControl") {
|
|
9353
|
-
eventsFiltered = removeDuplicated(eventsFiltered, "Crew_Id");
|
|
9354
|
-
}
|
|
9355
|
-
if (module === "CrewScheduling") {
|
|
9356
|
-
eventsFiltered = removeDuplicated(eventsFiltered, "AssignmentID");
|
|
9357
|
-
}
|
|
9358
|
-
if (module === "CrewSchedulingVacations") {
|
|
9359
|
-
eventsFiltered = removeDuplicated(eventsFiltered, "ID");
|
|
9360
|
-
}
|
|
9361
|
-
return eventsFiltered;
|
|
9362
|
-
};
|
|
9363
|
-
const sortByDate = (events) => events.sort((a, b) => +new Date(a.start) - +new Date(b.start));
|
|
9364
|
-
const removeDuplicated = (events, key) => {
|
|
9365
|
-
return events.filter((obj, index, self) => index === self.findIndex(o => o.data[key] === obj.data[key] && o.data.subject === obj.data.subject));
|
|
9366
|
-
};
|
|
9367
|
-
const setNotFullHeightEventsFirst = (events) => {
|
|
9368
|
-
const notFullHeight = [];
|
|
9369
|
-
const isFullHeight = [];
|
|
9370
|
-
events.forEach(element => {
|
|
9371
|
-
element.isFullHeight ? notFullHeight.push(element) : isFullHeight.push(element);
|
|
9372
|
-
});
|
|
9373
|
-
return notFullHeight.concat(isFullHeight);
|
|
9374
|
-
};
|
|
9375
|
-
|
|
9376
|
-
const compareStrings = (str1, str2) => {
|
|
9377
|
-
if (str1 > str2)
|
|
9378
|
-
return 1;
|
|
9379
|
-
if (str1 < str2)
|
|
9380
|
-
return -1;
|
|
9381
|
-
return 0;
|
|
9382
|
-
};
|
|
9383
|
-
|
|
9384
|
-
const filterResources = (module, resourceName, resources, groupByFunction, endDate, startDate, scheduleName) => {
|
|
9385
|
-
if ((module === "CrewControl" || module === "CrewScheduling" || module === "CrewSchedulingVacations") &&
|
|
9386
|
-
resourceName === "Employees") {
|
|
9387
|
-
resources = resources.filter(c => (c.data.Eintritt === null || (new Date(c.data.Eintritt) <= endDate)) && (c.data.Austritt === null || (new Date(c.data.Austritt) >= startDate)));
|
|
9388
|
-
}
|
|
9389
|
-
if (scheduleName === "crewPinnedScheduler" || (module === "CrewControl" || module === "CrewScheduling") && resourceName === "Employees") {
|
|
9390
|
-
const sortKey = (groupByFunction || scheduleName === "crewPinnedScheduler") ? "mainFunction" : "C3_LC";
|
|
9391
|
-
resources = resources.sort((a, b) => compareStrings(a.data[sortKey], b.data[sortKey]));
|
|
9392
|
-
}
|
|
9393
|
-
return resources;
|
|
9394
|
-
};
|
|
9395
|
-
|
|
9396
|
-
const heightScheduler = (resources, visibleRows, isPinnerScheduler) => {
|
|
9397
|
-
if (resources.length <= 0) {
|
|
9398
|
-
return 100;
|
|
9399
|
-
}
|
|
9400
|
-
const realVisibleRows = visibleRows > resources.length ? resources.length : visibleRows;
|
|
9401
|
-
const rowsHeight = resources.slice(0, realVisibleRows).map((row) => {
|
|
9402
|
-
return row.maxTop;
|
|
9403
|
-
});
|
|
9404
|
-
const height = rowsHeight.reduce((sum, row) => {
|
|
9405
|
-
return sum + row;
|
|
9406
|
-
}, 0);
|
|
9407
|
-
const headerHeight = isPinnerScheduler ? 0 : 60;
|
|
9408
|
-
return height + headerHeight;
|
|
9409
|
-
};
|
|
9410
|
-
|
|
9411
|
-
const getLeftPixels = (eventStart, scheduleStart, dayPx) => {
|
|
9412
|
-
if (scheduleStart >= eventStart)
|
|
9413
|
-
return 0;
|
|
9414
|
-
return daysBetweenTwoDatesIncludingBoth(scheduleStart, eventStart) * dayPx;
|
|
9415
|
-
};
|
|
9416
|
-
const getEventWithSize = (event, schedulerStart, dayPx) => {
|
|
9417
|
-
const eventStartBeforeScheduleStart = event.start.getTime() < schedulerStart.getTime();
|
|
9418
|
-
const lengthOfEvent = daysBetweenTwoDatesIncludingBoth(event.start, event.end);
|
|
9419
|
-
const daysUntilSchedulerStart = daysBetweenTwoDatesIncludingBoth(event.start, schedulerStart);
|
|
9420
|
-
const daysLong = eventStartBeforeScheduleStart ? lengthOfEvent - daysUntilSchedulerStart : lengthOfEvent;
|
|
9421
|
-
// we want minimum of 8 px
|
|
9422
|
-
const eventMinSize = 8;
|
|
9423
|
-
const newEvent = {
|
|
9424
|
-
...event,
|
|
9425
|
-
leftPx: getLeftPixels(event.start, schedulerStart, dayPx),
|
|
9426
|
-
width: Math.max(daysLong * dayPx, eventMinSize),
|
|
9427
|
-
};
|
|
9428
|
-
return newEvent;
|
|
9429
|
-
};
|
|
9430
|
-
|
|
9431
|
-
const checkIfSlotAvailable = (events, event) => {
|
|
9432
|
-
if (events.length == 0)
|
|
9433
|
-
return true;
|
|
9434
|
-
const collide = events.some(existent => {
|
|
9435
|
-
return !(existent.end <= event.start || event.end <= existent.start) && !existent.isFullHeight;
|
|
9436
|
-
});
|
|
9437
|
-
return !collide;
|
|
9438
|
-
};
|
|
9439
|
-
|
|
9440
|
-
const getEventsInInnerRows = (res, eventHeight, dayPx, start) => {
|
|
9441
|
-
let maxTop = 0;
|
|
9442
|
-
const tops = [];
|
|
9443
|
-
tops[0] = new Array();
|
|
9444
|
-
res.events
|
|
9445
|
-
.map((e) => {
|
|
9446
|
-
return getEventWithSize(e, start, dayPx);
|
|
9447
|
-
})
|
|
9448
|
-
.forEach((event, i) => {
|
|
9449
|
-
if (i === 0 || event.isFullHeight) {
|
|
9450
|
-
event.top = 0;
|
|
9451
|
-
tops[0].push(event);
|
|
9452
|
-
}
|
|
9453
|
-
else {
|
|
9454
|
-
let found = false;
|
|
9455
|
-
for (let j = 0; j < tops.length && found === false; j++) {
|
|
9456
|
-
found = checkIfSlotAvailable(tops[j], event);
|
|
9457
|
-
if (found === true || event.isFullHeight) {
|
|
9458
|
-
event.top = j * eventHeight;
|
|
9459
|
-
tops[j].push(event);
|
|
9460
|
-
break;
|
|
9461
|
-
}
|
|
9462
|
-
}
|
|
9463
|
-
if (found === false && !event.isFullHeight) {
|
|
9464
|
-
maxTop++;
|
|
9465
|
-
tops[maxTop] = new Array();
|
|
9466
|
-
event.top = maxTop * eventHeight;
|
|
9467
|
-
tops[maxTop].push(event);
|
|
9468
|
-
}
|
|
9469
|
-
else {
|
|
9470
|
-
// This is for flightwatch
|
|
9471
|
-
if (found === true && event.data.order === 2 && maxTop < 1) {
|
|
9472
|
-
maxTop++;
|
|
9473
|
-
tops[maxTop] = new Array();
|
|
9474
|
-
event.top = maxTop * eventHeight;
|
|
9475
|
-
tops[maxTop].push(event);
|
|
9476
|
-
maxTop--;
|
|
9477
|
-
}
|
|
9478
|
-
}
|
|
9479
|
-
}
|
|
9480
|
-
});
|
|
9481
|
-
return tops;
|
|
9482
|
-
};
|
|
9483
|
-
|
|
9484
|
-
const getTimeHeaders = (startDate, endDate) => {
|
|
9485
|
-
const dateArray = new Array();
|
|
9486
|
-
const currentDate = new Date(startDate);
|
|
9487
|
-
const startOffset = Math.abs(startDate.getTimezoneOffset());
|
|
9488
|
-
const endOffset = Math.abs(endDate.getTimezoneOffset());
|
|
9489
|
-
// Summer: +1 -> +2, true
|
|
9490
|
-
// Winter: +2 -> -1, false
|
|
9491
|
-
const offsetSummerWinter = startOffset < endOffset;
|
|
9492
|
-
if (offsetSummerWinter === true) {
|
|
9493
|
-
while (currentDate < endDate) {
|
|
9494
|
-
if (dateArray.length > 0) {
|
|
9495
|
-
const lastPosition = dateArray[dateArray.length - 1];
|
|
9496
|
-
const differenceHours = currentDate.getHours() - lastPosition.getHours();
|
|
9497
|
-
if (differenceHours === 1 || differenceHours < 0) {
|
|
9498
|
-
dateArray.push(new Date(currentDate));
|
|
9499
|
-
}
|
|
9500
|
-
else if (differenceHours > 1) {
|
|
9501
|
-
dateArray.push(new Date(currentDate.getHours() - 1));
|
|
9502
|
-
dateArray.push(new Date(currentDate));
|
|
9503
|
-
}
|
|
9504
|
-
}
|
|
9505
|
-
else {
|
|
9506
|
-
dateArray.push(new Date(currentDate));
|
|
9507
|
-
}
|
|
9508
|
-
currentDate.setHours(currentDate.getHours() + 1);
|
|
9509
|
-
}
|
|
9510
|
-
}
|
|
9511
|
-
else {
|
|
9512
|
-
while (currentDate < endDate) {
|
|
9513
|
-
dateArray.push(new Date(currentDate));
|
|
9514
|
-
currentDate.setHours(currentDate.getHours() + 1);
|
|
9515
|
-
}
|
|
9516
|
-
}
|
|
9517
|
-
return dateArray;
|
|
9518
|
-
};
|
|
9519
|
-
|
|
9520
|
-
class CwScheduler extends Component {
|
|
9521
|
-
contentArea;
|
|
9522
|
-
calculateMaxPx = () => {
|
|
9523
|
-
const mainElement = document.body;
|
|
9524
|
-
const mainRect = mainElement.getBoundingClientRect();
|
|
9525
|
-
return Math.floor(mainRect.width - 190);
|
|
9526
|
-
};
|
|
9527
|
-
constructor(props) {
|
|
9528
|
-
super(props);
|
|
9529
|
-
const maxPx = this.calculateMaxPx();
|
|
9530
|
-
const timeHeaders = getTimeHeaders(props.startDate, props.endDate);
|
|
9531
|
-
const dayPx = maxPx / Math.floor(daysBetweenTwoDates(props.startDate, props.endDate));
|
|
9532
|
-
const hourPx = dayPx / 24;
|
|
9533
|
-
const minutePx = dayPx / 1440;
|
|
9534
|
-
window?.addEventListener("resize", this.handleResize);
|
|
9535
|
-
const divisions = calculateDivisions(this.props.startDate, this.props.endDate);
|
|
9536
|
-
const divisionsLeftPx = timeHeaders
|
|
9537
|
-
.filter((_, index) => {
|
|
9538
|
-
return index != 0 && index % (24 / divisions) == 0;
|
|
9539
|
-
})
|
|
9540
|
-
.map((date) => {
|
|
9541
|
-
const daysDiff = daysBetweenTwoDatesIncludingBoth(date, props.startDate);
|
|
9542
|
-
const pixels = daysDiff * 24 * hourPx;
|
|
9543
|
-
return pixels;
|
|
9544
|
-
});
|
|
9545
|
-
this.state = {
|
|
9546
|
-
maxPx: maxPx,
|
|
9547
|
-
dayPx: dayPx,
|
|
9548
|
-
hourPx: hourPx,
|
|
9549
|
-
minutePx: minutePx,
|
|
9550
|
-
timeHeaders: timeHeaders,
|
|
9551
|
-
divisionsLeftPx: divisionsLeftPx,
|
|
9552
|
-
eventHeight: 30,
|
|
9553
|
-
resources: props.resources,
|
|
9554
|
-
lineStyle: 0,
|
|
9555
|
-
nowUtc: getUtcToday(),
|
|
9556
|
-
division: divisions,
|
|
9557
|
-
divisionType: "",
|
|
9558
|
-
pinnedResources: props.pinnedResources ? props.pinnedResources : [],
|
|
9559
|
-
selectedEvents: [],
|
|
9560
|
-
showConsoleLogs: false, // Change to false to not show the console.log(...)
|
|
9561
|
-
};
|
|
9562
|
-
}
|
|
9563
|
-
handleResize = () => {
|
|
9564
|
-
const maxPx = this.calculateMaxPx();
|
|
9565
|
-
const days = Math.floor(daysBetweenTwoDates(this.props.startDate, this.props.endDate));
|
|
9566
|
-
const dayPx = maxPx / days;
|
|
9567
|
-
const hourPx = dayPx / 24;
|
|
9568
|
-
const updated = { ...this.state, maxPx: maxPx, hourPx: hourPx, dayPx: dayPx };
|
|
9569
|
-
this.setState(updated);
|
|
9570
|
-
};
|
|
9571
|
-
objectsEqual = (o1, o2) => {
|
|
9572
|
-
Object.keys(o1).length === Object.keys(o2).length && Object.keys(o1).every((p) => o1[p] === o2[p]);
|
|
9573
|
-
};
|
|
9574
|
-
objectsEqualDeep = (o1, o2) => typeof o1 === "object" && Object.keys(o1).length > 0
|
|
9575
|
-
? Object.keys(o1).length === Object.keys(o2).length &&
|
|
9576
|
-
Object.keys(o1).every((p) => this.objectsEqual(o1[p], o2[p]))
|
|
9577
|
-
: o1 === o2;
|
|
9578
|
-
arraysEqual = (a1, a2) => a1.length === a2.length && a1.every((o, idx) => this.objectsEqualDeep(o, a2[idx]));
|
|
9579
|
-
componentWillReceiveProps(_nextProps) {
|
|
9580
|
-
if (this.state.showConsoleLogs) {
|
|
9581
|
-
console.log("Schedule - componentWillReceiveProps, start: ", new Date());
|
|
9582
|
-
console.log("Schedule - componentWillReceiveProps - has changes, start: ", new Date());
|
|
9583
|
-
}
|
|
9584
|
-
const dateChange = _nextProps.startDate.toISOString() !== this.props.startDate.toISOString() ||
|
|
9585
|
-
_nextProps.endDate.toISOString() !== this.props.endDate.toISOString();
|
|
9586
|
-
if (dateChange) {
|
|
9587
|
-
const startDate = _nextProps.startDate;
|
|
9588
|
-
const endDate = _nextProps.endDate;
|
|
9589
|
-
const maxPx = this.calculateMaxPx();
|
|
9590
|
-
const timeHeaders = getTimeHeaders(startDate, endDate);
|
|
9591
|
-
const days = Math.floor(daysBetweenTwoDates(startDate, endDate));
|
|
9592
|
-
const dayPx = maxPx / days;
|
|
9593
|
-
const hourPx = dayPx / 24;
|
|
9594
|
-
const minutePx = dayPx / 1440;
|
|
9595
|
-
const now = getUtcToday();
|
|
9596
|
-
const isInDateRange = now >= startDate && now <= endDate && this.contentArea !== undefined;
|
|
9597
|
-
const lineStyle = isInDateRange ? daysBetweenTwoDatesIncludingBoth(startDate, now) * dayPx : 0;
|
|
9598
|
-
const divisions = calculateDivisions(startDate, endDate);
|
|
9599
|
-
const divisionsLeftPx = timeHeaders
|
|
9600
|
-
.filter((_, index) => {
|
|
9601
|
-
return index != 0 && index % (24 / divisions) == 0;
|
|
9602
|
-
})
|
|
9603
|
-
.map((date) => {
|
|
9604
|
-
const daysDiff = daysBetweenTwoDatesIncludingBoth(date, startDate);
|
|
9605
|
-
const pixels = daysDiff * dayPx;
|
|
9606
|
-
return pixels;
|
|
9607
|
-
});
|
|
9608
|
-
this.setState({
|
|
9609
|
-
maxPx: maxPx, // window.screen.width * 0.9,
|
|
9610
|
-
dayPx: dayPx,
|
|
9611
|
-
hourPx: hourPx,
|
|
9612
|
-
minutePx: minutePx,
|
|
9613
|
-
timeHeaders: timeHeaders,
|
|
9614
|
-
divisionsLeftPx: divisionsLeftPx,
|
|
9615
|
-
resources: this.getNewResources(_nextProps, dayPx),
|
|
9616
|
-
lineStyle: lineStyle,
|
|
9617
|
-
nowUtc: now,
|
|
9618
|
-
division: divisions,
|
|
9619
|
-
divisionType: "",
|
|
9620
|
-
pinnedResources: this.props.pinnedResources ?? [],
|
|
9621
|
-
});
|
|
9622
|
-
if (this.state.showConsoleLogs) {
|
|
9623
|
-
console.log("Schedule - componentWillReceiveProps - print on schedule, end: ", new Date());
|
|
9624
|
-
console.log("Schedule - componentWillReceiveProps, end: ", new Date());
|
|
9625
|
-
}
|
|
9626
|
-
return;
|
|
9627
|
-
}
|
|
9628
|
-
const areSameEvents = this.arraysEqual(_nextProps.events, this.props.events);
|
|
9629
|
-
const areSameRows = this.arraysEqual(_nextProps.resources, this.props.resources);
|
|
9630
|
-
if (!areSameEvents || !areSameRows) {
|
|
9631
|
-
const startDate = _nextProps.startDate;
|
|
9632
|
-
const endDate = _nextProps.endDate;
|
|
9633
|
-
const maxPx = this.calculateMaxPx();
|
|
9634
|
-
const days = Math.floor(daysBetweenTwoDates(startDate, endDate));
|
|
9635
|
-
const dayPx = maxPx / days;
|
|
9636
|
-
this.setState({
|
|
9637
|
-
resources: this.getNewResources(_nextProps, dayPx),
|
|
9638
|
-
});
|
|
9639
|
-
return;
|
|
9640
|
-
}
|
|
9641
|
-
}
|
|
9642
|
-
getNewResources = (_nextProps, dayPx) => {
|
|
9643
|
-
const mappedEvents = filterEvents(_nextProps.events, _nextProps.startDate, _nextProps.endDate, this.props.id, this.props.module)
|
|
9644
|
-
.filter((event) => {
|
|
9645
|
-
const outOfRange = event.end <= this.props.startDate || event.start >= this.props.endDate;
|
|
9646
|
-
return !outOfRange;
|
|
9647
|
-
});
|
|
9648
|
-
const resources = filterResources(this.props.module, this.props.resourceName, _nextProps.resources, this.props.groupByFunction, _nextProps.endDate, _nextProps.startDate, this.props.id);
|
|
9649
|
-
const newResources = resources
|
|
9650
|
-
.map((resource) => {
|
|
9651
|
-
return {
|
|
9652
|
-
...resource,
|
|
9653
|
-
events: mappedEvents.filter((event) => event.resourceId === resource.id),
|
|
9654
|
-
};
|
|
9655
|
-
})
|
|
9656
|
-
.map((resource) => {
|
|
9657
|
-
const tops = getEventsInInnerRows(resource, this.state.eventHeight, dayPx, _nextProps.startDate);
|
|
9658
|
-
const height = tops.length === 0 ? this.state.eventHeight : tops.length * this.state.eventHeight;
|
|
9659
|
-
let flatMapEvents = [];
|
|
9660
|
-
for (let h = 0; h < tops.length; h++) {
|
|
9661
|
-
flatMapEvents = flatMapEvents.concat(tops[h]);
|
|
9662
|
-
}
|
|
9663
|
-
return {
|
|
9664
|
-
...resource,
|
|
9665
|
-
maxTop: height,
|
|
9666
|
-
events: flatMapEvents,
|
|
9667
|
-
};
|
|
9668
|
-
});
|
|
9669
|
-
return newResources;
|
|
9670
|
-
};
|
|
9671
|
-
handleOnClickContextMenuResourceScheduler = (_clickEvent, _resource) => {
|
|
9672
|
-
let datetime = new Date();
|
|
9673
|
-
const _ca = this.contentArea;
|
|
9674
|
-
if (_clickEvent.domEvent.currentTarget !== undefined) {
|
|
9675
|
-
const leftPos = _clickEvent.domEvent.currentTarget.parentElement.getBoundingClientRect().left -
|
|
9676
|
-
(_ca?.getBoundingClientRect()?.left ?? 0) -
|
|
9677
|
-
window.scrollX;
|
|
9678
|
-
datetime = addMinutesToDateFromPx(this.props.startDate, leftPos, this.state.minutePx);
|
|
9679
|
-
}
|
|
9680
|
-
if (this.props.scheduler_handleOnClickContextMenuResource) {
|
|
9681
|
-
this.props.scheduler_handleOnClickContextMenuResource(datetime, _resource, _clickEvent.key, this.props.id);
|
|
9682
|
-
}
|
|
9683
|
-
};
|
|
9684
|
-
handleCrewPinning = (resource, text) => {
|
|
9685
|
-
if (this.props.scheduler_handlePinned) {
|
|
9686
|
-
this.props.scheduler_handlePinned.call(this.props.parent, resource.id, text, this.props.id);
|
|
9687
|
-
}
|
|
9688
|
-
};
|
|
9689
|
-
render() {
|
|
9690
|
-
const isInDateRange = this.state.nowUtc >= this.props.startDate &&
|
|
9691
|
-
this.state.nowUtc <= this.props.endDate &&
|
|
9692
|
-
this.contentArea !== undefined;
|
|
9693
|
-
const showTimeline = isInDateRange && this.state.lineStyle < this.state.maxPx;
|
|
9694
|
-
const isPinnedTable = this.props.id.toLowerCase().includes("pinned");
|
|
9695
|
-
const schedulerHeight = heightScheduler(this.state.resources, this.props.height, this.props.id === "crewAssignmentsScheduler");
|
|
9696
|
-
return (jsx("div", { id: this.props.id, style: {
|
|
9697
|
-
maxHeight: isPinnedTable ? "auto" : schedulerHeight,
|
|
9698
|
-
}, className: this.state.resources.length > 0 ? "cwellt_tb_con" : "cwellt_tb_con cw_tb_con_emptyValues", children: jsxs("table", { id: "cwelltTableScheduler", children: [this.props.id !== "crewAssignmentsScheduler" && (jsx(SchedulerHeader$1, { timelineProps: {
|
|
9699
|
-
maxPx: this.state.maxPx,
|
|
9700
|
-
hoursList: this.state.timeHeaders,
|
|
9701
|
-
pxPerHour: this.state.hourPx,
|
|
9702
|
-
startDate: this.props.startDate,
|
|
9703
|
-
endDate: this.props.endDate,
|
|
9704
|
-
headerName: this.props.resourceName,
|
|
9705
|
-
}, descriptionColumn: this.props.descriptionColumn })), jsx("tbody", { style: {
|
|
9706
|
-
width: this.state.maxPx + 150,
|
|
9707
|
-
maxHeight: isPinnedTable ? "auto" : schedulerHeight,
|
|
9708
|
-
}, className: isPinnedTable ? "fc-body cw-fc-body-pinned" : "fc-body", children: jsxs("tr", { className: "fc_body_row", children: [jsx(ResourcesTitleList, { resources: this.state.resources, canBePinned: this.props.canBePinned ?? false, includesPinned: this.props.id.toLowerCase().includes("pinned"), onCrewPinning: this.handleCrewPinning, onClickResourceContextMenu: (_e, resource) => {
|
|
9709
|
-
if (this.props.scheduler_handleOnClickResourceContextMenu) {
|
|
9710
|
-
this.props.scheduler_handleOnClickResourceContextMenu(_e, resource);
|
|
9711
|
-
}
|
|
9712
|
-
}, ResourceTitleComponent: this.props.resourceComp }), jsx("td", { className: "dividerArea" }), jsx(SchedulerContentArea, { now: this.state.nowUtc, showTimeline: showTimeline, timeSeparatorLeftPx: this.state.divisionsLeftPx, timeLineLeftPx: this.state.lineStyle, resources: this.state.resources, contextMenuContents: this.props.resourceContextMenuContents, scheduler: this, onEmptyClick: this.props.scheduler_handleEmptyClick, setContentArea: (n) => (this.contentArea = n), onClickContextMenu: this.handleOnClickContextMenuResourceScheduler })] }) })] }) }));
|
|
9713
|
-
}
|
|
9714
|
-
}
|
|
9715
|
-
|
|
9716
8836
|
function dateFromPercentage(startDate, visibleDays, percentage) {
|
|
9717
8837
|
const start = Temporal.Instant.fromEpochMilliseconds(startDate.getTime());
|
|
9718
8838
|
const spanMs = Math.round(visibleDays) * 24 * 60 * 60 * 1000;
|
|
@@ -9853,7 +8973,7 @@ class OnClickContextMenu {
|
|
|
9853
8973
|
}
|
|
9854
8974
|
}
|
|
9855
8975
|
|
|
9856
|
-
var styles$3 = {"scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
|
|
8976
|
+
var styles$3 = {"scheduler-header":"scheduler-header-module__scheduler-header__Y7SNV","scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
|
|
9857
8977
|
|
|
9858
8978
|
const getNow$1 = (isUtc) => {
|
|
9859
8979
|
let now = new Date();
|
|
@@ -9919,7 +9039,7 @@ const HeaderTitle = ({ title, dividerText, width }) => {
|
|
|
9919
9039
|
const SchedulerHeader = ({ content, divisions, visibleDays, selectedDate, width, onEvent, timeLinePercentage, isUtc }) => {
|
|
9920
9040
|
const topWidth = (100 / visibleDays);
|
|
9921
9041
|
const { title, classification } = content;
|
|
9922
|
-
return (jsxs("div", {
|
|
9042
|
+
return (jsxs("div", { className: styles$3["scheduler-header"], children: [jsx(HeaderTitle, { title: title, dividerText: classification, width: width }), jsxs("div", { className: styles$3["scheduler-header-divisions"], style: { flex: 1, display: "flex", position: "relative" }, onMouseDown: (e) => {
|
|
9923
9043
|
e.preventDefault();
|
|
9924
9044
|
const clickPercentage = getPercentageFromMouseEvent(e);
|
|
9925
9045
|
const date = dateFromPercentage(selectedDate, visibleDays, clickPercentage);
|
|
@@ -10787,325 +9907,6 @@ const Scheduler = (props) => {
|
|
|
10787
9907
|
class UiEvent {
|
|
10788
9908
|
}
|
|
10789
9909
|
|
|
10790
|
-
let topsCounter = 0;
|
|
10791
|
-
class CwSuperScheduler extends React.Component {
|
|
10792
|
-
constructor(Props) {
|
|
10793
|
-
super(Props);
|
|
10794
|
-
this.state = {
|
|
10795
|
-
topsCalculated: 0,
|
|
10796
|
-
height: 50,
|
|
10797
|
-
dataConfig: this.props.dataConfig ? this.props.dataConfig : undefined,
|
|
10798
|
-
pinnedResources: []
|
|
10799
|
-
};
|
|
10800
|
-
}
|
|
10801
|
-
componentDidUpdate(_previousProps, _previousState) {
|
|
10802
|
-
if (this.props.pinnedResources !== _previousProps.pinnedResources) {
|
|
10803
|
-
let returnedTops = 0;
|
|
10804
|
-
let returnedHeight = 50;
|
|
10805
|
-
let data;
|
|
10806
|
-
if (this.props.pinnedResources) {
|
|
10807
|
-
const pinned = [...new Set(this.props.pinnedResources)];
|
|
10808
|
-
for (let i = 0; i < pinned.length; i++) {
|
|
10809
|
-
data = this.returnDynamicHeight(pinned[i], returnedTops);
|
|
10810
|
-
returnedTops = data.topsCalculated;
|
|
10811
|
-
returnedHeight = data.height;
|
|
10812
|
-
}
|
|
10813
|
-
this.setState({
|
|
10814
|
-
topsCalculated: returnedTops,
|
|
10815
|
-
height: returnedHeight !== 50 ? 80 + returnedHeight : 50,
|
|
10816
|
-
pinnedResources: this.props.pinnedResources
|
|
10817
|
-
});
|
|
10818
|
-
}
|
|
10819
|
-
}
|
|
10820
|
-
}
|
|
10821
|
-
scheduler_handleCblEventClick = (cblEvent, schedulerId) => {
|
|
10822
|
-
this.props.scheduler_handleCblEventClick(cblEvent, schedulerId);
|
|
10823
|
-
};
|
|
10824
|
-
scheduler_handleCblEventClickRight = (cblEvent, schedulerId) => {
|
|
10825
|
-
if (this.props.scheduler_handleCblEventClickRight) {
|
|
10826
|
-
this.props.scheduler_handleCblEventClickRight(cblEvent, schedulerId);
|
|
10827
|
-
}
|
|
10828
|
-
};
|
|
10829
|
-
scheduler_handleCblEventDoubleClick = (cblEvent, schedulerId) => {
|
|
10830
|
-
this.props.scheduler_handleCblEventDoubleClick(cblEvent, schedulerId);
|
|
10831
|
-
};
|
|
10832
|
-
scheduler_handlePinnedClickMultipleIds = (resIds, schedulerId, requestString) => {
|
|
10833
|
-
this.props.scheduler_handlePinningOfResources(resIds, "", schedulerId, requestString);
|
|
10834
|
-
};
|
|
10835
|
-
scheduler_handlePinnedClick = (resId, text, schedulerId) => {
|
|
10836
|
-
const array = new Array();
|
|
10837
|
-
array.push(resId);
|
|
10838
|
-
this.props.scheduler_handlePinningOfResources(array, text, schedulerId, "resources");
|
|
10839
|
-
};
|
|
10840
|
-
returnDynamicHeight(pinned, topsCalculated) {
|
|
10841
|
-
let height = 100;
|
|
10842
|
-
let maxTop = 0;
|
|
10843
|
-
const eventHeight = 30;
|
|
10844
|
-
const tops = new Array();
|
|
10845
|
-
tops[0] = new Array();
|
|
10846
|
-
const diffDates = this.props.endDate.getTime() - this.props.startDate.getTime();
|
|
10847
|
-
const diffDays = diffDates / (1000 * 3600 * 24);
|
|
10848
|
-
const dateToFilter = new Date(this.props.startDate.getTime());
|
|
10849
|
-
dateToFilter.setDate(dateToFilter.getDate() + diffDays);
|
|
10850
|
-
let events = this.props.pinnedEvents !== undefined ? this.props.pinnedEvents : new Array();
|
|
10851
|
-
events = events
|
|
10852
|
-
.filter(x => pinned === x.resourceId && x.start >= this.props.startDate && x.start <= dateToFilter)
|
|
10853
|
-
.sort((a, b) => {
|
|
10854
|
-
return +new Date(a.start) - +new Date(b.start);
|
|
10855
|
-
});
|
|
10856
|
-
for (let i = 0; i < events.length; i++) {
|
|
10857
|
-
const event = events[i];
|
|
10858
|
-
if (i === 0 || event.isFullHeight) {
|
|
10859
|
-
tops[0].push(event);
|
|
10860
|
-
}
|
|
10861
|
-
else {
|
|
10862
|
-
let found = false;
|
|
10863
|
-
for (let j = 0; j < tops.length && found === false; j++) {
|
|
10864
|
-
found = this.checkIfSlotAvailable(tops[j], event);
|
|
10865
|
-
if (found === true || event.isFullHeight) {
|
|
10866
|
-
tops[j].push(event);
|
|
10867
|
-
}
|
|
10868
|
-
}
|
|
10869
|
-
if (found === false) {
|
|
10870
|
-
maxTop++;
|
|
10871
|
-
tops[maxTop] = new Array();
|
|
10872
|
-
tops[maxTop].push(event);
|
|
10873
|
-
}
|
|
10874
|
-
}
|
|
10875
|
-
}
|
|
10876
|
-
for (let h = 0; h < tops.length; h++) {
|
|
10877
|
-
if (tops.length === 0) {
|
|
10878
|
-
height = 100;
|
|
10879
|
-
}
|
|
10880
|
-
else {
|
|
10881
|
-
height = (topsCalculated + tops.length) * eventHeight;
|
|
10882
|
-
}
|
|
10883
|
-
}
|
|
10884
|
-
topsCounter = topsCounter + tops.length;
|
|
10885
|
-
return {
|
|
10886
|
-
topsCalculated: topsCalculated + tops.length,
|
|
10887
|
-
height: height
|
|
10888
|
-
};
|
|
10889
|
-
}
|
|
10890
|
-
checkIfSlotAvailable(array, event) {
|
|
10891
|
-
let found = false;
|
|
10892
|
-
if (array[array.length - 1].end <= event.start || array[array.length - 1].isFullHeight) {
|
|
10893
|
-
found = true;
|
|
10894
|
-
}
|
|
10895
|
-
return found;
|
|
10896
|
-
}
|
|
10897
|
-
handleOnClickContextMenuResource = (date, resource, key, schedulerId) => {
|
|
10898
|
-
let url = "";
|
|
10899
|
-
switch (key) {
|
|
10900
|
-
case "showReserves": {
|
|
10901
|
-
// CrewControl
|
|
10902
|
-
if (this.props.module === "CrewControl") {
|
|
10903
|
-
url = "/Winops/CrewControl/CrewControlReact/GetCrewIdsOfReserve";
|
|
10904
|
-
}
|
|
10905
|
-
// CrewScheduling
|
|
10906
|
-
if (this.props.module === "CrewScheduling") {
|
|
10907
|
-
url = "/Winops/CrewPlanning/CrewPlanning/GetCrewIdsOfReserve";
|
|
10908
|
-
}
|
|
10909
|
-
const requestOptions = {
|
|
10910
|
-
method: "POST",
|
|
10911
|
-
headers: { "Content-Type": "application/json" },
|
|
10912
|
-
body: JSON.stringify({
|
|
10913
|
-
from: this.dateUTCString(this.props.startDate),
|
|
10914
|
-
to: this.dateUTCString(this.props.endDate),
|
|
10915
|
-
acftCategories: [],
|
|
10916
|
-
functions: [],
|
|
10917
|
-
clickedDate: this.dateUTCString(date),
|
|
10918
|
-
airportSelected: this.props.airportSelected
|
|
10919
|
-
})
|
|
10920
|
-
};
|
|
10921
|
-
if (this.state.dataConfig) {
|
|
10922
|
-
fetch(this.state.dataConfig + url, requestOptions)
|
|
10923
|
-
.then(response => response.json())
|
|
10924
|
-
.then(res => {
|
|
10925
|
-
if (res.length > 0) {
|
|
10926
|
-
this.scheduler_handlePinnedClickMultipleIds(res, schedulerId, "Reserves");
|
|
10927
|
-
}
|
|
10928
|
-
else {
|
|
10929
|
-
alert("No Reserves");
|
|
10930
|
-
}
|
|
10931
|
-
});
|
|
10932
|
-
}
|
|
10933
|
-
break;
|
|
10934
|
-
}
|
|
10935
|
-
case "showStandbys": {
|
|
10936
|
-
// CrewControl
|
|
10937
|
-
if (this.props.module === "CrewControl") {
|
|
10938
|
-
url = "/Winops/CrewControl/CrewControlReact/GetCrewIdsOfStandby";
|
|
10939
|
-
}
|
|
10940
|
-
// CrewScheduling
|
|
10941
|
-
if (this.props.module === "CrewScheduling") {
|
|
10942
|
-
url = "/Winops/CrewPlanning/CrewPlanning/GetCrewIdsOfStandby";
|
|
10943
|
-
}
|
|
10944
|
-
const requestOptions2 = {
|
|
10945
|
-
method: "POST",
|
|
10946
|
-
headers: { "Content-Type": "application/json" },
|
|
10947
|
-
body: JSON.stringify({
|
|
10948
|
-
from: this.dateUTCString(this.props.startDate),
|
|
10949
|
-
to: this.dateUTCString(this.props.startDate),
|
|
10950
|
-
acftCategories: [],
|
|
10951
|
-
functions: [],
|
|
10952
|
-
clickedDate: this.dateUTCString(date),
|
|
10953
|
-
airportSelected: this.props.airportSelected
|
|
10954
|
-
})
|
|
10955
|
-
};
|
|
10956
|
-
if (this.state.dataConfig) {
|
|
10957
|
-
fetch(this.state.dataConfig + url, requestOptions2)
|
|
10958
|
-
.then(response => response.json())
|
|
10959
|
-
.then(res => {
|
|
10960
|
-
if (res.length > 0) {
|
|
10961
|
-
this.scheduler_handlePinnedClickMultipleIds(res, schedulerId, "Standbys");
|
|
10962
|
-
}
|
|
10963
|
-
else {
|
|
10964
|
-
alert("No Standbys");
|
|
10965
|
-
}
|
|
10966
|
-
});
|
|
10967
|
-
}
|
|
10968
|
-
break;
|
|
10969
|
-
}
|
|
10970
|
-
case "showAvailables": {
|
|
10971
|
-
// CrewControl
|
|
10972
|
-
if (this.props.module === "CrewControl") {
|
|
10973
|
-
url = "/Winops/CrewControl/CrewControlReact/GetCrewIdsOfAvailables";
|
|
10974
|
-
}
|
|
10975
|
-
// CrewScheduling
|
|
10976
|
-
if (this.props.module === "CrewScheduling") {
|
|
10977
|
-
url = "/Winops/CrewPlanning/CrewPlanning/GetCrewIdsOfAvailables";
|
|
10978
|
-
}
|
|
10979
|
-
const requestOptions3 = {
|
|
10980
|
-
method: "POST",
|
|
10981
|
-
headers: { "Content-Type": "application/json" },
|
|
10982
|
-
body: JSON.stringify({
|
|
10983
|
-
from: this.dateUTCString(this.props.startDate),
|
|
10984
|
-
to: this.dateUTCString(this.props.startDate),
|
|
10985
|
-
acftCategories: [],
|
|
10986
|
-
functions: [],
|
|
10987
|
-
clickedDate: this.dateUTCString(date),
|
|
10988
|
-
airportSelected: this.props.airportSelected
|
|
10989
|
-
})
|
|
10990
|
-
};
|
|
10991
|
-
if (this.state.dataConfig) {
|
|
10992
|
-
fetch(this.state.dataConfig + url, requestOptions3)
|
|
10993
|
-
.then(response => response.json())
|
|
10994
|
-
.then(res => {
|
|
10995
|
-
if (res.length > 0) {
|
|
10996
|
-
this.scheduler_handlePinnedClickMultipleIds(res, schedulerId, "Availables");
|
|
10997
|
-
}
|
|
10998
|
-
else {
|
|
10999
|
-
alert("No Availables");
|
|
11000
|
-
}
|
|
11001
|
-
});
|
|
11002
|
-
}
|
|
11003
|
-
break;
|
|
11004
|
-
}
|
|
11005
|
-
default: {
|
|
11006
|
-
if (this.props.scheduler_handleOnClickContextMenuResource) {
|
|
11007
|
-
this.props.scheduler_handleOnClickContextMenuResource(date, resource, key);
|
|
11008
|
-
}
|
|
11009
|
-
break;
|
|
11010
|
-
}
|
|
11011
|
-
}
|
|
11012
|
-
};
|
|
11013
|
-
dateUTCString(date) {
|
|
11014
|
-
if (date instanceof Date) {
|
|
11015
|
-
if (date.getFullYear() > 1901)
|
|
11016
|
-
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes())).toISOString();
|
|
11017
|
-
}
|
|
11018
|
-
return date;
|
|
11019
|
-
}
|
|
11020
|
-
render() {
|
|
11021
|
-
const havePinnedResources = this.state.pinnedResources?.length > 0;
|
|
11022
|
-
const firstSchedulerResources = havePinnedResources
|
|
11023
|
-
? this.props.resourcesToPin.filter(x => this.state.pinnedResources.includes(x.id))
|
|
11024
|
-
: new Array();
|
|
11025
|
-
const secondSchedulerResources = this.props.resources.filter(x => !this.state.pinnedResources.includes(x.id));
|
|
11026
|
-
const pinnedEvents = this.props.pinnedEvents !== undefined
|
|
11027
|
-
? this.props.pinnedEvents.filter(x => this.state.pinnedResources.includes(x.resourceId))
|
|
11028
|
-
: new Array();
|
|
11029
|
-
const notPinnedEvents = this.props.events.filter(x => !this.props.pinnedResources?.includes(x.resourceId));
|
|
11030
|
-
return (jsxs("div", { className: "cwelltSuperScheduler_content", children: [jsx(CwScheduler, { id: "crewPinnedScheduler", events: pinnedEvents, resources: firstSchedulerResources, height: this.state.height, startDate: this.props.startDate, endDate: this.props.endDate, scheduler_handleCblEventClick: this.props.scheduler_handleCblEventClick, scheduler_handleCblEventClickRight: this.props.scheduler_handleCblEventClickRight, scheduler_handleCblEventDoubleClick: this.props.scheduler_handleCblEventDoubleClick, scheduler_handleOnDropCblEventsOnResource: this.props.scheduler_handleOnDropCblEventsOnResource, parent: this.props.parent, cblEventComp: this.props.cblEventComp, scheduler_handleOnClickEventContextMenu: this.props.scheduler_handleOnClickEventContextMenu, resourceComp: this.props.resourceComp, scheduler_handleOnClickContextMenuResource: this.props.scheduler_handleOnClickContextMenuResource, resourceContextMenuContents: this.props.resourceContextMenuContents, scheduler_handleDblClickOnResourceInScheduler: this.props.scheduler_handleDblClickOnResourceInScheduler, scheduler_handleEmptyClick: this.props.scheduler_handleEmptyClick, canBePinned: false, scheduler_handlePinned: this.scheduler_handlePinnedClick, resourceName: this.props.resourceName, descriptionColumn: this.props.descriptionColumn, scheduler_handleOnClickResourceContextMenu: this.props.scheduler_handleOnClickResourceContextMenu, groupByFunction: this.props.groupByFunction }), havePinnedResources && (jsx("div", { style: { padding: "0.5rem" }, children: jsx(CwButton, { text: "Clear", onClick: () => {
|
|
11031
|
-
this.props.scheduler_handleClearPinnedOnParent();
|
|
11032
|
-
} }) })), jsx(CwScheduler, { id: "crewAssignmentsScheduler", events: notPinnedEvents, resources: secondSchedulerResources, height: this.props.height, startDate: this.props.startDate, endDate: this.props.endDate, scheduler_handleCblEventClick: this.props.scheduler_handleCblEventClick, scheduler_handleCblEventClickRight: this.props.scheduler_handleCblEventClickRight, scheduler_handleCblEventDoubleClick: this.props.scheduler_handleCblEventDoubleClick, scheduler_handleOnDropCblEventsOnResource: this.props.scheduler_handleOnDropCblEventsOnResource, parent: this.props.parent, cblEventComp: this.props.cblEventComp, scheduler_handleOnClickEventContextMenu: this.props.scheduler_handleOnClickEventContextMenu, resourceComp: this.props.resourceComp, scheduler_handleOnClickContextMenuResource: this.handleOnClickContextMenuResource, resourceContextMenuContents: this.props.resourceContextMenuContents, scheduler_handleDblClickOnResourceInScheduler: this.props.scheduler_handleDblClickOnResourceInScheduler, scheduler_handleEmptyClick: this.props.scheduler_handleEmptyClick, canBePinned: true, scheduler_handlePinned: this.scheduler_handlePinnedClick, scheduler_handleCblEventResize: this.props.scheduler_handleCblEventResize, resourceName: this.props.resourceName, descriptionColumn: this.props.descriptionColumn, scheduler_handleOnClickResourceContextMenu: this.props.scheduler_handleOnClickResourceContextMenu, airportSelected: this.props.airportSelected, module: this.props.module, groupByFunction: this.props.groupByFunction })] }));
|
|
11033
|
-
}
|
|
11034
|
-
}
|
|
11035
|
-
class CblDragAndDrop {
|
|
11036
|
-
fromId;
|
|
11037
|
-
toId;
|
|
11038
|
-
data;
|
|
11039
|
-
droppedOnDate;
|
|
11040
|
-
resizeFromStart;
|
|
11041
|
-
resizeFromEnd;
|
|
11042
|
-
isCtrlKey;
|
|
11043
|
-
constructor(fromId, toId, data, droppedOnDate = null, resizeFromStart = null, resizeFromEnd = null, isCtrlKey = null) {
|
|
11044
|
-
this.fromId = fromId;
|
|
11045
|
-
this.toId = toId;
|
|
11046
|
-
this.data = data;
|
|
11047
|
-
this.droppedOnDate = droppedOnDate;
|
|
11048
|
-
this.resizeFromStart = resizeFromStart;
|
|
11049
|
-
this.resizeFromEnd = resizeFromEnd;
|
|
11050
|
-
this.isCtrlKey = isCtrlKey;
|
|
11051
|
-
}
|
|
11052
|
-
}
|
|
11053
|
-
|
|
11054
|
-
const getGUID = () => {
|
|
11055
|
-
return generateSegment(false) + generateSegment(true) + generateSegment(true) + generateSegment(false);
|
|
11056
|
-
};
|
|
11057
|
-
const generateSegment = (includeHyphens) => {
|
|
11058
|
-
const p = (Math.random().toString(16) + "000000000").substring(2, 10);
|
|
11059
|
-
return includeHyphens ? "-" + p.substring(0, 4) + "-" + p.substring(4, 8) : p;
|
|
11060
|
-
};
|
|
11061
|
-
|
|
11062
|
-
class cblEvent {
|
|
11063
|
-
id = "";
|
|
11064
|
-
start;
|
|
11065
|
-
end;
|
|
11066
|
-
resourceId;
|
|
11067
|
-
selected = false;
|
|
11068
|
-
top = 0;
|
|
11069
|
-
leftPx = 0;
|
|
11070
|
-
rightPx = 0;
|
|
11071
|
-
width = 0;
|
|
11072
|
-
isFullHeight = false;
|
|
11073
|
-
isReadOnly = false;
|
|
11074
|
-
isResizable = false;
|
|
11075
|
-
isDraggable = false;
|
|
11076
|
-
data = null;
|
|
11077
|
-
constructor(start, end, resourceId, data = null, isFullHeight = false, isReadOnly = false, isResizable = false, isDraggable = false) {
|
|
11078
|
-
this.start = start;
|
|
11079
|
-
this.end = end;
|
|
11080
|
-
this.resourceId = resourceId;
|
|
11081
|
-
this.data = data;
|
|
11082
|
-
this.isFullHeight = isFullHeight;
|
|
11083
|
-
this.isReadOnly = isReadOnly;
|
|
11084
|
-
this.isResizable = isResizable;
|
|
11085
|
-
this.isDraggable = isDraggable;
|
|
11086
|
-
this.id = getGUID();
|
|
11087
|
-
}
|
|
11088
|
-
}
|
|
11089
|
-
|
|
11090
|
-
class Resource {
|
|
11091
|
-
uid = "";
|
|
11092
|
-
id;
|
|
11093
|
-
name;
|
|
11094
|
-
maxTop;
|
|
11095
|
-
events = [];
|
|
11096
|
-
isInViewport = false;
|
|
11097
|
-
schedulerResourceDisplay;
|
|
11098
|
-
isLoading = false;
|
|
11099
|
-
data = null;
|
|
11100
|
-
constructor(id, name, eventHeight, data = null, schedulerResourceDisplay = null) {
|
|
11101
|
-
this.id = id;
|
|
11102
|
-
this.name = name;
|
|
11103
|
-
this.maxTop = eventHeight;
|
|
11104
|
-
this.data = data;
|
|
11105
|
-
this.schedulerResourceDisplay = schedulerResourceDisplay || this.name;
|
|
11106
|
-
}
|
|
11107
|
-
}
|
|
11108
|
-
|
|
11109
9910
|
var styles = {"super-scheduler-row-header":"super-scheduler-module__super-scheduler-row-header__TTs4e","indicators":"super-scheduler-module__indicators__f4lIT","scheduler-crewmember-functions":"super-scheduler-module__scheduler-crewmember-functions__BS2hs"};
|
|
11110
9911
|
|
|
11111
9912
|
class OnPinRow {
|
|
@@ -11588,4 +10389,4 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
|
|
|
11588
10389
|
}, "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", ref: wrapperRef, 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" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
|
|
11589
10390
|
};
|
|
11590
10391
|
|
|
11591
|
-
export {
|
|
10392
|
+
export { CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBadge, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNavMenu, CwNote, CwOption, CwPopoverButton, CwProgress, CwRadioGroup, CwReportModal, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSkeleton, CwSortableList, CwSortableTable, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, 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, PRESET_LIBRARY_TEMPORAL, PinRowHeader, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, configureCwLoading, eventIsVisible, filterNavItems, filterVisibleEvents, getCwLoadingDefaults, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, itemsToMultiFilterTags, sortNavItems, useCwMessage, useSortableList, useSortableTable, useTooltipConstraint };
|