@parallelworks/ui 0.78.0 → 0.79.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.
@@ -0,0 +1,21 @@
1
+ import { cx } from "../cx.js";
2
+ import { ExternalLink } from "../components/ExternalLink.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/graph/ProblemPageLink.tsx
5
+ /** The page a problem's type URI resolves to, or undefined for `about:blank` and no type, which
6
+ * have none. */
7
+ function problemPage(type) {
8
+ return type && type !== "about:blank" ? type : void 0;
9
+ }
10
+ /** Links a problem to the page that explains it, in a new tab, when its type has one. */
11
+ function ProblemPageLink({ type, label, className }) {
12
+ const href = problemPage(type);
13
+ if (!href) return null;
14
+ return /* @__PURE__ */ jsx(ExternalLink, {
15
+ href,
16
+ className: cx("rounded-sm text-xs underline underline-offset-2 hover:decoration-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus)", className),
17
+ children: label
18
+ });
19
+ }
20
+ //#endregion
21
+ export { ProblemPageLink, problemPage };
@@ -1,7 +1,9 @@
1
1
  import { WarningIcon } from "../icons.js";
2
2
  import { Tooltip } from "../components/Tooltip.js";
3
+ import { useProblemText } from "../components/Provider.js";
3
4
  import { keyedByContent } from "../components/keys.js";
4
5
  import { Popover } from "../components/Popover.js";
6
+ import { ProblemPageLink } from "./ProblemPageLink.js";
5
7
  import { useGraphEditorStrings } from "./editorStrings.js";
6
8
  import { toolbarPanel } from "./toolbarPanel.js";
7
9
  import { useState } from "react";
@@ -10,6 +12,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
12
  /** A toolbar's count of the problems it lists, which opens the list. */
11
13
  function ProblemsButton({ problems }) {
12
14
  const t = useGraphEditorStrings();
15
+ const problemText = useProblemText();
13
16
  const [open, setOpen] = useState(false);
14
17
  if (problems.length === 0) return null;
15
18
  const label = t.problemCount(problems.length);
@@ -37,20 +40,27 @@ function ProblemsButton({ problems }) {
37
40
  children: t.problemLine(problem.line)
38
41
  }), /* @__PURE__ */ jsx("span", {
39
42
  className: "text-(--theme-error-text)",
40
- children: problem.message
43
+ children: problemText(problem)
41
44
  })] });
42
- return /* @__PURE__ */ jsx("li", { children: pick ? /* @__PURE__ */ jsx("button", {
43
- type: "button",
44
- className: "w-full cursor-pointer rounded px-1.5 py-1 text-left theme-hover",
45
- onClick: () => {
46
- setOpen(false);
47
- pick();
48
- },
49
- children: text
50
- }) : /* @__PURE__ */ jsx("div", {
51
- className: "px-1.5 py-1",
52
- children: text
53
- }) }, key);
45
+ return /* @__PURE__ */ jsxs("li", {
46
+ className: "flex items-baseline gap-2",
47
+ children: [pick ? /* @__PURE__ */ jsx("button", {
48
+ type: "button",
49
+ className: "min-w-0 flex-1 cursor-pointer rounded px-1.5 py-1 text-left theme-hover",
50
+ onClick: () => {
51
+ setOpen(false);
52
+ pick();
53
+ },
54
+ children: text
55
+ }) : /* @__PURE__ */ jsx("div", {
56
+ className: "min-w-0 flex-1 px-1.5 py-1",
57
+ children: text
58
+ }), /* @__PURE__ */ jsx(ProblemPageLink, {
59
+ type: problem.type,
60
+ label: t.problemAbout,
61
+ className: "shrink-0"
62
+ })]
63
+ }, key);
54
64
  })
55
65
  })
56
66
  });
@@ -2,10 +2,11 @@ import { cx } from "../cx.js";
2
2
  import { WarningIcon } from "../icons.js";
3
3
  import { toneIcon } from "../components/tone.js";
4
4
  import { Tooltip } from "../components/Tooltip.js";
5
- import { useStrings, useWorkflowEngine } from "../components/Provider.js";
5
+ import { useProblemText, useStrings, useWorkflowEngine } from "../components/Provider.js";
6
6
  import { keyedByContent, withPositionKeys } from "../components/keys.js";
7
7
  import { Callout } from "../components/Callout.js";
8
8
  import { jobLabel } from "./util.js";
9
+ import { ProblemPageLink } from "./ProblemPageLink.js";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region src/graph/RunWarningsList.tsx
11
12
  /** A warning's message, with the text it puts in backticks, such as a keyword, set as code. */
