@arronqzy/react-blueprint 1.0.18 → 1.0.21
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/README.md +36 -26
- package/dist/blueprint.css +336 -54
- package/index.ts +23 -0
- package/package.json +5 -5
- package/src/BlueprintContextMenu.tsx +1 -1
- package/src/BlueprintNodeConfigSidebar.tsx +10 -2
- package/src/blueprint.css +336 -54
- package/src/components/ApiCollectionManagerDialog.tsx +448 -0
- package/src/components/BlueprintExecutionLogPanel.tsx +10 -2
- package/src/components/BlueprintLibrarySelect.tsx +1 -1
- package/src/components/BlueprintMetaDialog.tsx +1 -1
- package/src/components/BlueprintNodeSwitchTaskDialog.tsx +1 -1
- package/src/components/BlueprintPanelToolbar.tsx +10 -2
- package/src/components/ClockNodeConfigPanel.tsx +1 -1
- package/src/components/ConfigHintIcon.tsx +1 -1
- package/src/components/FetchNodeConfigPanel.tsx +314 -3
- package/src/components/FetchUrlAutocomplete.tsx +1 -1
- package/src/components/JsonLintTextarea.tsx +97 -0
- package/src/components/JsonNodeConfigPanel.tsx +14 -7
- package/src/components/LogicNodeConfigPanel.tsx +1 -1
- package/src/components/ScopeTemplateAutocompleteHost.tsx +4 -8
- package/src/components/StorageKeyAutocomplete.tsx +1 -1
- package/src/components/StorageNodeConfigPanel.tsx +1 -1
- package/src/components/ViewElementMultiSelect.tsx +1 -1
- package/src/edges/BlueprintSmoothEdge.tsx +2 -2
- package/src/graph/blueprint-graph.ts +9 -0
- package/src/graph/document.ts +12 -0
- package/src/graph/sync-edges.ts +2 -2
- package/src/hooks/useBlueprintFlowState.ts +1 -1
- package/src/index.tsx +41 -28
- package/src/library/api-collection-db.ts +98 -0
- package/src/library/api-collection-store.ts +139 -0
- package/src/nodes/AndFlowNode.tsx +4 -3
- package/src/nodes/BlueprintFlowNode.tsx +8 -3
- package/src/nodes/BlueprintNodeCard.tsx +137 -121
- package/src/nodes/BlueprintNodeShell.tsx +2 -1
- package/src/nodes/ClockFlowNode.tsx +1 -1
- package/src/nodes/EventFlowNode.tsx +1 -1
- package/src/nodes/FetchFlowNode.tsx +1 -1
- package/src/nodes/JsonFlowNode.tsx +1 -1
- package/src/nodes/LifecycleFlowNode.tsx +2 -1
- package/src/nodes/LogicFlowNode.tsx +1 -1
- package/src/nodes/StorageFlowNode.tsx +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useI18n } from "@arronqzy/i18n/react";
|
|
1
|
+
import { useI18nOptional as useI18n } from "@arronqzy/i18n/react";
|
|
2
2
|
import { cn } from "@arronqzy/ui";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
3
4
|
|
|
4
5
|
export type BlueprintNodeCardProps = {
|
|
5
6
|
nodeId: string;
|
|
@@ -9,78 +10,130 @@ export type BlueprintNodeCardProps = {
|
|
|
9
10
|
subtitle?: string;
|
|
10
11
|
/** 调试执行进度(如时钟 2/3) */
|
|
11
12
|
progressLabel?: string;
|
|
12
|
-
variant?: "blueprint" | "logic" | "and" | "lifecycle" | "event" | "fetch" | "json" | "storage" | "clock";
|
|
13
|
+
variant?: "blueprint" | "view" | "logic" | "and" | "lifecycle" | "event" | "fetch" | "json" | "storage" | "clock";
|
|
13
14
|
selected?: boolean;
|
|
14
15
|
hideLeadingDot?: boolean;
|
|
15
16
|
onSelect?: (nodeId: string) => void;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
blueprint: {
|
|
20
|
-
accent: "border-l-primary",
|
|
21
|
-
badge: "bg-primary/10 text-primary",
|
|
22
|
-
dot: "bg-primary",
|
|
23
|
-
},
|
|
24
|
-
logic: {
|
|
25
|
-
accent: "border-l-sky-500 dark:border-l-sky-400",
|
|
26
|
-
badge: "bg-sky-500/10 text-sky-700 dark:text-sky-300",
|
|
27
|
-
dot: "bg-sky-500",
|
|
28
|
-
},
|
|
29
|
-
and: {
|
|
30
|
-
accent: "border-l-indigo-500 dark:border-l-indigo-400",
|
|
31
|
-
badge: "bg-indigo-500/10 text-indigo-700 dark:text-indigo-300",
|
|
32
|
-
dot: "bg-indigo-500",
|
|
33
|
-
},
|
|
34
|
-
lifecycle: {
|
|
35
|
-
accent: "border-l-amber-500 dark:border-l-amber-400",
|
|
36
|
-
badge: "bg-amber-500/10 text-amber-700 dark:text-amber-300",
|
|
37
|
-
dot: "bg-amber-500",
|
|
38
|
-
},
|
|
39
|
-
event: {
|
|
40
|
-
accent: "border-l-fuchsia-500 dark:border-l-fuchsia-400",
|
|
41
|
-
badge: "bg-fuchsia-500/10 text-fuchsia-700 dark:text-fuchsia-300",
|
|
42
|
-
dot: "bg-fuchsia-500",
|
|
43
|
-
},
|
|
44
|
-
fetch: {
|
|
45
|
-
accent: "border-l-violet-500 dark:border-l-violet-400",
|
|
46
|
-
badge: "bg-violet-500/10 text-violet-700 dark:text-violet-300",
|
|
47
|
-
dot: "bg-violet-500",
|
|
48
|
-
},
|
|
49
|
-
json: {
|
|
50
|
-
accent: "border-l-teal-500 dark:border-l-teal-400",
|
|
51
|
-
badge: "bg-teal-500/10 text-teal-700 dark:text-teal-300",
|
|
52
|
-
dot: "bg-teal-500",
|
|
53
|
-
},
|
|
54
|
-
storage: {
|
|
55
|
-
accent: "border-l-emerald-500 dark:border-l-emerald-400",
|
|
56
|
-
badge: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
|
|
57
|
-
dot: "bg-emerald-500",
|
|
58
|
-
},
|
|
59
|
-
clock: {
|
|
60
|
-
accent: "border-l-rose-500 dark:border-l-rose-400",
|
|
61
|
-
badge: "bg-rose-500/10 text-rose-700 dark:text-rose-300",
|
|
62
|
-
dot: "bg-rose-500",
|
|
63
|
-
},
|
|
64
|
-
} as const;
|
|
65
|
-
|
|
66
|
-
function NodeGrip() {
|
|
19
|
+
function IconSvg({ children }: { children: ReactNode }) {
|
|
67
20
|
return (
|
|
68
|
-
<
|
|
69
|
-
|
|
21
|
+
<svg
|
|
22
|
+
viewBox="0 0 24 24"
|
|
23
|
+
fill="none"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
strokeWidth="2"
|
|
26
|
+
strokeLinecap="round"
|
|
27
|
+
strokeLinejoin="round"
|
|
70
28
|
aria-hidden="true"
|
|
71
29
|
>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<span className="h-[3px] w-[3px] rounded-full bg-current" />
|
|
75
|
-
</span>
|
|
76
|
-
<span className="flex gap-[3px]">
|
|
77
|
-
<span className="h-[3px] w-[3px] rounded-full bg-current" />
|
|
78
|
-
<span className="h-[3px] w-[3px] rounded-full bg-current" />
|
|
79
|
-
</span>
|
|
80
|
-
</div>
|
|
30
|
+
{children}
|
|
31
|
+
</svg>
|
|
81
32
|
);
|
|
82
33
|
}
|
|
83
34
|
|
|
35
|
+
function VariantIcon({
|
|
36
|
+
variant,
|
|
37
|
+
}: {
|
|
38
|
+
variant: NonNullable<BlueprintNodeCardProps["variant"]>;
|
|
39
|
+
}) {
|
|
40
|
+
switch (variant) {
|
|
41
|
+
case "logic":
|
|
42
|
+
return (
|
|
43
|
+
<IconSvg>
|
|
44
|
+
<path d="M6 4v6a4 4 0 0 0 4 4h4" />
|
|
45
|
+
<path d="M14 14v6" />
|
|
46
|
+
<circle cx="6" cy="4" r="1.5" fill="currentColor" stroke="none" />
|
|
47
|
+
<circle cx="14" cy="20" r="1.5" fill="currentColor" stroke="none" />
|
|
48
|
+
<circle cx="18" cy="14" r="1.5" fill="currentColor" stroke="none" />
|
|
49
|
+
</IconSvg>
|
|
50
|
+
);
|
|
51
|
+
case "and":
|
|
52
|
+
return (
|
|
53
|
+
<IconSvg>
|
|
54
|
+
<path d="M8 6v12" />
|
|
55
|
+
<path d="M8 12h8" />
|
|
56
|
+
<path d="M16 6v12" />
|
|
57
|
+
</IconSvg>
|
|
58
|
+
);
|
|
59
|
+
case "lifecycle":
|
|
60
|
+
return (
|
|
61
|
+
<IconSvg>
|
|
62
|
+
<circle cx="12" cy="12" r="7" />
|
|
63
|
+
<path d="M12 8v4l2.5 1.5" />
|
|
64
|
+
</IconSvg>
|
|
65
|
+
);
|
|
66
|
+
case "event":
|
|
67
|
+
return (
|
|
68
|
+
<IconSvg>
|
|
69
|
+
<path d="M13 2 4 14h7l-1 8 9-12h-7l1-8z" />
|
|
70
|
+
</IconSvg>
|
|
71
|
+
);
|
|
72
|
+
case "fetch":
|
|
73
|
+
return (
|
|
74
|
+
<IconSvg>
|
|
75
|
+
<path d="M12 3v12" />
|
|
76
|
+
<path d="m7 10 5 5 5-5" />
|
|
77
|
+
<path d="M5 19h14" />
|
|
78
|
+
</IconSvg>
|
|
79
|
+
);
|
|
80
|
+
case "json":
|
|
81
|
+
return (
|
|
82
|
+
<IconSvg>
|
|
83
|
+
<path d="M8 4c-2 0-3 1.5-3 4s1 4 3 4" />
|
|
84
|
+
<path d="M8 12c-2 0-3 1.5-3 4s1 4 3 4" />
|
|
85
|
+
<path d="M16 4c2 0 3 1.5 3 4s-1 4-3 4" />
|
|
86
|
+
<path d="M16 12c2 0 3 1.5 3 4s-1 4-3 4" />
|
|
87
|
+
</IconSvg>
|
|
88
|
+
);
|
|
89
|
+
case "storage":
|
|
90
|
+
return (
|
|
91
|
+
<IconSvg>
|
|
92
|
+
<ellipse cx="12" cy="6" rx="7" ry="3" />
|
|
93
|
+
<path d="M5 6v6c0 1.7 3.1 3 7 3s7-1.3 7-3V6" />
|
|
94
|
+
<path d="M5 12v6c0 1.7 3.1 3 7 3s7-1.3 7-3v-6" />
|
|
95
|
+
</IconSvg>
|
|
96
|
+
);
|
|
97
|
+
case "clock":
|
|
98
|
+
return (
|
|
99
|
+
<IconSvg>
|
|
100
|
+
<circle cx="12" cy="12" r="8" />
|
|
101
|
+
<path d="M12 8v4.5L15 15" />
|
|
102
|
+
</IconSvg>
|
|
103
|
+
);
|
|
104
|
+
case "blueprint":
|
|
105
|
+
return (
|
|
106
|
+
<IconSvg>
|
|
107
|
+
<circle cx="7" cy="7" r="2.5" />
|
|
108
|
+
<circle cx="17" cy="7" r="2.5" />
|
|
109
|
+
<circle cx="12" cy="17" r="2.5" />
|
|
110
|
+
<path d="M9.2 8.2 14.8 8.2" />
|
|
111
|
+
<path d="M8.2 9.2 11 14.8" />
|
|
112
|
+
<path d="M15.8 9.2 13 14.8" />
|
|
113
|
+
</IconSvg>
|
|
114
|
+
);
|
|
115
|
+
case "view":
|
|
116
|
+
return (
|
|
117
|
+
<IconSvg>
|
|
118
|
+
<rect x="3" y="5" width="18" height="14" rx="2" />
|
|
119
|
+
<path d="M3 9h18" />
|
|
120
|
+
<path d="M8 14h4" />
|
|
121
|
+
</IconSvg>
|
|
122
|
+
);
|
|
123
|
+
default:
|
|
124
|
+
return (
|
|
125
|
+
<IconSvg>
|
|
126
|
+
<circle cx="7" cy="7" r="2.5" />
|
|
127
|
+
<circle cx="17" cy="7" r="2.5" />
|
|
128
|
+
<circle cx="12" cy="17" r="2.5" />
|
|
129
|
+
<path d="M9.2 8.2 14.8 8.2" />
|
|
130
|
+
<path d="M8.2 9.2 11 14.8" />
|
|
131
|
+
<path d="M15.8 9.2 13 14.8" />
|
|
132
|
+
</IconSvg>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
84
137
|
export function BlueprintNodeCard({
|
|
85
138
|
nodeId,
|
|
86
139
|
label,
|
|
@@ -89,81 +142,42 @@ export function BlueprintNodeCard({
|
|
|
89
142
|
progressLabel,
|
|
90
143
|
variant = "blueprint",
|
|
91
144
|
selected = false,
|
|
92
|
-
hideLeadingDot = false,
|
|
93
145
|
onSelect,
|
|
94
146
|
}: BlueprintNodeCardProps) {
|
|
95
147
|
const { t } = useI18n();
|
|
96
|
-
const
|
|
148
|
+
const showMeta = Boolean(meta && meta !== label);
|
|
97
149
|
|
|
98
150
|
return (
|
|
99
151
|
<div
|
|
100
152
|
data-blueprint-node-card
|
|
101
153
|
className={cn(
|
|
102
|
-
"bp-node-card
|
|
103
|
-
"
|
|
104
|
-
hideLeadingDot
|
|
105
|
-
? cn(
|
|
106
|
-
"border-t-[3px]",
|
|
107
|
-
variant === "event"
|
|
108
|
-
? "border-t-fuchsia-500 dark:border-t-fuchsia-400"
|
|
109
|
-
: "border-t-amber-500 dark:border-t-amber-400"
|
|
110
|
-
)
|
|
111
|
-
: cn("border-l-[3px]", v.accent),
|
|
112
|
-
selected &&
|
|
113
|
-
"border-primary/50 shadow-[0_0_0_1px_hsl(var(--primary)/0.35),0_4px_12px_hsl(var(--primary)/0.12)]"
|
|
154
|
+
"bp-node-card bp-flow-drag-handle",
|
|
155
|
+
selected && "bp-node-card--selected"
|
|
114
156
|
)}
|
|
157
|
+
title={t("blueprint.node.dragToMove")}
|
|
115
158
|
>
|
|
116
|
-
<div
|
|
117
|
-
className={cn(
|
|
118
|
-
"bp-flow-drag-handle flex cursor-grab items-center gap-2 border-b border-border/50 px-2 py-1.5",
|
|
119
|
-
"bg-muted/25 text-muted-foreground active:cursor-grabbing"
|
|
120
|
-
)}
|
|
121
|
-
title={t("blueprint.node.dragToMove")}
|
|
122
|
-
>
|
|
123
|
-
<NodeGrip />
|
|
124
|
-
{meta ? (
|
|
125
|
-
<span
|
|
126
|
-
className={cn(
|
|
127
|
-
"min-w-0 flex-1 truncate rounded px-1.5 py-0.5 text-[10px] font-medium leading-none tracking-wide",
|
|
128
|
-
v.badge
|
|
129
|
-
)}
|
|
130
|
-
title={meta}
|
|
131
|
-
>
|
|
132
|
-
{meta}
|
|
133
|
-
</span>
|
|
134
|
-
) : null}
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
159
|
<button
|
|
138
160
|
type="button"
|
|
139
|
-
className=
|
|
140
|
-
"nodrag flex w-full text-left outline-none transition-colors hover:bg-accent/30",
|
|
141
|
-
"focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-inset",
|
|
142
|
-
hideLeadingDot
|
|
143
|
-
? cn("px-2.5 py-2", subtitle ? "items-start" : "items-center")
|
|
144
|
-
: "items-start gap-2 px-2.5 py-2"
|
|
145
|
-
)}
|
|
161
|
+
className="bp-node-card__body"
|
|
146
162
|
onClick={(e) => {
|
|
147
163
|
e.stopPropagation();
|
|
148
164
|
onSelect?.(nodeId);
|
|
149
165
|
}}
|
|
150
166
|
>
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
/>
|
|
156
|
-
|
|
157
|
-
<div className="
|
|
158
|
-
<div className="
|
|
159
|
-
<div className="
|
|
160
|
-
{label}
|
|
161
|
-
</div>
|
|
167
|
+
<span
|
|
168
|
+
className={cn("bp-node-icon", `bp-node-icon--${variant}`)}
|
|
169
|
+
aria-hidden="true"
|
|
170
|
+
>
|
|
171
|
+
<VariantIcon variant={variant} />
|
|
172
|
+
</span>
|
|
173
|
+
<div className="bp-node-card__content">
|
|
174
|
+
<div className="bp-node-card__title-row">
|
|
175
|
+
<div className="bp-node-card__title">{label}</div>
|
|
162
176
|
{progressLabel ? (
|
|
163
177
|
<span
|
|
164
178
|
className={cn(
|
|
165
|
-
"
|
|
166
|
-
|
|
179
|
+
"bp-node-card__badge",
|
|
180
|
+
`bp-node-card__badge--${variant}`
|
|
167
181
|
)}
|
|
168
182
|
title={t("blueprint.node.signalSentCount")}
|
|
169
183
|
>
|
|
@@ -171,11 +185,13 @@ export function BlueprintNodeCard({
|
|
|
171
185
|
</span>
|
|
172
186
|
) : null}
|
|
173
187
|
</div>
|
|
188
|
+
{showMeta ? (
|
|
189
|
+
<div className="bp-node-card__meta" title={meta}>
|
|
190
|
+
{meta}
|
|
191
|
+
</div>
|
|
192
|
+
) : null}
|
|
174
193
|
{subtitle ? (
|
|
175
|
-
<div
|
|
176
|
-
className="mt-0.5 truncate font-mono text-[10px] leading-tight text-muted-foreground"
|
|
177
|
-
title={subtitle}
|
|
178
|
-
>
|
|
194
|
+
<div className="bp-node-card__subtitle" title={subtitle}>
|
|
179
195
|
{subtitle}
|
|
180
196
|
</div>
|
|
181
197
|
) : null}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useI18n } from "@arronqzy/i18n/react";
|
|
1
|
+
import { useI18nOptional as useI18n } from "@arronqzy/i18n/react";
|
|
2
2
|
import { Handle, Position } from "@xyflow/react";
|
|
3
3
|
import { cn } from "@arronqzy/ui";
|
|
4
4
|
|
|
@@ -27,6 +27,7 @@ export function BlueprintNodeShell({
|
|
|
27
27
|
<div
|
|
28
28
|
className={cn(
|
|
29
29
|
"bp-node",
|
|
30
|
+
selected && "bp-node--selected",
|
|
30
31
|
executionTone === "success" && "bp-node--execution-true",
|
|
31
32
|
executionTone === "error" && "bp-node--execution-false"
|
|
32
33
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useI18n } from "@arronqzy/i18n/react";
|
|
1
|
+
import { useI18nOptional as useI18n } from "@arronqzy/i18n/react";
|
|
2
2
|
import { Handle, Position, type NodeProps } from "@xyflow/react";
|
|
3
3
|
import { cn } from "@arronqzy/ui";
|
|
4
4
|
|
|
@@ -20,6 +20,7 @@ export function LifecycleFlowNode({ id, data }: NodeProps) {
|
|
|
20
20
|
<div
|
|
21
21
|
className={cn(
|
|
22
22
|
"bp-node bp-node--lifecycle",
|
|
23
|
+
nodeData.isSelected && "bp-node--selected",
|
|
23
24
|
executionTone === "success" && "bp-node--execution-true",
|
|
24
25
|
executionTone === "error" && "bp-node--execution-false"
|
|
25
26
|
)}
|