@dxos/plugin-automation 0.8.4-main.69d29f4 → 0.8.4-main.6fa680abb7
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/AutomationPanel-GH5TMGD6.mjs +11 -0
- package/dist/lib/browser/AutomationSettings-M6VFFEWK.mjs +37 -0
- package/dist/lib/browser/AutomationSettings-M6VFFEWK.mjs.map +7 -0
- package/dist/lib/browser/FunctionsContainer-R4ZMYSFJ.mjs +43 -0
- package/dist/lib/browser/FunctionsContainer-R4ZMYSFJ.mjs.map +7 -0
- package/dist/lib/browser/{FunctionsPanel-ZX4J75UM.mjs → FunctionsPanel-NMA4RYJL.mjs} +3 -3
- package/dist/lib/browser/FunctionsRegistry-TMKAEG5E.mjs +10 -0
- package/dist/lib/browser/TriggerSettings-56AIMOEC.mjs +11 -0
- package/dist/lib/browser/{app-graph-builder-LAQMEBMH.mjs → app-graph-builder-74ILZP25.mjs} +19 -20
- package/dist/lib/browser/app-graph-builder-74ILZP25.mjs.map +7 -0
- package/dist/lib/browser/{chunk-QW3EM35H.mjs → chunk-24ZULVVT.mjs} +60 -15
- package/dist/lib/browser/chunk-24ZULVVT.mjs.map +7 -0
- package/dist/lib/browser/{chunk-BFUIVUQH.mjs → chunk-75XLBFAG.mjs} +11 -16
- package/dist/lib/browser/chunk-75XLBFAG.mjs.map +7 -0
- package/dist/lib/browser/{chunk-YWLEY2FD.mjs → chunk-7HT7OLB5.mjs} +119 -50
- package/dist/lib/browser/chunk-7HT7OLB5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PZNBEKO5.mjs → chunk-EL64ZPPN.mjs} +2 -2
- package/dist/lib/browser/{chunk-PZNBEKO5.mjs.map → chunk-EL64ZPPN.mjs.map} +1 -1
- package/dist/lib/browser/{FunctionsContainer-6QLC7JP4.mjs → chunk-FUVAC5EC.mjs} +15 -48
- package/dist/lib/browser/chunk-FUVAC5EC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JOXPQ27I.mjs → chunk-GVHAETEQ.mjs} +7 -7
- package/dist/lib/browser/chunk-GVHAETEQ.mjs.map +7 -0
- package/dist/lib/browser/chunk-H2MV4XE6.mjs +31 -0
- package/dist/lib/browser/chunk-H2MV4XE6.mjs.map +7 -0
- package/dist/lib/browser/{chunk-RAF2FJST.mjs → chunk-OAZ2JYXV.mjs} +19 -12
- package/dist/lib/browser/chunk-OAZ2JYXV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-BKFQBKYO.mjs → chunk-Z7F7X2C5.mjs} +2 -2
- package/dist/lib/browser/cli/index.mjs +62 -54
- package/dist/lib/browser/cli/index.mjs.map +3 -3
- package/dist/lib/browser/{compute-runtime-WTWLQ67J.mjs → compute-runtime-F3UMRKCL.mjs} +28 -18
- package/dist/lib/browser/compute-runtime-F3UMRKCL.mjs.map +7 -0
- package/dist/lib/browser/hooks/index.mjs +3 -3
- package/dist/lib/browser/index.mjs +26 -25
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{operation-resolver-Q3MWOR7K.mjs → operation-resolver-IRC2DZU7.mjs} +11 -9
- package/dist/lib/browser/operation-resolver-IRC2DZU7.mjs.map +7 -0
- package/dist/lib/browser/react-surface-RCVPEK2V.mjs +65 -0
- package/dist/lib/browser/react-surface-RCVPEK2V.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +2 -2
- package/dist/lib/node-esm/{AutomationPanel-B7NAGDFA.mjs → AutomationPanel-7LW44A5O.mjs} +4 -4
- package/dist/lib/node-esm/AutomationPanel-7LW44A5O.mjs.map +7 -0
- package/dist/lib/node-esm/AutomationSettings-EYJ4YLYT.mjs +38 -0
- package/dist/lib/node-esm/AutomationSettings-EYJ4YLYT.mjs.map +7 -0
- package/dist/lib/node-esm/FunctionsContainer-GYRPQZM7.mjs +44 -0
- package/dist/lib/node-esm/FunctionsContainer-GYRPQZM7.mjs.map +7 -0
- package/dist/lib/node-esm/{FunctionsPanel-SS6GIVNU.mjs → FunctionsPanel-DCXXLSVP.mjs} +3 -3
- package/dist/lib/node-esm/FunctionsPanel-DCXXLSVP.mjs.map +7 -0
- package/dist/lib/node-esm/FunctionsRegistry-7WCHC64E.mjs +11 -0
- package/dist/lib/node-esm/FunctionsRegistry-7WCHC64E.mjs.map +7 -0
- package/dist/lib/node-esm/TriggerSettings-ONY5ZUKW.mjs +12 -0
- package/dist/lib/node-esm/TriggerSettings-ONY5ZUKW.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-builder-4UCMXHYY.mjs → app-graph-builder-VDXPOWCH.mjs} +19 -20
- package/dist/lib/node-esm/app-graph-builder-VDXPOWCH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HQLVREIX.mjs → chunk-2UF55HSG.mjs} +19 -12
- package/dist/lib/node-esm/chunk-2UF55HSG.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-2CKVH7JC.mjs → chunk-37CFAD4Y.mjs} +119 -50
- package/dist/lib/node-esm/chunk-37CFAD4Y.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-RX52VKI2.mjs → chunk-6B4WZRVH.mjs} +7 -7
- package/dist/lib/node-esm/chunk-6B4WZRVH.mjs.map +7 -0
- package/dist/lib/node-esm/{FunctionsContainer-J4O2ULWR.mjs → chunk-6JVB3IHW.mjs} +15 -48
- package/dist/lib/node-esm/chunk-6JVB3IHW.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-JVUE5PMI.mjs +32 -0
- package/dist/lib/node-esm/chunk-JVUE5PMI.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-KWKWOGS5.mjs → chunk-K7T2MVB7.mjs} +11 -16
- package/dist/lib/node-esm/chunk-K7T2MVB7.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-LJAXQ6CX.mjs → chunk-QUJ4MTMR.mjs} +60 -15
- package/dist/lib/node-esm/chunk-QUJ4MTMR.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-K7GCM342.mjs → chunk-R5YEWJCG.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-5FXNN3MV.mjs → chunk-WC5AT7B3.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-5FXNN3MV.mjs.map → chunk-WC5AT7B3.mjs.map} +1 -1
- package/dist/lib/node-esm/cli/index.mjs +62 -54
- package/dist/lib/node-esm/cli/index.mjs.map +3 -3
- package/dist/lib/node-esm/{compute-runtime-ZHROOBLY.mjs → compute-runtime-AMFVJMF2.mjs} +28 -18
- package/dist/lib/node-esm/compute-runtime-AMFVJMF2.mjs.map +7 -0
- package/dist/lib/node-esm/hooks/index.mjs +3 -3
- package/dist/lib/node-esm/index.mjs +26 -25
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{operation-resolver-R5GA4YNO.mjs → operation-resolver-CBLQHL4N.mjs} +11 -9
- package/dist/lib/node-esm/operation-resolver-CBLQHL4N.mjs.map +7 -0
- package/dist/lib/node-esm/{react-surface-S6VZJCEZ.mjs → react-surface-X4ZKOBC3.mjs} +25 -25
- package/dist/lib/node-esm/react-surface-X4ZKOBC3.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +2 -2
- package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts +1 -1
- package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/update/queue.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/util.d.ts +2 -2
- package/dist/types/src/cli/commands/trigger/util.d.ts.map +1 -1
- package/dist/types/src/cli/plugin.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +3 -4
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +1 -0
- package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsRegistry/index.d.ts +3 -1
- package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +2 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +3 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +4 -0
- package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
- package/dist/types/src/containers/AutomationSettings/index.d.ts +3 -0
- package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
- package/dist/types/src/{components → containers/FunctionsContainer}/FunctionsContainer.d.ts +0 -1
- package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
- package/dist/types/src/containers/FunctionsContainer/index.d.ts +3 -0
- package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
- package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
- package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +5 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +2 -1
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +2 -2
- package/dist/types/src/types/capabilities.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +3 -3
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +50 -46
- package/src/AutomationPlugin.tsx +7 -6
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +17 -15
- package/src/capabilities/compute-runtime/compute-runtime.ts +26 -13
- package/src/capabilities/operation-resolver/operation-resolver.ts +7 -6
- package/src/capabilities/react-surface/react-surface.tsx +16 -19
- package/src/cli/commands/trigger/create/queue.ts +4 -4
- package/src/cli/commands/trigger/create/subscription.ts +4 -4
- package/src/cli/commands/trigger/create/timer.ts +4 -4
- package/src/cli/commands/trigger/list.ts +2 -2
- package/src/cli/commands/trigger/remove.ts +2 -2
- package/src/cli/commands/trigger/update/queue.ts +5 -5
- package/src/cli/commands/trigger/update/subscription.ts +5 -5
- package/src/cli/commands/trigger/update/timer.ts +5 -5
- package/src/cli/commands/trigger/util.ts +34 -25
- package/src/cli/plugin.ts +3 -2
- package/src/components/AutomationPanel/AutomationPanel.stories.tsx +3 -3
- package/src/components/AutomationPanel/AutomationPanel.tsx +137 -69
- package/src/components/FunctionsPanel/FunctionsPanel.tsx +9 -11
- package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +9 -10
- package/src/components/FunctionsRegistry/index.ts +4 -1
- package/src/components/TriggerEditor/FunctionInputEditor.tsx +13 -4
- package/src/components/TriggerEditor/SpecSelector.tsx +1 -1
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +46 -4
- package/src/components/TriggerEditor/TriggerEditor.tsx +37 -6
- package/src/components/index.ts +1 -2
- package/src/{components → containers/AutomationSettings}/AutomationSettings.tsx +8 -11
- package/src/containers/AutomationSettings/index.ts +7 -0
- package/src/{components → containers/FunctionsContainer}/FunctionsContainer.tsx +10 -13
- package/src/containers/FunctionsContainer/index.ts +7 -0
- package/src/containers/TriggerSettings/TriggerSettings.tsx +26 -0
- package/src/containers/TriggerSettings/index.ts +6 -0
- package/src/containers/index.ts +9 -0
- package/src/hooks/useComputeRuntimeCallback.ts +1 -1
- package/src/hooks/useTriggerRuntimeControls.ts +22 -8
- package/src/meta.ts +1 -1
- package/src/testing/test-functions.ts +5 -5
- package/src/translations.ts +2 -0
- package/src/types/capabilities.ts +3 -2
- package/src/types/events.ts +1 -1
- package/src/types/schema.ts +3 -3
- package/dist/lib/browser/AutomationPanel-FAS6ADCW.mjs +0 -11
- package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs +0 -56
- package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs.map +0 -7
- package/dist/lib/browser/FunctionsContainer-6QLC7JP4.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-LAQMEBMH.mjs.map +0 -7
- package/dist/lib/browser/chunk-54PANILA.mjs +0 -14
- package/dist/lib/browser/chunk-54PANILA.mjs.map +0 -7
- package/dist/lib/browser/chunk-BFUIVUQH.mjs.map +0 -7
- package/dist/lib/browser/chunk-JOXPQ27I.mjs.map +0 -7
- package/dist/lib/browser/chunk-QW3EM35H.mjs.map +0 -7
- package/dist/lib/browser/chunk-RAF2FJST.mjs.map +0 -7
- package/dist/lib/browser/chunk-YWLEY2FD.mjs.map +0 -7
- package/dist/lib/browser/compute-runtime-WTWLQ67J.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-Q3MWOR7K.mjs.map +0 -7
- package/dist/lib/browser/react-surface-EV3AC62F.mjs +0 -65
- package/dist/lib/browser/react-surface-EV3AC62F.mjs.map +0 -7
- package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs +0 -57
- package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs.map +0 -7
- package/dist/lib/node-esm/FunctionsContainer-J4O2ULWR.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-4UCMXHYY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2CKVH7JC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7QRUPEHH.mjs +0 -16
- package/dist/lib/node-esm/chunk-7QRUPEHH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HQLVREIX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KWKWOGS5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LJAXQ6CX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RX52VKI2.mjs.map +0 -7
- package/dist/lib/node-esm/compute-runtime-ZHROOBLY.mjs.map +0 -7
- package/dist/lib/node-esm/operation-resolver-R5GA4YNO.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-S6VZJCEZ.mjs.map +0 -7
- package/dist/types/src/components/AutomationSettings.d.ts +0 -5
- package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
- package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
- package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
- package/src/components/TriggerSettings.tsx +0 -25
- /package/dist/lib/browser/{AutomationPanel-FAS6ADCW.mjs.map → AutomationPanel-GH5TMGD6.mjs.map} +0 -0
- /package/dist/lib/browser/{FunctionsPanel-ZX4J75UM.mjs.map → FunctionsPanel-NMA4RYJL.mjs.map} +0 -0
- /package/dist/lib/{node-esm/AutomationPanel-B7NAGDFA.mjs.map → browser/FunctionsRegistry-TMKAEG5E.mjs.map} +0 -0
- /package/dist/lib/{node-esm/FunctionsPanel-SS6GIVNU.mjs.map → browser/TriggerSettings-56AIMOEC.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-BKFQBKYO.mjs.map → chunk-Z7F7X2C5.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-K7GCM342.mjs.map → chunk-R5YEWJCG.mjs.map} +0 -0
- /package/dist/types/src/{components → containers/TriggerSettings}/TriggerSettings.d.ts +0 -0
|
@@ -13,7 +13,7 @@ import * as Option from 'effect/Option';
|
|
|
13
13
|
import { CommandConfig } from '@dxos/cli-util';
|
|
14
14
|
import { flushAndSync, print, spaceLayer, withTypes } from '@dxos/cli-util';
|
|
15
15
|
import { Common } from '@dxos/cli-util';
|
|
16
|
-
import { DXN, Database, Filter, Obj, Query, Ref
|
|
16
|
+
import { DXN, Database, Filter, JsonSchema, Obj, Query, Ref } from '@dxos/echo';
|
|
17
17
|
import { Function, Trigger } from '@dxos/functions';
|
|
18
18
|
|
|
19
19
|
import { Deep, Delay, Enabled, Input, TriggerId, Typename } from '../options';
|
|
@@ -40,7 +40,7 @@ export const subscription = Command.make(
|
|
|
40
40
|
onSome: (id) => Effect.succeed(id),
|
|
41
41
|
});
|
|
42
42
|
const dxn = DXN.fromLocalObjectId(triggerId);
|
|
43
|
-
const trigger = yield* Database.
|
|
43
|
+
const trigger = yield* Database.resolve(dxn, Trigger.Trigger);
|
|
44
44
|
if (trigger.spec?.kind !== 'subscription') {
|
|
45
45
|
return yield* Effect.fail(new Error(`Invalid trigger type: ${trigger.spec?.kind}`));
|
|
46
46
|
}
|
|
@@ -96,7 +96,7 @@ const extractCurrentTypename = (spec: Trigger.SubscriptionSpec | undefined): Opt
|
|
|
96
96
|
*/
|
|
97
97
|
const updateFunction = Effect.fn(function* (trigger: Trigger.Trigger, functionIdOption: Option.Option<string>) {
|
|
98
98
|
let currentFn: Function.Function | undefined = trigger.function
|
|
99
|
-
? yield* Database.
|
|
99
|
+
? yield* Database.load(trigger.function) as any
|
|
100
100
|
: undefined;
|
|
101
101
|
if (currentFn && !Obj.instanceOf(Function.Function, currentFn)) {
|
|
102
102
|
currentFn = undefined;
|
|
@@ -115,7 +115,7 @@ const updateFunction = Effect.fn(function* (trigger: Trigger.Trigger, functionId
|
|
|
115
115
|
onNone: () => selectFunction(),
|
|
116
116
|
onSome: (id) => Effect.succeed(id),
|
|
117
117
|
});
|
|
118
|
-
const functions = yield* Database.
|
|
118
|
+
const functions = yield* Database.runQuery(Filter.type(Function.Function));
|
|
119
119
|
const foundFn = functions.find((fn) => fn.id === functionId);
|
|
120
120
|
if (!foundFn || !Obj.instanceOf(Function.Function, foundFn)) {
|
|
121
121
|
return yield* Effect.fail(new Error(`Function not found: ${functionId}`));
|
|
@@ -246,7 +246,7 @@ const updateInput = Effect.fn(function* (
|
|
|
246
246
|
if (shouldChangeInput) {
|
|
247
247
|
const inputObj = yield* Option.match(inputOption, {
|
|
248
248
|
onNone: () =>
|
|
249
|
-
promptForSchemaInput(fn.inputSchema ?
|
|
249
|
+
promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : undefined, currentInput),
|
|
250
250
|
onSome: (value) => Effect.succeed(value as Record<string, any>),
|
|
251
251
|
});
|
|
252
252
|
Obj.change(trigger, (mutableTrigger) => {
|
|
@@ -12,7 +12,7 @@ import * as Option from 'effect/Option';
|
|
|
12
12
|
import { CommandConfig } from '@dxos/cli-util';
|
|
13
13
|
import { flushAndSync, print, spaceLayer, withTypes } from '@dxos/cli-util';
|
|
14
14
|
import { Common } from '@dxos/cli-util';
|
|
15
|
-
import { DXN, Database, Filter, Obj, Ref
|
|
15
|
+
import { DXN, Database, Filter, JsonSchema, Obj, Ref } from '@dxos/echo';
|
|
16
16
|
import { Function, Trigger } from '@dxos/functions';
|
|
17
17
|
|
|
18
18
|
import { Cron, Enabled, Input, TriggerId } from '../options';
|
|
@@ -37,7 +37,7 @@ export const timer = Command.make(
|
|
|
37
37
|
onSome: (id) => Effect.succeed(id),
|
|
38
38
|
});
|
|
39
39
|
const dxn = DXN.fromLocalObjectId(triggerId);
|
|
40
|
-
const trigger = yield* Database.
|
|
40
|
+
const trigger = yield* Database.resolve(dxn, Trigger.Trigger);
|
|
41
41
|
if (!trigger.spec || trigger.spec?.kind !== 'timer') {
|
|
42
42
|
return yield* Effect.fail(new Error(`Invalid trigger type: ${trigger.spec?.kind}`));
|
|
43
43
|
}
|
|
@@ -68,7 +68,7 @@ export const timer = Command.make(
|
|
|
68
68
|
*/
|
|
69
69
|
const updateFunction = Effect.fn(function* (trigger: Trigger.Trigger, functionIdOption: Option.Option<string>) {
|
|
70
70
|
let currentFn: Function.Function | undefined = trigger.function
|
|
71
|
-
? yield* Database.
|
|
71
|
+
? yield* Database.load(trigger.function) as any
|
|
72
72
|
: undefined;
|
|
73
73
|
if (currentFn && !Obj.instanceOf(Function.Function, currentFn)) {
|
|
74
74
|
currentFn = undefined;
|
|
@@ -87,7 +87,7 @@ const updateFunction = Effect.fn(function* (trigger: Trigger.Trigger, functionId
|
|
|
87
87
|
onNone: () => selectFunction(),
|
|
88
88
|
onSome: (id) => Effect.succeed(id),
|
|
89
89
|
});
|
|
90
|
-
const functions = yield* Database.
|
|
90
|
+
const functions = yield* Database.runQuery(Filter.type(Function.Function));
|
|
91
91
|
const foundFn = functions.find((fn) => fn.id === functionId);
|
|
92
92
|
if (!foundFn || !Obj.instanceOf(Function.Function, foundFn)) {
|
|
93
93
|
return yield* Effect.fail(new Error(`Function not found: ${functionId}`));
|
|
@@ -161,7 +161,7 @@ const updateInput = Effect.fn(function* (
|
|
|
161
161
|
if (shouldChangeInput) {
|
|
162
162
|
const inputObj = yield* Option.match(inputOption, {
|
|
163
163
|
onNone: () =>
|
|
164
|
-
promptForSchemaInput(fn.inputSchema ?
|
|
164
|
+
promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : undefined, currentInput),
|
|
165
165
|
onSome: (value) => Effect.succeed(value as Record<string, any>),
|
|
166
166
|
});
|
|
167
167
|
Obj.change(trigger, (mutableTrigger) => {
|
|
@@ -12,10 +12,10 @@ import type * as Schema from 'effect/Schema';
|
|
|
12
12
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
13
13
|
|
|
14
14
|
import { FormBuilder } from '@dxos/cli-util';
|
|
15
|
-
import { Annotation, Database, Entity, Filter, Obj, Ref, Type } from '@dxos/echo';
|
|
15
|
+
import { Annotation, Database, Entity, Feed, Filter, Obj, Ref, Type } from '@dxos/echo';
|
|
16
16
|
import { getProperties } from '@dxos/effect';
|
|
17
17
|
import { Function, Trigger } from '@dxos/functions';
|
|
18
|
-
import {
|
|
18
|
+
import { FeedAnnotation } from '@dxos/schema';
|
|
19
19
|
|
|
20
20
|
export type TriggerRemoteStatus = 'available' | 'not available' | 'n/a';
|
|
21
21
|
|
|
@@ -34,7 +34,7 @@ export const getTriggerRemoteStatus = (trigger: Trigger.Trigger, remoteCronIds:
|
|
|
34
34
|
* Pretty prints a trigger with ANSI colors.
|
|
35
35
|
*/
|
|
36
36
|
export const printTrigger = Effect.fn(function* (trigger: Trigger.Trigger, remoteStatus?: TriggerRemoteStatus) {
|
|
37
|
-
const fn = trigger.function && (yield* Database.
|
|
37
|
+
const fn = trigger.function && (yield* Database.load(trigger.function));
|
|
38
38
|
|
|
39
39
|
return FormBuilder.make({
|
|
40
40
|
title: trigger.id,
|
|
@@ -239,7 +239,7 @@ export const promptForSchemaInput = Effect.fn(function* (
|
|
|
239
239
|
inputObj[key] = templateStr === '' && defaultValue !== undefined ? defaultValue : templateStr;
|
|
240
240
|
} else {
|
|
241
241
|
const annotation = Annotation.ReferenceAnnotation.getFromAst(propType).pipe(Option.getOrThrow);
|
|
242
|
-
const objects = yield* Database.
|
|
242
|
+
const objects = yield* Database.runQuery(Filter.typename(annotation.typename));
|
|
243
243
|
if (objects.length === 0) {
|
|
244
244
|
inputObj[key] = undefined;
|
|
245
245
|
} else {
|
|
@@ -272,7 +272,7 @@ export const promptForSchemaInput = Effect.fn(function* (
|
|
|
272
272
|
* Queries the database for functions and prompts the user to select one.
|
|
273
273
|
*/
|
|
274
274
|
export const selectFunction = Effect.fn(function* () {
|
|
275
|
-
const functions = yield* Database.
|
|
275
|
+
const functions = yield* Database.runQuery(Filter.type(Function.Function));
|
|
276
276
|
|
|
277
277
|
if (functions.length === 0) {
|
|
278
278
|
return yield* Effect.fail(new Error('No functions available'));
|
|
@@ -296,7 +296,7 @@ export const selectFunction = Effect.fn(function* () {
|
|
|
296
296
|
* Queries the database for triggers and prompts the user to select one.
|
|
297
297
|
*/
|
|
298
298
|
export const selectTrigger = Effect.fn(function* (kind?: Trigger.Kind) {
|
|
299
|
-
const triggers = yield* Database.
|
|
299
|
+
const triggers = yield* Database.runQuery(Filter.type(Trigger.Trigger));
|
|
300
300
|
const filteredTriggers = kind ? triggers.filter((trigger) => trigger.spec?.kind === kind) : triggers;
|
|
301
301
|
|
|
302
302
|
if (filteredTriggers.length === 0) {
|
|
@@ -306,7 +306,7 @@ export const selectTrigger = Effect.fn(function* (kind?: Trigger.Kind) {
|
|
|
306
306
|
const choices = yield* Effect.all(
|
|
307
307
|
filteredTriggers.map((trigger) =>
|
|
308
308
|
Effect.gen(function* () {
|
|
309
|
-
const fn = trigger.function ? yield* Database.
|
|
309
|
+
const fn = trigger.function ? yield* Database.load(trigger.function) : undefined;
|
|
310
310
|
const functionName = fn && Obj.instanceOf(Function.Function, fn) ? (fn.name ?? fn.key ?? fn.id) : undefined;
|
|
311
311
|
const title = functionName ?? trigger.id;
|
|
312
312
|
const description = `${trigger.enabled ? 'enabled' : 'disabled'} - ${trigger.spec?.kind ?? 'unknown'}`;
|
|
@@ -330,46 +330,55 @@ export const selectTrigger = Effect.fn(function* (kind?: Trigger.Kind) {
|
|
|
330
330
|
|
|
331
331
|
/**
|
|
332
332
|
* Selects a queue interactively from available queues in the database.
|
|
333
|
-
* Queries schemas with
|
|
334
|
-
* and extracts queue DXNs from the objects'
|
|
333
|
+
* Queries schemas with FeedAnnotation, then queries objects of those types,
|
|
334
|
+
* and extracts queue DXNs from the objects' feed properties.
|
|
335
335
|
*/
|
|
336
336
|
export const selectQueue = Effect.fn(function* () {
|
|
337
|
-
// Query schema registry for schemas with
|
|
338
|
-
const schemas = yield* Database.
|
|
337
|
+
// Query schema registry for schemas with FeedAnnotation.
|
|
338
|
+
const schemas = yield* Database.runSchemaQuery({ location: ['database', 'runtime'] });
|
|
339
339
|
|
|
340
|
-
// Filter schemas that have
|
|
341
|
-
const
|
|
342
|
-
const annotation =
|
|
340
|
+
// Filter schemas that have FeedAnnotation.
|
|
341
|
+
const feedSchemas = schemas.filter((schema) => {
|
|
342
|
+
const annotation = FeedAnnotation.get(schema);
|
|
343
343
|
return Option.isSome(annotation) && annotation.value === true;
|
|
344
344
|
});
|
|
345
345
|
|
|
346
|
-
if (
|
|
347
|
-
return yield* Effect.fail(new Error('No schemas with
|
|
346
|
+
if (feedSchemas.length === 0) {
|
|
347
|
+
return yield* Effect.fail(new Error('No schemas with Feed annotation found'));
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
// Collect all objects with queues
|
|
350
|
+
// Collect all objects with queues.
|
|
351
351
|
const queueChoices: Array<{ title: string; value: string; description?: string }> = [];
|
|
352
352
|
|
|
353
|
-
// Process each schema,
|
|
354
|
-
for (const schema of
|
|
353
|
+
// Process each feed schema, loading the Feed object to extract queue DXN.
|
|
354
|
+
for (const schema of feedSchemas) {
|
|
355
355
|
yield* Effect.gen(function* () {
|
|
356
356
|
const typename = Type.getTypename(schema);
|
|
357
|
-
const objects = yield* Database.
|
|
357
|
+
const objects = yield* Database.runQuery(Filter.type(typename));
|
|
358
358
|
|
|
359
359
|
for (const obj of objects) {
|
|
360
|
-
// Access the
|
|
361
|
-
const
|
|
362
|
-
if (!
|
|
360
|
+
// Access the feed property (which is a Ref<Feed>).
|
|
361
|
+
const feedRef = (obj as any).feed as Ref.Ref<any> | undefined;
|
|
362
|
+
if (!feedRef) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const feedObj = yield* Effect.promise(() => feedRef.tryLoad());
|
|
367
|
+
if (!feedObj || !Obj.instanceOf(Feed.Feed, feedObj)) {
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const queueDxn = Feed.getQueueDxn(feedObj);
|
|
372
|
+
if (!queueDxn) {
|
|
363
373
|
continue;
|
|
364
374
|
}
|
|
365
375
|
|
|
366
|
-
const queueDxn = queueRef.dxn.toString();
|
|
367
376
|
const label = Obj.getLabel(obj) ?? obj.id;
|
|
368
377
|
const description = Obj.getTypename(obj);
|
|
369
378
|
|
|
370
379
|
queueChoices.push({
|
|
371
380
|
title: label,
|
|
372
|
-
value: queueDxn,
|
|
381
|
+
value: queueDxn.toString(),
|
|
373
382
|
description,
|
|
374
383
|
});
|
|
375
384
|
}
|
package/src/cli/plugin.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Plugin } from '@dxos/app-framework';
|
|
6
|
+
import { AppPlugin } from '@dxos/app-toolkit';
|
|
6
7
|
import { ClientEvents } from '@dxos/plugin-client/types';
|
|
7
8
|
|
|
8
9
|
// NOTE: Must not import from index to avoid pulling in react dependencies.
|
|
@@ -13,7 +14,7 @@ import { AutomationEvents } from '../types';
|
|
|
13
14
|
import { trigger } from './commands';
|
|
14
15
|
|
|
15
16
|
export const AutomationPlugin = Plugin.define(meta).pipe(
|
|
16
|
-
|
|
17
|
+
AppPlugin.addCommandModule({ commands: [trigger] }),
|
|
17
18
|
Plugin.addModule({
|
|
18
19
|
activatesOn: ClientEvents.ClientReady,
|
|
19
20
|
activatesAfter: [AutomationEvents.ComputeRuntimeReady],
|
|
@@ -20,18 +20,18 @@ const DefaultStory = () => {
|
|
|
20
20
|
const space = spaces[1];
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<div className='
|
|
23
|
+
<div className='w-96'>
|
|
24
24
|
<AutomationPanel space={space} />
|
|
25
25
|
</div>
|
|
26
26
|
);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const meta = {
|
|
30
|
-
title: 'plugins/plugin-automation/AutomationPanel',
|
|
30
|
+
title: 'plugins/plugin-automation/components/AutomationPanel',
|
|
31
31
|
component: AutomationPanel as any,
|
|
32
32
|
render: DefaultStory,
|
|
33
33
|
decorators: [
|
|
34
|
-
withTheme,
|
|
34
|
+
withTheme(),
|
|
35
35
|
withClientProvider({
|
|
36
36
|
createIdentity: true,
|
|
37
37
|
createSpace: true,
|
|
@@ -6,35 +6,36 @@ import * as Array from 'effect/Array';
|
|
|
6
6
|
import * as EFn from 'effect/Function';
|
|
7
7
|
import * as Match from 'effect/Match';
|
|
8
8
|
import * as Schema from 'effect/Schema';
|
|
9
|
-
import React, { useMemo, useState } from 'react';
|
|
9
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
11
|
import { Filter, Obj, Tag } from '@dxos/echo';
|
|
12
12
|
import { Function, Script, Trigger } from '@dxos/functions';
|
|
13
|
+
import { KEY_QUEUE_CURSOR } from '@dxos/functions-runtime';
|
|
13
14
|
import { FunctionsServiceClient } from '@dxos/functions-runtime/edge';
|
|
14
15
|
import { useTypeOptions } from '@dxos/plugin-space';
|
|
15
16
|
import { type Client, useClient } from '@dxos/react-client';
|
|
16
|
-
import { type Space, useQuery } from '@dxos/react-client/echo';
|
|
17
|
-
import { Clipboard, IconButton, Input, Separator,
|
|
18
|
-
import {
|
|
17
|
+
import { type Space, useObject, useQuery } from '@dxos/react-client/echo';
|
|
18
|
+
import { Clipboard, IconButton, type IconButtonProps, Input, Separator, useTranslation } from '@dxos/react-ui';
|
|
19
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
19
20
|
import { List } from '@dxos/react-ui-list';
|
|
20
|
-
import {
|
|
21
|
+
import { Pipeline } from '@dxos/types';
|
|
21
22
|
import { ghostHover, mx } from '@dxos/ui-theme';
|
|
22
23
|
import { isNonNullable } from '@dxos/util';
|
|
23
24
|
|
|
24
25
|
import { meta } from '../../meta';
|
|
25
26
|
import { TriggerEditor, type TriggerEditorProps } from '../TriggerEditor';
|
|
26
27
|
|
|
27
|
-
const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-
|
|
28
|
+
const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-h-[2.5rem]';
|
|
28
29
|
|
|
29
|
-
export type AutomationPanelProps =
|
|
30
|
+
export type AutomationPanelProps = {
|
|
30
31
|
space: Space;
|
|
31
32
|
object?: Obj.Unknown;
|
|
32
33
|
initialTrigger?: Trigger.Trigger;
|
|
33
34
|
onDone?: () => void;
|
|
34
|
-
}
|
|
35
|
+
};
|
|
35
36
|
|
|
36
37
|
// TODO(burdon): Factor out common layout with ViewEditor.
|
|
37
|
-
export const AutomationPanel = ({
|
|
38
|
+
export const AutomationPanel = ({ space, object, initialTrigger, onDone }: AutomationPanelProps) => {
|
|
38
39
|
const { t } = useTranslation(meta.id);
|
|
39
40
|
const client = useClient();
|
|
40
41
|
const functionsServiceClient = useMemo(() => FunctionsServiceClient.fromClient(client), [client]);
|
|
@@ -49,7 +50,6 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
|
|
|
49
50
|
annotation: {
|
|
50
51
|
location: ['database', 'runtime'],
|
|
51
52
|
kind: ['user'],
|
|
52
|
-
registered: ['registered'],
|
|
53
53
|
},
|
|
54
54
|
});
|
|
55
55
|
|
|
@@ -74,7 +74,9 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
|
|
|
74
74
|
|
|
75
75
|
const handleSave: TriggerEditorProps['onSave'] = (trigger) => {
|
|
76
76
|
if (selected) {
|
|
77
|
-
|
|
77
|
+
Obj.change(selected, (mutable) => {
|
|
78
|
+
Object.assign(mutable, trigger);
|
|
79
|
+
});
|
|
78
80
|
} else {
|
|
79
81
|
space.db.add(Trigger.make(trigger));
|
|
80
82
|
}
|
|
@@ -93,9 +95,16 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
|
|
|
93
95
|
await functionsServiceClient.forceRunCronTrigger(space.id, trigger.id);
|
|
94
96
|
};
|
|
95
97
|
|
|
98
|
+
const handleResetCursor = async (trigger: Trigger.Trigger) => {
|
|
99
|
+
Obj.change(trigger, (t) => {
|
|
100
|
+
Obj.deleteKeys(t, KEY_QUEUE_CURSOR);
|
|
101
|
+
});
|
|
102
|
+
await space.db.flush({ indexes: true });
|
|
103
|
+
};
|
|
104
|
+
|
|
96
105
|
if (trigger) {
|
|
97
106
|
return (
|
|
98
|
-
<
|
|
107
|
+
<Settings.Item title={t('trigger editor title')} description={t('trigger editor description')}>
|
|
99
108
|
<TriggerEditor
|
|
100
109
|
db={space.db}
|
|
101
110
|
trigger={trigger}
|
|
@@ -105,12 +114,12 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
|
|
|
105
114
|
onSave={handleSave}
|
|
106
115
|
onCancel={handleCancel}
|
|
107
116
|
/>
|
|
108
|
-
</
|
|
117
|
+
</Settings.Item>
|
|
109
118
|
);
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
return (
|
|
113
|
-
<
|
|
122
|
+
<Settings.Container>
|
|
114
123
|
{filteredTriggers.length > 0 && (
|
|
115
124
|
<List.Root<Trigger.Trigger>
|
|
116
125
|
items={filteredTriggers}
|
|
@@ -118,75 +127,134 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
|
|
|
118
127
|
getId={(field) => field.id}
|
|
119
128
|
>
|
|
120
129
|
{({ items: filteredTriggers }) => (
|
|
121
|
-
<div role='list' className='flex flex-col
|
|
122
|
-
{filteredTriggers?.map((trigger) =>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
onCheckedChange={(checked) =>
|
|
134
|
-
Obj.change(trigger, (t) => {
|
|
135
|
-
t.enabled = checked;
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
/>
|
|
139
|
-
</Input.Root>
|
|
140
|
-
|
|
141
|
-
<div className={'flex'}>
|
|
142
|
-
<List.ItemTitle
|
|
143
|
-
classNames='pli-1 cursor-pointer is-0 shrink truncate'
|
|
144
|
-
onClick={() => handleSelect(trigger)}
|
|
145
|
-
>
|
|
146
|
-
{getFunctionName(functions, trigger) ?? '∅'}
|
|
147
|
-
</List.ItemTitle>
|
|
148
|
-
|
|
149
|
-
{/* TODO: a better way to expose copy action */}
|
|
150
|
-
{copyAction && (
|
|
151
|
-
<Clipboard.IconButton
|
|
152
|
-
label={t(copyAction.translationKey)}
|
|
153
|
-
value={copyAction.contentProvider()}
|
|
154
|
-
/>
|
|
155
|
-
)}
|
|
156
|
-
</div>
|
|
157
|
-
|
|
158
|
-
<List.ItemButton
|
|
159
|
-
autoHide={false}
|
|
160
|
-
disabled={!trigger.enabled || trigger.spec?.kind !== 'timer'}
|
|
161
|
-
icon='ph--play--regular'
|
|
162
|
-
label='Force run'
|
|
163
|
-
onClick={() => handleForceRunTrigger(trigger)}
|
|
164
|
-
/>
|
|
165
|
-
|
|
166
|
-
<List.ItemDeleteButton onClick={() => handleDelete(trigger)} />
|
|
167
|
-
</List.Item>
|
|
168
|
-
);
|
|
169
|
-
})}
|
|
130
|
+
<div role='list' className='flex flex-col w-full'>
|
|
131
|
+
{filteredTriggers?.map((trigger) => (
|
|
132
|
+
<TriggerListItem
|
|
133
|
+
key={trigger.id}
|
|
134
|
+
trigger={trigger}
|
|
135
|
+
functions={functions}
|
|
136
|
+
onSelect={handleSelect}
|
|
137
|
+
onDelete={handleDelete}
|
|
138
|
+
onResetCursor={handleResetCursor}
|
|
139
|
+
onForceRun={handleForceRunTrigger}
|
|
140
|
+
/>
|
|
141
|
+
))}
|
|
170
142
|
</div>
|
|
171
143
|
)}
|
|
172
144
|
</List.Root>
|
|
173
145
|
)}
|
|
174
|
-
|
|
146
|
+
|
|
147
|
+
{filteredTriggers.length > 0 && <Separator classNames='my-4' />}
|
|
175
148
|
<IconButton icon='ph--plus--regular' label={t('new trigger label')} onClick={handleAdd} />
|
|
176
|
-
</
|
|
149
|
+
</Settings.Container>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const TriggerListItem = ({
|
|
154
|
+
trigger,
|
|
155
|
+
functions,
|
|
156
|
+
onSelect,
|
|
157
|
+
onDelete,
|
|
158
|
+
onResetCursor,
|
|
159
|
+
onForceRun,
|
|
160
|
+
}: {
|
|
161
|
+
trigger: Trigger.Trigger;
|
|
162
|
+
functions: Function.Function[];
|
|
163
|
+
onSelect?: (trigger: Trigger.Trigger) => void;
|
|
164
|
+
onDelete?: (trigger: Trigger.Trigger) => void;
|
|
165
|
+
onResetCursor?: (trigger: Trigger.Trigger) => void;
|
|
166
|
+
onForceRun?: (trigger: Trigger.Trigger) => void;
|
|
167
|
+
}) => {
|
|
168
|
+
const client = useClient();
|
|
169
|
+
const copyAction = getCopyAction(client, trigger);
|
|
170
|
+
const { t } = useTranslation(meta.id);
|
|
171
|
+
const cursor = Obj.getKeys(trigger, KEY_QUEUE_CURSOR).at(0)?.id;
|
|
172
|
+
const [snapshot, updateTrigger] = useObject(trigger);
|
|
173
|
+
|
|
174
|
+
const enabled = snapshot.enabled ?? false;
|
|
175
|
+
const onEnabledChange = (checked: boolean) => {
|
|
176
|
+
updateTrigger((trigger) => {
|
|
177
|
+
trigger.enabled = checked;
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const handleSelect = useCallback(() => {
|
|
182
|
+
onSelect?.(trigger);
|
|
183
|
+
}, [onSelect, trigger]);
|
|
184
|
+
|
|
185
|
+
const handleDelete = useCallback(() => {
|
|
186
|
+
onDelete?.(trigger);
|
|
187
|
+
}, [onDelete, trigger]);
|
|
188
|
+
|
|
189
|
+
const handleResetCursor = useCallback(() => {
|
|
190
|
+
onResetCursor?.(trigger);
|
|
191
|
+
}, [onResetCursor, trigger]);
|
|
192
|
+
|
|
193
|
+
const handleForceRun = useCallback(() => {
|
|
194
|
+
onForceRun?.(trigger);
|
|
195
|
+
}, [onForceRun, trigger]);
|
|
196
|
+
|
|
197
|
+
const actionProps = useMemo<IconButtonProps | undefined>(() => {
|
|
198
|
+
if (trigger.spec?.kind === 'timer' && onForceRun) {
|
|
199
|
+
return {
|
|
200
|
+
disabled: !enabled || trigger.spec?.kind !== 'timer',
|
|
201
|
+
icon: 'ph--play--regular',
|
|
202
|
+
label: 'Force run',
|
|
203
|
+
onClick: handleForceRun,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (trigger.spec?.kind === 'queue' && onResetCursor) {
|
|
208
|
+
return {
|
|
209
|
+
disabled: !cursor,
|
|
210
|
+
icon: 'ph--arrow-clockwise--regular',
|
|
211
|
+
label: 'Reset cursor',
|
|
212
|
+
onClick: handleResetCursor,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}, [enabled, trigger.spec?.kind, handleForceRun]);
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<List.Item<Obj.Snapshot<Trigger.Trigger>>
|
|
219
|
+
key={trigger.id}
|
|
220
|
+
item={snapshot}
|
|
221
|
+
classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
|
|
222
|
+
>
|
|
223
|
+
<Input.Root>
|
|
224
|
+
<Input.Switch checked={enabled} onCheckedChange={onEnabledChange} />
|
|
225
|
+
</Input.Root>
|
|
226
|
+
|
|
227
|
+
<div className={'flex'}>
|
|
228
|
+
<List.ItemTitle classNames='px-1 cursor-pointer w-0 shrink truncate' onClick={handleSelect}>
|
|
229
|
+
{getFunctionName(functions, trigger) ?? '∅'}
|
|
230
|
+
{cursor && <div className='text-xs text-description truncate ml-4'>Position: {cursor}</div>}
|
|
231
|
+
</List.ItemTitle>
|
|
232
|
+
|
|
233
|
+
{copyAction && (
|
|
234
|
+
<Clipboard.IconButton label={t(copyAction.translationKey)} value={copyAction.contentProvider()} />
|
|
235
|
+
)}
|
|
236
|
+
</div>
|
|
237
|
+
|
|
238
|
+
{actionProps ? <List.ItemButton {...actionProps} autoHide={false} /> : <div />}
|
|
239
|
+
|
|
240
|
+
{onDelete && <List.ItemDeleteButton onClick={handleDelete} />}
|
|
241
|
+
</List.Item>
|
|
177
242
|
);
|
|
178
243
|
};
|
|
179
244
|
|
|
180
245
|
const getCopyAction = (client: Client, trigger: Trigger.Trigger | undefined) => {
|
|
181
246
|
if (trigger?.spec?.kind === 'email') {
|
|
182
247
|
return {
|
|
183
|
-
translationKey: 'trigger copy email',
|
|
248
|
+
translationKey: 'trigger copy email' as const,
|
|
184
249
|
contentProvider: () => `${Obj.getDatabase(trigger)!.spaceId}@dxos.network`,
|
|
185
250
|
};
|
|
186
251
|
}
|
|
187
252
|
|
|
188
253
|
if (trigger?.spec?.kind === 'webhook') {
|
|
189
|
-
return {
|
|
254
|
+
return {
|
|
255
|
+
translationKey: 'trigger copy url' as const,
|
|
256
|
+
contentProvider: () => getWebhookUrl(client, trigger!),
|
|
257
|
+
};
|
|
190
258
|
}
|
|
191
259
|
|
|
192
260
|
return undefined;
|
|
@@ -217,7 +285,7 @@ const scriptMatch = (script: Script.Script) => (trigger: Trigger.Trigger) => {
|
|
|
217
285
|
return fn.source?.target === script;
|
|
218
286
|
};
|
|
219
287
|
|
|
220
|
-
const projectMatch = (project:
|
|
288
|
+
const projectMatch = (project: Pipeline.Pipeline) => {
|
|
221
289
|
const viewQueries = EFn.pipe(
|
|
222
290
|
project.columns,
|
|
223
291
|
Array.map((column) => column.view.target),
|
|
@@ -244,7 +312,7 @@ const triggerMatch = Match.type<Obj.Unknown>().pipe(
|
|
|
244
312
|
(obj) => scriptMatch(obj),
|
|
245
313
|
),
|
|
246
314
|
Match.when(
|
|
247
|
-
(obj) => Obj.instanceOf(
|
|
315
|
+
(obj) => Obj.instanceOf(Pipeline.Pipeline, obj),
|
|
248
316
|
(obj) => projectMatch(obj),
|
|
249
317
|
),
|
|
250
318
|
Match.orElse((_obj) => () => true),
|
|
@@ -5,21 +5,19 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { useCallback, useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
9
|
+
import { LayoutOperation, getObjectPathFromObject } from '@dxos/app-toolkit';
|
|
10
10
|
import { Obj } from '@dxos/echo';
|
|
11
11
|
import { Function, Script } from '@dxos/functions';
|
|
12
12
|
import { SpaceOperation } from '@dxos/plugin-space/types';
|
|
13
13
|
import { Filter, type Space, useQuery } from '@dxos/react-client/echo';
|
|
14
14
|
import { Button, IconButton, useTranslation } from '@dxos/react-ui';
|
|
15
|
-
import {
|
|
15
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
16
16
|
import { List } from '@dxos/react-ui-list';
|
|
17
17
|
import { ghostHover, mx } from '@dxos/ui-theme';
|
|
18
18
|
|
|
19
19
|
import { meta } from '../../meta';
|
|
20
20
|
|
|
21
|
-
const grid = 'grid grid-cols-[1fr_auto] min-bs-[2.5rem]';
|
|
22
|
-
|
|
23
21
|
export type FunctionsPanelProps = {
|
|
24
22
|
space: Space;
|
|
25
23
|
};
|
|
@@ -60,7 +58,7 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
|
|
|
60
58
|
(func: Function.Function) => {
|
|
61
59
|
const script = functionToScriptMap[func.id];
|
|
62
60
|
if (script) {
|
|
63
|
-
void invokePromise(
|
|
61
|
+
void invokePromise(LayoutOperation.Open, { subject: [getObjectPathFromObject(script)] });
|
|
64
62
|
}
|
|
65
63
|
},
|
|
66
64
|
[functionToScriptMap, invokePromise],
|
|
@@ -72,16 +70,16 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
|
|
|
72
70
|
);
|
|
73
71
|
|
|
74
72
|
return (
|
|
75
|
-
<
|
|
73
|
+
<Settings.Container>
|
|
76
74
|
{functions.length > 0 && (
|
|
77
75
|
<List.Root<Function.Function> items={functions} isItem={Schema.is(Function.Function)} getId={(func) => func.id}>
|
|
78
76
|
{({ items }) => (
|
|
79
|
-
<div role='list' className='flex flex-col
|
|
77
|
+
<div role='list' className='flex flex-col w-full'>
|
|
80
78
|
{items?.map((func) => (
|
|
81
79
|
<List.Item<Function.Function>
|
|
82
80
|
key={func.id}
|
|
83
81
|
item={func}
|
|
84
|
-
classNames={mx(grid
|
|
82
|
+
classNames={mx('grid grid-cols-[1fr_auto] min-h-[2.5rem] min-h-[3rem] px-2 items-center', ghostHover)}
|
|
85
83
|
>
|
|
86
84
|
<div className='flex flex-col truncate'>
|
|
87
85
|
<List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
|
|
@@ -105,7 +103,7 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
|
|
|
105
103
|
</List.Root>
|
|
106
104
|
)}
|
|
107
105
|
|
|
108
|
-
{functions.length === 0 && <div className='text-center
|
|
109
|
-
</
|
|
106
|
+
{functions.length === 0 && <div className='text-center py-4 text-description'>{t('no functions found')}</div>}
|
|
107
|
+
</Settings.Container>
|
|
110
108
|
);
|
|
111
109
|
};
|