@dxos/plugin-preview 0.8.4-main.67995b8 → 0.8.4-main.72ec0f3
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/chunk-CEWM5LJG.mjs +17 -0
- package/dist/lib/browser/chunk-CEWM5LJG.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +14 -10
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{preview-popover-2UCEZUQW.mjs → preview-popover-IAPAEKZL.mjs} +9 -13
- package/dist/lib/browser/preview-popover-IAPAEKZL.mjs.map +7 -0
- package/dist/lib/browser/react-surface-LRMZKOJS.mjs +498 -0
- package/dist/lib/browser/react-surface-LRMZKOJS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-Q5MUNELK.mjs +19 -0
- package/dist/lib/node-esm/chunk-Q5MUNELK.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +14 -10
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{preview-popover-OSHWR2YE.mjs → preview-popover-CH2LDYWM.mjs} +9 -13
- package/dist/lib/node-esm/preview-popover-CH2LDYWM.mjs.map +7 -0
- package/dist/lib/node-esm/react-surface-65UVGBIZ.mjs +499 -0
- package/dist/lib/node-esm/react-surface-65UVGBIZ.mjs.map +7 -0
- package/dist/types/src/PreviewPlugin.d.ts +1 -1
- package/dist/types/src/PreviewPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/preview-popover.d.ts +1 -1
- package/dist/types/src/capabilities/preview-popover.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/cards/OrganizationCard.d.ts +5 -0
- package/dist/types/src/cards/OrganizationCard.d.ts.map +1 -0
- package/dist/types/src/cards/PersonCard.d.ts +5 -0
- package/dist/types/src/cards/PersonCard.d.ts.map +1 -0
- package/dist/types/src/cards/ProjectCard.d.ts +5 -0
- package/dist/types/src/cards/ProjectCard.d.ts.map +1 -0
- package/dist/types/src/cards/TaskCard.d.ts +5 -0
- package/dist/types/src/cards/TaskCard.d.ts.map +1 -0
- package/dist/types/src/cards/index.d.ts +5 -0
- package/dist/types/src/cards/index.d.ts.map +1 -0
- package/dist/types/src/components/CardComponents.d.ts +16 -0
- package/dist/types/src/components/CardComponents.d.ts.map +1 -0
- package/dist/types/src/components/CardSubjectMenu.d.ts +8 -0
- package/dist/types/src/components/CardSubjectMenu.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/stories/Card.stories.d.ts +29 -0
- package/dist/types/src/stories/Card.stories.d.ts.map +1 -0
- package/dist/types/src/stories/testing.d.ts +18 -0
- package/dist/types/src/stories/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +6 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +10 -4
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -31
- package/src/PreviewPlugin.tsx +23 -24
- package/src/capabilities/preview-popover.ts +9 -14
- package/src/capabilities/react-surface.tsx +92 -98
- package/src/cards/OrganizationCard.tsx +34 -0
- package/src/cards/PersonCard.tsx +63 -0
- package/src/cards/ProjectCard.tsx +24 -0
- package/src/cards/TaskCard.tsx +46 -0
- package/src/cards/index.ts +8 -0
- package/src/components/CardComponents.tsx +67 -0
- package/src/components/CardSubjectMenu.tsx +103 -0
- package/src/components/index.ts +2 -3
- package/src/meta.ts +6 -3
- package/src/stories/Card.stories.tsx +62 -0
- package/src/stories/testing.tsx +114 -0
- package/src/translations.ts +6 -0
- package/src/types.ts +23 -5
- package/dist/lib/browser/chunk-Z73ENKLE.mjs +0 -14
- package/dist/lib/browser/chunk-Z73ENKLE.mjs.map +0 -7
- package/dist/lib/browser/preview-popover-2UCEZUQW.mjs.map +0 -7
- package/dist/lib/browser/react-surface-CZMUEWPV.mjs +0 -303
- package/dist/lib/browser/react-surface-CZMUEWPV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2ORSL4GJ.mjs +0 -16
- package/dist/lib/node-esm/chunk-2ORSL4GJ.mjs.map +0 -7
- package/dist/lib/node-esm/preview-popover-OSHWR2YE.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-IPZBISWS.mjs +0 -304
- package/dist/lib/node-esm/react-surface-IPZBISWS.mjs.map +0 -7
- package/dist/types/src/components/ContactCard.d.ts +0 -7
- package/dist/types/src/components/ContactCard.d.ts.map +0 -1
- package/dist/types/src/components/OrganizationCard.d.ts +0 -5
- package/dist/types/src/components/OrganizationCard.d.ts.map +0 -1
- package/dist/types/src/components/ProjectCard.d.ts +0 -5
- package/dist/types/src/components/ProjectCard.d.ts.map +0 -1
- package/dist/types/src/testing/ExtrinsicPreviews.stories.d.ts +0 -35
- package/dist/types/src/testing/ExtrinsicPreviews.stories.d.ts.map +0 -1
- package/dist/types/src/testing/IntrinsicPreviews.stories.d.ts +0 -35
- package/dist/types/src/testing/IntrinsicPreviews.stories.d.ts.map +0 -1
- package/dist/types/src/testing/PopoverPreviews.stories.d.ts +0 -35
- package/dist/types/src/testing/PopoverPreviews.stories.d.ts.map +0 -1
- package/dist/types/src/testing/util.d.ts +0 -80
- package/dist/types/src/testing/util.d.ts.map +0 -1
- package/src/components/ContactCard.tsx +0 -70
- package/src/components/OrganizationCard.tsx +0 -41
- package/src/components/ProjectCard.tsx +0 -20
- package/src/testing/ExtrinsicPreviews.stories.tsx +0 -55
- package/src/testing/IntrinsicPreviews.stories.tsx +0 -55
- package/src/testing/PopoverPreviews.stories.tsx +0 -55
- package/src/testing/util.tsx +0 -79
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-preview",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.72ec0f3",
|
|
4
4
|
"description": "Preview plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
+
"source": "./src/index.ts",
|
|
13
14
|
"types": "./dist/types/src/index.d.ts",
|
|
14
|
-
"browser": "./dist/lib/browser/index.mjs"
|
|
15
|
-
"source": "./src/index.ts"
|
|
15
|
+
"browser": "./dist/lib/browser/index.mjs"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -24,40 +24,44 @@
|
|
|
24
24
|
"src"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@effect-atom/atom-react": "^0.3.4",
|
|
27
28
|
"@preact-signals/safe-react": "^0.9.0",
|
|
28
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/plugin-attention": "0.8.4-main.
|
|
37
|
-
"@dxos/plugin-
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/plugin-
|
|
40
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
41
|
-
"@dxos/react-ui-
|
|
42
|
-
"@dxos/react-
|
|
43
|
-
"@dxos/react-ui-stack": "0.8.4-main.
|
|
44
|
-
"@dxos/react-ui-
|
|
45
|
-
"@dxos/react-ui-
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
29
|
+
"@dxos/app-framework": "0.8.4-main.72ec0f3",
|
|
30
|
+
"@dxos/client": "0.8.4-main.72ec0f3",
|
|
31
|
+
"@dxos/async": "0.8.4-main.72ec0f3",
|
|
32
|
+
"@dxos/app-graph": "0.8.4-main.72ec0f3",
|
|
33
|
+
"@dxos/keys": "0.8.4-main.72ec0f3",
|
|
34
|
+
"@dxos/lit-ui": "0.8.4-main.72ec0f3",
|
|
35
|
+
"@dxos/log": "0.8.4-main.72ec0f3",
|
|
36
|
+
"@dxos/echo": "0.8.4-main.72ec0f3",
|
|
37
|
+
"@dxos/plugin-attention": "0.8.4-main.72ec0f3",
|
|
38
|
+
"@dxos/plugin-client": "0.8.4-main.72ec0f3",
|
|
39
|
+
"@dxos/plugin-deck": "0.8.4-main.72ec0f3",
|
|
40
|
+
"@dxos/plugin-space": "0.8.4-main.72ec0f3",
|
|
41
|
+
"@dxos/react-ui": "0.8.4-main.72ec0f3",
|
|
42
|
+
"@dxos/react-ui-form": "0.8.4-main.72ec0f3",
|
|
43
|
+
"@dxos/react-client": "0.8.4-main.72ec0f3",
|
|
44
|
+
"@dxos/react-ui-stack": "0.8.4-main.72ec0f3",
|
|
45
|
+
"@dxos/react-ui-editor": "0.8.4-main.72ec0f3",
|
|
46
|
+
"@dxos/react-ui-table": "0.8.4-main.72ec0f3",
|
|
47
|
+
"@dxos/react-ui-theme": "0.8.4-main.72ec0f3",
|
|
48
|
+
"@dxos/schema": "0.8.4-main.72ec0f3",
|
|
49
|
+
"@dxos/types": "0.8.4-main.72ec0f3",
|
|
50
|
+
"@dxos/util": "0.8.4-main.72ec0f3",
|
|
51
|
+
"@dxos/react-ui-menu": "0.8.4-main.72ec0f3"
|
|
48
52
|
},
|
|
49
53
|
"devDependencies": {
|
|
50
|
-
"effect": "3.
|
|
51
|
-
"react": "~
|
|
52
|
-
"react-dom": "~
|
|
53
|
-
"vite": "
|
|
54
|
-
"@dxos/random": "0.8.4-main.
|
|
55
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
54
|
+
"effect": "3.18.3",
|
|
55
|
+
"react": "~19.2.0",
|
|
56
|
+
"react-dom": "~19.2.0",
|
|
57
|
+
"vite": "7.1.9",
|
|
58
|
+
"@dxos/random": "0.8.4-main.72ec0f3",
|
|
59
|
+
"@dxos/storybook-utils": "0.8.4-main.72ec0f3"
|
|
56
60
|
},
|
|
57
61
|
"peerDependencies": {
|
|
58
62
|
"effect": "^3.13.3",
|
|
59
|
-
"react": "
|
|
60
|
-
"react-dom": "
|
|
63
|
+
"react": "^19.0.0",
|
|
64
|
+
"react-dom": "^19.0.0"
|
|
61
65
|
},
|
|
62
66
|
"publishConfig": {
|
|
63
67
|
"access": "public"
|
package/src/PreviewPlugin.tsx
CHANGED
|
@@ -4,32 +4,31 @@
|
|
|
4
4
|
|
|
5
5
|
import { Capabilities, Events, contributes, defineModule, definePlugin } from '@dxos/app-framework';
|
|
6
6
|
import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
|
|
7
|
-
import {
|
|
7
|
+
import { Organization, Person } from '@dxos/types';
|
|
8
8
|
|
|
9
9
|
import { PreviewPopover, ReactSurface } from './capabilities';
|
|
10
10
|
import { meta } from './meta';
|
|
11
11
|
import { translations } from './translations';
|
|
12
12
|
|
|
13
|
-
export const PreviewPlugin = () =>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
]);
|
|
13
|
+
export const PreviewPlugin = definePlugin(meta, () => [
|
|
14
|
+
defineModule({
|
|
15
|
+
id: `${meta.id}/module/translations`,
|
|
16
|
+
activatesOn: Events.SetupTranslations,
|
|
17
|
+
activate: () => contributes(Capabilities.Translations, translations),
|
|
18
|
+
}),
|
|
19
|
+
defineModule({
|
|
20
|
+
id: `${meta.id}/module/schema`,
|
|
21
|
+
activatesOn: ClientEvents.SetupSchema,
|
|
22
|
+
activate: () => [contributes(ClientCapabilities.Schema, [Person.Person, Organization.Organization])],
|
|
23
|
+
}),
|
|
24
|
+
defineModule({
|
|
25
|
+
id: `${meta.id}/module/preview-popover`,
|
|
26
|
+
activatesOn: Events.Startup,
|
|
27
|
+
activate: PreviewPopover,
|
|
28
|
+
}),
|
|
29
|
+
defineModule({
|
|
30
|
+
id: `${meta.id}/module/react-surface`,
|
|
31
|
+
activatesOn: Events.SetupReactSurface,
|
|
32
|
+
activate: ReactSurface,
|
|
33
|
+
}),
|
|
34
|
+
]);
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Capabilities, LayoutAction, contributes, createIntent
|
|
5
|
+
import { Capabilities, LayoutAction, type PluginContext, contributes, createIntent } from '@dxos/app-framework';
|
|
6
6
|
import { addEventListener } from '@dxos/async';
|
|
7
|
-
import { type Client
|
|
8
|
-
import {
|
|
7
|
+
import { type Client } from '@dxos/client';
|
|
8
|
+
import { type Space, parseId } from '@dxos/client/echo';
|
|
9
9
|
import { DXN } from '@dxos/keys';
|
|
10
|
-
import { type DxRefTagActivate } from '@dxos/lit-ui';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
12
11
|
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
12
|
+
import { DX_ANCHOR_ACTIVATE, type DxAnchorActivate } from '@dxos/react-ui';
|
|
13
13
|
import { type PreviewLinkRef, type PreviewLinkTarget } from '@dxos/react-ui-editor';
|
|
14
14
|
|
|
15
15
|
const customEventOptions = { capture: true, passive: false };
|
|
@@ -20,21 +20,16 @@ const handlePreviewLookup = async (
|
|
|
20
20
|
{ ref, label }: PreviewLinkRef,
|
|
21
21
|
): Promise<PreviewLinkTarget | null> => {
|
|
22
22
|
try {
|
|
23
|
-
const
|
|
24
|
-
if (!dxn) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const object = await resolveRef(client, dxn, defaultSpace);
|
|
23
|
+
const object = await defaultSpace.db.ref(DXN.parse(ref)).load();
|
|
29
24
|
return { label, object };
|
|
30
|
-
} catch
|
|
25
|
+
} catch {
|
|
31
26
|
return null;
|
|
32
27
|
}
|
|
33
28
|
};
|
|
34
29
|
|
|
35
30
|
export default (context: PluginContext) => {
|
|
36
31
|
// TODO(wittjosiah): Factor out lookup handlers to other plugins to make not ECHO-specific.
|
|
37
|
-
const
|
|
32
|
+
const handleAnchorActivate = async ({ refId, label, trigger }: DxAnchorActivate) => {
|
|
38
33
|
const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);
|
|
39
34
|
const client = context.getCapability(ClientCapabilities.Client);
|
|
40
35
|
const [layout] = context.getCapabilities(Capabilities.Layout);
|
|
@@ -62,8 +57,8 @@ export default (context: PluginContext) => {
|
|
|
62
57
|
if (document.defaultView) {
|
|
63
58
|
cleanup = addEventListener(
|
|
64
59
|
document.defaultView,
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
DX_ANCHOR_ACTIVATE as any,
|
|
61
|
+
handleAnchorActivate,
|
|
67
62
|
customEventOptions,
|
|
68
63
|
);
|
|
69
64
|
} else {
|
|
@@ -2,137 +2,111 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Effect } from 'effect';
|
|
6
5
|
import React, { useCallback } from 'react';
|
|
7
6
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
createSurface,
|
|
15
|
-
useIntentDispatcher,
|
|
16
|
-
} from '@dxos/app-framework';
|
|
17
|
-
import { fullyQualifiedId, getSchema, getSpace } from '@dxos/client/echo';
|
|
18
|
-
import { Filter, Obj } from '@dxos/echo';
|
|
19
|
-
import { type JsonPath, setValue } from '@dxos/echo-schema';
|
|
20
|
-
import { AttentionAction } from '@dxos/plugin-attention/types';
|
|
21
|
-
import { ATTENDABLE_PATH_SEPARATOR, DeckAction } from '@dxos/plugin-deck/types';
|
|
22
|
-
import { useQuery, useSpace } from '@dxos/react-client/echo';
|
|
7
|
+
import { Capabilities, LayoutAction, contributes, createIntent, createSurface } from '@dxos/app-framework';
|
|
8
|
+
import { Surface, SurfaceCardRole, useIntentDispatcher } from '@dxos/app-framework/react';
|
|
9
|
+
import { getSchema, getSpace } from '@dxos/client/echo';
|
|
10
|
+
import { Obj } from '@dxos/echo';
|
|
11
|
+
import { type JsonPath, setValue } from '@dxos/echo/internal';
|
|
12
|
+
import { useActiveSpace } from '@dxos/plugin-space';
|
|
23
13
|
import { useTranslation } from '@dxos/react-ui';
|
|
24
14
|
import { Form } from '@dxos/react-ui-form';
|
|
25
15
|
import { Card } from '@dxos/react-ui-stack';
|
|
26
|
-
import { TableView } from '@dxos/react-ui-table/types';
|
|
27
16
|
import { descriptionMessage, mx } from '@dxos/react-ui-theme';
|
|
28
|
-
import {
|
|
17
|
+
import { type ProjectionModel } from '@dxos/schema';
|
|
18
|
+
import { Organization, Person, Project, Task } from '@dxos/types';
|
|
29
19
|
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
20
|
+
import { OrganizationCard, PersonCard, ProjectCard, TaskCard } from '../cards';
|
|
21
|
+
import { meta } from '../meta';
|
|
22
|
+
import { type CardPreviewProps } from '../types';
|
|
32
23
|
|
|
33
24
|
export default () =>
|
|
34
25
|
contributes(Capabilities.ReactSurface, [
|
|
35
26
|
//
|
|
36
27
|
// Specific schema types.
|
|
28
|
+
// TODO(burdon): Create helpers and factor out.
|
|
37
29
|
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
|
|
31
|
+
// TODO(burdon): Infer Role type.
|
|
32
|
+
createSurface<{ subject: Person.Person }>({
|
|
33
|
+
id: `${meta.id}/schema-popover--contact`,
|
|
34
|
+
role: SurfaceCardRole.literals as any,
|
|
35
|
+
filter: (data): data is { subject: Person.Person } => Obj.instanceOf(Person.Person, data.subject),
|
|
42
36
|
component: ({ data, role }) => {
|
|
43
|
-
const { dispatch } = useIntentDispatcher();
|
|
37
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
44
38
|
const space = getSpace(data.subject);
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Obj.instanceOf(TableView, view.presentation.target),
|
|
39
|
+
const activeSpace = useActiveSpace(); // TODO(burdon): Disambiguate with space?
|
|
40
|
+
const handleSelect = useCallback<NonNullable<CardPreviewProps['onSelect']>>(
|
|
41
|
+
(object) =>
|
|
42
|
+
dispatch(
|
|
43
|
+
createIntent(LayoutAction.Open, {
|
|
44
|
+
part: 'main',
|
|
45
|
+
subject: [Obj.getDXN(object).toString()],
|
|
46
|
+
options: {
|
|
47
|
+
workspace: space?.id,
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
),
|
|
51
|
+
[dispatch],
|
|
59
52
|
);
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
state: false,
|
|
71
|
-
anchorId: '',
|
|
72
|
-
},
|
|
73
|
-
}),
|
|
74
|
-
);
|
|
75
|
-
if (view) {
|
|
76
|
-
const id = fullyQualifiedId(view);
|
|
77
|
-
yield* dispatch(
|
|
78
|
-
createIntent(LayoutAction.Open, {
|
|
79
|
-
part: 'main',
|
|
80
|
-
subject: [id],
|
|
81
|
-
options: { workspace: space?.id },
|
|
82
|
-
}),
|
|
83
|
-
);
|
|
84
|
-
yield* dispatch(
|
|
85
|
-
createIntent(DeckAction.ChangeCompanion, {
|
|
86
|
-
primary: id,
|
|
87
|
-
companion: [id, 'selected-objects'].join(ATTENDABLE_PATH_SEPARATOR),
|
|
88
|
-
}),
|
|
89
|
-
);
|
|
90
|
-
yield* dispatch(
|
|
91
|
-
createIntent(AttentionAction.Select, {
|
|
92
|
-
contextId: id,
|
|
93
|
-
selection: { mode: 'multi', ids: [org.id] },
|
|
94
|
-
}),
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
}).pipe(Effect.runPromise),
|
|
98
|
-
[dispatch, currentSpaceOrgs, currentSpaceOrgTable, defaultSpaceOrgTable],
|
|
54
|
+
return (
|
|
55
|
+
<PersonCard
|
|
56
|
+
role={role as SurfaceCardRole}
|
|
57
|
+
subject={data.subject}
|
|
58
|
+
activeSpace={activeSpace}
|
|
59
|
+
onSelect={handleSelect}
|
|
60
|
+
>
|
|
61
|
+
{role === 'card--popover' && <Surface role='related' data={data} />}
|
|
62
|
+
</PersonCard>
|
|
99
63
|
);
|
|
100
|
-
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
createSurface({
|
|
67
|
+
id: `${meta.id}/schema-popover--organization`,
|
|
68
|
+
role: SurfaceCardRole.literals as any,
|
|
69
|
+
filter: (data): data is { subject: Organization.Organization } =>
|
|
70
|
+
Obj.instanceOf(Organization.Organization, data.subject),
|
|
71
|
+
component: ({ data, role }) => {
|
|
72
|
+
const activeSpace = useActiveSpace();
|
|
101
73
|
return (
|
|
102
|
-
<
|
|
74
|
+
<OrganizationCard role={role as SurfaceCardRole} subject={data.subject} activeSpace={activeSpace}>
|
|
103
75
|
{role === 'card--popover' && <Surface role='related' data={data} />}
|
|
104
|
-
</
|
|
76
|
+
</OrganizationCard>
|
|
105
77
|
);
|
|
106
78
|
},
|
|
107
79
|
}),
|
|
108
80
|
createSurface({
|
|
109
|
-
id: `${
|
|
110
|
-
role:
|
|
111
|
-
filter: (data): data is { subject:
|
|
112
|
-
component: ({ data, role }) =>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
),
|
|
81
|
+
id: `${meta.id}/schema-popover--project`,
|
|
82
|
+
role: SurfaceCardRole.literals as any,
|
|
83
|
+
filter: (data): data is { subject: Project.Project } => Obj.instanceOf(Project.Project, data.subject),
|
|
84
|
+
component: ({ data, role }) => {
|
|
85
|
+
const activeSpace = useActiveSpace();
|
|
86
|
+
return <ProjectCard subject={data.subject} role={role as SurfaceCardRole} activeSpace={activeSpace} />;
|
|
87
|
+
},
|
|
117
88
|
}),
|
|
118
89
|
createSurface({
|
|
119
|
-
id: `${
|
|
120
|
-
role:
|
|
121
|
-
filter: (data): data is { subject:
|
|
122
|
-
component: ({ data, role }) =>
|
|
90
|
+
id: `${meta.id}/schema-popover--task`,
|
|
91
|
+
role: SurfaceCardRole.literals as any,
|
|
92
|
+
filter: (data): data is { subject: Task.Task } => Obj.instanceOf(Task.Task, data.subject),
|
|
93
|
+
component: ({ data, role }) => {
|
|
94
|
+
return <TaskCard subject={data.subject} role={role as SurfaceCardRole} />;
|
|
95
|
+
},
|
|
123
96
|
}),
|
|
124
97
|
|
|
125
98
|
//
|
|
126
99
|
// Fallback for any object.
|
|
127
100
|
//
|
|
101
|
+
|
|
128
102
|
createSurface({
|
|
129
|
-
id: `${
|
|
130
|
-
role:
|
|
103
|
+
id: `${meta.id}/fallback-popover`,
|
|
104
|
+
role: SurfaceCardRole.literals as any,
|
|
131
105
|
position: 'fallback',
|
|
132
|
-
filter: (data): data is { subject: Obj.Any } => Obj.isObject(data.subject),
|
|
106
|
+
filter: (data): data is { subject: Obj.Any; projection?: ProjectionModel } => Obj.isObject(data.subject),
|
|
133
107
|
component: ({ data, role }) => {
|
|
134
108
|
const schema = getSchema(data.subject);
|
|
135
|
-
const { t } = useTranslation(
|
|
109
|
+
const { t } = useTranslation(meta.id);
|
|
136
110
|
if (!schema) {
|
|
137
111
|
// TODO(burdon): Use Alert.
|
|
138
112
|
return <p className={mx(descriptionMessage)}>{t('unable to create preview message')}</p>;
|
|
@@ -149,15 +123,35 @@ export default () =>
|
|
|
149
123
|
return (
|
|
150
124
|
<Card.SurfaceRoot role={role}>
|
|
151
125
|
<Form
|
|
126
|
+
id={data.subject.id}
|
|
152
127
|
schema={schema}
|
|
128
|
+
projection={data.projection}
|
|
153
129
|
values={data.subject}
|
|
154
|
-
readonly={role === 'card--popover'}
|
|
130
|
+
readonly={role === 'card--popover' ? 'static' : false}
|
|
155
131
|
onSave={handleSave}
|
|
156
132
|
autoSave
|
|
157
|
-
{...(role === 'card--intrinsic' && {
|
|
133
|
+
{...(role === 'card--intrinsic' && {
|
|
134
|
+
outerSpacing: 'blockStart-0',
|
|
135
|
+
})}
|
|
158
136
|
/>
|
|
159
137
|
</Card.SurfaceRoot>
|
|
160
138
|
);
|
|
161
139
|
},
|
|
162
140
|
}),
|
|
141
|
+
|
|
142
|
+
createSurface({
|
|
143
|
+
id: `${meta.id}/section`,
|
|
144
|
+
role: ['section'],
|
|
145
|
+
position: 'fallback',
|
|
146
|
+
filter: (data): data is { subject: Obj.Any } => Obj.isObject(data.subject),
|
|
147
|
+
component: ({ data }) => {
|
|
148
|
+
return (
|
|
149
|
+
<div role='none' className='flex is-full justify-center'>
|
|
150
|
+
<div role='none' className='pbs-2 pbe-2 card-min-width card-max-width'>
|
|
151
|
+
<Surface role='card' data={data} limit={1} />
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
163
157
|
]);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Card } from '@dxos/react-ui-stack';
|
|
8
|
+
import { type Organization } from '@dxos/types';
|
|
9
|
+
|
|
10
|
+
import { CardHeader, CardLink } from '../components';
|
|
11
|
+
import { type CardPreviewProps } from '../types';
|
|
12
|
+
|
|
13
|
+
export const OrganizationCard = ({
|
|
14
|
+
children,
|
|
15
|
+
subject,
|
|
16
|
+
role,
|
|
17
|
+
activeSpace,
|
|
18
|
+
}: CardPreviewProps<Organization.Organization>) => {
|
|
19
|
+
const { name, image, description, website } = subject;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Card.SurfaceRoot id={subject.id} role={role}>
|
|
23
|
+
<Card.Poster
|
|
24
|
+
alt={name ?? ''}
|
|
25
|
+
{...(image ? { image } : { icon: 'ph--building-office--regular' })}
|
|
26
|
+
classNames={!image && 'opacity-50'}
|
|
27
|
+
/>
|
|
28
|
+
<CardHeader label={name} subject={subject} activeSpace={activeSpace} />
|
|
29
|
+
{description && <Card.Text classNames='line-clamp-2'>{description}</Card.Text>}
|
|
30
|
+
{website && <CardLink label={website} href={website} />}
|
|
31
|
+
{children}
|
|
32
|
+
</Card.SurfaceRoot>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { Fragment } from 'react';
|
|
6
|
+
|
|
7
|
+
import { Avatar, Icon } from '@dxos/react-ui';
|
|
8
|
+
import { Card, cardHeading, cardText } from '@dxos/react-ui-stack';
|
|
9
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
10
|
+
import { type Person } from '@dxos/types';
|
|
11
|
+
|
|
12
|
+
import { CardRow, CardSubjectMenu, gridRow } from '../components';
|
|
13
|
+
import { type CardPreviewProps } from '../types';
|
|
14
|
+
|
|
15
|
+
export const PersonCard = ({ children, role, subject, activeSpace, onSelect }: CardPreviewProps<Person.Person>) => {
|
|
16
|
+
const { fullName, image, organization: { target: organization } = {}, emails = [] } = subject;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Card.SurfaceRoot id={subject.id} role={role}>
|
|
20
|
+
<Avatar.Root>
|
|
21
|
+
<Card.Text role='group' classNames={mx('grid gap-2 grid-cols-[1fr_min-content]')}>
|
|
22
|
+
<div role='none' className={mx(gridRow, 'grid-rows-2')}>
|
|
23
|
+
{activeSpace ? <CardSubjectMenu subject={subject} activeSpace={activeSpace} /> : <div />}
|
|
24
|
+
<Avatar.Label asChild>
|
|
25
|
+
<h2 className={mx(cardHeading, 'grow truncate')}>{fullName}</h2>
|
|
26
|
+
</Avatar.Label>
|
|
27
|
+
</div>
|
|
28
|
+
<Avatar.Content
|
|
29
|
+
imgSrc={image}
|
|
30
|
+
icon='ph--user--regular'
|
|
31
|
+
size={16}
|
|
32
|
+
classNames={['text-subdued', !image && 'opacity-50']}
|
|
33
|
+
hue='neutral'
|
|
34
|
+
variant='square'
|
|
35
|
+
/>
|
|
36
|
+
</Card.Text>
|
|
37
|
+
</Avatar.Root>
|
|
38
|
+
{organization?.name && (
|
|
39
|
+
<CardRow
|
|
40
|
+
icon='ph--buildings--regular'
|
|
41
|
+
label={organization.name}
|
|
42
|
+
onClick={onSelect ? () => onSelect(organization) : undefined}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
{emails.length > 0 && (
|
|
46
|
+
<dl className={mx(cardText, gridRow, '[&_dt]:text-subdued [&_dt]:pbs-0.5 [&_dd]:min-is-0')}>
|
|
47
|
+
{emails.map(({ label, value }) => (
|
|
48
|
+
<Fragment key={value}>
|
|
49
|
+
<dt>
|
|
50
|
+
<span className='sr-only'>{label}</span>
|
|
51
|
+
<Icon icon='ph--at--regular' size={5} />
|
|
52
|
+
</dt>
|
|
53
|
+
<dd key={value} className='col-span-2 break-words'>
|
|
54
|
+
{value}
|
|
55
|
+
</dd>
|
|
56
|
+
</Fragment>
|
|
57
|
+
))}
|
|
58
|
+
</dl>
|
|
59
|
+
)}
|
|
60
|
+
{children}
|
|
61
|
+
</Card.SurfaceRoot>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Obj } from '@dxos/echo';
|
|
8
|
+
import { Card } from '@dxos/react-ui-stack';
|
|
9
|
+
import { type Project } from '@dxos/types';
|
|
10
|
+
|
|
11
|
+
import { CardHeader } from '../components';
|
|
12
|
+
import { type CardPreviewProps } from '../types';
|
|
13
|
+
|
|
14
|
+
export const ProjectCard = ({ subject, role, activeSpace }: CardPreviewProps<Project.Project>) => {
|
|
15
|
+
const { name, image, description } = subject;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Card.SurfaceRoot id={subject.id} role={role}>
|
|
19
|
+
{image && <Card.Poster image={image} alt={Obj.getLabel(subject) ?? ''} aspect='auto' />}
|
|
20
|
+
<CardHeader label={name} subject={subject} activeSpace={activeSpace} />
|
|
21
|
+
{description && <Card.Text classNames='line-clamp-2'>{description}</Card.Text>}
|
|
22
|
+
</Card.SurfaceRoot>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { type PropertyMetaAnnotation, PropertyMetaAnnotationId } from '@dxos/echo/internal';
|
|
9
|
+
import { Card, cardNoSpacing, cardSpacing } from '@dxos/react-ui-stack';
|
|
10
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
11
|
+
import { Task } from '@dxos/types';
|
|
12
|
+
|
|
13
|
+
import { CardSubjectMenu } from '../components';
|
|
14
|
+
import { type CardPreviewProps } from '../types';
|
|
15
|
+
|
|
16
|
+
// TODO(thure): Should this move upstream as a helper? Is there an easier way to get options?
|
|
17
|
+
const getActiveStatusOption = (status?: string) => {
|
|
18
|
+
const properties = SchemaAST.getPropertySignatures(Task.Task.ast);
|
|
19
|
+
const statusProperty = properties.find((p) => p.name === 'status');
|
|
20
|
+
const statusMeta = SchemaAST.getAnnotation<PropertyMetaAnnotation>(PropertyMetaAnnotationId)(
|
|
21
|
+
// TODO(thure): Typescript asserts `.type` doesn’t have `.types`, but in runtime it does.
|
|
22
|
+
(statusProperty!.type as any).types[0],
|
|
23
|
+
);
|
|
24
|
+
const options = // TODO(thure): Typescript asserts `statusMeta` doesn’t have `.value`, but in runtime it does.
|
|
25
|
+
(statusMeta as any).value.singleSelect.options as { id: string; title: string; color: string }[];
|
|
26
|
+
return options.find(({ id }) => id === status);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const TaskCard = ({ subject, role, activeSpace }: CardPreviewProps<Task.Task>) => {
|
|
30
|
+
const { title, status } = subject;
|
|
31
|
+
const statusOption = getActiveStatusOption(status);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Card.SurfaceRoot id={subject.id} role={role}>
|
|
35
|
+
<div role='none' className={mx('flex items-center gap-2', cardSpacing)}>
|
|
36
|
+
<Card.Heading classNames={[cardNoSpacing, 'min-is-0 flex-1 truncate']}>{title}</Card.Heading>
|
|
37
|
+
{statusOption && (
|
|
38
|
+
<span className='dx-tag' data-hue={statusOption.color}>
|
|
39
|
+
{statusOption.title}
|
|
40
|
+
</span>
|
|
41
|
+
)}
|
|
42
|
+
<CardSubjectMenu subject={subject} activeSpace={activeSpace} />
|
|
43
|
+
</div>
|
|
44
|
+
</Card.SurfaceRoot>
|
|
45
|
+
);
|
|
46
|
+
};
|