@dxos/plugin-explorer 0.8.4-main.e098934 → 0.8.4-main.e8ec1fe

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.
Files changed (127) hide show
  1. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs +50 -0
  2. package/dist/lib/browser/ExplorerContainer-NOLLVUTE.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-3YITRGGW.mjs → chunk-6BVXZQPP.mjs} +15 -30
  4. package/dist/lib/browser/chunk-6BVXZQPP.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-VNOGW2JS.mjs → chunk-ARBGXQFH.mjs} +6 -258
  6. package/dist/lib/browser/{chunk-VNOGW2JS.mjs.map → chunk-ARBGXQFH.mjs.map} +3 -3
  7. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  8. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-JDSUIUNR.mjs +80 -0
  10. package/dist/lib/browser/chunk-JDSUIUNR.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-UBHZGWZQ.mjs +24 -0
  12. package/dist/lib/browser/chunk-UBHZGWZQ.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +25 -18
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/intent-resolver-YS5LZC3A.mjs +31 -0
  16. package/dist/lib/browser/intent-resolver-YS5LZC3A.mjs.map +7 -0
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/meta.mjs +2 -3
  19. package/dist/lib/browser/react-surface-BVTCOVLK.mjs +35 -0
  20. package/dist/lib/browser/react-surface-BVTCOVLK.mjs.map +7 -0
  21. package/dist/lib/browser/types/index.mjs +7 -6
  22. package/dist/lib/node-esm/{ExplorerContainer-OBSRVHZZ.mjs → ExplorerContainer-N3S5KSUX.mjs} +19 -6
  23. package/dist/lib/node-esm/ExplorerContainer-N3S5KSUX.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-GFYXDQQV.mjs → chunk-CRSVAZNA.mjs} +15 -30
  25. package/dist/lib/node-esm/chunk-CRSVAZNA.mjs.map +7 -0
  26. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  27. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  28. package/dist/lib/node-esm/chunk-MS72BATS.mjs +81 -0
  29. package/dist/lib/node-esm/chunk-MS72BATS.mjs.map +7 -0
  30. package/dist/lib/node-esm/{chunk-ODMJ7DPA.mjs → chunk-NPIP4VEH.mjs} +6 -258
  31. package/dist/lib/node-esm/{chunk-ODMJ7DPA.mjs.map → chunk-NPIP4VEH.mjs.map} +3 -3
  32. package/dist/lib/node-esm/{chunk-PIAXA43R.mjs → chunk-UXZM5VJB.mjs} +8 -5
  33. package/dist/lib/node-esm/chunk-UXZM5VJB.mjs.map +7 -0
  34. package/dist/lib/node-esm/index.mjs +25 -18
  35. package/dist/lib/node-esm/index.mjs.map +3 -3
  36. package/dist/lib/node-esm/intent-resolver-VCEC67WX.mjs +32 -0
  37. package/dist/lib/node-esm/intent-resolver-VCEC67WX.mjs.map +7 -0
  38. package/dist/lib/node-esm/meta.json +1 -1
  39. package/dist/lib/node-esm/meta.mjs +2 -3
  40. package/dist/lib/node-esm/react-surface-4HFEX52O.mjs +36 -0
  41. package/dist/lib/node-esm/react-surface-4HFEX52O.mjs.map +7 -0
  42. package/dist/lib/node-esm/types/index.mjs +7 -6
  43. package/dist/types/src/ExplorerPlugin.d.ts +1 -1
  44. package/dist/types/src/ExplorerPlugin.d.ts.map +1 -1
  45. package/dist/types/src/capabilities/index.d.ts +1 -1
  46. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  47. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  48. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  49. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  50. package/dist/types/src/components/Chart/Chart.stories.d.ts +3 -1
  51. package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/ExplorerContainer.d.ts +2 -2
  53. package/dist/types/src/components/ExplorerContainer.d.ts.map +1 -1
  54. package/dist/types/src/components/Globe/Globe.stories.d.ts +3 -1
  55. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  56. package/dist/types/src/components/Graph/D3ForceGraph.d.ts +2 -2
  57. package/dist/types/src/components/Graph/D3ForceGraph.d.ts.map +1 -1
  58. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts +5 -10
  59. package/dist/types/src/components/Graph/D3ForceGraph.stories.d.ts.map +1 -1
  60. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +4 -2
  61. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  62. package/dist/types/src/components/Graph/testing.d.ts.map +1 -1
  63. package/dist/types/src/components/Tree/Tree.stories.d.ts +0 -1
  64. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Tree/types/tree.d.ts +1 -1
  66. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  67. package/dist/types/src/components/index.d.ts +2 -4
  68. package/dist/types/src/components/index.d.ts.map +1 -1
  69. package/dist/types/src/meta.d.ts +0 -1
  70. package/dist/types/src/meta.d.ts.map +1 -1
  71. package/dist/types/src/translations.d.ts +14 -2
  72. package/dist/types/src/translations.d.ts.map +1 -1
  73. package/dist/types/src/types/ExplorerAction.d.ts +23 -0
  74. package/dist/types/src/types/ExplorerAction.d.ts.map +1 -0
  75. package/dist/types/src/types/Graph.d.ts +33 -0
  76. package/dist/types/src/types/Graph.d.ts.map +1 -0
  77. package/dist/types/src/types/index.d.ts +2 -2
  78. package/dist/types/src/types/index.d.ts.map +1 -1
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +38 -36
  81. package/src/ExplorerPlugin.tsx +48 -46
  82. package/src/capabilities/intent-resolver.ts +10 -8
  83. package/src/capabilities/react-surface.tsx +9 -5
  84. package/src/components/Chart/Chart.stories.tsx +5 -4
  85. package/src/components/ExplorerContainer.tsx +22 -5
  86. package/src/components/Globe/Globe.stories.tsx +5 -4
  87. package/src/components/Graph/D3ForceGraph.stories.tsx +24 -13
  88. package/src/components/Graph/D3ForceGraph.tsx +4 -4
  89. package/src/components/Graph/ForceGraph.stories.tsx +24 -13
  90. package/src/components/Graph/ForceGraph.tsx +3 -3
  91. package/src/components/Graph/testing.ts +6 -6
  92. package/src/components/Tree/Tree.stories.tsx +2 -4
  93. package/src/components/Tree/Tree.tsx +2 -2
  94. package/src/components/Tree/types/tree.test.ts +2 -2
  95. package/src/components/Tree/types/tree.ts +1 -1
  96. package/src/components/index.ts +3 -3
  97. package/src/meta.ts +7 -4
  98. package/src/translations.ts +4 -2
  99. package/src/types/ExplorerAction.ts +30 -0
  100. package/src/types/Graph.ts +46 -0
  101. package/src/types/index.ts +2 -2
  102. package/dist/lib/browser/ExplorerContainer-7MTDS2TQ.mjs +0 -37
  103. package/dist/lib/browser/ExplorerContainer-7MTDS2TQ.mjs.map +0 -7
  104. package/dist/lib/browser/chunk-3YITRGGW.mjs.map +0 -7
  105. package/dist/lib/browser/chunk-CZZ3DDR7.mjs +0 -38
  106. package/dist/lib/browser/chunk-CZZ3DDR7.mjs.map +0 -7
  107. package/dist/lib/browser/chunk-UL5EDJPE.mjs +0 -21
  108. package/dist/lib/browser/chunk-UL5EDJPE.mjs.map +0 -7
  109. package/dist/lib/browser/intent-resolver-7MVEYNX7.mjs +0 -24
  110. package/dist/lib/browser/intent-resolver-7MVEYNX7.mjs.map +0 -7
  111. package/dist/lib/browser/react-surface-VLGQKYBI.mjs +0 -31
  112. package/dist/lib/browser/react-surface-VLGQKYBI.mjs.map +0 -7
  113. package/dist/lib/node-esm/ExplorerContainer-OBSRVHZZ.mjs.map +0 -7
  114. package/dist/lib/node-esm/chunk-4GWDNZ4Z.mjs +0 -39
  115. package/dist/lib/node-esm/chunk-4GWDNZ4Z.mjs.map +0 -7
  116. package/dist/lib/node-esm/chunk-GFYXDQQV.mjs.map +0 -7
  117. package/dist/lib/node-esm/chunk-PIAXA43R.mjs.map +0 -7
  118. package/dist/lib/node-esm/intent-resolver-NL3SR2XF.mjs +0 -25
  119. package/dist/lib/node-esm/intent-resolver-NL3SR2XF.mjs.map +0 -7
  120. package/dist/lib/node-esm/react-surface-BYJABDS5.mjs +0 -32
  121. package/dist/lib/node-esm/react-surface-BYJABDS5.mjs.map +0 -7
  122. package/dist/types/src/types/schema.d.ts +0 -12
  123. package/dist/types/src/types/schema.d.ts.map +0 -1
  124. package/dist/types/src/types/types.d.ts +0 -18
  125. package/dist/types/src/types/types.d.ts.map +0 -1
  126. package/src/types/schema.ts +0 -16
  127. 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.e098934",
