Skip to content

Commit e748be6

Browse files
authored
Merge pull request #537 from code0-tech/feat/#434
Export flow functionality for dev mode
2 parents 2e4d313 + ab07950 commit e748be6

File tree

7 files changed

+586
-21466
lines changed

7 files changed

+586
-21466
lines changed

src/components/d-flow/DFlow.view.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import type {
22
DataType,
3-
Flow,
4-
FlowSetting,
3+
Flow, FlowInput,
4+
FlowSetting, FlowSettingInput,
55
FlowType, FunctionDefinition,
66
LiteralValue,
77
Maybe,
8-
NodeFunction,
9-
NodeParameter,
8+
NodeFunction, NodeFunctionInput,
9+
NodeParameter, NodeParameterInput,
1010
NodeParameterValue,
1111
ReferenceValue,
1212
RuntimeParameterDefinition,
1313
Scalars
1414
} from "@code0-tech/sagittarius-graphql-types";
15-
import {ValidationResult} from "../../utils/inspection";
15+
import {ValidationResult} from "../../utils";
1616

1717
export class FlowView {
1818

@@ -156,6 +156,17 @@ export class FlowView {
156156
name: this._name,
157157
}
158158
}
159+
160+
jsonInput(): FlowInput {
161+
return <FlowInput>{
162+
name: this._name,
163+
nodes: this._nodes?.map(node => node.jsonInput()),
164+
settings: this._settings?.map(setting => setting.jsonInput()),
165+
startingNodeId: this._startingNodeId,
166+
type: `gid://sagittarius/FlowType/1`
167+
168+
}
169+
}
159170
}
160171

161172
export class NodeFunctionView {
@@ -229,6 +240,15 @@ export class NodeFunctionView {
229240
updatedAt: this._updatedAt,
230241
}
231242
}
243+
244+
jsonInput(): NodeFunctionInput {
245+
return <NodeFunctionInput>{
246+
nextNodeId: this._nextNodeId,
247+
id: this._id,
248+
parameters: this._parameters ? this._parameters.map(param => param.jsonInput()) : undefined,
249+
runtimeFunctionId: this._functionDefinition?.runtimeFunctionDefinition?.id
250+
}
251+
}
232252
}
233253

234254
export class NodeParameterView {
@@ -306,6 +326,19 @@ export class NodeParameterView {
306326
value: this._value instanceof NodeFunctionView ? this._value.json() : this._value,
307327
}
308328
}
329+
330+
jsonInput(): NodeParameterInput {
331+
return <NodeParameterInput>{
332+
value: this._value instanceof NodeFunctionView ? {
333+
functionValue: this._value.jsonInput()
334+
} : this._value?.__typename === "ReferenceValue" ? {
335+
referenceValue: this._value as ReferenceValue
336+
} : {
337+
literalValue: this._value as LiteralValue
338+
},
339+
runtimeParameterDefinitionId: this.runtimeParameter?.id
340+
}
341+
}
309342
}
310343

311344
export class FlowSettingView {
@@ -362,4 +395,11 @@ export class FlowSettingView {
362395
updatedAt: this._updatedAt
363396
}
364397
}
398+
399+
jsonInput(): FlowSettingInput {
400+
return <FlowSettingInput>{
401+
value: this.value,
402+
flowSettingIdentifier: this.flowSettingIdentifier
403+
}
404+
}
365405
}

