sag_components 2.0.0-beta193 → 2.0.0-beta195

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3782,7 +3782,7 @@ const TextFieldInput = styled__default["default"].input`
3782
3782
  }
3783
3783
  `;
3784
3784
 
3785
- const SearchInput = props => {
3785
+ const SearchInput$1 = props => {
3786
3786
  const {
3787
3787
  value,
3788
3788
  placeholder = 'Search',
@@ -3927,7 +3927,7 @@ const ActionsWrapper = styled__default["default"].div`
3927
3927
  gap: 10px;
3928
3928
  width: 100%;
3929
3929
  `;
3930
- const SearchInputWrap = styled__default["default"](SearchInput)`
3930
+ const SearchInputWrap = styled__default["default"](SearchInput$1)`
3931
3931
  margin-left: auto;
3932
3932
  `;
3933
3933
 
@@ -12262,16 +12262,13 @@ const Td$1 = styled__default["default"].td`
12262
12262
  `;
12263
12263
  const Tr = styled__default["default"].tr`
12264
12264
  border-bottom: 1px solid #f3f4f6;
12265
- ${_ref => {
12266
- let {
12267
- enableHover,
12268
- selectHoverColor
12269
- } = _ref;
12270
- return enableHover && `&:hover {
12265
+ ${({
12266
+ enableHover,
12267
+ selectHoverColor
12268
+ }) => enableHover && `&:hover {
12271
12269
  background-color: ${selectHoverColor};
12272
12270
  cursor: pointer;
12273
- }`;
12274
- }}
12271
+ }`}
12275
12272
  `;
12276
12273
  const InfoText = styled__default["default"].div`
12277
12274
  font-weight: 400;
@@ -37341,11 +37338,15 @@ const FilterPopContainer = styled__default["default"].div`
37341
37338
  font-family: 'Poppins', sans-serif;
37342
37339
  width: ${props => props.width || '300px'};
37343
37340
  height: ${props => props.height || 'auto'};
37341
+ max-height: ${props => props.maxHeight || '400px'};
37344
37342
  padding: 8px;
37345
37343
  color: #212121;
37346
37344
  background-color: #fff;
37347
37345
  border-radius: 4px;
37348
37346
  box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.10);
37347
+ display: flex;
37348
+ flex-direction: column;
37349
+ overflow: hidden;
37349
37350
 
37350
37351
  /* Add this CSS for checkbox styling */
37351
37352
  input[type="checkbox"] {
@@ -37360,52 +37361,133 @@ const Title$5 = styled__default["default"].h6`
37360
37361
  padding: 4px 12px;
37361
37362
  margin: 0 0 10px;
37362
37363
  text-align: left;
37364
+ flex-shrink: 0;
37365
+ `;
37366
+ const SearchInput = styled__default["default"].input`
37367
+ width: 100%;
37368
+ padding: 8px 12px;
37369
+ margin: 0 0 12px;
37370
+ font-size: 14px;
37371
+ font-family: 'Poppins', sans-serif;
37372
+ border: 1px solid #e0e0e0;
37373
+ border-radius: 4px;
37374
+ background-color: #fff;
37375
+ color: #212121;
37376
+ flex-shrink: 0;
37377
+ box-sizing: border-box;
37378
+
37379
+ &::placeholder {
37380
+ color: #999;
37381
+ font-style: italic;
37382
+ }
37383
+
37384
+ &:focus {
37385
+ outline: none;
37386
+ border-color: ${props => props.accentColor || '#066768'};
37387
+ box-shadow: 0 0 0 2px ${props => props.accentColor || '#066768'}20;
37388
+ }
37389
+
37390
+ &:hover {
37391
+ border-color: #c0c0c0;
37392
+ }
37363
37393
  `;
37364
37394
  const CheckboxGroup = styled__default["default"].div`
37365
- display: flex;
37366
- flex-direction: column;
37367
- gap: 8px;
37368
- margin-bottom: 16px;
37395
+ display: flex;
37396
+ flex-direction: column;
37397
+ gap: 8px;
37398
+ margin-bottom: 16px;
37399
+ overflow-y: auto;
37400
+ flex: 1;
37401
+ min-height: 0;
37402
+
37403
+ /* Custom scrollbar styling */
37404
+ &::-webkit-scrollbar {
37405
+ width: 6px;
37406
+ }
37407
+
37408
+ &::-webkit-scrollbar-track {
37409
+ background: #f1f1f1;
37410
+ border-radius: 3px;
37411
+ }
37412
+
37413
+ &::-webkit-scrollbar-thumb {
37414
+ background: #c1c1c1;
37415
+ border-radius: 3px;
37416
+ }
37417
+
37418
+ &::-webkit-scrollbar-thumb:hover {
37419
+ background: #a8a8a8;
37420
+ }
37421
+
37422
+ /* For Firefox */
37423
+ scrollbar-width: thin;
37424
+ scrollbar-color: #c1c1c1 #f1f1f1;
37369
37425
  `;
37370
37426
  const CheckboxLabel = styled__default["default"].label`
37371
- display: flex;
37372
- align-items: center;
37373
- gap: 8px;
37374
- padding: 8px 12px;
37375
- font-size: 14px;
37376
- font-weight: 400;
37377
- color: #212121;
37378
- cursor: pointer;
37379
-
37380
- &:hover {
37381
- background-color: #E6F0F0;
37382
- }
37383
-
37384
- > span {
37385
- width: ${props => props.width};
37386
- white-space: nowrap;
37387
- overflow: hidden;
37388
- text-overflow: ellipsis;
37389
- }
37427
+ display: flex;
37428
+ align-items: center;
37429
+ gap: 8px;
37430
+ padding: 8px 12px;
37431
+ font-size: 14px;
37432
+ font-weight: 400;
37433
+ color: #212121;
37434
+ cursor: pointer;
37435
+ flex-shrink: 0;
37436
+
37437
+ &:hover {
37438
+ background-color: #E6F0F0;
37439
+ }
37440
+
37441
+ > span {
37442
+ width: ${props => props.width};
37443
+ white-space: nowrap;
37444
+ overflow: hidden;
37445
+ text-overflow: ellipsis;
37446
+ }
37447
+ `;
37448
+ const NoResultsMessage = styled__default["default"].div`
37449
+ padding: 16px 12px;
37450
+ text-align: center;
37451
+ color: #999;
37452
+ font-size: 14px;
37453
+ font-style: italic;
37390
37454
  `;
37391
37455
  const ButtonWrapper$2 = styled__default["default"].div`
37392
37456
  text-align: right;
37457
+ flex-shrink: 0;
37458
+ padding-top: 8px;
37459
+ border-top: 1px solid #e0e0e0;
37460
+ display: flex;
37461
+ justify-content: flex-end;
37462
+ align-items: center;
37393
37463
  `;
37394
37464
  const ResetButton$1 = styled__default["default"].button`
37395
37465
  font-size: 14px;
37396
37466
  font-weight: 400;
37397
- padding: 2px 8px;
37467
+ padding: 4px 8px;
37398
37468
  background-color: transparent;
37399
37469
  border: none;
37400
37470
  cursor: pointer;
37471
+ border-radius: 3px;
37472
+
37473
+ &:hover {
37474
+ background-color: #f0f0f0;
37475
+ color: #066768;
37476
+ }
37401
37477
 
37402
- &:hover {
37403
- // color: #066768;
37404
- }
37405
-
37406
- &:active {
37407
- // color: #066768;
37408
- }
37478
+ &:active {
37479
+ color: #066768;
37480
+ }
37481
+
37482
+ &:disabled {
37483
+ color: #ccc;
37484
+ cursor: not-allowed;
37485
+
37486
+ &:hover {
37487
+ background-color: transparent;
37488
+ color: #ccc;
37489
+ }
37490
+ }
37409
37491
  `;
37410
37492
 
37411
37493
  const FilterPop = props => {
@@ -37413,15 +37495,22 @@ const FilterPop = props => {
37413
37495
  menuName = '',
37414
37496
  width = 'auto',
37415
37497
  height = 'auto',
37498
+ maxHeight = '400px',
37416
37499
  list = [],
37417
37500
  color = '#007bff',
37418
37501
  onCheck = () => {},
37419
37502
  onReset = () => {},
37420
37503
  doubleColumn = false,
37421
37504
  isAsc = true,
37422
- selectedAttributes: propSelectedAttributes = {} // Receive from parent
37505
+ selectedAttributes: propSelectedAttributes = {},
37506
+ showSearch = true,
37507
+ // New prop to enable/disable search
37508
+ searchPlaceholder = 'Search...' // New prop for search placeholder
37423
37509
  } = props;
37424
37510
 
37511
+ // State for search term
37512
+ const [searchTerm, setSearchTerm] = React$1.useState('');
37513
+
37425
37514
  // Add hardcoded "Select All" as first item
37426
37515
  const fullList = [{
37427
37516
  value: 'All',
@@ -37445,18 +37534,49 @@ const FilterPop = props => {
37445
37534
  return fullList.filter(item => item.value !== 'All');
37446
37535
  };
37447
37536
 
37448
- // Helper function to check if all non-"All" items are selected
37537
+ // Filter items based on search term
37538
+ const filteredList = React$1.useMemo(() => {
37539
+ if (!searchTerm.trim()) {
37540
+ return fullList;
37541
+ }
37542
+ const searchLower = searchTerm.toLowerCase().trim();
37543
+ const filteredNonAllItems = fullList.filter(item => {
37544
+ if (item.value === 'All') return false; // Don't filter out "Select All" in search
37545
+ return item.label.toLowerCase().includes(searchLower);
37546
+ });
37547
+
37548
+ // Always include "Select All" at the top when searching
37549
+ return [fullList.find(item => item.value === 'All'), ...filteredNonAllItems];
37550
+ }, [fullList, searchTerm]);
37551
+
37552
+ // Sort the filtered list based on the `isAsc` prop, keeping 'All' as the first option
37553
+ const sortedList = React$1.useMemo(() => {
37554
+ return [...filteredList.filter(item => item.value === 'All'), ...filteredList.filter(item => item.value !== 'All').sort((a, b) => {
37555
+ return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37556
+ })];
37557
+ }, [filteredList, isAsc]);
37558
+
37559
+ // Helper functions for "Select All" logic based on ALL items (not just filtered)
37449
37560
  const areAllNonAllItemsSelected = function () {
37450
37561
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37451
37562
  const nonAllItems = getNonAllItems();
37452
37563
  return nonAllItems.every(item => attributes[item.value]);
37453
37564
  };
37454
37565
 
37455
- // Helper function to check if any non-"All" items are selected
37456
- const areAnyNonAllItemsSelected = function () {
37566
+ // Helper functions for visible filtered items
37567
+ const getVisibleNonAllItems = () => {
37568
+ return sortedList.filter(item => item.value !== 'All');
37569
+ };
37570
+ const areAllVisibleItemsSelected = function () {
37457
37571
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37458
- const nonAllItems = getNonAllItems();
37459
- return nonAllItems.some(item => attributes[item.value]);
37572
+ const visibleItems = getVisibleNonAllItems();
37573
+ if (visibleItems.length === 0) return false;
37574
+ return visibleItems.every(item => attributes[item.value]);
37575
+ };
37576
+ const areAnyVisibleItemsSelected = function () {
37577
+ let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37578
+ const visibleItems = getVisibleNonAllItems();
37579
+ return visibleItems.some(item => attributes[item.value]);
37460
37580
  };
37461
37581
 
37462
37582
  // New helper function to create the efficient data structure
@@ -37480,14 +37600,12 @@ const FilterPop = props => {
37480
37600
  isSelectAll: false
37481
37601
  };
37482
37602
  } else if (mostSelected) {
37483
- // More items selected than unselected - use exclude approach
37484
37603
  return {
37485
37604
  excluded: unselectedItems.map(item => item.value),
37486
37605
  included: [],
37487
37606
  isSelectAll: true
37488
37607
  };
37489
37608
  } else {
37490
- // Fewer items selected than unselected - use include approach
37491
37609
  return {
37492
37610
  excluded: [],
37493
37611
  included: selectedItems.map(item => item.value),
@@ -37497,47 +37615,50 @@ const FilterPop = props => {
37497
37615
  };
37498
37616
  const handleCheckboxChange = attribute => {
37499
37617
  if (attribute === 'All') {
37500
- // If "Select All" is clicked - determine new state based on current "Select All" state
37501
- const currentSelectAllState = selectedAttributes.All || false;
37502
- const newState = !currentSelectAllState;
37503
- const updatedAttributes = {};
37618
+ // "Select All" behavior - affects ALL visible filtered items
37619
+ const visibleNonAllItems = getVisibleNonAllItems();
37620
+ const allVisibleSelected = areAllVisibleItemsSelected();
37504
37621
 
37505
- // Set all items to the same state as "Select All"
37506
- fullList.forEach(item => {
37507
- updatedAttributes[item.value] = newState;
37622
+ // Toggle all visible items
37623
+ const updatedAttributes = {
37624
+ ...selectedAttributes
37625
+ };
37626
+ visibleNonAllItems.forEach(item => {
37627
+ updatedAttributes[item.value] = !allVisibleSelected;
37508
37628
  });
37509
37629
 
37510
- // Call onCheck callback with new efficient structure
37630
+ // Update "Select All" state based on all items (not just visible)
37631
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37511
37632
  const filterData = createFilterData(updatedAttributes);
37512
37633
  onCheck({
37513
37634
  changedItem: attribute,
37514
37635
  filterData: filterData,
37515
- allItems: updatedAttributes // Keep for backward compatibility if needed
37636
+ allItems: updatedAttributes
37516
37637
  });
37517
37638
  } else {
37518
- // If any other item is clicked
37639
+ // Individual item clicked
37519
37640
  const updatedAttributes = {
37520
37641
  ...selectedAttributes,
37521
37642
  [attribute]: !selectedAttributes[attribute]
37522
37643
  };
37523
37644
 
37524
- // Call onCheck callback with new efficient structure
37645
+ // Update "Select All" state based on all items
37646
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37525
37647
  const filterData = createFilterData(updatedAttributes);
37526
37648
  onCheck({
37527
37649
  changedItem: attribute,
37528
37650
  filterData: filterData,
37529
- allItems: updatedAttributes // Keep for backward compatibility if needed
37651
+ allItems: updatedAttributes
37530
37652
  });
37531
37653
  }
37532
37654
  };
37533
37655
  const handleReset = () => {
37656
+ // Clear search when resetting
37657
+ setSearchTerm('');
37658
+
37534
37659
  // Reset to the original default state (all selected)
37535
37660
  const resetState = createInitialState();
37536
-
37537
- // Call the onReset callback
37538
37661
  onReset();
37539
-
37540
- // Also call onCheck to notify parent of the reset with new efficient structure
37541
37662
  const filterData = createFilterData(resetState);
37542
37663
  onCheck({
37543
37664
  changedItem: 'reset',
@@ -37546,17 +37667,24 @@ const FilterPop = props => {
37546
37667
  });
37547
37668
  };
37548
37669
 
37549
- // Function to determine checkbox state for "Select All"
37670
+ // Function to determine checkbox state for "Select All" based on visible items
37550
37671
  const getSelectAllCheckboxProps = () => {
37551
- const allSelected = areAllNonAllItemsSelected();
37552
- const anySelected = areAnyNonAllItemsSelected();
37553
- const noneSelected = !anySelected;
37554
- if (allSelected) {
37672
+ const visibleItems = getVisibleNonAllItems();
37673
+ if (visibleItems.length === 0) {
37674
+ return {
37675
+ checked: false,
37676
+ indeterminate: false
37677
+ };
37678
+ }
37679
+ const allVisibleSelected = areAllVisibleItemsSelected();
37680
+ const anyVisibleSelected = areAnyVisibleItemsSelected();
37681
+ const noneVisibleSelected = !anyVisibleSelected;
37682
+ if (allVisibleSelected) {
37555
37683
  return {
37556
37684
  checked: true,
37557
37685
  indeterminate: false
37558
37686
  };
37559
- } else if (noneSelected) {
37687
+ } else if (noneVisibleSelected) {
37560
37688
  return {
37561
37689
  checked: false,
37562
37690
  indeterminate: false
@@ -37569,38 +37697,50 @@ const FilterPop = props => {
37569
37697
  }
37570
37698
  };
37571
37699
 
37572
- // Sort the list based on the `isAsc` prop, keeping 'All' as the first option
37573
- const sortedList = [...fullList.filter(item => item.value === 'All'), ...fullList.filter(item => item.value !== 'All').sort((a, b) => {
37574
- return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37575
- })];
37700
+ // Handle search input change
37701
+ const handleSearchChange = e => {
37702
+ setSearchTerm(e.target.value);
37703
+ };
37704
+
37705
+ // Clear search
37706
+ const clearSearch = () => {
37707
+ setSearchTerm('');
37708
+ };
37576
37709
  return /*#__PURE__*/React__default["default"].createElement(FilterPopContainer, {
37577
37710
  width: width,
37578
37711
  height: height,
37579
- accentColor: color // Pass color as prop to styled component
37580
- }, /*#__PURE__*/React__default["default"].createElement(Title$5, null, menuName), /*#__PURE__*/React__default["default"].createElement(CheckboxGroup, {
37712
+ maxHeight: maxHeight,
37713
+ accentColor: color
37714
+ }, /*#__PURE__*/React__default["default"].createElement(Title$5, null, menuName), showSearch && /*#__PURE__*/React__default["default"].createElement(SearchInput, {
37715
+ type: "text",
37716
+ placeholder: searchPlaceholder,
37717
+ value: searchTerm,
37718
+ onChange: handleSearchChange,
37719
+ accentColor: color
37720
+ }), /*#__PURE__*/React__default["default"].createElement(CheckboxGroup, {
37581
37721
  style: {
37582
37722
  display: doubleColumn ? 'grid' : 'flex',
37583
37723
  gridTemplateColumns: doubleColumn ? '1fr 1fr' : 'none',
37584
37724
  gap: '8px'
37585
37725
  }
37586
- }, sortedList.map(item => {
37726
+ }, sortedList.length === 1 ?
37727
+ /*#__PURE__*/
37728
+ // Only "Select All" is visible
37729
+ React__default["default"].createElement(NoResultsMessage, null, "No items match your search") : sortedList.map(item => {
37587
37730
  const isSelectAll = item.value === 'All';
37588
37731
  const checkboxProps = isSelectAll ? getSelectAllCheckboxProps() : {};
37589
37732
  const isChecked = isSelectAll ? checkboxProps.checked : selectedAttributes[item.value] || false;
37590
37733
  return /*#__PURE__*/React__default["default"].createElement(CheckboxLabel, {
37591
37734
  width: !doubleColumn ?? width,
37592
- key: `${item.value}-${JSON.stringify(selectedAttributes)}`
37735
+ key: `${item.value}-${JSON.stringify(selectedAttributes)}-${searchTerm}`
37593
37736
  }, /*#__PURE__*/React__default["default"].createElement("input", {
37594
37737
  type: "checkbox",
37595
37738
  checked: isChecked,
37596
37739
  ref: el => {
37597
37740
  if (el) {
37598
- // Handle indeterminate for Select All FIRST
37599
37741
  if (isSelectAll) {
37600
37742
  el.indeterminate = checkboxProps.indeterminate;
37601
37743
  }
37602
-
37603
- // FORCE DOM SYNC - manually set DOM state to match React state
37604
37744
  if (el.checked !== isChecked) {
37605
37745
  el.checked = isChecked;
37606
37746
  }
@@ -37610,7 +37750,12 @@ const FilterPop = props => {
37610
37750
  handleCheckboxChange(item.value);
37611
37751
  }
37612
37752
  }), /*#__PURE__*/React__default["default"].createElement("span", null, item.label));
37613
- })), /*#__PURE__*/React__default["default"].createElement(ButtonWrapper$2, null, /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37753
+ })), /*#__PURE__*/React__default["default"].createElement(ButtonWrapper$2, null, showSearch && searchTerm && /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37754
+ onClick: clearSearch,
37755
+ style: {
37756
+ marginRight: '8px'
37757
+ }
37758
+ }, "Clear Search"), /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37614
37759
  onClick: handleReset,
37615
37760
  disabled: areAllNonAllItemsSelected() && selectedAttributes.All
37616
37761
  }, "Reset")));
@@ -55049,6 +55194,7 @@ const ToasterMessageBox = _ref => {
55049
55194
  linkText = '',
55050
55195
  duration = 5,
55051
55196
  width = '500px',
55197
+ icon = OkCircleIcon,
55052
55198
  onLinkClick = () => {},
55053
55199
  onClose = () => {}
55054
55200
  } = _ref;
@@ -55087,7 +55233,9 @@ const ToasterMessageBox = _ref => {
55087
55233
  $isClosing: isClosing
55088
55234
  }, /*#__PURE__*/React__default["default"].createElement(IconWrapper, {
55089
55235
  $color: color
55090
- }, /*#__PURE__*/React__default["default"].createElement(OkCircleIcon, {
55236
+ }, icon === 'error' ? /*#__PURE__*/React__default["default"].createElement(ErrorIcon, {
55237
+ color: "white"
55238
+ }) : /*#__PURE__*/React__default["default"].createElement(OkCircleIcon, {
55091
55239
  color: color,
55092
55240
  width: "40",
55093
55241
  height: "40"
@@ -55368,7 +55516,7 @@ exports.RangePop = RangePop;
55368
55516
  exports.ReportTable = ReportTable;
55369
55517
  exports.RulesEngine = RulesEngine;
55370
55518
  exports.SampleRunEngine = SampleRunEngine;
55371
- exports.SearchInput = SearchInput;
55519
+ exports.SearchInput = SearchInput$1;
55372
55520
  exports.SingleBarLineCharts = SingleBarLineCharts;
55373
55521
  exports.SortPop = SortPop;
55374
55522
  exports.TabMenu = TabMenu;