@dxos/plugin-kanban 0.9.0 → 0.9.1-main.c7dcc2e112
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/neutral/KanbanPlugin.mjs +2 -2
- package/dist/lib/neutral/KanbanPlugin.mjs.map +4 -4
- package/dist/lib/neutral/{KanbanSettings-5WOS4CUE.mjs → KanbanSettings-FTIIR6PR.mjs} +3 -3
- package/dist/lib/neutral/{KanbanSettings-5WOS4CUE.mjs.map → KanbanSettings-FTIIR6PR.mjs.map} +3 -3
- package/dist/lib/neutral/capabilities/index.mjs +2 -2
- package/dist/lib/neutral/capabilities/index.mjs.map +2 -2
- package/dist/lib/neutral/chunk-2IGEE5J5.mjs +50 -0
- package/dist/lib/neutral/chunk-2IGEE5J5.mjs.map +7 -0
- package/dist/lib/neutral/chunk-NDJNHR4K.mjs +8 -0
- package/dist/lib/neutral/{chunk-DAKIZO46.mjs → chunk-Y2G24ZGD.mjs} +2 -2
- package/dist/lib/neutral/{chunk-DAKIZO46.mjs.map → chunk-Y2G24ZGD.mjs.map} +3 -3
- package/dist/lib/neutral/components/index.mjs +9 -7
- package/dist/lib/neutral/components/index.mjs.map +3 -3
- package/dist/lib/neutral/containers/index.mjs +1 -1
- package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs → delete-card-NMULYEXS.mjs} +2 -2
- package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs → delete-card-field-NGYNI6GL.mjs} +2 -2
- package/dist/lib/neutral/index.mjs +3 -3
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/{react-surface-VZEVEJL5.mjs → react-surface-5Y6IHGKR.mjs} +7 -10
- package/dist/lib/neutral/react-surface-5Y6IHGKR.mjs.map +7 -0
- package/dist/lib/neutral/{restore-card-EKVEPATL.mjs → restore-card-JQ5N7G6G.mjs} +2 -2
- package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs → restore-card-field-4SU6IR4V.mjs} +2 -2
- package/dist/lib/neutral/testing/index.mjs +7 -5
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/lib/neutral/translations.mjs +1 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +1 -1
- package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs → undo-mappings-EZTHO4UL.mjs} +3 -3
- package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs.map → undo-mappings-EZTHO4UL.mjs.map} +3 -3
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +4 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -1
- package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +28 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +36 -0
- package/package.json +33 -32
- package/src/KanbanPlugin.test.ts +1 -1
- package/src/KanbanPlugin.tsx +1 -1
- package/src/capabilities/index.ts +1 -7
- package/src/capabilities/react-surface.tsx +13 -24
- package/src/capabilities/undo-mappings.ts +2 -2
- package/src/components/KanbanBoard/KanbanBoard.tsx +1 -1
- package/src/components/KanbanBoard/KanbanCard.tsx +14 -12
- package/src/containers/KanbanSettings/KanbanSettings.tsx +10 -3
- package/src/meta.ts +2 -29
- package/src/testing/KanbanCardTileSimple.tsx +13 -11
- package/src/translations.ts +1 -1
- package/src/types/KanbanOperation.ts +1 -1
- package/dist/lib/neutral/chunk-6ZHHQWO5.mjs +0 -39
- package/dist/lib/neutral/chunk-6ZHHQWO5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-M5ISZWZU.mjs +0 -8
- package/dist/lib/neutral/react-surface-VZEVEJL5.mjs.map +0 -7
- /package/dist/lib/neutral/{chunk-M5ISZWZU.mjs.map → chunk-NDJNHR4K.mjs.map} +0 -0
- /package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs.map → delete-card-NMULYEXS.mjs.map} +0 -0
- /package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs.map → delete-card-field-NGYNI6GL.mjs.map} +0 -0
- /package/dist/lib/neutral/{restore-card-EKVEPATL.mjs.map → restore-card-JQ5N7G6G.mjs.map} +0 -0
- /package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs.map → restore-card-field-4SU6IR4V.mjs.map} +0 -0
package/dx.config.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Config2 } from '@dxos/app-framework/config';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
export default Config2.make({
|
|
9
|
+
plugin: {
|
|
10
|
+
key: 'org.dxos.plugin.kanban',
|
|
11
|
+
name: 'Kanban',
|
|
12
|
+
author: 'DXOS',
|
|
13
|
+
description: trim`
|
|
14
|
+
Visual project management using customizable kanban boards to track workflow progress.
|
|
15
|
+
Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
|
|
16
|
+
between stages, and reorder both columns and cards — all changes are persisted to ECHO and
|
|
17
|
+
replicated to collaborators in real time.
|
|
18
|
+
|
|
19
|
+
Kanban boards come in two variants: view-variant boards source their cards through a linked
|
|
20
|
+
View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
|
|
21
|
+
own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
|
|
22
|
+
Both variants share the same arrangement storage and drag-and-drop mechanics.
|
|
23
|
+
|
|
24
|
+
Board settings let users choose which single-select field drives the column layout and
|
|
25
|
+
optionally hide the uncategorized column for items that have no pivot value.
|
|
26
|
+
Field-level undo support allows deleted card fields to be restored without data loss.
|
|
27
|
+
|
|
28
|
+
The plugin contributes a Kanban blueprint that exposes board creation and card management
|
|
29
|
+
to AI agents, enabling automated project tracking workflows.
|
|
30
|
+
`,
|
|
31
|
+
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
|
|
32
|
+
icon: { key: 'ph--kanban--regular', hue: 'green' },
|
|
33
|
+
spec: 'PLUGIN.mdl',
|
|
34
|
+
screenshots: [{ dark: 'https://dxos.network/plugin-details-kanban-dark.png' }],
|
|
35
|
+
},
|
|
36
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-kanban",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-main.c7dcc2e112",
|
|
4
4
|
"description": "Kanban DXOS Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"types": "dist/types/src/index.d.ts",
|
|
103
103
|
"files": [
|
|
104
104
|
"dist",
|
|
105
|
+
"dx.config.ts",
|
|
105
106
|
"src",
|
|
106
107
|
"PLUGIN.mdl"
|
|
107
108
|
],
|
|
@@ -109,26 +110,26 @@
|
|
|
109
110
|
"@effect-atom/atom-react": "^0.5.0",
|
|
110
111
|
"@radix-ui/react-context": "1.1.1",
|
|
111
112
|
"effect": "3.21.3",
|
|
112
|
-
"@dxos/ai": "0.9.
|
|
113
|
-
"@dxos/app-framework": "0.9.
|
|
114
|
-
"@dxos/app-toolkit": "0.9.
|
|
115
|
-
"@dxos/assistant": "0.9.
|
|
116
|
-
"@dxos/
|
|
117
|
-
"@dxos/compute": "0.9.
|
|
118
|
-
"@dxos/log": "0.9.
|
|
119
|
-
"@dxos/
|
|
120
|
-
"@dxos/plugin-
|
|
121
|
-
"@dxos/
|
|
122
|
-
"@dxos/
|
|
123
|
-
"@dxos/
|
|
124
|
-
"@dxos/
|
|
125
|
-
"@dxos/react-ui
|
|
126
|
-
"@dxos/react-ui-menu": "0.9.
|
|
127
|
-
"@dxos/
|
|
128
|
-
"@dxos/react-ui": "0.9.
|
|
129
|
-
"@dxos/
|
|
130
|
-
"@dxos/
|
|
131
|
-
"@dxos/
|
|
113
|
+
"@dxos/ai": "0.9.1-main.c7dcc2e112",
|
|
114
|
+
"@dxos/app-framework": "0.9.1-main.c7dcc2e112",
|
|
115
|
+
"@dxos/app-toolkit": "0.9.1-main.c7dcc2e112",
|
|
116
|
+
"@dxos/assistant": "0.9.1-main.c7dcc2e112",
|
|
117
|
+
"@dxos/effect": "0.9.1-main.c7dcc2e112",
|
|
118
|
+
"@dxos/compute": "0.9.1-main.c7dcc2e112",
|
|
119
|
+
"@dxos/log": "0.9.1-main.c7dcc2e112",
|
|
120
|
+
"@dxos/invariant": "0.9.1-main.c7dcc2e112",
|
|
121
|
+
"@dxos/plugin-client": "0.9.1-main.c7dcc2e112",
|
|
122
|
+
"@dxos/echo": "0.9.1-main.c7dcc2e112",
|
|
123
|
+
"@dxos/plugin-space": "0.9.1-main.c7dcc2e112",
|
|
124
|
+
"@dxos/react-client": "0.9.1-main.c7dcc2e112",
|
|
125
|
+
"@dxos/random": "0.9.1-main.c7dcc2e112",
|
|
126
|
+
"@dxos/react-ui": "0.9.1-main.c7dcc2e112",
|
|
127
|
+
"@dxos/react-ui-menu": "0.9.1-main.c7dcc2e112",
|
|
128
|
+
"@dxos/react-ui-mosaic": "0.9.1-main.c7dcc2e112",
|
|
129
|
+
"@dxos/react-ui-form": "0.9.1-main.c7dcc2e112",
|
|
130
|
+
"@dxos/schema": "0.9.1-main.c7dcc2e112",
|
|
131
|
+
"@dxos/types": "0.9.1-main.c7dcc2e112",
|
|
132
|
+
"@dxos/util": "0.9.1-main.c7dcc2e112"
|
|
132
133
|
},
|
|
133
134
|
"devDependencies": {
|
|
134
135
|
"@types/react": "~19.2.7",
|
|
@@ -136,22 +137,22 @@
|
|
|
136
137
|
"react": "~19.2.3",
|
|
137
138
|
"react-dom": "~19.2.3",
|
|
138
139
|
"vite": "^8.0.16",
|
|
139
|
-
"@dxos/
|
|
140
|
-
"@dxos/
|
|
141
|
-
"@dxos/plugin-preview": "0.9.
|
|
142
|
-
"@dxos/plugin-testing": "0.9.
|
|
143
|
-
"@dxos/plugin-theme": "0.9.
|
|
144
|
-
"@dxos/
|
|
145
|
-
"@dxos/
|
|
146
|
-
"@dxos/
|
|
147
|
-
"@dxos/
|
|
140
|
+
"@dxos/echo-client": "0.9.1-main.c7dcc2e112",
|
|
141
|
+
"@dxos/keys": "0.9.1-main.c7dcc2e112",
|
|
142
|
+
"@dxos/plugin-preview": "0.9.1-main.c7dcc2e112",
|
|
143
|
+
"@dxos/plugin-testing": "0.9.1-main.c7dcc2e112",
|
|
144
|
+
"@dxos/plugin-theme": "0.9.1-main.c7dcc2e112",
|
|
145
|
+
"@dxos/react-ui-syntax-highlighter": "0.9.1-main.c7dcc2e112",
|
|
146
|
+
"@dxos/storybook-utils": "0.9.1-main.c7dcc2e112",
|
|
147
|
+
"@dxos/test-utils": "0.9.1-main.c7dcc2e112",
|
|
148
|
+
"@dxos/ui-theme": "0.9.1-main.c7dcc2e112"
|
|
148
149
|
},
|
|
149
150
|
"peerDependencies": {
|
|
150
151
|
"effect": "3.21.3",
|
|
151
152
|
"react": "~19.2.3",
|
|
152
153
|
"react-dom": "~19.2.3",
|
|
153
|
-
"@dxos/react-ui": "0.9.
|
|
154
|
-
"@dxos/ui-theme": "0.9.
|
|
154
|
+
"@dxos/react-ui": "0.9.1-main.c7dcc2e112",
|
|
155
|
+
"@dxos/ui-theme": "0.9.1-main.c7dcc2e112"
|
|
155
156
|
},
|
|
156
157
|
"publishConfig": {
|
|
157
158
|
"access": "public"
|
package/src/KanbanPlugin.test.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { KanbanPlugin } from '#plugin';
|
|
|
11
11
|
|
|
12
12
|
import { meta } from './meta';
|
|
13
13
|
|
|
14
|
-
const moduleId = (name: string) => `${meta.
|
|
14
|
+
const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
|
|
15
15
|
|
|
16
16
|
describe('KanbanPlugin', () => {
|
|
17
17
|
test('modules activate on the expected events', async ({ expect }) => {
|
package/src/KanbanPlugin.tsx
CHANGED
|
@@ -22,7 +22,7 @@ export const KanbanPlugin = Plugin.define(meta).pipe(
|
|
|
22
22
|
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
23
23
|
AppPlugin.addTranslationsModule({ translations }),
|
|
24
24
|
AppPlugin.addPluginAssetModule({
|
|
25
|
-
asset: { pluginId: meta.
|
|
25
|
+
asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
26
26
|
}),
|
|
27
27
|
Plugin.make,
|
|
28
28
|
);
|
|
@@ -3,15 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capability } from '@dxos/app-framework';
|
|
6
|
-
import { type AppCapabilities } from '@dxos/app-toolkit';
|
|
7
6
|
import type { OperationHandlerSet } from '@dxos/compute';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
// wrapper needs an explicit annotation to keep the inferred type portable (TS2883).
|
|
11
|
-
export const BlueprintDefinition: Capability.LazyCapability<
|
|
12
|
-
void,
|
|
13
|
-
Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
|
|
14
|
-
> = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
|
|
8
|
+
export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
|
|
15
9
|
export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
|
|
16
10
|
export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
|
|
17
11
|
'OperationHandler',
|
|
@@ -3,16 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
|
-
import type * as Schema from 'effect/Schema';
|
|
7
|
-
import * as SchemaAST from 'effect/SchemaAST';
|
|
8
6
|
import React, { useMemo } from 'react';
|
|
9
7
|
|
|
10
8
|
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
11
9
|
import { Surface } from '@dxos/app-framework/ui';
|
|
12
10
|
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
13
|
-
import {
|
|
11
|
+
import { Database, Obj, Type } from '@dxos/echo';
|
|
14
12
|
import { SchemaEx } from '@dxos/effect';
|
|
15
|
-
import { type
|
|
13
|
+
import { type FormFieldRendererProps, SelectField, useFormValues } from '@dxos/react-ui-form';
|
|
16
14
|
|
|
17
15
|
import { KanbanArticle, KanbanSettings } from '#containers';
|
|
18
16
|
import { Kanban, PivotColumnAnnotationId } from '#types';
|
|
@@ -37,29 +35,16 @@ export default Capability.makeModule(() =>
|
|
|
37
35
|
}),
|
|
38
36
|
Surface.create({
|
|
39
37
|
id: 'createInitialSchemaForm',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
data
|
|
43
|
-
): data is {
|
|
44
|
-
prop: string;
|
|
45
|
-
schema: Schema.Schema<any>;
|
|
46
|
-
target: Database.Database | Collection.Collection | undefined;
|
|
47
|
-
fieldPropertyAst?: SchemaAST.AST;
|
|
48
|
-
} => {
|
|
49
|
-
const annotation = SchemaEx.findAnnotation<boolean>(
|
|
50
|
-
(data.schema as Schema.Schema.All).ast,
|
|
51
|
-
PivotColumnAnnotationId,
|
|
52
|
-
);
|
|
53
|
-
return !!annotation;
|
|
54
|
-
},
|
|
55
|
-
component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
|
|
56
|
-
const ast = fieldPropertyAst;
|
|
38
|
+
filter: AppSurface.formInputBySchema((ast) => !!SchemaEx.findAnnotation<boolean>(ast, PivotColumnAnnotationId)),
|
|
39
|
+
component: ({ data, ...inputProps }) => {
|
|
40
|
+
const ast = data.fieldPropertyAst;
|
|
57
41
|
if (!ast) {
|
|
58
42
|
return null;
|
|
59
43
|
}
|
|
60
44
|
|
|
61
|
-
const props = { ...inputProps, type: ast } as any as
|
|
62
|
-
const
|
|
45
|
+
const props = { ...inputProps, type: ast } as any as FormFieldRendererProps;
|
|
46
|
+
const target = data.target;
|
|
47
|
+
const db = Database.isDatabase(target) ? target : Obj.isObject(target) ? Obj.getDatabase(target) : undefined;
|
|
63
48
|
if (!db) {
|
|
64
49
|
return null;
|
|
65
50
|
}
|
|
@@ -84,7 +69,11 @@ export default Capability.makeModule(() =>
|
|
|
84
69
|
}
|
|
85
70
|
|
|
86
71
|
const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
|
|
87
|
-
if (
|
|
72
|
+
if (
|
|
73
|
+
typeof value === 'object' &&
|
|
74
|
+
value !== null &&
|
|
75
|
+
(value as { format?: string }).format === 'single-select'
|
|
76
|
+
) {
|
|
88
77
|
acc.push(key);
|
|
89
78
|
}
|
|
90
79
|
return acc;
|
|
@@ -19,7 +19,7 @@ export default Capability.makeModule(() =>
|
|
|
19
19
|
props: output.props,
|
|
20
20
|
index: output.index,
|
|
21
21
|
}),
|
|
22
|
-
message: ['card-field-deleted.label', { ns: meta.
|
|
22
|
+
message: ['card-field-deleted.label', { ns: meta.profile.key }],
|
|
23
23
|
}),
|
|
24
24
|
UndoMapping.make({
|
|
25
25
|
operation: KanbanOperation.DeleteCard,
|
|
@@ -27,7 +27,7 @@ export default Capability.makeModule(() =>
|
|
|
27
27
|
deriveContext: (_input, output) => ({
|
|
28
28
|
card: output.card,
|
|
29
29
|
}),
|
|
30
|
-
message: ['card-deleted.label', { ns: meta.
|
|
30
|
+
message: ['card-deleted.label', { ns: meta.profile.key }],
|
|
31
31
|
}),
|
|
32
32
|
]),
|
|
33
33
|
),
|
|
@@ -57,7 +57,7 @@ export const KanbanBoardRoot = ({
|
|
|
57
57
|
onCardRemove,
|
|
58
58
|
}: KanbanBoardRootProps) => {
|
|
59
59
|
const registry = useContext(RegistryContext);
|
|
60
|
-
const { t } = useTranslation(meta.
|
|
60
|
+
const { t } = useTranslation(meta.profile.key);
|
|
61
61
|
const model = useKanbanBoardModel(kanban, projection, items, registry);
|
|
62
62
|
const columns = model?.getColumns?.() ?? [];
|
|
63
63
|
const view = kanban?.spec.kind === 'view' ? kanban.spec.view.target : undefined;
|
|
@@ -7,7 +7,7 @@ import React, { forwardRef, useCallback, useMemo, useState } from 'react';
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
|
|
9
9
|
import { Obj } from '@dxos/echo';
|
|
10
|
-
import { Card,
|
|
10
|
+
import { Card, IconButton, useTranslation } from '@dxos/react-ui';
|
|
11
11
|
import { Menu, createMenuAction } from '@dxos/react-ui-menu';
|
|
12
12
|
import { Focus, Mosaic, useBoard } from '@dxos/react-ui-mosaic';
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ const KANBAN_CARD_TILE_NAME = 'KanbanBoard.Card';
|
|
|
25
25
|
*/
|
|
26
26
|
export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
27
27
|
({ data, location, debug, draggable }, forwardedRef) => {
|
|
28
|
-
const { t } = useTranslation(meta.
|
|
28
|
+
const { t } = useTranslation(meta.profile.key);
|
|
29
29
|
const { model } = useBoard(KANBAN_CARD_TILE_NAME);
|
|
30
30
|
const { projection, columnFieldPath, onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_NAME);
|
|
31
31
|
const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);
|
|
@@ -65,20 +65,22 @@ export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
|
65
65
|
<Card.DragHandle ref={dragHandleRef} testId='mosaicBoard.cardDragHandle' />
|
|
66
66
|
<Card.Title data-testid='mosaicBoard.cardTitle'>{Obj.getLabel(data)}</Card.Title>
|
|
67
67
|
{/* TODO(wittjosiah): Reconcile with Card.Menu. */}
|
|
68
|
-
<
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
<Card.Block end>
|
|
69
|
+
<Menu.Trigger asChild disabled={!menuItems?.length}>
|
|
70
|
+
<IconButton
|
|
71
|
+
iconOnly
|
|
72
|
+
variant='ghost'
|
|
73
|
+
icon='ph--dots-three-vertical--regular'
|
|
74
|
+
label={t('action-menu.label')}
|
|
75
|
+
/>
|
|
76
|
+
</Menu.Trigger>
|
|
77
|
+
<Menu.Content items={menuItems} />
|
|
78
|
+
</Card.Block>
|
|
77
79
|
</Card.Header>
|
|
78
80
|
<Card.Body>
|
|
79
81
|
{projection && (
|
|
80
82
|
<Surface.Surface
|
|
81
|
-
type={AppSurface.
|
|
83
|
+
type={AppSurface.CardContent}
|
|
82
84
|
limit={1}
|
|
83
85
|
data={{
|
|
84
86
|
subject: data,
|
|
@@ -87,8 +87,15 @@ export const KanbanSettings = ({ subject: object }: KanbanSettingsProps) => {
|
|
|
87
87
|
const settingsSchema = (isView ? KanbanViewSettingsSchema : KanbanSettingsSchema) as any;
|
|
88
88
|
|
|
89
89
|
return (
|
|
90
|
-
<Form.
|
|
91
|
-
<Form.
|
|
92
|
-
|
|
90
|
+
<Form.Section>
|
|
91
|
+
<Form.Root
|
|
92
|
+
schema={settingsSchema}
|
|
93
|
+
values={initialValues}
|
|
94
|
+
fieldMap={fieldMap}
|
|
95
|
+
onValuesChanged={handleValuesChanged}
|
|
96
|
+
>
|
|
97
|
+
<Form.FieldSet />
|
|
98
|
+
</Form.Root>
|
|
99
|
+
</Form.Section>
|
|
93
100
|
);
|
|
94
101
|
};
|
package/src/meta.ts
CHANGED
|
@@ -3,34 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import { DXN } from '@dxos/echo';
|
|
7
|
-
import { trim } from '@dxos/util';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
key: DXN.make('org.dxos.plugin.kanban'),
|
|
11
|
-
name: 'Kanban',
|
|
12
|
-
author: 'DXOS',
|
|
13
|
-
description: trim`
|
|
14
|
-
Visual project management using customizable kanban boards to track workflow progress.
|
|
15
|
-
Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
|
|
16
|
-
between stages, and reorder both columns and cards — all changes are persisted to ECHO and
|
|
17
|
-
replicated to collaborators in real time.
|
|
7
|
+
import config from '../dx.config';
|
|
18
8
|
|
|
19
|
-
|
|
20
|
-
View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
|
|
21
|
-
own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
|
|
22
|
-
Both variants share the same arrangement storage and drag-and-drop mechanics.
|
|
23
|
-
|
|
24
|
-
Board settings let users choose which single-select field drives the column layout and
|
|
25
|
-
optionally hide the uncategorized column for items that have no pivot value.
|
|
26
|
-
Field-level undo support allows deleted card fields to be restored without data loss.
|
|
27
|
-
|
|
28
|
-
The plugin contributes a Kanban blueprint that exposes board creation and card management
|
|
29
|
-
to AI agents, enabling automated project tracking workflows.
|
|
30
|
-
`,
|
|
31
|
-
icon: 'ph--kanban--regular',
|
|
32
|
-
iconHue: 'green',
|
|
33
|
-
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
|
|
34
|
-
spec: 'PLUGIN.mdl',
|
|
35
|
-
screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],
|
|
36
|
-
});
|
|
9
|
+
export const meta = Plugin.getMetaFromConfig(config);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import React, { forwardRef, useCallback, useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { Obj } from '@dxos/echo';
|
|
8
|
-
import { Card,
|
|
8
|
+
import { Card, IconButton, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
import { Menu, createMenuAction } from '@dxos/react-ui-menu';
|
|
10
10
|
import { Focus, Mosaic, useBoard } from '@dxos/react-ui-mosaic';
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ const KANBAN_CARD_TILE_SIMPLE_NAME = 'KanbanCardTileSimple';
|
|
|
19
19
|
*/
|
|
20
20
|
export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
21
21
|
({ data, location, debug }, forwardedRef) => {
|
|
22
|
-
const { t } = useTranslation(meta.
|
|
22
|
+
const { t } = useTranslation(meta.profile.key);
|
|
23
23
|
const { model } = useBoard(KANBAN_CARD_TILE_SIMPLE_NAME);
|
|
24
24
|
const { onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_SIMPLE_NAME);
|
|
25
25
|
const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);
|
|
@@ -54,15 +54,17 @@ export const KanbanCardTileSimple = forwardRef<HTMLDivElement, KanbanCardProps>(
|
|
|
54
54
|
<Card.DragHandle ref={dragHandleRef} />
|
|
55
55
|
<Card.Title>{Obj.getLabel(data)}</Card.Title>
|
|
56
56
|
{/* TODO(wittjosiah): Reconcile with Card.Menu. */}
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
<Card.Block end>
|
|
58
|
+
<Menu.Trigger asChild disabled={!menuItems?.length}>
|
|
59
|
+
<IconButton
|
|
60
|
+
iconOnly
|
|
61
|
+
variant='ghost'
|
|
62
|
+
icon='ph--dots-three-vertical--regular'
|
|
63
|
+
label={t('action-menu.label')}
|
|
64
|
+
/>
|
|
65
|
+
</Menu.Trigger>
|
|
66
|
+
<Menu.Content items={menuItems} />
|
|
67
|
+
</Card.Block>
|
|
66
68
|
</Card.Header>
|
|
67
69
|
<Card.Body>
|
|
68
70
|
<Card.Row fullWidth>
|
package/src/translations.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const translations = [
|
|
|
22
22
|
'delete-object.label': 'Delete kanban',
|
|
23
23
|
'object-deleted.label': 'Kanban deleted',
|
|
24
24
|
},
|
|
25
|
-
[meta.
|
|
25
|
+
[meta.profile.key]: {
|
|
26
26
|
'action-menu.label': 'Actions',
|
|
27
27
|
'plugin.name': 'Kanban',
|
|
28
28
|
'kanban-title.label': 'Title',
|
|
@@ -12,7 +12,7 @@ import { Type, View, DXN } from '@dxos/echo';
|
|
|
12
12
|
|
|
13
13
|
import { meta } from '#meta';
|
|
14
14
|
|
|
15
|
-
const makeKey = (name: string) => DXN.make(`${meta.
|
|
15
|
+
const makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);
|
|
16
16
|
|
|
17
17
|
export const DeleteCardFieldOutput = Schema.Struct({
|
|
18
18
|
field: View.FieldSchema.annotations({ description: 'The deleted field schema.' }),
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// src/meta.ts
|
|
2
|
-
import { Plugin } from "@dxos/app-framework";
|
|
3
|
-
import { DXN } from "@dxos/echo";
|
|
4
|
-
import { trim } from "@dxos/util";
|
|
5
|
-
var meta = Plugin.makeMeta({
|
|
6
|
-
key: DXN.make("org.dxos.plugin.kanban"),
|
|
7
|
-
name: "Kanban",
|
|
8
|
-
author: "DXOS",
|
|
9
|
-
description: trim`
|
|
10
|
-
Visual project management using customizable kanban boards to track workflow progress.
|
|
11
|
-
Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
|
|
12
|
-
between stages, and reorder both columns and cards — all changes are persisted to ECHO and
|
|
13
|
-
replicated to collaborators in real time.
|
|
14
|
-
|
|
15
|
-
Kanban boards come in two variants: view-variant boards source their cards through a linked
|
|
16
|
-
View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
|
|
17
|
-
own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
|
|
18
|
-
Both variants share the same arrangement storage and drag-and-drop mechanics.
|
|
19
|
-
|
|
20
|
-
Board settings let users choose which single-select field drives the column layout and
|
|
21
|
-
optionally hide the uncategorized column for items that have no pivot value.
|
|
22
|
-
Field-level undo support allows deleted card fields to be restored without data loss.
|
|
23
|
-
|
|
24
|
-
The plugin contributes a Kanban blueprint that exposes board creation and card management
|
|
25
|
-
to AI agents, enabling automated project tracking workflows.
|
|
26
|
-
`,
|
|
27
|
-
icon: "ph--kanban--regular",
|
|
28
|
-
iconHue: "green",
|
|
29
|
-
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban",
|
|
30
|
-
spec: "PLUGIN.mdl",
|
|
31
|
-
screenshots: [
|
|
32
|
-
"https://dxos.network/plugin-details-kanban-dark.png"
|
|
33
|
-
]
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export {
|
|
37
|
-
meta
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=chunk-6ZHHQWO5.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { DXN } from '@dxos/echo';\nimport { trim } from '@dxos/util';\n\nexport const meta = Plugin.makeMeta({\n key: DXN.make('org.dxos.plugin.kanban'),\n name: 'Kanban',\n author: 'DXOS',\n description: trim`\n Visual project management using customizable kanban boards to track workflow progress.\n Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards\n between stages, and reorder both columns and cards — all changes are persisted to ECHO and\n replicated to collaborators in real time.\n\n Kanban boards come in two variants: view-variant boards source their cards through a linked\n View query (any ECHO type can be pivoted on a single-select field), while items-variant boards\n own their cards explicitly and are used by external sync integrations such as Linear or GitHub.\n Both variants share the same arrangement storage and drag-and-drop mechanics.\n\n Board settings let users choose which single-select field drives the column layout and\n optionally hide the uncategorized column for items that have no pivot value.\n Field-level undo support allows deleted card fields to be restored without data loss.\n\n The plugin contributes a Kanban blueprint that exposes board creation and card management\n to AI agents, enabling automated project tracking workflows.\n `,\n icon: 'ph--kanban--regular',\n iconHue: 'green',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',\n spec: 'PLUGIN.mdl',\n screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],\n});\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,WAAW;AACpB,SAASC,YAAY;AAEd,IAAMC,OAAOH,OAAOI,SAAS;EAClCC,KAAKJ,IAAIK,KAAK,wBAAA;EACdC,MAAM;EACNC,QAAQ;EACRC,aAAaP;;;;;;;;;;;;;;;;;;EAkBbQ,MAAM;EACNC,SAAS;EACTC,QAAQ;EACRC,MAAM;EACNC,aAAa;IAAC;;AAChB,CAAA;",
|
|
6
|
-
"names": ["Plugin", "DXN", "trim", "meta", "makeMeta", "key", "make", "name", "author", "description", "icon", "iconHue", "source", "spec", "screenshots"]
|
|
7
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// src/operations/index.ts
|
|
2
|
-
import { OperationHandlerSet } from "@dxos/compute";
|
|
3
|
-
var KanbanOperationHandlerSet = OperationHandlerSet.lazy(() => import("./delete-card-VNAV3CZV.mjs"), () => import("./delete-card-field-XHOLGS6L.mjs"), () => import("./restore-card-EKVEPATL.mjs"), () => import("./restore-card-field-TQCTGGNO.mjs"));
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
KanbanOperationHandlerSet
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=chunk-M5ISZWZU.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/capabilities/react-surface.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport type * as Schema from 'effect/Schema';\nimport * as SchemaAST from 'effect/SchemaAST';\nimport React, { useMemo } from 'react';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { type Collection, Database, Obj, Type } from '@dxos/echo';\nimport { SchemaEx } from '@dxos/effect';\nimport { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';\n\nimport { KanbanArticle, KanbanSettings } from '#containers';\nimport { Kanban, PivotColumnAnnotationId } from '#types';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contributes(Capabilities.ReactSurface, [\n Surface.create({\n id: 'root',\n // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.\n filter: AppSurface.oneOf(\n AppSurface.object(AppSurface.Article, Kanban.Kanban),\n AppSurface.object(AppSurface.Section, Kanban.Kanban),\n ),\n component: ({ data, role }) => <KanbanArticle role={role} subject={data.subject} />,\n }),\n Surface.create({\n id: 'objectProperties',\n position: 'first',\n filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),\n component: ({ data }) => <KanbanSettings subject={data.subject} />,\n }),\n Surface.create({\n id: 'createInitialSchemaForm',\n role: 'form-input',\n filter: (\n data,\n ): data is {\n prop: string;\n schema: Schema.Schema<any>;\n target: Database.Database | Collection.Collection | undefined;\n fieldPropertyAst?: SchemaAST.AST;\n } => {\n const annotation = SchemaEx.findAnnotation<boolean>(\n (data.schema as Schema.Schema.All).ast,\n PivotColumnAnnotationId,\n );\n return !!annotation;\n },\n component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {\n const ast = fieldPropertyAst;\n if (!ast) {\n return null;\n }\n\n const props = { ...inputProps, type: ast } as any as FormFieldComponentProps;\n const db = Database.isDatabase(target) ? target : target && Obj.getDatabase(target);\n if (!db) {\n return null;\n }\n\n const { typename } = useFormValues('KanbanForm');\n const [selectedSchema] = useMemo(\n () =>\n db.graph.registry\n .list()\n .filter(Type.isType)\n .filter((t) => Type.getTypename(t) === typename),\n [db, typename],\n );\n const singleSelectColumns = useMemo(() => {\n if (!selectedSchema) {\n return [];\n }\n const jsonSchema = selectedSchema.jsonSchema;\n const properties = jsonSchema.properties;\n if (!properties) {\n return [];\n }\n\n const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {\n if (typeof value === 'object' && value?.format === 'single-select') {\n acc.push(key);\n }\n return acc;\n }, []);\n\n return columns;\n }, [selectedSchema]);\n\n if (!typename) {\n return null;\n }\n\n return <SelectField {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;\n },\n }),\n ]),\n ),\n);\n"],
|
|
5
|
-
"mappings": ";;;AAIA,YAAYA,YAAY;AAGxB,OAAOC,SAASC,eAAe;AAE/B,SAASC,cAAcC,kBAAkB;AACzC,SAASC,eAAe;AACxB,SAASC,kBAAkB;AAC3B,SAA0BC,UAAUC,KAAKC,YAAY;AACrD,SAASC,gBAAgB;AACzB,SAAuCC,aAAaC,qBAAqB;AAEzE,SAASC,eAAeC,sBAAsB;AAC9C,SAASC,QAAQC,+BAA+B;AAEhD,IAAA,wBAAeZ,WAAWa,WAAW,MAC5BC,eACLd,WAAWe,YAAYhB,aAAaiB,cAAc;EAChDf,QAAQgB,OAAO;IACbC,IAAI;;IAEJC,QAAQjB,WAAWkB,MACjBlB,WAAWmB,OAAOnB,WAAWoB,SAASX,OAAOA,MAAM,GACnDT,WAAWmB,OAAOnB,WAAWqB,SAASZ,OAAOA,MAAM,CAAA;IAErDa,WAAW,CAAC,EAAEC,MAAMC,KAAI,MAAO,sBAAA,cAACjB,eAAAA;MAAciB;MAAYC,SAASF,KAAKE;;EAC1E,CAAA;EACA1B,QAAQgB,OAAO;IACbC,IAAI;IACJU,UAAU;IACVT,QAAQjB,WAAWmB,OAAOnB,WAAW2B,kBAAkBlB,OAAOA,MAAM;IACpEa,WAAW,CAAC,EAAEC,KAAI,MAAO,sBAAA,cAACf,gBAAAA;MAAeiB,SAASF,KAAKE;;EACzD,CAAA;EACA1B,QAAQgB,OAAO;IACbC,IAAI;IACJQ,MAAM;IACNP,QAAQ,CACNM,SAAAA;AAOA,YAAMK,aAAaxB,SAASyB,eACzBN,KAAKO,OAA6BC,KACnCrB,uBAAAA;AAEF,aAAO,CAAC,CAACkB;IACX;IACAN,WAAW,CAAC,EAAEC,MAAM,EAAES,QAAQC,iBAAgB,GAAI,GAAGC,WAAAA,MAAY;AAC/D,YAAMH,MAAME;AACZ,UAAI,CAACF,KAAK;AACR,eAAO;MACT;AAEA,YAAMI,QAAQ;QAAE,GAAGD;QAAYE,MAAML;MAAI;AACzC,YAAMM,KAAKpC,SAASqC,WAAWN,MAAAA,IAAUA,SAASA,UAAU9B,IAAIqC,YAAYP,MAAAA;AAC5E,UAAI,CAACK,IAAI;AACP,eAAO;MACT;AAEA,YAAM,EAAEG,SAAQ,IAAKlC,cAAc,YAAA;AACnC,YAAM,CAACmC,cAAAA,IAAkB7C,QACvB,MACEyC,GAAGK,MAAMC,SACNC,KAAI,EACJ3B,OAAOd,KAAK0C,MAAM,EAClB5B,OAAO,CAAC6B,MAAM3C,KAAK4C,YAAYD,CAAAA,MAAON,QAAAA,GAC3C;QAACH;QAAIG;OAAS;AAEhB,YAAMQ,sBAAsBpD,QAAQ,MAAA;AAClC,YAAI,CAAC6C,gBAAgB;AACnB,iBAAO,CAAA;QACT;AACA,cAAMQ,aAAaR,eAAeQ;AAClC,cAAMC,aAAaD,WAAWC;AAC9B,YAAI,CAACA,YAAY;AACf,iBAAO,CAAA;QACT;AAEA,cAAMC,UAAUC,OAAOC,QAAQH,UAAAA,EAAYI,OAAiB,CAACC,KAAK,CAACC,KAAKC,KAAAA,MAAM;AAC5E,cAAI,OAAOA,UAAU,YAAYA,OAAOC,WAAW,iBAAiB;AAClEH,gBAAII,KAAKH,GAAAA;UACX;AACA,iBAAOD;QACT,GAAG,CAAA,CAAE;AAEL,eAAOJ;MACT,GAAG;QAACV;OAAe;AAEnB,UAAI,CAACD,UAAU;AACb,eAAO;MACT;AAEA,aAAO,sBAAA,cAACnC,aAAAA;QAAa,GAAG8B;QAAOyB,SAASZ,oBAAoBa,IAAI,CAACC,YAAY;UAAEL,OAAOK;QAAO,EAAA;;IAC/F;EACF,CAAA;CACD,CAAA,CAAA;",
|
|
6
|
-
"names": ["Effect", "React", "useMemo", "Capabilities", "Capability", "Surface", "AppSurface", "Database", "Obj", "Type", "SchemaEx", "SelectField", "useFormValues", "KanbanArticle", "KanbanSettings", "Kanban", "PivotColumnAnnotationId", "makeModule", "succeed", "contributes", "ReactSurface", "create", "id", "filter", "oneOf", "object", "Article", "Section", "component", "data", "role", "subject", "position", "ObjectProperties", "annotation", "findAnnotation", "schema", "ast", "target", "fieldPropertyAst", "inputProps", "props", "type", "db", "isDatabase", "getDatabase", "typename", "selectedSchema", "graph", "registry", "list", "isType", "t", "getTypename", "singleSelectColumns", "jsonSchema", "properties", "columns", "Object", "entries", "reduce", "acc", "key", "value", "format", "push", "options", "map", "column"]
|
|
7
|
-
}
|
|
File without changes
|
|
File without changes
|
/package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs.map → delete-card-field-NGYNI6GL.mjs.map}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|