@cwellt_software/cwellt-reactjs-lib 1.0.3 → 1.0.5

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.
Files changed (56) hide show
  1. package/dist/content/icons/new-cw-icons/NewCwIcons.html +390 -6
  2. package/dist/content/icons/new-cw-icons/NewCwIcons.json +1 -1
  3. package/dist/content/icons/new-cw-icons/css/new-cw-icons.css +20 -6
  4. package/dist/content/icons/new-cw-icons/fonts/NewCwIcons.woff +0 -0
  5. package/dist/index.cjs.js +653 -356
  6. package/dist/index.css +2 -2
  7. package/dist/index.d.ts +284 -134
  8. package/dist/index.es.js +658 -351
  9. package/dist/src/common/functions/colorManipulation.d.ts.map +1 -1
  10. package/dist/src/components/control/action/button/CwButton.d.ts +3 -2
  11. package/dist/src/components/control/action/button/CwButton.d.ts.map +1 -1
  12. package/dist/src/components/control/action/buttons/CwButtons.d.ts +0 -11
  13. package/dist/src/components/control/action/buttons/CwButtons.d.ts.map +1 -1
  14. package/dist/src/components/control/action/contextmenu/CwContextMenu.d.ts +4 -0
  15. package/dist/src/components/control/action/contextmenu/CwContextMenu.d.ts.map +1 -1
  16. package/dist/src/components/control/action/search/CwSearch.d.ts +1 -1
  17. package/dist/src/components/control/action/search/CwSearch.d.ts.map +1 -1
  18. package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts +2 -2
  19. package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts.map +1 -1
  20. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts +122 -33
  21. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts.map +1 -1
  22. package/dist/src/components/control/choice/toggle/CwToggle.d.ts +0 -4
  23. package/dist/src/components/control/choice/toggle/CwToggle.d.ts.map +1 -1
  24. package/dist/src/components/control/input/any/CwInput.d.ts.map +1 -1
  25. package/dist/src/components/control/input/number/CwInputNumber.d.ts.map +1 -1
  26. package/dist/src/components/custom/scheduler/CwSchedulerComp.d.ts.map +1 -1
  27. package/dist/src/components/custom/scheduler-new/presentation/NewScheduler.d.ts.map +1 -1
  28. package/dist/src/components/custom/scheduler-new/presentation/components/row/BackgroundEvent.d.ts +0 -1
  29. package/dist/src/components/custom/scheduler-new/presentation/components/row/BackgroundEvent.d.ts.map +1 -1
  30. package/dist/src/components/custom/scheduler-new/presentation/components/row/DefaultRowHeader.d.ts.map +1 -1
  31. package/dist/src/components/custom/scheduler-new/presentation/components/row/Event.d.ts +1 -0
  32. package/dist/src/components/custom/scheduler-new/presentation/components/row/Event.d.ts.map +1 -1
  33. package/dist/src/components/custom/super-scheduler/PinRowHeader.d.ts.map +1 -1
  34. package/dist/src/components/display/data/accordion/CwAccordionContainer.d.ts.map +1 -1
  35. package/dist/src/components/display/data/generic_tooltip/CwGenericTooltip.d.ts +1 -0
  36. package/dist/src/components/display/data/generic_tooltip/CwGenericTooltip.d.ts.map +1 -1
  37. package/dist/src/components/display/data/table/CwTable.d.ts +48 -63
  38. package/dist/src/components/display/data/table/CwTable.d.ts.map +1 -1
  39. package/dist/src/components/display/graphics/loading/CwLoading.d.ts +39 -9
  40. package/dist/src/components/display/graphics/loading/CwLoading.d.ts.map +1 -1
  41. package/dist/src/components/display/graphics/loading-small/CwLoadingSmall.d.ts +13 -1
  42. package/dist/src/components/display/graphics/loading-small/CwLoadingSmall.d.ts.map +1 -1
  43. package/dist/src/components/display/text/tag/CwTag.d.ts +2 -2
  44. package/dist/src/components/display/text/tag/CwTag.d.ts.map +1 -1
  45. package/dist/src/components/layout/dialog/CwDialog.d.ts +15 -4
  46. package/dist/src/components/layout/dialog/CwDialog.d.ts.map +1 -1
  47. package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts +33 -0
  48. package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts.map +1 -0
  49. package/dist/src/components/layout/modal/CwModalReportFunctional.d.ts +2 -2
  50. package/dist/src/components/layout/modal/CwModalReportFunctional.d.ts.map +1 -1
  51. package/dist/src/components/layout/modal/legacy/cw_modal_report.d.ts.map +1 -1
  52. package/dist/src/components/layout/tabs/CwTabs.d.ts +2 -1
  53. package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
  54. package/dist/src/index.d.ts +3 -2
  55. package/dist/src/index.d.ts.map +1 -1
  56. package/package.json +1 -1
package/dist/index.cjs.js CHANGED
@@ -140,17 +140,17 @@ function CwTooltip(CwelltTooltipProps) {
140
140
  function CwTag(tagProps) {
141
141
  const hideTag = (event_clickTag) => {
142
142
  const tag = event_clickTag.currentTarget.parentElement;
143
- tag.classList.add("cwellt_display_none");
143
+ tag?.classList.add("cwellt_display_none");
144
144
  };
145
145
  const onClickClosableCustomTag = (event_clickClosableT) => {
146
146
  hideTag(event_clickClosableT);
147
- if (typeof tagProps.onClickClosableTag === "function") {
147
+ if (tagProps.onClickClosableTag != undefined) {
148
148
  tagProps.onClickClosableTag(event_clickClosableT);
149
149
  }
150
150
  };
151
151
  const onClickCustomTag = (event_clickTag) => {
152
152
  // click option interface
153
- if (typeof tagProps.onClickTag === "function") {
153
+ if (tagProps.onClickTag !== undefined) {
154
154
  tagProps.onClickTag(event_clickTag);
155
155
  }
156
156
  };
@@ -242,30 +242,53 @@ function CwDisplayMessage(message, type, duration) {
242
242
  CwMessageManager.getInstance().showMessage(message, type, duration);
243
243
  }
244
244
 
245
- function CwLoading(props) {
246
- return (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("div", { "aria-busy": props.cwelltBooleanLoading, className: props.cwelltBooleanLoading === true
247
- ? "cwellt_flex cwellt_flex_column cwelltContentLoading " +
248
- (props.cwelltClassNameContentLoading === undefined ? "" : props.cwelltClassNameContentLoading)
249
- : "", children: [props.cwelltBooleanLoading === true ? (
250
- // Container loading [ Icon and text of loading here is the property: cwelltClassNameLoading to custom orientation Vertical or Horizontal ]
251
- jsxRuntime.jsxs("div", { className: props.cwelltClassNameLoading === undefined
252
- ? "cwelltContainerLoading cwellt_flex cwellt_justify_center cwellt_align_items_center cwellt_flex_wrap "
253
- : props.cwelltClassNameLoading +
254
- " cwelltContainerLoading cwellt_flex cwellt_justify_center cwellt_align_items_center cwellt_flex_wrap", children: [jsxRuntime.jsx("div", { className: props.cwelltSizeLoading === undefined
255
- ? "cwelltDefaultLoadingSize cwellt_loading cwellt_flex cwellt_align_items_center "
256
- : props.cwelltSizeLoading +
257
- " cwelltDefaultLoadingSize cwellt_loading cwellt_flex cwellt_align_items_center ", children: jsxRuntime.jsx("span", { className: "cwelltIconLoading cwellt_flex cwellt_justify_center cwellt_align_items_center" }) }), jsxRuntime.jsx("div", { className: "cwelltTextLoading", children: jsxRuntime.jsx("h1", { children: props.cwelltTextLoading }) })] })) : (jsxRuntime.jsx("div", {})), jsxRuntime.jsx("div", { className: props.cwelltBooleanLoading === true ? "cwelltContentLoadingDisabled" : "", children: props.children })] }) }));
245
+ /**
246
+ * CwLoading
247
+ *
248
+ * A versatile loading component that shows a spinner with optional text
249
+ * and disables the wrapped content while in loading state.
250
+ *
251
+ * @example
252
+ * // Basic usage
253
+ * <CwLoading isLoading={isSubmitting}>
254
+ * <form>...</form>
255
+ * </CwLoading>
256
+ *
257
+ * // With custom text and size
258
+ * <CwLoading
259
+ * isLoading={isLoading}
260
+ * text="Please wait..."
261
+ * size="large"
262
+ * >
263
+ * <UserProfile />
264
+ * </CwLoading>
265
+ */
266
+ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName = 'cwi-plane-solid', animation = 'spin', children }) {
267
+ const iconClasses = `cwi-icons ${iconName || ''}`;
268
+ return (jsxRuntime.jsxs("div", { "aria-busy": isLoading, className: isLoading ? 'cw-loading-container' : '', children: [isLoading && (jsxRuntime.jsxs("div", { className: "cw-loading-content", "data-size": size, "data-animation": animation, children: [jsxRuntime.jsx("div", { className: "cw-loading", "data-icon-position": iconPosition, children: jsxRuntime.jsx("span", { className: iconClasses }) }), text && (jsxRuntime.jsx("p", { children: text }))] })), jsxRuntime.jsx("div", { className: isLoading ? 'cw-loading-disabled-content' : '', children: children })] }));
258
269
  }
259
270
 
271
+ /**
272
+ * @deprecated since may 2025. Use <CwLoading size="small"> instead.
273
+ *
274
+ * This component will be removed in a future release.
275
+ *
276
+ * @example
277
+ * // Instead of:
278
+ * <CwLoadingSmall />
279
+ *
280
+ * // Use:
281
+ * <CwLoading size="small" />
282
+ */
260
283
  function CwLoadingSmall(CwelltLoadingAppointements) {
261
- return (jsxRuntime.jsx("div", { children: CwelltLoadingAppointements.cwelltBooleanLoadingAppointment === true ? (
284
+ return (jsxRuntime.jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (
262
285
  // * Show loading appointment
263
- jsxRuntime.jsx("div", { className: "cwellt_loadingAppointmentContainer cwellt_loading cwellt_flex cwellt_align_items_center cwellt_loading cwellt_flex cwellt_align_items_center ", children: jsxRuntime.jsx("span", { className: "cwelltIconLoading cwellt_flex cwellt_justify_center cwellt_align_items_center" }) })) : (
286
+ jsxRuntime.jsx("div", { className: "cw-loading-container", children: jsxRuntime.jsx("div", { className: "cw-loading" }) })) : (
264
287
  // Show empty div
265
- jsxRuntime.jsx("div", { className: "cwellt_d_none" })) }));
288
+ jsxRuntime.jsx("div", {})) }));
266
289
  }
267
290
 
268
- var styles$a = {"cw-generic-tooltip":"cw-generic-tooltip-module_cw-generic-tooltip__Ij76M","cw-generic-tooltip-content":"cw-generic-tooltip-module_cw-generic-tooltip-content__la-Si"};
291
+ var styles$b = {"cw-generic-tooltip-content":"cw-generic-tooltip-module_cw-generic-tooltip-content__la-Si"};
269
292
 
270
293
  // Constants moved outside to prevent recreation
271
294
  const margin = 16;
@@ -370,23 +393,25 @@ const useTooltipPosition = (isVisible, containerRef, preferredPosition, tooltipC
370
393
  return tooltipState;
371
394
  };
372
395
  // Main component with optimizations
373
- const CwGenericTooltip = ({ children, content = null, position = defaultPosition, dissapearsWhenHover = false, overlayStyle = {}, showDelay = 0, }) => {
396
+ const CwGenericTooltip = ({ children, content = null, position = defaultPosition, dissapearsWhenHover = false, hide = false, overlayStyle = {}, showDelay = 0, }) => {
374
397
  const [isVisible, setIsVisible] = React.useState(false);
375
398
  const containerRef = React.useRef(null);
376
- const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => setIsVisible(true), showDelay);
377
- const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$a["cw-generic-tooltip-content"]);
399
+ const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
400
+ setIsVisible(true);
401
+ }, showDelay);
402
+ const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$b["cw-generic-tooltip-content"]);
378
403
  // Memoize tooltip content creation
379
404
  const tooltipContent = React.useMemo(() => {
380
- if (!isVisible || !content)
405
+ if (hide || !isVisible || !content)
381
406
  return null;
382
- return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$a["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, style: {
407
+ return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$b["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, style: {
383
408
  position: 'fixed',
384
409
  top: `${tooltipPosition.top}px`,
385
410
  left: `${tooltipPosition.left}px`,
386
411
  visibility: tooltipPosition.top === 0 && tooltipPosition.left === 0 ? 'hidden' : 'visible',
387
412
  ...overlayStyle
388
413
  }, onMouseEnter: () => dissapearsWhenHover && setIsVisible(false), children: content }), document.body);
389
- }, [isVisible, content, actualPosition, tooltipPosition, dissapearsWhenHover, overlayStyle]);
414
+ }, [isVisible, content, actualPosition, tooltipPosition, dissapearsWhenHover, overlayStyle, hide]);
390
415
  const handleMouseEnter = React.useCallback(() => {
391
416
  setTooltipTimeout();
392
417
  }, [setTooltipTimeout]);
