@shipfox/client-workflows 4.0.0 → 5.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +15 -0
- package/dist/feature.d.ts +10 -0
- package/dist/feature.d.ts.map +1 -1
- package/dist/feature.js +12 -0
- package/dist/feature.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pages/project-workflows-page.d.ts +4 -0
- package/dist/pages/project-workflows-page.d.ts.map +1 -0
- package/dist/pages/project-workflows-page.js +479 -0
- package/dist/pages/project-workflows-page.js.map +1 -0
- package/dist/routes/workflows.d.ts +5 -0
- package/dist/routes/workflows.d.ts.map +1 -0
- package/dist/routes/workflows.js +16 -0
- package/dist/routes/workflows.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -5
- package/src/feature.ts +12 -0
- package/src/index.ts +1 -0
- package/src/page-harness-budget.test.ts +1 -0
- package/src/pages/project-workflows-page.test.tsx +247 -0
- package/src/pages/project-workflows-page.tsx +443 -0
- package/src/routes/workflows.tsx +10 -0
- package/test/pages.tsx +29 -2
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled:
|
|
2
|
+
Successfully compiled: 58 files with swc (549.51ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @shipfox/client-workflows
|
|
2
2
|
|
|
3
|
+
## 5.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f1d6465: Moves workspace-settings and project-workflow route ownership from centralized packages into each feature's own route module, so a feature package declares and ships its own settings pages.
|
|
8
|
+
- Updated dependencies [8d8cdef]
|
|
9
|
+
- Updated dependencies [ee9d641]
|
|
10
|
+
- Updated dependencies [ffd727b]
|
|
11
|
+
- Updated dependencies [f1d6465]
|
|
12
|
+
- @shipfox/client-projects@5.0.0
|
|
13
|
+
- @shipfox/client-logs@5.0.0
|
|
14
|
+
- @shipfox/client-shell@5.0.0
|
|
15
|
+
- @shipfox/client-triggers@5.0.0
|
|
16
|
+
- @shipfox/api-workflows-dto@8.0.0
|
|
17
|
+
|
|
3
18
|
## 4.0.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/feature.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export declare const workflowsFeature: {
|
|
2
2
|
readonly id: "shipfox.workflows";
|
|
3
3
|
readonly routes: readonly [{
|
|
4
|
+
readonly path: "/workspaces/$wid/projects/$pid/workflows";
|
|
5
|
+
readonly parent: "projectLayout";
|
|
6
|
+
readonly impl: "@shipfox/client-workflows/routes/workflows";
|
|
7
|
+
}, {
|
|
4
8
|
readonly path: "/workspaces/$wid/projects/$pid/runs";
|
|
5
9
|
readonly parent: "projectLayout";
|
|
6
10
|
readonly impl: "@shipfox/client-workflows/routes/runs";
|
|
@@ -15,6 +19,12 @@ export declare const workflowsFeature: {
|
|
|
15
19
|
readonly label: "Runs";
|
|
16
20
|
readonly to: "/workspaces/$wid/projects/$pid/runs";
|
|
17
21
|
readonly order: 100;
|
|
22
|
+
}, {
|
|
23
|
+
readonly id: "nav.workflows";
|
|
24
|
+
readonly scope: "project";
|
|
25
|
+
readonly label: "Workflows";
|
|
26
|
+
readonly to: "/workspaces/$wid/projects/$pid/workflows";
|
|
27
|
+
readonly order: 200;
|
|
18
28
|
}];
|
|
19
29
|
};
|
|
20
30
|
//# sourceMappingURL=feature.d.ts.map
|
package/dist/feature.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmC3B,CAAC"}
|
package/dist/feature.js
CHANGED
|
@@ -2,6 +2,11 @@ import { defineClientFeature } from '@shipfox/client-shell';
|
|
|
2
2
|
export const workflowsFeature = defineClientFeature({
|
|
3
3
|
id: 'shipfox.workflows',
|
|
4
4
|
routes: [
|
|
5
|
+
{
|
|
6
|
+
path: '/workspaces/$wid/projects/$pid/workflows',
|
|
7
|
+
parent: 'projectLayout',
|
|
8
|
+
impl: '@shipfox/client-workflows/routes/workflows'
|
|
9
|
+
},
|
|
5
10
|
{
|
|
6
11
|
path: '/workspaces/$wid/projects/$pid/runs',
|
|
7
12
|
parent: 'projectLayout',
|
|
@@ -20,6 +25,13 @@ export const workflowsFeature = defineClientFeature({
|
|
|
20
25
|
label: 'Runs',
|
|
21
26
|
to: '/workspaces/$wid/projects/$pid/runs',
|
|
22
27
|
order: 100
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'nav.workflows',
|
|
31
|
+
scope: 'project',
|
|
32
|
+
label: 'Workflows',
|
|
33
|
+
to: '/workspaces/$wid/projects/$pid/workflows',
|
|
34
|
+
order: 200
|
|
23
35
|
}
|
|
24
36
|
]
|
|
25
37
|
});
|
package/dist/feature.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const workflowsFeature = defineClientFeature({\n id: 'shipfox.workflows',\n routes: [\n {\n path: '/workspaces/$wid/projects/$pid/runs',\n parent: 'projectLayout',\n impl: '@shipfox/client-workflows/routes/runs',\n },\n {\n path: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',\n parent: 'projectLayout',\n impl: '@shipfox/client-workflows/routes/run-detail',\n },\n ],\n navigation: [\n {\n id: 'nav.runs',\n scope: 'project',\n label: 'Runs',\n to: '/workspaces/$wid/projects/$pid/runs',\n order: 100,\n },\n ],\n});\n"],"names":["defineClientFeature","workflowsFeature","id","routes","path","parent","impl","navigation","scope","label","to","order"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,mBAAmBD,oBAAoB;IAClDE,IAAI;IACJC,QAAQ;QACN;YACEC,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;KACD;IACDC,YAAY;QACV;YACEL,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJC,OAAO;QACT;KACD;AACH,GAAG"}
|
|
1
|
+
{"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const workflowsFeature = defineClientFeature({\n id: 'shipfox.workflows',\n routes: [\n {\n path: '/workspaces/$wid/projects/$pid/workflows',\n parent: 'projectLayout',\n impl: '@shipfox/client-workflows/routes/workflows',\n },\n {\n path: '/workspaces/$wid/projects/$pid/runs',\n parent: 'projectLayout',\n impl: '@shipfox/client-workflows/routes/runs',\n },\n {\n path: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',\n parent: 'projectLayout',\n impl: '@shipfox/client-workflows/routes/run-detail',\n },\n ],\n navigation: [\n {\n id: 'nav.runs',\n scope: 'project',\n label: 'Runs',\n to: '/workspaces/$wid/projects/$pid/runs',\n order: 100,\n },\n {\n id: 'nav.workflows',\n scope: 'project',\n label: 'Workflows',\n to: '/workspaces/$wid/projects/$pid/workflows',\n order: 200,\n },\n ],\n});\n"],"names":["defineClientFeature","workflowsFeature","id","routes","path","parent","impl","navigation","scope","label","to","order"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,mBAAmBD,oBAAoB;IAClDE,IAAI;IACJC,QAAQ;QACN;YACEC,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;KACD;IACDC,YAAY;QACV;YACEL,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJC,OAAO;QACT;QACA;YACET,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJC,OAAO;QACT;KACD;AACH,GAAG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { AgentConfigIssue, JobDisplayDuration, JobExecutionDisplayDuration, JobExecutionStatus, JobExecutionTime, JobStatus, Step, StepAttempt, StepAttemptDisplayDuration, StepError, StepErrorCategory, StepErrorReason, StepGateResult, StepSourceLocation, WorkflowRun, WorkflowRunAttempt, WorkflowRunDetail, WorkflowRunListPage, WorkflowRunStatus, WorkflowSourceSnapshot, WorkflowStatus, } from '#core/workflow-run.js';
|
|
2
2
|
export { isWorkflowRunTerminal, isWorkflowStatus, Job, JobExecution, TERMINAL_WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_STATUSES, workflowRunShortId, workflowRunTriggerLabel, } from '#core/workflow-run.js';
|
|
3
3
|
export { type FireManualWorkflowVariables, fireManualWorkflow, useCancelWorkflowRunMutation, useFireManualWorkflowMutation, useWorkflowRunAttemptsQuery, useWorkflowRunQuery, useWorkflowRunsInfiniteQuery, type WorkflowRunFilters, workflowRunsQueryKeys, } from './hooks/api/workflow-runs.js';
|
|
4
|
+
export { ProjectWorkflowsPage } from './pages/project-workflows-page.js';
|
|
4
5
|
export { WorkflowRunPage } from './pages/workflow-run-page.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,IAAI,EACJ,WAAW,EACX,0BAA0B,EAC1B,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,GAAG,EACH,YAAY,EACZ,8BAA8B,EAC9B,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,2BAA2B,EAChC,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC7B,2BAA2B,EAC3B,mBAAmB,EACnB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,IAAI,EACJ,WAAW,EACX,0BAA0B,EAC1B,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,GAAG,EACH,YAAY,EACZ,8BAA8B,EAC9B,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,2BAA2B,EAChC,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC7B,2BAA2B,EAC3B,mBAAmB,EACnB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAC,oBAAoB,EAAC,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { isWorkflowRunTerminal, isWorkflowStatus, Job, JobExecution, TERMINAL_WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_STATUSES, workflowRunShortId, workflowRunTriggerLabel } from '#core/workflow-run.js';
|
|
2
2
|
export { fireManualWorkflow, useCancelWorkflowRunMutation, useFireManualWorkflowMutation, useWorkflowRunAttemptsQuery, useWorkflowRunQuery, useWorkflowRunsInfiniteQuery, workflowRunsQueryKeys } from './hooks/api/workflow-runs.js';
|
|
3
|
+
export { ProjectWorkflowsPage } from './pages/project-workflows-page.js';
|
|
3
4
|
export { WorkflowRunPage } from './pages/workflow-run-page.js';
|
|
4
5
|
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type {\n AgentConfigIssue,\n JobDisplayDuration,\n JobExecutionDisplayDuration,\n JobExecutionStatus,\n JobExecutionTime,\n JobStatus,\n Step,\n StepAttempt,\n StepAttemptDisplayDuration,\n StepError,\n StepErrorCategory,\n StepErrorReason,\n StepGateResult,\n StepSourceLocation,\n WorkflowRun,\n WorkflowRunAttempt,\n WorkflowRunDetail,\n WorkflowRunListPage,\n WorkflowRunStatus,\n WorkflowSourceSnapshot,\n WorkflowStatus,\n} from '#core/workflow-run.js';\nexport {\n isWorkflowRunTerminal,\n isWorkflowStatus,\n Job,\n JobExecution,\n TERMINAL_WORKFLOW_RUN_STATUSES,\n WORKFLOW_RUN_STATUSES,\n workflowRunShortId,\n workflowRunTriggerLabel,\n} from '#core/workflow-run.js';\nexport {\n type FireManualWorkflowVariables,\n fireManualWorkflow,\n useCancelWorkflowRunMutation,\n useFireManualWorkflowMutation,\n useWorkflowRunAttemptsQuery,\n useWorkflowRunQuery,\n useWorkflowRunsInfiniteQuery,\n type WorkflowRunFilters,\n workflowRunsQueryKeys,\n} from './hooks/api/workflow-runs.js';\nexport {WorkflowRunPage} from './pages/workflow-run-page.js';\n"],"names":["isWorkflowRunTerminal","isWorkflowStatus","Job","JobExecution","TERMINAL_WORKFLOW_RUN_STATUSES","WORKFLOW_RUN_STATUSES","workflowRunShortId","workflowRunTriggerLabel","fireManualWorkflow","useCancelWorkflowRunMutation","useFireManualWorkflowMutation","useWorkflowRunAttemptsQuery","useWorkflowRunQuery","useWorkflowRunsInfiniteQuery","workflowRunsQueryKeys","WorkflowRunPage"],"mappings":"AAuBA,SACEA,qBAAqB,EACrBC,gBAAgB,EAChBC,GAAG,EACHC,YAAY,EACZC,8BAA8B,EAC9BC,qBAAqB,EACrBC,kBAAkB,EAClBC,uBAAuB,QAClB,wBAAwB;AAC/B,SAEEC,kBAAkB,EAClBC,4BAA4B,EAC5BC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,mBAAmB,EACnBC,4BAA4B,EAE5BC,qBAAqB,QAChB,+BAA+B;AACtC,SAAQC,eAAe,QAAO,+BAA+B"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type {\n AgentConfigIssue,\n JobDisplayDuration,\n JobExecutionDisplayDuration,\n JobExecutionStatus,\n JobExecutionTime,\n JobStatus,\n Step,\n StepAttempt,\n StepAttemptDisplayDuration,\n StepError,\n StepErrorCategory,\n StepErrorReason,\n StepGateResult,\n StepSourceLocation,\n WorkflowRun,\n WorkflowRunAttempt,\n WorkflowRunDetail,\n WorkflowRunListPage,\n WorkflowRunStatus,\n WorkflowSourceSnapshot,\n WorkflowStatus,\n} from '#core/workflow-run.js';\nexport {\n isWorkflowRunTerminal,\n isWorkflowStatus,\n Job,\n JobExecution,\n TERMINAL_WORKFLOW_RUN_STATUSES,\n WORKFLOW_RUN_STATUSES,\n workflowRunShortId,\n workflowRunTriggerLabel,\n} from '#core/workflow-run.js';\nexport {\n type FireManualWorkflowVariables,\n fireManualWorkflow,\n useCancelWorkflowRunMutation,\n useFireManualWorkflowMutation,\n useWorkflowRunAttemptsQuery,\n useWorkflowRunQuery,\n useWorkflowRunsInfiniteQuery,\n type WorkflowRunFilters,\n workflowRunsQueryKeys,\n} from './hooks/api/workflow-runs.js';\nexport {ProjectWorkflowsPage} from './pages/project-workflows-page.js';\nexport {WorkflowRunPage} from './pages/workflow-run-page.js';\n"],"names":["isWorkflowRunTerminal","isWorkflowStatus","Job","JobExecution","TERMINAL_WORKFLOW_RUN_STATUSES","WORKFLOW_RUN_STATUSES","workflowRunShortId","workflowRunTriggerLabel","fireManualWorkflow","useCancelWorkflowRunMutation","useFireManualWorkflowMutation","useWorkflowRunAttemptsQuery","useWorkflowRunQuery","useWorkflowRunsInfiniteQuery","workflowRunsQueryKeys","ProjectWorkflowsPage","WorkflowRunPage"],"mappings":"AAuBA,SACEA,qBAAqB,EACrBC,gBAAgB,EAChBC,GAAG,EACHC,YAAY,EACZC,8BAA8B,EAC9BC,qBAAqB,EACrBC,kBAAkB,EAClBC,uBAAuB,QAClB,wBAAwB;AAC/B,SAEEC,kBAAkB,EAClBC,4BAA4B,EAC5BC,6BAA6B,EAC7BC,2BAA2B,EAC3BC,mBAAmB,EACnBC,4BAA4B,EAE5BC,qBAAqB,QAChB,+BAA+B;AACtC,SAAQC,oBAAoB,QAAO,oCAAoC;AACvE,SAAQC,eAAe,QAAO,+BAA+B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-workflows-page.d.ts","sourceRoot":"","sources":["../../src/pages/project-workflows-page.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,oBAAoB,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,+BAMpE"}
|
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ApiError } from '@shipfox/client-api';
|
|
3
|
+
import { SourceStrip, useDefinitionsInfiniteQuery, useProjectQuery } from '@shipfox/client-projects';
|
|
4
|
+
import { QueryLoadError } from '@shipfox/client-ui';
|
|
5
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
6
|
+
import { Callout } from '@shipfox/react-ui/callout';
|
|
7
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
8
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
9
|
+
import { LoadErrorState } from '@shipfox/react-ui/load-error-state';
|
|
10
|
+
import { RelativeTime, RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
|
|
11
|
+
import { Sheet, SheetBody, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@shipfox/react-ui/sheet';
|
|
12
|
+
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
13
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
|
|
14
|
+
import { toast } from '@shipfox/react-ui/toast';
|
|
15
|
+
import { Code, Header, Text } from '@shipfox/react-ui/typography';
|
|
16
|
+
import { useState } from 'react';
|
|
17
|
+
import { useFireManualWorkflowMutation } from '#hooks/api/workflow-runs.js';
|
|
18
|
+
export function ProjectWorkflowsPage({ projectId }) {
|
|
19
|
+
return /*#__PURE__*/ _jsx(RelativeTimeProvider, {
|
|
20
|
+
children: /*#__PURE__*/ _jsx(ProjectWorkflowsPageInner, {
|
|
21
|
+
projectId: projectId
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function ProjectWorkflowsPageInner({ projectId }) {
|
|
26
|
+
const projectQuery = useProjectQuery(projectId);
|
|
27
|
+
const definitionsQuery = useDefinitionsInfiniteQuery(projectId);
|
|
28
|
+
const fireManual = useFireManualWorkflowMutation();
|
|
29
|
+
const [selectedDefinition, setSelectedDefinition] = useState(null);
|
|
30
|
+
const [runError, setRunError] = useState(null);
|
|
31
|
+
const definitions = definitionsQuery.data?.pages.flatMap((page)=>page.definitions) ?? [];
|
|
32
|
+
const sync = definitionsQuery.data?.pages[0]?.sync;
|
|
33
|
+
async function handleRun(definition) {
|
|
34
|
+
setRunError(null);
|
|
35
|
+
if (!definition.manual_trigger) return;
|
|
36
|
+
try {
|
|
37
|
+
await fireManual.mutateAsync({
|
|
38
|
+
projectId,
|
|
39
|
+
definitionId: definition.id
|
|
40
|
+
});
|
|
41
|
+
toast.success('Run queued');
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const message = errorMessage(error, 'Could not queue run.');
|
|
44
|
+
setRunError({
|
|
45
|
+
definitionId: definition.id,
|
|
46
|
+
message
|
|
47
|
+
});
|
|
48
|
+
toast.error(message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
52
|
+
className: "flex w-full flex-col gap-24",
|
|
53
|
+
children: [
|
|
54
|
+
projectQuery.isPending ? /*#__PURE__*/ _jsxs("div", {
|
|
55
|
+
className: "flex flex-col gap-12",
|
|
56
|
+
children: [
|
|
57
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
58
|
+
className: "h-28 w-1/3"
|
|
59
|
+
}),
|
|
60
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
61
|
+
className: "h-18 w-1/2"
|
|
62
|
+
})
|
|
63
|
+
]
|
|
64
|
+
}) : null,
|
|
65
|
+
projectQuery.isError && projectQuery.data === undefined ? projectQuery.error instanceof ApiError && projectQuery.error.status === 404 ? /*#__PURE__*/ _jsx(EmptyState, {
|
|
66
|
+
icon: "errorWarningLine",
|
|
67
|
+
title: "Project not found",
|
|
68
|
+
description: "This project doesn't exist, or you don't have access to it."
|
|
69
|
+
}) : /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
70
|
+
query: projectQuery,
|
|
71
|
+
subject: "project"
|
|
72
|
+
}) : null,
|
|
73
|
+
projectQuery.data ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
74
|
+
children: [
|
|
75
|
+
/*#__PURE__*/ _jsxs("header", {
|
|
76
|
+
className: "flex flex-col gap-4",
|
|
77
|
+
children: [
|
|
78
|
+
/*#__PURE__*/ _jsx(Header, {
|
|
79
|
+
variant: "h2",
|
|
80
|
+
children: "Workflows"
|
|
81
|
+
}),
|
|
82
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
83
|
+
size: "sm",
|
|
84
|
+
className: "text-foreground-neutral-muted",
|
|
85
|
+
children: "Synced workflow definitions for this project source."
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ _jsx(SourceStrip, {
|
|
90
|
+
connectionId: projectQuery.data.source.connection_id,
|
|
91
|
+
externalRepositoryId: projectQuery.data.source.external_repository_id,
|
|
92
|
+
sync: sync,
|
|
93
|
+
isPending: definitionsQuery.isPending
|
|
94
|
+
}),
|
|
95
|
+
/*#__PURE__*/ _jsx(WorkflowSyncAlert, {
|
|
96
|
+
sync: sync
|
|
97
|
+
}),
|
|
98
|
+
/*#__PURE__*/ _jsx(WorkflowDefinitionsList, {
|
|
99
|
+
definitions: definitions,
|
|
100
|
+
isPending: definitionsQuery.isPending,
|
|
101
|
+
isError: definitionsQuery.isError,
|
|
102
|
+
sync: sync ?? null,
|
|
103
|
+
runError: runError,
|
|
104
|
+
runningDefinitionId: fireManual.isPending && fireManual.variables ? fireManual.variables.definitionId : null,
|
|
105
|
+
hasNextPage: definitionsQuery.hasNextPage,
|
|
106
|
+
isFetchingNextPage: definitionsQuery.isFetchingNextPage,
|
|
107
|
+
isFetchNextPageError: definitionsQuery.isFetchNextPageError,
|
|
108
|
+
onRetry: ()=>definitionsQuery.refetch(),
|
|
109
|
+
onLoadMore: ()=>definitionsQuery.fetchNextPage(),
|
|
110
|
+
onOpenDefinition: setSelectedDefinition,
|
|
111
|
+
onRun: (definition)=>{
|
|
112
|
+
void handleRun(definition);
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
]
|
|
116
|
+
}) : null,
|
|
117
|
+
/*#__PURE__*/ _jsx(DefinitionSheet, {
|
|
118
|
+
definition: selectedDefinition,
|
|
119
|
+
onOpenChange: (open)=>{
|
|
120
|
+
if (!open) setSelectedDefinition(null);
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function WorkflowDefinitionsList({ definitions, isPending, isError, sync, runError, runningDefinitionId, hasNextPage, isFetchingNextPage, isFetchNextPageError, onRetry, onLoadMore, onOpenDefinition, onRun }) {
|
|
127
|
+
if (isPending) {
|
|
128
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
129
|
+
className: "flex flex-col gap-8",
|
|
130
|
+
children: [
|
|
131
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
132
|
+
className: "h-40 w-full"
|
|
133
|
+
}),
|
|
134
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
135
|
+
className: "h-40 w-full"
|
|
136
|
+
}),
|
|
137
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
138
|
+
className: "h-40 w-full"
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if (isError && definitions.length === 0) {
|
|
144
|
+
return /*#__PURE__*/ _jsx(LoadErrorState, {
|
|
145
|
+
title: "Couldn't load workflows",
|
|
146
|
+
description: "Definitions could not be loaded. Source metadata remains visible.",
|
|
147
|
+
onRetry: onRetry,
|
|
148
|
+
retryLabel: "Retry loading workflows"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (definitions.length === 0) {
|
|
152
|
+
return /*#__PURE__*/ _jsx(WorkflowEmptyState, {
|
|
153
|
+
sync: sync
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
157
|
+
children: [
|
|
158
|
+
/*#__PURE__*/ _jsx("div", {
|
|
159
|
+
className: "hidden rounded-8 border border-border-neutral-base md:block",
|
|
160
|
+
children: /*#__PURE__*/ _jsxs(Table, {
|
|
161
|
+
children: [
|
|
162
|
+
/*#__PURE__*/ _jsx(TableHeader, {
|
|
163
|
+
children: /*#__PURE__*/ _jsxs(TableRow, {
|
|
164
|
+
children: [
|
|
165
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
166
|
+
className: "w-40"
|
|
167
|
+
}),
|
|
168
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
169
|
+
children: "Workflow"
|
|
170
|
+
}),
|
|
171
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
172
|
+
className: "w-180",
|
|
173
|
+
children: "Updated"
|
|
174
|
+
}),
|
|
175
|
+
/*#__PURE__*/ _jsx(TableHead, {
|
|
176
|
+
className: "w-80 text-right"
|
|
177
|
+
})
|
|
178
|
+
]
|
|
179
|
+
})
|
|
180
|
+
}),
|
|
181
|
+
/*#__PURE__*/ _jsx(TableBody, {
|
|
182
|
+
children: definitions.map((definition)=>{
|
|
183
|
+
const runErrorMessage = runError?.definitionId === definition.id ? runError.message : null;
|
|
184
|
+
const isRunning = runningDefinitionId === definition.id;
|
|
185
|
+
return(// The workflow-name cell holds a `<button>` so the row is
|
|
186
|
+
// keyboard-reachable (Tab focuses, Enter/Space activates
|
|
187
|
+
// via native button semantics). The TableRow itself is no
|
|
188
|
+
// longer clickable — a row-level onClick would be invisible
|
|
189
|
+
// to keyboard users and require custom keydown handling.
|
|
190
|
+
// The `group` class on the row still drives the Run button
|
|
191
|
+
// reveal on hover or focus-within.
|
|
192
|
+
/*#__PURE__*/ _jsxs(TableRow, {
|
|
193
|
+
className: "group",
|
|
194
|
+
children: [
|
|
195
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
196
|
+
children: /*#__PURE__*/ _jsx(Icon, {
|
|
197
|
+
name: sourceIcon(definition.source),
|
|
198
|
+
className: "size-16 text-foreground-neutral-muted",
|
|
199
|
+
"aria-hidden": "true"
|
|
200
|
+
})
|
|
201
|
+
}),
|
|
202
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
203
|
+
className: "max-w-260",
|
|
204
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
205
|
+
className: "flex min-w-0 flex-col gap-2",
|
|
206
|
+
children: [
|
|
207
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
208
|
+
type: "button",
|
|
209
|
+
onClick: ()=>onOpenDefinition(definition),
|
|
210
|
+
className: "flex min-w-0 flex-col gap-2 text-left outline-none focus-visible:shadow-border-interactive-with-active rounded-4",
|
|
211
|
+
children: [
|
|
212
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
213
|
+
size: "sm",
|
|
214
|
+
bold: true,
|
|
215
|
+
className: "truncate",
|
|
216
|
+
children: definition.name
|
|
217
|
+
}),
|
|
218
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
219
|
+
className: "truncate text-foreground-neutral-muted",
|
|
220
|
+
children: definition.config_path ?? 'Manual definition'
|
|
221
|
+
})
|
|
222
|
+
]
|
|
223
|
+
}),
|
|
224
|
+
runErrorMessage ? /*#__PURE__*/ _jsx(Text, {
|
|
225
|
+
size: "xs",
|
|
226
|
+
className: "text-tag-error-text",
|
|
227
|
+
children: runErrorMessage
|
|
228
|
+
}) : null
|
|
229
|
+
]
|
|
230
|
+
})
|
|
231
|
+
}),
|
|
232
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
233
|
+
className: "text-foreground-neutral-muted",
|
|
234
|
+
children: /*#__PURE__*/ _jsx(RelativeTime, {
|
|
235
|
+
value: definition.updated_at
|
|
236
|
+
})
|
|
237
|
+
}),
|
|
238
|
+
/*#__PURE__*/ _jsx(TableCell, {
|
|
239
|
+
children: definition.manual_trigger ? /*#__PURE__*/ _jsx("div", {
|
|
240
|
+
className: "flex justify-end opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",
|
|
241
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
242
|
+
size: "xs",
|
|
243
|
+
isLoading: isRunning,
|
|
244
|
+
onClick: ()=>onRun(definition),
|
|
245
|
+
children: "Run"
|
|
246
|
+
})
|
|
247
|
+
}) : null
|
|
248
|
+
})
|
|
249
|
+
]
|
|
250
|
+
}, definition.id));
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
]
|
|
254
|
+
})
|
|
255
|
+
}),
|
|
256
|
+
/*#__PURE__*/ _jsx("div", {
|
|
257
|
+
className: "flex flex-col rounded-8 border border-border-neutral-base md:hidden",
|
|
258
|
+
children: definitions.map((definition)=>{
|
|
259
|
+
const runErrorMessage = runError?.definitionId === definition.id ? runError.message : null;
|
|
260
|
+
const isRunning = runningDefinitionId === definition.id;
|
|
261
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
262
|
+
className: "flex flex-col gap-10 border-b border-border-neutral-base p-12 last:border-b-0",
|
|
263
|
+
children: [
|
|
264
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
265
|
+
type: "button",
|
|
266
|
+
className: "flex min-w-0 items-start gap-10 text-left",
|
|
267
|
+
onClick: ()=>onOpenDefinition(definition),
|
|
268
|
+
children: [
|
|
269
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
270
|
+
name: sourceIcon(definition.source),
|
|
271
|
+
className: "size-16 shrink-0 text-foreground-neutral-muted",
|
|
272
|
+
"aria-hidden": "true"
|
|
273
|
+
}),
|
|
274
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
275
|
+
className: "flex min-w-0 flex-col gap-4",
|
|
276
|
+
children: [
|
|
277
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
278
|
+
size: "sm",
|
|
279
|
+
bold: true,
|
|
280
|
+
className: "break-words",
|
|
281
|
+
children: definition.name
|
|
282
|
+
}),
|
|
283
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
284
|
+
className: "break-words text-foreground-neutral-muted",
|
|
285
|
+
children: definition.config_path ?? 'Manual definition'
|
|
286
|
+
})
|
|
287
|
+
]
|
|
288
|
+
})
|
|
289
|
+
]
|
|
290
|
+
}),
|
|
291
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
292
|
+
className: "flex items-center justify-between gap-8",
|
|
293
|
+
children: [
|
|
294
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
295
|
+
size: "xs",
|
|
296
|
+
className: "text-foreground-neutral-muted",
|
|
297
|
+
children: [
|
|
298
|
+
"Updated ",
|
|
299
|
+
/*#__PURE__*/ _jsx(RelativeTime, {
|
|
300
|
+
value: definition.updated_at
|
|
301
|
+
})
|
|
302
|
+
]
|
|
303
|
+
}),
|
|
304
|
+
definition.manual_trigger ? /*#__PURE__*/ _jsx(Button, {
|
|
305
|
+
size: "sm",
|
|
306
|
+
isLoading: isRunning,
|
|
307
|
+
onClick: ()=>onRun(definition),
|
|
308
|
+
children: "Run"
|
|
309
|
+
}) : null
|
|
310
|
+
]
|
|
311
|
+
}),
|
|
312
|
+
runErrorMessage ? /*#__PURE__*/ _jsx(Text, {
|
|
313
|
+
size: "xs",
|
|
314
|
+
className: "text-tag-error-text",
|
|
315
|
+
children: runErrorMessage
|
|
316
|
+
}) : null
|
|
317
|
+
]
|
|
318
|
+
}, definition.id);
|
|
319
|
+
})
|
|
320
|
+
}),
|
|
321
|
+
isFetchNextPageError ? /*#__PURE__*/ _jsx(Callout, {
|
|
322
|
+
role: "alert",
|
|
323
|
+
type: "error",
|
|
324
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
325
|
+
className: "flex items-center justify-between gap-12",
|
|
326
|
+
children: [
|
|
327
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
328
|
+
size: "sm",
|
|
329
|
+
children: "Could not load more workflows."
|
|
330
|
+
}),
|
|
331
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
332
|
+
size: "sm",
|
|
333
|
+
variant: "secondary",
|
|
334
|
+
onClick: onLoadMore,
|
|
335
|
+
children: "Retry"
|
|
336
|
+
})
|
|
337
|
+
]
|
|
338
|
+
})
|
|
339
|
+
}) : null,
|
|
340
|
+
hasNextPage ? /*#__PURE__*/ _jsx("div", {
|
|
341
|
+
className: "flex justify-center",
|
|
342
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
343
|
+
size: "sm",
|
|
344
|
+
variant: "secondary",
|
|
345
|
+
isLoading: isFetchingNextPage,
|
|
346
|
+
onClick: onLoadMore,
|
|
347
|
+
children: "Load more"
|
|
348
|
+
})
|
|
349
|
+
}) : null
|
|
350
|
+
]
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
function sourceIcon(source) {
|
|
354
|
+
return source === 'vcs' ? 'gitBranchLine' : 'terminalLine';
|
|
355
|
+
}
|
|
356
|
+
function WorkflowEmptyState({ sync }) {
|
|
357
|
+
const message = sync?.status === 'failed' && sync.last_error_code === 'no-workflow-files' ? 'No workflow files found under .shipfox/workflows/.' : sync?.status === 'failed' ? sync.last_error_message ?? 'Workflow definitions could not be synced.' : sync?.status === 'syncing' ? 'Workflow definitions are being discovered.' : sync?.status === 'succeeded' ? 'No workflow definitions found.' : 'Workflow sync has not reported yet.';
|
|
358
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
359
|
+
icon: "flowChart",
|
|
360
|
+
title: "No workflows",
|
|
361
|
+
description: message
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function WorkflowSyncAlert({ sync }) {
|
|
365
|
+
if (sync?.status !== 'failed') return null;
|
|
366
|
+
return /*#__PURE__*/ _jsx(Callout, {
|
|
367
|
+
role: "alert",
|
|
368
|
+
type: "error",
|
|
369
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
370
|
+
className: "flex flex-col gap-4",
|
|
371
|
+
children: [
|
|
372
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
373
|
+
size: "sm",
|
|
374
|
+
bold: true,
|
|
375
|
+
children: "Workflow sync failed"
|
|
376
|
+
}),
|
|
377
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
378
|
+
size: "sm",
|
|
379
|
+
children: sync.last_error_message ?? 'The latest workflow sync failed before definitions updated.'
|
|
380
|
+
})
|
|
381
|
+
]
|
|
382
|
+
})
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
function DefinitionSheet({ definition, onOpenChange }) {
|
|
386
|
+
const normalizedJson = definition ? JSON.stringify({
|
|
387
|
+
workflow_document: definition.workflow_document,
|
|
388
|
+
workflow_model: definition.workflow_model
|
|
389
|
+
}, null, 2) : '';
|
|
390
|
+
return /*#__PURE__*/ _jsx(Sheet, {
|
|
391
|
+
open: Boolean(definition),
|
|
392
|
+
onOpenChange: onOpenChange,
|
|
393
|
+
children: /*#__PURE__*/ _jsx(SheetContent, {
|
|
394
|
+
className: "w-full sm:max-w-[560px]",
|
|
395
|
+
children: definition ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
396
|
+
children: [
|
|
397
|
+
/*#__PURE__*/ _jsxs(SheetHeader, {
|
|
398
|
+
children: [
|
|
399
|
+
/*#__PURE__*/ _jsx(SheetTitle, {
|
|
400
|
+
children: definition.name
|
|
401
|
+
}),
|
|
402
|
+
/*#__PURE__*/ _jsx(SheetDescription, {
|
|
403
|
+
children: definition.config_path ?? 'Manual workflow definition'
|
|
404
|
+
})
|
|
405
|
+
]
|
|
406
|
+
}),
|
|
407
|
+
/*#__PURE__*/ _jsxs(SheetBody, {
|
|
408
|
+
className: "gap-18",
|
|
409
|
+
children: [
|
|
410
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
411
|
+
className: "grid w-full gap-10",
|
|
412
|
+
children: [
|
|
413
|
+
/*#__PURE__*/ _jsx(Metadata, {
|
|
414
|
+
label: "Definition id",
|
|
415
|
+
value: definition.id
|
|
416
|
+
}),
|
|
417
|
+
/*#__PURE__*/ _jsx(Metadata, {
|
|
418
|
+
label: "Source",
|
|
419
|
+
value: definition.source
|
|
420
|
+
}),
|
|
421
|
+
/*#__PURE__*/ _jsx(Metadata, {
|
|
422
|
+
label: "Ref",
|
|
423
|
+
value: definition.ref ?? 'Not set'
|
|
424
|
+
}),
|
|
425
|
+
/*#__PURE__*/ _jsx(Metadata, {
|
|
426
|
+
label: "SHA",
|
|
427
|
+
value: definition.sha ?? 'Not set'
|
|
428
|
+
})
|
|
429
|
+
]
|
|
430
|
+
}),
|
|
431
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
432
|
+
className: "flex w-full flex-col gap-8",
|
|
433
|
+
children: [
|
|
434
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
435
|
+
size: "sm",
|
|
436
|
+
bold: true,
|
|
437
|
+
children: "Normalized definition"
|
|
438
|
+
}),
|
|
439
|
+
/*#__PURE__*/ _jsx("pre", {
|
|
440
|
+
className: "max-h-[52vh] w-full overflow-auto rounded-8 border border-border-neutral-base bg-background-neutral-subtle p-12 scrollbar",
|
|
441
|
+
children: /*#__PURE__*/ _jsx(Code, {
|
|
442
|
+
as: "code",
|
|
443
|
+
className: "whitespace-pre text-foreground-neutral-base",
|
|
444
|
+
children: normalizedJson
|
|
445
|
+
})
|
|
446
|
+
})
|
|
447
|
+
]
|
|
448
|
+
})
|
|
449
|
+
]
|
|
450
|
+
})
|
|
451
|
+
]
|
|
452
|
+
}) : null
|
|
453
|
+
})
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function Metadata({ label, value }) {
|
|
457
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
458
|
+
className: "min-w-0 py-12 first:pt-0 last:pb-0",
|
|
459
|
+
children: [
|
|
460
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
461
|
+
size: "xs",
|
|
462
|
+
className: "text-foreground-neutral-muted",
|
|
463
|
+
children: label
|
|
464
|
+
}),
|
|
465
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
466
|
+
size: "sm",
|
|
467
|
+
className: "break-words",
|
|
468
|
+
children: value
|
|
469
|
+
})
|
|
470
|
+
]
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
function errorMessage(error, fallback) {
|
|
474
|
+
if (error instanceof ApiError && error.message) return error.message;
|
|
475
|
+
if (error instanceof Error && error.message) return error.message;
|
|
476
|
+
return fallback;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
//# sourceMappingURL=project-workflows-page.js.map
|