@@ -21,11 +22,12 @@ function WarningText({ message }) {
21
22
  * it lists them. */
22
23
  function WarningMark({ warnings, className }) {
23
24
  const { dag } = useStrings();
25
+ const problemText = useProblemText();
24
26
  if (warnings.length === 0) return null;
25
27
  return /* @__PURE__ */ jsx(Tooltip, {
26
28
  content: /* @__PURE__ */ jsx("ul", {
27
29
  className: "m-0 flex list-none flex-col gap-1 p-0",
28
- children: keyedByContent(warnings, (w) => w.message).map(({ key, item }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(WarningText, { message: item.message }) }, key))
30
+ children: keyedByContent(warnings, (w) => w.message).map(({ key, item }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(WarningText, { message: problemText(item) }) }, key))
29
31
  }),
30
32
  children: /* @__PURE__ */ jsx("span", {
31
33
  role: "img",
@@ -61,6 +63,7 @@ function placeOf({ warning, targets: [target] }, rootJobs, stepLabel, stepNumber
61
63
  function RunWarningsList({ warnings, rootJobs, onShow }) {
62
64
  const { dag } = useStrings();
63
65
  const engine = useWorkflowEngine();
66
+ const problemText = useProblemText();
64
67
  if (warnings.length === 0) return null;
65
68
  return /* @__PURE__ */ jsx(Callout, {
66
69
  tone: "warning",
@@ -75,15 +78,21 @@ function RunWarningsList({ warnings, rootJobs, onShow }) {
75
78
  className: "flex flex-col items-start gap-0.5",
76
79
  children: [/* @__PURE__ */ jsx("span", {
77
80
  className: "min-w-0 break-words",
78
- children: /* @__PURE__ */ jsx(WarningText, { message: item.warning.message })
79
- }), target && onShow ? /* @__PURE__ */ jsx("button", {
80
- type: "button",
81
- onClick: () => onShow(target),
82
- className: "cursor-pointer rounded-sm text-xs font-medium underline underline-offset-2 hover:decoration-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus)",
83
- children: where
84
- }) : /* @__PURE__ */ jsx("span", {
85
- className: "text-xs",
86
- children: where
81
+ children: /* @__PURE__ */ jsx(WarningText, { message: problemText(item.warning) })
82
+ }), /* @__PURE__ */ jsxs("span", {
83
+ className: "flex flex-wrap items-baseline gap-x-3 gap-y-0.5",
84
+ children: [target && onShow ? /* @__PURE__ */ jsx("button", {
85
+ type: "button",
86
+ onClick: () => onShow(target),
87
+ className: "cursor-pointer rounded-sm text-xs font-medium underline underline-offset-2 hover:decoration-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus)",
88
+ children: where
89
+ }) : /* @__PURE__ */ jsx("span", {
90
+ className: "text-xs",
91
+ children: where
92
+ }), /* @__PURE__ */ jsx(ProblemPageLink, {
93
+ type: item.warning.type,
94
+ label: dag.warningAbout
95
+ })]
87
96
  })]
88
97
  }, key);
89
98
  })
@@ -1,10 +1,20 @@
1
+ import type { ProblemParams } from '../components/Provider.js';
1
2
  import type { GraphEdit, GraphEditResult } from '../editing.js';
2
3
  import type { Box } from './editorPrimitives.js';
3
4
  import type { ListedProblem } from './ProblemsButton.js';
4
5
  import type { SettingsView } from './settingsViews.js';
5
6
  export type { Box };
6
7
  export interface EditorProblem {
8
+ /** Its text, shown when it has no `code` or the host has no message for it. */
7
9
  message: string;
10
+ /** Its stable code, which the host's `useProblemMessage` shows in the reader's language with
11
+ * `params`. */
12
+ code?: string | null | undefined;
13
+ /** The values the code's message shows, by name. */
14
+ params?: ProblemParams | null | undefined;
15
+ /** The URI of the page that explains it, which the problems list links to, and which the host's
16
+ * `useProblemMessage` gets with its `code`. `about:blank` has none. */
17
+ type?: string | null | undefined;
8
18
  line: number;
9
19
  job?: string;
10
20
  step?: number;
@@ -1,6 +1,7 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { AddIcon, DragHandleIcon, MoreIcon, WarningIcon } from "../icons.js";
3
3
  import { Tooltip } from "../components/Tooltip.js";
4
+ import { useProblemText } from "../components/Provider.js";
4
5
  import { MarqueeBox, place } from "./editorPrimitives.js";
5
6
  import { EDITOR_HANDLE_CLASS, NO_SELECTION, labelsOf, problemsIn, sameEdge, sameStep, selectionBounds, useGraphEditor, useSelectedEdges, useUi } from "./graphEditorState.js";
6
7
  import { useEffect, useMemo, useRef } from "react";
@@ -145,12 +146,13 @@ var NO_PROBLEMS = [];
145
146
  function ProblemBadge({ api, job, step }) {
146
147
  const t = api.t;
147
148
  const problems = useUi(api, (state) => state.problems, NO_PROBLEMS);
149
+ const problemText = useProblemText();
148
150
  const mine = useMemo(() => step === void 0 ? problems.filter((problem) => problem.job === job) : problemsIn(problems, job, step), [
149
151
  problems,
150
152
  job,
151
153
  step
152
154
  ]);
153
- const messages = mine.map((problem) => problem.message).join("\n");
155
+ const messages = mine.map(problemText).join("\n");
154
156
  const line = mine[0]?.line ?? 0;
155
157
  if (!messages) return null;
156
158
  return /* @__PURE__ */ jsx(Tooltip, {
@@ -12,6 +12,7 @@ export declare const GRAPH_EDITOR_STRINGS: {
12
12
  stepCount: (count: number) => string;
13
13
  problemCount: (count: number) => string;
14
14
  problemLine: (line: number) => string;
15
+ problemAbout: string;
15
16
  connectOutHint: string;
16
17
  connectInHint: string;
17
18
  moveBoxHint: string;
@@ -13,6 +13,7 @@ var GRAPH_EDITOR_STRINGS = {
13
13
  stepCount: (count) => count === 1 ? "1 step" : `${count} steps`,
14
14
  problemCount: (count) => count === 1 ? "1 problem" : `${count} problems`,
15
15
  problemLine: (line) => `Line ${line}`,
16
+ problemAbout: "About this problem",
16
17
  connectOutHint: "Drag onto a job to make it depend on this node. Drop on a circle to cover every job in that node.",
17
18
  connectInHint: "Drag onto a job to make this node depend on it. Drop on a circle to cover every job in that node.",
18
19
  moveBoxHint: "Drag to move these jobs together",
@@ -1,3 +1,4 @@
1
+ import type { ProblemParams } from '../components/Provider.js';
1
2
  import type { WorkflowJob } from './types.js';
2
3
  /** Something probably wrong with a run's workflow, found when the run was created, about one of its jobs or steps. */
3
4
  export interface RunWarning {
@@ -8,8 +9,18 @@ export interface RunWarning {
8
9
  job: string;
9
10
  /** The step's index among the job's steps as the run lists them; absent for the job's own. */
10
11
  step?: number | null | undefined;
11
- /** What is wrong and what to write instead. Text in backticks shows as code. */
12
+ /** What is wrong and what to write instead. Text in backticks shows as code. It shows when the
13
+ * warning has no `code`, or the host has no message for it. */
12
14
  message: string;
15
+ /** The warning's stable code, such as `undefined_input`, which the host's `useProblemMessage`
16
+ * shows in the reader's language with `params`. */
17
+ code?: string | null | undefined;
18
+ /** The values the code's message shows, by name. */
19
+ params?: ProblemParams | null | undefined;
20
+ /** The URI of the page that explains it, such as `/problems/workflow/undefined_input`, which the
21
+ * warning links to, and which the host's `useProblemMessage` gets with its `code`. `about:blank`
22
+ * has none. */
23
+ type?: string | null | undefined;
13
24
  }
14
25
  /** A subworkflow step on the way to a warning: its level's prefix, its job and its index. */
15
26
  interface Via {
package/dist/index.d.ts CHANGED
@@ -47,7 +47,7 @@ export { PageHeader, PageHeaderBar, type PageHeaderBarProps, type PageHeaderProp
47
47
  export { PageHeaderAction, type PageHeaderActionProps, PageHeaderAddButton, type PageHeaderAddButtonProps, PageHeaderMenu, } from './components/PageHeaderAction.js';
48
48
  export { PAGE_SIZES, Pagination, type PaginationProps } from './components/Pagination.js';
49
49
  export { Popover, PopoverClose, type PopoverProps, useClosePopover, } from './components/Popover.js';
50
- export { type AvatarColoring, type PersistedStateHook, type RunFileResult, type UIData, type UILinkComponent, type UINavigation, UIProvider, type UIProviderProps, type UISlots, type UIStringOverrides, type UIStrings, useAvatarColoring, useLocale, useNavigation, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader, type WorkflowEngineSource, type WorkflowJsonRef, } from './components/Provider.js';
50
+ export { type AvatarColoring, type CodedProblem, type PersistedStateHook, type ProblemMessage, type ProblemParams, type RunFileResult, type UIData, type UILinkComponent, type UINavigation, UIProvider, type UIProviderProps, type UISlots, type UIStringOverrides, type UIStrings, useAvatarColoring, useLocale, useNavigation, useOptionalWorkflowEngine, usePersistedState, useProblemText, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader, type WorkflowEngineSource, type WorkflowJsonRef, } from './components/Provider.js';
51
51
  export { Radio, RadioGroup, type RadioProps } from './components/Radio.js';
52
52
  export { RefreshButton, type RefreshButtonProps } from './components/RefreshButton.js';
53
53
  export { RequiredMark } from './components/RequiredMark.js';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { Loader } from "./components/Loader.js";
7
7
  import { toast } from "./components/Toast.js";
8
8
  import { Kbd, ariaKeyShortcuts, formatShortcut, isApplePlatform, shortcutText, useShortcutFormat } from "./components/Kbd.js";
9
9
  import { Tooltip, TooltipProvider } from "./components/Tooltip.js";
10
- import { UIProvider, useAvatarColoring, useLocale, useNavigation, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader } from "./components/Provider.js";
10
+ import { UIProvider, useAvatarColoring, useLocale, useNavigation, useOptionalWorkflowEngine, usePersistedState, useProblemText, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader } from "./components/Provider.js";
11
11
  import { AppLink, isPlainClick } from "./components/AppLink.js";
12
12
  import { useCopy } from "./components/useCopy.js";
13
13
  import { MenuEntries, MenuFilter, isMenuDivider, isMenuGroup, isMenuSubmenu, menuDivider } from "./components/MenuEntries.js";
@@ -83,4 +83,4 @@ import { ToggleGroup } from "./components/ToggleGroup.js";
83
83
  import { useClosingValue } from "./components/useClosingValue.js";
84
84
  import { useCssIsDark } from "./components/useCssIsDark.js";
85
85
  import { useApplyTheme, useColorMode } from "./components/useTheme.js";
86
- export { ActionMenu, AppLink, Autocomplete, Avatar, AvatarGroup, Breadcrumbs, Button, CODE_STYLES, Calendar, Callout, Card, CardHeader, ChartLegendList, ChartTooltipContent, Checkbox, CheckboxGroup, ColorInput, Combobox, ConfirmModal, ContextMenuProvider, CopyButton, CopyCodeBlock, CountBadge, CreateModal, CreateModalSelect, CreateModalSwitch, DEFAULT_CONTRAST, DEFAULT_PRESET, DEFAULT_THEME, DatePicker, DescriptionList, DescriptionListGroup, DescriptionListItem, Disclosure, DisclosurePanel, Drawer, Elapsed, EmptyState, ErrorPage, ErrorText, ExternalLink, Field, FieldOption, FieldValue, FileButton, HoverCard, IconButton, InfoTip, Input, JND, Kbd, LetterBadge, ListboxGroup, ListboxOption, ListboxPanel, Loader, LoadingRegion, Markdown, MenuCheckboxItem, MenuEntries, MenuFilter, MenuGroupLabel, MenuItem, MenuLinkItem, MenuPopup, MenuRadioItem, MenuSeparator, MenuSubmenuTrigger, Meter, MethodButton, Modal, ModalDescription, ModalTitle, NumberInput, OneTimeCodeInput, Overview, PAGE_SIZES, PageHeader, PageHeaderAction, PageHeaderAddButton, PageHeaderBar, PageHeaderMenu, PageHeaderProvider, Pagination, Popover, PopoverClose, ProgressBar, Radio, RadioGroup, RefreshButton, RelativeTime, RequiredMark, RevealToggle, RunStatusIcon, SIDEBAR_TOKENS, SearchInput, Section, SegmentedControl, Select, SelectionCopy, SeriesSwatch, SettingModeOption, SettingRow, SettingsCard, SettingsHeading, Skeleton, Slider, StatusBadge, StatusDot, StickyBar, Switch, THEME_PRESETS, THEME_TOKENS, TabPanel, Table, Tabs, Tag, TagList, Textarea, ThemeEditor, ThemePreview, TitleInput, ToggleGroup, Tooltip, TooltipProvider, UIProvider, apcaContrast, applyTheme, ariaKeyShortcuts, avatarInitials, buttonClasses, categoryClasses, categoryOf, collapsePanelClassName, composite, contrastRatio, cx, deltaE, deriveTheme, errorPageKind, fieldBox, fitSeed, formatBytes, formatCount, formatDateTime, formatDuration, formatInfoTipContent, formatShortcut, formatTimeLeft, generateTheme, isApplePlatform, isDarkColor, isMenuDivider, isMenuGroup, isMenuSubmenu, isPlainClick, isTextEntryContext, levelTone, menuDivider, modalPanelClassName, modeOf, normalizeTags, parseColor, parseTheme, prefersWideGamut, resolveMode, runStatusTone, schemeFor, serializeTheme, seriesColor, seriesColors, seriesOpacity, seriesSlotColor, shortcutText, statusTextClass, tagClasses, themeStylesheet, toHex, toP3, toast, useApplyTheme, useAvatarColoring, useClock, useClosePopover, useClosingValue, useColorMode, useConfirm, useContextMenu, useCopy, useCssIsDark, useElapsed, useFieldControl, useFieldLabelledControl, useListboxNavigation, useLocale, useMenuOpenedBy, useNavigation, useOpenMenu, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRelativeTime, useRunFile, useSeriesHighlight, useShortcutFormat, useShortcutKey, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader };
86
+ export { ActionMenu, AppLink, Autocomplete, Avatar, AvatarGroup, Breadcrumbs, Button, CODE_STYLES, Calendar, Callout, Card, CardHeader, ChartLegendList, ChartTooltipContent, Checkbox, CheckboxGroup, ColorInput, Combobox, ConfirmModal, ContextMenuProvider, CopyButton, CopyCodeBlock, CountBadge, CreateModal, CreateModalSelect, CreateModalSwitch, DEFAULT_CONTRAST, DEFAULT_PRESET, DEFAULT_THEME, DatePicker, DescriptionList, DescriptionListGroup, DescriptionListItem, Disclosure, DisclosurePanel, Drawer, Elapsed, EmptyState, ErrorPage, ErrorText, ExternalLink, Field, FieldOption, FieldValue, FileButton, HoverCard, IconButton, InfoTip, Input, JND, Kbd, LetterBadge, ListboxGroup, ListboxOption, ListboxPanel, Loader, LoadingRegion, Markdown, MenuCheckboxItem, MenuEntries, MenuFilter, MenuGroupLabel, MenuItem, MenuLinkItem, MenuPopup, MenuRadioItem, MenuSeparator, MenuSubmenuTrigger, Meter, MethodButton, Modal, ModalDescription, ModalTitle, NumberInput, OneTimeCodeInput, Overview, PAGE_SIZES, PageHeader, PageHeaderAction, PageHeaderAddButton, PageHeaderBar, PageHeaderMenu, PageHeaderProvider, Pagination, Popover, PopoverClose, ProgressBar, Radio, RadioGroup, RefreshButton, RelativeTime, RequiredMark, RevealToggle, RunStatusIcon, SIDEBAR_TOKENS, SearchInput, Section, SegmentedControl, Select, SelectionCopy, SeriesSwatch, SettingModeOption, SettingRow, SettingsCard, SettingsHeading, Skeleton, Slider, StatusBadge, StatusDot, StickyBar, Switch, THEME_PRESETS, THEME_TOKENS, TabPanel, Table, Tabs, Tag, TagList, Textarea, ThemeEditor, ThemePreview, TitleInput, ToggleGroup, Tooltip, TooltipProvider, UIProvider, apcaContrast, applyTheme, ariaKeyShortcuts, avatarInitials, buttonClasses, categoryClasses, categoryOf, collapsePanelClassName, composite, contrastRatio, cx, deltaE, deriveTheme, errorPageKind, fieldBox, fitSeed, formatBytes, formatCount, formatDateTime, formatDuration, formatInfoTipContent, formatShortcut, formatTimeLeft, generateTheme, isApplePlatform, isDarkColor, isMenuDivider, isMenuGroup, isMenuSubmenu, isPlainClick, isTextEntryContext, levelTone, menuDivider, modalPanelClassName, modeOf, normalizeTags, parseColor, parseTheme, prefersWideGamut, resolveMode, runStatusTone, schemeFor, serializeTheme, seriesColor, seriesColors, seriesOpacity, seriesSlotColor, shortcutText, statusTextClass, tagClasses, themeStylesheet, toHex, toP3, toast, useApplyTheme, useAvatarColoring, useClock, useClosePopover, useClosingValue, useColorMode, useConfirm, useContextMenu, useCopy, useCssIsDark, useElapsed, useFieldControl, useFieldLabelledControl, useListboxNavigation, useLocale, useMenuOpenedBy, useNavigation, useOpenMenu, useOptionalWorkflowEngine, usePersistedState, useProblemText, useProvisionCorsRules, useRelativeTime, useRunFile, useSeriesHighlight, useShortcutFormat, useShortcutKey, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader };