diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index 51c203bf..2257cddc 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -15,19 +15,19 @@ const ( ) const ( - WorkflowTypeAuto = "auto" - WorkflowTypeManual = "manual" + WorkflowTriggerAuto = "auto" + WorkflowTriggerManual = "manual" ) type Workflow struct { Meta Name string `json:"name"` Description string `json:"description"` - Type string `json:"type"` - Crontab string `json:"crontab"` + Trigger string `json:"trigger"` + TriggerCron string `json:"triggerCron"` + Enabled bool `json:"enabled"` Content *WorkflowNode `json:"content"` Draft *WorkflowNode `json:"draft"` - Enabled bool `json:"enabled"` HasDraft bool `json:"hasDraft"` } diff --git a/internal/repository/workflow.go b/internal/repository/workflow.go index 39f5823f..681b177e 100644 --- a/internal/repository/workflow.go +++ b/internal/repository/workflow.go @@ -20,8 +20,8 @@ func NewWorkflowRepository() *WorkflowRepository { func (w *WorkflowRepository) ListEnabledAuto(ctx context.Context) ([]domain.Workflow, error) { records, err := app.GetApp().Dao().FindRecordsByFilter( "workflow", - "enabled={:enabled} && type={:type}", - "-created", 1000, 0, dbx.Params{"enabled": true, "type": domain.WorkflowTypeAuto}, + "enabled={:enabled} && trigger={:trigger}", + "-created", 1000, 0, dbx.Params{"enabled": true, "trigger": domain.WorkflowTriggerAuto}, ) if err != nil { return nil, err @@ -83,13 +83,12 @@ func record2Workflow(record *models.Record) (*domain.Workflow, error) { }, Name: record.GetString("name"), Description: record.GetString("description"), - Type: record.GetString("type"), - Crontab: record.GetString("crontab"), + Trigger: record.GetString("trigger"), + TriggerCron: record.GetString("triggerCron"), Enabled: record.GetBool("enabled"), + Content: content, + Draft: draft, HasDraft: record.GetBool("hasDraft"), - - Content: content, - Draft: draft, } return workflow, nil diff --git a/internal/workflow/event.go b/internal/workflow/event.go index 06c91676..a15861ab 100644 --- a/internal/workflow/event.go +++ b/internal/workflow/event.go @@ -46,16 +46,16 @@ func update(ctx context.Context, record *models.Record) error { id := record.Id enabled := record.GetBool("enabled") - executeMethod := record.GetString("type") + trigger := record.GetString("trigger") scheduler := app.GetScheduler() - if !enabled || executeMethod == domain.WorkflowTypeManual { + if !enabled || trigger == domain.WorkflowTriggerManual { scheduler.Remove(id) scheduler.Start() return nil } - err := scheduler.Add(id, record.GetString("crontab"), func() { + err := scheduler.Add(id, record.GetString("triggerCron"), func() { NewWorkflowService(repository.NewWorkflowRepository()).Run(ctx, &domain.WorkflowRunReq{ Id: id, }) diff --git a/internal/workflow/service.go b/internal/workflow/service.go index 65a08397..1bd3c0ca 100644 --- a/internal/workflow/service.go +++ b/internal/workflow/service.go @@ -33,7 +33,7 @@ func (s *WorkflowService) InitSchedule(ctx context.Context) error { } scheduler := app.GetScheduler() for _, workflow := range workflows { - err := scheduler.Add(workflow.Id, workflow.Crontab, func() { + err := scheduler.Add(workflow.Id, workflow.TriggerCron, func() { s.Run(ctx, &domain.WorkflowRunReq{ Id: workflow.Id, }) diff --git a/migrations/1735966817_updated_workflow.go b/migrations/1735966817_updated_workflow.go new file mode 100644 index 00000000..6d714a0b --- /dev/null +++ b/migrations/1735966817_updated_workflow.go @@ -0,0 +1,116 @@ +package migrations + +import ( + "encoding/json" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/daos" + m "github.com/pocketbase/pocketbase/migrations" + "github.com/pocketbase/pocketbase/models/schema" +) + +func init() { + m.Register(func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // update + edit_trigger := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "vqoajwjq", + "name": "trigger", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "auto", + "manual" + ] + } + }`), edit_trigger); err != nil { + return err + } + collection.Schema.AddField(edit_trigger) + + // update + edit_triggerCron := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "8ho247wh", + "name": "triggerCron", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_triggerCron); err != nil { + return err + } + collection.Schema.AddField(edit_triggerCron) + + return dao.SaveCollection(collection) + }, func(db dbx.Builder) error { + dao := daos.New(db); + + collection, err := dao.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + // update + edit_trigger := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "vqoajwjq", + "name": "type", + "type": "select", + "required": false, + "presentable": false, + "unique": false, + "options": { + "maxSelect": 1, + "values": [ + "auto", + "manual" + ] + } + }`), edit_trigger); err != nil { + return err + } + collection.Schema.AddField(edit_trigger) + + // update + edit_triggerCron := &schema.SchemaField{} + if err := json.Unmarshal([]byte(`{ + "system": false, + "id": "8ho247wh", + "name": "crontab", + "type": "text", + "required": false, + "presentable": false, + "unique": false, + "options": { + "min": null, + "max": null, + "pattern": "" + } + }`), edit_triggerCron); err != nil { + return err + } + collection.Schema.AddField(edit_triggerCron) + + return dao.SaveCollection(collection) + }) +} diff --git a/ui/src/components/workflow/WorkflowElement.tsx b/ui/src/components/workflow/WorkflowElement.tsx index 0f2ed3d3..c609853f 100644 --- a/ui/src/components/workflow/WorkflowElement.tsx +++ b/ui/src/components/workflow/WorkflowElement.tsx @@ -6,7 +6,7 @@ import { produce } from "immer"; import Show from "@/components/Show"; import { deployProvidersMap } from "@/domain/provider"; import { notifyChannelsMap } from "@/domain/settings"; -import { type WorkflowNode, WorkflowNodeType } from "@/domain/workflow"; +import { WORKFLOW_TRIGGERS, type WorkflowNode, WorkflowNodeType } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; @@ -35,21 +35,21 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { return (
- {node.config?.executionMethod === "auto" + {node.config?.trigger === WORKFLOW_TRIGGERS.AUTO ? t("workflow.props.trigger.auto") - : node.config?.executionMethod === "manual" + : node.config?.trigger === WORKFLOW_TRIGGERS.MANUAL ? t("workflow.props.trigger.manual") - : ""} + : " "} - {node.config?.executionMethod === "auto" ? (node.config?.crontab as string) : ""} + {node.config?.trigger === WORKFLOW_TRIGGERS.AUTO ? (node.config?.triggerCron as string) : ""}
); } case WorkflowNodeType.Apply: { - return {node.config?.domain as string}; + return {(node.config?.domain as string) || " "}; } case WorkflowNodeType.Deploy: { @@ -57,7 +57,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { return ( - {t(provider?.name ?? "")} + {t(provider?.name ?? " ")} ); } @@ -66,7 +66,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { const channel = notifyChannelsMap.get(node.config?.channel as string); return (
- {t(channel?.name ?? "")} + {t(channel?.name ?? " ")} {(node.config?.subject as string) ?? ""} diff --git a/ui/src/components/workflow/node/AddNode.tsx b/ui/src/components/workflow/node/AddNode.tsx index b9d93fee..f01532de 100644 --- a/ui/src/components/workflow/node/AddNode.tsx +++ b/ui/src/components/workflow/node/AddNode.tsx @@ -32,7 +32,7 @@ const AddNode = ({ node, disabled }: AddNodeProps) => { ].map(([type, label, icon]) => { return { key: type as string, - disabled: true, + disabled: disabled, label: t(label as string), icon: icon, onClick: () => { diff --git a/ui/src/components/workflow/node/StartNodeForm.tsx b/ui/src/components/workflow/node/StartNodeForm.tsx index 22664ac3..01d7541a 100644 --- a/ui/src/components/workflow/node/StartNodeForm.tsx +++ b/ui/src/components/workflow/node/StartNodeForm.tsx @@ -7,7 +7,7 @@ import { produce } from "immer"; import { z } from "zod"; import Show from "@/components/Show"; -import { type WorkflowNode, type WorkflowStartNodeConfig } from "@/domain/workflow"; +import { WORKFLOW_TRIGGERS, type WorkflowNode, type WorkflowStartNodeConfig } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { getNextCronExecutions, validCronExpression } from "@/utils/cron"; @@ -19,8 +19,8 @@ export type StartNodeFormProps = { const initFormModel = (): WorkflowStartNodeConfig => { return { - executionMethod: "auto", - crontab: "0 0 * * *", + trigger: WORKFLOW_TRIGGERS.AUTO, + triggerCron: "0 0 * * *", }; }; @@ -32,19 +32,19 @@ const StartNodeForm = ({ node }: StartNodeFormProps) => { const formSchema = z .object({ - executionMethod: z.string({ message: t("workflow_node.start.form.trigger.placeholder") }).min(1, t("workflow_node.start.form.trigger.placeholder")), - crontab: z.string().nullish(), + trigger: z.string({ message: t("workflow_node.start.form.trigger.placeholder") }).min(1, t("workflow_node.start.form.trigger.placeholder")), + triggerCron: z.string().nullish(), }) .superRefine((data, ctx) => { - if (data.executionMethod !== "auto") { + if (data.trigger !== WORKFLOW_TRIGGERS.AUTO) { return; } - if (!validCronExpression(data.crontab!)) { + if (!validCronExpression(data.triggerCron!)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: t("workflow_node.start.form.trigger_cron.errmsg.invalid"), - path: ["crontab"], + path: ["triggerCron"], }); } }); @@ -67,51 +67,45 @@ const StartNodeForm = ({ node }: StartNodeFormProps) => { }, }); - const [triggerType, setTriggerType] = useState(node?.config?.executionMethod); - const [triggerCronLastExecutions, setTriggerCronExecutions] = useState([]); + const fieldTrigger = Form.useWatch("trigger", formInst); + const fieldTriggerCron = Form.useWatch("triggerCron", formInst); + const [fieldTriggerCronExpectedExecutions, setFieldTriggerCronExpectedExecutions] = useState([]); useEffect(() => { - setTriggerType(node?.config?.executionMethod); - setTriggerCronExecutions(getNextCronExecutions(node?.config?.crontab as string, 5)); - }, [node?.config?.executionMethod, node?.config?.crontab]); + setFieldTriggerCronExpectedExecutions(getNextCronExecutions(fieldTriggerCron, 5)); + }, [fieldTriggerCron]); - const handleTriggerTypeChange = (value: string) => { - setTriggerType(value); - - if (value === "auto") { - formInst.setFieldValue("crontab", formInst.getFieldValue("crontab") || initFormModel().crontab); + const handleTriggerChange = (value: string) => { + if (value === WORKFLOW_TRIGGERS.AUTO) { + formInst.setFieldValue("triggerCron", formInst.getFieldValue("triggerCron") || initFormModel().triggerCron); } }; - const handleTriggerCronChange = (value: string) => { - setTriggerCronExecutions(getNextCronExecutions(value, 5)); - }; - return (
} > - handleTriggerTypeChange(e.target.value)}> - {t("workflow_node.start.form.trigger.option.auto.label")} - {t("workflow_node.start.form.trigger.option.manual.label")} + handleTriggerChange(e.target.value)}> + {t("workflow_node.start.form.trigger.option.auto.label")} + {t("workflow_node.start.form.trigger.option.manual.label")}