@@ -394,7 +419,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
394
419
  clearTooltipTimeout();
395
420
  setIsVisible(false);
396
421
  }, [clearTooltipTimeout]);
397
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$a["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, children: [tooltipContent, children] }));
422
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$b["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, children: [tooltipContent, children] }));
398
423
  };
399
424
 
400
425
  // Reference for draggable modal
@@ -513,19 +538,107 @@ class CwModalIframe extends React__namespace.Component {
513
538
  }
514
539
  }
515
540
 
516
- var styles$9 = {"cw-dialog-main":"cw-dialog-module_cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module_cw-dialog-button-close__9GRd8","cw-dialog-button-save":"cw-dialog-module_cw-dialog-button-save__eZ9SI"};
541
+ var styles$a = {"cw-dialog-main":"cw-dialog-module_cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module_cw-dialog-button-close__9GRd8"};
517
542
 
543
+ // Helper function to parse size values
544
+ const parseSize = (size) => {
545
+ if (typeof size === 'number')
546
+ return { value: size, unit: 'px' };
547
+ // Match numeric value and unit
548
+ const match = String(size).match(/^([\d.]+)(\D+)$/);
549
+ if (match) {
550
+ const unit = match[2];
551
+ // Only allow px, rem, vw, vh
552
+ if (['px', 'rem', 'vw', 'vh'].includes(unit)) {
553
+ return { value: parseFloat(match[1]), unit };
554
+ }
555
+ }
556
+ // Default to pixels if no unit specified or unit not supported
557
+ return { value: parseFloat(String(size)), unit: 'px' };
558
+ };
559
+ // Helper to convert size to px for calculations
560
+ const convertToPx = (size) => {
561
+ switch (size.unit) {
562
+ case 'px': return size.value;
563
+ case 'rem': return size.value * 16; // Assuming 1rem = 16px
564
+ case 'vh': return (window.innerHeight * size.value) / 100;
565
+ case 'vw': return (window.innerWidth * size.value) / 100;
566
+ default: return size.value; // Default fallback
567
+ }
568
+ };
569
+ // Function to convert from px back to original unit
570
+ const convertFromPx = (px, unit) => {
571
+ switch (unit) {
572
+ case 'px': return px;
573
+ case 'rem': return px / 16;
574
+ case 'vh': return (px * 100) / window.innerHeight;
575
+ case 'vw': return (px * 100) / window.innerWidth;
576
+ default: return px;
577
+ }
578
+ };
518
579
  const CwDialog = props => {
580
+ const { customFooter, customHeader, headline, width, height, dialogSize, scrim, onSave, onClose, hideFooter, children, open, ...domProps } = props;
519
581
  const dialogRef = React.useRef(null);
520
- const initialDialogSize = { width: props.dialogSize?.width ?? 800, height: props.dialogSize?.height ?? 600 };
582
+ const initialSetup = React.useMemo(() => {
583
+ // Default width and height with units
584
+ const defaultWidth = 800;
585
+ // Priority: direct props > dialogSize > default values
586
+ const initialWidth = width !== undefined
587
+ ? width
588
+ : dialogSize?.width !== undefined
589
+ ? dialogSize.width
590
+ : defaultWidth;
591
+ const initialHeight = height !== undefined
592
+ ? height
593
+ : dialogSize?.height !== undefined
594
+ ? dialogSize.height
595
+ : undefined; // Undefined for autoHeight
596
+ // Determine if height is automatic when height is not provided
597
+ const isAutoHeight = initialHeight === undefined;
598
+ // Parse the sizes to separate value and unit
599
+ const parsedWidth = parseSize(initialWidth);
600
+ const parsedHeight = isAutoHeight
601
+ ? { value: 0, unit: 'auto' }
602
+ : parseSize(initialHeight);
603
+ // Convert to px for internal calculations
604
+ const initialWidthPx = convertToPx(parsedWidth);
605
+ const initialHeightPx = isAutoHeight ? 0 : convertToPx(parsedHeight);
606
+ // Use estimated height for initial positioning when autoHeight is true
607
+ const initialEstimatedHeight = isAutoHeight ? 300 : initialHeightPx;
608
+ const initialDialogSize = {
609
+ width: initialWidthPx,
610
+ height: initialHeightPx,
611
+ widthUnit: parsedWidth.unit,
612
+ heightUnit: parsedHeight.unit,
613
+ autoHeight: isAutoHeight
614
+ };
615
+ const initialPosition = {
616
+ x: window.document.body.clientWidth / 2 - initialWidthPx / 2,
617
+ y: window.document.body.clientHeight / 2 - initialEstimatedHeight / 2
618
+ };
619
+ return { initialDialogSize, initialPosition };
620
+ }, [width, height, dialogSize]); // Only recalculate when these props change
521
621
  const [isDragging, setIsDragging] = React.useState(false);
522
622
  const [resizeDirection, setResizeDirection] = React.useState(null);
523
- const [position, setPosition] = React.useState({
524
- x: window.document.body.clientWidth / 2 - initialDialogSize.width / 2,
525
- y: window.document.body.clientHeight / 2 - initialDialogSize.height / 2
526
- });
527
- const [size, setSize] = React.useState(initialDialogSize);
623
+ const [position, setPosition] = React.useState(initialSetup.initialPosition);
624
+ const [size, setSize] = React.useState(initialSetup.initialDialogSize);
528
625
  const [dragStart, setDragStart] = React.useState({ x: 0, y: 0 });
626
+ // scrim is true by default
627
+ const hasScrim = scrim !== false;
628
+ // Adjust position after the dialog is rendered when using autoHeight
629
+ React.useEffect(() => {
630
+ if (size.autoHeight && dialogRef.current && open) {
631
+ // Get the actual height after rendering
632
+ const actualHeight = dialogRef.current.offsetHeight;
633
+ // Only update position if height is available
634
+ if (actualHeight > 0) {
635
+ setPosition(prevPos => ({
636
+ ...prevPos,
637
+ y: window.document.body.clientHeight / 2 - actualHeight / 2
638
+ }));
639
+ }
640
+ }
641
+ }, [size.autoHeight, open]);
529
642
  React.useEffect(() => {
530
643
  const handleMouseMove = (e) => {
531
644
  if (isDragging) {
@@ -555,26 +668,40 @@ const CwDialog = props => {
555
668
  let newY = position.y;
556
669
  const minVisiblePx = 64;
557
670
  const minSize = 100;
558
- if (resizeDirection.includes("w")) {
559
- const dx = e.clientX - position.x;
560
- newWidth = Math.max(size.width - dx, minSize);
561
- newX = Math.min(Math.max(position.x + dx, minVisiblePx - newWidth), position.x + size.width - minSize);
562
- }
563
- if (resizeDirection.includes("e")) {
564
- newWidth = Math.min(Math.max(e.clientX - position.x, minSize), parentRect.width - position.x + dialogRect.width - minVisiblePx);
671
+ // Only allow horizontal resizing if autoHeight is true
672
+ if (!size.autoHeight || (!resizeDirection.includes("n") && !resizeDirection.includes("s"))) {
673
+ // Logic for horizontal resizing
674
+ if (resizeDirection.includes("w")) {
675
+ const dx = e.clientX - position.x;
676
+ newWidth = Math.max(size.width - dx, minSize);
677
+ newX = Math.min(Math.max(position.x + dx, minVisiblePx - newWidth), position.x + size.width - minSize);
678
+ }
679
+ if (resizeDirection.includes("e")) {
680
+ newWidth = Math.min(Math.max(e.clientX - position.x, minSize), parentRect.width - position.x + dialogRect.width - minVisiblePx);
681
+ }
565
682
  }
566
- if (resizeDirection.includes("n")) {
567
- const dy = e.clientY - position.y;
568
- newHeight = Math.max(size.height - dy, minSize);
569
- newY = Math.min(Math.max(position.y + dy, minVisiblePx - newHeight), position.y + size.height - minSize);
570
- }
571
- if (resizeDirection.includes("s")) {
572
- newHeight = Math.min(Math.max(e.clientY - position.y, minSize), parentRect.height - position.y + dialogRect.height - minVisiblePx);
683
+ // Only apply vertical resizing if autoHeight is false
684
+ if (!size.autoHeight) {
685
+ if (resizeDirection.includes("n")) {
686
+ const dy = e.clientY - position.y;
687
+ newHeight = Math.max(size.height - dy, minSize);
688
+ newY = Math.min(Math.max(position.y + dy, minVisiblePx - newHeight), position.y + size.height - minSize);
689
+ }
690
+ if (resizeDirection.includes("s")) {
691
+ newHeight = Math.min(Math.max(e.clientY - position.y, minSize), parentRect.height - position.y + dialogRect.height - minVisiblePx);
692
+ }
573
693
  }
574
694
  // Ensure the modal stays within bounds after resizing
575
695
  newX = Math.min(Math.max(newX, minVisiblePx - newWidth), parentRect.width - minVisiblePx);
576
696
  newY = Math.min(Math.max(newY, minVisiblePx - newHeight), parentRect.height - minVisiblePx);
577
- setSize({ width: newWidth, height: newHeight });
697
+ // Update state maintaining original units
698
+ setSize({
699
+ width: newWidth,
700
+ height: newHeight,
701
+ widthUnit: size.widthUnit,
702
+ heightUnit: size.heightUnit,
703
+ autoHeight: size.autoHeight
704
+ });
578
705
  setPosition({ x: newX, y: newY });
579
706
  }
580
707
  }
@@ -591,38 +718,54 @@ const CwDialog = props => {
591
718
  document.removeEventListener("mouseup", handleMouseUp);
592
719
  };
593
720
  }, [isDragging, resizeDirection, dragStart, position, size]);
594
- const handleMouseDown = (e) => {
721
+ const handleMouseDown = React.useCallback((e) => {
595
722
  setIsDragging(true);
596
723
  setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });
597
- };
598
- const handleResizeMouseDown = (direction) => (e) => {
724
+ }, [position]);
725
+ const handleResizeMouseDown = React.useCallback((direction) => (e) => {
599
726
  e.stopPropagation();
600
727
  setResizeDirection(direction);
601
- };
602
- const header = (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: props.headline }), props.customHeader || (jsxRuntime.jsx("button", { className: styles$9["cw-dialog-button-close"], onClick: props.onClose, children: "\u2A2F" }))] }));
603
- const content = (jsxRuntime.jsx("section", { style: { flex: 1, overflowX: "auto", overflowY: "auto", width: "100%" }, children: props.children }));
604
- const footer = (jsxRuntime.jsx("footer", { style: { width: "100%" }, children: props.customFooter || (jsxRuntime.jsx("button", { className: styles$9["cw-dialog-button-save"], onClick: props.onSave, children: "\uD83D\uDDAB" })) }));
605
- const resizeHandles = [
606
- jsxRuntime.jsx("div", { "data-handle-n": true, onMouseDown: handleResizeMouseDown("n") }, "handle-n"),
607
- jsxRuntime.jsx("div", { "data-handle-s": true, onMouseDown: handleResizeMouseDown("s") }, "handle-s"),
608
- jsxRuntime.jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
609
- jsxRuntime.jsx("div", { "data-handle-w": true, onMouseDown: handleResizeMouseDown("w") }, "handle-w"),
610
- jsxRuntime.jsx("div", { "data-handle-ne": true, onMouseDown: handleResizeMouseDown("ne") }, "handle-ne"),
611
- jsxRuntime.jsx("div", { "data-handle-nw": true, onMouseDown: handleResizeMouseDown("nw") }, "handle-nw"),
612
- jsxRuntime.jsx("div", { "data-handle-se": true, onMouseDown: handleResizeMouseDown("se") }, "handle-se"),
613
- jsxRuntime.jsx("div", { "data-handle-sw": true, onMouseDown: handleResizeMouseDown("sw") }, "handle-sw")
614
- ];
615
- return (props.open && (jsxRuntime.jsx("div", { "data-has-scrim": props.scrim, className: styles$9["cw-dialog-main"], children: jsxRuntime.jsxs("dialog", { ...props, ref: dialogRef, style: {
728
+ }, []);
729
+ const handleScrimClick = React.useCallback((e) => {
730
+ if (e.target === e.currentTarget && onClose) {
731
+ onClose();
732
+ }
733
+ }, [onClose]);
734
+ const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$a["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
735
+ const content = React.useMemo(() => (jsxRuntime.jsx("section", { children: children })), [children]);
736
+ const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx("button", { className: "cw-button-icon cwi-save", onClick: onSave })) })), [customFooter, onSave]);
737
+ const resizeHandles = React.useMemo(() => size.autoHeight
738
+ ? [
739
+ // Only horizontal handles if autoHeight is true
740
+ jsxRuntime.jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
741
+ jsxRuntime.jsx("div", { "data-handle-w": true, onMouseDown: handleResizeMouseDown("w") }, "handle-w")
742
+ ]
743
+ : [
744
+ // All handles if autoHeight is false
745
+ jsxRuntime.jsx("div", { "data-handle-n": true, onMouseDown: handleResizeMouseDown("n") }, "handle-n"),
746
+ jsxRuntime.jsx("div", { "data-handle-s": true, onMouseDown: handleResizeMouseDown("s") }, "handle-s"),
747
+ jsxRuntime.jsx("div", { "data-handle-e": true, onMouseDown: handleResizeMouseDown("e") }, "handle-e"),
748
+ jsxRuntime.jsx("div", { "data-handle-w": true, onMouseDown: handleResizeMouseDown("w") }, "handle-w"),
749
+ jsxRuntime.jsx("div", { "data-handle-ne": true, onMouseDown: handleResizeMouseDown("ne") }, "handle-ne"),
750
+ jsxRuntime.jsx("div", { "data-handle-nw": true, onMouseDown: handleResizeMouseDown("nw") }, "handle-nw"),
751
+ jsxRuntime.jsx("div", { "data-handle-se": true, onMouseDown: handleResizeMouseDown("se") }, "handle-se"),
752
+ jsxRuntime.jsx("div", { "data-handle-sw": true, onMouseDown: handleResizeMouseDown("sw") }, "handle-sw")
753
+ ], [size.autoHeight, handleResizeMouseDown]);
754
+ const displayDimensions = React.useMemo(() => {
755
+ // Prepare width and height with original units for display
756
+ const displayWidth = `${convertFromPx(size.width, size.widthUnit)}${size.widthUnit}`;
757
+ // If autoHeight, don't specify height and let it adapt to content
758
+ const displayHeight = size.autoHeight
759
+ ? 'auto'
760
+ : `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
761
+ return { displayWidth, displayHeight };
762
+ }, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
763
+ return (open && (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$a["cw-dialog-main"], onClick: handleScrimClick, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
616
764
  left: `${position.x}px`,
617
765
  top: `${position.y}px`,
618
- width: `${size.width}px`,
619
- height: `${size.height}px`,
620
- zIndex: props.zIndex,
621
- minWidth: "200px", // Set an appropriate minimum size
622
- minHeight: "200px", // Set an appropriate minimum size
623
- display: "flex",
624
- flexDirection: "column"
625
- }, children: [header, content, props.isReport !== true && footer, resizeHandles] }) })));
766
+ width: displayDimensions.displayWidth,
767
+ height: displayDimensions.displayHeight
768
+ }, children: [header, content, hideFooter !== true && footer, resizeHandles] }) })));
626
769
  };
627
770
 
628
771
  const CwModalReportFunctional = (props) => {
@@ -643,7 +786,9 @@ const CwModalReportFunctional = (props) => {
643
786
  return (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", props.reportName, " report in ", props.moduleSettings, " Settings"] }));
644
787
  }
645
788
  };
646
- return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: isModal ? (jsxRuntime.jsx(CwDialog, { open: props.visible, dialogSize: { width: props.width, height: props.height }, headline: props.title, customFooter: [jsxRuntime.jsx("div", {}, "footer")], onClose: props.onCloseModal, isReport: true, children: renderContentModal() })) : (jsxRuntime.jsx("div", { children: renderContentNotModal() })) }));
789
+ return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: isModal ? (jsxRuntime.jsx(CwDialog, { open: props.visible, width: props.width, headline: props.title,
790
+ //customFooter={[<div key="footer"></div>]}
791
+ onClose: props.onCloseModal, hideFooter: true, children: renderContentModal() })) : (jsxRuntime.jsx("div", { children: renderContentNotModal() })) }));
647
792
  };
648
793
 
649
794
  class CwReportModal extends React__namespace.Component {
@@ -663,10 +808,10 @@ class CwReportModal extends React__namespace.Component {
663
808
  };
664
809
  }
665
810
  render() {
666
- return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: this.state.isModal === true ? (jsxRuntime.jsxs(CwDialog, { open: this.props.visible, dialogSize: { width: this.props.width, height: this.props.height }, headline: this.props.title, customFooter: new Array(jsxRuntime.jsx("div", {})), onClose: () => {
811
+ return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: this.state.isModal === true ? (jsxRuntime.jsxs(CwDialog, { open: this.props.visible, width: this.props.width, headline: this.props.title, customFooter: new Array(jsxRuntime.jsx("div", {})), onClose: () => {
667
812
  this.formRef?.current?.resetFields();
668
813
  this.props.SET_MODAL_REPORT_VISIBLE(false);
669
- }, isReport: true, children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", overflowX: "auto", overflowY: "auto" }, children: jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", style: { width: "100%", height: "100%", display: "block" } }) })), this.props.name === "Empty.pdf" && (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("h1", { style: { marginLeft: "2em" }, children: [" ", "Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }) }))] })) : (jsxRuntime.jsxs("div", { children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", width: "100%", height: "600px" })), this.props.name === "Empty.pdf" && (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }))] })) }));
814
+ }, hideFooter: true, children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", overflowX: "auto", overflowY: "auto" }, children: jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", style: { width: "100%", height: "100%", display: "block" } }) })), this.props.name === "Empty.pdf" && (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("h1", { style: { marginLeft: "2em" }, children: [" ", "Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }) }))] })) : (jsxRuntime.jsxs("div", { children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", width: "100%", height: "600px" })), this.props.name === "Empty.pdf" && (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }))] })) }));
670
815
  }
671
816
  }
672
817
 
@@ -767,6 +912,8 @@ class CwDialogManager {
767
912
  }
768
913
  }
769
914
 
915
+ var styles$9 = {"cw-accordion":"cw-accordion-module_cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module_cw-accordion-body__xlI8b"};
916
+
770
917
  /**
771
918
  *
772
919
  * @param CwelltAccordionContainerProps
@@ -782,169 +929,211 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
782
929
  setVisible_accordionBody(!isVisible_accordionBody);
783
930
  };
784
931
  // #endregion
785
- return (jsxRuntime.jsxs("div", { className: "cwellt_accordionContainer cwellt_flex cwellt_flex_column cwellt_justify_center cwellt_align_items_center", style: CwelltAccordionContainerProps.style, children: [jsxRuntime.jsxs("div", { className: "cwellt_flex cwelt_accordionHeader cwellt_align_items_center", onClick: () => showAccordionBody(), children: [jsxRuntime.jsx("div", { className: "cwellt_descAccordion cwellt_flex cwellt_align_items_center cwellt_justify_flex_start cwellt_flex_11", children: jsxRuntime.jsx("div", { className: "cwellt_desc_tex", children: CwelltAccordionContainerProps.desc_text }) }), jsxRuntime.jsx("div", { className: "cwellt_btnContent_expandCollapse cwellt_flex cwellt_align_items_center cwellt_justify_center cwellt_flex_1", children: jsxRuntime.jsx("button", { className: isVisible_accordionBody
786
- ? "cwellt_expandCollapse_active cwellt_flex cwellt_align_items_center cwellt_justify_center"
787
- : "cwellt_expandCollapse cwellt_flex cwellt_align_items_center cwellt_justify_center" }) })] }), jsxRuntime.jsx("div", { className: isVisible_accordionBody
788
- ? "cwellt_accordionBody cwellt_flex cwellt_flex_column cwellt_justify_flex_start"
789
- : "cwellt_accordionBody cwellt_display_none cwellt_flex_column cwellt_justify_flex_start", children: CwelltAccordionContainerProps.children })] }));
932
+ return (jsxRuntime.jsxs("div", { className: styles$9["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxRuntime.jsxs("header", { onClick: () => showAccordionBody(), children: [jsxRuntime.jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsxRuntime.jsx("button", { className: "cw-button-icon" })] }), jsxRuntime.jsx("div", { className: styles$9["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
790
933
  }
791
934
 
792
935
  /**
793
- * A Table view
794
- * @param props
936
+ * A reusable and customizable table component.
937
+ *
938
+ * @param props - Component props to configure columns, data, styles, pagination, expanded rows, and more.
939
+ *
795
940
  * @example
796
941
  * const columns = [
797
942
  * {
798
943
  * title: 'Name',
799
944
  * dataIndex: 'name',
800
945
  * key: 'name',
946
+ * sortable: true, // Column is sortable
947
+ * width: 100 // You can define the width of the column
801
948
  * },
802
949
  * {
803
950
  * title: 'Age',
804
951
  * dataIndex: 'age',
805
952
  * key: 'age',
806
- * render: (age) => <span>{age} years</span>, // Example of custom rendering
953
+ * sortable: true,
954
+ * render: (item) => <span>{item.age} years</span> // Custom rendering
807
955
  * },
808
956
  * {
809
957
  * title: 'Address',
810
958
  * dataIndex: 'address',
811
959
  * key: 'address',
812
- * render: (address) => (
813
- * <a href={`https://maps.google.com/?q=${encodeURIComponent(address)}`} target="_blank">
814
- * {address}
960
+ * render: (item) => (
961
+ * <a href={`https://maps.google.com/?q=${encodeURIComponent(item.address)}`} target="_blank" rel="noreferrer">
962
+ * {item.address}
815
963
  * </a>
816
- * ), // Example of custom link rendering
817
- * },
964
+ * ) // Link rendering
965
+ * }
818
966
  * ];
