@dxos/plugin-registry 0.13.0 → 0.14.0
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/chunk-BaseRegistryArticle.mjs +6 -7
- package/dist/lib/chunk-BaseRegistryArticle.mjs.map +1 -1
- package/dist/lib/chunk-PluginArticle.mjs +2 -2
- package/dist/lib/chunk-PluginArticle.mjs.map +1 -1
- package/dist/lib/chunk-PublicRegistryArticle.mjs +2 -2
- package/dist/lib/chunk-PublicRegistryArticle.mjs.map +1 -1
- package/dist/lib/chunk-RegistryArticle.mjs +2 -2
- package/dist/lib/chunk-RegistryArticle.mjs.map +1 -1
- package/dist/lib/chunk-react-surface.mjs +19 -7
- package/dist/lib/chunk-react-surface.mjs.map +1 -1
- package/dist/lib/components.mjs +31 -19
- package/dist/lib/components.mjs.map +1 -1
- package/dist/types/src/capabilities/RegistryCategoryArticle.d.ts +2 -1
- package/dist/types/src/capabilities/RegistryCategoryArticle.d.ts.map +1 -1
- package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts.map +1 -1
- package/dist/types/src/components/PluginList/PluginItem.d.ts +2 -1
- package/dist/types/src/components/PluginList/PluginItem.d.ts.map +1 -1
- package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts +1 -2
- package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts.map +1 -1
- package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts +1 -1
- package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts.map +1 -1
- package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts +1 -1
- package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -30
- package/src/capabilities/RegistryCategoryArticle.tsx +8 -2
- package/src/capabilities/react-surface.ts +5 -5
- package/src/components/PluginDetail/PluginDetail.tsx +17 -15
- package/src/components/PluginFailureBadge/PluginFailureBadge.tsx +3 -2
- package/src/components/PluginList/PluginItem.tsx +7 -3
- package/src/containers/BaseRegistryArticle/BaseRegistryArticle.tsx +4 -13
- package/src/containers/PluginArticle/PluginArticle.tsx +1 -1
- package/src/containers/PublicRegistryArticle/PublicRegistryArticle.tsx +3 -3
- package/src/containers/RegistryArticle/RegistryArticle.tsx +3 -3
- package/src/hooks/usePluginActions.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-registry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Braneframe plugin gallery",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -122,29 +122,29 @@
|
|
|
122
122
|
"dependencies": {
|
|
123
123
|
"@effect/atom-react": "4.0.0",
|
|
124
124
|
"yaml": "^2.8.2",
|
|
125
|
-
"@dxos/app-framework": "0.
|
|
126
|
-
"@dxos/app-graph": "0.
|
|
127
|
-
"@dxos/app-toolkit": "0.
|
|
128
|
-
"@dxos/cli-util": "0.
|
|
129
|
-
"@dxos/client": "0.
|
|
130
|
-
"@dxos/client-protocol": "0.
|
|
131
|
-
"@dxos/compute": "0.
|
|
132
|
-
"@dxos/context": "0.
|
|
133
|
-
"@dxos/echo": "0.
|
|
134
|
-
"@dxos/edge-client": "0.
|
|
135
|
-
"@dxos/effect": "0.
|
|
136
|
-
"@dxos/errors": "0.
|
|
137
|
-
"@dxos/graph": "0.
|
|
138
|
-
"@dxos/keys": "0.
|
|
139
|
-
"@dxos/link": "0.
|
|
140
|
-
"@dxos/log": "0.
|
|
141
|
-
"@dxos/plugin-client": "0.
|
|
142
|
-
"@dxos/plugin-graph": "0.
|
|
143
|
-
"@dxos/plugin-observability": "0.
|
|
144
|
-
"@dxos/protocols": "0.
|
|
145
|
-
"@dxos/react-ui-form": "0.
|
|
146
|
-
"@dxos/react-ui-markdown": "0.
|
|
147
|
-
"@dxos/util": "0.
|
|
125
|
+
"@dxos/app-framework": "0.14.0",
|
|
126
|
+
"@dxos/app-graph": "0.14.0",
|
|
127
|
+
"@dxos/app-toolkit": "0.14.0",
|
|
128
|
+
"@dxos/cli-util": "0.14.0",
|
|
129
|
+
"@dxos/client": "0.14.0",
|
|
130
|
+
"@dxos/client-protocol": "0.14.0",
|
|
131
|
+
"@dxos/compute": "0.14.0",
|
|
132
|
+
"@dxos/context": "0.14.0",
|
|
133
|
+
"@dxos/echo": "0.14.0",
|
|
134
|
+
"@dxos/edge-client": "0.14.0",
|
|
135
|
+
"@dxos/effect": "0.14.0",
|
|
136
|
+
"@dxos/errors": "0.14.0",
|
|
137
|
+
"@dxos/graph": "0.14.0",
|
|
138
|
+
"@dxos/keys": "0.14.0",
|
|
139
|
+
"@dxos/link": "0.14.0",
|
|
140
|
+
"@dxos/log": "0.14.0",
|
|
141
|
+
"@dxos/plugin-client": "0.14.0",
|
|
142
|
+
"@dxos/plugin-graph": "0.14.0",
|
|
143
|
+
"@dxos/plugin-observability": "0.14.0",
|
|
144
|
+
"@dxos/protocols": "0.14.0",
|
|
145
|
+
"@dxos/react-ui-form": "0.14.0",
|
|
146
|
+
"@dxos/react-ui-markdown": "0.14.0",
|
|
147
|
+
"@dxos/util": "0.14.0"
|
|
148
148
|
},
|
|
149
149
|
"devDependencies": {
|
|
150
150
|
"@effect/atom-react": "4.0.0",
|
|
@@ -155,18 +155,18 @@
|
|
|
155
155
|
"react": "~19.2.7",
|
|
156
156
|
"react-dom": "~19.2.7",
|
|
157
157
|
"vite": "^8.2.2",
|
|
158
|
-
"@dxos/plugin-testing": "0.
|
|
159
|
-
"@dxos/random": "0.
|
|
160
|
-
"@dxos/react-ui": "0.
|
|
161
|
-
"@dxos/ui-theme": "0.
|
|
158
|
+
"@dxos/plugin-testing": "0.14.0",
|
|
159
|
+
"@dxos/random": "0.14.0",
|
|
160
|
+
"@dxos/react-ui": "0.14.0",
|
|
161
|
+
"@dxos/ui-theme": "0.14.0"
|
|
162
162
|
},
|
|
163
163
|
"peerDependencies": {
|
|
164
164
|
"@effect/atom-react": "4.0.0",
|
|
165
165
|
"effect": "4.0.0",
|
|
166
166
|
"react": "~19.2.7",
|
|
167
167
|
"react-dom": "~19.2.7",
|
|
168
|
-
"@dxos/react-ui": "^0.
|
|
169
|
-
"@dxos/ui-theme": "^0.
|
|
168
|
+
"@dxos/react-ui": "^0.14.0",
|
|
169
|
+
"@dxos/ui-theme": "^0.14.0"
|
|
170
170
|
},
|
|
171
171
|
"publishConfig": {
|
|
172
172
|
"access": "public"
|
|
@@ -29,6 +29,7 @@ const useCategoryPredicate = (category: string): PluginPredicate => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export type RegistryCategoryArticleProps = {
|
|
32
|
+
contextId: string;
|
|
32
33
|
category: string;
|
|
33
34
|
};
|
|
34
35
|
|
|
@@ -37,7 +38,7 @@ export type RegistryCategoryArticleProps = {
|
|
|
37
38
|
* `usePluginManager` + `useRegistryPlugins` + `useAutoTags` wiring shared by every category surface,
|
|
38
39
|
* none of which can live in a surface's `props` mapper.
|
|
39
40
|
*/
|
|
40
|
-
export const RegistryCategoryArticle = ({ category }: RegistryCategoryArticleProps) => {
|
|
41
|
+
export const RegistryCategoryArticle = ({ contextId, category }: RegistryCategoryArticleProps) => {
|
|
41
42
|
const manager = PluginManagerProvider.usePluginManager();
|
|
42
43
|
const filter = useCategoryPredicate(category);
|
|
43
44
|
const { entries } = useRegistryPlugins();
|
|
@@ -46,6 +47,11 @@ export const RegistryCategoryArticle = ({ category }: RegistryCategoryArticlePro
|
|
|
46
47
|
const filtered = useMemo(() => manager.getPlugins().filter(filter), [manager, filter]);
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
|
-
<RegistryArticle
|
|
50
|
+
<RegistryArticle
|
|
51
|
+
contextId={contextId}
|
|
52
|
+
plugins={filtered}
|
|
53
|
+
extraTagsById={extraTagsById}
|
|
54
|
+
deviceOnlyIds={deviceOnlyIds}
|
|
55
|
+
/>
|
|
50
56
|
);
|
|
51
57
|
};
|
|
@@ -26,7 +26,7 @@ export default Capability.makeModule(({ externalPlugins = true }: RegistryPlugin
|
|
|
26
26
|
id: 'registry',
|
|
27
27
|
filter: AppSurface.literal(AppSurface.Article, 'registry'),
|
|
28
28
|
component: PublicRegistryArticle,
|
|
29
|
-
props: () => ({
|
|
29
|
+
props: ({ data: { attendableId } }) => ({ contextId: attendableId }),
|
|
30
30
|
}),
|
|
31
31
|
Surface.create({
|
|
32
32
|
id: LOAD_PLUGIN_DIALOG,
|
|
@@ -48,25 +48,25 @@ export default Capability.makeModule(({ externalPlugins = true }: RegistryPlugin
|
|
|
48
48
|
id: 'bundled',
|
|
49
49
|
filter: AppSurface.literal(AppSurface.Article, 'bundled'),
|
|
50
50
|
component: RegistryCategoryArticle,
|
|
51
|
-
props: () => ({ category: 'bundled' }),
|
|
51
|
+
props: ({ data: { attendableId } }) => ({ contextId: attendableId, category: 'bundled' }),
|
|
52
52
|
}),
|
|
53
53
|
Surface.create({
|
|
54
54
|
id: 'installed',
|
|
55
55
|
filter: AppSurface.literal(AppSurface.Article, 'installed'),
|
|
56
56
|
component: RegistryCategoryArticle,
|
|
57
|
-
props: () => ({ category: 'installed' }),
|
|
57
|
+
props: ({ data: { attendableId } }) => ({ contextId: attendableId, category: 'installed' }),
|
|
58
58
|
}),
|
|
59
59
|
Surface.create({
|
|
60
60
|
id: 'recommended',
|
|
61
61
|
filter: AppSurface.literal(AppSurface.Article, 'recommended'),
|
|
62
62
|
component: RegistryCategoryArticle,
|
|
63
|
-
props: () => ({ category: 'recommended' }),
|
|
63
|
+
props: ({ data: { attendableId } }) => ({ contextId: attendableId, category: 'recommended' }),
|
|
64
64
|
}),
|
|
65
65
|
Surface.create({
|
|
66
66
|
id: 'labs',
|
|
67
67
|
filter: AppSurface.literal(AppSurface.Article, 'labs'),
|
|
68
68
|
component: RegistryCategoryArticle,
|
|
69
|
-
props: () => ({ category: 'labs' }),
|
|
69
|
+
props: ({ data: { attendableId } }) => ({ contextId: attendableId, category: 'labs' }),
|
|
70
70
|
}),
|
|
71
71
|
Surface.create({
|
|
72
72
|
id: 'pluginDetails',
|
|
@@ -180,10 +180,10 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
180
180
|
/>
|
|
181
181
|
|
|
182
182
|
<Layout.Grid cols={['fill', 'min']} classNames='row-start-1 col-start-2 col-span-2 gap-x-3 w-full pt-1'>
|
|
183
|
-
<
|
|
183
|
+
<Layout.Flex align='center' gap='sm'>
|
|
184
184
|
<h2 className='text-xl'>{name}</h2>
|
|
185
185
|
{failure && <PluginFailureBadge failure={failure} size='lg' />}
|
|
186
|
-
</
|
|
186
|
+
</Layout.Flex>
|
|
187
187
|
{onInstall ? (
|
|
188
188
|
<Button.Root size='md' variant='primary' disabled={installing} onClick={onInstall}>
|
|
189
189
|
{installing ? t('installing.label') : t('install.label')}
|
|
@@ -197,14 +197,14 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
197
197
|
/>
|
|
198
198
|
</Field.Root>
|
|
199
199
|
)}
|
|
200
|
-
<
|
|
200
|
+
<Layout.Flex align='center' gap='xs' classNames='pt-0.5 text-sm text-fg-muted'>
|
|
201
201
|
{slug}
|
|
202
202
|
{author && (
|
|
203
203
|
<span className='dx-tag dx-tag-inline' data-hue='info'>
|
|
204
204
|
{author}
|
|
205
205
|
</span>
|
|
206
206
|
)}
|
|
207
|
-
</
|
|
207
|
+
</Layout.Flex>
|
|
208
208
|
</Layout.Grid>
|
|
209
209
|
|
|
210
210
|
{scope && (
|
|
@@ -242,7 +242,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
242
242
|
<Section.Root>
|
|
243
243
|
<Section.Heading title={t('resources.label')} />
|
|
244
244
|
<Section.Body>
|
|
245
|
-
<
|
|
245
|
+
<Layout.Flex gap='md' align='center'>
|
|
246
246
|
{homePage && (
|
|
247
247
|
<Typography.Link href={homePage} classNames='text-sm text-fg-muted'>
|
|
248
248
|
{t('home-page.label')}
|
|
@@ -266,7 +266,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
266
266
|
)}
|
|
267
267
|
|
|
268
268
|
{onOpenSpec && <Chip id={slug} name={t('open-spec.label')} onClick={onOpenSpec} />}
|
|
269
|
-
</
|
|
269
|
+
</Layout.Flex>
|
|
270
270
|
</Section.Body>
|
|
271
271
|
</Section.Root>
|
|
272
272
|
|
|
@@ -274,7 +274,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
274
274
|
<Section.Root>
|
|
275
275
|
<Section.Heading title={t('dependencies.label')} />
|
|
276
276
|
<Section.Body>
|
|
277
|
-
<
|
|
277
|
+
<Layout.Flex wrap gap='xs'>
|
|
278
278
|
{dependencies.map((depId) => (
|
|
279
279
|
<Chip
|
|
280
280
|
key={depId}
|
|
@@ -283,7 +283,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
283
283
|
onClick={onNavigateToPlugin}
|
|
284
284
|
/>
|
|
285
285
|
))}
|
|
286
|
-
</
|
|
286
|
+
</Layout.Flex>
|
|
287
287
|
</Section.Body>
|
|
288
288
|
</Section.Root>
|
|
289
289
|
)}
|
|
@@ -292,7 +292,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
292
292
|
<Section.Root>
|
|
293
293
|
<Section.Heading title={t('dependents.label')} />
|
|
294
294
|
<Section.Body>
|
|
295
|
-
<
|
|
295
|
+
<Layout.Flex wrap gap='xs'>
|
|
296
296
|
{dependents.map((dependentId) => (
|
|
297
297
|
<Chip
|
|
298
298
|
key={dependentId}
|
|
@@ -301,7 +301,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
301
301
|
onClick={onNavigateToPlugin}
|
|
302
302
|
/>
|
|
303
303
|
))}
|
|
304
|
-
</
|
|
304
|
+
</Layout.Flex>
|
|
305
305
|
</Section.Body>
|
|
306
306
|
</Section.Root>
|
|
307
307
|
)}
|
|
@@ -310,7 +310,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
310
310
|
<Section.Root>
|
|
311
311
|
<Section.Heading title={t('versions.label')} />
|
|
312
312
|
<Section.Body>
|
|
313
|
-
<
|
|
313
|
+
<Layout.Flex gap='sm' align='center'>
|
|
314
314
|
<Select.Root
|
|
315
315
|
items={versionItems}
|
|
316
316
|
value={selectedVersionTag ? [selectedVersionTag] : []}
|
|
@@ -333,13 +333,13 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
333
333
|
{installing ? t('installing.label') : t('install-version.label')}
|
|
334
334
|
</Button.Root>
|
|
335
335
|
)}
|
|
336
|
-
</
|
|
336
|
+
</Layout.Flex>
|
|
337
337
|
</Section.Body>
|
|
338
338
|
</Section.Root>
|
|
339
339
|
)}
|
|
340
340
|
|
|
341
341
|
{(onUninstall || (hasUpdate && onUpdate) || updating) && (
|
|
342
|
-
<
|
|
342
|
+
<Layout.Flex gap='sm' classNames='col-start-2 col-span-2'>
|
|
343
343
|
{updating ? (
|
|
344
344
|
<Button.Root variant='primary' disabled>
|
|
345
345
|
{t('updating.label')}
|
|
@@ -350,7 +350,7 @@ export const PluginDetail = Util.composable<HTMLDivElement, PluginDetailProps>(
|
|
|
350
350
|
</Button.Root>
|
|
351
351
|
) : null}
|
|
352
352
|
{onUninstall && <Button.Root onClick={onUninstall}>{t('uninstall.label')}</Button.Root>}
|
|
353
|
-
</
|
|
353
|
+
</Layout.Flex>
|
|
354
354
|
)}
|
|
355
355
|
</Layout.Grid>
|
|
356
356
|
</ScrollArea.Viewport>
|
|
@@ -368,7 +368,9 @@ const SectionHeading = ({ title }: { title: string }) => (
|
|
|
368
368
|
);
|
|
369
369
|
|
|
370
370
|
const SectionBody = ({ classNames, children }: Util.ThemedClassName<PropsWithChildren>) => (
|
|
371
|
-
<
|
|
371
|
+
<Layout.Flex column gap='sm' classNames={['col-start-2', classNames]}>
|
|
372
|
+
{children}
|
|
373
|
+
</Layout.Flex>
|
|
372
374
|
);
|
|
373
375
|
|
|
374
376
|
const Section = {
|
|
@@ -7,6 +7,7 @@ import React, { type ComponentPropsWithoutRef } from 'react';
|
|
|
7
7
|
import type * as PluginManager from '@dxos/app-framework/PluginManager';
|
|
8
8
|
import * as Button from '@dxos/react-ui/Button';
|
|
9
9
|
import * as Hooks from '@dxos/react-ui/Hooks';
|
|
10
|
+
import * as Layout from '@dxos/react-ui/Layout';
|
|
10
11
|
import * as Popover from '@dxos/react-ui/Popover';
|
|
11
12
|
|
|
12
13
|
import { meta } from '#meta';
|
|
@@ -43,7 +44,7 @@ export const PluginFailureBadge = ({ failure, size }: PluginFailureBadgeProps) =
|
|
|
43
44
|
</Popover.Trigger>
|
|
44
45
|
<Popover.Content>
|
|
45
46
|
<Popover.Body>
|
|
46
|
-
<
|
|
47
|
+
<Layout.Flex column gap='xs' classNames='px-3 py-2 min-w-[18rem] max-w-[28rem]'>
|
|
47
48
|
<p className='font-medium text-sm'>
|
|
48
49
|
{t('failure-title.label', {
|
|
49
50
|
phase: failure.phase === 'load' ? t('failure-phase-load.label') : t('failure-phase-activation.label'),
|
|
@@ -52,7 +53,7 @@ export const PluginFailureBadge = ({ failure, size }: PluginFailureBadgeProps) =
|
|
|
52
53
|
})}
|
|
53
54
|
</p>
|
|
54
55
|
<p className='text-fg-muted text-sm break-words'>{failure.error.message}</p>
|
|
55
|
-
</
|
|
56
|
+
</Layout.Flex>
|
|
56
57
|
</Popover.Body>
|
|
57
58
|
</Popover.Content>
|
|
58
59
|
</Popover.Root>
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useCallback, useMemo } from 'react';
|
|
5
|
+
import React, { type MouseEvent, useCallback, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import type * as Plugin from '@dxos/app-framework/Plugin';
|
|
8
8
|
import type * as PluginManager from '@dxos/app-framework/PluginManager';
|
|
9
|
+
import type * as ToolkitHooks from '@dxos/app-toolkit/Hooks';
|
|
9
10
|
import * as Button from '@dxos/react-ui/Button';
|
|
10
11
|
import * as Card from '@dxos/react-ui/Card';
|
|
11
12
|
import * as Hooks from '@dxos/react-ui/Hooks';
|
|
@@ -34,7 +35,7 @@ export type PluginItemProps = {
|
|
|
34
35
|
extraTags?: readonly string[];
|
|
35
36
|
/** Whether this device's answer for this plugin differs from the account's. */
|
|
36
37
|
deviceOnly?: boolean;
|
|
37
|
-
onClick?: (id: string) => void;
|
|
38
|
+
onClick?: (id: string, activation: ToolkitHooks.DetailActivation) => void;
|
|
38
39
|
onChange?: (id: string, enabled: boolean) => void;
|
|
39
40
|
/**
|
|
40
41
|
* Install handler. When provided and the plugin is not installed, an Install button
|
|
@@ -101,7 +102,10 @@ export const PluginItem = ({
|
|
|
101
102
|
const showUpdateButton = !!onUpdate && isInstalled && !!hasUpdate;
|
|
102
103
|
const hasSettings = hasSettingsProp?.(id) ?? false;
|
|
103
104
|
const titleId = `${id}-title`;
|
|
104
|
-
const handleClick = useCallback(
|
|
105
|
+
const handleClick = useCallback(
|
|
106
|
+
(event: MouseEvent) => onClick?.(id, { modified: event.metaKey || event.ctrlKey }),
|
|
107
|
+
[id, onClick],
|
|
108
|
+
);
|
|
105
109
|
const handleSettings = useCallback(() => onSettings?.(id), [id, onSettings]);
|
|
106
110
|
const handleInstall = useCallback(() => onInstall?.(id), [id, onInstall]);
|
|
107
111
|
const handleUpdate = useCallback(() => onUpdate?.(id), [id, onUpdate]);
|
|
@@ -12,7 +12,7 @@ import '@dxos/react-ui/theme.css';
|
|
|
12
12
|
import type * as Plugin from '@dxos/app-framework/Plugin';
|
|
13
13
|
import * as PluginManagerProvider from '@dxos/app-framework/PluginManagerProvider';
|
|
14
14
|
import * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';
|
|
15
|
-
import * as
|
|
15
|
+
import * as ToolkitHooks from '@dxos/app-toolkit/Hooks';
|
|
16
16
|
import * as SettingsOperation from '@dxos/app-toolkit/SettingsOperation';
|
|
17
17
|
import * as EffectEx from '@dxos/effect/EffectEx';
|
|
18
18
|
import * as ObservabilityOperation from '@dxos/plugin-observability/ObservabilityOperation';
|
|
@@ -36,8 +36,7 @@ const matchesFilter = (plugin: Plugin.Plugin, query: string) => {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
export type BaseRegistryArticleProps = {
|
|
39
|
-
|
|
40
|
-
id: string;
|
|
39
|
+
contextId: string;
|
|
41
40
|
/** Plugins to display, pre-sorted by the caller. */
|
|
42
41
|
plugins: readonly Plugin.Plugin[];
|
|
43
42
|
/**
|
|
@@ -63,7 +62,7 @@ export type BaseRegistryArticleProps = {
|
|
|
63
62
|
export const BaseRegistryArticle = Util.composable<HTMLDivElement, BaseRegistryArticleProps>(
|
|
64
63
|
(
|
|
65
64
|
{
|
|
66
|
-
|
|
65
|
+
contextId,
|
|
67
66
|
plugins,
|
|
68
67
|
source,
|
|
69
68
|
empty,
|
|
@@ -124,15 +123,7 @@ export const BaseRegistryArticle = Util.composable<HTMLDivElement, BaseRegistryA
|
|
|
124
123
|
[dispatchToggle, requestDisable],
|
|
125
124
|
);
|
|
126
125
|
|
|
127
|
-
const handleClick =
|
|
128
|
-
(pluginId: string) =>
|
|
129
|
-
invokePromise(LayoutOperation.Open, {
|
|
130
|
-
subject: [getPluginPath(pluginId)],
|
|
131
|
-
pivotId: getPluginPath(id),
|
|
132
|
-
disposition: 'add',
|
|
133
|
-
}),
|
|
134
|
-
[invokePromise, id],
|
|
135
|
-
);
|
|
126
|
+
const handleClick = ToolkitHooks.useDetailNavigation({ contextId, getPath: getPluginPath });
|
|
136
127
|
|
|
137
128
|
const hasSettings = useCallback(
|
|
138
129
|
(pluginId: string) => allSettings.some((setting) => setting.prefix === pluginId),
|
|
@@ -82,7 +82,7 @@ export const PluginArticle = ({ subject: plugin }: PluginArticleProps) => {
|
|
|
82
82
|
void invokePromise(LayoutOperation.Open, {
|
|
83
83
|
subject: [getPluginPath(targetId)],
|
|
84
84
|
pivotId: getPluginPath(pluginId),
|
|
85
|
-
disposition: '
|
|
85
|
+
disposition: 'detail',
|
|
86
86
|
});
|
|
87
87
|
},
|
|
88
88
|
[invokePromise, pluginId],
|
|
@@ -52,11 +52,11 @@ const toDisplayPlugin = (plugin: Plugin.Meta): Plugin.Plugin =>
|
|
|
52
52
|
}) as Plugin.Plugin;
|
|
53
53
|
|
|
54
54
|
export type PublicRegistryArticleProps = {
|
|
55
|
-
|
|
55
|
+
contextId: string;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
export const PublicRegistryArticle = Util.composable<HTMLDivElement, PublicRegistryArticleProps>(
|
|
59
|
-
({
|
|
59
|
+
({ contextId, ...props }, forwardedRef) => {
|
|
60
60
|
const { t } = UiHooks.useTranslation(meta.profile.key);
|
|
61
61
|
const manager = PluginManagerProvider.usePluginManager();
|
|
62
62
|
const { invoke } = Hooks.useOperationInvoker();
|
|
@@ -187,7 +187,7 @@ export const PublicRegistryArticle = Util.composable<HTMLDivElement, PublicRegis
|
|
|
187
187
|
return (
|
|
188
188
|
<BaseRegistryArticle
|
|
189
189
|
{...props}
|
|
190
|
-
|
|
190
|
+
contextId={contextId}
|
|
191
191
|
source='registry'
|
|
192
192
|
plugins={items}
|
|
193
193
|
installed={installedIds}
|
|
@@ -16,7 +16,7 @@ const sortByPluginMeta = (a: Plugin.Plugin, b: Plugin.Plugin) =>
|
|
|
16
16
|
(a.meta.profile.name ?? a.meta.profile.key).localeCompare(b.meta.profile.name ?? b.meta.profile.key);
|
|
17
17
|
|
|
18
18
|
export type RegistryArticleProps = {
|
|
19
|
-
|
|
19
|
+
contextId: string;
|
|
20
20
|
plugins: Plugin.Plugin[];
|
|
21
21
|
/**
|
|
22
22
|
* Map from plugin id → display-only tags (e.g. `registry`, `local`) computed by the caller.
|
|
@@ -25,7 +25,7 @@ export type RegistryArticleProps = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export const RegistryArticle = Util.composable<HTMLDivElement, RegistryArticleProps>(
|
|
28
|
-
({
|
|
28
|
+
({ contextId, plugins: pluginsProp, extraTagsById, ...props }, forwardedRef) => {
|
|
29
29
|
const manager = PluginManagerProvider.usePluginManager();
|
|
30
30
|
const failed = useAtomValue(manager.failed);
|
|
31
31
|
const plugins = useMemo(() => [...pluginsProp].sort(sortByPluginMeta), [pluginsProp]);
|
|
@@ -41,7 +41,7 @@ export const RegistryArticle = Util.composable<HTMLDivElement, RegistryArticlePr
|
|
|
41
41
|
return (
|
|
42
42
|
<BaseRegistryArticle
|
|
43
43
|
{...props}
|
|
44
|
-
|
|
44
|
+
contextId={contextId}
|
|
45
45
|
plugins={plugins}
|
|
46
46
|
extraTagsById={extraTagsById}
|
|
47
47
|
failuresById={failuresById}
|