@shipfox/client-workflows 12.0.2 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/preview.tsx +3 -3
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +56 -0
- package/dist/components/job-graph/job-duration-format.d.ts +2 -2
- package/dist/components/job-graph/job-duration-format.d.ts.map +1 -1
- package/dist/components/job-graph/job-duration-format.js +4 -2
- package/dist/components/job-graph/job-duration-format.js.map +1 -1
- package/dist/components/job-graph/job-node.d.ts +1 -1
- package/dist/components/job-graph/job-node.d.ts.map +1 -1
- package/dist/components/job-graph/job-node.js +5 -4
- package/dist/components/job-graph/job-node.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +2 -2
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.d.ts +21 -0
- package/dist/components/workflow-run-list/job-status-strip.d.ts.map +1 -0
- package/dist/components/workflow-run-list/job-status-strip.js +185 -0
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -0
- package/dist/components/workflow-run-list/run-display.d.ts +27 -3
- package/dist/components/workflow-run-list/run-display.d.ts.map +1 -1
- package/dist/components/workflow-run-list/run-display.js +78 -7
- package/dist/components/workflow-run-list/run-display.js.map +1 -1
- package/dist/components/workflow-run-list/types.d.ts +23 -24
- package/dist/components/workflow-run-list/types.d.ts.map +1 -1
- package/dist/components/workflow-run-list/types.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts +22 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js +68 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filters.d.ts +18 -0
- package/dist/components/workflow-run-list/workflow-run-filters.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filters.js +236 -0
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +8 -4
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-content.js +40 -12
- package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +29 -2
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -44
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +60 -43
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.d.ts +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.js +20 -8
- package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.d.ts +19 -9
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +179 -112
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-number-label.d.ts +15 -0
- package/dist/components/workflow-run-number-label.d.ts.map +1 -0
- package/dist/components/workflow-run-number-label.js +41 -0
- package/dist/components/workflow-run-number-label.js.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +3 -3
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +8 -7
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +3 -3
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +16 -7
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +2 -2
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/workflow-run-view/agent-config-failure-callout.js +4 -4
- package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -1
- package/dist/components/workflow-run-view/job-card.d.ts +2 -2
- package/dist/components/workflow-run-view/job-card.d.ts.map +1 -1
- package/dist/components/workflow-run-view/job-card.js +51 -32
- package/dist/components/workflow-run-view/job-card.js.map +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.js +20 -8
- package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts +3 -2
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +15 -11
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/components/workflow-status/status-visuals.d.ts +4 -4
- package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
- package/dist/components/workflow-status/status-visuals.js +7 -0
- package/dist/components/workflow-status/status-visuals.js.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.d.ts +3 -4
- package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.js +6 -4
- package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +10 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js +11 -0
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts +4 -2
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js +8 -1
- package/dist/core/entities/job.js.map +1 -1
- package/dist/core/entities/workflow-run.d.ts +52 -4
- package/dist/core/entities/workflow-run.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.js +22 -3
- package/dist/core/entities/workflow-run.js.map +1 -1
- package/dist/core/workflow-run.d.ts +6 -6
- package/dist/core/workflow-run.d.ts.map +1 -1
- package/dist/core/workflow-run.js +3 -3
- package/dist/core/workflow-run.js.map +1 -1
- package/dist/feature.d.ts +7 -7
- package/dist/feature.js +5 -5
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.d.ts +4 -3
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +31 -3
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/hooks/api/workflow-runs.d.ts +4 -4
- package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
- package/dist/hooks/api/workflow-runs.js +12 -4
- package/dist/hooks/api/workflow-runs.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/pages/project-workflows-page.js +46 -1
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-run-detail-page.d.ts +11 -0
- package/dist/pages/workflow-run-detail-page.d.ts.map +1 -0
- package/dist/pages/workflow-run-detail-page.js +30 -0
- package/dist/pages/workflow-run-detail-page.js.map +1 -0
- package/dist/pages/workflow-run-list-page.d.ts +10 -0
- package/dist/pages/workflow-run-list-page.d.ts.map +1 -0
- package/dist/pages/workflow-run-list-page.js +43 -0
- package/dist/pages/workflow-run-list-page.js.map +1 -0
- package/dist/routes/inputs.d.ts +61 -5
- package/dist/routes/inputs.d.ts.map +1 -1
- package/dist/routes/inputs.js +150 -13
- package/dist/routes/inputs.js.map +1 -1
- package/dist/routes/project-route.d.ts +6 -0
- package/dist/routes/project-route.d.ts.map +1 -0
- package/dist/routes/project-route.js +25 -0
- package/dist/routes/project-route.js.map +1 -0
- package/dist/routes/run-detail.d.ts.map +1 -1
- package/dist/routes/run-detail.js +12 -7
- package/dist/routes/run-detail.js.map +1 -1
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +11 -6
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +6 -5
- package/dist/routes/workflows.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/components/job-graph/job-duration-format.ts +11 -2
- package/src/components/job-graph/job-graph-view.test.tsx +19 -8
- package/src/components/job-graph/job-graph.stories.tsx +23 -19
- package/src/components/job-graph/job-node.stories.tsx +10 -5
- package/src/components/job-graph/job-node.test.tsx +55 -10
- package/src/components/job-graph/job-node.tsx +16 -9
- package/src/components/step-list/step-list.stories.tsx +2 -3
- package/src/components/step-list/step-list.tsx +3 -2
- package/src/components/workflow-run-list/job-status-strip.tsx +189 -0
- package/src/components/workflow-run-list/run-display.test.ts +169 -30
- package/src/components/workflow-run-list/run-display.ts +116 -9
- package/src/components/workflow-run-list/types.ts +21 -17
- package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +100 -0
- package/src/components/workflow-run-list/workflow-run-filters.tsx +243 -0
- package/src/components/workflow-run-list/workflow-run-list-content.tsx +44 -16
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +128 -27
- package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +441 -104
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +73 -43
- package/src/components/workflow-run-list/workflow-run-list.stories.tsx +140 -20
- package/src/components/workflow-run-list/workflow-run-list.tsx +20 -10
- package/src/components/workflow-run-list/workflow-run-row.tsx +173 -106
- package/src/components/workflow-run-number-label.test.tsx +45 -0
- package/src/components/workflow-run-number-label.tsx +47 -0
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +7 -8
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +13 -12
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +6 -8
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +27 -2
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +19 -9
- package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +2 -3
- package/src/components/workflow-run-view/agent-config-failure-callout.tsx +4 -4
- package/src/components/workflow-run-view/job-card.stories.tsx +11 -10
- package/src/components/workflow-run-view/job-card.test.tsx +115 -0
- package/src/components/workflow-run-view/job-card.tsx +74 -35
- package/src/components/workflow-run-view/job-execution-switcher.tsx +31 -9
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +88 -30
- package/src/components/workflow-run-view/workflow-run-view.tsx +24 -14
- package/src/components/workflow-status/status-visuals.test.ts +9 -0
- package/src/components/workflow-status/status-visuals.ts +6 -4
- package/src/components/workflow-status/workflow-status-icon.stories.tsx +10 -2
- package/src/components/workflow-status/workflow-status-icon.test.tsx +18 -0
- package/src/components/workflow-status/workflow-status-icon.tsx +17 -24
- package/src/core/entities/job-execution.ts +22 -0
- package/src/core/entities/job-status.test.ts +104 -0
- package/src/core/entities/job.ts +18 -3
- package/src/core/entities/workflow-run.ts +76 -7
- package/src/core/workflow-run.test.ts +24 -9
- package/src/core/workflow-run.ts +17 -2
- package/src/feature.ts +5 -5
- package/src/hooks/api/workflow-run-mapper.ts +30 -3
- package/src/hooks/api/workflow-runs.test.tsx +2 -0
- package/src/hooks/api/workflow-runs.ts +12 -7
- package/src/index.ts +7 -2
- package/src/page-harness-budget.test.ts +1 -1
- package/src/pages/project-workflows-page.test.tsx +59 -5
- package/src/pages/project-workflows-page.tsx +34 -1
- package/src/pages/workflow-run-detail-page.tsx +45 -0
- package/src/pages/workflow-run-list-page.tsx +65 -0
- package/src/pages/{workflow-run-page.test.tsx → workflow-run-pages.test.tsx} +211 -47
- package/src/routes/inputs.test.ts +193 -12
- package/src/routes/inputs.ts +170 -11
- package/src/routes/project-route.tsx +25 -0
- package/src/routes/run-detail.tsx +15 -8
- package/src/routes/runs.tsx +14 -7
- package/src/routes/workflows.tsx +5 -4
- package/test/fixtures/workflow-run.ts +76 -7
- package/test/pages.tsx +18 -8
- package/test/render.tsx +8 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +0 -10
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +0 -1
- package/dist/components/workflow-run-list/workflow-run-list-header.js +0 -55
- package/dist/components/workflow-run-list/workflow-run-list-header.js.map +0 -1
- package/dist/pages/workflow-run-first-time-use.d.ts +0 -6
- package/dist/pages/workflow-run-first-time-use.d.ts.map +0 -1
- package/dist/pages/workflow-run-first-time-use.js +0 -17
- package/dist/pages/workflow-run-first-time-use.js.map +0 -1
- package/dist/pages/workflow-run-page.d.ts +0 -10
- package/dist/pages/workflow-run-page.d.ts.map +0 -1
- package/dist/pages/workflow-run-page.js +0 -90
- package/dist/pages/workflow-run-page.js.map +0 -1
- package/src/components/workflow-run-list/workflow-run-list-header.tsx +0 -53
- package/src/pages/workflow-run-first-time-use.tsx +0 -17
- package/src/pages/workflow-run-page.tsx +0 -94
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
3
|
+
import { DateRangePicker } from '@shipfox/react-ui/date-range-picker';
|
|
4
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
5
|
+
import { Input } from '@shipfox/react-ui/input';
|
|
6
|
+
import { Label } from '@shipfox/react-ui/label';
|
|
7
|
+
import { Sheet, SheetBody, SheetContent, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from '@shipfox/react-ui/sheet';
|
|
8
|
+
import { useState } from 'react';
|
|
9
|
+
import { getWorkflowStatusVisual } from '#components/workflow-status/status-visuals.js';
|
|
10
|
+
import { WORKFLOW_RUN_LIST_STATUSES } from '#routes/inputs.js';
|
|
11
|
+
import { WorkflowRunFilterMenu } from './workflow-run-filter-menu.js';
|
|
12
|
+
const STATUS_OPTIONS = WORKFLOW_RUN_LIST_STATUSES.map((status)=>({
|
|
13
|
+
value: status,
|
|
14
|
+
label: getWorkflowStatusVisual(status).label
|
|
15
|
+
}));
|
|
16
|
+
/**
|
|
17
|
+
* The run list filter row.
|
|
18
|
+
*
|
|
19
|
+
* Inline from `md` up, and behind a sheet below it, where a five-control toolbar would eat
|
|
20
|
+
* the viewport the list is supposed to fill. Both layouts render the same controls, so the
|
|
21
|
+
* narrow surface is the full filter set rather than a reduced one.
|
|
22
|
+
*/ export function WorkflowRunFilters({ search, facets, onChange, onClear, hasActiveFilters }) {
|
|
23
|
+
const [sheetOpen, setSheetOpen] = useState(false);
|
|
24
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
25
|
+
className: "flex flex-wrap items-center gap-8",
|
|
26
|
+
children: [
|
|
27
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
28
|
+
value: search.search ?? '',
|
|
29
|
+
onChange: (event)=>onChange({
|
|
30
|
+
search: event.target.value
|
|
31
|
+
}),
|
|
32
|
+
placeholder: "Search runs by name, number, branch, or commit",
|
|
33
|
+
"aria-label": "Search runs",
|
|
34
|
+
size: "small",
|
|
35
|
+
className: "min-w-[240px] flex-1",
|
|
36
|
+
iconLeft: /*#__PURE__*/ _jsx(Icon, {
|
|
37
|
+
name: "searchLine",
|
|
38
|
+
className: "size-14 text-foreground-neutral-muted"
|
|
39
|
+
})
|
|
40
|
+
}),
|
|
41
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
42
|
+
className: "hidden flex-wrap items-center gap-8 md:flex",
|
|
43
|
+
children: [
|
|
44
|
+
/*#__PURE__*/ _jsx(WorkflowRunFilterControls, {
|
|
45
|
+
search: search,
|
|
46
|
+
facets: facets,
|
|
47
|
+
onChange: onChange
|
|
48
|
+
}),
|
|
49
|
+
hasActiveFilters ? /*#__PURE__*/ _jsx(ClearFiltersButton, {
|
|
50
|
+
onClear: onClear
|
|
51
|
+
}) : null
|
|
52
|
+
]
|
|
53
|
+
}),
|
|
54
|
+
/*#__PURE__*/ _jsxs(Sheet, {
|
|
55
|
+
open: sheetOpen,
|
|
56
|
+
onOpenChange: setSheetOpen,
|
|
57
|
+
children: [
|
|
58
|
+
/*#__PURE__*/ _jsx(SheetTrigger, {
|
|
59
|
+
asChild: true,
|
|
60
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
61
|
+
type: "button",
|
|
62
|
+
variant: "secondary",
|
|
63
|
+
size: "sm",
|
|
64
|
+
iconLeft: "filterLine",
|
|
65
|
+
className: "md:hidden",
|
|
66
|
+
children: "Filters"
|
|
67
|
+
})
|
|
68
|
+
}),
|
|
69
|
+
/*#__PURE__*/ _jsxs(SheetContent, {
|
|
70
|
+
side: "bottom",
|
|
71
|
+
"aria-describedby": undefined,
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ _jsx(SheetHeader, {
|
|
74
|
+
children: /*#__PURE__*/ _jsx(SheetTitle, {
|
|
75
|
+
children: "Filter runs"
|
|
76
|
+
})
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ _jsx(SheetBody, {
|
|
79
|
+
className: "flex flex-col gap-12",
|
|
80
|
+
children: /*#__PURE__*/ _jsx(WorkflowRunFilterControls, {
|
|
81
|
+
search: search,
|
|
82
|
+
facets: facets,
|
|
83
|
+
onChange: onChange,
|
|
84
|
+
stacked: true
|
|
85
|
+
})
|
|
86
|
+
}),
|
|
87
|
+
/*#__PURE__*/ _jsxs(SheetFooter, {
|
|
88
|
+
children: [
|
|
89
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
90
|
+
type: "button",
|
|
91
|
+
variant: "secondary",
|
|
92
|
+
size: "sm",
|
|
93
|
+
disabled: !hasActiveFilters,
|
|
94
|
+
onClick: onClear,
|
|
95
|
+
children: "Clear filters"
|
|
96
|
+
}),
|
|
97
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
98
|
+
type: "button",
|
|
99
|
+
variant: "primary",
|
|
100
|
+
size: "sm",
|
|
101
|
+
onClick: ()=>setSheetOpen(false),
|
|
102
|
+
children: "Show runs"
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function WorkflowRunFilterControls({ search, facets, onChange, stacked = false }) {
|
|
114
|
+
const controlClassName = stacked ? 'w-full max-w-none' : undefined;
|
|
115
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ _jsx(WorkflowRunFilterMenu, {
|
|
118
|
+
label: "Status",
|
|
119
|
+
options: STATUS_OPTIONS,
|
|
120
|
+
selected: search.status ?? [],
|
|
121
|
+
onChange: (next)=>onChange({
|
|
122
|
+
status: next
|
|
123
|
+
}),
|
|
124
|
+
emptyMessage: "No statuses available.",
|
|
125
|
+
className: controlClassName
|
|
126
|
+
}),
|
|
127
|
+
/*#__PURE__*/ _jsx(WorkflowRunFilterMenu, {
|
|
128
|
+
label: "Branch",
|
|
129
|
+
options: toOptions(facets.branch),
|
|
130
|
+
selected: search.branch ?? [],
|
|
131
|
+
onChange: (branch)=>onChange({
|
|
132
|
+
branch
|
|
133
|
+
}),
|
|
134
|
+
emptyMessage: "No branches in the loaded runs.",
|
|
135
|
+
className: controlClassName
|
|
136
|
+
}),
|
|
137
|
+
/*#__PURE__*/ _jsx(WorkflowRunFilterMenu, {
|
|
138
|
+
label: "Actor",
|
|
139
|
+
options: toOptions(facets.actor),
|
|
140
|
+
selected: search.actor ?? [],
|
|
141
|
+
onChange: (actor)=>onChange({
|
|
142
|
+
actor
|
|
143
|
+
}),
|
|
144
|
+
emptyMessage: "No actors in the loaded runs.",
|
|
145
|
+
className: controlClassName
|
|
146
|
+
}),
|
|
147
|
+
/*#__PURE__*/ _jsx(WorkflowRunFilterMenu, {
|
|
148
|
+
label: "Event",
|
|
149
|
+
options: toOptions(facets.event),
|
|
150
|
+
selected: search.event ?? [],
|
|
151
|
+
onChange: (event)=>onChange({
|
|
152
|
+
event
|
|
153
|
+
}),
|
|
154
|
+
emptyMessage: "No events in the loaded runs.",
|
|
155
|
+
className: controlClassName
|
|
156
|
+
}),
|
|
157
|
+
stacked ? /*#__PURE__*/ _jsxs("div", {
|
|
158
|
+
className: "flex flex-col gap-6",
|
|
159
|
+
children: [
|
|
160
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
161
|
+
children: "Created between"
|
|
162
|
+
}),
|
|
163
|
+
/*#__PURE__*/ _jsx(RunDateRangeFilter, {
|
|
164
|
+
search: search,
|
|
165
|
+
onChange: onChange
|
|
166
|
+
})
|
|
167
|
+
]
|
|
168
|
+
}) : /*#__PURE__*/ _jsx(RunDateRangeFilter, {
|
|
169
|
+
search: search,
|
|
170
|
+
onChange: onChange
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function RunDateRangeFilter({ search, onChange }) {
|
|
176
|
+
return /*#__PURE__*/ _jsx(DateRangePicker, {
|
|
177
|
+
size: "small",
|
|
178
|
+
"aria-label": "Filter runs by creation date",
|
|
179
|
+
// The shared picker renders a value only when both bounds are set, so a one-sided filter
|
|
180
|
+
// would otherwise read as unset. Naming the active bound keeps it visible without
|
|
181
|
+
// inventing the bound the user did not choose.
|
|
182
|
+
placeholder: partialDateLabel(search) ?? 'Any date',
|
|
183
|
+
dateRange: {
|
|
184
|
+
...search.after ? {
|
|
185
|
+
start: fromCalendarDate(search.after)
|
|
186
|
+
} : {},
|
|
187
|
+
...search.before ? {
|
|
188
|
+
end: fromCalendarDate(search.before)
|
|
189
|
+
} : {}
|
|
190
|
+
},
|
|
191
|
+
onDateRangeSelect: (range)=>onChange({
|
|
192
|
+
after: range?.start ? toCalendarDate(range.start) : undefined,
|
|
193
|
+
before: range?.end ? toCalendarDate(range.end) : undefined
|
|
194
|
+
}),
|
|
195
|
+
onClear: ()=>onChange({
|
|
196
|
+
after: undefined,
|
|
197
|
+
before: undefined
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function ClearFiltersButton({ onClear }) {
|
|
202
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
203
|
+
type: "button",
|
|
204
|
+
variant: "transparentMuted",
|
|
205
|
+
size: "sm",
|
|
206
|
+
iconLeft: "closeLine",
|
|
207
|
+
onClick: onClear,
|
|
208
|
+
children: "Clear filters"
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/** Describes a bound the picker cannot display on its own, or nothing when it can. */ function partialDateLabel(search) {
|
|
212
|
+
if (search.after && search.before) return undefined;
|
|
213
|
+
if (search.after) return `From ${search.after}`;
|
|
214
|
+
if (search.before) return `Until ${search.before}`;
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
function toOptions(values) {
|
|
218
|
+
return values.map((value)=>({
|
|
219
|
+
value,
|
|
220
|
+
label: value
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
// The bounds are local calendar dates, matching how each row's date reads, so the picker and
|
|
224
|
+
// the URL agree with what the list shows rather than with UTC.
|
|
225
|
+
function toCalendarDate(date) {
|
|
226
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
227
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
228
|
+
return `${date.getFullYear()}-${month}-${day}`;
|
|
229
|
+
}
|
|
230
|
+
function fromCalendarDate(value) {
|
|
231
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
232
|
+
const date = new Date(year, month - 1, day);
|
|
233
|
+
return Number.isNaN(date.getTime()) ? undefined : date;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
//# sourceMappingURL=workflow-run-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-filters.tsx"],"sourcesContent":["import {Button} from '@shipfox/react-ui/button';\nimport {DateRangePicker} from '@shipfox/react-ui/date-range-picker';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Input} from '@shipfox/react-ui/input';\nimport {Label} from '@shipfox/react-ui/label';\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from '@shipfox/react-ui/sheet';\nimport {useState} from 'react';\nimport {getWorkflowStatusVisual} from '#components/workflow-status/status-visuals.js';\nimport {\n WORKFLOW_RUN_LIST_STATUSES,\n type WorkflowRunFilterPatch,\n type WorkflowRunListStatus,\n type WorkflowRunsSearch,\n} from '#routes/inputs.js';\nimport type {WorkflowRunFacets} from './run-display.js';\nimport {WorkflowRunFilterMenu, type WorkflowRunFilterOption} from './workflow-run-filter-menu.js';\n\nconst STATUS_OPTIONS: WorkflowRunFilterOption[] = WORKFLOW_RUN_LIST_STATUSES.map((status) => ({\n value: status,\n label: getWorkflowStatusVisual(status).label,\n}));\n\nexport interface WorkflowRunFiltersProps {\n search: WorkflowRunsSearch;\n facets: WorkflowRunFacets;\n onChange: (patch: WorkflowRunFilterPatch) => void;\n onClear: () => void;\n hasActiveFilters: boolean;\n}\n\n/**\n * The run list filter row.\n *\n * Inline from `md` up, and behind a sheet below it, where a five-control toolbar would eat\n * the viewport the list is supposed to fill. Both layouts render the same controls, so the\n * narrow surface is the full filter set rather than a reduced one.\n */\nexport function WorkflowRunFilters({\n search,\n facets,\n onChange,\n onClear,\n hasActiveFilters,\n}: WorkflowRunFiltersProps) {\n const [sheetOpen, setSheetOpen] = useState(false);\n\n return (\n <div className=\"flex flex-wrap items-center gap-8\">\n <Input\n value={search.search ?? ''}\n onChange={(event) => onChange({search: event.target.value})}\n placeholder=\"Search runs by name, number, branch, or commit\"\n aria-label=\"Search runs\"\n size=\"small\"\n className=\"min-w-[240px] flex-1\"\n iconLeft={<Icon name=\"searchLine\" className=\"size-14 text-foreground-neutral-muted\" />}\n />\n\n <div className=\"hidden flex-wrap items-center gap-8 md:flex\">\n <WorkflowRunFilterControls search={search} facets={facets} onChange={onChange} />\n {hasActiveFilters ? <ClearFiltersButton onClear={onClear} /> : null}\n </div>\n\n <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <SheetTrigger asChild>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n iconLeft=\"filterLine\"\n className=\"md:hidden\"\n >\n Filters\n </Button>\n </SheetTrigger>\n <SheetContent side=\"bottom\" aria-describedby={undefined}>\n <SheetHeader>\n <SheetTitle>Filter runs</SheetTitle>\n </SheetHeader>\n <SheetBody className=\"flex flex-col gap-12\">\n <WorkflowRunFilterControls\n search={search}\n facets={facets}\n onChange={onChange}\n stacked\n />\n </SheetBody>\n <SheetFooter>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n disabled={!hasActiveFilters}\n onClick={onClear}\n >\n Clear filters\n </Button>\n <Button type=\"button\" variant=\"primary\" size=\"sm\" onClick={() => setSheetOpen(false)}>\n Show runs\n </Button>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n </div>\n );\n}\n\nfunction WorkflowRunFilterControls({\n search,\n facets,\n onChange,\n stacked = false,\n}: {\n search: WorkflowRunsSearch;\n facets: WorkflowRunFacets;\n onChange: (patch: WorkflowRunFilterPatch) => void;\n stacked?: boolean;\n}) {\n const controlClassName = stacked ? 'w-full max-w-none' : undefined;\n\n return (\n <>\n <WorkflowRunFilterMenu\n label=\"Status\"\n options={STATUS_OPTIONS}\n selected={search.status ?? []}\n onChange={(next) => onChange({status: next as WorkflowRunListStatus[]})}\n emptyMessage=\"No statuses available.\"\n className={controlClassName}\n />\n <WorkflowRunFilterMenu\n label=\"Branch\"\n options={toOptions(facets.branch)}\n selected={search.branch ?? []}\n onChange={(branch) => onChange({branch})}\n emptyMessage=\"No branches in the loaded runs.\"\n className={controlClassName}\n />\n <WorkflowRunFilterMenu\n label=\"Actor\"\n options={toOptions(facets.actor)}\n selected={search.actor ?? []}\n onChange={(actor) => onChange({actor})}\n emptyMessage=\"No actors in the loaded runs.\"\n className={controlClassName}\n />\n <WorkflowRunFilterMenu\n label=\"Event\"\n options={toOptions(facets.event)}\n selected={search.event ?? []}\n onChange={(event) => onChange({event})}\n emptyMessage=\"No events in the loaded runs.\"\n className={controlClassName}\n />\n {stacked ? (\n <div className=\"flex flex-col gap-6\">\n <Label>Created between</Label>\n <RunDateRangeFilter search={search} onChange={onChange} />\n </div>\n ) : (\n <RunDateRangeFilter search={search} onChange={onChange} />\n )}\n </>\n );\n}\n\nfunction RunDateRangeFilter({\n search,\n onChange,\n}: {\n search: WorkflowRunsSearch;\n onChange: (patch: WorkflowRunFilterPatch) => void;\n}) {\n return (\n <DateRangePicker\n size=\"small\"\n aria-label=\"Filter runs by creation date\"\n // The shared picker renders a value only when both bounds are set, so a one-sided filter\n // would otherwise read as unset. Naming the active bound keeps it visible without\n // inventing the bound the user did not choose.\n placeholder={partialDateLabel(search) ?? 'Any date'}\n dateRange={{\n ...(search.after ? {start: fromCalendarDate(search.after)} : {}),\n ...(search.before ? {end: fromCalendarDate(search.before)} : {}),\n }}\n onDateRangeSelect={(range) =>\n onChange({\n after: range?.start ? toCalendarDate(range.start) : undefined,\n before: range?.end ? toCalendarDate(range.end) : undefined,\n })\n }\n onClear={() => onChange({after: undefined, before: undefined})}\n />\n );\n}\n\nfunction ClearFiltersButton({onClear}: {onClear: () => void}) {\n return (\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"sm\"\n iconLeft=\"closeLine\"\n onClick={onClear}\n >\n Clear filters\n </Button>\n );\n}\n\n/** Describes a bound the picker cannot display on its own, or nothing when it can. */\nfunction partialDateLabel(search: WorkflowRunsSearch): string | undefined {\n if (search.after && search.before) return undefined;\n if (search.after) return `From ${search.after}`;\n if (search.before) return `Until ${search.before}`;\n return undefined;\n}\n\nfunction toOptions(values: readonly string[]): WorkflowRunFilterOption[] {\n return values.map((value) => ({value, label: value}));\n}\n\n// The bounds are local calendar dates, matching how each row's date reads, so the picker and\n// the URL agree with what the list shows rather than with UTC.\nfunction toCalendarDate(date: Date): string {\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n}\n\nfunction fromCalendarDate(value: string): Date | undefined {\n const [year, month, day] = value.split('-').map(Number) as [number, number, number];\n const date = new Date(year, month - 1, day);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n"],"names":["Button","DateRangePicker","Icon","Input","Label","Sheet","SheetBody","SheetContent","SheetFooter","SheetHeader","SheetTitle","SheetTrigger","useState","getWorkflowStatusVisual","WORKFLOW_RUN_LIST_STATUSES","WorkflowRunFilterMenu","STATUS_OPTIONS","map","status","value","label","WorkflowRunFilters","search","facets","onChange","onClear","hasActiveFilters","sheetOpen","setSheetOpen","div","className","event","target","placeholder","aria-label","size","iconLeft","name","WorkflowRunFilterControls","ClearFiltersButton","open","onOpenChange","asChild","type","variant","side","aria-describedby","undefined","stacked","disabled","onClick","controlClassName","options","selected","next","emptyMessage","toOptions","branch","actor","RunDateRangeFilter","partialDateLabel","dateRange","after","start","fromCalendarDate","before","end","onDateRangeSelect","range","toCalendarDate","values","date","month","String","getMonth","padStart","day","getDate","getFullYear","year","split","Number","Date","isNaN","getTime"],"mappings":"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"}
|
|
@@ -4,11 +4,15 @@ interface WorkflowRunListContentProps {
|
|
|
4
4
|
query: WorkflowRunListQuery;
|
|
5
5
|
totalRuns: number;
|
|
6
6
|
runs: WorkflowRunListItem[];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
workspaceSlug?: string | undefined;
|
|
8
|
+
projectSlug?: string | undefined;
|
|
9
|
+
hasActiveFilters: boolean;
|
|
10
10
|
onClearFilters: () => void;
|
|
11
|
+
hasNextPage: boolean;
|
|
12
|
+
isFetchingNextPage: boolean;
|
|
13
|
+
isFetchNextPageError: boolean;
|
|
14
|
+
onLoadMore?: () => void;
|
|
11
15
|
}
|
|
12
|
-
export declare function WorkflowRunListContent({ query, totalRuns, runs,
|
|
16
|
+
export declare function WorkflowRunListContent({ query, totalRuns, runs, workspaceSlug, projectSlug, hasActiveFilters, onClearFilters, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore, }: WorkflowRunListContentProps): import("react").JSX.Element;
|
|
13
17
|
export {};
|
|
14
18
|
//# sourceMappingURL=workflow-run-list-content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-run-list-content.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-list-content.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-run-list-content.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-list-content.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,YAAY,CAAC;AAUrD,UAAU,2BAA2B;IACnC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,KAAK,EACL,SAAS,EACT,IAAI,EACJ,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,EAAE,2BAA2B,+BA+C7B"}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { QueryLoadError } from '@shipfox/client-ui';
|
|
3
|
-
import { WorkflowRunListEmpty, WorkflowRunListNoMatches, WorkflowRunListSkeleton, WorkflowRunListStaleError } from './workflow-run-list-states.js';
|
|
3
|
+
import { WorkflowRunListEmpty, WorkflowRunListLoadMore, WorkflowRunListNoMatches, WorkflowRunListSkeleton, WorkflowRunListStaleError } from './workflow-run-list-states.js';
|
|
4
4
|
import { WorkflowRunRowList } from './workflow-run-row.js';
|
|
5
|
-
export function WorkflowRunListContent({ query, totalRuns, runs,
|
|
5
|
+
export function WorkflowRunListContent({ query, totalRuns, runs, workspaceSlug, projectSlug, hasActiveFilters, onClearFilters, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
6
6
|
const { isPending, isError } = query;
|
|
7
7
|
// A refetch that fails after a prior success keeps the rows on screen behind a slim
|
|
8
8
|
// banner. QueryLoadError owns the inverse case (errored before anything loaded) and
|
|
9
|
-
// self-gates to nothing here once data exists.
|
|
9
|
+
// self-gates to nothing here once data exists. A failed fetch never renders as an empty
|
|
10
|
+
// list: "nothing here" and "we could not find out" are different answers.
|
|
10
11
|
const refreshFailed = isError && query.data !== undefined;
|
|
12
|
+
// Keyed off "we have an answer" rather than "no error", so a stale refresh still reports
|
|
13
|
+
// whether the filters match anything instead of leaving the list blank under the banner.
|
|
14
|
+
const hasLoaded = !isPending && query.data !== undefined;
|
|
15
|
+
// An empty result is only an empty *list* when no filter is on. With filters active it is a
|
|
16
|
+
// no-matches state even at zero loaded runs, so the way out is clearing them.
|
|
17
|
+
const showEmptyState = hasLoaded && totalRuns === 0 && !hasActiveFilters;
|
|
18
|
+
const showNoMatches = hasLoaded && runs.length === 0 && !showEmptyState;
|
|
11
19
|
return /*#__PURE__*/ _jsxs("div", {
|
|
12
20
|
className: "min-h-0 flex-1 overflow-y-auto",
|
|
13
21
|
children: [
|
|
@@ -20,15 +28,35 @@ export function WorkflowRunListContent({ query, totalRuns, runs, workspaceId, pr
|
|
|
20
28
|
!isPending && refreshFailed ? /*#__PURE__*/ _jsx(WorkflowRunListStaleError, {
|
|
21
29
|
query: query
|
|
22
30
|
}) : null,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
showEmptyState ? /*#__PURE__*/ _jsx(WorkflowRunListEmpty, {
|
|
32
|
+
workspaceSlug: workspaceSlug,
|
|
33
|
+
projectSlug: projectSlug
|
|
26
34
|
}) : null,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
showNoMatches ? /*#__PURE__*/ _jsx(WorkflowRunListNoMatches, {
|
|
36
|
+
onClear: onClearFilters,
|
|
37
|
+
hasNextPage: hasNextPage,
|
|
38
|
+
isFetchingNextPage: isFetchingNextPage,
|
|
39
|
+
isFetchNextPageError: isFetchNextPageError,
|
|
40
|
+
...onLoadMore ? {
|
|
41
|
+
onLoadMore
|
|
42
|
+
} : {}
|
|
43
|
+
}) : null,
|
|
44
|
+
!isPending && runs.length > 0 ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
45
|
+
children: [
|
|
46
|
+
/*#__PURE__*/ _jsx(WorkflowRunRowList, {
|
|
47
|
+
runs: runs,
|
|
48
|
+
workspaceSlug: workspaceSlug,
|
|
49
|
+
projectSlug: projectSlug
|
|
50
|
+
}),
|
|
51
|
+
/*#__PURE__*/ _jsx(WorkflowRunListLoadMore, {
|
|
52
|
+
hasNextPage: hasNextPage,
|
|
53
|
+
isFetchingNextPage: isFetchingNextPage,
|
|
54
|
+
isFetchNextPageError: isFetchNextPageError,
|
|
55
|
+
...onLoadMore ? {
|
|
56
|
+
onLoadMore
|
|
57
|
+
} : {}
|
|
58
|
+
})
|
|
59
|
+
]
|
|
32
60
|
}) : null
|
|
33
61
|
]
|
|
34
62
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-content.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport type {WorkflowRunListItem} from '#core/workflow-run.js';\nimport type {WorkflowRunListQuery} from './types.js';\nimport {\n WorkflowRunListEmpty,\n WorkflowRunListNoMatches,\n WorkflowRunListSkeleton,\n WorkflowRunListStaleError,\n} from './workflow-run-list-states.js';\nimport {WorkflowRunRowList} from './workflow-run-row.js';\n\ninterface WorkflowRunListContentProps {\n query: WorkflowRunListQuery;\n totalRuns: number;\n runs: WorkflowRunListItem[];\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-content.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport type {WorkflowRunListItem} from '#core/workflow-run.js';\nimport type {WorkflowRunListQuery} from './types.js';\nimport {\n WorkflowRunListEmpty,\n WorkflowRunListLoadMore,\n WorkflowRunListNoMatches,\n WorkflowRunListSkeleton,\n WorkflowRunListStaleError,\n} from './workflow-run-list-states.js';\nimport {WorkflowRunRowList} from './workflow-run-row.js';\n\ninterface WorkflowRunListContentProps {\n query: WorkflowRunListQuery;\n totalRuns: number;\n runs: WorkflowRunListItem[];\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n isFetchNextPageError: boolean;\n onLoadMore?: () => void;\n}\n\nexport function WorkflowRunListContent({\n query,\n totalRuns,\n runs,\n workspaceSlug,\n projectSlug,\n hasActiveFilters,\n onClearFilters,\n hasNextPage,\n isFetchingNextPage,\n isFetchNextPageError,\n onLoadMore,\n}: WorkflowRunListContentProps) {\n const {isPending, isError} = query;\n // A refetch that fails after a prior success keeps the rows on screen behind a slim\n // banner. QueryLoadError owns the inverse case (errored before anything loaded) and\n // self-gates to nothing here once data exists. A failed fetch never renders as an empty\n // list: \"nothing here\" and \"we could not find out\" are different answers.\n const refreshFailed = isError && query.data !== undefined;\n // Keyed off \"we have an answer\" rather than \"no error\", so a stale refresh still reports\n // whether the filters match anything instead of leaving the list blank under the banner.\n const hasLoaded = !isPending && query.data !== undefined;\n // An empty result is only an empty *list* when no filter is on. With filters active it is a\n // no-matches state even at zero loaded runs, so the way out is clearing them.\n const showEmptyState = hasLoaded && totalRuns === 0 && !hasActiveFilters;\n const showNoMatches = hasLoaded && runs.length === 0 && !showEmptyState;\n\n return (\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {isPending ? <WorkflowRunListSkeleton /> : null}\n {!isPending ? (\n <QueryLoadError query={query} subject=\"workflow runs\" icon=\"pulseLine\" />\n ) : null}\n {!isPending && refreshFailed ? <WorkflowRunListStaleError query={query} /> : null}\n {showEmptyState ? (\n <WorkflowRunListEmpty workspaceSlug={workspaceSlug} projectSlug={projectSlug} />\n ) : null}\n {showNoMatches ? (\n <WorkflowRunListNoMatches\n onClear={onClearFilters}\n hasNextPage={hasNextPage}\n isFetchingNextPage={isFetchingNextPage}\n isFetchNextPageError={isFetchNextPageError}\n {...(onLoadMore ? {onLoadMore} : {})}\n />\n ) : null}\n {!isPending && runs.length > 0 ? (\n <>\n <WorkflowRunRowList runs={runs} workspaceSlug={workspaceSlug} projectSlug={projectSlug} />\n <WorkflowRunListLoadMore\n hasNextPage={hasNextPage}\n isFetchingNextPage={isFetchingNextPage}\n isFetchNextPageError={isFetchNextPageError}\n {...(onLoadMore ? {onLoadMore} : {})}\n />\n </>\n ) : null}\n </div>\n );\n}\n"],"names":["QueryLoadError","WorkflowRunListEmpty","WorkflowRunListLoadMore","WorkflowRunListNoMatches","WorkflowRunListSkeleton","WorkflowRunListStaleError","WorkflowRunRowList","WorkflowRunListContent","query","totalRuns","runs","workspaceSlug","projectSlug","hasActiveFilters","onClearFilters","hasNextPage","isFetchingNextPage","isFetchNextPageError","onLoadMore","isPending","isError","refreshFailed","data","undefined","hasLoaded","showEmptyState","showNoMatches","length","div","className","subject","icon","onClear"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAGlD,SACEC,oBAAoB,EACpBC,uBAAuB,EACvBC,wBAAwB,EACxBC,uBAAuB,EACvBC,yBAAyB,QACpB,gCAAgC;AACvC,SAAQC,kBAAkB,QAAO,wBAAwB;AAgBzD,OAAO,SAASC,uBAAuB,EACrCC,KAAK,EACLC,SAAS,EACTC,IAAI,EACJC,aAAa,EACbC,WAAW,EACXC,gBAAgB,EAChBC,cAAc,EACdC,WAAW,EACXC,kBAAkB,EAClBC,oBAAoB,EACpBC,UAAU,EACkB;IAC5B,MAAM,EAACC,SAAS,EAAEC,OAAO,EAAC,GAAGZ;IAC7B,oFAAoF;IACpF,oFAAoF;IACpF,wFAAwF;IACxF,0EAA0E;IAC1E,MAAMa,gBAAgBD,WAAWZ,MAAMc,IAAI,KAAKC;IAChD,yFAAyF;IACzF,yFAAyF;IACzF,MAAMC,YAAY,CAACL,aAAaX,MAAMc,IAAI,KAAKC;IAC/C,4FAA4F;IAC5F,8EAA8E;IAC9E,MAAME,iBAAiBD,aAAaf,cAAc,KAAK,CAACI;IACxD,MAAMa,gBAAgBF,aAAad,KAAKiB,MAAM,KAAK,KAAK,CAACF;IAEzD,qBACE,MAACG;QAAIC,WAAU;;YACZV,0BAAY,KAACf,+BAA6B;YAC1C,CAACe,0BACA,KAACnB;gBAAeQ,OAAOA;gBAAOsB,SAAQ;gBAAgBC,MAAK;iBACzD;YACH,CAACZ,aAAaE,8BAAgB,KAAChB;gBAA0BG,OAAOA;iBAAY;YAC5EiB,+BACC,KAACxB;gBAAqBU,eAAeA;gBAAeC,aAAaA;iBAC/D;YACHc,8BACC,KAACvB;gBACC6B,SAASlB;gBACTC,aAAaA;gBACbC,oBAAoBA;gBACpBC,sBAAsBA;gBACrB,GAAIC,aAAa;oBAACA;gBAAU,IAAI,CAAC,CAAC;iBAEnC;YACH,CAACC,aAAaT,KAAKiB,MAAM,GAAG,kBAC3B;;kCACE,KAACrB;wBAAmBI,MAAMA;wBAAMC,eAAeA;wBAAeC,aAAaA;;kCAC3E,KAACV;wBACCa,aAAaA;wBACbC,oBAAoBA;wBACpBC,sBAAsBA;wBACrB,GAAIC,aAAa;4BAACA;wBAAU,IAAI,CAAC,CAAC;;;iBAGrC;;;AAGV"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { QueryLoadErrorQuery } from '@shipfox/client-ui';
|
|
2
|
+
/**
|
|
3
|
+
* Placeholder rows at the real row height, so the list does not resize under the cursor when
|
|
4
|
+
* the first page lands. Only the initial load renders these: a refetch keeps the rows it has,
|
|
5
|
+
* per the design system's rule against animating frequently-updating data.
|
|
6
|
+
*/
|
|
2
7
|
export declare function WorkflowRunListSkeleton(): import("react").JSX.Element;
|
|
3
8
|
/**
|
|
4
9
|
* Slim non-blocking banner shown when a background refetch fails after a prior success,
|
|
@@ -8,8 +13,30 @@ export declare function WorkflowRunListSkeleton(): import("react").JSX.Element;
|
|
|
8
13
|
export declare function WorkflowRunListStaleError({ query }: {
|
|
9
14
|
query: QueryLoadErrorQuery;
|
|
10
15
|
}): import("react").JSX.Element;
|
|
11
|
-
export declare function WorkflowRunListEmpty(
|
|
12
|
-
|
|
16
|
+
export declare function WorkflowRunListEmpty({ workspaceSlug, projectSlug, }: {
|
|
17
|
+
workspaceSlug?: string | undefined;
|
|
18
|
+
projectSlug?: string | undefined;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* The filtered-empty state, deliberately distinct from the unfiltered one: someone who
|
|
22
|
+
* filtered their way to nothing needs a way back out, not an onboarding call to action.
|
|
23
|
+
*
|
|
24
|
+
* Its reset is worded as its outcome rather than repeating the toolbar's "Clear filters"
|
|
25
|
+
* verbatim, so the two controls on screen read as one action offered twice rather than two
|
|
26
|
+
* different ones. It is also the only reset within reach below `md`, where the toolbar's
|
|
27
|
+
* lives inside the filter sheet.
|
|
28
|
+
*/
|
|
29
|
+
export declare function WorkflowRunListNoMatches({ onClear, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore, }: {
|
|
13
30
|
onClear: () => void;
|
|
31
|
+
hasNextPage: boolean;
|
|
32
|
+
isFetchingNextPage: boolean;
|
|
33
|
+
isFetchNextPageError: boolean;
|
|
34
|
+
onLoadMore?: () => void;
|
|
14
35
|
}): import("react").JSX.Element;
|
|
36
|
+
export declare function WorkflowRunListLoadMore({ hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore, }: {
|
|
37
|
+
hasNextPage: boolean;
|
|
38
|
+
isFetchingNextPage: boolean;
|
|
39
|
+
isFetchNextPageError: boolean;
|
|
40
|
+
onLoadMore?: () => void;
|
|
41
|
+
}): import("react").JSX.Element | null;
|
|
15
42
|
//# sourceMappingURL=workflow-run-list-states.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-run-list-states.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-list-states.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-run-list-states.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-list-states.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAU5D;;;;GAIG;AACH,wBAAgB,uBAAuB,gCAsBtC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,EAAC,KAAK,EAAC,EAAE;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAC,+BAqB9E;AAED,wBAAgB,oBAAoB,CAAC,EACnC,aAAa,EACb,WAAW,GACZ,EAAE;IACD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,+BAoBA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,EAAE;IACD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,+BAqCA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,GACX,EAAE;IACD,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,sCAqBA"}
|
|
@@ -4,37 +4,36 @@ import { Callout } from '@shipfox/react-ui/callout';
|
|
|
4
4
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
5
5
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
6
6
|
import { Text } from '@shipfox/react-ui/typography';
|
|
7
|
-
|
|
7
|
+
import { Link } from '@tanstack/react-router';
|
|
8
|
+
const SKELETON_ROW_COUNT = 8;
|
|
9
|
+
/**
|
|
10
|
+
* Placeholder rows at the real row height, so the list does not resize under the cursor when
|
|
11
|
+
* the first page lands. Only the initial load renders these: a refetch keeps the rows it has,
|
|
12
|
+
* per the design system's rule against animating frequently-updating data.
|
|
13
|
+
*/ export function WorkflowRunListSkeleton() {
|
|
8
14
|
return /*#__PURE__*/ _jsx("div", {
|
|
9
|
-
className: "
|
|
15
|
+
className: "@container divide-y divide-border-neutral-base border-t border-border-neutral-base",
|
|
10
16
|
role: "status",
|
|
11
17
|
"aria-label": "Loading runs",
|
|
12
18
|
children: Array.from({
|
|
13
|
-
length:
|
|
19
|
+
length: SKELETON_ROW_COUNT
|
|
14
20
|
}).map((_, index)=>/*#__PURE__*/ _jsxs("div", {
|
|
15
|
-
className: "flex
|
|
21
|
+
className: "flex items-center gap-10 px-12 py-8 @min-[976px]:h-44 @min-[976px]:py-0",
|
|
16
22
|
children: [
|
|
17
|
-
/*#__PURE__*/
|
|
18
|
-
className: "
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
24
|
+
className: "size-14 shrink-0 rounded-full"
|
|
25
|
+
}),
|
|
26
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
27
|
+
className: "h-12 w-[220px] max-w-[40%]"
|
|
28
|
+
}),
|
|
29
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
30
|
+
className: "ml-auto hidden h-12 w-96 @min-[1040px]:block"
|
|
31
|
+
}),
|
|
32
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
33
|
+
className: "h-12 w-48"
|
|
27
34
|
}),
|
|
28
|
-
/*#__PURE__*/
|
|
29
|
-
className: "
|
|
30
|
-
children: [
|
|
31
|
-
/*#__PURE__*/ _jsx(Skeleton, {
|
|
32
|
-
className: "h-12 flex-1"
|
|
33
|
-
}),
|
|
34
|
-
/*#__PURE__*/ _jsx(Skeleton, {
|
|
35
|
-
className: "h-12 w-40"
|
|
36
|
-
})
|
|
37
|
-
]
|
|
35
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
36
|
+
className: "h-12 w-48"
|
|
38
37
|
})
|
|
39
38
|
]
|
|
40
39
|
}, index))
|
|
@@ -46,7 +45,7 @@ export function WorkflowRunListSkeleton() {
|
|
|
46
45
|
* replaced by a full-placeholder error.
|
|
47
46
|
*/ export function WorkflowRunListStaleError({ query }) {
|
|
48
47
|
return /*#__PURE__*/ _jsx("div", {
|
|
49
|
-
className: "
|
|
48
|
+
className: "pb-8",
|
|
50
49
|
children: /*#__PURE__*/ _jsx(Callout, {
|
|
51
50
|
role: "alert",
|
|
52
51
|
type: "error",
|
|
@@ -72,31 +71,91 @@ export function WorkflowRunListSkeleton() {
|
|
|
72
71
|
})
|
|
73
72
|
});
|
|
74
73
|
}
|
|
75
|
-
export function WorkflowRunListEmpty() {
|
|
76
|
-
return /*#__PURE__*/ _jsx(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
export function WorkflowRunListEmpty({ workspaceSlug, projectSlug }) {
|
|
75
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
76
|
+
icon: "pulseLine",
|
|
77
|
+
title: "No runs yet",
|
|
78
|
+
description: "Runs from this project's workflows appear here the moment one is launched.",
|
|
79
|
+
action: workspaceSlug && projectSlug ? /*#__PURE__*/ _jsx(Button, {
|
|
80
|
+
asChild: true,
|
|
81
|
+
type: "button",
|
|
82
|
+
size: "sm",
|
|
83
|
+
variant: "primary",
|
|
84
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
85
|
+
to: "/w/$workspaceSlug/p/$projectSlug/workflows",
|
|
86
|
+
params: {
|
|
87
|
+
workspaceSlug,
|
|
88
|
+
projectSlug
|
|
89
|
+
},
|
|
90
|
+
children: "View workflows"
|
|
91
|
+
})
|
|
92
|
+
}) : null
|
|
83
93
|
});
|
|
84
94
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
/**
|
|
96
|
+
* The filtered-empty state, deliberately distinct from the unfiltered one: someone who
|
|
97
|
+
* filtered their way to nothing needs a way back out, not an onboarding call to action.
|
|
98
|
+
*
|
|
99
|
+
* Its reset is worded as its outcome rather than repeating the toolbar's "Clear filters"
|
|
100
|
+
* verbatim, so the two controls on screen read as one action offered twice rather than two
|
|
101
|
+
* different ones. It is also the only reset within reach below `md`, where the toolbar's
|
|
102
|
+
* lives inside the filter sheet.
|
|
103
|
+
*/ export function WorkflowRunListNoMatches({ onClear, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
104
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
105
|
+
className: "flex flex-col gap-8",
|
|
106
|
+
children: [
|
|
107
|
+
isFetchNextPageError ? /*#__PURE__*/ _jsx(Callout, {
|
|
108
|
+
role: "alert",
|
|
109
|
+
type: "error",
|
|
110
|
+
children: "Could not load more workflow runs. Try again to continue searching older runs."
|
|
111
|
+
}) : null,
|
|
112
|
+
/*#__PURE__*/ _jsx(EmptyState, {
|
|
113
|
+
icon: "filterOffLine",
|
|
114
|
+
title: hasNextPage ? 'No matches in loaded history' : 'No matching runs',
|
|
115
|
+
description: hasNextPage ? 'No loaded run matches these filters. Load more to search further back.' : 'No run matches these filters.',
|
|
116
|
+
action: /*#__PURE__*/ _jsxs("div", {
|
|
117
|
+
className: "flex flex-wrap justify-center gap-8",
|
|
118
|
+
children: [
|
|
119
|
+
hasNextPage && onLoadMore ? /*#__PURE__*/ _jsx(Button, {
|
|
120
|
+
type: "button",
|
|
121
|
+
size: "sm",
|
|
122
|
+
variant: "primary",
|
|
123
|
+
isLoading: isFetchingNextPage,
|
|
124
|
+
onClick: onLoadMore,
|
|
125
|
+
children: "Load more runs"
|
|
126
|
+
}) : null,
|
|
127
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
128
|
+
type: "button",
|
|
129
|
+
size: "sm",
|
|
130
|
+
variant: "secondary",
|
|
131
|
+
onClick: onClear,
|
|
132
|
+
children: "Show all runs"
|
|
133
|
+
})
|
|
134
|
+
]
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export function WorkflowRunListLoadMore({ hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
141
|
+
if (!hasNextPage || !onLoadMore) return null;
|
|
142
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
143
|
+
className: "flex flex-col items-center gap-8 border-t border-border-neutral-base py-12",
|
|
144
|
+
children: [
|
|
145
|
+
isFetchNextPageError ? /*#__PURE__*/ _jsx(Callout, {
|
|
146
|
+
role: "alert",
|
|
147
|
+
type: "error",
|
|
148
|
+
children: "Could not load more workflow runs. Try again."
|
|
149
|
+
}) : null,
|
|
150
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
93
151
|
type: "button",
|
|
94
152
|
size: "sm",
|
|
95
153
|
variant: "secondary",
|
|
96
|
-
|
|
97
|
-
|
|
154
|
+
isLoading: isFetchingNextPage,
|
|
155
|
+
onClick: onLoadMore,
|
|
156
|
+
children: "Load more runs"
|
|
98
157
|
})
|
|
99
|
-
|
|
158
|
+
]
|
|
100
159
|
});
|
|
101
160
|
}
|
|
102
161
|
|