@voyantjs/workflows-ui 0.37.1 → 0.38.1

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.
Files changed (48) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -3
  3. package/dist/client.d.ts +1 -1
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +1 -1
  6. package/dist/components/common.d.ts +30 -0
  7. package/dist/components/common.d.ts.map +1 -0
  8. package/dist/components/common.js +108 -0
  9. package/dist/components/workflow-run-actions.d.ts +7 -0
  10. package/dist/components/workflow-run-actions.d.ts.map +1 -0
  11. package/dist/components/workflow-run-actions.js +72 -0
  12. package/dist/components/workflow-run-detail-page.d.ts +9 -1
  13. package/dist/components/workflow-run-detail-page.d.ts.map +1 -1
  14. package/dist/components/workflow-run-detail-page.js +96 -1
  15. package/dist/components/workflow-runs-filters.d.ts +32 -0
  16. package/dist/components/workflow-runs-filters.d.ts.map +1 -0
  17. package/dist/components/workflow-runs-filters.js +97 -0
  18. package/dist/components/workflow-runs-page.d.ts +11 -1
  19. package/dist/components/workflow-runs-page.d.ts.map +1 -1
  20. package/dist/components/workflow-runs-page.js +132 -1
  21. package/dist/i18n/en.d.ts +3 -2
  22. package/dist/i18n/en.d.ts.map +1 -1
  23. package/dist/i18n/en.js +96 -2
  24. package/dist/i18n/index.d.ts +4 -2
  25. package/dist/i18n/index.d.ts.map +1 -1
  26. package/dist/i18n/index.js +3 -2
  27. package/dist/i18n/messages.d.ts +86 -0
  28. package/dist/i18n/messages.d.ts.map +1 -0
  29. package/dist/i18n/messages.js +1 -0
  30. package/dist/i18n/provider.d.ts +26 -0
  31. package/dist/i18n/provider.d.ts.map +1 -0
  32. package/dist/i18n/provider.js +44 -0
  33. package/dist/i18n/ro.d.ts +3 -2
  34. package/dist/i18n/ro.d.ts.map +1 -1
  35. package/dist/i18n/ro.js +98 -2
  36. package/dist/index.d.ts +6 -2
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +4 -2
  39. package/dist/types.d.ts +2 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +1 -0
  42. package/package.json +55 -68
  43. package/src/components/common.tsx +182 -0
  44. package/src/components/workflow-run-actions.tsx +160 -0
  45. package/src/components/workflow-run-detail-page.tsx +393 -0
  46. package/src/components/workflow-runs-filters.tsx +349 -0
  47. package/src/components/workflow-runs-page.tsx +357 -0
  48. package/src/styles.css +5 -3
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button } from "@voyantjs/ui/components/button";
4
+ import { Card, CardContent, CardHeader, CardTitle } from "@voyantjs/ui/components/card";
5
+ import { Combobox, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList, } from "@voyantjs/ui/components/combobox";
6
+ import { Input } from "@voyantjs/ui/components/input";
7
+ import { CheckCircle2, Clock, Search, X, XCircle } from "lucide-react";
8
+ import { useEffect, useMemo, useRef, useState } from "react";
9
+ import { useWorkflowRunsUiMessagesOrDefault } from "../i18n/index.js";
10
+ import { TagChip } from "./common.js";
11
+ export const STATUS_OPTIONS = ["running", "failed", "succeeded", "cancelled"];
12
+ export const TIME_RANGES = ["15m", "1h", "24h", "7d", "all"];
13
+ export function WorkflowRunsFilters({ filters, workflowOptions, tagOptions, statusFilters, tagFilters, searchQuery, timeRange, onChange, onToggleStatus, onAddTagFilter, onRemoveTagFilter, onSearchChange, onTimeRangeChange, onClear, }) {
14
+ const messages = useWorkflowRunsUiMessagesOrDefault();
15
+ const searchInputRef = useRef(null);
16
+ useEffect(() => {
17
+ const onKeyDown = (event) => {
18
+ if (!(event.metaKey || event.ctrlKey) || event.key.toLowerCase() !== "k")
19
+ return;
20
+ event.preventDefault();
21
+ searchInputRef.current?.focus();
22
+ };
23
+ globalThis.addEventListener("keydown", onKeyDown);
24
+ return () => globalThis.removeEventListener("keydown", onKeyDown);
25
+ }, []);
26
+ return (_jsxs(Card, { children: [_jsx(CardHeader, { className: "pb-3", children: _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx(CardTitle, { className: "text-sm", children: messages.page.filterTitle }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onClear, children: messages.page.clearFilters })] }) }), _jsxs(CardContent, { className: "space-y-4", children: [_jsx(Field, { label: messages.page.searchLabel, children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute top-1/2 left-2.5 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { ref: searchInputRef, className: "pl-8", placeholder: messages.page.searchPlaceholder, value: searchQuery, onChange: (event) => onSearchChange(event.target.value) })] }) }), _jsx(Field, { label: messages.page.workflowLabel, children: _jsx(WorkflowCombobox, { value: filters.workflowName ?? null, options: workflowOptions, placeholder: messages.page.workflowPlaceholder, emptyLabel: messages.page.workflowEmpty, onChange: (workflowName) => onChange({ ...filters, workflowName: workflowName ?? undefined }) }) }), _jsx(Field, { label: messages.page.statusLabel, children: _jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(Button, { type: "button", variant: statusFilters.length === 0 ? "default" : "outline", size: "sm", onClick: () => {
27
+ for (const status of statusFilters)
28
+ onToggleStatus(status);
29
+ }, children: messages.page.anyStatus }), STATUS_OPTIONS.map((status) => (_jsxs(Button, { type: "button", variant: statusFilters.includes(status) ? "default" : "outline", size: "sm", onClick: () => onToggleStatus(status), "aria-pressed": statusFilters.includes(status), children: [_jsx(StatusGlyph, { status: status }), messages.status[status]] }, status)))] }) }), _jsx(Field, { label: messages.page.timeRangeLabel, children: _jsx("div", { className: "flex flex-wrap gap-1.5", children: TIME_RANGES.map((range) => (_jsx(Button, { type: "button", variant: timeRange === range ? "default" : "outline", size: "sm", onClick: () => onTimeRangeChange(range), "aria-pressed": timeRange === range, children: messages.page.timeRanges[range] }, range))) }) }), _jsx(Field, { label: messages.page.tagLabel, children: _jsx(TagFilterBuilder, { tagOptions: tagOptions, tagFilters: tagFilters, placeholder: messages.page.tagPlaceholder, emptyLabel: messages.page.tagEmpty, addLabel: messages.page.addTag, removeLabel: messages.page.removeTag, onAdd: onAddTagFilter, onRemove: onRemoveTagFilter }) })] })] }));
30
+ }
31
+ export function buildFilterOptions(runs, selectedWorkflow) {
32
+ const workflowCounts = new Map();
33
+ const tags = new Set();
34
+ for (const run of runs) {
35
+ workflowCounts.set(run.workflowName, (workflowCounts.get(run.workflowName) ?? 0) + 1);
36
+ for (const tag of run.tags)
37
+ tags.add(tag);
38
+ }
39
+ if (selectedWorkflow && !workflowCounts.has(selectedWorkflow)) {
40
+ workflowCounts.set(selectedWorkflow, 0);
41
+ }
42
+ return {
43
+ workflows: Array.from(workflowCounts.entries())
44
+ .map(([name, count]) => ({ name, count }))
45
+ .sort((a, b) => b.count - a.count || a.name.localeCompare(b.name)),
46
+ tags: Array.from(tags).sort((a, b) => a.localeCompare(b)),
47
+ };
48
+ }
49
+ function WorkflowCombobox({ value, options, placeholder, emptyLabel, onChange, }) {
50
+ const itemMap = useMemo(() => new Map(options.map((item) => [item.name, item])), [options]);
51
+ const selectedLabel = value ?? "";
52
+ const [inputValue, setInputValue] = useState(selectedLabel);
53
+ useEffect(() => {
54
+ setInputValue(selectedLabel);
55
+ }, [selectedLabel]);
56
+ return (_jsxs(Combobox, { items: options.map((item) => item.name), value: value, inputValue: inputValue, autoHighlight: true, itemToStringValue: (item) => String(item), onInputValueChange: (next) => {
57
+ setInputValue(next);
58
+ if (!next)
59
+ onChange(null);
60
+ }, onValueChange: (next) => {
61
+ const nextValue = next ?? null;
62
+ onChange(nextValue);
63
+ setInputValue(nextValue ?? "");
64
+ }, children: [_jsx(ComboboxInput, { placeholder: placeholder, showClear: !!value, className: "w-full" }), _jsxs(ComboboxContent, { children: [_jsx(ComboboxEmpty, { children: emptyLabel }), _jsx(ComboboxList, { children: _jsx(ComboboxCollection, { children: (name) => {
65
+ const option = itemMap.get(String(name));
66
+ if (!option)
67
+ return null;
68
+ return (_jsx(ComboboxItem, { value: option.name, children: _jsxs("div", { className: "flex min-w-0 flex-1 items-center justify-between gap-3", children: [_jsx("span", { className: "truncate font-medium", children: option.name }), _jsx("span", { className: "text-muted-foreground text-xs", children: option.count })] }) }, option.name));
69
+ } }) })] })] }));
70
+ }
71
+ function TagFilterBuilder({ tagOptions, tagFilters, placeholder, emptyLabel, addLabel, removeLabel, onAdd, onRemove, }) {
72
+ const [inputValue, setInputValue] = useState("");
73
+ const submit = () => {
74
+ const next = inputValue.trim();
75
+ if (!next)
76
+ return;
77
+ onAdd(next);
78
+ setInputValue("");
79
+ };
80
+ return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-2", children: [_jsxs(Combobox, { items: tagOptions, value: null, inputValue: inputValue, autoHighlight: true, itemToStringValue: (item) => String(item), onInputValueChange: setInputValue, onValueChange: (next) => {
81
+ const tag = next ?? "";
82
+ if (tag) {
83
+ onAdd(tag);
84
+ setInputValue("");
85
+ }
86
+ }, children: [_jsx(ComboboxInput, { placeholder: placeholder, className: "w-full" }), _jsxs(ComboboxContent, { children: [_jsx(ComboboxEmpty, { children: emptyLabel }), _jsx(ComboboxList, { children: _jsx(ComboboxCollection, { children: (tag) => (_jsx(ComboboxItem, { value: String(tag), children: _jsx(TagChip, { tag: String(tag) }) }, String(tag))) }) })] })] }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: submit, children: addLabel })] }), tagFilters.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-1.5", children: tagFilters.map((tag) => (_jsxs("button", { type: "button", className: "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 font-mono text-[10px] hover:bg-muted", onClick: () => onRemove(tag), "aria-label": `${removeLabel}: ${tag}`, children: [_jsx(TagChip, { tag: tag }), _jsx(X, { className: "h-3 w-3", "aria-hidden": "true" })] }, tag))) })) : null] }));
87
+ }
88
+ function Field({ label, children }) {
89
+ return (_jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: label }), children] }));
90
+ }
91
+ function StatusGlyph({ status }) {
92
+ if (status === "succeeded")
93
+ return _jsx(CheckCircle2, { "data-icon": "inline-start", "aria-hidden": "true" });
94
+ if (status === "failed")
95
+ return _jsx(XCircle, { "data-icon": "inline-start", "aria-hidden": "true" });
96
+ return _jsx(Clock, { "data-icon": "inline-start", "aria-hidden": "true" });
97
+ }
@@ -1,2 +1,12 @@
1
- export { WorkflowRunsPage, type WorkflowRunsPageProps, WorkflowRunsPageSkeleton, } from "@voyantjs/workflow-runs-ui/components/workflow-runs-page";
1
+ import type { ListWorkflowRunsQuery, WorkflowRunsApi } from "../types.js";
2
+ export interface WorkflowRunsPageProps {
3
+ api: WorkflowRunsApi;
4
+ selectedRunId?: string | null;
5
+ onOpenRun?: (id: string) => void;
6
+ initialFilters?: ListWorkflowRunsQuery;
7
+ pollIntervalMs?: number;
8
+ className?: string;
9
+ }
10
+ export declare function WorkflowRunsPage({ api, selectedRunId, onOpenRun, initialFilters, pollIntervalMs, className, }: WorkflowRunsPageProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function WorkflowRunsPageSkeleton(): import("react/jsx-runtime").JSX.Element;
2
12
  //# sourceMappingURL=workflow-runs-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-runs-page.d.ts","sourceRoot":"","sources":["../../src/components/workflow-runs-page.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,wBAAwB,GACzB,MAAM,0DAA0D,CAAA"}
1
+ {"version":3,"file":"workflow-runs-page.d.ts","sourceRoot":"","sources":["../../src/components/workflow-runs-page.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,qBAAqB,EAGrB,eAAe,EAChB,MAAM,aAAa,CAAA;AAKpB,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,eAAe,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,qBAAqB,CAAA;IACtC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,aAAa,EACb,SAAS,EACT,cAAc,EACd,cAAqB,EACrB,SAAS,GACV,EAAE,qBAAqB,2CAuKvB;AAED,wBAAgB,wBAAwB,4CAqBvC"}
@@ -1 +1,132 @@
1
- export { WorkflowRunsPage, WorkflowRunsPageSkeleton, } from "@voyantjs/workflow-runs-ui/components/workflow-runs-page";
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button } from "@voyantjs/ui/components/button";
4
+ import { Card, CardContent } from "@voyantjs/ui/components/card";
5
+ import { Clock, Workflow } from "lucide-react";
6
+ import { useEffect, useMemo, useState } from "react";
7
+ import { useWorkflowRunsUiMessagesOrDefault } from "../i18n/index.js";
8
+ import { formatDuration, formatRelative, StatusBadge, StatusIcon, TagChip } from "./common.js";
9
+ import { WorkflowRunDetailPage } from "./workflow-run-detail-page.js";
10
+ import { buildFilterOptions, WorkflowRunsFilters } from "./workflow-runs-filters.js";
11
+ export function WorkflowRunsPage({ api, selectedRunId, onOpenRun, initialFilters, pollIntervalMs = 5000, className, }) {
12
+ const messages = useWorkflowRunsUiMessagesOrDefault();
13
+ const [filters, setFilters] = useState(initialFilters ?? { limit: 50 });
14
+ const [statusFilters, setStatusFilters] = useState(initialFilters?.status ? [initialFilters.status] : []);
15
+ const [tagFilters, setTagFilters] = useState(initialFilters?.tag ? [initialFilters.tag] : []);
16
+ const [searchQuery, setSearchQuery] = useState("");
17
+ const [timeRange, setTimeRange] = useState("24h");
18
+ const [live, setLive] = useState(false);
19
+ const [runs, setRuns] = useState([]);
20
+ const [error, setError] = useState(null);
21
+ const [loading, setLoading] = useState(false);
22
+ const [localSelectedRunId, setLocalSelectedRunId] = useState(null);
23
+ const activeRunId = selectedRunId !== undefined ? selectedRunId : localSelectedRunId;
24
+ const serverFilters = useMemo(() => ({
25
+ ...filters,
26
+ status: statusFilters.length === 1 ? statusFilters[0] : undefined,
27
+ tag: tagFilters.length === 1 ? tagFilters[0] : undefined,
28
+ }), [filters, statusFilters, tagFilters]);
29
+ useEffect(() => {
30
+ let cancelled = false;
31
+ const refresh = async () => {
32
+ if (typeof document !== "undefined" && document.hidden)
33
+ return;
34
+ setLoading(true);
35
+ try {
36
+ const res = await api.listRuns(serverFilters);
37
+ if (!cancelled) {
38
+ setRuns(res.data);
39
+ setError(null);
40
+ }
41
+ }
42
+ catch (err) {
43
+ if (!cancelled)
44
+ setError(err instanceof Error ? err.message : messages.page.loadError);
45
+ }
46
+ finally {
47
+ if (!cancelled)
48
+ setLoading(false);
49
+ }
50
+ };
51
+ void refresh();
52
+ const interval = setInterval(() => void refresh(), live ? 1000 : pollIntervalMs);
53
+ return () => {
54
+ cancelled = true;
55
+ clearInterval(interval);
56
+ };
57
+ }, [api, live, messages.page.loadError, pollIntervalMs, serverFilters]);
58
+ const filterOptions = useMemo(() => buildFilterOptions(runs, filters.workflowName), [filters.workflowName, runs]);
59
+ const filteredRuns = useMemo(() => filterRuns({ runs, statusFilters, tagFilters, searchQuery, timeRange }), [runs, searchQuery, statusFilters, tagFilters, timeRange]);
60
+ const openRun = (id) => {
61
+ setLocalSelectedRunId(id);
62
+ onOpenRun?.(id);
63
+ };
64
+ const toggleStatus = (status) => {
65
+ setStatusFilters((current) => current.includes(status) ? current.filter((item) => item !== status) : [...current, status]);
66
+ };
67
+ const addTagFilter = (tag) => {
68
+ const trimmed = tag.trim();
69
+ if (!trimmed)
70
+ return;
71
+ setTagFilters((current) => (current.includes(trimmed) ? current : [...current, trimmed]));
72
+ };
73
+ const removeTagFilter = (tag) => setTagFilters((current) => current.filter((item) => item !== tag));
74
+ return (_jsxs("div", { className: `flex min-h-screen flex-col bg-background ${className ?? ""}`, children: [_jsx("header", { className: "sticky top-0 z-10 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60", children: _jsxs("div", { className: "container mx-auto flex items-center gap-3 px-4 py-3", children: [_jsx(Workflow, { className: "h-5 w-5" }), _jsxs("div", { className: "min-w-0", children: [_jsx("h1", { className: "font-semibold text-base", children: messages.page.title }), _jsx("p", { className: "text-muted-foreground text-xs", children: messages.page.subtitle })] }), _jsxs("div", { className: "ml-auto flex items-center gap-2", children: [_jsxs(Button, { type: "button", variant: live ? "default" : "outline", size: "sm", onClick: () => setLive((value) => !value), "aria-pressed": live, children: [_jsx(Clock, { "data-icon": "inline-start", "aria-hidden": "true" }), messages.page.live] }), _jsx("span", { className: "text-muted-foreground text-xs", children: messages.page.filteredRunCount(filteredRuns.length, runs.length) })] })] }) }), _jsxs("main", { className: "container mx-auto flex flex-1 flex-col gap-6 px-4 py-6 md:flex-row", children: [_jsxs("aside", { className: "space-y-3 md:w-96 md:shrink-0", children: [_jsx(WorkflowRunsFilters, { filters: filters, workflowOptions: filterOptions.workflows, tagOptions: filterOptions.tags, statusFilters: statusFilters, tagFilters: tagFilters, searchQuery: searchQuery, timeRange: timeRange, onChange: setFilters, onToggleStatus: toggleStatus, onAddTagFilter: addTagFilter, onRemoveTagFilter: removeTagFilter, onSearchChange: setSearchQuery, onTimeRangeChange: setTimeRange, onClear: () => {
75
+ setFilters({ limit: filters.limit ?? 50 });
76
+ setStatusFilters([]);
77
+ setTagFilters([]);
78
+ setSearchQuery("");
79
+ setTimeRange("24h");
80
+ } }), error ? (_jsx(Card, { className: "border-destructive/40", children: _jsx(CardContent, { className: "pt-4 text-destructive text-sm", children: error }) })) : null, _jsxs("div", { className: "space-y-2", children: [filteredRuns.length === 0 && !loading ? (_jsx(Card, { children: _jsx(CardContent, { className: "pt-4 text-muted-foreground text-sm", children: messages.page.empty }) })) : null, filteredRuns.map((run) => (_jsx(RunListItem, { run: run, selected: activeRunId === run.id, activeTagFilters: tagFilters, activeStatusFilters: statusFilters, onSelect: () => openRun(run.id), onToggleStatus: toggleStatus, onToggleTag: (tag) => tagFilters.includes(tag) ? removeTagFilter(tag) : addTagFilter(tag) }, run.id)))] })] }), _jsx("section", { className: "min-w-0 flex-1", children: activeRunId ? (_jsx(WorkflowRunDetailPage, { api: api, runId: activeRunId, onOpenRun: openRun })) : (_jsx(SelectPrompt, {})) })] })] }));
81
+ }
82
+ export function WorkflowRunsPageSkeleton() {
83
+ const messages = useWorkflowRunsUiMessagesOrDefault();
84
+ return (_jsxs("div", { className: "flex min-h-screen flex-col bg-background", children: [_jsx("header", { className: "border-b px-4 py-3", children: _jsx("div", { className: "h-5 w-40 rounded bg-muted", role: "status", "aria-label": messages.page.loading }) }), _jsxs("main", { className: "container mx-auto flex flex-1 flex-col gap-6 px-4 py-6 md:flex-row", children: [_jsxs("aside", { className: "space-y-3 md:w-96 md:shrink-0", children: [_jsx("div", { className: "h-56 rounded-md bg-muted" }), _jsx("div", { className: "h-20 rounded-md bg-muted" }), _jsx("div", { className: "h-20 rounded-md bg-muted" })] }), _jsx("section", { className: "min-h-[24rem] flex-1 rounded-md bg-muted" })] })] }));
85
+ }
86
+ function RunListItem({ run, selected, activeTagFilters, activeStatusFilters, onSelect, onToggleStatus, onToggleTag, }) {
87
+ const messages = useWorkflowRunsUiMessagesOrDefault();
88
+ return (_jsxs("div", { className: `rounded-md border bg-card p-3 text-sm transition-colors hover:bg-muted/50 ${selected ? "border-primary bg-primary/5" : "" // i18n-literal-ok: CSS classes
89
+ }`, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: onSelect, className: "flex min-w-0 flex-1 items-center gap-2 text-left", children: [_jsx(StatusIcon, { status: run.status }), _jsx("span", { className: "truncate font-medium", children: run.workflowName }), _jsx("span", { className: "ml-auto whitespace-nowrap text-muted-foreground text-xs", children: formatRelative(run.startedAt, messages) })] }), _jsx("button", { type: "button", onClick: () => onToggleStatus(run.status), "aria-pressed": activeStatusFilters.includes(run.status), children: _jsx(StatusBadge, { status: run.status, messages: messages }) })] }), run.durationMs != null ? (_jsx("div", { className: "mt-1 text-muted-foreground text-xs", children: formatDuration(run.durationMs) })) : null, run.tags.length > 0 ? (_jsxs("div", { className: "mt-2 flex flex-wrap gap-1", children: [run.tags.slice(0, 3).map((tag) => (_jsx("button", { type: "button", onClick: () => onToggleTag(tag), "aria-pressed": activeTagFilters.includes(tag), className: activeTagFilters.includes(tag) ? "rounded-full ring-2 ring-primary/40" : undefined, children: _jsx(TagChip, { tag: tag }) }, tag))), run.tags.length > 3 ? (_jsx("span", { className: "text-muted-foreground text-xs", children: `+${run.tags.length - 3}` })) : null] })) : null] }));
90
+ }
91
+ function SelectPrompt() {
92
+ const messages = useWorkflowRunsUiMessagesOrDefault();
93
+ return (_jsx(Card, { children: _jsx(CardContent, { className: "flex min-h-[24rem] items-center justify-center text-muted-foreground text-sm", children: messages.page.selectPrompt }) }));
94
+ }
95
+ function filterRuns({ runs, statusFilters, tagFilters, searchQuery, timeRange, }) {
96
+ const search = searchQuery.trim().toLowerCase();
97
+ const cutoff = rangeCutoff(timeRange);
98
+ return runs.filter((run) => {
99
+ if (statusFilters.length > 0 && !statusFilters.includes(run.status))
100
+ return false;
101
+ if (tagFilters.length > 0 && !tagFilters.every((tag) => run.tags.includes(tag)))
102
+ return false;
103
+ if (cutoff && new Date(run.startedAt).getTime() < cutoff)
104
+ return false;
105
+ if (!search)
106
+ return true;
107
+ return runSearchText(run).includes(search);
108
+ });
109
+ }
110
+ function rangeCutoff(range) {
111
+ if (range === "all")
112
+ return null;
113
+ const minutes = range === "15m" ? 15 : range === "1h" ? 60 : range === "24h" ? 24 * 60 : 7 * 24 * 60;
114
+ return Date.now() - minutes * 60_000;
115
+ }
116
+ function runSearchText(run) {
117
+ return [
118
+ run.id,
119
+ run.workflowName,
120
+ run.trigger,
121
+ run.correlationId,
122
+ run.status,
123
+ ...run.tags,
124
+ run.error?.message,
125
+ run.error?.code,
126
+ run.input ? JSON.stringify(run.input) : null,
127
+ run.result ? JSON.stringify(run.result) : null,
128
+ ]
129
+ .filter(Boolean)
130
+ .join(" ")
131
+ .toLowerCase();
132
+ }
package/dist/i18n/en.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export * from "@voyantjs/workflow-runs-ui/i18n/en";
2
- export { workflowRunsUiEn as workflowsUiEn } from "@voyantjs/workflow-runs-ui/i18n/en";
1
+ import type { WorkflowRunsUiMessages } from "./messages.js";
2
+ export declare const workflowRunsUiEn: WorkflowRunsUiMessages;
3
+ export declare const workflowsUiEn: WorkflowRunsUiMessages;
3
4
  //# sourceMappingURL=en.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAA;AAElD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAA"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,eAAO,MAAM,gBAAgB,EAAE,sBAkG9B,CAAA;AAED,eAAO,MAAM,aAAa,wBAAmB,CAAA"}
