@w6w/ui 0.1.0 → 0.2.0
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/CHANGELOG.md +40 -0
- package/README.md +25 -8
- package/dist/AppPicker.d.ts +1 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs +11 -0
- package/dist/ConfirmModal-ChoiGy2K.cjs.map +1 -0
- package/dist/{ConfirmModal-sY1tzkBO.js → ConfirmModal-Wx3i8F1n.js} +4470 -4446
- package/dist/ConfirmModal-Wx3i8F1n.js.map +1 -0
- package/dist/ConnectionHeader.d.ts +19 -0
- package/dist/EditConnectionModal.d.ts +21 -0
- package/dist/app-pages.d.ts +3 -0
- package/dist/code.cjs +1 -1
- package/dist/code.mjs +1 -0
- package/dist/code.mjs.map +1 -1
- package/dist/components/AuthFieldsForm.d.ts +8 -1
- package/dist/components/CallableList.d.ts +57 -0
- package/dist/components/ConnectionList.d.ts +44 -0
- package/dist/components/ListItem.d.ts +16 -6
- package/dist/components/ReliabilityChart.d.ts +10 -0
- package/dist/components/ReliabilityList.d.ts +47 -0
- package/dist/connection-app-meta.d.ts +32 -0
- package/dist/flow.cjs +1 -1
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.ts +3 -1
- package/dist/flow.mjs +50 -49
- package/dist/flow.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.mjs +1701 -891
- package/dist/index.mjs.map +1 -1
- package/dist/provider.d.ts +21 -1
- package/dist/reliability-board-layout.d.ts +121 -0
- package/dist/types.d.ts +8 -0
- package/package.json +3 -2
- package/src/code.css +23 -4
- package/src/styles/_callable-list.scss +60 -0
- package/src/styles/_connections.scss +100 -0
- package/src/styles/_flow.scss +4 -4
- package/src/styles/_lists.scss +4 -0
- package/src/styles/_reliability.scss +339 -0
- package/src/styles/_tokens.scss +23 -4
- package/src/styles.css +4386 -3108
- package/src/styles.scss +3 -0
- package/dist/ConfirmModal-DJPYXE9t.cjs +0 -11
- package/dist/ConfirmModal-DJPYXE9t.cjs.map +0 -1
- package/dist/ConfirmModal-sY1tzkBO.js.map +0 -1
- package/dist/ui.css +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ConnectionSummary } from './types.ts';
|
|
3
|
+
export interface ConnectionHeaderProps {
|
|
4
|
+
conn: ConnectionSummary;
|
|
5
|
+
/** The connection's app display meta (inline `app`, or the by-id record). */
|
|
6
|
+
app: {
|
|
7
|
+
displayName?: string;
|
|
8
|
+
iconSvg?: string;
|
|
9
|
+
iconSvgDark?: string;
|
|
10
|
+
brandColor?: string;
|
|
11
|
+
} | undefined;
|
|
12
|
+
/** Actions slot, right-aligned (e.g. a Test or Edit button, or a back link). */
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Connection identity strip: app icon, display name, copyable id, app id, auth key and state tag
|
|
17
|
+
* (plus `invalid` after a failed test). Presentational; the actions live in `children`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ConnectionHeader({ conn, app, children }: ConnectionHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConnectionSummary, ThemeMode } from './types.ts';
|
|
2
|
+
export interface EditConnectionModalProps {
|
|
3
|
+
/** The row being edited. `builtIn` rows have nothing to edit: the modal shows a notice only. */
|
|
4
|
+
connection: Pick<ConnectionSummary, "id" | "appId" | "authKey" | "displayName" | "builtIn">;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
/** Fired with the server's updated row. The typed credential is cleared before this runs. */
|
|
7
|
+
onSaved: (updated: ConnectionSummary) => void;
|
|
8
|
+
/** Reserved for icon variants, like the other modals. */
|
|
9
|
+
theme?: ThemeMode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Edit an existing connection: rename it and/or replace some of its credential fields. Runs on
|
|
13
|
+
* the {@link useW6WApi} adapter alone. The server never returns the stored secret, so credential
|
|
14
|
+
* fields start empty and blank means "keep what is stored" — only the fields the user filled are
|
|
15
|
+
* sent, and the server merges them over the stored credential. OAuth connections can be renamed
|
|
16
|
+
* here; re-authorizing is not part of this modal.
|
|
17
|
+
*
|
|
18
|
+
* Needs `api.updateConnection`. Without it (or for a `builtIn` row) there is no Save button, a
|
|
19
|
+
* one-line notice shows instead, and nothing is called. Hosts should not offer Edit in that case.
|
|
20
|
+
*/
|
|
21
|
+
export declare function EditConnectionModal({ connection, onClose, onSaved }: EditConnectionModalProps): import("react").JSX.Element;
|
package/dist/app-pages.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface AppsPageState {
|
|
|
29
29
|
/** Cursor to send on the NEXT "load more"; absent once the server has no more pages. */
|
|
30
30
|
cursor?: string;
|
|
31
31
|
hasMore: boolean;
|
|
32
|
+
/** The server's total for the current query, once a page has carried it. */
|
|
33
|
+
total?: number;
|
|
32
34
|
error?: string;
|
|
33
35
|
}
|
|
34
36
|
export declare function initialAppsPageState(query: AppsPageQuery, generation?: number): AppsPageState;
|
|
@@ -65,6 +67,7 @@ export type AppsPageAction =
|
|
|
65
67
|
apps: AppSummary[];
|
|
66
68
|
nextCursor?: string;
|
|
67
69
|
requestedCursor?: string;
|
|
70
|
+
total?: number;
|
|
68
71
|
} | {
|
|
69
72
|
type: "page-failed";
|
|
70
73
|
generation: number;
|
package/dist/code.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./CodeBlock-CZu4TFSi.cjs"),o=require("./Copyable-CYZU1o4X.cjs");exports.CodeBlock=e.CodeBlock;exports.Copyable=o.Copyable;
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./CodeBlock-CZu4TFSi.cjs"),o=require("./Copyable-CYZU1o4X.cjs");exports.CodeBlock=e.CodeBlock;exports.Copyable=o.Copyable;
|
|
2
2
|
//# sourceMappingURL=code.cjs.map
|
package/dist/code.mjs
CHANGED
package/dist/code.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"code.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
|
@@ -13,10 +13,17 @@ interface Props {
|
|
|
13
13
|
enterSubmitProps?: {
|
|
14
14
|
onKeyDown: KeyboardEventHandler<HTMLElement>;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* `"create"` (default) seeds each field from its manifest `default`. `"edit"` is for replacing
|
|
18
|
+
* part of a stored credential: it never seeds `default`, gives secret inputs the placeholder
|
|
19
|
+
* `•••••• (unchanged)`, and reports an emptied number input as `""` (not `0`) so the caller can
|
|
20
|
+
* treat blank as "keep what is stored".
|
|
21
|
+
*/
|
|
22
|
+
mode?: "create" | "edit";
|
|
16
23
|
}
|
|
17
24
|
/**
|
|
18
25
|
* Renders the form for an Auth method's `fields` declaration. Field shape
|
|
19
26
|
* comes from the app's manifest so no app-specific knowledge is needed here.
|
|
20
27
|
*/
|
|
21
|
-
export declare function AuthFieldsForm({ fields, values, onChange, enterSubmitProps }: Props): import("react").JSX.Element;
|
|
28
|
+
export declare function AuthFieldsForm({ fields, values, onChange, enterSubmitProps, mode, }: Props): import("react").JSX.Element;
|
|
22
29
|
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { MouseEvent, ReactNode } from 'react';
|
|
2
|
+
/** One row of a {@link CallableList}. The host decides `archived`; the list never learns a kind. */
|
|
3
|
+
export interface CallableListRow {
|
|
4
|
+
id: string;
|
|
5
|
+
title: ReactNode;
|
|
6
|
+
description?: ReactNode;
|
|
7
|
+
archived: boolean;
|
|
8
|
+
/** Extra badges, rendered before the archived badge in the trailing slot. */
|
|
9
|
+
badges?: ReactNode;
|
|
10
|
+
/** Trailing content; sits inside the row's anchor when `getHref` is set, so keep it non-interactive. */
|
|
11
|
+
trailing?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export interface CallableListProps {
|
|
14
|
+
rows: readonly CallableListRow[];
|
|
15
|
+
title: ReactNode;
|
|
16
|
+
description?: ReactNode;
|
|
17
|
+
/** Shown when `rows` is empty (total, not the visible subset) and not `loading`. */
|
|
18
|
+
emptyCopy?: ReactNode;
|
|
19
|
+
/** Label of the New button. Defaults to "New". */
|
|
20
|
+
newLabel?: string;
|
|
21
|
+
/** Tooltip (`title` attribute) on each openable row. */
|
|
22
|
+
openRowTitle?: string;
|
|
23
|
+
testIds?: {
|
|
24
|
+
showArchived?: string;
|
|
25
|
+
importOpen?: string;
|
|
26
|
+
archivedBadge?: string;
|
|
27
|
+
};
|
|
28
|
+
loading?: boolean;
|
|
29
|
+
error?: string | null;
|
|
30
|
+
/** The New button renders only when this is set. */
|
|
31
|
+
onCreate?: () => void;
|
|
32
|
+
/** New button is disabled and reads "Creating…" while true. */
|
|
33
|
+
creating?: boolean;
|
|
34
|
+
/** The Import button renders only when this is set. */
|
|
35
|
+
onImport?: () => void;
|
|
36
|
+
/** Row click. The event is passed through untouched; the host may `preventDefault`. */
|
|
37
|
+
onOpen?: (id: string, event: MouseEvent<Element>) => void;
|
|
38
|
+
/** When set, each row is a real `<a href>`. */
|
|
39
|
+
getHref?: (id: string) => string;
|
|
40
|
+
/** Controlled "Show archived". Omit for an uncontrolled toggle that starts off. */
|
|
41
|
+
showArchived?: boolean;
|
|
42
|
+
onShowArchivedChange?: (next: boolean) => void;
|
|
43
|
+
slots?: {
|
|
44
|
+
/** Replaces the default title/description block (the Show-archived toggle stays). */
|
|
45
|
+
header?: ReactNode;
|
|
46
|
+
/** Rendered before Import/New. */
|
|
47
|
+
actions?: ReactNode;
|
|
48
|
+
/** Replaces `emptyCopy`. */
|
|
49
|
+
empty?: ReactNode;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A presentational list of callables (Functions, Endpoints, Workflows): rows in, callbacks out.
|
|
54
|
+
* Owns only the archived filter and its toggle; it knows no router, query, modal or kind.
|
|
55
|
+
* Rows render through {@link ListItem}: a button with `onOpen`, an anchor with `getHref`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function CallableList({ rows, title, description, emptyCopy, newLabel, openRowTitle, testIds, loading, error, onCreate, creating, onImport, onOpen, getHref, showArchived: showArchivedProp, onShowArchivedChange, slots, }: CallableListProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MouseEvent, ReactNode } from 'react';
|
|
2
|
+
import { InlineAppMeta } from '../connection-app-meta.ts';
|
|
3
|
+
import { ConnectionSummary } from '../types.ts';
|
|
4
|
+
export interface ConnectionListProps {
|
|
5
|
+
connections: readonly ConnectionSummary[];
|
|
6
|
+
/**
|
|
7
|
+
* App meta by id, used for rows whose own inline `app` is `undefined` (an older server).
|
|
8
|
+
* Rows with an inline `app` object, or `null`, never consult it.
|
|
9
|
+
*/
|
|
10
|
+
appsById?: ReadonlyMap<string, InlineAppMeta>;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
error?: string | null;
|
|
13
|
+
/** Row click. The event is passed through untouched; the host may `preventDefault`. */
|
|
14
|
+
onOpen?: (id: string, event: MouseEvent<Element>) => void;
|
|
15
|
+
/** When set, each openable row is a real `<a href>`. */
|
|
16
|
+
getHref?: (id: string) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Renders an Edit button per row. Pass it only when the host's adapter has `updateConnection`
|
|
19
|
+
* (otherwise the modal it opens has nothing to save with).
|
|
20
|
+
*/
|
|
21
|
+
onEdit?: (connection: ConnectionSummary) => void;
|
|
22
|
+
/** Renders a Delete button per row. Confirmation and the delete call are the host's. */
|
|
23
|
+
onDelete?: (connection: ConnectionSummary) => void;
|
|
24
|
+
/** Disables every Delete button while a delete is in flight. */
|
|
25
|
+
busy?: boolean;
|
|
26
|
+
slots?: {
|
|
27
|
+
/** Heading block above the rows. */
|
|
28
|
+
header?: ReactNode;
|
|
29
|
+
/** Trailing action(s) next to the header (e.g. an "Add" button). */
|
|
30
|
+
actions?: ReactNode;
|
|
31
|
+
/** Shown when there are no connections and the list is not `loading`. */
|
|
32
|
+
empty?: ReactNode;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A presentational list of connections: rows in, callbacks out; it needs no provider. Each row is
|
|
37
|
+
* a {@link ListItem} (app icon, name, auth key, state, an `invalid` tag after a failed test) with
|
|
38
|
+
* Edit and Delete buttons as SIBLINGS of its link, never inside it.
|
|
39
|
+
*
|
|
40
|
+
* A `builtIn` row (the server's synthetic "no credential" entry) is a plain non-interactive item:
|
|
41
|
+
* no link, no `onOpen`, no Edit, no Delete, because the server 404s get/test/delete on its id.
|
|
42
|
+
* Detection is `row.builtIn === true`, never an id prefix.
|
|
43
|
+
*/
|
|
44
|
+
export declare function ConnectionList({ connections, appsById, loading, error, onOpen, getHref, onEdit, onDelete, busy, slots, }: ConnectionListProps): import("react").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { MouseEvent, ReactNode } from 'react';
|
|
2
2
|
export interface ListItemProps {
|
|
3
3
|
/** Primary label — prominent, single-line with ellipsis overflow. */
|
|
4
4
|
title: ReactNode;
|
|
@@ -6,12 +6,21 @@ export interface ListItemProps {
|
|
|
6
6
|
subtitle?: ReactNode;
|
|
7
7
|
/** Leading slot (e.g. an `<AppIcon />` or status glyph). */
|
|
8
8
|
icon?: ReactNode;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Trailing slot pushed to the right (e.g. a badge or chevron). With `href` it sits INSIDE the
|
|
11
|
+
* anchor, so it must stay non-interactive (no buttons or links).
|
|
12
|
+
*/
|
|
10
13
|
trailing?: ReactNode;
|
|
11
14
|
/** Highlights the row as selected/current. Reflected as `aria-pressed` when clickable. */
|
|
12
15
|
active?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
|
|
16
|
+
/**
|
|
17
|
+
* When provided, the row renders as a focusable, keyboard-activatable button — or, with `href`,
|
|
18
|
+
* still fires on a click of the anchor. Receives the click event; ListItem never calls
|
|
19
|
+
* `preventDefault`, so the host decides whether the browser navigates.
|
|
20
|
+
*/
|
|
21
|
+
onClick?: (event: MouseEvent<HTMLElement>) => void;
|
|
22
|
+
/** When provided, the row renders as a real `<a href>` (middle-click, copy link, new tab). */
|
|
23
|
+
href?: string;
|
|
15
24
|
/** Accessible label for the clickable row (falls back to the `title` DOM text). */
|
|
16
25
|
ariaLabel?: string;
|
|
17
26
|
}
|
|
@@ -20,6 +29,7 @@ export interface ListItemProps {
|
|
|
20
29
|
*
|
|
21
30
|
* Mirrors the look/behaviour of the saved-test button rows it replaces. When
|
|
22
31
|
* `onClick` is given it renders a `<button type="button">` (focusable, Enter/Space
|
|
23
|
-
* activatable) with `aria-pressed={active}`;
|
|
32
|
+
* activatable) with `aria-pressed={active}`; with `href` an `<a href>` (the click still reaches
|
|
33
|
+
* `onClick`); otherwise a plain, non-interactive row.
|
|
24
34
|
*/
|
|
25
|
-
export declare function ListItem({ title, subtitle, icon, trailing, active, onClick, ariaLabel, }: ListItemProps): import("react").JSX.Element;
|
|
35
|
+
export declare function ListItem({ title, subtitle, icon, trailing, active, onClick, href, ariaLabel, }: ListItemProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactElement, MouseEvent as ReactMouseEvent } from 'react';
|
|
2
|
+
import { ReliabilityServiceView } from '../reliability-board-layout.ts';
|
|
3
|
+
export interface ReliabilityChartProps<T extends ReliabilityServiceView = ReliabilityServiceView> {
|
|
4
|
+
services: readonly T[];
|
|
5
|
+
/** Real `<a href>` on each point when given. */
|
|
6
|
+
getHref?: (appId: string) => string;
|
|
7
|
+
/** Called on a point click; the host decides whether to `preventDefault`. */
|
|
8
|
+
onOpen?: (appId: string, event: ReactMouseEvent<Element>) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function ReliabilityChart<T extends ReliabilityServiceView>({ services, getHref, onOpen, }: ReliabilityChartProps<T>): ReactElement;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { MouseEvent, ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { ReliabilityServiceView } from '../reliability-board-layout.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The reliability board's presentation: needs-attention cards, the
|
|
5
|
+
* performance chart and the services table, drawn from rows passed in.
|
|
6
|
+
* Router-free and request-free (no provider needed) — icons come from the
|
|
7
|
+
* rows' own `iconSrc`/`iconSrcDark`/`brandColor`. Loading, error and
|
|
8
|
+
* no-project states belong to whatever fetches the rows.
|
|
9
|
+
*
|
|
10
|
+
* Navigation, at every site (issue card, service cell, chart point): with
|
|
11
|
+
* `getHref` a real anchor; a click calls `onOpen(appId, event)` and is never
|
|
12
|
+
* `preventDefault`ed here; only `onOpen` ⇒ a button; neither ⇒ not a link.
|
|
13
|
+
*/
|
|
14
|
+
type Open = (appId: string, event: MouseEvent<Element>) => void;
|
|
15
|
+
export interface ReliabilityListWindow {
|
|
16
|
+
from: string;
|
|
17
|
+
to: string;
|
|
18
|
+
days: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ReliabilityListProps<T extends ReliabilityServiceView = ReliabilityServiceView> {
|
|
21
|
+
services: readonly T[];
|
|
22
|
+
/** The window the rows cover; labels the heading. */
|
|
23
|
+
window?: ReliabilityListWindow;
|
|
24
|
+
/** Table column label ("Last N days"); defaults to `window?.days ?? 30`. */
|
|
25
|
+
days?: number;
|
|
26
|
+
/** Trim the display: ≤3 attention cards, `limit ?? 5` table rows, chart off. */
|
|
27
|
+
compact?: boolean;
|
|
28
|
+
/** Defaults to `!compact`. */
|
|
29
|
+
showChart?: boolean;
|
|
30
|
+
/** Compact table row cap (default 5). */
|
|
31
|
+
limit?: number;
|
|
32
|
+
getHref?: (appId: string) => string;
|
|
33
|
+
onOpen?: Open;
|
|
34
|
+
/** "Show all services →" / "view all →" render only when one of these is given. */
|
|
35
|
+
showAllHref?: string;
|
|
36
|
+
onShowAll?: (event: MouseEvent<Element>) => void;
|
|
37
|
+
slots?: {
|
|
38
|
+
/** Replaces the "Service reliability" title text. */
|
|
39
|
+
header?: ReactNode;
|
|
40
|
+
/** Rendered at the end of the heading row. */
|
|
41
|
+
actions?: ReactNode;
|
|
42
|
+
/** Replaces the "No services yet" message. */
|
|
43
|
+
empty?: ReactNode;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function ReliabilityList<T extends ReliabilityServiceView>({ services, window: win, days, compact, showChart, limit, getHref, onOpen, showAllHref, onShowAll, slots, }: ReliabilityListProps<T>): ReactElement;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which app meta (name/icon/brand) a connection renders with. PURE and free of
|
|
3
|
+
* runtime imports so `node --test` can load it.
|
|
4
|
+
*
|
|
5
|
+
* The server inlines `app` on each connection summary. Three states:
|
|
6
|
+
* - an object -> render from it; no lookup.
|
|
7
|
+
* - `null` -> the server found no app row; render the `appId` fallback and
|
|
8
|
+
* never look it up (a lookup would only miss again).
|
|
9
|
+
* - `undefined`-> an older server that does not inline it; use the by-id record
|
|
10
|
+
* the apps provider resolved.
|
|
11
|
+
*/
|
|
12
|
+
/** The display fields every renderer of a connection's app reads. */
|
|
13
|
+
export interface InlineAppMeta {
|
|
14
|
+
displayName?: string;
|
|
15
|
+
iconSvg?: string;
|
|
16
|
+
iconSvgDark?: string;
|
|
17
|
+
brandColor?: string;
|
|
18
|
+
brandColorDark?: string;
|
|
19
|
+
}
|
|
20
|
+
interface ConnectionLike {
|
|
21
|
+
appId: string;
|
|
22
|
+
app?: InlineAppMeta | null;
|
|
23
|
+
}
|
|
24
|
+
/** The meta to render a connection with, or `undefined` for the `appId` fallback. */
|
|
25
|
+
export declare function resolveConnectionAppMeta<A extends InlineAppMeta>(connection: ConnectionLike, byId: ReadonlyMap<string, A>): InlineAppMeta | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* The app ids to look up by id: the unique `appId`s, first-seen order, of the
|
|
28
|
+
* connections whose `app` is `undefined`. Rows with an object or `null` are
|
|
29
|
+
* excluded.
|
|
30
|
+
*/
|
|
31
|
+
export declare function connectionAppIdsToLookUp(connections: readonly ConnectionLike[]): string[];
|
|
32
|
+
export {};
|
package/dist/flow.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),R=require("@xyflow/react"),n=require("./ConfirmModal-DJPYXE9t.cjs"),i=require("react"),xt=require("react-dom"),de=require("./Copyable-CYZU1o4X.cjs"),tt=220;function bt(t){return t.length<=tt?{text:t,clipped:!1,length:t.length}:{text:t.slice(0,tt).trimEnd(),clipped:!0,length:t.length}}function jt({params:t,values:s,testStartState:r,view:a="props"}){const{sampleValues:d}=n.useExpressionOptions(),u=i.useMemo(()=>n.buildResolveScope(d,r),[d,r]),f=n.flattenParams(t),S=m=>{var l;return s[m]!==void 0?s[m]:(l=f.find(x=>x.key===m))==null?void 0:l.default},N=f.filter(m=>m.type!=="section"&&n.isParamVisible(m,S));if(a==="code"){const m=vt(N,s,u);return e.jsx("div",{className:"w6w-resolved-params",children:e.jsx(n.JsonEditor,{value:JSON.stringify(m,null,2),onChange:()=>{},readOnly:!0,minHeight:"260px",height:"100%","aria-label":"Resolved test values (JSON)"})})}const v=N.filter(m=>!n.deepEqual(S(m.key),m.default));return N.length===0?e.jsx("div",{className:"w6w-resolved-params",children:e.jsx("p",{className:"w6w-muted w6w-small",children:"This action takes no parameters."})}):v.length===0?e.jsx("div",{className:"w6w-resolved-params",children:e.jsx("p",{className:"w6w-muted w6w-small",children:"Every configured value matches its default — nothing to show here. Switch to JSON to see the full set."})}):e.jsx("div",{className:"w6w-resolved-params w6w-resolved-table",children:v.map(m=>m.type==="vars"?e.jsx(Nt,{param:m,value:s[m.key],scope:u},m.key):e.jsx(St,{label:m.label??m.key,segments:n.resolveParamValue(s[m.key]!==void 0?s[m.key]:m.default,u)},m.key))})}function vt(t,s,r){const a={};for(const d of t)if(d.type==="vars"){const u=Array.isArray(s[d.key])?s[d.key]:Array.isArray(d.default)?d.default:[];a[d.key]=n.resolveVarsJson(u,r)}else a[d.key]=n.resolveParamJson(s[d.key]!==void 0?s[d.key]:d.default,r);return a}function St({label:t,segments:s}){return e.jsxs("div",{className:"w6w-resolved-row",children:[e.jsx("span",{className:"w6w-resolved-label",children:t}),e.jsx("div",{className:"w6w-resolved-value",children:e.jsx(it,{segments:s})})]})}function Nt({param:t,value:s,scope:r}){const a=Array.isArray(s)?s:Array.isArray(t.default)?t.default:[];return e.jsxs("div",{className:"w6w-resolved-row",children:[e.jsx("span",{className:"w6w-resolved-label",children:t.label??t.key}),a.length===0?e.jsx("p",{className:"w6w-muted w6w-small",children:"None configured."}):e.jsx("div",{className:"w6w-stack",children:a.map((d,u)=>e.jsxs("div",{className:"w6w-resolved-value",children:[e.jsx("code",{children:d.key||"(no key)"})," → ",e.jsx(it,{segments:n.resolveParamValue(d.value,r)})]},u))})]})}function it({segments:t}){return e.jsx(e.Fragment,{children:t.map((s,r)=>e.jsx(Ct,{segment:s},r))})}function Ct({segment:t}){switch(t.status){case"resolved":return t.ref?e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"var",refName:t.ref}),e.jsx(st,{value:t.value})]}):e.jsx(st,{value:t.value});case"unresolved":return e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"var",refName:t.ref}),e.jsx("span",{className:"w6w-param-unresolved",children:"unresolved"})]});case"not-evaluated":return e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"expr"}),e.jsx("span",{className:"w6w-param-unevaluated",children:"not evaluated"})]});case"masked":return e.jsx(ke,{kind:"secret",refName:t.ref})}}function st({value:t}){const[s,r]=i.useState(!1),a=kt(t),d=bt(a);return d.clipped?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:s?"w6w-resolved-text-full":void 0,children:s?a:`${d.text}…`}),e.jsx("button",{type:"button",className:"w6w-resolved-more","aria-expanded":s,onClick:()=>r(u=>!u),children:s?"Show less":`Show all (${d.length.toLocaleString()} characters)`})]}):e.jsx("span",{children:a})}const yt={var:"◆",secret:"🔒",expr:"ƒ"};function ke({kind:t,refName:s}){const r=t==="expr"?"expr":n.varLabel(s??"");return e.jsxs("span",{className:`w6w-expr-chip w6w-expr-chip-${t}`,children:[e.jsx("span",{className:"w6w-expr-chip-sigil",children:yt[t]}),e.jsx("span",{className:"w6w-expr-chip-label",children:r})]})}function kt(t){if(t===null)return"null";if(t===void 0)return"(not set)";if(t==="")return'""';if(typeof t=="string"||typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return String(t)}}function Y(t){var s;return((s=t.data)==null?void 0:s.when)==="error"?"error":"success"}function lt(t,s){var r;return((r=t.find(a=>a.id===s))==null?void 0:r.id)??null}function ct(t,s,r,a,d){var v,m;if(!t||!s||t===s||a.some(l=>l.source===t&&l.target===s))return!1;const u=(v=r.find(l=>l.id===t))==null?void 0:v.data.step,f=(m=r.find(l=>l.id===s))==null?void 0:m.data.step;if(!u||!f)return!1;const S=n.nodePortsForStep(u,d),N=n.nodePortsForStep(f,d);return S.out>=1&&N.in>=1}function Le(t,s,r,a,d,u){var T,E;if(!ct(t,s,r,a,u)||!t||!s)return null;const f=(T=r.find(D=>D.id===t))==null?void 0:T.data.step,S=(E=r.find(D=>D.id===s))==null?void 0:E.data.step;if(!f||!S)return null;const N=n.nodePortsForStep(f,u),v=n.nodePortsForStep(S,u);let m=a;if(m.filter(D=>D.source===t&&Y(D)===d).length>=N.out)return{next:a,conflict:null,refusal:{refused:"out_cap",cap:N.out}};const x=m.filter(D=>D.target===s);if(x.length>=v.in){const D=new Set(x.slice(0,x.length-v.in+1).map(p=>p.id));m=m.filter(p=>!D.has(p.id))}const y=n.flowEdgeId(t,s,d);return{next:R.addEdge({source:t,target:s,id:y,sourceHandle:n.sourceHandleForLane(d),data:{when:d},...n.edgeVisuals(d,void 0)},m),conflict:lt(m,y),refusal:null}}function Ee(t,s,r,a,d="success",u){const f=Le(t,s,r,a,d,u);return!f||f.conflict||f.refusal?null:f.next}function Et(t,s,r,a,d="success",u){var f;return((f=Le(t,s,r,a,d,u))==null?void 0:f.conflict)??null}function Pt(t,s,r,a,d="success",u){var f;return((f=Le(t,s,r,a,d,u))==null?void 0:f.refusal)??null}function De(t,s,r,a,d){var T;const u=t.filter(E=>E.id===s);if(u.length!==1)return null;const f=u[0],S=(T=a.find(E=>E.id===f.source))==null?void 0:T.data.step;if(!S)return null;const N=n.nodePortsForStep(S,d).out,v=t.filter(E=>E.id!==s);if((Y(f)===r?[]:v.filter(E=>E.source===f.source&&Y(E)===r)).length>=N)return{next:t,conflict:null,refusal:{refused:"out_cap",cap:N}};const l=n.edgeVisuals(r,void 0),x={...f,id:n.flowEdgeId(f.source,f.target,r),data:{...f.data,when:r},className:l.className,label:l.label,sourceHandle:n.sourceHandleForLane(r)},y=lt(v,x.id);return{next:t.map(E=>E.id===s?x:E),conflict:y,refusal:null}}function At(t,s,r,a,d){const u=De(t,s,r,a,d);return!u||u.conflict||u.refusal?null:u.next}function Tt(t,s,r,a,d){var u;return((u=De(t,s,r,a,d))==null?void 0:u.conflict)??null}function Rt(t,s,r,a,d){var u;return((u=De(t,s,r,a,d))==null?void 0:u.refusal)??null}function It(t,s,r){return t.map(a=>{const d=a.source===s?r:a.source,u=a.target===s?r:a.target;return{...a,source:d,target:u,id:n.flowEdgeId(d,u,Y(a))}})}function Ft(t,s){const r={success:0,error:0};for(const d of s)d.source===t&&r[Y(d)]++;const a=Math.max(r.success,r.error);return{enabled:a>=2,count:a}}function Lt(t,s){const{fanOut:r,...a}=t;return s==="parallel"?{...a,fanOut:"parallel"}:a}function Dt(t,s){return`Runs these ${t} steps in ${s==="parallel"?"parallel":"sequence"}`}const Wt=new Set(["succeeded","failed","canceled"]);function Mt(t,s){var r;return t?((r=t.steps[s])==null?void 0:r.status)??"pending":"no-run"}const nt={borderColor:"var(--w6w-border)",borderStyle:"solid",borderWidth:1,opacity:1};function ut(t,s){const r=s!==void 0&&Wt.has(s);switch(t){case"no-run":return nt;case"pending":return r?{borderColor:"var(--w6w-muted)",borderStyle:"dashed",borderWidth:1,opacity:.5}:{borderColor:"var(--w6w-border)",borderStyle:"dashed",borderWidth:1,opacity:1};case"running":return{borderColor:"var(--w6w-accent)",borderStyle:"solid",borderWidth:2,opacity:1};case"succeeded":return{borderColor:"var(--w6w-success)",borderStyle:"solid",borderWidth:2,opacity:1};case"failed":return{borderColor:"var(--w6w-danger)",borderStyle:"solid",borderWidth:2,opacity:1};case"skipped":return{borderColor:"var(--w6w-muted)",borderStyle:"dashed",borderWidth:1,opacity:.7};default:return nt}}function Vt(t,s,r){if(!t)return;const a=t.steps[s];if(!a)return;const d=r??"success";if(a.status==="succeeded")return d==="success"?"taken":"skipped";if(a.status==="failed")return d==="error"?"taken":"skipped";if(a.status==="skipped")return"skipped"}function Ot(t,s){const[r,a]=i.useState({}),d=i.useRef(new Set),u=JSON.stringify([...new Set(s.map(f=>f.data.step.uses.app))].filter(f=>f&&!n.isInternalApp(f)).sort());return i.useEffect(()=>{const f=JSON.parse(u).filter(S=>!d.current.has(S));if(f.length!==0){for(const S of f)d.current.add(S);Promise.all(f.map(async S=>{try{return[S,await t.getAppActions(S)]}catch{return d.current.delete(S),null}})).then(S=>{const N=S.filter(v=>v!==null);N.length!==0&&a(v=>({...v,...Object.fromEntries(N)}))})}},[t,u]),r}function _t(t){return(s,r)=>{var a,d;return(d=(a=t[s])==null?void 0:a.find(u=>u.key===r))==null?void 0:d.ports}}const Ht="Which outcome of the source step this edge carries. An error edge is drawn by dragging from the step's error exit port; use this control to re-lane an edge already drawn. An error edge overrides the step’s “On error” policy.";function ot(t,s,r,a){const d=t.find(u=>u.id===s);return[r,a,d==null?void 0:d.source,d==null?void 0:d.target]}const We=i.createContext(void 0),Me=i.createContext(new Map);function rt(t){return`Can’t draw that edge: this node allows at most ${t} outgoing edge${t===1?"":"s"} per lane.`}const Ve=i.createContext(new Map),dt=i.createContext(null);function Jt(t){return e.jsx(R.ReactFlowProvider,{children:e.jsx($t,{...t})})}function $t({value:t,onChange:s,readOnly:r,height:a=480,apps:d,exprOptions:u,project:f,runState:S,onTestRun:N,fitViewKey:v}){var Qe,Ze,et;const m=n.useW6WApi(),l=i.useMemo(()=>new Map((d??[]).map(o=>[o.id,o])),[d]),[x,y]=i.useState(null),T=i.useMemo(()=>n.workflowToFlow(t),[t.id]),E=i.useMemo(()=>n.storedViewport(t),[t.id]),D=((Qe=t.settings)==null?void 0:Qe.savePosition)!==!1,[p,I,re]=R.useNodesState(T.nodes),Z=Ot(m,p),M=i.useMemo(()=>_t(Z),[Z]),[b,A,ae]=R.useEdgesState(T.edges);i.useEffect(()=>{I(o=>o.map(c=>{const w=Mt(S,c.id);return c.data.stepStatus===w&&c.data.runStatus===(S==null?void 0:S.status)?c:{...c,data:{...c.data,stepStatus:w,runStatus:S==null?void 0:S.status}}})),A(o=>o.map(c=>{const w=Y(c),g=Vt(S,c.source,w),j=n.edgeVisuals(w,g);return c.className===j.className&&c.label===j.label?c:{...c,className:j.className,label:j.label}}))},[S,I,A]);const[U,q]=i.useState(null),[k,$]=i.useState(null),[V,Q]=i.useState(!1),[O,ee]=i.useState(null),[pe,te]=i.useState("props"),[se,he]=i.useState(null),ie=i.useRef(!1),ve=i.useRef(null),[_,z]=i.useState(null),{screenToFlowPosition:Se,fitView:H}=R.useReactFlow(),Pe=n.useEffectiveTheme();i.useEffect(()=>{I(T.nodes),A(T.edges),q(null),ee(null)},[T,I,A]);const F=i.useCallback((o,c)=>{s(n.flowToWorkflow(t,o,c))},[t,s]),oe=i.useCallback(o=>ct(o.source,o.target,p,b,M),[p,b,M]),ne=i.useCallback(o=>{if(r)return;const c=Ee(o.source,o.target,p,b,n.laneForSourceHandle(o.sourceHandle),M);if(!c){const w=n.laneForSourceHandle(o.sourceHandle),g=Pt(o.source,o.target,p,b,w,M);if(g){const C=b.find(P=>P.source===o.source&&Y(P)===w);C&&(A(b.map(P=>({...P,selected:P.id===C.id}))),$(C.id),W({edgeId:C.id,message:rt(g.cap)}));return}const j=Et(o.source,o.target,p,b,n.laneForSourceHandle(o.sourceHandle));if(!j)return;A(b.map(C=>({...C,selected:C.id===j}))),$(j),W({edgeId:j,message:n.idClashMessage("Can’t draw that edge",j,ot(b,j,o.source,o.target))});return}W(null),A(c),F(p,c)},[b,p,A,F,r,M]),Ae=i.useCallback((o,c)=>{var J,L,G;if(r||c.isValid)return;const w=c.fromNode;if(!w)return;const g=((J=c.fromHandle)==null?void 0:J.type)==="target"?"target":"source",j=(L=p.find(X=>X.id===w.id))==null?void 0:L.data.step;if(j){const X=n.nodePortsForStep(j,M);if((g==="source"?X.out:X.in)<1)return}const C="changedTouches"in o?o.changedTouches[0]:o,P=Se({x:C.clientX,y:C.clientY});z({nodeId:w.id,handleType:g,position:P,lane:n.laneForSourceHandle((G=c.fromHandle)==null?void 0:G.id)}),Q(!0)},[r,Se,p,M]),fe=i.useCallback(o=>{r||he(o)},[r]),Ne=i.useCallback(o=>{if(r)return;const c=p.filter(g=>g.id!==o),w=b.filter(g=>g.source!==o&&g.target!==o);I(c),A(w),U===o&&q(null),O===o&&ee(null),F(c,w)},[p,b,I,A,F,r,U,O]),ge=i.useCallback(()=>{if(r)return;const o=n.relayoutNodes(p,b);I(o),ie.current=!0,F(o,b)},[p,b,I,F,r]),xe=i.useCallback(()=>{r||ge()},[r,ge]);i.useEffect(()=>{ie.current&&(ie.current=!1,H({duration:300}))},[p,H]);const be=i.useRef(v);i.useEffect(()=>{Object.is(be.current,v)||(be.current=v,H({duration:300}))},[v,H]);const[le,W]=i.useState(null),ce=i.useMemo(()=>b.find(o=>o.id===k)??null,[b,k]),Te=i.useCallback(o=>{if(r||!k)return;const c=b.find(P=>P.id===k);if(!c||Y(c)===o)return;const w=Tt(b,k,o,p),g=Rt(b,k,o,p,M),j=w||g?null:At(b,k,o,p,M);if(!j){if(g){W({edgeId:k,message:rt(g.cap)});return}W({edgeId:k,message:w?n.idClashMessage("Can’t switch this edge",w,ot(b,w,c.source,c.target)):"This edge can’t be switched right now."});return}W(null),A(j);const C=j.find(P=>P.source===c.source&&P.target===c.target&&Y(P)===o);$((C==null?void 0:C.id)??null),F(p,j)},[b,p,A,F,r,k,M]),Ce=i.useCallback(o=>{if(r)return;const c=b.filter(w=>w.id!==o);c.length!==b.length&&(A(c),k===o&&$(null),F(p,c))},[p,b,A,F,r,k]),h=i.useCallback(o=>{if(r)return;const c=p.find(P=>P.id===o);if(!c)return;const w=n.suggestStepId(p.map(P=>P.id),`${c.data.step.id}_copy`),g={...structuredClone(c.data.step),id:w},j={id:w,type:c.type,position:{x:c.position.x+40,y:c.position.y+60},data:{step:g,isInternal:c.data.isInternal}},C=[...p,j];I(C),q(w),F(C,b)},[p,b,I,F,r]),B=i.useCallback(o=>{if(r)return;const c=n.isInternalApp(o.uses.app),w=n.suggestStepId(p.map(J=>J.id),n.slugifyLabel(n.internalNodeLabel(o.uses.app,o.uses.action))),g={id:w,uses:o.uses,...o.with&&Object.keys(o.with).length>0?{with:o.with}:{}},j={id:w,type:c?"control":"step",position:(_==null?void 0:_.position)??{x:80,y:80+p.length*24},data:{step:g,isInternal:c}},C=[...p,j];let P=b;if(_){const[J,L]=_.handleType==="target"?[w,_.nodeId]:[_.nodeId,w];P=Ee(J,L,C,b,_.lane,M)??b}else{const J=p.find(L=>n.isTriggerApp(L.data.step.uses.app));if(n.isTriggerApp(o.uses.app)){if(!J){const L=n.findChainRoot(p,b);L&&(P=Ee(w,L.id,C,b,"success",M)??b)}}else{const G=(J&&!b.some(X=>X.source===J.id)?J:void 0)??n.findChainTail(p,b);G&&(P=Ee(G.id,w,C,b,"success",M)??b)}}return I(C),P!==b&&A(P),q(w),F(C,P),w},[p,b,I,A,F,r,_,M]),K=i.useCallback((o,c)=>{const w=c.id!==o;if(w&&p.some(j=>j.id===c.id))return;const g=p.map(j=>j.id===o?{...j,id:c.id,data:{step:c,isInternal:n.isInternalApp(c.uses.app)}}:j);if(w){const j=It(b,o,c.id);I(g),A(j),U===o&&q(c.id),O===o&&ee(c.id),F(g,j);return}I(g),F(g,b)},[p,b,I,A,U,O,F]),ue=i.useCallback((o,c,w)=>{(async()=>{const g=await m.saveStepTest(t.id,o,c).catch(j=>(console.error("step run fixture save failed",j),null));await m.recordStepTestRun(t.id,o,{stepTestId:(g==null?void 0:g.id)??null,status:w.status,input:c.input,output:w.output,error:w.error,...w.meta?{meta:w.meta}:{}})})().catch(g=>{console.error("step run persist failed",g)})},[m,t.id]),je=i.useCallback(o=>{const c=p.find(w=>w.id===o);!c||n.isControlApp(c.data.step.uses.app)||y({stepId:o,status:"collect"})},[p]),mt=i.useCallback(async(o,c,w)=>{N==null||N();const g=p.find(L=>L.id===o);if(!g)return;const j=g.data.step,C=n.isTriggerApp(j.uses.app),P=C?{input:c}:{...j.with??{},...c},J=C?{input:c,with:c}:{input:c,with:P};y({stepId:o,status:"running"});try{const L=await m.invokeAction(j.uses.app,j.uses.action,P,{...j.uses.connection?{connectionId:j.uses.connection}:{},project:f,...w?{state:w}:{}}),G=L.logs,X=L.meta;y({stepId:o,status:"done",value:L.value,logs:G,...X?{meta:X}:{}}),ue(o,J,{status:"succeeded",output:L.value,...X?{meta:X}:{}})}catch(L){const G=L;y({stepId:o,status:"error",error:G.message??String(L),errorCode:G.code}),ue(o,J,{status:"failed",error:G.message??String(L)})}},[p,m,ue,f,N]),Re=i.useMemo(()=>({onEdit:o=>{te("props"),ee(o)},onEditJson:o=>{te("json"),ee(o)},onRun:je,onDuplicate:h,onDelete:fe,readOnly:r}),[je,h,fe,r]);i.useEffect(()=>{const o=ve.current;if(!o)return;const c=w=>{const g=w.target.closest(".react-flow__node");if(!g)return;const j=g.getAttribute("data-id");j&&(w.stopPropagation(),Re.onEdit(j))};return o.addEventListener("dblclick",c,!0),()=>o.removeEventListener("dblclick",c,!0)},[Re]);const _e=((Ze=p.find(o=>o.id===O))==null?void 0:Ze.data.step)??null,Ie=x?((et=p.find(o=>o.id===x.stepId))==null?void 0:et.data.step)??null:null,Fe=(x==null?void 0:x.status)==="collect"&&!!Ie,ht=i.useMemo(()=>x?n.upstreamStateSources(x.stepId,p,b).steps:[],[x,p,b]),He=i.useMemo(()=>{const o=new Map;for(const c of p)o.set(c.id,Ft(c.id,b).count);return o},[p,b]),gt=i.useMemo(()=>({step:Ut,control:qt}),[]),[ye,Je]=i.useState({}),[$e,Be]=i.useState({}),Ue=i.useMemo(()=>({actionDef:(o,c)=>{var w;return(w=Z[o])==null?void 0:w.find(g=>g.key===c)},testOutputs:ye}),[Z,ye]),[qe,ze]=i.useState(null),we=i.useMemo(()=>{const o=n.upstreamStateSources(O,p,b,Ue);return{...o,steps:n.excludeSelfStep(o.steps,O??qe)}},[O,qe,p,b,Ue]),Ke=JSON.stringify(we.steps.map(o=>o.id));i.useEffect(()=>{const o=JSON.parse(Ke);if(!O||o.length===0){Je({}),Be({});return}let c=!1;return Promise.all(o.map(async w=>{try{const g=await m.listStepTests(t.id,w),j=g.length?g[g.length-1]:null;return j?{id:w,output:j.lastRunOutput,meta:j.lastRunMeta}:null}catch{return null}})).then(w=>{if(c)return;const g={},j={};for(const C of w)C!=null&&C.meta&&(j[C.id]=C.meta),!(!C||C.output===void 0||C.output===null)&&(g[C.id]=C.output);Je(g),Be(j)}),()=>{c=!0}},[m,t.id,O,Ke]);const Ge=i.useMemo(()=>{const o={};for(const c of we.steps){Object.assign(o,n.stepMetaSampleValues(c.id,$e[c.id]));const w=ye[c.id];if(w!==void 0){if(o[`steps.${c.id}.output`]=w,typeof w=="object"&&w!==null&&!Array.isArray(w))for(const[g,j]of Object.entries(w))o[`steps.${c.id}.output.${g}`]=j;for(const g of c.outputs??[]){if(!g.path||!g.key.includes("."))continue;const j=n.valueAtPath(w,g.key);j!==void 0&&(o[`steps.${c.id}.output.${g.key}`]=j)}}}return o},[we.steps,ye,$e]),Xe=n.useExpressionOptions(),Ye=i.useMemo(()=>({...u??{},steps:we.steps,hasTrigger:we.hasTrigger,sampleValues:{...Xe.sampleValues??{},...(u==null?void 0:u.sampleValues)??{},...Ge}}),[u,Xe.sampleValues,we,Ge]);return e.jsx(dt.Provider,{value:Re,children:e.jsx(We.Provider,{value:M,children:e.jsx(Me.Provider,{value:He,children:e.jsx(Ve.Provider,{value:l,children:e.jsx(n.WorkflowProjectProvider,{project:f,children:e.jsx(n.ExpressionOptionsProvider,{value:Ye,children:e.jsxs("div",{ref:ve,className:"w6w-flow",style:{width:"100%",height:a,position:"relative"},onKeyDown:o=>{if(o.key!=="Backspace"&&o.key!=="Delete"||O||V||!U&&!k)return;const c=o.target;c.isContentEditable||c.tagName==="INPUT"||c.tagName==="TEXTAREA"||c.tagName==="SELECT"||c.closest("dialog, .w6w-modal")!==null||(o.preventDefault(),U?fe(U):k&&Ce(k))},children:[e.jsxs(R.ReactFlow,{nodes:p,edges:b,defaultEdgeOptions:{type:"smoothstep"},connectionLineType:R.ConnectionLineType.SmoothStep,onNodesChange:re,onEdgesChange:ae,onConnect:ne,onConnectEnd:Ae,isValidConnection:oe,onNodeDragStop:()=>{D&&F(p,b)},onMoveEnd:(o,c)=>{if(!o||r)return;const w=n.flowToWorkflow(t,p,b),g=n.withViewport(w,c);g!==w&&s(g)},onSelectionChange:({nodes:o,edges:c})=>{var w,g;q(((w=o[0])==null?void 0:w.id)??null),$(((g=c[0])==null?void 0:g.id)??null)},nodeTypes:gt,nodesDraggable:!r,nodesConnectable:!r,elementsSelectable:!0,...E?{defaultViewport:E}:{fitView:!0},deleteKeyCode:null,colorMode:Pe,proOptions:{hideAttribution:!0},children:[e.jsx(R.Background,{gap:16}),e.jsx(R.Controls,{showInteractive:!1,children:!r&&e.jsx(R.ControlButton,{onClick:xe,title:"Auto-layout — re-flow the graph into columns","aria-label":"Auto-layout the graph",children:e.jsx(de.Icon,{name:"layout"})})}),e.jsx(R.MiniMap,{pannable:!0,zoomable:!0,style:{background:"var(--w6w-panel-2)"}}),!r&&e.jsx(R.Panel,{position:"top-left",children:e.jsx("button",{type:"button",className:"w6w-btn",onClick:()=>Q(!0),children:"+ Step"})}),!r&&ce&&e.jsx(R.Panel,{position:"top-right",children:e.jsxs("div",{className:"w6w-edge-lane",children:[e.jsx("span",{className:"w6w-muted w6w-small",children:"Run on"}),["success","error"].map(o=>e.jsx("button",{type:"button",className:`w6w-btn w6w-btn-sm w6w-btn-ghost${Y(ce)===o?" active":""}`,"aria-pressed":Y(ce)===o,title:Ht,onClick:()=>Te(o),children:o==="success"?"Success":"Error"},o)),(le==null?void 0:le.edgeId)===ce.id&&e.jsx("span",{className:"w6w-edge-lane-err w6w-small",role:"alert",children:le.message})]})})]}),V&&e.jsx(n.StepBuilderModal,{onClose:()=>{Q(!1),z(null),ze(null)},onAdd:o=>{const c=B(o);return c&&ze(c),c},onDraftChange:(o,c)=>K(o,{id:o,...c}),workflowId:t.id,upstreamSteps:n.stepBuilderUpstreamSteps(_,p,b)}),_e&&O&&e.jsx(zt,{workflowId:t.id,step:_e,upstreamSteps:Ye.steps??[],readOnly:r,fanOutCount:He.get(O)??0,initialView:pe,onChange:o=>K(O,o),onClose:()=>ee(null),onTestRun:N}),x&&e.jsxs(n.Modal,{title:`${Fe?"Run step":"Test run"}: ${x.stepId}`,onClose:()=>y(null),children:[Fe&&Ie&&e.jsx(Bt,{workflowId:t.id,step:Ie,upstreamSteps:ht,onCancel:()=>y(null),onRun:(o,c)=>mt(x.stepId,o,c)},x.stepId),!Fe&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"w6w-modal-body",children:[x.status==="running"&&e.jsx("p",{className:"w6w-muted w6w-small",children:"Running…"}),x.status==="error"&&e.jsxs("div",{className:"w6w-result w6w-error",children:[x.errorCode&&e.jsx("div",{className:"w6w-small",style:{opacity:.75,marginBottom:4},children:e.jsx("code",{children:x.errorCode})}),x.error||"The step failed with no error message."]}),x.status==="done"&&e.jsxs("div",{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{marginBottom:6},children:"Result"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:360,overflow:"auto",margin:0},children:JSON.stringify(x.value,null,2)}),x.meta&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{margin:"10px 0 6px"},children:"Metadata"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:360,overflow:"auto",margin:0},children:JSON.stringify(x.meta,null,2)})]})]}),x.logs&&x.logs.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{margin:"10px 0 6px"},children:"Console output"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:200,overflow:"auto",margin:0},children:x.logs.join(`
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),R=require("@xyflow/react"),i=require("react"),xt=require("react-dom"),n=require("./ConfirmModal-ChoiGy2K.cjs"),de=require("./Copyable-CYZU1o4X.cjs"),tt=220;function bt(t){return t.length<=tt?{text:t,clipped:!1,length:t.length}:{text:t.slice(0,tt).trimEnd(),clipped:!0,length:t.length}}function jt({params:t,values:s,testStartState:r,view:a="props"}){const{sampleValues:d}=n.useExpressionOptions(),u=i.useMemo(()=>n.buildResolveScope(d,r),[d,r]),f=n.flattenParams(t),S=m=>{var l;return s[m]!==void 0?s[m]:(l=f.find(x=>x.key===m))==null?void 0:l.default},N=f.filter(m=>m.type!=="section"&&n.isParamVisible(m,S));if(a==="code"){const m=vt(N,s,u);return e.jsx("div",{className:"w6w-resolved-params",children:e.jsx(n.JsonEditor,{value:JSON.stringify(m,null,2),onChange:()=>{},readOnly:!0,minHeight:"260px",height:"100%","aria-label":"Resolved test values (JSON)"})})}const v=N.filter(m=>!n.deepEqual(S(m.key),m.default));return N.length===0?e.jsx("div",{className:"w6w-resolved-params",children:e.jsx("p",{className:"w6w-muted w6w-small",children:"This action takes no parameters."})}):v.length===0?e.jsx("div",{className:"w6w-resolved-params",children:e.jsx("p",{className:"w6w-muted w6w-small",children:"Every configured value matches its default — nothing to show here. Switch to JSON to see the full set."})}):e.jsx("div",{className:"w6w-resolved-params w6w-resolved-table",children:v.map(m=>m.type==="vars"?e.jsx(Nt,{param:m,value:s[m.key],scope:u},m.key):e.jsx(St,{label:m.label??m.key,segments:n.resolveParamValue(s[m.key]!==void 0?s[m.key]:m.default,u)},m.key))})}function vt(t,s,r){const a={};for(const d of t)if(d.type==="vars"){const u=Array.isArray(s[d.key])?s[d.key]:Array.isArray(d.default)?d.default:[];a[d.key]=n.resolveVarsJson(u,r)}else a[d.key]=n.resolveParamJson(s[d.key]!==void 0?s[d.key]:d.default,r);return a}function St({label:t,segments:s}){return e.jsxs("div",{className:"w6w-resolved-row",children:[e.jsx("span",{className:"w6w-resolved-label",children:t}),e.jsx("div",{className:"w6w-resolved-value",children:e.jsx(it,{segments:s})})]})}function Nt({param:t,value:s,scope:r}){const a=Array.isArray(s)?s:Array.isArray(t.default)?t.default:[];return e.jsxs("div",{className:"w6w-resolved-row",children:[e.jsx("span",{className:"w6w-resolved-label",children:t.label??t.key}),a.length===0?e.jsx("p",{className:"w6w-muted w6w-small",children:"None configured."}):e.jsx("div",{className:"w6w-stack",children:a.map((d,u)=>e.jsxs("div",{className:"w6w-resolved-value",children:[e.jsx("code",{children:d.key||"(no key)"})," → ",e.jsx(it,{segments:n.resolveParamValue(d.value,r)})]},u))})]})}function it({segments:t}){return e.jsx(e.Fragment,{children:t.map((s,r)=>e.jsx(Ct,{segment:s},r))})}function Ct({segment:t}){switch(t.status){case"resolved":return t.ref?e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"var",refName:t.ref}),e.jsx(st,{value:t.value})]}):e.jsx(st,{value:t.value});case"unresolved":return e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"var",refName:t.ref}),e.jsx("span",{className:"w6w-param-unresolved",children:"unresolved"})]});case"not-evaluated":return e.jsxs(e.Fragment,{children:[e.jsx(ke,{kind:"expr"}),e.jsx("span",{className:"w6w-param-unevaluated",children:"not evaluated"})]});case"masked":return e.jsx(ke,{kind:"secret",refName:t.ref})}}function st({value:t}){const[s,r]=i.useState(!1),a=kt(t),d=bt(a);return d.clipped?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:s?"w6w-resolved-text-full":void 0,children:s?a:`${d.text}…`}),e.jsx("button",{type:"button",className:"w6w-resolved-more","aria-expanded":s,onClick:()=>r(u=>!u),children:s?"Show less":`Show all (${d.length.toLocaleString()} characters)`})]}):e.jsx("span",{children:a})}const yt={var:"◆",secret:"🔒",expr:"ƒ"};function ke({kind:t,refName:s}){const r=t==="expr"?"expr":n.varLabel(s??"");return e.jsxs("span",{className:`w6w-expr-chip w6w-expr-chip-${t}`,children:[e.jsx("span",{className:"w6w-expr-chip-sigil",children:yt[t]}),e.jsx("span",{className:"w6w-expr-chip-label",children:r})]})}function kt(t){if(t===null)return"null";if(t===void 0)return"(not set)";if(t==="")return'""';if(typeof t=="string"||typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return String(t)}}function Y(t){var s;return((s=t.data)==null?void 0:s.when)==="error"?"error":"success"}function lt(t,s){var r;return((r=t.find(a=>a.id===s))==null?void 0:r.id)??null}function ct(t,s,r,a,d){var v,m;if(!t||!s||t===s||a.some(l=>l.source===t&&l.target===s))return!1;const u=(v=r.find(l=>l.id===t))==null?void 0:v.data.step,f=(m=r.find(l=>l.id===s))==null?void 0:m.data.step;if(!u||!f)return!1;const S=n.nodePortsForStep(u,d),N=n.nodePortsForStep(f,d);return S.out>=1&&N.in>=1}function Le(t,s,r,a,d,u){var T,E;if(!ct(t,s,r,a,u)||!t||!s)return null;const f=(T=r.find(D=>D.id===t))==null?void 0:T.data.step,S=(E=r.find(D=>D.id===s))==null?void 0:E.data.step;if(!f||!S)return null;const N=n.nodePortsForStep(f,u),v=n.nodePortsForStep(S,u);let m=a;if(m.filter(D=>D.source===t&&Y(D)===d).length>=N.out)return{next:a,conflict:null,refusal:{refused:"out_cap",cap:N.out}};const x=m.filter(D=>D.target===s);if(x.length>=v.in){const D=new Set(x.slice(0,x.length-v.in+1).map(p=>p.id));m=m.filter(p=>!D.has(p.id))}const y=n.flowEdgeId(t,s,d);return{next:R.addEdge({source:t,target:s,id:y,sourceHandle:n.sourceHandleForLane(d),data:{when:d},...n.edgeVisuals(d,void 0)},m),conflict:lt(m,y),refusal:null}}function Ee(t,s,r,a,d="success",u){const f=Le(t,s,r,a,d,u);return!f||f.conflict||f.refusal?null:f.next}function Et(t,s,r,a,d="success",u){var f;return((f=Le(t,s,r,a,d,u))==null?void 0:f.conflict)??null}function Pt(t,s,r,a,d="success",u){var f;return((f=Le(t,s,r,a,d,u))==null?void 0:f.refusal)??null}function De(t,s,r,a,d){var T;const u=t.filter(E=>E.id===s);if(u.length!==1)return null;const f=u[0],S=(T=a.find(E=>E.id===f.source))==null?void 0:T.data.step;if(!S)return null;const N=n.nodePortsForStep(S,d).out,v=t.filter(E=>E.id!==s);if((Y(f)===r?[]:v.filter(E=>E.source===f.source&&Y(E)===r)).length>=N)return{next:t,conflict:null,refusal:{refused:"out_cap",cap:N}};const l=n.edgeVisuals(r,void 0),x={...f,id:n.flowEdgeId(f.source,f.target,r),data:{...f.data,when:r},className:l.className,label:l.label,sourceHandle:n.sourceHandleForLane(r)},y=lt(v,x.id);return{next:t.map(E=>E.id===s?x:E),conflict:y,refusal:null}}function At(t,s,r,a,d){const u=De(t,s,r,a,d);return!u||u.conflict||u.refusal?null:u.next}function Tt(t,s,r,a,d){var u;return((u=De(t,s,r,a,d))==null?void 0:u.conflict)??null}function Rt(t,s,r,a,d){var u;return((u=De(t,s,r,a,d))==null?void 0:u.refusal)??null}function It(t,s,r){return t.map(a=>{const d=a.source===s?r:a.source,u=a.target===s?r:a.target;return{...a,source:d,target:u,id:n.flowEdgeId(d,u,Y(a))}})}function Ft(t,s){const r={success:0,error:0};for(const d of s)d.source===t&&r[Y(d)]++;const a=Math.max(r.success,r.error);return{enabled:a>=2,count:a}}function Lt(t,s){const{fanOut:r,...a}=t;return s==="parallel"?{...a,fanOut:"parallel"}:a}function Dt(t,s){return`Runs these ${t} steps in ${s==="parallel"?"parallel":"sequence"}`}const Wt=new Set(["succeeded","failed","canceled"]);function Mt(t,s){var r;return t?((r=t.steps[s])==null?void 0:r.status)??"pending":"no-run"}const nt={borderColor:"var(--w6w-border)",borderStyle:"solid",borderWidth:1,opacity:1};function ut(t,s){const r=s!==void 0&&Wt.has(s);switch(t){case"no-run":return nt;case"pending":return r?{borderColor:"var(--w6w-muted)",borderStyle:"dashed",borderWidth:1,opacity:.5}:{borderColor:"var(--w6w-border)",borderStyle:"dashed",borderWidth:1,opacity:1};case"running":return{borderColor:"var(--w6w-accent)",borderStyle:"solid",borderWidth:2,opacity:1};case"succeeded":return{borderColor:"var(--w6w-success)",borderStyle:"solid",borderWidth:2,opacity:1};case"failed":return{borderColor:"var(--w6w-danger)",borderStyle:"solid",borderWidth:2,opacity:1};case"skipped":return{borderColor:"var(--w6w-muted)",borderStyle:"dashed",borderWidth:1,opacity:.7};default:return nt}}function Vt(t,s,r){if(!t)return;const a=t.steps[s];if(!a)return;const d=r??"success";if(a.status==="succeeded")return d==="success"?"taken":"skipped";if(a.status==="failed")return d==="error"?"taken":"skipped";if(a.status==="skipped")return"skipped"}function Ot(t,s){const[r,a]=i.useState({}),d=i.useRef(new Set),u=JSON.stringify([...new Set(s.map(f=>f.data.step.uses.app))].filter(f=>f&&!n.isInternalApp(f)).sort());return i.useEffect(()=>{const f=JSON.parse(u).filter(S=>!d.current.has(S));if(f.length!==0){for(const S of f)d.current.add(S);Promise.all(f.map(async S=>{try{return[S,await t.getAppActions(S)]}catch{return d.current.delete(S),null}})).then(S=>{const N=S.filter(v=>v!==null);N.length!==0&&a(v=>({...v,...Object.fromEntries(N)}))})}},[t,u]),r}function _t(t){return(s,r)=>{var a,d;return(d=(a=t[s])==null?void 0:a.find(u=>u.key===r))==null?void 0:d.ports}}const Ht="Which outcome of the source step this edge carries. An error edge is drawn by dragging from the step's error exit port; use this control to re-lane an edge already drawn. An error edge overrides the step’s “On error” policy.";function ot(t,s,r,a){const d=t.find(u=>u.id===s);return[r,a,d==null?void 0:d.source,d==null?void 0:d.target]}const We=i.createContext(void 0),Me=i.createContext(new Map);function rt(t){return`Can’t draw that edge: this node allows at most ${t} outgoing edge${t===1?"":"s"} per lane.`}const Ve=i.createContext(new Map),dt=i.createContext(null);function Jt(t){return e.jsx(R.ReactFlowProvider,{children:e.jsx($t,{...t})})}function $t({value:t,onChange:s,readOnly:r,height:a=480,apps:d,exprOptions:u,project:f,runState:S,onTestRun:N,fitViewKey:v}){var Qe,Ze,et;const m=n.useW6WApi(),l=i.useMemo(()=>new Map((d??[]).map(o=>[o.id,o])),[d]),[x,y]=i.useState(null),T=i.useMemo(()=>n.workflowToFlow(t),[t.id]),E=i.useMemo(()=>n.storedViewport(t),[t.id]),D=((Qe=t.settings)==null?void 0:Qe.savePosition)!==!1,[p,I,re]=R.useNodesState(T.nodes),Z=Ot(m,p),M=i.useMemo(()=>_t(Z),[Z]),[b,A,ae]=R.useEdgesState(T.edges);i.useEffect(()=>{I(o=>o.map(c=>{const w=Mt(S,c.id);return c.data.stepStatus===w&&c.data.runStatus===(S==null?void 0:S.status)?c:{...c,data:{...c.data,stepStatus:w,runStatus:S==null?void 0:S.status}}})),A(o=>o.map(c=>{const w=Y(c),g=Vt(S,c.source,w),j=n.edgeVisuals(w,g);return c.className===j.className&&c.label===j.label?c:{...c,className:j.className,label:j.label}}))},[S,I,A]);const[U,q]=i.useState(null),[k,$]=i.useState(null),[V,Q]=i.useState(!1),[O,ee]=i.useState(null),[pe,te]=i.useState("props"),[se,he]=i.useState(null),ie=i.useRef(!1),ve=i.useRef(null),[_,z]=i.useState(null),{screenToFlowPosition:Se,fitView:H}=R.useReactFlow(),Pe=n.useEffectiveTheme();i.useEffect(()=>{I(T.nodes),A(T.edges),q(null),ee(null)},[T,I,A]);const F=i.useCallback((o,c)=>{s(n.flowToWorkflow(t,o,c))},[t,s]),oe=i.useCallback(o=>ct(o.source,o.target,p,b,M),[p,b,M]),ne=i.useCallback(o=>{if(r)return;const c=Ee(o.source,o.target,p,b,n.laneForSourceHandle(o.sourceHandle),M);if(!c){const w=n.laneForSourceHandle(o.sourceHandle),g=Pt(o.source,o.target,p,b,w,M);if(g){const C=b.find(P=>P.source===o.source&&Y(P)===w);C&&(A(b.map(P=>({...P,selected:P.id===C.id}))),$(C.id),W({edgeId:C.id,message:rt(g.cap)}));return}const j=Et(o.source,o.target,p,b,n.laneForSourceHandle(o.sourceHandle));if(!j)return;A(b.map(C=>({...C,selected:C.id===j}))),$(j),W({edgeId:j,message:n.idClashMessage("Can’t draw that edge",j,ot(b,j,o.source,o.target))});return}W(null),A(c),F(p,c)},[b,p,A,F,r,M]),Ae=i.useCallback((o,c)=>{var J,L,G;if(r||c.isValid)return;const w=c.fromNode;if(!w)return;const g=((J=c.fromHandle)==null?void 0:J.type)==="target"?"target":"source",j=(L=p.find(X=>X.id===w.id))==null?void 0:L.data.step;if(j){const X=n.nodePortsForStep(j,M);if((g==="source"?X.out:X.in)<1)return}const C="changedTouches"in o?o.changedTouches[0]:o,P=Se({x:C.clientX,y:C.clientY});z({nodeId:w.id,handleType:g,position:P,lane:n.laneForSourceHandle((G=c.fromHandle)==null?void 0:G.id)}),Q(!0)},[r,Se,p,M]),fe=i.useCallback(o=>{r||he(o)},[r]),Ne=i.useCallback(o=>{if(r)return;const c=p.filter(g=>g.id!==o),w=b.filter(g=>g.source!==o&&g.target!==o);I(c),A(w),U===o&&q(null),O===o&&ee(null),F(c,w)},[p,b,I,A,F,r,U,O]),ge=i.useCallback(()=>{if(r)return;const o=n.relayoutNodes(p,b);I(o),ie.current=!0,F(o,b)},[p,b,I,F,r]),xe=i.useCallback(()=>{r||ge()},[r,ge]);i.useEffect(()=>{ie.current&&(ie.current=!1,H({duration:300}))},[p,H]);const be=i.useRef(v);i.useEffect(()=>{Object.is(be.current,v)||(be.current=v,H({duration:300}))},[v,H]);const[le,W]=i.useState(null),ce=i.useMemo(()=>b.find(o=>o.id===k)??null,[b,k]),Te=i.useCallback(o=>{if(r||!k)return;const c=b.find(P=>P.id===k);if(!c||Y(c)===o)return;const w=Tt(b,k,o,p),g=Rt(b,k,o,p,M),j=w||g?null:At(b,k,o,p,M);if(!j){if(g){W({edgeId:k,message:rt(g.cap)});return}W({edgeId:k,message:w?n.idClashMessage("Can’t switch this edge",w,ot(b,w,c.source,c.target)):"This edge can’t be switched right now."});return}W(null),A(j);const C=j.find(P=>P.source===c.source&&P.target===c.target&&Y(P)===o);$((C==null?void 0:C.id)??null),F(p,j)},[b,p,A,F,r,k,M]),Ce=i.useCallback(o=>{if(r)return;const c=b.filter(w=>w.id!==o);c.length!==b.length&&(A(c),k===o&&$(null),F(p,c))},[p,b,A,F,r,k]),h=i.useCallback(o=>{if(r)return;const c=p.find(P=>P.id===o);if(!c)return;const w=n.suggestStepId(p.map(P=>P.id),`${c.data.step.id}_copy`),g={...structuredClone(c.data.step),id:w},j={id:w,type:c.type,position:{x:c.position.x+40,y:c.position.y+60},data:{step:g,isInternal:c.data.isInternal}},C=[...p,j];I(C),q(w),F(C,b)},[p,b,I,F,r]),B=i.useCallback(o=>{if(r)return;const c=n.isInternalApp(o.uses.app),w=n.suggestStepId(p.map(J=>J.id),n.slugifyLabel(n.internalNodeLabel(o.uses.app,o.uses.action))),g={id:w,uses:o.uses,...o.with&&Object.keys(o.with).length>0?{with:o.with}:{}},j={id:w,type:c?"control":"step",position:(_==null?void 0:_.position)??{x:80,y:80+p.length*24},data:{step:g,isInternal:c}},C=[...p,j];let P=b;if(_){const[J,L]=_.handleType==="target"?[w,_.nodeId]:[_.nodeId,w];P=Ee(J,L,C,b,_.lane,M)??b}else{const J=p.find(L=>n.isTriggerApp(L.data.step.uses.app));if(n.isTriggerApp(o.uses.app)){if(!J){const L=n.findChainRoot(p,b);L&&(P=Ee(w,L.id,C,b,"success",M)??b)}}else{const G=(J&&!b.some(X=>X.source===J.id)?J:void 0)??n.findChainTail(p,b);G&&(P=Ee(G.id,w,C,b,"success",M)??b)}}return I(C),P!==b&&A(P),q(w),F(C,P),w},[p,b,I,A,F,r,_,M]),K=i.useCallback((o,c)=>{const w=c.id!==o;if(w&&p.some(j=>j.id===c.id))return;const g=p.map(j=>j.id===o?{...j,id:c.id,data:{step:c,isInternal:n.isInternalApp(c.uses.app)}}:j);if(w){const j=It(b,o,c.id);I(g),A(j),U===o&&q(c.id),O===o&&ee(c.id),F(g,j);return}I(g),F(g,b)},[p,b,I,A,U,O,F]),ue=i.useCallback((o,c,w)=>{(async()=>{const g=await m.saveStepTest(t.id,o,c).catch(j=>(console.error("step run fixture save failed",j),null));await m.recordStepTestRun(t.id,o,{stepTestId:(g==null?void 0:g.id)??null,status:w.status,input:c.input,output:w.output,error:w.error,...w.meta?{meta:w.meta}:{}})})().catch(g=>{console.error("step run persist failed",g)})},[m,t.id]),je=i.useCallback(o=>{const c=p.find(w=>w.id===o);!c||n.isControlApp(c.data.step.uses.app)||y({stepId:o,status:"collect"})},[p]),mt=i.useCallback(async(o,c,w)=>{N==null||N();const g=p.find(L=>L.id===o);if(!g)return;const j=g.data.step,C=n.isTriggerApp(j.uses.app),P=C?{input:c}:{...j.with??{},...c},J=C?{input:c,with:c}:{input:c,with:P};y({stepId:o,status:"running"});try{const L=await m.invokeAction(j.uses.app,j.uses.action,P,{...j.uses.connection?{connectionId:j.uses.connection}:{},project:f,...w?{state:w}:{}}),G=L.logs,X=L.meta;y({stepId:o,status:"done",value:L.value,logs:G,...X?{meta:X}:{}}),ue(o,J,{status:"succeeded",output:L.value,...X?{meta:X}:{}})}catch(L){const G=L;y({stepId:o,status:"error",error:G.message??String(L),errorCode:G.code}),ue(o,J,{status:"failed",error:G.message??String(L)})}},[p,m,ue,f,N]),Re=i.useMemo(()=>({onEdit:o=>{te("props"),ee(o)},onEditJson:o=>{te("json"),ee(o)},onRun:je,onDuplicate:h,onDelete:fe,readOnly:r}),[je,h,fe,r]);i.useEffect(()=>{const o=ve.current;if(!o)return;const c=w=>{const g=w.target.closest(".react-flow__node");if(!g)return;const j=g.getAttribute("data-id");j&&(w.stopPropagation(),Re.onEdit(j))};return o.addEventListener("dblclick",c,!0),()=>o.removeEventListener("dblclick",c,!0)},[Re]);const _e=((Ze=p.find(o=>o.id===O))==null?void 0:Ze.data.step)??null,Ie=x?((et=p.find(o=>o.id===x.stepId))==null?void 0:et.data.step)??null:null,Fe=(x==null?void 0:x.status)==="collect"&&!!Ie,ht=i.useMemo(()=>x?n.upstreamStateSources(x.stepId,p,b).steps:[],[x,p,b]),He=i.useMemo(()=>{const o=new Map;for(const c of p)o.set(c.id,Ft(c.id,b).count);return o},[p,b]),gt=i.useMemo(()=>({step:Ut,control:qt}),[]),[ye,Je]=i.useState({}),[$e,Be]=i.useState({}),Ue=i.useMemo(()=>({actionDef:(o,c)=>{var w;return(w=Z[o])==null?void 0:w.find(g=>g.key===c)},testOutputs:ye}),[Z,ye]),[qe,ze]=i.useState(null),we=i.useMemo(()=>{const o=n.upstreamStateSources(O,p,b,Ue);return{...o,steps:n.excludeSelfStep(o.steps,O??qe)}},[O,qe,p,b,Ue]),Ke=JSON.stringify(we.steps.map(o=>o.id));i.useEffect(()=>{const o=JSON.parse(Ke);if(!O||o.length===0){Je({}),Be({});return}let c=!1;return Promise.all(o.map(async w=>{try{const g=await m.listStepTests(t.id,w),j=g.length?g[g.length-1]:null;return j?{id:w,output:j.lastRunOutput,meta:j.lastRunMeta}:null}catch{return null}})).then(w=>{if(c)return;const g={},j={};for(const C of w)C!=null&&C.meta&&(j[C.id]=C.meta),!(!C||C.output===void 0||C.output===null)&&(g[C.id]=C.output);Je(g),Be(j)}),()=>{c=!0}},[m,t.id,O,Ke]);const Ge=i.useMemo(()=>{const o={};for(const c of we.steps){Object.assign(o,n.stepMetaSampleValues(c.id,$e[c.id]));const w=ye[c.id];if(w!==void 0){if(o[`steps.${c.id}.output`]=w,typeof w=="object"&&w!==null&&!Array.isArray(w))for(const[g,j]of Object.entries(w))o[`steps.${c.id}.output.${g}`]=j;for(const g of c.outputs??[]){if(!g.path||!g.key.includes("."))continue;const j=n.valueAtPath(w,g.key);j!==void 0&&(o[`steps.${c.id}.output.${g.key}`]=j)}}}return o},[we.steps,ye,$e]),Xe=n.useExpressionOptions(),Ye=i.useMemo(()=>({...u??{},steps:we.steps,hasTrigger:we.hasTrigger,sampleValues:{...Xe.sampleValues??{},...(u==null?void 0:u.sampleValues)??{},...Ge}}),[u,Xe.sampleValues,we,Ge]);return e.jsx(dt.Provider,{value:Re,children:e.jsx(We.Provider,{value:M,children:e.jsx(Me.Provider,{value:He,children:e.jsx(Ve.Provider,{value:l,children:e.jsx(n.WorkflowProjectProvider,{project:f,children:e.jsx(n.ExpressionOptionsProvider,{value:Ye,children:e.jsxs("div",{ref:ve,className:"w6w-flow",style:{width:"100%",height:a,position:"relative"},onKeyDown:o=>{if(o.key!=="Backspace"&&o.key!=="Delete"||O||V||!U&&!k)return;const c=o.target;c.isContentEditable||c.tagName==="INPUT"||c.tagName==="TEXTAREA"||c.tagName==="SELECT"||c.closest("dialog, .w6w-modal")!==null||(o.preventDefault(),U?fe(U):k&&Ce(k))},children:[e.jsxs(R.ReactFlow,{nodes:p,edges:b,defaultEdgeOptions:{type:"smoothstep"},connectionLineType:R.ConnectionLineType.SmoothStep,onNodesChange:re,onEdgesChange:ae,onConnect:ne,onConnectEnd:Ae,isValidConnection:oe,onNodeDragStop:()=>{D&&F(p,b)},onMoveEnd:(o,c)=>{if(!o||r)return;const w=n.flowToWorkflow(t,p,b),g=n.withViewport(w,c);g!==w&&s(g)},onSelectionChange:({nodes:o,edges:c})=>{var w,g;q(((w=o[0])==null?void 0:w.id)??null),$(((g=c[0])==null?void 0:g.id)??null)},nodeTypes:gt,nodesDraggable:!r,nodesConnectable:!r,elementsSelectable:!0,...E?{defaultViewport:E}:{fitView:!0},deleteKeyCode:null,colorMode:Pe,proOptions:{hideAttribution:!0},children:[e.jsx(R.Background,{gap:16}),e.jsx(R.Controls,{showInteractive:!1,children:!r&&e.jsx(R.ControlButton,{onClick:xe,title:"Auto-layout — re-flow the graph into columns","aria-label":"Auto-layout the graph",children:e.jsx(de.Icon,{name:"layout"})})}),e.jsx(R.MiniMap,{pannable:!0,zoomable:!0,style:{background:"var(--w6w-panel-2)"}}),!r&&e.jsx(R.Panel,{position:"top-left",children:e.jsx("button",{type:"button",className:"w6w-btn",onClick:()=>Q(!0),children:"+ Step"})}),!r&&ce&&e.jsx(R.Panel,{position:"top-right",children:e.jsxs("div",{className:"w6w-edge-lane",children:[e.jsx("span",{className:"w6w-muted w6w-small",children:"Run on"}),["success","error"].map(o=>e.jsx("button",{type:"button",className:`w6w-btn w6w-btn-sm w6w-btn-ghost${Y(ce)===o?" active":""}`,"aria-pressed":Y(ce)===o,title:Ht,onClick:()=>Te(o),children:o==="success"?"Success":"Error"},o)),(le==null?void 0:le.edgeId)===ce.id&&e.jsx("span",{className:"w6w-edge-lane-err w6w-small",role:"alert",children:le.message})]})})]}),V&&e.jsx(n.StepBuilderModal,{onClose:()=>{Q(!1),z(null),ze(null)},onAdd:o=>{const c=B(o);return c&&ze(c),c},onDraftChange:(o,c)=>K(o,{id:o,...c}),workflowId:t.id,upstreamSteps:n.stepBuilderUpstreamSteps(_,p,b)}),_e&&O&&e.jsx(zt,{workflowId:t.id,step:_e,upstreamSteps:Ye.steps??[],readOnly:r,fanOutCount:He.get(O)??0,initialView:pe,onChange:o=>K(O,o),onClose:()=>ee(null),onTestRun:N}),x&&e.jsxs(n.Modal,{title:`${Fe?"Run step":"Test run"}: ${x.stepId}`,onClose:()=>y(null),children:[Fe&&Ie&&e.jsx(Bt,{workflowId:t.id,step:Ie,upstreamSteps:ht,onCancel:()=>y(null),onRun:(o,c)=>mt(x.stepId,o,c)},x.stepId),!Fe&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"w6w-modal-body",children:[x.status==="running"&&e.jsx("p",{className:"w6w-muted w6w-small",children:"Running…"}),x.status==="error"&&e.jsxs("div",{className:"w6w-result w6w-error",children:[x.errorCode&&e.jsx("div",{className:"w6w-small",style:{opacity:.75,marginBottom:4},children:e.jsx("code",{children:x.errorCode})}),x.error||"The step failed with no error message."]}),x.status==="done"&&e.jsxs("div",{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{marginBottom:6},children:"Result"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:360,overflow:"auto",margin:0},children:JSON.stringify(x.value,null,2)}),x.meta&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{margin:"10px 0 6px"},children:"Metadata"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:360,overflow:"auto",margin:0},children:JSON.stringify(x.meta,null,2)})]})]}),x.logs&&x.logs.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"w6w-muted w6w-small",style:{margin:"10px 0 6px"},children:"Console output"}),e.jsx("pre",{className:"w6w-result",style:{whiteSpace:"pre-wrap",maxHeight:200,overflow:"auto",margin:0},children:x.logs.join(`
|
|
2
2
|
`)})]})]}),e.jsx("div",{className:"w6w-modal-actions",children:e.jsx("button",{type:"button",className:"w6w-btn",onClick:()=>y(null),children:"Close"})})]})]}),se!==null&&e.jsx(n.ConfirmModal,{title:"Delete step",message:`Delete step "${se}"? Its connections are removed too.`,confirmLabel:"Delete",onConfirm:()=>{Ne(se),he(null)},onClose:()=>he(null)})]})})})})})})})}function Oe(t){try{const s=JSON.parse(t);return s&&typeof s=="object"&&!Array.isArray(s)?s:null}catch{return null}}function pt({text:t,onChange:s,seeds:r,readOnly:a}){const d=Oe(t),u=d?Object.keys(d).length:0,f=u>0,[S,N]=i.useState(f);i.useEffect(()=>{f&&N(!0)},[f]);const v=m=>{s(JSON.stringify(m.lastRunOutput??m.input??{},null,2)),N(!0)};return e.jsxs("div",{className:"w6w-field w6w-incoming-state",children:[e.jsx("span",{children:"Incoming state"}),r.length>0&&e.jsx("div",{className:"w6w-seed-picker",children:e.jsx("div",{className:"w6w-seed-chips",children:r.map(m=>e.jsxs("button",{type:"button",className:"w6w-chip w6w-seed-chip",title:`Use ${m.label}'s saved test as the incoming state`,disabled:a,onClick:()=>v(m.test),children:[e.jsx("code",{children:m.label}),m.test.lastRunStatus?e.jsxs("span",{className:"w6w-muted w6w-small",children:[" · ",m.test.lastRunStatus]}):null]},m.stepId))})}),e.jsxs("details",{className:"w6w-state-override",open:S,onToggle:m=>N(m.currentTarget.open),children:[e.jsxs("summary",{children:["Override the incoming state",u>0?` · ${u} key${u===1?"":"s"} set`:""]}),e.jsx("textarea",{rows:3,value:t,readOnly:a,spellCheck:!1,"aria-label":"Incoming state override (JSON)",onChange:m=>s(m.target.value)}),e.jsxs("span",{className:"w6w-hint",children:["JSON merged into the call (e.g. a script's ",e.jsx("code",{children:"input"}),"). Reach for this to test against a state the flow cannot currently produce — a field no upstream step returns yet, or a case you can't reproduce by running the flow."]})]})]})}function Bt({workflowId:t,step:s,upstreamSteps:r,onRun:a,onCancel:d}){const u=n.useW6WApi(),f=n.isTriggerApp(s.uses.app),S=n.isInternalApp(s.uses.app),N=i.useMemo(()=>{var k;return f?n.asFieldDefs((k=s.with)==null?void 0:k.fields):[]},[f,s.with]),v=i.useMemo(()=>f?n.fieldsToParams(N):S?n.internalNodeParams(s.uses.app,s.uses.action):null,[f,S,N,s.uses.app,s.uses.action]),[m,l]=i.useState(null),x=v??m;i.useEffect(()=>{if(v)return;if(!s.uses.app||!s.uses.action){l([]);return}let k=!1;return l(null),u.getAppActions(s.uses.app).then($=>{var V;k||l(((V=$.find(Q=>Q.key===s.uses.action))==null?void 0:V.params)??[])}).catch(()=>!k&&l([])),()=>{k=!0}},[u,v,s.uses.app,s.uses.action]);const[y,T]=i.useState(()=>{var k;return f?n.seedValues(n.asFieldDefs((k=s.with)==null?void 0:k.fields)):{}}),[E,D]=i.useState("{}"),p=n.useSeedSources(t,r,!f),I=n.startStateFromSeeds(p),[re,Z]=i.useState(!1);i.useEffect(()=>{let k=!1;return u.listStepTests(t,s.id).then($=>{if(k)return;const V=$.length?$[$.length-1]:null;f?V!=null&&V.with&&T(Q=>({...Q,...V.with})):V!=null&&V.input&&Object.keys(V.input).length>0&&D(JSON.stringify(V.input,null,2)),Z(!0)}).catch(()=>{k||Z(!0)}),()=>{k=!0}},[u,t,s.id,f]);const[M,b]=i.useState(!0),A=Oe(E),ae=f?M:A!==null,U=f?y:{...s.with??{},...A??{}},q=!!x&&re&&ae&&n.requiredParamsFilled(x,U);return e.jsxs("div",{className:"w6w-stepconfig",children:[e.jsx("div",{className:"w6w-modal-body",children:e.jsx("div",{className:"w6w-stack",children:x===null||!re?e.jsx("p",{className:"w6w-muted w6w-small",children:x===null?"Loading parameters…":"Loading saved values…"}):f?e.jsxs(e.Fragment,{children:[e.jsx(n.PropertyEntryForm,{params:x,values:y,onChange:T,onValidityChange:b}),x.length===0&&e.jsxs("span",{className:"w6w-hint",children:["This trigger declares no fields — provide a sample payload to run with. It becomes the trigger's output state (",e.jsx("code",{children:"input"}),")."]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"w6w-muted w6w-small",children:["Runs ",e.jsx("code",{children:s.uses.action})," with the configuration saved on this step — only the incoming state changes per run. Edit the step to change how it is configured."]}),e.jsx(pt,{text:E,onChange:D,seeds:p})]})})}),e.jsxs("div",{className:"w6w-modal-actions",children:[e.jsx("button",{type:"button",className:"w6w-btn w6w-btn-ghost",onClick:d,children:"Cancel"}),!q&&x!==null&&re&&e.jsx("span",{className:"w6w-muted w6w-small",children:ae?f?"Fill the required fields to test.":"This step is missing required configuration — set it on the Configure tab.":f?"The payload must be a JSON object to run.":"The incoming state must be a JSON object to run."}),e.jsx("button",{type:"button",className:"w6w-btn",disabled:!q,onClick:()=>a(f?y:A??{},f?void 0:I),children:"▶ Run"})]})]})}function me({type:t,position:s,multiple:r,id:a,variant:d}){return e.jsx(R.Handle,{type:t,position:s,id:a,className:d==="error"?"w6w-handle-error":r?"w6w-handle-multi":void 0,style:r?{height:22,borderRadius:3,width:8}:void 0,title:d==="error"?"On error — drag to route this step's failure separately":r?t==="target"?"Accepts multiple incoming connections":"Multiple outgoing connections":void 0})}function ft({id:t,runnable:s}){const r=i.useContext(dt);return!r||r.readOnly?null:e.jsxs(R.NodeToolbar,{position:R.Position.Top,className:"w6w-node-toolbar",children:[s&&e.jsx("button",{type:"button",className:"w6w-node-toolbar-btn",title:"Test-run this step","aria-label":"Test-run this step",onClick:()=>r.onRun(t),children:e.jsx(de.Icon,{name:"run",size:15})}),e.jsx("button",{type:"button",className:"w6w-node-toolbar-btn",title:"Edit","aria-label":"Edit step",onClick:()=>r.onEdit(t),children:e.jsx(de.Icon,{name:"edit",size:15})}),e.jsx("button",{type:"button",className:"w6w-node-toolbar-btn",title:"Duplicate","aria-label":"Duplicate step",onClick:()=>r.onDuplicate(t),children:e.jsx(de.Icon,{name:"copy",size:15})}),e.jsx("button",{type:"button",className:"w6w-node-toolbar-btn danger",title:"Delete","aria-label":"Delete step",onClick:()=>r.onDelete(t),children:e.jsx(de.Icon,{name:"trash",size:15})})]})}function wt({step:t,count:s}){if(s<2)return null;const r=t.fanOut==="parallel",a=Dt(s,r?"parallel":"sequential");return e.jsxs("div",{className:"w6w-fanout-badge",role:"img","aria-label":a,title:a,children:[e.jsx("span",{"aria-hidden":"true",children:r?"⇉":"→"})," ",s]})}function Ut({id:t,data:s,selected:r}){const a=s.step,u=i.useContext(Ve).get(a.uses.app),f=(u==null?void 0:u.displayName)||a.uses.app||"—",S=n.nodePortsForStep(a,i.useContext(We)),N=ut(s.stepStatus??"no-run",s.runStatus),v=e.jsx(wt,{step:a,count:i.useContext(Me).get(t)??0});return e.jsxs("div",{children:[e.jsx(ft,{id:t,runnable:!0}),e.jsxs("div",{"data-run-status":s.stepStatus??"no-run",style:{position:"relative",border:`${N.borderWidth}px ${N.borderStyle} ${r?"var(--w6w-accent)":N.borderColor}`,opacity:r?1:N.opacity,background:"var(--w6w-panel)",color:"var(--w6w-text)",borderRadius:4,padding:"8px 12px",minWidth:180,fontSize:13,display:"flex",alignItems:"center",gap:10},children:[S.in>0&&e.jsx(me,{type:"target",position:R.Position.Left,multiple:S.in>1}),e.jsx(n.AppIcon,{src:u==null?void 0:u.iconSvg,srcDark:u==null?void 0:u.iconSvgDark,brandColor:u==null?void 0:u.brandColor,name:f,size:28}),e.jsxs("div",{style:{minWidth:0},children:[e.jsx("div",{style:{fontWeight:600},children:f}),e.jsx("div",{className:"w6w-muted w6w-small",style:{marginTop:2},children:e.jsx("code",{children:a.uses.action||"—"})})]}),S.out>0&&e.jsxs(e.Fragment,{children:[e.jsx(me,{type:"source",position:R.Position.Right,multiple:S.out>1}),e.jsx(me,{type:"source",position:R.Position.Bottom,multiple:!1,id:n.ERROR_SOURCE_HANDLE,variant:"error"})]})]}),v,e.jsxs("div",{className:"w6w-muted",style:{marginTop:3,fontSize:10,opacity:.75,paddingLeft:2},children:[a.id,u!=null&&u.version?` - v${u.version}`:""]}),a.notes&&e.jsx("div",{className:"w6w-muted w6w-node-notes",title:a.notes,children:a.notes})]})}function qt({id:t,data:s,selected:r}){const a=s.step,d=n.internalNodeLabel(a.uses.app,a.uses.action),u=n.internalNodeIcon(a.uses.app,a.uses.action),f=n.nodePortsForStep(a,i.useContext(We)),S=n.isTriggerApp(a.uses.app),N=ut(s.stepStatus??"no-run",s.runStatus),v=e.jsx(wt,{step:a,count:i.useContext(Me).get(t)??0});return e.jsxs("div",{children:[e.jsx(ft,{id:t,runnable:!n.isControlApp(a.uses.app)}),e.jsxs("div",{"data-run-status":s.stepStatus??"no-run",style:{position:"relative",border:`${N.borderWidth}px ${N.borderStyle} ${r?"var(--w6w-accent)":N.borderColor}`,opacity:r?1:N.opacity,background:"var(--w6w-panel-2)",color:"var(--w6w-text)",borderRadius:4,padding:"6px 14px 6px 8px",minWidth:140,fontSize:13,display:"flex",alignItems:"center",gap:10},children:[f.in>0&&e.jsx(me,{type:"target",position:R.Position.Left,multiple:f.in>1}),u&&e.jsx(n.InternalIcon,{icon:u}),e.jsxs("div",{style:{minWidth:0,textAlign:"left"},children:[e.jsx("div",{style:{fontWeight:600},children:d}),e.jsx("div",{className:"w6w-muted w6w-small",style:{marginTop:2},children:e.jsx("code",{children:a.uses.action||"—"})})]}),f.out>0&&e.jsxs(e.Fragment,{children:[e.jsx(me,{type:"source",position:R.Position.Right,multiple:f.out>1}),!S&&e.jsx(me,{type:"source",position:R.Position.Bottom,multiple:!1,id:n.ERROR_SOURCE_HANDLE,variant:"error"})]})]}),v,e.jsx("div",{className:"w6w-muted",style:{marginTop:3,fontSize:10,opacity:.75,paddingLeft:2},children:a.id}),a.notes&&e.jsx("div",{className:"w6w-muted w6w-node-notes",title:a.notes,children:a.notes})]})}function zt({workflowId:t,step:s,upstreamSteps:r,onChange:a,onClose:d,readOnly:u,initialView:f="props",fanOutCount:S=0,onTestRun:N}){var Ce;const v=n.useW6WApi(),m=i.useContext(Ve),[l,x]=i.useState(s),[y,T]=i.useState("configure"),[E,D]=i.useState(f==="json"?"code":f==="settings"?"config":"props"),[p,I]=i.useState("props"),[re,Z]=i.useState(()=>n.stepToJson(s)),[M,b]=i.useState(()=>n.paramsToJson(s)),[A,ae]=i.useState("{}"),U=i.useRef(null),[q,k]=i.useState(!1),[$,V]=i.useState(!1),[Q,O]=i.useState(l.id),[ee,pe]=i.useState(null),[te,se]=i.useState(null),[he,ie]=i.useState(null),[ve,_]=i.useState(null),z=n.isInternalApp(l.uses.app);i.useEffect(()=>{if(z){se(n.internalNodeParams(l.uses.app,l.uses.action)),ie(null);return}if(!l.uses.app){ie(null),se([]);return}let h=!1;return se(null),v.getAppActions(l.uses.app).then(B=>{var K;h||(ie(B),se(l.uses.action?((K=B.find(ue=>ue.key===l.uses.action))==null?void 0:K.params)??[]:[]))}).catch(()=>!h&&se([])),()=>{h=!0}},[v,l.uses.app,l.uses.action,z]);const Se=i.useCallback(()=>{z||!l.uses.app||v.listConnectionsForApp(l.uses.app).then(h=>_(h)).catch(()=>_([]))},[v,l.uses.app,z]);i.useEffect(()=>{if(z||!l.uses.app)return;let h=!1;return v.listConnectionsForApp(l.uses.app).then(B=>!h&&_(B)).catch(()=>!h&&_([])),()=>{h=!0}},[v,l.uses.app,z]);const H=i.useCallback(h=>{x(h),a(h)},[a]),Pe=h=>{h==="code"?Z(n.stepToJson(l)):h==="params-code"&&b(n.paramsToJson(l)),D(h)},F=()=>{const h=Q.trim(),B=h&&h!==l.id?n.stepIdError(h):null;if(B){pe(B);return}h&&h!==l.id&&H({...l,id:h}),pe(null),V(!1)},oe=!!l.uses.app&&!!l.uses.action&&!n.isControlApp(l.uses.app),ne=n.isTriggerApp(l.uses.app),Ae=y==="test"&&oe&&!ne,fe=n.useSeedSources(t,r,oe&&!ne),Ne=n.startStateFromSeeds(fe);i.useEffect(()=>{if(!oe||ne)return;let h=!1;return v.listStepTests(t,l.id).then(B=>{if(h)return;const K=B.length?B[B.length-1]:null;if(!(K!=null&&K.input)||Object.keys(K.input).length===0)return;const ue=JSON.stringify(K.input,null,2);ae(je=>je.trim()==="{}"?ue:je)}).catch(()=>{}),()=>{h=!0}},[v,t,l.id,oe,ne]);const ge=Oe(A),xe={...l.with??{},...ge??{}},be=ge??{},le=!!te&&n.requiredParamsFilled(te,xe),W=m.get(l.uses.app),ce=z?n.internalNodeIcon(l.uses.app,l.uses.action):null,Te=z?ce?e.jsx(n.InternalIcon,{icon:ce}):null:e.jsx(n.AppIcon,{src:W==null?void 0:W.iconSvg,srcDark:W==null?void 0:W.iconSvgDark,brandColor:W==null?void 0:W.brandColor,name:W==null?void 0:W.displayName});return e.jsx(n.Modal,{ariaLabel:"Edit step",titleIcon:Te,title:e.jsxs("span",{className:"w6w-step-rename",children:[$&&!u?e.jsx("input",{autoFocus:!0,value:Q,onChange:h=>{O(h.target.value),pe(null)},onBlur:F,onKeyDown:h=>{h.key==="Enter"&&F(),h.key==="Escape"&&(O(l.id),pe(null),V(!1))}}):e.jsxs(e.Fragment,{children:[e.jsx("code",{children:l.id}),!u&&e.jsx("button",{type:"button",className:"w6w-icon-btn w6w-btn-sm",title:"Rename step","aria-label":"Rename step",onClick:()=>{O(l.id),V(!0)},children:e.jsx(de.Icon,{name:"edit",size:15})})]}),ee&&e.jsx("span",{className:"w6w-hint",role:"alert",style:{color:"var(--w6w-danger)"},children:ee})]}),onClose:d,size:"wide",children:e.jsxs("div",{className:"w6w-stepconfig",children:[e.jsxs("div",{className:"w6w-tabsbar",children:[e.jsx("div",{className:"w6w-subtabs",children:["setup","configure","test"].map(h=>e.jsx("button",{type:"button",className:`w6w-subtab${y===h?" active":""}`,onClick:()=>T(h),children:h==="setup"?"Setup":h==="configure"?"Configure":"Test"},h))}),Ae?e.jsx(n.ConfigViewToggle,{view:p,views:["props","code"],onChange:h=>I(h)}):e.jsx(n.ConfigViewToggle,{view:E,onChange:Pe,disabled:y!=="configure"})]}),e.jsxs("div",{className:"w6w-stepconfig-body",children:[y==="setup"&&e.jsx(Yt,{step:l,app:W,actions:he,conns:ve,isInternal:z,readOnly:u,onChangeAction:h=>H({...l,uses:{...l.uses,action:h},with:{}}),onChangeConnection:h=>H({...l,uses:{...l.uses,connection:h}}),onConnectionCreated:Se,onChangeApp:h=>H(h===l.uses.app?l:{...l,uses:{app:h,action:"",connection:void 0},with:{}})}),y==="configure"&&e.jsxs(e.Fragment,{children:[l.uses.app===n.WEBHOOK_APP&&v.listSubscriptionsForWorkflow&&v.createSubscription&&e.jsx(Xt,{workflowId:t,step:l,readOnly:u}),te===null?e.jsx("p",{className:"w6w-muted w6w-small",children:"Loading parameters…"}):E==="props"?l.uses.action==="wait"&&n.isControlApp(l.uses.app)?e.jsx(n.WaitEditor,{values:l.with??{},readOnly:u,onChange:h=>H({...l,with:h})}):e.jsx(n.ParamsForm,{params:te,values:l.with??{},readOnly:u,onChange:h=>H({...l,with:h})}):E==="code"?e.jsx(n.JsonEditor,{value:re,onChange:()=>{},readOnly:!0,minHeight:"260px",height:"100%","aria-label":`Step ${l.id} JSON`,copyable:!0}):E==="params-code"?e.jsx(n.JsonEditor,{value:M,onChange:b,readOnly:u,minHeight:"260px",height:"100%","aria-label":`Step ${l.id} params JSON`,copyable:!0,onValidChange:h=>h&&typeof h=="object"&&!Array.isArray(h)&&H({...l,with:h})}):e.jsxs("div",{className:"w6w-stack",children:[e.jsx(n.NodeConfigForm,{config:{retry:l.retry,onError:l.onError,notes:l.notes},onChange:h=>H({...l,...h}),readOnly:u,failureHandling:!ne,retryControls:!n.isControlApp(l.uses.app)&&l.uses.app!==n.CALL_APP}),Kt,e.jsx(Gt,{step:l,count:S,readOnly:u,onChange:H})]})]}),y==="test"&&e.jsx("div",{className:"w6w-stack",children:oe?ne?e.jsx(n.TriggerFillForm,{app:l.uses.app,action:l.uses.action,fields:(Ce=l.with)==null?void 0:Ce.fields,persist:{workflowId:t,stepId:l.id,input:be}}):e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"w6w-muted w6w-small",children:["Tests ",e.jsx("code",{children:l.uses.action})," with the configuration saved on this step — only the incoming state changes per run."]}),e.jsx(pt,{text:A,onChange:ae,seeds:fe,readOnly:u}),te===null?e.jsx("p",{className:"w6w-muted w6w-small",children:"Loading parameters…"}):e.jsx(jt,{params:te,values:xe,testStartState:Ne,view:p}),e.jsx(n.StepTestRun,{ref:U,app:l.uses.app,action:l.uses.action,connectionId:l.uses.connection??void 0,values:xe,state:Ne,canRun:le,hideRunButton:!0,persist:{workflowId:t,stepId:l.id,input:be},onBusyChange:k})]}):e.jsx("p",{className:"w6w-muted w6w-small",children:"Flow-control nodes can't be tested on their own."})})]}),e.jsx("div",{className:"w6w-modal-actions w6w-stepconfig-footer",children:y!=="test"?e.jsx("button",{type:"button",className:"w6w-btn",onClick:()=>T(y==="setup"?"configure":"test"),children:"Next →"}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"w6w-btn w6w-btn-ghost",onClick:d,children:"Done"}),oe&&!ne&&e.jsx("button",{type:"button",className:"w6w-btn",disabled:u||!le||q,onClick:()=>{var h;N==null||N(),(h=U.current)==null||h.run()},children:q?"Testing…":"Test"})]})})]})})}const Kt=!1;function Gt({step:t,count:s,readOnly:r,onChange:a}){const d=s>=2,u=t.fanOut==="parallel"?"parallel":"sequential";return e.jsxs("label",{className:"w6w-field",children:[e.jsx("span",{children:"Run next steps"}),e.jsxs("select",{"aria-label":"Run next steps",value:u,disabled:r||!d,onChange:f=>a(Lt(t,f.target.value)),children:[e.jsx("option",{value:"sequential",children:"In sequence"}),e.jsx("option",{value:"parallel",children:"In parallel"})]}),!d&&e.jsx("span",{className:"w6w-muted w6w-small",children:"Connect two or more steps after this one to choose how they run."})]})}function Xt({workflowId:t,step:s,readOnly:r}){const a=n.useW6WApi(),[d,u]=i.useState(void 0),[f,S]=i.useState(null),[N,v]=i.useState(!1);i.useEffect(()=>{const l=a.listSubscriptionsForWorkflow;if(!l)return;let x=!1;return l(t).then(y=>{x||u(y.find(T=>T.appId===n.WEBHOOK_APP)??null)}).catch(y=>!x&&S(y.message)),()=>{x=!0}},[a,t]);const m=()=>{const l=a.createSubscription;l&&(S(null),v(!0),l(n.WEBHOOK_APP,s.uses.action,{workflowId:t,connectionId:null,params:s.with??{}}).then(x=>{v(!1),u(x)}).catch(x=>{v(!1),S(x instanceof Error?x.message:String(x))}))};return e.jsxs("div",{className:"w6w-stack",children:[e.jsxs("p",{className:"w6w-muted w6w-small",children:[e.jsx("strong",{children:"Webhook URL"})," — the address a third party posts to."]}),f&&e.jsx("div",{className:"w6w-result w6w-error",children:f}),d!=null&&d.webhookUrl?e.jsx(de.Copyable,{value:d.webhookUrl,readOnly:!0,children:e.jsx("input",{type:"text",readOnly:!0,value:d.webhookUrl,"aria-label":"Webhook URL"})}):d===void 0?e.jsx("p",{className:"w6w-muted w6w-small",children:"Loading…"}):!r&&e.jsx("button",{type:"button",className:"w6w-btn",disabled:N,onClick:m,children:N?"Creating…":"Create webhook URL"})]})}function at({anchorRef:t,onClose:s,children:r}){const a=i.useRef(null),[d,u]=i.useState(null),[f,S]=i.useState(null);return i.useEffect(()=>{const N=t.current;if(!N)return;const v=N.getBoundingClientRect();u({top:v.bottom+6,left:v.left,width:v.width}),S(N.closest("dialog")??document.body)},[t]),i.useEffect(()=>{function N(m){var x,y;const l=m.target;(x=a.current)!=null&&x.contains(l)||(y=t.current)!=null&&y.contains(l)||s()}function v(m){m.key==="Escape"&&s()}return document.addEventListener("mousedown",N),document.addEventListener("keydown",v),()=>{document.removeEventListener("mousedown",N),document.removeEventListener("keydown",v)}},[s,t]),!d||!f?null:xt.createPortal(e.jsx("div",{ref:a,className:"w6w-flyout",style:{top:d.top,left:d.left,width:d.width},children:r}),f)}function Yt({step:t,app:s,actions:r,conns:a,isInternal:d,readOnly:u,onChangeAction:f,onChangeConnection:S,onChangeApp:N,onConnectionCreated:v}){var D;const[m,l]=i.useState(null),[x,y]=i.useState(!1),T=i.useRef(null),E=t.uses.connection?((D=(a??[]).find(p=>p.id===t.uses.connection))==null?void 0:D.displayName)??t.uses.connection:"No connection";return e.jsxs("div",{className:"w6w-stack",children:[e.jsxs("div",{className:"w6w-field",children:[e.jsx("span",{children:"App"}),e.jsxs("div",{className:"w6w-app-conn-row",ref:T,children:[e.jsxs("button",{type:"button",className:"w6w-app-conn-btn","aria-label":"App","aria-expanded":m==="app",disabled:u,onClick:()=>l(p=>p==="app"?null:"app"),children:[!d&&s&&e.jsx(n.AppIcon,{src:s.iconSvg,srcDark:s.iconSvgDark,brandColor:s.brandColor,name:s.displayName,size:20}),e.jsx("span",{className:"w6w-conn-label-name",children:d?t.uses.app:(s==null?void 0:s.displayName)??t.uses.app})]}),!d&&e.jsx("button",{type:"button",className:"w6w-app-conn-btn","aria-label":"Connection","aria-expanded":m==="conn",disabled:u,onClick:()=>l(p=>p==="conn"?null:"conn"),children:e.jsx("span",{className:"w6w-conn-label-name",children:E})})]}),m==="app"&&e.jsx(at,{anchorRef:T,onClose:()=>l(null),children:e.jsx(n.AppPicker,{onSelectApp:p=>{const I=p.id===t.uses.app;N(p.id),l(I?"conn":null)}})}),m==="conn"&&e.jsx(at,{anchorRef:T,onClose:()=>l(null),children:e.jsxs("div",{className:"w6w-stack",children:[e.jsx("div",{className:"w6w-stepbuilder-list",children:(a??[]).map(p=>e.jsx("button",{type:"button",className:"w6w-stepbuilder-item",onClick:()=>{S(p.id),l(null)},children:e.jsxs("span",{className:"w6w-stepbuilder-item-main",children:[e.jsx("strong",{children:p.displayName||p.id}),p.state&&e.jsx("span",{className:"w6w-muted w6w-small",children:p.state})]})},p.id))}),e.jsx("button",{type:"button",className:"w6w-btn",disabled:u,onClick:()=>{y(!0),l(null)},children:"+ New connection"})]})})]}),!d&&x&&e.jsx(n.AddConnectionModal,{initialAppId:t.uses.app,onClose:()=>y(!1),onCreated:({connectionId:p})=>{y(!1),S(p),v(),l(null)}}),d?e.jsxs("div",{className:"w6w-field",children:[e.jsx("span",{children:"Action"}),e.jsx("div",{className:"w6w-muted w6w-small",children:e.jsx("code",{children:t.uses.action})})]}):e.jsxs("label",{className:"w6w-field",children:[e.jsx("span",{children:"Action"}),e.jsx(n.Combobox,{value:t.uses.action,disabled:u||r===null,onChange:f,options:r===null?[{value:t.uses.action,label:t.uses.action}]:r.map(p=>({value:p.key,label:p.title??p.key}))})]})]})}exports.CALL_APP=n.CALL_APP;exports.CONTROL_APP=n.CONTROL_APP;exports.DATA_APP=n.DATA_APP;exports.ExpressionOptionsProvider=n.ExpressionOptionsProvider;exports.INTERNAL_NODES=n.INTERNAL_NODES;exports.SCHEDULER_APP=n.SCHEDULER_APP;exports.SCRIPT_APP=n.SCRIPT_APP;exports.TRIGGER_APP=n.TRIGGER_APP;exports.WEBHOOK_APP=n.WEBHOOK_APP;exports.asFieldDefs=n.asFieldDefs;exports.coerceDefault=n.coerceDefault;exports.fieldWidget=n.fieldWidget;exports.fieldsToParams=n.fieldsToParams;exports.flowToWorkflow=n.flowToWorkflow;exports.internalNodeDefaults=n.internalNodeDefaults;exports.internalNodeIcon=n.internalNodeIcon;exports.internalNodeLabel=n.internalNodeLabel;exports.internalNodeParams=n.internalNodeParams;exports.isControlApp=n.isControlApp;exports.isInternalApp=n.isInternalApp;exports.isTriggerApp=n.isTriggerApp;exports.seedValues=n.seedValues;exports.workflowToFlow=n.workflowToFlow;exports.WorkflowFlowEditor=Jt;
|
|
3
3
|
//# sourceMappingURL=flow.cjs.map
|