@oomol-lab/open-flow 0.1.0-beta.59 → 0.1.0-beta.60

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.
@@ -16,7 +16,8 @@ export type { WorkbenchActor } from './workbench-contract.js';
16
16
  export type { FlowCatalogEvent, FlowChangeEvent, WorkbenchHost, WorkbenchLanguage, WorkbenchLocation, WorkbenchNavigationOptions, WorkbenchNotification, WorkbenchPreferences, WorkbenchTheme, WorkbenchView, } from './workbench-contract.js';
17
17
  export { isUiLanguage as isWorkbenchLanguage, resolveUiLanguage as resolveWorkbenchLanguage, uiLanguageNames as workbenchLanguageNames, uiLanguages as workbenchLanguages, } from '../common/localization.js';
18
18
  export interface OpenFlowWorkbenchProps {
19
- readonly catalogWidth?: 'default' | 'full' | undefined;
19
+ /** Embedded catalogs fill a host-owned page without adding width limits or page padding. */
20
+ readonly catalogWidth?: 'default' | 'full' | 'embedded' | undefined;
20
21
  readonly createFlow?: ((name: string) => Promise<string>) | undefined;
21
22
  readonly createFlowDisabled?: boolean | undefined;
22
23
  readonly createFlowField?: {
@@ -46,6 +47,8 @@ export interface OpenFlowWorkbenchProps {
46
47
  } | undefined;
47
48
  readonly connectionHref?: ConnectionHref | undefined;
48
49
  readonly flowBadges?: Readonly<Record<string, string>> | undefined;
50
+ /** Reports the active Flow name, including renames; clears it on exit or unmount. Hosts own document titles. */
51
+ readonly onFlowNameChange?: ((name: string | undefined) => void) | undefined;
49
52
  readonly host: WorkbenchHost;
50
53
  readonly hrefFor: (location: WorkbenchLocation) => string;
51
54
  readonly language: WorkbenchLanguage;
@@ -1,7 +1,7 @@
1
- import { $ as RunStore, $t as EventSourcesPage, An as providerIconAppearance, At as followWorkbenchLink, B as CacheResource, Bn as invalidResponse, Cn as sampleErrorOutputs, Ct as setCodeActions, Dt as updateTriggerConfig, Et as setTriggerConnection, F as feishuResourceKind, Gn as controlErrorCode, Gt as InputGroupAddon, H as resourceData, Hn as record, I as supportsFeishuChatFilter, J as providerIcon, Jt as EmptyContent, Kt as InputGroupInput, L as combineSources, Lt as PopoverTitle, M as addNodeIntent, Mt as Popover, N as deriveAddNodeOptions, Nt as PopoverContent, On as connection, Ot as updateTriggerSchedule, Qt as EmptyTitle, Rt as PopoverTrigger, St as resetInputValues, Tn as isJsonObject, Tt as setInputSources, U as resourceValue, Un as string, Vn as jsonValue, W as designerGraph, Wn as ApiError, Wt as InputGroup, Xt as EmptyHeader, Yt as EmptyDescription, Zt as EmptyMedia, _ as updateValue, _n as randomId, _t as setComment, a as nameCreatedNodes, at as deriveInspectorDiagnostics, bn as decodeTriggerCatalog, bt as setNodePositions, c as updateCondition, d as updateNodeName, dt as connectionCatalog, f as updateNodeSettings, ft as canvasPresentationChange, g as updateTaskPorts, gn as WorkbenchClient, gt as restoreCanvasPresentation, h as updateTaskAdditionalInputs, hn as errorNotice, ht as removeComments, i as deleteSelection, it as Latest, jt as Switch, kn as connectorActionMetadata, kt as IdTooltip, l as updateNodeDescription, m as updateTask, mt as flowPresentation, nn as createI18n, nt as revisionView, o as setInputValue, ot as diagnosticItems, p as updateResolution, pt as commentIds, qn as IconThemeContext, qt as Empty, r as applyFlowChanges, rt as flowResourceReferences, s as setInputVariable, t as addNode, u as updateNodeIcon, ut as actionWithConnections, v as updateWebhook, vn as allConnectorConnectionsQuery, vt as setFlowViewport, wn as triggerOutputDefinitions, wt as setConnectorConnection, xt as repairNodeNames, yt as setNodeContentHidden, z as scopedValue, zn as inputValue } from "./flowChanges-DL0Njlg6.js";
1
+ import { $ as RunStore, $n as connection, $t as DropdownMenuContent, At as followWorkbenchLink, B as CacheResource, Bn as errorNotice, Cn as Badge, Ct as setCodeActions, Dn as createI18n, Dt as updateTriggerConfig, Et as setTriggerConnection, F as feishuResourceKind, Gn as decodeTriggerCatalog, Gt as Empty, H as resourceData, Hn as randomId, Ht as InputGroup, I as supportsFeishuChatFilter, It as PopoverTitle, J as providerIcon, Jn as sampleErrorOutputs, Jt as EmptyHeader, Kt as EmptyContent, L as combineSources, M as addNodeIntent, Mt as PopoverContent, N as deriveAddNodeOptions, Ot as updateTriggerSchedule, St as resetInputValues, Tt as setInputSources, U as resourceValue, Un as allConnectorConnectionsQuery, Ut as InputGroupAddon, Vn as WorkbenchClient, W as designerGraph, Wt as InputGroupInput, Xn as isJsonObject, Xt as EmptyTitle, Yn as triggerOutputDefinitions, Yt as EmptyMedia, Zt as DropdownMenu, _ as updateValue, _t as setComment, a as nameCreatedNodes, an as DropdownMenuSeparator, at as deriveInspectorDiagnostics, bt as setNodePositions, c as updateCondition, d as updateNodeName, dr as invalidResponse, dt as connectionCatalog, er as connectorActionMetadata, f as updateNodeSettings, fr as jsonValue, ft as canvasPresentationChange, g as updateTaskPorts, gr as controlErrorCode, gt as restoreCanvasPresentation, h as updateTaskAdditionalInputs, hr as ApiError, ht as removeComments, i as deleteSelection, it as Latest, jt as Popover, kt as IdTooltip, l as updateNodeDescription, ln as DropdownMenuTrigger, m as updateTask, mr as string, mt as flowPresentation, nt as revisionView, o as setInputValue, ot as diagnosticItems, p as updateResolution, pr as record, pt as commentIds, qt as EmptyDescription, r as applyFlowChanges, rt as flowResourceReferences, s as setInputVariable, t as addNode, tn as DropdownMenuItem, tr as providerIconAppearance, u as updateNodeIcon, ur as inputValue, ut as actionWithConnections, v as updateWebhook, vt as setFlowViewport, wn as EventSourcesPage, wt as setConnectorConnection, xt as repairNodeNames, yr as IconThemeContext, yt as setNodeContentHidden, z as scopedValue } from "./flowChanges-Cbl6Izr-.js";
2
2
  import { a as derive, i as compute, l as val } from "./dist-bO8nvHFH.js";
3
3
  import { a as toPlainObject, c as useLang, l as useTranslate, o as I18nProvider, u as useVal } from "./dist-BFmpkX4P.js";
4
- import { E as FieldLabel, H as applyFlowChanges$1, J as resourceNameIssue, Q as nodeInputMappings, S as Field, T as FieldGroup, V as FlowChangeError, Z as mapConditionSources, a as DialogDescription, at as dequal$1, bi as cn, c as DialogTitle, d as TooltipContent, i as DialogContent, n as Dialog, o as DialogFooter, or as Input, p as TooltipTrigger, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, vi as Button, w as FieldError, x as Spinner } from "./icons-6oQ8Q9Wm.js";
4
+ import { E as FieldLabel, H as applyFlowChanges$1, J as resourceNameIssue, Q as nodeInputMappings, S as Field, T as FieldGroup, V as FlowChangeError, Z as mapConditionSources, a as DialogDescription, at as dequal$1, bi as cn, c as DialogTitle, d as TooltipContent, i as DialogContent, n as Dialog, o as DialogFooter, or as Input, p as TooltipTrigger, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, vi as Button, w as FieldError, x as Spinner } from "./icons-D70mz3qW.js";
5
5
  import { c as isUiLanguage, d as uiLanguages, l as resolveUiLanguage, u as uiLanguageNames } from "./value-DL_poNiC.js";
6
6
  import { Suspense, lazy, useEffect, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -106,13 +106,13 @@ var NavigationStore = class {
106
106
  if (change == this.#change) this.#syncing = false;
107
107
  }
108
108
  }
109
- async selectFlow(flow) {
109
+ async selectFlow(flow, view = "design") {
110
110
  const change = ++this.#change;
111
111
  this.#syncing = true;
112
112
  this.#store.runRequests.dismissInputs();
113
113
  await this.#store.selectFlow(flow.flowId);
114
114
  if (change == this.#change) {
115
- this.#write("design", false);
115
+ this.#write(view, false, {});
116
116
  this.#syncing = false;
117
117
  }
118
118
  }
@@ -184,11 +184,10 @@ function Skeleton({ className, ...props }) {
184
184
  }
185
185
  //#endregion
186
186
  //#region src/workbench/browser/runtime/shell/resourceBrowser.tsx
187
- var CreateResourceDialog = lazy(() => import("./createResourceDialog-C23SBjYd.js"));
187
+ var CreateResourceDialog = lazy(() => import("./createResourceDialog-B7ThMSeA.js"));
188
188
  var flowIdTooltipAlignOffset = 44;
189
189
  var renamePopoverAlignOffset = -12;
190
190
  var renamePopoverVerticalShift = 8;
191
- var rowControlSelector = "a, button, input, select, textarea, [data-slot=\"tooltip-trigger\"]";
192
191
  function compactFlowId(flowId) {
193
192
  return flowId.length <= 20 ? flowId : `${flowId.slice(0, 10)}…${flowId.slice(-6)}`;
194
193
  }
@@ -203,9 +202,6 @@ function formatUpdatedAt(updatedAt, locale) {
203
202
  year: date.getFullYear() == current.getFullYear() ? void 0 : "numeric"
204
203
  });
205
204
  }
206
- function clickedRowControl(event) {
207
- return event.target instanceof Element && event.target.closest(rowControlSelector) != null;
208
- }
209
205
  function FlowDeletionImpact({ listeners, failed, onRetry }) {
210
206
  const t = useTranslate();
211
207
  if (failed) return /* @__PURE__ */ jsxs("div", {
@@ -256,10 +252,10 @@ function FlowDeletionImpact({ listeners, failed, onRetry }) {
256
252
  ]
257
253
  });
258
254
  }
259
- function FlowItem({ badge, busy, flow, href, onSelect, store }) {
255
+ function FlowItem({ showTeam, badge, busy, flow, href, onSelect, store }) {
260
256
  const [root, setRoot] = useState(null);
261
257
  const renameAnchor = useRef(null);
262
- const deleteButton = useRef(null);
258
+ const actionsButton = useRef(null);
263
259
  const nameInput = useRef(null);
264
260
  const cancelDelete = useRef(null);
265
261
  const locale = useLang();
@@ -287,6 +283,7 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
287
283
  listenersRetry
288
284
  ]);
289
285
  const [pending, setPending] = useState();
286
+ const hasTeam = showTeam && Boolean(badge?.trim());
290
287
  const changed = flow.live != null && flow.live.revisionId != flow.draftRevisionId;
291
288
  const publicationStatus = flow.status == "retiring" ? "resource.retiring" : flow.live == null ? "resource.notPublished" : changed ? "resource.unpublishedChanges" : "resource.isPublished";
292
289
  const publicationTone = flow.status == "retiring" ? "danger" : flow.live == null ? "neutral" : changed ? "running" : "success";
@@ -308,16 +305,13 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
308
305
  async function remove() {
309
306
  if (await store.workspace.deleteFlow(flow.flowId)) setMode("idle");
310
307
  }
311
- function openFromRow(event) {
312
- if (!clickedRowControl(event)) onSelect(flow);
313
- }
314
308
  return /* @__PURE__ */ jsxs("div", {
315
309
  className: "resource-item-row",
316
310
  ref: setRoot,
317
311
  children: [
318
312
  /* @__PURE__ */ jsxs("div", {
319
313
  className: "resource-list-row flow-columns",
320
- onClick: openFromRow,
314
+ "data-has-team": hasTeam,
321
315
  children: [
322
316
  /* @__PURE__ */ jsxs("span", {
323
317
  className: "resource-primary-cell",
@@ -325,46 +319,41 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
325
319
  "aria-hidden": "true",
326
320
  className: "resource-flow-icon",
327
321
  children: /* @__PURE__ */ jsx("i", { className: "i-lucide-light:workflow" })
328
- }), /* @__PURE__ */ jsxs("span", {
322
+ }), /* @__PURE__ */ jsx("span", {
329
323
  className: "resource-primary-copy",
330
- children: [/* @__PURE__ */ jsxs("span", {
324
+ children: /* @__PURE__ */ jsxs("span", {
331
325
  className: "resource-primary-heading",
332
- ref: renameAnchor,
333
- children: [/* @__PURE__ */ jsx(Button, {
334
- "aria-disabled": flow.status == "retiring",
335
- className: "resource-primary-title",
336
- nativeButton: false,
337
- onClick: (event) => {
338
- if (flow.status == "retiring") {
339
- event.preventDefault();
340
- return;
341
- }
342
- followWorkbenchLink(event, () => onSelect(flow));
343
- },
344
- render: /* @__PURE__ */ jsx("a", { href: flow.status == "retiring" ? void 0 : href }),
345
- tabIndex: flow.status == "retiring" ? -1 : void 0,
346
- title: flow.name,
347
- variant: "link",
326
+ children: [/* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
327
+ render: /* @__PURE__ */ jsx("a", {
328
+ "aria-disabled": flow.status == "retiring",
329
+ className: "resource-primary-title",
330
+ onClick: (event) => {
331
+ if (flow.status == "retiring") {
332
+ event.preventDefault();
333
+ return;
334
+ }
335
+ followWorkbenchLink(event, () => onSelect(flow));
336
+ },
337
+ href: flow.status == "retiring" ? void 0 : href,
338
+ tabIndex: flow.status == "retiring" ? -1 : void 0
339
+ }),
340
+ children: /* @__PURE__ */ jsx("span", {
341
+ className: "resource-primary-name",
342
+ ref: renameAnchor,
343
+ children: flow.name
344
+ })
345
+ }), /* @__PURE__ */ jsx(TooltipContent, {
346
+ container: root,
347
+ collisionBoundary: [],
348
+ positionMethod: "fixed",
348
349
  children: flow.name
349
- }), flow.status == "active" && /* @__PURE__ */ jsxs(Popover, {
350
+ })] }), flow.status == "active" && /* @__PURE__ */ jsx(Popover, {
350
351
  onOpenChange: (open) => {
351
352
  setMode(open ? "rename" : "idle");
352
353
  if (open) setName(flow.name);
353
354
  },
354
355
  open: mode == "rename",
355
- children: [/* @__PURE__ */ jsx(PopoverTrigger, {
356
- render: /* @__PURE__ */ jsx(Button, {
357
- "aria-label": t("sidebar.renameFlow", { name: flow.name }),
358
- className: "resource-rename-trigger",
359
- size: "icon-xs",
360
- type: "button",
361
- variant: "ghost"
362
- }),
363
- children: /* @__PURE__ */ jsx("i", {
364
- "aria-hidden": "true",
365
- className: "i-lucide-light:pencil"
366
- })
367
- }), /* @__PURE__ */ jsxs(PopoverContent, {
356
+ children: /* @__PURE__ */ jsxs(PopoverContent, {
368
357
  align: "start",
369
358
  alignOffset: renamePopoverAlignOffset,
370
359
  anchor: renameAnchor,
@@ -372,6 +361,7 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
372
361
  collisionBoundary: [],
373
362
  container: root,
374
363
  initialFocus: nameInput,
364
+ finalFocus: actionsButton,
375
365
  positionMethod: "fixed",
376
366
  side: "top",
377
367
  sideOffset: ({ anchor, positioner }) => -(anchor.height + positioner.height) / 2 - renamePopoverVerticalShift,
@@ -423,13 +413,9 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
423
413
  })
424
414
  ]
425
415
  })]
426
- })]
416
+ })
427
417
  })]
428
- }), badge != null && /* @__PURE__ */ jsx("span", {
429
- className: "resource-team-label",
430
- title: badge,
431
- children: badge
432
- })]
418
+ })
433
419
  })]
