@inceptionbg/iui 2.0.19 → 2.0.21
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/icons/index.d.ts +5 -1
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +18 -7
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/iui.css +1 -1
- package/package.json +2 -1
- package/src/assets/icons/index.ts +2 -0
- package/src/assets/icons/light/faArrowLeft.ts +15 -0
- package/src/assets/icons/light/faArrowRight.ts +15 -0
- package/src/components/Accordions/Accordions.tsx +22 -10
- package/src/components/Dialog/Dialog.tsx +27 -25
- package/src/components/Header/Components/EnvBadge.tsx +17 -0
- package/src/components/Header/Header.tsx +7 -3
- package/src/components/Helper/Collapse.tsx +5 -1
- package/src/components/Inputs/Selects/components/SelectWrapper.tsx +1 -1
- package/src/components/Table/components/items/TableItemActions.tsx +5 -3
- package/src/components/Table/contexts/TableContext.tsx +8 -5
- package/src/components/Table/hooks/localHooks/useLocalTableData.tsx +1 -1
- package/src/components/Table/hooks/localHooks/useLocalTableKeyboard.ts +3 -1
- package/src/components/Table/hooks/useTableEdit.tsx +9 -2
- package/src/components/Table/hooks/useTableSearch.ts +2 -1
- package/src/components/Tabs/Tabs.tsx +3 -3
- package/src/components/Wrappers/FormWrapper.tsx +2 -0
- package/src/components/Wrappers/PageLayout.tsx +14 -6
- package/src/index.ts +2 -0
- package/src/styles/common/_typography.scss +2 -2
- package/src/styles/common/helpers/_size.scss +3 -0
- package/src/styles/components/_accordions.scss +3 -0
- package/src/styles/components/_dialog.scss +25 -19
- package/src/styles/components/_header.scss +5 -0
- package/src/styles/components/_page.scss +45 -12
- package/src/styles/components/_table.scss +2 -1
- package/src/styles/components/_tabs.scss +1 -1
- package/src/types/ITable.ts +1 -1
- package/src/utils/InputPatternValidation.ts +2 -2
- package/src/utils/objectUtils.ts +15 -5
|
@@ -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={
|
|
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]
|
|
30
|
+
const [selected, setSelected] = useState(initialValue || filteredTabs[0]?.value || '');
|
|
31
31
|
|
|
32
|
-
const activeTab = filteredTabs.find(tab => (control?.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
|
|
42
|
+
selected: (control?.value ?? selected) === tab.value,
|
|
43
43
|
disabled: tab.disabled,
|
|
44
44
|
'no-wrap': noWrap,
|
|
45
45
|
})}
|
|
@@ -61,6 +61,7 @@ export const FormWrapper: FC<IFormWrapper> = ({
|
|
|
61
61
|
variant={e.variant}
|
|
62
62
|
color={e.color}
|
|
63
63
|
onClick={e.onClick}
|
|
64
|
+
type="button"
|
|
64
65
|
/>
|
|
65
66
|
)
|
|
66
67
|
)}
|
|
@@ -71,6 +72,7 @@ export const FormWrapper: FC<IFormWrapper> = ({
|
|
|
71
72
|
disabled={isLoading || submitButton.disabled}
|
|
72
73
|
variant={submitButton.variant}
|
|
73
74
|
color={submitButton.color}
|
|
75
|
+
type="submit"
|
|
74
76
|
/>
|
|
75
77
|
)}
|
|
76
78
|
</div>
|
|
@@ -28,6 +28,7 @@ export interface IPageLayoutProps {
|
|
|
28
28
|
noAccess?: boolean;
|
|
29
29
|
isInitiallyLoading?: boolean;
|
|
30
30
|
isLoading?: boolean;
|
|
31
|
+
hideFooter?: boolean;
|
|
31
32
|
children?: ReactNode;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -40,6 +41,7 @@ export const PageLayout: FC<IPageLayoutProps> = ({
|
|
|
40
41
|
noAccess,
|
|
41
42
|
isLoading,
|
|
42
43
|
isInitiallyLoading,
|
|
44
|
+
hideFooter,
|
|
43
45
|
children,
|
|
44
46
|
}) => {
|
|
45
47
|
const [isMoreActionsOpen, setIsMoreActionsOpen] = useState(false);
|
|
@@ -56,9 +58,11 @@ export const PageLayout: FC<IPageLayoutProps> = ({
|
|
|
56
58
|
return null;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
<Loader isLoading isFullPage
|
|
61
|
-
|
|
61
|
+
if (isInitiallyLoading) {
|
|
62
|
+
return <Loader isLoading isFullPage />;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (
|
|
62
66
|
<Loader isLoading={!!isLoading}>
|
|
63
67
|
<div className="page-container">
|
|
64
68
|
{breadcrumbs && (
|
|
@@ -138,9 +142,13 @@ export const PageLayout: FC<IPageLayoutProps> = ({
|
|
|
138
142
|
</div>
|
|
139
143
|
)}
|
|
140
144
|
<div className="page-content">{children}</div>
|
|
141
|
-
|
|
142
|
-
<
|
|
143
|
-
|
|
145
|
+
{!hideFooter && (
|
|
146
|
+
<footer className="page-footer">
|
|
147
|
+
<p className="page-footer-text">
|
|
148
|
+
<Trans i18nKey="FooterText" />
|
|
149
|
+
</p>
|
|
150
|
+
</footer>
|
|
151
|
+
)}
|
|
144
152
|
</div>
|
|
145
153
|
</Loader>
|
|
146
154
|
);
|
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('
|
|
2
|
+
@import url('@fontsource-variable/ibm-plex-sans');
|
|
3
3
|
|
|
4
4
|
* {
|
|
5
|
-
font-family: '
|
|
5
|
+
font-family: 'IBM Plex Sans Variable', sans-serif;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
body {
|
|
@@ -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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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;
|
|
@@ -32,14 +32,6 @@
|
|
|
32
32
|
max-height: calc(100vh - var(--header-height));
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
.page-content {
|
|
36
|
-
display: flex;
|
|
37
|
-
flex-direction: column;
|
|
38
|
-
padding: 1.5rem 1.5rem 1rem 1.5rem;
|
|
39
|
-
flex: 1;
|
|
40
|
-
overflow-y: auto;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
35
|
.page-header {
|
|
44
36
|
display: flex;
|
|
45
37
|
justify-content: space-between;
|
|
@@ -57,9 +49,50 @@
|
|
|
57
49
|
}
|
|
58
50
|
}
|
|
59
51
|
|
|
52
|
+
.page-content {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
padding: 1.5rem 1.5rem 1rem 1.5rem;
|
|
56
|
+
flex: 1;
|
|
57
|
+
overflow-y: auto;
|
|
58
|
+
}
|
|
59
|
+
.scrollable-content {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
flex: 1;
|
|
63
|
+
overflow-y: auto;
|
|
64
|
+
margin-right: -1.5rem;
|
|
65
|
+
padding-right: 1.5rem;
|
|
66
|
+
padding-bottom: 1rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
.page-footer {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
gap: 16px;
|
|
74
|
+
padding: 16px 24px;
|
|
75
|
+
margin: 0 -1.5rem -1rem;
|
|
76
|
+
&.footer-actions {
|
|
77
|
+
box-shadow: var(--container-shadow);
|
|
78
|
+
z-index: 2;
|
|
79
|
+
}
|
|
80
|
+
.page-footer-text {
|
|
81
|
+
text-align: center;
|
|
82
|
+
font-size: 12px;
|
|
83
|
+
white-space: pre-line;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.page-footer-text {
|
|
88
|
+
display: flex;
|
|
89
|
+
align-items: center;
|
|
90
|
+
justify-content: center;
|
|
91
|
+
gap: 16px;
|
|
92
|
+
padding: 16px 24px;
|
|
93
|
+
.page-footer-text {
|
|
94
|
+
text-align: center;
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
white-space: pre-line;
|
|
97
|
+
}
|
|
65
98
|
}
|
|
@@ -94,13 +94,14 @@ table {
|
|
|
94
94
|
}
|
|
95
95
|
.clickable-cell:hover {
|
|
96
96
|
background-color: var(--primary-100) !important;
|
|
97
|
+
cursor: pointer;
|
|
97
98
|
}
|
|
98
99
|
// Item Actions
|
|
99
100
|
.table-item-actions {
|
|
100
101
|
display: flex;
|
|
101
102
|
align-items: center;
|
|
102
103
|
justify-content: center;
|
|
103
|
-
padding: 0
|
|
104
|
+
padding: 0 8px;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
//// Footer ////
|
package/src/types/ITable.ts
CHANGED
|
@@ -3,10 +3,10 @@ export const inputPattern = {
|
|
|
3
3
|
businessCode: '^\\d{8}$',
|
|
4
4
|
umcn: '^\\d{13}$',
|
|
5
5
|
idCardNumber: '^\\d{9}$',
|
|
6
|
-
phoneNumber: '
|
|
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
|
-
|
|
11
|
+
email: '\\S+@\\S+\\.\\S+',
|
|
12
12
|
};
|
package/src/utils/objectUtils.ts
CHANGED
|
@@ -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
|
|
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
|
+
};
|