@akinon/akitable 0.5.0 → 1.0.1
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/cjs/akitable.d.ts +11 -0
- package/dist/cjs/akitable.d.ts.map +1 -1
- package/dist/cjs/akitable.js +33 -11
- package/dist/cjs/components/actions.js +3 -3
- package/dist/cjs/components/controls.js +2 -2
- package/dist/cjs/components/datatable.css +67 -20
- package/dist/cjs/components/datatable.d.ts.map +1 -1
- package/dist/cjs/components/datatable.js +55 -18
- package/dist/cjs/components/footer.d.ts.map +1 -1
- package/dist/cjs/components/footer.js +2 -2
- package/dist/cjs/components/header.css +33 -1
- package/dist/cjs/components/header.d.ts.map +1 -1
- package/dist/cjs/components/header.js +19 -11
- package/dist/cjs/components/pagination.css +1 -1
- package/dist/cjs/components/pagination.d.ts.map +1 -1
- package/dist/cjs/components/pagination.js +19 -4
- package/dist/cjs/i18n/translations/en.d.ts +1 -0
- package/dist/cjs/i18n/translations/en.d.ts.map +1 -1
- package/dist/cjs/i18n/translations/en.js +2 -1
- package/dist/cjs/i18n/translations/tr.d.ts +2 -1
- package/dist/cjs/i18n/translations/tr.d.ts.map +1 -1
- package/dist/cjs/i18n/translations/tr.js +3 -2
- package/dist/cjs/types.d.ts +100 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +5 -0
- package/dist/esm/akitable.d.ts +11 -0
- package/dist/esm/akitable.d.ts.map +1 -1
- package/dist/esm/akitable.js +33 -11
- package/dist/esm/components/actions.js +3 -3
- package/dist/esm/components/controls.js +2 -2
- package/dist/esm/components/datatable.css +67 -20
- package/dist/esm/components/datatable.d.ts.map +1 -1
- package/dist/esm/components/datatable.js +55 -18
- package/dist/esm/components/footer.d.ts.map +1 -1
- package/dist/esm/components/footer.js +2 -2
- package/dist/esm/components/header.css +33 -1
- package/dist/esm/components/header.d.ts.map +1 -1
- package/dist/esm/components/header.js +19 -11
- package/dist/esm/components/pagination.css +1 -1
- package/dist/esm/components/pagination.d.ts.map +1 -1
- package/dist/esm/components/pagination.js +19 -4
- package/dist/esm/i18n/translations/en.d.ts +1 -0
- package/dist/esm/i18n/translations/en.d.ts.map +1 -1
- package/dist/esm/i18n/translations/en.js +2 -1
- package/dist/esm/i18n/translations/tr.d.ts +2 -1
- package/dist/esm/i18n/translations/tr.d.ts.map +1 -1
- package/dist/esm/i18n/translations/tr.js +3 -2
- package/dist/esm/types.d.ts +100 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +4 -1
- package/package.json +22 -21
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,55 +1,154 @@
|
|
|
1
1
|
import { TableColumnType } from 'antd';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
type RowClickEvent = (record: AkitableData, event?: React.MouseEvent<HTMLElement>, rowIndex?: number) => void;
|
|
4
|
-
type RowEditCallback = (modifiedRecord: AkitableData, payload: AkitableData) => void
|
|
4
|
+
type RowEditCallback = (modifiedRecord: AkitableData, payload: AkitableData) => void | Promise<void>;
|
|
5
5
|
export type PaginationChangeEvent = (page: number, size: number) => void;
|
|
6
6
|
export interface AkitableProps {
|
|
7
|
+
/**
|
|
8
|
+
* Actions available for the table rows.
|
|
9
|
+
*/
|
|
7
10
|
actions?: AkitableAction[];
|
|
11
|
+
/**
|
|
12
|
+
* Columns definition for the table.
|
|
13
|
+
*/
|
|
8
14
|
columns: AkitableColumn[];
|
|
15
|
+
/**
|
|
16
|
+
* Data source for the table.
|
|
17
|
+
*/
|
|
9
18
|
data: AkitableData[] | AkitablePaginatedData;
|
|
19
|
+
/**
|
|
20
|
+
* Header configuration for the table.
|
|
21
|
+
*/
|
|
10
22
|
header?: AkitableHeaderProps;
|
|
23
|
+
/**
|
|
24
|
+
* Footer configuration for the table.
|
|
25
|
+
*/
|
|
11
26
|
footer?: AkitableFooterProps;
|
|
27
|
+
/**
|
|
28
|
+
* Loading state for the table.
|
|
29
|
+
*/
|
|
12
30
|
isLoading?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Pagination configuration for the table.
|
|
33
|
+
*/
|
|
13
34
|
pagination?: AkitablePaginationProps;
|
|
35
|
+
/**
|
|
36
|
+
* Unique key for each table row.
|
|
37
|
+
*/
|
|
14
38
|
rowKey: string;
|
|
39
|
+
/**
|
|
40
|
+
* Callback when pagination changes.
|
|
41
|
+
*/
|
|
15
42
|
onPaginationChanged?: PaginationChangeEvent;
|
|
43
|
+
/**
|
|
44
|
+
* Callback for row click events.
|
|
45
|
+
*/
|
|
16
46
|
onRowClick?: RowClickEvent;
|
|
47
|
+
/**
|
|
48
|
+
* Callback for row edit events.
|
|
49
|
+
*/
|
|
17
50
|
onRowEdit?: RowEditCallback;
|
|
18
51
|
}
|
|
19
52
|
export interface AkitableHeaderProps {
|
|
53
|
+
/**
|
|
54
|
+
* Title of the table header.
|
|
55
|
+
*/
|
|
20
56
|
title?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Additional content for the table header.
|
|
59
|
+
*/
|
|
21
60
|
extra?: ReactNode;
|
|
22
61
|
}
|
|
23
62
|
export interface AkitableFooterProps {
|
|
63
|
+
/**
|
|
64
|
+
* Additional content for the table footer.
|
|
65
|
+
*/
|
|
24
66
|
extra?: ReactNode;
|
|
25
67
|
}
|
|
26
68
|
export interface AkitableDataTableProps {
|
|
69
|
+
/**
|
|
70
|
+
* Columns definition for the table.
|
|
71
|
+
*/
|
|
27
72
|
columns: AkitableColumn[];
|
|
73
|
+
/**
|
|
74
|
+
* Data source for the table.
|
|
75
|
+
*/
|
|
28
76
|
data: AkitableData[];
|
|
77
|
+
/**
|
|
78
|
+
* Unique key for each table row.
|
|
79
|
+
*/
|
|
29
80
|
rowKey: string;
|
|
81
|
+
/**
|
|
82
|
+
* Callback for row click events.
|
|
83
|
+
*/
|
|
30
84
|
onRowClick?: RowClickEvent;
|
|
85
|
+
/**
|
|
86
|
+
* Callback for row edit events.
|
|
87
|
+
*/
|
|
31
88
|
onRowEdit?: RowEditCallback;
|
|
32
89
|
}
|
|
33
90
|
export type AkitablePageSizes = 20 | 50 | 100 | 250;
|
|
34
91
|
export interface AkitablePaginationProps {
|
|
92
|
+
/**
|
|
93
|
+
* Current page number.
|
|
94
|
+
*/
|
|
35
95
|
page: number;
|
|
96
|
+
/**
|
|
97
|
+
* Number of rows per page.
|
|
98
|
+
*/
|
|
36
99
|
size: AkitablePageSizes;
|
|
37
100
|
}
|
|
38
101
|
export interface AkitableColumn extends TableColumnType<AkitableData> {
|
|
102
|
+
/**
|
|
103
|
+
* Whether the column is copyable.
|
|
104
|
+
*/
|
|
39
105
|
copyable?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the column is editable.
|
|
108
|
+
*/
|
|
40
109
|
editable?: boolean;
|
|
41
110
|
}
|
|
111
|
+
export declare const AkitableRowStatus: {
|
|
112
|
+
readonly PENDING: "pending";
|
|
113
|
+
readonly ERROR: "error";
|
|
114
|
+
};
|
|
115
|
+
type AllAkitableRowStatuses = `${(typeof AkitableRowStatus)[keyof typeof AkitableRowStatus]}`;
|
|
42
116
|
export interface AkitableData {
|
|
117
|
+
/**
|
|
118
|
+
* Status of the table row.
|
|
119
|
+
*/
|
|
120
|
+
rowStatus?: AllAkitableRowStatuses;
|
|
121
|
+
/**
|
|
122
|
+
* Additional properties for the table row.
|
|
123
|
+
*/
|
|
43
124
|
[key: string]: any;
|
|
44
125
|
}
|
|
45
126
|
export interface AkitablePaginatedData {
|
|
127
|
+
/**
|
|
128
|
+
* Total count of rows.
|
|
129
|
+
*/
|
|
46
130
|
count: number;
|
|
131
|
+
/**
|
|
132
|
+
* URL for the next set of paginated data.
|
|
133
|
+
*/
|
|
47
134
|
next?: string | null;
|
|
135
|
+
/**
|
|
136
|
+
* URL for the previous set of paginated data.
|
|
137
|
+
*/
|
|
48
138
|
previous?: string | null;
|
|
139
|
+
/**
|
|
140
|
+
* Results of the current page.
|
|
141
|
+
*/
|
|
49
142
|
results: AkitableData[];
|
|
50
143
|
}
|
|
51
144
|
export interface AkitableAction {
|
|
145
|
+
/**
|
|
146
|
+
* Label for the action.
|
|
147
|
+
*/
|
|
52
148
|
label: string;
|
|
149
|
+
/**
|
|
150
|
+
* Callback when the action is selected.
|
|
151
|
+
*/
|
|
53
152
|
onSelect: (selectedRowKeys: React.Key[]) => void;
|
|
54
153
|
}
|
|
55
154
|
export {};
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,KAAK,aAAa,GAAG,CACnB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,EACrC,QAAQ,CAAC,EAAE,MAAM,KACd,IAAI,CAAC;AAEV,KAAK,eAAe,GAAG,CACrB,cAAc,EAAE,YAAY,EAC5B,OAAO,EAAE,YAAY,KAClB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.js
CHANGED
package/dist/esm/akitable.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import './akitable.css';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { AkitableProps } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Akitable component for Akinon UI.
|
|
6
|
+
*
|
|
7
|
+
* The Akitable component is a versatile and feature-rich table component designed for displaying,
|
|
8
|
+
* editing, and interacting with tabular data. It supports custom columns, pagination, row actions,
|
|
9
|
+
* and event callbacks for enhanced user experience and flexibility.
|
|
10
|
+
*
|
|
11
|
+
* Features include row click/edit actions, customizable headers and footers, pagination controls,
|
|
12
|
+
* and integration with Akinon design system standards. It is ideal for complex data visualization
|
|
13
|
+
* needs in enterprise applications.
|
|
14
|
+
*/
|
|
4
15
|
export declare const Akitable: (props: AkitableProps) => React.JSX.Element;
|
|
5
16
|
//# sourceMappingURL=akitable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"akitable.d.ts","sourceRoot":"","sources":["../../src/akitable.tsx"],"names":[],"mappings":"AACA,OAAO,gBAAgB,CAAC;AAGxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EAAuC,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7E,eAAO,MAAM,QAAQ,UAAW,aAAa,
|
|
1
|
+
{"version":3,"file":"akitable.d.ts","sourceRoot":"","sources":["../../src/akitable.tsx"],"names":[],"mappings":"AACA,OAAO,gBAAgB,CAAC;AAGxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EAAuC,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7E;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,QAAQ,UAAW,aAAa,sBAuF5C,CAAC"}
|
package/dist/esm/akitable.js
CHANGED
|
@@ -10,22 +10,44 @@ import { AkitableDataTable } from './components/datatable';
|
|
|
10
10
|
import { fallbackRender } from './components/error';
|
|
11
11
|
import { AkitableFooter } from './components/footer';
|
|
12
12
|
import { AkitableHeader } from './components/header';
|
|
13
|
+
/**
|
|
14
|
+
* Akitable component for Akinon UI.
|
|
15
|
+
*
|
|
16
|
+
* The Akitable component is a versatile and feature-rich table component designed for displaying,
|
|
17
|
+
* editing, and interacting with tabular data. It supports custom columns, pagination, row actions,
|
|
18
|
+
* and event callbacks for enhanced user experience and flexibility.
|
|
19
|
+
*
|
|
20
|
+
* Features include row click/edit actions, customizable headers and footers, pagination controls,
|
|
21
|
+
* and integration with Akinon design system standards. It is ideal for complex data visualization
|
|
22
|
+
* needs in enterprise applications.
|
|
23
|
+
*/
|
|
13
24
|
export const Akitable = (props) => {
|
|
14
25
|
const { actions, columns, data, footer, header, isLoading, pagination, rowKey, onPaginationChanged, onRowClick, onRowEdit } = props;
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
const handleGetSplittedDataByPagination = ({ result }) => {
|
|
27
|
+
if (!pagination)
|
|
28
|
+
return result;
|
|
29
|
+
const { page, size } = pagination;
|
|
30
|
+
const startIndex = (page - 1) * size;
|
|
31
|
+
const endIndex = startIndex + size;
|
|
32
|
+
return result.slice(startIndex, endIndex);
|
|
33
|
+
};
|
|
17
34
|
// If there is a pagination object, table data should be accessed from type AkitablePaginatedData.
|
|
18
35
|
// If not, table data should be accessed from type AkitableData.
|
|
19
|
-
|
|
36
|
+
const handleGetParsedData = () => {
|
|
37
|
+
if (pagination) {
|
|
38
|
+
const result = data;
|
|
39
|
+
const total = (result === null || result === void 0 ? void 0 : result.count) || 0;
|
|
40
|
+
const parsedData = handleGetSplittedDataByPagination({
|
|
41
|
+
result: (result === null || result === void 0 ? void 0 : result.results) || []
|
|
42
|
+
});
|
|
43
|
+
return { total, parsedData };
|
|
44
|
+
}
|
|
20
45
|
const result = data;
|
|
21
|
-
total = (result === null || result === void 0 ? void 0 : result.
|
|
22
|
-
parsedData =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
total = (result === null || result === void 0 ? void 0 : result.length) || 0;
|
|
27
|
-
parsedData = result || [];
|
|
28
|
-
}
|
|
46
|
+
const total = (result === null || result === void 0 ? void 0 : result.length) || 0;
|
|
47
|
+
const parsedData = result || [];
|
|
48
|
+
return { total, parsedData };
|
|
49
|
+
};
|
|
50
|
+
const { total, parsedData } = handleGetParsedData();
|
|
29
51
|
return (React.createElement("div", { className: "akitable-container" },
|
|
30
52
|
React.createElement(ErrorBoundary, { fallbackRender: fallbackRender },
|
|
31
53
|
React.createElement(AkitableProvider, { actions: actions, isLoading: isLoading, pagination: Object.assign(Object.assign({}, pagination), { total, hasPagination: !!pagination }), onPaginationChanged: onPaginationChanged },
|
|
@@ -17,13 +17,13 @@ export const AkitableActions = () => {
|
|
|
17
17
|
setSelectedAction(value);
|
|
18
18
|
};
|
|
19
19
|
const handleActionTrigger = () => {
|
|
20
|
-
if (!selectedAction || !
|
|
20
|
+
if (!selectedAction || !hasSelections)
|
|
21
21
|
return;
|
|
22
22
|
const action = actions === null || actions === void 0 ? void 0 : actions.find((_, index) => index === selectedAction - 1);
|
|
23
23
|
action === null || action === void 0 ? void 0 : action.onSelect(selectedRowKeys);
|
|
24
24
|
};
|
|
25
|
-
return (React.createElement("div", { className: "akitable-actions" },
|
|
26
|
-
React.createElement(Select, { placeholder: t('selectAction'), value: selectedAction, options: options, onChange: value => handleActionChange(value), disabled: isLoading || (pagination === null || pagination === void 0 ? void 0 : pagination.total) === 0, allowClear: true }),
|
|
25
|
+
return (React.createElement("div", { "data-testid": "akitable-actions", className: "akitable-actions" },
|
|
26
|
+
React.createElement(Select, { placeholder: t('selectAction'), value: selectedAction, options: options, onChange: value => handleActionChange(value), disabled: isLoading || (pagination === null || pagination === void 0 ? void 0 : pagination.total) === 0, allowClear: true, "data-testid": "akitable-actions-select" }),
|
|
27
27
|
selectedAction && (React.createElement(React.Fragment, null,
|
|
28
28
|
React.createElement(Button, { type: "primary", icon: "katalogkontrol", disabled: isLoading || !hasSelections, onClick: handleActionTrigger }, t('apply')),
|
|
29
29
|
hasSelections && (React.createElement("span", { className: "akitable-actions-info" }, t('selectedCount', { count: selectedRowKeys === null || selectedRowKeys === void 0 ? void 0 : selectedRowKeys.length })))))));
|
|
@@ -7,8 +7,8 @@ export const AkitableControls = () => {
|
|
|
7
7
|
const { actions, pagination } = useAkitableContext();
|
|
8
8
|
if (!actions)
|
|
9
9
|
return null;
|
|
10
|
-
return (React.createElement("div", { className: "akitable-controls" },
|
|
10
|
+
return (React.createElement("div", { "data-testid": "akitable-controls", className: "akitable-controls" },
|
|
11
11
|
actions && actions.length > 0 && React.createElement(AkitableActions, null),
|
|
12
|
-
(pagination === null || pagination === void 0 ? void 0 : pagination.hasPagination) && (React.createElement("div", { className: "ml-auto" },
|
|
12
|
+
(pagination === null || pagination === void 0 ? void 0 : pagination.hasPagination) && (React.createElement("div", { "data-testid": "akitable-controls-pagination", className: "ml-auto" },
|
|
13
13
|
React.createElement(AkitablePagination, null)))));
|
|
14
14
|
};
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
.
|
|
1
|
+
.akitable-wrapper {
|
|
2
|
+
margin-left: -1.5rem;
|
|
3
|
+
margin-right: -1.5rem;
|
|
4
|
+
margin-bottom: 1rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.akitable-wrapper .akinon-table-wrapper .akinon-table-thead > tr > th {
|
|
2
8
|
text-transform: uppercase;
|
|
3
9
|
font-size: 0.75rem;
|
|
4
10
|
font-weight: 600;
|
|
@@ -6,50 +12,91 @@
|
|
|
6
12
|
padding-top: 0.65rem;
|
|
7
13
|
}
|
|
8
14
|
|
|
9
|
-
.akitable-wrapper {
|
|
10
|
-
margin-left: -1.5rem;
|
|
11
|
-
margin-right: -1.5rem;
|
|
12
|
-
margin-bottom: 1rem;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.akinon-table-content {
|
|
15
|
+
.akitable-wrapper .akinon-table-content {
|
|
16
16
|
scrollbar-color: auto;
|
|
17
17
|
scrollbar-width: auto;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
.akinon-table-content::-webkit-scrollbar {
|
|
20
|
+
.akitable-wrapper .akinon-table-content::-webkit-scrollbar {
|
|
21
21
|
height: 8px;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
.akinon-table-content::-webkit-scrollbar-track {
|
|
24
|
+
.akitable-wrapper .akinon-table-content::-webkit-scrollbar-track {
|
|
25
25
|
background-color: var(--color-neutral-100);
|
|
26
26
|
border: none;
|
|
27
27
|
padding: 1px;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
.akinon-table-content::-webkit-scrollbar-thumb {
|
|
30
|
+
.akitable-wrapper .akinon-table-content::-webkit-scrollbar-thumb {
|
|
31
31
|
background-color: var(--color-neutral-300);
|
|
32
32
|
border-radius: 3px;
|
|
33
33
|
border: none;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/* Add background for alternate rows. */
|
|
37
|
-
.akinon-table-row:nth-child(odd)
|
|
38
|
-
background-color: var(--color-neutral-
|
|
37
|
+
.akitable-wrapper .akinon-table-row:nth-child(odd) {
|
|
38
|
+
background-color: var(--color-neutral-75);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
.akinon-table-row.is-selectable {
|
|
41
|
+
.akitable-wrapper .akinon-table-row.is-selectable {
|
|
42
42
|
cursor: pointer;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.akinon-table-row.is-selectable td {
|
|
46
43
|
transition: background-color 0.2s;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
.akinon-table-row.is-selectable:hover
|
|
50
|
-
background-color: var(--color-blue-100)
|
|
46
|
+
.akitable-wrapper .akinon-table-row.is-selectable:hover {
|
|
47
|
+
background-color: var(--color-blue-100);
|
|
51
48
|
}
|
|
52
49
|
|
|
53
|
-
.
|
|
50
|
+
.akitable-wrapper
|
|
51
|
+
.akinon-table-row.is-selectable:hover
|
|
52
|
+
td[class*='akinon-table-cell-fix-'] {
|
|
54
53
|
background-color: var(--color-blue-200) !important;
|
|
55
54
|
}
|
|
55
|
+
|
|
56
|
+
.akitable-wrapper .akinon-table-row.akitable-row-pending {
|
|
57
|
+
background-color: var(--color-green-952-10);
|
|
58
|
+
position: relative;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.akitable-wrapper .akinon-table-cell {
|
|
62
|
+
z-index: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.akitable-wrapper .akinon-table-row.akitable-row-pending::after {
|
|
66
|
+
content: '';
|
|
67
|
+
position: absolute;
|
|
68
|
+
top: 0;
|
|
69
|
+
left: 0;
|
|
70
|
+
right: 0;
|
|
71
|
+
bottom: 0;
|
|
72
|
+
background: repeating-linear-gradient(
|
|
73
|
+
60deg,
|
|
74
|
+
transparent 0px,
|
|
75
|
+
transparent 18px,
|
|
76
|
+
var(--color-green-952-15) 18px,
|
|
77
|
+
var(--color-green-952-15) 36px,
|
|
78
|
+
transparent 36px
|
|
79
|
+
);
|
|
80
|
+
animation: shimmer 20s linear infinite;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@keyframes shimmer {
|
|
84
|
+
0% {
|
|
85
|
+
left: -100%;
|
|
86
|
+
}
|
|
87
|
+
100% {
|
|
88
|
+
left: -4.82596083%;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.akitable-wrapper .akinon-table-row.akitable-row-error {
|
|
93
|
+
background-color: var(--color-red-425-10);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.akitable-wrapper .akinon-table-tbody tr:last-child td {
|
|
97
|
+
border-bottom: 1px solid var(--color-neutral-350);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.akitable-wrapper .akinon-table-row .akinon-table-edit-button--disable {
|
|
101
|
+
cursor: not-allowed;
|
|
102
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datatable.d.ts","sourceRoot":"","sources":["../../../src/components/datatable.tsx"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC;AAOzB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,
|
|
1
|
+
{"version":3,"file":"datatable.d.ts","sourceRoot":"","sources":["../../../src/components/datatable.tsx"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC;AAOzB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAGL,sBAAsB,EAEvB,MAAM,UAAU,CAAC;AAIlB,eAAO,MAAM,iBAAiB,UAAW,sBAAsB,sBAoK9D,CAAC"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import './datatable.css';
|
|
2
11
|
import { Akiform } from '@akinon/akiform';
|
|
3
12
|
import { Button } from '@akinon/ui-button';
|
|
@@ -7,6 +16,7 @@ import clsx from 'clsx';
|
|
|
7
16
|
import React from 'react';
|
|
8
17
|
import { useAkitableContext } from '../akitable-context';
|
|
9
18
|
import { i18n } from '../i18n';
|
|
19
|
+
import { AkitableRowStatus } from '../types';
|
|
10
20
|
import EditableCell from './EditableCell';
|
|
11
21
|
const { t } = i18n;
|
|
12
22
|
export const AkitableDataTable = (props) => {
|
|
@@ -15,7 +25,10 @@ export const AkitableDataTable = (props) => {
|
|
|
15
25
|
const [form] = Akiform.useForm();
|
|
16
26
|
const [localColumns, setLocalColumns] = React.useState(columns);
|
|
17
27
|
const [editingKey, setEditingKey] = React.useState(null);
|
|
28
|
+
const [isLoadingSaveButton, setIsLoadingSaveButton] = React.useState(false);
|
|
18
29
|
const hasActions = actions && actions.length > 0;
|
|
30
|
+
const getRowKeyData = (record) => record[rowKey];
|
|
31
|
+
const checkIsEditingRow = (recordId) => recordId === editingKey;
|
|
19
32
|
const onSelectChange = (newSelectedRowKeys) => {
|
|
20
33
|
setSelectedRowKeys === null || setSelectedRowKeys === void 0 ? void 0 : setSelectedRowKeys(newSelectedRowKeys);
|
|
21
34
|
};
|
|
@@ -30,6 +43,7 @@ export const AkitableDataTable = (props) => {
|
|
|
30
43
|
*/
|
|
31
44
|
React.useEffect(() => {
|
|
32
45
|
if (!onRowEdit) {
|
|
46
|
+
setLocalColumns(columns);
|
|
33
47
|
return;
|
|
34
48
|
}
|
|
35
49
|
const modifiedColumns = columns.map(column => {
|
|
@@ -39,40 +53,63 @@ export const AkitableDataTable = (props) => {
|
|
|
39
53
|
record,
|
|
40
54
|
dataIndex: column.dataIndex,
|
|
41
55
|
title: column.title,
|
|
42
|
-
editing: record
|
|
56
|
+
editing: checkIsEditingRow(getRowKeyData(record))
|
|
43
57
|
}) });
|
|
44
58
|
});
|
|
45
59
|
const editColumn = {
|
|
46
60
|
key: 'edit',
|
|
47
61
|
title: t('edit'),
|
|
48
62
|
render: (record) => {
|
|
49
|
-
const isRowEditing = record
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} }, t('save')),
|
|
56
|
-
React.createElement(Text, { type: "danger", onClick: () => setEditingKey(null), style: { marginLeft: 8, cursor: 'pointer' } }, t('cancel')))) : (React.createElement(Button, { type: "primary", size: "small", onClick: () => {
|
|
63
|
+
const isRowEditing = checkIsEditingRow(getRowKeyData(record));
|
|
64
|
+
const handleOnClickSaveButton = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
try {
|
|
66
|
+
setIsLoadingSaveButton(true);
|
|
67
|
+
yield onRowEdit(record, form.getFieldsValue());
|
|
68
|
+
setEditingKey(null);
|
|
57
69
|
form.resetFields();
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
setIsLoadingSaveButton(false);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const handleOnClickEditButton = (e) => {
|
|
76
|
+
if (!isLoadingSaveButton) {
|
|
77
|
+
form.resetFields();
|
|
78
|
+
setEditingKey(getRowKeyData(record));
|
|
79
|
+
}
|
|
80
|
+
e.stopPropagation(); // To prevent row click event
|
|
81
|
+
};
|
|
82
|
+
const handleOnClickCancelButton = () => {
|
|
83
|
+
setEditingKey(null);
|
|
84
|
+
};
|
|
85
|
+
return isRowEditing ? (React.createElement("span", null,
|
|
86
|
+
React.createElement(Button, { size: "small", onClick: handleOnClickSaveButton, loading: isLoadingSaveButton }, t('save')),
|
|
87
|
+
React.createElement(Text, Object.assign({ type: "danger", disabled: isLoadingSaveButton, className: "cursor-pointer ml-2" }, (!isLoadingSaveButton && {
|
|
88
|
+
onClick: handleOnClickCancelButton
|
|
89
|
+
})), t('cancel')))) : (React.createElement(Button, { type: "primary", size: "small", onClick: handleOnClickEditButton, className: clsx({
|
|
90
|
+
'akinon-table-edit-button--disable': isLoadingSaveButton
|
|
91
|
+
}) }, t('edit')));
|
|
60
92
|
},
|
|
61
93
|
width: 200
|
|
62
94
|
};
|
|
63
95
|
setLocalColumns([...modifiedColumns, editColumn]);
|
|
64
|
-
}, [columns, onRowEdit, editingKey]);
|
|
65
|
-
return (React.createElement("div", { className: "akitable-wrapper" },
|
|
96
|
+
}, [columns, onRowEdit, editingKey, isLoadingSaveButton]);
|
|
97
|
+
return (React.createElement("div", { "data-testid": "akitable-datatable-wrapper", className: "akitable-wrapper" },
|
|
66
98
|
React.createElement(Akiform, { form: form, component: false },
|
|
67
|
-
React.createElement(Table, { components: {
|
|
99
|
+
React.createElement(Table, { "data-testid": "akitable-datatable", components: {
|
|
68
100
|
body: {
|
|
69
101
|
cell: EditableCell
|
|
70
102
|
}
|
|
71
|
-
}, columns: localColumns, dataSource: data, rowKey: (record) => record
|
|
72
|
-
|
|
103
|
+
}, columns: localColumns, dataSource: data, rowKey: (record) => getRowKeyData(record), bordered: true, rowHoverable: true, pagination: false, scroll: { x: 'max-content', scrollToFirstRowOnChange: true }, loading: isLoading, onRow: (record, rowIndex) => {
|
|
104
|
+
const isEditingRow = checkIsEditingRow(getRowKeyData(record));
|
|
105
|
+
return Object.assign({}, (!isEditingRow && {
|
|
73
106
|
onClick: (event) => {
|
|
74
107
|
onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(record, event, rowIndex);
|
|
75
108
|
}
|
|
76
|
-
};
|
|
77
|
-
}, rowClassName:
|
|
109
|
+
}));
|
|
110
|
+
}, rowClassName: (record) => clsx({
|
|
111
|
+
'is-selectable': !!onRowClick && !checkIsEditingRow(getRowKeyData(record)),
|
|
112
|
+
'akitable-row-pending': record.rowStatus === AkitableRowStatus.PENDING,
|
|
113
|
+
'akitable-row-error': record.rowStatus === AkitableRowStatus.ERROR
|
|
114
|
+
}), rowSelection: hasActions ? rowSelection : undefined }))));
|
|
78
115
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../src/components/footer.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,eAAO,MAAM,cAAc,UAAW,mBAAmB,
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../src/components/footer.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAGtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,eAAO,MAAM,cAAc,UAAW,mBAAmB,6BAsBxD,CAAC"}
|
|
@@ -8,8 +8,8 @@ export const AkitableFooter = (props) => {
|
|
|
8
8
|
const { extra } = props;
|
|
9
9
|
if (!extra && !(pagination === null || pagination === void 0 ? void 0 : pagination.hasPagination))
|
|
10
10
|
return null;
|
|
11
|
-
return (React.createElement("div", { className: "akitable-footer" },
|
|
12
|
-
extra && (React.createElement("div", { className: "akitable-footer-extra" }, isLoading ? React.createElement(Spin,
|
|
11
|
+
return (React.createElement("div", { "data-testid": "akitable-footer", className: "akitable-footer" },
|
|
12
|
+
extra && (React.createElement("div", { className: "akitable-footer-extra" }, isLoading ? (React.createElement(Spin, { "data-testid": "akitable-footer-extra-loading-skeleton" })) : (extra))),
|
|
13
13
|
React.createElement("div", { className: "ml-auto" },
|
|
14
14
|
React.createElement(AkitablePagination, null))));
|
|
15
15
|
};
|
|
@@ -5,13 +5,40 @@
|
|
|
5
5
|
min-height: 40px;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
.akitable-header-title-container {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: 0.1rem;
|
|
12
|
+
color: var(--color-gray-900);
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
.akitable-header-title {
|
|
9
16
|
font-size: 1.25rem;
|
|
10
17
|
font-weight: bold;
|
|
11
18
|
margin: 0;
|
|
12
19
|
padding: 0;
|
|
13
20
|
line-height: 1;
|
|
14
|
-
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.akitable-header-title-count-skeleton {
|
|
26
|
+
width: 50px;
|
|
27
|
+
height: 20px;
|
|
28
|
+
margin-left: 0.7rem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.akitable-header-title-count {
|
|
32
|
+
font-size: 1.25rem;
|
|
33
|
+
font-weight: bold;
|
|
34
|
+
margin: 0;
|
|
35
|
+
padding: 0;
|
|
36
|
+
line-height: 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.akitable-header-title-description-skeleton {
|
|
40
|
+
width: 120px;
|
|
41
|
+
height: 10px;
|
|
15
42
|
}
|
|
16
43
|
|
|
17
44
|
.akitable-header-description {
|
|
@@ -20,6 +47,11 @@
|
|
|
20
47
|
margin-top: 0.5rem;
|
|
21
48
|
}
|
|
22
49
|
|
|
50
|
+
.akitable-header-extra-content {
|
|
51
|
+
margin-bottom: 1rem;
|
|
52
|
+
color: var(--color-gray-300);
|
|
53
|
+
}
|
|
54
|
+
|
|
23
55
|
.akitable-header-extra {
|
|
24
56
|
margin-left: auto;
|
|
25
57
|
text-align: right;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../src/components/header.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAItB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,eAAO,MAAM,cAAc,UAAW,mBAAmB,
|
|
1
|
+
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../src/components/header.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAItB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,eAAO,MAAM,cAAc,UAAW,mBAAmB,6BA4ExD,CAAC"}
|
|
@@ -11,17 +11,25 @@ export const AkitableHeader = (props) => {
|
|
|
11
11
|
const hasActions = actions && (actions === null || actions === void 0 ? void 0 : actions.length) > 0;
|
|
12
12
|
if (!title && !extra)
|
|
13
13
|
return null;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
React.createElement("h2", { className: "akitable-header-title" },
|
|
17
|
-
|
|
18
|
-
" ",
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
const renderTitle = () => {
|
|
15
|
+
return (React.createElement("div", { className: "akitable-header-title-container" },
|
|
16
|
+
React.createElement("h2", { className: "akitable-header-title" }, title),
|
|
17
|
+
isLoading ? (React.createElement("span", { "data-testid": "akitable-title-loading-skeleton" },
|
|
18
|
+
React.createElement(Skeleton.Button, { active: true, size: "small", className: "ml-1" }))) : (React.createElement("span", { className: "akitable-header-title-count" }, `(${pagination === null || pagination === void 0 ? void 0 : pagination.total})`))));
|
|
19
|
+
};
|
|
20
|
+
const renderTitleDescription = () => {
|
|
21
|
+
const descriptionContent = !(pagination === null || pagination === void 0 ? void 0 : pagination.total)
|
|
22
|
+
? i18n.t('noData')
|
|
23
|
+
: i18n.t('resultsFound', { count: pagination === null || pagination === void 0 ? void 0 : pagination.total });
|
|
24
|
+
return (React.createElement("span", { "data-testid": "akitable-header-description", className: "akitable-header-description" }, descriptionContent));
|
|
25
|
+
};
|
|
26
|
+
return (React.createElement("div", { "data-testid": "akitable-header", className: "akitable-header" },
|
|
27
|
+
!!title && (React.createElement("div", { "data-testid": "akitable-header-title-container" },
|
|
28
|
+
renderTitle(),
|
|
29
|
+
isLoading ? (React.createElement("span", { "data-testid": "akitable-title-description-loading-skeleton" },
|
|
30
|
+
React.createElement(Skeleton.Input, { active: true, size: "small", className: "mt-2" }))) : (renderTitleDescription()))),
|
|
23
31
|
React.createElement("div", { className: "akitable-header-extra" },
|
|
24
|
-
extra && React.createElement("div", { className: "
|
|
25
|
-
!hasActions && (pagination === null || pagination === void 0 ? void 0 : pagination.hasPagination) && (React.createElement("div",
|
|
32
|
+
extra && (React.createElement("div", { "data-testid": "akitable-header-extra-content", className: "akitable-header-extra-content" }, isLoading ? (React.createElement(Spin, { "data-testid": "akitable-header-extra-loading-skeleton" })) : (extra))),
|
|
33
|
+
!hasActions && (pagination === null || pagination === void 0 ? void 0 : pagination.hasPagination) && (React.createElement("div", { "data-testid": "akitable-header-pagination" },
|
|
26
34
|
React.createElement(AkitablePagination, null))))));
|
|
27
35
|
};
|