3
+ "version": "0.8.4-main.e8ec1fe",
4
4
  "description": "Braneframe data visualization plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -47,57 +47,59 @@
47
47
  "3d-force-graph": "^1.76.1",
48
48
  "@observablehq/plot": "^0.6.11",
49
49
  "@preact-signals/safe-react": "^0.9.0",
50
- "@preact/signals-core": "^1.9.0",
50
+ "@preact/signals-core": "^1.12.1",
51
51
  "d3": "^7.9.0",
52
- "effect": "3.17.7",
52
+ "effect": "3.18.3",
53
53
  "force-graph": "^1.49.4",
54
54
  "lodash.defaultsdeep": "^4.6.1",
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.e098934",
59
- "@dxos/async": "0.8.4-main.e098934",
60
- "@dxos/echo": "0.8.4-main.e098934",
61
- "@dxos/echo-schema": "0.8.4-main.e098934",
62
- "@dxos/graph": "0.8.4-main.e098934",
63
- "@dxos/invariant": "0.8.4-main.e098934",
64
- "@dxos/live-object": "0.8.4-main.e098934",
65
- "@dxos/client": "0.8.4-main.e098934",
66
- "@dxos/log": "0.8.4-main.e098934",
67
- "@dxos/plugin-client": "0.8.4-main.e098934",
68
- "@dxos/plugin-graph": "0.8.4-main.e098934",
69
- "@dxos/plugin-search": "0.8.4-main.e098934",
70
- "@dxos/react-client": "0.8.4-main.e098934",
71
- "@dxos/react-ui-attention": "0.8.4-main.e098934",
72
- "@dxos/plugin-space": "0.8.4-main.e098934",
73
- "@dxos/react-ui-graph": "0.8.4-main.e098934",
74
- "@dxos/react-ui-stack": "0.8.4-main.e098934",
75
- "@dxos/schema": "0.8.4-main.e098934",
76
- "@dxos/util": "0.8.4-main.e098934"
58
+ "@dxos/app-framework": "0.8.4-main.e8ec1fe",
59
+ "@dxos/async": "0.8.4-main.e8ec1fe",
60
+ "@dxos/client": "0.8.4-main.e8ec1fe",
61
+ "@dxos/echo": "0.8.4-main.e8ec1fe",
62
+ "@dxos/graph": "0.8.4-main.e8ec1fe",
63
+ "@dxos/echo-query": "0.8.4-main.e8ec1fe",
64
+ "@dxos/log": "0.8.4-main.e8ec1fe",
65
+ "@dxos/invariant": "0.8.4-main.e8ec1fe",
66
+ "@dxos/plugin-client": "0.8.4-main.e8ec1fe",
67
+ "@dxos/live-object": "0.8.4-main.e8ec1fe",
68
+ "@dxos/plugin-search": "0.8.4-main.e8ec1fe",
69
+ "@dxos/react-client": "0.8.4-main.e8ec1fe",
70
+ "@dxos/plugin-graph": "0.8.4-main.e8ec1fe",
71
+ "@dxos/plugin-space": "0.8.4-main.e8ec1fe",
72
+ "@dxos/react-ui-components": "0.8.4-main.e8ec1fe",
73
+ "@dxos/react-ui-graph": "0.8.4-main.e8ec1fe",
74
+ "@dxos/react-ui-stack": "0.8.4-main.e8ec1fe",
75
+ "@dxos/schema": "0.8.4-main.e8ec1fe",
76
+ "@dxos/react-ui-attention": "0.8.4-main.e8ec1fe",
77
+ "@dxos/types": "0.8.4-main.e8ec1fe",
78
+ "@dxos/util": "0.8.4-main.e8ec1fe"
77
79
  },
