pixel-react 1.13.92 → 1.13.94

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 (41) hide show
  1. package/lib/components/AttachmentButton/AttachmentButton.js +1 -1
  2. package/lib/components/EditLabel/EditLabel.js +1 -1
  3. package/lib/components/EditLabel/EditLabel.js.map +1 -1
  4. package/lib/components/Excel/ExcelFile/ExcelFileComponents/ActiveCell.js +29 -20
  5. package/lib/components/Excel/ExcelFile/ExcelFileComponents/ActiveCell.js.map +1 -1
  6. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.d.ts +1 -1
  7. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.js +8 -9
  8. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.js.map +1 -1
  9. package/lib/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.js +3 -3
  10. package/lib/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.js.map +1 -1
  11. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.js +3 -1
  12. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.js.map +1 -1
  13. package/lib/components/MachineInputField/MachineInputField.js +15 -3
  14. package/lib/components/MachineInputField/MachineInputField.js.map +1 -1
  15. package/lib/components/MachineInputField/types.d.ts +1 -0
  16. package/lib/components/SequentialConnectingBranch/components/Branches/Branches.js +3 -2
  17. package/lib/components/SequentialConnectingBranch/components/Branches/Branches.js.map +1 -1
  18. package/lib/components/Table/Table.d.ts +1 -1
  19. package/lib/components/Table/Table.js +88 -58
  20. package/lib/components/Table/Table.js.map +1 -1
  21. package/lib/components/Table/Types.d.ts +2 -4
  22. package/lib/components/TableTreeFn/Components/TableBody.js +4 -16
  23. package/lib/components/TableTreeFn/Components/TableBody.js.map +1 -1
  24. package/lib/components/TableTreeFn/TableTreeFn.js +140 -128
  25. package/lib/components/TableTreeFn/TableTreeFn.js.map +1 -1
  26. package/lib/components/TableTreeFn/types.d.ts +1 -0
  27. package/lib/components/TextArea/Textarea.js +1 -1
  28. package/lib/components/TextArea/Textarea.js.map +1 -1
  29. package/lib/index.cjs +294 -242
  30. package/lib/index.cjs.map +1 -1
  31. package/lib/index.d.ts +5 -2
  32. package/lib/node_modules/js-beautify/js/src/css/beautifier.js +1 -1
  33. package/lib/node_modules/js-beautify/js/src/css/options.js +1 -1
  34. package/lib/node_modules/js-beautify/js/src/javascript/beautifier.js +1 -1
  35. package/lib/node_modules/js-beautify/js/src/javascript/options.js +1 -1
  36. package/lib/styles.css +1 -1
  37. package/lib/styles.css.map +1 -1
  38. package/package.json +1 -1
  39. package/lib/components/TableTreeFn/TableTree.storiesFn.d.ts +0 -11
  40. package/lib/components/TableTreeFn/TableTree.storiesFn.js +0 -340
  41. package/lib/components/TableTreeFn/TableTree.storiesFn.js.map +0 -1