434
420
  }),
435
421
  /* @__PURE__ */ jsx("span", {
@@ -446,6 +432,11 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
446
432
  alignOffset: flowIdTooltipAlignOffset
447
433
  })
448
434
  }),
435
+ showTeam && /* @__PURE__ */ jsx("span", {
436
+ className: "resource-team-cell",
437
+ title: badge,
438
+ children: hasTeam ? badge : "—"
439
+ }),
449
440
  /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
450
441
  render: /* @__PURE__ */ jsx("time", {
451
442
  className: "resource-updated-at",
@@ -462,70 +453,112 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
462
453
  sideOffset: 6,
463
454
  children: new Date(flow.updatedAt).toLocaleString(locale)
464
455
  })] }),
456
+ /* @__PURE__ */ jsx(Badge, {
457
+ variant: "secondary",
458
+ className: cn("resource-publication-status h-auto px-2.5 py-0.75", publicationTone),
459
+ children: t(publicationStatus)
460
+ }),
465
461
  /* @__PURE__ */ jsxs("span", {
466
462
  className: "resource-status",
467
- children: [
468
- /* @__PURE__ */ jsx("span", {
469
- "aria-hidden": "true",
470
- className: cn("status-dot", publicationTone)
471
- }),
472
- /* @__PURE__ */ jsx("span", { children: t(publicationStatus) }),
473
- flow.live != null && /* @__PURE__ */ jsxs("span", {
474
- className: "resource-enabled-status",
475
- "aria-busy": pending == "enabled",
476
- children: [/* @__PURE__ */ jsx("span", { children: t(flow.live.enabled ? "resource.enabled" : "resource.disabled") }), /* @__PURE__ */ jsx(Switch, {
477
- "aria-label": t("resource.enableFlow", { name: flow.name }),
478
- checked: flow.live.enabled,
479
- disabled: flow.status != "active" || busy != null || pending != null,
480
- onCheckedChange: (enabled) => void update(enabled),
481
- size: "sm",
482
- title: t("resource.enabledHint")
483
- })]
484
- })
485
- ]
463
+ "aria-busy": pending == "enabled",
464
+ children: [/* @__PURE__ */ jsx("span", {
465
+ "aria-hidden": "true",
466
+ className: cn("status-dot", flow.live?.enabled ? "success" : "neutral")
467
+ }), /* @__PURE__ */ jsx("span", { children: t(flow.live == null ? "resource.runtimeUnpublished" : flow.live.enabled ? "resource.enabled" : "resource.disabled") })]
486
468
  })
