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