src/components/d-flow/control/DFlowControl.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ export const DFlowControl: React.FC = () => {
2929

3030
return <Panel position="bottom-left">
3131
<Flex style={{flexDirection: "column", gap: "1rem"}}>
32-
<Flex align="stretch" style={{gap: ".7rem"}}>
32+
<Flex align="center" style={{gap: ".7rem"}}>
3333
<ButtonGroup>
34-
<Button paddingSize={"xxs"} color={"secondary"} onClick={() => zoomIn()}><IconPlus size={15}/></Button>
35-
<Button paddingSize={"xxs"} color={"secondary"} onClick={() => zoomOut()}><IconMinus size={15}/></Button>
36-
<Button paddingSize={"xxs"} color={"secondary"} onClick={() => center()}><IconFocusCentered size={15}/></Button>
34+
<Button py={"0"} paddingSize={"xxs"} variant={"none"} color={"secondary"}
35+
onClick={() => zoomIn()}><IconPlus size={15}/></Button>
36+
<Button py={"0"} paddingSize={"xxs"} variant={"none"} color={"secondary"} onClick={() => zoomOut()}><IconMinus
37+
size={15}/></Button>
38+
<Button py={"0"} paddingSize={"xxs"} variant={"none"} color={"secondary"}
39+
onClick={() => center()}><IconFocusCentered size={15}/></Button>
3740
</ButtonGroup>
3841
<Badge color={"primary"} style={{border: "none"}}>{getCurrentZoomInPercent()}%</Badge>
3942
</Flex>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"use client"
2+
3+
import React from "react"
4+
import {Panel} from "@xyflow/react"
5+
import {Flow} from "@code0-tech/sagittarius-graphql-types"
6+
import {useService, useStore} from "../../../utils"
7+
import {DFlowReactiveService} from "../DFlow.service"
8+
import {Button} from "../../button/Button"
9+
10+
export interface DFlowExportProps {
11+
flowId: Flow['id']
12+
}
13+
14+
export const DFlowExport: React.FC<DFlowExportProps> = (props) => {
15+
16+
const {flowId} = props
17+
18+
const flowService = useService(DFlowReactiveService)
19+
const flowStore = useStore(DFlowReactiveService)
20+
const flow = React.useMemo(() => flowService.getById(flowId), [flowStore, flowId])
21+
22+
const handleExport = React.useCallback(() => {
23+
if (!flow) return
24+
25+
// Hole JSON-Daten
26+
const data = flow.jsonInput?.()
27+
if (!data) return
28+
29+
const json =
30+
typeof data === "string" ? data : JSON.stringify(data, null, 2)
31+
32+
// Blob + Download-Link
33+
const blob = new Blob([json], { type: "application/json" })
34+
const url = URL.createObjectURL(blob)
35+
36+
const a = document.createElement("a")
37+
a.href = url
38+
a.download = `flow-${flow.name}.json`
39+
document.body.appendChild(a)
40+
a.click()
41+
a.remove()
42+
43+
URL.revokeObjectURL(url)
44+
}, [flow])
45+
46+
return <Panel position="top-right">
47+
<Button paddingSize={"xxs"} onClick={handleExport}>
48+
Export flow
49+
</Button>
50+
</Panel>
51+
}

src/components/d-resizable/DResizable.stories.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
NamespacesProjectsFlowsCreateInput,
3737
NamespacesProjectsFlowsCreatePayload, NamespacesProjectsFlowsDeleteInput, NamespacesProjectsFlowsDeletePayload
3838
} from "@code0-tech/sagittarius-graphql-types";
39+
import {DFlowExport} from "../d-flow/export/DFlowExport";
3940

4041
const meta: Meta = {
4142
title: "Dashboard Resizable",
@@ -72,7 +73,7 @@ export const Dashboard = () => {
7273
const [flowStore, flowService] = useReactiveArrayService<FlowView, DFlowReactiveService>(DFlowReactiveServiceExtend, [new FlowView({
7374
id: "gid://sagittarius/Flow/1",
7475
type: {
75-
id: "gid://sagittarius/TypesFlowType/842",
76+
id: "gid://sagittarius/FlowType/867",
7677
},
7778
name: "de/codezero/examples/REST Flow",
7879
settings: {
@@ -179,6 +180,7 @@ const FlowExample = () => {
179180
<Background variant={BackgroundVariant.Dots} color="rgba(255,255,255, .05)" gap={8} size={2}/>
180181
<DFlowControl/>
181182
<DFlowValidation flowId={"gid://sagittarius/Flow/1"}/>
183+
<DFlowExport flowId={"gid://sagittarius/Flow/1"}/>
182184
{/*<DFlowViewportMiniMap/>*/}
183185
</DFlow>
184186
}

0 commit comments

Comments
 (0)