819
967
  *
820
968
  * const data = [
821
- * {
822
- * key: '1',
823
- * name: 'Mike',
824
- * age: 32,
825
- * address: '10 Downing Street',
826
- * },
827
- * {
828
- * key: '2',
829
- * name: 'John',
830
- * age: 42,
831
- * address: '10 Downing Street',
832
- * },
833
- * {
834
- * key: '3',
835
- * name: 'Andres',
836
- * age: 33,
837
- * address: '10 Downing Street',
838
- * },
839
- * {
840
- * key: '4',
841
- * name: 'Gabriel',
842
- * age: 22,
843
- * address: '10 Downing Street',
844
- * },
845
- * {
846
- * key: '5',
847
- * name: 'Sergio',
848
- * age: 47,
849
- * address: '10 Downing Street',
850
- * },
851
- * {
852
- * key: '6',
853
- * name: 'Zacarias',
854
- * age: 61,
855
- * address: '10 Downing Street',
856
- * },
969
+ * { key: '1', name: 'Mike', age: 32, address: '10 Downing Street' },
970
+ * { key: '2', name: 'John', age: 42, address: '11 Downing Street' },
971
+ * { key: '3', name: 'Andres', age: 33, address: '12 Downing Street' },
972
+ * { key: '4', name: 'Gabriel', age: 22, address: '13 Downing Street' },
973
+ * { key: '5', name: 'Sergio', age: 47, address: '14 Downing Street' },
974
+ * { key: '6', name: 'Zacarias', age: 61, address: '15 Downing Street' }
857
975
  * ];
858
976
  *
859
- * const generateExpandedContent = (record) => {
860
- * var testValue = record;
861
- * return (
862
- * <div>
863
- * Contenido expandido personalizado para {record.name}
864
- * </div>
865
- * );
866
- * };
867
- *
868
- * ------------------------- render ---------------------------
977
+ * const generateExpandedContent = (record) => (
978
+ * <div>
979
+ * Custom expanded content for {record.name}
980
+ * </div>
981
+ * );
869
982
  *
870
983
  * <CwTable
871
984
  * columns={columns}
872
- * data={data} // WTF whatever array of objects you add here, make sure each has a key otherwise everything will expand
873
- * itemsPerPage={3}
985
+ * data={data}
874
986
  * pagination={true}
987
+ * pageSizeOptions={[3, 5, 10]} // Optional, defaults to [5, 10, 20, 50]
875
988
  * expandedRowRender={generateExpandedContent}
876
- * onExpand={(e)=> test(e)}
989
+ * onExpand={(item) => console.log('Expanded:', item)}
990
+ * rowKey="key" // Optional, defaults to 'key'
991
+ * textNoData="No data available" // Optional message when no data
992
+ * loading={false} // Optional, shows loading indicator
993
+ * scrollHeight={300} // Optional scroll height, defaults to 300
994
+ * stickyHeader={true} // Optional, makes header sticky on scroll
995
+ * classNameContainer="my-table-wrapper" // Optional wrapper class
996
+ * className="my-table" // Optional table class
997
+ * classNameRow="my-table-row" // Optional class for each row
998
+ * id="custom-table-id" // Optional ID for the container
999
+ * style={{ border: '1px solid #ccc' }} // Optional inline styles
877
1000
  * />
1001
+ *
878
1002
  * @returns React component
879
1003
  */
