@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
|
@@ -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
|
});
|
|
@@ -16,6 +16,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
16
16
|
import { ConfigProvider } from 'antd';
|
|
17
17
|
import React from 'react';
|
|
18
18
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
19
|
+
import { EDIT_FIELD_TYPES } from '../../constants';
|
|
19
20
|
import { TableContent } from '../content';
|
|
20
21
|
vi.mock('@akinon/icons', () => ({
|
|
21
22
|
Icon: (_a) => {
|
|
@@ -29,6 +30,12 @@ vi.mock('@akinon/ui-input', () => ({
|
|
|
29
30
|
return (React.createElement("input", Object.assign({ onChange: onChange, value: value, className: className, "data-testid": "edit-input" }, props)));
|
|
30
31
|
}
|
|
31
32
|
}));
|
|
33
|
+
vi.mock('@akinon/ui-select', () => ({
|
|
34
|
+
Select: (_a) => {
|
|
35
|
+
var { value, onChange, rootClassName, options } = _a, props = __rest(_a, ["value", "onChange", "rootClassName", "options"]);
|
|
36
|
+
return (React.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.createElement("option", { key: opt.value, value: String(opt.value) }, opt.label)))));
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
32
39
|
vi.mock('@akinon/ui-layout', () => ({
|
|
33
40
|
Flex: (_a) => {
|
|
34
41
|
var { children } = _a, props = __rest(_a, ["children"]);
|
|
@@ -335,12 +342,13 @@ describe('TableContent', () => {
|
|
|
335
342
|
});
|
|
336
343
|
it('should apply collapsed style when not expanded', () => {
|
|
337
344
|
renderComponent({ expandedRows: [] });
|
|
345
|
+
// Row 2 (pk: 2) has multiple mapper items, so it has the expand button
|
|
338
346
|
const expandIcons = screen.getAllByTestId('icon-chevron_down');
|
|
339
347
|
expect(expandIcons[0].className).toContain('ai-modal-table__icon--collapsed');
|
|
340
348
|
});
|
|
341
349
|
it('should not apply collapsed style when expanded', () => {
|
|
342
|
-
renderComponent({ expandedRows: [
|
|
343
|
-
//
|
|
350
|
+
renderComponent({ expandedRows: [2] });
|
|
351
|
+
// Icon for row 2 (which has multiple mapper items)
|
|
344
352
|
const icons = screen.getAllByTestId('icon-chevron_down');
|
|
345
353
|
expect(icons[0].className).not.toContain('ai-modal-table__icon--collapsed');
|
|
346
354
|
});
|
|
@@ -351,9 +359,10 @@ describe('TableContent', () => {
|
|
|
351
359
|
});
|
|
352
360
|
expect(screen.queryByTestId('icon-chevron_down')).not.toBeInTheDocument();
|
|
353
361
|
});
|
|
354
|
-
it('should render
|
|
362
|
+
it('should render expand button for rows with multiple mapper items', () => {
|
|
355
363
|
renderComponent();
|
|
356
|
-
|
|
364
|
+
// Only row 2 has multiple mapper items (2 items), so only 1 expand button should be rendered
|
|
365
|
+
expect(screen.getAllByTestId('icon-chevron_down').length).toBe(1);
|
|
357
366
|
});
|
|
358
367
|
});
|
|
359
368
|
describe('Mapper Column', () => {
|
|
@@ -550,8 +559,10 @@ describe('TableContent', () => {
|
|
|
550
559
|
});
|
|
551
560
|
it('should render expand button in first column', () => {
|
|
552
561
|
renderComponent();
|
|
553
|
-
|
|
554
|
-
const
|
|
562
|
+
// Row 2 (index 2) has multiple mapper items, so it has the expand button
|
|
563
|
+
const rows = screen.getAllByRole('row');
|
|
564
|
+
const rowWithExpandButton = rows[2]; // Row 2 (pk: 2) has multiple mapper items
|
|
565
|
+
const firstCell = within(rowWithExpandButton).getAllByRole('cell')[0];
|
|
555
566
|
expect(firstCell).toContainElement(screen.getAllByTestId('icon-chevron_down')[0]);
|
|
556
567
|
});
|
|
557
568
|
it('should handle missing optional data gracefully', () => {
|
|
@@ -786,18 +797,20 @@ describe('TableContent', () => {
|
|
|
786
797
|
});
|
|
787
798
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
788
799
|
fireEvent.click(expandButtons[0]);
|
|
789
|
-
|
|
800
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
801
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
790
802
|
});
|
|
791
803
|
it('should call onToggleExpand when expand button clicked on expanded row', () => {
|
|
792
804
|
const onToggleExpand = vi.fn();
|
|
793
805
|
renderComponent({
|
|
794
|
-
expandedRows: [
|
|
806
|
+
expandedRows: [2],
|
|
795
807
|
onToggleExpand
|
|
796
808
|
});
|
|
797
809
|
const expandButtons = screen.getAllByTestId('icon-chevron_down');
|
|
798
810
|
fireEvent.click(expandButtons[0]);
|
|
799
811
|
// The expand button is a toggle - it should call onToggleExpand to collapse the row
|
|
800
|
-
|
|
812
|
+
// Row 2 (pk: 2) has multiple mapper items and is the one with expand button
|
|
813
|
+
expect(onToggleExpand).toHaveBeenCalledWith(2);
|
|
801
814
|
});
|
|
802
815
|
it('should call onAddItem with correct rowId and dataIndex when add button clicked', () => {
|
|
803
816
|
const onAddItem = vi.fn();
|
|
@@ -1343,5 +1356,44 @@ describe('TableContent', () => {
|
|
|
1343
1356
|
const inputs = screen.queryAllByTestId('edit-input');
|
|
1344
1357
|
expect(inputs.length).toBeGreaterThan(0);
|
|
1345
1358
|
});
|
|
1359
|
+
it('should render Select for editable column when editDataIndexes has SELECT config', async () => {
|
|
1360
|
+
const user = userEvent.setup();
|
|
1361
|
+
const onEdit = vi.fn();
|
|
1362
|
+
renderComponent({
|
|
1363
|
+
data: [
|
|
1364
|
+
{
|
|
1365
|
+
pk: 1,
|
|
1366
|
+
name: 'Item 1',
|
|
1367
|
+
status: 'active',
|
|
1368
|
+
mappings: []
|
|
1369
|
+
}
|
|
1370
|
+
],
|
|
1371
|
+
columns: [
|
|
1372
|
+
{ title: 'Name', dataIndex: 'name' },
|
|
1373
|
+
{ title: 'Status', dataIndex: 'status' }
|
|
1374
|
+
],
|
|
1375
|
+
mapperConfig: undefined,
|
|
1376
|
+
onEdit,
|
|
1377
|
+
editDataIndexes: [
|
|
1378
|
+
'name',
|
|
1379
|
+
{
|
|
1380
|
+
key: 'status',
|
|
1381
|
+
type: EDIT_FIELD_TYPES.SELECT,
|
|
1382
|
+
attributes: {
|
|
1383
|
+
options: [
|
|
1384
|
+
{ label: 'Active', value: 'active' },
|
|
1385
|
+
{ label: 'Inactive', value: 'inactive' }
|
|
1386
|
+
]
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
]
|
|
1390
|
+
});
|
|
1391
|
+
const editButton = screen.getByTestId('edit-button-1');
|
|
1392
|
+
await user.click(editButton);
|
|
1393
|
+
const inputs = screen.queryAllByTestId('edit-input');
|
|
1394
|
+
const selects = screen.queryAllByTestId('edit-select');
|
|
1395
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
1396
|
+
expect(selects.length).toBeGreaterThan(0);
|
|
1397
|
+
});
|
|
1346
1398
|
});
|
|
1347
1399
|
});
|
|
@@ -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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { Icon } from '@akinon/icons';
|
|
3
|
-
import { Input } from '@akinon/ui-input';
|
|
4
3
|
import { Flex } from '@akinon/ui-layout';
|
|
5
4
|
import { useToken } from '@akinon/ui-theme';
|
|
6
5
|
import { useStyleRegister } from '@ant-design/cssinjs';
|
|
@@ -10,10 +9,11 @@ import { get } from 'lodash-es';
|
|
|
10
9
|
import * as React from 'react';
|
|
11
10
|
import { IS_EDITING_INITIAL_VALUE } from '../constants';
|
|
12
11
|
import { i18n } from '../i18n';
|
|
12
|
+
import { getEditFieldConfig, renderEditField } from '../utils/render-edit-fields';
|
|
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);
|
|
@@ -146,16 +147,20 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
146
147
|
const renderCellValue = ({ column, row, rowId }) => {
|
|
147
148
|
const dataIndex = get(column, 'dataIndex', '');
|
|
148
149
|
const value = get(row, dataIndex, '');
|
|
149
|
-
if (hasEdit &&
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
if (hasEdit && checkIsEditing(rowId)) {
|
|
151
|
+
const config = getEditFieldConfig(editDataIndexes, dataIndex);
|
|
152
|
+
if (config) {
|
|
153
|
+
const handleOnChangeValue = (changedValue) => {
|
|
154
|
+
onEdit(rowId, {
|
|
155
|
+
[dataIndex]: changedValue
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
return renderEditField({
|
|
159
|
+
config,
|
|
160
|
+
value,
|
|
161
|
+
onChange: handleOnChangeValue
|
|
156
162
|
});
|
|
157
|
-
}
|
|
158
|
-
return (React.createElement(Input, { className: "w-44 h-9", onChange: handleOnChangeValue, value: value }));
|
|
163
|
+
}
|
|
159
164
|
}
|
|
160
165
|
if (hasMapper && isMapperColumn(dataIndex)) {
|
|
161
166
|
return renderMapper({
|
|
@@ -182,10 +187,15 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
182
187
|
}), onClick: handleClick }));
|
|
183
188
|
};
|
|
184
189
|
const renderTableCells = (row, rowId) => {
|
|
190
|
+
const mapperValue = hasMapper && mapperDataIndex ? row[mapperDataIndex] : null;
|
|
191
|
+
const hasMultipleMapperItems = Array.isArray(mapperValue) && mapperValue.length > 1;
|
|
185
192
|
return columns.map((column, colIndex) => {
|
|
186
193
|
const isFirstColumn = colIndex === 0;
|
|
187
194
|
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 &&
|
|
195
|
+
isFirstColumn &&
|
|
196
|
+
hasMapper &&
|
|
197
|
+
hasMultipleMapperItems &&
|
|
198
|
+
renderExpandButton(rowId),
|
|
189
199
|
renderCellValue({
|
|
190
200
|
column,
|
|
191
201
|
row,
|
|
@@ -213,7 +223,7 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
213
223
|
};
|
|
214
224
|
const renderEmptyRow = () => {
|
|
215
225
|
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'))));
|
|
226
|
+
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
227
|
};
|
|
218
228
|
const renderGradientOverlay = () => {
|
|
219
229
|
return (React.createElement(React.Fragment, null,
|
|
@@ -298,7 +308,7 @@ export const TableContent = ({ columns, customActionButtons, data, editDataIndex
|
|
|
298
308
|
return useStyle(React.createElement("div", { className: "bg-ebonyClay-450 rounded-lg overflow-hidden" },
|
|
299
309
|
React.createElement("div", { className: `${baseCls}__table-wrapper ${hashId} overflow-x-auto overflow-y-auto` },
|
|
300
310
|
React.createElement("div", { className: "relative" },
|
|
301
|
-
renderGradientOverlay(),
|
|
311
|
+
data.length > 0 && renderGradientOverlay(),
|
|
302
312
|
React.createElement("table", { ref: tableRef, className: `${baseCls}__table-element ${hashId} w-full bg-ebonyClay-450` },
|
|
303
313
|
React.createElement("thead", null, renderTableHeaders()),
|
|
304
314
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/constants/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;CAExB,CAAC;AAEF,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,eAAO,MAAM,iBAAiB;;;GAG3B,CAAC;AAEJ,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,eAAO,MAAM,wBAAwB,MAAO,CAAC;AAE7C,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ai-table/constants/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;CAExB,CAAC;AAEF,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,eAAO,MAAM,iBAAiB;;;GAG3B,CAAC;AAEJ,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,eAAO,MAAM,wBAAwB,MAAO,CAAC;AAE7C,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC"}
|
|
@@ -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
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../../../src/ai-table/utils/render-edit-fields/__tests__/index.test.tsx"],"names":[],"mappings":""}
|