487
469
  ]
488
470
  }),
489
- /* @__PURE__ */ jsxs("div", {
471
+ /* @__PURE__ */ jsx("div", {
490
472
  className: "resource-live-controls",
491
473
  "aria-busy": pending != null,
492
- onClick: openFromRow,
493
- children: [
494
- flow.status == "active" && /* @__PURE__ */ jsx(Button, {
495
- onClick: () => onSelect(flow),
496
- size: "sm",
497
- variant: "outline",
498
- children: t("resource.edit")
499
- }),
500
- /* @__PURE__ */ jsx(Button, {
501
- disabled: flow.status != "active" || busy != null || pending != null || flow.live != null && !changed,
502
- onClick: () => void update("publish"),
503
- size: "sm",
504
- variant: "outline",
505
- children: t(pending == "publish" ? "workspace.publishing" : flow.live == null ? "resource.publish" : "resource.publishUpdate")
506
- }),
507
- flow.status == "active" && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
508
- render: /* @__PURE__ */ jsx(Button, {
509
- "aria-label": t("sidebar.deleteFlow", { name: flow.name }),
510
- ref: deleteButton,
511
- disabled: busy != null || pending != null,
512
- onClick: () => setMode("delete"),
513
- size: "icon-sm",
514
- variant: "destructive"
474
+ children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
475
+ render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button, {
476
+ ref: actionsButton,
477
+ "aria-label": t("resource.actions"),
478
+ size: "icon-sm",
479
+ variant: "ghost"
480
+ }) }),
481
+ children: /* @__PURE__ */ jsx("i", {
482
+ "aria-hidden": "true",
483
+ className: "i-lucide-light:ellipsis"
484
+ })
485
+ }), /* @__PURE__ */ jsx(TooltipContent, {
486
+ container: root,
487
+ collisionBoundary: [],
488
+ positionMethod: "fixed",
489
+ children: t("resource.actions")
490
+ })] }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
491
+ align: "end",
492
+ collisionBoundary: [],
493
+ positionMethod: "fixed",
494
+ container: root,
495
+ className: "w-48",
496
+ finalFocus: mode == "idle" ? actionsButton : false,
497
+ children: [
498
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
499
+ disabled: flow.status != "active",
500
+ onClick: () => onSelect(flow),
501
+ children: [/* @__PURE__ */ jsx("i", {
502
+ "aria-hidden": "true",
503
+ className: "i-lucide-light:square-pen size-4 shrink-0"
504
+ }), t("resource.edit")]
515
505
  }),
