@inceptionbg/iui 2.0.17 → 2.0.20

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 (35) hide show
  1. package/dist/index.d.ts +16 -7
  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 +2 -1
  6. package/src/components/Accordions/Accordions.tsx +35 -27
  7. package/src/components/Dialog/Dialog.tsx +27 -25
  8. package/src/components/Header/Components/EnvBadge.tsx +17 -0
  9. package/src/components/Header/Header.tsx +7 -3
  10. package/src/components/Inputs/Selects/components/SelectWrapper.tsx +4 -33
  11. package/src/components/Pullover/Pullover.tsx +32 -26
  12. package/src/components/Table/components/items/TableItemActions.tsx +5 -7
  13. package/src/components/Table/contexts/TableContext.tsx +8 -5
  14. package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +1 -1
  15. package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +3 -1
  16. package/src/components/Table/hooks/useTableEdit.tsx +9 -2
  17. package/src/components/Table/hooks/useTableSearch.ts +2 -1
  18. package/src/components/Tabs/Tabs.tsx +3 -3
  19. package/src/components/Tooltip/Tooltip.tsx +14 -81
  20. package/src/index.ts +2 -0
  21. package/src/styles/common/_typography.scss +2 -2
  22. package/src/styles/components/_accordions.scss +1 -0
  23. package/src/styles/components/_dialog.scss +25 -19
  24. package/src/styles/components/_header.scss +5 -0
  25. package/src/styles/components/_table.scss +1 -1
  26. package/src/styles/components/_tabs.scss +1 -1
  27. package/src/types/ISelect.ts +1 -0
  28. package/src/types/ITable.ts +1 -1
  29. package/src/utils/InputPatternValidation.ts +2 -2
  30. package/src/utils/objectUtils.ts +15 -5
  31. package/src/assets/icons/duotone/faPen.ts +0 -18
  32. package/src/assets/icons/duotone/faTrashCan.ts +0 -18
  33. package/src/assets/icons/regular/faEllipsisVertical.ts +0 -15
  34. package/src/components/Inputs/Select2/Select.tsx +0 -258
  35. package/src/components/Inputs/Select2/select.scss +0 -42
@@ -2,10 +2,6 @@ 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';
9
5
  import { useIsMenuOpen } from '../../../../hooks/useIsMenuOpen';
10
6
  import { Menu } from '../../../Menu/Menu';
11
7
  import { ITableDataItem } from '../../../../types/ITable';
