@dxos/plugin-automation 0.8.2-main.f081794 → 0.8.2-main.fbd8ed0
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/{AutomationContainer-KEQ5RNIW.mjs → AutomationContainer-DA6IW7O2.mjs} +3 -3
- package/dist/lib/browser/{AutomationPanel-G3OB6ELR.mjs → AutomationPanel-R42D3LDD.mjs} +3 -3
- package/dist/lib/browser/{FunctionsContainer-STXBW4CX.mjs → FunctionsContainer-MPBMMOMS.mjs} +2 -2
- package/dist/lib/browser/{FunctionsPanel-JJPLIAJW.mjs → FunctionsPanel-NSI3P53X.mjs} +2 -2
- package/dist/lib/browser/{app-graph-builder-ND64CHOM.mjs → app-graph-builder-2OGPEVBA.mjs} +13 -15
- package/dist/lib/browser/app-graph-builder-2OGPEVBA.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NGG4ICAQ.mjs → chunk-2QF27UJ2.mjs} +12 -12
- package/dist/lib/browser/chunk-2QF27UJ2.mjs.map +7 -0
- package/dist/lib/browser/chunk-ADYCSC6Y.mjs +39 -0
- package/dist/lib/browser/chunk-ADYCSC6Y.mjs.map +7 -0
- package/dist/lib/browser/chunk-BNQNURZN.mjs +211 -0
- package/dist/lib/browser/chunk-BNQNURZN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-QJPKWYTL.mjs → chunk-SGT76SL2.mjs} +5 -5
- package/dist/lib/browser/{chunk-65VL4EYS.mjs → chunk-TRC3J2I6.mjs} +6 -6
- package/dist/lib/browser/chunk-TRC3J2I6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +6 -6
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/{intent-resolver-3J647TIZ.mjs → intent-resolver-X3H6ZSP4.mjs} +22 -16
- package/dist/lib/browser/intent-resolver-X3H6ZSP4.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-L22QIANU.mjs → react-surface-MOXIHBMS.mjs} +4 -4
- package/dist/lib/browser/{react-surface-L22QIANU.mjs.map → react-surface-MOXIHBMS.mjs.map} +1 -1
- package/dist/lib/browser/types.mjs +1 -1
- package/dist/lib/node/{AutomationContainer-E5I76FPP.cjs → AutomationContainer-FIFH4P5T.cjs} +7 -7
- package/dist/lib/node/{AutomationPanel-YLXAFJDP.cjs → AutomationPanel-HTNEWBGB.cjs} +8 -8
- package/dist/lib/node/{AutomationPanel-YLXAFJDP.cjs.map → AutomationPanel-HTNEWBGB.cjs.map} +2 -2
- package/dist/lib/node/{FunctionsContainer-3HCURMEB.cjs → FunctionsContainer-LF2F6CPE.cjs} +6 -6
- package/dist/lib/node/{FunctionsPanel-SYIZHPGU.cjs → FunctionsPanel-6HOAIMQ3.cjs} +7 -7
- package/dist/lib/node/{FunctionsPanel-SYIZHPGU.cjs.map → FunctionsPanel-6HOAIMQ3.cjs.map} +2 -2
- package/dist/lib/node/{app-graph-builder-TVFR6RXO.cjs → app-graph-builder-3XGDVWHR.cjs} +16 -18
- package/dist/lib/node/app-graph-builder-3XGDVWHR.cjs.map +7 -0
- package/dist/lib/node/{chunk-BSK5SHTR.cjs → chunk-CBHWMYKF.cjs} +9 -9
- package/dist/lib/node/chunk-CBHWMYKF.cjs.map +7 -0
- package/dist/lib/node/{chunk-PSIJDHAX.cjs → chunk-GDCG2BML.cjs} +19 -19
- package/dist/lib/node/chunk-GDCG2BML.cjs.map +7 -0
- package/dist/lib/node/chunk-S3Z4AP77.cjs +234 -0
- package/dist/lib/node/chunk-S3Z4AP77.cjs.map +7 -0
- package/dist/lib/node/{chunk-L5TWLPGA.cjs → chunk-SV2CB3FT.cjs} +8 -8
- package/dist/lib/node/{chunk-SRXHHBDE.cjs → chunk-TI3WBQIB.cjs} +18 -18
- package/dist/lib/node/chunk-TI3WBQIB.cjs.map +7 -0
- package/dist/lib/node/index.cjs +13 -13
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/{intent-resolver-4YYZ2MMZ.cjs → intent-resolver-Q7WJ4PZZ.cjs} +28 -22
- package/dist/lib/node/intent-resolver-Q7WJ4PZZ.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-PCZCHIET.cjs → react-surface-43VHU36V.cjs} +11 -11
- package/dist/lib/node/react-surface-43VHU36V.cjs.map +7 -0
- package/dist/lib/node/types.cjs +2 -2
- package/dist/lib/node/types.cjs.map +1 -1
- package/dist/lib/node-esm/{AutomationContainer-22PUFPSE.mjs → AutomationContainer-OP43F4PD.mjs} +3 -3
- package/dist/lib/node-esm/{AutomationPanel-6UXIAJVS.mjs → AutomationPanel-ZQKRBWP2.mjs} +3 -3
- package/dist/lib/node-esm/{FunctionsContainer-XG5WVAN3.mjs → FunctionsContainer-5TVRDIX5.mjs} +2 -2
- package/dist/lib/node-esm/{FunctionsPanel-J3QGUESH.mjs → FunctionsPanel-NMEW26KL.mjs} +2 -2
- package/dist/lib/node-esm/{app-graph-builder-NYLOXWVV.mjs → app-graph-builder-UR2E5CQY.mjs} +13 -15
- package/dist/lib/node-esm/app-graph-builder-UR2E5CQY.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-4UPGANGV.mjs → chunk-AD4C4IK2.mjs} +6 -6
- package/dist/lib/node-esm/chunk-AD4C4IK2.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-TMMB5ETD.mjs → chunk-CUPEMOYK.mjs} +5 -5
- package/dist/lib/node-esm/{chunk-HMYAQLGF.mjs → chunk-DIUPZXCQ.mjs} +12 -12
- package/dist/lib/node-esm/chunk-DIUPZXCQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-DZ7RKC52.mjs +212 -0
- package/dist/lib/node-esm/chunk-DZ7RKC52.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YYBCQXB2.mjs → chunk-EEA6CZ6B.mjs} +16 -16
- package/dist/lib/node-esm/chunk-EEA6CZ6B.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +6 -6
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/{intent-resolver-WXIXG5UY.mjs → intent-resolver-HEUGQ6SL.mjs} +22 -16
- package/dist/lib/node-esm/intent-resolver-HEUGQ6SL.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-VSO4NWC6.mjs → react-surface-TER7JEF6.mjs} +4 -4
- package/dist/lib/node-esm/{react-surface-VSO4NWC6.mjs.map → react-surface-TER7JEF6.mjs.map} +1 -1
- package/dist/lib/node-esm/types.mjs +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +2 -179
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -178
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/components/AutomationContainer.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsContainer.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +12 -0
- package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts +5 -0
- package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
- package/dist/types/src/testing/test-functions.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +15 -15
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -24
- package/src/AutomationPlugin.tsx +1 -1
- package/src/capabilities/app-graph-builder.ts +64 -41
- package/src/capabilities/intent-resolver.ts +25 -14
- package/src/capabilities/react-surface.tsx +1 -1
- package/src/components/AutomationPanel/AutomationPanel.stories.tsx +2 -2
- package/src/components/AutomationPanel/AutomationPanel.tsx +11 -10
- package/src/components/FunctionsPanel/FunctionsPanel.tsx +5 -5
- package/src/components/TriggerEditor/FunctionInputEditor.tsx +77 -0
- package/src/components/TriggerEditor/SpecSelector.tsx +59 -0
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +17 -8
- package/src/components/TriggerEditor/TriggerEditor.tsx +53 -93
- package/src/testing/test-functions.ts +23 -9
- package/src/types.ts +11 -10
- package/dist/lib/browser/app-graph-builder-ND64CHOM.mjs.map +0 -7
- package/dist/lib/browser/chunk-65VL4EYS.mjs.map +0 -7
- package/dist/lib/browser/chunk-FALBBJNO.mjs +0 -138
- package/dist/lib/browser/chunk-FALBBJNO.mjs.map +0 -7
- package/dist/lib/browser/chunk-FCLWFVFX.mjs +0 -39
- package/dist/lib/browser/chunk-FCLWFVFX.mjs.map +0 -7
- package/dist/lib/browser/chunk-NGG4ICAQ.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-3J647TIZ.mjs.map +0 -7
- package/dist/lib/node/app-graph-builder-TVFR6RXO.cjs.map +0 -7
- package/dist/lib/node/chunk-BSK5SHTR.cjs.map +0 -7
- package/dist/lib/node/chunk-FTEDH5Q6.cjs +0 -167
- package/dist/lib/node/chunk-FTEDH5Q6.cjs.map +0 -7
- package/dist/lib/node/chunk-PSIJDHAX.cjs.map +0 -7
- package/dist/lib/node/chunk-SRXHHBDE.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-4YYZ2MMZ.cjs.map +0 -7
- package/dist/lib/node/react-surface-PCZCHIET.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-NYLOXWVV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4UPGANGV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HMYAQLGF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-M4QXMIIB.mjs +0 -139
- package/dist/lib/node-esm/chunk-M4QXMIIB.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YYBCQXB2.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-WXIXG5UY.mjs.map +0 -7
- /package/dist/lib/browser/{AutomationContainer-KEQ5RNIW.mjs.map → AutomationContainer-DA6IW7O2.mjs.map} +0 -0
- /package/dist/lib/browser/{AutomationPanel-G3OB6ELR.mjs.map → AutomationPanel-R42D3LDD.mjs.map} +0 -0
- /package/dist/lib/browser/{FunctionsContainer-STXBW4CX.mjs.map → FunctionsContainer-MPBMMOMS.mjs.map} +0 -0
- /package/dist/lib/browser/{FunctionsPanel-JJPLIAJW.mjs.map → FunctionsPanel-NSI3P53X.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-QJPKWYTL.mjs.map → chunk-SGT76SL2.mjs.map} +0 -0
- /package/dist/lib/node/{AutomationContainer-E5I76FPP.cjs.map → AutomationContainer-FIFH4P5T.cjs.map} +0 -0
- /package/dist/lib/node/{FunctionsContainer-3HCURMEB.cjs.map → FunctionsContainer-LF2F6CPE.cjs.map} +0 -0
- /package/dist/lib/node/{chunk-L5TWLPGA.cjs.map → chunk-SV2CB3FT.cjs.map} +0 -0
- /package/dist/lib/node-esm/{AutomationContainer-22PUFPSE.mjs.map → AutomationContainer-OP43F4PD.mjs.map} +0 -0
- /package/dist/lib/node-esm/{AutomationPanel-6UXIAJVS.mjs.map → AutomationPanel-ZQKRBWP2.mjs.map} +0 -0
- /package/dist/lib/node-esm/{FunctionsContainer-XG5WVAN3.mjs.map → FunctionsContainer-5TVRDIX5.mjs.map} +0 -0
- /package/dist/lib/node-esm/{FunctionsPanel-J3QGUESH.mjs.map → FunctionsPanel-NMEW26KL.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-TMMB5ETD.mjs.map → chunk-CUPEMOYK.mjs.map} +0 -0
|
@@ -2,61 +2,84 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Rx } from '@effect-rx/rx-react';
|
|
6
|
+
import { Option, pipe } from 'effect';
|
|
7
|
+
|
|
8
|
+
import { Capabilities, contributes, type PluginContext } from '@dxos/app-framework';
|
|
6
9
|
import { isInstanceOf } from '@dxos/echo-schema';
|
|
7
10
|
import { ScriptType } from '@dxos/functions';
|
|
8
11
|
import { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR } from '@dxos/plugin-deck/types';
|
|
9
|
-
import { createExtension
|
|
10
|
-
import { SCRIPT_PLUGIN } from '@dxos/plugin-script/types';
|
|
12
|
+
import { createExtension } from '@dxos/plugin-graph';
|
|
11
13
|
import { SPACE_PLUGIN } from '@dxos/plugin-space';
|
|
12
14
|
|
|
13
15
|
import { meta } from '../meta';
|
|
14
16
|
|
|
15
|
-
export default (context:
|
|
17
|
+
export default (context: PluginContext) =>
|
|
16
18
|
contributes(Capabilities.AppGraphBuilder, [
|
|
17
19
|
createExtension({
|
|
18
20
|
id: `${meta.id}/space-settings-automation`,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
connector: (node) =>
|
|
22
|
+
Rx.make((get) =>
|
|
23
|
+
pipe(
|
|
24
|
+
get(node),
|
|
25
|
+
Option.flatMap((node) => (node.type === `${SPACE_PLUGIN}/settings` ? Option.some(node) : Option.none())),
|
|
26
|
+
Option.map((node) => [
|
|
27
|
+
{
|
|
28
|
+
id: `automation-${node.id}`,
|
|
29
|
+
type: `${meta.id}/space-settings-automation`,
|
|
30
|
+
data: `${meta.id}/space-settings-automation`,
|
|
31
|
+
properties: {
|
|
32
|
+
label: ['automation panel label', { ns: meta.id }],
|
|
33
|
+
icon: 'ph--lightning--regular',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
]),
|
|
37
|
+
Option.getOrElse(() => []),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
31
40
|
}),
|
|
32
41
|
createExtension({
|
|
33
42
|
id: `${meta.id}/space-settings-functions`,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
connector: (node) =>
|
|
44
|
+
Rx.make((get) =>
|
|
45
|
+
pipe(
|
|
46
|
+
get(node),
|
|
47
|
+
Option.flatMap((node) => (node.type === `${SPACE_PLUGIN}/settings` ? Option.some(node) : Option.none())),
|
|
48
|
+
Option.map((node) => [
|
|
49
|
+
{
|
|
50
|
+
id: `functions-${node.id}`,
|
|
51
|
+
type: `${meta.id}/space-settings-functions`,
|
|
52
|
+
data: `${meta.id}/space-settings-functions`,
|
|
53
|
+
properties: {
|
|
54
|
+
label: ['functions panel label', { ns: meta.id }],
|
|
55
|
+
icon: 'ph--function--regular',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
]),
|
|
59
|
+
Option.getOrElse(() => []),
|
|
60
|
+
),
|
|
61
|
+
),
|
|
46
62
|
}),
|
|
47
63
|
createExtension({
|
|
48
|
-
id: `${
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
id: `${meta.id}/script-companion`,
|
|
65
|
+
connector: (node) =>
|
|
66
|
+
Rx.make((get) =>
|
|
67
|
+
pipe(
|
|
68
|
+
get(node),
|
|
69
|
+
Option.flatMap((node) => (isInstanceOf(ScriptType, node.data) ? Option.some(node) : Option.none())),
|
|
70
|
+
Option.map((node) => [
|
|
71
|
+
{
|
|
72
|
+
id: [node.id, 'automation'].join(ATTENDABLE_PATH_SEPARATOR),
|
|
73
|
+
type: PLANK_COMPANION_TYPE,
|
|
74
|
+
data: 'automation',
|
|
75
|
+
properties: {
|
|
76
|
+
label: ['script automation label', { ns: meta.id }],
|
|
77
|
+
icon: 'ph--lightning--regular',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
]),
|
|
81
|
+
Option.getOrElse(() => []),
|
|
82
|
+
),
|
|
83
|
+
),
|
|
61
84
|
}),
|
|
62
85
|
]);
|
|
@@ -2,48 +2,53 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
contributes,
|
|
7
|
+
Capabilities,
|
|
8
|
+
createResolver,
|
|
9
|
+
type PluginContext,
|
|
10
|
+
createIntent,
|
|
11
|
+
LayoutAction,
|
|
12
|
+
} from '@dxos/app-framework';
|
|
13
|
+
import { Ref } from '@dxos/echo';
|
|
6
14
|
import { FunctionTrigger, FunctionType, ScriptType, TriggerKind } from '@dxos/functions';
|
|
7
15
|
import { type DXN } from '@dxos/keys';
|
|
8
16
|
import { live } from '@dxos/live-object';
|
|
17
|
+
import { ATTENDABLE_PATH_SEPARATOR } from '@dxos/plugin-deck/types';
|
|
9
18
|
import { SpaceAction } from '@dxos/plugin-space/types';
|
|
10
19
|
import { Filter } from '@dxos/react-client/echo';
|
|
11
20
|
|
|
12
21
|
import { AutomationAction } from '../types';
|
|
13
22
|
|
|
14
|
-
export default (context:
|
|
23
|
+
export default (context: PluginContext) =>
|
|
15
24
|
contributes(Capabilities.IntentResolver, [
|
|
16
25
|
createResolver({
|
|
17
26
|
intent: AutomationAction.CreateTriggerFromTemplate,
|
|
18
|
-
resolve: async ({ space, template, enabled = false, scriptName,
|
|
19
|
-
const trigger = live(FunctionTrigger, { enabled });
|
|
27
|
+
resolve: async ({ space, template, enabled = false, scriptName, input }) => {
|
|
28
|
+
const trigger = live(FunctionTrigger, { enabled, input });
|
|
20
29
|
|
|
21
30
|
// TODO(wittjosiah): Factor out function lookup by script name?
|
|
22
31
|
if (scriptName) {
|
|
23
32
|
const {
|
|
24
33
|
objects: [script],
|
|
25
|
-
} = await space.db.query(Filter.
|
|
34
|
+
} = await space.db.query(Filter.type(ScriptType, { name: scriptName })).run();
|
|
26
35
|
if (script) {
|
|
27
36
|
const {
|
|
28
37
|
objects: [fn],
|
|
29
|
-
} = await space.db.query(Filter.
|
|
38
|
+
} = await space.db.query(Filter.type(FunctionType, { source: Ref.make(script) })).run();
|
|
30
39
|
if (fn) {
|
|
31
|
-
trigger.function =
|
|
40
|
+
trigger.function = Ref.make(fn);
|
|
32
41
|
}
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
if (payload) {
|
|
37
|
-
trigger.meta = payload;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
45
|
switch (template.type) {
|
|
41
46
|
case 'timer': {
|
|
42
|
-
trigger.spec = {
|
|
47
|
+
trigger.spec = { kind: TriggerKind.Timer, cron: template.cron };
|
|
43
48
|
break;
|
|
44
49
|
}
|
|
45
50
|
case 'queue': {
|
|
46
|
-
trigger.spec = {
|
|
51
|
+
trigger.spec = { kind: TriggerKind.Queue, queue: (template.queueDXN as DXN).toString() };
|
|
47
52
|
break;
|
|
48
53
|
}
|
|
49
54
|
default: {
|
|
@@ -54,7 +59,13 @@ export default (context: PluginsContext) =>
|
|
|
54
59
|
return {
|
|
55
60
|
intents: [
|
|
56
61
|
createIntent(SpaceAction.AddObject, { object: trigger, target: space }),
|
|
57
|
-
createIntent(
|
|
62
|
+
createIntent(LayoutAction.Open, {
|
|
63
|
+
part: 'main',
|
|
64
|
+
subject: [`automation-settings${ATTENDABLE_PATH_SEPARATOR}${space.id}`],
|
|
65
|
+
options: {
|
|
66
|
+
workspace: space.id,
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
58
69
|
],
|
|
59
70
|
};
|
|
60
71
|
},
|
|
@@ -6,7 +6,7 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Capabilities, contributes, createSurface, useLayout } from '@dxos/app-framework';
|
|
8
8
|
import { isInstanceOf } from '@dxos/echo-schema';
|
|
9
|
-
import { ScriptType } from '@dxos/functions
|
|
9
|
+
import { ScriptType } from '@dxos/functions';
|
|
10
10
|
import { getSpace, parseId, useSpace } from '@dxos/react-client/echo';
|
|
11
11
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
12
12
|
|
|
@@ -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 { FunctionType, FunctionTrigger } from '@dxos/functions
|
|
10
|
+
import { FunctionType, FunctionTrigger } from '@dxos/functions';
|
|
11
11
|
import { live, useSpaces } from '@dxos/react-client/echo';
|
|
12
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
13
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
@@ -42,7 +42,7 @@ const meta: Meta = {
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
}),
|
|
45
|
-
withLayout({ fullscreen: true,
|
|
45
|
+
withLayout({ fullscreen: true, classNames: 'flex juastify-center m-2' }),
|
|
46
46
|
withTheme,
|
|
47
47
|
],
|
|
48
48
|
parameters: {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Schema } from 'effect';
|
|
5
6
|
import React, { useState } from 'react';
|
|
6
7
|
|
|
7
|
-
import { S } from '@dxos/echo-schema';
|
|
8
8
|
import {
|
|
9
9
|
FunctionType,
|
|
10
10
|
FunctionTrigger,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
TriggerKind,
|
|
13
13
|
type FunctionTriggerType,
|
|
14
14
|
ScriptType,
|
|
15
|
-
} from '@dxos/functions
|
|
15
|
+
} from '@dxos/functions';
|
|
16
16
|
import { type Client, useClient } from '@dxos/react-client';
|
|
17
17
|
import { live, Filter, useQuery, type Space, type Live, getSpace } from '@dxos/react-client/echo';
|
|
18
18
|
import { Clipboard, IconButton, Input, Separator, useTranslation } from '@dxos/react-ui';
|
|
@@ -36,9 +36,9 @@ export type AutomationPanelProps = {
|
|
|
36
36
|
export const AutomationPanel = ({ space, object, initialTrigger, onDone }: AutomationPanelProps) => {
|
|
37
37
|
const { t } = useTranslation(AUTOMATION_PLUGIN);
|
|
38
38
|
const client = useClient();
|
|
39
|
-
const triggers = useQuery(space, Filter.
|
|
40
|
-
const functions = useQuery(space, Filter.
|
|
41
|
-
const scripts = useQuery(space, Filter.
|
|
39
|
+
const triggers = useQuery(space, Filter.type(FunctionTrigger));
|
|
40
|
+
const functions = useQuery(space, Filter.type(FunctionType));
|
|
41
|
+
const scripts = useQuery(space, Filter.type(ScriptType));
|
|
42
42
|
|
|
43
43
|
const [trigger, setTrigger] = useState<FunctionTriggerType | undefined>(initialTrigger);
|
|
44
44
|
const [selected, setSelected] = useState<FunctionTrigger>();
|
|
@@ -85,7 +85,7 @@ export const AutomationPanel = ({ space, object, initialTrigger, onDone }: Autom
|
|
|
85
85
|
</ControlItem>
|
|
86
86
|
) : (
|
|
87
87
|
<div role='none' className={controlItemClasses}>
|
|
88
|
-
<List.Root<FunctionTrigger> items={triggers} isItem={
|
|
88
|
+
<List.Root<FunctionTrigger> items={triggers} isItem={Schema.is(FunctionTrigger)} getId={(field) => field.id}>
|
|
89
89
|
{({ items: triggers }) => (
|
|
90
90
|
<div role='list' className='flex flex-col w-full'>
|
|
91
91
|
{triggers?.map((trigger) => {
|
|
@@ -136,11 +136,11 @@ export const AutomationPanel = ({ space, object, initialTrigger, onDone }: Autom
|
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
const getCopyAction = (client: Client, trigger: FunctionTrigger | undefined) => {
|
|
139
|
-
if (trigger?.spec?.
|
|
139
|
+
if (trigger?.spec?.kind === TriggerKind.Email) {
|
|
140
140
|
return { translationKey: 'trigger copy email', contentProvider: () => `${getSpace(trigger)!.id}@dxos.network` };
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
if (trigger?.spec?.
|
|
143
|
+
if (trigger?.spec?.kind === TriggerKind.Webhook) {
|
|
144
144
|
return { translationKey: 'trigger copy url', contentProvider: () => getWebhookUrl(client, trigger) };
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -158,10 +158,11 @@ const getWebhookUrl = (client: Client, trigger: FunctionTrigger) => {
|
|
|
158
158
|
const getFunctionName = (scripts: ScriptType[], functions: FunctionType[], trigger: FunctionTriggerType) => {
|
|
159
159
|
// TODO(wittjosiah): Truncation should be done in the UI.
|
|
160
160
|
// Warning that the List component is currently a can of worms.
|
|
161
|
-
const shortId = trigger.function && `${trigger.function
|
|
162
|
-
const functionObject = functions.find((fn) =>
|
|
161
|
+
const shortId = trigger.function && `${trigger.function.dxn.toString().slice(0, 16)}…`;
|
|
162
|
+
const functionObject = functions.find((fn) => fn === trigger.function?.target);
|
|
163
163
|
if (!functionObject) {
|
|
164
164
|
return shortId;
|
|
165
165
|
}
|
|
166
|
+
|
|
166
167
|
return scripts.find((s) => functionObject.source?.target?.id === s.id)?.name ?? shortId;
|
|
167
168
|
};
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Schema } from 'effect';
|
|
5
6
|
import React, { useCallback, useMemo } from 'react';
|
|
6
7
|
|
|
7
8
|
import { createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
-
import {
|
|
9
|
-
import { FunctionType, ScriptType } from '@dxos/functions/types';
|
|
9
|
+
import { FunctionType, ScriptType } from '@dxos/functions';
|
|
10
10
|
import { Filter, fullyQualifiedId, useQuery, type Space } from '@dxos/react-client/echo';
|
|
11
11
|
import { Button, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
import { controlItemClasses } from '@dxos/react-ui-form';
|
|
@@ -23,8 +23,8 @@ export type FunctionsPanelProps = {
|
|
|
23
23
|
|
|
24
24
|
export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
|
|
25
25
|
const { t } = useTranslation(AUTOMATION_PLUGIN);
|
|
26
|
-
const functions = useQuery(space, Filter.
|
|
27
|
-
const scripts = useQuery(space, Filter.
|
|
26
|
+
const functions = useQuery(space, Filter.type(FunctionType));
|
|
27
|
+
const scripts = useQuery(space, Filter.type(ScriptType));
|
|
28
28
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
29
29
|
|
|
30
30
|
const functionToScriptMap = useMemo(
|
|
@@ -65,7 +65,7 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
|
|
|
65
65
|
|
|
66
66
|
return (
|
|
67
67
|
<div role='none' className={mx(controlItemClasses)}>
|
|
68
|
-
<List.Root<FunctionType> items={functions} isItem={
|
|
68
|
+
<List.Root<FunctionType> items={functions} isItem={Schema.is(FunctionType)} getId={(func) => func.id}>
|
|
69
69
|
{({ items }) => (
|
|
70
70
|
<div role='list' className='flex flex-col w-full'>
|
|
71
71
|
{items?.map((func) => (
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback, useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type JsonPath, RefImpl, toEffectSchema } from '@dxos/echo-schema';
|
|
8
|
+
import { type FunctionType } from '@dxos/functions';
|
|
9
|
+
import { useOnTransition } from '@dxos/react-ui';
|
|
10
|
+
import { Form, type FormInputStateProps, type QueryRefOptions, useFormValues } from '@dxos/react-ui-form';
|
|
11
|
+
|
|
12
|
+
export type FunctionInputEditorProps = {
|
|
13
|
+
functions: FunctionType[];
|
|
14
|
+
onQueryRefOptions: QueryRefOptions;
|
|
15
|
+
} & FormInputStateProps;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Editor component for function input parameters.
|
|
19
|
+
*/
|
|
20
|
+
export const FunctionInputEditor = ({
|
|
21
|
+
functions,
|
|
22
|
+
getValue,
|
|
23
|
+
onValueChange,
|
|
24
|
+
onQueryRefOptions,
|
|
25
|
+
}: FunctionInputEditorProps) => {
|
|
26
|
+
const selectedFunctionValue = useFormValues(['function' as JsonPath]);
|
|
27
|
+
const selectedFunctionId = useMemo(() => {
|
|
28
|
+
if (selectedFunctionValue instanceof RefImpl) {
|
|
29
|
+
return selectedFunctionValue.dxn.toString().split('dxn:echo:@:').at(1);
|
|
30
|
+
}
|
|
31
|
+
}, [selectedFunctionValue]);
|
|
32
|
+
|
|
33
|
+
const selectedFunction = useMemo(
|
|
34
|
+
() => functions.find((f) => f.id === selectedFunctionId),
|
|
35
|
+
[functions, selectedFunctionId],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
useOnTransition(
|
|
39
|
+
// Clear function parameter input when the function changes.
|
|
40
|
+
selectedFunctionValue,
|
|
41
|
+
(prevValue) => prevValue !== undefined && prevValue !== selectedFunctionValue,
|
|
42
|
+
(currValue) => currValue !== undefined,
|
|
43
|
+
() => onValueChange('object', {}),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const inputSchema = useMemo(() => selectedFunction?.inputSchema, [selectedFunction]);
|
|
47
|
+
const effectSchema = useMemo(() => (inputSchema ? toEffectSchema(inputSchema) : undefined), [inputSchema]);
|
|
48
|
+
const propertyCount = inputSchema?.properties ? Object.keys(inputSchema.properties).length : 0;
|
|
49
|
+
|
|
50
|
+
const values = useMemo(() => getValue() ?? {}, [getValue]);
|
|
51
|
+
|
|
52
|
+
const handleValuesChanged = useCallback(
|
|
53
|
+
(values: any) => {
|
|
54
|
+
onValueChange('object', values);
|
|
55
|
+
},
|
|
56
|
+
[onValueChange],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (selectedFunction === undefined || effectSchema === undefined || propertyCount === 0) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
<h3 className='text-md'>Function parameters</h3>
|
|
66
|
+
{/* TODO(ZaymonFC): Try using <FormFields /> internal component for this nesting.
|
|
67
|
+
This would allow errors to flow up to the root context. */}
|
|
68
|
+
<Form
|
|
69
|
+
schema={effectSchema}
|
|
70
|
+
values={values}
|
|
71
|
+
classNames='p-0'
|
|
72
|
+
onValuesChanged={handleValuesChanged}
|
|
73
|
+
onQueryRefOptions={onQueryRefOptions}
|
|
74
|
+
/>
|
|
75
|
+
</>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback, useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type FunctionTriggerType, TriggerKind, type TriggerType } from '@dxos/functions';
|
|
8
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { SelectInput, type InputProps, useInputProps } from '@dxos/react-ui-form';
|
|
10
|
+
|
|
11
|
+
import { AUTOMATION_PLUGIN } from '../../meta';
|
|
12
|
+
|
|
13
|
+
export type SpecSelectorProps = InputProps;
|
|
14
|
+
|
|
15
|
+
export const SpecSelector = (props: SpecSelectorProps) => {
|
|
16
|
+
const { t } = useTranslation(AUTOMATION_PLUGIN);
|
|
17
|
+
const specProps = useInputProps(['spec' satisfies keyof FunctionTriggerType]);
|
|
18
|
+
|
|
19
|
+
const handleTypeChange = useCallback(
|
|
20
|
+
(_type: any, value: string): TriggerType | undefined => {
|
|
21
|
+
const getDefaultTriggerSpec = (kind: string) => {
|
|
22
|
+
switch (kind) {
|
|
23
|
+
case TriggerKind.Timer:
|
|
24
|
+
return { kind: TriggerKind.Timer, cron: '' };
|
|
25
|
+
case TriggerKind.Subscription:
|
|
26
|
+
return { kind: TriggerKind.Subscription, filter: {} };
|
|
27
|
+
case TriggerKind.Queue:
|
|
28
|
+
return { kind: TriggerKind.Queue, queue: '' };
|
|
29
|
+
case TriggerKind.Email:
|
|
30
|
+
return { kind: TriggerKind.Email };
|
|
31
|
+
case TriggerKind.Webhook:
|
|
32
|
+
return { kind: TriggerKind.Webhook };
|
|
33
|
+
default:
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const defaultSpec = getDefaultTriggerSpec(value);
|
|
39
|
+
if (!defaultSpec) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Update the entire spec object, not just the `spec.kind`.
|
|
44
|
+
specProps.onValueChange('object', defaultSpec);
|
|
45
|
+
},
|
|
46
|
+
[specProps],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const options = useMemo(
|
|
50
|
+
() =>
|
|
51
|
+
Object.values(TriggerKind).map((kind) => ({
|
|
52
|
+
value: kind,
|
|
53
|
+
label: t(`trigger type ${kind}`),
|
|
54
|
+
})),
|
|
55
|
+
[t],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return <SelectInput {...props} options={options} onValueChange={handleTypeChange} />;
|
|
59
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
@@ -7,10 +7,11 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React, { useEffect, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import { FunctionType, FunctionTrigger, TriggerKind } from '@dxos/functions
|
|
10
|
+
import { FunctionType, FunctionTrigger, TriggerKind } from '@dxos/functions';
|
|
11
11
|
import { live } from '@dxos/live-object';
|
|
12
|
+
import { faker } from '@dxos/random';
|
|
12
13
|
import { useSpaces } from '@dxos/react-client/echo';
|
|
13
|
-
import { withClientProvider } from '@dxos/react-client/testing';
|
|
14
|
+
import { ContactType, withClientProvider } from '@dxos/react-client/testing';
|
|
14
15
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
15
16
|
|
|
16
17
|
import { TriggerEditor } from './TriggerEditor';
|
|
@@ -26,7 +27,7 @@ const DefaultStory = () => {
|
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
const trigger = space.db.add(live(FunctionTrigger, { spec: {
|
|
30
|
+
const trigger = space.db.add(live(FunctionTrigger, { spec: { kind: TriggerKind.Timer, cron: '' } }));
|
|
30
31
|
setTrigger(trigger);
|
|
31
32
|
}, [space]);
|
|
32
33
|
|
|
@@ -35,8 +36,8 @@ const DefaultStory = () => {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
return (
|
|
38
|
-
<div role='none' className='
|
|
39
|
-
<TriggerEditor space={space} trigger={trigger} />
|
|
39
|
+
<div role='none' className='w-[32rem] bs-fit border border-separator rounded-sm'>
|
|
40
|
+
<TriggerEditor space={space} trigger={trigger} onSave={(values) => console.log('on save', values)} />
|
|
40
41
|
</div>
|
|
41
42
|
);
|
|
42
43
|
};
|
|
@@ -49,14 +50,22 @@ const meta: Meta = {
|
|
|
49
50
|
withClientProvider({
|
|
50
51
|
createIdentity: true,
|
|
51
52
|
createSpace: true,
|
|
52
|
-
types: [FunctionType, FunctionTrigger],
|
|
53
|
+
types: [FunctionType, FunctionTrigger, ContactType],
|
|
53
54
|
onSpaceCreated: ({ space }) => {
|
|
54
55
|
for (const fn of functions) {
|
|
55
56
|
space.db.add(live(FunctionType, fn));
|
|
56
57
|
}
|
|
58
|
+
Array.from({ length: 10 }).map(() => {
|
|
59
|
+
return space.db.add(
|
|
60
|
+
live(ContactType, {
|
|
61
|
+
name: faker.person.fullName(),
|
|
62
|
+
identifiers: [],
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
});
|
|
57
66
|
},
|
|
58
67
|
}),
|
|
59
|
-
withLayout({ fullscreen: true,
|
|
68
|
+
withLayout({ fullscreen: true, classNames: 'flex justify-center m-2' }),
|
|
60
69
|
withTheme,
|
|
61
70
|
],
|
|
62
71
|
parameters: {
|