516
- children: /* @__PURE__ */ jsx("i", {
517
- "aria-hidden": "true",
518
- className: "i-lucide-light:trash-2"
506
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
507
+ disabled: flow.status != "active" || busy != null || pending != null,
508
+ onClick: () => {
509
+ setName(flow.name);
510
+ setMode("rename");
511
+ },
512
+ children: [/* @__PURE__ */ jsx("i", {
513
+ "aria-hidden": "true",
514
+ className: "i-lucide-light:text-cursor-input size-4 shrink-0"
515
+ }), t("common.rename")]
516
+ }),
517
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
518
+ disabled: flow.status != "active" || busy != null || pending != null || flow.live != null && !changed,
519
+ onClick: () => void update("publish"),
520
+ children: [/* @__PURE__ */ jsx("i", {
521
+ "aria-hidden": "true",
522
+ className: "i-lucide-light:upload size-4 shrink-0"
523
+ }), t(pending == "publish" ? "workspace.publishing" : flow.live == null ? "resource.publish" : "resource.publishUpdate")]
524
+ }),
525
+ flow.live != null && /* @__PURE__ */ jsxs(DropdownMenuItem, {
526
+ disabled: flow.status != "active" || busy != null || pending != null,
527
+ onClick: () => void update(flow.live?.enabled != true),
528
+ children: [/* @__PURE__ */ jsx("i", {
529
+ "aria-hidden": "true",
530
+ className: cn("size-4 shrink-0", flow.live.enabled ? "i-lucide-light:square" : "i-lucide-light:play")
531
+ }), t(flow.live.enabled ? "resource.stop" : "resource.start")]
532
+ }),
533
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "mx-2 bg-border/50" }),
534
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
535
+ disabled: flow.status != "active",
536
+ onClick: () => onSelect(flow, "publications"),
537
+ children: [/* @__PURE__ */ jsx("i", {
538
+ "aria-hidden": "true",
539
+ className: "i-lucide-light:cloud-upload size-4 shrink-0"
540
+ }), t("workspace.publications")]
541
+ }),
542
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
543
+ disabled: flow.status != "active",
544
+ onClick: () => onSelect(flow, "runs"),
545
+ children: [/* @__PURE__ */ jsx("i", {
546
+ "aria-hidden": "true",
547
+ className: "i-lucide-light:history size-4 shrink-0"
548
+ }), t("workspace.runs")]
549
+ }),
550
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "mx-2 bg-border/50" }),
551
+ /* @__PURE__ */ jsxs(DropdownMenuItem, {
552
+ disabled: flow.status != "active" || busy != null || pending != null,
553
+ variant: "destructive",
554
+ onClick: () => setMode("delete"),
555
+ children: [/* @__PURE__ */ jsx("i", {
556
+ "aria-hidden": "true",
557
+ className: "i-lucide-light:trash-2 size-4 shrink-0"
558
+ }), t("common.delete")]
519
559
  })