@@ -21,6 +17,9 @@ export const TableItemActions: FC<{ tableDataItem: ITableDataItem<any> }> = ({
21
17
  return null;
22
18
  }
23
19
 
20
+ const filteredActions =
21
+ dataActions.actions?.(tableDataItem.item).filter(e => e.hasAccess) ?? [];
22
+
24
23
  return (
25
24
  <div className="table-item-actions">
26
25
  {dataActions.isEditable && (
@@ -44,8 +43,7 @@ export const TableItemActions: FC<{ tableDataItem: ITableDataItem<any> }> = ({
44
43
  color="danger"
45
44
  />
46
45
  )}
47
-
48
- {!!dataActions.filteredActions?.length && (
46
+ {!!filteredActions?.length && (
49
47
  <Menu
50
48
  isOpen={isOpen}
51
49
  onClose={onClose}
@@ -63,7 +61,7 @@ export const TableItemActions: FC<{ tableDataItem: ITableDataItem<any> }> = ({
63
61
  />
64
62
  )}
65
63
  items={
66
- dataActions.actions?.(tableDataItem.item)?.map(action => ({
64
+ filteredActions?.map(action => ({
67
65
  label: action.label,
68
66
  hidden: !action.hasAccess,
69
67
  disabled: action.disabled,
@@ -26,7 +26,6 @@ interface ITableContext<T = unknown> extends ITable<T> {
26
26
  hasItemActions: boolean;
27
27
  isEditable: boolean;
28
28
  isDeletable: boolean;
29
- filteredActions: ITableSelectedAction[];
30
29
  };
31
30
  editable?: ITableEdit<T> & {
32
31
  isAdding: boolean;
@@ -71,16 +70,20 @@ export const TableProvider = <T,>({
71
70
  const updatedDataActions = useMemo(() => {
72
71
  const isEditable = Boolean(dataActions?.hasEditAccess);
73
72
  const isDeletable = Boolean(rest.itemDeleteData?.hasAccess);
74
- const filteredActions = dataActions?.actions?.().filter(e => e.hasAccess) ?? [];
73
+
74
+ const hasCustomActions = initialData.some(({ item }) => {
75
+ const actions = dataActions?.actions?.(item).filter(e => e.hasAccess) ?? [];
76
+ return actions.length > 0;
77
+ });
78
+
75
79
  return {
76
80
  hasEditAccess: isEditable,
77
81
  actions: dataActions?.actions,
78
- filteredActions,
79
- hasItemActions: isEditable || isDeletable || filteredActions.length > 0,
82
+ hasItemActions: isEditable || isDeletable || hasCustomActions,
80
83
  isEditable,
81
84
  isDeletable,
82
85
  };
83
- }, [dataActions, rest.itemDeleteData?.hasAccess]);
86
+ }, [dataActions, initialData, rest.itemDeleteData?.hasAccess]);
84
87
 
85
88
  const localPagination = useLocalTablePagination({
86
89
  defaultLimit: footer?.customPagination?.defaultLimit,
@@ -36,7 +36,7 @@ export const useLocalTableData = <T,>({
36
36
  localPagination.offset * localPagination.limit + localPagination.limit
37
37
  );
38
38
 
39
- const additionalDataActions = dataActions?.actions?.().filter(e => e.hasAccess) ?? [];
39
+ const additionalDataActions = dataActions?.actions?.() ?? [];
40
40
  const withActions = Boolean(
41
41
  dataActions?.hasEditAccess || isDeletable || additionalDataActions.length
42
42
  );
@@ -117,7 +117,8 @@ export const useLocalTableKeyboard = () => {
117
117
  },
118
118
  {
119
119
  code: 'Space',
120
- disabled: !dataActions?.hasItemActions && !!focusedRow?.uuid,
120
+ disabled:
121
+ !dataActions?.hasItemActions || !focusedRow?.uuid || isEditing || isAdding,
121
122
  onAction: () => {
122
123
  const rowUuid = focusedRow?.uuid!;
123
124
  const isRowSelected = rowSelect?.selectedRows.has(rowUuid);
@@ -138,6 +139,7 @@ export const useLocalTableKeyboard = () => {
138
139
  ) {
139
140
  event.preventDefault();
140
141
  event.stopPropagation();
142
+ console.log(action);
141
143
  if (
142
144
  action.onBulkAction &&
143
145
  dataActions?.hasItemActions &&
@@ -11,9 +11,11 @@ interface BaseItemProps<T> {
11
11
  placeholder?: string;
12
12
  required?: boolean;
13
13
  additionalClearIds?: (keyof T)[];
14
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
14
15
  }
15
16
  interface SelectProps<T> extends BaseItemProps<T> {
16
17
  options: readonly (string | boolean)[] | (string | boolean)[];
18
+ minWidth?: number;
17
19
  formatOption: (value: string | boolean) => {
18
20
  value: string | boolean;
19
21
  label: string;
@@ -30,6 +32,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
30
32
  required,
31
33
  id,
32
34
  additionalClearIds = [],
35
+ inputProps,
33
36
  }: BaseItemProps<T>) => ({
34
37
  value: (
35
38
  <TextInput
@@ -39,6 +42,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
39
42
  setValue={e =>
40
43
  setEditData(e ? { ...editData, [id]: e } : deleteProps(editData as T, [id]))
41
44
  }
45
+ inputProps={inputProps}
42
46
  onClear={() => deleteProps(editData as T, [id, ...additionalClearIds])}
43
47
  />
44
48
  ),
@@ -50,6 +54,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
50
54
  required,
51
55
  id,
52
56
  additionalClearIds = [],
57
+ inputProps,
53
58
  }: BaseItemProps<T>) => ({
54
59
  value: (
55
60
  <NumberInput
@@ -59,6 +64,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
59
64
  setValue={e =>
60
65
  setEditData(e ? { ...editData, [id]: e } : deleteProps(editData as T, [id]))
61
66
  }
67
+ inputProps={inputProps}
62
68
  onClear={() => deleteProps(editData as T, [id, ...additionalClearIds])}
63
69
  />
64
70
  ),
@@ -69,7 +75,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
69
75
  id,
70
76
  required,
71
77
  additionalClearIds,
72
- }: Omit<BaseItemProps<T>, 'placeholder'>) => ({
78
+ }: Omit<BaseItemProps<T>, 'placeholder' | 'inputProps'>) => ({
73
79
  value: (
74
80
  <DateInput
75
81
  required={required}
@@ -92,6 +98,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
92
98
  options,
93
99
  formatOption,
94
100
  additionalClearIds = [],
101
+ minWidth = 110,
95
102
  }: SelectProps<T>) => ({
96
103
  value: (
97
104
  <Select
@@ -99,7 +106,7 @@ export const useTableEdit = <T extends Record<string, any>>() => {
99
106
  placeholder={placeholder}
100
107
  value={hasValue(editData[id]) ? formatOption(editData[id]!) : null}
101
108
  options={options.map(formatOption)}
102
- minWidth={150}
109
+ minWidth={minWidth}
103
110
  onChange={e => {
104
111
  e
105
112
  ? setEditData({
@@ -1,4 +1,5 @@
1
1
  import { Dispatch, SetStateAction, useState } from 'react';
2
+ import { deletePropsThatEndsWith } from '../../../utils/objectUtils';
2
3
 
3
4
  export interface ITableSearchProps<T> {
4
5
  setOffset: Dispatch<SetStateAction<number>>;
@@ -17,7 +18,7 @@ export const useTableSearch = <T>({
17
18
  const onSearch = (filters: T) => {
18
19
  setOffset(0);
19
20
  resetSelectedRows?.();
20
- setSearch(filters);
21
+ setSearch(<T>deletePropsThatEndsWith(filters, 'Obj'));
21
22
  };
22
23
 
23
24
  return {
@@ -27,9 +27,9 @@ export const Tabs: FC<Props> = ({
27
27
  }) => {
28
28
  const filteredTabs = useMemo(() => tabs.filter(e => !e.hidden), [tabs]);
29
29
 
30
- const [selected, setSelected] = useState(initialValue || filteredTabs[0].value);
30
+ const [selected, setSelected] = useState(initialValue || filteredTabs[0]?.value || '');
31
31
 
32
- const activeTab = filteredTabs.find(tab => (control?.value || selected) === tab.value);
32
+ const activeTab = filteredTabs.find(tab => (control?.value ?? selected) === tab.value);
33
33
 
34
34
  return filteredTabs.length > 0 ? (
35
35
  <div className={className}>
@@ -39,7 +39,7 @@ export const Tabs: FC<Props> = ({
39
39
  id={tab.value}
40
40
  key={tab.value}
41
41
  className={clsx('iui-tab clickable', {
42
- selected: (control?.value || selected) === tab.value,
42
+ selected: (control?.value ?? selected) === tab.value,
43
43
  disabled: tab.disabled,
44
44
  'no-wrap': noWrap,
45
45
  })}
@@ -103,98 +103,31 @@ const setAbsolutePosition = (
103
103
  ) => {
104
104
  const containerRect = containerEl.getBoundingClientRect();
105
105
  const tooltipRect = targetEl.getBoundingClientRect();
106
- const margin = 16; // Distance from container
107
- const screenPadding = 8; // Minimum distance from screen edges
108
106
 
109
107
  if (position === 'bottom' || position === 'top') {
110
- const bottom = Math.floor(containerRect.bottom + margin);
111
- const top = Math.floor(containerRect.top - tooltipRect.height - margin);
112
- let leftCenter = Math.floor(
108
+ const bottom = Math.floor(containerRect.bottom + 16);
109
+ const top = Math.floor(containerRect.top - tooltipRect.height - 16);
110
+ const leftCenter = Math.floor(
113
111
  containerRect.left + containerRect.width / 2 - tooltipRect.width / 2
114
112
  );
115
-
116
- // Check if tooltip overflows horizontally and adjust
117
- if (leftCenter < screenPadding) {
118
- targetEl.style.width = `${tooltipRect.width + leftCenter}px`;
119
- leftCenter = screenPadding;
120
- } else if (leftCenter + tooltipRect.width > window.innerWidth - screenPadding) {
121
- leftCenter = window.innerWidth - tooltipRect.width - screenPadding;
122
- }
123
-
124
113
  const reverse =
125
114
  position === 'top' ? top < 0 : bottom + tooltipRect.height > window.innerHeight;
126
115
 
127
116
  setNewPosition(reverse ? (position === 'bottom' ? 'top' : 'bottom') : '');
128
117
 
129
- let finalTop =
130
- position === 'bottom' ? (reverse ? top : bottom) : reverse ? bottom : top;
131
-
132
- // Ensure tooltip doesn't go above screen
133
- if (finalTop < screenPadding) {
134
- finalTop = screenPadding;
135
- }
136
- // Ensure tooltip doesn't go below screen
137
- if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
138
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
139
- }
140
-
141
- targetEl.style.top = `${finalTop}px`;
118
+ targetEl.style.top = `${
119
+ position === 'bottom' ? (reverse ? top : bottom) : reverse ? bottom : top
120
+ }px`;
142
121
  targetEl.style.left = `${leftCenter}px`;
143
122
  } else if (position === 'right') {
144
- let finalTop = Math.floor(
145
- containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
146
- );
147
- let finalLeft = Math.floor(containerRect.right + margin);
148
-
149
- // Check if tooltip overflows vertically and adjust
150
- if (finalTop < screenPadding) {
151
- finalTop = screenPadding;
152
- } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
153
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
154
- }
155
-
156
- // Check if tooltip overflows to the right and flip to left
157
- if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
158
- finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
159
- setNewPosition('left');
160
-
161
- // If it still overflows on the left, position it at the edge
162
- if (finalLeft < screenPadding) {
163
- finalLeft = screenPadding;
164
- }
165
- } else {
166
- setNewPosition('');
167
- }
168
-
169
- targetEl.style.top = `${finalTop}px`;
170
- targetEl.style.left = `${finalLeft}px`;
123
+ targetEl.style.top =
124
+ Math.floor(containerRect.top + containerRect.height / 2 - tooltipRect.height / 2) +
125
+ 'px';
126
+ targetEl.style.left = Math.floor(containerRect.right + 16) + 'px';
171
127
  } else if (position === 'left') {
172
- let finalTop = Math.floor(
173
- containerRect.top + containerRect.height / 2 - tooltipRect.height / 2
174
- );
175
- let finalLeft = Math.floor(containerRect.left - tooltipRect.width - margin);
176
-
177
- // Check if tooltip overflows vertically and adjust
178
- if (finalTop < screenPadding) {
179
- finalTop = screenPadding;
180
- } else if (finalTop + tooltipRect.height > window.innerHeight - screenPadding) {
181
- finalTop = window.innerHeight - tooltipRect.height - screenPadding;
182
- }
183
-
184
- // Check if tooltip overflows to the left and flip to right
185
- if (finalLeft < screenPadding) {
186
- finalLeft = Math.floor(containerRect.right + margin);
187
- setNewPosition('right');
188
-
189
- // If it still overflows on the right, position it at the edge
190
- if (finalLeft + tooltipRect.width > window.innerWidth - screenPadding) {
191
- finalLeft = window.innerWidth - tooltipRect.width - screenPadding;
192
- }
193
- } else {
194
- setNewPosition('');
195
- }
196
-
197
- targetEl.style.top = `${finalTop}px`;
198
- targetEl.style.left = `${finalLeft}px`;
128
+ targetEl.style.top =
129
+ Math.floor(containerRect.top + containerRect.height / 2 - tooltipRect.height / 2) +
130
+ 'px';
131
+ targetEl.style.left = Math.floor(containerRect.left - tooltipRect.width - 16) + 'px';
199
132
  }
200
133
  };
package/src/index.ts CHANGED
@@ -173,6 +173,7 @@ import {
173
173
  deleteEmptyPropsIncludingArray,
174
174
  deleteProps,
175
175
  deletePropsThatEndsWith,
176
+ flattenTreeForSelect,
176
177
  intersectArrays,
177
178
  } from './utils/objectUtils';
178
179
  import {
@@ -345,6 +346,7 @@ export {
345
346
  setTemplateData,
346
347
  getVisibleColumnsIds,
347
348
  inputPattern,
349
+ flattenTreeForSelect,
348
350
  intersectArrays,
349
351
  maxChar,
350
352
  parseUrlSearch,
@@ -1,8 +1,8 @@
1
1
  @use '../variables/bp';
2
- @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,600;0,700;0,900;1,400;1,500;1,600;1,700;1,900&display=swap');
2
+ @import url('@fontsource-variable/ibm-plex-sans');
3
3
 
4
4
  * {
5
- font-family: 'Poppins', sans-serif;
5
+ font-family: 'IBM Plex Sans Variable', sans-serif;
6
6
  }
7
7
 
8
8
  body {
@@ -26,6 +26,7 @@
26
26
  align-items: center;
27
27
  justify-content: space-between;
28
28
  user-select: none;
29
+ font-size: 14px;
29
30
  font-weight: 500;
30
31
  margin-bottom: 1px;
31
32
  padding: 0 16px;
@@ -24,15 +24,22 @@ $dialog-sizes: (
24
24
  }
25
25
 
26
26
  .iui-dialog-container {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: 24px;
27
30
  background-color: var(--background);
28
31
  border-radius: 16px;
29
32
  min-width: 400px;
30
33
  max-width: 98vw;
34
+ max-height: 95dvh;
31
35
  animation: scale-in 0.2s forwards;
32
36
  overflow: hidden;
37
+ padding: 24px;
38
+
33
39
  .iui-dialog-header {
34
40
  display: flex;
35
41
  gap: 16px;
42
+ flex-shrink: 0;
36
43
  .iui-dialog-desc {
37
44
  color: var(--text);
38
45
  word-break: break-word;
@@ -53,6 +60,18 @@ $dialog-sizes: (
53
60
  }
54
61
  }
55
62
  }
63
+ .iui-dialog-content {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 8px;
67
+ flex: 1;
68
+ margin-right: -24px;
69
+ padding-right: 24px;
70
+ &:not(.no-overflow) {
71
+ overflow: auto;
72
+ overscroll-behavior: none;
73
+ }
74
+ }
56
75
 
57
76
  @each $key, $value in $dialog-sizes {
58
77
  &.#{$key} {
@@ -71,28 +90,15 @@ $dialog-sizes: (
71
90
  }
72
91
  }
73
92
  }
74
- }
75
-
76
- .iui-dialog-content {
77
- display: flex;
78
- flex-direction: column;
79
- gap: 8px;
80
- max-height: 80vh;
81
- padding: 24px;
82
- &:not(.no-overflow) {
83
- overflow: auto;
84
- overscroll-behavior: none;
93
+ .iui-dialog-actions {
94
+ display: flex;
95
+ gap: 8px;
96
+ justify-content: right;
97
+ padding-top: 24px;
98
+ border-top: var(--border);
85
99
  }
86
100
  }
87
101
 
88
- .iui-dialog-actions {
89
- display: flex;
90
- gap: 8px;
91
- justify-content: right;
92
- padding: 24px;
93
- border-top: var(--border);
94
- }
95
-
96
102
  @media #{bp.$mobile} {
97
103
  .iui-dialog-container {
98
104
  height: 100dvh;
@@ -12,6 +12,11 @@
12
12
  padding-left: 8px;
13
13
  box-sizing: border-box;
14
14
  z-index: 2;
15
+ .env-badge {
16
+ color: var(--text);
17
+ font-weight: bold;
18
+ font-size: 14px;
19
+ }
15
20
  .header-button {
16
21
  height: 40px;
17
22
  width: 40px;
@@ -100,7 +100,7 @@ table {
100
100
  display: flex;
101
101
  align-items: center;
102
102
  justify-content: center;
103
- padding: 0 4px;
103
+ padding: 0 8px;
104
104
  }
105
105
 
106
106
  //// Footer ////
@@ -2,7 +2,7 @@
2
2
  display: flex;
3
3
  overflow: auto;
4
4
  border-bottom: var(--border);
5
- padding-bottom: 4px;
5
+ flex-shrink: 0;
6
6
  &::-webkit-scrollbar {
7
7
  height: 5px;
8
8
  }
@@ -43,6 +43,7 @@ export interface AsyncSelectProps extends BaseSelectProps {
43
43
  variant: 'async';
44
44
  loadOptions: any;
45
45
  defaultData?: ISelectData[];
46
+ refresh?: any[];
46
47
  }
47
48
 
48
49
  export interface CreatableSelectProps extends BaseSelectProps {
@@ -97,7 +97,7 @@ export interface ITableDataItemCells {
97
97
  }
98
98
 
99
99
  export interface ITableDataActions<T = unknown> {
100
- hasEditAccess: boolean;
100
+ hasEditAccess?: boolean;
101
101
  actions?: (item?: T) => {
102
102
  label: string;
103
103
  onClick: () => void;
@@ -3,10 +3,10 @@ export const inputPattern = {
3
3
  businessCode: '^\\d{8}$',
4
4
  umcn: '^\\d{13}$',
5
5
  idCardNumber: '^\\d{9}$',
6
- phoneNumber: '^\\d{8,9}$',
6
+ phoneNumber: '^\\+\\d{11,13}$',
7
7
  port: '^\\d{4}$',
8
8
  year: '^\\d{4}$',
9
9
  number: '^\\d*$',
10
10
  strongPassword: '^.*(?=.{8,})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$',
11
- // email: '\\S+@\\S+\\.\\S+',
11
+ email: '\\S+@\\S+\\.\\S+',
12
12
  };
@@ -14,17 +14,14 @@ export const deleteProps = <T extends Record<string, any>>(
14
14
  return newObj as Partial<T>;
15
15
  };
16
16
 
17
- export const deletePropsThatEndsWith = <T extends Record<string, any>>(
18
- obj: T,
19
- endsWith: string
20
- ) => {
17
+ export const deletePropsThatEndsWith = <T>(obj: T, endsWith: string) => {
21
18
  const newObj = { ...obj };
22
19
  for (const prop in newObj) {
23
20
  if (prop.endsWith(endsWith)) {
24
21
  delete newObj[prop];
25
22
  }
26
23
  }
27
- return newObj;
24
+ return newObj as Partial<T>;
28
25
  };
29
26
 
30
27
  export const deleteEmptyProps = <T extends Record<string, any>>(obj: T): T =>
@@ -102,3 +99,16 @@ export const getNotificationValues = (
102
99
  }
103
100
  return { ...obj, [item.key]: processedValue };
104
101
  }, {});
102
+
103
+ export const flattenTreeForSelect = (items: any[], depth = 0, maxDepth = 5): any[] => {
104
+ if (!Array.isArray(items)) return [];
105
+ const indent = '\u00A0'.repeat(Math.min(depth, maxDepth) * 3);
106
+ return items.flatMap(node => [
107
+ {
108
+ value: node.uuid,
109
+ label: `${indent}${node.code ? node.code + ' - ' : ''}${node.name}`,
110
+ disabled: node.active === false || node.hasUserAccess === false,
111
+ },
112
+ ...(node.children ? flattenTreeForSelect(node.children, depth + 1, maxDepth) : []),
113
+ ]);
114
+ };
@@ -1,18 +0,0 @@
1
- import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
-
3
- const prefix = "fad";
4
- const iconName = "pen";
5
- const width = 512;
6
- const height = 512;
7
- const unicode = "f304";
8
- const svgPathData = [
9
- "M497.9 74.16L437.8 14.06c-18.75-18.75-49.19-18.75-67.93 0l-56.53 56.55l127.1 128l56.56-56.55C516.7 123.3 516.7 92.91 497.9 74.16z",
10
- "M313.4 70.61l-282.3 282.3c-2.234 2.234-3.755 5.078-4.376 8.176l-26.34 131.7C-1.921 504 7.95 513.9 19.15 511.7l131.7-26.34c3.098-.6191 5.941-2.141 8.175-4.373l282.3-282.3L313.4 70.61z",
11
- ];
12
-
13
- export const faPen: IconDefinition = {
14
- prefix,
15
- iconName,
16
- icon: [width, height, [], unicode, svgPathData],
17
- };
18
-
@@ -1,18 +0,0 @@
1
- import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
-
3
- const prefix = "fad";
4
- const iconName = "trash-can";
5
- const width = 448;
6
- const height = 512;
7
- const unicode = "f2ed";
8
- const svgPathData = [
9
- "M32 96v368C32 490.5 53.5 512 80 512h288c26.5 0 48-21.5 48-48V96H32zM144 416c0 8.875-7.125 16-16 16S112 424.9 112 416V192c0-8.875 7.125-16 16-16S144 183.1 144 192V416zM240 416c0 8.875-7.125 16-16 16S208 424.9 208 416V192c0-8.875 7.125-16 16-16s16 7.125 16 16V416zM336 416c0 8.875-7.125 16-16 16s-16-7.125-16-16V192c0-8.875 7.125-16 16-16s16 7.125 16 16V416z",
10
- "M432 32H320l-11.58-23.16c-2.709-5.42-8.25-8.844-14.31-8.844H153.9c-6.061 0-11.6 3.424-14.31 8.844L128 32H16c-8.836 0-16 7.162-16 16V80c0 8.836 7.164 16 16 16h416c8.838 0 16-7.164 16-16V48C448 39.16 440.8 32 432 32z",
11
- ];
12
-
13
- export const faTrashCan: IconDefinition = {
14
- prefix,
15
- iconName,
16
- icon: [width, height, [], unicode, svgPathData],
17
- };
18
-
@@ -1,15 +0,0 @@
1
- import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
2
-
3
- const prefix = "far";
4
- const iconName = "ellipsis-vertical";
5
- const width = 128;
6
- const height = 512;
7
- const unicode = "f142";
8
- const svgPathData =
9
- "M64 368C90.51 368 112 389.5 112 416C112 442.5 90.51 464 64 464C37.49 464 16 442.5 16 416C16 389.5 37.49 368 64 368zM64 208C90.51 208 112 229.5 112 256C112 282.5 90.51 304 64 304C37.49 304 16 282.5 16 256C16 229.5 37.49 208 64 208zM64 144C37.49 144 16 122.5 16 96C16 69.49 37.49 48 64 48C90.51 48 112 69.49 112 96C112 122.5 90.51 144 64 144z";
10
-
11
- export const faEllipsisVertical: IconDefinition = {
12
- prefix,
13
- iconName,
14
- icon: [width, height, [], unicode, svgPathData],
15
- };