@inceptionbg/iui 2.0.16 → 2.0.17

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 (61) hide show
  1. package/dist/index.d.ts +155 -89
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/iui.css +1 -1
  5. package/package.json +3 -5
  6. package/src/assets/icons/duotone/faBell.ts +17 -0
  7. package/src/assets/icons/duotone/faPen.ts +18 -0
  8. package/src/assets/icons/duotone/faTrashCan.ts +18 -0
  9. package/src/assets/icons/light/faBell.ts +15 -0
  10. package/src/assets/icons/light/faEnvelope.ts +15 -0
  11. package/src/assets/icons/regular/faEllipsisVertical.ts +15 -0
  12. package/src/assets/icons/solid/faEnvelopeDot.ts +15 -0
  13. package/src/components/Button/SplitButton.tsx +5 -5
  14. package/src/components/Header/Components/ModuleSelect.tsx +5 -5
  15. package/src/components/Header/Components/Notifications.tsx +208 -0
  16. package/src/components/Header/Header.tsx +5 -4
  17. package/src/components/Inputs/NumberInput.tsx +3 -0
  18. package/src/components/Inputs/Selects/components/SelectWrapper.tsx +48 -29
  19. package/src/components/Loader/ProgressBar.tsx +1 -1
  20. package/src/components/Pullover/Pullover.tsx +12 -7
  21. package/src/components/Table/Table.tsx +5 -3
  22. package/src/components/Table/components/columns/TableColumnsEdit.tsx +5 -9
  23. package/src/components/Table/components/edit/TableEditRow.tsx +23 -12
  24. package/src/components/Table/components/header/TableHeaderRow.tsx +1 -0
  25. package/src/components/Table/components/items/TableItemActions.tsx +18 -13
  26. package/src/components/Table/components/print/TablePrint.tsx +1 -5
  27. package/src/components/Table/components/templates/CreateTemplateDialog.tsx +48 -0
  28. package/src/components/Table/components/templates/TableTemplates.tsx +24 -4
  29. package/src/components/Table/contexts/TableContext.tsx +33 -24
  30. package/src/components/Table/hooks/localHooks/useLocalTableColumns.tsx +6 -4
  31. package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +17 -11
  32. package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +8 -6
  33. package/src/components/Table/hooks/useTableColumns.ts +1 -3
  34. package/src/components/Table/hooks/useTableEdit.tsx +24 -2
  35. package/src/components/Table/hooks/useTablePrint.ts +12 -4
  36. package/src/components/Table/hooks/useTableSelect.ts +1 -1
  37. package/src/components/Tooltip/Tooltip.tsx +81 -14
  38. package/src/hooks/useIsMenuOpen.ts +3 -3
  39. package/src/hooks/usePopupControl.ts +9 -4
  40. package/src/index.ts +23 -4
  41. package/src/styles/App.scss +1 -0
  42. package/src/styles/components/_badge.scss +7 -0
  43. package/src/styles/components/_header.scss +14 -1
  44. package/src/styles/components/_notifications.scss +71 -0
  45. package/src/styles/components/_page.scss +1 -0
  46. package/src/styles/components/_pullover.scss +1 -1
  47. package/src/styles/components/_sidebar.scss +1 -3
  48. package/src/styles/components/_table.scss +96 -54
  49. package/src/types/IKeyboard.ts +0 -5
  50. package/src/types/IMenu.ts +2 -2
  51. package/src/types/INotifications.ts +15 -0
  52. package/src/types/IPopup.ts +2 -2
  53. package/src/types/ITable.ts +35 -32
  54. package/src/utils/i18n/i18nIUICyrilic.ts +12 -0
  55. package/src/utils/i18n/i18nIUILatin.ts +13 -0
  56. package/src/utils/i18n/i18nIUIMe.ts +12 -0
  57. package/src/utils/objectUtils.ts +19 -0
  58. package/src/utils/tableUtils.ts +1 -1
  59. package/idea/Notifications.tsx +0 -245
  60. package/idea/Table/Components/Columns/ColumnsList.tsx +0 -61
  61. package/idea/Table/Components/Columns/SetColumnsList.tsx +0 -113