520
- }), /* @__PURE__ */ jsx(TooltipContent, {
521
- align: "center",
522
- collisionBoundary: [],
523
- container: root,
524
- positionMethod: "fixed",
525
- side: "top",
526
- children: t("common.delete")
527
- })] })
528
- ]
560
+ ]
561
+ })] })
529
562
  }),
530
563
  /* @__PURE__ */ jsx(Dialog, {
531
564
  open: mode == "delete",
@@ -535,7 +568,7 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
535
568
  children: /* @__PURE__ */ jsxs(DialogContent, {
536
569
  container: root,
537
570
  initialFocus: cancelDelete,
538
- finalFocus: deleteButton,
571
+ finalFocus: actionsButton,
539
572
  showCloseButton: false,
540
573
  children: [
541
574
  /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: t("sidebar.deleteFlowConfirm", { name: flow.name }) }), /* @__PURE__ */ jsx(DialogDescription, { children: t("resource.deleteDescription") })] }),
@@ -562,24 +595,30 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
562
595
  ]
563
596
  });
564
597
  }
565
- function FlowSkeleton() {
598
+ function FlowSkeleton({ showTeam }) {
566
599
  return /* @__PURE__ */ jsxs("div", {
567
600
  "aria-hidden": "true",
568
601
  className: "resource-item-row",
569
602
  children: [/* @__PURE__ */ jsxs("div", {
570
- className: "resource-list-row resource-skeleton-row flow-columns",
603
+ className: "resource-list-row flow-columns",
604
+ "data-has-team": showTeam,
571
605
  children: [
572
606
  /* @__PURE__ */ jsxs("span", {
573
- className: "resource-skeleton-copy",
574
- children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-36 max-w-full" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-24 max-w-full" })]
607
+ className: "resource-primary-cell",
608
+ children: [/* @__PURE__ */ jsx(Skeleton, { className: "resource-flow-icon" }), /* @__PURE__ */ jsx("span", {
609
+ className: "resource-primary-copy",
610
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-36 max-w-full" })
611
+ })]
575
612
  }),
576
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-36 max-w-full" }),
577
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-28 max-w-full" }),
578
- /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-16" })
613
+ /* @__PURE__ */ jsx(Skeleton, { className: "resource-flow-id-cell h-3 w-36 max-w-full" }),
614
+ showTeam && /* @__PURE__ */ jsx(Skeleton, { className: "resource-team-cell h-3 w-24 max-w-full" }),
615
+ /* @__PURE__ */ jsx(Skeleton, { className: "resource-updated-at h-3 w-28 max-w-full" }),
616
+ /* @__PURE__ */ jsx(Skeleton, { className: "resource-publication-status h-3 w-16" }),
617
+ /* @__PURE__ */ jsx(Skeleton, { className: "resource-status h-3 w-16" })
579
618
  ]
580
- }), /* @__PURE__ */ jsxs("div", {
619
+ }), /* @__PURE__ */ jsx("div", {
581
620
  className: "resource-live-controls",
582
- children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-16" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-14" })]
621
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "size-7" })
583
622
  })]
