@shipfox/client-workflows 22.0.1 → 22.0.3
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 +2 -2
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +31 -0
- package/dist/components/job-detail/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js +15 -0
- package/dist/components/job-detail/agent-config-failure-callout.js.map +1 -1
- package/dist/components/job-detail/job-empty-states.d.ts.map +1 -1
- package/dist/components/job-detail/job-empty-states.js +8 -0
- package/dist/components/job-detail/job-empty-states.js.map +1 -1
- 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 +9 -15
- 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.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +36 -39
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +9 -13
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/core/entities/step.d.ts +2 -0
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +6 -0
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/components/job-detail/agent-config-failure-callout.stories.tsx +29 -0
- package/src/components/job-detail/agent-config-failure-callout.tsx +18 -0
- package/src/components/job-detail/job-empty-states.test.ts +21 -0
- package/src/components/job-detail/job-empty-states.tsx +10 -0
- package/src/components/workflow-run-list/workflow-run-list-content.tsx +4 -9
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +36 -39
- package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +5 -0
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-row.tsx +7 -10
- package/src/core/entities/step.ts +2 -0
- package/src/hooks/api/workflow-run-mapper.ts +4 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/.storybook/preview.tsx
CHANGED
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
|
|
13
13
|
if (typeof document !== 'undefined' && document.fonts) {
|
|
14
14
|
void Promise.all([
|
|
15
|
-
document.fonts.load("16px '
|
|
16
|
-
document.fonts.load("italic 16px '
|
|
15
|
+
document.fonts.load("16px 'IBM Plex Sans'"),
|
|
16
|
+
document.fonts.load("italic 16px 'IBM Plex Sans'"),
|
|
17
17
|
document.fonts.load("16px 'Commit Mono'"),
|
|
18
18
|
document.fonts.load("bold 16px 'Commit Mono'"),
|
|
19
19
|
]);
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 86 files with swc (
|
|
2
|
+
Successfully compiled: 86 files with swc (508.33ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @shipfox/client-workflows
|
|
2
2
|
|
|
3
|
+
## 22.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0d3c2e3: Updates @shipfox/client-agent, @shipfox/client-onboarding, and @shipfox/client-workflows to show
|
|
8
|
+
managed inference providers without exposing workspace credential setup, keep workflow examples
|
|
9
|
+
limited to supported models, and explain managed-provider failures in workflow runs.
|
|
10
|
+
- Updated dependencies [a7fb52d]
|
|
11
|
+
- Updated dependencies [0d3c2e3]
|
|
12
|
+
- Updated dependencies [ddcc546]
|
|
13
|
+
- @shipfox/react-ui@2.2.0
|
|
14
|
+
- @shipfox/api-workflows-dto@13.1.0
|
|
15
|
+
- @shipfox/client-projects@22.0.3
|
|
16
|
+
- @shipfox/client-logs@22.0.3
|
|
17
|
+
- @shipfox/client-shell@22.0.3
|
|
18
|
+
- @shipfox/client-triggers@22.0.3
|
|
19
|
+
- @shipfox/client-ui@22.0.3
|
|
20
|
+
|
|
21
|
+
## 22.0.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 383b9dd: Remove nested panel borders from workflow run list content and states.
|
|
26
|
+
- Updated dependencies [87d9bd8]
|
|
27
|
+
- @shipfox/react-ui@2.1.1
|
|
28
|
+
- @shipfox/client-logs@22.0.2
|
|
29
|
+
- @shipfox/client-projects@22.0.2
|
|
30
|
+
- @shipfox/client-shell@22.0.2
|
|
31
|
+
- @shipfox/client-triggers@22.0.2
|
|
32
|
+
- @shipfox/client-ui@22.0.2
|
|
33
|
+
|
|
3
34
|
## 22.0.1
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-config-failure-callout.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/agent-config-failure-callout.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,eAAe,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-config-failure-callout.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/agent-config-failure-callout.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,eAAe,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAItE,wBAAgB,yBAAyB,CAAC,EACxC,aAAa,EACb,MAAM,EACN,KAAK,GACN,EAAE;IACD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,+BAwBA"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Alert, AlertActions, AlertContent, AlertDescription, AlertTitle } from '@shipfox/react-ui/alert';
|
|
3
3
|
import { Button } from '@shipfox/react-ui/button';
|
|
4
4
|
import { Link } from '@tanstack/react-router';
|
|
5
|
+
const MANAGED_ONLY_PROVIDER_CODE = 'workspace-providers-disabled';
|
|
5
6
|
export function AgentConfigFailureCallout({ workspaceSlug, config, error }) {
|
|
6
7
|
const copy = agentConfigFailureCopy(config, error);
|
|
7
8
|
return /*#__PURE__*/ _jsx(Alert, {
|
|
@@ -36,6 +37,14 @@ export function AgentConfigFailureCallout({ workspaceSlug, config, error }) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
function agentConfigFailureCopy(config, error) {
|
|
40
|
+
const managedOnlyProvider = managedOnlyProviderFromError(error);
|
|
41
|
+
if (managedOnlyProvider) {
|
|
42
|
+
return {
|
|
43
|
+
title: `Use ${managedOnlyProvider} for this instance`,
|
|
44
|
+
description: `This instance only supports provider \`${managedOnlyProvider}\`. Update this step to use \`${managedOnlyProvider}\`, or remove its provider field to use the managed default.`,
|
|
45
|
+
showProviderCta: false
|
|
46
|
+
};
|
|
47
|
+
}
|
|
39
48
|
const provider = configValue(config?.provider, 'the selected provider');
|
|
40
49
|
const model = configValue(config?.model, 'the selected model');
|
|
41
50
|
switch(error?.agentConfigIssue){
|
|
@@ -77,6 +86,12 @@ function agentConfigFailureCopy(config, error) {
|
|
|
77
86
|
};
|
|
78
87
|
}
|
|
79
88
|
}
|
|
89
|
+
function managedOnlyProviderFromError(error) {
|
|
90
|
+
if (error?.code !== MANAGED_ONLY_PROVIDER_CODE && error?.managedProviderId === undefined) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return error.managedProviderId ?? 'the managed provider';
|
|
94
|
+
}
|
|
80
95
|
function configValue(value, fallback) {
|
|
81
96
|
return value ?? fallback;
|
|
82
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/job-detail/agent-config-failure-callout.tsx"],"sourcesContent":["import {\n Alert,\n AlertActions,\n AlertContent,\n AlertDescription,\n AlertTitle,\n} from '@shipfox/react-ui/alert';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Link} from '@tanstack/react-router';\nimport type {AgentStepConfig, StepError} from '#core/workflow-run.js';\n\nexport function AgentConfigFailureCallout({\n workspaceSlug,\n config,\n error,\n}: {\n workspaceSlug?: string | undefined;\n config: AgentStepConfig | null;\n error: StepError | null;\n}) {\n const copy = agentConfigFailureCopy(config, error);\n\n return (\n <Alert\n variant=\"warning\"\n animated={false}\n className=\"rounded-none border-x-0 border-t-0 border-b border-tag-warning-border bg-transparent px-0 py-row\"\n >\n <AlertContent>\n <AlertTitle>{copy.title}</AlertTitle>\n <AlertDescription>{copy.description}</AlertDescription>\n {copy.showProviderCta && workspaceSlug ? (\n <AlertActions>\n <Button asChild size=\"2xs\" variant=\"secondary\" iconRight=\"chevronRight\">\n <Link to=\"/w/$workspaceSlug/settings/agents\" params={{workspaceSlug}}>\n Configure Agents\n </Link>\n </Button>\n </AlertActions>\n ) : null}\n </AlertContent>\n </Alert>\n );\n}\n\nfunction agentConfigFailureCopy(\n config: AgentStepConfig | null,\n error: StepError | null,\n): {title: string; description: string; showProviderCta: boolean} {\n const provider = configValue(config?.provider, 'the selected provider');\n const model = configValue(config?.model, 'the selected model');\n\n switch (error?.agentConfigIssue) {\n case 'provider_not_configured':\n return {\n title: `Configure credentials for ${provider}`,\n description: `This step uses ${provider}, but no workspace credentials are configured for that model provider. Configure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'credentials_invalid':\n return {\n title: `Update credentials for ${provider}`,\n description: `This step uses ${provider}, but the saved credentials could not be used. Reconfigure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'provider_unsupported':\n return {\n title: 'Choose a supported model provider',\n description: `This step references ${provider}, which is not available to the agent runner. Update the workflow to use a supported provider, then re-run it.`,\n showProviderCta: false,\n };\n case 'model_unavailable':\n return {\n title: 'Choose an available model',\n description: `This step uses ${model} with ${provider}, but that model is not available for the provider. Update the model or provider in the workflow, then re-run it.`,\n showProviderCta: false,\n };\n case 'step_config_invalid':\n return {\n title: \"Fix this step's agent settings\",\n description:\n 'Make sure the step has a prompt, provider, model, and thinking value, then re-run the workflow.',\n showProviderCta: false,\n };\n case undefined:\n return {\n title: \"We couldn't load the agent configuration for this step\",\n description:\n 'Make sure the step has a prompt, provider, model, and thinking value. Then configure credentials for the model provider in Agents and re-run the workflow.',\n showProviderCta: true,\n };\n }\n}\n\nfunction configValue(value: string | null | undefined, fallback: string): string {\n return value ?? fallback;\n}\n"],"names":["Alert","AlertActions","AlertContent","AlertDescription","AlertTitle","Button","Link","AgentConfigFailureCallout","workspaceSlug","config","error","copy","agentConfigFailureCopy","variant","animated","className","title","description","showProviderCta","asChild","size","iconRight","to","params","provider","configValue","model","agentConfigIssue","undefined","value","fallback"],"mappings":";AAAA,SACEA,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,gBAAgB,EAChBC,UAAU,QACL,0BAA0B;AACjC,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAG5C,OAAO,SAASC,0BAA0B,EACxCC,aAAa,EACbC,MAAM,EACNC,KAAK,EAKN;IACC,MAAMC,OAAOC,uBAAuBH,QAAQC;IAE5C,qBACE,
|
|
1
|
+
{"version":3,"sources":["../../../src/components/job-detail/agent-config-failure-callout.tsx"],"sourcesContent":["import {\n Alert,\n AlertActions,\n AlertContent,\n AlertDescription,\n AlertTitle,\n} from '@shipfox/react-ui/alert';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Link} from '@tanstack/react-router';\nimport type {AgentStepConfig, StepError} from '#core/workflow-run.js';\n\nconst MANAGED_ONLY_PROVIDER_CODE = 'workspace-providers-disabled';\n\nexport function AgentConfigFailureCallout({\n workspaceSlug,\n config,\n error,\n}: {\n workspaceSlug?: string | undefined;\n config: AgentStepConfig | null;\n error: StepError | null;\n}) {\n const copy = agentConfigFailureCopy(config, error);\n\n return (\n <Alert\n variant=\"warning\"\n animated={false}\n className=\"rounded-none border-x-0 border-t-0 border-b border-tag-warning-border bg-transparent px-0 py-row\"\n >\n <AlertContent>\n <AlertTitle>{copy.title}</AlertTitle>\n <AlertDescription>{copy.description}</AlertDescription>\n {copy.showProviderCta && workspaceSlug ? (\n <AlertActions>\n <Button asChild size=\"2xs\" variant=\"secondary\" iconRight=\"chevronRight\">\n <Link to=\"/w/$workspaceSlug/settings/agents\" params={{workspaceSlug}}>\n Configure Agents\n </Link>\n </Button>\n </AlertActions>\n ) : null}\n </AlertContent>\n </Alert>\n );\n}\n\nfunction agentConfigFailureCopy(\n config: AgentStepConfig | null,\n error: StepError | null,\n): {title: string; description: string; showProviderCta: boolean} {\n const managedOnlyProvider = managedOnlyProviderFromError(error);\n if (managedOnlyProvider) {\n return {\n title: `Use ${managedOnlyProvider} for this instance`,\n description: `This instance only supports provider \\`${managedOnlyProvider}\\`. Update this step to use \\`${managedOnlyProvider}\\`, or remove its provider field to use the managed default.`,\n showProviderCta: false,\n };\n }\n\n const provider = configValue(config?.provider, 'the selected provider');\n const model = configValue(config?.model, 'the selected model');\n\n switch (error?.agentConfigIssue) {\n case 'provider_not_configured':\n return {\n title: `Configure credentials for ${provider}`,\n description: `This step uses ${provider}, but no workspace credentials are configured for that model provider. Configure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'credentials_invalid':\n return {\n title: `Update credentials for ${provider}`,\n description: `This step uses ${provider}, but the saved credentials could not be used. Reconfigure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'provider_unsupported':\n return {\n title: 'Choose a supported model provider',\n description: `This step references ${provider}, which is not available to the agent runner. Update the workflow to use a supported provider, then re-run it.`,\n showProviderCta: false,\n };\n case 'model_unavailable':\n return {\n title: 'Choose an available model',\n description: `This step uses ${model} with ${provider}, but that model is not available for the provider. Update the model or provider in the workflow, then re-run it.`,\n showProviderCta: false,\n };\n case 'step_config_invalid':\n return {\n title: \"Fix this step's agent settings\",\n description:\n 'Make sure the step has a prompt, provider, model, and thinking value, then re-run the workflow.',\n showProviderCta: false,\n };\n case undefined:\n return {\n title: \"We couldn't load the agent configuration for this step\",\n description:\n 'Make sure the step has a prompt, provider, model, and thinking value. Then configure credentials for the model provider in Agents and re-run the workflow.',\n showProviderCta: true,\n };\n }\n}\n\nfunction managedOnlyProviderFromError(error: StepError | null): string | undefined {\n if (error?.code !== MANAGED_ONLY_PROVIDER_CODE && error?.managedProviderId === undefined) {\n return undefined;\n }\n return error.managedProviderId ?? 'the managed provider';\n}\n\nfunction configValue(value: string | null | undefined, fallback: string): string {\n return value ?? fallback;\n}\n"],"names":["Alert","AlertActions","AlertContent","AlertDescription","AlertTitle","Button","Link","MANAGED_ONLY_PROVIDER_CODE","AgentConfigFailureCallout","workspaceSlug","config","error","copy","agentConfigFailureCopy","variant","animated","className","title","description","showProviderCta","asChild","size","iconRight","to","params","managedOnlyProvider","managedOnlyProviderFromError","provider","configValue","model","agentConfigIssue","undefined","code","managedProviderId","value","fallback"],"mappings":";AAAA,SACEA,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,gBAAgB,EAChBC,UAAU,QACL,0BAA0B;AACjC,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAG5C,MAAMC,6BAA6B;AAEnC,OAAO,SAASC,0BAA0B,EACxCC,aAAa,EACbC,MAAM,EACNC,KAAK,EAKN;IACC,MAAMC,OAAOC,uBAAuBH,QAAQC;IAE5C,qBACE,KAACX;QACCc,SAAQ;QACRC,UAAU;QACVC,WAAU;kBAEV,cAAA,MAACd;;8BACC,KAACE;8BAAYQ,KAAKK,KAAK;;8BACvB,KAACd;8BAAkBS,KAAKM,WAAW;;gBAClCN,KAAKO,eAAe,IAAIV,8BACvB,KAACR;8BACC,cAAA,KAACI;wBAAOe,OAAO;wBAACC,MAAK;wBAAMP,SAAQ;wBAAYQ,WAAU;kCACvD,cAAA,KAAChB;4BAAKiB,IAAG;4BAAoCC,QAAQ;gCAACf;4BAAa;sCAAG;;;qBAKxE;;;;AAIZ;AAEA,SAASI,uBACPH,MAA8B,EAC9BC,KAAuB;IAEvB,MAAMc,sBAAsBC,6BAA6Bf;IACzD,IAAIc,qBAAqB;QACvB,OAAO;YACLR,OAAO,CAAC,IAAI,EAAEQ,oBAAoB,kBAAkB,CAAC;YACrDP,aAAa,CAAC,uCAAuC,EAAEO,oBAAoB,8BAA8B,EAAEA,oBAAoB,4DAA4D,CAAC;YAC5LN,iBAAiB;QACnB;IACF;IAEA,MAAMQ,WAAWC,YAAYlB,QAAQiB,UAAU;IAC/C,MAAME,QAAQD,YAAYlB,QAAQmB,OAAO;IAEzC,OAAQlB,OAAOmB;QACb,KAAK;YACH,OAAO;gBACLb,OAAO,CAAC,0BAA0B,EAAEU,UAAU;gBAC9CT,aAAa,CAAC,eAAe,EAAES,SAAS,iFAAiF,EAAEA,SAAS,qCAAqC,CAAC;gBAC1KR,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,uBAAuB,EAAEU,UAAU;gBAC3CT,aAAa,CAAC,eAAe,EAAES,SAAS,2DAA2D,EAAEA,SAAS,qCAAqC,CAAC;gBACpJR,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aAAa,CAAC,qBAAqB,EAAES,SAAS,8GAA8G,CAAC;gBAC7JR,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aAAa,CAAC,eAAe,EAAEW,MAAM,MAAM,EAAEF,SAAS,iHAAiH,CAAC;gBACxKR,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;QACF,KAAKY;YACH,OAAO;gBACLd,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;IACJ;AACF;AAEA,SAASO,6BAA6Bf,KAAuB;IAC3D,IAAIA,OAAOqB,SAASzB,8BAA8BI,OAAOsB,sBAAsBF,WAAW;QACxF,OAAOA;IACT;IACA,OAAOpB,MAAMsB,iBAAiB,IAAI;AACpC;AAEA,SAASL,YAAYM,KAAgC,EAAEC,QAAgB;IACrE,OAAOD,SAASC;AAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-empty-states.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/job-empty-states.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAO9E,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AAQ9D,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,YAAY,GACzB,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,+BAA+B,CAAC,EAAC,YAAY,EAAC,EAAE;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,sCAiB3F;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,YAAY,GACzB,kBAAkB,GAAG,SAAS,CAsEhC;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,GAAG,GAAG,kBAAkB,CA8D1E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,GAAG,MAAM,CAuBzE;AA2CD,wBAAgB,oBAAoB,gCAUnC;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACpC,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"job-empty-states.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/job-empty-states.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAO9E,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AAQ9D,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,YAAY,GACzB,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,+BAA+B,CAAC,EAAC,YAAY,EAAC,EAAE;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,sCAiB3F;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,YAAY,GACzB,kBAAkB,GAAG,SAAS,CAsEhC;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,GAAG,GAAG,kBAAkB,CA8D1E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,GAAG,MAAM,CAuBzE;AA2CD,wBAAgB,oBAAoB,gCAUnC;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACpC,SAAS,GAAG,IAAI,CA0ClB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAEjF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAMzF"}
|
|
@@ -221,8 +221,16 @@ export function toSelectedAttemptError(step, error) {
|
|
|
221
221
|
const exitCode = error.exitCode ?? error.exit_code;
|
|
222
222
|
const resolvedReason = parsedReason ? parsedReason : agentConfigIssue ? 'agent_config_invalid' : undefined;
|
|
223
223
|
if (resolvedReason === undefined) return null;
|
|
224
|
+
const code = typeof error.code === 'string' ? error.code : undefined;
|
|
225
|
+
const managedProviderId = typeof error.managedProviderId === 'string' ? error.managedProviderId : typeof error.managed_provider_id === 'string' ? error.managed_provider_id : undefined;
|
|
224
226
|
return {
|
|
225
227
|
message: typeof error.message === 'string' ? error.message : '',
|
|
228
|
+
...code === undefined ? {} : {
|
|
229
|
+
code
|
|
230
|
+
},
|
|
231
|
+
...managedProviderId === undefined ? {} : {
|
|
232
|
+
managedProviderId
|
|
233
|
+
},
|
|
226
234
|
exitCode: exitCode === null || typeof exitCode === 'number' ? exitCode : null,
|
|
227
235
|
signal: typeof error.signal === 'string' ? error.signal : undefined,
|
|
228
236
|
reason: resolvedReason,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/job-detail/job-empty-states.tsx"],"sourcesContent":["import {Callout, CalloutContent, CalloutDescription, CalloutTitle} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport type {Job, JobExecution, Step, StepError} from '#core/workflow-run.js';\nimport {\n AGENT_CONFIG_ISSUES,\n deriveJobDisplayStatus,\n deriveJobExecutionDisplayStatus,\n STEP_ERROR_REASONS,\n} from '#core/workflow-run.js';\nimport type {StepListEmptyState} from '../step-list/index.js';\nimport {formatJobExecutionTime} from './job-execution-time-text.js';\n\nconst MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION =\n 'A materialized job output could not be persisted: it exceeded a size or entry cap, contained a non-JSON-safe value, or referenced an unresolved value. Check the output mapping and values before re-running the workflow.';\nconst OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION =\n 'The materialized job output exceeded its configured size limit. Review the failure details before re-running the workflow.';\n\nexport function outputFailureDescriptionForExecution(\n jobExecution: JobExecution,\n): string | undefined {\n if (jobExecution.steps.length === 0) return undefined;\n\n if (jobExecution.statusReason === 'output_invalid') {\n return jobExecution.statusReasonMessage || MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION;\n }\n if (jobExecution.statusReason === 'output_too_large') {\n return jobExecution.statusReasonMessage || OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION;\n }\n return undefined;\n}\n\nexport function MaterializedOutputFailureNotice({jobExecution}: {jobExecution: JobExecution}) {\n const description = outputFailureDescriptionForExecution(jobExecution);\n if (!description) return null;\n\n return (\n <Callout\n role=\"alert\"\n type=\"error\"\n variant=\"secondary\"\n className=\"border-b border-border-neutral-base px-row py-row\"\n >\n <CalloutContent>\n <CalloutTitle>Job output could not be persisted</CalloutTitle>\n <CalloutDescription>{description}</CalloutDescription>\n </CalloutContent>\n </Callout>\n );\n}\n\nexport function emptyStateForJob(\n job: Job,\n jobExecution: JobExecution,\n): StepListEmptyState | undefined {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n const displayStatus =\n job.mode === 'listening'\n ? deriveJobExecutionDisplayStatus(jobExecution)\n : deriveJobDisplayStatus(job);\n const runner = jobExecution.runner?.length ? jobExecution.runner : job.runner;\n\n if (jobExecution.status === 'running' && displayStatus === 'pending') {\n return {\n title: runner?.length ? 'Runner preparing job' : 'Waiting for a runner',\n description: runner?.length\n ? `Runner ${runner.join(', ')} is preparing the job. Steps will appear here when work begins.`\n : 'No runner has claimed this job yet. Steps will appear here when a runner starts work.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'Steps will appear here once the job starts.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'running') {\n return {\n title: 'Waiting for the first step',\n description: 'The first running step will appear here shortly.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before any step started.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'failed') {\n return {\n title: 'Job failed before its first step started',\n description: preStepFailureDescription(\n jobExecution.statusReason ?? job.statusReason,\n runner,\n jobExecution.statusReasonMessage,\n ),\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'succeeded') {\n return {\n title: 'Completed without recorded steps',\n description: `Execution #${jobExecution.sequence} succeeded before any step output was recorded.`,\n status: displayStatus,\n };\n }\n\n return undefined;\n}\n\nexport function emptyStateForMissingExecution(job: Job): StepListEmptyState {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'listening') {\n return {\n title: 'Waiting for trigger events',\n description: 'Matching trigger events will create job executions here.',\n status: deriveJobDisplayStatus(job),\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'resolved') {\n return {\n title: 'Listener resolved without executions',\n description: 'No matching trigger event created a job execution before the listener stopped.',\n status: job.status,\n };\n }\n\n if (job.status === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'No execution has been created for this job yet.',\n status: 'pending',\n };\n }\n\n if (job.status === 'skipped') {\n return {\n title: 'This job was skipped',\n description: skippedJobDescription(job.statusReason),\n status: 'skipped',\n };\n }\n\n if (job.status === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before an execution was created.',\n status: 'cancelled',\n };\n }\n\n if (job.status === 'failed') {\n return {\n title: 'Job failed before an execution was created',\n description: preStepFailureDescription(job.statusReason, job.runner),\n status: 'failed',\n };\n }\n\n return {\n title: 'Execution details unavailable',\n description: 'This job finished, but no job execution record is available.',\n status: job.status,\n };\n}\n\nexport function skippedJobDescription(reason: Job['statusReason']): string {\n switch (reason) {\n case 'dependency_not_completed':\n return 'A required job did not complete, so this job was skipped.';\n case 'default_gate_rejected':\n return 'A required job did not succeed, so this job was skipped.';\n case 'condition_false':\n case 'condition_rejected':\n return 'The job condition did not match, so this job was skipped.';\n case 'condition_errored':\n return 'The job condition could not be evaluated, so this job was skipped.';\n case 'user_cancelled':\n case 'run_cancelled':\n case 'timed_out':\n case 'runner_lost':\n case 'output_invalid':\n case 'step_failed':\n case 'unknown':\n case null:\n return 'This job did not start.';\n case 'output_too_large':\n return 'The materialized job output exceeded its configured size limit.';\n }\n}\n\nfunction preStepFailureDescription(\n reason: string | null,\n runner: string[] | null = null,\n statusReasonMessage: string | null = null,\n): string {\n const runnerCopy = runner?.length ? ` Required runner labels: ${runner.join(', ')}.` : '';\n\n switch (reason) {\n case 'runner_lost':\n return `The runner stopped responding before work began.${runnerCopy} Check runner availability before re-running the workflow.`;\n case 'timed_out':\n return `The job timed out before work began.${runnerCopy} Check runner capacity and timeout configuration before re-running the workflow.`;\n case 'user_cancelled':\n case 'run_cancelled':\n return 'The execution ended while the run was being cancelled.';\n case 'step_failed':\n return `The execution failed before step details were recorded.${runnerCopy} Review run annotations before re-running the workflow.`;\n case 'output_too_large':\n return statusReasonMessage || OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION;\n case 'output_invalid':\n return statusReasonMessage || MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION;\n case 'condition_errored':\n return 'The job condition could not be evaluated. Review run annotations before re-running the workflow.';\n case 'dependency_not_completed':\n case 'default_gate_rejected':\n return 'A required job did not complete successfully. Resolve that failure before re-running the workflow.';\n case 'condition_false':\n case 'condition_rejected':\n return 'The job condition did not match, so no work started.';\n case 'unknown':\n case null:\n return `Shipfox did not record a failure reason.${runnerCopy} Re-run only after checking the runner and workflow configuration.`;\n default:\n return `The execution ended because ${humanizeFailureReason(reason)}.${runnerCopy} Resolve that condition before re-running the workflow.`;\n }\n}\n\nfunction humanizeFailureReason(reason: string): string {\n return reason.replaceAll('_', ' ').replaceAll('-', ' ');\n}\n\nexport function CarriedOverStepPanel() {\n return (\n <EmptyState\n className=\"rounded-8 border border-border-neutral-base bg-background-components-base\"\n icon=\"componentLine\"\n title=\"Carried over from a previous attempt\"\n description=\"Not executed in this run.\"\n variant=\"panel\"\n />\n );\n}\n\nexport function toSelectedAttemptError(\n step: Step,\n error: Record<string, unknown> | null,\n): StepError | null {\n if (error === null) return null;\n\n const rawReason = error.reason;\n const parsedReason =\n typeof rawReason === 'string' &&\n STEP_ERROR_REASONS.has(rawReason as StepError['reason'] & string)\n ? (rawReason as NonNullable<StepError['reason']>)\n : undefined;\n const rawAgentConfigIssue = error.agentConfigIssue ?? error.agent_config_issue;\n const agentConfigIssue =\n typeof rawAgentConfigIssue === 'string' &&\n AGENT_CONFIG_ISSUES.has(rawAgentConfigIssue as NonNullable<StepError['agentConfigIssue']>)\n ? (rawAgentConfigIssue as NonNullable<StepError['agentConfigIssue']>)\n : undefined;\n const exitCode = error.exitCode ?? error.exit_code;\n const resolvedReason = parsedReason\n ? parsedReason\n : agentConfigIssue\n ? 'agent_config_invalid'\n : undefined;\n\n if (resolvedReason === undefined) return null;\n\n return {\n message: typeof error.message === 'string' ? error.message : '',\n exitCode: exitCode === null || typeof exitCode === 'number' ? exitCode : null,\n signal: typeof error.signal === 'string' ? error.signal : undefined,\n reason: resolvedReason,\n agentConfigIssue,\n category: step.type === 'setup' || step.type === 'checkout' ? 'setup' : 'user',\n };\n}\n\nexport function isAgentConfigFailure(step: Step, error: StepError | null): boolean {\n return step.type === 'agent' && error?.reason === 'agent_config_invalid';\n}\n\nexport function jobSucceededSummary(job: Job, execution: JobExecution): string | undefined {\n if (job.carriedOver || execution.status !== 'succeeded') return undefined;\n const stepCount = execution.steps.filter((step) => step.status === 'succeeded').length;\n if (stepCount === 0) return undefined;\n const duration = execution.displayDuration;\n return `${stepCount} step${stepCount === 1 ? '' : 's'} succeeded${duration ? ` in ${formatJobExecutionTime(duration)}` : ''}`;\n}\n"],"names":["Callout","CalloutContent","CalloutDescription","CalloutTitle","EmptyState","AGENT_CONFIG_ISSUES","deriveJobDisplayStatus","deriveJobExecutionDisplayStatus","STEP_ERROR_REASONS","formatJobExecutionTime","MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION","OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION","outputFailureDescriptionForExecution","jobExecution","steps","length","undefined","statusReason","statusReasonMessage","MaterializedOutputFailureNotice","description","role","type","variant","className","emptyStateForJob","job","carriedOver","title","status","displayStatus","mode","runner","join","preStepFailureDescription","sequence","emptyStateForMissingExecution","listenerStatus","skippedJobDescription","reason","runnerCopy","humanizeFailureReason","replaceAll","CarriedOverStepPanel","icon","toSelectedAttemptError","step","error","rawReason","parsedReason","has","rawAgentConfigIssue","agentConfigIssue","agent_config_issue","exitCode","exit_code","resolvedReason","message","signal","category","isAgentConfigFailure","jobSucceededSummary","execution","stepCount","filter","duration","displayDuration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/job-detail/job-empty-states.tsx"],"sourcesContent":["import {Callout, CalloutContent, CalloutDescription, CalloutTitle} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport type {Job, JobExecution, Step, StepError} from '#core/workflow-run.js';\nimport {\n AGENT_CONFIG_ISSUES,\n deriveJobDisplayStatus,\n deriveJobExecutionDisplayStatus,\n STEP_ERROR_REASONS,\n} from '#core/workflow-run.js';\nimport type {StepListEmptyState} from '../step-list/index.js';\nimport {formatJobExecutionTime} from './job-execution-time-text.js';\n\nconst MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION =\n 'A materialized job output could not be persisted: it exceeded a size or entry cap, contained a non-JSON-safe value, or referenced an unresolved value. Check the output mapping and values before re-running the workflow.';\nconst OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION =\n 'The materialized job output exceeded its configured size limit. Review the failure details before re-running the workflow.';\n\nexport function outputFailureDescriptionForExecution(\n jobExecution: JobExecution,\n): string | undefined {\n if (jobExecution.steps.length === 0) return undefined;\n\n if (jobExecution.statusReason === 'output_invalid') {\n return jobExecution.statusReasonMessage || MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION;\n }\n if (jobExecution.statusReason === 'output_too_large') {\n return jobExecution.statusReasonMessage || OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION;\n }\n return undefined;\n}\n\nexport function MaterializedOutputFailureNotice({jobExecution}: {jobExecution: JobExecution}) {\n const description = outputFailureDescriptionForExecution(jobExecution);\n if (!description) return null;\n\n return (\n <Callout\n role=\"alert\"\n type=\"error\"\n variant=\"secondary\"\n className=\"border-b border-border-neutral-base px-row py-row\"\n >\n <CalloutContent>\n <CalloutTitle>Job output could not be persisted</CalloutTitle>\n <CalloutDescription>{description}</CalloutDescription>\n </CalloutContent>\n </Callout>\n );\n}\n\nexport function emptyStateForJob(\n job: Job,\n jobExecution: JobExecution,\n): StepListEmptyState | undefined {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n const displayStatus =\n job.mode === 'listening'\n ? deriveJobExecutionDisplayStatus(jobExecution)\n : deriveJobDisplayStatus(job);\n const runner = jobExecution.runner?.length ? jobExecution.runner : job.runner;\n\n if (jobExecution.status === 'running' && displayStatus === 'pending') {\n return {\n title: runner?.length ? 'Runner preparing job' : 'Waiting for a runner',\n description: runner?.length\n ? `Runner ${runner.join(', ')} is preparing the job. Steps will appear here when work begins.`\n : 'No runner has claimed this job yet. Steps will appear here when a runner starts work.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'Steps will appear here once the job starts.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'running') {\n return {\n title: 'Waiting for the first step',\n description: 'The first running step will appear here shortly.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before any step started.',\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'failed') {\n return {\n title: 'Job failed before its first step started',\n description: preStepFailureDescription(\n jobExecution.statusReason ?? job.statusReason,\n runner,\n jobExecution.statusReasonMessage,\n ),\n status: displayStatus,\n };\n }\n\n if (displayStatus === 'succeeded') {\n return {\n title: 'Completed without recorded steps',\n description: `Execution #${jobExecution.sequence} succeeded before any step output was recorded.`,\n status: displayStatus,\n };\n }\n\n return undefined;\n}\n\nexport function emptyStateForMissingExecution(job: Job): StepListEmptyState {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'listening') {\n return {\n title: 'Waiting for trigger events',\n description: 'Matching trigger events will create job executions here.',\n status: deriveJobDisplayStatus(job),\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'resolved') {\n return {\n title: 'Listener resolved without executions',\n description: 'No matching trigger event created a job execution before the listener stopped.',\n status: job.status,\n };\n }\n\n if (job.status === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'No execution has been created for this job yet.',\n status: 'pending',\n };\n }\n\n if (job.status === 'skipped') {\n return {\n title: 'This job was skipped',\n description: skippedJobDescription(job.statusReason),\n status: 'skipped',\n };\n }\n\n if (job.status === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before an execution was created.',\n status: 'cancelled',\n };\n }\n\n if (job.status === 'failed') {\n return {\n title: 'Job failed before an execution was created',\n description: preStepFailureDescription(job.statusReason, job.runner),\n status: 'failed',\n };\n }\n\n return {\n title: 'Execution details unavailable',\n description: 'This job finished, but no job execution record is available.',\n status: job.status,\n };\n}\n\nexport function skippedJobDescription(reason: Job['statusReason']): string {\n switch (reason) {\n case 'dependency_not_completed':\n return 'A required job did not complete, so this job was skipped.';\n case 'default_gate_rejected':\n return 'A required job did not succeed, so this job was skipped.';\n case 'condition_false':\n case 'condition_rejected':\n return 'The job condition did not match, so this job was skipped.';\n case 'condition_errored':\n return 'The job condition could not be evaluated, so this job was skipped.';\n case 'user_cancelled':\n case 'run_cancelled':\n case 'timed_out':\n case 'runner_lost':\n case 'output_invalid':\n case 'step_failed':\n case 'unknown':\n case null:\n return 'This job did not start.';\n case 'output_too_large':\n return 'The materialized job output exceeded its configured size limit.';\n }\n}\n\nfunction preStepFailureDescription(\n reason: string | null,\n runner: string[] | null = null,\n statusReasonMessage: string | null = null,\n): string {\n const runnerCopy = runner?.length ? ` Required runner labels: ${runner.join(', ')}.` : '';\n\n switch (reason) {\n case 'runner_lost':\n return `The runner stopped responding before work began.${runnerCopy} Check runner availability before re-running the workflow.`;\n case 'timed_out':\n return `The job timed out before work began.${runnerCopy} Check runner capacity and timeout configuration before re-running the workflow.`;\n case 'user_cancelled':\n case 'run_cancelled':\n return 'The execution ended while the run was being cancelled.';\n case 'step_failed':\n return `The execution failed before step details were recorded.${runnerCopy} Review run annotations before re-running the workflow.`;\n case 'output_too_large':\n return statusReasonMessage || OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION;\n case 'output_invalid':\n return statusReasonMessage || MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION;\n case 'condition_errored':\n return 'The job condition could not be evaluated. Review run annotations before re-running the workflow.';\n case 'dependency_not_completed':\n case 'default_gate_rejected':\n return 'A required job did not complete successfully. Resolve that failure before re-running the workflow.';\n case 'condition_false':\n case 'condition_rejected':\n return 'The job condition did not match, so no work started.';\n case 'unknown':\n case null:\n return `Shipfox did not record a failure reason.${runnerCopy} Re-run only after checking the runner and workflow configuration.`;\n default:\n return `The execution ended because ${humanizeFailureReason(reason)}.${runnerCopy} Resolve that condition before re-running the workflow.`;\n }\n}\n\nfunction humanizeFailureReason(reason: string): string {\n return reason.replaceAll('_', ' ').replaceAll('-', ' ');\n}\n\nexport function CarriedOverStepPanel() {\n return (\n <EmptyState\n className=\"rounded-8 border border-border-neutral-base bg-background-components-base\"\n icon=\"componentLine\"\n title=\"Carried over from a previous attempt\"\n description=\"Not executed in this run.\"\n variant=\"panel\"\n />\n );\n}\n\nexport function toSelectedAttemptError(\n step: Step,\n error: Record<string, unknown> | null,\n): StepError | null {\n if (error === null) return null;\n\n const rawReason = error.reason;\n const parsedReason =\n typeof rawReason === 'string' &&\n STEP_ERROR_REASONS.has(rawReason as StepError['reason'] & string)\n ? (rawReason as NonNullable<StepError['reason']>)\n : undefined;\n const rawAgentConfigIssue = error.agentConfigIssue ?? error.agent_config_issue;\n const agentConfigIssue =\n typeof rawAgentConfigIssue === 'string' &&\n AGENT_CONFIG_ISSUES.has(rawAgentConfigIssue as NonNullable<StepError['agentConfigIssue']>)\n ? (rawAgentConfigIssue as NonNullable<StepError['agentConfigIssue']>)\n : undefined;\n const exitCode = error.exitCode ?? error.exit_code;\n const resolvedReason = parsedReason\n ? parsedReason\n : agentConfigIssue\n ? 'agent_config_invalid'\n : undefined;\n\n if (resolvedReason === undefined) return null;\n\n const code = typeof error.code === 'string' ? error.code : undefined;\n const managedProviderId =\n typeof error.managedProviderId === 'string'\n ? error.managedProviderId\n : typeof error.managed_provider_id === 'string'\n ? error.managed_provider_id\n : undefined;\n\n return {\n message: typeof error.message === 'string' ? error.message : '',\n ...(code === undefined ? {} : {code}),\n ...(managedProviderId === undefined ? {} : {managedProviderId}),\n exitCode: exitCode === null || typeof exitCode === 'number' ? exitCode : null,\n signal: typeof error.signal === 'string' ? error.signal : undefined,\n reason: resolvedReason,\n agentConfigIssue,\n category: step.type === 'setup' || step.type === 'checkout' ? 'setup' : 'user',\n };\n}\n\nexport function isAgentConfigFailure(step: Step, error: StepError | null): boolean {\n return step.type === 'agent' && error?.reason === 'agent_config_invalid';\n}\n\nexport function jobSucceededSummary(job: Job, execution: JobExecution): string | undefined {\n if (job.carriedOver || execution.status !== 'succeeded') return undefined;\n const stepCount = execution.steps.filter((step) => step.status === 'succeeded').length;\n if (stepCount === 0) return undefined;\n const duration = execution.displayDuration;\n return `${stepCount} step${stepCount === 1 ? '' : 's'} succeeded${duration ? ` in ${formatJobExecutionTime(duration)}` : ''}`;\n}\n"],"names":["Callout","CalloutContent","CalloutDescription","CalloutTitle","EmptyState","AGENT_CONFIG_ISSUES","deriveJobDisplayStatus","deriveJobExecutionDisplayStatus","STEP_ERROR_REASONS","formatJobExecutionTime","MATERIALIZED_OUTPUT_FAILURE_DESCRIPTION","OUTPUT_TOO_LARGE_FAILURE_DESCRIPTION","outputFailureDescriptionForExecution","jobExecution","steps","length","undefined","statusReason","statusReasonMessage","MaterializedOutputFailureNotice","description","role","type","variant","className","emptyStateForJob","job","carriedOver","title","status","displayStatus","mode","runner","join","preStepFailureDescription","sequence","emptyStateForMissingExecution","listenerStatus","skippedJobDescription","reason","runnerCopy","humanizeFailureReason","replaceAll","CarriedOverStepPanel","icon","toSelectedAttemptError","step","error","rawReason","parsedReason","has","rawAgentConfigIssue","agentConfigIssue","agent_config_issue","exitCode","exit_code","resolvedReason","code","managedProviderId","managed_provider_id","message","signal","category","isAgentConfigFailure","jobSucceededSummary","execution","stepCount","filter","duration","displayDuration"],"mappings":"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"}
|
|
@@ -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":"
|
|
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,6 +1,5 @@
|
|
|
1
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 { Panel } from '@shipfox/react-ui/panel';
|
|
4
3
|
import { WorkflowRunListEmpty, WorkflowRunListLoadMore, WorkflowRunListNoMatches, WorkflowRunListSkeleton, WorkflowRunListStaleError } from './workflow-run-list-states.js';
|
|
5
4
|
import { WorkflowRunRowList } from './workflow-run-row.js';
|
|
6
5
|
export function WorkflowRunListContent({ query, totalRuns, runs, workspaceSlug, projectSlug, hasActiveFilters, onClearFilters, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
@@ -17,26 +16,21 @@ export function WorkflowRunListContent({ query, totalRuns, runs, workspaceSlug,
|
|
|
17
16
|
// no-matches state even at zero loaded runs, so the way out is clearing them.
|
|
18
17
|
const showEmptyState = hasLoaded && totalRuns === 0 && !hasActiveFilters;
|
|
19
18
|
const showNoMatches = hasLoaded && runs.length === 0 && !showEmptyState;
|
|
20
|
-
return /*#__PURE__*/ _jsxs(
|
|
21
|
-
className: "min-h-0 flex-1 overflow-y-auto",
|
|
19
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
22
20
|
children: [
|
|
23
21
|
isPending ? /*#__PURE__*/ _jsx(WorkflowRunListSkeleton, {}) : null,
|
|
24
|
-
!isPending ? /*#__PURE__*/ _jsx(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
variant: "panel"
|
|
30
|
-
})
|
|
22
|
+
!isPending ? /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
23
|
+
query: query,
|
|
24
|
+
subject: "workflow runs",
|
|
25
|
+
icon: "pulseLine",
|
|
26
|
+
variant: "panel"
|
|
31
27
|
}) : null,
|
|
32
28
|
!isPending && refreshFailed ? /*#__PURE__*/ _jsx(WorkflowRunListStaleError, {
|
|
33
29
|
query: query
|
|
34
30
|
}) : null,
|
|
35
|
-
showEmptyState ? /*#__PURE__*/ _jsx(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
projectSlug: projectSlug
|
|
39
|
-
})
|
|
31
|
+
showEmptyState ? /*#__PURE__*/ _jsx(WorkflowRunListEmpty, {
|
|
32
|
+
workspaceSlug: workspaceSlug,
|
|
33
|
+
projectSlug: projectSlug
|
|
40
34
|
}) : null,
|
|
41
35
|
showNoMatches ? /*#__PURE__*/ _jsx(WorkflowRunListNoMatches, {
|
|
42
36
|
onClear: onClearFilters,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-content.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport
|
|
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 <>\n {isPending ? <WorkflowRunListSkeleton /> : null}\n {!isPending ? (\n <QueryLoadError query={query} subject=\"workflow runs\" icon=\"pulseLine\" variant=\"panel\" />\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 </>\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","subject","icon","variant","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;;YACGN,0BAAY,KAACf,+BAA6B;YAC1C,CAACe,0BACA,KAACnB;gBAAeQ,OAAOA;gBAAOoB,SAAQ;gBAAgBC,MAAK;gBAAYC,SAAQ;iBAC7E;YACH,CAACX,aAAaE,8BAAgB,KAAChB;gBAA0BG,OAAOA;iBAAY;YAC5EiB,+BACC,KAACxB;gBAAqBU,eAAeA;gBAAeC,aAAaA;iBAC/D;YACHc,8BACC,KAACvB;gBACC4B,SAASjB;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 +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,gCAkBtC;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,+BAqBA;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,+BAsCA;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"}
|
|
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from '@shipfox/react-ui/button';
|
|
3
3
|
import { Callout } from '@shipfox/react-ui/callout';
|
|
4
4
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
5
|
-
import { Panel } from '@shipfox/react-ui/panel';
|
|
6
5
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
7
6
|
import { Text } from '@shipfox/react-ui/typography';
|
|
8
7
|
import { Link } from '@tanstack/react-router';
|
|
@@ -12,7 +11,7 @@ const SKELETON_ROW_COUNT = 8;
|
|
|
12
11
|
* the first page lands. Only the initial load renders these: a refetch keeps the rows it has,
|
|
13
12
|
* per the design system's rule against animating frequently-updating data.
|
|
14
13
|
*/ export function WorkflowRunListSkeleton() {
|
|
15
|
-
return /*#__PURE__*/ _jsx(
|
|
14
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
16
15
|
role: "status",
|
|
17
16
|
"aria-label": "Loading runs",
|
|
18
17
|
className: "@container divide-y",
|
|
@@ -103,43 +102,41 @@ export function WorkflowRunListEmpty({ workspaceSlug, projectSlug }) {
|
|
|
103
102
|
* different ones. It is also the only reset within reach below `md`, where the toolbar's
|
|
104
103
|
* lives inside the filter sheet.
|
|
105
104
|
*/ export function WorkflowRunListNoMatches({ onClear, hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
106
|
-
return /*#__PURE__*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
]
|
|
142
|
-
})
|
|
105
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
106
|
+
className: "flex flex-col gap-inline",
|
|
107
|
+
children: [
|
|
108
|
+
isFetchNextPageError ? /*#__PURE__*/ _jsx(Callout, {
|
|
109
|
+
role: "alert",
|
|
110
|
+
type: "error",
|
|
111
|
+
children: "Could not load more workflow runs. Try again to continue searching older runs."
|
|
112
|
+
}) : null,
|
|
113
|
+
/*#__PURE__*/ _jsx(EmptyState, {
|
|
114
|
+
icon: "filterOffLine",
|
|
115
|
+
title: hasNextPage ? 'No matches in loaded history' : 'No matching runs',
|
|
116
|
+
description: hasNextPage ? 'No loaded run matches these filters. Load more to search further back.' : 'No run matches these filters.',
|
|
117
|
+
action: /*#__PURE__*/ _jsxs("div", {
|
|
118
|
+
className: "flex flex-wrap justify-center gap-inline",
|
|
119
|
+
children: [
|
|
120
|
+
hasNextPage && onLoadMore ? /*#__PURE__*/ _jsx(Button, {
|
|
121
|
+
type: "button",
|
|
122
|
+
size: "sm",
|
|
123
|
+
variant: "primary",
|
|
124
|
+
isLoading: isFetchingNextPage,
|
|
125
|
+
onClick: onLoadMore,
|
|
126
|
+
children: "Load more runs"
|
|
127
|
+
}) : null,
|
|
128
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
129
|
+
type: "button",
|
|
130
|
+
size: "sm",
|
|
131
|
+
variant: "secondary",
|
|
132
|
+
onClick: onClear,
|
|
133
|
+
children: "Show all runs"
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
}),
|
|
137
|
+
variant: "panel"
|
|
138
|
+
})
|
|
139
|
+
]
|
|
143
140
|
});
|
|
144
141
|
}
|
|
145
142
|
export function WorkflowRunListLoadMore({ hasNextPage, isFetchingNextPage, isFetchNextPageError, onLoadMore }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-states.tsx"],"sourcesContent":["import type {QueryLoadErrorQuery} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-states.tsx"],"sourcesContent":["import type {QueryLoadErrorQuery} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\n\nconst SKELETON_ROW_COUNT = 8;\n\n/**\n * Placeholder rows at the real row height, so the list does not resize under the cursor when\n * the first page lands. Only the initial load renders these: a refetch keeps the rows it has,\n * per the design system's rule against animating frequently-updating data.\n */\nexport function WorkflowRunListSkeleton() {\n return (\n <div role=\"status\" aria-label=\"Loading runs\" className=\"@container divide-y\">\n {Array.from({length: SKELETON_ROW_COUNT}).map((_, index) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: skeleton row, stable position\n key={index}\n className=\"flex min-h-44 items-center gap-inline px-row py-row @min-[976px]:h-44 @min-[976px]:py-0\"\n >\n <Skeleton className=\"size-14 shrink-0 rounded-full\" />\n <Skeleton className=\"h-12 w-[220px] max-w-[40%]\" />\n <Skeleton className=\"ml-auto hidden h-12 w-96 @min-[1200px]:block\" />\n <Skeleton className=\"h-12 w-48\" />\n <Skeleton className=\"h-12 w-48\" />\n </div>\n ))}\n </div>\n );\n}\n\n/**\n * Slim non-blocking banner shown when a background refetch fails after a prior success,\n * so the already-loaded rows stay on screen with the retry inline rather than being\n * replaced by a full-placeholder error.\n */\nexport function WorkflowRunListStaleError({query}: {query: QueryLoadErrorQuery}) {\n return (\n <div className=\"pb-[8px]\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex items-center justify-between gap-inline\">\n <Text size=\"xs\">Could not refresh workflow runs.</Text>\n <Button\n type=\"button\"\n size=\"2xs\"\n variant=\"secondary\"\n isLoading={query.isFetching}\n onClick={() => {\n void query.refetch();\n }}\n >\n Retry\n </Button>\n </div>\n </Callout>\n </div>\n );\n}\n\nexport function WorkflowRunListEmpty({\n workspaceSlug,\n projectSlug,\n}: {\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n}) {\n return (\n <EmptyState\n icon=\"pulseLine\"\n title=\"No runs yet\"\n description=\"Runs from this project's workflows appear here the moment one is launched.\"\n action={\n workspaceSlug && projectSlug ? (\n <Button asChild type=\"button\" size=\"sm\" variant=\"primary\">\n <Link\n to=\"/w/$workspaceSlug/p/$projectSlug/workflows\"\n params={{workspaceSlug, projectSlug}}\n >\n View workflows\n </Link>\n </Button>\n ) : null\n }\n variant=\"panel\"\n />\n );\n}\n\n/**\n * The filtered-empty state, deliberately distinct from the unfiltered one: someone who\n * filtered their way to nothing needs a way back out, not an onboarding call to action.\n *\n * Its reset is worded as its outcome rather than repeating the toolbar's \"Clear filters\"\n * verbatim, so the two controls on screen read as one action offered twice rather than two\n * different ones. It is also the only reset within reach below `md`, where the toolbar's\n * lives inside the filter sheet.\n */\nexport function WorkflowRunListNoMatches({\n onClear,\n hasNextPage,\n isFetchingNextPage,\n isFetchNextPageError,\n onLoadMore,\n}: {\n onClear: () => void;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n isFetchNextPageError: boolean;\n onLoadMore?: () => void;\n}) {\n return (\n <div className=\"flex flex-col gap-inline\">\n {isFetchNextPageError ? (\n <Callout role=\"alert\" type=\"error\">\n Could not load more workflow runs. Try again to continue searching older runs.\n </Callout>\n ) : null}\n <EmptyState\n icon=\"filterOffLine\"\n title={hasNextPage ? 'No matches in loaded history' : 'No matching runs'}\n description={\n hasNextPage\n ? 'No loaded run matches these filters. Load more to search further back.'\n : 'No run matches these filters.'\n }\n action={\n <div className=\"flex flex-wrap justify-center gap-inline\">\n {hasNextPage && onLoadMore ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"primary\"\n isLoading={isFetchingNextPage}\n onClick={onLoadMore}\n >\n Load more runs\n </Button>\n ) : null}\n <Button type=\"button\" size=\"sm\" variant=\"secondary\" onClick={onClear}>\n Show all runs\n </Button>\n </div>\n }\n variant=\"panel\"\n />\n </div>\n );\n}\n\nexport function WorkflowRunListLoadMore({\n hasNextPage,\n isFetchingNextPage,\n isFetchNextPageError,\n onLoadMore,\n}: {\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n isFetchNextPageError: boolean;\n onLoadMore?: () => void;\n}) {\n if (!hasNextPage || !onLoadMore) return null;\n\n return (\n <div className=\"flex flex-col items-center gap-inline border-t border-border-neutral-base py-row\">\n {isFetchNextPageError ? (\n <Callout role=\"alert\" type=\"error\">\n Could not load more workflow runs. Try again.\n </Callout>\n ) : null}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"secondary\"\n isLoading={isFetchingNextPage}\n onClick={onLoadMore}\n >\n Load more runs\n </Button>\n </div>\n );\n}\n"],"names":["Button","Callout","EmptyState","Skeleton","Text","Link","SKELETON_ROW_COUNT","WorkflowRunListSkeleton","div","role","aria-label","className","Array","from","length","map","_","index","WorkflowRunListStaleError","query","type","size","variant","isLoading","isFetching","onClick","refetch","WorkflowRunListEmpty","workspaceSlug","projectSlug","icon","title","description","action","asChild","to","params","WorkflowRunListNoMatches","onClear","hasNextPage","isFetchingNextPage","isFetchNextPageError","onLoadMore","WorkflowRunListLoadMore"],"mappings":";AACA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAE5C,MAAMC,qBAAqB;AAE3B;;;;CAIC,GACD,OAAO,SAASC;IACd,qBACE,KAACC;QAAIC,MAAK;QAASC,cAAW;QAAeC,WAAU;kBACpDC,MAAMC,IAAI,CAAC;YAACC,QAAQR;QAAkB,GAAGS,GAAG,CAAC,CAACC,GAAGC,sBAChD,MAACT;gBAGCG,WAAU;;kCAEV,KAACR;wBAASQ,WAAU;;kCACpB,KAACR;wBAASQ,WAAU;;kCACpB,KAACR;wBAASQ,WAAU;;kCACpB,KAACR;wBAASQ,WAAU;;kCACpB,KAACR;wBAASQ,WAAU;;;eAPfM;;AAYf;AAEA;;;;CAIC,GACD,OAAO,SAASC,0BAA0B,EAACC,KAAK,EAA+B;IAC7E,qBACE,KAACX;QAAIG,WAAU;kBACb,cAAA,KAACV;YAAQQ,MAAK;YAAQW,MAAK;sBACzB,cAAA,MAACZ;gBAAIG,WAAU;;kCACb,KAACP;wBAAKiB,MAAK;kCAAK;;kCAChB,KAACrB;wBACCoB,MAAK;wBACLC,MAAK;wBACLC,SAAQ;wBACRC,WAAWJ,MAAMK,UAAU;wBAC3BC,SAAS;4BACP,KAAKN,MAAMO,OAAO;wBACpB;kCACD;;;;;;AAOX;AAEA,OAAO,SAASC,qBAAqB,EACnCC,aAAa,EACbC,WAAW,EAIZ;IACC,qBACE,KAAC3B;QACC4B,MAAK;QACLC,OAAM;QACNC,aAAY;QACZC,QACEL,iBAAiBC,4BACf,KAAC7B;YAAOkC,OAAO;YAACd,MAAK;YAASC,MAAK;YAAKC,SAAQ;sBAC9C,cAAA,KAACjB;gBACC8B,IAAG;gBACHC,QAAQ;oBAACR;oBAAeC;gBAAW;0BACpC;;aAID;QAENP,SAAQ;;AAGd;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASe,yBAAyB,EACvCC,OAAO,EACPC,WAAW,EACXC,kBAAkB,EAClBC,oBAAoB,EACpBC,UAAU,EAOX;IACC,qBACE,MAAClC;QAAIG,WAAU;;YACZ8B,qCACC,KAACxC;gBAAQQ,MAAK;gBAAQW,MAAK;0BAAQ;iBAGjC;0BACJ,KAAClB;gBACC4B,MAAK;gBACLC,OAAOQ,cAAc,iCAAiC;gBACtDP,aACEO,cACI,2EACA;gBAENN,sBACE,MAACzB;oBAAIG,WAAU;;wBACZ4B,eAAeG,2BACd,KAAC1C;4BACCoB,MAAK;4BACLC,MAAK;4BACLC,SAAQ;4BACRC,WAAWiB;4BACXf,SAASiB;sCACV;6BAGC;sCACJ,KAAC1C;4BAAOoB,MAAK;4BAASC,MAAK;4BAAKC,SAAQ;4BAAYG,SAASa;sCAAS;;;;gBAK1EhB,SAAQ;;;;AAIhB;AAEA,OAAO,SAASqB,wBAAwB,EACtCJ,WAAW,EACXC,kBAAkB,EAClBC,oBAAoB,EACpBC,UAAU,EAMX;IACC,IAAI,CAACH,eAAe,CAACG,YAAY,OAAO;IAExC,qBACE,MAAClC;QAAIG,WAAU;;YACZ8B,qCACC,KAACxC;gBAAQQ,MAAK;gBAAQW,MAAK;0BAAQ;iBAGjC;0BACJ,KAACpB;gBACCoB,MAAK;gBACLC,MAAK;gBACLC,SAAQ;gBACRC,WAAWiB;gBACXf,SAASiB;0BACV;;;;AAKP"}
|
|
@@ -60,7 +60,7 @@ export function WorkflowRunListView({ runs, query, workspaceSlug, projectSlug, c
|
|
|
60
60
|
})
|
|
61
61
|
}),
|
|
62
62
|
/*#__PURE__*/ _jsx(PanelBody, {
|
|
63
|
-
className: "min-h-0 flex-1",
|
|
63
|
+
className: "min-h-0 flex-1 overflow-y-auto",
|
|
64
64
|
children: /*#__PURE__*/ _jsx(WorkflowRunListContent, {
|
|
65
65
|
query: query,
|
|
66
66
|
totalRuns: runs.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-view.tsx"],"sourcesContent":["import {Panel, PanelBody, PanelHeader} from '@shipfox/react-ui/panel';\nimport {TimeTickerProvider} from '@shipfox/react-ui/time-ticker';\nimport {Header} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useId, useMemo, useState} from 'react';\nimport {\n applyWorkflowRunFilterPatch,\n clearWorkflowRunFilters,\n hasWorkflowRunFilters,\n type WorkflowRunFilterPatch,\n type WorkflowRunsSearch,\n} from '#routes/inputs.js';\nimport {runMatchesFilters, workflowRunFacets} from './run-display.js';\nimport type {WorkflowRunListViewProps} from './types.js';\nimport {WorkflowRunFilters} from './workflow-run-filters.js';\nimport {WorkflowRunListContent} from './workflow-run-list-content.js';\n\nconst EMPTY_SEARCH: WorkflowRunsSearch = {};\n\nexport function WorkflowRunListView({\n runs,\n query,\n workspaceSlug,\n projectSlug,\n className,\n search = EMPTY_SEARCH,\n onFiltersChange,\n onClearFilters,\n hasNextPage = false,\n isFetchingNextPage = false,\n isFetchNextPageError = false,\n onLoadMore,\n}: WorkflowRunListViewProps) {\n const headingId = useId();\n const [localSearch, setLocalSearch] = useState<WorkflowRunsSearch>(search);\n const currentSearch = onFiltersChange ? search : localSearch;\n\n const filteredRuns = useMemo(\n () => runs.filter((run) => runMatchesFilters(run, currentSearch)),\n [runs, currentSearch],\n );\n const facets = useMemo(() => workflowRunFacets(runs, currentSearch), [runs, currentSearch]);\n const hasActiveFilters = hasWorkflowRunFilters(currentSearch);\n\n function handleFiltersChange(patch: WorkflowRunFilterPatch) {\n if (onFiltersChange) onFiltersChange(patch);\n else setLocalSearch((previous) => applyWorkflowRunFilterPatch(previous, patch));\n }\n\n function handleClearFilters() {\n // Uncontrolled, the view owns the filters, so it clears them itself and still reports the\n // change; a caller that passes only `onClearFilters` would otherwise see nothing happen.\n if (!onFiltersChange) setLocalSearch(clearWorkflowRunFilters);\n else if (!onClearFilters) onFiltersChange(CLEAR_ALL_FILTERS);\n onClearFilters?.();\n }\n\n return (\n <TimeTickerProvider intervalMs={1000} reducedMotionIntervalMs={10_000}>\n <section\n aria-labelledby={headingId}\n className={cn('flex min-h-0 min-w-0 flex-1 flex-col', className)}\n >\n {/* The tab strip above already reads \"Runs\", so the page heading is for structure and\n assistive tech rather than a second visible title competing with it. */}\n <Header id={headingId} variant=\"h1\" className=\"sr-only\">\n Workflow runs\n </Header>\n\n <Panel className=\"min-h-0 flex-1\">\n <PanelHeader className=\"flex-wrap\">\n <WorkflowRunFilters\n search={currentSearch}\n facets={facets}\n onChange={handleFiltersChange}\n onClear={handleClearFilters}\n hasActiveFilters={hasActiveFilters}\n />\n </PanelHeader>\n <PanelBody className=\"min-h-0 flex-1\">\n <WorkflowRunListContent\n query={query}\n totalRuns={runs.length}\n runs={filteredRuns}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n hasActiveFilters={hasActiveFilters}\n onClearFilters={handleClearFilters}\n hasNextPage={hasNextPage}\n isFetchingNextPage={isFetchingNextPage}\n isFetchNextPageError={isFetchNextPageError}\n {...(onLoadMore ? {onLoadMore} : {})}\n />\n </PanelBody>\n </Panel>\n </section>\n </TimeTickerProvider>\n );\n}\n\nconst CLEAR_ALL_FILTERS: WorkflowRunFilterPatch = {\n search: undefined,\n status: undefined,\n branch: undefined,\n actor: undefined,\n event: undefined,\n after: undefined,\n before: undefined,\n};\n"],"names":["Panel","PanelBody","PanelHeader","TimeTickerProvider","Header","cn","useId","useMemo","useState","applyWorkflowRunFilterPatch","clearWorkflowRunFilters","hasWorkflowRunFilters","runMatchesFilters","workflowRunFacets","WorkflowRunFilters","WorkflowRunListContent","EMPTY_SEARCH","WorkflowRunListView","runs","query","workspaceSlug","projectSlug","className","search","onFiltersChange","onClearFilters","hasNextPage","isFetchingNextPage","isFetchNextPageError","onLoadMore","headingId","localSearch","setLocalSearch","currentSearch","filteredRuns","filter","run","facets","hasActiveFilters","handleFiltersChange","patch","previous","handleClearFilters","CLEAR_ALL_FILTERS","intervalMs","reducedMotionIntervalMs","section","aria-labelledby","id","variant","onChange","onClear","totalRuns","length","undefined","status","branch","actor","event","after","before"],"mappings":";AAAA,SAAQA,KAAK,EAAEC,SAAS,EAAEC,WAAW,QAAO,0BAA0B;AACtE,SAAQC,kBAAkB,QAAO,gCAAgC;AACjE,SAAQC,MAAM,QAAO,+BAA+B;AACpD,SAAQC,EAAE,QAAO,0BAA0B;AAC3C,SAAQC,KAAK,EAAEC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAC/C,SACEC,2BAA2B,EAC3BC,uBAAuB,EACvBC,qBAAqB,QAGhB,oBAAoB;AAC3B,SAAQC,iBAAiB,EAAEC,iBAAiB,QAAO,mBAAmB;AAEtE,SAAQC,kBAAkB,QAAO,4BAA4B;AAC7D,SAAQC,sBAAsB,QAAO,iCAAiC;AAEtE,MAAMC,eAAmC,CAAC;AAE1C,OAAO,SAASC,oBAAoB,EAClCC,IAAI,EACJC,KAAK,EACLC,aAAa,EACbC,WAAW,EACXC,SAAS,EACTC,SAASP,YAAY,EACrBQ,eAAe,EACfC,cAAc,EACdC,cAAc,KAAK,EACnBC,qBAAqB,KAAK,EAC1BC,uBAAuB,KAAK,EAC5BC,UAAU,EACe;IACzB,MAAMC,YAAYxB;IAClB,MAAM,CAACyB,aAAaC,eAAe,GAAGxB,SAA6Be;IACnE,MAAMU,gBAAgBT,kBAAkBD,SAASQ;IAEjD,MAAMG,eAAe3B,QACnB,IAAMW,KAAKiB,MAAM,CAAC,CAACC,MAAQxB,kBAAkBwB,KAAKH,iBAClD;QAACf;QAAMe;KAAc;IAEvB,MAAMI,SAAS9B,QAAQ,IAAMM,kBAAkBK,MAAMe,gBAAgB;QAACf;QAAMe;KAAc;IAC1F,MAAMK,mBAAmB3B,sBAAsBsB;IAE/C,SAASM,oBAAoBC,KAA6B;QACxD,IAAIhB,iBAAiBA,gBAAgBgB;aAChCR,eAAe,CAACS,WAAahC,4BAA4BgC,UAAUD;IAC1E;IAEA,SAASE;QACP,0FAA0F;QAC1F,yFAAyF;QACzF,IAAI,CAAClB,iBAAiBQ,eAAetB;aAChC,IAAI,CAACe,gBAAgBD,gBAAgBmB;QAC1ClB;IACF;IAEA,qBACE,KAACtB;QAAmByC,YAAY;QAAMC,yBAAyB;kBAC7D,cAAA,MAACC;YACCC,mBAAiBjB;YACjBR,WAAWjB,GAAG,wCAAwCiB;;8BAItD,KAAClB;oBAAO4C,IAAIlB;oBAAWmB,SAAQ;oBAAK3B,WAAU;8BAAU;;8BAIxD,MAACtB;oBAAMsB,WAAU;;sCACf,KAACpB;4BAAYoB,WAAU;sCACrB,cAAA,KAACR;gCACCS,QAAQU;gCACRI,QAAQA;gCACRa,UAAUX;gCACVY,SAAST;gCACTJ,kBAAkBA;;;sCAGtB,KAACrC;4BAAUqB,WAAU;sCACnB,cAAA,KAACP;gCACCI,OAAOA;gCACPiC,WAAWlC,KAAKmC,MAAM;gCACtBnC,MAAMgB;gCACNd,eAAeA;gCACfC,aAAaA;gCACbiB,kBAAkBA;gCAClBb,gBAAgBiB;gCAChBhB,aAAaA;gCACbC,oBAAoBA;gCACpBC,sBAAsBA;gCACrB,GAAIC,aAAa;oCAACA;gCAAU,IAAI,CAAC,CAAC;;;;;;;;AAOjD;AAEA,MAAMc,oBAA4C;IAChDpB,QAAQ+B;IACRC,QAAQD;IACRE,QAAQF;IACRG,OAAOH;IACPI,OAAOJ;IACPK,OAAOL;IACPM,QAAQN;AACV"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-list/workflow-run-list-view.tsx"],"sourcesContent":["import {Panel, PanelBody, PanelHeader} from '@shipfox/react-ui/panel';\nimport {TimeTickerProvider} from '@shipfox/react-ui/time-ticker';\nimport {Header} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useId, useMemo, useState} from 'react';\nimport {\n applyWorkflowRunFilterPatch,\n clearWorkflowRunFilters,\n hasWorkflowRunFilters,\n type WorkflowRunFilterPatch,\n type WorkflowRunsSearch,\n} from '#routes/inputs.js';\nimport {runMatchesFilters, workflowRunFacets} from './run-display.js';\nimport type {WorkflowRunListViewProps} from './types.js';\nimport {WorkflowRunFilters} from './workflow-run-filters.js';\nimport {WorkflowRunListContent} from './workflow-run-list-content.js';\n\nconst EMPTY_SEARCH: WorkflowRunsSearch = {};\n\nexport function WorkflowRunListView({\n runs,\n query,\n workspaceSlug,\n projectSlug,\n className,\n search = EMPTY_SEARCH,\n onFiltersChange,\n onClearFilters,\n hasNextPage = false,\n isFetchingNextPage = false,\n isFetchNextPageError = false,\n onLoadMore,\n}: WorkflowRunListViewProps) {\n const headingId = useId();\n const [localSearch, setLocalSearch] = useState<WorkflowRunsSearch>(search);\n const currentSearch = onFiltersChange ? search : localSearch;\n\n const filteredRuns = useMemo(\n () => runs.filter((run) => runMatchesFilters(run, currentSearch)),\n [runs, currentSearch],\n );\n const facets = useMemo(() => workflowRunFacets(runs, currentSearch), [runs, currentSearch]);\n const hasActiveFilters = hasWorkflowRunFilters(currentSearch);\n\n function handleFiltersChange(patch: WorkflowRunFilterPatch) {\n if (onFiltersChange) onFiltersChange(patch);\n else setLocalSearch((previous) => applyWorkflowRunFilterPatch(previous, patch));\n }\n\n function handleClearFilters() {\n // Uncontrolled, the view owns the filters, so it clears them itself and still reports the\n // change; a caller that passes only `onClearFilters` would otherwise see nothing happen.\n if (!onFiltersChange) setLocalSearch(clearWorkflowRunFilters);\n else if (!onClearFilters) onFiltersChange(CLEAR_ALL_FILTERS);\n onClearFilters?.();\n }\n\n return (\n <TimeTickerProvider intervalMs={1000} reducedMotionIntervalMs={10_000}>\n <section\n aria-labelledby={headingId}\n className={cn('flex min-h-0 min-w-0 flex-1 flex-col', className)}\n >\n {/* The tab strip above already reads \"Runs\", so the page heading is for structure and\n assistive tech rather than a second visible title competing with it. */}\n <Header id={headingId} variant=\"h1\" className=\"sr-only\">\n Workflow runs\n </Header>\n\n <Panel className=\"min-h-0 flex-1\">\n <PanelHeader className=\"flex-wrap\">\n <WorkflowRunFilters\n search={currentSearch}\n facets={facets}\n onChange={handleFiltersChange}\n onClear={handleClearFilters}\n hasActiveFilters={hasActiveFilters}\n />\n </PanelHeader>\n <PanelBody className=\"min-h-0 flex-1 overflow-y-auto\">\n <WorkflowRunListContent\n query={query}\n totalRuns={runs.length}\n runs={filteredRuns}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n hasActiveFilters={hasActiveFilters}\n onClearFilters={handleClearFilters}\n hasNextPage={hasNextPage}\n isFetchingNextPage={isFetchingNextPage}\n isFetchNextPageError={isFetchNextPageError}\n {...(onLoadMore ? {onLoadMore} : {})}\n />\n </PanelBody>\n </Panel>\n </section>\n </TimeTickerProvider>\n );\n}\n\nconst CLEAR_ALL_FILTERS: WorkflowRunFilterPatch = {\n search: undefined,\n status: undefined,\n branch: undefined,\n actor: undefined,\n event: undefined,\n after: undefined,\n before: undefined,\n};\n"],"names":["Panel","PanelBody","PanelHeader","TimeTickerProvider","Header","cn","useId","useMemo","useState","applyWorkflowRunFilterPatch","clearWorkflowRunFilters","hasWorkflowRunFilters","runMatchesFilters","workflowRunFacets","WorkflowRunFilters","WorkflowRunListContent","EMPTY_SEARCH","WorkflowRunListView","runs","query","workspaceSlug","projectSlug","className","search","onFiltersChange","onClearFilters","hasNextPage","isFetchingNextPage","isFetchNextPageError","onLoadMore","headingId","localSearch","setLocalSearch","currentSearch","filteredRuns","filter","run","facets","hasActiveFilters","handleFiltersChange","patch","previous","handleClearFilters","CLEAR_ALL_FILTERS","intervalMs","reducedMotionIntervalMs","section","aria-labelledby","id","variant","onChange","onClear","totalRuns","length","undefined","status","branch","actor","event","after","before"],"mappings":";AAAA,SAAQA,KAAK,EAAEC,SAAS,EAAEC,WAAW,QAAO,0BAA0B;AACtE,SAAQC,kBAAkB,QAAO,gCAAgC;AACjE,SAAQC,MAAM,QAAO,+BAA+B;AACpD,SAAQC,EAAE,QAAO,0BAA0B;AAC3C,SAAQC,KAAK,EAAEC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAC/C,SACEC,2BAA2B,EAC3BC,uBAAuB,EACvBC,qBAAqB,QAGhB,oBAAoB;AAC3B,SAAQC,iBAAiB,EAAEC,iBAAiB,QAAO,mBAAmB;AAEtE,SAAQC,kBAAkB,QAAO,4BAA4B;AAC7D,SAAQC,sBAAsB,QAAO,iCAAiC;AAEtE,MAAMC,eAAmC,CAAC;AAE1C,OAAO,SAASC,oBAAoB,EAClCC,IAAI,EACJC,KAAK,EACLC,aAAa,EACbC,WAAW,EACXC,SAAS,EACTC,SAASP,YAAY,EACrBQ,eAAe,EACfC,cAAc,EACdC,cAAc,KAAK,EACnBC,qBAAqB,KAAK,EAC1BC,uBAAuB,KAAK,EAC5BC,UAAU,EACe;IACzB,MAAMC,YAAYxB;IAClB,MAAM,CAACyB,aAAaC,eAAe,GAAGxB,SAA6Be;IACnE,MAAMU,gBAAgBT,kBAAkBD,SAASQ;IAEjD,MAAMG,eAAe3B,QACnB,IAAMW,KAAKiB,MAAM,CAAC,CAACC,MAAQxB,kBAAkBwB,KAAKH,iBAClD;QAACf;QAAMe;KAAc;IAEvB,MAAMI,SAAS9B,QAAQ,IAAMM,kBAAkBK,MAAMe,gBAAgB;QAACf;QAAMe;KAAc;IAC1F,MAAMK,mBAAmB3B,sBAAsBsB;IAE/C,SAASM,oBAAoBC,KAA6B;QACxD,IAAIhB,iBAAiBA,gBAAgBgB;aAChCR,eAAe,CAACS,WAAahC,4BAA4BgC,UAAUD;IAC1E;IAEA,SAASE;QACP,0FAA0F;QAC1F,yFAAyF;QACzF,IAAI,CAAClB,iBAAiBQ,eAAetB;aAChC,IAAI,CAACe,gBAAgBD,gBAAgBmB;QAC1ClB;IACF;IAEA,qBACE,KAACtB;QAAmByC,YAAY;QAAMC,yBAAyB;kBAC7D,cAAA,MAACC;YACCC,mBAAiBjB;YACjBR,WAAWjB,GAAG,wCAAwCiB;;8BAItD,KAAClB;oBAAO4C,IAAIlB;oBAAWmB,SAAQ;oBAAK3B,WAAU;8BAAU;;8BAIxD,MAACtB;oBAAMsB,WAAU;;sCACf,KAACpB;4BAAYoB,WAAU;sCACrB,cAAA,KAACR;gCACCS,QAAQU;gCACRI,QAAQA;gCACRa,UAAUX;gCACVY,SAAST;gCACTJ,kBAAkBA;;;sCAGtB,KAACrC;4BAAUqB,WAAU;sCACnB,cAAA,KAACP;gCACCI,OAAOA;gCACPiC,WAAWlC,KAAKmC,MAAM;gCACtBnC,MAAMgB;gCACNd,eAAeA;gCACfC,aAAaA;gCACbiB,kBAAkBA;gCAClBb,gBAAgBiB;gCAChBhB,aAAaA;gCACbC,oBAAoBA;gCACpBC,sBAAsBA;gCACrB,GAAIC,aAAa;oCAACA;gCAAU,IAAI,CAAC,CAAC;;;;;;;;AAOjD;AAEA,MAAMc,oBAA4C;IAChDpB,QAAQ+B;IACRC,QAAQD;IACRE,QAAQF;IACRG,OAAOH;IACPI,OAAOJ;IACPK,OAAOL;IACPM,QAAQN;AACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-run-row.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-row.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workflow-run-row.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-list/workflow-run-row.tsx"],"names":[],"mappings":"AAiBA,OAAO,EACL,KAAK,mBAAmB,EAIzB,MAAM,uBAAuB,CAAC;AAI/B,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,aAAa,EACb,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,+BAaA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,aAAa,EACb,WAAW,GACZ,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,+BAgGA"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { TriggerSourceIcon } from '@shipfox/client-triggers';
|
|
3
3
|
import { Icon } from '@shipfox/react-ui/icon';
|
|
4
|
-
import { Panel } from '@shipfox/react-ui/panel';
|
|
5
4
|
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
6
5
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
7
6
|
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
@@ -18,18 +17,15 @@ export function WorkflowRunRowList({ runs, workspaceSlug, projectSlug }) {
|
|
|
18
17
|
return(// A container, not the viewport, drives the row's breakpoints. What a row can afford is its
|
|
19
18
|
// own width; keying off the viewport would keep the job strip hidden on a wide screen or
|
|
20
19
|
// crush it on a narrow one.
|
|
21
|
-
/*#__PURE__*/ _jsx(
|
|
22
|
-
className: "@container",
|
|
23
|
-
children:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
})
|
|
31
|
-
}, run.id))
|
|
32
|
-
})
|
|
20
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
21
|
+
className: "@container divide-y divide-border-neutral-base",
|
|
22
|
+
children: runs.map((run)=>/*#__PURE__*/ _jsx("li", {
|
|
23
|
+
children: /*#__PURE__*/ _jsx(WorkflowRunRow, {
|
|
24
|
+
run: run,
|
|
25
|
+
workspaceSlug: workspaceSlug,
|
|
26
|
+
projectSlug: projectSlug
|
|
27
|
+
})
|
|
28
|
+
}, run.id))
|
|
33
29
|
}));
|
|
34
30
|
}
|
|
35
31
|
/**
|