@@ -0,0 +1,208 @@
1
+ import {
2
+ Dispatch,
3
+ SetStateAction,
4
+ useCallback,
5
+ useEffect,
6
+ useState,
7
+ type FC,
8
+ } from 'react';
9
+ import { INotification } from '../../../types/INotifications';
10
+ import { Menu } from '../../Menu/Menu';
11
+ import { useIsMenuOpen } from '../../../hooks/useIsMenuOpen';
12
+ import { IconButton } from '../../Button/IconButton';
13
+ import { NotificationBadge } from '../../Badge/NotificationBadge';
14
+ import { faBell } from '../../../assets/icons/duotone/faBell';
15
+ import { faBell as faBellLight } from '../../../assets/icons/light/faBell';
16
+ import { Trans, useTranslation } from 'react-i18next';
17
+ import { Link } from 'react-router';
18
+ import clsx from 'clsx';
19
+ import { formatDateAndTime } from '../../../utils/dateUtils';
20
+ import { faEnvelope } from '../../../assets/icons/light/faEnvelope';
21
+ import { faEnvelopeDot } from '../../../assets/icons/solid/faEnvelopeDot';
22
+ import { SearchInput } from '../../Inputs/SearchInput';
23
+ import { Loader } from '../../Loader/Loader';
24
+ import { ISelectData } from '../../../types/ISelect';
25
+ import { faEllipsisVertical } from '../../../assets/icons';
26
+ import { getNotificationValues } from '../../../utils/objectUtils';
27
+
28
+ export interface INotificationsProps {
29
+ notificationCount: number;
30
+ notifications: INotification[];
31
+ isLoading: boolean;
32
+ menuControl: { isOpen: boolean; onClose: () => void; onOpen: () => void };
33
+ seen: boolean | null;
34
+ setSeen: Dispatch<SetStateAction<boolean | null>>;
35
+ markAsSeen: (uuid: string) => void;
36
+ markAllAsSeen: () => void;
37
+ }
38
+
39
+ export const Notifications: FC<INotificationsProps> = ({
40
+ notificationCount,
41
+ notifications = [],
42
+ isLoading,
43
+ menuControl,
44
+ seen,
45
+ setSeen,
46
+ markAsSeen,
47
+ markAllAsSeen,
48
+ }) => {
49
+ const { t } = useTranslation();
50
+ const { isOpen, onClose, onOpen } = menuControl;
51
+ const {
52
+ isOpen: isOpenOptions,
53
+ onClose: onCloseOptions,
54
+ onOpen: onOpenOptions,
55
+ } = useIsMenuOpen();
56
+
57
+ const seenOptions: ISelectData[] = [
58
+ { label: t('NotificationsAll'), value: null },
59
+ { label: t('NotificationsUnread'), value: false },
60
+ { label: t('NotificationsRead'), value: true },
61
+ ];
62
+
63
+ const [filteredNotifications, setFilteredNotifications] = useState<INotification[]>([]);
64
+
65
+ useEffect(() => {
66
+ setFilteredNotifications(notifications);
67
+ }, [notifications]);
68
+
69
+ const onSearch = useCallback(
70
+ (e: string) =>
71
+ setFilteredNotifications(
72
+ !e
73
+ ? notifications
74
+ : notifications.filter(notification => {
75
+ const title = t(`NTitle${notification.event}`);
76
+ const description = t(`NContent${notification.event}`, {
77
+ ...getNotificationValues(t, notification.values),
78
+ });
79
+
80
+ const searchContent = `${title} ${description}`.toLowerCase();
81
+ const searchWords = e.toLowerCase().trim().split(/\s+/);
82
+
83
+ return searchWords.every(word => searchContent.includes(word));
84
+ })
85
+ ),
86
+ [notifications, t]
87
+ );
88
+
89
+ return (
90
+ <Menu
91
+ isOpen={isOpen}
92
+ onClose={onClose}
93
+ placement="bottom-right"
94
+ size="m"
95
+ className="header-user-menu"
96
+ renderButton={ref => (
97
+ <NotificationBadge
98
+ number={notificationCount}
99
+ className="header-btn-badge"
100
+ size="s"
101
+ >
102
+ <IconButton
103
+ ref={ref}
104
+ icon={!!notificationCount ? faBell : faBellLight}
105
+ onClick={onOpen}
106
+ className="header-button notification-button"
107
+ active={isOpen}
108
+ variant="solid"
109
+ />
110
+ </NotificationBadge>
111
+ )}
112
+ >
113
+ <div className="notifications">
114
+ <div className="notifications-content-header">
115
+ <h3>{t('Notifications')}</h3>
116
+ <SearchInput onSearch={onSearch} />
117
+ </div>
118
+ <div className="notifications-options">
119
+ <div className="flex gap-2">
120
+ {seenOptions.map(({ label, value }) => (
121
+ <div
122
+ key={label}
123
+ className={clsx('link fs-13', {
124
+ inactive: seen !== value,
125
+ })}
126
+ onClick={() => setSeen(value)}
127
+ >
128
+ {label}
129
+ </div>
130
+ ))}
131
+ </div>
132
+ <Menu
133
+ isOpen={isOpenOptions}
134
+ onClose={onCloseOptions}
135
+ placement="bottom-right"
136
+ size="m"
137
+ renderButton={ref => (
138
+ <IconButton
139
+ ref={ref}
140
+ icon={faEllipsisVertical}
141
+ onClick={onOpenOptions}
142
+ className="header-button notification-button"
143
+ active={isOpenOptions}
144
+ size="s"
145
+ />
146
+ )}
147
+ items={[{ label: t('MarkAllAsRead'), onClick: markAllAsSeen }]}
148
+ />
149
+ </div>
150
+ <Loader isLoading={isLoading}>
151
+ <div className="notifications-container">
152
+ {!!filteredNotifications.length ? (
153
+ filteredNotifications.map(notification => (
154
+ <div
155
+ key={notification.uuid}
156
+ className={clsx('notification', { seen: notification.seen })}
157
+ >
158
+ <div className="notification-header">
159
+ <div>
160
+ <p className="title">{t(`NTitle${notification.event}`)}</p>
161
+ <p className="date">{formatDateAndTime(notification.createdAt)}</p>
162
+ </div>
163
+ <IconButton
164
+ // tooltip={t('MarkAsRead')}
165
+ icon={notification.seen ? faEnvelope : faEnvelopeDot}
166
+ disabled={notification.seen}
167
+ onClick={() => markAsSeen(notification.uuid)}
168
+ size="s"
169
+ />
170
+ </div>
171
+ <p className="desc">
172
+ <Trans
173
+ i18nKey={`NContent${notification.event}`}
174
+ values={getNotificationValues(t, notification.values)}
175
+ t={t}
176
+ components={notification.values?.reduce(
177
+ (obj, e) =>
178
+ e.url
179
+ ? {
180
+ ...obj,
181
+ [e.key]: (
182
+ <Link
183
+ to={e.url}
184
+ className="link"
185
+ onClick={() =>
186
+ !notification.seen && markAsSeen(notification.uuid)
187
+ }
188
+ />
189
+ ),
190
+ }
191
+ : obj,
192
+ {
193
+ bold: <span className="bold" />,
194
+ }
195
+ )}
196
+ />
197
+ </p>
198
+ </div>
199
+ ))
200
+ ) : (
201
+ <p className="text-center fs-13 pt-2">{t('NoNewNotifications')}</p>
202
+ )}
203
+ </div>
204
+ </Loader>
205
+ </div>
206
+ </Menu>
207
+ );
208
+ };
@@ -2,14 +2,14 @@ import { ComponentProps, FC, ReactNode } from 'react';
2
2
  import { UserMenu } from './Components/UserMenu';