584
623
  });
585
624
  }
@@ -598,6 +637,7 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
598
637
  const [creating, setCreating] = useState(false);
599
638
  const [filter, setFilter] = useState("");
600
639
  const [name, setName] = useState("");
640
+ const showTeam = flows.some((flow) => (flowBadges?.[flow.flowId]?.trim().length ?? 0) > 0);
601
641
  const normalized = filter.trim().toLocaleLowerCase();
602
642
  const visible = flows.filter((flow) => flow.name.toLocaleLowerCase().includes(normalized));
603
643
  async function create(event) {
@@ -611,7 +651,10 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
611
651
  className: "resource-browser",
612
652
  "data-tooltip-portal": true,
613
653
  children: /* @__PURE__ */ jsxs("div", {
614
- className: cn("resource-page", catalogWidth != "default" && "resource-page-full"),
654
+ className: cn("resource-page", {
655
+ "resource-page-full": catalogWidth == null || catalogWidth == "full",
656
+ "resource-page-embedded": catalogWidth == "embedded"
657
+ }),
615
658
  children: [
616
659
  /* @__PURE__ */ jsx("h1", {
617
660
  className: "sr-only",
@@ -659,7 +702,7 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
659
702
  /* @__PURE__ */ jsx("div", {
660
703
  className: "resource-table-scroll",
661
704
  children: /* @__PURE__ */ jsxs("div", {
662
- className: "resource-table",
705
+ className: cn("resource-table", showTeam && "resource-table-with-teams"),
663
706
  children: [/* @__PURE__ */ jsxs("div", {
664
707
  "aria-hidden": "true",
665
708
  className: "resource-list-columns-shell",
@@ -671,11 +714,16 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
671
714
  className: "resource-flow-id-heading",
672
715
  children: t("resource.flowId")
673
716
  }),
717
+ showTeam && /* @__PURE__ */ jsx("span", {
718
+ className: "resource-team-heading",
719
+ children: t("resource.team")
720
+ }),
674
721
  /* @__PURE__ */ jsx("span", {
675
722
  className: "resource-updated-heading",
676
723
  children: t("resource.updated")
677
724
  }),
678
- /* @__PURE__ */ jsx("span", { children: t("resource.status") })
725
+ /* @__PURE__ */ jsx("span", { children: t("resource.publicationStatus") }),
726
+ /* @__PURE__ */ jsx("span", { children: t("resource.runtimeStatus") })
679
727
  ]
680
728
  }), /* @__PURE__ */ jsx("span", {
681
729
  className: "resource-actions-heading",
@@ -683,7 +731,7 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
683
731
  })]
684
732
  }), /* @__PURE__ */ jsx("div", {
685
733
  className: "resource-list",
686
- children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, {}, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
734
+ children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, { showTeam }, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
687
735
  className: "min-h-64",
688
736
  role: "alert",
689
737
  children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
@@ -722,6 +770,7 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
722
770
  }), t("resource.newFlow")]
723
771
  }) })]
