@dxos/plugin-space 0.8.4-main.72ec0f3 → 0.8.4-main.7ace549
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/{ObjectDetailsPanel-2BRUBHP6.mjs → ObjectDetailsPanel-ACGHWPDX.mjs} +2 -2
- package/dist/lib/browser/{ObjectDetailsPanel-2BRUBHP6.mjs.map → ObjectDetailsPanel-ACGHWPDX.mjs.map} +3 -3
- package/dist/lib/browser/{ObjectSettings-5LLWCVEK.mjs → ObjectSettings-U3IH7BMV.mjs} +2 -2
- package/dist/lib/browser/{ObjectSettings-5LLWCVEK.mjs.map → ObjectSettings-U3IH7BMV.mjs.map} +3 -3
- package/dist/lib/browser/{RecordArticle-SXDRWTTU.mjs → RecordArticle-2PFEBPXY.mjs} +1 -1
- package/dist/lib/browser/RecordArticle-2PFEBPXY.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-builder-VQAB3GCQ.mjs → app-graph-builder-HABMCWAI.mjs} +140 -151
- package/dist/lib/browser/app-graph-builder-HABMCWAI.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-serializer-KSLKMEPP.mjs → app-graph-serializer-G3VFEGTN.mjs} +4 -4
- package/dist/lib/browser/chunk-6A3NWBB6.mjs +392 -0
- package/dist/lib/browser/chunk-6A3NWBB6.mjs.map +7 -0
- package/dist/lib/browser/{chunk-K5J7ZB5P.mjs → chunk-C6DAPIFF.mjs} +3 -3
- package/dist/lib/browser/chunk-C6DAPIFF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ERQMHU7L.mjs → chunk-GJOZILGC.mjs} +163 -105
- package/dist/lib/browser/chunk-GJOZILGC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-J2BUK5E6.mjs → chunk-KCZ527AM.mjs} +169 -101
- package/dist/lib/browser/chunk-KCZ527AM.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PU5IOFMG.mjs → chunk-P25R3AOK.mjs} +4 -47
- package/dist/lib/browser/{chunk-PU5IOFMG.mjs.map → chunk-P25R3AOK.mjs.map} +4 -4
- package/dist/lib/browser/{chunk-OLBBSOVI.mjs → chunk-POFUXISV.mjs} +53 -59
- package/dist/lib/browser/chunk-POFUXISV.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +47 -94
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-Q2XWHAVA.mjs → intent-resolver-RZEWNJ2K.mjs} +51 -40
- package/dist/lib/browser/intent-resolver-RZEWNJ2K.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-MM4HADPE.mjs → react-root-JCRD74GI.mjs} +6 -6
- package/dist/lib/browser/{react-surface-SGZC3Y4U.mjs → react-surface-VOETEAG3.mjs} +28 -14
- package/dist/lib/browser/react-surface-VOETEAG3.mjs.map +7 -0
- package/dist/lib/browser/repair-CNLE35NF.mjs +44 -0
- package/dist/lib/browser/repair-CNLE35NF.mjs.map +7 -0
- package/dist/lib/browser/{settings-WKLGKUHQ.mjs → settings-TRLI52I5.mjs} +2 -2
- package/dist/lib/browser/{spaces-ready-C5QC2UFL.mjs → spaces-ready-OHGCWZHQ.mjs} +13 -7
- package/dist/lib/browser/{spaces-ready-C5QC2UFL.mjs.map → spaces-ready-OHGCWZHQ.mjs.map} +2 -2
- package/dist/lib/browser/{state-Q7YRE5KG.mjs → state-C7N6EDDZ.mjs} +2 -2
- package/dist/lib/browser/types/index.mjs +9 -3
- package/dist/lib/node-esm/{ObjectDetailsPanel-6PZQIQG3.mjs → ObjectDetailsPanel-6OFTT3GG.mjs} +2 -2
- package/dist/lib/node-esm/{ObjectDetailsPanel-6PZQIQG3.mjs.map → ObjectDetailsPanel-6OFTT3GG.mjs.map} +3 -3
- package/dist/lib/node-esm/{ObjectSettings-OQSBOH7K.mjs → ObjectSettings-YXPJQMJ5.mjs} +2 -2
- package/dist/lib/node-esm/{ObjectSettings-OQSBOH7K.mjs.map → ObjectSettings-YXPJQMJ5.mjs.map} +3 -3
- package/dist/lib/node-esm/{RecordArticle-NACBH42P.mjs → RecordArticle-SSJ7PULS.mjs} +1 -1
- package/dist/lib/node-esm/RecordArticle-SSJ7PULS.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-builder-24JCLJPX.mjs → app-graph-builder-T6VJKIOA.mjs} +140 -151
- package/dist/lib/node-esm/app-graph-builder-T6VJKIOA.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-serializer-R723K764.mjs → app-graph-serializer-2NLWWFUB.mjs} +4 -4
- package/dist/lib/node-esm/{chunk-TJPQDQNI.mjs → chunk-7EV4SN47.mjs} +4 -47
- package/dist/lib/node-esm/{chunk-TJPQDQNI.mjs.map → chunk-7EV4SN47.mjs.map} +4 -4
- package/dist/lib/node-esm/{chunk-WC4VBFMA.mjs → chunk-AX3UGL5D.mjs} +53 -59
- package/dist/lib/node-esm/chunk-AX3UGL5D.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-VH2EBZEV.mjs → chunk-I6FZP42D.mjs} +163 -105
- package/dist/lib/node-esm/chunk-I6FZP42D.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ITQFSFQ3.mjs → chunk-JAMGJUFU.mjs} +169 -101
- package/dist/lib/node-esm/chunk-JAMGJUFU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Z7BB6HC2.mjs → chunk-WWGV5FJM.mjs} +3 -3
- package/dist/lib/node-esm/chunk-WWGV5FJM.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-X34VDVMY.mjs +393 -0
- package/dist/lib/node-esm/chunk-X34VDVMY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +47 -94
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-YK4ESSET.mjs → intent-resolver-4PHJWDXW.mjs} +51 -40
- package/dist/lib/node-esm/intent-resolver-4PHJWDXW.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-root-5ANDLQMX.mjs → react-root-O5I5CDJ7.mjs} +6 -6
- package/dist/lib/node-esm/{react-surface-V7J2QB44.mjs → react-surface-J3XDMU2D.mjs} +28 -14
- package/dist/lib/node-esm/react-surface-J3XDMU2D.mjs.map +7 -0
- package/dist/lib/node-esm/repair-EHZS6MFY.mjs +45 -0
- package/dist/lib/node-esm/repair-EHZS6MFY.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-RBB5633M.mjs → settings-MNQTKHL7.mjs} +2 -2
- package/dist/lib/node-esm/{spaces-ready-SJCXV6YH.mjs → spaces-ready-ZPU24DA2.mjs} +13 -7
- package/dist/lib/node-esm/{spaces-ready-SJCXV6YH.mjs.map → spaces-ready-ZPU24DA2.mjs.map} +2 -2
- package/dist/lib/node-esm/{state-362I5BMK.mjs → state-45TXZQJ6.mjs} +2 -2
- package/dist/lib/node-esm/types/index.mjs +9 -3
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +9 -4
- package/dist/types/src/capabilities/capabilities.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.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/repair.d.ts +4 -0
- package/dist/types/src/capabilities/repair.d.ts.map +1 -0
- package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts +147 -253
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +14 -7
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
- package/dist/types/src/components/MembersContainer/MembersContainer.stories.d.ts +147 -253
- package/dist/types/src/components/MembersContainer/MembersContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectSettings/AdvancedObjectSettings.d.ts.map +1 -1
- package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts +147 -253
- package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts +3 -3
- package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts.map +1 -1
- package/dist/types/src/components/RecordArticle.stories.d.ts +147 -253
- package/dist/types/src/components/RecordArticle.stories.d.ts.map +1 -1
- package/dist/types/src/components/SchemaContainer.d.ts +1 -1
- package/dist/types/src/components/SchemaContainer.d.ts.map +1 -1
- package/dist/types/src/components/SpacePresence/SpacePresence.d.ts +2 -2
- package/dist/types/src/components/SpacePresence/SpacePresence.d.ts.map +1 -1
- package/dist/types/src/components/SpacePresence/SpacePresence.stories.d.ts +147 -253
- package/dist/types/src/components/SpacePresence/SpacePresence.stories.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts +147 -253
- package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +147 -253
- package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/helpers/query.d.ts +1 -1
- package/dist/types/src/helpers/query.d.ts.map +1 -1
- package/dist/types/src/hooks/useTypeOptions.d.ts +2 -2
- package/dist/types/src/hooks/useTypeOptions.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +147 -253
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/form.d.ts +24 -0
- package/dist/types/src/types/form.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +29 -72
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +16 -32
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +54 -50
- package/src/SpacePlugin.ts +34 -84
- package/src/capabilities/app-graph-builder.ts +130 -227
- package/src/capabilities/capabilities.ts +10 -5
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/intent-resolver.ts +31 -35
- package/src/capabilities/react-surface.tsx +34 -8
- package/src/capabilities/repair.ts +57 -0
- package/src/capabilities/spaces-ready.ts +7 -1
- package/src/components/CreateDialog/CreateObjectDialog.tsx +33 -23
- package/src/components/CreateDialog/CreateObjectPanel.tsx +32 -25
- package/src/components/ObjectDetailsPanel/ObjectForm.tsx +1 -1
- package/src/components/ObjectSettings/AdvancedObjectSettings.tsx +4 -5
- package/src/components/ObjectSettings/BaseObjectSettings.tsx +1 -1
- package/src/components/ObjectSettings/ForeignKeys.tsx +5 -5
- package/src/components/RecordArticle.tsx +6 -6
- package/src/components/SchemaContainer.tsx +2 -2
- package/src/components/SpacePresence/SpacePresence.tsx +2 -2
- package/src/components/SpaceSettings/SpaceSettingsContainer.tsx +25 -6
- package/src/components/ViewEditor.tsx +9 -3
- package/src/helpers/query.ts +1 -1
- package/src/hooks/useTypeOptions.ts +3 -35
- package/src/translations.ts +52 -57
- package/src/types/form.ts +75 -0
- package/src/types/index.ts +1 -0
- package/src/types/types.ts +26 -36
- package/src/util.tsx +165 -107
- package/dist/lib/browser/RecordArticle-SXDRWTTU.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-VQAB3GCQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-ERQMHU7L.mjs.map +0 -7
- package/dist/lib/browser/chunk-J2BUK5E6.mjs.map +0 -7
- package/dist/lib/browser/chunk-K5J7ZB5P.mjs.map +0 -7
- package/dist/lib/browser/chunk-M2Z6D4ZI.mjs +0 -349
- package/dist/lib/browser/chunk-M2Z6D4ZI.mjs.map +0 -7
- package/dist/lib/browser/chunk-OLBBSOVI.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-Q2XWHAVA.mjs.map +0 -7
- package/dist/lib/browser/react-surface-SGZC3Y4U.mjs.map +0 -7
- package/dist/lib/browser/schema-defs-QPI2JU3X.mjs +0 -26
- package/dist/lib/browser/schema-defs-QPI2JU3X.mjs.map +0 -7
- package/dist/lib/node-esm/RecordArticle-NACBH42P.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-24JCLJPX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2PN7QNGV.mjs +0 -350
- package/dist/lib/node-esm/chunk-2PN7QNGV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ITQFSFQ3.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-VH2EBZEV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WC4VBFMA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Z7BB6HC2.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-YK4ESSET.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-V7J2QB44.mjs.map +0 -7
- package/dist/lib/node-esm/schema-defs-ZS2D47XW.mjs +0 -27
- package/dist/lib/node-esm/schema-defs-ZS2D47XW.mjs.map +0 -7
- package/dist/types/src/capabilities/schema-defs.d.ts +0 -4
- package/dist/types/src/capabilities/schema-defs.d.ts.map +0 -1
- package/src/capabilities/schema-defs.ts +0 -31
- /package/dist/lib/browser/{app-graph-serializer-KSLKMEPP.mjs.map → app-graph-serializer-G3VFEGTN.mjs.map} +0 -0
- /package/dist/lib/browser/{react-root-MM4HADPE.mjs.map → react-root-JCRD74GI.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-WKLGKUHQ.mjs.map → settings-TRLI52I5.mjs.map} +0 -0
- /package/dist/lib/browser/{state-Q7YRE5KG.mjs.map → state-C7N6EDDZ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{app-graph-serializer-R723K764.mjs.map → app-graph-serializer-2NLWWFUB.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-root-5ANDLQMX.mjs.map → react-root-O5I5CDJ7.mjs.map} +0 -0
- /package/dist/lib/node-esm/{settings-RBB5633M.mjs.map → settings-MNQTKHL7.mjs.map} +0 -0
- /package/dist/lib/node-esm/{state-362I5BMK.mjs.map → state-45TXZQJ6.mjs.map} +0 -0
|
@@ -6,13 +6,15 @@ import * as Effect from 'effect/Effect';
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
Capabilities,
|
|
9
|
+
type Label,
|
|
9
10
|
LayoutAction,
|
|
10
11
|
type PluginContext,
|
|
11
12
|
contributes,
|
|
12
13
|
createIntent,
|
|
13
14
|
createResolver,
|
|
14
15
|
} from '@dxos/app-framework';
|
|
15
|
-
import {
|
|
16
|
+
import { Obj, Query, Ref, Relation, Type } from '@dxos/echo';
|
|
17
|
+
import { Serializer } from '@dxos/echo-db';
|
|
16
18
|
import { DatabaseService } from '@dxos/functions';
|
|
17
19
|
import { invariant } from '@dxos/invariant';
|
|
18
20
|
import { Migrations } from '@dxos/migrations';
|
|
@@ -24,7 +26,7 @@ import { Invitation, InvitationEncoder } from '@dxos/react-client/invitations';
|
|
|
24
26
|
import { ATTENDABLE_PATH_SEPARATOR } from '@dxos/react-ui-attention';
|
|
25
27
|
import { iconValues } from '@dxos/react-ui-pickers';
|
|
26
28
|
import { hues } from '@dxos/react-ui-theme';
|
|
27
|
-
import { Collection, ProjectionModel,
|
|
29
|
+
import { Collection, ProjectionModel, getTypenameFromQuery } from '@dxos/schema';
|
|
28
30
|
|
|
29
31
|
import {
|
|
30
32
|
CREATE_OBJECT_DIALOG,
|
|
@@ -43,7 +45,7 @@ import { COMPOSER_SPACE_LOCK, cloneObject, getNestedObjects } from '../util';
|
|
|
43
45
|
import { SpaceCapabilities } from './capabilities';
|
|
44
46
|
|
|
45
47
|
// TODO(wittjosiah): Remove.
|
|
46
|
-
const SPACE_MAX_OBJECTS =
|
|
48
|
+
const SPACE_MAX_OBJECTS = 750;
|
|
47
49
|
|
|
48
50
|
type IntentResolverOptions = {
|
|
49
51
|
context: PluginContext;
|
|
@@ -92,20 +94,13 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
// Create records smart collection.
|
|
95
|
-
collection.objects.push(
|
|
96
|
-
Ref.make(
|
|
97
|
-
Obj.make(Collection.QueryCollection, {
|
|
98
|
-
// NOTE: This is specifically Filter.typename due to current limitations in query collection parsing.
|
|
99
|
-
query: Query.select(Filter.typename(StoredSchema.typename)).ast,
|
|
100
|
-
}),
|
|
101
|
-
),
|
|
102
|
-
);
|
|
97
|
+
collection.objects.push(Ref.make(Collection.makeManaged({ key: Type.getTypename(Type.PersistentType) })));
|
|
103
98
|
|
|
104
99
|
// Allow other plugins to add default content.
|
|
105
100
|
await context.activatePromise(SpaceEvents.SpaceCreated);
|
|
106
|
-
const onCreateSpaceCallbacks = context.getCapabilities(SpaceCapabilities.
|
|
101
|
+
const onCreateSpaceCallbacks = context.getCapabilities(SpaceCapabilities.OnCreateSpace);
|
|
107
102
|
const spaceCreatedIntents = onCreateSpaceCallbacks.map((onCreateSpace) =>
|
|
108
|
-
onCreateSpace({ space, rootCollection: collection }),
|
|
103
|
+
onCreateSpace({ space, isDefault: false, rootCollection: collection }),
|
|
109
104
|
);
|
|
110
105
|
|
|
111
106
|
return {
|
|
@@ -330,6 +325,17 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
330
325
|
};
|
|
331
326
|
},
|
|
332
327
|
}),
|
|
328
|
+
createResolver({
|
|
329
|
+
intent: SpaceAction.Snapshot,
|
|
330
|
+
resolve: async ({ space, query }) => {
|
|
331
|
+
const backup = await new Serializer().export(space.db, query && Query.fromAst(query));
|
|
332
|
+
return {
|
|
333
|
+
data: {
|
|
334
|
+
snapshot: new Blob([JSON.stringify(backup, null, 2)], { type: 'application/json' }),
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
},
|
|
338
|
+
}),
|
|
333
339
|
createResolver({
|
|
334
340
|
intent: SpaceAction.UseStaticSchema,
|
|
335
341
|
resolve: async ({ space, typename, show }) => {
|
|
@@ -455,8 +461,8 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
455
461
|
shouldNavigate: navigable
|
|
456
462
|
? (object: Obj.Any) => {
|
|
457
463
|
const isCollection = Obj.instanceOf(Collection.Collection, object);
|
|
458
|
-
const
|
|
459
|
-
return (!isCollection && !
|
|
464
|
+
const isSystemCollection = Obj.instanceOf(Collection.Managed, object);
|
|
465
|
+
return (!isCollection && !isSystemCollection) || state.navigableCollections;
|
|
460
466
|
}
|
|
461
467
|
: () => false,
|
|
462
468
|
} satisfies Partial<CreateObjectDialogProps>,
|
|
@@ -598,16 +604,17 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
598
604
|
});
|
|
599
605
|
objects.forEach((obj) => space.db.remove(obj));
|
|
600
606
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
607
|
+
// TODO(wittjosiah): Once we can compose translations outside of react, use count instead.
|
|
608
|
+
// ['deleted label', { ns: meta.id, typename: ['typename label', { ns: typename, count: objects.length }] }]
|
|
609
|
+
const undoMessageLabel: Label =
|
|
610
|
+
objects.length === 1
|
|
611
|
+
? ['object deleted label', { ns: Obj.getTypename(objects[0]) ?? meta.id, defaultValue: 'Object deleted' }]
|
|
612
|
+
: ['objects deleted label', { ns: meta.id }];
|
|
606
613
|
|
|
607
614
|
return {
|
|
608
615
|
undoable: {
|
|
609
616
|
// TODO(ZaymonFC): Pluralize if more than one object.
|
|
610
|
-
message:
|
|
617
|
+
message: undoMessageLabel,
|
|
611
618
|
data: { deletionData },
|
|
612
619
|
},
|
|
613
620
|
intents:
|
|
@@ -628,16 +635,16 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
628
635
|
Obj.instanceOf(Collection.Collection, deletionData.parentCollection)
|
|
629
636
|
) {
|
|
630
637
|
// Restore the object to the space.
|
|
631
|
-
const restoredObjects = deletionData.objects.map((obj:
|
|
638
|
+
const restoredObjects = deletionData.objects.map((obj: Obj.Any) => space.db.add(obj));
|
|
632
639
|
|
|
633
640
|
// Restore nested objects to the space.
|
|
634
|
-
deletionData.nestedObjectsList.flat().forEach((obj:
|
|
641
|
+
deletionData.nestedObjectsList.flat().forEach((obj: Obj.Any) => {
|
|
635
642
|
space.db.add(obj);
|
|
636
643
|
});
|
|
637
644
|
|
|
638
645
|
deletionData.indices.forEach((index: number, i: number) => {
|
|
639
646
|
if (index !== -1) {
|
|
640
|
-
deletionData.parentCollection.objects.splice(index, 0, Ref.make(restoredObjects[i] as
|
|
647
|
+
deletionData.parentCollection.objects.splice(index, 0, Ref.make(restoredObjects[i] as Obj.Any));
|
|
641
648
|
}
|
|
642
649
|
});
|
|
643
650
|
|
|
@@ -695,16 +702,5 @@ export default ({ context, observability, createInvitationUrl }: IntentResolverO
|
|
|
695
702
|
data: { object: Obj.make(Collection.Collection, { name, objects: [] }) },
|
|
696
703
|
}),
|
|
697
704
|
}),
|
|
698
|
-
createResolver({
|
|
699
|
-
intent: CollectionAction.CreateQueryCollection,
|
|
700
|
-
resolve: async ({ name, typename }) => ({
|
|
701
|
-
data: {
|
|
702
|
-
object: Obj.make(Collection.QueryCollection, {
|
|
703
|
-
name,
|
|
704
|
-
query: Query.select(Filter.typename(typename)).ast,
|
|
705
|
-
}),
|
|
706
|
-
},
|
|
707
|
-
}),
|
|
708
|
-
}),
|
|
709
705
|
]);
|
|
710
706
|
};
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Option from 'effect/Option';
|
|
5
6
|
import type * as Schema from 'effect/Schema';
|
|
6
7
|
import React, { useCallback } from 'react';
|
|
7
8
|
|
|
8
9
|
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
9
10
|
import { Surface, useCapability, useLayout } from '@dxos/app-framework/react';
|
|
10
|
-
import { Obj } from '@dxos/echo';
|
|
11
|
+
import { Obj, type Ref } from '@dxos/echo';
|
|
11
12
|
import { findAnnotation } from '@dxos/effect';
|
|
12
13
|
import { SettingsStore } from '@dxos/local-storage';
|
|
13
14
|
import { type Space, SpaceState, getSpace, isLiveObject, isSpace, parseId, useSpace } from '@dxos/react-client/echo';
|
|
14
15
|
import { Input } from '@dxos/react-ui';
|
|
15
16
|
import { type InputProps, SelectInput } from '@dxos/react-ui-form';
|
|
16
17
|
import { HuePicker, IconPicker } from '@dxos/react-ui-pickers';
|
|
17
|
-
import { Collection,
|
|
18
|
+
import { Collection, View, ViewAnnotation } from '@dxos/schema';
|
|
18
19
|
import { type JoinPanelProps } from '@dxos/shell/react';
|
|
19
20
|
|
|
20
21
|
// TODO(burdon): Component name standard: NounVerbComponent.
|
|
@@ -48,7 +49,13 @@ import {
|
|
|
48
49
|
} from '../components';
|
|
49
50
|
import { useTypeOptions } from '../hooks';
|
|
50
51
|
import { meta } from '../meta';
|
|
51
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
HueAnnotationId,
|
|
54
|
+
IconAnnotationId,
|
|
55
|
+
type SpaceSettingsProps,
|
|
56
|
+
type TypeInputOptions,
|
|
57
|
+
TypeInputOptionsAnnotationId,
|
|
58
|
+
} from '../types';
|
|
52
59
|
|
|
53
60
|
import { SpaceCapabilities } from './capabilities';
|
|
54
61
|
|
|
@@ -224,20 +231,22 @@ export default ({ createInvitationUrl }: ReactSurfaceOptions) =>
|
|
|
224
231
|
data,
|
|
225
232
|
): data is {
|
|
226
233
|
prop: string;
|
|
227
|
-
schema: Schema.Schema
|
|
234
|
+
schema: Schema.Schema.Any;
|
|
228
235
|
target: Space | Collection.Collection | undefined;
|
|
229
236
|
} => {
|
|
230
237
|
if (data.prop !== 'typename') {
|
|
231
238
|
return false;
|
|
232
239
|
}
|
|
233
240
|
|
|
234
|
-
|
|
241
|
+
// TODO(wittjosiah): This doesn't work here.
|
|
242
|
+
// const annotation = TypeInputOptionsAnnotation.get(data.schema as Schema.Schema.Any);
|
|
243
|
+
const annotation = findAnnotation((data.schema as Schema.Schema.All).ast, TypeInputOptionsAnnotationId);
|
|
235
244
|
return !!annotation;
|
|
236
245
|
},
|
|
237
246
|
component: ({ data: { schema, target }, ...inputProps }) => {
|
|
238
247
|
const props = inputProps as any as InputProps;
|
|
239
248
|
const space = isSpace(target) ? target : getSpace(target);
|
|
240
|
-
const annotation = findAnnotation<
|
|
249
|
+
const annotation = findAnnotation<TypeInputOptions>(schema.ast, TypeInputOptionsAnnotationId)!;
|
|
241
250
|
const options = useTypeOptions({ space, annotation });
|
|
242
251
|
|
|
243
252
|
return <SelectInput {...props} options={options} />;
|
|
@@ -246,8 +255,25 @@ export default ({ createInvitationUrl }: ReactSurfaceOptions) =>
|
|
|
246
255
|
createSurface({
|
|
247
256
|
id: `${meta.id}/object-settings`,
|
|
248
257
|
role: 'object-settings',
|
|
249
|
-
filter: (data): data is { subject: View.View } =>
|
|
250
|
-
|
|
258
|
+
filter: (data): data is { subject: { view: Ref.Ref<View.View> } } => {
|
|
259
|
+
if (!Obj.isObject(data.subject)) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const schema = Obj.getSchema(data.subject);
|
|
264
|
+
return Option.fromNullable(schema).pipe(
|
|
265
|
+
Option.flatMap((schema) => ViewAnnotation.get(schema)),
|
|
266
|
+
Option.getOrElse(() => false),
|
|
267
|
+
);
|
|
268
|
+
},
|
|
269
|
+
component: ({ data }) => {
|
|
270
|
+
const view = data.subject.view.target;
|
|
271
|
+
if (!view) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return <ViewEditor view={view} />;
|
|
276
|
+
},
|
|
251
277
|
}),
|
|
252
278
|
createSurface({
|
|
253
279
|
id: SPACE_RENAME_POPOVER,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { contributes } from '@dxos/app-framework';
|
|
6
|
+
import { Obj, Ref, Type } from '@dxos/echo';
|
|
7
|
+
import { type Space } from '@dxos/react-client/echo';
|
|
8
|
+
import { Collection } from '@dxos/schema';
|
|
9
|
+
|
|
10
|
+
import { SpaceCapabilities } from './capabilities';
|
|
11
|
+
|
|
12
|
+
export default () =>
|
|
13
|
+
contributes(SpaceCapabilities.Repair, async ({ space }) => {
|
|
14
|
+
await removeQueryCollections(space);
|
|
15
|
+
await ensureSystemCollection(space);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Remove all existing query collections from the root collection.
|
|
20
|
+
*/
|
|
21
|
+
const removeQueryCollections = async (space: Space) => {
|
|
22
|
+
const rootCollection: Collection.Collection = await space.properties[Collection.Collection.typename]?.load();
|
|
23
|
+
if (!rootCollection) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const objects = await Promise.all(rootCollection.objects.map((ref) => ref.load()));
|
|
28
|
+
const queryCollections = objects.filter((object) => Obj.getTypename(object) === 'dxos.org/type/QueryCollection');
|
|
29
|
+
if (queryCollections.length === 0) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
rootCollection.objects = objects
|
|
34
|
+
.filter((object) => Obj.getTypename(object) !== 'dxos.org/type/QueryCollection')
|
|
35
|
+
.map((object) => Ref.make(object));
|
|
36
|
+
queryCollections.forEach((object) => space.db.remove(object));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Ensure the root collection has a system collection for StoredSchema.
|
|
41
|
+
*/
|
|
42
|
+
const ensureSystemCollection = async (space: Space) => {
|
|
43
|
+
const rootCollection: Collection.Collection = await space.properties[Collection.Collection.typename]?.load();
|
|
44
|
+
if (!rootCollection) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const objects = await Promise.all(rootCollection.objects.map((ref) => ref.load()));
|
|
49
|
+
const records = objects.find(
|
|
50
|
+
(object) => Obj.instanceOf(Collection.Managed, object) && object.key === Type.getTypename(Type.PersistentType),
|
|
51
|
+
);
|
|
52
|
+
if (records) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
rootCollection.objects.push(Ref.make(Collection.makeManaged({ key: Type.getTypename(Type.PersistentType) })));
|
|
57
|
+
};
|
|
@@ -101,7 +101,13 @@ export default async (context: PluginContext) => {
|
|
|
101
101
|
subscriptions.add(
|
|
102
102
|
scheduledEffect(
|
|
103
103
|
() => ({ name: space.properties.name }),
|
|
104
|
-
({ name }) =>
|
|
104
|
+
({ name }) => {
|
|
105
|
+
if (!name) {
|
|
106
|
+
delete state.spaceNames[space.id];
|
|
107
|
+
} else {
|
|
108
|
+
state.spaceNames[space.id] = name;
|
|
109
|
+
}
|
|
110
|
+
},
|
|
105
111
|
),
|
|
106
112
|
);
|
|
107
113
|
});
|
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
import * as Function from 'effect/Function';
|
|
7
|
-
import
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
8
|
+
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
8
9
|
|
|
9
10
|
import { Capabilities, LayoutAction, chain, createIntent } from '@dxos/app-framework';
|
|
10
|
-
import {
|
|
11
|
-
import { Obj,
|
|
11
|
+
import { useIntentDispatcher, usePluginManager } from '@dxos/app-framework/react';
|
|
12
|
+
import { Obj, Type } from '@dxos/echo';
|
|
13
|
+
import { EntityKind, SystemTypeAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
|
|
12
14
|
import { invariant } from '@dxos/invariant';
|
|
13
15
|
import { useClient } from '@dxos/react-client';
|
|
14
|
-
import { type Space, getSpace, isLiveObject, isSpace,
|
|
16
|
+
import { type Space, getSpace, isLiveObject, isSpace, useSpaces } from '@dxos/react-client/echo';
|
|
15
17
|
import { Dialog, IconButton, useTranslation } from '@dxos/react-ui';
|
|
16
18
|
import { cardDialogContent, cardDialogHeader } from '@dxos/react-ui-stack';
|
|
17
|
-
import { Collection
|
|
18
|
-
import { isNonNullable } from '@dxos/util';
|
|
19
|
+
import { type Collection } from '@dxos/schema';
|
|
19
20
|
|
|
20
|
-
import { SpaceCapabilities } from '../../capabilities';
|
|
21
21
|
import { meta } from '../../meta';
|
|
22
22
|
import { SpaceAction } from '../../types';
|
|
23
23
|
|
|
24
|
-
import { CreateObjectPanel, type CreateObjectPanelProps } from './CreateObjectPanel';
|
|
24
|
+
import { CreateObjectPanel, type CreateObjectPanelProps, type Metadata } from './CreateObjectPanel';
|
|
25
25
|
|
|
26
26
|
export const CREATE_OBJECT_DIALOG = `${meta.id}/CreateObjectDialog`;
|
|
27
27
|
|
|
@@ -44,26 +44,36 @@ export const CreateObjectDialog = ({
|
|
|
44
44
|
const manager = usePluginManager();
|
|
45
45
|
const { t } = useTranslation(meta.id);
|
|
46
46
|
const { dispatch } = useIntentDispatcher();
|
|
47
|
-
const forms = useCapabilities(SpaceCapabilities.ObjectForm);
|
|
48
47
|
const [target, setTarget] = useState<Space | Collection.Collection | undefined>(initialTarget);
|
|
49
48
|
const [typename, setTypename] = useState<string | undefined>(initialTypename);
|
|
50
49
|
const client = useClient();
|
|
51
50
|
const spaces = useSpaces();
|
|
52
|
-
const space = isSpace(target) ? target : getSpace(target);
|
|
53
|
-
const queryCollections = useQuery(space, Query.type(Collection.QueryCollection));
|
|
54
|
-
const hiddenTypenames = queryCollections
|
|
55
|
-
.map((collection) => getTypenameFromQuery(collection.query))
|
|
56
|
-
.filter(isNonNullable);
|
|
57
51
|
const closeRef = useRef<HTMLButtonElement | null>(null);
|
|
58
52
|
|
|
59
53
|
const resolve = useCallback<NonNullable<CreateObjectPanelProps['resolve']>>(
|
|
60
|
-
(typename) =>
|
|
61
|
-
|
|
54
|
+
(typename) => {
|
|
55
|
+
const metadata = manager.context
|
|
56
|
+
.getCapabilities(Capabilities.Metadata)
|
|
57
|
+
.find(({ id }) => id === typename)?.metadata;
|
|
58
|
+
return metadata?.createObjectIntent ? (metadata as Metadata) : undefined;
|
|
59
|
+
},
|
|
62
60
|
[manager],
|
|
63
61
|
);
|
|
64
62
|
|
|
63
|
+
const space = isSpace(target) ? target : getSpace(target);
|
|
64
|
+
// TODO(wittjosiah): Support database schemas.
|
|
65
|
+
const schemas = space?.db.schemaRegistry.query({ location: ['runtime'] }).runSync();
|
|
66
|
+
const userSchemas = useMemo(
|
|
67
|
+
() =>
|
|
68
|
+
schemas
|
|
69
|
+
?.filter((schema) => getTypeAnnotation(schema)?.kind !== EntityKind.Relation)
|
|
70
|
+
.filter((schema) => !!resolve(Type.getTypename(schema)))
|
|
71
|
+
.filter((schema) => !SystemTypeAnnotation.get(schema).pipe(Option.getOrElse(() => false))) ?? [],
|
|
72
|
+
[schemas],
|
|
73
|
+
);
|
|
74
|
+
|
|
65
75
|
const handleCreateObject = useCallback<NonNullable<CreateObjectPanelProps['onCreateObject']>>(
|
|
66
|
-
({
|
|
76
|
+
({ metadata, data = {} }) =>
|
|
67
77
|
Effect.gen(function* () {
|
|
68
78
|
if (!target) {
|
|
69
79
|
// TODO(wittjosiah): UI feedback.
|
|
@@ -75,10 +85,10 @@ export const CreateObjectDialog = ({
|
|
|
75
85
|
|
|
76
86
|
const space = isSpace(target) ? target : getSpace(target);
|
|
77
87
|
invariant(space, 'Missing space');
|
|
78
|
-
const { object } = yield* dispatch(
|
|
79
|
-
if (isLiveObject(object) && !Obj.instanceOf(
|
|
88
|
+
const { object } = yield* dispatch(metadata.createObjectIntent(data, { space }));
|
|
89
|
+
if (isLiveObject(object) && !Obj.instanceOf(Type.PersistentType, object)) {
|
|
80
90
|
// TODO(wittjosiah): Selection in navtree isn't working as expected when hidden typenames evals to true.
|
|
81
|
-
const hidden =
|
|
91
|
+
const hidden = !metadata.addToCollectionOnCreate;
|
|
82
92
|
const addObjectIntent = createIntent(SpaceAction.AddObject, {
|
|
83
93
|
target,
|
|
84
94
|
object,
|
|
@@ -94,7 +104,7 @@ export const CreateObjectDialog = ({
|
|
|
94
104
|
onCreateObject?.(object);
|
|
95
105
|
}
|
|
96
106
|
}).pipe(Effect.runPromise),
|
|
97
|
-
[dispatch, target, resolve,
|
|
107
|
+
[dispatch, target, resolve, _shouldNavigate],
|
|
98
108
|
);
|
|
99
109
|
|
|
100
110
|
return (
|
|
@@ -106,7 +116,7 @@ export const CreateObjectDialog = ({
|
|
|
106
116
|
{t('create object dialog title', {
|
|
107
117
|
object: t('typename label', {
|
|
108
118
|
ns: typename,
|
|
109
|
-
defaultValue: views ? 'View' : '
|
|
119
|
+
defaultValue: views ? 'View' : 'Object',
|
|
110
120
|
}),
|
|
111
121
|
})}
|
|
112
122
|
</Dialog.Title>
|
|
@@ -125,7 +135,7 @@ export const CreateObjectDialog = ({
|
|
|
125
135
|
</div>
|
|
126
136
|
|
|
127
137
|
<CreateObjectPanel
|
|
128
|
-
|
|
138
|
+
schemas={userSchemas}
|
|
129
139
|
spaces={spaces}
|
|
130
140
|
target={target}
|
|
131
141
|
views={views}
|
|
@@ -3,39 +3,46 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Option from 'effect/Option';
|
|
6
|
+
import type * as Schema from 'effect/Schema';
|
|
6
7
|
import React, { useCallback } from 'react';
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
-
import { type BaseObject, type TypeAnnotation, ViewAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
|
|
9
|
+
import { type AnyProperties, type TypeAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
|
|
10
10
|
import { type Space, type SpaceId } from '@dxos/react-client/echo';
|
|
11
11
|
import { Icon, toLocalizedString, useDefaultValue, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
import { Form } from '@dxos/react-ui-form';
|
|
13
13
|
import { SearchList } from '@dxos/react-ui-searchlist';
|
|
14
14
|
import { cardDialogOverflow, cardDialogPaddedOverflow, cardDialogSearchListRoot } from '@dxos/react-ui-stack';
|
|
15
|
-
import { type Collection } from '@dxos/schema';
|
|
15
|
+
import { type Collection, ViewAnnotation } from '@dxos/schema';
|
|
16
16
|
import { type MaybePromise, isNonNullable } from '@dxos/util';
|
|
17
17
|
|
|
18
18
|
import { useInputSurfaceLookup } from '../../hooks';
|
|
19
19
|
import { meta } from '../../meta';
|
|
20
|
-
import { type
|
|
20
|
+
import { type CreateObjectIntent } from '../../types';
|
|
21
21
|
import { getSpaceDisplayName } from '../../util';
|
|
22
22
|
|
|
23
|
+
export type Metadata = {
|
|
24
|
+
createObjectIntent: CreateObjectIntent;
|
|
25
|
+
inputSchema?: Schema.Schema.AnyNoContext;
|
|
26
|
+
addToCollectionOnCreate?: boolean;
|
|
27
|
+
icon?: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
23
30
|
export type CreateObjectPanelProps = {
|
|
24
|
-
|
|
31
|
+
schemas: Schema.Schema.AnyNoContext[];
|
|
25
32
|
spaces: Space[];
|
|
26
33
|
typename?: string;
|
|
27
34
|
target?: Space | Collection.Collection;
|
|
28
35
|
views?: boolean;
|
|
29
|
-
initialFormValues?: Partial<
|
|
36
|
+
initialFormValues?: Partial<AnyProperties>;
|
|
30
37
|
defaultSpaceId?: SpaceId;
|
|
31
|
-
resolve?: (typename: string) =>
|
|
38
|
+
resolve?: (typename: string) => Metadata | undefined;
|
|
32
39
|
onTargetChange?: (target: Space) => void;
|
|
33
40
|
onTypenameChange?: (typename: string) => void;
|
|
34
|
-
onCreateObject?: (params: {
|
|
41
|
+
onCreateObject?: (params: { metadata: Metadata; data?: Record<string, any> }) => MaybePromise<void>;
|
|
35
42
|
};
|
|
36
43
|
|
|
37
44
|
export const CreateObjectPanel = ({
|
|
38
|
-
|
|
45
|
+
schemas,
|
|
39
46
|
spaces,
|
|
40
47
|
typename,
|
|
41
48
|
target,
|
|
@@ -49,16 +56,16 @@ export const CreateObjectPanel = ({
|
|
|
49
56
|
}: CreateObjectPanelProps) => {
|
|
50
57
|
const { t } = useTranslation(meta.id);
|
|
51
58
|
const initialFormValues = useDefaultValue(_initialFormValues, () => ({}));
|
|
52
|
-
const
|
|
53
|
-
const options: TypeAnnotation[] =
|
|
54
|
-
.filter((
|
|
59
|
+
const metadata = typename && resolve?.(typename);
|
|
60
|
+
const options: TypeAnnotation[] = schemas
|
|
61
|
+
.filter((schema) => {
|
|
55
62
|
if (views == null) {
|
|
56
63
|
return true;
|
|
57
64
|
} else {
|
|
58
|
-
return views === ViewAnnotation.get(
|
|
65
|
+
return views === ViewAnnotation.get(schema).pipe(Option.getOrElse(() => false));
|
|
59
66
|
}
|
|
60
67
|
})
|
|
61
|
-
.map((
|
|
68
|
+
.map((schema) => getTypeAnnotation(schema))
|
|
62
69
|
.filter(isNonNullable)
|
|
63
70
|
.sort((a, b) => {
|
|
64
71
|
const nameA = t('typename label', { ns: a.typename, defaultValue: a.typename });
|
|
@@ -68,39 +75,39 @@ export const CreateObjectPanel = ({
|
|
|
68
75
|
|
|
69
76
|
const handleCreateObject = useCallback(
|
|
70
77
|
async (props: Record<string, any>) => {
|
|
71
|
-
if (!
|
|
78
|
+
if (!metadata) {
|
|
72
79
|
return;
|
|
73
80
|
}
|
|
74
|
-
await onCreateObject?.({
|
|
81
|
+
await onCreateObject?.({ metadata, data: props });
|
|
75
82
|
},
|
|
76
|
-
[onCreateObject,
|
|
83
|
+
[onCreateObject, metadata],
|
|
77
84
|
);
|
|
78
85
|
|
|
79
86
|
const handleSetTypename = useCallback(
|
|
80
87
|
async (typename: string) => {
|
|
81
|
-
const
|
|
82
|
-
if (
|
|
83
|
-
await onCreateObject?.({
|
|
88
|
+
const metadata = resolve?.(typename);
|
|
89
|
+
if (metadata && !metadata.inputSchema) {
|
|
90
|
+
await onCreateObject?.({ metadata });
|
|
84
91
|
} else {
|
|
85
92
|
onTypenameChange?.(typename);
|
|
86
93
|
}
|
|
87
94
|
},
|
|
88
|
-
[
|
|
95
|
+
[resolve, onCreateObject],
|
|
89
96
|
);
|
|
90
97
|
|
|
91
98
|
const inputSurfaceLookup = useInputSurfaceLookup({ target });
|
|
92
99
|
|
|
93
100
|
// TODO(wittjosiah): These inputs should be rolled into a `Form` once it supports the necessary variants.
|
|
94
|
-
return !
|
|
101
|
+
return !metadata ? (
|
|
95
102
|
<SelectSchema options={options} resolve={resolve} onChange={handleSetTypename} />
|
|
96
103
|
) : !target ? (
|
|
97
104
|
<SelectSpace spaces={spaces} defaultSpaceId={defaultSpaceId} onChange={onTargetChange} />
|
|
98
|
-
) :
|
|
105
|
+
) : metadata.inputSchema ? (
|
|
99
106
|
<div role='none' className={cardDialogOverflow}>
|
|
100
107
|
<Form
|
|
101
108
|
autoFocus
|
|
102
109
|
values={initialFormValues}
|
|
103
|
-
schema={
|
|
110
|
+
schema={metadata.inputSchema}
|
|
104
111
|
testId='create-object-form'
|
|
105
112
|
onSave={handleCreateObject}
|
|
106
113
|
lookupComponent={inputSurfaceLookup}
|
|
@@ -174,7 +181,7 @@ const SelectSchema = ({
|
|
|
174
181
|
classNames='flex items-center gap-2'
|
|
175
182
|
>
|
|
176
183
|
<span className='flex gap-2 items-center grow truncate'>
|
|
177
|
-
<Icon icon={resolve?.(option.typename)
|
|
184
|
+
<Icon icon={resolve?.(option.typename)?.icon ?? 'ph--placeholder--regular'} size={5} />
|
|
178
185
|
{t('typename label', { ns: option.typename, defaultValue: option.typename })}
|
|
179
186
|
</span>
|
|
180
187
|
</SearchList.Item>
|
|
@@ -28,7 +28,7 @@ export const ObjectForm = ({ object, schema }: ObjectFormProps) => {
|
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
const meta = Obj.getMeta(object);
|
|
31
|
-
const tags = (meta.tags ?? []).map((tag) => space?.db.
|
|
31
|
+
const tags = (meta.tags ?? []).map((tag) => space?.db.makeRef(DXN.parse(tag))).filter(isNonNullable);
|
|
32
32
|
const values = useMemo(() => ({ tags, ...object }), [object, tags]);
|
|
33
33
|
|
|
34
34
|
const handleCreateTag = useCallback((values: Schema.Schema.Type<typeof TagSchema>) => {
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { Obj } from '@dxos/echo';
|
|
8
|
-
import { ForeignKey } from '@dxos/echo/internal';
|
|
7
|
+
import { Key, Obj } from '@dxos/echo';
|
|
9
8
|
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
10
9
|
import { Form } from '@dxos/react-ui-form';
|
|
11
10
|
|
|
@@ -30,7 +29,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
|
|
|
30
29
|
const handleNew = useCallback(() => setAdding(true), []);
|
|
31
30
|
const handleCancel = useCallback(() => setAdding(false), []);
|
|
32
31
|
const handleSave = useCallback(
|
|
33
|
-
(key: ForeignKey) => {
|
|
32
|
+
(key: Key.ForeignKey) => {
|
|
34
33
|
const index = keys.findIndex(({ source, id }) => source === key.source && id === key.id);
|
|
35
34
|
if (index === -1) {
|
|
36
35
|
keys.push(key);
|
|
@@ -40,7 +39,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
|
|
|
40
39
|
[keys],
|
|
41
40
|
);
|
|
42
41
|
const handleDelete = useCallback(
|
|
43
|
-
(key: ForeignKey) => {
|
|
42
|
+
(key: Key.ForeignKey) => {
|
|
44
43
|
const index = keys.findIndex(({ source, id }) => source === key.source && id === key.id);
|
|
45
44
|
if (index !== -1) {
|
|
46
45
|
keys.splice(index, 1);
|
|
@@ -70,7 +69,7 @@ export const AdvancedObjectSettings = ({ object }: AdvancedObjectSettingsProps)
|
|
|
70
69
|
{adding && (
|
|
71
70
|
<Form
|
|
72
71
|
outerSpacing={false}
|
|
73
|
-
schema={ForeignKey}
|
|
72
|
+
schema={Key.ForeignKey}
|
|
74
73
|
values={initialValues}
|
|
75
74
|
onSave={handleSave}
|
|
76
75
|
onCancel={handleCancel}
|
|
@@ -47,7 +47,7 @@ export const BaseObjectSettings = ({ classNames, children, object }: BaseObjectS
|
|
|
47
47
|
}, [object]);
|
|
48
48
|
|
|
49
49
|
const meta = Obj.getMeta(object);
|
|
50
|
-
const tags = (meta.tags ?? []).map((tag) => space?.db.
|
|
50
|
+
const tags = (meta.tags ?? []).map((tag) => space?.db.makeRef(DXN.parse(tag))).filter(isNonNullable);
|
|
51
51
|
const values = useMemo(
|
|
52
52
|
() => ({
|
|
53
53
|
tags,
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type Key } from '@dxos/echo';
|
|
8
8
|
import { IconButton, List, ListItem, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
|
|
10
10
|
import { meta } from '../../meta';
|
|
11
11
|
|
|
12
12
|
export type ForeignKeysProps = {
|
|
13
|
-
keys: ForeignKey[];
|
|
14
|
-
onDelete?: (key: ForeignKey) => void;
|
|
13
|
+
keys: Key.ForeignKey[];
|
|
14
|
+
onDelete?: (key: Key.ForeignKey) => void;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// TODO(wittjosiah): This is a clone of `TokenManager`. Consider a form variant for arrays of read-only objects.
|
|
@@ -26,8 +26,8 @@ export const ForeignKeys = ({ keys, onDelete }: ForeignKeysProps) => {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
type KeyItemProps = {
|
|
29
|
-
forignKey: ForeignKey;
|
|
30
|
-
onDelete?: (key: ForeignKey) => void;
|
|
29
|
+
forignKey: Key.ForeignKey;
|
|
30
|
+
onDelete?: (key: Key.ForeignKey) => void;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const KeyItem = ({ forignKey, onDelete }: KeyItemProps) => {
|