880
- function CwTable({ columns, data, pagination, itemsPerPage, expandedRowRender, onExpand, className, classNameHeader, classNameTr_row, style, classNameContainer, id, textNoData }) {
1004
+ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, }) {
881
1005
  const [currentPage, setCurrentPage] = React.useState(1);
882
1006
  const [expandedRowKey, setExpandedRowKey] = React.useState(null);
883
1007
  const [sortConfig, setSortConfig] = React.useState({
884
1008
  key: null,
885
1009
  direction: "asc"
886
1010
  });
887
- // Function to handle expanding/collapsing rows
888
- const handleRowExpand = (rowKey) => {
889
- if (expandedRowKey === rowKey.key) {
890
- setExpandedRowKey(null);
891
- }
892
- else {
893
- setExpandedRowKey(rowKey.key);
894
- }
895
- if (typeof onExpand === "function") {
896
- onExpand(rowKey);
897
- }
898
- };
899
- // Function to handle sorting by column
900
- const handleSort = (columnKey) => {
901
- let direction = "asc";
902
- if (sortConfig.key === columnKey && sortConfig.direction === "asc") {
903
- direction = "desc";
904
- }
905
- setSortConfig({ key: columnKey, direction });
906
- };
907
- // Use useMemo to calculate sortedData
1011
+ const [localItemsPerPage, setLocalItemsPerPage] = React.useState(pageSizeOptions[0]);
1012
+ const [columnWidths, setColumnWidths] = React.useState(() => columns.reduce((acc, col) => {
1013
+ if (col.width)
1014
+ acc[col.key] = col.width;
1015
+ return acc;
1016
+ }, {}));
1017
+ const handleItemsPerPageChange = React.useCallback((e) => {
1018
+ setLocalItemsPerPage(parseInt(e.target.value, 10));
1019
+ setCurrentPage(1);
1020
+ }, []);
1021
+ const handleRowExpand = React.useCallback((item) => {
1022
+ const itemKey = item[rowKey];
1023
+ setExpandedRowKey(prev => (prev === itemKey ? null : itemKey));
1024
+ onExpand?.(item);
1025
+ }, [rowKey, onExpand]);
1026
+ const handleSort = React.useCallback((columnKey) => {
1027
+ setSortConfig(prev => {
1028
+ if (prev.key !== columnKey)
1029
+ return { key: columnKey, direction: "asc" };
1030
+ if (prev.direction === "asc")
1031
+ return { key: columnKey, direction: "desc" };
1032
+ return { key: null, direction: "asc" };
1033
+ });
1034
+ }, []);
908
1035
  const sortedData = React.useMemo(() => {
909
1036
  if (!data || data.length === 0)
910
- return null;
1037
+ return [];
911
1038
  const dataCopy = [...data];
912
- if (sortConfig.key !== null) {
1039
+ if (sortConfig.key) {
913
1040
  dataCopy.sort((a, b) => {
914
- const aValue = a[sortConfig.key];
915
- const bValue = b[sortConfig.key];
916
- if (aValue < bValue) {
917
- return sortConfig.direction === "asc" ? -1 : 1;
918
- }
919
- if (aValue > bValue) {
920
- return sortConfig.direction === "asc" ? 1 : -1;
921
- }
922
- return 0;
1041
+ const aVal = a[sortConfig.key];
1042
+ const bVal = b[sortConfig.key];
1043
+ return (aVal < bVal ? -1 : aVal > bVal ? 1 : 0) * (sortConfig.direction === "asc" ? 1 : -1);
923
1044
  });
924
1045
  }
925
1046
  return dataCopy;
926
1047
  }, [data, sortConfig]);
927
- // Calculate paged data only if sortedData is not null
928
1048
  const paginatedData = React.useMemo(() => {
929
1049
  if (!sortedData)
930
- return null;
931
- const startIndex = itemsPerPage !== undefined ? (currentPage - 1) * itemsPerPage : 0;
932
- const endIndex = itemsPerPage !== undefined ? startIndex + itemsPerPage : sortedData.length;
933
- return sortedData.slice(startIndex, endIndex);
934
- }, [sortedData, currentPage, itemsPerPage]);
935
- // Calculate the total number of pages for pagination
1050
+ return [];
1051
+ if (!pagination)
1052
+ return sortedData;
1053
+ const start = (currentPage - 1) * localItemsPerPage;
1054
+ return sortedData.slice(start, start + localItemsPerPage);
1055
+ }, [sortedData, currentPage, localItemsPerPage, pagination]);
936
1056
  const totalPages = React.useMemo(() => {
937
- if (!sortedData)
938
- return 0;
939
- return itemsPerPage !== undefined ? Math.ceil(sortedData.length / itemsPerPage) : 1;
940
- }, [sortedData, itemsPerPage]);
941
- // Function to handle page change
942
- const handlePageChange = (newPage) => {
943
- if (newPage >= 1 && newPage <= totalPages) {
944
- setCurrentPage(newPage);
1057
+ return pagination ? Math.ceil(sortedData.length / localItemsPerPage) : 1;
1058
+ }, [sortedData, localItemsPerPage, pagination]);
1059
+ const handlePageChange = (page) => {
1060
+ if (page >= 1 && page <= totalPages)
1061
+ setCurrentPage(page);
1062
+ };
1063
+ const startResize = (e, key) => {
1064
+ e.preventDefault();
1065
+ const startX = e.clientX;
1066
+ const startWidth = e.target.parentElement?.offsetWidth || 0;
1067
+ const onMouseMove = (moveEvent) => {
1068
+ const newWidth = Math.max(startWidth + moveEvent.clientX - startX, 50); // mínimo 50px
1069
+ setColumnWidths(prev => ({ ...prev, [key]: newWidth }));
1070
+ };
1071
+ const onMouseUp = () => {
1072
+ window.removeEventListener("mousemove", onMouseMove);
1073
+ window.removeEventListener("mouseup", onMouseUp);
1074
+ };
1075
+ window.addEventListener("mousemove", onMouseMove);
1076
+ window.addEventListener("mouseup", onMouseUp);
1077
+ };
1078
+ const scrollContainerStyle = React.useMemo(() => {
1079
+ if (stickyHeader || scrollHeight) {
1080
+ return {
1081
+ maxHeight: scrollHeight ?? 300,
1082
+ overflowY: "auto"
1083
+ };
945
1084
  }
1085
+ return {}; // sin altura ni scroll
1086
+ }, [stickyHeader, scrollHeight]);
1087
+ const getColSpan = () => columns.length + (expandedRowRender ? 1 : 0);
1088
+ const renderTableBody = () => {
1089
+ if (loading) {
1090
+ return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: getColSpan(), children: jsxRuntime.jsx("div", { className: "text-center py-4 text-muted-foreground", children: "Loading data..." }) }) }));
1091
+ }
1092
+ if (!paginatedData || paginatedData.length === 0) {
1093
+ return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: getColSpan(), className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
1094
+ }
1095
+ return paginatedData.map(item => {
1096
+ const itemKey = item[rowKey];
1097
+ if (!itemKey)
1098
+ console.warn("Missing row key for item", item);
1099
+ return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("tr", { className: classNameRow ?? "", children: [expandedRowRender && (jsxRuntime.jsx("td", { className: "cw-table-col-action cw-table-col-expand", children: jsxRuntime.jsx("button", { onClick: () => handleRowExpand(item), className: `cw-button-icon ${expandedRowKey === itemKey ? "cwi-chevron-down" : "cwi-chevron-right"}` }) })), columns.map(col => (jsxRuntime.jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : item[col.dataIndex] }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsxRuntime.jsx("tr", { className: "cw-table-row-expanded", children: jsxRuntime.jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, itemKey));
1100
+ });
946
1101
  };
947
- return (jsxRuntime.jsxs("div", { id: id, className: classNameContainer + " " + "cwTableComp", children: [jsxRuntime.jsxs("table", { className: className + " " + "cw_table", style: style, children: [jsxRuntime.jsx("thead", { className: `${classNameHeader} cw_thead`, children: jsxRuntime.jsxs("tr", { className: "cw_thead_tr", children: [expandedRowRender && jsxRuntime.jsx("th", { className: "cw_thead_th cw_thead_th_expand" }), columns.map(column => (jsxRuntime.jsx("th", { onClick: () => handleSort(column.dataIndex), className: `cw_thead_th ${column.className} ${sortConfig.key === column.dataIndex ? sortConfig.direction : ""}`, children: column.title }, column.key)))] }) }), jsxRuntime.jsx("tbody", { className: "cw_tbody", children: !paginatedData || paginatedData.length === 0 ? (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: columns.length + (expandedRowRender ? 1 : 0), style: { textAlign: "center" }, children: textNoData !== undefined && textNoData !== "" ? textNoData : "No data" }) })) : (paginatedData.map(item => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("tr", { className: `${classNameTr_row} cw_tbody_tr`, children: [expandedRowRender && (jsxRuntime.jsx("td", { className: "cw_tbody_td", children: jsxRuntime.jsx("button", { onClick: () => handleRowExpand(item), className: `cwellt_flex cwellt_justify_center cwellt_align_items_center cw_button_expanded_collapse ${expandedRowKey === item.key ? "cw_button_expanded" : "cw_button_collapse"}` }) })), columns.map(column => (jsxRuntime.jsx("td", { className: "cw_tbody_td", children: column.render ? column.render(item) : item[column.dataIndex] }, `${item.key}_${column.key}`)))] }), expandedRowKey === item.key && expandedRowRender && (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: columns.length + 1, children: expandedRowRender(item) }) }))] }, item.key)))) })] }), pagination && totalPages > 1 && (jsxRuntime.jsxs("div", { className: "cw_table_pagination cwellt_flex cwellt_align-items-start cwellt_align_items_center", children: [jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1, className: "cw_tb_button_pag cw_tb_button_prev cwellt_flex cwellt_justify_center cwellt_align_items_center" }), jsxRuntime.jsxs("span", { className: "cw_table_pag_desc", children: ["Page ", currentPage, " of ", totalPages] }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages, className: "cw_tb_button_pag cw_tb_button_next cwellt_flex cwellt_justify_center cwellt_align_items_center" })] }))] }));
1102
+ return (jsxRuntime.jsxs("div", { id: id, className: `cw-table-container ${classNameContainer ?? ""}`, style: style, children: [jsxRuntime.jsx("div", { style: scrollContainerStyle, children: jsxRuntime.jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { style: stickyHeader
1103
+ ? { position: "sticky", top: 0, background: "white", zIndex: 2 }
1104
+ : undefined, children: jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("th", {}), columns.map(col => (jsxRuntime.jsxs("th", { onClick: () => col.sortable && handleSort(col.dataIndex), className: `${col.className ?? ""} ${sortConfig.key === col.dataIndex ? sortConfig.direction : ""}`.trim(), style: {
1105
+ cursor: col.sortable ? "pointer" : "default",
1106
+ userSelect: "none",
1107
+ width: columnWidths[col.key] ?? col.width,
1108
+ position: "relative",
1109
+ ...((col.width || columnWidths[col.key]) && {
1110
+ minWidth: 50,
1111
+ maxWidth: columnWidths[col.key] ?? col.width
1112
+ }),
1113
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { children: col.title }), col.sortable && (jsxRuntime.jsx("span", { style: { fontSize: "12px", marginLeft: "6px" }, children: sortConfig.key !== col.dataIndex ? "↕" : sortConfig.direction === "asc" ? "↑" : "↓" }))] }), jsxRuntime.jsx("div", { onMouseDown: (e) => startResize(e, col.key), style: {
1114
+ position: "absolute",
1115
+ right: 0,
1116
+ top: 7,
1117
+ bottom: 0,
1118
+ width: "2px",
1119
+ cursor: "col-resize",
1120
+ zIndex: 1,
1121
+ backgroundColor: "white",
1122
+ height: 20,
1123
+ } })] }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderTableBody() })] }) }), pagination && (jsxRuntime.jsxs("footer", { className: "cw-table-pagination", children: [jsxRuntime.jsx("button", { onClick: () => handlePageChange(1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left-double", title: "First" }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left", title: "Previous" }), totalPages > 1 && (jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx("input", { type: "number", value: currentPage, onChange: (e) => {
1124
+ const value = parseInt(e.target.value, 10);
1125
+ if (!isNaN(value))
1126
+ handlePageChange(value);
1127
+ }, onBlur: (e) => {
1128
+ const value = parseInt(e.target.value, 10);
1129
+ if (isNaN(value) || value < 1 || value > totalPages) {
1130
+ handlePageChange(1);
1131
+ }
1132
+ }, min: 1, max: totalPages, style: {
1133
+ width: "4rem",
1134
+ textAlign: "center",
1135
+ marginRight: "0.5rem"
1136
+ } }), "of ", totalPages] })), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages === 1, className: "cw-button-icon cwi-chevron-right", title: "Next" }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages === 1, className: "cw-button-icon cwi-chevron-right-double", title: "Last" }), jsxRuntime.jsx("select", { value: localItemsPerPage, onChange: handleItemsPerPageChange, style: { marginLeft: "1rem" }, children: pageSizeOptions.map(size => (jsxRuntime.jsxs("option", { value: size, children: [size, " / page"] }, size))) })] }))] }));
948
1137
  }
949
1138
 
950
1139
  var styles$8 = {"cw-tabs":"cw-tabs-module_cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module_cw-tabs-content__HTp8d"};
@@ -987,7 +1176,10 @@ function CwTabs(CwTabsProps) {
987
1176
  }
988
1177
  };
989
1178
  const position = CwTabsProps.tabsPosition || 'top';
