@shipfox/client-workflows 16.0.0 → 17.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/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +20 -0
- package/dist/components/identifier/identifier.js +2 -2
- package/dist/components/identifier/identifier.js.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js.map +1 -1
- package/dist/components/job-detail/job-context-panel.d.ts +6 -0
- package/dist/components/job-detail/job-context-panel.d.ts.map +1 -0
- package/dist/components/job-detail/job-context-panel.js +224 -0
- package/dist/components/job-detail/job-context-panel.js.map +1 -0
- package/dist/components/job-detail/job-detail-header.d.ts +3 -1
- package/dist/components/job-detail/job-detail-header.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-header.js +54 -48
- package/dist/components/job-detail/job-detail-header.js.map +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-view.js +80 -44
- package/dist/components/job-detail/job-detail-view.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 +19 -10
- package/dist/components/job-detail/job-empty-states.js.map +1 -1
- package/dist/components/job-detail/job-execution-switcher.js +4 -4
- package/dist/components/job-detail/job-execution-switcher.js.map +1 -1
- package/dist/components/job-detail/json-code.d.ts +14 -0
- package/dist/components/job-detail/json-code.d.ts.map +1 -0
- package/dist/components/job-detail/json-code.js +93 -0
- package/dist/components/job-detail/json-code.js.map +1 -0
- package/dist/components/job-detail/step-attempt-log-panel.d.ts.map +1 -1
- package/dist/components/job-detail/step-attempt-log-panel.js +9 -6
- package/dist/components/job-detail/step-attempt-log-panel.js.map +1 -1
- package/dist/components/job-detail/step-troubleshooting.d.ts +18 -0
- package/dist/components/job-detail/step-troubleshooting.d.ts.map +1 -0
- package/dist/components/job-detail/step-troubleshooting.js +493 -0
- package/dist/components/job-detail/step-troubleshooting.js.map +1 -0
- package/dist/components/job-graph/job-graph-content.d.ts.map +1 -1
- package/dist/components/job-graph/job-graph-content.js +5 -4
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/job-graph/job-node.js +3 -3
- package/dist/components/job-graph/job-node.js.map +1 -1
- package/dist/components/step-list/index.d.ts +1 -0
- package/dist/components/step-list/index.d.ts.map +1 -1
- package/dist/components/step-list/index.js.map +1 -1
- package/dist/components/step-list/step-list-model.d.ts.map +1 -1
- package/dist/components/step-list/step-list-model.js +5 -0
- package/dist/components/step-list/step-list-model.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +5 -1
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js +117 -82
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-duration-label.js +1 -1
- package/dist/components/workflow-run-duration-label.js.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.js +6 -6
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filters.js +4 -4
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +6 -6
- 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.js +7 -7
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +0 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +8 -13
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/index.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js +2 -2
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts +9 -2
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-list.js +28 -19
- package/dist/components/workflow-run-tabs/run-annotation-list.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +5 -5
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.js +7 -7
- package/dist/components/workflow-run-view/run-workspace-nav.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js +6 -6
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +72 -12
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +7 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts +9 -0
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js.map +1 -1
- package/dist/core/entities/step-attempt.d.ts +29 -0
- package/dist/core/entities/step-attempt.d.ts.map +1 -1
- package/dist/core/entities/step-attempt.js.map +1 -1
- package/dist/core/entities/step.d.ts +3 -1
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/run-annotation.d.ts +6 -0
- package/dist/core/run-annotation.d.ts.map +1 -1
- package/dist/core/run-annotation.js.map +1 -1
- package/dist/core/workflow-run.d.ts +1 -1
- package/dist/core/workflow-run.d.ts.map +1 -1
- package/dist/core/workflow-run.js.map +1 -1
- package/dist/hooks/api/annotations.d.ts +63 -0
- package/dist/hooks/api/annotations.d.ts.map +1 -0
- package/dist/hooks/api/annotations.js +145 -0
- package/dist/hooks/api/annotations.js.map +1 -0
- package/dist/hooks/api/step-attempt-detail.d.ts +14 -0
- package/dist/hooks/api/step-attempt-detail.d.ts.map +1 -0
- package/dist/hooks/api/step-attempt-detail.js +43 -0
- package/dist/hooks/api/step-attempt-detail.js.map +1 -0
- package/dist/hooks/api/workflow-run-mapper.d.ts +9 -2
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +47 -0
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/pages/project-workflows-page.js +19 -19
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-run-list-page.js +1 -1
- package/dist/pages/workflow-run-list-page.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/components/identifier/identifier.tsx +2 -2
- package/src/components/job-detail/agent-config-failure-callout.tsx +5 -1
- package/src/components/job-detail/job-context-panel.test.tsx +72 -0
- package/src/components/job-detail/job-context-panel.tsx +237 -0
- package/src/components/job-detail/job-detail-header.tsx +52 -46
- package/src/components/job-detail/job-detail-view.stories.tsx +555 -53
- package/src/components/job-detail/job-detail-view.tsx +87 -45
- package/src/components/job-detail/job-empty-states.tsx +23 -10
- package/src/components/job-detail/job-execution-switcher.tsx +5 -5
- package/src/components/job-detail/json-code.tsx +120 -0
- package/src/components/job-detail/step-attempt-log-panel.test.tsx +1 -0
- package/src/components/job-detail/step-attempt-log-panel.tsx +17 -6
- package/src/components/job-detail/step-troubleshooting.stories.tsx +120 -0
- package/src/components/job-detail/step-troubleshooting.test.tsx +337 -0
- package/src/components/job-detail/step-troubleshooting.tsx +537 -0
- package/src/components/job-graph/job-graph-content.tsx +4 -3
- package/src/components/job-graph/job-node.tsx +3 -3
- package/src/components/step-list/index.ts +1 -0
- package/src/components/step-list/step-list-model.ts +5 -0
- package/src/components/step-list/step-list.test.tsx +75 -2
- package/src/components/step-list/step-list.tsx +73 -20
- package/src/components/workflow-run-duration-label.tsx +1 -1
- package/src/components/workflow-run-list/job-status-strip.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-filters.tsx +4 -4
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-row.tsx +7 -7
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +11 -11
- package/src/components/workflow-run-tabs/index.ts +5 -1
- package/src/components/workflow-run-tabs/run-annotation-count-chip.tsx +2 -2
- package/src/components/workflow-run-tabs/run-annotation-list.tsx +25 -10
- package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +5 -5
- package/src/components/workflow-run-view/run-workspace-nav.tsx +7 -7
- package/src/components/workflow-run-view/workflow-run-states.tsx +6 -6
- package/src/components/workflow-run-view/workflow-run-view.tsx +114 -14
- package/src/core/entities/job-execution.ts +7 -0
- package/src/core/entities/job.ts +9 -0
- package/src/core/entities/step-attempt.ts +33 -0
- package/src/core/entities/step.ts +3 -1
- package/src/core/run-annotation.ts +6 -0
- package/src/core/workflow-run.ts +4 -0
- package/src/hooks/api/annotations.test.ts +84 -0
- package/src/hooks/api/annotations.ts +240 -0
- package/src/hooks/api/step-attempt-detail.ts +67 -0
- package/src/hooks/api/workflow-run-mapper.ts +46 -0
- package/src/hooks/api/workflow-runs.test.tsx +61 -1
- package/src/pages/project-workflows-page.tsx +19 -19
- package/src/pages/workflow-job-detail-page.test.tsx +52 -1
- package/src/pages/workflow-run-list-page.tsx +1 -1
- package/test/fixtures/workflow-run.ts +7 -0
- 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: 86 files with swc (708.85ms)
|
package/.turbo/turbo-type.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @shipfox/client-workflows
|
|
2
2
|
|
|
3
|
+
## 17.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4b0731e: Adds workflow troubleshooting details, evaluation traces, failure annotations, runner context, step output metadata, and lazy paginated annotation summaries.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 7b2436c: Migrates the workflow client surfaces to semantic spacing roles.
|
|
12
|
+
- Updated dependencies [4b0731e]
|
|
13
|
+
- @shipfox/api-workflows-dto@12.3.0
|
|
14
|
+
- @shipfox/annotations-dto@12.3.0
|
|
15
|
+
- @shipfox/client-logs@17.0.0
|
|
16
|
+
- @shipfox/react-ui@1.2.0
|
|
17
|
+
- @shipfox/client-ui@17.0.0
|
|
18
|
+
- @shipfox/client-projects@17.0.0
|
|
19
|
+
- @shipfox/client-shell@17.0.0
|
|
20
|
+
- @shipfox/client-triggers@17.0.0
|
|
21
|
+
- @shipfox/api-definitions-dto@12.3.0
|
|
22
|
+
|
|
3
23
|
## 16.0.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -84,7 +84,7 @@ export function Identifier({ display, value, label = 'identifier' }) {
|
|
|
84
84
|
onClick: ()=>{
|
|
85
85
|
void handleCopy();
|
|
86
86
|
},
|
|
87
|
-
className: "inline-flex h-20 min-w-0 shrink-0 items-center gap-
|
|
87
|
+
className: "inline-flex h-20 min-w-0 shrink-0 items-center gap-tight rounded-4 px-[var(--pad-menu-surface)] text-foreground-neutral-muted outline-none transition-colors hover:bg-background-components-hover hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active",
|
|
88
88
|
children: [
|
|
89
89
|
/*#__PURE__*/ _jsx(Icon, {
|
|
90
90
|
name: "copy",
|
|
@@ -136,7 +136,7 @@ function CopyFeedbackPortal({ anchor, children, kind }) {
|
|
|
136
136
|
top: placement === 'top' ? anchor.top : anchor.bottom,
|
|
137
137
|
transform: placement === 'top' ? `translate(-50%, calc(-100% - ${COPY_FEEDBACK_OFFSET_PX}px))` : `translate(-50%, ${COPY_FEEDBACK_OFFSET_PX}px)`
|
|
138
138
|
},
|
|
139
|
-
className: cn('pointer-events-none fixed z-50 whitespace-nowrap rounded-8 bg-background-components-base px-
|
|
139
|
+
className: cn('pointer-events-none fixed z-50 whitespace-nowrap rounded-8 bg-background-components-base px-tight py-[4px] text-xs font-display font-medium leading-20 shadow-tooltip', kind === 'failed' ? 'text-foreground-highlight-error' : 'text-foreground-neutral-base'),
|
|
140
140
|
children: children
|
|
141
141
|
}), document.body);
|
|
142
142
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/identifier/identifier.tsx"],"sourcesContent":["import {useCopyToClipboard} from '@shipfox/react-ui/hooks';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';\nimport {createPortal} from 'react-dom';\n\nconst COPY_FEEDBACK_OFFSET_PX = 8;\n\ntype CopyState = 'idle' | 'copied' | 'failed';\n\ninterface FeedbackAnchor {\n bottom: number;\n left: number;\n top: number;\n}\n\nexport function Identifier({\n display,\n value,\n label = 'identifier',\n}: {\n display: string;\n value: string;\n label?: string | undefined;\n}) {\n const [copyState, setCopyState] = useState<CopyState>('idle');\n const [tooltipOpen, setTooltipOpen] = useState(false);\n const [feedbackAnchor, setFeedbackAnchor] = useState<FeedbackAnchor | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const {copy} = useCopyToClipboard({\n text: value,\n onCopy: () => {\n setTemporaryCopyState('copied', 2500);\n },\n });\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const resetCopyFeedback = useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n setCopyState('idle');\n setTooltipOpen(false);\n setFeedbackAnchor(null);\n }, []);\n\n useEffect(() => {\n if (copyState === 'idle') return;\n\n window.addEventListener('scroll', resetCopyFeedback, true);\n window.addEventListener('resize', resetCopyFeedback);\n\n return () => {\n window.removeEventListener('scroll', resetCopyFeedback, true);\n window.removeEventListener('resize', resetCopyFeedback);\n };\n }, [copyState, resetCopyFeedback]);\n\n function setTemporaryCopyState(state: Exclude<CopyState, 'idle'>, timeout: number) {\n const rect = buttonRef.current?.getBoundingClientRect();\n setCopyState(state);\n setTooltipOpen(false);\n setFeedbackAnchor(\n rect\n ? {\n left: rect.left + rect.width / 2,\n top: rect.top,\n bottom: rect.bottom,\n }\n : null,\n );\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(resetCopyFeedback, timeout);\n }\n\n async function handleCopy() {\n try {\n await copy();\n } catch {\n setTemporaryCopyState('failed', 2500);\n }\n }\n\n const ariaLabel =\n copyState === 'copied'\n ? `Copied ${label} ${value}`\n : copyState === 'failed'\n ? `Could not copy ${label} ${value}`\n : `Copy ${label} ${value}`;\n\n const feedback =\n copyState === 'copied'\n ? {kind: copyState, label: 'Copied'}\n : copyState === 'failed'\n ? {kind: copyState, label: 'Could not copy'}\n : null;\n\n return (\n <>\n <Tooltip open={copyState === 'idle' ? tooltipOpen : false} onOpenChange={setTooltipOpen}>\n <TooltipTrigger asChild>\n <button\n ref={buttonRef}\n type=\"button\"\n aria-label={ariaLabel}\n onClick={() => {\n void handleCopy();\n }}\n className=\"inline-flex h-20 min-w-0 shrink-0 items-center gap-
|
|
1
|
+
{"version":3,"sources":["../../../src/components/identifier/identifier.tsx"],"sourcesContent":["import {useCopyToClipboard} from '@shipfox/react-ui/hooks';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';\nimport {createPortal} from 'react-dom';\n\nconst COPY_FEEDBACK_OFFSET_PX = 8;\n\ntype CopyState = 'idle' | 'copied' | 'failed';\n\ninterface FeedbackAnchor {\n bottom: number;\n left: number;\n top: number;\n}\n\nexport function Identifier({\n display,\n value,\n label = 'identifier',\n}: {\n display: string;\n value: string;\n label?: string | undefined;\n}) {\n const [copyState, setCopyState] = useState<CopyState>('idle');\n const [tooltipOpen, setTooltipOpen] = useState(false);\n const [feedbackAnchor, setFeedbackAnchor] = useState<FeedbackAnchor | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const {copy} = useCopyToClipboard({\n text: value,\n onCopy: () => {\n setTemporaryCopyState('copied', 2500);\n },\n });\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const resetCopyFeedback = useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n setCopyState('idle');\n setTooltipOpen(false);\n setFeedbackAnchor(null);\n }, []);\n\n useEffect(() => {\n if (copyState === 'idle') return;\n\n window.addEventListener('scroll', resetCopyFeedback, true);\n window.addEventListener('resize', resetCopyFeedback);\n\n return () => {\n window.removeEventListener('scroll', resetCopyFeedback, true);\n window.removeEventListener('resize', resetCopyFeedback);\n };\n }, [copyState, resetCopyFeedback]);\n\n function setTemporaryCopyState(state: Exclude<CopyState, 'idle'>, timeout: number) {\n const rect = buttonRef.current?.getBoundingClientRect();\n setCopyState(state);\n setTooltipOpen(false);\n setFeedbackAnchor(\n rect\n ? {\n left: rect.left + rect.width / 2,\n top: rect.top,\n bottom: rect.bottom,\n }\n : null,\n );\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(resetCopyFeedback, timeout);\n }\n\n async function handleCopy() {\n try {\n await copy();\n } catch {\n setTemporaryCopyState('failed', 2500);\n }\n }\n\n const ariaLabel =\n copyState === 'copied'\n ? `Copied ${label} ${value}`\n : copyState === 'failed'\n ? `Could not copy ${label} ${value}`\n : `Copy ${label} ${value}`;\n\n const feedback =\n copyState === 'copied'\n ? {kind: copyState, label: 'Copied'}\n : copyState === 'failed'\n ? {kind: copyState, label: 'Could not copy'}\n : null;\n\n return (\n <>\n <Tooltip open={copyState === 'idle' ? tooltipOpen : false} onOpenChange={setTooltipOpen}>\n <TooltipTrigger asChild>\n <button\n ref={buttonRef}\n type=\"button\"\n aria-label={ariaLabel}\n onClick={() => {\n void handleCopy();\n }}\n className=\"inline-flex h-20 min-w-0 shrink-0 items-center gap-tight rounded-4 px-[var(--pad-menu-surface)] text-foreground-neutral-muted outline-none transition-colors hover:bg-background-components-hover hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active\"\n >\n <Icon name=\"copy\" aria-hidden=\"true\" className=\"size-12 shrink-0\" />\n <Code as=\"span\" variant=\"label\" className=\"truncate\">\n {display}\n </Code>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Code as=\"span\" variant=\"label\" className=\"block max-w-[360px] truncate\">\n {value}\n </Code>\n </TooltipContent>\n </Tooltip>\n {feedback && feedbackAnchor ? (\n <CopyFeedbackPortal anchor={feedbackAnchor} kind={feedback.kind}>\n {feedback.label}\n </CopyFeedbackPortal>\n ) : null}\n </>\n );\n}\n\nfunction CopyFeedbackPortal({\n anchor,\n children,\n kind,\n}: {\n anchor: FeedbackAnchor;\n children: string;\n kind: Exclude<CopyState, 'idle'>;\n}) {\n const feedbackRef = useRef<HTMLSpanElement | null>(null);\n const [placement, setPlacement] = useState<'top' | 'bottom'>('bottom');\n\n useLayoutEffect(() => {\n const height = feedbackRef.current?.offsetHeight ?? 0;\n setPlacement(anchor.top >= height + COPY_FEEDBACK_OFFSET_PX ? 'top' : 'bottom');\n }, [anchor.top]);\n\n if (typeof document === 'undefined') return null;\n\n return createPortal(\n <span\n ref={feedbackRef}\n role=\"status\"\n style={{\n left: anchor.left,\n top: placement === 'top' ? anchor.top : anchor.bottom,\n transform:\n placement === 'top'\n ? `translate(-50%, calc(-100% - ${COPY_FEEDBACK_OFFSET_PX}px))`\n : `translate(-50%, ${COPY_FEEDBACK_OFFSET_PX}px)`,\n }}\n className={cn(\n 'pointer-events-none fixed z-50 whitespace-nowrap rounded-8 bg-background-components-base px-tight py-[4px] text-xs font-display font-medium leading-20 shadow-tooltip',\n kind === 'failed' ? 'text-foreground-highlight-error' : 'text-foreground-neutral-base',\n )}\n >\n {children}\n </span>,\n document.body,\n );\n}\n"],"names":["useCopyToClipboard","Icon","Tooltip","TooltipContent","TooltipTrigger","Code","cn","useCallback","useEffect","useLayoutEffect","useRef","useState","createPortal","COPY_FEEDBACK_OFFSET_PX","Identifier","display","value","label","copyState","setCopyState","tooltipOpen","setTooltipOpen","feedbackAnchor","setFeedbackAnchor","buttonRef","timeoutRef","undefined","copy","text","onCopy","setTemporaryCopyState","current","clearTimeout","resetCopyFeedback","window","addEventListener","removeEventListener","state","timeout","rect","getBoundingClientRect","left","width","top","bottom","setTimeout","handleCopy","ariaLabel","feedback","kind","open","onOpenChange","asChild","button","ref","type","aria-label","onClick","className","name","aria-hidden","as","variant","CopyFeedbackPortal","anchor","children","feedbackRef","placement","setPlacement","height","offsetHeight","document","span","role","style","transform","body"],"mappings":"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"}
|
|
@@ -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;AAEtE,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,+
|
|
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;AAEtE,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"}
|
|
@@ -7,7 +7,7 @@ export function AgentConfigFailureCallout({ workspaceSlug, config, error }) {
|
|
|
7
7
|
return /*#__PURE__*/ _jsx(Alert, {
|
|
8
8
|
variant: "warning",
|
|
9
9
|
animated: false,
|
|
10
|
-
className: "px-
|
|
10
|
+
className: "rounded-none border-x-0 border-t-0 border-b border-tag-warning-border bg-transparent px-0 py-row",
|
|
11
11
|
children: /*#__PURE__*/ _jsxs(AlertContent, {
|
|
12
12
|
children: [
|
|
13
13
|
/*#__PURE__*/ _jsx(AlertTitle, {
|
|
@@ -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
|
|
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,KAACV;QACCa,SAAQ;QACRC,UAAU;QACVC,WAAU;kBAEV,cAAA,MAACb;;8BACC,KAACE;8BAAYO,KAAKK,KAAK;;8BACvB,KAACb;8BAAkBQ,KAAKM,WAAW;;gBAClCN,KAAKO,eAAe,IAAIV,8BACvB,KAACP;8BACC,cAAA,KAACI;wBAAOc,OAAO;wBAACC,MAAK;wBAAMP,SAAQ;wBAAYQ,WAAU;kCACvD,cAAA,KAACf;4BAAKgB,IAAG;4BAAoCC,QAAQ;gCAACf;4BAAa;sCAAG;;;qBAKxE;;;;AAIZ;AAEA,SAASI,uBACPH,MAA8B,EAC9BC,KAAuB;IAEvB,MAAMc,WAAWC,YAAYhB,QAAQe,UAAU;IAC/C,MAAME,QAAQD,YAAYhB,QAAQiB,OAAO;IAEzC,OAAQhB,OAAOiB;QACb,KAAK;YACH,OAAO;gBACLX,OAAO,CAAC,0BAA0B,EAAEQ,UAAU;gBAC9CP,aAAa,CAAC,eAAe,EAAEO,SAAS,iFAAiF,EAAEA,SAAS,qCAAqC,CAAC;gBAC1KN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,uBAAuB,EAAEQ,UAAU;gBAC3CP,aAAa,CAAC,eAAe,EAAEO,SAAS,2DAA2D,EAAEA,SAAS,qCAAqC,CAAC;gBACpJN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aAAa,CAAC,qBAAqB,EAAEO,SAAS,8GAA8G,CAAC;gBAC7JN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aAAa,CAAC,eAAe,EAAES,MAAM,MAAM,EAAEF,SAAS,iHAAiH,CAAC;gBACxKN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;QACF,KAAKU;YACH,OAAO;gBACLZ,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;IACJ;AACF;AAEA,SAASO,YAAYI,KAAgC,EAAEC,QAAgB;IACrE,OAAOD,SAASC;AAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-context-panel.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/job-context-panel.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAuB,GAAG,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAKnF,wBAAgB,eAAe,CAAC,EAAC,GAAG,EAAE,SAAS,EAAC,EAAE;IAAC,GAAG,EAAE,GAAG,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAC,sCA4BpF"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
3
|
+
import { Sheet, SheetBody, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@shipfox/react-ui/sheet';
|
|
4
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
5
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
6
|
+
import { useState } from 'react';
|
|
7
|
+
import { formatJobExecutionTime } from './job-execution-time-text.js';
|
|
8
|
+
import { JsonCode } from './json-code.js';
|
|
9
|
+
import { EvaluationTrace } from './step-troubleshooting.js';
|
|
10
|
+
export function JobContextPanel({ job, execution }) {
|
|
11
|
+
const runner = execution.runner?.length ? execution.runner : job.runner;
|
|
12
|
+
const outputs = execution.outputs ?? job.outputs;
|
|
13
|
+
const trace = [
|
|
14
|
+
...job.evaluationTrace ?? [],
|
|
15
|
+
...execution.evaluationTrace ?? []
|
|
16
|
+
];
|
|
17
|
+
const statusReason = execution.statusReason ?? job.statusReason;
|
|
18
|
+
const hasTiming = Boolean(execution.queueTime || execution.runTime);
|
|
19
|
+
const hasContext = Boolean(runner?.length || outputs || execution.triggerEvents.length || job.success || statusReason || trace?.length || hasTiming);
|
|
20
|
+
if (!hasContext) return null;
|
|
21
|
+
return /*#__PURE__*/ _jsx(JobContextSheet, {
|
|
22
|
+
job: job,
|
|
23
|
+
execution: execution,
|
|
24
|
+
runner: runner,
|
|
25
|
+
outputs: outputs,
|
|
26
|
+
trace: trace,
|
|
27
|
+
statusReason: statusReason
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function JobContextSheet({ job, execution, runner, outputs, trace, statusReason }) {
|
|
31
|
+
const [open, setOpen] = useState(false);
|
|
32
|
+
const { conditionTrace, executionNameTrace } = splitJobEvaluationTrace(trace);
|
|
33
|
+
return /*#__PURE__*/ _jsxs(Sheet, {
|
|
34
|
+
open: open,
|
|
35
|
+
onOpenChange: setOpen,
|
|
36
|
+
children: [
|
|
37
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
38
|
+
children: [
|
|
39
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
40
|
+
asChild: true,
|
|
41
|
+
children: /*#__PURE__*/ _jsx("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
"aria-label": "Inspect job details",
|
|
44
|
+
onClick: ()=>setOpen(true),
|
|
45
|
+
className: "flex size-28 shrink-0 items-center justify-center rounded-4 bg-transparent text-foreground-neutral-muted outline-none transition-colors hover:bg-transparent hover:text-foreground-neutral-base active:bg-transparent focus-visible:shadow-button-neutral-focus",
|
|
46
|
+
children: /*#__PURE__*/ _jsx(Icon, {
|
|
47
|
+
name: "informationLine",
|
|
48
|
+
size: 14,
|
|
49
|
+
"aria-hidden": "true"
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}),
|
|
53
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
54
|
+
children: "Inspect job details"
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ _jsxs(SheetContent, {
|
|
59
|
+
side: "right",
|
|
60
|
+
className: "w-full sm:max-w-[560px]",
|
|
61
|
+
children: [
|
|
62
|
+
/*#__PURE__*/ _jsxs(SheetHeader, {
|
|
63
|
+
children: [
|
|
64
|
+
/*#__PURE__*/ _jsx(SheetTitle, {
|
|
65
|
+
children: job.displayName
|
|
66
|
+
}),
|
|
67
|
+
/*#__PURE__*/ _jsxs(SheetDescription, {
|
|
68
|
+
children: [
|
|
69
|
+
"Execution #",
|
|
70
|
+
execution.sequence,
|
|
71
|
+
" · ",
|
|
72
|
+
execution.displayName
|
|
73
|
+
]
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ _jsx(SheetBody, {
|
|
78
|
+
className: "gap-section",
|
|
79
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
80
|
+
className: "grid w-full min-w-0 gap-group min-[640px]:grid-cols-2",
|
|
81
|
+
children: [
|
|
82
|
+
runner?.length ? /*#__PURE__*/ _jsx(ContextList, {
|
|
83
|
+
label: "Runner",
|
|
84
|
+
values: runner,
|
|
85
|
+
mono: true
|
|
86
|
+
}) : null,
|
|
87
|
+
execution.queueTime || execution.runTime ? /*#__PURE__*/ _jsxs("div", {
|
|
88
|
+
className: "flex min-w-0 flex-col gap-tight",
|
|
89
|
+
children: [
|
|
90
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
91
|
+
size: "xs",
|
|
92
|
+
bold: true,
|
|
93
|
+
className: "text-foreground-neutral-base",
|
|
94
|
+
children: "Timing"
|
|
95
|
+
}),
|
|
96
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
97
|
+
className: "flex flex-wrap gap-inline text-xs text-foreground-neutral-muted",
|
|
98
|
+
children: [
|
|
99
|
+
execution.queueTime ? /*#__PURE__*/ _jsxs("span", {
|
|
100
|
+
children: [
|
|
101
|
+
"Queue ",
|
|
102
|
+
formatJobExecutionTime(execution.queueTime)
|
|
103
|
+
]
|
|
104
|
+
}) : null,
|
|
105
|
+
execution.runTime ? /*#__PURE__*/ _jsxs("span", {
|
|
106
|
+
children: [
|
|
107
|
+
"Run ",
|
|
108
|
+
formatJobExecutionTime(execution.runTime)
|
|
109
|
+
]
|
|
110
|
+
}) : null
|
|
111
|
+
]
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
}) : null,
|
|
115
|
+
outputs ? /*#__PURE__*/ _jsx(JsonCode, {
|
|
116
|
+
title: "Outputs",
|
|
117
|
+
value: outputs,
|
|
118
|
+
emptyMessage: "No outputs declared; the `outputs:` mapping is empty."
|
|
119
|
+
}) : null,
|
|
120
|
+
job.success ? /*#__PURE__*/ _jsx(ContextValue, {
|
|
121
|
+
label: "Condition",
|
|
122
|
+
value: job.success,
|
|
123
|
+
mono: true
|
|
124
|
+
}) : null,
|
|
125
|
+
statusReason ? /*#__PURE__*/ _jsx(ContextValue, {
|
|
126
|
+
label: "Status reason",
|
|
127
|
+
value: humanize(statusReason)
|
|
128
|
+
}) : null,
|
|
129
|
+
execution.triggerEvents.length ? /*#__PURE__*/ _jsx(JsonCode, {
|
|
130
|
+
title: `Trigger events (${execution.triggerEvents.length})`,
|
|
131
|
+
value: execution.triggerEvents
|
|
132
|
+
}) : null,
|
|
133
|
+
executionNameTrace.length ? /*#__PURE__*/ _jsx(EvaluationTraceSection, {
|
|
134
|
+
title: `Execution name evaluation (${executionNameTrace.length})`,
|
|
135
|
+
trace: executionNameTrace
|
|
136
|
+
}) : null,
|
|
137
|
+
conditionTrace.length ? /*#__PURE__*/ _jsx(EvaluationTraceSection, {
|
|
138
|
+
title: `Condition evaluation (${conditionTrace.length})`,
|
|
139
|
+
trace: conditionTrace
|
|
140
|
+
}) : null
|
|
141
|
+
]
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
]
|
|
145
|
+
})
|
|
146
|
+
]
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function EvaluationTraceSection({ title, trace }) {
|
|
150
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
151
|
+
className: "flex min-w-0 flex-col gap-tight",
|
|
152
|
+
children: [
|
|
153
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
154
|
+
size: "xs",
|
|
155
|
+
bold: true,
|
|
156
|
+
className: "text-foreground-neutral-base",
|
|
157
|
+
children: title
|
|
158
|
+
}),
|
|
159
|
+
/*#__PURE__*/ _jsx(EvaluationTrace, {
|
|
160
|
+
trace: trace
|
|
161
|
+
})
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function ContextValue({ label, value, mono = false }) {
|
|
166
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
167
|
+
className: "flex min-w-0 flex-col gap-tight",
|
|
168
|
+
children: [
|
|
169
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
170
|
+
size: "xs",
|
|
171
|
+
bold: true,
|
|
172
|
+
className: "text-foreground-neutral-base",
|
|
173
|
+
children: label
|
|
174
|
+
}),
|
|
175
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
176
|
+
size: "xs",
|
|
177
|
+
className: mono ? 'break-words font-code text-foreground-neutral-muted' : 'text-foreground-neutral-muted',
|
|
178
|
+
children: value
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function ContextList({ label, values, mono = false }) {
|
|
184
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
185
|
+
className: "flex min-w-0 flex-col gap-tight",
|
|
186
|
+
children: [
|
|
187
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
188
|
+
size: "xs",
|
|
189
|
+
bold: true,
|
|
190
|
+
className: "text-foreground-neutral-base",
|
|
191
|
+
children: label
|
|
192
|
+
}),
|
|
193
|
+
/*#__PURE__*/ _jsx("div", {
|
|
194
|
+
className: "flex min-w-0 flex-wrap gap-tight",
|
|
195
|
+
children: values.map((value)=>/*#__PURE__*/ _jsx(Code, {
|
|
196
|
+
as: "span",
|
|
197
|
+
variant: "label",
|
|
198
|
+
className: mono ? 'text-foreground-neutral-muted' : 'text-foreground-neutral-base',
|
|
199
|
+
children: value
|
|
200
|
+
}, value))
|
|
201
|
+
})
|
|
202
|
+
]
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function humanize(value) {
|
|
206
|
+
return value.replaceAll('_', ' ').replace(/\b\w/g, (letter)=>letter.toUpperCase());
|
|
207
|
+
}
|
|
208
|
+
function splitJobEvaluationTrace(trace) {
|
|
209
|
+
const conditionTrace = [];
|
|
210
|
+
const executionNameTrace = [];
|
|
211
|
+
for (const entry of trace){
|
|
212
|
+
if (!('dropped' in entry) && entry.field === 'job.execution_name') {
|
|
213
|
+
executionNameTrace.push(entry);
|
|
214
|
+
} else {
|
|
215
|
+
conditionTrace.push(entry);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
conditionTrace,
|
|
220
|
+
executionNameTrace
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
//# sourceMappingURL=job-context-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/job-detail/job-context-panel.tsx"],"sourcesContent":["import {Icon} from '@shipfox/react-ui/icon';\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from '@shipfox/react-ui/sheet';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport type {EvaluationTraceEntry, Job, JobExecution} from '#core/workflow-run.js';\nimport {formatJobExecutionTime} from './job-execution-time-text.js';\nimport {JsonCode} from './json-code.js';\nimport {EvaluationTrace} from './step-troubleshooting.js';\n\nexport function JobContextPanel({job, execution}: {job: Job; execution: JobExecution}) {\n const runner = execution.runner?.length ? execution.runner : job.runner;\n const outputs = execution.outputs ?? job.outputs;\n const trace = [...(job.evaluationTrace ?? []), ...(execution.evaluationTrace ?? [])];\n const statusReason = execution.statusReason ?? job.statusReason;\n const hasTiming = Boolean(execution.queueTime || execution.runTime);\n const hasContext = Boolean(\n runner?.length ||\n outputs ||\n execution.triggerEvents.length ||\n job.success ||\n statusReason ||\n trace?.length ||\n hasTiming,\n );\n\n if (!hasContext) return null;\n\n return (\n <JobContextSheet\n job={job}\n execution={execution}\n runner={runner}\n outputs={outputs}\n trace={trace}\n statusReason={statusReason}\n />\n );\n}\n\nfunction JobContextSheet({\n job,\n execution,\n runner,\n outputs,\n trace,\n statusReason,\n}: {\n job: Job;\n execution: JobExecution;\n runner: string[] | null;\n outputs: Record<string, unknown> | null;\n trace: EvaluationTraceEntry[];\n statusReason: JobExecution['statusReason'];\n}) {\n const [open, setOpen] = useState(false);\n const {conditionTrace, executionNameTrace} = splitJobEvaluationTrace(trace);\n\n return (\n <Sheet open={open} onOpenChange={setOpen}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label=\"Inspect job details\"\n onClick={() => setOpen(true)}\n className=\"flex size-28 shrink-0 items-center justify-center rounded-4 bg-transparent text-foreground-neutral-muted outline-none transition-colors hover:bg-transparent hover:text-foreground-neutral-base active:bg-transparent focus-visible:shadow-button-neutral-focus\"\n >\n <Icon name=\"informationLine\" size={14} aria-hidden=\"true\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Inspect job details</TooltipContent>\n </Tooltip>\n <SheetContent side=\"right\" className=\"w-full sm:max-w-[560px]\">\n <SheetHeader>\n <SheetTitle>{job.displayName}</SheetTitle>\n <SheetDescription>\n Execution #{execution.sequence} · {execution.displayName}\n </SheetDescription>\n </SheetHeader>\n <SheetBody className=\"gap-section\">\n <div className=\"grid w-full min-w-0 gap-group min-[640px]:grid-cols-2\">\n {runner?.length ? <ContextList label=\"Runner\" values={runner} mono /> : null}\n {execution.queueTime || execution.runTime ? (\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"xs\" bold className=\"text-foreground-neutral-base\">\n Timing\n </Text>\n <div className=\"flex flex-wrap gap-inline text-xs text-foreground-neutral-muted\">\n {execution.queueTime ? (\n <span>Queue {formatJobExecutionTime(execution.queueTime)}</span>\n ) : null}\n {execution.runTime ? (\n <span>Run {formatJobExecutionTime(execution.runTime)}</span>\n ) : null}\n </div>\n </div>\n ) : null}\n {outputs ? (\n <JsonCode\n title=\"Outputs\"\n value={outputs}\n emptyMessage=\"No outputs declared; the `outputs:` mapping is empty.\"\n />\n ) : null}\n {job.success ? <ContextValue label=\"Condition\" value={job.success} mono /> : null}\n {statusReason ? (\n <ContextValue label=\"Status reason\" value={humanize(statusReason)} />\n ) : null}\n {execution.triggerEvents.length ? (\n <JsonCode\n title={`Trigger events (${execution.triggerEvents.length})`}\n value={execution.triggerEvents}\n />\n ) : null}\n {executionNameTrace.length ? (\n <EvaluationTraceSection\n title={`Execution name evaluation (${executionNameTrace.length})`}\n trace={executionNameTrace}\n />\n ) : null}\n {conditionTrace.length ? (\n <EvaluationTraceSection\n title={`Condition evaluation (${conditionTrace.length})`}\n trace={conditionTrace}\n />\n ) : null}\n </div>\n </SheetBody>\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction EvaluationTraceSection({\n title,\n trace,\n}: {\n title: string;\n trace: readonly EvaluationTraceEntry[];\n}) {\n return (\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"xs\" bold className=\"text-foreground-neutral-base\">\n {title}\n </Text>\n <EvaluationTrace trace={trace} />\n </div>\n );\n}\n\nfunction ContextValue({\n label,\n value,\n mono = false,\n}: {\n label: string;\n value: string;\n mono?: boolean;\n}) {\n return (\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"xs\" bold className=\"text-foreground-neutral-base\">\n {label}\n </Text>\n <Text\n size=\"xs\"\n className={\n mono\n ? 'break-words font-code text-foreground-neutral-muted'\n : 'text-foreground-neutral-muted'\n }\n >\n {value}\n </Text>\n </div>\n );\n}\n\nfunction ContextList({\n label,\n values,\n mono = false,\n}: {\n label: string;\n values: string[];\n mono?: boolean;\n}) {\n return (\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"xs\" bold className=\"text-foreground-neutral-base\">\n {label}\n </Text>\n <div className=\"flex min-w-0 flex-wrap gap-tight\">\n {values.map((value) => (\n <Code\n key={value}\n as=\"span\"\n variant=\"label\"\n className={mono ? 'text-foreground-neutral-muted' : 'text-foreground-neutral-base'}\n >\n {value}\n </Code>\n ))}\n </div>\n </div>\n );\n}\n\nfunction humanize(value: string): string {\n return value.replaceAll('_', ' ').replace(/\\b\\w/g, (letter) => letter.toUpperCase());\n}\n\nfunction splitJobEvaluationTrace(trace: readonly EvaluationTraceEntry[]): {\n conditionTrace: EvaluationTraceEntry[];\n executionNameTrace: EvaluationTraceEntry[];\n} {\n const conditionTrace: EvaluationTraceEntry[] = [];\n const executionNameTrace: EvaluationTraceEntry[] = [];\n\n for (const entry of trace) {\n if (!('dropped' in entry) && entry.field === 'job.execution_name') {\n executionNameTrace.push(entry);\n } else {\n conditionTrace.push(entry);\n }\n }\n\n return {conditionTrace, executionNameTrace};\n}\n"],"names":["Icon","Sheet","SheetBody","SheetContent","SheetDescription","SheetHeader","SheetTitle","Tooltip","TooltipContent","TooltipTrigger","Code","Text","useState","formatJobExecutionTime","JsonCode","EvaluationTrace","JobContextPanel","job","execution","runner","length","outputs","trace","evaluationTrace","statusReason","hasTiming","Boolean","queueTime","runTime","hasContext","triggerEvents","success","JobContextSheet","open","setOpen","conditionTrace","executionNameTrace","splitJobEvaluationTrace","onOpenChange","asChild","button","type","aria-label","onClick","className","name","size","aria-hidden","side","displayName","sequence","div","ContextList","label","values","mono","bold","span","title","value","emptyMessage","ContextValue","humanize","EvaluationTraceSection","map","as","variant","replaceAll","replace","letter","toUpperCase","entry","field","push"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { RunAnnotationSummary } from '#core/run-annotation.js';
|
|
2
3
|
import { type Job, type JobExecution } from '#core/workflow-run.js';
|
|
3
4
|
export interface JobDetailHeaderProps {
|
|
@@ -10,6 +11,7 @@ export interface JobDetailHeaderProps {
|
|
|
10
11
|
runAttempt?: number | undefined;
|
|
11
12
|
/** Counts for this job only. Renders a link into the run's Annotations section, never a body. */
|
|
12
13
|
annotationSummary?: RunAnnotationSummary | undefined;
|
|
14
|
+
jobContext?: ReactNode;
|
|
13
15
|
}
|
|
14
|
-
export declare function JobDetailHeader({ job, selectedJobExecution, onSelectedJobExecutionChange, workspaceSlug, projectSlug, workflowRunId, runAttempt, annotationSummary, }: JobDetailHeaderProps): import("react").JSX.Element;
|
|
16
|
+
export declare function JobDetailHeader({ job, selectedJobExecution, onSelectedJobExecutionChange, workspaceSlug, projectSlug, workflowRunId, runAttempt, annotationSummary, jobContext, }: JobDetailHeaderProps): import("react").JSX.Element;
|
|
15
17
|
//# sourceMappingURL=job-detail-header.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-detail-header.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/job-detail-header.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"job-detail-header.d.ts","sourceRoot":"","sources":["../../../src/components/job-detail/job-detail-header.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAIL,KAAK,GAAG,EACR,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAK/B,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,GAAG,CAAC;IACT,oBAAoB,EAAE,YAAY,GAAG,SAAS,CAAC;IAC/C,4BAA4B,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACrD,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,oBAAoB,EACpB,4BAA4B,EAC5B,aAAa,EACb,WAAW,EACX,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,UAAU,GACX,EAAE,oBAAoB,+BA0DtB"}
|
|
@@ -9,65 +9,71 @@ import { defaultJobExecution, deriveJobDisplayStatus, deriveJobExecutionDisplayS
|
|
|
9
9
|
import { RunAnnotationCountChip } from '../workflow-run-tabs/index.js';
|
|
10
10
|
import { JobExecutionSwitcher } from './job-execution-switcher.js';
|
|
11
11
|
import { JobExecutionTimeText } from './job-execution-time-text.js';
|
|
12
|
-
export function JobDetailHeader({ job, selectedJobExecution, onSelectedJobExecutionChange, workspaceSlug, projectSlug, workflowRunId, runAttempt, annotationSummary }) {
|
|
12
|
+
export function JobDetailHeader({ job, selectedJobExecution, onSelectedJobExecutionChange, workspaceSlug, projectSlug, workflowRunId, runAttempt, annotationSummary, jobContext }) {
|
|
13
13
|
const selectedStatus = selectedExecutionStatus(job, selectedJobExecution);
|
|
14
14
|
const jobStatus = getWorkflowStatusVisual(selectedStatus);
|
|
15
15
|
return /*#__PURE__*/ _jsx("header", {
|
|
16
|
-
className: "border-b border-border-neutral-base px-
|
|
16
|
+
className: "border-b border-border-neutral-base px-row py-row",
|
|
17
17
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
18
|
-
className: "flex min-w-0
|
|
18
|
+
className: "flex min-w-0 items-start justify-between gap-cluster",
|
|
19
19
|
children: [
|
|
20
20
|
/*#__PURE__*/ _jsxs("div", {
|
|
21
|
-
className: "flex min-w-0
|
|
21
|
+
className: "flex min-w-0 flex-col gap-inline",
|
|
22
22
|
children: [
|
|
23
|
-
/*#__PURE__*/
|
|
24
|
-
|
|
25
|
-
size: 14,
|
|
26
|
-
tooltip: true,
|
|
27
|
-
ariaLabel: `Job status: ${jobStatus.label}`
|
|
28
|
-
}),
|
|
29
|
-
/*#__PURE__*/ _jsx(Code, {
|
|
30
|
-
as: "h2",
|
|
31
|
-
variant: "paragraph",
|
|
32
|
-
bold: true,
|
|
33
|
-
tabIndex: -1,
|
|
34
|
-
className: "min-w-0 truncate text-lg leading-24 text-foreground-neutral-base outline-none",
|
|
35
|
-
"data-job-heading": true,
|
|
36
|
-
children: job.displayName
|
|
37
|
-
})
|
|
38
|
-
]
|
|
39
|
-
}),
|
|
40
|
-
selectedJobExecution || annotationSummary?.total ? /*#__PURE__*/ _jsxs("div", {
|
|
41
|
-
className: "flex min-w-0 flex-wrap items-center gap-10 text-foreground-neutral-muted",
|
|
42
|
-
children: [
|
|
43
|
-
selectedJobExecution && job.executionCountVisible ? /*#__PURE__*/ _jsx(JobExecutionSwitcher, {
|
|
44
|
-
job: job,
|
|
45
|
-
selectedJobExecution: selectedJobExecution.id,
|
|
46
|
-
onSelectedJobExecutionChange: onSelectedJobExecutionChange,
|
|
47
|
-
variant: "title"
|
|
48
|
-
}) : null,
|
|
49
|
-
selectedJobExecution ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
23
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
24
|
+
className: "flex min-w-0 items-center gap-inline",
|
|
50
25
|
children: [
|
|
51
|
-
/*#__PURE__*/ _jsx(
|
|
52
|
-
|
|
53
|
-
|
|
26
|
+
/*#__PURE__*/ _jsx(WorkflowStatusIcon, {
|
|
27
|
+
status: selectedStatus,
|
|
28
|
+
size: 14,
|
|
29
|
+
tooltip: true,
|
|
30
|
+
ariaLabel: `Job status: ${jobStatus.label}`
|
|
54
31
|
}),
|
|
55
|
-
/*#__PURE__*/ _jsx(
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
33
|
+
as: "h1",
|
|
34
|
+
variant: "paragraph",
|
|
35
|
+
bold: true,
|
|
36
|
+
tabIndex: -1,
|
|
37
|
+
className: "min-w-0 truncate text-lg leading-24 text-foreground-neutral-base outline-none",
|
|
38
|
+
"data-job-heading": true,
|
|
39
|
+
children: job.displayName
|
|
58
40
|
})
|
|
59
41
|
]
|
|
60
|
-
})
|
|
61
|
-
/*#__PURE__*/
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
42
|
+
}),
|
|
43
|
+
selectedJobExecution || annotationSummary?.total ? /*#__PURE__*/ _jsxs("div", {
|
|
44
|
+
className: "flex min-w-0 flex-wrap items-center gap-inline text-foreground-neutral-muted",
|
|
45
|
+
children: [
|
|
46
|
+
selectedJobExecution && job.executionCountVisible ? /*#__PURE__*/ _jsx(JobExecutionSwitcher, {
|
|
47
|
+
job: job,
|
|
48
|
+
selectedJobExecution: selectedJobExecution.id,
|
|
49
|
+
onSelectedJobExecutionChange: onSelectedJobExecutionChange,
|
|
50
|
+
variant: "title"
|
|
51
|
+
}) : null,
|
|
52
|
+
selectedJobExecution ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
53
|
+
children: [
|
|
54
|
+
/*#__PURE__*/ _jsx(JobDurationMeta, {
|
|
55
|
+
execution: selectedJobExecution,
|
|
56
|
+
kind: "queue"
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ _jsx(JobDurationMeta, {
|
|
59
|
+
execution: selectedJobExecution,
|
|
60
|
+
kind: "run"
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
}) : null,
|
|
64
|
+
/*#__PURE__*/ _jsx(RunAnnotationCountChip, {
|
|
65
|
+
summary: annotationSummary,
|
|
66
|
+
workspaceSlug: workspaceSlug,
|
|
67
|
+
projectSlug: projectSlug,
|
|
68
|
+
workflowRunId: workflowRunId,
|
|
69
|
+
runAttempt: runAttempt,
|
|
70
|
+
jobId: job.id
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}) : null
|
|
69
74
|
]
|
|
70
|
-
})
|
|
75
|
+
}),
|
|
76
|
+
jobContext
|
|
71
77
|
]
|
|
72
78
|
})
|
|
73
79
|
});
|
|
@@ -91,7 +97,7 @@ function JobDurationMeta({ execution, kind }) {
|
|
|
91
97
|
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
92
98
|
asChild: true,
|
|
93
99
|
children: /*#__PURE__*/ _jsxs("span", {
|
|
94
|
-
className: "inline-flex items-center gap-
|
|
100
|
+
className: "inline-flex items-center gap-tight whitespace-nowrap font-code text-xs leading-20 tabular-nums",
|
|
95
101
|
children: [
|
|
96
102
|
/*#__PURE__*/ _jsx(Icon, {
|
|
97
103
|
name: kind === 'queue' ? 'hourglassLine' : 'timerLine',
|