78
80
  "devDependencies": {
79
81
  "@types/d3": "^7.4.3",
80
82
  "@types/d3-hierarchy": "^3.1.6",
81
83
  "@types/lodash.defaultsdeep": "^4.6.6",
82
- "@types/react": "~18.2.0",
83
- "@types/react-dom": "~18.2.0",
84
+ "@types/react": "~19.2.2",
85
+ "@types/react-dom": "~19.2.2",
84
86
  "@types/topojson-client": "^3.1.4",
85
87
  "@types/topojson-specification": "^1.0.5",
86
- "react": "~18.2.0",
87
- "react-dom": "~18.2.0",
88
- "vite": "7.1.1",
89
- "@dxos/echo-generator": "0.8.4-main.e098934",
90
- "@dxos/react-ui-theme": "0.8.4-main.e098934",
91
- "@dxos/storybook-utils": "0.8.4-main.e098934",
92
- "@dxos/random": "0.8.4-main.e098934",
93
- "@dxos/react-ui": "0.8.4-main.e098934"
88
+ "react": "~19.2.0",
89
+ "react-dom": "~19.2.0",
90
+ "vite": "7.1.9",
91
+ "@dxos/echo-generator": "0.8.4-main.e8ec1fe",
92
+ "@dxos/random": "0.8.4-main.e8ec1fe",
93
+ "@dxos/react-ui-theme": "0.8.4-main.e8ec1fe",
94
+ "@dxos/react-ui": "0.8.4-main.e8ec1fe",
95
+ "@dxos/storybook-utils": "0.8.4-main.e8ec1fe"
94
96
  },
