@dxos/plugin-explorer 0.8.4-main.5ad4a44 → 0.8.4-main.66e292d
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/{ExplorerContainer-S66JDOAF.mjs → ExplorerContainer-NOLLVUTE.mjs} +8 -7
- package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NXGP6NTP.mjs → chunk-6BVXZQPP.mjs} +10 -25
- package/dist/lib/browser/{chunk-NXGP6NTP.mjs.map → chunk-6BVXZQPP.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-UCDNCIRV.mjs → chunk-ARBGXQFH.mjs} +4 -256
- package/dist/lib/browser/{chunk-UCDNCIRV.mjs.map → chunk-ARBGXQFH.mjs.map} +3 -3
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/chunk-P6FFFVPM.mjs +100 -0
- package/dist/lib/browser/chunk-P6FFFVPM.mjs.map +7 -0
- package/dist/lib/browser/{chunk-2DGFNLRO.mjs → chunk-UBHZGWZQ.mjs} +7 -2
- package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +23 -23
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-EWB3H5KH.mjs +35 -0
- package/dist/lib/browser/intent-resolver-EWB3H5KH.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +2 -1
- package/dist/lib/browser/{react-surface-C4EC6ZDZ.mjs → react-surface-BY2DYCTH.mjs} +14 -11
- package/dist/lib/browser/react-surface-BY2DYCTH.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +7 -6
- package/dist/lib/node-esm/{ExplorerContainer-GIJN67DO.mjs → ExplorerContainer-N3S5KSUX.mjs} +8 -7
- package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-4BY2XZET.mjs +101 -0
- package/dist/lib/node-esm/chunk-4BY2XZET.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-6JACZE7E.mjs → chunk-CRSVAZNA.mjs} +10 -25
- package/dist/lib/node-esm/{chunk-6JACZE7E.mjs.map → chunk-CRSVAZNA.mjs.map} +2 -2
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WHKUQG5M.mjs → chunk-NPIP4VEH.mjs} +4 -256
- package/dist/lib/node-esm/{chunk-WHKUQG5M.mjs.map → chunk-NPIP4VEH.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-PX6LHR2N.mjs → chunk-UXZM5VJB.mjs} +7 -2
- package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +23 -23
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-SH6PW7VF.mjs +36 -0
- package/dist/lib/node-esm/intent-resolver-SH6PW7VF.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/meta.mjs +2 -1
- package/dist/lib/node-esm/{react-surface-YGGLTBF3.mjs → react-surface-7AAV7GBG.mjs} +14 -11
- package/dist/lib/node-esm/react-surface-7AAV7GBG.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +7 -6
- package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/ExplorerContainer.d.ts +2 -2
- package/dist/types/src/components/ExplorerContainer.d.ts.map +1 -1
- package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
- package/dist/types/src/components/Tree/types/tree.d.ts +6 -6
- package/dist/types/src/components/index.d.ts +2 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +14 -6
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/ExplorerAction.d.ts +23 -0
- package/dist/types/src/types/ExplorerAction.d.ts.map +1 -0
- package/dist/types/src/types/Graph.d.ts +32 -0
- package/dist/types/src/types/Graph.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -2
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -29
- package/src/ExplorerPlugin.tsx +9 -17
- package/src/capabilities/intent-resolver.ts +12 -8
- package/src/capabilities/react-surface.tsx +6 -3
- package/src/components/ExplorerContainer.tsx +11 -7
- package/src/components/Graph/D3ForceGraph.stories.tsx +22 -10
- package/src/components/Graph/ForceGraph.stories.tsx +22 -10
- package/src/components/Graph/testing.ts +6 -6
- package/src/components/Tree/types/tree.test.ts +2 -2
- package/src/components/index.ts +3 -3
- package/src/meta.ts +6 -1
- package/src/translations.ts +4 -2
- package/src/types/ExplorerAction.ts +37 -0
- package/src/types/Graph.ts +63 -0
- package/src/types/index.ts +2 -2
- package/dist/lib/browser/ExplorerContainer-S66JDOAF.mjs.map +0 -7
- package/dist/lib/browser/chunk-2DGFNLRO.mjs.map +0 -7
- package/dist/lib/browser/chunk-4ETQJYX4.mjs +0 -38
- package/dist/lib/browser/chunk-4ETQJYX4.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs +0 -24
- package/dist/lib/browser/intent-resolver-OXJJ3PII.mjs.map +0 -7
- package/dist/lib/browser/react-surface-C4EC6ZDZ.mjs.map +0 -7
- package/dist/lib/node-esm/ExplorerContainer-GIJN67DO.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-AGHU3KVI.mjs +0 -39
- package/dist/lib/node-esm/chunk-AGHU3KVI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PX6LHR2N.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs +0 -25
- package/dist/lib/node-esm/intent-resolver-GVM36TJX.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-YGGLTBF3.mjs.map +0 -7
- package/dist/types/src/types/schema.d.ts +0 -12
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/types/types.d.ts +0 -18
- package/dist/types/src/types/types.d.ts.map +0 -1
- package/src/types/schema.ts +0 -16
- package/src/types/types.ts +0 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-explorer",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.66e292d",
|
|
4
4
|
"description": "Braneframe data visualization plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -55,50 +55,51 @@
|
|
|
55
55
|
"react-resize-detector": "^11.0.1",
|
|
56
56
|
"three": "^0.178.0",
|
|
57
57
|
"topojson-client": "^3.1.0",
|
|
58
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
59
|
-
"@dxos/async": "0.8.4-main.
|
|
60
|
-
"@dxos/
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/plugin-client": "0.8.4-main.
|
|
68
|
-
"@dxos/plugin-search": "0.8.4-main.
|
|
69
|
-
"@dxos/plugin-graph": "0.8.4-main.
|
|
70
|
-
"@dxos/plugin-space": "0.8.4-main.
|
|
71
|
-
"@dxos/react-client": "0.8.4-main.
|
|
72
|
-
"@dxos/react-ui-attention": "0.8.4-main.
|
|
73
|
-
"@dxos/react-ui-graph": "0.8.4-main.
|
|
74
|
-
"@dxos/react-ui-
|
|
75
|
-
"@dxos/react-ui-
|
|
76
|
-
"@dxos/schema": "0.8.4-main.
|
|
77
|
-
"@dxos/util": "0.8.4-main.
|
|
58
|
+
"@dxos/app-framework": "0.8.4-main.66e292d",
|
|
59
|
+
"@dxos/async": "0.8.4-main.66e292d",
|
|
60
|
+
"@dxos/client": "0.8.4-main.66e292d",
|
|
61
|
+
"@dxos/invariant": "0.8.4-main.66e292d",
|
|
62
|
+
"@dxos/graph": "0.8.4-main.66e292d",
|
|
63
|
+
"@dxos/echo-query": "0.8.4-main.66e292d",
|
|
64
|
+
"@dxos/echo": "0.8.4-main.66e292d",
|
|
65
|
+
"@dxos/live-object": "0.8.4-main.66e292d",
|
|
66
|
+
"@dxos/log": "0.8.4-main.66e292d",
|
|
67
|
+
"@dxos/plugin-client": "0.8.4-main.66e292d",
|
|
68
|
+
"@dxos/plugin-search": "0.8.4-main.66e292d",
|
|
69
|
+
"@dxos/plugin-graph": "0.8.4-main.66e292d",
|
|
70
|
+
"@dxos/plugin-space": "0.8.4-main.66e292d",
|
|
71
|
+
"@dxos/react-client": "0.8.4-main.66e292d",
|
|
72
|
+
"@dxos/react-ui-attention": "0.8.4-main.66e292d",
|
|
73
|
+
"@dxos/react-ui-graph": "0.8.4-main.66e292d",
|
|
74
|
+
"@dxos/react-ui-components": "0.8.4-main.66e292d",
|
|
75
|
+
"@dxos/react-ui-stack": "0.8.4-main.66e292d",
|
|
76
|
+
"@dxos/schema": "0.8.4-main.66e292d",
|
|
77
|
+
"@dxos/util": "0.8.4-main.66e292d",
|
|
78
|
+
"@dxos/types": "0.8.4-main.66e292d"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@types/d3": "^7.4.3",
|
|
81
82
|
"@types/d3-hierarchy": "^3.1.6",
|
|
82
83
|
"@types/lodash.defaultsdeep": "^4.6.6",
|
|
83
84
|
"@types/react": "~19.2.2",
|
|
84
|
-
"@types/react-dom": "~19.2.
|
|
85
|
+
"@types/react-dom": "~19.2.2",
|
|
85
86
|
"@types/topojson-client": "^3.1.4",
|
|
86
87
|
"@types/topojson-specification": "^1.0.5",
|
|
87
88
|
"react": "~19.2.0",
|
|
88
89
|
"react-dom": "~19.2.0",
|
|
89
90
|
"vite": "7.1.9",
|
|
90
|
-
"@dxos/echo-generator": "0.8.4-main.
|
|
91
|
-
"@dxos/random": "0.8.4-main.
|
|
92
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
93
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
94
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
91
|
+
"@dxos/echo-generator": "0.8.4-main.66e292d",
|
|
92
|
+
"@dxos/random": "0.8.4-main.66e292d",
|
|
93
|
+
"@dxos/react-ui": "0.8.4-main.66e292d",
|
|
94
|
+
"@dxos/react-ui-theme": "0.8.4-main.66e292d",
|
|
95
|
+
"@dxos/storybook-utils": "0.8.4-main.66e292d"
|
|
95
96
|
},
|
|
96
97
|
"peerDependencies": {
|
|
97
98
|
"effect": "^3.13.3",
|
|
98
99
|
"react": "^19.0.0",
|
|
99
100
|
"react-dom": "^19.0.0",
|
|
100
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
101
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
101
|
+
"@dxos/react-ui": "0.8.4-main.66e292d",
|
|
102
|
+
"@dxos/react-ui-theme": "0.8.4-main.66e292d"
|
|
102
103
|
},
|
|
103
104
|
"publishConfig": {
|
|
104
105
|
"access": "public"
|
package/src/ExplorerPlugin.tsx
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
|
|
6
|
+
import { Type } from '@dxos/echo';
|
|
6
7
|
import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
|
|
7
|
-
import {
|
|
8
|
-
import { defineObjectForm } from '@dxos/plugin-space/types';
|
|
8
|
+
import { type CreateObjectIntent } from '@dxos/plugin-space/types';
|
|
9
9
|
|
|
10
10
|
import { IntentResolver, ReactSurface } from './capabilities';
|
|
11
11
|
import { meta } from './meta';
|
|
12
12
|
import { translations } from './translations';
|
|
13
|
-
import { ExplorerAction,
|
|
13
|
+
import { ExplorerAction, Graph } from './types';
|
|
14
14
|
|
|
15
15
|
export const ExplorerPlugin = definePlugin(meta, () => [
|
|
16
16
|
defineModule({
|
|
@@ -23,28 +23,20 @@ export const ExplorerPlugin = definePlugin(meta, () => [
|
|
|
23
23
|
activatesOn: Events.SetupMetadata,
|
|
24
24
|
activate: () =>
|
|
25
25
|
contributes(Capabilities.Metadata, {
|
|
26
|
-
id:
|
|
26
|
+
id: Type.getTypename(Graph.Graph),
|
|
27
27
|
metadata: {
|
|
28
28
|
icon: 'ph--graph--regular',
|
|
29
|
+
iconHue: 'green',
|
|
30
|
+
inputSchema: ExplorerAction.GraphProps,
|
|
31
|
+
createObjectIntent: ((props, options) =>
|
|
32
|
+
createIntent(ExplorerAction.CreateGraph, { ...props, space: options.space })) satisfies CreateObjectIntent,
|
|
29
33
|
},
|
|
30
34
|
}),
|
|
31
35
|
}),
|
|
32
|
-
defineModule({
|
|
33
|
-
id: `${meta.id}/module/object-form`,
|
|
34
|
-
activatesOn: ClientEvents.SetupSchema,
|
|
35
|
-
activate: () =>
|
|
36
|
-
contributes(
|
|
37
|
-
SpaceCapabilities.ObjectForm,
|
|
38
|
-
defineObjectForm({
|
|
39
|
-
objectSchema: ViewType,
|
|
40
|
-
getIntent: () => createIntent(ExplorerAction.Create),
|
|
41
|
-
}),
|
|
42
|
-
),
|
|
43
|
-
}),
|
|
44
36
|
defineModule({
|
|
45
37
|
id: `${meta.id}/module/schema`,
|
|
46
38
|
activatesOn: ClientEvents.SetupSchema,
|
|
47
|
-
activate: () => contributes(ClientCapabilities.Schema, [
|
|
39
|
+
activate: () => contributes(ClientCapabilities.Schema, [Graph.Graph]),
|
|
48
40
|
}),
|
|
49
41
|
defineModule({
|
|
50
42
|
id: `${meta.id}/module/react-surface`,
|
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Capabilities, contributes, createResolver } from '@dxos/app-framework';
|
|
6
|
-
import {
|
|
5
|
+
import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
|
|
6
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
7
|
+
import { View } from '@dxos/schema';
|
|
7
8
|
|
|
8
|
-
import { ExplorerAction,
|
|
9
|
+
import { ExplorerAction, Graph } from '../types';
|
|
9
10
|
|
|
10
|
-
export default () =>
|
|
11
|
+
export default (context: PluginContext) =>
|
|
11
12
|
contributes(
|
|
12
13
|
Capabilities.IntentResolver,
|
|
13
14
|
createResolver({
|
|
14
|
-
intent: ExplorerAction.
|
|
15
|
-
resolve: ({ name }) =>
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
intent: ExplorerAction.CreateGraph,
|
|
16
|
+
resolve: async ({ space, name, typename }) => {
|
|
17
|
+
const client = context.getCapability(ClientCapabilities.Client);
|
|
18
|
+
const { view } = await View.makeFromSpace({ client, space, typename });
|
|
19
|
+
const graph = Graph.make({ name, view });
|
|
20
|
+
return { data: { object: graph } };
|
|
21
|
+
},
|
|
18
22
|
}),
|
|
19
23
|
);
|
|
@@ -6,10 +6,11 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
|
+
import { type View } from '@dxos/schema';
|
|
9
10
|
|
|
10
11
|
import { ExplorerContainer } from '../components';
|
|
11
12
|
import { meta } from '../meta';
|
|
12
|
-
import {
|
|
13
|
+
import { Graph } from '../types';
|
|
13
14
|
|
|
14
15
|
export default () =>
|
|
15
16
|
contributes(
|
|
@@ -17,7 +18,9 @@ export default () =>
|
|
|
17
18
|
createSurface({
|
|
18
19
|
id: `${meta.id}/article`,
|
|
19
20
|
role: ['article', 'section'],
|
|
20
|
-
filter: (data): data is { subject:
|
|
21
|
-
component: ({ data, role }) =>
|
|
21
|
+
filter: (data): data is { subject: View.View } => Obj.instanceOf(Graph.Graph, data.subject),
|
|
22
|
+
component: ({ data, role }) => {
|
|
23
|
+
return <ExplorerContainer view={data.subject} role={role} />;
|
|
24
|
+
},
|
|
22
25
|
}),
|
|
23
26
|
);
|
|
@@ -11,15 +11,15 @@ import { getSpace } from '@dxos/react-client/echo';
|
|
|
11
11
|
import { Toolbar } from '@dxos/react-ui';
|
|
12
12
|
import { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';
|
|
13
13
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
14
|
+
import { type View } from '@dxos/schema';
|
|
14
15
|
|
|
15
16
|
import { useGraphModel } from '../hooks';
|
|
16
|
-
import { type ViewType } from '../types';
|
|
17
17
|
|
|
18
18
|
import { D3ForceGraph } from './Graph';
|
|
19
19
|
|
|
20
20
|
type ExplorerContainerProps = {
|
|
21
21
|
role: string;
|
|
22
|
-
view:
|
|
22
|
+
view: View.View;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
|
|
@@ -30,18 +30,22 @@ const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
|
|
|
30
30
|
|
|
31
31
|
const builder = useMemo(() => new QueryBuilder(), []);
|
|
32
32
|
const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {
|
|
33
|
-
setFilter(builder.build(value));
|
|
33
|
+
setFilter(builder.build(value).filter);
|
|
34
34
|
}, []);
|
|
35
35
|
|
|
36
|
+
const showToolbar = role === 'article';
|
|
37
|
+
|
|
36
38
|
if (!space || !model) {
|
|
37
39
|
return null;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
return (
|
|
41
|
-
<StackItem.Content toolbar
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
43
|
+
<StackItem.Content toolbar={showToolbar}>
|
|
44
|
+
{showToolbar && (
|
|
45
|
+
<Toolbar.Root>
|
|
46
|
+
<QueryEditor db={space.db} onChange={handleChange} />
|
|
47
|
+
</Toolbar.Root>
|
|
48
|
+
)}
|
|
45
49
|
<D3ForceGraph model={model} match={match} />
|
|
46
50
|
</StackItem.Content>
|
|
47
51
|
);
|
|
@@ -3,20 +3,22 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
-
import React, {
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Type } from '@dxos/echo';
|
|
9
9
|
import { faker } from '@dxos/random';
|
|
10
10
|
import { useClient } from '@dxos/react-client';
|
|
11
11
|
import { type Space } from '@dxos/react-client/echo';
|
|
12
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
|
+
import { useAsyncEffect } from '@dxos/react-ui';
|
|
13
14
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
|
-
import {
|
|
15
|
+
import { View } from '@dxos/schema';
|
|
15
16
|
import { type ValueGenerator } from '@dxos/schema/testing';
|
|
16
17
|
import { render } from '@dxos/storybook-utils';
|
|
18
|
+
import { HasRelationship, Organization, Person, Project } from '@dxos/types';
|
|
17
19
|
|
|
18
20
|
import { useGraphModel } from '../../hooks';
|
|
19
|
-
import {
|
|
21
|
+
import { Graph } from '../../types';
|
|
20
22
|
|
|
21
23
|
import { D3ForceGraph } from './D3ForceGraph';
|
|
22
24
|
import { generate } from './testing';
|
|
@@ -28,17 +30,20 @@ faker.seed(1);
|
|
|
28
30
|
const DefaultStory = () => {
|
|
29
31
|
const client = useClient();
|
|
30
32
|
const [space, setSpace] = useState<Space>();
|
|
31
|
-
const [
|
|
32
|
-
|
|
33
|
+
const [graph, setGraph] = useState<Graph.Graph>();
|
|
34
|
+
|
|
35
|
+
useAsyncEffect(async () => {
|
|
33
36
|
const space = client.spaces.default;
|
|
34
37
|
void generate(space, generator);
|
|
35
|
-
const view =
|
|
38
|
+
const { view } = await View.makeFromSpace({ client, space, typename: Type.getTypename(Graph.Graph) });
|
|
39
|
+
const graph = Graph.make({ name: 'Test', view });
|
|
40
|
+
space.db.add(graph);
|
|
36
41
|
setSpace(space);
|
|
37
|
-
|
|
42
|
+
setGraph(graph);
|
|
38
43
|
}, []);
|
|
39
44
|
|
|
40
45
|
const model = useGraphModel(space);
|
|
41
|
-
if (!model || !space || !
|
|
46
|
+
if (!model || !space || !graph) {
|
|
42
47
|
return null;
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -53,7 +58,14 @@ const meta = {
|
|
|
53
58
|
withTheme,
|
|
54
59
|
withClientProvider({
|
|
55
60
|
createSpace: true,
|
|
56
|
-
types: [
|
|
61
|
+
types: [
|
|
62
|
+
Graph.Graph,
|
|
63
|
+
View.View,
|
|
64
|
+
Organization.Organization,
|
|
65
|
+
Project.Project,
|
|
66
|
+
Person.Person,
|
|
67
|
+
HasRelationship.HasRelationship,
|
|
68
|
+
],
|
|
57
69
|
}),
|
|
58
70
|
],
|
|
59
71
|
parameters: {
|
|
@@ -3,20 +3,22 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
-
import React, {
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Type } from '@dxos/echo';
|
|
9
9
|
import { faker } from '@dxos/random';
|
|
10
10
|
import { useClient } from '@dxos/react-client';
|
|
11
11
|
import { type Space } from '@dxos/react-client/echo';
|
|
12
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
|
+
import { useAsyncEffect } from '@dxos/react-ui';
|
|
13
14
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
|
-
import {
|
|
15
|
+
import { View } from '@dxos/schema';
|
|
15
16
|
import { type ValueGenerator } from '@dxos/schema/testing';
|
|
16
17
|
import { render } from '@dxos/storybook-utils';
|
|
18
|
+
import { HasRelationship, Organization, Person, Project } from '@dxos/types';
|
|
17
19
|
|
|
18
20
|
import { useGraphModel } from '../../hooks';
|
|
19
|
-
import {
|
|
21
|
+
import { Graph } from '../../types';
|
|
20
22
|
|
|
21
23
|
import { ForceGraph } from './ForceGraph';
|
|
22
24
|
import { generate } from './testing';
|
|
@@ -28,17 +30,20 @@ faker.seed(1);
|
|
|
28
30
|
const DefaultStory = () => {
|
|
29
31
|
const client = useClient();
|
|
30
32
|
const [space, setSpace] = useState<Space>();
|
|
31
|
-
const [
|
|
32
|
-
|
|
33
|
+
const [graph, setGraph] = useState<Graph.Graph>();
|
|
34
|
+
|
|
35
|
+
useAsyncEffect(async () => {
|
|
33
36
|
const space = client.spaces.default;
|
|
34
37
|
void generate(space, generator);
|
|
35
|
-
const view =
|
|
38
|
+
const { view } = await View.makeFromSpace({ client, space, typename: Type.getTypename(Graph.Graph) });
|
|
39
|
+
const graph = Graph.make({ name: 'Test', view });
|
|
40
|
+
space.db.add(graph);
|
|
36
41
|
setSpace(space);
|
|
37
|
-
|
|
42
|
+
setGraph(graph);
|
|
38
43
|
}, []);
|
|
39
44
|
|
|
40
45
|
const model = useGraphModel(space);
|
|
41
|
-
if (!model || !space || !
|
|
46
|
+
if (!model || !space || !graph) {
|
|
42
47
|
return null;
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -53,7 +58,14 @@ const meta = {
|
|
|
53
58
|
withTheme,
|
|
54
59
|
withClientProvider({
|
|
55
60
|
createSpace: true,
|
|
56
|
-
types: [
|
|
61
|
+
types: [
|
|
62
|
+
Graph.Graph,
|
|
63
|
+
View.View,
|
|
64
|
+
HasRelationship.HasRelationship,
|
|
65
|
+
Organization.Organization,
|
|
66
|
+
Project.Project,
|
|
67
|
+
Person.Person,
|
|
68
|
+
],
|
|
57
69
|
}),
|
|
58
70
|
],
|
|
59
71
|
parameters: {
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Space } from '@dxos/client/echo';
|
|
6
6
|
import { type Obj, Query, Relation } from '@dxos/echo';
|
|
7
|
-
import { DataType } from '@dxos/schema';
|
|
8
7
|
import { type TypeSpec, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
|
|
8
|
+
import { HasRelationship, Organization, Person, Project } from '@dxos/types';
|
|
9
9
|
import { range } from '@dxos/util';
|
|
10
10
|
|
|
11
11
|
const getObject = (objects: Obj.Any[]) => objects[Math.floor(Math.random() * objects.length)];
|
|
12
12
|
|
|
13
13
|
const defaultTypes: TypeSpec[] = [
|
|
14
|
-
{ type:
|
|
15
|
-
{ type:
|
|
16
|
-
{ type:
|
|
14
|
+
{ type: Organization.Organization, count: 5 },
|
|
15
|
+
{ type: Project.Project, count: 5 },
|
|
16
|
+
{ type: Person.Person, count: 10 },
|
|
17
17
|
];
|
|
18
18
|
|
|
19
19
|
export type GenerateOptions = {
|
|
@@ -38,13 +38,13 @@ export const generate = async (
|
|
|
38
38
|
await createObjects(spec);
|
|
39
39
|
|
|
40
40
|
// Add relations between objects.
|
|
41
|
-
const { objects: contacts } = await space.db.query(Query.type(
|
|
41
|
+
const { objects: contacts } = await space.db.query(Query.type(Person.Person)).run();
|
|
42
42
|
for (const _ of range(relations.count)) {
|
|
43
43
|
const source = getObject(contacts);
|
|
44
44
|
const target = getObject(contacts);
|
|
45
45
|
if (source.id !== target.id) {
|
|
46
46
|
space.db.add(
|
|
47
|
-
Relation.make(
|
|
47
|
+
Relation.make(HasRelationship.HasRelationship, {
|
|
48
48
|
[Relation.Source]: source,
|
|
49
49
|
[Relation.Target]: target,
|
|
50
50
|
kind: relations.kind,
|
|
@@ -6,7 +6,7 @@ import { describe, test } from 'vitest';
|
|
|
6
6
|
|
|
7
7
|
import { Obj, Ref } from '@dxos/echo';
|
|
8
8
|
import { faker } from '@dxos/random';
|
|
9
|
-
import {
|
|
9
|
+
import { Task } from '@dxos/types';
|
|
10
10
|
|
|
11
11
|
import { createTree } from '../testing';
|
|
12
12
|
|
|
@@ -124,7 +124,7 @@ describe('tree', () => {
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
test('task', ({ expect }) => {
|
|
127
|
-
const task = Obj.make(
|
|
127
|
+
const task = Obj.make(Task.Task, { title: 'Test task.' });
|
|
128
128
|
expect(task.title).to.eq('Test task.');
|
|
129
129
|
|
|
130
130
|
const tree = createTree();
|
package/src/components/index.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { lazy } from 'react';
|
|
6
|
-
|
|
7
|
-
export const ExplorerContainer = lazy(() => import('./ExplorerContainer'));
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
8
6
|
|
|
9
7
|
export * from './Chart';
|
|
10
8
|
export * from './Globe';
|
|
11
9
|
export * from './Graph';
|
|
12
10
|
export * from './Tree';
|
|
11
|
+
|
|
12
|
+
export const ExplorerContainer: ComponentType<any> = lazy(() => import('./ExplorerContainer'));
|
package/src/meta.ts
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type PluginMeta } from '@dxos/app-framework';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
6
7
|
|
|
7
8
|
export const meta: PluginMeta = {
|
|
8
9
|
id: 'dxos.org/plugin/explorer',
|
|
9
10
|
name: 'Explorer',
|
|
10
|
-
description:
|
|
11
|
+
description: trim`
|
|
12
|
+
Interactive hypergraph visualization that reveals relationships between objects in your workspace.
|
|
13
|
+
Navigate complex data structures and discover connections through a dynamic network view.
|
|
14
|
+
`,
|
|
11
15
|
icon: 'ph--graph--regular',
|
|
16
|
+
iconHue: 'green',
|
|
12
17
|
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',
|
|
13
18
|
tags: ['labs'],
|
|
14
19
|
screenshots: ['https://dxos.network/plugin-details-explorer-dark.png'],
|
package/src/translations.ts
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Type } from '@dxos/echo';
|
|
5
6
|
import { type Resource } from '@dxos/react-ui';
|
|
6
7
|
import { translations as componentsTranslations } from '@dxos/react-ui-components';
|
|
7
8
|
|
|
8
9
|
import { meta } from './meta';
|
|
9
|
-
import {
|
|
10
|
+
import { Graph } from './types';
|
|
10
11
|
|
|
11
12
|
export const translations = [
|
|
12
13
|
{
|
|
13
14
|
'en-US': {
|
|
14
|
-
[
|
|
15
|
+
[Type.getTypename(Graph.Graph)]: {
|
|
15
16
|
'typename label': 'Explorer',
|
|
16
17
|
'typename label_zero': 'Explorers',
|
|
17
18
|
'typename label_one': 'Explorer',
|
|
@@ -19,6 +20,7 @@ export const translations = [
|
|
|
19
20
|
'object name placeholder': 'New explorer',
|
|
20
21
|
'rename object label': 'Rename explorer',
|
|
21
22
|
'delete object label': 'Delete explorer',
|
|
23
|
+
'object deleted label': 'Explorer deleted',
|
|
22
24
|
},
|
|
23
25
|
[meta.id]: {
|
|
24
26
|
'plugin name': 'Explorer',
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
|
|
7
|
+
import { TypeInputOptionsAnnotation } from '@dxos/plugin-space/types';
|
|
8
|
+
import { SpaceSchema } from '@dxos/react-client/echo';
|
|
9
|
+
|
|
10
|
+
import { meta } from '../meta';
|
|
11
|
+
|
|
12
|
+
import * as Graph from './Graph';
|
|
13
|
+
|
|
14
|
+
const EXPLORER_ACTION = `${meta.id}/action`;
|
|
15
|
+
|
|
16
|
+
export const GraphProps = Schema.Struct({
|
|
17
|
+
name: Schema.optional(Schema.String),
|
|
18
|
+
// TODO(wittjosiah): This should be a query input instead.
|
|
19
|
+
typename: Schema.String.pipe(
|
|
20
|
+
Schema.annotations({ title: 'Select type' }),
|
|
21
|
+
TypeInputOptionsAnnotation.set({
|
|
22
|
+
location: ['database', 'runtime'],
|
|
23
|
+
kind: ['user'],
|
|
24
|
+
registered: ['registered'],
|
|
25
|
+
}),
|
|
26
|
+
Schema.optional,
|
|
27
|
+
),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export class CreateGraph extends Schema.TaggedClass<CreateGraph>()(`${EXPLORER_ACTION}/create-graph`, {
|
|
31
|
+
input: Schema.Struct({
|
|
32
|
+
space: SpaceSchema,
|
|
33
|
+
}).pipe(Schema.extend(GraphProps)),
|
|
34
|
+
output: Schema.Struct({
|
|
35
|
+
object: Graph.Graph,
|
|
36
|
+
}),
|
|
37
|
+
}) {}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
|
|
7
|
+
import { Filter, Obj, Query, QueryAST, Ref, Type } from '@dxos/echo';
|
|
8
|
+
import { FormInputAnnotation, LabelAnnotation } from '@dxos/echo/internal';
|
|
9
|
+
import { View, ViewAnnotation } from '@dxos/schema';
|
|
10
|
+
|
|
11
|
+
const GraphSchema = Schema.Struct({
|
|
12
|
+
name: Schema.optional(Schema.String),
|
|
13
|
+
|
|
14
|
+
view: Type.Ref(View.View).pipe(FormInputAnnotation.set(false)),
|
|
15
|
+
|
|
16
|
+
query: Schema.Struct({
|
|
17
|
+
raw: Schema.optional(Schema.String),
|
|
18
|
+
ast: QueryAST.Query,
|
|
19
|
+
}).pipe(Schema.mutable, FormInputAnnotation.set(false)),
|
|
20
|
+
}).pipe(
|
|
21
|
+
Type.Obj({
|
|
22
|
+
typename: 'dxos.org/type/Graph',
|
|
23
|
+
version: '0.2.0',
|
|
24
|
+
}),
|
|
25
|
+
LabelAnnotation.set(['name']),
|
|
26
|
+
ViewAnnotation.set(true),
|
|
27
|
+
);
|
|
28
|
+
export interface Graph extends Schema.Schema.Type<typeof GraphSchema> {}
|
|
29
|
+
export interface GraphEncoded extends Schema.Schema.Encoded<typeof GraphSchema> {}
|
|
30
|
+
export const Graph: Schema.Schema<Graph, GraphEncoded> = GraphSchema;
|
|
31
|
+
|
|
32
|
+
type MakeProps = Omit<Partial<Obj.MakeProps<typeof Graph>>, 'view'> & {
|
|
33
|
+
view: View.View;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Make a graph as a view of a data set.
|
|
38
|
+
*/
|
|
39
|
+
export const make = ({
|
|
40
|
+
name,
|
|
41
|
+
query = { raw: '', ast: Query.select(Filter.nothing()).ast },
|
|
42
|
+
view,
|
|
43
|
+
}: MakeProps): Graph => {
|
|
44
|
+
return Obj.make(Graph, { name, view: Ref.make(view), query });
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
//
|
|
48
|
+
// V1
|
|
49
|
+
//
|
|
50
|
+
|
|
51
|
+
export const GraphV1 = Schema.Struct({
|
|
52
|
+
name: Schema.optional(Schema.String),
|
|
53
|
+
query: Schema.Struct({
|
|
54
|
+
raw: Schema.optional(Schema.String),
|
|
55
|
+
ast: QueryAST.Query,
|
|
56
|
+
}).pipe(Schema.mutable),
|
|
57
|
+
}).pipe(
|
|
58
|
+
Type.Obj({
|
|
59
|
+
typename: 'dxos.org/type/Graph',
|
|
60
|
+
version: '0.1.0',
|
|
61
|
+
}),
|
|
62
|
+
LabelAnnotation.set(['name']),
|
|
63
|
+
);
|
package/src/types/index.ts
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/ExplorerContainer.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { type Filter } from '@dxos/echo';\nimport { QueryBuilder } from '@dxos/echo-query';\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { Toolbar } from '@dxos/react-ui';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';\nimport { StackItem } from '@dxos/react-ui-stack';\n\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\nimport { D3ForceGraph } from './Graph';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const [filter, setFilter] = useState<Filter.Any>();\n const model = useGraphModel(space, filter);\n const { match } = useGlobalSearch();\n\n const builder = useMemo(() => new QueryBuilder(), []);\n const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {\n setFilter(builder.build(value));\n }, []);\n\n if (!space || !model) {\n return null;\n }\n\n return (\n <StackItem.Content toolbar size={role === 'section' ? 'square' : 'intrinsic'}>\n <Toolbar.Root>\n <QueryEditor space={space} onChange={handleChange} />\n </Toolbar.Root>\n <D3ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;AAIA,OAAOA,SAASC,aAAaC,SAASC,gBAAgB;AAGtD,SAASC,oBAAoB;AAC7B,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,eAAe;AACxB,SAASC,mBAA0C;AACnD,SAASC,iBAAiB;AAY1B,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,QAAQC,SAASF,IAAAA;AACvB,UAAM,CAACG,QAAQC,SAAAA,IAAaC,SAAAA;AAC5B,UAAMC,QAAQC,cAAcN,OAAOE,MAAAA;AACnC,UAAM,EAAEK,MAAK,IAAKC,gBAAAA;AAElB,UAAMC,UAAUC,QAAQ,MAAM,IAAIC,aAAAA,GAAgB,CAAA,CAAE;AACpD,UAAMC,eAAeC,YAAuD,CAACC,UAAAA;AAC3EX,gBAAUM,QAAQM,MAAMD,KAAAA,CAAAA;IAC1B,GAAG,CAAA,CAAE;AAEL,QAAI,CAACd,SAAS,CAACK,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACW,UAAUC,SAAO;MAACC,SAAAA;MAAQC,MAAMrB,SAAS,YAAY,WAAW;OAC/D,sBAAA,cAACsB,QAAQC,MAAI,MACX,sBAAA,cAACC,aAAAA;MAAYtB;MAAcuB,UAAUX;SAEvC,sBAAA,cAACY,cAAAA;MAAanB;MAAcE;;;;;AAGlC;AAEA,IAAA,4BAAeV;",
|
|
6
|
-
"names": ["React", "useCallback", "useMemo", "useState", "QueryBuilder", "useGlobalSearch", "getSpace", "Toolbar", "QueryEditor", "StackItem", "ExplorerContainer", "role", "view", "space", "getSpace", "filter", "setFilter", "useState", "model", "useGraphModel", "match", "useGlobalSearch", "builder", "useMemo", "QueryBuilder", "handleChange", "useCallback", "value", "build", "StackItem", "Content", "toolbar", "size", "Toolbar", "Root", "QueryEditor", "onChange", "D3ForceGraph"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const meta: PluginMeta = {\n id: 'dxos.org/plugin/explorer',\n name: 'Explorer',\n description: 'Install this plugin to view a hypergraph of all objects inside of your Space.',\n icon: 'ph--graph--regular',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',\n tags: ['labs'],\n screenshots: ['https://dxos.network/plugin-details-explorer-dark.png'],\n};\n"],
|
|
5
|
-
"mappings": ";AAMO,IAAMA,OAAmB;EAC9BC,IAAI;EACJC,MAAM;EACNC,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,MAAM;IAAC;;EACPC,aAAa;IAAC;;AAChB;",
|
|
6
|
-
"names": ["meta", "id", "name", "description", "icon", "source", "tags", "screenshots"]
|
|
7
|
-
}
|