@akinon/ai-modal-table 1.0.0 → 1.0.2
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/ai-modal-table/__tests__/index.test.js +36 -2
- package/dist/cjs/ai-modal-table/__tests__/index.test.tsx +74 -2
- package/dist/cjs/ai-modal-table/index.d.ts +1 -1
- package/dist/cjs/ai-modal-table/index.d.ts.map +1 -1
- package/dist/cjs/ai-modal-table/index.js +2 -2
- package/dist/cjs/ai-table/__tests__/index.test.js +23 -0
- package/dist/cjs/ai-table/__tests__/index.test.tsx +39 -0
- package/dist/cjs/ai-table/components/__tests__/content.test.js +15 -9
- package/dist/cjs/ai-table/components/__tests__/content.test.tsx +15 -9
- package/dist/cjs/ai-table/components/content.d.ts +2 -1
- package/dist/cjs/ai-table/components/content.d.ts.map +1 -1
- package/dist/cjs/ai-table/components/content.js +11 -5
- package/dist/cjs/ai-table/components/footer.js +1 -1
- package/dist/cjs/ai-table/components/mapper.js +1 -1
- package/dist/cjs/ai-table/index.d.ts +1 -1
- package/dist/cjs/ai-table/index.d.ts.map +1 -1
- package/dist/cjs/ai-table/index.js +3 -3
- package/dist/cjs/types/index.d.ts +4 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/esm/ai-modal-table/__tests__/index.test.js +36 -2
- package/dist/esm/ai-modal-table/__tests__/index.test.tsx +74 -2
- package/dist/esm/ai-modal-table/index.d.ts +1 -1
- package/dist/esm/ai-modal-table/index.d.ts.map +1 -1
- package/dist/esm/ai-modal-table/index.js +2 -2
- package/dist/esm/ai-table/__tests__/index.test.js +23 -0
- package/dist/esm/ai-table/__tests__/index.test.tsx +39 -0
- package/dist/esm/ai-table/components/__tests__/content.test.js +15 -9
- package/dist/esm/ai-table/components/__tests__/content.test.tsx +15 -9
- package/dist/esm/ai-table/components/content.d.ts +2 -1
- package/dist/esm/ai-table/components/content.d.ts.map +1 -1
- package/dist/esm/ai-table/components/content.js +11 -5
- package/dist/esm/ai-table/components/footer.js +1 -1
- package/dist/esm/ai-table/components/mapper.js +1 -1
- package/dist/esm/ai-table/index.d.ts +1 -1
- package/dist/esm/ai-table/index.d.ts.map +1 -1
- package/dist/esm/ai-table/index.js +3 -3
- package/dist/esm/types/index.d.ts +4 -0
- package/dist/esm/types/index.d.ts.map +1 -1
- package/package.json +13 -13
|
@@ -17,8 +17,32 @@ const react_2 = require("react");
|
|
|
17
17
|
const vitest_1 = require("vitest");
|
|
18
18
|
vitest_1.vi.mock('@akinon/ui-theme', async (importOriginal) => {
|
|
19
19
|
const actual = (await importOriginal());
|
|
20
|
-
return Object.assign(Object.assign({}, actual), { useToken: () => ({
|
|
20
|
+
return Object.assign(Object.assign({}, actual), { useToken: () => ({
|
|
21
|
+
token: {
|
|
22
|
+
fontWeight: 400,
|
|
23
|
+
fontWeightStrong: 600,
|
|
24
|
+
fontSizeSM: 12,
|
|
25
|
+
colorTextBase: '#000000',
|
|
26
|
+
colorBgBase: '#ffffff',
|
|
27
|
+
fontSize: 14,
|
|
28
|
+
borderRadius: 4,
|
|
29
|
+
colorPrimary: '#1890ff'
|
|
30
|
+
},
|
|
31
|
+
hashId: 'hash123'
|
|
32
|
+
}) });
|
|
21
33
|
});
|
|
34
|
+
vitest_1.vi.mock('@akinon/ui-select', () => ({
|
|
35
|
+
Select: (_a) => {
|
|
36
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
37
|
+
return (react_2.default.createElement("select", Object.assign({ "data-testid": "select" }, props), children));
|
|
38
|
+
}
|
|
39
|
+
}));
|
|
40
|
+
vitest_1.vi.mock('@akinon/ui-button', () => ({
|
|
41
|
+
Button: (_a) => {
|
|
42
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
43
|
+
return (react_2.default.createElement("button", Object.assign({}, props), children));
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
22
46
|
vitest_1.vi.mock('@akinon/ui-layout', () => ({
|
|
23
47
|
Flex: ({ children }) => react_2.default.createElement("div", { "data-testid": "flex" }, children)
|
|
24
48
|
}));
|
|
@@ -35,7 +59,8 @@ vitest_1.vi.mock('../ai-table', () => ({
|
|
|
35
59
|
react_2.default.createElement("pre", { "data-testid": "ai-table-props" }, JSON.stringify({
|
|
36
60
|
columns: props.columns,
|
|
37
61
|
data: props.data,
|
|
38
|
-
isLoading: props.isLoading
|
|
62
|
+
isLoading: props.isLoading,
|
|
63
|
+
emptyText: props.emptyText
|
|
39
64
|
})))),
|
|
40
65
|
DEFAULT_ROW_KEY: 'id'
|
|
41
66
|
}));
|
|
@@ -56,4 +81,13 @@ const index_1 = require("../index");
|
|
|
56
81
|
react_1.fireEvent.click(react_1.screen.getByTestId('close-button'));
|
|
57
82
|
(0, vitest_1.expect)(onCancel).toHaveBeenCalledTimes(1);
|
|
58
83
|
});
|
|
84
|
+
(0, vitest_1.it)('passes emptyText prop to AiTable when provided', () => {
|
|
85
|
+
const columns = [{ title: 'Name', dataIndex: 'name' }];
|
|
86
|
+
const data = [{ id: 1, name: 'Alice' }];
|
|
87
|
+
const { rerender } = (0, react_1.render)(react_2.default.createElement(index_1.AiModalTable, { description: "My description", columns: columns, data: data, isLoading: true, submitAllLabel: "Submit All", submitSelectedLabel: "Submit Selected", filters: [], selectedRows: [], onChangeSelectedRows: () => { }, isSubmitting: false, onSubmitAllData: () => { }, onSubmitSelectedData: () => { } }));
|
|
88
|
+
(0, vitest_1.expect)(react_1.screen.getByText('My description')).toBeInTheDocument();
|
|
89
|
+
// Re-render with emptyText prop
|
|
90
|
+
rerender(react_2.default.createElement(index_1.AiModalTable, { description: "My description", columns: columns, data: data, isLoading: true, submitAllLabel: "Submit All", submitSelectedLabel: "Submit Selected", filters: [], selectedRows: [], onChangeSelectedRows: () => { }, isSubmitting: false, onSubmitAllData: () => { }, onSubmitSelectedData: () => { }, emptyText: "No data available" }));
|
|
91
|
+
(0, vitest_1.expect)(react_1.screen.getByText('My description')).toBeInTheDocument();
|
|
92
|
+
});
|
|
59
93
|
});
|
|
@@ -8,10 +8,36 @@ vi.mock('@akinon/ui-theme', async importOriginal => {
|
|
|
8
8
|
|
|
9
9
|
return {
|
|
10
10
|
...actual,
|
|
11
|
-
useToken: () => ({
|
|
11
|
+
useToken: () => ({
|
|
12
|
+
token: {
|
|
13
|
+
fontWeight: 400,
|
|
14
|
+
fontWeightStrong: 600,
|
|
15
|
+
fontSizeSM: 12,
|
|
16
|
+
colorTextBase: '#000000',
|
|
17
|
+
colorBgBase: '#ffffff',
|
|
18
|
+
fontSize: 14,
|
|
19
|
+
borderRadius: 4,
|
|
20
|
+
colorPrimary: '#1890ff'
|
|
21
|
+
},
|
|
22
|
+
hashId: 'hash123'
|
|
23
|
+
})
|
|
12
24
|
};
|
|
13
25
|
});
|
|
14
26
|
|
|
27
|
+
vi.mock('@akinon/ui-select', () => ({
|
|
28
|
+
Select: ({ children, ...props }: any) => (
|
|
29
|
+
<select data-testid="select" {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</select>
|
|
32
|
+
)
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
vi.mock('@akinon/ui-button', () => ({
|
|
36
|
+
Button: ({ children, ...props }: any) => (
|
|
37
|
+
<button {...props}>{children}</button>
|
|
38
|
+
)
|
|
39
|
+
}));
|
|
40
|
+
|
|
15
41
|
vi.mock('@akinon/ui-layout', () => ({
|
|
16
42
|
Flex: ({ children }: any) => <div data-testid="flex">{children}</div>
|
|
17
43
|
}));
|
|
@@ -32,7 +58,8 @@ vi.mock('../ai-table', () => ({
|
|
|
32
58
|
{JSON.stringify({
|
|
33
59
|
columns: props.columns,
|
|
34
60
|
data: props.data,
|
|
35
|
-
isLoading: props.isLoading
|
|
61
|
+
isLoading: props.isLoading,
|
|
62
|
+
emptyText: props.emptyText
|
|
36
63
|
})}
|
|
37
64
|
</pre>
|
|
38
65
|
</div>
|
|
@@ -95,4 +122,49 @@ describe('AiModalTable', () => {
|
|
|
95
122
|
fireEvent.click(screen.getByTestId('close-button'));
|
|
96
123
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
97
124
|
});
|
|
125
|
+
|
|
126
|
+
it('passes emptyText prop to AiTable when provided', () => {
|
|
127
|
+
const columns = [{ title: 'Name', dataIndex: 'name' }];
|
|
128
|
+
const data = [{ id: 1, name: 'Alice' }];
|
|
129
|
+
|
|
130
|
+
const { rerender } = render(
|
|
131
|
+
<AiModalTable
|
|
132
|
+
description="My description"
|
|
133
|
+
columns={columns}
|
|
134
|
+
data={data}
|
|
135
|
+
isLoading={true}
|
|
136
|
+
submitAllLabel="Submit All"
|
|
137
|
+
submitSelectedLabel="Submit Selected"
|
|
138
|
+
filters={[]}
|
|
139
|
+
selectedRows={[]}
|
|
140
|
+
onChangeSelectedRows={() => {}}
|
|
141
|
+
isSubmitting={false}
|
|
142
|
+
onSubmitAllData={() => {}}
|
|
143
|
+
onSubmitSelectedData={() => {}}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
148
|
+
|
|
149
|
+
// Re-render with emptyText prop
|
|
150
|
+
rerender(
|
|
151
|
+
<AiModalTable
|
|
152
|
+
description="My description"
|
|
153
|
+
columns={columns}
|
|
154
|
+
data={data}
|
|
155
|
+
isLoading={true}
|
|
156
|
+
submitAllLabel="Submit All"
|
|
157
|
+
submitSelectedLabel="Submit Selected"
|
|
158
|
+
filters={[]}
|
|
159
|
+
selectedRows={[]}
|
|
160
|
+
onChangeSelectedRows={() => {}}
|
|
161
|
+
isSubmitting={false}
|
|
162
|
+
onSubmitAllData={() => {}}
|
|
163
|
+
onSubmitSelectedData={() => {}}
|
|
164
|
+
emptyText="No data available"
|
|
165
|
+
/>
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
169
|
+
});
|
|
98
170
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { AiModalTableProps } from '../types';
|
|
3
|
-
export declare const AiModalTable: ({ columns, customActionButtons, data, description, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, ...modalProps }: AiModalTableProps) => React.JSX.Element;
|
|
3
|
+
export declare const AiModalTable: ({ columns, customActionButtons, data, description, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText, ...modalProps }: AiModalTableProps) => React.JSX.Element;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-modal-table/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-modal-table/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,gSAqB1B,iBAAiB,sBAqEnB,CAAC"}
|
|
@@ -22,7 +22,7 @@ const React = require("react");
|
|
|
22
22
|
const ai_table_1 = require("../ai-table");
|
|
23
23
|
const constants_1 = require("../ai-table/constants");
|
|
24
24
|
const AiModalTable = (_a) => {
|
|
25
|
-
var { columns = [], customActionButtons, data = [], description, editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = constants_1.DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName } = _a, modalProps = __rest(_a, ["columns", "customActionButtons", "data", "description", "editDataIndexes", "filters", "isLoading", "isSubmitting", "onChangeSelectedRows", "onEdit", "onSubmitAllData", "onSubmitSelectedData", "rowKey", "selectedRows", "submitAllLabel", "submitSelectedLabel", "mapperConfig", "tableClassName"]);
|
|
25
|
+
var { columns = [], customActionButtons, data = [], description, editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = constants_1.DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText } = _a, modalProps = __rest(_a, ["columns", "customActionButtons", "data", "description", "editDataIndexes", "filters", "isLoading", "isSubmitting", "onChangeSelectedRows", "onEdit", "onSubmitAllData", "onSubmitSelectedData", "rowKey", "selectedRows", "submitAllLabel", "submitSelectedLabel", "mapperConfig", "tableClassName", "emptyText"]);
|
|
26
26
|
const { onCancel, className } = modalProps, restModalProps = __rest(modalProps, ["onCancel", "className"]);
|
|
27
27
|
const { getPrefixCls, theme } = React.useContext(antd_1.ConfigProvider.ConfigContext);
|
|
28
28
|
const { token, hashId } = (0, ui_theme_1.useToken)();
|
|
@@ -49,6 +49,6 @@ const AiModalTable = (_a) => {
|
|
|
49
49
|
return useStyle(React.createElement(ui_modal_1.Modal, Object.assign({ className: (0, classnames_1.default)(baseCls, hashId, className), footer: null, onCancel: handleCancel, centered: true, destroyOnClose: true, width: 1200 }, restModalProps),
|
|
50
50
|
React.createElement(ui_layout_1.Flex, { gap: 10, vertical: true },
|
|
51
51
|
React.createElement("div", { className: "text-neutral-50 text-sm mb-2" }, description),
|
|
52
|
-
React.createElement(ai_table_1.AiTable, { columns: columns, customActionButtons: customActionButtons, data: data, editDataIndexes: editDataIndexes, filters: filters, isLoading: isLoading, isSubmitting: isSubmitting, onChangeSelectedRows: onChangeSelectedRows, onEdit: onEdit, onSubmitAllData: onSubmitAllData, onSubmitSelectedData: onSubmitSelectedData, rowKey: rowKey, selectedRows: selectedRows, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, mapperConfig: mapperConfig, tableClassName: tableClassName }))));
|
|
52
|
+
React.createElement(ai_table_1.AiTable, { columns: columns, customActionButtons: customActionButtons, data: data, editDataIndexes: editDataIndexes, filters: filters, isLoading: isLoading, isSubmitting: isSubmitting, onChangeSelectedRows: onChangeSelectedRows, onEdit: onEdit, onSubmitAllData: onSubmitAllData, onSubmitSelectedData: onSubmitSelectedData, rowKey: rowKey, selectedRows: selectedRows, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, mapperConfig: mapperConfig, tableClassName: tableClassName, emptyText: emptyText }))));
|
|
53
53
|
};
|
|
54
54
|
exports.AiModalTable = AiModalTable;
|
|
@@ -345,4 +345,27 @@ vitest_1.vi.mock('@akinon/ui-layout', () => ({
|
|
|
345
345
|
(0, vitest_1.expect)(react_1.screen.getByTestId('table-content')).toBeInTheDocument();
|
|
346
346
|
});
|
|
347
347
|
});
|
|
348
|
+
(0, vitest_1.describe)('Empty Text', () => {
|
|
349
|
+
(0, vitest_1.it)('should render table without emptyText prop', () => {
|
|
350
|
+
(0, react_1.render)(React.createElement(index_1.AiTable, Object.assign({}, defaultProps)));
|
|
351
|
+
(0, vitest_1.expect)(react_1.screen.getByTestId('table-content')).toBeInTheDocument();
|
|
352
|
+
});
|
|
353
|
+
(0, vitest_1.it)('should pass emptyText prop to TableContent when provided', () => {
|
|
354
|
+
const customEmptyText = 'No data found';
|
|
355
|
+
(0, react_1.render)(React.createElement(index_1.AiTable, Object.assign({}, defaultProps, { emptyText: customEmptyText })));
|
|
356
|
+
(0, vitest_1.expect)(react_1.screen.getByTestId('table-content')).toBeInTheDocument();
|
|
357
|
+
});
|
|
358
|
+
(0, vitest_1.it)('should handle React nodes as emptyText', () => {
|
|
359
|
+
const customEmptyNode = (React.createElement("div", { "data-testid": "custom-empty-message" },
|
|
360
|
+
React.createElement("p", null, "No results available")));
|
|
361
|
+
(0, react_1.render)(React.createElement(index_1.AiTable, Object.assign({}, defaultProps, { emptyText: customEmptyNode })));
|
|
362
|
+
(0, vitest_1.expect)(react_1.screen.getByTestId('table-content')).toBeInTheDocument();
|
|
363
|
+
});
|
|
364
|
+
(0, vitest_1.it)('should work with empty data and custom emptyText', () => {
|
|
365
|
+
const customEmptyText = 'The table is empty';
|
|
366
|
+
(0, react_1.render)(React.createElement(index_1.AiTable, Object.assign({}, defaultProps, { data: [], emptyText: customEmptyText })));
|
|
367
|
+
(0, vitest_1.expect)(react_1.screen.getByTestId('table-content')).toBeInTheDocument();
|
|
368
|
+
(0, vitest_1.expect)(react_1.screen.queryByTestId('row-1')).not.toBeInTheDocument();
|
|
369
|
+
});
|
|
370
|
+
});
|
|
348
371
|
});
|
|
@@ -569,4 +569,43 @@ describe('AiTable', () => {
|
|
|
569
569
|
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
570
570
|
});
|
|
571
571
|
});
|
|
572
|
+
|
|
573
|
+
describe('Empty Text', () => {
|
|
574
|
+
it('should render table without emptyText prop', () => {
|
|
575
|
+
render(<AiTable {...defaultProps} />);
|
|
576
|
+
|
|
577
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
it('should pass emptyText prop to TableContent when provided', () => {
|
|
581
|
+
const customEmptyText = 'No data found';
|
|
582
|
+
|
|
583
|
+
render(<AiTable {...defaultProps} emptyText={customEmptyText} />);
|
|
584
|
+
|
|
585
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it('should handle React nodes as emptyText', () => {
|
|
589
|
+
const customEmptyNode = (
|
|
590
|
+
<div data-testid="custom-empty-message">
|
|
591
|
+
<p>No results available</p>
|
|
592
|
+
</div>
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
render(<AiTable {...defaultProps} emptyText={customEmptyNode} />);
|
|
596
|
+
|
|
597
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('should work with empty data and custom emptyText', () => {
|
|
601
|
+
const customEmptyText = 'The table is empty';
|
|
602
|
+
|
|
603
|
+
render(
|
|
604
|
+
<AiTable {...defaultProps} data={[]} emptyText={customEmptyText} />
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
608
|
+
expect(screen.queryByTestId('row-1')).not.toBeInTheDocument();
|
|
609
|
+
});
|
|
610
|
+
});
|
|
572
611
|
});
|
|
@@ -337,12 +337,13 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
337
337
|
});
|
|
338
338
|
(0, vitest_1.it)('should apply collapsed style when not expanded', () => {
|
|
339
339
|
renderComponent({ expandedRows: [] });
|
|
340
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
340
341
|
const expandIcons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
341
342
|
(0, vitest_1.expect)(expandIcons[0].className).toContain('ai-modal-table__icon--collapsed');
|
|
342
343
|
});
|
|
343
344
|
(0, vitest_1.it)('should not apply collapsed style when expanded', () => {
|
|
344
|
-
renderComponent({ expandedRows: [
|
|
345
|
-
//
|
|
345
|
+
renderComponent({ expandedRows: [2] });
|
|
346
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
346
347
|
const icons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
347
348
|
(0, vitest_1.expect)(icons[0].className).not.toContain('ai-modal-table__icon--collapsed');
|
|
348
349
|
});
|
|
@@ -353,9 +354,10 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
353
354
|
});
|
|
354
355
|
(0, vitest_1.expect)(react_1.screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
355
356
|
});
|
|
356
|
-
(0, vitest_1.it)('should render
|
|
357
|
+
(0, vitest_1.it)('should render expand button for rows with multiple mapper items', () => {
|
|
357
358
|
renderComponent();
|
|
358
|
-
|
|
359
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
360
|
+
(0, vitest_1.expect)(react_1.screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
359
361
|
});
|
|
360
362
|
});
|
|
361
363
|
(0, vitest_1.describe)('Mapper Column', () => {
|
|
@@ -552,8 +554,10 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
552
554
|
});
|
|
553
555
|
(0, vitest_1.it)('should render expand button in first column', () => {
|
|
554
556
|
renderComponent();
|
|
555
|
-
|
|
556
|
-
const
|
|
557
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
558
|
+
const rows = react_1.screen.getAllByRole('row');
|
|
559
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
560
|
+
const firstCell = (0, react_1.within)(rowWithExpandButton).getAllByRole('cell')[0];
|
|
557
561
|
(0, vitest_1.expect)(firstCell).toContainElement(react_1.screen.getAllByTestId('icon-chevron_down')[0]);
|
|
558
562
|
});
|
|
559
563
|
(0, vitest_1.it)('should handle missing optional data gracefully', () => {
|
|
@@ -788,18 +792,20 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
788
792
|
});
|
|
789
793
|
const expandButtons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
790
794
|
react_1.fireEvent.click(expandButtons[0]);
|
|
791
|
-
(
|
|
795
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
796
|
+
(0, vitest_1.expect)(onToggleExpand).toHaveBeenCalledWith(2);
|
|
792
797
|
});
|
|
793
798
|
(0, vitest_1.it)('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
794
799
|
const onToggleExpand = vitest_1.vi.fn();
|
|
795
800
|
renderComponent({
|
|
796
|
-
expandedRows: [
|
|
801
|
+
expandedRows: [2],
|
|
797
802
|
onToggleExpand
|
|
798
803
|
});
|
|
799
804
|
const expandButtons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
800
805
|
react_1.fireEvent.click(expandButtons[0]);
|
|
801
806
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
802
|
-
(
|
|
807
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
808
|
+
(0, vitest_1.expect)(onToggleExpand).toHaveBeenCalledWith(2);
|
|
803
809
|
});
|
|
804
810
|
(0, vitest_1.it)('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
805
811
|
const onAddItem = vitest_1.vi.fn();
|
|
@@ -434,6 +434,7 @@ describe('TableContent', () => {
|
|
|
434
434
|
|
|
435
435
|
it('should apply collapsed style when not expanded', () => {
|
|
436
436
|
renderComponent({ expandedRows: [] });
|
|
437
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
437
438
|
const expandIcons = screen.getAllByTestId('icon-chevron_down');
|
|
438
439
|
expect(expandIcons[0].className).toContain(
|
|
439
440
|
'ai-modal-table__icon--collapsed'
|
|
@@ -441,8 +442,8 @@ describe('TableContent', () => {
|
|
|
441
442
|
});
|
|
442
443
|
|
|
443
444
|
it('should not apply collapsed style when expanded', () => {
|
|
444
|
-
renderComponent({ expandedRows: [
|
|
445
|
-
//
|
|
445
|
+
renderComponent({ expandedRows: [2] });
|
|
446
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
446
447
|
const icons = screen.getAllByTestId('icon-chevron_down');
|
|
447
448
|
expect(icons[0].className).not.toContain(
|
|
448
449
|
'ai-modal-table__icon--collapsed'
|
|
@@ -457,9 +458,10 @@ describe('TableContent', () => {
|
|
|
457
458
|
expect(screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
458
459
|
});
|
|
459
460
|
|
|
460
|
-
it('should render
|
|
461
|
+
it('should render expand button for rows with multiple mapper items', () => {
|
|
461
462
|
renderComponent();
|
|
462
|
-
|
|
463
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
464
|
+
expect(screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
463
465
|
});
|
|
464
466
|
});
|
|
465
467
|
|
|
@@ -691,8 +693,10 @@ describe('TableContent', () => {
|
|
|
691
693
|
|
|
692
694
|
it('should render expand button in first column', () => {
|
|
693
695
|
renderComponent();
|
|
694
|
-
|
|
695
|
-
const
|
|
696
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
697
|
+
const rows = screen.getAllByRole('row');
|
|
698
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
699
|
+
const firstCell = within(rowWithExpandButton).getAllByRole('cell')[0];
|
|
696
700
|
expect(firstCell).toContainElement(
|
|
697
701
|
screen.getAllByTestId('icon-chevron_down')[0]
|
|
698
702
|
);
|
|
@@ -986,13 +990,14 @@ describe('TableContent', () => {
|
|
|
986
990
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
987
991
|
fireEvent.click(expandButtons[0]);
|
|
988
992
|
|
|
989
|
-
|
|
993
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
994
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
990
995
|
});
|
|
991
996
|
|
|
992
997
|
it('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
993
998
|
const onToggleExpand = vi.fn();
|
|
994
999
|
renderComponent({
|
|
995
|
-
expandedRows: [
|
|
1000
|
+
expandedRows: [2],
|
|
996
1001
|
onToggleExpand
|
|
997
1002
|
});
|
|
998
1003
|
|
|
@@ -1000,7 +1005,8 @@ describe('TableContent', () => {
|
|
|
1000
1005
|
fireEvent.click(expandButtons[0]);
|
|
1001
1006
|
|
|
1002
1007
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
1003
|
-
|
|
1008
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
1009
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
1004
1010
|
});
|
|
1005
1011
|
|
|
1006
1012
|
it('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
@@ -5,7 +5,8 @@ interface TableContentProps extends Omit<TableBaseProps, 'onChangeSelectedRows'
|
|
|
5
5
|
expandedRows: Array<number | string>;
|
|
6
6
|
onToggleExpand: (rowId: number | string) => void;
|
|
7
7
|
rowKey: string;
|
|
8
|
+
emptyText?: React.ReactNode;
|
|
8
9
|
}
|
|
9
|
-
export declare const TableContent: ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig }: TableContentProps) => React.JSX.Element;
|
|
10
|
+
export declare const TableContent: ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig, emptyText }: TableContentProps) => React.JSX.Element;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/components/content.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ9E,UAAU,iBACR,SAAQ,IAAI,CAAC,cAAc,EAAE,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/components/content.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ9E,UAAU,iBACR,SAAQ,IAAI,CAAC,cAAc,EAAE,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY,GAAI,iKAa1B,iBAAiB,sBA2hBnB,CAAC"}
|
|
@@ -16,7 +16,7 @@ const i18n_1 = require("../i18n");
|
|
|
16
16
|
const mapper_1 = require("./mapper");
|
|
17
17
|
const row_actions_1 = require("./row-actions");
|
|
18
18
|
const { t } = i18n_1.i18n;
|
|
19
|
-
const TableContent = ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig }) => {
|
|
19
|
+
const TableContent = ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig, emptyText }) => {
|
|
20
20
|
const { getPrefixCls, theme } = React.useContext(antd_1.ConfigProvider.ConfigContext);
|
|
21
21
|
const { token, hashId } = (0, ui_theme_1.useToken)();
|
|
22
22
|
const baseCls = getPrefixCls('ai-modal-table');
|
|
@@ -113,7 +113,8 @@ const TableContent = ({ columns, customActionButtons, data, editDataIndexes, exp
|
|
|
113
113
|
};
|
|
114
114
|
const renderMapper = ({ rowId, value, dataIndex }) => {
|
|
115
115
|
const isExpanded = isRowExpanded(rowId);
|
|
116
|
-
const
|
|
116
|
+
const hasMultipleItems = value.length > 1;
|
|
117
|
+
const displayedValues = hasMultipleItems && !isExpanded ? value.slice(0, 1) : value;
|
|
117
118
|
const handleExpand = () => {
|
|
118
119
|
if (!isExpanded) {
|
|
119
120
|
onToggleExpand(rowId);
|
|
@@ -185,10 +186,15 @@ const TableContent = ({ columns, customActionButtons, data, editDataIndexes, exp
|
|
|
185
186
|
}), onClick: handleClick }));
|
|
186
187
|
};
|
|
187
188
|
const renderTableCells = (row, rowId) => {
|
|
189
|
+
const mapperValue = hasMapper && mapperDataIndex ? row[mapperDataIndex] : null;
|
|
190
|
+
const hasMultipleMapperItems = Array.isArray(mapperValue) && mapperValue.length > 1;
|
|
188
191
|
return columns.map((column, colIndex) => {
|
|
189
192
|
const isFirstColumn = colIndex === 0;
|
|
190
193
|
return (React.createElement("td", { className: "text-blue-50 font-normal text-base whitespace-nowrap py-0 px-5", key: `cell-${rowId}-${column.dataIndex || colIndex}` },
|
|
191
|
-
isFirstColumn &&
|
|
194
|
+
isFirstColumn &&
|
|
195
|
+
hasMapper &&
|
|
196
|
+
hasMultipleMapperItems &&
|
|
197
|
+
renderExpandButton(rowId),
|
|
192
198
|
renderCellValue({
|
|
193
199
|
column,
|
|
194
200
|
row,
|
|
@@ -216,7 +222,7 @@ const TableContent = ({ columns, customActionButtons, data, editDataIndexes, exp
|
|
|
216
222
|
};
|
|
217
223
|
const renderEmptyRow = () => {
|
|
218
224
|
return (React.createElement("tr", null,
|
|
219
|
-
React.createElement("td", { className: "font-normal text-center text-gray-500 text-sm py-10 px-4", colSpan: columns.length + 1 }, t('filter.no.match'))));
|
|
225
|
+
React.createElement("td", { className: "font-normal text-center text-gray-500 text-sm py-10 px-4", colSpan: columns.length + 1 }, emptyText !== null && emptyText !== void 0 ? emptyText : t('filter.no.match'))));
|
|
220
226
|
};
|
|
221
227
|
const renderGradientOverlay = () => {
|
|
222
228
|
return (React.createElement(React.Fragment, null,
|
|
@@ -301,7 +307,7 @@ const TableContent = ({ columns, customActionButtons, data, editDataIndexes, exp
|
|
|
301
307
|
return useStyle(React.createElement("div", { className: "bg-ebonyClay-450 rounded-lg overflow-hidden" },
|
|
302
308
|
React.createElement("div", { className: `${baseCls}__table-wrapper ${hashId} overflow-x-auto overflow-y-auto` },
|
|
303
309
|
React.createElement("div", { className: "relative" },
|
|
304
|
-
renderGradientOverlay(),
|
|
310
|
+
data.length > 0 && renderGradientOverlay(),
|
|
305
311
|
React.createElement("table", { ref: tableRef, className: `${baseCls}__table-element ${hashId} w-full bg-ebonyClay-450` },
|
|
306
312
|
React.createElement("thead", null, renderTableHeaders()),
|
|
307
313
|
React.createElement("tbody", null, renderTableRows()))))));
|
|
@@ -15,7 +15,7 @@ const TableFooter = ({ isSubmitting, selectedCount, submitAllLabel, submitSelect
|
|
|
15
15
|
onSubmitSelected();
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
-
return (React.createElement(ui_layout_1.Flex, { justify: "end", gap: 10 },
|
|
18
|
+
return (React.createElement(ui_layout_1.Flex, { justify: "end", gap: 10, className: "mt-4" },
|
|
19
19
|
React.createElement(ui_button_1.Button, { className: "uppercase font-semibold", disabled: isSubmitting, loading: isSubmitting, onClick: handleSubmitAll }, submitAllLabel),
|
|
20
20
|
React.createElement(ui_button_1.Button, { className: "uppercase font-semibold", disabled: selectedCount === 0 || isSubmitting, loading: isSubmitting, onClick: handleSubmitSelected, type: "primary" },
|
|
21
21
|
submitSelectedLabel,
|
|
@@ -6,7 +6,7 @@ const ui_layout_1 = require("@akinon/ui-layout");
|
|
|
6
6
|
const React = require("react");
|
|
7
7
|
const render_mapper_fields_1 = require("../utils/render-mapper-fields");
|
|
8
8
|
const TableMapper = ({ values, handleAddItem, handleRemoveItem, handleItemChange }) => {
|
|
9
|
-
return (React.createElement(ui_layout_1.Flex, { gap: 5, vertical: true, rootClassName: "py-
|
|
9
|
+
return (React.createElement(ui_layout_1.Flex, { gap: 5, vertical: true, rootClassName: "py-3" }, values.map((row, index) => {
|
|
10
10
|
return (React.createElement(ui_layout_1.Flex, { gap: 12, align: "center", key: index },
|
|
11
11
|
(0, render_mapper_fields_1.renderMapperRow)({
|
|
12
12
|
row,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { AiTableProps } from '../types';
|
|
3
|
-
export declare const AiTable: ({ columns, customActionButtons, data, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName }: AiTableProps) => React.JSX.Element;
|
|
3
|
+
export declare const AiTable: ({ columns, customActionButtons, data, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText }: AiTableProps) => React.JSX.Element;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-table/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAe7C,eAAO,MAAM,OAAO,GAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-table/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAe7C,eAAO,MAAM,OAAO,GAAI,oQAmBrB,YAAY,sBA6Hd,CAAC"}
|
|
@@ -13,7 +13,7 @@ const constants_1 = require("./constants");
|
|
|
13
13
|
const i18n_1 = require("./i18n");
|
|
14
14
|
const data_format_1 = require("./utils/data-format");
|
|
15
15
|
const { t } = i18n_1.i18n;
|
|
16
|
-
const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = constants_1.DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName }) => {
|
|
16
|
+
const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = constants_1.DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText }) => {
|
|
17
17
|
const [currentPage, setCurrentPage] = React.useState(constants_1.DEFAULT_CURRENT_PAGE);
|
|
18
18
|
const [pageSize, setPageSize] = React.useState(constants_1.DEFAULT_PAGE_SIZE);
|
|
19
19
|
const [filterValues, setFilterValues] = React.useState({});
|
|
@@ -57,7 +57,7 @@ const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes
|
|
|
57
57
|
return (React.createElement("div", { className: "w-full h-80" },
|
|
58
58
|
React.createElement(ui_ai_spinner_1.AiSpinner, null)));
|
|
59
59
|
}
|
|
60
|
-
return (React.createElement(ui_layout_1.Flex, { gap:
|
|
60
|
+
return (React.createElement(ui_layout_1.Flex, { gap: 18, vertical: true, className: tableClassName },
|
|
61
61
|
React.createElement(ui_layout_1.Flex, { justify: "space-between", align: "center" },
|
|
62
62
|
React.createElement(ui_layout_1.Flex, { align: "center", gap: 22 },
|
|
63
63
|
React.createElement(filters_1.TableFilters, { filters: filters, filterValues: filterValues, onFilterChange: handleFilterChange }),
|
|
@@ -65,7 +65,7 @@ const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes
|
|
|
65
65
|
React.createElement(ui_button_1.Button, { size: "small", onClick: handleExpandAll }, t('expand.all')),
|
|
66
66
|
React.createElement(ui_button_1.Button, { size: "small", onClick: handleCollapseAll }, t('collapse.all'))))),
|
|
67
67
|
React.createElement(pagination_1.TablePagination, { currentPage: currentPage, onPageChange: handlePageChange, onPageSizeChange: handlePageSizeChange, pageSize: pageSize, total: filteredData.length })),
|
|
68
|
-
React.createElement(content_1.TableContent, { columns: columns, customActionButtons: customActionButtons, data: paginatedData, editDataIndexes: editDataIndexes, expandedRows: expandedRows, onEdit: onEdit, onToggleExpand: handleToggleExpand, onToggleSelection: handleToggleSelection, rowKey: rowKey, selectedRows: selectedRows, mapperConfig: mapperConfig }),
|
|
68
|
+
React.createElement(content_1.TableContent, { columns: columns, customActionButtons: customActionButtons, data: paginatedData, editDataIndexes: editDataIndexes, emptyText: emptyText, expandedRows: expandedRows, onEdit: onEdit, onToggleExpand: handleToggleExpand, onToggleSelection: handleToggleSelection, rowKey: rowKey, selectedRows: selectedRows, mapperConfig: mapperConfig }),
|
|
69
69
|
React.createElement(footer_1.TableFooter, { isSubmitting: isSubmitting, selectedCount: selectedRows.length, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, onSubmitAll: onSubmitAllData, onSubmitSelected: onSubmitSelectedData })));
|
|
70
70
|
};
|
|
71
71
|
exports.AiTable = AiTable;
|
|
@@ -97,6 +97,10 @@ export interface TableBaseProps {
|
|
|
97
97
|
* CSS class name to apply to the table wrapper element
|
|
98
98
|
*/
|
|
99
99
|
tableClassName?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Custom text or node to display when no data matches the filters. Defaults to "No matching results found".
|
|
102
|
+
*/
|
|
103
|
+
emptyText?: React.ReactNode;
|
|
100
104
|
}
|
|
101
105
|
export interface AiTableProps extends TableBaseProps {
|
|
102
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,KAAK,eAAe,GAClB,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAAG,CAAC,EACpC,KAAK,EACL,GAAG,EACH,KAAK,EACN,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,eAAe,CAAC;CACxB,KAAK,IAAI,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;CACxB,CAAC;AACF,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,KAAK,EAAE,eAAe,CAAC;QACvB,IAAI,EAAE,eAAe,CAAC;QACtB,OAAO,CAAC,EAAE,sBAAsB,EAAE,CAAC;KACpC,CAAC;CACH;AAED,KAAK,MAAM,GAAG;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,MAAM,GAAG;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;CAC/E,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAE5D;;OAEG;IACH,YAAY,EAAE,CAAC,EACb,EAAE,EACF,SAAS,EACT,KAAK,EACN,EAAE;QACD,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,IAAI,CAAC;IAEX;;OAEG;IACH,YAAY,EAAE,CACZ,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,KACjC,IAAI,CAAC;IAEV;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAEhC;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAExE;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAElE;;OAEG;IACH,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAErC;;OAEG;IACH,oBAAoB,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAE7D;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,8 +15,32 @@ import React from 'react';
|
|
|
15
15
|
import { describe, expect, it, vi } from 'vitest';
|
|
16
16
|
vi.mock('@akinon/ui-theme', async (importOriginal) => {
|
|
17
17
|
const actual = (await importOriginal());
|
|
18
|
-
return Object.assign(Object.assign({}, actual), { useToken: () => ({
|
|
18
|
+
return Object.assign(Object.assign({}, actual), { useToken: () => ({
|
|
19
|
+
token: {
|
|
20
|
+
fontWeight: 400,
|
|
21
|
+
fontWeightStrong: 600,
|
|
22
|
+
fontSizeSM: 12,
|
|
23
|
+
colorTextBase: '#000000',
|
|
24
|
+
colorBgBase: '#ffffff',
|
|
25
|
+
fontSize: 14,
|
|
26
|
+
borderRadius: 4,
|
|
27
|
+
colorPrimary: '#1890ff'
|
|
28
|
+
},
|
|
29
|
+
hashId: 'hash123'
|
|
30
|
+
}) });
|
|
19
31
|
});
|
|
32
|
+
vi.mock('@akinon/ui-select', () => ({
|
|
33
|
+
Select: (_a) => {
|
|
34
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
35
|
+
return (React.createElement("select", Object.assign({ "data-testid": "select" }, props), children));
|
|
36
|
+
}
|
|
37
|
+
}));
|
|
38
|
+
vi.mock('@akinon/ui-button', () => ({
|
|
39
|
+
Button: (_a) => {
|
|
40
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
41
|
+
return (React.createElement("button", Object.assign({}, props), children));
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
20
44
|
vi.mock('@akinon/ui-layout', () => ({
|
|
21
45
|
Flex: ({ children }) => React.createElement("div", { "data-testid": "flex" }, children)
|
|
22
46
|
}));
|
|
@@ -33,7 +57,8 @@ vi.mock('../ai-table', () => ({
|
|
|
33
57
|
React.createElement("pre", { "data-testid": "ai-table-props" }, JSON.stringify({
|
|
34
58
|
columns: props.columns,
|
|
35
59
|
data: props.data,
|
|
36
|
-
isLoading: props.isLoading
|
|
60
|
+
isLoading: props.isLoading,
|
|
61
|
+
emptyText: props.emptyText
|
|
37
62
|
})))),
|
|
38
63
|
DEFAULT_ROW_KEY: 'id'
|
|
39
64
|
}));
|
|
@@ -54,4 +79,13 @@ describe('AiModalTable', () => {
|
|
|
54
79
|
fireEvent.click(screen.getByTestId('close-button'));
|
|
55
80
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
56
81
|
});
|
|
82
|
+
it('passes emptyText prop to AiTable when provided', () => {
|
|
83
|
+
const columns = [{ title: 'Name', dataIndex: 'name' }];
|
|
84
|
+
const data = [{ id: 1, name: 'Alice' }];
|
|
85
|
+
const { rerender } = render(React.createElement(AiModalTable, { description: "My description", columns: columns, data: data, isLoading: true, submitAllLabel: "Submit All", submitSelectedLabel: "Submit Selected", filters: [], selectedRows: [], onChangeSelectedRows: () => { }, isSubmitting: false, onSubmitAllData: () => { }, onSubmitSelectedData: () => { } }));
|
|
86
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
87
|
+
// Re-render with emptyText prop
|
|
88
|
+
rerender(React.createElement(AiModalTable, { description: "My description", columns: columns, data: data, isLoading: true, submitAllLabel: "Submit All", submitSelectedLabel: "Submit Selected", filters: [], selectedRows: [], onChangeSelectedRows: () => { }, isSubmitting: false, onSubmitAllData: () => { }, onSubmitSelectedData: () => { }, emptyText: "No data available" }));
|
|
89
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
90
|
+
});
|
|
57
91
|
});
|
|
@@ -8,10 +8,36 @@ vi.mock('@akinon/ui-theme', async importOriginal => {
|
|
|
8
8
|
|
|
9
9
|
return {
|
|
10
10
|
...actual,
|
|
11
|
-
useToken: () => ({
|
|
11
|
+
useToken: () => ({
|
|
12
|
+
token: {
|
|
13
|
+
fontWeight: 400,
|
|
14
|
+
fontWeightStrong: 600,
|
|
15
|
+
fontSizeSM: 12,
|
|
16
|
+
colorTextBase: '#000000',
|
|
17
|
+
colorBgBase: '#ffffff',
|
|
18
|
+
fontSize: 14,
|
|
19
|
+
borderRadius: 4,
|
|
20
|
+
colorPrimary: '#1890ff'
|
|
21
|
+
},
|
|
22
|
+
hashId: 'hash123'
|
|
23
|
+
})
|
|
12
24
|
};
|
|
13
25
|
});
|
|
14
26
|
|
|
27
|
+
vi.mock('@akinon/ui-select', () => ({
|
|
28
|
+
Select: ({ children, ...props }: any) => (
|
|
29
|
+
<select data-testid="select" {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</select>
|
|
32
|
+
)
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
vi.mock('@akinon/ui-button', () => ({
|
|
36
|
+
Button: ({ children, ...props }: any) => (
|
|
37
|
+
<button {...props}>{children}</button>
|
|
38
|
+
)
|
|
39
|
+
}));
|
|
40
|
+
|
|
15
41
|
vi.mock('@akinon/ui-layout', () => ({
|
|
16
42
|
Flex: ({ children }: any) => <div data-testid="flex">{children}</div>
|
|
17
43
|
}));
|
|
@@ -32,7 +58,8 @@ vi.mock('../ai-table', () => ({
|
|
|
32
58
|
{JSON.stringify({
|
|
33
59
|
columns: props.columns,
|
|
34
60
|
data: props.data,
|
|
35
|
-
isLoading: props.isLoading
|
|
61
|
+
isLoading: props.isLoading,
|
|
62
|
+
emptyText: props.emptyText
|
|
36
63
|
})}
|
|
37
64
|
</pre>
|
|
38
65
|
</div>
|
|
@@ -95,4 +122,49 @@ describe('AiModalTable', () => {
|
|
|
95
122
|
fireEvent.click(screen.getByTestId('close-button'));
|
|
96
123
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
97
124
|
});
|
|
125
|
+
|
|
126
|
+
it('passes emptyText prop to AiTable when provided', () => {
|
|
127
|
+
const columns = [{ title: 'Name', dataIndex: 'name' }];
|
|
128
|
+
const data = [{ id: 1, name: 'Alice' }];
|
|
129
|
+
|
|
130
|
+
const { rerender } = render(
|
|
131
|
+
<AiModalTable
|
|
132
|
+
description="My description"
|
|
133
|
+
columns={columns}
|
|
134
|
+
data={data}
|
|
135
|
+
isLoading={true}
|
|
136
|
+
submitAllLabel="Submit All"
|
|
137
|
+
submitSelectedLabel="Submit Selected"
|
|
138
|
+
filters={[]}
|
|
139
|
+
selectedRows={[]}
|
|
140
|
+
onChangeSelectedRows={() => {}}
|
|
141
|
+
isSubmitting={false}
|
|
142
|
+
onSubmitAllData={() => {}}
|
|
143
|
+
onSubmitSelectedData={() => {}}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
148
|
+
|
|
149
|
+
// Re-render with emptyText prop
|
|
150
|
+
rerender(
|
|
151
|
+
<AiModalTable
|
|
152
|
+
description="My description"
|
|
153
|
+
columns={columns}
|
|
154
|
+
data={data}
|
|
155
|
+
isLoading={true}
|
|
156
|
+
submitAllLabel="Submit All"
|
|
157
|
+
submitSelectedLabel="Submit Selected"
|
|
158
|
+
filters={[]}
|
|
159
|
+
selectedRows={[]}
|
|
160
|
+
onChangeSelectedRows={() => {}}
|
|
161
|
+
isSubmitting={false}
|
|
162
|
+
onSubmitAllData={() => {}}
|
|
163
|
+
onSubmitSelectedData={() => {}}
|
|
164
|
+
emptyText="No data available"
|
|
165
|
+
/>
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
expect(screen.getByText('My description')).toBeInTheDocument();
|
|
169
|
+
});
|
|
98
170
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { AiModalTableProps } from '../types';
|
|
3
|
-
export declare const AiModalTable: ({ columns, customActionButtons, data, description, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, ...modalProps }: AiModalTableProps) => React.JSX.Element;
|
|
3
|
+
export declare const AiModalTable: ({ columns, customActionButtons, data, description, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText, ...modalProps }: AiModalTableProps) => React.JSX.Element;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-modal-table/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-modal-table/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,gSAqB1B,iBAAiB,sBAqEnB,CAAC"}
|
|
@@ -19,7 +19,7 @@ import * as React from 'react';
|
|
|
19
19
|
import { AiTable } from '../ai-table';
|
|
20
20
|
import { DEFAULT_ROW_KEY } from '../ai-table/constants';
|
|
21
21
|
export const AiModalTable = (_a) => {
|
|
22
|
-
var { columns = [], customActionButtons, data = [], description, editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName } = _a, modalProps = __rest(_a, ["columns", "customActionButtons", "data", "description", "editDataIndexes", "filters", "isLoading", "isSubmitting", "onChangeSelectedRows", "onEdit", "onSubmitAllData", "onSubmitSelectedData", "rowKey", "selectedRows", "submitAllLabel", "submitSelectedLabel", "mapperConfig", "tableClassName"]);
|
|
22
|
+
var { columns = [], customActionButtons, data = [], description, editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText } = _a, modalProps = __rest(_a, ["columns", "customActionButtons", "data", "description", "editDataIndexes", "filters", "isLoading", "isSubmitting", "onChangeSelectedRows", "onEdit", "onSubmitAllData", "onSubmitSelectedData", "rowKey", "selectedRows", "submitAllLabel", "submitSelectedLabel", "mapperConfig", "tableClassName", "emptyText"]);
|
|
23
23
|
const { onCancel, className } = modalProps, restModalProps = __rest(modalProps, ["onCancel", "className"]);
|
|
24
24
|
const { getPrefixCls, theme } = React.useContext(ConfigProvider.ConfigContext);
|
|
25
25
|
const { token, hashId } = useToken();
|
|
@@ -46,5 +46,5 @@ export const AiModalTable = (_a) => {
|
|
|
46
46
|
return useStyle(React.createElement(Modal, Object.assign({ className: classNames(baseCls, hashId, className), footer: null, onCancel: handleCancel, centered: true, destroyOnClose: true, width: 1200 }, restModalProps),
|
|
47
47
|
React.createElement(Flex, { gap: 10, vertical: true },
|
|
48
48
|
React.createElement("div", { className: "text-neutral-50 text-sm mb-2" }, description),
|
|
49
|
-
React.createElement(AiTable, { columns: columns, customActionButtons: customActionButtons, data: data, editDataIndexes: editDataIndexes, filters: filters, isLoading: isLoading, isSubmitting: isSubmitting, onChangeSelectedRows: onChangeSelectedRows, onEdit: onEdit, onSubmitAllData: onSubmitAllData, onSubmitSelectedData: onSubmitSelectedData, rowKey: rowKey, selectedRows: selectedRows, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, mapperConfig: mapperConfig, tableClassName: tableClassName }))));
|
|
49
|
+
React.createElement(AiTable, { columns: columns, customActionButtons: customActionButtons, data: data, editDataIndexes: editDataIndexes, filters: filters, isLoading: isLoading, isSubmitting: isSubmitting, onChangeSelectedRows: onChangeSelectedRows, onEdit: onEdit, onSubmitAllData: onSubmitAllData, onSubmitSelectedData: onSubmitSelectedData, rowKey: rowKey, selectedRows: selectedRows, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, mapperConfig: mapperConfig, tableClassName: tableClassName, emptyText: emptyText }))));
|
|
50
50
|
};
|
|
@@ -343,4 +343,27 @@ describe('AiTable', () => {
|
|
|
343
343
|
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
344
344
|
});
|
|
345
345
|
});
|
|
346
|
+
describe('Empty Text', () => {
|
|
347
|
+
it('should render table without emptyText prop', () => {
|
|
348
|
+
render(React.createElement(AiTable, Object.assign({}, defaultProps)));
|
|
349
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
350
|
+
});
|
|
351
|
+
it('should pass emptyText prop to TableContent when provided', () => {
|
|
352
|
+
const customEmptyText = 'No data found';
|
|
353
|
+
render(React.createElement(AiTable, Object.assign({}, defaultProps, { emptyText: customEmptyText })));
|
|
354
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
355
|
+
});
|
|
356
|
+
it('should handle React nodes as emptyText', () => {
|
|
357
|
+
const customEmptyNode = (React.createElement("div", { "data-testid": "custom-empty-message" },
|
|
358
|
+
React.createElement("p", null, "No results available")));
|
|
359
|
+
render(React.createElement(AiTable, Object.assign({}, defaultProps, { emptyText: customEmptyNode })));
|
|
360
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
361
|
+
});
|
|
362
|
+
it('should work with empty data and custom emptyText', () => {
|
|
363
|
+
const customEmptyText = 'The table is empty';
|
|
364
|
+
render(React.createElement(AiTable, Object.assign({}, defaultProps, { data: [], emptyText: customEmptyText })));
|
|
365
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
366
|
+
expect(screen.queryByTestId('row-1')).not.toBeInTheDocument();
|
|
367
|
+
});
|
|
368
|
+
});
|
|
346
369
|
});
|
|
@@ -569,4 +569,43 @@ describe('AiTable', () => {
|
|
|
569
569
|
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
570
570
|
});
|
|
571
571
|
});
|
|
572
|
+
|
|
573
|
+
describe('Empty Text', () => {
|
|
574
|
+
it('should render table without emptyText prop', () => {
|
|
575
|
+
render(<AiTable {...defaultProps} />);
|
|
576
|
+
|
|
577
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
it('should pass emptyText prop to TableContent when provided', () => {
|
|
581
|
+
const customEmptyText = 'No data found';
|
|
582
|
+
|
|
583
|
+
render(<AiTable {...defaultProps} emptyText={customEmptyText} />);
|
|
584
|
+
|
|
585
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it('should handle React nodes as emptyText', () => {
|
|
589
|
+
const customEmptyNode = (
|
|
590
|
+
<div data-testid="custom-empty-message">
|
|
591
|
+
<p>No results available</p>
|
|
592
|
+
</div>
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
render(<AiTable {...defaultProps} emptyText={customEmptyNode} />);
|
|
596
|
+
|
|
597
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('should work with empty data and custom emptyText', () => {
|
|
601
|
+
const customEmptyText = 'The table is empty';
|
|
602
|
+
|
|
603
|
+
render(
|
|
604
|
+
<AiTable {...defaultProps} data={[]} emptyText={customEmptyText} />
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
expect(screen.getByTestId('table-content')).toBeInTheDocument();
|
|
608
|
+
expect(screen.queryByTestId('row-1')).not.toBeInTheDocument();
|
|
609
|
+
});
|
|
610
|
+
});
|
|
572
611
|
});
|
|
@@ -335,12 +335,13 @@ describe('TableContent', () => {
|
|
|
335
335
|
});
|
|
336
336
|
it('should apply collapsed style when not expanded', () => {
|
|
337
337
|
renderComponent({ expandedRows: [] });
|
|
338
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
338
339
|
const expandIcons = screen.getAllByTestId('icon-chevron_down');
|
|
339
340
|
expect(expandIcons[0].className).toContain('ai-modal-table__icon--collapsed');
|
|
340
341
|
});
|
|
341
342
|
it('should not apply collapsed style when expanded', () => {
|
|
342
|
-
renderComponent({ expandedRows: [
|
|
343
|
-
//
|
|
343
|
+
renderComponent({ expandedRows: [2] });
|
|
344
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
344
345
|
const icons = screen.getAllByTestId('icon-chevron_down');
|
|
345
346
|
expect(icons[0].className).not.toContain('ai-modal-table__icon--collapsed');
|
|
346
347
|
});
|
|
@@ -351,9 +352,10 @@ describe('TableContent', () => {
|
|
|
351
352
|
});
|
|
352
353
|
expect(screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
353
354
|
});
|
|
354
|
-
it('should render
|
|
355
|
+
it('should render expand button for rows with multiple mapper items', () => {
|
|
355
356
|
renderComponent();
|
|
356
|
-
|
|
357
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
358
|
+
expect(screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
357
359
|
});
|
|
358
360
|
});
|
|
359
361
|
describe('Mapper Column', () => {
|
|
@@ -550,8 +552,10 @@ describe('TableContent', () => {
|
|
|
550
552
|
});
|
|
551
553
|
it('should render expand button in first column', () => {
|
|
552
554
|
renderComponent();
|
|
553
|
-
|
|
554
|
-
const
|
|
555
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
556
|
+
const rows = screen.getAllByRole('row');
|
|
557
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
558
|
+
const firstCell = within(rowWithExpandButton).getAllByRole('cell')[0];
|
|
555
559
|
expect(firstCell).toContainElement(screen.getAllByTestId('icon-chevron_down')[0]);
|
|
556
560
|
});
|
|
557
561
|
it('should handle missing optional data gracefully', () => {
|
|
@@ -786,18 +790,20 @@ describe('TableContent', () => {
|
|
|
786
790
|
});
|
|
787
791
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
788
792
|
fireEvent.click(expandButtons[0]);
|
|
789
|
-
|
|
793
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
794
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
790
795
|
});
|
|
791
796
|
it('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
792
797
|
const onToggleExpand = vi.fn();
|
|
793
798
|
renderComponent({
|
|
794
|
-
expandedRows: [
|
|
799
|
+
expandedRows: [2],
|
|
795
800
|
onToggleExpand
|
|
796
801
|
});
|
|
797
802
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
798
803
|
fireEvent.click(expandButtons[0]);
|
|
799
804
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
800
|
-
|
|
805
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
806
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
801
807
|
});
|
|
802
808
|
it('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
803
809
|
const onAddItem = vi.fn();
|
|
@@ -434,6 +434,7 @@ describe('TableContent', () => {
|
|
|
434
434
|
|
|
435
435
|
it('should apply collapsed style when not expanded', () => {
|
|
436
436
|
renderComponent({ expandedRows: [] });
|
|
437
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
437
438
|
const expandIcons = screen.getAllByTestId('icon-chevron_down');
|
|
438
439
|
expect(expandIcons[0].className).toContain(
|
|
439
440
|
'ai-modal-table__icon--collapsed'
|
|
@@ -441,8 +442,8 @@ describe('TableContent', () => {
|
|
|
441
442
|
});
|
|
442
443
|
|
|
443
444
|
it('should not apply collapsed style when expanded', () => {
|
|
444
|
-
renderComponent({ expandedRows: [
|
|
445
|
-
//
|
|
445
|
+
renderComponent({ expandedRows: [2] });
|
|
446
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
446
447
|
const icons = screen.getAllByTestId('icon-chevron_down');
|
|
447
448
|
expect(icons[0].className).not.toContain(
|
|
448
449
|
'ai-modal-table__icon--collapsed'
|
|
@@ -457,9 +458,10 @@ describe('TableContent', () => {
|
|
|
457
458
|
expect(screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
458
459
|
});
|
|
459
460
|
|
|
460
|
-
it('should render
|
|
461
|
+
it('should render expand button for rows with multiple mapper items', () => {
|
|
461
462
|
renderComponent();
|
|
462
|
-
|
|
463
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
464
|
+
expect(screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
463
465
|
});
|
|
464
466
|
});
|
|
465
467
|
|
|
@@ -691,8 +693,10 @@ describe('TableContent', () => {
|
|
|
691
693
|
|
|
692
694
|
it('should render expand button in first column', () => {
|
|
693
695
|
renderComponent();
|
|
694
|
-
|
|
695
|
-
const
|
|
696
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
697
|
+
const rows = screen.getAllByRole('row');
|
|
698
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
699
|
+
const firstCell = within(rowWithExpandButton).getAllByRole('cell')[0];
|
|
696
700
|
expect(firstCell).toContainElement(
|
|
697
701
|
screen.getAllByTestId('icon-chevron_down')[0]
|
|
698
702
|
);
|
|
@@ -986,13 +990,14 @@ describe('TableContent', () => {
|
|
|
986
990
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
987
991
|
fireEvent.click(expandButtons[0]);
|
|
988
992
|
|
|
989
|
-
|
|
993
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
994
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
990
995
|
});
|
|
991
996
|
|
|
992
997
|
it('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
993
998
|
const onToggleExpand = vi.fn();
|
|
994
999
|
renderComponent({
|
|
995
|
-
expandedRows: [
|
|
1000
|
+
expandedRows: [2],
|
|
996
1001
|
onToggleExpand
|
|
997
1002
|
});
|
|
998
1003
|
|
|
@@ -1000,7 +1005,8 @@ describe('TableContent', () => {
|
|
|
1000
1005
|
fireEvent.click(expandButtons[0]);
|
|
1001
1006
|
|
|
1002
1007
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
1003
|
-
|
|
1008
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
1009
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
1004
1010
|
});
|
|
1005
1011
|
|
|
1006
1012
|
it('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
@@ -5,7 +5,8 @@ interface TableContentProps extends Omit<TableBaseProps, 'onChangeSelectedRows'
|
|
|
5
5
|
expandedRows: Array<number | string>;
|
|
6
6
|
onToggleExpand: (rowId: number | string) => void;
|
|
7
7
|
rowKey: string;
|
|
8
|
+
emptyText?: React.ReactNode;
|
|
8
9
|
}
|
|
9
|
-
export declare const TableContent: ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig }: TableContentProps) => React.JSX.Element;
|
|
10
|
+
export declare const TableContent: ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig, emptyText }: TableContentProps) => React.JSX.Element;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/components/content.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ9E,UAAU,iBACR,SAAQ,IAAI,CAAC,cAAc,EAAE,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/components/content.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ9E,UAAU,iBACR,SAAQ,IAAI,CAAC,cAAc,EAAE,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,eAAO,MAAM,YAAY,GAAI,iKAa1B,iBAAiB,sBA2hBnB,CAAC"}
|
|
@@ -13,7 +13,7 @@ import { i18n } from '../i18n';
|
|
|
13
13
|
import { TableMapper } from './mapper';
|
|
14
14
|
import { ActionButtons } from './row-actions';
|
|
15
15
|
const { t } = i18n;
|
|
16
|
-
export const TableContent = ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig }) => {
|
|
16
|
+
export const TableContent = ({ columns, customActionButtons, data, editDataIndexes, expandedRows, onEdit, onToggleExpand, onToggleSelection, rowKey, selectedRows, mapperConfig, emptyText }) => {
|
|
17
17
|
const { getPrefixCls, theme } = React.useContext(ConfigProvider.ConfigContext);
|
|
18
18
|
const { token, hashId } = useToken();
|
|
19
19
|
const baseCls = getPrefixCls('ai-modal-table');
|
|
@@ -110,7 +110,8 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
110
110
|
};
|
|
111
111
|
const renderMapper = ({ rowId, value, dataIndex }) => {
|
|
112
112
|
const isExpanded = isRowExpanded(rowId);
|
|
113
|
-
const
|
|
113
|
+
const hasMultipleItems = value.length > 1;
|
|
114
|
+
const displayedValues = hasMultipleItems && !isExpanded ? value.slice(0, 1) : value;
|
|
114
115
|
const handleExpand = () => {
|
|
115
116
|
if (!isExpanded) {
|
|
116
117
|
onToggleExpand(rowId);
|
|
@@ -182,10 +183,15 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
182
183
|
}), onClick: handleClick }));
|
|
183
184
|
};
|
|
184
185
|
const renderTableCells = (row, rowId) => {
|
|
186
|
+
const mapperValue = hasMapper && mapperDataIndex ? row[mapperDataIndex] : null;
|
|
187
|
+
const hasMultipleMapperItems = Array.isArray(mapperValue) && mapperValue.length > 1;
|
|
185
188
|
return columns.map((column, colIndex) => {
|
|
186
189
|
const isFirstColumn = colIndex === 0;
|
|
187
190
|
return (React.createElement("td", { className: "text-blue-50 font-normal text-base whitespace-nowrap py-0 px-5", key: `cell-${rowId}-${column.dataIndex || colIndex}` },
|
|
188
|
-
isFirstColumn &&
|
|
191
|
+
isFirstColumn &&
|
|
192
|
+
hasMapper &&
|
|
193
|
+
hasMultipleMapperItems &&
|
|
194
|
+
renderExpandButton(rowId),
|
|
189
195
|
renderCellValue({
|
|
190
196
|
column,
|
|
191
197
|
row,
|
|
@@ -213,7 +219,7 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
213
219
|
};
|
|
214
220
|
const renderEmptyRow = () => {
|
|
215
221
|
return (React.createElement("tr", null,
|
|
216
|
-
React.createElement("td", { className: "font-normal text-center text-gray-500 text-sm py-10 px-4", colSpan: columns.length + 1 }, t('filter.no.match'))));
|
|
222
|
+
React.createElement("td", { className: "font-normal text-center text-gray-500 text-sm py-10 px-4", colSpan: columns.length + 1 }, emptyText !== null && emptyText !== void 0 ? emptyText : t('filter.no.match'))));
|
|
217
223
|
};
|
|
218
224
|
const renderGradientOverlay = () => {
|
|
219
225
|
return (React.createElement(React.Fragment, null,
|
|
@@ -298,7 +304,7 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
298
304
|
return useStyle(React.createElement("div", { className: "bg-ebonyClay-450 rounded-lg overflow-hidden" },
|
|
299
305
|
React.createElement("div", { className: `${baseCls}__table-wrapper ${hashId} overflow-x-auto overflow-y-auto` },
|
|
300
306
|
React.createElement("div", { className: "relative" },
|
|
301
|
-
renderGradientOverlay(),
|
|
307
|
+
data.length > 0 && renderGradientOverlay(),
|
|
302
308
|
React.createElement("table", { ref: tableRef, className: `${baseCls}__table-element ${hashId} w-full bg-ebonyClay-450` },
|
|
303
309
|
React.createElement("thead", null, renderTableHeaders()),
|
|
304
310
|
React.createElement("tbody", null, renderTableRows()))))));
|
|
@@ -12,7 +12,7 @@ export const TableFooter = ({ isSubmitting, selectedCount, submitAllLabel, submi
|
|
|
12
12
|
onSubmitSelected();
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
|
-
return (React.createElement(Flex, { justify: "end", gap: 10 },
|
|
15
|
+
return (React.createElement(Flex, { justify: "end", gap: 10, className: "mt-4" },
|
|
16
16
|
React.createElement(Button, { className: "uppercase font-semibold", disabled: isSubmitting, loading: isSubmitting, onClick: handleSubmitAll }, submitAllLabel),
|
|
17
17
|
React.createElement(Button, { className: "uppercase font-semibold", disabled: selectedCount === 0 || isSubmitting, loading: isSubmitting, onClick: handleSubmitSelected, type: "primary" },
|
|
18
18
|
submitSelectedLabel,
|
|
@@ -3,7 +3,7 @@ import { Flex } from '@akinon/ui-layout';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { renderMapperRow } from '../utils/render-mapper-fields';
|
|
5
5
|
export const TableMapper = ({ values, handleAddItem, handleRemoveItem, handleItemChange }) => {
|
|
6
|
-
return (React.createElement(Flex, { gap: 5, vertical: true, rootClassName: "py-
|
|
6
|
+
return (React.createElement(Flex, { gap: 5, vertical: true, rootClassName: "py-3" }, values.map((row, index) => {
|
|
7
7
|
return (React.createElement(Flex, { gap: 12, align: "center", key: index },
|
|
8
8
|
renderMapperRow({
|
|
9
9
|
row,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { AiTableProps } from '../types';
|
|
3
|
-
export declare const AiTable: ({ columns, customActionButtons, data, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName }: AiTableProps) => React.JSX.Element;
|
|
3
|
+
export declare const AiTable: ({ columns, customActionButtons, data, editDataIndexes, filters, isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText }: AiTableProps) => React.JSX.Element;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-table/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAe7C,eAAO,MAAM,OAAO,GAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-table/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAe7C,eAAO,MAAM,OAAO,GAAI,oQAmBrB,YAAY,sBA6Hd,CAAC"}
|
|
@@ -10,7 +10,7 @@ import { DEFAULT_CURRENT_PAGE, DEFAULT_PAGE_SIZE, DEFAULT_ROW_KEY } from './cons
|
|
|
10
10
|
import { i18n } from './i18n';
|
|
11
11
|
import { filterDataByFilters, paginateData } from './utils/data-format';
|
|
12
12
|
const { t } = i18n;
|
|
13
|
-
export const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName }) => {
|
|
13
|
+
export const AiTable = ({ columns = [], customActionButtons, data = [], editDataIndexes, filters = [], isLoading, isSubmitting, onChangeSelectedRows, onEdit, onSubmitAllData, onSubmitSelectedData, rowKey = DEFAULT_ROW_KEY, selectedRows, submitAllLabel, submitSelectedLabel, mapperConfig, tableClassName, emptyText }) => {
|
|
14
14
|
const [currentPage, setCurrentPage] = React.useState(DEFAULT_CURRENT_PAGE);
|
|
15
15
|
const [pageSize, setPageSize] = React.useState(DEFAULT_PAGE_SIZE);
|
|
16
16
|
const [filterValues, setFilterValues] = React.useState({});
|
|
@@ -54,7 +54,7 @@ export const AiTable = ({ columns = [], customActionButtons, data = [], editData
|
|
|
54
54
|
return (React.createElement("div", { className: "w-full h-80" },
|
|
55
55
|
React.createElement(AiSpinner, null)));
|
|
56
56
|
}
|
|
57
|
-
return (React.createElement(Flex, { gap:
|
|
57
|
+
return (React.createElement(Flex, { gap: 18, vertical: true, className: tableClassName },
|
|
58
58
|
React.createElement(Flex, { justify: "space-between", align: "center" },
|
|
59
59
|
React.createElement(Flex, { align: "center", gap: 22 },
|
|
60
60
|
React.createElement(TableFilters, { filters: filters, filterValues: filterValues, onFilterChange: handleFilterChange }),
|
|
@@ -62,6 +62,6 @@ export const AiTable = ({ columns = [], customActionButtons, data = [], editData
|
|
|
62
62
|
React.createElement(Button, { size: "small", onClick: handleExpandAll }, t('expand.all')),
|
|
63
63
|
React.createElement(Button, { size: "small", onClick: handleCollapseAll }, t('collapse.all'))))),
|
|
64
64
|
React.createElement(TablePagination, { currentPage: currentPage, onPageChange: handlePageChange, onPageSizeChange: handlePageSizeChange, pageSize: pageSize, total: filteredData.length })),
|
|
65
|
-
React.createElement(TableContent, { columns: columns, customActionButtons: customActionButtons, data: paginatedData, editDataIndexes: editDataIndexes, expandedRows: expandedRows, onEdit: onEdit, onToggleExpand: handleToggleExpand, onToggleSelection: handleToggleSelection, rowKey: rowKey, selectedRows: selectedRows, mapperConfig: mapperConfig }),
|
|
65
|
+
React.createElement(TableContent, { columns: columns, customActionButtons: customActionButtons, data: paginatedData, editDataIndexes: editDataIndexes, emptyText: emptyText, expandedRows: expandedRows, onEdit: onEdit, onToggleExpand: handleToggleExpand, onToggleSelection: handleToggleSelection, rowKey: rowKey, selectedRows: selectedRows, mapperConfig: mapperConfig }),
|
|
66
66
|
React.createElement(TableFooter, { isSubmitting: isSubmitting, selectedCount: selectedRows.length, submitAllLabel: submitAllLabel, submitSelectedLabel: submitSelectedLabel, onSubmitAll: onSubmitAllData, onSubmitSelected: onSubmitSelectedData })));
|
|
67
67
|
};
|
|
@@ -97,6 +97,10 @@ export interface TableBaseProps {
|
|
|
97
97
|
* CSS class name to apply to the table wrapper element
|
|
98
98
|
*/
|
|
99
99
|
tableClassName?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Custom text or node to display when no data matches the filters. Defaults to "No matching results found".
|
|
102
|
+
*/
|
|
103
|
+
emptyText?: React.ReactNode;
|
|
100
104
|
}
|
|
101
105
|
export interface AiTableProps extends TableBaseProps {
|
|
102
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/ai-modal-table",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"antd": "^5.27.0",
|
|
14
14
|
"classnames": "^2.5.1",
|
|
15
15
|
"lodash-es": "^4.17.21",
|
|
16
|
-
"@akinon/icons": "1.2.
|
|
17
|
-
"@akinon/ui-
|
|
18
|
-
"@akinon/ui-
|
|
19
|
-
"@akinon/ui-
|
|
20
|
-
"@akinon/ui-pagination": "1.4.
|
|
21
|
-
"@akinon/
|
|
22
|
-
"@akinon/ui-
|
|
23
|
-
"@akinon/
|
|
24
|
-
"@akinon/ui-
|
|
25
|
-
"@akinon/ui-
|
|
16
|
+
"@akinon/icons": "1.2.3",
|
|
17
|
+
"@akinon/ui-button": "1.4.4",
|
|
18
|
+
"@akinon/ui-input": "1.2.3",
|
|
19
|
+
"@akinon/ui-modal": "1.2.3",
|
|
20
|
+
"@akinon/ui-pagination": "1.4.4",
|
|
21
|
+
"@akinon/akilocale": "1.2.3",
|
|
22
|
+
"@akinon/ui-select": "1.4.4",
|
|
23
|
+
"@akinon/ui-theme": "1.2.3",
|
|
24
|
+
"@akinon/ui-layout": "1.7.4",
|
|
25
|
+
"@akinon/ui-ai-spinner": "1.0.4"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"copyfiles": "^2.4.1",
|
|
31
31
|
"rimraf": "^5.0.5",
|
|
32
32
|
"typescript": "*",
|
|
33
|
-
"@akinon/typescript-config": "1.1.
|
|
34
|
-
"@akinon/vitest-config": "1.1.
|
|
33
|
+
"@akinon/typescript-config": "1.1.3",
|
|
34
|
+
"@akinon/vitest-config": "1.1.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"react": "^18 || ^19",
|