3
3
  import { ModuleSelect } from './Components/ModuleSelect';
4
4
  import { IHeaderUserMenuProps } from '../../types/IHeader';
5
+ import { INotificationsProps, Notifications } from './Components/Notifications';
5
6
 
6
7
  interface Props {
7
8
  customTitle?: string;
8
9
  modulesProps?: ComponentProps<typeof ModuleSelect>;
9
- // actions: {
10
- // icon: IconDefinition;
11
- // };
10
+ // actions: { icon: IconDefinition };
12
11
  userMenuProps: IHeaderUserMenuProps;
12
+ notificationsProps?: INotificationsProps;
13
13
  children?: ReactNode;
14
14
  }
15
15
 
@@ -17,6 +17,7 @@ export const Header: FC<Props> = ({
17
17
  customTitle,
18
18
  modulesProps,
19
19
  userMenuProps,
20
+ notificationsProps,
20
21
  children,
21
22
  }) => (
22
23
  <div className="iui-header">
@@ -24,7 +25,7 @@ export const Header: FC<Props> = ({
24
25
  {customTitle && <h3 className="ml-3">{customTitle}</h3>}
25
26
  <div className="flex gap-2 align-center">
26
27
  {children}
27
- {/* {!hideNotifications && <Notifications />} */}
28
+ {notificationsProps && <Notifications {...notificationsProps} />}
28
29
  <UserMenu {...userMenuProps} />
29
30
  </div>
30
31
  </div>
@@ -11,6 +11,7 @@ export interface INumberInputProps {
11
11
  placeholder?: string;
12
12
  endText?: string;
13
13
  isClearable?: boolean;
14
+ onClear?: () => void;
14
15
  helperText?: string;
15
16
  errorText?: string;
16
17
  error?: boolean;
@@ -32,6 +33,7 @@ export const NumberInput: FC<INumberInputProps> = ({
32
33
  placeholder,
33
34
  endText,
34
35
  isClearable,
36
+ onClear,
35
37
  helperText,
36
38
  errorText,
37
39
  error,
@@ -64,6 +66,7 @@ export const NumberInput: FC<INumberInputProps> = ({
64
66
  disabled={disabled}
65
67
  endText={endText}
66
68
  isClearable={isClearable}
69
+ onClear={onClear}
67
70
  placeholder={
68
71
  placeholder ? placeholder : decimalPlaces ? `0.${'0'.repeat(decimalPlaces)}` : '0'
69
72
  }
@@ -68,34 +68,34 @@ export const SelectWrapper = forwardRef<any, ISelectProps>((props, forwardedRef)
68
68
  formatOptionLabel,
69
69
  };
70
70
 
71
- const renderSelect = () => {
72
- switch (variant) {
73
- case 'basic':
74
- return <ReactSelect {...commonProps} options={props.options} />;
75
- case 'async':
76
- return (
77
- <AsyncPaginate
78
- {...commonProps}
79
- loadOptions={props.loadOptions}
80
- defaultOptions={props.defaultData ?? true}
81
- />
82
- );
83
- case 'async-creatable':
84
- return (
85
- <AsyncCreatableSelect
86
- {...commonProps}
87
- loadOptions={props.loadOptions}
88
- defaultOptions={props.defaultData ?? true}
89
- onCreateOption={props.onCreate}
90
- formatCreateLabel={(inputValue: string) => (
91
- <p>{`${t('FreeText')} "${inputValue}"`}</p>
92
- )}
93
- />
94
- );
95
- default:
96
- return null;
97
- }
98
- };
71
+ // const renderSelect = () => {
72
+ // switch (variant) {
73
+ // case 'basic':
74
+ // return <ReactSelect {...commonProps} options={props.options} />;
75
+ // case 'async':
76
+ // return (
77
+ // <AsyncPaginate
78
+ // {...commonProps}
79
+ // loadOptions={props.loadOptions}
80
+ // defaultOptions={props.defaultData ?? true}
81
+ // />
82
+ // );
83
+ // case 'async-creatable':
84
+ // return (
85
+ // <AsyncCreatableSelect
86
+ // {...commonProps}
87
+ // loadOptions={props.loadOptions}
88
+ // defaultOptions={props.defaultData ?? true}
89
+ // onCreateOption={props.onCreate}
90
+ // formatCreateLabel={(inputValue: string) => (
91
+ // <p>{`${t('FreeText')} "${inputValue}"`}</p>
92
+ // )}
93
+ // />
94
+ // );
95
+ // default:
96
+ // return null;
97
+ // }
98
+ // };
99
99
 
100
100
  return (
101
101
  <InputWrapper
@@ -109,7 +109,26 @@ export const SelectWrapper = forwardRef<any, ISelectProps>((props, forwardedRef)
109
109
  minWidth={minWidth}
110
110
  heightAuto
111
111
  >
112
- {renderSelect()}
112
+ {/* {renderSelect()} */}
113
+ {variant === 'async' ? (
114
+ <AsyncPaginate
115
+ {...commonProps}
116
+ loadOptions={props.loadOptions}
117
+ defaultOptions={props.defaultData ?? true}
118
+ />
119
+ ) : variant === 'async-creatable' ? (
120
+ <AsyncCreatableSelect
121
+ {...commonProps}
122
+ loadOptions={props.loadOptions}
123
+ defaultOptions={props.defaultData ?? true}
124
+ onCreateOption={props.onCreate}
125
+ formatCreateLabel={(inputValue: string) => (
126
+ <p>{`${t('FreeText')} "${inputValue}"`}</p>
127
+ )}
128
+ />
129
+ ) : (
130
+ <ReactSelect {...commonProps} options={props.options} />
131
+ )}
113
132
  {required && !disabled && (
114
133
  <input
115
134
  className="fake-input"
@@ -27,7 +27,7 @@ export const ProgressBar: FC<Props> = ({ progress, label }) => {
27
27
  {
28
28
  '--progress-clip': `${now}%`,
29
29
  '--progress-text': `'${now}%'`,
30
- } as CSSProperties
30
+ } as CSSProperties & { [key: string]: string }
31
31
  }
32
32
  >
33
33
  <div
@@ -13,6 +13,8 @@ import { onPopupKeyDown } from '../../utils/popupUtils';
13
13
  import { ILocalPopupControl } from '../../types/IPopup';
14
14
  import { Loader } from '../Loader/Loader';
15
15
  import { SplitButton } from '../Button/SplitButton';
16
+ import { IconButton } from '../Button/IconButton';
17
+ import { faXmark } from '../../assets/icons';
16
18
 
17
19
  interface Props {
18
20
  id?: string;
@@ -108,13 +110,16 @@ export const Pullover: FC<Props> = ({
108
110
  {header && (
109
111
  <div className="pullover-header no-print">
110
112
  <h3>{header.title}</h3>
111
- {header.onSearch && (
112
- <SearchInput
113
- ref={searchRef}
114
- onSearch={header.onSearch}
115
- className="search-input"
116
- />
117
- )}
113
+ <div className="flex gap-2">
114
+ {header.onSearch && (
115
+ <SearchInput
116
+ ref={searchRef}
117
+ onSearch={header.onSearch}
118
+ className="search-input"
119
+ />
120
+ )}
121
+ <IconButton icon={faXmark} onClick={onClose} color="neutral" />
122
+ </div>
118
123
  </div>
119
124
  )}
120
125
  <ConditionalWrapper
@@ -155,8 +155,9 @@ export const TableContent: FC = () => {
155
155
  cell?.className,
156
156
  rowHeight,
157
157
  {
158
+ 'sticky-column': column.sticky,
158
159
  link: cell?.link,
159
- 'clickable-column': cell?.onClick,
160
+ 'clickable-cell': cell?.onClick,
160
161
  'word-break': column.break,
161
162
  }
162
163
  )}
@@ -249,8 +250,9 @@ export const TableContent: FC = () => {
249
250
  );
250
251
  };
251
252
 
252
- export const Table: FC<ITable> = props => (
253
- <TableProvider {...props}>
253
+ export const Table = <T,>(props: ITable<T>) => (
254
+ <TableProvider<T> {...props}>
254
255
  <TableContent />
256
+ {props.itemDeleteData?.DeleteDialog}
255
257
  </TableProvider>
256
258
  );
@@ -20,7 +20,7 @@ export const TableColumnsEdit: FC = () => {
20
20
 
21
21
  const { t } = useTranslation();
22
22
  const {
23
- columnData: { defaultColumns, setColumns },
23
+ columnData: { columns, setColumns },
24
24
  } = useTableContext();
25
25
  const { control, onClose, onOpen } = usePopupControl();
26
26
 
@@ -28,13 +28,13 @@ export const TableColumnsEdit: FC = () => {
28
28
  if (control.isOpen) {
29
29
  let hiddenCols: ITableColumn[] = [];
30
30
  let visibleCols: ITableColumn[] = [];
31
- defaultColumns.forEach(col =>
31
+ columns.forEach(col =>
32
32
  !!col.hidden ? hiddenCols.push(col) : visibleCols.push(col)
33
33
  );
34
34
  setHidden(hiddenCols);
35
35
  setVisible(visibleCols);
36
36
  }
37
- }, [control.isOpen, defaultColumns]);
37
+ }, [control.isOpen, columns]);
38
38
 
39
39
  const onDragEnd = ({ source, destination }: DropResult) => {
40
40
  if (!destination) return;
@@ -79,6 +79,7 @@ export const TableColumnsEdit: FC = () => {
79
79
  <Pullover
80
80
  control={control}
81
81
  header={{ title: t('Columns') }}
82
+ className="column-pullover"
82
83
  footer={{
83
84
  confirmButton: {
84
85
  label: t('Confirm'),
@@ -93,19 +94,14 @@ export const TableColumnsEdit: FC = () => {
93
94
  <div />
94
95
  <p className="bold ml-2">{t('SelectedColumns')}:</p>
95
96
 
96
- {/* {withSearch && (
97
- <> */}
98
97
  <SearchInput onSearch={setSearchHidden} />
99
98
  <div />
100
99
  <SearchInput onSearch={setSearchVisible} />
101
- {/* </>
102
- )} */}
103
- <ColumnsList id="hidden" items={hidden} search={searchHidden} />
104
100
 
101
+ <ColumnsList id="hidden" items={hidden} search={searchHidden} />
105
102
  <div className="exchange-icon">
106
103
  <FontAwesomeIcon icon={faArrowRightArrowLeft} />
107
104
  </div>
108
-
109
105
  <ColumnsList id="visible" items={visible} search={searchVisible} />
110
106
  </div>
111
107
  </div>
@@ -4,6 +4,7 @@ import { IconButton } from '../../../Button/IconButton';
4
4
  import { faCheck, faXmark } from '../../../../assets/icons';
5
5
  import { useTableContext } from '../../contexts/TableContext';
6
6
  import { useGetFocusableElements } from '../../../../hooks/useGetFocusableElements';
7
+ import clsx from 'clsx';
7
8
 
8
9
  export const TableEditRow: FC<{ columns: ITableColumn[] }> = ({ columns }) => {
9
10
  const { editable } = useTableContext();
@@ -20,7 +21,9 @@ export const TableEditRow: FC<{ columns: ITableColumn[] }> = ({ columns }) => {
20
21
  }, [focusableElements]);
21
22
 
22
23
  useEffect(() => {
23
- editable!.setEditData(editable!.selectedItem ?? editable!.defaultDataValue ?? {});
24
+ editable!.setEditData(
25
+ editable!.selectedItem?.item ?? editable!.defaultDataValue ?? {}
26
+ );
24
27
  // eslint-disable-next-line
25
28
  }, [editable?.setEditData, editable?.selectedItem, editable?.defaultDataValue]);
26
29
 
@@ -47,20 +50,28 @@ export const TableEditRow: FC<{ columns: ITableColumn[] }> = ({ columns }) => {
47
50
  },
48
51
  };
49
52
 
50
- const rowData: ITableDataItem = { uuid: editable?.selectedItem?.uuid, cells: rowCells };
53
+ const rowData: ITableDataItem = {
54
+ uuid: editable?.selectedItem?.uuid as string,
55
+ cells: rowCells,
56
+ };
51
57
 
52
58
  return (
53
59
  <tr ref={elementRef} data-id={rowData.uuid} className="edit-row">
54
- {columns.map(column => (
55
- <td
56
- key={column.id}
57
- align={column.align}
58
- colSpan={rowData.cells[column.id]?.span}
59
- className={rowData.cells[column.id]?.className}
60
- >
61
- {rowData.cells[column.id]?.value ?? ''}
62
- </td>
63
- ))}
60
+ {columns.map(column => {
61
+ const item = rowData.cells[column.id];
62
+ return (
63
+ <td
64
+ key={column.id}
65
+ align={column.align}
66
+ colSpan={item?.span}
67
+ className={clsx(item?.className, {
68
+ editable: typeof item?.value === 'object',
69
+ })}
70
+ >
71
+ {item?.value ?? ''}
72
+ </td>
73
+ );
74
+ })}
64
75
  </tr>
65
76
  );
66
77
  };
@@ -23,6 +23,7 @@ export const TableHeaderRow: FC<Props> = ({ row, print }) => {
23
23
  print
24
24
  ? undefined
25
25
  : clsx(col.color, col.className, {
26
+ 'sticky-column': col.sticky,
26
27
  'not-first-cell': col.notFirstCell,
27
28
  })
28
29
  }
@@ -2,16 +2,20 @@ import { type FC } from 'react';
2
2
  import { useTableContext } from '../../contexts/TableContext';
3
3
  import { IconButton } from '../../../Button/IconButton';
4
4
  import { faEllipsisVertical, faPen, faTrashCan } from '../../../../assets/icons';
5
+ // TO CONSIDER
6
+ // import { faPen } from '../../../../assets/icons/duotone/faPen';
7
+ // import { faTrashCan } from '../../../../assets/icons/duotone/faTrashCan';
8
+ // import { faEllipsisVertical } from '../../../../assets/icons/regular/faEllipsisVertical';
5
9
  import { useIsMenuOpen } from '../../../../hooks/useIsMenuOpen';
6
10
  import { Menu } from '../../../Menu/Menu';
7
11
  import { ITableDataItem } from '../../../../types/ITable';
8
12
 
9
- export const TableItemActions: FC<{ tableDataItem: ITableDataItem }> = ({
13
+ export const TableItemActions: FC<{ tableDataItem: ITableDataItem<any> }> = ({
10
14
  tableDataItem,
11
15
  }) => {
12
- const { isMenuOpen, onMenuClose, onMenuOpen } = useIsMenuOpen();
16
+ const { isOpen, onClose, onOpen } = useIsMenuOpen();
13
17
 
14
- const { dataActions, editable } = useTableContext();
18
+ const { dataActions, itemDeleteData, editable } = useTableContext();
15
19
 
16
20
  if (!dataActions?.hasItemActions) {
17
21
  return null;
@@ -24,7 +28,7 @@ export const TableItemActions: FC<{ tableDataItem: ITableDataItem }> = ({
24
28
  icon={faPen}
25
29
  onClick={e => {
26
30
  e.stopPropagation();
27
- editable?.setSelectedItem(tableDataItem.item ?? null);
31
+ editable?.setSelectedItem(tableDataItem);
28
32
  }}
29
33
  size="s"
30
34
  />
@@ -34,37 +38,38 @@ export const TableItemActions: FC<{ tableDataItem: ITableDataItem }> = ({
34
38
  icon={faTrashCan}
35
39
  onClick={e => {
36
40
  e.stopPropagation();
37
- dataActions.delete?.onClick?.(tableDataItem.uuid);
41
+ itemDeleteData?.setItemToDeleteUuids([tableDataItem.uuid]);
38
42
  }}
39
43
  size="s"
40
44
  color="danger"
41
45
  />
42
46
  )}
43
47
 
44
- {!!dataActions.actions?.length && (
48
+ {!!dataActions.filteredActions?.length && (
45
49
  <Menu
46
- isOpen={isMenuOpen}
47
- onClose={onMenuClose}
50
+ isOpen={isOpen}
51
+ onClose={onClose}
48
52
  placement="bottom-right"
49
53
  renderButton={ref => (
50
54
  <IconButton
51
55
  ref={ref}
52
56
  icon={faEllipsisVertical}
53
- active={isMenuOpen}
57
+ active={isOpen}
54
58
  onClick={e => {
55
59
  e.stopPropagation();
56
- onMenuOpen();
60
+ onOpen();
57
61
  }}
58
62
  size="s"
59
63
  />
60
64
  )}
61
65
  items={
62
- dataActions.actions?.map(action => ({
66
+ dataActions.actions?.(tableDataItem.item)?.map(action => ({
63
67
  label: action.label,
64
68
  hidden: !action.hasAccess,
69
+ disabled: action.disabled,
65
70
  onClick: () => {
66
- action.onClick(tableDataItem);
67
- onMenuClose();
71
+ action.onClick();
72
+ onClose();
68
73
  },
69
74
  })) ?? []
70
75
  }
@@ -28,7 +28,6 @@ export const TablePrint: FC = () => {
28
28
  paginationControl,
29
29
  printPopupControl,
30
30
  customHeader,
31
- excludeColumnIds,
32
31
  filters,
33
32
  optionalNode,
34
33
  organization,
@@ -37,10 +36,7 @@ export const TablePrint: FC = () => {
37
36
  } = useMemo(() => (printData ?? {}) as IPrintData, [printData]);
38
37
  const { control, onOpen } = printPopupControl;
39
38
 
40
- const cols = useMemo(
41
- () => columns.filter(e => !['actions', 'select', excludeColumnIds].includes(e.id)),
42
- [columns, excludeColumnIds]
43
- );
39
+ const cols = useMemo(() => columns.filter(e => !e.hidden && !e.printHidden), [columns]);
44
40
 
45
41
  useEffect(() => {
46
42
  if (control.isOpen) {