@dxos/plugin-space 0.7.5-feature-compute.4d9d99a → 0.7.5-labs.401163d
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/{app-graph-builder-5D2QB43K.mjs → app-graph-builder-GSS3V7IN.mjs} +15 -13
- package/dist/lib/browser/app-graph-builder-GSS3V7IN.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-serializer-VNWPLPDF.mjs → app-graph-serializer-QDXM5M6K.mjs} +5 -5
- package/dist/lib/browser/{chunk-6SWQRWOD.mjs → chunk-DIBLC24B.mjs} +308 -251
- package/dist/lib/browser/chunk-DIBLC24B.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SOXNANA6.mjs → chunk-PQXZCNAU.mjs} +3 -2
- package/dist/lib/browser/{chunk-SOXNANA6.mjs.map → chunk-PQXZCNAU.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-UH5P4UL3.mjs → chunk-RLZQJD47.mjs} +3 -2
- package/dist/lib/browser/chunk-RLZQJD47.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5TBRONF6.mjs → chunk-SDK7RZI3.mjs} +3 -3
- package/dist/lib/browser/{chunk-HCXWKGTE.mjs → chunk-XPZ6IIXF.mjs} +4 -9
- package/dist/lib/browser/chunk-XPZ6IIXF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ZBKFJNHH.mjs → chunk-ZL5ZFGBK.mjs} +15 -9
- package/dist/lib/browser/chunk-ZL5ZFGBK.mjs.map +7 -0
- package/dist/lib/browser/{identity-created-EC5FOCX2.mjs → identity-created-25TK5XNO.mjs} +3 -3
- package/dist/lib/browser/index.mjs +14 -13
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-LNTCXZ57.mjs +537 -0
- package/dist/lib/browser/intent-resolver-LNTCXZ57.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-AZJFNTKK.mjs → react-root-Q7JJDCPB.mjs} +6 -6
- package/dist/lib/browser/{react-surface-E2VSYVNZ.mjs → react-surface-BDMYLARO.mjs} +26 -33
- package/dist/lib/browser/react-surface-BDMYLARO.mjs.map +7 -0
- package/dist/lib/browser/{settings-ASFF5BZL.mjs → settings-K4JPYYEM.mjs} +3 -3
- package/dist/lib/browser/{spaces-ready-4SFNS5JQ.mjs → spaces-ready-THYJEJYZ.mjs} +31 -32
- package/dist/lib/browser/spaces-ready-THYJEJYZ.mjs.map +7 -0
- package/dist/lib/browser/{state-MS4KYJWI.mjs → state-6DCY5YJP.mjs} +3 -3
- package/dist/lib/browser/types/index.mjs +2 -4
- package/dist/lib/node/{app-graph-builder-ZQ5S62YR.cjs → app-graph-builder-V3RCGDV7.cjs} +60 -58
- package/dist/lib/node/app-graph-builder-V3RCGDV7.cjs.map +7 -0
- package/dist/lib/node/{app-graph-serializer-72S7P33H.cjs → app-graph-serializer-H4UACG57.cjs} +21 -21
- package/dist/lib/node/{chunk-M64YG2FY.cjs → chunk-4AZ2DD4G.cjs} +308 -251
- package/dist/lib/node/chunk-4AZ2DD4G.cjs.map +7 -0
- package/dist/lib/node/{chunk-DDZYVNVP.cjs → chunk-6MEOP3DH.cjs} +8 -14
- package/dist/lib/node/chunk-6MEOP3DH.cjs.map +7 -0
- package/dist/lib/node/{chunk-BQRNTKSQ.cjs → chunk-D6BFKOXY.cjs} +8 -8
- package/dist/lib/node/{chunk-Z34MTEU7.cjs → chunk-SYVPVU3K.cjs} +66 -60
- package/dist/lib/node/chunk-SYVPVU3K.cjs.map +7 -0
- package/dist/lib/node/{chunk-56NGXG2A.cjs → chunk-UX3U4RU2.cjs} +9 -8
- package/dist/lib/node/chunk-UX3U4RU2.cjs.map +7 -0
- package/dist/lib/node/{chunk-AO4EW2RX.cjs → chunk-WZR6OAN3.cjs} +6 -5
- package/dist/lib/node/{chunk-AO4EW2RX.cjs.map → chunk-WZR6OAN3.cjs.map} +3 -3
- package/dist/lib/node/{identity-created-IMDS4A6A.cjs → identity-created-7G5U7R36.cjs} +7 -7
- package/dist/lib/node/index.cjs +93 -92
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/intent-resolver-CDE4M3TW.cjs +536 -0
- package/dist/lib/node/intent-resolver-CDE4M3TW.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-root-RB3OM3QG.cjs → react-root-JN6AIHMS.cjs} +12 -12
- package/dist/lib/node/{react-surface-TLKQEHHT.cjs → react-surface-XSK2QEQV.cjs} +72 -76
- package/dist/lib/node/react-surface-XSK2QEQV.cjs.map +7 -0
- package/dist/lib/node/{settings-QLCKAUHK.cjs → settings-TEELGWS4.cjs} +8 -8
- package/dist/lib/node/{spaces-ready-RZTKEXOL.cjs → spaces-ready-L4MJTFQ6.cjs} +39 -40
- package/dist/lib/node/spaces-ready-L4MJTFQ6.cjs.map +7 -0
- package/dist/lib/node/{state-4UIOUKLJ.cjs → state-WPZC4JXB.cjs} +8 -8
- package/dist/lib/node/types/index.cjs +16 -18
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{app-graph-builder-CD6IYPSS.mjs → app-graph-builder-VFHK7OQI.mjs} +15 -13
- package/dist/lib/node-esm/app-graph-builder-VFHK7OQI.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-serializer-CFXS6ZE2.mjs → app-graph-serializer-PIPJVXYZ.mjs} +5 -5
- package/dist/lib/node-esm/{chunk-M4XTHK35.mjs → chunk-4UX5WGKJ.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-CLGCKZ2D.mjs → chunk-AAQRELDK.mjs} +4 -9
- package/dist/lib/node-esm/chunk-AAQRELDK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CMKML5IN.mjs → chunk-FTVEA5LO.mjs} +308 -251
- package/dist/lib/node-esm/chunk-FTVEA5LO.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-7FUVU45N.mjs → chunk-ICCM4YRJ.mjs} +3 -2
- package/dist/lib/node-esm/{chunk-7FUVU45N.mjs.map → chunk-ICCM4YRJ.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-375RB3CZ.mjs → chunk-LGL4A5B5.mjs} +3 -2
- package/dist/lib/node-esm/chunk-LGL4A5B5.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FUMGYUD3.mjs → chunk-RCZRYXI3.mjs} +15 -9
- package/dist/lib/node-esm/chunk-RCZRYXI3.mjs.map +7 -0
- package/dist/lib/node-esm/{identity-created-SJYZZ7Q3.mjs → identity-created-7THGZ7EW.mjs} +3 -3
- package/dist/lib/node-esm/index.mjs +14 -13
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-7L3GJAZE.mjs +538 -0
- package/dist/lib/node-esm/intent-resolver-7L3GJAZE.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-root-WKJWCHXR.mjs → react-root-BNA6PBFZ.mjs} +6 -6
- package/dist/lib/node-esm/{react-surface-RVEHOSAD.mjs → react-surface-FTI2LQNL.mjs} +26 -33
- package/dist/lib/node-esm/react-surface-FTI2LQNL.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-WLVEO4JM.mjs → settings-KXYUZBLN.mjs} +3 -3
- package/dist/lib/node-esm/{spaces-ready-ITGYYT5A.mjs → spaces-ready-ZC2R73H3.mjs} +31 -32
- package/dist/lib/node-esm/spaces-ready-ZC2R73H3.mjs.map +7 -0
- package/dist/lib/node-esm/{state-BMISGQ2O.mjs → state-5GH2D5U4.mjs} +3 -3
- package/dist/lib/node-esm/types/index.mjs +2 -4
- package/dist/types/src/SpacePlugin.d.ts +5 -1
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +22 -22
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +6 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +34 -33
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +2 -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/spaces-ready.d.ts.map +1 -1
- package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +4 -3
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
- package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
- package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +3 -4
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +2 -5
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +1 -0
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -37
- package/src/SpacePlugin.tsx +11 -6
- package/src/capabilities/app-graph-builder.ts +9 -8
- package/src/capabilities/capabilities.ts +4 -1
- package/src/capabilities/intent-resolver.ts +410 -312
- package/src/capabilities/react-surface.tsx +22 -30
- package/src/capabilities/spaces-ready.ts +20 -21
- package/src/components/AwaitingObject.tsx +5 -5
- package/src/components/BaseObjectSettings.tsx +7 -0
- package/src/components/CreateDialog/CreateObjectDialog.tsx +15 -15
- package/src/components/CreateDialog/CreateObjectPanel.tsx +115 -116
- package/src/components/CreateDialog/CreateSpaceDialog.tsx +18 -9
- package/src/components/JoinDialog.tsx +27 -19
- package/src/components/SpacePluginSettings.tsx +3 -3
- package/src/components/SpacePresence.stories.tsx +2 -2
- package/src/components/SpacePresence.tsx +2 -3
- package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +16 -1
- package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +5 -1
- package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +15 -8
- package/src/components/SyncStatus/InlineSyncStatus.tsx +2 -2
- package/src/components/SyncStatus/SyncStatus.tsx +2 -1
- package/src/meta.ts +1 -0
- package/src/types/types.ts +2 -7
- package/src/util.tsx +9 -4
- package/dist/lib/browser/app-graph-builder-5D2QB43K.mjs.map +0 -7
- package/dist/lib/browser/chunk-6SWQRWOD.mjs.map +0 -7
- package/dist/lib/browser/chunk-HCXWKGTE.mjs.map +0 -7
- package/dist/lib/browser/chunk-UH5P4UL3.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZBKFJNHH.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-VBL572N7.mjs +0 -459
- package/dist/lib/browser/intent-resolver-VBL572N7.mjs.map +0 -7
- package/dist/lib/browser/react-surface-E2VSYVNZ.mjs.map +0 -7
- package/dist/lib/browser/spaces-ready-4SFNS5JQ.mjs.map +0 -7
- package/dist/lib/node/app-graph-builder-ZQ5S62YR.cjs.map +0 -7
- package/dist/lib/node/chunk-56NGXG2A.cjs.map +0 -7
- package/dist/lib/node/chunk-DDZYVNVP.cjs.map +0 -7
- package/dist/lib/node/chunk-M64YG2FY.cjs.map +0 -7
- package/dist/lib/node/chunk-Z34MTEU7.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-S4HZABYI.cjs +0 -458
- package/dist/lib/node/intent-resolver-S4HZABYI.cjs.map +0 -7
- package/dist/lib/node/react-surface-TLKQEHHT.cjs.map +0 -7
- package/dist/lib/node/spaces-ready-RZTKEXOL.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-CD6IYPSS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-375RB3CZ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CLGCKZ2D.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CMKML5IN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FUMGYUD3.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-OIQH7HN7.mjs +0 -460
- package/dist/lib/node-esm/intent-resolver-OIQH7HN7.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-RVEHOSAD.mjs.map +0 -7
- package/dist/lib/node-esm/spaces-ready-ITGYYT5A.mjs.map +0 -7
- /package/dist/lib/browser/{app-graph-serializer-VNWPLPDF.mjs.map → app-graph-serializer-QDXM5M6K.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-5TBRONF6.mjs.map → chunk-SDK7RZI3.mjs.map} +0 -0
- /package/dist/lib/browser/{identity-created-EC5FOCX2.mjs.map → identity-created-25TK5XNO.mjs.map} +0 -0
- /package/dist/lib/browser/{react-root-AZJFNTKK.mjs.map → react-root-Q7JJDCPB.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-ASFF5BZL.mjs.map → settings-K4JPYYEM.mjs.map} +0 -0
- /package/dist/lib/browser/{state-MS4KYJWI.mjs.map → state-6DCY5YJP.mjs.map} +0 -0
- /package/dist/lib/node/{app-graph-serializer-72S7P33H.cjs.map → app-graph-serializer-H4UACG57.cjs.map} +0 -0
- /package/dist/lib/node/{chunk-BQRNTKSQ.cjs.map → chunk-D6BFKOXY.cjs.map} +0 -0
- /package/dist/lib/node/{identity-created-IMDS4A6A.cjs.map → identity-created-7G5U7R36.cjs.map} +0 -0
- /package/dist/lib/node/{react-root-RB3OM3QG.cjs.map → react-root-JN6AIHMS.cjs.map} +0 -0
- /package/dist/lib/node/{settings-QLCKAUHK.cjs.map → settings-TEELGWS4.cjs.map} +0 -0
- /package/dist/lib/node/{state-4UIOUKLJ.cjs.map → state-WPZC4JXB.cjs.map} +0 -0
- /package/dist/lib/node-esm/{app-graph-serializer-CFXS6ZE2.mjs.map → app-graph-serializer-PIPJVXYZ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-M4XTHK35.mjs.map → chunk-4UX5WGKJ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{identity-created-SJYZZ7Q3.mjs.map → identity-created-7THGZ7EW.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-root-WKJWCHXR.mjs.map → react-root-BNA6PBFZ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{settings-WLVEO4JM.mjs.map → settings-KXYUZBLN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{state-BMISGQ2O.mjs.map → state-5GH2D5U4.mjs.map} +0 -0
|
@@ -5,32 +5,18 @@
|
|
|
5
5
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { Surface, isSurfaceAvailable, usePluginManager } from '@dxos/app-framework';
|
|
8
|
-
import { type TypedObject, getObjectAnnotation, S } from '@dxos/echo-schema';
|
|
9
|
-
import { type SpaceId, type Space
|
|
10
|
-
import { Icon,
|
|
11
|
-
import { Form,
|
|
8
|
+
import { type TypedObject, getObjectAnnotation, type ObjectAnnotation, S } from '@dxos/echo-schema';
|
|
9
|
+
import { type SpaceId, type Space } from '@dxos/react-client/echo';
|
|
10
|
+
import { Icon, type ThemedClassName, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
11
|
+
import { Form, type InputProps } from '@dxos/react-ui-form';
|
|
12
12
|
import { SearchList } from '@dxos/react-ui-searchlist';
|
|
13
|
-
import {
|
|
13
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
14
|
+
import { isNonNullable, type MaybePromise } from '@dxos/util';
|
|
14
15
|
|
|
15
16
|
import { SPACE_PLUGIN } from '../../meta';
|
|
16
17
|
import { type CollectionType } from '../../types';
|
|
17
18
|
import { getSpaceDisplayName } from '../../util';
|
|
18
19
|
|
|
19
|
-
export type CreateObjectPanelProps = {
|
|
20
|
-
schemas: TypedObject[];
|
|
21
|
-
spaces: Space[];
|
|
22
|
-
typename?: string;
|
|
23
|
-
target?: Space | CollectionType;
|
|
24
|
-
name?: string;
|
|
25
|
-
defaultSpaceId?: SpaceId;
|
|
26
|
-
resolve?: (typename: string) => Record<string, any>;
|
|
27
|
-
onCreateObject?: (params: {
|
|
28
|
-
schema: TypedObject;
|
|
29
|
-
target: Space | CollectionType;
|
|
30
|
-
data: Record<string, any>;
|
|
31
|
-
}) => MaybePromise<void>;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
20
|
// TODO(ZaymonFC): Move this if you find yourself needing it elsewhere.
|
|
35
21
|
/**
|
|
36
22
|
* Creates a surface input component based on plugin context.
|
|
@@ -41,9 +27,8 @@ const useInputSurfaceLookup = (baseData?: Record<string, any>) => {
|
|
|
41
27
|
const pluginManager = usePluginManager();
|
|
42
28
|
|
|
43
29
|
return useCallback(
|
|
44
|
-
({ prop, schema, inputProps }: { prop: string; schema: S.Schema<any>; inputProps: InputProps
|
|
30
|
+
({ prop, schema, inputProps }: { prop: string; schema: S.Schema<any>; inputProps: InputProps }) => {
|
|
45
31
|
const composedData = { prop, schema, ...baseData };
|
|
46
|
-
|
|
47
32
|
if (!isSurfaceAvailable(pluginManager.context, { role: 'form-input', data: composedData })) {
|
|
48
33
|
return undefined;
|
|
49
34
|
}
|
|
@@ -54,7 +39,23 @@ const useInputSurfaceLookup = (baseData?: Record<string, any>) => {
|
|
|
54
39
|
);
|
|
55
40
|
};
|
|
56
41
|
|
|
42
|
+
export type CreateObjectPanelProps = ThemedClassName<{
|
|
43
|
+
schemas: TypedObject[];
|
|
44
|
+
spaces: Space[];
|
|
45
|
+
typename?: string;
|
|
46
|
+
target?: Space | CollectionType;
|
|
47
|
+
name?: string;
|
|
48
|
+
defaultSpaceId?: SpaceId;
|
|
49
|
+
resolve?: (typename: string) => Record<string, any>;
|
|
50
|
+
onCreateObject?: (params: {
|
|
51
|
+
schema: TypedObject;
|
|
52
|
+
target: Space | CollectionType;
|
|
53
|
+
data: Record<string, any>;
|
|
54
|
+
}) => MaybePromise<void>;
|
|
55
|
+
}>;
|
|
56
|
+
|
|
57
57
|
export const CreateObjectPanel = ({
|
|
58
|
+
classNames,
|
|
58
59
|
schemas,
|
|
59
60
|
spaces,
|
|
60
61
|
typename: initialTypename,
|
|
@@ -68,10 +69,14 @@ export const CreateObjectPanel = ({
|
|
|
68
69
|
const [typename, setTypename] = useState<string | undefined>(initialTypename);
|
|
69
70
|
const [target, setTarget] = useState<Space | CollectionType | undefined>(initialTarget);
|
|
70
71
|
const schema = schemas.find((schema) => getObjectAnnotation(schema)?.typename === typename);
|
|
71
|
-
const options = schemas
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const options: ObjectAnnotation[] = schemas
|
|
73
|
+
.map(getObjectAnnotation)
|
|
74
|
+
.filter(isNonNullable)
|
|
75
|
+
.sort((a, b) => {
|
|
76
|
+
const nameA = t('typename label', { ns: a.typename, defaultValue: a.typename });
|
|
77
|
+
const nameB = t('typename label', { ns: b.typename, defaultValue: b.typename });
|
|
78
|
+
return nameA.localeCompare(nameB);
|
|
79
|
+
});
|
|
75
80
|
|
|
76
81
|
const handleCreateObject = useCallback(
|
|
77
82
|
async (props: Record<string, any>) => {
|
|
@@ -90,117 +95,111 @@ export const CreateObjectPanel = ({
|
|
|
90
95
|
return resolve?.(typename);
|
|
91
96
|
}, [resolve, typename]);
|
|
92
97
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
const inputSurfaceLookup = useInputSurfaceLookup({ target });
|
|
99
|
+
|
|
100
|
+
const form = useMemo(() => {
|
|
101
|
+
// TODO(ZaymonFC): Move this default object creation schema somewhere?
|
|
102
|
+
const schema = (metadata?.creationSchema ?? S.Struct({ name: S.optional(S.String) })) as S.Schema<any>;
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<Form
|
|
106
|
+
classNames='!p-0'
|
|
107
|
+
autoFocus
|
|
108
|
+
values={{ name: initialName }}
|
|
109
|
+
schema={schema}
|
|
110
|
+
testId='create-object-form'
|
|
111
|
+
onSave={handleCreateObject}
|
|
112
|
+
lookupComponent={inputSurfaceLookup}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
}, [initialName, handleCreateObject, metadata]);
|
|
116
|
+
|
|
117
|
+
// TODO(wittjosiah): These inputs should be rolled into a `Form` once it supports the necessary variants.
|
|
118
|
+
return (
|
|
119
|
+
<div role='form' className={mx('flex flex-col gap-2', classNames)}>
|
|
120
|
+
{!schema ? (
|
|
121
|
+
<SelectSchema options={options} resolve={resolve} onChange={setTypename} />
|
|
122
|
+
) : !target ? (
|
|
123
|
+
<SelectSpace spaces={spaces} defaultSpaceId={defaultSpaceId} onChange={setTarget} />
|
|
124
|
+
) : (
|
|
125
|
+
form
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const SelectSpace = ({
|
|
132
|
+
spaces,
|
|
133
|
+
defaultSpaceId,
|
|
134
|
+
onChange,
|
|
135
|
+
}: { onChange: (space: Space) => void } & Pick<CreateObjectPanelProps, 'spaces' | 'defaultSpaceId'>) => {
|
|
136
|
+
const { t } = useTranslation(SPACE_PLUGIN);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<SearchList.Root label={t('space input label')} classNames='flex flex-col grow overflow-hidden'>
|
|
96
140
|
<SearchList.Input
|
|
97
141
|
autoFocus
|
|
98
|
-
data-testid='create-object-form.
|
|
99
|
-
placeholder={t('
|
|
142
|
+
data-testid='create-object-form.space-input'
|
|
143
|
+
placeholder={t('space input placeholder')}
|
|
100
144
|
classNames='px-1 my-2'
|
|
101
145
|
/>
|
|
102
146
|
<SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
147
|
+
{spaces
|
|
148
|
+
.sort((a, b) => {
|
|
149
|
+
const aName = toLocalizedString(getSpaceDisplayName(a, { personal: a.id === defaultSpaceId }), t);
|
|
150
|
+
const bName = toLocalizedString(getSpaceDisplayName(b, { personal: b.id === defaultSpaceId }), t);
|
|
151
|
+
return aName.localeCompare(bName);
|
|
152
|
+
})
|
|
153
|
+
.map((space) => (
|
|
154
|
+
<SearchList.Item
|
|
155
|
+
key={space.id}
|
|
156
|
+
value={toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
|
|
157
|
+
onSelect={() => onChange(space)}
|
|
158
|
+
classNames='flex items-center gap-2'
|
|
159
|
+
>
|
|
160
|
+
<span className='grow truncate'>
|
|
161
|
+
{toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
|
|
162
|
+
</span>
|
|
163
|
+
</SearchList.Item>
|
|
164
|
+
))}
|
|
116
165
|
</SearchList.Content>
|
|
117
166
|
</SearchList.Root>
|
|
118
167
|
);
|
|
168
|
+
};
|
|
119
169
|
|
|
120
|
-
|
|
121
|
-
|
|
170
|
+
const SelectSchema = ({
|
|
171
|
+
options,
|
|
172
|
+
resolve,
|
|
173
|
+
onChange,
|
|
174
|
+
}: {
|
|
175
|
+
options: ObjectAnnotation[];
|
|
176
|
+
onChange: (type: string) => void;
|
|
177
|
+
} & Pick<CreateObjectPanelProps, 'resolve'>) => {
|
|
178
|
+
const { t } = useTranslation(SPACE_PLUGIN);
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<SearchList.Root label={t('schema input label')} classNames='flex flex-col grow overflow-hidden'>
|
|
122
182
|
<SearchList.Input
|
|
123
183
|
autoFocus
|
|
124
|
-
data-testid='create-object-form.
|
|
125
|
-
placeholder={t('
|
|
184
|
+
data-testid='create-object-form.schema-input'
|
|
185
|
+
placeholder={t('schema input placeholder')}
|
|
126
186
|
classNames='px-1 my-2'
|
|
127
187
|
/>
|
|
128
188
|
<SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
|
|
129
|
-
{
|
|
189
|
+
{options.map((option) => (
|
|
130
190
|
<SearchList.Item
|
|
131
|
-
key={
|
|
132
|
-
value={
|
|
133
|
-
onSelect={() =>
|
|
191
|
+
key={option.typename}
|
|
192
|
+
value={t('typename label', { ns: option.typename, defaultValue: option.typename })}
|
|
193
|
+
onSelect={() => onChange(option.typename)}
|
|
134
194
|
classNames='flex items-center gap-2'
|
|
135
195
|
>
|
|
136
|
-
<span className='grow truncate'>
|
|
137
|
-
{
|
|
196
|
+
<span className='flex gap-2 items-center grow truncate'>
|
|
197
|
+
<Icon icon={resolve?.(option.typename).icon ?? 'ph--placeholder--regular'} size={5} />
|
|
198
|
+
{t('typename label', { ns: option.typename, defaultValue: option.typename })}
|
|
138
199
|
</span>
|
|
139
200
|
</SearchList.Item>
|
|
140
201
|
))}
|
|
141
202
|
</SearchList.Content>
|
|
142
203
|
</SearchList.Root>
|
|
143
204
|
);
|
|
144
|
-
|
|
145
|
-
const inputSurfaceLookup = useInputSurfaceLookup({ target });
|
|
146
|
-
|
|
147
|
-
const form = useMemo(() => {
|
|
148
|
-
// TODO(ZaymonFC): Move this default object creation schema somewhere?
|
|
149
|
-
const schema = (metadata?.creationSchema ?? S.Struct({ name: S.optional(S.String) })) as S.Schema<any>;
|
|
150
|
-
|
|
151
|
-
return (
|
|
152
|
-
<Form
|
|
153
|
-
autoFocus
|
|
154
|
-
values={{ name: initialName }}
|
|
155
|
-
schema={schema}
|
|
156
|
-
testId='create-object-form'
|
|
157
|
-
onSave={handleCreateObject}
|
|
158
|
-
lookupComponent={inputSurfaceLookup}
|
|
159
|
-
/>
|
|
160
|
-
);
|
|
161
|
-
}, [initialName, handleCreateObject, metadata]);
|
|
162
|
-
|
|
163
|
-
return (
|
|
164
|
-
<div role='form' className='flex flex-col gap-2'>
|
|
165
|
-
{target && (
|
|
166
|
-
<div role='none'>
|
|
167
|
-
<Input.Root>
|
|
168
|
-
<InputHeader>
|
|
169
|
-
<Input.Label>
|
|
170
|
-
{t(isSpace(target) ? 'creating in space label' : 'creating in collection label')}
|
|
171
|
-
</Input.Label>
|
|
172
|
-
</InputHeader>
|
|
173
|
-
<div role='none' className='flex gap-2'>
|
|
174
|
-
<Input.TextInput
|
|
175
|
-
disabled
|
|
176
|
-
value={
|
|
177
|
-
isSpace(target)
|
|
178
|
-
? toLocalizedString(getSpaceDisplayName(target, { personal: target.id === defaultSpaceId }), t)
|
|
179
|
-
: target.name || t('unnamed collection label')
|
|
180
|
-
}
|
|
181
|
-
/>
|
|
182
|
-
<IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearTarget} />
|
|
183
|
-
</div>
|
|
184
|
-
</Input.Root>
|
|
185
|
-
</div>
|
|
186
|
-
)}
|
|
187
|
-
{schema && (
|
|
188
|
-
<div role='none'>
|
|
189
|
-
<Input.Root>
|
|
190
|
-
<InputHeader>
|
|
191
|
-
<Input.Label>{t('creating object type label')}</Input.Label>
|
|
192
|
-
</InputHeader>
|
|
193
|
-
<div role='none' className='flex gap-2'>
|
|
194
|
-
<Input.TextInput
|
|
195
|
-
disabled
|
|
196
|
-
value={t('typename label', { ns: schema.typename, defaultValue: schema.typename })}
|
|
197
|
-
/>
|
|
198
|
-
<IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearSchema} />
|
|
199
|
-
</div>
|
|
200
|
-
</Input.Root>
|
|
201
|
-
</div>
|
|
202
|
-
)}
|
|
203
|
-
{!schema ? schemaInput : !target ? spaceInput : form}
|
|
204
|
-
</div>
|
|
205
|
-
);
|
|
206
205
|
};
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Effect } from 'effect';
|
|
5
6
|
import React, { useCallback, useRef } from 'react';
|
|
6
7
|
|
|
7
|
-
import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
+
import { createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
9
|
import { type S } from '@dxos/echo-schema';
|
|
9
10
|
import { Button, Dialog, Icon, useTranslation } from '@dxos/react-ui';
|
|
10
11
|
import { Form } from '@dxos/react-ui-form';
|
|
@@ -20,15 +21,16 @@ const initialValues: FormValues = { edgeReplication: true };
|
|
|
20
21
|
export const CreateSpaceDialog = () => {
|
|
21
22
|
const closeRef = useRef<HTMLButtonElement | null>(null);
|
|
22
23
|
const { t } = useTranslation(SPACE_PLUGIN);
|
|
23
|
-
const {
|
|
24
|
+
const { dispatch } = useIntentDispatcher();
|
|
24
25
|
|
|
25
26
|
const handleCreateSpace = useCallback(
|
|
26
27
|
async (data: FormValues) => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
28
|
+
const program = Effect.gen(function* () {
|
|
29
|
+
const { space } = yield* dispatch(createIntent(SpaceAction.Create, data));
|
|
30
|
+
yield* dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: space.id }));
|
|
31
|
+
yield* dispatch(createIntent(SpaceAction.OpenCreateObject, { target: space }));
|
|
32
|
+
});
|
|
33
|
+
await Effect.runPromise(program);
|
|
32
34
|
},
|
|
33
35
|
[dispatch],
|
|
34
36
|
);
|
|
@@ -36,7 +38,7 @@ export const CreateSpaceDialog = () => {
|
|
|
36
38
|
return (
|
|
37
39
|
// TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
|
|
38
40
|
// Consider factoring it out to the tabs package.
|
|
39
|
-
<Dialog.Content classNames='p-0 bs-content min-bs-[
|
|
41
|
+
<Dialog.Content classNames='p-0 bs-content min-bs-[16rem] max-bs-full md:max-is-[32rem] overflow-hidden'>
|
|
40
42
|
<div role='none' className='flex justify-between pbs-2 pis-2 pie-2 @md:pbs-4 @md:pis-4 @md:pie-4'>
|
|
41
43
|
<Dialog.Title>{t('create space dialog title')}</Dialog.Title>
|
|
42
44
|
<Dialog.Close asChild>
|
|
@@ -46,7 +48,14 @@ export const CreateSpaceDialog = () => {
|
|
|
46
48
|
</Dialog.Close>
|
|
47
49
|
</div>
|
|
48
50
|
<div className='p-4'>
|
|
49
|
-
<Form
|
|
51
|
+
<Form
|
|
52
|
+
testId='create-space-form'
|
|
53
|
+
classNames='!p-0'
|
|
54
|
+
autoFocus
|
|
55
|
+
values={initialValues}
|
|
56
|
+
schema={SpaceForm}
|
|
57
|
+
onSave={handleCreateSpace}
|
|
58
|
+
/>
|
|
50
59
|
</div>
|
|
51
60
|
</Dialog.Content>
|
|
52
61
|
);
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import { createIntent, LayoutAction,
|
|
8
|
-
import {
|
|
7
|
+
import { createIntent, LayoutAction, useAppGraph, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
+
import { log } from '@dxos/log';
|
|
9
9
|
import { ObservabilityAction } from '@dxos/plugin-observability/types';
|
|
10
|
-
import {
|
|
10
|
+
import { useClient } from '@dxos/react-client';
|
|
11
11
|
import { type InvitationResult } from '@dxos/react-client/invitations';
|
|
12
|
-
import { Dialog
|
|
12
|
+
import { Dialog } from '@dxos/react-ui';
|
|
13
13
|
import { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';
|
|
14
14
|
|
|
15
15
|
import { SPACE_PLUGIN } from '../meta';
|
|
@@ -21,47 +21,55 @@ export type JoinDialogProps = JoinPanelProps & {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export const JoinDialog = ({ navigableCollections, onDone, ...props }: JoinDialogProps) => {
|
|
24
|
-
const { t } = useTranslation(SPACE_PLUGIN);
|
|
25
24
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
26
|
-
const
|
|
27
|
-
const { graph } =
|
|
25
|
+
const client = useClient();
|
|
26
|
+
const { graph } = useAppGraph();
|
|
28
27
|
|
|
29
28
|
const handleDone = useCallback(
|
|
30
29
|
async (result: InvitationResult | null) => {
|
|
31
30
|
if (result?.spaceKey) {
|
|
32
31
|
await Promise.all([
|
|
33
32
|
dispatch(
|
|
34
|
-
createIntent(LayoutAction.
|
|
35
|
-
|
|
33
|
+
createIntent(LayoutAction.AddToast, {
|
|
34
|
+
part: 'toast',
|
|
36
35
|
subject: {
|
|
37
36
|
id: `${SPACE_PLUGIN}/join-success`,
|
|
38
37
|
duration: 5_000,
|
|
39
|
-
title:
|
|
40
|
-
closeLabel:
|
|
38
|
+
title: ['join success label', { ns: SPACE_PLUGIN }],
|
|
39
|
+
closeLabel: ['dismiss label', { ns: SPACE_PLUGIN }],
|
|
41
40
|
},
|
|
42
41
|
}),
|
|
43
42
|
),
|
|
44
43
|
dispatch(
|
|
45
|
-
createIntent(LayoutAction.
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
createIntent(LayoutAction.UpdateDialog, {
|
|
45
|
+
part: 'dialog',
|
|
46
|
+
options: {
|
|
47
|
+
state: false,
|
|
48
|
+
},
|
|
48
49
|
}),
|
|
49
50
|
),
|
|
50
51
|
]);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
const space = spaces.
|
|
54
|
+
const space = result?.spaceKey ? client.spaces.get(result.spaceKey) : undefined;
|
|
55
|
+
if (!space) {
|
|
56
|
+
log.warn('Space not found', result?.spaceKey);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: space.id }));
|
|
61
|
+
|
|
54
62
|
// TODO(wittjosiah): If navigableCollections is false and there's no target,
|
|
55
63
|
// should try to navigate to the first object of the space replicates.
|
|
56
64
|
// Potentially this could also be done on the inviters side to ensure there's always a target.
|
|
57
65
|
const target = result?.target || (navigableCollections ? space?.id : undefined);
|
|
58
66
|
if (target) {
|
|
59
|
-
// Wait
|
|
67
|
+
// Wait before navigating to the target node.
|
|
60
68
|
// If the target has not yet replicated, this will trigger a loading toast.
|
|
61
69
|
await graph.waitForPath({ target }).catch(() => {});
|
|
62
70
|
await Promise.all([
|
|
63
|
-
dispatch(createIntent(
|
|
64
|
-
dispatch(createIntent(
|
|
71
|
+
dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [target] })),
|
|
72
|
+
dispatch(createIntent(LayoutAction.Expose, { part: 'navigation', subject: target })),
|
|
65
73
|
]);
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -73,7 +81,7 @@ export const JoinDialog = ({ navigableCollections, onDone, ...props }: JoinDialo
|
|
|
73
81
|
);
|
|
74
82
|
}
|
|
75
83
|
},
|
|
76
|
-
[dispatch,
|
|
84
|
+
[dispatch, client, graph],
|
|
77
85
|
);
|
|
78
86
|
|
|
79
87
|
return (
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import { Input, useTranslation } from '@dxos/react-ui';
|
|
8
|
-
import { DeprecatedFormInput } from '@dxos/react-ui-form';
|
|
8
|
+
import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
|
|
9
9
|
|
|
10
10
|
import { SPACE_PLUGIN } from '../meta';
|
|
11
11
|
import { type SpaceSettingsProps } from '../types';
|
|
@@ -14,10 +14,10 @@ export const SpacePluginSettings = ({ settings }: { settings: SpaceSettingsProps
|
|
|
14
14
|
const { t } = useTranslation(SPACE_PLUGIN);
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
-
|
|
17
|
+
<DeprecatedFormContainer>
|
|
18
18
|
<DeprecatedFormInput label={t('show hidden spaces label')}>
|
|
19
19
|
<Input.Switch checked={settings.showHidden} onCheckedChange={(checked) => (settings.showHidden = !!checked)} />
|
|
20
20
|
</DeprecatedFormInput>
|
|
21
|
-
|
|
21
|
+
</DeprecatedFormContainer>
|
|
22
22
|
);
|
|
23
23
|
};
|
|
@@ -7,7 +7,7 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
|
-
import { PublicKey } from '@dxos/keys';
|
|
10
|
+
import { IdentityDid, PublicKey } from '@dxos/keys';
|
|
11
11
|
import { HaloSpaceMember, SpaceMember } from '@dxos/react-client/echo';
|
|
12
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
13
|
|
|
@@ -17,7 +17,7 @@ import translations from '../translations';
|
|
|
17
17
|
const nViewers = (n: number, currentlyAttended = true): Member[] =>
|
|
18
18
|
Array.from({ length: n }, () => ({
|
|
19
19
|
role: HaloSpaceMember.Role.ADMIN,
|
|
20
|
-
identity: { identityKey: PublicKey.random() },
|
|
20
|
+
identity: { did: IdentityDid.random(), identityKey: PublicKey.random() },
|
|
21
21
|
presence: SpaceMember.PresenceState.ONLINE,
|
|
22
22
|
lastSeen: Date.now(),
|
|
23
23
|
currentlyAttended,
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { useCapability } from '@dxos/app-framework';
|
|
7
|
+
import { useAppGraph, useCapability } from '@dxos/app-framework';
|
|
8
8
|
import { generateName } from '@dxos/display-name';
|
|
9
9
|
import { type Expando } from '@dxos/echo-schema';
|
|
10
|
-
import { useGraph } from '@dxos/plugin-graph';
|
|
11
10
|
import { PublicKey, useClient } from '@dxos/react-client';
|
|
12
11
|
import { getSpace, useMembers, type SpaceMember, fullyQualifiedId } from '@dxos/react-client/echo';
|
|
13
12
|
import { type Identity, useIdentity } from '@dxos/react-client/halo';
|
|
@@ -210,7 +209,7 @@ export const SmallPresenceLive = ({ id, open, viewers }: SmallPresenceLiveProps)
|
|
|
210
209
|
// TODO(wittjosiah): If the attended node is deep in the graph and the graph is not fully loaded
|
|
211
210
|
// this will result in an empty path until the graph is connected.
|
|
212
211
|
// TODO(wittjosiah): Consider using this indicator for all open nodes instead of just attended.
|
|
213
|
-
const { graph } =
|
|
212
|
+
const { graph } = useAppGraph();
|
|
214
213
|
const attended = useAttended();
|
|
215
214
|
const startOfAttention = attended.at(-1);
|
|
216
215
|
const path = usePath(graph, startOfAttention);
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useState } from 'react';
|
|
5
|
+
import React, { useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
|
+
import { Surface, useCapabilities } from '@dxos/app-framework';
|
|
7
8
|
import { useClient } from '@dxos/react-client';
|
|
8
9
|
import { Button, Clipboard, Dialog, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
9
10
|
import { Tabs, type TabsRootProps, type TabsActivePart } from '@dxos/react-ui-tabs';
|
|
10
11
|
import { SpacePanel, type SpacePanelProps } from '@dxos/shell/react';
|
|
11
12
|
|
|
12
13
|
import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
|
|
14
|
+
import { SpaceCapabilities } from '../../capabilities';
|
|
13
15
|
import { SPACE_PLUGIN } from '../../meta';
|
|
14
16
|
import { COMPOSER_SPACE_LOCK, getSpaceDisplayName } from '../../util';
|
|
15
17
|
|
|
@@ -36,6 +38,8 @@ export const SpaceSettingsDialog = ({
|
|
|
36
38
|
const [selected, setSelected] = useState<SpaceSettingsTab>(initialTab);
|
|
37
39
|
const locked = space.properties[COMPOSER_SPACE_LOCK];
|
|
38
40
|
const name = getSpaceDisplayName(space, { personal: client.spaces.default === space, namesCache });
|
|
41
|
+
const panels = useCapabilities(SpaceCapabilities.SettingsPanel);
|
|
42
|
+
const data = useMemo(() => ({ subject: space }), [space]);
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
45
|
// TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
|
|
@@ -84,6 +88,11 @@ export const SpaceSettingsDialog = ({
|
|
|
84
88
|
<Tabs.Tab value='members' disabled={locked}>
|
|
85
89
|
{t('members tab label')}
|
|
86
90
|
</Tabs.Tab>
|
|
91
|
+
{panels.map((panel) => (
|
|
92
|
+
<Tabs.Tab key={panel.id} value={panel.id}>
|
|
93
|
+
{toLocalizedString(panel.label, t)}
|
|
94
|
+
</Tabs.Tab>
|
|
95
|
+
))}
|
|
87
96
|
</div>
|
|
88
97
|
</Tabs.Tablist>
|
|
89
98
|
</div>
|
|
@@ -98,6 +107,12 @@ export const SpaceSettingsDialog = ({
|
|
|
98
107
|
<SpacePanel space={space} hideHeading target={target} createInvitationUrl={createInvitationUrl} />
|
|
99
108
|
</Clipboard.Provider>
|
|
100
109
|
</Tabs.Tabpanel>
|
|
110
|
+
|
|
111
|
+
{panels.map((panel) => (
|
|
112
|
+
<Tabs.Tabpanel key={panel.id} value={panel.id} classNames='pli-3 @md:pli-5 max-bs-dvh overflow-y-auto'>
|
|
113
|
+
<Surface role={`space-settings--${panel.id}`} data={data} />
|
|
114
|
+
</Tabs.Tabpanel>
|
|
115
|
+
))}
|
|
101
116
|
</Tabs.Viewport>
|
|
102
117
|
</Tabs.Root>
|
|
103
118
|
</Dialog.Content>
|
|
@@ -15,7 +15,11 @@ import translations from '../../translations';
|
|
|
15
15
|
|
|
16
16
|
const Story = (args: Partial<SpaceSettingsPanelProps>) => {
|
|
17
17
|
const { space } = useClientProvider();
|
|
18
|
-
return
|
|
18
|
+
return (
|
|
19
|
+
<div role='none' className='p-2 border border-primary-500 rounded'>
|
|
20
|
+
<SpaceSettingsPanel {...args} space={space!} />
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
19
23
|
};
|
|
20
24
|
|
|
21
25
|
const meta: Meta = {
|
|
@@ -8,17 +8,17 @@ import { log } from '@dxos/log';
|
|
|
8
8
|
import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
9
9
|
import { useClient } from '@dxos/react-client';
|
|
10
10
|
import { type Space } from '@dxos/react-client/echo';
|
|
11
|
-
import {
|
|
12
|
-
import { DeprecatedFormInput } from '@dxos/react-ui-form';
|
|
13
|
-
import {
|
|
11
|
+
import { Input, useTranslation } from '@dxos/react-ui';
|
|
12
|
+
import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
|
|
13
|
+
import { HuePickerBlock } from '@dxos/react-ui-pickers';
|
|
14
14
|
|
|
15
15
|
import { SPACE_PLUGIN } from '../../meta';
|
|
16
16
|
|
|
17
|
-
export type SpaceSettingsPanelProps =
|
|
17
|
+
export type SpaceSettingsPanelProps = {
|
|
18
18
|
space: Space;
|
|
19
|
-
}
|
|
19
|
+
};
|
|
20
20
|
|
|
21
|
-
export const SpaceSettingsPanel = ({
|
|
21
|
+
export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
|
|
22
22
|
const { t } = useTranslation(SPACE_PLUGIN);
|
|
23
23
|
|
|
24
24
|
const client = useClient();
|
|
@@ -41,7 +41,7 @@ export const SpaceSettingsPanel = ({ classNames, space }: SpaceSettingsPanelProp
|
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
44
|
+
<DeprecatedFormContainer>
|
|
45
45
|
<DeprecatedFormInput label={t('name label')}>
|
|
46
46
|
<Input.TextInput
|
|
47
47
|
placeholder={t('unnamed space label')}
|
|
@@ -51,11 +51,18 @@ export const SpaceSettingsPanel = ({ classNames, space }: SpaceSettingsPanelProp
|
|
|
51
51
|
}}
|
|
52
52
|
/>
|
|
53
53
|
</DeprecatedFormInput>
|
|
54
|
+
<DeprecatedFormInput label={t('hue label')}>
|
|
55
|
+
<HuePickerBlock
|
|
56
|
+
hue={space.properties.hue}
|
|
57
|
+
onChangeHue={(nextHue) => (space.properties.hue = nextHue)}
|
|
58
|
+
onClickClear={() => (space.properties.hue = undefined)}
|
|
59
|
+
/>
|
|
60
|
+
</DeprecatedFormInput>
|
|
54
61
|
{edgeEnabled && (
|
|
55
62
|
<DeprecatedFormInput label={t('edge replication label')}>
|
|
56
63
|
<Input.Switch checked={edgeReplication} onCheckedChange={toggleEdgeReplication} />
|
|
57
64
|
</DeprecatedFormInput>
|
|
58
65
|
)}
|
|
59
|
-
</
|
|
66
|
+
</DeprecatedFormContainer>
|
|
60
67
|
);
|
|
61
68
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { useAppGraph } from '@dxos/app-framework';
|
|
8
8
|
import { QueryEdgeStatusResponse } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
9
|
import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
10
10
|
import { useClient } from '@dxos/react-client';
|
|
@@ -38,7 +38,7 @@ export const InlineSyncStatus = ({ space, open }: { space: Space; open?: boolean
|
|
|
38
38
|
// TODO(wittjosiah): If the attended node is deep in the graph and the graph is not fully loaded
|
|
39
39
|
// this will result in an empty path until the graph is connected.
|
|
40
40
|
// TODO(wittjosiah): Consider using this indicator for all open nodes instead of just attended.
|
|
41
|
-
const { graph } =
|
|
41
|
+
const { graph } = useAppGraph();
|
|
42
42
|
const attended = useAttended();
|
|
43
43
|
const startOfAttention = attended.at(-1);
|
|
44
44
|
const path = usePath(graph, startOfAttention);
|
|
@@ -66,8 +66,9 @@ export const SyncStatusIndicator = ({ state, saved }: { state: SpaceSyncStateMap
|
|
|
66
66
|
<StatusBar.Button title={title}>{icon}</StatusBar.Button>
|
|
67
67
|
</Popover.Trigger>
|
|
68
68
|
<Popover.Portal>
|
|
69
|
-
<Popover.Content
|
|
69
|
+
<Popover.Content>
|
|
70
70
|
<SyncStatusDetail state={state} summary={summary} debug={false} />
|
|
71
|
+
<Popover.Arrow />
|
|
71
72
|
</Popover.Content>
|
|
72
73
|
</Popover.Portal>
|
|
73
74
|
</Popover.Root>
|