@dxos/react-ui-table 0.6.13-main.ed424a1 → 0.6.13
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/lib/browser/index.mjs +127 -43
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts +3 -6
- package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts +3 -3
- package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.d.ts +12 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.d.ts.map +1 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.stories.d.ts +63 -0
- package/dist/types/src/components/ColumnMenu/ColumnSettingsForm.stories.d.ts.map +1 -0
- package/dist/types/src/components/ColumnMenu/index.d.ts +1 -1
- package/dist/types/src/components/ColumnMenu/index.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +9 -21
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableContext.d.ts +4 -2
- package/dist/types/src/components/Table/TableContext.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableHead.d.ts.map +1 -1
- package/dist/types/src/components/Table/index.d.ts +1 -2
- package/dist/types/src/components/Table/index.d.ts.map +1 -1
- package/dist/types/src/helpers.d.ts +1 -1
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/hooks/useRowSelection.d.ts.map +1 -1
- package/dist/types/src/schema/{Schema.stories.d.ts → SchemaToTable.stories.d.ts} +3 -2
- package/dist/types/src/schema/SchemaToTable.stories.d.ts.map +1 -0
- package/dist/types/src/schema/index.d.ts +1 -1
- package/dist/types/src/schema/index.d.ts.map +1 -1
- package/dist/types/src/schema/schema.d.ts +5 -0
- package/dist/types/src/schema/schema.d.ts.map +1 -0
- package/dist/types/src/schema/schema.test.d.ts +2 -0
- package/dist/types/src/schema/schema.test.d.ts.map +1 -0
- package/dist/types/src/schema/{column-utils.d.ts → schemaToColumns.d.ts} +2 -2
- package/dist/types/src/schema/schemaToColumns.d.ts.map +1 -0
- package/dist/types/src/schema/types.d.ts +4 -10
- package/dist/types/src/schema/types.d.ts.map +1 -1
- package/package.json +20 -21
- package/src/components/ColumnMenu/ColumnMenu.stories.tsx +12 -13
- package/src/components/ColumnMenu/ColumnMenu.tsx +5 -8
- package/src/components/ColumnMenu/{ColumnSettings.stories.tsx → ColumnSettingsForm.stories.tsx} +23 -27
- package/src/components/ColumnMenu/{ColumnSettings.tsx → ColumnSettingsForm.tsx} +43 -44
- package/src/components/ColumnMenu/index.ts +1 -1
- package/src/components/Table/Table.stories.tsx +85 -97
- package/src/components/Table/Table.tsx +9 -8
- package/src/components/Table/TableContext.tsx +7 -13
- package/src/components/Table/TableHead.tsx +1 -0
- package/src/components/Table/index.ts +1 -2
- package/src/components/Table/props.ts +4 -4
- package/src/helpers.tsx +6 -4
- package/src/hooks/useRowSelection.ts +0 -1
- package/src/schema/{Schema.stories.tsx → SchemaToTable.stories.tsx} +23 -11
- package/src/schema/index.ts +1 -1
- package/src/schema/schema.test.ts +148 -0
- package/src/schema/schema.ts +93 -0
- package/src/schema/{column-utils.ts → schemaToColumns.ts} +9 -9
- package/src/schema/types.ts +6 -14
- package/src/translations.ts +1 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts +0 -15
- package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
- package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts +0 -84
- package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
- package/dist/types/src/schema/Schema.stories.d.ts.map +0 -1
- package/dist/types/src/schema/column-utils.d.ts.map +0 -1
|
@@ -7,12 +7,11 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type SortDirection } from '@tanstack/react-table';
|
|
8
8
|
import React, { useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import { FieldValueType } from '@dxos/schema';
|
|
11
10
|
import { withTheme } from '@dxos/storybook-utils';
|
|
12
11
|
|
|
13
12
|
import { ColumnMenu } from './ColumnMenu';
|
|
14
|
-
import { type
|
|
15
|
-
import { type
|
|
13
|
+
import { type ColumnSettingsFormProps } from './ColumnSettingsForm';
|
|
14
|
+
import { type ColumnProps } from '../../schema';
|
|
16
15
|
|
|
17
16
|
export default {
|
|
18
17
|
title: 'react-ui-table/ColumnMenu',
|
|
@@ -20,27 +19,27 @@ export default {
|
|
|
20
19
|
decorators: [withTheme],
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
const defs: Pick<
|
|
22
|
+
const defs: Pick<ColumnSettingsFormProps, 'tableDef' | 'tablesToReference'> = {
|
|
24
23
|
tableDef: {
|
|
25
24
|
id: '1',
|
|
26
25
|
name: 'table 1',
|
|
27
|
-
columns: [{ id: 'col-1', prop: 'one', type:
|
|
26
|
+
columns: [{ id: 'col-1', prop: 'one-foo', type: 'string' }],
|
|
28
27
|
},
|
|
29
28
|
tablesToReference: [
|
|
30
29
|
{
|
|
31
30
|
id: '1',
|
|
32
31
|
name: 'table 1',
|
|
33
|
-
columns: [{ id: 'col-1', prop: 'one', type:
|
|
32
|
+
columns: [{ id: 'col-1', prop: 'one-foo', type: 'string' }],
|
|
34
33
|
},
|
|
35
34
|
{
|
|
36
35
|
id: '2',
|
|
37
36
|
name: 'table 2',
|
|
38
|
-
columns: [{ id: 'col-1', prop: 'two', type:
|
|
37
|
+
columns: [{ id: 'col-1', prop: 'two-foo', type: 'string' }],
|
|
39
38
|
},
|
|
40
39
|
],
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
const
|
|
42
|
+
const funcs: Pick<ColumnSettingsFormProps, 'onUpdate' | 'onDelete'> = {
|
|
44
43
|
onUpdate: (...args: any) => console.log('onUpdate args', args),
|
|
45
44
|
onDelete: (...args: any) => console.log('onDelete args', args),
|
|
46
45
|
};
|
|
@@ -50,10 +49,10 @@ export const Default = {
|
|
|
50
49
|
column: {
|
|
51
50
|
id: 'test',
|
|
52
51
|
label: 'test',
|
|
53
|
-
} as
|
|
52
|
+
} as ColumnProps,
|
|
54
53
|
|
|
55
54
|
...defs,
|
|
56
|
-
...
|
|
55
|
+
...funcs,
|
|
57
56
|
|
|
58
57
|
context: {
|
|
59
58
|
header: {
|
|
@@ -90,13 +89,11 @@ export const ReactiveSort = {
|
|
|
90
89
|
column: {
|
|
91
90
|
id: 'test',
|
|
92
91
|
label: 'test',
|
|
93
|
-
} as
|
|
92
|
+
} as ColumnProps,
|
|
94
93
|
context: {
|
|
95
94
|
header: {
|
|
96
95
|
column: {
|
|
97
96
|
getCanSort: () => true,
|
|
98
|
-
getIsSorted: () => sort,
|
|
99
|
-
clearSorting: () => setSort(false),
|
|
100
97
|
toggleSorting: (desc?: boolean) => {
|
|
101
98
|
if (desc === undefined) {
|
|
102
99
|
setSort(false);
|
|
@@ -106,6 +103,8 @@ export const ReactiveSort = {
|
|
|
106
103
|
setSort('asc');
|
|
107
104
|
}
|
|
108
105
|
},
|
|
106
|
+
getIsSorted: () => sort,
|
|
107
|
+
clearSorting: () => setSort(false),
|
|
109
108
|
getToggleSortingHandler: () => () => {
|
|
110
109
|
if (sort === 'asc') {
|
|
111
110
|
setSort('desc');
|
|
@@ -9,25 +9,22 @@ import React, { useRef, useState, useCallback } from 'react';
|
|
|
9
9
|
import { Button, Popover, DropdownMenu } from '@dxos/react-ui';
|
|
10
10
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { ColumnSettingsForm } from './ColumnSettingsForm';
|
|
13
13
|
import { useSortColumn } from '../../hooks';
|
|
14
|
-
import { type TableDef, type
|
|
14
|
+
import { type TableDef, type ColumnProps } from '../../schema';
|
|
15
15
|
|
|
16
16
|
export type ColumnMenuProps<TData extends RowData, TValue> = {
|
|
17
17
|
context: HeaderContext<TData, TValue>;
|
|
18
18
|
tablesToReference: TableDef[];
|
|
19
19
|
tableDef: TableDef;
|
|
20
|
-
column:
|
|
20
|
+
column: ColumnProps;
|
|
21
21
|
columnOrderable: boolean;
|
|
22
22
|
columnPosition: 'start' | 'end' | undefined;
|
|
23
23
|
onColumnReorder: (columnId: string, direction: 'left' | 'right') => void;
|
|
24
|
-
onUpdate?: (id: string, column:
|
|
24
|
+
onUpdate?: (id: string, column: ColumnProps) => void;
|
|
25
25
|
onDelete?: (id: string) => void;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* @deprecated
|
|
30
|
-
*/
|
|
31
28
|
export const ColumnMenu = <TData extends RowData, TValue>({
|
|
32
29
|
column,
|
|
33
30
|
columnOrderable,
|
|
@@ -141,7 +138,7 @@ export const ColumnMenu = <TData extends RowData, TValue>({
|
|
|
141
138
|
<Popover.Portal>
|
|
142
139
|
<Popover.Content>
|
|
143
140
|
<Popover.Viewport>
|
|
144
|
-
<
|
|
141
|
+
<ColumnSettingsForm {...props} column={column} onClose={() => setIsColumnSettingsOpen(false)} />
|
|
145
142
|
</Popover.Viewport>
|
|
146
143
|
<Popover.Arrow />
|
|
147
144
|
</Popover.Content>
|
package/src/components/ColumnMenu/{ColumnSettings.stories.tsx → ColumnSettingsForm.stories.tsx}
RENAMED
|
@@ -3,38 +3,25 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
|
-
|
|
7
6
|
import React from 'react';
|
|
8
7
|
|
|
9
|
-
import {
|
|
10
|
-
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
8
|
+
import { withTheme } from '@dxos/storybook-utils';
|
|
11
9
|
|
|
12
|
-
import {
|
|
10
|
+
import { ColumnSettingsForm, type ColumnSettingsFormProps } from './ColumnSettingsForm';
|
|
13
11
|
import { type TableDef } from '../../schema';
|
|
14
|
-
import translations from '../../translations';
|
|
15
|
-
|
|
16
|
-
const Story = (props: ColumnSettingsProps) => (
|
|
17
|
-
<div className='flex w-[240px] m-2 p-2 border border-separator rounded'>
|
|
18
|
-
<ColumnSettings {...props} />
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
12
|
|
|
22
13
|
export default {
|
|
23
|
-
title: 'react-ui-table/
|
|
24
|
-
component:
|
|
25
|
-
decorators: [withTheme
|
|
26
|
-
parameters: {
|
|
27
|
-
translations,
|
|
28
|
-
},
|
|
29
|
-
render: Story,
|
|
14
|
+
title: 'react-ui-table/ColumnSettingsForm',
|
|
15
|
+
component: ColumnSettingsForm,
|
|
16
|
+
decorators: [withTheme],
|
|
30
17
|
};
|
|
31
18
|
|
|
32
19
|
const sampleTableDef: TableDef = {
|
|
33
20
|
id: '1',
|
|
34
21
|
name: 'Sample Table',
|
|
35
22
|
columns: [
|
|
36
|
-
{ id: 'col-1', prop: 'name', type:
|
|
37
|
-
{ id: 'col-2', prop: 'age', type:
|
|
23
|
+
{ id: 'col-1', prop: 'name', type: 'string', label: 'Name' },
|
|
24
|
+
{ id: 'col-2', prop: 'age', type: 'number', label: 'Age', digits: 0 },
|
|
38
25
|
],
|
|
39
26
|
};
|
|
40
27
|
|
|
@@ -44,17 +31,17 @@ const sampleTablesToReference: TableDef[] = [
|
|
|
44
31
|
id: '2',
|
|
45
32
|
name: 'Reference Table',
|
|
46
33
|
columns: [
|
|
47
|
-
{ id: 'ref-col-1', prop: 'id', type:
|
|
48
|
-
{ id: 'ref-col-2', prop: 'description', type:
|
|
34
|
+
{ id: 'ref-col-1', prop: 'id', type: 'string', label: 'ID' },
|
|
35
|
+
{ id: 'ref-col-2', prop: 'description', type: 'string', label: 'Description' },
|
|
49
36
|
],
|
|
50
37
|
},
|
|
51
38
|
];
|
|
52
39
|
|
|
53
|
-
const defaultArgs:
|
|
40
|
+
const defaultArgs: ColumnSettingsFormProps = {
|
|
54
41
|
column: {
|
|
55
42
|
id: 'col-1',
|
|
56
43
|
prop: 'name',
|
|
57
|
-
type:
|
|
44
|
+
type: 'string',
|
|
58
45
|
label: 'Name',
|
|
59
46
|
},
|
|
60
47
|
tableDef: sampleTableDef,
|
|
@@ -74,7 +61,7 @@ export const NumberColumn = {
|
|
|
74
61
|
column: {
|
|
75
62
|
id: 'col-2',
|
|
76
63
|
prop: 'age',
|
|
77
|
-
type:
|
|
64
|
+
type: 'number',
|
|
78
65
|
label: 'Age',
|
|
79
66
|
digits: 0,
|
|
80
67
|
},
|
|
@@ -87,7 +74,7 @@ export const ReferenceColumn = {
|
|
|
87
74
|
column: {
|
|
88
75
|
id: 'col-3',
|
|
89
76
|
prop: 'reference',
|
|
90
|
-
type:
|
|
77
|
+
type: 'ref',
|
|
91
78
|
label: 'Reference',
|
|
92
79
|
refTable: '2',
|
|
93
80
|
refProp: 'ref-col-1',
|
|
@@ -101,8 +88,17 @@ export const NewColumn = {
|
|
|
101
88
|
column: {
|
|
102
89
|
id: 'new-col',
|
|
103
90
|
prop: '',
|
|
104
|
-
type:
|
|
91
|
+
type: 'string',
|
|
105
92
|
label: '',
|
|
106
93
|
},
|
|
107
94
|
},
|
|
108
95
|
};
|
|
96
|
+
|
|
97
|
+
const Template = (args: ColumnSettingsFormProps) => (
|
|
98
|
+
<div className='p-4 max-is-64'>
|
|
99
|
+
<ColumnSettingsForm {...args} />
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
export const Interactive = Template.bind({});
|
|
104
|
+
(Interactive as any).args = defaultArgs;
|
|
@@ -1,39 +1,31 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
|
|
5
4
|
import React, { useRef, useState } from 'react';
|
|
6
5
|
|
|
7
6
|
import { Button, Input, Select, useTranslation } from '@dxos/react-ui';
|
|
8
|
-
import { FieldValueTypes, type FieldValueType } from '@dxos/schema';
|
|
9
7
|
import { safeParseInt } from '@dxos/util';
|
|
10
8
|
|
|
11
|
-
import { type TableDef, type
|
|
9
|
+
import { type TableDef, type ColumnProps, type ColumnType } from '../../schema';
|
|
12
10
|
import { translationKey } from '../../translations';
|
|
13
11
|
|
|
14
|
-
export type
|
|
15
|
-
column:
|
|
12
|
+
export type ColumnSettingsFormProps = {
|
|
13
|
+
column: ColumnProps;
|
|
16
14
|
tableDef: TableDef;
|
|
17
|
-
// TODO(burdon): Rename.
|
|
18
15
|
tablesToReference: TableDef[];
|
|
19
|
-
onUpdate?: (id: string, column:
|
|
20
|
-
onDelete?: (id: string) => void;
|
|
16
|
+
onUpdate?: ((id: string, column: ColumnProps) => void) | undefined;
|
|
17
|
+
onDelete?: ((id: string) => void) | undefined;
|
|
21
18
|
onClose?: () => void;
|
|
22
19
|
};
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
* @deprecated
|
|
26
|
-
*/
|
|
27
|
-
export const ColumnSettings = ({
|
|
21
|
+
export const ColumnSettingsForm = ({
|
|
28
22
|
column,
|
|
29
23
|
tableDef,
|
|
30
24
|
tablesToReference,
|
|
31
25
|
onUpdate,
|
|
32
26
|
onDelete,
|
|
33
27
|
onClose,
|
|
34
|
-
}:
|
|
35
|
-
const { t } = useTranslation(translationKey);
|
|
36
|
-
const propRef = useRef<HTMLInputElement>(null);
|
|
28
|
+
}: ColumnSettingsFormProps) => {
|
|
37
29
|
const [formState, setFormState] = useState({
|
|
38
30
|
prop: column.id,
|
|
39
31
|
refTable: column.refTable,
|
|
@@ -43,6 +35,9 @@ export const ColumnSettings = ({
|
|
|
43
35
|
digits: String(column.digits ?? '0'),
|
|
44
36
|
});
|
|
45
37
|
|
|
38
|
+
const propRef = useRef<HTMLInputElement>(null);
|
|
39
|
+
const { t } = useTranslation(translationKey);
|
|
40
|
+
|
|
46
41
|
const handleSave = () => {
|
|
47
42
|
const { prop, refTable, refProp, type, label, digits } = formState;
|
|
48
43
|
|
|
@@ -67,7 +62,7 @@ export const ColumnSettings = ({
|
|
|
67
62
|
id: prop, // TODO(burdon): Make unique.
|
|
68
63
|
prop,
|
|
69
64
|
label,
|
|
70
|
-
type: type as
|
|
65
|
+
type: type as ColumnProps['type'],
|
|
71
66
|
refTable,
|
|
72
67
|
refProp,
|
|
73
68
|
digits: safeParseInt(digits),
|
|
@@ -80,10 +75,9 @@ export const ColumnSettings = ({
|
|
|
80
75
|
onClose?.();
|
|
81
76
|
};
|
|
82
77
|
|
|
83
|
-
// TODO(burdon): Standardize dialog/popup.
|
|
84
78
|
return (
|
|
85
|
-
<div className='
|
|
86
|
-
<div className='
|
|
79
|
+
<div className='p-1 space-y-2'>
|
|
80
|
+
<div className='space-y-1'>
|
|
87
81
|
<Input.Root>
|
|
88
82
|
<Input.Label>{t('column label label')}</Input.Label>
|
|
89
83
|
<Input.TextInput
|
|
@@ -94,7 +88,8 @@ export const ColumnSettings = ({
|
|
|
94
88
|
data-testid='table.column-settings.label'
|
|
95
89
|
/>
|
|
96
90
|
</Input.Root>
|
|
97
|
-
|
|
91
|
+
</div>
|
|
92
|
+
<div className='space-y-1'>
|
|
98
93
|
<Input.Root>
|
|
99
94
|
<Input.Label>{t('property key label')}</Input.Label>
|
|
100
95
|
<Input.TextInput
|
|
@@ -106,7 +101,8 @@ export const ColumnSettings = ({
|
|
|
106
101
|
}
|
|
107
102
|
/>
|
|
108
103
|
</Input.Root>
|
|
109
|
-
|
|
104
|
+
</div>
|
|
105
|
+
<div className='space-y-1'>
|
|
110
106
|
<Input.Root>
|
|
111
107
|
<Input.Label>{t('column type label')}</Input.Label>
|
|
112
108
|
<Select.Root
|
|
@@ -117,7 +113,7 @@ export const ColumnSettings = ({
|
|
|
117
113
|
<Select.Portal>
|
|
118
114
|
<Select.Content>
|
|
119
115
|
<Select.Viewport>
|
|
120
|
-
{
|
|
116
|
+
{(['number', 'boolean', 'string', 'ref'] as ColumnType[]).map((type) => (
|
|
121
117
|
<Select.Option key={type} value={type}>
|
|
122
118
|
{t(`${type} column type label`)}
|
|
123
119
|
</Select.Option>
|
|
@@ -127,8 +123,9 @@ export const ColumnSettings = ({
|
|
|
127
123
|
</Select.Portal>
|
|
128
124
|
</Select.Root>
|
|
129
125
|
</Input.Root>
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
</div>
|
|
127
|
+
{formState.type === 'number' && (
|
|
128
|
+
<div className='space-y-1'>
|
|
132
129
|
<Input.Root>
|
|
133
130
|
<Input.Label>{t('digits label')}</Input.Label>
|
|
134
131
|
<Input.TextInput
|
|
@@ -136,10 +133,12 @@ export const ColumnSettings = ({
|
|
|
136
133
|
onChange={(event) => setFormState((prevState) => ({ ...prevState, digits: event.target.value }))}
|
|
137
134
|
/>
|
|
138
135
|
</Input.Root>
|
|
139
|
-
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
140
138
|
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
{formState.type === 'ref' && (
|
|
140
|
+
<>
|
|
141
|
+
<div className='space-y-1'>
|
|
143
142
|
<Input.Root>
|
|
144
143
|
<Input.Label>Table</Input.Label>
|
|
145
144
|
<Select.Root
|
|
@@ -162,8 +161,9 @@ export const ColumnSettings = ({
|
|
|
162
161
|
</Select.Portal>
|
|
163
162
|
</Select.Root>
|
|
164
163
|
</Input.Root>
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
</div>
|
|
165
|
+
{formState.refTable && (
|
|
166
|
+
<div className='space-y-1'>
|
|
167
167
|
<Input.Root>
|
|
168
168
|
<Input.Label>Table property</Input.Label>
|
|
169
169
|
<Select.Root
|
|
@@ -186,21 +186,20 @@ export const ColumnSettings = ({
|
|
|
186
186
|
</Select.Portal>
|
|
187
187
|
</Select.Root>
|
|
188
188
|
</Input.Root>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
<div
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
</div>
|
|
189
|
+
</div>
|
|
190
|
+
)}
|
|
191
|
+
</>
|
|
192
|
+
)}
|
|
193
|
+
|
|
194
|
+
<div role='none' className='h-1' />
|
|
195
|
+
|
|
196
|
+
<div className='flex flex-row justify-end gap-1'>
|
|
197
|
+
<Button onClick={handleDelete} data-testid='table.column-settings.delete'>
|
|
198
|
+
{t('delete label')}
|
|
199
|
+
</Button>
|
|
200
|
+
<Button variant='primary' onClick={handleSave} data-testid='table.column-settings.save'>
|
|
201
|
+
{t('save label')}
|
|
202
|
+
</Button>
|
|
204
203
|
</div>
|
|
205
204
|
</div>
|
|
206
205
|
);
|
|
@@ -8,11 +8,11 @@ import { Plugs, PlugsConnected } from '@phosphor-icons/react';
|
|
|
8
8
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
9
9
|
|
|
10
10
|
import { create } from '@dxos/echo-schema';
|
|
11
|
+
import { registerSignalRuntime } from '@dxos/echo-signals/react';
|
|
11
12
|
import { PublicKey } from '@dxos/keys';
|
|
12
|
-
import { log } from '@dxos/log';
|
|
13
13
|
import { faker } from '@dxos/random';
|
|
14
14
|
import { Button, DensityProvider } from '@dxos/react-ui';
|
|
15
|
-
import {
|
|
15
|
+
import { withTheme } from '@dxos/storybook-utils';
|
|
16
16
|
import { range } from '@dxos/util';
|
|
17
17
|
|
|
18
18
|
import { Table } from './Table';
|
|
@@ -406,117 +406,105 @@ export const TenThousandRows = {
|
|
|
406
406
|
},
|
|
407
407
|
};
|
|
408
408
|
|
|
409
|
-
|
|
409
|
+
registerSignalRuntime();
|
|
410
|
+
const state = create({ items: createItems(10) });
|
|
410
411
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (
|
|
412
|
+
export const RealTimeUpdates = {
|
|
413
|
+
args: {
|
|
414
|
+
periodicMutations: true,
|
|
415
|
+
mutationInterval: 1000,
|
|
416
|
+
periodicDeletions: false,
|
|
417
|
+
deletionInterval: 5000,
|
|
418
|
+
periodicInsertions: false,
|
|
419
|
+
insertionInterval: 3000,
|
|
420
|
+
},
|
|
421
|
+
argTypes: {
|
|
422
|
+
mutationInterval: { control: 'number' },
|
|
423
|
+
periodicDeletions: { control: 'boolean' },
|
|
424
|
+
deletionInterval: { control: 'number' },
|
|
425
|
+
periodicInsertions: { control: 'boolean' },
|
|
426
|
+
insertionInterval: { control: 'number' },
|
|
427
|
+
},
|
|
428
|
+
render: ({
|
|
429
|
+
periodicMutations,
|
|
430
|
+
mutationInterval,
|
|
431
|
+
periodicDeletions,
|
|
432
|
+
deletionInterval,
|
|
433
|
+
periodicInsertions,
|
|
434
|
+
insertionInterval,
|
|
435
|
+
}: any) => {
|
|
436
|
+
useEffect(() => {
|
|
437
|
+
if (!periodicMutations) {
|
|
437
438
|
return;
|
|
438
439
|
}
|
|
439
440
|
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
state.items[idx].started = new Date();
|
|
445
|
-
}, mutationInterval);
|
|
441
|
+
const interval = setInterval(() => {
|
|
442
|
+
if (state.items.length === 0) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
446
445
|
|
|
447
|
-
|
|
448
|
-
|
|
446
|
+
const randomIndex = Math.floor(Math.random() * state.items.length);
|
|
447
|
+
console.log('Mutating row', randomIndex);
|
|
448
|
+
state.items[randomIndex].name = faker.commerce.productName();
|
|
449
|
+
state.items[randomIndex].count = Math.floor(Math.random() * 1000);
|
|
450
|
+
state.items[randomIndex].started = new Date();
|
|
451
|
+
}, mutationInterval);
|
|
449
452
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
453
|
+
return () => clearInterval(interval);
|
|
454
|
+
}, [periodicMutations, mutationInterval, state.items]);
|
|
454
455
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
if (!periodicInsertions) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
459
460
|
|
|
460
|
-
|
|
461
|
-
|
|
461
|
+
const interval = setInterval(() => {
|
|
462
|
+
console.log('Inserting...');
|
|
463
|
+
state.items.push(createItems(1)[0]);
|
|
464
|
+
}, insertionInterval);
|
|
462
465
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
466
|
+
return () => clearInterval(interval);
|
|
467
|
+
}, [periodicInsertions, insertionInterval, state.items]);
|
|
467
468
|
|
|
468
|
-
|
|
469
|
-
if (
|
|
469
|
+
useEffect(() => {
|
|
470
|
+
if (!periodicDeletions) {
|
|
470
471
|
return;
|
|
471
472
|
}
|
|
472
473
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
474
|
+
const interval = setInterval(() => {
|
|
475
|
+
if (state.items.length === 0) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
477
478
|
|
|
478
|
-
|
|
479
|
-
}, [periodicDeletions, deletionInterval, state.items]);
|
|
479
|
+
console.log('Deleting');
|
|
480
480
|
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
// Randomly delete a row from state.items
|
|
482
|
+
const randomIndex = Math.floor(Math.random() * state.items.length);
|
|
483
|
+
state.items.splice(randomIndex, 1);
|
|
484
|
+
}, deletionInterval);
|
|
483
485
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
<Table.Viewport classNames='fixed inset-0'>
|
|
487
|
-
<Table.Main<Item>
|
|
488
|
-
role='grid'
|
|
489
|
-
rowsSelectable='multi'
|
|
490
|
-
keyAccessor={(row) => row.publicKey.toHex()}
|
|
491
|
-
columns={columns}
|
|
492
|
-
data={state.items}
|
|
493
|
-
fullWidth
|
|
494
|
-
stickyHeader
|
|
495
|
-
border
|
|
496
|
-
pinLastRow
|
|
497
|
-
/>
|
|
498
|
-
</Table.Viewport>
|
|
499
|
-
</Table.Root>
|
|
500
|
-
);
|
|
501
|
-
};
|
|
486
|
+
return () => clearInterval(interval);
|
|
487
|
+
}, [periodicDeletions, deletionInterval, state.items]);
|
|
502
488
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
489
|
+
const onUpdate = useCallback((...args: any[]) => {}, []);
|
|
490
|
+
const columns = useMemo(() => makeColumns(onUpdate), []);
|
|
491
|
+
|
|
492
|
+
return (
|
|
493
|
+
<Table.Root>
|
|
494
|
+
<Table.Viewport classNames='fixed inset-0'>
|
|
495
|
+
<Table.Main<Item>
|
|
496
|
+
role='grid'
|
|
497
|
+
rowsSelectable='multi'
|
|
498
|
+
keyAccessor={(row) => row.publicKey.toHex()}
|
|
499
|
+
columns={columns}
|
|
500
|
+
data={state.items}
|
|
501
|
+
fullWidth
|
|
502
|
+
stickyHeader
|
|
503
|
+
border
|
|
504
|
+
pinLastRow
|
|
505
|
+
/>
|
|
506
|
+
</Table.Viewport>
|
|
507
|
+
</Table.Root>
|
|
508
|
+
);
|
|
511
509
|
},
|
|
512
|
-
args: {
|
|
513
|
-
periodicMutations: true,
|
|
514
|
-
mutationInterval: 1000,
|
|
515
|
-
periodicDeletions: false,
|
|
516
|
-
deletionInterval: 5000,
|
|
517
|
-
periodicInsertions: false,
|
|
518
|
-
insertionInterval: 3000,
|
|
519
|
-
} satisfies StoryProps,
|
|
520
|
-
decorators: [withSignals],
|
|
521
|
-
render: Story,
|
|
522
510
|
};
|