@akinon/ai-modal-table 1.0.1 → 1.0.3
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 +61 -9
- package/dist/cjs/ai-table/components/__tests__/content.test.tsx +77 -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 +25 -15
- 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/constants/index.d.ts +4 -0
- package/dist/cjs/ai-table/constants/index.d.ts.map +1 -1
- package/dist/cjs/ai-table/constants/index.js +5 -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/ai-table/utils/render-edit-fields/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/__tests__/index.test.js +220 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/__tests__/index.test.tsx +283 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/index.d.ts +13 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/render-edit-fields/index.js +65 -0
- package/dist/cjs/types/index.d.ts +24 -4
- 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 +61 -9
- package/dist/esm/ai-table/components/__tests__/content.test.tsx +77 -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 +25 -15
- 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/constants/index.d.ts +4 -0
- package/dist/esm/ai-table/constants/index.d.ts.map +1 -1
- package/dist/esm/ai-table/constants/index.js +4 -0
- 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/ai-table/utils/render-edit-fields/__tests__/index.test.d.ts +2 -0
- package/dist/esm/ai-table/utils/render-edit-fields/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/render-edit-fields/__tests__/index.test.js +218 -0
- package/dist/esm/ai-table/utils/render-edit-fields/__tests__/index.test.tsx +283 -0
- package/dist/esm/ai-table/utils/render-edit-fields/index.d.ts +13 -0
- package/dist/esm/ai-table/utils/render-edit-fields/index.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/render-edit-fields/index.js +60 -0
- package/dist/esm/types/index.d.ts +24 -4
- 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
|
});
|
|
@@ -18,6 +18,7 @@ const user_event_1 = require("@testing-library/user-event");
|
|
|
18
18
|
const antd_1 = require("antd");
|
|
19
19
|
const react_2 = require("react");
|
|
20
20
|
const vitest_1 = require("vitest");
|
|
21
|
+
const constants_1 = require("../../constants");
|
|
21
22
|
const content_1 = require("../content");
|
|
22
23
|
vitest_1.vi.mock('@akinon/icons', () => ({
|
|
23
24
|
Icon: (_a) => {
|
|
@@ -31,6 +32,12 @@ vitest_1.vi.mock('@akinon/ui-input', () => ({
|
|
|
31
32
|
return (react_2.default.createElement("input", Object.assign({ onChange: onChange, value: value, className: className, "data-testid": "edit-input" }, props)));
|
|
32
33
|
}
|
|
33
34
|
}));
|
|
35
|
+
vitest_1.vi.mock('@akinon/ui-select', () => ({
|
|
36
|
+
Select: (_a) => {
|
|
37
|
+
var { value, onChange, rootClassName, options } = _a, props = __rest(_a, ["value", "onChange", "rootClassName", "options"]);
|
|
38
|
+
return (react_2.default.createElement("select", Object.assign({ "data-testid": "edit-select", value: value !== null && value !== void 0 ? value : '', onChange: e => onChange === null || onChange === void 0 ? void 0 : onChange(e.target.value), className: rootClassName }, props), options === null || options === void 0 ? void 0 : options.map((opt) => (react_2.default.createElement("option", { key: opt.value, value: String(opt.value) }, opt.label)))));
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
34
41
|
vitest_1.vi.mock('@akinon/ui-layout', () => ({
|
|
35
42
|
Flex: (_a) => {
|
|
36
43
|
var { children } = _a, props = __rest(_a, ["children"]);
|
|
@@ -337,12 +344,13 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
337
344
|
});
|
|
338
345
|
(0, vitest_1.it)('should apply collapsed style when not expanded', () => {
|
|
339
346
|
renderComponent({ expandedRows: [] });
|
|
347
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
340
348
|
const expandIcons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
341
349
|
(0, vitest_1.expect)(expandIcons[0].className).toContain('ai-modal-table__icon--collapsed');
|
|
342
350
|
});
|
|
343
351
|
(0, vitest_1.it)('should not apply collapsed style when expanded', () => {
|
|
344
|
-
renderComponent({ expandedRows: [
|
|
345
|
-
//
|
|
352
|
+
renderComponent({ expandedRows: [2] });
|
|
353
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
346
354
|
const icons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
347
355
|
(0, vitest_1.expect)(icons[0].className).not.toContain('ai-modal-table__icon--collapsed');
|
|
348
356
|
});
|
|
@@ -353,9 +361,10 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
353
361
|
});
|
|
354
362
|
(0, vitest_1.expect)(react_1.screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
355
363
|
});
|
|
356
|
-
(0, vitest_1.it)('should render
|
|
364
|
+
(0, vitest_1.it)('should render expand button for rows with multiple mapper items', () => {
|
|
357
365
|
renderComponent();
|
|
358
|
-
|
|
366
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
367
|
+
(0, vitest_1.expect)(react_1.screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
359
368
|
});
|
|
360
369
|
});
|
|
361
370
|
(0, vitest_1.describe)('Mapper Column', () => {
|
|
@@ -552,8 +561,10 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
552
561
|
});
|
|
553
562
|
(0, vitest_1.it)('should render expand button in first column', () => {
|
|
554
563
|
renderComponent();
|
|
555
|
-
|
|
556
|
-
const
|
|
564
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
565
|
+
const rows = react_1.screen.getAllByRole('row');
|
|
566
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
567
|
+
const firstCell = (0, react_1.within)(rowWithExpandButton).getAllByRole('cell')[0];
|
|
557
568
|
(0, vitest_1.expect)(firstCell).toContainElement(react_1.screen.getAllByTestId('icon-chevron_down')[0]);
|
|
558
569
|
});
|
|
559
570
|
(0, vitest_1.it)('should handle missing optional data gracefully', () => {
|
|
@@ -788,18 +799,20 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
788
799
|
});
|
|
789
800
|
const expandButtons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
790
801
|
react_1.fireEvent.click(expandButtons[0]);
|
|
791
|
-
(
|
|
802
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
803
|
+
(0, vitest_1.expect)(onToggleExpand).toHaveBeenCalledWith(2);
|
|
792
804
|
});
|
|
793
805
|
(0, vitest_1.it)('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
794
806
|
const onToggleExpand = vitest_1.vi.fn();
|
|
795
807
|
renderComponent({
|
|
796
|
-
expandedRows: [
|
|
808
|
+
expandedRows: [2],
|
|
797
809
|
onToggleExpand
|
|
798
810
|
});
|
|
799
811
|
const expandButtons = react_1.screen.getAllByTestId('icon-chevron_down');
|
|
800
812
|
react_1.fireEvent.click(expandButtons[0]);
|
|
801
813
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
802
|
-
(
|
|
814
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
815
|
+
(0, vitest_1.expect)(onToggleExpand).toHaveBeenCalledWith(2);
|
|
803
816
|
});
|
|
804
817
|
(0, vitest_1.it)('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
805
818
|
const onAddItem = vitest_1.vi.fn();
|
|
@@ -1345,5 +1358,44 @@ vitest_1.vi.mock('../../i18n', () => ({
|
|
|
1345
1358
|
const inputs = react_1.screen.queryAllByTestId('edit-input');
|
|
1346
1359
|
(0, vitest_1.expect)(inputs.length).toBeGreaterThan(0);
|
|
1347
1360
|
});
|
|
1361
|
+
(0, vitest_1.it)('should render Select for editable column when editDataIndexes has SELECT config', async () => {
|
|
1362
|
+
const user = user_event_1.default.setup();
|
|
1363
|
+
const onEdit = vitest_1.vi.fn();
|
|
1364
|
+
renderComponent({
|
|
1365
|
+
data: [
|
|
1366
|
+
{
|
|
1367
|
+
pk: 1,
|
|
1368
|
+
name: 'Item 1',
|
|
1369
|
+
status: 'active',
|
|
1370
|
+
mappings: []
|
|
1371
|
+
}
|
|
1372
|
+
],
|
|
1373
|
+
columns: [
|
|
1374
|
+
{ title: 'Name', dataIndex: 'name' },
|
|
1375
|
+
{ title: 'Status', dataIndex: 'status' }
|
|
1376
|
+
],
|
|
1377
|
+
mapperConfig: undefined,
|
|
1378
|
+
onEdit,
|
|
1379
|
+
editDataIndexes: [
|
|
1380
|
+
'name',
|
|
1381
|
+
{
|
|
1382
|
+
key: 'status',
|
|
1383
|
+
type: constants_1.EDIT_FIELD_TYPES.SELECT,
|
|
1384
|
+
attributes: {
|
|
1385
|
+
options: [
|
|
1386
|
+
{ label: 'Active', value: 'active' },
|
|
1387
|
+
{ label: 'Inactive', value: 'inactive' }
|
|
1388
|
+
]
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
]
|
|
1392
|
+
});
|
|
1393
|
+
const editButton = react_1.screen.getByTestId('edit-button-1');
|
|
1394
|
+
await user.click(editButton);
|
|
1395
|
+
const inputs = react_1.screen.queryAllByTestId('edit-input');
|
|
1396
|
+
const selects = react_1.screen.queryAllByTestId('edit-select');
|
|
1397
|
+
(0, vitest_1.expect)(inputs.length).toBeGreaterThan(0);
|
|
1398
|
+
(0, vitest_1.expect)(selects.length).toBeGreaterThan(0);
|
|
1399
|
+
});
|
|
1348
1400
|
});
|
|
1349
1401
|
});
|
|
@@ -7,6 +7,7 @@ import { ConfigProvider } from 'antd';
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
9
9
|
|
|
10
|
+
import { EDIT_FIELD_TYPES } from '../../constants';
|
|
10
11
|
import { TableContent } from '../content';
|
|
11
12
|
|
|
12
13
|
vi.mock('@akinon/icons', () => ({
|
|
@@ -35,6 +36,24 @@ vi.mock('@akinon/ui-input', () => ({
|
|
|
35
36
|
)
|
|
36
37
|
}));
|
|
37
38
|
|
|
39
|
+
vi.mock('@akinon/ui-select', () => ({
|
|
40
|
+
Select: ({ value, onChange, rootClassName, options, ...props }: any) => (
|
|
41
|
+
<select
|
|
42
|
+
data-testid="edit-select"
|
|
43
|
+
value={value ?? ''}
|
|
44
|
+
onChange={e => onChange?.(e.target.value)}
|
|
45
|
+
className={rootClassName}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
{options?.map((opt: { label: string; value: string | number }) => (
|
|
49
|
+
<option key={opt.value} value={String(opt.value)}>
|
|
50
|
+
{opt.label}
|
|
51
|
+
</option>
|
|
52
|
+
))}
|
|
53
|
+
</select>
|
|
54
|
+
)
|
|
55
|
+
}));
|
|
56
|
+
|
|
38
57
|
vi.mock('@akinon/ui-layout', () => ({
|
|
39
58
|
Flex: ({ children, ...props }: any) => (
|
|
40
59
|
<div data-testid="flex" {...props}>
|
|
@@ -434,6 +453,7 @@ describe('TableContent', () => {
|
|
|
434
453
|
|
|
435
454
|
it('should apply collapsed style when not expanded', () => {
|
|
436
455
|
renderComponent({ expandedRows: [] });
|
|
456
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
437
457
|
const expandIcons = screen.getAllByTestId('icon-chevron_down');
|
|
438
458
|
expect(expandIcons[0].className).toContain(
|
|
439
459
|
'ai-modal-table__icon--collapsed'
|
|
@@ -441,8 +461,8 @@ describe('TableContent', () => {
|
|
|
441
461
|
});
|
|
442
462
|
|
|
443
463
|
it('should not apply collapsed style when expanded', () => {
|
|
444
|
-
renderComponent({ expandedRows: [
|
|
445
|
-
//
|
|
464
|
+
renderComponent({ expandedRows: [2] });
|
|
465
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
446
466
|
const icons = screen.getAllByTestId('icon-chevron_down');
|
|
447
467
|
expect(icons[0].className).not.toContain(
|
|
448
468
|
'ai-modal-table__icon--collapsed'
|
|
@@ -457,9 +477,10 @@ describe('TableContent', () => {
|
|
|
457
477
|
expect(screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
458
478
|
});
|
|
459
479
|
|
|
460
|
-
it('should render
|
|
480
|
+
it('should render expand button for rows with multiple mapper items', () => {
|
|
461
481
|
renderComponent();
|
|
462
|
-
|
|
482
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
483
|
+
expect(screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
463
484
|
});
|
|
464
485
|
});
|
|
465
486
|
|
|
@@ -691,8 +712,10 @@ describe('TableContent', () => {
|
|
|
691
712
|
|
|
692
713
|
it('should render expand button in first column', () => {
|
|
693
714
|
renderComponent();
|
|
694
|
-
|
|
695
|
-
const
|
|
715
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
716
|
+
const rows = screen.getAllByRole('row');
|
|
717
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
718
|
+
const firstCell = within(rowWithExpandButton).getAllByRole('cell')[0];
|
|
696
719
|
expect(firstCell).toContainElement(
|
|
697
720
|
screen.getAllByTestId('icon-chevron_down')[0]
|
|
698
721
|
);
|
|
@@ -986,13 +1009,14 @@ describe('TableContent', () => {
|
|
|
986
1009
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
987
1010
|
fireEvent.click(expandButtons[0]);
|
|
988
1011
|
|
|
989
|
-
|
|
1012
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
1013
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
990
1014
|
});
|
|
991
1015
|
|
|
992
1016
|
it('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
993
1017
|
const onToggleExpand = vi.fn();
|
|
994
1018
|
renderComponent({
|
|
995
|
-
expandedRows: [
|
|
1019
|
+
expandedRows: [2],
|
|
996
1020
|
onToggleExpand
|
|
997
1021
|
});
|
|
998
1022
|
|
|
@@ -1000,7 +1024,8 @@ describe('TableContent', () => {
|
|
|
1000
1024
|
fireEvent.click(expandButtons[0]);
|
|
1001
1025
|
|
|
1002
1026
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
1003
|
-
|
|
1027
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
1028
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
1004
1029
|
});
|
|
1005
1030
|
|
|
1006
1031
|
it('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
@@ -1633,5 +1658,48 @@ describe('TableContent', () => {
|
|
|
1633
1658
|
const inputs = screen.queryAllByTestId('edit-input');
|
|
1634
1659
|
expect(inputs.length).toBeGreaterThan(0);
|
|
1635
1660
|
});
|
|
1661
|
+
|
|
1662
|
+
it('should render Select for editable column when editDataIndexes has SELECT config', async () => {
|
|
1663
|
+
const user = userEvent.setup();
|
|
1664
|
+
const onEdit = vi.fn();
|
|
1665
|
+
|
|
1666
|
+
renderComponent({
|
|
1667
|
+
data: [
|
|
1668
|
+
{
|
|
1669
|
+
pk: 1,
|
|
1670
|
+
name: 'Item 1',
|
|
1671
|
+
status: 'active',
|
|
1672
|
+
mappings: []
|
|
1673
|
+
}
|
|
1674
|
+
],
|
|
1675
|
+
columns: [
|
|
1676
|
+
{ title: 'Name', dataIndex: 'name' },
|
|
1677
|
+
{ title: 'Status', dataIndex: 'status' }
|
|
1678
|
+
],
|
|
1679
|
+
mapperConfig: undefined,
|
|
1680
|
+
onEdit,
|
|
1681
|
+
editDataIndexes: [
|
|
1682
|
+
'name',
|
|
1683
|
+
{
|
|
1684
|
+
key: 'status',
|
|
1685
|
+
type: EDIT_FIELD_TYPES.SELECT,
|
|
1686
|
+
attributes: {
|
|
1687
|
+
options: [
|
|
1688
|
+
{ label: 'Active', value: 'active' },
|
|
1689
|
+
{ label: 'Inactive', value: 'inactive' }
|
|
1690
|
+
]
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
]
|
|
1694
|
+
});
|
|
1695
|
+
|
|
1696
|
+
const editButton = screen.getByTestId('edit-button-1');
|
|
1697
|
+
await user.click(editButton);
|
|
1698
|
+
|
|
1699
|
+
const inputs = screen.queryAllByTestId('edit-input');
|
|
1700
|
+
const selects = screen.queryAllByTestId('edit-select');
|
|
1701
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
1702
|
+
expect(selects.length).toBeGreaterThan(0);
|
|
1703
|
+
});
|
|
1636
1704
|
});
|
|
1637
1705
|
});
|
|
@@ -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":"
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/components/content.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAA8B,cAAc,EAAE,MAAM,aAAa,CAAC;AAY9E,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,sBAuhBnB,CAAC"}
|