package/lib/index.cjs CHANGED
@@ -4641,7 +4641,7 @@ const Textarea = ({
4641
4641
  }) => {
4642
4642
  const labelClasses = classNames('ff-textarea-label ff-textarea-label--' + variant, {
4643
4643
  'ff-textarea-label--danger': error,
4644
- 'ff-textarea-label--disabled': disabled
4644
+ 'ff-textarea-label--disabled': disabled && !value
4645
4645
  });
4646
4646
  const textareaClasses = classNames(`ff-textarea ff-textarea--${variant}`, className, {
4647
4647
  'ff-textarea--danger': error,
@@ -9826,10 +9826,25 @@ var DNDSortable = /*#__PURE__*/Object.freeze({
9826
9826
  verticalListSortingStrategy: verticalListSortingStrategy
9827
9827
  });
9828
9828
 
9829
- const getColumnWidth = (index, column, columns) => {
9830
- if (index === 0) return `${index * (column?.width || 0)}px`;
9831
- if (index === 1) return `${columns?.[0]?.width || 0}px`;
9832
- return 'auto';
9829
+ const getColumnLeftPosition = (index, columns, freezeColumns) => {
9830
+ if (index === 0) return '0px';
9831
+ // Calculate cumulative width of all previous columns including padding
9832
+ let leftPosition = 0;
9833
+ const CELL_PADDING = 8; // Each cell has 8px padding
9834
+ for (let i = 0; i < index; i++) {
9835
+ const width = columns[i]?.width;
9836
+ // Add column width plus left padding only
9837
+ leftPosition += width ? parseInt(width.toString(), 10) : DEFAULT_COLUMN_WIDTH;
9838
+ // Add padding between frozen columns
9839
+ if (freezeColumns && i < freezeColumns - 1) {
9840
+ leftPosition += CELL_PADDING;
9841
+ }
9842
+ }
9843
+ return `${leftPosition}px`;
9844
+ };
9845
+ const DEFAULT_COLUMN_WIDTH = 400;
9846
+ const calculateFrozenWidth = (columnData, freezeColumns) => {
9847
+ return columnData.slice(0, freezeColumns).reduce((acc, col) => acc + parseInt(col.width?.toString() || `${DEFAULT_COLUMN_WIDTH}`, 10), 1) + 8 * (freezeColumns - 0.17);
9833
9848
  };
9834
9849
  const SortableRow = ({
9835
9850
  row,
@@ -9844,9 +9859,9 @@ const SortableRow = ({
9844
9859
  editMode,
9845
9860
  isAccordionOpen,
9846
9861
  accordionContent,
9847
- columnSticky,
9848
9862
  isRowCheckBoxDisable,
9849
- isRowDisabled = true
9863
+ isRowDisabled = true,
9864
+ freezeColumns
9850
9865
  }) => {
9851
9866
  const {
9852
9867
  attributes,
@@ -9872,15 +9887,19 @@ const SortableRow = ({
9872
9887
  }),
9873
9888
  id: key,
9874
9889
  children: columns.map((column, index) => {
9875
- const isSticky = columnSticky && (index === 0 || index === 1);
9890
+ const isFrozen = freezeColumns && index < freezeColumns;
9876
9891
  return jsxRuntime.jsx("td", {
9877
9892
  style: {
9878
- paddingLeft: index === 0 && draggable ? '0px' : '8px',
9879
- position: isSticky ? 'sticky' : 'static',
9880
- left: getColumnWidth(index, column, columns),
9881
- zIndex: isSticky ? 999 : 'auto',
9882
- backgroundColor: isSticky ? 'var(--input-label-bg-color)' : 'transparent'
9893
+ position: isFrozen ? 'sticky' : 'static',
9894
+ left: isFrozen ? getColumnLeftPosition(index, columns, freezeColumns) : 'auto',
9895
+ zIndex: isFrozen ? 999 : 'auto',
9896
+ backgroundColor: isFrozen ? 'var(--input-label-bg-color)' : 'transparent',
9897
+ width: column.width ? `${column.width}px` : 'auto',
9898
+ padding: '7px 8px',
9899
+ boxSizing: 'border-box',
9900
+ paddingRight: isFrozen ? 0 : '8px'
9883
9901
  },
9902
+ "data-frozen": isFrozen || undefined,
9884
9903
  onClick: () => handleOnclick(column, row),
9885
9904
  className: classNames(column.className, {
9886
9905
  'clickable-cell': column.onClick
@@ -9954,15 +9973,19 @@ const Table$1 = ({
9954
9973
  editComponent,
9955
9974
  getAccordionStatus = () => {},
9956
9975
  accordionContent,
9957
- columnSticky = false,
9958
9976
  tableRef = null,
9959
9977
  isRowCheckBoxDisable,
9960
9978
  isRowDisabled = true,
9961
- tableHeaderZindex = 99
9979
+ tableHeaderZindex = 99,
9980
+ freezeColumns
9962
9981
  }) => {
9963
9982
  const observerRef = React.useRef(null);
9983
+ let frozenWidth;
9984
+ if (freezeColumns) {
9985
+ frozenWidth = calculateFrozenWidth(columns, freezeColumns);
9986
+ }
9964
9987
  React.useEffect(() => {
9965
- const scrollContainer = document.getElementById('ff-table-scroll-container');
9988
+ const scrollContainer = document.getElementById('ff-sortable-table-scroll-container');
9966
9989
  const firstNode = document.getElementById('ff-table-first-node');
9967
9990
  const lastNode = document.getElementById('ff-table-last-node');
9968
9991
  // Exit early if data is empty or elements are missing
@@ -10023,12 +10046,10 @@ const Table$1 = ({
10023
10046
  children: jsxRuntime.jsxs("div", {
10024
10047
  style: {
10025
10048
  height: height,
10026
- position: 'relative',
10027
- overflowX: 'auto',
10028
- whiteSpace: 'nowrap',
10029
- scrollbarWidth: draggable ? 'none' : 'auto'
10049
+ scrollbarWidth: draggable ? 'none' : 'auto',
10050
+ '--frozen-column-width': freezeColumns ? `${frozenWidth}px` : '0px'
10030
10051
  },
10031
- id: "ff-table-scroll-container",
10052
+ id: "ff-sortable-table-scroll-container",
10032
10053
  className: classNames(className, {
10033
10054
  'ff-fixed-header-table': withFixedHeader,
10034
10055
  'border-borderRadius': borderWithRadius
@@ -10045,44 +10066,52 @@ const Table$1 = ({
10045
10066
  zIndex: tableHeaderZindex
10046
10067
  },
10047
10068
  children: jsxRuntime.jsx("tr", {
10048
- children: columns.map((column, index) => jsxRuntime.jsxs("th", {
10049
- className: classNames(`${headerType !== 'default' ? `${headerType}-bg` : ''}`, `${headerTextColor && `${headerTextColor}-color`}`, {
10050
- 'sticky-column': columnSticky && (index === 0 || index === 1)
10051
- }),
10052
- style: {
10053
- width: column?.width,
10054
- left: getColumnWidth(index, column, columns)
10055
- },
10056
- children: [jsxRuntime.jsx("div", {
10057
- className: "ff-table-icon",
10058
- children: jsxRuntime.jsx(Icon, {
10059
- height: 14,
10060
- width: 14,
10061
- name: headerIconName,
10062
- onClick: headerIconOnClick
10063
- })
10064
- }), jsxRuntime.jsxs(Typography, {
10065
- style: column?.width && {
10066
- width: column?.width
10069
+ children: columns.map((column, index) => {
10070
+ const isFrozen = freezeColumns && index < freezeColumns;
10071
+ return jsxRuntime.jsxs("th", {
10072
+ className: classNames(`${headerType !== 'default' ? `${headerType}-bg` : ''}`, `${headerTextColor && `${headerTextColor}-color`}`),
10073
+ style: {
10074
+ position: isFrozen ? 'sticky' : 'static',
10075
+ left: isFrozen ? getColumnLeftPosition(index, columns, freezeColumns) : 'auto',
10076
+ zIndex: isFrozen ? 999 : 'auto',
10077
+ backgroundColor: isFrozen ? 'var(--input-label-bg-color)' : 'transparent',
10078
+ width: column.width ? `${column.width}px` : 'auto',
10079
+ padding: '7px 8px',
10080
+ boxSizing: 'border-box',
10081
+ // Remove right padding from frozen columns to prevent overlap
10082
+ paddingRight: isFrozen ? 0 : '8px'
10067
10083
  },
10068
- as: "div",
10069
- fontWeight: "semi-bold",
10070
- className: "ff-label-checkbox-container",
10071
- children: [index === 0 && withCheckbox && jsxRuntime.jsx("span", {
10072
- className: "ff-table-checkbox",
10073
- children: jsxRuntime.jsx(Checkbox, {
10074
- onChange: e => {
10075
- onSelectClick(e, {
10076
- allSelected: e.target.checked
10077
- });
10078
- },
10079
- checked: allSelected !== undefined ? allSelected : false,
10080
- partial: !!partialSelected,
10081
- disabled: headerCheckboxDisabled
10084
+ children: [jsxRuntime.jsx("div", {
10085
+ className: "ff-table-icon",
10086
+ children: jsxRuntime.jsx(Icon, {
10087
+ height: 14,
10088
+ width: 14,
10089
+ name: headerIconName,
10090
+ onClick: headerIconOnClick
10082
10091
  })
10083
- }), column.header]
10084
- })]
10085
- }, column.header))
10092
+ }), jsxRuntime.jsxs(Typography, {
10093
+ style: column?.width && {
10094
+ width: column?.width
10095
+ },
10096
+ as: "div",
10097
+ fontWeight: "semi-bold",
10098
+ className: "ff-label-checkbox-container",
10099
+ children: [index === 0 && withCheckbox && jsxRuntime.jsx("span", {
10100
+ className: "ff-table-checkbox",
10101
+ children: jsxRuntime.jsx(Checkbox, {
10102
+ onChange: e => {
10103
+ onSelectClick(e, {
10104
+ allSelected: e.target.checked
10105
+ });
10106
+ },
10107
+ checked: allSelected !== undefined ? allSelected : false,
10108
+ partial: !!partialSelected,
10109
+ disabled: headerCheckboxDisabled
10110
+ })
10111
+ }), column.header]
10112
+ })]
10113
+ }, column.header);
10114
+ })
10086
10115
  })
10087
10116
  }), jsxRuntime.jsxs("tbody", {
10088
10117
  className: "ff-fixed-header-table",
@@ -10115,11 +10144,12 @@ const Table$1 = ({
10115
10144
  withCheckbox: withCheckbox,
10116
10145
  onSelectClick: onSelectClick,
10117
10146
  draggable: draggable,
10118
- columnSticky: columnSticky,
10119
10147
  isAccordionOpen: isOpen,
10120
10148
  accordionContent: accordionContent,
10121
10149
  isRowCheckBoxDisable: isRowCheckBoxDisable,
10122
- isRowDisabled: isRowDisabled
10150
+ isRowDisabled: isRowDisabled,
10151
+ freezeColumns: freezeColumns,
10152
+ frozenWidth: frozenWidth
10123
10153
  })
10124
10154
  });
10125
10155
  }), jsxRuntime.jsx("tr", {
@@ -16977,7 +17007,7 @@ const EditLabel = ({
16977
17007
  })]
16978
17008
  })]
16979
17009
  }) : jsxRuntime.jsx(Tooltip, {
16980
- title: getTooltipTitle(),
17010
+ title: isTextTruncated(text, truncatedTextCount, truncatedType) ? getTooltipTitle() : '',
16981
17011
  placement: tooltip?.tooltipPlacement ?? 'bottom',
16982
17012
  children: jsxRuntime.jsx("span", {
16983
17013
  className: 'ff-add-module-display-text',
@@ -35097,7 +35127,8 @@ const MachineInputField = ({
35097
35127
  edge: 'edge',
35098
35128
  firefox: 'fire_fox',
35099
35129
  chrome: 'chrome_icon',
35100
- explorer: 'internet_explorer'
35130
+ explorer: 'internet_explorer',
35131
+ ios: 'mac_icon'
35101
35132
  };
35102
35133
  const isManualScript = scriptType.toLowerCase() === 'manual';
35103
35134
  return jsxRuntime.jsxs("div", {
@@ -35125,7 +35156,8 @@ const MachineInputField = ({
35125
35156
  }),
35126
35157
  children: options.map(({
35127
35158
  label,
35128
- type = 'local'
35159
+ type = 'local',
35160
+ version
35129
35161
  }) => jsxRuntime.jsxs("div", {
35130
35162
  className: classNames('ff-machine-icon-text-wrapper', {
35131
35163
  'ff-machine-icon-text-wrapper-reverse': contentReverse
@@ -35140,8 +35172,17 @@ const MachineInputField = ({
35140
35172
  'ff-machine-text-reverse': contentReverse
35141
35173
  }),
35142
35174
  color: "var(--ff-machine-input-field-text-color)",
35143
- children: isTextTruncated(label, 15) ? truncateText(label, 15) : label
35175
+ children: isTextTruncated(label, 10) ? truncateText(label, 10) : label
35144
35176
  })
35177
+ }), isManualScript && !checkEmpty(version) && jsxRuntime.jsxs(Tooltip, {
35178
+ title: version,
35179
+ children: ["\u00A0 \u00A0", jsxRuntime.jsx(Typography, {
35180
+ className: classNames('ff-machine-text', {
35181
+ 'ff-machine-text-reverse': contentReverse
35182
+ }),
35183
+ color: "var(--ff-machine-input-field-text-color)",
35184
+ children: isTextTruncated(version ?? '', 10) ? truncateText(version ?? '', 10) : version
35185
+ })]
35145
35186
  })]
35146
35187
  }, type))
35147
35188
  })]
@@ -35271,8 +35312,9 @@ const Branches = ({
35271
35312
  const mobileOptions = deviceInfo?.reduce((acc, device, index) => {
35272
35313
  if (device?.name) {
35273
35314
  acc.push({
35274
- label: scriptType.toLowerCase() === 'manual' ? device?.version : device?.name,
35275
- type: index === 0 ? 'android' : 'mac'
35315
+ label: device?.name,
35316
+ type: index === 0 ? 'android' : 'mac',
35317
+ version: scriptType?.toLowerCase() === 'manual' ? device?.version : ''
35276
35318
  });
35277
35319
  }
35278
35320
  return acc;
@@ -35758,7 +35800,7 @@ const AttachmentButton = ({
35758
35800
  if (fileInputRef.current?.files) {
35759
35801
  const files = Array.from(fileInputRef.current.files);
35760
35802
  if (files.length > 5) {
35761
- setFileError('Maximun file(s) can be uploaded: 5');
35803
+ setFileError('Maximum file(s) can be uploaded: 5');
35762
35804
  fileInputRef.current.value = '';
35763
35805
  return;
35764
35806
  }
@@ -41026,7 +41068,6 @@ const Cell = ({
41026
41068
  row,
41027
41069
  column,
41028
41070
  DataViewer,
41029
- selected,
41030
41071
  active,
41031
41072
  dragging,
41032
41073
  mode,
@@ -41060,13 +41101,15 @@ const Cell = ({
41060
41101
  }, [setCellDimensions, select, dragging, point]);
41061
41102
  React__namespace.useEffect(() => {
41062
41103
  const root = rootRef.current;
41063
- if (selected && root) {
41104
+ if (!root) return;
41105
+ const updateDimensions = () => {
41064
41106
  setCellDimensions(point, getOffsetRect(root));
41065
- }
41066
- if (root && active && mode === 'view') {
41067
- root.focus();
41068
- }
41069
- }, [setCellDimensions, selected, active, mode, point, data]);
41107
+ };
41108
+ updateDimensions();
41109
+ const observer = new ResizeObserver(updateDimensions);
41110
+ observer.observe(root);
41111
+ return () => observer.disconnect();
41112
+ }, [setCellDimensions, point]);
41070
41113
  if (data && data.DataViewer) {
41071
41114
  DataViewer = data.DataViewer;
41072
41115
  }
@@ -41109,12 +41152,10 @@ const enhance = CellComponent => {
41109
41152
  const mode = useSelector(state => active ? state.mode : 'view');
41110
41153
  const data = useSelector(state => get$1(point, state.model.data));
41111
41154
  const evaluatedData = useSelector(state => get$1(point, state.model.evaluatedData));
41112
- const selected = useSelector(state => state.selected.has(state.model.data, point));
41113
41155
  const dragging = useSelector(state => state.dragging);
41114
41156
  const copied = useSelector(state => state.copied?.has(point) || false);
41115
41157
  return jsxRuntime.jsx(CellComponent, {
41116
41158
  ...props,
41117
- selected: selected,
41118
41159
  active: active,
41119
41160
  copied: copied,
41120
41161
  dragging: dragging,
@@ -41143,10 +41184,10 @@ const DataViewer = ({
41143
41184
  return jsxRuntime.jsx(jsxRuntime.Fragment, {});
41144
41185
  }
41145
41186
  const fileList = JSON.parse(value);
41146
- return fileList.map((file, index) => {
41147
- return jsxRuntime.jsxs("div", {
41187
+ return fileList.map(file => {
41188
+ return jsxRuntime.jsx("div", {
41148
41189
  className: "ff-spreadsheet-data-viewer--fileType",
41149
- children: [index + 1, ". ", file.name]
41190
+ children: file.name.split('*')[0]
41150
41191
  }, file.name);
41151
41192
  });
41152
41193
  };
@@ -41304,9 +41345,6 @@ const ActiveCell = props => {
41304
41345
  const fileLength = selectedFiles?.length + uniqueFiles?.length;
41305
41346
  const extractHeight = fileLength > 0 ? fileLength * 25 : 1;
41306
41347
  const processedFiles = [...existingFiles];
41307
- if (duplicateCount > 0) {
41308
- toast.info('Duplicate attachments not allowed within the same row');
41309
- }
41310
41348
  const uploadPromises = uniqueFiles?.map(async file => {
41311
41349
  try {
41312
41350
  if (file.name.includes('*')) {
@@ -41428,7 +41466,7 @@ const ActiveCell = props => {
41428
41466
  inputType: cell?.inputType
41429
41467
  });
41430
41468
  dispatch(setRowHeight(active?.row || 0, extractHeight));
41431
- setSelectedFiles(processedFiles.map(file => new File([new Blob()], file.name)));
41469
+ setSelectedFiles(processedFiles.map(file => new File([new Blob()], file.name?.split('*')[0] ?? 'default')));
41432
41470
  }
41433
41471
  if (memoryFullCount > 0) {
41434
41472
  toast.info('No memory available to add the file');
@@ -41443,8 +41481,6 @@ const ActiveCell = props => {
41443
41481
  console.error('Upload operation failed:', error);
41444
41482
  toast.error('Operation failed');
41445
41483
  }
41446
- } else if (duplicateCount > 0) {
41447
- toast.info('Duplicate attachments not allowed within the same row');
41448
41484
  }
41449
41485
  } else if (actionType === 'DELETE' && cell?.inputType?.type === 'file') {
41450
41486
  try {
@@ -41486,7 +41522,7 @@ const ActiveCell = props => {
41486
41522
  style: cell?.style,
41487
41523
  inputType: cell?.inputType
41488
41524
  });
41489
- setSelectedFiles(updatedFileDetails?.map(file => new File([new Blob()], file.name)));
41525
+ setSelectedFiles(updatedFileDetails?.map(file => new File([new Blob()], file.name.split('*')[0])));
41490
41526
  toast.success(`${deletedCount} file${deletedCount > 1 ? 's' : ''} deleted successfully`);
41491
41527
  } else if (selected?.length) {
41492
41528
  const validFiles = updatedFileDetails?.filter(file => file.id && file.name);
@@ -41498,7 +41534,7 @@ const ActiveCell = props => {
41498
41534
  style: cell?.style,
41499
41535
  inputType: cell?.inputType
41500
41536
  });
41501
- setSelectedFiles(validFiles.map(file => new File([new Blob()], file.name)));
41537
+ setSelectedFiles(validFiles.map(file => new File([new Blob()], file.name.split('*')[0])));
41502
41538
  toast.error('Failed to delete file(s). Invalid file data detected.');
41503
41539
  } else {
41504
41540
  toast.error('Failed to delete file(s). No valid files removed.');
@@ -41515,13 +41551,24 @@ const ActiveCell = props => {
41515
41551
  }
41516
41552
  };
41517
41553
  const handleClick = e => {
41518
- const selectedList = e.target.innerText;
41519
- if (selectedList) {
41520
- JSON.parse(cell?.value).map(file => {
41521
- if (file.name === selectedList && props.attachmentAction?.viewAttachment) {
41522
- props.attachmentAction?.viewAttachment(file.id, file.name);
41523
- }
41524
- });
41554
+ const fileElement = e.target.closest('.ff-attachment-files');
41555
+ const isIconClick = e.target.closest('.ff-icon-container, .ff-icon-click, .ff-icon-danger');
41556
+ if (!fileElement || isIconClick || !cell?.value || !props.attachmentAction?.viewAttachment) {
41557
+ console.warn('Missing file element, icon click, cell value, or viewAttachment action');
41558
+ return;
41559
+ }
41560
+ try {
41561
+ const files = JSON.parse(cell.value);
41562
+ const fileElements = fileElement.parentElement?.querySelectorAll('.ff-attachment-files') || [];
41563
+ const fileIndex = Array.from(fileElements).indexOf(fileElement);
41564
+ if (fileIndex === -1 || !files[fileIndex]) {
41565
+ console.error('File index not found or invalid');
41566
+ return;
41567
+ }
41568
+ const file = files[fileIndex];
41569
+ props.attachmentAction.viewAttachment(file.id, file.name?.split('*')[0] ?? 'default');
41570
+ } catch (error) {
41571
+ console.error('Error parsing cell value:', error);
41525
41572
  }
41526
41573
  };
41527
41574
  React__namespace.useEffect(() => {
@@ -41529,11 +41576,13 @@ const ActiveCell = props => {
41529
41576
  if (!hidden && root) {
41530
41577
  root.focus();
41531
41578
  if (cell?.inputType?.type === 'file' && cell?.value) {
41532
- const parsedFiles = JSON.parse(cell.value).map(file => {
41533
- const blob = new Blob([]);
41534
- return new File([blob], file.name);
41535
- });
41536
- setSelectedFiles(parsedFiles);
41579
+ try {
41580
+ const parsedFiles = JSON.parse(cell.value).map(file => new File([new Blob()], file.name.split('*')[0] ?? 'default'));
41581
+ setSelectedFiles(parsedFiles);
41582
+ } catch (error) {
41583
+ console.error('Error parsing cell value for files:', error);
41584
+ setSelectedFiles([]);
41585
+ }
41537
41586
  } else {
41538
41587
  setSelectedFiles([]);
41539
41588
  }
@@ -41640,6 +41689,7 @@ const ActiveCell = props => {
41640
41689
  buttonLabel: "+ Attachments",
41641
41690
  buttonVariant: "tertiary",
41642
41691
  deleteButton: true,
41692
+ selectedFileMessage: 'Duplicate attachments not allowed within the same row',
41643
41693
  addAttachmentButton: true,
41644
41694
  isInfoIconRequired: false,
41645
41695
  truncateMaxLimit: dimensions.width - 60
@@ -42249,7 +42299,9 @@ const Spreadsheet = props => {
42249
42299
  clientHeight
42250
42300
  } = target;
42251
42301
  setMaxHeight(Math.min(rootRef.current.clientHeight, clientHeight));
42252
- showHider && setMaxWidth(Math.min(rootRef.current.clientWidth, clientWidth));
42302
+ if (showHider) {
42303
+ setMaxWidth(Math.min(rootRef.current.clientWidth, clientWidth));
42304
+ }
42253
42305
  }
42254
42306
  }
42255
42307
  });
@@ -47036,15 +47088,9 @@ const TableBody = ({
47036
47088
  // if (checkEmpty(flattenedTreeData)) {
47037
47089
  // return null;
47038
47090
  // }
47039
- return jsxRuntime.jsxs("tbody", {
47091
+ return jsxRuntime.jsx("tbody", {
47040
47092
  className: "ff-table-tree-body",
47041
- children: [jsxRuntime.jsx("div", {
47042
- style: {
47043
- position: 'sticky',
47044
- left: 0
47045
- },
47046
- id: "ff-table-tree-first-node"
47047
- }), addNewRow(flattenedTreeData, newNode ?? {}, rootNode)?.map((node, index) => !node?.hide ? jsxRuntime.jsx(TableRow, {
47093
+ children: addNewRow(flattenedTreeData, newNode ?? {}, rootNode)?.map((node, index) => !node?.hide ? jsxRuntime.jsx(TableRow, {
47048
47094
  node: node,
47049
47095
  columnsData: columnsData,
47050
47096
  selected: selected,
@@ -47063,13 +47109,7 @@ const TableBody = ({
47063
47109
  addModuleInputWidth: addModuleInputWidth,
47064
47110
  addModuleSelectWidth: addModuleSelectWidth,
47065
47111
  disableEditLabelConfirmIcon: disableEditLabelConfirmIcon
47066
- }, node.key) : null), jsxRuntime.jsx("div", {
47067
- style: {
47068
- position: 'sticky',
47069
- left: 0
47070
- },
47071
- id: "ff-table-tree-last-node"
47072
- })]
47112
+ }, node.key) : null)
47073
47113
  });
47074
47114
  };
47075
47115
 
@@ -47090,7 +47130,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47090
47130
  handleEditFieldError,
47091
47131
  loading = false,
47092
47132
  rootNode,
47093
- getContentLength,
47094
47133
  pagination = true,
47095
47134
  selectedNode,
47096
47135
  tableHeaderBgColor = 'var(--border-color)',
@@ -47102,130 +47141,167 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47102
47141
  onScroll,
47103
47142
  disableEditLabelConfirmIcon = false,
47104
47143
  transparentHeader = false,
47105
- navigateTreeNode = null
47144
+ navigateTreeNode = null,
47145
+ handleRemoveNavigateTreeNode = () => {}
47106
47146
  }, ref) => {
47107
47147
  const [expanding, setExpanding] = React.useState(null);
47108
- const [isLoading, setIsLoading] = React.useState(null);
47109
- const observerRef = React.useRef(null);
47110
- const containerRef = React.useRef(null); // Reference for scroll container
47148
+ const [scrollDirection, setScrollDirection] = React.useState(null); // this state will help to idenetify the direction during the pagination api call
47111
47149
  const [prevScrollTop, setPrevScrollTop] = React.useState(null);
47150
+ const [prevScrollHeight, setPrevScrollHeight] = React.useState(null);
47151
+ const [maintainScrollPosition, setMaintainScrollPosition] = React.useState(null);
47152
+ const containerRef = React.useRef(null);
47112
47153
  const previousTreeDataRef = React.useRef([]);
47113
- //new loadMoreAbove function
47114
- const loadMoreAbove = () => {
47115
- if (loading || isLoading === 'above') return;
47116
- console.log('calling above');
47117
- setIsLoading('above');
47154
+ const scrollPositionRef = React.useRef({
47155
+ lastScrollTop: 0,
47156
+ lastScrollTime: 0,
47157
+ direction: null
47158
+ });
47159
+ const scrollDebounceRef = React.useRef(null);
47160
+ // this is the Distance from edge to trigger the scroll below and above
47161
+ const scrollThreshold = 128;
47162
+ // this is loadMore functions which will the trigger the pagination apis in platform
47163
+ const loadMoreAbove = React.useCallback(() => {
47164
+ if (loading || scrollDirection === 'above') return;
47165
+ setScrollDirection('above');
47118
47166
  setPrevScrollTop(containerRef.current?.scrollTop ?? null);
47167
+ setPrevScrollHeight(containerRef.current?.scrollHeight ?? null);
47119
47168
  loadMore('above');
47120
- };
47121
- const loadMoreBelow = () => {
47122
- if (loading || isLoading === 'below') return;
47123
- console.log('calling below');
47124
- setIsLoading('below');
47125
- // Trigger the loadMore callback for data loading from below
47169
+ }, [loading, scrollDirection, loadMore]);
47170
+ const loadMoreBelow = React.useCallback(() => {
47171
+ if (loading || scrollDirection === 'below') return;
47172
+ setScrollDirection('below');
47126
47173
  loadMore('below');
47127
- };
47128
- //new handle Scroll function
47174
+ }, [loading, scrollDirection, loadMore]);
47175
+ // this is scroll handler
47129
47176
  const handleScroll = React.useCallback(() => {
47130
47177
  const container = containerRef.current;
47131
- const previousTreeData = previousTreeDataRef.current;
47132
- if (!loading && container && isLoading === 'above' && previousTreeData.length > 0 && prevScrollTop !== null) {
47133
- let addedRowsCount = 0;
47134
- if (getContentLength) {
47135
- addedRowsCount = getContentLength;
47136
- } else {
47137
- for (let i = 0; i < treeData.length; i++) {
47138
- if (previousTreeData[0] === treeData[i]) break;
47139
- addedRowsCount++;
47140
- }
47178
+ if (!container) return;
47179
+ const now = Date.now();
47180
+ const currentScrollTop = container.scrollTop;
47181
+ const scrollHeight = container.scrollHeight;
47182
+ const clientHeight = container.clientHeight;
47183
+ // Determine scroll direction
47184
+ const direction = currentScrollTop > scrollPositionRef.current.lastScrollTop ? 'down' : 'up';
47185
+ scrollPositionRef.current = {
47186
+ lastScrollTop: currentScrollTop,
47187
+ lastScrollTime: now,
47188
+ direction
47189
+ };
47190
+ // Clear any pending debounce
47191
+ if (scrollDebounceRef.current) {
47192
+ clearTimeout(scrollDebounceRef.current);
47193
+ }
47194
+ // Check if we're near the bottom (for loading more below)
47195
+ const nearBottom = scrollHeight - (currentScrollTop + clientHeight) < scrollThreshold;
47196
+ if (direction === 'down' && nearBottom && !loading && !scrollDirection && treeData[treeData.length - 1]?.lastResource !== true) {
47197
+ console.log('Loading more below');
47198
+ scrollDebounceRef.current = setTimeout(() => {
47199
+ loadMoreBelow();
47200
+ }, 150);
47201
+ }
47202
+ // Check if we're near the top (for loading more above)
47203
+ const nearTop = currentScrollTop < scrollThreshold;
47204
+ if (direction === 'up' && nearTop && !loading && !scrollDirection && treeData[0]?.lastResource !== true) {
47205
+ console.log('Loading more above');
47206
+ scrollDebounceRef.current = setTimeout(() => {
47207
+ loadMoreAbove();
47208
+ }, 150);
47209
+ }
47210
+ console.log('hanldeScroll called');
47211
+ // if (onScroll) {
47212
+ // onScroll();
47213
+ // }
47214
+ }, [loading, scrollDirection, treeData, loadMoreAbove, loadMoreBelow, onScroll]);
47215
+ // Attach scroll event listener for updated first node when we scroll
47216
+ React.useEffect(() => {
47217
+ const scrollDiv = containerRef.current;
47218
+ if (scrollDiv && onScroll) {
47219
+ scrollDiv.addEventListener('scroll', onScroll);
47220
+ }
47221
+ return () => {
47222
+ if (scrollDiv && onScroll) {
47223
+ scrollDiv.removeEventListener('scroll', onScroll);
47141
47224
  }
47142
- let retries = 0;
47143
- const maxRetries = 30;
47144
- const tryRestoreScroll = () => {
47145
- const allRows = Array.from(container.querySelectorAll('.ff-table-tree-row'));
47146
- // Total added height of new rows
47147
- let totalAddedHeight = 0;
47148
- for (let i = 0; i < addedRowsCount; i++) {
47149
- const height = allRows[i]?.getBoundingClientRect().height || 0;
47150
- totalAddedHeight += height;
47151
- }
47152
- const canScroll = container.scrollHeight > container.clientHeight;
47153
- const validHeights = totalAddedHeight > 0;
47154
- if (validHeights && canScroll) {
47155
- container.scrollTop = prevScrollTop + totalAddedHeight;
47156
- previousTreeDataRef.current = treeData;
47157
- } else if (retries < maxRetries) {
47158
- retries++;
47159
- requestAnimationFrame(tryRestoreScroll);
47160
- } else {
47161
- previousTreeDataRef.current = treeData;
47162
- console.warn('Failed to restore scroll position after max retries');
47163
- }
47164
- };
47165
- console.log(`Attempting to restore scroll position after loading more data. Added rows count: ${addedRowsCount}, retries: ${retries}`);
47166
- // Start scroll adjustment
47167
- requestAnimationFrame(tryRestoreScroll);
47225
+ };
47226
+ }, [onScroll]);
47227
+ React.useEffect(() => {
47228
+ return () => {
47229
+ if (scrollDebounceRef.current) {
47230
+ clearTimeout(scrollDebounceRef.current);
47231
+ }
47232
+ };
47233
+ }, []);
47234
+ // Handle scroll position restoration after loading
47235
+ React.useLayoutEffect(() => {
47236
+ if (!loading && scrollDirection === 'above' && prevScrollTop !== null && prevScrollHeight !== null) {
47237
+ const container = containerRef.current;
47238
+ if (!container) return;
47239
+ const scrollHeightDiff = container.scrollHeight - prevScrollHeight;
47240
+ if (scrollHeightDiff > 0) {
47241
+ container.scrollTop = prevScrollTop + scrollHeightDiff;
47242
+ }
47243
+ setScrollDirection(null);
47244
+ setPrevScrollTop(null);
47245
+ setPrevScrollHeight(null);
47246
+ } else if (!loading) {
47247
+ setScrollDirection(null);
47168
47248
  }
47169
- }, [loading, isLoading, treeData, getContentLength, prevScrollTop]);
47249
+ }, [loading, scrollDirection, prevScrollTop, prevScrollHeight]);
47250
+ // Handle navigation to specific nodes
47170
47251
  React.useEffect(() => {
47171
- const scrollContainer = document.getElementById('ff-table-tree-scroll-container');
47172
- const lastNode = document.getElementById('ff-table-tree-last-node');
47173
- const firstNode = document.getElementById('ff-table-tree-first-node');
47174
- if (!scrollContainer || !lastNode || !firstNode || !treeData?.length || !pagination) return;
47175
- const isLastResourceBelow = !!treeData[treeData.length - 1]?.lastResource;
47176
- const isLastResourceAbove = !!treeData[0]?.lastResource;
47177
- // Clean up old observer before creating a new one
47178
- observerRef.current?.disconnect();
47179
- const observerCallback = entries => {
47180
- entries.forEach(entry => {
47181
- const nodeId = entry.target.id;
47182
- const direction = nodeId === 'ff-table-tree-last-node' ? 'below' : 'above';
47183
- console.log('entries', entry);
47184
- if (entry.isIntersecting) {
47185
- if (direction === 'below' && !isLastResourceBelow) {
47186
- console.log('LoadMoreBelow from observer');
47187
- loadMoreBelow();
47188
- } else if (direction === 'above' && !isLastResourceAbove) {
47189
- console.log('LoadMoreAbove from observer');
47190
- loadMoreAbove();
47191
- }
47192
- }
47193
- });
47252
+ if (navigateTreeNode) {
47253
+ const node = document.getElementById(navigateTreeNode);
47254
+ const container = containerRef.current;
47255
+ if (node && container) {
47256
+ // Store current scroll position
47257
+ setMaintainScrollPosition(container.scrollTop);
47258
+ // Calculate scroll position
47259
+ const nodeRect = node.getBoundingClientRect();
47260
+ const containerRect = container.getBoundingClientRect();
47261
+ const scrollTop = container.scrollTop;
47262
+ const nodeTop = nodeRect.top - containerRect.top + scrollTop;
47263
+ const containerHeight = containerRect.height;
47264
+ // Scroll to center the node
47265
+ container.scrollTo({
47266
+ top: nodeTop - containerHeight / 2 + nodeRect.height / 2,
47267
+ behavior: 'smooth'
47268
+ });
47269
+ }
47270
+ }
47271
+ return () => {
47272
+ handleRemoveNavigateTreeNode();
47194
47273
  };
47195
- observerRef.current = new IntersectionObserver(observerCallback, {
47196
- root: scrollContainer,
47197
- rootMargin: '30px',
47198
- threshold: 1
47199
- });
47200
- if (!isLastResourceBelow) observerRef.current.observe(lastNode);
47201
- if (!isLastResourceAbove) observerRef.current.observe(firstNode);
47202
- if (previousTreeDataRef.current.length === 0) {
47203
- previousTreeDataRef.current = treeData;
47274
+ }, [navigateTreeNode, treeData]);
47275
+ // Restore scroll position after navigation
47276
+ React.useEffect(() => {
47277
+ if (maintainScrollPosition !== null && !loading && containerRef.current) {
47278
+ containerRef.current.scrollTop = maintainScrollPosition;
47279
+ setMaintainScrollPosition(null);
47204
47280
  }
47281
+ }, [maintainScrollPosition, loading]);
47282
+ // Setup scroll listener
47283
+ React.useEffect(() => {
47284
+ const container = containerRef.current;
47285
+ if (!container || !pagination) return;
47286
+ container.addEventListener('scroll', handleScroll);
47287
+ // Initial check in case we're already at the bottom/top
47288
+ handleScroll();
47205
47289
  return () => {
47206
- observerRef.current?.disconnect();
47290
+ container.removeEventListener('scroll', handleScroll);
47291
+ if (scrollDebounceRef.current) {
47292
+ clearTimeout(scrollDebounceRef.current);
47293
+ }
47207
47294
  };
47208
- }, [treeData, loadMore, isLoading]);
47209
- // new useLayoutEffect to handle loading state
47210
- React.useLayoutEffect(() => {
47211
- if (!loading && isLoading === 'above' && pagination) {
47212
- const raf = requestAnimationFrame(() => {
47213
- handleScroll();
47214
- setIsLoading(null);
47215
- });
47216
- return () => {
47217
- cancelAnimationFrame(raf);
47218
- };
47219
- } else if (!loading) {
47295
+ }, [handleScroll, pagination]);
47296
+ // Track previous tree data for scroll restoration
47297
+ React.useEffect(() => {
47298
+ if (treeData.length > 0) {
47220
47299
  previousTreeDataRef.current = treeData;
47221
- setIsLoading(null);
47222
47300
  }
47223
- return undefined;
47224
- }, [loading, onScroll]);
47301
+ }, [treeData]);
47225
47302
  React.useEffect(() => {
47226
47303
  if (!loading && expanding) {
47227
47304
  setExpanding(null);
47228
- previousTreeDataRef.current = treeData;
47229
47305
  }
47230
47306
  }, [loading]);
47231
47307
  const handleToggleExpand = React.useCallback(node => {
@@ -47233,17 +47309,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47233
47309
  setExpanding(node.key);
47234
47310
  onExpand?.(node);
47235
47311
  }, [onExpand, expanding]);
47236
- React.useEffect(() => {
47237
- const scrollDiv = containerRef.current;
47238
- if (scrollDiv && onScroll) {
47239
- scrollDiv.addEventListener('scroll', onScroll);
47240
- }
47241
- return () => {
47242
- if (scrollDiv && onScroll) {
47243
- scrollDiv.removeEventListener('scroll', onScroll);
47244
- }
47245
- };
47246
- }, [onScroll]);
47247
47312
  const handleCheckBoxChange = React.useCallback((e, node) => {
47248
47313
  if (expanding) return;
47249
47314
  onChange?.(e, node);
@@ -47252,18 +47317,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47252
47317
  if (expanding) return;
47253
47318
  onClick?.(e, node);
47254
47319
  }, [onClick, expanding]);
47255
- React.useEffect(() => {
47256
- console.log(`Navigating to tree nodeFromUseEffect: ${navigateTreeNode}`);
47257
- if (navigateTreeNode) {
47258
- const node = document.getElementById(navigateTreeNode);
47259
- if (node) {
47260
- node.scrollIntoView({
47261
- behavior: 'smooth',
47262
- block: 'nearest'
47263
- });
47264
- }
47265
- }
47266
- }, [navigateTreeNode]);
47267
47320
  const DEFAULT_COLUMN_WIDTH = 400;
47268
47321
  const calculateFrozenWidth = (columnData, freezeColumns) => {
47269
47322
  return columnData.slice(0, freezeColumns).reduce((acc, col) => acc + parseInt(col.width || `${DEFAULT_COLUMN_WIDTH}`, 10), 0);
@@ -47278,7 +47331,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47278
47331
  children: jsxRuntime.jsx("div", {
47279
47332
  className: `table-scrollable ${treeData.length ? '' : 'table-empty'}`,
47280
47333
  ref: containerRef,
47281
- id: "ff-table-tree-scroll-container",
47282
47334
  style: {
47283
47335
  '--table-height': treeData.length ? height : 'auto',
47284
47336
  '--frozen-column-width': freezeColumns ? `${frozenWidth}px` : '0px',