95
97
  "peerDependencies": {
96
98
  "effect": "^3.13.3",
97
- "react": "~18.2.0",
98
- "react-dom": "~18.2.0",
99
- "@dxos/react-ui": "0.8.4-main.e098934",
100
- "@dxos/react-ui-theme": "0.8.4-main.e098934"
99
+ "react": "^19.0.0",
100
+ "react-dom": "^19.0.0",
101
+ "@dxos/react-ui": "0.8.4-main.e8ec1fe",
102
+ "@dxos/react-ui-theme": "0.8.4-main.e8ec1fe"
101
103
  },
102
104
  "publishConfig": {
103
105
  "access": "public"
@@ -10,51 +10,53 @@ import { defineObjectForm } from '@dxos/plugin-space/types';
10
10
  import { IntentResolver, ReactSurface } from './capabilities';
11
11
  import { meta } from './meta';
12
12
  import { translations } from './translations';
13
- import { ExplorerAction, ViewType } from './types';
13
+ import { ExplorerAction, Graph } from './types';
14
14
 
15
- export const ExplorerPlugin = () =>
16
- definePlugin(meta, [
17
- defineModule({
18
- id: `${meta.id}/module/translations`,
19
- activatesOn: Events.SetupTranslations,
20
- activate: () => contributes(Capabilities.Translations, translations),
21
- }),
22
- defineModule({
23
- id: `${meta.id}/module/metadata`,
24
- activatesOn: Events.SetupMetadata,
25
- activate: () =>
26
- contributes(Capabilities.Metadata, {
27
- id: ViewType.typename,
28
- metadata: {
29
- icon: 'ph--graph--regular',
30
- },
15
+ export const ExplorerPlugin = definePlugin(meta, () => [
16
+ defineModule({
17
+ id: `${meta.id}/module/translations`,
18
+ activatesOn: Events.SetupTranslations,
19
+ activate: () => contributes(Capabilities.Translations, translations),
20
+ }),
21
+ defineModule({
22
+ id: `${meta.id}/module/metadata`,
23
+ activatesOn: Events.SetupMetadata,
24
+ activate: () =>
25
+ contributes(Capabilities.Metadata, {
26
+ id: Graph.Graph.typename,
27
+ metadata: {
28
+ icon: 'ph--graph--regular',
29
+ iconHue: 'green',
30
+ },
31
+ }),
32
+ }),
33
+ defineModule({
34
+ id: `${meta.id}/module/object-form`,
35
+ activatesOn: ClientEvents.SetupSchema,
36
+ activate: () =>
37
+ contributes(
38
+ SpaceCapabilities.ObjectForm,
39
+ defineObjectForm({
40
+ objectSchema: Graph.Graph,
41
+ formSchema: ExplorerAction.GraphProps,
42
+ hidden: true,
43
+ getIntent: (props, options) => createIntent(ExplorerAction.CreateGraph, { ...props, space: options.space }),
31
44
  }),
32
- }),
33
- defineModule({
34
- id: `${meta.id}/module/object-form`,
35
- activatesOn: ClientEvents.SetupSchema,
36
- activate: () =>
37
- contributes(
38
- SpaceCapabilities.ObjectForm,
39
- defineObjectForm({
40
- objectSchema: ViewType,
41
- getIntent: () => createIntent(ExplorerAction.Create),
42
- }),
43
- ),
44
- }),
45
- defineModule({
46
- id: `${meta.id}/module/schema`,
47
- activatesOn: ClientEvents.SetupSchema,
48
- activate: () => contributes(ClientCapabilities.Schema, [ViewType]),
49
- }),
50
- defineModule({
51
- id: `${meta.id}/module/react-surface`,
52
- activatesOn: Events.SetupReactSurface,
53
- activate: ReactSurface,
54
- }),
55
- defineModule({
56
- id: `${meta.id}/module/intent-resolver`,
57
- activatesOn: Events.SetupIntentResolver,
58
- activate: IntentResolver,
59
- }),
60
- ]);
45
+ ),
46
+ }),
47
+ defineModule({
48
+ id: `${meta.id}/module/schema`,
49
+ activatesOn: ClientEvents.SetupSchema,
50
+ activate: () => contributes(ClientCapabilities.Schema, [Graph.Graph]),
51
+ }),
52
+ defineModule({
53
+ id: `${meta.id}/module/react-surface`,
54
+ activatesOn: Events.SetupReactSurface,
55
+ activate: ReactSurface,
56
+ }),
57
+ defineModule({
58
+ id: `${meta.id}/module/intent-resolver`,
59
+ activatesOn: Events.SetupIntentResolver,
60
+ activate: IntentResolver,
61
+ }),
62
+ ]);
@@ -2,18 +2,20 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, createResolver } from '@dxos/app-framework';
6
- import { Obj } from '@dxos/echo';
5
+ import { Capabilities, type PluginContext, contributes, createResolver } from '@dxos/app-framework';
6
+ import { ClientCapabilities } from '@dxos/plugin-client';
7
7
 
8
- import { ExplorerAction, ViewType } from '../types';
8
+ import { ExplorerAction, Graph } from '../types';
9
9
 
10
- export default () =>
10
+ export default (context: PluginContext) =>
11
11
  contributes(
12
12
  Capabilities.IntentResolver,
13
13
  createResolver({
14
- intent: ExplorerAction.Create,
15
- resolve: ({ name }) => ({
16
- data: { object: Obj.make(ViewType, { name, type: '' }) },
17
- }),
14
+ intent: ExplorerAction.CreateGraph,
15
+ resolve: async ({ space, name, typename }) => {
16
+ const client = context.getCapability(ClientCapabilities.Client);
17
+ const { view } = await Graph.makeView({ client, space, name, typename });
18
+ return { data: { object: view } };
19
+ },
18
20
  }),
19
21
  );
@@ -6,18 +6,22 @@ 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 { View } from '@dxos/schema';
9
10
 
10
11
  import { ExplorerContainer } from '../components';
11
- import { EXPLORER_PLUGIN } from '../meta';
12
- import { ViewType } from '../types';
12
+ import { meta } from '../meta';
13
+ import { Graph } from '../types';
13
14
 
14
15
  export default () =>
15
16
  contributes(
16
17
  Capabilities.ReactSurface,
17
18
  createSurface({
18
- id: `${EXPLORER_PLUGIN}/article`,
19
+ id: `${meta.id}/article`,
19
20
  role: ['article', 'section'],
20
- filter: (data): data is { subject: ViewType } => Obj.instanceOf(ViewType, data.subject),
21
- component: ({ data, role }) => <ExplorerContainer view={data.subject} role={role} />,
21
+ filter: (data): data is { subject: View.View } =>
22
+ Obj.instanceOf(View.View, data.subject) && Obj.instanceOf(Graph.Graph, data.subject.presentation.target),
23
+ component: ({ data, role }) => {
24
+ return <ExplorerContainer view={data.subject} role={role} />;
25
+ },
22
26
  }),
23
27
  );
@@ -2,13 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
8
  import { ClientRepeater } from '@dxos/react-client/testing';
11
- import { withLayout, withTheme } from '@dxos/storybook-utils';
9
+ import { withTheme } from '@dxos/react-ui/testing';
12
10
 
13
11
  import CitiesData from '../../../data/cities.js';
14
12
 
@@ -36,7 +34,10 @@ export const Default = () => <ClientRepeater component={Story} />;
36
34
  const meta = {
37
35
  title: 'plugins/plugin-explorer/Chart',
38
36
  component: Chart,
39
- decorators: [withTheme, withLayout({ fullscreen: true })],
37
+ decorators: [withTheme],
38
+ parameters: {
39
+ layout: 'fullscreen',
40
+ },
40
41
  } satisfies Meta<typeof Chart>;
41
42
 
42
43
  export default meta;
@@ -2,33 +2,50 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import React, { useCallback, useMemo, useState } from 'react';
6
6
 
7
+ import { type Filter } from '@dxos/echo';
8
+ import { QueryBuilder } from '@dxos/echo-query';
7
9
  import { useGlobalSearch } from '@dxos/plugin-search';
8
10
  import { getSpace } from '@dxos/react-client/echo';
11
+ import { Toolbar } from '@dxos/react-ui';
12
+ import { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';
9
13
  import { StackItem } from '@dxos/react-ui-stack';
14
+ import { type View } from '@dxos/schema';
10
15
 
11
16
  import { useGraphModel } from '../hooks';
12
- import { type ViewType } from '../types';
13
17
 
14
18
  import { D3ForceGraph } from './Graph';
15
19
 
16
20
  type ExplorerContainerProps = {
17
21
  role: string;
18
- view: ViewType;
22
+ view: View.View;
19
23
  };
20
24
 
21
25
  const ExplorerContainer = ({ role, view }: ExplorerContainerProps) => {
22
26
  const space = getSpace(view);
23
- const model = useGraphModel(space);
27
+ const [filter, setFilter] = useState<Filter.Any>();
28
+ const model = useGraphModel(space, filter);
24
29
  const { match } = useGlobalSearch();
25
30
 
31
+ const builder = useMemo(() => new QueryBuilder(), []);
32
+ const handleChange = useCallback<NonNullable<QueryEditorProps['onChange']>>((value) => {
33
+ setFilter(builder.build(value).filter);
34
+ }, []);
35
+
36
+ const showToolbar = role === 'article';
37
+
26
38
  if (!space || !model) {
27
39
  return null;
28
40
  }
29
41
 
30
42
  return (
31
- <StackItem.Content size={role === 'section' ? 'square' : 'intrinsic'}>
43
+ <StackItem.Content toolbar={showToolbar}>
44
+ {showToolbar && (
45
+ <Toolbar.Root>
46
+ <QueryEditor db={space.db} onChange={handleChange} />
47
+ </Toolbar.Root>
48
+ )}
32
49
  <D3ForceGraph model={model} match={match} />
33
50
  </StackItem.Content>
34
51
  );
@@ -2,8 +2,6 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { dot, geo, graticule, plot, sphere } from '@observablehq/plot';
8
6
  import { type Meta } from '@storybook/react-vite';
9
7
  import { geoCircle } from 'd3';
@@ -12,7 +10,7 @@ import { useResizeDetector } from 'react-resize-detector';
12
10
  import { feature } from 'topojson-client';
13
11
 
14
12
  import { ClientRepeater } from '@dxos/react-client/testing';
15
- import { withLayout, withTheme } from '@dxos/storybook-utils';
13
+ import { withTheme } from '@dxos/react-ui/testing';
16
14
 
17
15
  import CitiesData from '../../../data/cities.js';
18
16
  import CountriesData from '../../../data/countries-110m.js';
@@ -83,7 +81,10 @@ const ExtendedStory = () => {
83
81
 
84
82
  const meta = {
85
83
  title: 'plugins/plugin-explorer/Globe',
86
- decorators: [withTheme, withLayout({ fullscreen: true })],
84
+ decorators: [withTheme],
85
+ parameters: {
86
+ layout: 'fullscreen',
87
+ },
87
88
  } satisfies Meta;
88
89
 
89
90
  export default meta;
@@ -2,22 +2,22 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React, { useEffect, useState } from 'react';
6
+ import React, { useState } from 'react';
9
7
 
10
- import { Obj } from '@dxos/echo';
11
8
  import { faker } from '@dxos/random';
12
9
  import { useClient } from '@dxos/react-client';
13
10
  import { type Space } from '@dxos/react-client/echo';
14
11
  import { withClientProvider } from '@dxos/react-client/testing';
15
- import { DataType } from '@dxos/schema';
12
+ import { useAsyncEffect } from '@dxos/react-ui';
13
+ import { withTheme } from '@dxos/react-ui/testing';
14
+ import { View } from '@dxos/schema';
16
15
  import { type ValueGenerator } from '@dxos/schema/testing';
17
- import { render, withLayout, withTheme } from '@dxos/storybook-utils';
16
+ import { render } from '@dxos/storybook-utils';
17
+ import { HasRelationship, Organization, Person, Project } from '@dxos/types';
18
18
 
19
19
  import { useGraphModel } from '../../hooks';
20
- import { ViewType } from '../../types';
20
+ import { Graph } from '../../types';
21
21
 
22
22
  import { D3ForceGraph } from './D3ForceGraph';
23
23
  import { generate } from './testing';
@@ -29,11 +29,13 @@ faker.seed(1);
29
29
  const DefaultStory = () => {
30
30
  const client = useClient();
31
31
  const [space, setSpace] = useState<Space>();
32
- const [view, setView] = useState<ViewType>();
33
- useEffect(() => {
32
+ const [view, setView] = useState<View.View>();
33
+
34
+ useAsyncEffect(async () => {
34
35
  const space = client.spaces.default;
35
36
  void generate(space, generator);
36
- const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
37
+ const { view } = await Graph.makeView({ client, space, name: 'Test', typename: Graph.Graph.typename });
38
+ space.db.add(view);
37
39
  setSpace(space);
38
40
  setView(view);
39
41
  }, []);
@@ -51,13 +53,22 @@ const meta = {
51
53
  component: D3ForceGraph,
52
54
  render: render(DefaultStory),
53
55
  decorators: [
56
+ withTheme,
54
57
  withClientProvider({
55
58
  createSpace: true,
56
- types: [ViewType, DataType.Organization, DataType.Project, DataType.Person, DataType.HasRelationship],
59
+ types: [
60
+ Graph.Graph,
61
+ View.View,
62
+ Organization.Organization,
63
+ Project.Project,
64
+ Person.Person,
65
+ HasRelationship.HasRelationship,
66
+ ],
57
67
  }),
58
- withTheme,
59
- withLayout({ fullscreen: true }),
60
68
  ],
69
+ parameters: {
70
+ layout: 'fullscreen',
71
+ },
61
72
  } satisfies Meta<typeof D3ForceGraph>;
62
73
 
63
74
  export default meta;
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';
5
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
6
6
 
7
7
  import { Obj } from '@dxos/echo';
8
8
  import { SelectionModel } from '@dxos/graph';
@@ -15,7 +15,7 @@ import {
15
15
  SVG,
16
16
  type SVGContext,
17
17
  } from '@dxos/react-ui-graph';
18
- import { getHashColor } from '@dxos/react-ui-theme';
18
+ import { getHashStyles } from '@dxos/react-ui-theme';
19
19
  import { type SpaceGraphEdge, type SpaceGraphModel, type SpaceGraphNode } from '@dxos/schema';
20
20
 
21
21
  import '@dxos/react-ui-graph/styles/graph.css';
@@ -29,7 +29,7 @@ export type D3ForceGraphProps = ThemedClassName<
29
29
  } & Pick<GraphProps, 'drag'>
30
30
  >;
31
31
 
32
- export const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selection: _selection, grid, ...props }) => {
32
+ export const D3ForceGraph = ({ classNames, model, selection: _selection, grid, ...props }: D3ForceGraphProps) => {
33
33
  const context = useRef<SVGContext>(null);
34
34
  const projector = useMemo<GraphForceProjector | undefined>(() => {
35
35
  if (context.current) {
@@ -85,7 +85,7 @@ export const D3ForceGraph: FC<D3ForceGraphProps> = ({ classNames, model, selecti
85
85
  const obj = node.data?.data.object;
86
86
  return {
87
87
  data: {
88
- color: getHashColor(obj && Obj.getTypename(obj))?.color,
88
+ color: getHashStyles(obj && Obj.getTypename(obj))?.hue,
89
89
  },
90
90
  classes: {
91
91
  'dx-selected': selection.contains(node.id),
@@ -2,22 +2,22 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React, { useEffect, useState } from 'react';
6
+ import React, { useState } from 'react';
9
7
 
10
- import { Obj } from '@dxos/echo';
11
8
  import { faker } from '@dxos/random';
12
9
  import { useClient } from '@dxos/react-client';
13
10
  import { type Space } from '@dxos/react-client/echo';
14
11
  import { withClientProvider } from '@dxos/react-client/testing';
15
- import { DataType } from '@dxos/schema';
12
+ import { useAsyncEffect } from '@dxos/react-ui';
13
+ import { withTheme } from '@dxos/react-ui/testing';
14
+ import { View } from '@dxos/schema';
16
15
  import { type ValueGenerator } from '@dxos/schema/testing';
17
- import { render, withLayout, withTheme } from '@dxos/storybook-utils';
16
+ import { render } from '@dxos/storybook-utils';
17
+ import { HasRelationship, Organization, Person, Project } from '@dxos/types';
18
18
 
19
19
  import { useGraphModel } from '../../hooks';
20
- import { ViewType } from '../../types';
20
+ import { Graph } from '../../types';
21
21
 
22
22
  import { ForceGraph } from './ForceGraph';
23
23
  import { generate } from './testing';
@@ -29,11 +29,13 @@ faker.seed(1);
29
29
  const DefaultStory = () => {
30
30
  const client = useClient();
31
31
  const [space, setSpace] = useState<Space>();
32
- const [view, setView] = useState<ViewType>();
33
- useEffect(() => {
32
+ const [view, setView] = useState<View.View>();
33
+
34
+ useAsyncEffect(async () => {
34
35
  const space = client.spaces.default;
35
36
  void generate(space, generator);
36
- const view = space.db.add(Obj.make(ViewType, { name: '', type: '' }));
37
+ const { view } = await Graph.makeView({ client, space, name: 'Test', typename: Graph.Graph.typename });
38
+ space.db.add(view);
37
39
  setSpace(space);
38
40
  setView(view);
39
41
  }, []);
@@ -51,13 +53,22 @@ const meta = {
51
53
  component: ForceGraph,
52
54
  render: render(DefaultStory),
53
55
  decorators: [
56
+ withTheme,
54
57
  withClientProvider({
55
58
  createSpace: true,
56
- types: [ViewType, DataType.HasRelationship, DataType.Organization, DataType.Project, DataType.Person],
59
+ types: [
60
+ Graph.Graph,
61
+ View.View,
62
+ HasRelationship.HasRelationship,
63
+ Organization.Organization,
64
+ Project.Project,
65
+ Person.Person,
66
+ ],
57
67
  }),
58
- withTheme,
59
- withLayout({ fullscreen: true }),
60
68
  ],
69
+ parameters: {
70
+ layout: 'fullscreen',
71
+ },
61
72
  } satisfies Meta<typeof ForceGraph>;
62
73
 
63
74
  export default meta;
@@ -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 = undefined;
51
+ forceGraph.current = null;
52
52
  };
53
53
  }, []);
54
54
 
@@ -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: DataType.Organization, count: 5 },
15
- { type: DataType.Project, count: 5 },
16
- { type: DataType.Person, count: 10 },
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(DataType.Person)).run();
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(DataType.HasRelationship, {
47
+ Relation.make(HasRelationship.HasRelationship, {
48
48
  [Relation.Source]: source,
49
49
  [Relation.Target]: target,
50
50
  kind: relations.kind,
@@ -2,15 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
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 { withLayout, withTheme } from '@dxos/storybook-utils';
11
+ import { withTheme } from '@dxos/react-ui/testing';
14
12
 
15
13
  import { Tree, type TreeComponentProps } from './Tree';
16
14
  import { Tree as TreeModel, TreeType } from './types';
@@ -48,7 +46,7 @@ const meta = {
48
46
  title: 'plugins/plugin-explorer/Tree',
49
47
  component: Tree as any,
50
48
  render: DefaultStory,
51
- decorators: [withTheme, withLayout({ fullscreen: true })],
49
+ decorators: [withTheme],
52
50
  parameters: {
53
51
  layout: 'fullscreen',
54
52
  },
@@ -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 = {