990
- return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, className: styles$8['cw-tabs'], "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { children: CwTabsProps.tabs.map(tab => (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title] }, tab.key))) }), jsxRuntime.jsx("div", { className: styles$8['cw-tabs-content'], children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
1179
+ const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
1180
+ ? { minWidth: CwTabsProps.tabsListWidth }
1181
+ : undefined;
1182
+ return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, className: styles$8['cw-tabs'], style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title] }, tab.key))) }), jsxRuntime.jsx("div", { className: styles$8['cw-tabs-content'], children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
991
1183
  }
992
1184
 
993
1185
  /**
@@ -1014,6 +1206,25 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
1014
1206
  return (jsxRuntime.jsx("div", { className: "cw-expandable", children: jsxRuntime.jsxs("details", { ref: myRef, ...detailsProps, children: [jsxRuntime.jsx("summary", { children: briefing }), children && jsxRuntime.jsx("section", { children: children })] }) }));
1015
1207
  };
1016
1208
 
1209
+ /**
1210
+ * A component for displaying key-value pairs in a definition list format
1211
+ * Used for read-only display of structured data
1212
+ *
1213
+ * @example
1214
+ * <CwKeyValueList
1215
+ * items={[
1216
+ * { key: "length", label: "Length", value: "10", suffix: "m" },
1217
+ * { key: "width", label: "Width", value: null, suffix: "m" }
1218
+ * ]}
1219
+ * emptyValue="N/A"
1220
+ * />
1221
+ */
1222
+ const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "row" }) => {
1223
+ return (jsxRuntime.jsx("dl", { className: `cw-keyvalue-list ${className}`, children: items.map(item => (jsxRuntime.jsxs("div", { className: `cw-keyvalue-list-item cw-flex-${direction}`, children: [jsxRuntime.jsx("dt", { children: item.label }), jsxRuntime.jsx("dd", { children: item.value !== undefined && item.value !== null && item.value !== ""
1224
+ ? `${item.value}${item.suffix ? ` ${item.suffix}` : ''}`
1225
+ : emptyValue })] }, item.key))) }));
1226
+ };
1227
+
1017
1228
  /**
1018
1229
  * A table with expandable row groups.
1019
1230
  * @param props The data to display
@@ -1137,20 +1348,24 @@ function CwInput(CwInputProps) {
1137
1348
  const handleClearClick = () => {
1138
1349
  CwInputProps.onChange("");
1139
1350
  };
1140
- return (jsxRuntime.jsxs("div", { className: CwInputProps.labelPosition === "inline"
1141
- ? "cwellt_flex cwellt_flex_row cwellt_align_items_center cw_inputContent"
1142
- : CwInputProps.labelPosition === "column"
1143
- ? "cwellt_flex cwellt_flex_column cwellt_align-items_baseline cw_inputContent"
1144
- : "cwellt_flex cwellt_flex_row cwellt_align_items_center cw_inputContent", children: [jsxRuntime.jsx("label", { className: CwInputProps.disabled === true
1351
+ return (jsxRuntime.jsxs("div", { className: CwInputProps.labelPosition === "column"
1352
+ ? "cw-flex-column"
1353
+ : "cw-flex-row ", children: [jsxRuntime.jsx("label", { className: CwInputProps.disabled === true
1145
1354
  ? CwInputProps.labelClassName + " " + "cw_label_text cw_label_text_disabled"
1146
1355
  : CwInputProps.labelClassName + " " + "cw_label_text", children: CwInputProps.labelName }), jsxRuntime.jsx("input", { id: CwInputProps.id, type: "text", value: CwInputProps.value, onChange: e => handleChange(e), className: CwInputProps.className + " " + "cw_input", placeholder: CwInputProps.placeholder === undefined ? "Write a text please" : CwInputProps.placeholder, style: CwInputProps.style, disabled: CwInputProps.disabled, required: CwInputProps.required }), CwInputProps.value && (
1147
1356
  // if the component is disabled do not show clear button
1148
1357
  jsxRuntime.jsx("button", { className: "cw_button_clear cwellt_flex cwellt_justify_center cwellt_align_items_center", onClick: handleClearClick }))] }));
1149
1358
  }
1150
1359
 
1151
- function CwButton(props) {
1152
- const { text, ...buttonProps } = props;
1153
- return (jsxRuntime.jsx("button", { type: "button", className: "cw-button", ...buttonProps, children: buttonProps.children ?? text }));
1360
+ function CwButton({ text, variant = 'solid', className = '', children, ...buttonProps }) {
1361
+ let buttonClass = "cw-button";
1362
+ if (variant === 'outline') {
1363
+ buttonClass += " cw-button-outline";
1364
+ }
1365
+ if (className) {
1366
+ buttonClass += ` ${className}`;
1367
+ }
1368
+ return (jsxRuntime.jsx("button", { type: "button", className: buttonClass, ...buttonProps, children: children ?? text }));
1154
1369
  }
1155
1370
 
1156
1371
  /**
@@ -1225,11 +1440,9 @@ function CwInputNumber(CwInputNumberProps) {
1225
1440
  const handleChange = (e) => {
1226
1441
  CwInputNumberProps.onChange(e.target.value);
1227
1442
  };
1228
- return (jsxRuntime.jsxs("div", { className: CwInputNumberProps.labelPosition == "inline"
1229
- ? "cw-label-input"
1230
- : CwInputNumberProps.labelPosition == "column"
1231
- ? "cwellt_flex cwellt_flex_column cwellt_align-items_baseline cw-label-input"
1232
- : "cw-label-input", children: [jsxRuntime.jsx("label", { className: CwInputNumberProps.disabled === true
1443
+ return (jsxRuntime.jsxs("div", { className: CwInputNumberProps.labelPosition == "column"
1444
+ ? "cw-flex-column"
1445
+ : "cw-flex-row", children: [jsxRuntime.jsx("label", { className: CwInputNumberProps.disabled === true
1233
1446
  ? CwInputNumberProps.labelClassName + " " + "cw_label_text cw_label_text_disabled"
1234
1447
  : CwInputNumberProps.labelClassName + " " + "cw_label_text", children: CwInputNumberProps.labelName }), jsxRuntime.jsx("input", { id: CwInputNumberProps.id, type: "number", value: CwInputNumberProps.value, onChange: e => handleChange(e), className: CwInputNumberProps.className + " " + " cw-input-number", placeholder: CwInputNumberProps.placeholder == undefined ? "Write a number please" : CwInputNumberProps.placeholder, style: CwInputNumberProps.style, disabled: CwInputNumberProps.disabled, required: CwInputNumberProps.required, step: CwInputNumberProps.step, min: CwInputNumberProps.min, max: CwInputNumberProps.max })] }));
1235
1448
  }
@@ -1698,7 +1911,7 @@ class Weekdays {
1698
1911
  static WEEKDAYS_TO_USA_SHORT_FORMAT = new Map([
1699
1912
  ["M", "Mon"],
1700
1913
  ["T", "Tue"],
1701
- ["W", "Wen"],
1914
+ ["W", "Wed"],
1702
1915
  ["R", "Thu"],
1703
1916
  ["F", "Fri"],
1704
1917
  ["S", "Sat"],
@@ -1832,8 +2045,8 @@ function CwCheckbox(CwCheckboxProps) {
1832
2045
  * <CwToggle checked/>
1833
2046
  */