724
772
  }) : visible.map((flow) => /* @__PURE__ */ jsx(FlowItem, {
773
+ showTeam,
725
774
  badge: flowBadges?.[flow.flowId],
726
775
  busy,
727
776
  flow,
@@ -6735,7 +6784,7 @@ var WorkbenchStore = class {
6735
6784
  };
6736
6785
  //#endregion
6737
6786
  //#region src/workbench/browser/runtime/openFlowWorkbench.tsx
6738
- var FlowWorkspace = lazy(() => import("./flowWorkspace-Cp5CcEGu.js"));
6787
+ var FlowWorkspace = lazy(() => import("./flowWorkspace-BdbsnUDs.js"));
6739
6788
  function OpenFlowSessionGate({ action, description, error, onSubmit, onTokenChange, pending = false, title, token, tokenLabel }) {
6740
6789
  const hasToken = token != null && tokenLabel != null && onTokenChange != null;
6741
6790
  const tokenValue = token ?? "";
@@ -6835,6 +6884,12 @@ function NotificationBridge({ host, store }) {
6835
6884
  useEffect(() => () => notify(void 0), [notify]);
6836
6885
  return null;
6837
6886
  }
6887
+ function FlowNameBridge({ store, onChange }) {
6888
+ const name = useVal(store.workspace.$.flow)?.name;
6889
+ useEffect(() => onChange(name), [name, onChange]);
6890
+ useEffect(() => () => onChange(void 0), [onChange]);
6891
+ return null;
6892
+ }
6838
6893
  function Workbench({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, hrefFor, initializing, language, navigation, onConfigureConnector, onManageConnectorAccess, onLanguageChange, store, theme }) {
6839
6894
  const flowId = useVal(store.workspace.$.flowId);
6840
6895
  return /* @__PURE__ */ jsx("div", {
@@ -6852,7 +6907,7 @@ function Workbench({ catalogWidth, createFlow, createFlowDisabled, createFlowFie
6852
6907
  language,
6853
6908
  onCreateFlow: (name) => navigation.createFlow(name, createFlow),
6854
6909
  onLanguageChange,
6855
- onSelectFlow: (flow) => void navigation.selectFlow(flow),
6910
+ onSelectFlow: (flow, view) => void navigation.selectFlow(flow, view),
6856
6911
  store
6857
6912
  }) : /* @__PURE__ */ jsx(Suspense, {
6858
6913
  fallback: /* @__PURE__ */ jsx("main", {
@@ -6871,7 +6926,7 @@ function Workbench({ catalogWidth, createFlow, createFlowDisabled, createFlowFie
6871
6926
  })
6872
6927
  });
6873
6928
  }
6874
- function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, preferences, sessionKey, theme, variables = true }) {
6929
+ function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, onFlowNameChange, preferences, sessionKey, theme, variables = true }) {
6875
6930
  const navigate = useRef(onNavigate);
6876
6931
  navigate.current = onNavigate;
6877
6932
  const [{ i18n, navigation, store }] = useState(() => {
@@ -6925,29 +6980,36 @@ function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField
6925
6980
  children: /* @__PURE__ */ jsxs("div", {
6926
6981
  className: "open-flow-theme open-flow-workbench",
6927
6982
  "data-theme": theme,
6928
- children: [/* @__PURE__ */ jsx(NotificationBridge, {
6929
- host,
6930
- store
6931
- }), started || location.flowId == null ? /* @__PURE__ */ jsx(Workbench, {
6932
- catalogWidth,
6933
- createFlow,
6934
- createFlowDisabled,
6935
- createFlowField,
6936
- flowBadges,
6937
- connectionHref,
6938
- hrefFor,
6939
- initializing: !started,
6940
- language,
6941
- navigation,
6942
- onConfigureConnector,
6943
- onManageConnectorAccess,
6944
- onLanguageChange,
6945
- store,
6946
- theme
6947
- }) : /* @__PURE__ */ jsx("main", {
6948
- "aria-busy": "true",
6949
- className: "workspace"
6950
- })]
6983
+ children: [
6984
+ /* @__PURE__ */ jsx(NotificationBridge, {
6985
+ host,
6986
+ store
6987
+ }),
6988
+ onFlowNameChange != null && /* @__PURE__ */ jsx(FlowNameBridge, {
6989
+ store,
6990
+ onChange: onFlowNameChange
6991
+ }),
6992
+ started || location.flowId == null ? /* @__PURE__ */ jsx(Workbench, {
6993
+ catalogWidth,
6994
+ createFlow,
6995
+ createFlowDisabled,
6996
+ createFlowField,
6997
+ flowBadges,
6998
+ connectionHref,
6999
+ hrefFor,
7000
+ initializing: !started,
7001
+ language,
7002
+ navigation,
7003
+ onConfigureConnector,
7004
+ onManageConnectorAccess,
7005
+ onLanguageChange,
7006
+ store,
7007
+ theme
7008
+ }) : /* @__PURE__ */ jsx("main", {
7009
+ "aria-busy": "true",
7010
+ className: "workspace"
7011
+ })
7012
+ ]
6951
7013
  })
6952
7014
  })
6953
7015
  });
@@ -1,4 +1,4 @@
1
- import { Ct as SelectGroup, Dt as SelectValue, Et as SelectTrigger, St as SelectContent, bi as cn, bt as Select, wt as SelectItem } from "./icons-6oQ8Q9Wm.js";
1
+ import { Ct as SelectGroup, Dt as SelectValue, Et as SelectTrigger, St as SelectContent, bi as cn, bt as Select, wt as SelectItem } from "./icons-D70mz3qW.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/workbench/browser/runtime/shell/workbenchSelect.tsx
4
4
  function WorkbenchSelect({ ariaLabel, className, disabled = false, id, onValueChange, options, portalRoot, size, value, variant }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oomol-lab/open-flow",
3
- "version": "0.1.0-beta.59",
3
+ "version": "0.1.0-beta.60",
4
4
  "description": "TypeScript contracts and Browser runtime for Open Flow.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {