@dxos/react-ui-table 0.7.2 → 0.7.3-staging.0905f03
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/{chunk-EWGUNGJC.mjs → chunk-IYCSJDMB.mjs} +5 -3
- package/dist/lib/browser/chunk-IYCSJDMB.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +461 -237
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +3 -1
- package/dist/lib/node/{chunk-A2N7XWW6.cjs → chunk-MHBMVCFZ.cjs} +8 -5
- package/dist/lib/node/chunk-MHBMVCFZ.cjs.map +7 -0
- package/dist/lib/node/index.cjs +471 -253
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +4 -2
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{chunk-SABDOZ6I.mjs → chunk-BMWGPXPL.mjs} +5 -3
- package/dist/lib/node-esm/chunk-BMWGPXPL.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +461 -237
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +3 -1
- package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +8 -0
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -0
- package/dist/types/src/components/Table/RefPanel.d.ts +8 -0
- package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -0
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +2 -2
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +16 -7
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts +2 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +11 -0
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +4 -5
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +57 -2
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts +8 -0
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/package.json +29 -28
- package/src/_deprecated/components/Table/Table.stories.tsx +1 -1
- package/src/components/Table/ColumnActionsMenu.tsx +0 -1
- package/src/components/Table/ColumnSettings.tsx +7 -4
- package/src/components/Table/CreateRefPanel.tsx +83 -0
- package/src/components/Table/RefPanel.tsx +52 -0
- package/src/components/Table/RowActionsMenu.tsx +1 -2
- package/src/components/Table/Table.stories.tsx +1 -1
- package/src/components/Table/Table.tsx +60 -33
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +1 -1
- package/src/components/TableCellEditor/TableCellEditor.tsx +72 -23
- package/src/components/TableCellEditor/extension.ts +3 -4
- package/src/components/testing.ts +2 -1
- package/src/model/modal-controller.ts +43 -0
- package/src/model/table-model.test.ts +5 -3
- package/src/model/table-model.ts +34 -22
- package/src/playwright/smoke.spec.ts +0 -4
- package/src/translations.ts +1 -0
- package/src/types/table.ts +5 -5
- package/src/util/index.ts +0 -1
- package/src/util/table-buttons.ts +18 -1
- package/dist/lib/browser/chunk-EWGUNGJC.mjs.map +0 -7
- package/dist/lib/node/chunk-A2N7XWW6.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-SABDOZ6I.mjs.map +0 -7
- package/dist/types/src/util/grid.d.ts +0 -14
- package/dist/types/src/util/grid.d.ts.map +0 -1
- package/src/util/grid.ts +0 -23
|
@@ -1,4 +1,57 @@
|
|
|
1
|
-
import { ref, S } from '@dxos/echo-schema';
|
|
1
|
+
import { ref, ObjectId, S } from '@dxos/echo-schema';
|
|
2
|
+
export declare const TableSchema: S.Struct<{
|
|
3
|
+
id: S.SchemaClass<string, string, never> & {
|
|
4
|
+
random(): ObjectId;
|
|
5
|
+
};
|
|
6
|
+
name: S.optional<typeof S.String>;
|
|
7
|
+
view: S.optional<ref<{
|
|
8
|
+
name: string;
|
|
9
|
+
schema?: import("@dxos/echo-schema").JsonSchemaType | undefined;
|
|
10
|
+
query: import("@dxos/echo-schema").QueryType;
|
|
11
|
+
fields: {
|
|
12
|
+
referencePath?: import("@dxos/echo-schema").JsonPath | undefined;
|
|
13
|
+
id: string;
|
|
14
|
+
path: import("@dxos/echo-schema").JsonPath;
|
|
15
|
+
visible?: boolean | undefined;
|
|
16
|
+
size?: number | undefined;
|
|
17
|
+
}[];
|
|
18
|
+
} & {
|
|
19
|
+
id: string;
|
|
20
|
+
}>>;
|
|
21
|
+
threads: S.optional<S.Array$<ref<{
|
|
22
|
+
name?: string | undefined;
|
|
23
|
+
anchor?: string | undefined;
|
|
24
|
+
status?: "active" | "staged" | "resolved" | undefined;
|
|
25
|
+
messages: import("@dxos/echo-schema").Ref<{
|
|
26
|
+
text: string;
|
|
27
|
+
timestamp: string;
|
|
28
|
+
state?: import("@dxos/plugin-space").MessageState | undefined;
|
|
29
|
+
sender: {
|
|
30
|
+
name?: string | undefined;
|
|
31
|
+
contact?: import("@dxos/echo-schema").Ref<{
|
|
32
|
+
name?: string | undefined;
|
|
33
|
+
identifiers: {
|
|
34
|
+
readonly value: string;
|
|
35
|
+
readonly type: string;
|
|
36
|
+
}[];
|
|
37
|
+
} & {
|
|
38
|
+
id: string;
|
|
39
|
+
}>;
|
|
40
|
+
identityKey?: string | undefined;
|
|
41
|
+
email?: string | undefined;
|
|
42
|
+
};
|
|
43
|
+
parts?: import("@dxos/echo-schema").Ref<import("@dxos/echo-schema").Expando>[] | undefined;
|
|
44
|
+
properties?: {
|
|
45
|
+
[x: string]: any;
|
|
46
|
+
} | undefined;
|
|
47
|
+
context?: import("@dxos/echo-schema").Ref<import("@dxos/echo-schema").Expando>;
|
|
48
|
+
} & {
|
|
49
|
+
id: string;
|
|
50
|
+
}>[];
|
|
51
|
+
} & {
|
|
52
|
+
id: string;
|
|
53
|
+
}>>>;
|
|
54
|
+
}>;
|
|
2
55
|
declare const TableType_base: import("@dxos/echo-schema").AbstractTypedObject<{
|
|
3
56
|
name?: string | undefined;
|
|
4
57
|
id: string;
|
|
@@ -52,7 +105,9 @@ declare const TableType_base: import("@dxos/echo-schema").AbstractTypedObject<{
|
|
|
52
105
|
} & {
|
|
53
106
|
id: string;
|
|
54
107
|
}, S.Struct.Encoded<{
|
|
55
|
-
readonly id:
|
|
108
|
+
readonly id: S.SchemaClass<string, string, never> & {
|
|
109
|
+
random(): ObjectId;
|
|
110
|
+
};
|
|
56
111
|
readonly name: S.optional<typeof S.String>;
|
|
57
112
|
readonly view: S.optional<ref<{
|
|
58
113
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../../src/types/table.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../../src/types/table.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAIlE,eAAO,MAAM,WAAW;;;;;;;;;;yBAcD,CAAC;;;mBAAmF,CAAC;gBAAmC,CAAC;;;;;;;;;;;;iBAAglF,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;EARr2G,CAAC;;;;;;;;;yBAQoB,CAAC;;;mBAAmF,CAAC;gBAAmC,CAAC;;;;;;;;;;;;iBAAglF,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;;;;;;;;;;;;yBAAh1G,CAAC;;;mBAAmF,CAAC;gBAAmC,CAAC;;;;;;;;;;;;iBAAglF,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;AAJv2G,qBAAa,SAAU,SAAQ,cAGT;CAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":"AAIA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/index.ts"],"names":[],"mappings":"AAIA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export declare const tableButtons: {
|
|
2
|
+
readonly referencedCell: {
|
|
3
|
+
readonly attr: string;
|
|
4
|
+
readonly icon: string;
|
|
5
|
+
readonly render: ({ targetId, schemaId }: {
|
|
6
|
+
targetId: string;
|
|
7
|
+
schemaId: string;
|
|
8
|
+
}) => string;
|
|
9
|
+
};
|
|
2
10
|
readonly columnSettings: {
|
|
3
11
|
readonly attr: string;
|
|
4
12
|
readonly icon: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-buttons.d.ts","sourceRoot":"","sources":["../../../../src/util/table-buttons.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"table-buttons.d.ts","sourceRoot":"","sources":["../../../../src/util/table-buttons.ts"],"names":[],"mappings":"AAwCA,eAAO,MAAM,YAAY;;;;kDAIY;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE;;;;;uCAUjD;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE;;;;;wCAMlB;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE;;;;;yCAMpB;YAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;SAAE;;CAGvC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-table",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-staging.0905f03",
|
|
4
4
|
"description": "A table component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -53,25 +53,26 @@
|
|
|
53
53
|
"@tanstack/react-virtual": "^3.9.0",
|
|
54
54
|
"date-fns": "^3.3.1",
|
|
55
55
|
"lodash.orderby": "^4.6.0",
|
|
56
|
-
"@dxos/debug": "0.7.
|
|
57
|
-
"@dxos/context": "0.7.
|
|
58
|
-
"@dxos/echo-schema": "0.7.
|
|
59
|
-
"@dxos/invariant": "0.7.
|
|
60
|
-
"@dxos/
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/plugin-space": "0.7.
|
|
66
|
-
"@dxos/react-ui-attention": "0.7.
|
|
67
|
-
"@dxos/react-
|
|
68
|
-
"@dxos/react-ui-grid": "0.7.
|
|
69
|
-
"@dxos/react-ui-
|
|
70
|
-
"@dxos/react-ui-
|
|
71
|
-
"@dxos/react-ui-
|
|
72
|
-
"@dxos/react-ui-syntax-highlighter": "0.7.
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/
|
|
56
|
+
"@dxos/debug": "0.7.3-staging.0905f03",
|
|
57
|
+
"@dxos/context": "0.7.3-staging.0905f03",
|
|
58
|
+
"@dxos/echo-schema": "0.7.3-staging.0905f03",
|
|
59
|
+
"@dxos/invariant": "0.7.3-staging.0905f03",
|
|
60
|
+
"@dxos/live-object": "0.7.3-staging.0905f03",
|
|
61
|
+
"@dxos/keys": "0.7.3-staging.0905f03",
|
|
62
|
+
"@dxos/lit-grid": "0.7.3-staging.0905f03",
|
|
63
|
+
"@dxos/log": "0.7.3-staging.0905f03",
|
|
64
|
+
"@dxos/plugin-search": "0.7.3-staging.0905f03",
|
|
65
|
+
"@dxos/plugin-space": "0.7.3-staging.0905f03",
|
|
66
|
+
"@dxos/react-ui-attention": "0.7.3-staging.0905f03",
|
|
67
|
+
"@dxos/react-client": "0.7.3-staging.0905f03",
|
|
68
|
+
"@dxos/react-ui-grid": "0.7.3-staging.0905f03",
|
|
69
|
+
"@dxos/react-ui-form": "0.7.3-staging.0905f03",
|
|
70
|
+
"@dxos/react-ui-searchlist": "0.7.3-staging.0905f03",
|
|
71
|
+
"@dxos/react-ui-stack": "0.7.3-staging.0905f03",
|
|
72
|
+
"@dxos/react-ui-syntax-highlighter": "0.7.3-staging.0905f03",
|
|
73
|
+
"@dxos/react-ui-types": "0.7.3-staging.0905f03",
|
|
74
|
+
"@dxos/util": "0.7.3-staging.0905f03",
|
|
75
|
+
"@dxos/schema": "0.7.3-staging.0905f03"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
77
78
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -82,19 +83,19 @@
|
|
|
82
83
|
"react": "~18.2.0",
|
|
83
84
|
"react-dom": "~18.2.0",
|
|
84
85
|
"vite": "5.4.7",
|
|
85
|
-
"@dxos/echo-signals": "0.7.
|
|
86
|
-
"@dxos/
|
|
87
|
-
"@dxos/
|
|
88
|
-
"@dxos/react-ui-theme": "0.7.
|
|
89
|
-
"@dxos/
|
|
90
|
-
"@dxos/
|
|
86
|
+
"@dxos/echo-signals": "0.7.3-staging.0905f03",
|
|
87
|
+
"@dxos/react-ui": "0.7.3-staging.0905f03",
|
|
88
|
+
"@dxos/random": "0.7.3-staging.0905f03",
|
|
89
|
+
"@dxos/react-ui-theme": "0.7.3-staging.0905f03",
|
|
90
|
+
"@dxos/test-utils": "0.7.3-staging.0905f03",
|
|
91
|
+
"@dxos/storybook-utils": "0.7.3-staging.0905f03"
|
|
91
92
|
},
|
|
92
93
|
"peerDependencies": {
|
|
93
94
|
"@phosphor-icons/react": "^2.1.5",
|
|
94
95
|
"react": "~18.2.0",
|
|
95
96
|
"react-dom": "~18.2.0",
|
|
96
|
-
"@dxos/react-ui": "0.7.
|
|
97
|
-
"@dxos/react-ui
|
|
97
|
+
"@dxos/react-ui-theme": "0.7.3-staging.0905f03",
|
|
98
|
+
"@dxos/react-ui": "0.7.3-staging.0905f03"
|
|
98
99
|
},
|
|
99
100
|
"publishConfig": {
|
|
100
101
|
"access": "public"
|
|
@@ -8,8 +8,8 @@ import { Plugs, PlugsConnected } from '@phosphor-icons/react';
|
|
|
8
8
|
import { type StoryObj } from '@storybook/react';
|
|
9
9
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
|
-
import { create } from '@dxos/echo-schema';
|
|
12
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
|
+
import { create } from '@dxos/live-object';
|
|
13
13
|
import { log } from '@dxos/log';
|
|
14
14
|
import { faker } from '@dxos/random';
|
|
15
15
|
import { Button } from '@dxos/react-ui';
|
|
@@ -14,7 +14,6 @@ type ColumnActionsMenuProps = { model?: TableModel };
|
|
|
14
14
|
export const ColumnActionsMenu = ({ model }: ColumnActionsMenuProps) => {
|
|
15
15
|
const { t } = useTranslation(translationKey);
|
|
16
16
|
const state = model?.modalController.state.value;
|
|
17
|
-
|
|
18
17
|
if (!model || state?.type !== 'column') {
|
|
19
18
|
return null;
|
|
20
19
|
}
|
|
@@ -11,9 +11,9 @@ import { type FieldType } from '@dxos/schema';
|
|
|
11
11
|
|
|
12
12
|
import { type TableModel } from '../../model';
|
|
13
13
|
|
|
14
|
-
type ColumnSettingsProps = { model?: TableModel };
|
|
14
|
+
type ColumnSettingsProps = { model?: TableModel; onNewColumn: () => void };
|
|
15
15
|
|
|
16
|
-
export const ColumnSettings = ({ model }: ColumnSettingsProps) => {
|
|
16
|
+
export const ColumnSettings = ({ model, onNewColumn }: ColumnSettingsProps) => {
|
|
17
17
|
const [newField, setNewField] = useState<FieldType>();
|
|
18
18
|
const state = model?.modalController.state.value;
|
|
19
19
|
|
|
@@ -22,6 +22,9 @@ export const ColumnSettings = ({ model }: ColumnSettingsProps) => {
|
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
if (state?.type === 'columnSettings' && state.mode.type === 'create' && model?.projection) {
|
|
24
24
|
setNewField(model.projection.createFieldProjection());
|
|
25
|
+
requestAnimationFrame(() => {
|
|
26
|
+
onNewColumn();
|
|
27
|
+
});
|
|
25
28
|
} else {
|
|
26
29
|
setNewField(undefined);
|
|
27
30
|
}
|
|
@@ -39,7 +42,7 @@ export const ColumnSettings = ({ model }: ColumnSettingsProps) => {
|
|
|
39
42
|
|
|
40
43
|
const field = existingField ?? newField;
|
|
41
44
|
|
|
42
|
-
const
|
|
45
|
+
const handleSave = useCallback(() => {
|
|
43
46
|
model?.modalController.close();
|
|
44
47
|
}, [model?.modalController]);
|
|
45
48
|
|
|
@@ -64,7 +67,7 @@ export const ColumnSettings = ({ model }: ColumnSettingsProps) => {
|
|
|
64
67
|
projection={model.projection}
|
|
65
68
|
field={field}
|
|
66
69
|
registry={space?.db.schemaRegistry}
|
|
67
|
-
|
|
70
|
+
onSave={handleSave}
|
|
68
71
|
onCancel={handleCancel}
|
|
69
72
|
/>
|
|
70
73
|
</DropdownMenu.Viewport>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback, useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { S } from '@dxos/echo-schema';
|
|
8
|
+
import { create, getSpace } from '@dxos/react-client/echo';
|
|
9
|
+
import { Popover } from '@dxos/react-ui';
|
|
10
|
+
import { Form } from '@dxos/react-ui-form';
|
|
11
|
+
import { type GridScopedProps, useGridContext } from '@dxos/react-ui-grid';
|
|
12
|
+
|
|
13
|
+
import { type TableModel } from '../../model';
|
|
14
|
+
|
|
15
|
+
export type CreateRefPanelProps = { model?: TableModel };
|
|
16
|
+
|
|
17
|
+
// TODO(burdon): Factor out Space dependency (to plugin?)
|
|
18
|
+
export const CreateRefPanel = ({ model, __gridScope }: GridScopedProps<CreateRefPanelProps>) => {
|
|
19
|
+
const { id: gridId } = useGridContext('TableCellEditor', __gridScope);
|
|
20
|
+
const space = getSpace(model?.table);
|
|
21
|
+
const state = model?.modalController.state.value;
|
|
22
|
+
const schema = useMemo<S.Schema<any> | undefined>(() => {
|
|
23
|
+
if (!space || state?.type !== 'createRefPanel') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// TODO(burdon): Factor out.
|
|
28
|
+
const schema: S.Schema<any> | undefined = space.db.schemaRegistry.getSchema(state.typename)?.schema;
|
|
29
|
+
if (schema) {
|
|
30
|
+
const omit = S.omit<any, any, ['id']>('id');
|
|
31
|
+
return omit(schema);
|
|
32
|
+
}
|
|
33
|
+
}, [space, state]);
|
|
34
|
+
|
|
35
|
+
const handleSave = useCallback(
|
|
36
|
+
(values: any) => {
|
|
37
|
+
if (!model || !space || state?.type !== 'createRefPanel') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const schema: S.Schema<any> | undefined = space.db.schemaRegistry.getSchema(state.typename)?.schema;
|
|
42
|
+
if (schema) {
|
|
43
|
+
const obj = space.db.add(create(schema, values));
|
|
44
|
+
state.onCreate?.(obj);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
void model.modalController.close();
|
|
48
|
+
},
|
|
49
|
+
[model?.modalController, space, state],
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const handleCancel = useCallback(() => {
|
|
53
|
+
if (model) {
|
|
54
|
+
model.modalController.close();
|
|
55
|
+
}
|
|
56
|
+
}, [model?.modalController]);
|
|
57
|
+
|
|
58
|
+
if (!model?.table?.view || !model.projection) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<Popover.Root
|
|
64
|
+
modal={false}
|
|
65
|
+
open={state?.type === 'createRefPanel' && !!schema}
|
|
66
|
+
onOpenChange={(nextOpen) => {
|
|
67
|
+
if (model && !nextOpen) {
|
|
68
|
+
return model.modalController.close();
|
|
69
|
+
}
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<Popover.VirtualTrigger virtualRef={model.modalController.trigger} />
|
|
73
|
+
<Popover.Portal>
|
|
74
|
+
<Popover.Content classNames='md:is-64' data-grid={gridId}>
|
|
75
|
+
{state?.type === 'createRefPanel' && schema && (
|
|
76
|
+
<Form schema={schema} values={state.initialValues ?? {}} onSave={handleSave} onCancel={handleCancel} />
|
|
77
|
+
)}
|
|
78
|
+
<Popover.Arrow />
|
|
79
|
+
</Popover.Content>
|
|
80
|
+
</Popover.Portal>
|
|
81
|
+
</Popover.Root>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { getSpace, type Space } from '@dxos/react-client/echo';
|
|
8
|
+
import { Popover } from '@dxos/react-ui';
|
|
9
|
+
import { Form } from '@dxos/react-ui-form';
|
|
10
|
+
|
|
11
|
+
import { type TableModel } from '../../model';
|
|
12
|
+
|
|
13
|
+
type RefPanelProps = { model?: TableModel };
|
|
14
|
+
|
|
15
|
+
const getRefTargetObj = (space?: Space, id?: string) => {
|
|
16
|
+
if (space && id) {
|
|
17
|
+
return space?.db.getObjectById(id);
|
|
18
|
+
} else {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const RefPanel = ({ model }: RefPanelProps) => {
|
|
24
|
+
const state = model?.modalController.state.value;
|
|
25
|
+
const space = getSpace(model?.table);
|
|
26
|
+
const targetObj = getRefTargetObj(space, state?.type === 'refPanel' ? state.targetId : undefined);
|
|
27
|
+
const schema = space && state?.type === 'refPanel' ? space.db.schemaRegistry.getSchema(state.typename) : undefined;
|
|
28
|
+
|
|
29
|
+
if (!model?.table?.view || !model.projection) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Popover.Root
|
|
35
|
+
modal={false}
|
|
36
|
+
open={state?.type === 'refPanel' && !!targetObj && !!schema}
|
|
37
|
+
onOpenChange={(nextOpen) => {
|
|
38
|
+
if (model && !nextOpen) {
|
|
39
|
+
return model.modalController.close();
|
|
40
|
+
}
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<Popover.VirtualTrigger virtualRef={model.modalController.trigger} />
|
|
44
|
+
<Popover.Portal>
|
|
45
|
+
<Popover.Content classNames='md:is-64'>
|
|
46
|
+
{targetObj && schema && <Form readonly values={targetObj} schema={schema} />}
|
|
47
|
+
<Popover.Arrow />
|
|
48
|
+
</Popover.Content>
|
|
49
|
+
</Popover.Portal>
|
|
50
|
+
</Popover.Root>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -13,9 +13,8 @@ type RowActionsMenuProps = { model: TableModel };
|
|
|
13
13
|
|
|
14
14
|
export const RowActionsMenu = ({ model }: RowActionsMenuProps) => {
|
|
15
15
|
const { t } = useTranslation(translationKey);
|
|
16
|
-
const state = model.modalController.state.value;
|
|
17
16
|
const hasSelection = model.selection.hasSelection.value;
|
|
18
|
-
|
|
17
|
+
const state = model.modalController.state.value;
|
|
19
18
|
if (state?.type !== 'row') {
|
|
20
19
|
return null;
|
|
21
20
|
}
|
|
@@ -54,7 +54,7 @@ const DefaultStory = () => {
|
|
|
54
54
|
}
|
|
55
55
|
}, [schema, table?.view]);
|
|
56
56
|
|
|
57
|
-
const objects = useQuery(space, schema ? Filter.schema(schema) : ()
|
|
57
|
+
const objects = useQuery(space, schema ? Filter.schema(schema) : Filter.nothing());
|
|
58
58
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
59
59
|
|
|
60
60
|
const handleInsertRow = useCallback(() => {
|
|
@@ -14,17 +14,20 @@ import React, {
|
|
|
14
14
|
import { getValue } from '@dxos/echo-schema';
|
|
15
15
|
import { invariant } from '@dxos/invariant';
|
|
16
16
|
import { Filter, getSpace, fullyQualifiedId } from '@dxos/react-client/echo';
|
|
17
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
17
18
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
18
|
-
import { type DxGridElement, Grid, type GridContentProps, closestCell } from '@dxos/react-ui-grid';
|
|
19
|
+
import { type DxGridElement, Grid, type GridContentProps, closestCell, type DxGridPosition } from '@dxos/react-ui-grid';
|
|
19
20
|
import { mx } from '@dxos/react-ui-theme';
|
|
20
21
|
import { isNotFalsy } from '@dxos/util';
|
|
21
22
|
|
|
22
23
|
import { ColumnActionsMenu } from './ColumnActionsMenu';
|
|
23
24
|
import { ColumnSettings } from './ColumnSettings';
|
|
25
|
+
import { CreateRefPanel } from './CreateRefPanel';
|
|
26
|
+
import { RefPanel } from './RefPanel';
|
|
24
27
|
import { RowActionsMenu } from './RowActionsMenu';
|
|
25
28
|
import { type TableModel } from '../../model';
|
|
26
|
-
import {
|
|
27
|
-
import { TableCellEditor, type TableCellEditorProps } from '../TableCellEditor';
|
|
29
|
+
import { translationKey } from '../../translations';
|
|
30
|
+
import { createOption, TableCellEditor, type TableCellEditorProps } from '../TableCellEditor';
|
|
28
31
|
|
|
29
32
|
// NOTE(Zan): These fragments add border to inline-end and block-end of the grid using pseudo-elements.
|
|
30
33
|
// These are offset by 1px to avoid double borders in planks.
|
|
@@ -62,7 +65,7 @@ const TableRoot = ({ children, role }: TableRootProps) => {
|
|
|
62
65
|
//
|
|
63
66
|
|
|
64
67
|
export type TableController = {
|
|
65
|
-
update?: (cell?:
|
|
68
|
+
update?: (cell?: DxGridPosition) => void;
|
|
66
69
|
};
|
|
67
70
|
|
|
68
71
|
export type TableMainProps = {
|
|
@@ -72,8 +75,8 @@ export type TableMainProps = {
|
|
|
72
75
|
|
|
73
76
|
const TableMain = forwardRef<TableController, TableMainProps>(({ model, ignoreAttention }, forwardedRef) => {
|
|
74
77
|
const [dxGrid, setDxGrid] = useState<DxGridElement | null>(null);
|
|
75
|
-
|
|
76
78
|
const { hasAttention } = useAttention(model?.table ? fullyQualifiedId(model.table) : 'table');
|
|
79
|
+
const { t } = useTranslation(translationKey);
|
|
77
80
|
|
|
78
81
|
/**
|
|
79
82
|
* Provides an external controller that can be called to repaint the table.
|
|
@@ -99,18 +102,29 @@ const TableMain = forwardRef<TableController, TableMainProps>(({ model, ignoreAt
|
|
|
99
102
|
[model, dxGrid],
|
|
100
103
|
);
|
|
101
104
|
|
|
102
|
-
const handleFocus
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
const handleFocus = useCallback<NonNullable<TableCellEditorProps['onFocus']>>(
|
|
106
|
+
(increment, delta) => {
|
|
107
|
+
if (dxGrid) {
|
|
108
|
+
dxGrid.refocus(increment, delta);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
[dxGrid],
|
|
112
|
+
);
|
|
105
113
|
|
|
106
114
|
const handleEnter = useCallback<NonNullable<TableCellEditorProps['onEnter']>>(
|
|
107
115
|
(cell) => {
|
|
108
116
|
// TODO(burdon): Insert row only if bottom row isn't completely blank already.
|
|
109
117
|
if (model && cell.row === model.getRowCount() - 1) {
|
|
110
118
|
model.insertRow(cell.row);
|
|
119
|
+
if (dxGrid) {
|
|
120
|
+
requestAnimationFrame(() => {
|
|
121
|
+
dxGrid?.scrollToRow(cell.row + 1);
|
|
122
|
+
dxGrid?.refocus('row', 1);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
111
125
|
}
|
|
112
126
|
},
|
|
113
|
-
[model],
|
|
127
|
+
[model, dxGrid],
|
|
114
128
|
);
|
|
115
129
|
|
|
116
130
|
const handleKeyDown = useCallback<NonNullable<GridContentProps['onKeyDown']>>(
|
|
@@ -150,17 +164,24 @@ const TableMain = forwardRef<TableController, TableMainProps>(({ model, ignoreAt
|
|
|
150
164
|
[hasAttention, ignoreAttention],
|
|
151
165
|
);
|
|
152
166
|
|
|
167
|
+
const handleNewColumn = useCallback(() => {
|
|
168
|
+
const columns = model?.getColumnCount();
|
|
169
|
+
if (dxGrid && columns) {
|
|
170
|
+
dxGrid.scrollToColumn(columns - 1);
|
|
171
|
+
}
|
|
172
|
+
}, [model, dxGrid]);
|
|
173
|
+
|
|
153
174
|
// TODO(burdon): Factor out?
|
|
175
|
+
// TODO(burdon): Generalize to handle other value types (e.g., enums).
|
|
154
176
|
const handleQuery = useCallback<NonNullable<TableCellEditorProps['onQuery']>>(
|
|
155
|
-
async ({ field, props },
|
|
177
|
+
async ({ field, props }, text) => {
|
|
156
178
|
if (model && props.referenceSchema && field.referencePath) {
|
|
157
179
|
const space = getSpace(model.table);
|
|
158
180
|
invariant(space);
|
|
159
181
|
const schema = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
160
182
|
if (schema) {
|
|
161
|
-
// TODO(burdon): Cache/filter.
|
|
162
183
|
const { objects } = await space.db.query(Filter.schema(schema)).run();
|
|
163
|
-
|
|
184
|
+
const options = objects
|
|
164
185
|
.map((obj) => {
|
|
165
186
|
const value = getValue(obj, field.referencePath!);
|
|
166
187
|
if (!value || typeof value !== 'string') {
|
|
@@ -173,6 +194,14 @@ const TableMain = forwardRef<TableController, TableMainProps>(({ model, ignoreAt
|
|
|
173
194
|
};
|
|
174
195
|
})
|
|
175
196
|
.filter(isNotFalsy);
|
|
197
|
+
|
|
198
|
+
return [
|
|
199
|
+
...options,
|
|
200
|
+
{
|
|
201
|
+
label: t('create new object label', { text }),
|
|
202
|
+
data: createOption(text),
|
|
203
|
+
},
|
|
204
|
+
];
|
|
176
205
|
}
|
|
177
206
|
}
|
|
178
207
|
|
|
@@ -186,29 +215,27 @@ const TableMain = forwardRef<TableController, TableMainProps>(({ model, ignoreAt
|
|
|
186
215
|
}
|
|
187
216
|
|
|
188
217
|
return (
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
ref={setDxGrid}
|
|
205
|
-
/>
|
|
206
|
-
</Grid.Root>
|
|
207
|
-
|
|
218
|
+
<Grid.Root id={model.table.id ?? 'table-grid'}>
|
|
219
|
+
<TableCellEditor model={model} onEnter={handleEnter} onFocus={handleFocus} onQuery={handleQuery} />
|
|
220
|
+
<Grid.Content
|
|
221
|
+
onWheelCapture={handleWheel}
|
|
222
|
+
className={mx('[--dx-grid-base:var(--surface-bg)]', inlineEndLine, blockEndLine)}
|
|
223
|
+
frozen={frozen}
|
|
224
|
+
columns={model.columnMeta.value}
|
|
225
|
+
limitRows={model.getRowCount() ?? 0}
|
|
226
|
+
limitColumns={model.table.view?.fields?.length ?? 0}
|
|
227
|
+
onAxisResize={handleAxisResize}
|
|
228
|
+
onClick={model?.handleGridClick}
|
|
229
|
+
onKeyDown={handleKeyDown}
|
|
230
|
+
overscroll='trap'
|
|
231
|
+
ref={setDxGrid}
|
|
232
|
+
/>
|
|
208
233
|
<RowActionsMenu model={model} />
|
|
209
234
|
<ColumnActionsMenu model={model} />
|
|
210
|
-
<ColumnSettings model={model} />
|
|
211
|
-
|
|
235
|
+
<ColumnSettings model={model} onNewColumn={handleNewColumn} />
|
|
236
|
+
<RefPanel model={model} />
|
|
237
|
+
<CreateRefPanel model={model} />
|
|
238
|
+
</Grid.Root>
|
|
212
239
|
);
|
|
213
240
|
});
|
|
214
241
|
|