1834
2047
  function CwToggle(props) {
1835
- const { alignProps, labelProps, buttonProps, iconProps, ...inputProps } = props;
1836
- return (jsxRuntime.jsx("div", { className: "cw-toggle", children: jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsx("input", { className: "cw-toggle", type: "checkbox", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
2048
+ const { labelProps, buttonProps, iconProps, ...inputProps } = props;
2049
+ return (jsxRuntime.jsxs("div", { className: "cw-toggle", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsx("input", { className: "cw-toggle", type: "checkbox", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }));
1837
2050
  }
1838
2051
 
1839
2052
  /**
@@ -1902,9 +2115,9 @@ function CwDropdown(optionsProps) {
1902
2115
  ? "cwellt_flex cwellt_flex_row cwellt_align_items_center cwDropDownComp" + " " + optionsProps.className
1903
2116
  : optionsProps.labelPosition === "column"
1904
2117
  ? "cwellt_flex cwellt_flex_column cwellt_align-items_baseline cwDropDownComp" + " " + optionsProps.className
1905
- : "cwellt_flex cwellt_flex_row cwellt_align_items_center cwDropDownComp" + " " + optionsProps.className, style: optionsProps.style, children: [jsxRuntime.jsx("label", { className: optionsProps.disabled === true
2118
+ : "cwellt_flex cwellt_flex_row cwellt_align_items_center cwDropDownComp" + " " + optionsProps.className, style: optionsProps.style, id: optionsProps.id, children: [jsxRuntime.jsx("label", { className: optionsProps.disabled === true
1906
2119
  ? "cw_label_text cw_label_text_disabled" + " " + optionsProps.labelClassName
1907
- : "cw_label_text" + " " + optionsProps.labelClassName, children: optionsProps.labelName }), jsxRuntime.jsxs("select", { value: selectedOption, onChange: handleOptionSelect, className: "cw_select", style: optionsProps.styleSelect, disabled: optionsProps.disabled, children: [jsxRuntime.jsx("option", { value: "", className: "cw_option", children: optionsProps.placeholder }), optionsProps.selectList.map(option => (jsxRuntime.jsx("option", { value: option.id, className: "cw_option", style: optionsProps.styleOption, children: option.description }, option.id)))] })] }));
2120
+ : "cw_label_text" + " " + optionsProps.labelClassName, children: optionsProps.labelName }), jsxRuntime.jsx("select", { value: selectedOption, onChange: handleOptionSelect, className: "cw_select", style: optionsProps.styleSelect, disabled: optionsProps.disabled || optionsProps.selectList.length === 0, children: optionsProps.selectList.length === 0 ? (jsxRuntime.jsx("option", { value: "", className: "cw_option", disabled: true, children: "No data" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("option", { value: "", className: "cw_option", children: optionsProps.placeholder }), optionsProps.selectList.map(option => (jsxRuntime.jsx("option", { value: option.id, className: "cw_option", style: optionsProps.styleOption, children: option.description }, option.id)))] })) })] }));
1908
2121
  }
1909
2122
 
1910
2123
  function CwDropdownContainer(dropDownContainerProps) {
@@ -2737,7 +2950,7 @@ function CwMultiselect(CwelltCustomFilterTabProps) {
2737
2950
  const luminance = 0.299 * redBgColor_custom_tag_selected_list +
2738
2951
  0.587 * greenBgColor_custom_tag_selected_list +
2739
2952
  0.114 * blueBgColor_custom_tag_selected_list;
2740
- return s.type !== undefined && s.type !== undefined ? (jsxRuntime.jsx("div", { id: "cwContent_tag", "data-id": s.type + "_" + s.id, className: "cwellt_flex cwellt_align_items_center", children: jsxRuntime.jsx(CwTag, { styleTag: {
2953
+ return s.type !== undefined ? (jsxRuntime.jsx("div", { id: "cwContent_tag", "data-id": s.type + "_" + s.id, className: "cwellt_flex cwellt_align_items_center", children: jsxRuntime.jsx(CwTag, { styleTag: {
2741
2954
  background: s.color
2742
2955
  }, styleTag_description: {
2743
2956
  background: s.color,
@@ -2794,8 +3007,20 @@ const CwMultiFilterTag = props => {
2794
3007
  var styles$5 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module_cw-multi-filter__zipBK","cw-multi-filter-search":"cw-multi-filter-module_cw-multi-filter-search__eyHr0"};
2795
3008
 
2796
3009
  /**
2797
- * A multiple filter selector, a MULTI-SELECT even.
3010
+ * A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
2798
3011
  * @remark
3012
+ * The CwMultiFilter component provides a user interface for selecting multiple filter options
3013
+ * organized by categories. Each filter option is represented as a clickable tag with customizable
3014
+ * colors. The component manages the selection state internally but reports changes via a callback.
3015
+ *
3016
+ * Filter tags should include the following properties:
3017
+ * - `Name`: Display name of the filter
3018
+ * - `Value`: Actual value used for filtering logic
3019
+ * - `Category`: Group the filter belongs to
3020
+ * - `ID`: Unique identifier for the filter
3021
+ * - `PrimaryColor`: Background color of the tag
3022
+ * - `OnPrimaryColor`: Text color of the tag
3023
+ *
2799
3024
  * ```
2800
3025
  * ╭───────────────────────────────────────────────────────────────╮
2801
3026
  * │ ╭──────────╮ ╭──────────╮ ╭──────────╮ │
@@ -2810,39 +3035,116 @@ var styles$5 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
2810
3035
  * ╰─────────────────────────────────────────────────────────────╯
2811
3036
  * ```
2812
3037
  * @example
2813
- * ```
2814
- * /// Use setSelectedTags to set the initial selected tags or to add/remove them after an action.
2815
- * const [selectedTags, setSelectedTags] = useState(new Set<CwMultiFilterTagProps>());
2816
- * const [selectedCategory, setSelectedCategory] = useState("");
3038
+ * ```tsx
3039
+ * import { CwMultiFilter, type CwMultiFilterTagProps, type ICwMultiFilterTag } from "cwellt-reactjs-lib";
3040
+ * import { useCallback, useState } from "react";
3041
+ * import { hexToRGB } from "../common/functions/color";
3042
+ *
3043
+ * function FilterExample() {
3044
+ * // State to track selected filter tags
3045
+ * const [selectedTags, setSelectedTags] = useState(new Set<CwMultiFilterTagProps>());
3046
+ *
3047
+ * // Sample data to filter
3048
+ * const [users, setUsers] = useState([
3049
+ * { id: 1, name: "John", role: "admin", department: "IT" },
3050
+ * { id: 2, name: "Sarah", role: "user", department: "HR" },
3051
+ * // More users...
3052
+ * ]);
3053
+ *
3054
+ * // Filtered users based on selected tags
3055
+ * const [filteredUsers, setFilteredUsers] = useState(users);
3056
+ *
3057
+ * // Define filter options
3058
+ * const filterOptions = new Set([
3059
+ * {
3060
+ * Name: "Admin",
3061
+ * Value: "admin",
3062
+ * Category: "Roles",
3063
+ * ID: "Roles_admin",
3064
+ * OnPrimaryColor: hexToRGB("#2050a8"),
3065
+ * PrimaryColor: hexToRGB("#cedcff")
3066
+ * },
3067
+ * {
3068
+ * Name: "User",
3069
+ * Value: "user",
3070
+ * Category: "Roles",
3071
+ * ID: "Roles_user",
3072
+ * OnPrimaryColor: hexToRGB("#2050a8"),
3073
+ * PrimaryColor: hexToRGB("#cedcff")
3074
+ * },
3075
+ * {
3076
+ * Name: "IT",
3077
+ * Value: "IT",
3078
+ * Category: "Departments",
3079
+ * ID: "Departments_IT",
3080
+ * OnPrimaryColor: hexToRGB("#a82037"),
3081
+ * PrimaryColor: hexToRGB("#ffceda")
3082
+ * },
3083
+ * {
3084
+ * Name: "HR",
3085
+ * Value: "HR",
3086
+ * Category: "Departments",
3087
+ * ID: "Departments_HR",
3088
+ * OnPrimaryColor: hexToRGB("#a82037"),
3089
+ * PrimaryColor: hexToRGB("#ffceda")
3090
+ * }
3091
+ * ]);
3092
+ *
3093
+ * // Handle filter changes
3094
+ * const onChangeFilters = useCallback((tags: Set<ICwMultiFilterTag>) => {
3095
+ * setSelectedTags(tags);
3096
+ * const tagsArray = Array.from(tags);
2817
3097
  *
2818
- * <CwMultiFilter
2819
- * id="multifilter"
2820
- * onChange={tags => { // Collection of currently active tags
2821
- * console.log("This will get called every time the selected filters change");
2822
- * }}
2823
- * selectedTags={selectedTags} // Selected filters, in case you want to modify them manually
2824
- * selectedCategory={selectedCategory}
2825
- * onChangeCategory={setSelectedCategory}
2826
- * allTags={
2827
- * new Set([
2828
- * {
2829
- * Name: "DEF", // The text displayed on the tag/filter/chip
2830
- * Value: "DEF", // Working value, used for whatever you need, it might be the CrewmemberID or the same as Name
2831
- * Category: "Crewmembers", // Category it belongs to (you don't need to define categories elsewhere)
2832
- * ID: "Crewmembers_DEF", // make sure each ID is unique
2833
- * OnPrimaryColor: hexToRGB("#2050a8"), // color for text and outline of the tag/filter/chip
2834
- * PrimaryColor: hexToRGB("#cedcff"), // background color for the tag/filter/chip
2835
- * },
2836
- * {
2837
- * Name: "ABC",
2838
- * Value: "ABC",
2839
- * Category: "Crewmembers",
2840
- * ID: "Crewmembers_ABC",
2841
- * OnPrimaryColor: hexToRGB("#2050a8"), // you can also do { r: 255, g: 128, b: 64 }
2842
- * PrimaryColor: hexToRGB("#cedcff")
2843
- * }
2844
- * ])
2845
- * }
3098
+ * // Get values for each category
3099
+ * const roleValues = tagsArray
3100
+ * .filter(tag => tag.Category === "Roles")
3101
+ * .map(tag => tag.Value);
3102
+ *
3103
+ * const departmentValues = tagsArray
3104
+ * .filter(tag => tag.Category === "Departments")
3105
+ * .map(tag => tag.Value);
3106
+ *
3107
+ * // Apply filters
3108
+ * if (tagsArray.length === 0) {
3109
+ * // No filters applied
3110
+ * setFilteredUsers(users);
3111
+ * } else {
3112
+ * let filtered = users;
3113
+ *
3114
+ * if (roleValues.length > 0) {
3115
+ * filtered = filtered.filter(user => roleValues.includes(user.role));
3116
+ * }
3117
+ *
3118
+ * if (departmentValues.length > 0) {
3119
+ * filtered = filtered.filter(user => departmentValues.includes(user.department));
3120
+ * }
3121
+ *
3122
+ * setFilteredUsers(filtered);
3123
+ * }
3124
+ * }, [users]);
3125
+ *
3126
+ * return (
3127
+ * <div>
3128
+ * <h2>Filter Users</h2>
3129
+ * <div style={{ width: "50%" }}>
3130
+ * <CwMultiFilter
3131
+ * id="user-filter"
3132
+ * allTags={filterOptions}
3133
+ * onChangeSelectedTags={onChangeFilters}
3134
+ * selectedTags={selectedTags}
3135
+ * />
3136
+ * </div>
3137
+ * <div style={{ marginTop: "20px" }}>
3138
+ * <h3>Filtered Results ({filteredUsers.length})</h3>
3139
+ * <ul>
3140
+ * {filteredUsers.map(user => (
3141
+ * <li key={user.id}>{user.name} - {user.role} ({user.department})</li>
3142
+ * ))}
3143
+ * </ul>
3144
+ * </div>
3145
+ * </div>
3146
+ * );
3147
+ * }
2846
3148
  * ```
2847
3149
  * @param {CwMultiFilterProps} props
2848
3150
  * @returns Set the `onChange` callback to a function to check for changes in the selected filters
@@ -2950,7 +3252,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
2950
3252
  };
2951
3253
  return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: styles$5["cw-multi-filter"], style: style, onSubmit: (e) => {
2952
3254
  e.preventDefault();
2953
- }, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, className: styles$5["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.target.value), autoComplete: "off", onKeyDown: e => {
3255
+ }, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, className: styles$5["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-primary)", outlineOffset: "-2px" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.target.value), autoComplete: "off", placeholder: "Write to filter", onKeyDown: e => {
2954
3256
  switch (e.key) {
2955
3257
  case "Enter":
2956
3258
  case "Tab":
@@ -3001,20 +3303,49 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
3001
3303
  function CwSearchInput(optionsProps) {
3002
3304
  const [searchText, setSearchText] = React.useState("");
3003
3305
  const [filteredOptions, setFilteredOptions] = React.useState([]);
3306
+ const [_selectedOption, setSelectedOption] = React.useState(null);
3307
+ // Make default value selection when loading the component
3308
+ React.useEffect(() => {
3309
+ if (optionsProps.defaultValue && optionsProps.selectList && optionsProps.selectList.length > 0) {
3310
+ const defaultOption = optionsProps.selectList.find(option => option.id === optionsProps.defaultValue?.toString());
3311
+ if (defaultOption) {
3312
+ setSearchText(defaultOption.description);
3313
+ setSelectedOption(defaultOption);
3314
+ // Notify the parent component if there is a handleChange
3315
+ if (optionsProps.handleChange) {
3316
+ optionsProps.handleChange(defaultOption.id);
3317
+ }
3318
+ }
3319
+ }
3320
+ }, [optionsProps.defaultValue, optionsProps.selectList]);
3004
3321
  const handleInputChange = (event) => {
3005
3322
  const text = event.target.value;
3006
3323
  setSearchText(text);
3007
3324
  if (text === "") {
3008
3325
  setFilteredOptions([]);
3326
+ setSelectedOption(null);
3327
+ // Notify that there is no selection
3328
+ if (optionsProps.handleChange) {
3329
+ optionsProps.handleChange("");
3330
+ }
3009
3331
  }
3010
3332
  else {
3011
- // Filter options based on search text
3012
- const filtered = optionsProps.selectList.filter((option) => option.description.toLowerCase().includes(text.toLowerCase()));
3333
+ // Filter options based on search text in any text property
3334
+ const filtered = optionsProps.selectList.filter((option) => {
3335
+ // Search all properties of the object
3336
+ return Object.keys(option).some(key => {
3337
+ const value = option[key];
3338
+ // Verify that the value is a string or number and contains the search text
3339
+ return (typeof value === 'string' || typeof value === 'number') &&
3340
+ String(value).toLowerCase().includes(text.toLowerCase());
3341
+ });
3342
+ });
3013
3343
  setFilteredOptions(filtered);
3014
3344
  }
3015
3345
  };
3016
3346
  const handleOptionSelect = (option) => {
3017
3347
  setSearchText(option.description);
3348
+ setSelectedOption(option);
3018
3349
  if (optionsProps.handleChange) {
3019
3350
  optionsProps.handleChange(option.id);
3020
3351
  }
@@ -3024,14 +3355,15 @@ function CwSearchInput(optionsProps) {
3024
3355
  const handleClearClick = () => {
3025
3356
  setSearchText("");
3026
3357
  setFilteredOptions([]);
3358
+ setSelectedOption(null);
3027
3359
  };
3028
- return (jsxRuntime.jsxs("div", { className: "cwellt_flex cwellt_flex_row cwellt_flex_wrap cwellt_p_rel cwSearchInputComp", style: optionsProps.style, id: optionsProps.id, children: [jsxRuntime.jsxs("div", { className: optionsProps.labelPosition === "inline"
3029
- ? "cwellt_flex cwellt_flex_row "
3360
+ return (jsxRuntime.jsxs("div", { className: "cwSearchInputComp", style: optionsProps.style, id: optionsProps.id, children: [jsxRuntime.jsxs("div", { className: optionsProps.labelPosition === "inline"
3361
+ ? "cw-flex-row "
3030
3362
  : optionsProps.labelPosition === "column"
3031
- ? "cwellt_flex cwellt_flex_column"
3032
- : "cwellt_flex cwellt_flex_row ", children: [jsxRuntime.jsx("label", { className: optionsProps.disabled === true
3363
+ ? "cw-flex-column"
3364
+ : "cw-flex-row ", children: [optionsProps.labelName && (jsxRuntime.jsx("label", { className: optionsProps.disabled === true
3033
3365
  ? "cw_label_text cw_label_text_disabled" + " " + optionsProps.labelClassName
3034
- : "cw_label_text" + " " + optionsProps.labelClassName, children: optionsProps.labelName }), jsxRuntime.jsx("input", { type: "text", value: searchText, onChange: handleInputChange, placeholder: "Search...", className: "cw_input_search", disabled: optionsProps.disabled }), searchText && (jsxRuntime.jsx("button", { className: "cw_button_search_clear cwelt_flex cwellt_justify_center cwellt_align_items_center cwellt_p_abs", onClick: handleClearClick }))] }), filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "cw_searchInput_dropDown cwellt_p_abs", children: jsxRuntime.jsx("ul", { className: "cw_searchInput_listContainer", children: filteredOptions.map((option) => (jsxRuntime.jsx("li", { onClick: () => handleOptionSelect(option), className: "cw_searchInput_list cwellt_flex cwellt_align_items_center", children: option.description }, option.id))) }) }))] }));
3366
+ : "cw_label_text" + " " + optionsProps.labelClassName, children: optionsProps.labelName })), jsxRuntime.jsx("input", { type: "text", value: searchText, onChange: handleInputChange, placeholder: "Search...", className: "cw_input_search", disabled: optionsProps.disabled }), searchText && (jsxRuntime.jsx("button", { className: "cw-button-icon cwi-close cw-input-search-clear", onClick: handleClearClick }))] }), filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "cw-input-search-dropdown", children: jsxRuntime.jsx("ul", { children: filteredOptions.map((option) => (jsxRuntime.jsx("li", { onClick: () => handleOptionSelect(option), children: option.description }, option.id))) }) }))] }));
3035
3367
  }
3036
3368
 
3037
3369
  var styles$4 = {"context-menu":"cw-context-menu-module_context-menu__dbxnO","context-menu-item":"cw-context-menu-module_context-menu-item__B2W-Q"};
@@ -3047,7 +3379,7 @@ var styles$4 = {"context-menu":"cw-context-menu-module_context-menu__dbxnO","con
3047
3379
  * <div>Right-click me!</div>
3048
3380
  * </ContextMenu>
3049
3381
  */
3050
- const CwContextMenu = ({ children, options, onSelect }) => {
3382
+ const CwContextMenu = ({ children, options, offset, onSelect }) => {
3051
3383
  const [isOpen, setIsOpen] = React.useState(false);
3052
3384
  const [position, setPosition] = React.useState({ x: 0, y: 0 });
3053
3385
  const menuRef = React.useRef(null);
@@ -3072,8 +3404,8 @@ const CwContextMenu = ({ children, options, onSelect }) => {
3072
3404
  };
3073
3405
  }, []);
3074
3406
  return (jsxRuntime.jsxs("div", { onContextMenu: handleContextMenu, children: [children, isOpen && (jsxRuntime.jsx("div", { ref: menuRef, className: styles$4["context-menu"], style: {
3075
- top: position.y,
3076
- left: position.x
3407
+ top: position.y + (offset?.y || 0),
3408
+ left: position.x + (offset?.x || 0),
3077
3409
  }, children: options.map(option => (jsxRuntime.jsx("div", { onClick: () => handleOptionClick(option), className: styles$4["context-menu-item"], children: option }, option))) }))] }));
3078
3410
  };
3079
3411
 
@@ -3153,47 +3485,11 @@ function CwFloatingButton() {
3153
3485
  };
3154
3486
  return jsxRuntime.jsx("button", { className: "cw_btnFloatingButton", onClick: cwShowElement, id: "cw_btnFloatingButton" });
3155
3487
  }
3156
- // Button for expand and collapase
3157
- function CwButtonExpandAndCollapse() {
3158
- const cwExpandCollapseButton = () => {
3159
- // cwellt_btnExpandCollapse
3160
- const cw_btnExpandCollapse = document.getElementById("cw_btnExpandCollapse");
3161
- cw_btnExpandCollapse?.classList.toggle("cw_btnExpandCollapseActive");
3162
- // text of tooltip
3163
- // Switches
3164
- const cwSwitches = document.getElementsByClassName("CwSwitches")[0];
3165
- cwSwitches.classList.toggle("cwSwitchesActive");
3166
- // ContentButton
3167
- };
3168
- return jsxRuntime.jsx("button", { className: "cw_btnExpandCollapse", onClick: cwExpandCollapseButton, id: "cw_btnExpandCollapse" });
3169
- }
3170
3488
  // Primary button => CwButtonDef
3171
3489
  // CwButtonDef
3172
3490
  function CwButtonDef({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3173
3491
  return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_primary", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3174
3492
  }
3175
- // CwButtonDefOutline
3176
- function CwButtonDefOutline({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3177
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_primaryOutline", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3178
- }
3179
- // Primary button => CwButtonSecondary
3180
- // CweButtonSec
3181
- function CwButtonSec({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3182
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_secondary", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3183
- }
3184
- // CwButtonSecOutline
3185
- function CwButtonSecOutline({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3186
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_secondaryOutline", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3187
- }
3188
- // Primary button => cwelltButton_danger
3189
- // CwButton_danger
3190
- function CwButtonDanger({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3191
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_danger", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3192
- }
3193
- // CwButtonDangerOutline
3194
- function CwButtonDangerOutline({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
3195
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_dangerOutline", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
3196
- }
3197
3493
  // Cw add button
3198
3494
  function CwBtnAdd({ cw_btnOnclick, cw_btn_disabled }) {
3199
3495
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_add", disabled: cw_btn_disabled });
@@ -3262,10 +3558,6 @@ function CwBtnFiles({ cw_btnOnclick, cw_btn_disabled }) {
3262
3558
  function CwBtnAirport({ cw_btnOnclick, cw_btn_disabled }) {
3263
3559
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_airport", disabled: cw_btn_disabled });
3264
3560
  }
3265
- // userFolder
3266
- function CwBtnUserFolder({ cw_btnOnclick, cw_btn_disabled }) {
3267
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-user", disabled: cw_btn_disabled });
3268
- }
3269
3561
  // DownLoadAllInfo
3270
3562
  function CwBtnDownLoadAllInfo({ cw_btnOnclick, cw_btn_disabled }) {
3271
3563
  return (jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-download", disabled: cw_btn_disabled }));
@@ -3282,10 +3574,6 @@ function CwBtnAddFolder({ cw_btnOnclick, cw_btn_disabled }) {
3282
3574
  function CwBtnEditFolder({ cw_btnOnclick, cw_btn_disabled }) {
3283
3575
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-edit", disabled: cw_btn_disabled });
3284
3576
  }
3285
- // PropertyFolder
3286
- function CwBtnSelectedFolder({ cw_btnOnclick, cw_btn_disabled }) {
3287
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-selected", disabled: cw_btn_disabled });
3288
- }
3289
3577
  // UploadFiles
3290
3578
  function CwBtnUploadFiles({ cw_btnOnclick, cw_btn_disabled }) {
3291
3579
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_uploadFiles", disabled: cw_btn_disabled });
@@ -3298,14 +3586,6 @@ function CwBtnGoBackFolder({ cw_btnOnclick, cw_btn_disabled }) {
3298
3586
  function CwBtnBookMark({ cw_btnOnclick, cw_btn_disabled }) {
3299
3587
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-star", disabled: cw_btn_disabled });
3300
3588
  }
3301
- // Archive
3302
- function CwBtnArchive({ cw_btnOnclick, cw_btn_disabled }) {
3303
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-archive", disabled: cw_btn_disabled });
3304
- }
3305
- // Archive
3306
- function CwBtnArchiveRestore({ cw_btnOnclick, cw_btn_disabled }) {
3307
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-archive-restore", disabled: cw_btn_disabled });
3308
- }
3309
3589
  // Publish
3310
3590
  function CwBtnPublish({ cw_btnOnclick, cw_btn_disabled }) {
3311
3591
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnPublish", disabled: cw_btn_disabled });
@@ -3314,10 +3594,6 @@ function CwBtnPublish({ cw_btnOnclick, cw_btn_disabled }) {
3314
3594
  function CwBtnApprove({ cw_btnOnclick, cw_btn_disabled }) {
3315
3595
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnApprove", disabled: cw_btn_disabled });
3316
3596
  }
3317
- // BookMarkLinkPag
3318
- function CwBtnBookMarkLinkPage({ cw_btnOnclick, cw_btn_disabled }) {
3319
- return (jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-favorite-files", disabled: cw_btn_disabled }));
3320
- }
3321
3597
  // Bulk duty
3322
3598
  function CwBtnBulkDuty({ cw_btnOnclick, cw_btn_disabled }) {
3323
3599
  return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnBulkDuty", disabled: cw_btn_disabled });
@@ -5373,8 +5649,9 @@ const getTimeHeaders = (startDate, endDate) => {
5373
5649
  class CwScheduler extends React.Component {
5374
5650
  contentArea;
5375
5651
  calculateMaxPx = () => {
5376
- const mainRect = document.body.getBoundingClientRect();
5377
- return Math.floor(mainRect.width - 200);
5652
+ const mainElement = document.body;
5653
+ const mainRect = mainElement.getBoundingClientRect();
5654
+ return Math.floor(mainRect.width - 190);
5378
5655
  };
5379
5656
  constructor(props) {
5380
5657
  super(props);
@@ -5546,9 +5823,7 @@ class CwScheduler extends React.Component {
5546
5823
  const isPinnedTable = this.props.id.toLowerCase().includes("pinned");
5547
5824
  const schedulerHeight = heightScheduler(this.state.resources, this.props.height, this.props.id === "crewAssignmentsScheduler");
5548
5825
  return (jsxRuntime.jsx("div", { id: this.props.id, style: {
5549
- overflowY: "scroll",
5550
5826
  maxHeight: isPinnedTable ? "auto" : schedulerHeight,
5551
- minHeight: (this.state.resources.length === 1 || this.state.resources.length === 2) ? schedulerHeight + 10 : 0
5552
5827
  }, className: this.state.resources.length > 0 ? "cwellt_tb_con" : "cwellt_tb_con cw_tb_con_emptyValues", children: jsxRuntime.jsxs("table", { id: "cwelltTableScheduler", children: [this.props.id !== "crewAssignmentsScheduler" && (jsxRuntime.jsx(SchedulerHeader$1, { timelineProps: {
5553
5828
  maxPx: this.state.maxPx,
5554
5829
  hoursList: this.state.timeHeaders,
@@ -5557,8 +5832,8 @@ class CwScheduler extends React.Component {
5557
5832
  endDate: this.props.endDate,
5558
5833
  headerName: this.props.resourceName,
5559
5834
  }, descriptionColumn: this.props.descriptionColumn })), jsxRuntime.jsx("tbody", { style: {
5560
- overflow: "visible",
5561
- width: this.state.maxPx + 150
5835
+ width: this.state.maxPx + 150,
5836
+ maxHeight: isPinnedTable ? "auto" : schedulerHeight,
5562
5837
  }, className: isPinnedTable ? "fc-body cw-fc-body-pinned" : "fc-body", children: jsxRuntime.jsxs("tr", { className: "fc_body_row", children: [jsxRuntime.jsx(ResourcesTitleList, { resources: this.state.resources, canBePinned: this.props.canBePinned ?? false, includesPinned: this.props.id.toLowerCase().includes("pinned"), onCrewPinning: this.handleCrewPinning, onClickResourceContextMenu: (_e, resource) => {
5563
5838
  if (this.props.scheduler_handleOnClickResourceContextMenu) {
5564
5839
  this.props.scheduler_handleOnClickResourceContextMenu(_e, resource);
@@ -5823,13 +6098,40 @@ function getHSLColor(color, alpha = 1) {
5823
6098
  return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha})`;
5824
6099
  }
5825
6100
  function getContrastColor(color) {
6101
+ if (color === null) {
6102
+ return '#000000';
6103
+ }
5826
6104
  const hsl = colorToHSL(color);
5827
- const contrastL = hsl.l > 50 ? 20 : 90;
5828
- return `hsl(${hsl.h}, ${hsl.s}%, ${contrastL}%)`;
6105
+ // Saturated greenyellow and cyan tones need lower luminance threshold (40-35)
6106
+ // Saturated mediumblue and blueviolet tones need higher luminance threshold (55-60)
6107
+ // Saturated orangered tones need lower luminance threshold (45)
6108
+ const isYellowGreen = (hsl.h >= 45 && hsl.h <= 180);
6109
+ const isBlueViolet = (hsl.h >= 210 && hsl.h <= 300);
6110
+ const isRedOrange = (hsl.h >= 0 && hsl.h <= 30) || (hsl.h >= 330 && hsl.h <= 360);
6111
+ let threshold = 50;
6112
+ if (isYellowGreen) {
6113
+ threshold = 40;
6114
+ if (hsl.s >= 70) {
6115
+ threshold = 35;
6116
+ }
6117
+ }
6118
+ else if (isBlueViolet) {
6119
+ threshold = 55;
6120
+ if (hsl.s >= 70) {
6121
+ threshold = 60;
6122
+ }
6123
+ }
6124
+ else if (isRedOrange && hsl.s >= 80) {
6125
+ threshold = 45;
6126
+ }
6127
+ const contrastL = hsl.l >= threshold ? 20 : 90;
6128
+ const contrastS = Math.min(hsl.s, 90);
6129
+ return `hsl(${hsl.h}, ${contrastS}%, ${contrastL}%)`;
5829
6130
  }
5830
6131
 
6132
+ var styles$2 = {"hide-scrollbar":"new-scheduler-module_hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module_scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module_scheduler-event-container__-h1xm","time-marker":"new-scheduler-module_time-marker__2BejU","scheduler-event-text":"new-scheduler-module_scheduler-event-text__zjvd7"};
6133
+
5831
6134
  const BackgroundEvent = ({ value, heightRem }) => {
5832
- const isVerticalText = value.isVerticalText ?? false;
5833
6135
  const backColor = getHSLColor(value.color, value.alpha ?? 0.5);
5834
6136
  const textColor = getContrastColor(value.color);
5835
6137
  return value.isVisible ? (jsxRuntime.jsx("div", { style: {
@@ -5837,6 +6139,7 @@ const BackgroundEvent = ({ value, heightRem }) => {
5837
6139
  width: `${value.width}%`,
5838
6140
  position: "absolute",
5839
6141
  height: `${heightRem}rem`,
6142
+ pointerEvents: "auto",
5840
6143
  }, children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "bottom", dissapearsWhenHover: true, showDelay: 200, children: jsxRuntime.jsx("div", { style: {
5841
6144
  overflow: "hidden",
5842
6145
  backgroundColor: backColor,
@@ -5848,28 +6151,21 @@ const BackgroundEvent = ({ value, heightRem }) => {
5848
6151
  contentVisibility: "auto",
5849
6152
  height: `${heightRem}rem`,
5850
6153
  }, children: jsxRuntime.jsxs("div", { style: {
5851
- flex: 1,
5852
- display: "flex",
5853
- flexDirection: "row",
5854
- alignItems: "center",
5855
- whiteSpace: "nowrap",
5856
- overflow: "hidden",
5857
6154
  width: value.width + "%",
5858
- fontSize: "var(--cw-font-size-smallest)"
5859
- }, children: [value.icons ? jsxRuntime.jsx("div", { style: {
6155
+ fontSize: "var(--cw-font-size-smallest)",
6156
+ padding: "0.25rem",
6157
+ color: textColor,
6158
+ alignItems: "flex-end"
6159
+ }, className: styles$2["scheduler-event-container"], children: [value.icons ? jsxRuntime.jsx("div", { style: {
5860
6160
  display: "flex",
5861
6161
  flexDirection: "row",
5862
6162
  alignItems: "center",
5863
6163
  whiteSpace: "nowrap",
5864
6164
  color: textColor,
5865
- }, children: value.icons }) : null, jsxRuntime.jsx("span", { style: {
5866
- color: textColor,
5867
- writingMode: isVerticalText ? "vertical-lr" : "initial",
5868
- textOrientation: isVerticalText ? "upright" : "initial"
5869
- }, children: value.name })] }) }) }) }) })) : null;
6165
+ }, children: value.icons }) : null, jsxRuntime.jsx("span", { className: styles$2["scheduler-event-text"], children: value.name })] }) }) }) }) })) : null;
5870
6166
  };
5871
6167
 
5872
- var styles$2 = {"scheduler-row-header":"scheduler-row-module_scheduler-row-header__S-iv4"};
6168
+ var styles$1 = {"scheduler-row-header":"scheduler-row-module_scheduler-row-header__S-iv4"};
5873
6169
 
5874
6170
  const DefaultRowHeader = ({ value, width, onEvent }) => {
5875
6171
  return (jsxRuntime.jsxs("div", { style: {
@@ -5877,7 +6173,7 @@ const DefaultRowHeader = ({ value, width, onEvent }) => {
5877
6173
  // background: color,
5878
6174
  }, onClick: (_) => {
5879
6175
  onEvent(new OnClickRowHeader(value.rowId));
5880
- }, className: styles$2["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), value.title3 && jsxRuntime.jsxs("span", { className: styles$2["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [jsxRuntime.jsx("strong", { children: value.subtitle }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
6176
+ }, className: styles$1["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles$1["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
5881
6177
  };
5882
6178
 
5883
6179
  function useSingleAndDoubleClicks(onClick, onDoubleClick) {
@@ -5907,8 +6203,6 @@ function useSingleAndDoubleClicks(onClick, onDoubleClick) {
5907
6203
  return { handleClick, handleDoubleClick };
5908
6204
  }
5909
6205
 
5910
- var styles$1 = {"hide-scrollbar":"new-scheduler-module_hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module_scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module_scheduler-event-container__-h1xm","time-marker":"new-scheduler-module_time-marker__2BejU"};
5911
-
5912
6206
  const EventSideDrag = ({ left = false, heightRem, onStartEvent }) => {
5913
6207
  return (jsxRuntime.jsx("span", { draggable: true, onDragStart: (e) => {
5914
6208
  e.stopPropagation();
@@ -5986,12 +6280,12 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
5986
6280
  e.stopPropagation();
5987
6281
  e.preventDefault();
5988
6282
  onEvent(new OnRightClickEvent(value.id));
5989
- }, children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "bottom", dissapearsWhenHover: true, showDelay: 200, children: jsxRuntime.jsxs("div", { style: {
6283
+ }, children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "bottom", hide: isOnDrag, dissapearsWhenHover: true, showDelay: 200, children: jsxRuntime.jsxs("div", { style: {
5990
6284
  border: value.selected ? "2px solid black" : "none",
5991
6285
  backgroundColor: backColor,
5992
6286
  height: `calc(${heightRem}rem - 4px)`,
5993
6287
  opacity: eventTransparent ? 0.5 : 1,
5994
- }, className: styles$1["scheduler-event"], children: [jsxRuntime.jsxs("div", { style: {
6288
+ }, className: styles$2["scheduler-event"], children: [jsxRuntime.jsxs("div", { style: {
5995
6289
  display: "flex",
5996
6290
  flexDirection: "row",
5997
6291
  alignItems: "stretch",
@@ -6000,7 +6294,7 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
6000
6294
  height: `calc(${heightRem}rem - 10px)`,
6001
6295
  }, children: [value.isResizable && (jsxRuntime.jsx(EventSideDrag, { left: true, heightRem: heightRem * 0.7, onStartEvent: () => {
6002
6296
  onEvent(new OnLeftDragStart(value.id));
6003
- } })), jsxRuntime.jsxs("div", { className: styles$1["scheduler-event-container"], children: [jsxRuntime.jsx("div", { style: {
6297
+ } })), jsxRuntime.jsxs("div", { className: styles$2["scheduler-event-container"], children: [jsxRuntime.jsx("div", { style: {
6004
6298
  display: "flex",
6005
6299
  flexDirection: "row",
6006
6300
  alignItems: "center",
@@ -6009,11 +6303,24 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
6009
6303
  }, children: value.icons }), jsxRuntime.jsx("span", { style: {
6010
6304
  padding: "0.1rem",
6011
6305
  color: textColor,
6012
- }, children: value.name })] }), value.isResizable && (jsxRuntime.jsx(EventSideDrag, { heightRem: heightRem * 0.7, onStartEvent: () => {
6306
+ display: "flex",
6307
+ flex: 1,
6308
+ alignItems: "center",
6309
+ width: "100%",
6310
+ }, children: value.rectangleColors && value.rectangleColors.length > 0 ? (jsxRuntime.jsx("div", { style: {
6311
+ display: "flex",
6312
+ width: "100%",
6313
+ }, children: value.rectangleColors.map((item, i) => (jsxRuntime.jsx("div", { className: "cwellt_rectangle_indicator", style: {
6314
+ backgroundColor: item,
6315
+ flex: 1,
6316
+ height: "8px",
6317
+ margin: 0,
6318
+ padding: 0,
6319
+ } }, value.id + "_" + i))) })) : (value.name) })] }), value.isResizable && (jsxRuntime.jsx(EventSideDrag, { heightRem: heightRem * 0.7, onStartEvent: () => {
6013
6320
  onEvent(new OnRightDragStart(value.id));
6014
- } }))] }), value.primaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$1["time-marker"], style: {
6321
+ } }))] }), value.primaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$2["time-marker"], style: {
6015
6322
  backgroundColor: value.primaryTimeMarkerColor,
6016
- } })), value.secondaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$1["time-marker"], style: {
6323
+ } })), value.secondaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$2["time-marker"], style: {
6017
6324
  backgroundColor: value.secondaryTimeMarkerColor,
6018
6325
  } }))] }) }) }, value.id) }, value.id));
6019
6326
  };
@@ -6392,6 +6699,7 @@ const getNow = (isUtc) => {
6392
6699
  }
6393
6700
  return now;
6394
6701
  };
6702
+ const rowsHeight = 1.75; // rem
6395
6703
  const Scheduler = (props) => {
6396
6704
  const { header: headerContent, id, events: eventsState, backgroundEvents, contextMenuItems, EventComp, RowTitleComp, orderCategories = ["title"], useOrderCategory, onEvent, groupRowColors, rowHeaderWidth = 180, } = props;
6397
6705
  const BackgroundEventComp = props.BackgroundEventComp ?? BackgroundEvent;
@@ -6425,7 +6733,6 @@ const Scheduler = (props) => {
6425
6733
  };
6426
6734
  const evenColor = "var(--cw-color-surface-container-low)";
6427
6735
  const oddColor = "var(--cw-color-surface-container)";
6428
- const rowsHeight = 1.75; // rem
6429
6736
  const schedulerContentHeight = rowsHeight * visibleRows;
6430
6737
  const weekendsLines = getWeekendLinesByDatesVisible(selectedDate, visibleDays);
6431
6738
  const divisionLines = getLinesByDivisions(header.divisions);
@@ -6462,7 +6769,7 @@ const Scheduler = (props) => {
6462
6769
  const rowsNumber = innerRows.length > 0 ? innerRows.length : 1;
6463
6770
  const pixelsInRem = 16;
6464
6771
  return rowsNumber * rowsHeight * pixelsInRem;
6465
- }, [rows, events, selectedDate, visibleDays, rowsHeight]);
6772
+ }, [rows, events]);
6466
6773
  // Render
6467
6774
  return (jsxRuntime.jsxs("div", { id: id, style: {
6468
6775
  position: "relative",
@@ -6473,7 +6780,7 @@ const Scheduler = (props) => {
6473
6780
  position: "sticky",
6474
6781
  top: 0,
6475
6782
  zIndex: 1,
6476
- }, children: jsxRuntime.jsx(SchedulerHeader, { ...header }) })), jsxRuntime.jsx(reactWindow.VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$1["hide-scrollbar"], children: Row })] }));
6783
+ }, children: jsxRuntime.jsx(SchedulerHeader, { ...header }) })), jsxRuntime.jsx(reactWindow.VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$2["hide-scrollbar"], children: Row })] }));
6477
6784
  };
6478
6785
  const height = (events, rows, rowsNumber) => {
6479
6786
  const selectedRows = rows.slice(0, rowsNumber);
@@ -6852,7 +7159,7 @@ const PinRowHeader = ({ value, width, onEvent }) => {
6852
7159
  flexDirection: "column",
6853
7160
  justifyContent: "center",
6854
7161
  alignItems: "flex-start",
6855
- }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), value.title3 && jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: [" (", value.title3, ")"] })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [jsxRuntime.jsx("strong", { children: value.subtitle }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }) }, value.rowId) }, value.rowId), isLoading ? jsxRuntime.jsx(CwIcon, { iconId: "spinner fa-spin" }) : undefined] }));
7162
+ }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }) }, value.rowId) }, value.rowId), isLoading ? jsxRuntime.jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }));
6856
7163
  };
6857
7164
 
6858
7165
  const SuperScheduler = ({ id, state, header, rows, events, pinnedOrderCategory, unPinnedOrderCategory, backgroundEvents, contextMenuItems, onEvent }) => {
@@ -7028,10 +7335,7 @@ exports.CwBtnAddFolder = CwBtnAddFolder;
7028
7335
  exports.CwBtnAirport = CwBtnAirport;
7029
7336
  exports.CwBtnAlert = CwBtnAlert;
7030
7337
  exports.CwBtnApprove = CwBtnApprove;
7031
- exports.CwBtnArchive = CwBtnArchive;
7032
- exports.CwBtnArchiveRestore = CwBtnArchiveRestore;
7033
7338
  exports.CwBtnBookMark = CwBtnBookMark;
7034
- exports.CwBtnBookMarkLinkPage = CwBtnBookMarkLinkPage;
7035
7339
  exports.CwBtnBulkDuty = CwBtnBulkDuty;
7036
7340
  exports.CwBtnCancel = CwBtnCancel;
7037
7341
  exports.CwBtnCrewPlanning = CwBtnCrewPlanning;
@@ -7062,22 +7366,14 @@ exports.CwBtnReleasePeriod = CwBtnReleasePeriod;
7062
7366
  exports.CwBtnSave = CwBtnSave;
7063
7367
  exports.CwBtnSearch = CwBtnSearch;
7064
7368
  exports.CwBtnSelect = CwBtnSelect;
7065
- exports.CwBtnSelectedFolder = CwBtnSelectedFolder;
7066
7369
  exports.CwBtnShare = CwBtnShare;
7067
7370
  exports.CwBtnStatistic = CwBtnStatistic;
7068
7371
  exports.CwBtnUploadFiles = CwBtnUploadFiles;
7069
- exports.CwBtnUserFolder = CwBtnUserFolder;
7070
7372
  exports.CwBtnVacations = CwBtnVacations;
7071
7373
  exports.CwBtnView = CwBtnView;
7072
7374
  exports.CwBtnWarning = CwBtnWarning;
7073
7375
  exports.CwButton = CwButton;
7074
- exports.CwButtonDanger = CwButtonDanger;
7075
- exports.CwButtonDangerOutline = CwButtonDangerOutline;
7076
7376
  exports.CwButtonDef = CwButtonDef;
7077
- exports.CwButtonDefOutline = CwButtonDefOutline;
7078
- exports.CwButtonExpandAndCollapse = CwButtonExpandAndCollapse;
7079
- exports.CwButtonSec = CwButtonSec;
7080
- exports.CwButtonSecOutline = CwButtonSecOutline;
7081
7377
  exports.CwCheckbox = CwCheckbox;
7082
7378
  exports.CwContextMenu = CwContextMenu;
7083
7379
  exports.CwContextualMenu = CwContextualMenu;
@@ -7108,6 +7404,7 @@ exports.CwInputImage = CwInputImage;
7108
7404
  exports.CwInputNumber = CwInputNumber;
7109
7405
  exports.CwInputPhone = CwInputPhone;
7110
7406
  exports.CwInputText = CwInputText;
7407
+ exports.CwKeyValueList = CwKeyValueList;
7111
7408
  exports.CwLabel = CwLabel;
7112
7409
  exports.CwLoading = CwLoading;
7113
7410
  exports.CwLoadingSmall = CwLoadingSmall;