package/dist/i18n/en.js CHANGED
@@ -1,2 +1,96 @@
1
- export * from "@voyantjs/workflow-runs-ui/i18n/en";
2
- export { workflowRunsUiEn as workflowsUiEn } from "@voyantjs/workflow-runs-ui/i18n/en";
1
+ export const workflowRunsUiEn = {
2
+ page: {
3
+ title: "Workflow runs",
4
+ subtitle: "Recent workflow executions and recorded steps.",
5
+ filterTitle: "Filter",
6
+ workflowLabel: "Workflow",
7
+ workflowPlaceholder: "checkout-finalize",
8
+ workflowEmpty: "No workflows in the visible runs.",
9
+ searchLabel: "Search",
10
+ searchPlaceholder: "Correlation, tag, error, input...",
11
+ statusLabel: "Status",
12
+ tagLabel: "Tag",
13
+ tagPlaceholder: "bookingId:bk_...",
14
+ tagEmpty: "No tags in the visible runs.",
15
+ addTag: "Add",
16
+ removeTag: "Remove tag",
17
+ timeRangeLabel: "Started",
18
+ live: "Live",
19
+ clearFilters: "Clear",
20
+ anyStatus: "Any",
21
+ empty: "No runs yet.",
22
+ selectPrompt: "Pick a run from the list to see its steps and payloads.",
23
+ loading: "Loading...",
24
+ loadError: "Could not load workflow runs.",
25
+ runCount: (count) => `${count} ${count === 1 ? "run" : "runs"}`,
26
+ filteredRunCount: (filtered, total) => filtered === total ? `${total} ${total === 1 ? "run" : "runs"}` : `${filtered}/${total} runs`,
27
+ timeRanges: {
28
+ "15m": "15m",
29
+ "1h": "1h",
30
+ "24h": "24h",
31
+ "7d": "7d",
32
+ all: "All",
33
+ },
34
+ },
35
+ status: {
36
+ running: "Running",
37
+ succeeded: "Succeeded",
38
+ failed: "Failed",
39
+ cancelled: "Cancelled",
40
+ },
41
+ stepStatus: {
42
+ running: "Running",
43
+ succeeded: "Succeeded",
44
+ failed: "Failed",
45
+ skipped: "Skipped",
46
+ compensated: "Compensated",
47
+ },
48
+ detail: {
49
+ trigger: "Trigger",
50
+ correlation: "Correlation",
51
+ parent: "Parent",
52
+ triggeredBy: "Triggered by",
53
+ tags: "Tags",
54
+ started: "Started",
55
+ finished: "Finished",
56
+ steps: "Steps",
57
+ noSteps: "No steps recorded.",
58
+ input: "Input",
59
+ output: "Output",
60
+ result: "Result",
61
+ runError: "Run error",
62
+ stackTrace: "Stack trace",
63
+ copy: "Copy",
64
+ copied: "Copied",
65
+ code: "code",
66
+ step: "step",
67
+ reruns: "Reruns of this run",
68
+ resumedAt: (step) => `resumed @ ${step}`,
69
+ durationUnavailable: "-",
70
+ },
71
+ actions: {
72
+ rerun: "Rerun",
73
+ rerunBusy: "Rerunning",
74
+ resume: "Resume from failed step",
75
+ resumeBusy: "Resuming",
76
+ waitForCompletion: "Wait for this run to finish before rerunning.",
77
+ rerunDescription: "Start a new run with the same recorded input.",
78
+ resumeDescription: "Skip already-completed steps and retry from the failed step.",
79
+ resumeUnavailable: "Resume is only available for failed runs.",
80
+ actionFailed: "Action failed.",
81
+ rerunStarted: "Rerun started; opening new run.",
82
+ resumeStarted: (step) => `Resumed from step "${step}"; opening new run.`,
83
+ runnerMissing: "No runner is registered for this workflow. Register a WorkflowRunner before rerun is available.",
84
+ rerunBlocked: "Rerun was blocked by the runner safety predicate.",
85
+ incompletePriorStep: "Cannot resume because an earlier step is incomplete.",
86
+ confirmTitle: "Confirm rerun",
87
+ confirmBody: "This workflow has side effects that re-fire on rerun. The new run starts from the first step with the same recorded input.",
88
+ confirmTip: "If the original failed mid-way, prefer Resume from failed step because it skips completed work.",
89
+ cancel: "Cancel",
90
+ rerunAnyway: "Rerun anyway",
91
+ },
92
+ format: {
93
+ relativeNow: "now",
94
+ },
95
+ };
96
+ export const workflowsUiEn = workflowRunsUiEn;
@@ -1,3 +1,5 @@
1
- export * from "@voyantjs/workflow-runs-ui/i18n";
2
- export { getWorkflowRunsUiI18n as getWorkflowsUiI18n, resolveWorkflowRunsUiMessages as resolveWorkflowsUiMessages, useWorkflowRunsUiI18n as useWorkflowsUiI18n, useWorkflowRunsUiI18nOrDefault as useWorkflowsUiI18nOrDefault, useWorkflowRunsUiMessages as useWorkflowsUiMessages, useWorkflowRunsUiMessagesOrDefault as useWorkflowsUiMessagesOrDefault, type WorkflowRunsUiMessageOverrides as WorkflowsUiMessageOverrides, type WorkflowRunsUiMessages as WorkflowsUiMessages, WorkflowRunsUiMessagesProvider as WorkflowsUiMessagesProvider, workflowRunsUiEn as workflowsUiEn, workflowRunsUiMessageDefinitions as workflowsUiMessageDefinitions, workflowRunsUiRo as workflowsUiRo, } from "@voyantjs/workflow-runs-ui/i18n";
1
+ export { workflowRunsUiEn, workflowRunsUiEn as workflowsUiEn } from "./en.js";
2
+ export type { WorkflowRunsUiMessages, WorkflowRunsUiMessages as WorkflowsUiMessages, } from "./messages.js";
3
+ export { getWorkflowRunsUiI18n, getWorkflowRunsUiI18n as getWorkflowsUiI18n, resolveWorkflowRunsUiMessages, resolveWorkflowRunsUiMessages as resolveWorkflowsUiMessages, useWorkflowRunsUiI18n, useWorkflowRunsUiI18n as useWorkflowsUiI18n, useWorkflowRunsUiI18nOrDefault, useWorkflowRunsUiI18nOrDefault as useWorkflowsUiI18nOrDefault, useWorkflowRunsUiMessages, useWorkflowRunsUiMessages as useWorkflowsUiMessages, useWorkflowRunsUiMessagesOrDefault, useWorkflowRunsUiMessagesOrDefault as useWorkflowsUiMessagesOrDefault, type WorkflowRunsUiMessageOverrides, type WorkflowRunsUiMessageOverrides as WorkflowsUiMessageOverrides, WorkflowRunsUiMessagesProvider, WorkflowRunsUiMessagesProvider as WorkflowsUiMessagesProvider, workflowRunsUiMessageDefinitions, workflowRunsUiMessageDefinitions as workflowsUiMessageDefinitions, } from "./provider.js";
4
+ export { workflowRunsUiRo, workflowRunsUiRo as workflowsUiRo } from "./ro.js";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAA;AAE/C,OAAO,EACL,qBAAqB,IAAI,kBAAkB,EAC3C,6BAA6B,IAAI,0BAA0B,EAC3D,qBAAqB,IAAI,kBAAkB,EAC3C,8BAA8B,IAAI,2BAA2B,EAC7D,yBAAyB,IAAI,sBAAsB,EACnD,kCAAkC,IAAI,+BAA+B,EACrE,KAAK,8BAA8B,IAAI,2BAA2B,EAClE,KAAK,sBAAsB,IAAI,mBAAmB,EAClD,8BAA8B,IAAI,2BAA2B,EAC7D,gBAAgB,IAAI,aAAa,EACjC,gCAAgC,IAAI,6BAA6B,EACjE,gBAAgB,IAAI,aAAa,GAClC,MAAM,iCAAiC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,IAAI,aAAa,EAAE,MAAM,SAAS,CAAA;AAC7E,YAAY,EACV,sBAAsB,EACtB,sBAAsB,IAAI,mBAAmB,GAC9C,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,IAAI,kBAAkB,EAC3C,6BAA6B,EAC7B,6BAA6B,IAAI,0BAA0B,EAC3D,qBAAqB,EACrB,qBAAqB,IAAI,kBAAkB,EAC3C,8BAA8B,EAC9B,8BAA8B,IAAI,2BAA2B,EAC7D,yBAAyB,EACzB,yBAAyB,IAAI,sBAAsB,EACnD,kCAAkC,EAClC,kCAAkC,IAAI,+BAA+B,EACrE,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,IAAI,2BAA2B,EAClE,8BAA8B,EAC9B,8BAA8B,IAAI,2BAA2B,EAC7D,gCAAgC,EAChC,gCAAgC,IAAI,6BAA6B,GAClE,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,IAAI,aAAa,EAAE,MAAM,SAAS,CAAA"}
@@ -1,2 +1,3 @@
1
- export * from "@voyantjs/workflow-runs-ui/i18n";
2
- export { getWorkflowRunsUiI18n as getWorkflowsUiI18n, resolveWorkflowRunsUiMessages as resolveWorkflowsUiMessages, useWorkflowRunsUiI18n as useWorkflowsUiI18n, useWorkflowRunsUiI18nOrDefault as useWorkflowsUiI18nOrDefault, useWorkflowRunsUiMessages as useWorkflowsUiMessages, useWorkflowRunsUiMessagesOrDefault as useWorkflowsUiMessagesOrDefault, WorkflowRunsUiMessagesProvider as WorkflowsUiMessagesProvider, workflowRunsUiEn as workflowsUiEn, workflowRunsUiMessageDefinitions as workflowsUiMessageDefinitions, workflowRunsUiRo as workflowsUiRo, } from "@voyantjs/workflow-runs-ui/i18n";
1
+ export { workflowRunsUiEn, workflowRunsUiEn as workflowsUiEn } from "./en.js";
2
+ export { getWorkflowRunsUiI18n, getWorkflowRunsUiI18n as getWorkflowsUiI18n, resolveWorkflowRunsUiMessages, resolveWorkflowRunsUiMessages as resolveWorkflowsUiMessages, useWorkflowRunsUiI18n, useWorkflowRunsUiI18n as useWorkflowsUiI18n, useWorkflowRunsUiI18nOrDefault, useWorkflowRunsUiI18nOrDefault as useWorkflowsUiI18nOrDefault, useWorkflowRunsUiMessages, useWorkflowRunsUiMessages as useWorkflowsUiMessages, useWorkflowRunsUiMessagesOrDefault, useWorkflowRunsUiMessagesOrDefault as useWorkflowsUiMessagesOrDefault, WorkflowRunsUiMessagesProvider, WorkflowRunsUiMessagesProvider as WorkflowsUiMessagesProvider, workflowRunsUiMessageDefinitions, workflowRunsUiMessageDefinitions as workflowsUiMessageDefinitions, } from "./provider.js";
3
+ export { workflowRunsUiRo, workflowRunsUiRo as workflowsUiRo } from "./ro.js";
@@ -0,0 +1,86 @@
1
+ import type { WorkflowRunStatus, WorkflowRunStepStatus } from "../types.js";
2
+ export type WorkflowRunsUiMessages = {
3
+ page: {
4
+ title: string;
5
+ subtitle: string;
6
+ filterTitle: string;
7
+ workflowLabel: string;
8
+ workflowPlaceholder: string;
9
+ workflowEmpty: string;
10
+ searchLabel: string;
11
+ searchPlaceholder: string;
12
+ statusLabel: string;
13
+ tagLabel: string;
14
+ tagPlaceholder: string;
15
+ tagEmpty: string;
16
+ addTag: string;
17
+ removeTag: string;
18
+ timeRangeLabel: string;
19
+ live: string;
20
+ clearFilters: string;
21
+ anyStatus: string;
22
+ empty: string;
23
+ selectPrompt: string;
24
+ loading: string;
25
+ loadError: string;
26
+ runCount: (count: number) => string;
27
+ filteredRunCount: (filtered: number, total: number) => string;
28
+ timeRanges: {
29
+ "15m": string;
30
+ "1h": string;
31
+ "24h": string;
32
+ "7d": string;
33
+ all: string;
34
+ };
35
+ };
36
+ status: Record<WorkflowRunStatus, string>;
37
+ stepStatus: Record<WorkflowRunStepStatus, string>;
38
+ detail: {
39
+ trigger: string;
40
+ correlation: string;
41
+ parent: string;
42
+ triggeredBy: string;
43
+ tags: string;
44
+ started: string;
45
+ finished: string;
46
+ steps: string;
47
+ noSteps: string;
48
+ input: string;
49
+ output: string;
50
+ result: string;
51
+ runError: string;
52
+ stackTrace: string;
53
+ copy: string;
54
+ copied: string;
55
+ code: string;
56
+ step: string;
57
+ reruns: string;
58
+ resumedAt: (step: string) => string;
59
+ durationUnavailable: string;
60
+ };
61
+ actions: {
62
+ rerun: string;
63
+ rerunBusy: string;
64
+ resume: string;
65
+ resumeBusy: string;
66
+ waitForCompletion: string;
67
+ rerunDescription: string;
68
+ resumeDescription: string;
69
+ resumeUnavailable: string;
70
+ actionFailed: string;
71
+ rerunStarted: string;
72
+ resumeStarted: (step: string) => string;
73
+ runnerMissing: string;
74
+ rerunBlocked: string;
75
+ incompletePriorStep: string;
76
+ confirmTitle: string;
77
+ confirmBody: string;
78
+ confirmTip: string;
79
+ cancel: string;
80
+ rerunAnyway: string;
81
+ };
82
+ format: {
83
+ relativeNow: string;
84
+ };
85
+ };
86
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/i18n/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { type LocaleMessageOverrides, type PackageI18nValue } from "@voyantjs/i18n";
2
+ import type { ReactNode } from "react";
3
+ import type { WorkflowRunsUiMessages } from "./messages.js";
4
+ export declare const workflowRunsUiMessageDefinitions: {
5
+ en: WorkflowRunsUiMessages;
6
+ ro: WorkflowRunsUiMessages;
7
+ };
8
+ export type WorkflowRunsUiMessageOverrides = LocaleMessageOverrides<WorkflowRunsUiMessages>;
9
+ export declare function resolveWorkflowRunsUiMessages({ locale, overrides, }: {
10
+ locale: string | null | undefined;
11
+ overrides?: WorkflowRunsUiMessageOverrides | null;
12
+ }): WorkflowRunsUiMessages;
13
+ export declare function getWorkflowRunsUiI18n({ locale, overrides, }: {
14
+ locale?: string | null | undefined;
15
+ overrides?: WorkflowRunsUiMessageOverrides | null;
16
+ }): PackageI18nValue<WorkflowRunsUiMessages>;
17
+ export declare function WorkflowRunsUiMessagesProvider({ children, locale, overrides, }: {
18
+ children: ReactNode;
19
+ locale: string | null | undefined;
20
+ overrides?: WorkflowRunsUiMessageOverrides | null;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ export declare const useWorkflowRunsUiI18n: () => PackageI18nValue<WorkflowRunsUiMessages>;
23
+ export declare const useWorkflowRunsUiMessages: () => WorkflowRunsUiMessages;
24
+ export declare function useWorkflowRunsUiI18nOrDefault(): PackageI18nValue<WorkflowRunsUiMessages>;
25
+ export declare function useWorkflowRunsUiMessagesOrDefault(): WorkflowRunsUiMessages;
26
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/i18n/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAK3D,eAAO,MAAM,gCAAgC;;;CAGe,CAAA;AAE5D,MAAM,MAAM,8BAA8B,GAAG,sBAAsB,CAAC,sBAAsB,CAAC,CAAA;AAU3F,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,EACN,SAAS,GACV,EAAE;IACD,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACjC,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,CAAA;CAClD,0BAOA;AAED,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,SAAS,GACV,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAClC,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,CAAA;CAClD,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAS3C;AAED,wBAAgB,8BAA8B,CAAC,EAC7C,QAAQ,EACR,MAAM,EACN,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACjC,SAAS,CAAC,EAAE,8BAA8B,GAAG,IAAI,CAAA;CAClD,2CAWA;AAED,eAAO,MAAM,qBAAqB,gDAAgC,CAAA;AAClE,eAAO,MAAM,yBAAyB,8BAAoC,CAAA;AAE1E,wBAAgB,8BAA8B,6CAE7C;AAED,wBAAgB,kCAAkC,2BAEjD"}
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createLocaleFormatters, createPackageMessagesContext, resolvePackageMessages, } from "@voyantjs/i18n";
4
+ import { workflowRunsUiEn } from "./en.js";
5
+ import { workflowRunsUiRo } from "./ro.js";
6
+ const fallbackLocale = "en";
7
+ export const workflowRunsUiMessageDefinitions = {
8
+ en: workflowRunsUiEn,
9
+ ro: workflowRunsUiRo,
10
+ };
11
+ const workflowRunsUiContext = createPackageMessagesContext("WorkflowRunsUiMessages");
12
+ const defaultWorkflowRunsUiI18n = {
13
+ messages: workflowRunsUiEn,
14
+ ...createLocaleFormatters(fallbackLocale),
15
+ };
16
+ export function resolveWorkflowRunsUiMessages({ locale, overrides, }) {
17
+ return resolvePackageMessages({
18
+ definitions: workflowRunsUiMessageDefinitions,
19
+ fallbackLocale,
20
+ locale,
21
+ overrides,
22
+ });
23
+ }
24
+ export function getWorkflowRunsUiI18n({ locale, overrides, }) {
25
+ const resolvedLocale = locale ?? fallbackLocale;
26
+ return {
27
+ messages: resolveWorkflowRunsUiMessages({
28
+ locale: resolvedLocale,
29
+ overrides,
30
+ }),
31
+ ...createLocaleFormatters(resolvedLocale),
32
+ };
33
+ }
34
+ export function WorkflowRunsUiMessagesProvider({ children, locale, overrides, }) {
35
+ return (_jsx(workflowRunsUiContext.ResolvedMessagesProvider, { definitions: workflowRunsUiMessageDefinitions, fallbackLocale: fallbackLocale, locale: locale, overrides: overrides, children: children }));
36
+ }
37
+ export const useWorkflowRunsUiI18n = workflowRunsUiContext.useI18n;
38
+ export const useWorkflowRunsUiMessages = workflowRunsUiContext.useMessages;
39
+ export function useWorkflowRunsUiI18nOrDefault() {
40
+ return workflowRunsUiContext.useOptionalI18n() ?? defaultWorkflowRunsUiI18n;
41
+ }
42
+ export function useWorkflowRunsUiMessagesOrDefault() {
43
+ return useWorkflowRunsUiI18nOrDefault().messages;
44
+ }
package/dist/i18n/ro.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export * from "@voyantjs/workflow-runs-ui/i18n/ro";
2
- export { workflowRunsUiRo as workflowsUiRo } from "@voyantjs/workflow-runs-ui/i18n/ro";
1
+ import type { WorkflowRunsUiMessages } from "./messages.js";
2
+ export declare const workflowRunsUiRo: WorkflowRunsUiMessages;
3
+ export declare const workflowsUiRo: WorkflowRunsUiMessages;
3
4
  //# sourceMappingURL=ro.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ro.d.ts","sourceRoot":"","sources":["../../src/i18n/ro.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAA;AAElD,OAAO,EAAE,gBAAgB,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAA"}
1
+ {"version":3,"file":"ro.d.ts","sourceRoot":"","sources":["../../src/i18n/ro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,eAAO,MAAM,gBAAgB,EAAE,sBAoG9B,CAAA;AAED,eAAO,MAAM,aAAa,wBAAmB,CAAA"}