@dxos/plugin-explorer 0.8.4-main.67995b8 → 0.8.4-main.70d3990
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-NOLLVUTE.mjs +50 -0
- package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-OAOY7SHY.mjs → chunk-2MKBRIUT.mjs} +6 -5
- package/dist/lib/browser/chunk-2MKBRIUT.mjs.map +7 -0
- package/dist/lib/browser/{chunk-J2BBZOSF.mjs → chunk-6BVXZQPP.mjs} +9 -8
- package/dist/lib/browser/chunk-6BVXZQPP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PVFZFKQ6.mjs → chunk-ARBGXQFH.mjs} +6 -246
- package/dist/lib/browser/{chunk-PVFZFKQ6.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-UBHZGWZQ.mjs +24 -0
- package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +29 -29
- 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 -3
- package/dist/lib/browser/react-surface-BY2DYCTH.mjs +34 -0
- 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-N3S5KSUX.mjs +51 -0
- package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PPBUWC7F.mjs → chunk-3ODK27PU.mjs} +6 -5
- package/dist/lib/node-esm/chunk-3ODK27PU.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-4VMSNXYL.mjs → chunk-CRSVAZNA.mjs} +9 -8
- package/dist/lib/node-esm/chunk-CRSVAZNA.mjs.map +7 -0
- 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-S5A2EUSJ.mjs → chunk-NPIP4VEH.mjs} +6 -246
- package/dist/lib/node-esm/{chunk-S5A2EUSJ.mjs.map → chunk-NPIP4VEH.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-PIAXA43R.mjs → chunk-UXZM5VJB.mjs} +8 -5
- package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +29 -29
- 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 -3
- package/dist/lib/node-esm/react-surface-7AAV7GBG.mjs +35 -0
- 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 +1 -1
- package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -2
- 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 +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
- package/dist/types/src/components/Chart/Chart.stories.d.ts +8 -4
- package/dist/types/src/components/Chart/Chart.stories.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/Globe/Globe.d.ts.map +1 -1
- package/dist/types/src/components/Globe/Globe.stories.d.ts +8 -4
- package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/D3ForceGraph.d.ts +2 -2
- package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -1
- package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +13 -4
- package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +13 -4
- package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
- package/dist/types/src/components/Graph/testing.d.ts +1 -1
- package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
- package/dist/types/src/components/Tree/Tree.stories.d.ts +13 -16
- package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tree/types/tree.d.ts +7 -7
- package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
- 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/hooks/useGraphModel.d.ts +2 -2
- package/dist/types/src/hooks/useGraphModel.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +25 -5
- 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 +44 -42
- package/src/ExplorerPlugin.tsx +41 -50
- package/src/capabilities/intent-resolver.ts +12 -8
- package/src/capabilities/react-surface.tsx +8 -5
- package/src/components/Chart/Chart.stories.tsx +9 -7
- package/src/components/Chart/Chart.tsx +1 -1
- package/src/components/ExplorerContainer.tsx +24 -6
- package/src/components/Globe/Globe.stories.tsx +14 -12
- package/src/components/Globe/Globe.tsx +1 -1
- package/src/components/Graph/D3ForceGraph.stories.tsx +36 -20
- package/src/components/Graph/D3ForceGraph.tsx +5 -5
- package/src/components/Graph/ForceGraph.stories.tsx +36 -20
- package/src/components/Graph/ForceGraph.tsx +4 -4
- package/src/components/Graph/testing.ts +8 -8
- package/src/components/Tree/Tree.stories.tsx +28 -22
- package/src/components/Tree/Tree.tsx +3 -3
- package/src/components/Tree/types/tree.test.ts +4 -3
- package/src/components/Tree/types/tree.ts +1 -1
- package/src/components/index.ts +3 -3
- package/src/hooks/useGraphModel.ts +5 -4
- package/src/meta.ts +7 -4
- package/src/translations.ts +6 -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-OGHSHZD5.mjs +0 -37
- package/dist/lib/browser/ExplorerContainer-OGHSHZD5.mjs.map +0 -7
- package/dist/lib/browser/chunk-EF4BFHTI.mjs +0 -38
- package/dist/lib/browser/chunk-EF4BFHTI.mjs.map +0 -7
- package/dist/lib/browser/chunk-J2BBZOSF.mjs.map +0 -7
- package/dist/lib/browser/chunk-OAOY7SHY.mjs.map +0 -7
- package/dist/lib/browser/chunk-UL5EDJPE.mjs +0 -21
- package/dist/lib/browser/chunk-UL5EDJPE.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-XH2UO2FM.mjs +0 -24
- package/dist/lib/browser/intent-resolver-XH2UO2FM.mjs.map +0 -7
- package/dist/lib/browser/react-surface-65VQ42HX.mjs +0 -31
- package/dist/lib/browser/react-surface-65VQ42HX.mjs.map +0 -7
- package/dist/lib/node-esm/ExplorerContainer-6ON5NA2P.mjs +0 -38
- package/dist/lib/node-esm/ExplorerContainer-6ON5NA2P.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4VMSNXYL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PIAXA43R.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PPBUWC7F.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-VKCOKQRG.mjs +0 -39
- package/dist/lib/node-esm/chunk-VKCOKQRG.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-AGBBNA67.mjs +0 -25
- package/dist/lib/node-esm/intent-resolver-AGBBNA67.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-IJIMYAST.mjs +0 -32
- package/dist/lib/node-esm/react-surface-IJIMYAST.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 -21
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useState } from 'react';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
9
|
-
|
|
10
|
-
import { Obj } from '@dxos/echo';
|
|
8
|
+
import { Type } from '@dxos/echo';
|
|
11
9
|
import { faker } from '@dxos/random';
|
|
12
10
|
import { useClient } from '@dxos/react-client';
|
|
13
11
|
import { type Space } from '@dxos/react-client/echo';
|
|
14
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
15
|
-
import {
|
|
13
|
+
import { useAsyncEffect } from '@dxos/react-ui';
|
|
14
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
15
|
+
import { View } from '@dxos/schema';
|
|
16
16
|
import { type ValueGenerator } from '@dxos/schema/testing';
|
|
17
|
-
import {
|
|
17
|
+
import { render } from '@dxos/storybook-utils';
|
|
18
|
+
import { HasRelationship, Organization, Person, Project } from '@dxos/types';
|
|
19
|
+
|
|
20
|
+
import { useGraphModel } from '../../hooks';
|
|
21
|
+
import { Graph } from '../../types';
|
|
18
22
|
|
|
19
23
|
import { ForceGraph } from './ForceGraph';
|
|
20
24
|
import { generate } from './testing';
|
|
21
|
-
import { useGraphModel } from '../../hooks';
|
|
22
|
-
import { ViewType } from '../../types';
|
|
23
25
|
|
|
24
26
|
const generator = faker as any as ValueGenerator;
|
|
25
27
|
|
|
@@ -28,37 +30,51 @@ 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
|
|
|
45
50
|
return <ForceGraph model={model} />;
|
|
46
51
|
};
|
|
47
52
|
|
|
48
|
-
const meta
|
|
53
|
+
const meta = {
|
|
49
54
|
title: 'plugins/plugin-explorer/ForceGraph',
|
|
50
55
|
component: ForceGraph,
|
|
51
56
|
render: render(DefaultStory),
|
|
52
57
|
decorators: [
|
|
58
|
+
withTheme,
|
|
53
59
|
withClientProvider({
|
|
54
60
|
createSpace: true,
|
|
55
|
-
types: [
|
|
61
|
+
types: [
|
|
62
|
+
Graph.Graph,
|
|
63
|
+
View.View,
|
|
64
|
+
HasRelationship.HasRelationship,
|
|
65
|
+
Organization.Organization,
|
|
66
|
+
Project.Project,
|
|
67
|
+
Person.Person,
|
|
68
|
+
],
|
|
56
69
|
}),
|
|
57
|
-
withTheme,
|
|
58
|
-
withLayout({ fullscreen: true }),
|
|
59
70
|
],
|
|
60
|
-
|
|
71
|
+
parameters: {
|
|
72
|
+
layout: 'fullscreen',
|
|
73
|
+
},
|
|
74
|
+
} satisfies Meta<typeof ForceGraph>;
|
|
61
75
|
|
|
62
76
|
export default meta;
|
|
63
77
|
|
|
64
|
-
|
|
78
|
+
type Story = StoryObj<typeof meta>;
|
|
79
|
+
|
|
80
|
+
export const Default: Story = {};
|
|
@@ -7,7 +7,7 @@ import NativeForceGraph from 'force-graph';
|
|
|
7
7
|
import React, { type FC, useEffect, useRef, useState } from 'react';
|
|
8
8
|
import { useResizeDetector } from 'react-resize-detector';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { type SearchResult, filterObjectsSync } from '@dxos/plugin-search';
|
|
11
11
|
import { type SpaceGraphModel } from '@dxos/schema';
|
|
12
12
|
|
|
13
13
|
import { GraphAdapter } from './adapter';
|
|
@@ -20,9 +20,9 @@ export type ForceGraphProps = {
|
|
|
20
20
|
export const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {
|
|
21
21
|
const { ref, width, height } = useResizeDetector({ refreshRate: 200 });
|
|
22
22
|
const rootRef = useRef<HTMLDivElement>(null);
|
|
23
|
-
const forceGraph = useRef<NativeForceGraph>();
|
|
23
|
+
const forceGraph = useRef<NativeForceGraph>(null);
|
|
24
24
|
|
|
25
|
-
const filteredRef = useRef<SearchResult[]>();
|
|
25
|
+
const filteredRef = useRef<SearchResult[]>([]);
|
|
26
26
|
filteredRef.current = filterObjectsSync(model?.objects ?? [], match);
|
|
27
27
|
|
|
28
28
|
const [data, setData] = useState<GraphAdapter>();
|
|
@@ -48,7 +48,7 @@ export const ForceGraph: FC<ForceGraphProps> = ({ model, match }) => {
|
|
|
48
48
|
|
|
49
49
|
return () => {
|
|
50
50
|
forceGraph.current?.pauseAnimation().graphData({ nodes: [], links: [] });
|
|
51
|
-
forceGraph.current =
|
|
51
|
+
forceGraph.current = null;
|
|
52
52
|
};
|
|
53
53
|
}, []);
|
|
54
54
|
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Space } from '@dxos/client/echo';
|
|
6
|
-
import { Query, Relation
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { type Obj, Query, Relation } from '@dxos/echo';
|
|
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,
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type Meta } from '@storybook/react-vite';
|
|
8
|
-
import React, { type FC, useEffect, useState } from 'react';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { faker } from '@dxos/random';
|
|
11
9
|
import { useClient } from '@dxos/react-client';
|
|
12
10
|
import { type ClientRepeatedComponentProps, ClientRepeater } from '@dxos/react-client/testing';
|
|
13
|
-
import {
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
12
|
|
|
15
13
|
import { Tree, type TreeComponentProps } from './Tree';
|
|
16
|
-
import {
|
|
14
|
+
import { Tree as TreeModel, TreeType } from './types';
|
|
17
15
|
|
|
18
16
|
// TODO(burdon): Storybook for Graph/Tree/Plot (generics); incl. GraphModel.
|
|
19
17
|
// TODO(burdon): Type for all Explorer components (Space, Object, Query, etc.) incl.
|
|
20
18
|
|
|
21
19
|
faker.seed(1);
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
type ComponentProps = ClientRepeatedComponentProps & { type?: TreeComponentProps<any>['variant'] };
|
|
22
|
+
|
|
23
|
+
const Component = ({ type }: ComponentProps) => {
|
|
24
24
|
const client = useClient();
|
|
25
25
|
const space = client.spaces.default;
|
|
26
26
|
const [object, setObject] = useState<TreeType>();
|
|
@@ -38,32 +38,38 @@ const Story: FC<ClientRepeatedComponentProps & { type?: TreeComponentProps<any>[
|
|
|
38
38
|
return <Tree space={space} selected={object?.id} variant={type} />;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
const DefaultStory = () => {
|
|
42
|
+
return <ClientRepeater component={Component} types={[TreeType]} createSpace />;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const meta = {
|
|
46
|
+
title: 'plugins/plugin-explorer/Tree',
|
|
47
|
+
component: Tree as any,
|
|
48
|
+
render: DefaultStory,
|
|
49
|
+
decorators: [withTheme],
|
|
50
|
+
parameters: {
|
|
51
|
+
layout: 'fullscreen',
|
|
52
|
+
},
|
|
53
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
54
|
+
|
|
55
|
+
export default meta;
|
|
56
|
+
|
|
57
|
+
type Story = StoryObj<typeof meta>;
|
|
58
|
+
|
|
59
|
+
export const Tidy: Story = {
|
|
42
60
|
args: {
|
|
43
61
|
type: 'tidy',
|
|
44
62
|
},
|
|
45
63
|
};
|
|
46
64
|
|
|
47
|
-
export const Radial = {
|
|
65
|
+
export const Radial: Story = {
|
|
48
66
|
args: {
|
|
49
67
|
type: 'radial',
|
|
50
68
|
},
|
|
51
69
|
};
|
|
52
70
|
|
|
53
|
-
export const Edge = {
|
|
71
|
+
export const Edge: Story = {
|
|
54
72
|
args: {
|
|
55
73
|
type: 'edge',
|
|
56
74
|
},
|
|
57
75
|
};
|
|
58
|
-
|
|
59
|
-
const meta: Meta = {
|
|
60
|
-
title: 'plugins/plugin-explorer/Tree',
|
|
61
|
-
component: Tree,
|
|
62
|
-
render: () => <ClientRepeater component={Story} types={[TreeType]} createSpace />,
|
|
63
|
-
decorators: [withTheme, withLayout({ fullscreen: true })],
|
|
64
|
-
parameters: {
|
|
65
|
-
layout: 'fullscreen',
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export default meta;
|
|
@@ -10,7 +10,7 @@ import { SVG, type SVGContext } from '@dxos/react-ui-graph';
|
|
|
10
10
|
import { SpaceGraphModel } from '@dxos/schema';
|
|
11
11
|
|
|
12
12
|
import { HierarchicalEdgeBundling, RadialTree, TidyTree } from './layout';
|
|
13
|
-
import {
|
|
13
|
+
import { type TreeNode, mapGraphToTreeData } from './types';
|
|
14
14
|
|
|
15
15
|
// TODO(burdon): Create dge bundling graph using d3.hierarchy.
|
|
16
16
|
// https://observablehq.com/@d3/hierarchical-edge-bundling?intent=fork
|
|
@@ -75,8 +75,8 @@ export const Tree = <N,>({ space, selected, variant = 'tidy', onNodeClick }: Tre
|
|
|
75
75
|
const context = useRef<SVGContext>(null);
|
|
76
76
|
|
|
77
77
|
useEffect(() => {
|
|
78
|
-
if (context.current) {
|
|
79
|
-
const { width, height } = context.current.size
|
|
78
|
+
if (context.current?.size) {
|
|
79
|
+
const { width, height } = context.current.size;
|
|
80
80
|
const size = Math.min(width, height);
|
|
81
81
|
const radius = size * 0.4;
|
|
82
82
|
const options = {
|
|
@@ -6,11 +6,12 @@ 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
|
-
import { type Tree } from './tree';
|
|
12
11
|
import { createTree } from '../testing';
|
|
13
12
|
|
|
13
|
+
import { type Tree } from './tree';
|
|
14
|
+
|
|
14
15
|
faker.seed(0);
|
|
15
16
|
|
|
16
17
|
const print = (tree: Tree) => {
|
|
@@ -123,7 +124,7 @@ describe('tree', () => {
|
|
|
123
124
|
});
|
|
124
125
|
|
|
125
126
|
test('task', ({ expect }) => {
|
|
126
|
-
const task = Obj.make(
|
|
127
|
+
const task = Obj.make(Task.Task, { title: 'Test task.' });
|
|
127
128
|
expect(task.title).to.eq('Test task.');
|
|
128
129
|
|
|
129
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'));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { type Filter, type Space } from '@dxos/client/echo';
|
|
7
|
+
import { type Filter, type Queue, type Space } from '@dxos/client/echo';
|
|
8
8
|
import { SpaceGraphModel, type SpaceGraphModelOptions } from '@dxos/schema';
|
|
9
9
|
|
|
10
10
|
// TODO(burdon): Factor out.
|
|
@@ -12,6 +12,7 @@ export const useGraphModel = (
|
|
|
12
12
|
space: Space | undefined,
|
|
13
13
|
filter?: Filter.Any | undefined,
|
|
14
14
|
options?: SpaceGraphModelOptions,
|
|
15
|
+
queue?: Queue,
|
|
15
16
|
): SpaceGraphModel | undefined => {
|
|
16
17
|
const [model, setModel] = useState<SpaceGraphModel | undefined>(undefined);
|
|
17
18
|
useEffect(() => {
|
|
@@ -22,14 +23,14 @@ export const useGraphModel = (
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
// TODO(burdon): Does this need to be a dependency?
|
|
25
|
-
if (!model) {
|
|
26
|
+
if (!model || model.queue !== queue) {
|
|
26
27
|
const model = new SpaceGraphModel().setFilter(filter).setOptions(options);
|
|
27
|
-
void model.open(space);
|
|
28
|
+
void model.open(space, queue);
|
|
28
29
|
setModel(model);
|
|
29
30
|
} else {
|
|
30
31
|
model.setFilter(filter).setOptions(options);
|
|
31
32
|
}
|
|
32
|
-
}, [space, filter, options]);
|
|
33
|
+
}, [space, filter, options, queue]);
|
|
33
34
|
|
|
34
35
|
return model;
|
|
35
36
|
};
|
package/src/meta.ts
CHANGED
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type PluginMeta } from '@dxos/app-framework';
|
|
6
|
-
|
|
7
|
-
export const EXPLORER_PLUGIN = 'dxos.org/plugin/explorer';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
8
7
|
|
|
9
8
|
export const meta: PluginMeta = {
|
|
10
|
-
id:
|
|
9
|
+
id: 'dxos.org/plugin/explorer',
|
|
11
10
|
name: 'Explorer',
|
|
12
|
-
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
|
+
`,
|
|
13
15
|
icon: 'ph--graph--regular',
|
|
16
|
+
iconHue: 'green',
|
|
14
17
|
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-explorer',
|
|
15
18
|
tags: ['labs'],
|
|
16
19
|
screenshots: ['https://dxos.network/plugin-details-explorer-dark.png'],
|
package/src/translations.ts
CHANGED
|
@@ -2,15 +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';
|
|
7
|
+
import { translations as componentsTranslations } from '@dxos/react-ui-components';
|
|
6
8
|
|
|
7
9
|
import { meta } from './meta';
|
|
8
|
-
import {
|
|
10
|
+
import { Graph } from './types';
|
|
9
11
|
|
|
10
12
|
export const translations = [
|
|
11
13
|
{
|
|
12
14
|
'en-US': {
|
|
13
|
-
[
|
|
15
|
+
[Type.getTypename(Graph.Graph)]: {
|
|
14
16
|
'typename label': 'Explorer',
|
|
15
17
|
'typename label_zero': 'Explorers',
|
|
16
18
|
'typename label_one': 'Explorer',
|
|
@@ -18,6 +20,7 @@ export const translations = [
|
|
|
18
20
|
'object name placeholder': 'New explorer',
|
|
19
21
|
'rename object label': 'Rename explorer',
|
|
20
22
|
'delete object label': 'Delete explorer',
|
|
23
|
+
'object deleted label': 'Explorer deleted',
|
|
21
24
|
},
|
|
22
25
|
[meta.id]: {
|
|
23
26
|
'plugin name': 'Explorer',
|
|
@@ -25,4 +28,5 @@ export const translations = [
|
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
},
|
|
31
|
+
...componentsTranslations,
|
|
28
32
|
] as const satisfies Resource[];
|
|
@@ -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,37 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useGraphModel
|
|
3
|
-
} from "./chunk-OAOY7SHY.mjs";
|
|
4
|
-
import {
|
|
5
|
-
D3ForceGraph
|
|
6
|
-
} from "./chunk-J2BBZOSF.mjs";
|
|
7
|
-
|
|
8
|
-
// src/components/ExplorerContainer.tsx
|
|
9
|
-
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
10
|
-
import React from "react";
|
|
11
|
-
import { useGlobalSearch } from "@dxos/plugin-search";
|
|
12
|
-
import { getSpace } from "@dxos/react-client/echo";
|
|
13
|
-
import { StackItem } from "@dxos/react-ui-stack";
|
|
14
|
-
var ExplorerContainer = ({ role, view }) => {
|
|
15
|
-
var _effect = _useSignals();
|
|
16
|
-
try {
|
|
17
|
-
const space = getSpace(view);
|
|
18
|
-
const model = useGraphModel(space);
|
|
19
|
-
const { match } = useGlobalSearch();
|
|
20
|
-
if (!space || !model) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
return /* @__PURE__ */ React.createElement(StackItem.Content, {
|
|
24
|
-
size: role === "section" ? "square" : "intrinsic"
|
|
25
|
-
}, /* @__PURE__ */ React.createElement(D3ForceGraph, {
|
|
26
|
-
model,
|
|
27
|
-
match
|
|
28
|
-
}));
|
|
29
|
-
} finally {
|
|
30
|
-
_effect.f();
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
var ExplorerContainer_default = ExplorerContainer;
|
|
34
|
-
export {
|
|
35
|
-
ExplorerContainer_default as default
|
|
36
|
-
};
|
|
37
|
-
//# sourceMappingURL=ExplorerContainer-OGHSHZD5.mjs.map
|
|
@@ -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 from 'react';\n\nimport { useGlobalSearch } from '@dxos/plugin-search';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { StackItem } from '@dxos/react-ui-stack';\n\nimport { D3ForceGraph } from './Graph';\nimport { useGraphModel } from '../hooks';\nimport { type ViewType } from '../types';\n\ntype ExplorerContainerProps = {\n role: string;\n view: ViewType;\n};\n\nconst ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {\n const space = getSpace(view);\n const model = useGraphModel(space);\n const { match } = useGlobalSearch();\n\n if (!space || !model) {\n return null;\n }\n\n return (\n <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>\n <D3ForceGraph model={model} match={match} />\n </StackItem.Content>\n );\n};\n\nexport default ExplorerContainer;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;AAIA,OAAOA,WAAW;AAElB,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,iBAAiB;AAW1B,IAAMC,oBAAoB,CAAC,EAAEC,MAAMC,KAAI,MAA0B;;;AAC/D,UAAMC,QAAQC,SAASF,IAAAA;AACvB,UAAMG,QAAQC,cAAcH,KAAAA;AAC5B,UAAM,EAAEI,MAAK,IAAKC,gBAAAA;AAElB,QAAI,CAACL,SAAS,CAACE,OAAO;AACpB,aAAO;IACT;AAEA,WACE,sBAAA,cAACI,UAAUC,SAAO;MAACC,MAAMV,SAAS,YAAY,WAAW;OACvD,sBAAA,cAACW,cAAAA;MAAaP;MAAcE;;;;;AAGlC;AAEA,IAAA,4BAAeP;",
|
|
6
|
-
"names": ["React", "useGlobalSearch", "getSpace", "StackItem", "ExplorerContainer", "role", "view", "space", "getSpace", "model", "useGraphModel", "match", "useGlobalSearch", "StackItem", "Content", "size", "D3ForceGraph"]
|
|
7
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EXPLORER_PLUGIN
|
|
3
|
-
} from "./chunk-UL5EDJPE.mjs";
|
|
4
|
-
|
|
5
|
-
// src/types/schema.ts
|
|
6
|
-
import { Schema } from "effect";
|
|
7
|
-
import { TypedObject } from "@dxos/echo-schema";
|
|
8
|
-
var ViewType = class extends TypedObject({
|
|
9
|
-
typename: "dxos.org/type/ExplorerView",
|
|
10
|
-
version: "0.1.0"
|
|
11
|
-
})({
|
|
12
|
-
name: Schema.optional(Schema.String),
|
|
13
|
-
type: Schema.String
|
|
14
|
-
}) {
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// src/types/types.ts
|
|
18
|
-
import { Schema as Schema2 } from "effect";
|
|
19
|
-
(function(ExplorerAction2) {
|
|
20
|
-
const EXPLORER_ACTION = `${EXPLORER_PLUGIN}/action`;
|
|
21
|
-
class Create extends Schema2.TaggedClass()(`${EXPLORER_ACTION}/create`, {
|
|
22
|
-
input: Schema2.Struct({
|
|
23
|
-
name: Schema2.optional(Schema2.String)
|
|
24
|
-
}),
|
|
25
|
-
output: Schema2.Struct({
|
|
26
|
-
object: ViewType
|
|
27
|
-
})
|
|
28
|
-
}) {
|
|
29
|
-
}
|
|
30
|
-
ExplorerAction2.Create = Create;
|
|
31
|
-
})(ExplorerAction || (ExplorerAction = {}));
|
|
32
|
-
var ExplorerAction;
|
|
33
|
-
|
|
34
|
-
export {
|
|
35
|
-
ViewType,
|
|
36
|
-
ExplorerAction
|
|
37
|
-
};
|
|
38
|
-
//# sourceMappingURL=chunk-EF4BFHTI.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/types/schema.ts", "../../../src/types/types.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { TypedObject } from '@dxos/echo-schema';\n\n// TODO(burdon): Clashes with sdk/view.\nexport class ViewType extends TypedObject({\n typename: 'dxos.org/type/ExplorerView',\n version: '0.1.0',\n})({\n name: Schema.optional(Schema.String),\n type: Schema.String,\n}) {}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { Schema } from 'effect';\n\nimport { ViewType } from './schema';\nimport { EXPLORER_PLUGIN } from '../meta';\n\nexport namespace ExplorerAction {\n const EXPLORER_ACTION = `${EXPLORER_PLUGIN}/action`;\n\n export class Create extends Schema.TaggedClass<Create>()(`${EXPLORER_ACTION}/create`, {\n input: Schema.Struct({\n name: Schema.optional(Schema.String),\n }),\n output: Schema.Struct({\n object: ViewType,\n }),\n }) {}\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAIA,SAASA,cAAc;AAEvB,SAASC,mBAAmB;AAGrB,IAAMC,WAAN,cAAuBC,YAAY;EACxCC,UAAU;EACVC,SAAS;AACX,CAAA,EAAG;EACDC,MAAMC,OAAOC,SAASD,OAAOE,MAAM;EACnCC,MAAMH,OAAOE;AACf,CAAA,EAAA;AAAI;;;ACXJ,SAASE,UAAAA,eAAc;UAKNC,iBAAAA;AACf,QAAMC,kBAAkB,GAAGC,eAAAA;EAEpB,MAAMC,eAAeC,QAAOC,YAAW,EAAW,GAAGJ,eAAAA,WAA0B;IACpFK,OAAOF,QAAOG,OAAO;MACnBC,MAAMJ,QAAOK,SAASL,QAAOM,MAAM;IACrC,CAAA;IACAC,QAAQP,QAAOG,OAAO;MACpBK,QAAQC;IACV,CAAA;EACF,CAAA,EAAA;EAAI;kBAPSV,SAAAA;AAQf,GAXiBH,mBAAAA,iBAAAA,CAAAA,EAAAA;;",
|
|
6
|
-
"names": ["Schema", "TypedObject", "ViewType", "TypedObject", "typename", "version", "name", "Schema", "optional", "String", "type", "Schema", "ExplorerAction", "EXPLORER_ACTION", "EXPLORER_PLUGIN", "Create", "Schema", "TaggedClass", "input", "Struct", "name", "optional", "String", "output", "object", "ViewType"]
|
|
7
|
-
}
|