@cat-factory/app 0.307.1 → 0.309.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/README.md +21 -0
- package/app/assets/css/main.css +22 -0
- package/app/assets/css/prose.css +4 -4
- package/app/assets/css/type.css +24 -0
- package/app/components/assistant/AssistantModal.vue +3 -2
- package/app/components/auth/UserMenu.vue +1 -1
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +15 -15
- package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
- package/app/components/binaryOutput/StoredAssetView.vue +5 -5
- package/app/components/board/AddTaskModal.vue +16 -14
- package/app/components/board/AgentFailureCard.vue +9 -9
- package/app/components/board/AgentFailureHistory.vue +1 -1
- package/app/components/board/CreateInitiativeModal.vue +2 -2
- package/app/components/board/FailureDetail.vue +1 -1
- package/app/components/board/FailureHistoryList.vue +5 -5
- package/app/components/board/RecurringPipelineModal.vue +12 -11
- package/app/components/board/ReviewFrictionDialog.vue +4 -3
- package/app/components/board/StepExecutionHistory.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +1 -1
- package/app/components/board/nodes/BlockNode.vue +8 -9
- package/app/components/board/nodes/EpicNode.vue +4 -4
- package/app/components/board/nodes/FrameSwimlanes.vue +4 -7
- package/app/components/board/nodes/InitiativeCard.vue +4 -4
- package/app/components/board/nodes/LaneGroup.vue +3 -5
- package/app/components/board/nodes/TaskCard.vue +8 -8
- package/app/components/board/nodes/TaskLane.vue +3 -3
- package/app/components/board/nodes/TaskPipelineMini.vue +13 -12
- package/app/components/bootstrap/AdoptionReviewModal.vue +7 -6
- package/app/components/bootstrap/BootstrapModal.vue +11 -10
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +8 -7
- package/app/components/bugFishing/BugFishingWindow.vue +37 -36
- package/app/components/clarity/ClarityReviewWindow.vue +8 -7
- package/app/components/common/AsyncViewError.vue +1 -1
- package/app/components/common/ClarificationItem.vue +6 -6
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +1 -1
- package/app/components/common/InterviewGateNotice.vue +4 -4
- package/app/components/common/MarkdownProse.vue +8 -2
- package/app/components/common/SectionLabel.vue +38 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
- package/app/components/context/ContextAttachmentFields.vue +9 -8
- package/app/components/docs/DocInterviewWindow.vue +10 -9
- package/app/components/documents/ContextDocumentPicker.vue +10 -12
- package/app/components/documents/DocumentImportModal.vue +3 -2
- package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
- package/app/components/documents/DocumentSyncState.vue +1 -1
- package/app/components/documents/DocumentTemplatesModal.vue +5 -4
- package/app/components/documents/RepoContextDocPicker.vue +3 -6
- package/app/components/documents/StartFromDesignModal.vue +4 -4
- package/app/components/documents/TaskContextDocs.vue +1 -1
- package/app/components/environments/EnvSetupStepper.vue +3 -3
- package/app/components/environments/EnvironmentStatusPanel.vue +11 -10
- package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
- package/app/components/environments/steps/EnvReviewStep.vue +23 -22
- package/app/components/environments/steps/EnvSaveStep.vue +5 -5
- package/app/components/focus/BlockFocusView.vue +11 -10
- package/app/components/followUp/FollowUpWindow.vue +10 -10
- package/app/components/forkDecision/ForkDecisionWindow.vue +23 -26
- package/app/components/foundational/FoundationalContractSummary.vue +2 -2
- package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -3
- package/app/components/foundational/FoundationalServiceRegistry.vue +3 -3
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/fragments/FragmentLibraryManager.vue +3 -3
- package/app/components/fragments/FragmentSelector.vue +10 -11
- package/app/components/gates/GateFailingCheckList.vue +3 -3
- package/app/components/gates/GateResultView.vue +39 -38
- package/app/components/github/AddServiceFromRepoModal.vue +5 -4
- package/app/components/github/BranchProtectionPreflight.vue +5 -5
- package/app/components/github/GitHubConnect.vue +5 -3
- package/app/components/github/GitHubPanel.vue +14 -13
- package/app/components/github/RepoTreeBrowser.vue +1 -1
- package/app/components/humanTest/HumanTestWindow.vue +18 -17
- package/app/components/initiative/InitiativePlanNotice.vue +3 -3
- package/app/components/initiative/InitiativePlanReview.vue +19 -21
- package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
- package/app/components/initiative/InitiativeTrackerWindow.vue +54 -53
- package/app/components/judge/JudgeResultView.vue +24 -25
- package/app/components/kaizen/KaizenPanel.vue +4 -4
- package/app/components/kaizen/KaizenStepStatus.vue +7 -6
- package/app/components/layout/AccountAuditLog.vue +1 -1
- package/app/components/layout/AccountDeploymentSettings.vue +10 -10
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +7 -7
- package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +4 -0
- package/app/components/layout/AiProvidersBanner.vue +1 -1
- package/app/components/layout/AppearanceSwitcher.vue +1 -1
- package/app/components/layout/BoardSwitcher.vue +3 -2
- package/app/components/layout/BoardToolbar.vue +6 -2
- package/app/components/layout/CommandBar.vue +4 -2
- package/app/components/layout/DefaultTestEnvBanner.vue +2 -2
- package/app/components/layout/IntegrationsHub.vue +4 -3
- package/app/components/layout/LanguageSwitcher.vue +1 -1
- package/app/components/layout/ModelProvidersHub.vue +6 -4
- package/app/components/layout/NotificationsInbox.vue +8 -7
- package/app/components/layout/PersonalSetupModal.vue +5 -3
- package/app/components/layout/RolePrompt.vue +1 -1
- package/app/components/layout/SideBar.vue +3 -5
- package/app/components/layout/SpendWarningBanner.vue +3 -3
- package/app/components/layout/TranslationWarningBanner.vue +1 -1
- package/app/components/layout/UiModeSwitcher.vue +7 -6
- package/app/components/layout/UiRoleSwitcher.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +6 -6
- package/app/components/media/ImageCompare.vue +16 -16
- package/app/components/merge/MergeEffortChips.vue +4 -6
- package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
- package/app/components/observability/OutcomeFilterChips.vue +1 -1
- package/app/components/observability/RunFailureSummary.vue +14 -17
- package/app/components/observability/StepMetricsBar.vue +9 -8
- package/app/components/observability/StepModelActivity.vue +4 -3
- package/app/components/observability/ToolCallList.vue +15 -18
- package/app/components/outcome/OutcomeSummaryWindow.vue +43 -42
- package/app/components/palettes/AgentPalette.vue +7 -5
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +2 -1
- package/app/components/panels/AgentStepDetail.vue +27 -30
- package/app/components/panels/AttemptEntryHeader.vue +2 -2
- package/app/components/panels/DecisionModal.vue +1 -1
- package/app/components/panels/GenericStructuredResultView.vue +6 -5
- package/app/components/panels/InspectorPanel.vue +15 -13
- package/app/components/panels/MergerResultView.vue +10 -9
- package/app/components/panels/ObservabilityPanel.vue +66 -76
- package/app/components/panels/OperatorDashboardPanel.vue +27 -26
- package/app/components/panels/ReportsPanel.vue +26 -25
- package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
- package/app/components/panels/ResultWindowShell.vue +19 -18
- package/app/components/panels/RunDetailLoadState.vue +1 -1
- package/app/components/panels/StepContainerStatus.vue +8 -7
- package/app/components/panels/StepDelegatedStatus.vue +13 -12
- package/app/components/panels/StepEffortReport.vue +12 -17
- package/app/components/panels/StepFragmentAdherence.vue +9 -10
- package/app/components/panels/StepMetadataCard.vue +41 -43
- package/app/components/panels/StepReproductionReport.vue +18 -20
- package/app/components/panels/StepRunMeta.vue +27 -26
- package/app/components/panels/StepTestReport.vue +16 -15
- package/app/components/panels/StepToolServers.vue +7 -8
- package/app/components/panels/StepValidationReport.vue +5 -5
- package/app/components/panels/inspector/ContainerSummary.vue +4 -4
- package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
- package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
- package/app/components/panels/inspector/EpicChildren.vue +8 -7
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
- package/app/components/panels/inspector/FrontendConfig.vue +26 -34
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +7 -4
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
- package/app/components/panels/inspector/ServiceConnections.vue +2 -2
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
- package/app/components/panels/inspector/ServiceTestConfig.vue +41 -45
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
- package/app/components/panels/inspector/TaskExecution.vue +13 -12
- package/app/components/panels/inspector/TaskRunSettings.vue +35 -38
- package/app/components/panels/inspector/TaskStructure.vue +5 -4
- package/app/components/pipeline/AgentPromptEditor.vue +15 -14
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
- package/app/components/pipeline/EstimateThresholdFields.vue +2 -2
- package/app/components/pipeline/GateConfigFields.vue +6 -6
- package/app/components/pipeline/IterationCapPrompt.vue +1 -1
- package/app/components/pipeline/PipelineBuilder.vue +28 -27
- package/app/components/pipeline/PipelineHealthModal.vue +7 -7
- package/app/components/pipeline/PipelinePicker.vue +3 -3
- package/app/components/pipeline/PipelinePreview.vue +6 -7
- package/app/components/pipeline/PipelineProgress.vue +23 -24
- package/app/components/prReview/PrReviewWindow.vue +42 -41
- package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
- package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
- package/app/components/providers/ApiKeysSection.vue +7 -6
- package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
- package/app/components/providers/VendorCredentialsModal.vue +5 -4
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
- package/app/components/ralph/RalphLoopResultView.vue +25 -26
- package/app/components/requirements/RequirementsReviewWindow.vue +13 -12
- package/app/components/riskPolicy/RiskPolicyPicker.vue +5 -5
- package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
- package/app/components/sandbox/SandboxPanel.vue +21 -20
- package/app/components/settings/ApiTokensPanel.vue +1 -1
- package/app/components/settings/BudgetSettings.vue +18 -17
- package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
- package/app/components/settings/CloudflareHandlerSection.vue +16 -16
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
- package/app/components/settings/ConnectionTestVerdict.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +21 -20
- package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
- package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +14 -15
- package/app/components/settings/InfrastructureBackendPicker.vue +2 -2
- package/app/components/settings/IssueTrackerPanel.vue +9 -15
- package/app/components/settings/KubernetesEngineForm.vue +9 -8
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
- package/app/components/settings/LocalModelEndpointsPanel.vue +10 -9
- package/app/components/settings/MergeClassRulesEditor.vue +6 -5
- package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
- package/app/components/settings/ModelConfigurationPanel.vue +8 -11
- package/app/components/settings/ModelPresetHealthModal.vue +3 -3
- package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
- package/app/components/settings/OpenRouterCatalogPanel.vue +6 -5
- package/app/components/settings/PackageRegistriesPanel.vue +4 -4
- package/app/components/settings/ProviderConnectionTab.vue +5 -4
- package/app/components/settings/ProviderManifestEditor.vue +9 -8
- package/app/components/settings/ProviderPreferenceEditor.vue +8 -7
- package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
- package/app/components/settings/RiskPolicyEditorRow.vue +18 -17
- package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
- package/app/components/settings/RiskPolicyPanel.vue +11 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +5 -4
- package/app/components/settings/SharedStacksPanel.vue +5 -5
- package/app/components/settings/TaskSourceCard.vue +2 -2
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
- package/app/components/settings/ToolServerChecklist.vue +22 -22
- package/app/components/settings/UsageSettings.vue +13 -13
- package/app/components/settings/UserSecretsSection.vue +4 -3
- package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
- package/app/components/skills/ReviewSkillQueue.vue +8 -7
- package/app/components/skills/SkillLibraryManager.vue +2 -2
- package/app/components/slack/SlackPanel.vue +8 -7
- package/app/components/spec/ServiceSpecWindow.vue +15 -16
- package/app/components/tasks/BugHuntModal.vue +1 -1
- package/app/components/tasks/ContextIssuePicker.vue +4 -6
- package/app/components/tasks/TaskContextIssues.vue +1 -1
- package/app/components/tasks/TaskImportModal.vue +3 -2
- package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
- package/app/components/testing/TestReportWindow.vue +54 -53
- package/app/components/tutorial/TutorialNudge.vue +3 -2
- package/app/components/tutorial/TutorialOverlay.vue +3 -2
- package/app/components/vcs/GitLabConnect.vue +1 -1
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +23 -25
- package/app/composables/usePipelineErrorToast.ts +2 -0
- package/app/utils/catalog.ts +8 -0
- package/app/utils/theme/builtins.ts +7 -1
- package/i18n/locales/de.json +6 -3
- package/i18n/locales/en.json +6 -3
- package/i18n/locales/es.json +6 -3
- package/i18n/locales/fr.json +6 -3
- package/i18n/locales/he.json +6 -3
- package/i18n/locales/it.json +6 -3
- package/i18n/locales/ja.json +6 -3
- package/i18n/locales/pl.json +6 -3
- package/i18n/locales/tr.json +6 -3
- package/i18n/locales/uk.json +6 -3
- package/package.json +2 -2
|
@@ -41,7 +41,7 @@ function addTask() {
|
|
|
41
41
|
>
|
|
42
42
|
<UIcon name="i-lucide-package" class="h-3.5 w-3.5 text-app-secondary-400" />
|
|
43
43
|
<span class="truncate text-xs text-default">{{ m.title }}</span>
|
|
44
|
-
<span class="ms-auto text-
|
|
44
|
+
<span class="ms-auto text-3xs text-dimmed">{{
|
|
45
45
|
t(
|
|
46
46
|
'inspector.container.taskCount',
|
|
47
47
|
{ count: board.tasksOf(m.id).length },
|
|
@@ -76,11 +76,11 @@ function addTask() {
|
|
|
76
76
|
:style="{ backgroundColor: STATUS_META[task.status].color }"
|
|
77
77
|
/>
|
|
78
78
|
<span class="truncate text-xs text-default">{{ task.title }}</span>
|
|
79
|
-
<span class="ms-auto text-
|
|
79
|
+
<span class="ms-auto text-3xs text-dimmed">{{ STATUS_META[task.status].label }}</span>
|
|
80
80
|
</li>
|
|
81
81
|
</ul>
|
|
82
|
-
<div v-else class="text-
|
|
83
|
-
<p v-if="isFrame" class="text-
|
|
82
|
+
<div v-else class="text-2xs text-dimmed">{{ t('inspector.container.noTasks') }}</div>
|
|
83
|
+
<p v-if="isFrame" class="text-2xs text-dimmed">
|
|
84
84
|
{{ t('inspector.container.servicesHint') }}
|
|
85
85
|
</p>
|
|
86
86
|
</InspectorSection>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// search as the add-service picker (`useRepoSearch`), not a filter over the synced projection.
|
|
7
7
|
import type { Block, GitHubAvailableRepo, ReferenceRepo } from '~/types/domain'
|
|
8
8
|
import RepoSearchEmpty from '~/components/github/RepoSearchEmpty.vue'
|
|
9
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
9
10
|
|
|
10
11
|
const props = defineProps<{ block: Block }>()
|
|
11
12
|
|
|
@@ -83,9 +84,9 @@ function detach(repoId: number) {
|
|
|
83
84
|
<template>
|
|
84
85
|
<div data-testid="doc-reference-repos">
|
|
85
86
|
<div class="mb-1 flex items-center justify-between">
|
|
86
|
-
<
|
|
87
|
+
<SectionLabel as="span">
|
|
87
88
|
{{ t('inspector.referenceRepos.title') }}
|
|
88
|
-
</
|
|
89
|
+
</SectionLabel>
|
|
89
90
|
</div>
|
|
90
91
|
|
|
91
92
|
<!-- Attached reference repos: chips with a remove control. -->
|
|
@@ -133,11 +134,11 @@ function detach(repoId: number) {
|
|
|
133
134
|
/>
|
|
134
135
|
</template>
|
|
135
136
|
</UInputMenu>
|
|
136
|
-
<div v-else class="text-
|
|
137
|
+
<div v-else class="text-2xs text-dimmed">
|
|
137
138
|
{{ t('inspector.referenceRepos.connectFirst') }}
|
|
138
139
|
</div>
|
|
139
140
|
|
|
140
|
-
<div class="mt-1 text-
|
|
141
|
+
<div class="mt-1 text-2xs text-dimmed">
|
|
141
142
|
{{ t('inspector.referenceRepos.hint') }}
|
|
142
143
|
</div>
|
|
143
144
|
</div>
|
|
@@ -81,14 +81,17 @@ function outcomeClass(outcome: EnvironmentProbeReport['operations'][number]['out
|
|
|
81
81
|
</script>
|
|
82
82
|
|
|
83
83
|
<template>
|
|
84
|
-
<div
|
|
85
|
-
|
|
84
|
+
<div
|
|
85
|
+
class="space-y-2 rounded-sm border border-default bg-muted p-2"
|
|
86
|
+
data-testid="env-probe-report"
|
|
87
|
+
>
|
|
88
|
+
<p class="text-2xs font-medium" :class="verdictClass" data-testid="env-probe-verdict">
|
|
86
89
|
{{ verdictLabel }}
|
|
87
90
|
</p>
|
|
88
91
|
|
|
89
92
|
<!-- The tallies the PLATFORM computed from the agent's per-operation judgements, including
|
|
90
93
|
how many successes were behind authentication: the count the verdict turns on. -->
|
|
91
|
-
<p class="text-
|
|
94
|
+
<p class="text-2xs text-muted">
|
|
92
95
|
{{
|
|
93
96
|
t('inspector.testConfig.envProbe.counts', {
|
|
94
97
|
succeeded: report.succeeded,
|
|
@@ -101,19 +104,19 @@ function outcomeClass(outcome: EnvironmentProbeReport['operations'][number]['out
|
|
|
101
104
|
<!-- What the platform did not tell the agent: the actionable half of the report, so it comes
|
|
102
105
|
before the evidence. -->
|
|
103
106
|
<div v-if="report.missingContext.length" data-testid="env-probe-missing">
|
|
104
|
-
<p class="text-
|
|
107
|
+
<p class="text-2xs font-medium text-app-warning-300/90">
|
|
105
108
|
{{ t('inspector.testConfig.envProbe.missingContext') }}
|
|
106
109
|
</p>
|
|
107
|
-
<ul class="mt-0.5 list-disc space-y-0.5 pl-4 text-
|
|
110
|
+
<ul class="mt-0.5 list-disc space-y-0.5 pl-4 text-2xs text-toned">
|
|
108
111
|
<li v-for="(line, i) in report.missingContext" :key="i">{{ line }}</li>
|
|
109
112
|
</ul>
|
|
110
113
|
</div>
|
|
111
114
|
|
|
112
115
|
<div v-if="report.blockers.length" data-testid="env-probe-blockers">
|
|
113
|
-
<p class="text-
|
|
116
|
+
<p class="text-2xs font-medium text-app-error-300/90">
|
|
114
117
|
{{ t('inspector.testConfig.envProbe.blockers') }}
|
|
115
118
|
</p>
|
|
116
|
-
<ul class="mt-0.5 space-y-0.5 text-
|
|
119
|
+
<ul class="mt-0.5 space-y-0.5 text-2xs text-toned">
|
|
117
120
|
<li v-for="(blocker, i) in report.blockers" :key="i">
|
|
118
121
|
<span class="text-muted">{{ failureLabel(blocker.kind) }}:</span>
|
|
119
122
|
{{ blocker.detail }}
|
|
@@ -124,10 +127,10 @@ function outcomeClass(outcome: EnvironmentProbeReport['operations'][number]['out
|
|
|
124
127
|
<!-- The operations, as evidence for the verdict above. This is the "what was attempted" a dry
|
|
125
128
|
run exists to report: without it a verdict is an opinion. -->
|
|
126
129
|
<div v-if="report.operations.length" data-testid="env-probe-operations">
|
|
127
|
-
<p class="text-
|
|
130
|
+
<p class="text-2xs font-medium text-toned">
|
|
128
131
|
{{ t('inspector.testConfig.envProbe.operations') }}
|
|
129
132
|
</p>
|
|
130
|
-
<ul class="mt-0.5 space-y-1 text-
|
|
133
|
+
<ul class="mt-0.5 space-y-1 text-2xs">
|
|
131
134
|
<li v-for="(op, i) in report.operations" :key="i" class="flex items-start gap-1.5">
|
|
132
135
|
<UIcon
|
|
133
136
|
:name="outcomeIcon(op.outcome)"
|
|
@@ -151,12 +154,12 @@ function outcomeClass(outcome: EnvironmentProbeReport['operations'][number]['out
|
|
|
151
154
|
whole attempt. The two ways an operation fails to reach the list are rendered SEPARATELY
|
|
152
155
|
because they send a reader somewhere different: one says the agent reported more than is
|
|
153
156
|
shown, the other says its reply was malformed. -->
|
|
154
|
-
<p v-if="report.operationsOmitted" class="mt-1 text-
|
|
157
|
+
<p v-if="report.operationsOmitted" class="mt-1 text-2xs text-dimmed">
|
|
155
158
|
{{
|
|
156
159
|
t('inspector.testConfig.envProbe.operationsOmitted', { count: report.operationsOmitted })
|
|
157
160
|
}}
|
|
158
161
|
</p>
|
|
159
|
-
<p v-if="report.operationsUnreadable" class="mt-1 text-
|
|
162
|
+
<p v-if="report.operationsUnreadable" class="mt-1 text-2xs text-dimmed">
|
|
160
163
|
{{
|
|
161
164
|
t('inspector.testConfig.envProbe.operationsUnreadable', {
|
|
162
165
|
count: report.operationsUnreadable,
|
|
@@ -165,8 +168,8 @@ function outcomeClass(outcome: EnvironmentProbeReport['operations'][number]['out
|
|
|
165
168
|
</p>
|
|
166
169
|
</div>
|
|
167
170
|
|
|
168
|
-
<p v-if="report.summary" class="text-
|
|
169
|
-
<p v-if="report.model" class="text-
|
|
171
|
+
<p v-if="report.summary" class="text-2xs text-muted">{{ report.summary }}</p>
|
|
172
|
+
<p v-if="report.model" class="text-2xs text-app-600">
|
|
170
173
|
{{ t('inspector.testConfig.envProbe.model', { model: report.model }) }}
|
|
171
174
|
</p>
|
|
172
175
|
</div>
|
|
@@ -3,6 +3,7 @@ import { computed } from 'vue'
|
|
|
3
3
|
import type { Block } from '~/types/domain'
|
|
4
4
|
import { STATUS_META } from '~/utils/catalog'
|
|
5
5
|
import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
|
|
6
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
6
7
|
|
|
7
8
|
// The epic inspector body: the full tree of member tasks (which may live under different
|
|
8
9
|
// services/modules), grouped service → module → task. Each task row selects it. Membership
|
|
@@ -52,30 +53,30 @@ const groups = computed(() => {
|
|
|
52
53
|
default-open
|
|
53
54
|
>
|
|
54
55
|
<template #actions>
|
|
55
|
-
<span class="text-
|
|
56
|
+
<span class="text-2xs text-dimmed">{{
|
|
56
57
|
t('inspector.epicChildren.doneCount', { done, total: members.length })
|
|
57
58
|
}}</span>
|
|
58
59
|
</template>
|
|
59
60
|
|
|
60
|
-
<div v-if="members.length === 0" class="text-
|
|
61
|
+
<div v-if="members.length === 0" class="text-2xs text-dimmed">
|
|
61
62
|
{{ t('inspector.epicChildren.empty') }}
|
|
62
63
|
</div>
|
|
63
64
|
|
|
64
65
|
<div v-else class="space-y-2">
|
|
65
66
|
<div v-for="(group, gi) in groups" :key="gi" class="rounded-md border border-muted/60 p-2">
|
|
66
|
-
<div class="mb-1 flex items-center gap-1 text-
|
|
67
|
+
<div class="mb-1 flex items-center gap-1 text-2xs font-medium text-toned">
|
|
67
68
|
<UIcon name="i-lucide-box" class="h-3 w-3 text-dimmed" />
|
|
68
69
|
{{ group.service?.title ?? t('inspector.epicChildren.unassigned') }}
|
|
69
70
|
</div>
|
|
70
71
|
<div v-for="(mod, mi) in [...group.modules.values()]" :key="mi" class="ps-1">
|
|
71
|
-
<
|
|
72
|
+
<SectionLabel v-if="mod.module">
|
|
72
73
|
{{ mod.module.title }}
|
|
73
|
-
</
|
|
74
|
+
</SectionLabel>
|
|
74
75
|
<button
|
|
75
76
|
v-for="task in mod.tasks"
|
|
76
77
|
:key="task.id"
|
|
77
78
|
type="button"
|
|
78
|
-
class="flex w-full items-center gap-1.5 rounded px-1 py-0.5 text-start text-xs text-default hover:bg-elevated"
|
|
79
|
+
class="flex w-full items-center gap-1.5 rounded-sm px-1 py-0.5 text-start text-xs text-default hover:bg-elevated"
|
|
79
80
|
@click="ui.select(task.id)"
|
|
80
81
|
>
|
|
81
82
|
<span
|
|
@@ -83,7 +84,7 @@ const groups = computed(() => {
|
|
|
83
84
|
:style="{ backgroundColor: STATUS_META[task.status].color }"
|
|
84
85
|
/>
|
|
85
86
|
<span class="truncate">{{ task.title }}</span>
|
|
86
|
-
<span class="ms-auto shrink-0 text-
|
|
87
|
+
<span class="ms-auto shrink-0 text-3xs text-dimmed">
|
|
87
88
|
{{ STATUS_META[task.status].label }}
|
|
88
89
|
</span>
|
|
89
90
|
</button>
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type FrontendConfig,
|
|
8
8
|
type ResolvedFrontendBinding,
|
|
9
9
|
} from '@cat-factory/contracts'
|
|
10
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
10
11
|
|
|
11
12
|
// The resolution of a frontend frame's backend bindings — each env var → a bound service's live
|
|
12
13
|
// ephemeral URL, or WireMock. Two modes, same view:
|
|
@@ -66,13 +67,13 @@ const rows = computed(() => {
|
|
|
66
67
|
|
|
67
68
|
<template>
|
|
68
69
|
<div v-if="rows.length || duplicates.length" class="space-y-1.5" data-testid="frontend-resolved">
|
|
69
|
-
<
|
|
70
|
+
<SectionLabel>
|
|
70
71
|
{{ t('inspector.frontendConfig.resolved.title') }}
|
|
71
|
-
</
|
|
72
|
+
</SectionLabel>
|
|
72
73
|
|
|
73
74
|
<p
|
|
74
75
|
v-if="duplicates.length"
|
|
75
|
-
class="text-
|
|
76
|
+
class="text-2xs leading-snug text-app-warning-300/80"
|
|
76
77
|
data-testid="frontend-resolved-duplicates"
|
|
77
78
|
>
|
|
78
79
|
{{ t('inspector.frontendConfig.resolved.duplicateWarning', { vars: duplicates.join(', ') }) }}
|
|
@@ -82,7 +83,7 @@ const rows = computed(() => {
|
|
|
82
83
|
<li
|
|
83
84
|
v-for="row in rows"
|
|
84
85
|
:key="row.envVar"
|
|
85
|
-
class="flex items-baseline gap-1.5 text-
|
|
86
|
+
class="flex items-baseline gap-1.5 text-2xs leading-snug"
|
|
86
87
|
data-testid="frontend-resolved-row"
|
|
87
88
|
>
|
|
88
89
|
<span
|
|
@@ -229,11 +229,11 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
229
229
|
persisted until Apply. Only shown when the frame is linked to a repo. -->
|
|
230
230
|
<div
|
|
231
231
|
v-if="repoLink"
|
|
232
|
-
class="space-y-2 rounded border border-default bg-default/40 p-2"
|
|
232
|
+
class="space-y-2 rounded-sm border border-default bg-default/40 p-2"
|
|
233
233
|
data-testid="frontend-detect"
|
|
234
234
|
>
|
|
235
235
|
<div class="flex items-center justify-between gap-2">
|
|
236
|
-
<span class="text-
|
|
236
|
+
<span class="text-2xs text-muted">{{ t('inspector.frontendConfig.detect.title') }}</span>
|
|
237
237
|
<UButton
|
|
238
238
|
size="xs"
|
|
239
239
|
variant="soft"
|
|
@@ -246,16 +246,16 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
246
246
|
{{ t('inspector.frontendConfig.detect.button') }}
|
|
247
247
|
</UButton>
|
|
248
248
|
</div>
|
|
249
|
-
<p class="text-
|
|
249
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
250
250
|
{{ t('inspector.frontendConfig.detect.hint') }}
|
|
251
251
|
</p>
|
|
252
252
|
|
|
253
|
-
<p v-if="detectError" class="text-
|
|
253
|
+
<p v-if="detectError" class="text-2xs text-app-error-300/80">
|
|
254
254
|
{{ detectError }}
|
|
255
255
|
</p>
|
|
256
256
|
|
|
257
257
|
<template v-if="detectResult && !detecting">
|
|
258
|
-
<p v-if="!detectResult.detected" class="text-
|
|
258
|
+
<p v-if="!detectResult.detected" class="text-2xs text-app-warning-300/80">
|
|
259
259
|
{{ t('inspector.frontendConfig.detect.none') }}
|
|
260
260
|
</p>
|
|
261
261
|
|
|
@@ -263,7 +263,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
263
263
|
<li
|
|
264
264
|
v-for="(n, i) in detectResult.notes"
|
|
265
265
|
:key="i"
|
|
266
|
-
class="flex items-start gap-1.5 text-
|
|
266
|
+
class="flex items-start gap-1.5 text-2xs leading-snug text-dimmed"
|
|
267
267
|
>
|
|
268
268
|
<span
|
|
269
269
|
:class="
|
|
@@ -310,9 +310,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
310
310
|
<!-- Build: package manager + frontend directory + install command + build script + output dir -->
|
|
311
311
|
<InspectorSection v-model:open="showBuild" :title="t('inspector.frontendConfig.groups.build')">
|
|
312
312
|
<div class="space-y-1">
|
|
313
|
-
<span class="text-
|
|
314
|
-
t('inspector.frontendConfig.packageManager')
|
|
315
|
-
}}</span>
|
|
313
|
+
<span class="text-2xs text-muted">{{ t('inspector.frontendConfig.packageManager') }}</span>
|
|
316
314
|
<div class="flex flex-wrap gap-1">
|
|
317
315
|
<UButton
|
|
318
316
|
v-for="pm in PACKAGE_MANAGERS"
|
|
@@ -328,7 +326,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
328
326
|
</div>
|
|
329
327
|
|
|
330
328
|
<div class="space-y-1">
|
|
331
|
-
<label class="text-
|
|
329
|
+
<label class="text-2xs text-muted">{{ t('inspector.frontendConfig.directory') }}</label>
|
|
332
330
|
<UInput
|
|
333
331
|
:model-value="config.directory ?? ''"
|
|
334
332
|
size="xs"
|
|
@@ -340,13 +338,13 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
340
338
|
(e: KeyboardEvent) => saveText('directory', (e.target as HTMLInputElement).value)
|
|
341
339
|
"
|
|
342
340
|
/>
|
|
343
|
-
<p class="text-
|
|
341
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
344
342
|
{{ t('inspector.frontendConfig.directoryHint') }}
|
|
345
343
|
</p>
|
|
346
344
|
</div>
|
|
347
345
|
|
|
348
346
|
<div class="space-y-1">
|
|
349
|
-
<label class="text-
|
|
347
|
+
<label class="text-2xs text-muted">{{
|
|
350
348
|
t('inspector.frontendConfig.installCommand')
|
|
351
349
|
}}</label>
|
|
352
350
|
<UInput
|
|
@@ -366,9 +364,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
366
364
|
|
|
367
365
|
<div class="grid grid-cols-2 gap-2">
|
|
368
366
|
<div class="space-y-1">
|
|
369
|
-
<label class="text-
|
|
370
|
-
t('inspector.frontendConfig.buildScript')
|
|
371
|
-
}}</label>
|
|
367
|
+
<label class="text-2xs text-muted">{{ t('inspector.frontendConfig.buildScript') }}</label>
|
|
372
368
|
<UInput
|
|
373
369
|
:model-value="config.buildScript ?? ''"
|
|
374
370
|
size="xs"
|
|
@@ -382,9 +378,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
382
378
|
/>
|
|
383
379
|
</div>
|
|
384
380
|
<div class="space-y-1">
|
|
385
|
-
<label class="text-
|
|
386
|
-
t('inspector.frontendConfig.outputDir')
|
|
387
|
-
}}</label>
|
|
381
|
+
<label class="text-2xs text-muted">{{ t('inspector.frontendConfig.outputDir') }}</label>
|
|
388
382
|
<UInput
|
|
389
383
|
:model-value="config.outputDir ?? ''"
|
|
390
384
|
size="xs"
|
|
@@ -403,7 +397,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
403
397
|
<!-- Serve: mode (static vs command) + serve script (command mode) + port -->
|
|
404
398
|
<InspectorSection v-model:open="showServe" :title="t('inspector.frontendConfig.groups.serve')">
|
|
405
399
|
<div class="space-y-1">
|
|
406
|
-
<span class="text-
|
|
400
|
+
<span class="text-2xs text-muted">{{ t('inspector.frontendConfig.serveMode') }}</span>
|
|
407
401
|
<div class="flex flex-wrap gap-1">
|
|
408
402
|
<UButton
|
|
409
403
|
:color="serveMode === 'static' ? 'primary' : 'neutral'"
|
|
@@ -423,23 +417,21 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
423
417
|
</UButton>
|
|
424
418
|
</div>
|
|
425
419
|
<!-- Explain each mode, and disambiguate from the separate envInjection axis. -->
|
|
426
|
-
<p class="text-
|
|
420
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
427
421
|
<span class="text-muted">{{ t('inspector.frontendConfig.serveStatic') }}:</span>
|
|
428
422
|
{{ t('inspector.frontendConfig.serveStaticDesc') }}
|
|
429
423
|
</p>
|
|
430
|
-
<p class="text-
|
|
424
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
431
425
|
<span class="text-muted">{{ t('inspector.frontendConfig.serveCommand') }}:</span>
|
|
432
426
|
{{ t('inspector.frontendConfig.serveCommandDesc') }}
|
|
433
427
|
</p>
|
|
434
|
-
<p class="text-
|
|
428
|
+
<p class="text-2xs leading-snug text-dimmed/80">
|
|
435
429
|
{{ t('inspector.frontendConfig.serveEnvAxisNote') }}
|
|
436
430
|
</p>
|
|
437
431
|
</div>
|
|
438
432
|
|
|
439
433
|
<div v-if="serveMode === 'command'" class="space-y-1">
|
|
440
|
-
<label class="text-
|
|
441
|
-
t('inspector.frontendConfig.serveScript')
|
|
442
|
-
}}</label>
|
|
434
|
+
<label class="text-2xs text-muted">{{ t('inspector.frontendConfig.serveScript') }}</label>
|
|
443
435
|
<UInput
|
|
444
436
|
:model-value="config.serveScript ?? ''"
|
|
445
437
|
size="xs"
|
|
@@ -454,7 +446,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
454
446
|
</div>
|
|
455
447
|
|
|
456
448
|
<div class="space-y-1">
|
|
457
|
-
<label class="text-
|
|
449
|
+
<label class="text-2xs text-muted">{{ t('inspector.frontendConfig.servePort') }}</label>
|
|
458
450
|
<UInput
|
|
459
451
|
:model-value="config.servePort != null ? String(config.servePort) : ''"
|
|
460
452
|
type="number"
|
|
@@ -475,7 +467,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
475
467
|
:title="t('inspector.frontendConfig.groups.mocking')"
|
|
476
468
|
>
|
|
477
469
|
<div class="space-y-1">
|
|
478
|
-
<label class="text-
|
|
470
|
+
<label class="text-2xs text-muted">{{
|
|
479
471
|
t('inspector.frontendConfig.mockMappingsPath')
|
|
480
472
|
}}</label>
|
|
481
473
|
<UInput
|
|
@@ -491,7 +483,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
491
483
|
(e: KeyboardEvent) => saveText('mockMappingsPath', (e.target as HTMLInputElement).value)
|
|
492
484
|
"
|
|
493
485
|
/>
|
|
494
|
-
<p class="text-
|
|
486
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
495
487
|
{{ t('inspector.frontendConfig.mockMappingsHint') }}
|
|
496
488
|
</p>
|
|
497
489
|
</div>
|
|
@@ -521,7 +513,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
521
513
|
{{ t('inspector.frontendConfig.envRuntime') }}
|
|
522
514
|
</UButton>
|
|
523
515
|
</div>
|
|
524
|
-
<p class="text-
|
|
516
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
525
517
|
{{ t('inspector.frontendConfig.envInjectionHint') }}
|
|
526
518
|
</p>
|
|
527
519
|
</div>
|
|
@@ -574,7 +566,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
574
566
|
/>
|
|
575
567
|
</div>
|
|
576
568
|
</div>
|
|
577
|
-
<div v-else class="text-
|
|
569
|
+
<div v-else class="text-2xs text-dimmed">
|
|
578
570
|
{{ t('inspector.frontendConfig.bindings.empty') }}
|
|
579
571
|
</div>
|
|
580
572
|
|
|
@@ -603,7 +595,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
603
595
|
save({ previewEnabled: v === true ? true : undefined })
|
|
604
596
|
"
|
|
605
597
|
/>
|
|
606
|
-
<p class="mt-1 text-
|
|
598
|
+
<p class="mt-1 text-2xs leading-snug text-dimmed">
|
|
607
599
|
{{
|
|
608
600
|
previewSupported
|
|
609
601
|
? t('inspector.frontendConfig.previewHint')
|
|
@@ -615,7 +607,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
615
607
|
<div v-if="previewActive" class="mt-2 space-y-1.5" data-testid="preview-panel">
|
|
616
608
|
<div class="flex items-center gap-2">
|
|
617
609
|
<span
|
|
618
|
-
class="text-
|
|
610
|
+
class="text-2xs font-medium"
|
|
619
611
|
:class="{
|
|
620
612
|
'text-app-success-400': previewStatus === 'ready',
|
|
621
613
|
'text-app-warning-400': previewStatus === 'starting',
|
|
@@ -671,7 +663,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
671
663
|
|
|
672
664
|
<p
|
|
673
665
|
v-if="previewStatus === 'failed' && previewState?.error"
|
|
674
|
-
class="text-
|
|
666
|
+
class="text-2xs leading-snug text-app-error-400"
|
|
675
667
|
data-testid="preview-error"
|
|
676
668
|
>
|
|
677
669
|
{{ previewState.error }}
|
|
@@ -679,7 +671,7 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
679
671
|
|
|
680
672
|
<p
|
|
681
673
|
v-if="previewRequestError"
|
|
682
|
-
class="text-
|
|
674
|
+
class="text-2xs leading-snug text-app-error-400"
|
|
683
675
|
data-testid="preview-request-error"
|
|
684
676
|
>
|
|
685
677
|
{{ previewRequestError }}
|
|
@@ -52,12 +52,12 @@ function control(action: 'pause' | 'resume' | 'cancel') {
|
|
|
52
52
|
<UBadge color="primary" variant="subtle" size="sm">
|
|
53
53
|
{{ t(INITIATIVE_STATUS_LABEL_KEYS[status]) }}
|
|
54
54
|
</UBadge>
|
|
55
|
-
<span v-if="progress" class="text-
|
|
55
|
+
<span v-if="progress" class="text-2xs text-muted">
|
|
56
56
|
{{ t('initiative.card.progress', { done: progress.settled, total: progress.total }) }}
|
|
57
57
|
</span>
|
|
58
58
|
</div>
|
|
59
59
|
|
|
60
|
-
<p v-if="initiative?.goal" class="whitespace-pre-wrap text-
|
|
60
|
+
<p v-if="initiative?.goal" class="whitespace-pre-wrap text-xs text-toned">
|
|
61
61
|
{{ initiative.goal }}
|
|
62
62
|
</p>
|
|
63
63
|
|
|
@@ -165,7 +165,7 @@ function control(action: 'pause' | 'resume' | 'cancel') {
|
|
|
165
165
|
</UButton>
|
|
166
166
|
</div>
|
|
167
167
|
|
|
168
|
-
<p class="text-
|
|
168
|
+
<p class="text-2xs text-dimmed">
|
|
169
169
|
{{ t('initiative.inspector.hint') }}
|
|
170
170
|
</p>
|
|
171
171
|
</div>
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
// FrontendConfig opening its Build group after a detect run) can bind `v-model:open`;
|
|
11
11
|
// without a binding the model acts as local state and `defaultOpen` picks the initial
|
|
12
12
|
// value (controlled callers should drive their own ref instead of passing it).
|
|
13
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
14
|
+
|
|
13
15
|
const props = defineProps<{
|
|
14
16
|
title: string
|
|
15
17
|
icon?: string
|
|
@@ -26,9 +28,10 @@ if (props.defaultOpen) open.value = true
|
|
|
26
28
|
<template>
|
|
27
29
|
<section class="border-t border-default pt-2" data-testid="inspector-section">
|
|
28
30
|
<div class="flex items-center gap-1.5">
|
|
29
|
-
<
|
|
31
|
+
<SectionLabel
|
|
32
|
+
as="button"
|
|
30
33
|
type="button"
|
|
31
|
-
class="flex min-w-0 flex-1 items-center gap-1.5 text-start
|
|
34
|
+
class="flex min-w-0 flex-1 items-center gap-1.5 text-start hover:text-default"
|
|
32
35
|
:aria-expanded="open"
|
|
33
36
|
data-testid="inspector-section-toggle"
|
|
34
37
|
@click="open = !open"
|
|
@@ -45,7 +48,7 @@ if (props.defaultOpen) open.value = true
|
|
|
45
48
|
name="i-lucide-triangle-alert"
|
|
46
49
|
class="h-3.5 w-3.5 shrink-0 text-app-warning-400"
|
|
47
50
|
/>
|
|
48
|
-
</
|
|
51
|
+
</SectionLabel>
|
|
49
52
|
<!-- An action ("+", attach, menu) mutates the body list, so expand (never collapse)
|
|
50
53
|
on interaction — otherwise the new row lands inside the collapsed body. -->
|
|
51
54
|
<div v-if="$slots.actions" class="contents" @click="open = true">
|
|
@@ -53,7 +56,7 @@ if (props.defaultOpen) open.value = true
|
|
|
53
56
|
</div>
|
|
54
57
|
</div>
|
|
55
58
|
<div v-if="open" class="mt-2 space-y-3">
|
|
56
|
-
<p v-if="hint" class="text-
|
|
59
|
+
<p v-if="hint" class="text-2xs leading-snug text-dimmed">{{ hint }}</p>
|
|
57
60
|
<slot />
|
|
58
61
|
</div>
|
|
59
62
|
</section>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// (lazily loaded; retained ~1 week on the backend).
|
|
5
5
|
import type { Block } from '~/types/domain'
|
|
6
6
|
import type { Recurrence } from '~/types/recurring'
|
|
7
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
7
8
|
|
|
8
9
|
const props = defineProps<{ block: Block }>()
|
|
9
10
|
const recurring = useRecurringPipelinesStore()
|
|
@@ -126,7 +127,7 @@ function fmtTime(ms: number) {
|
|
|
126
127
|
<div v-if="schedule" class="space-y-2 rounded-lg border border-primary/50 bg-primary/10 p-3">
|
|
127
128
|
<div class="flex items-center justify-between">
|
|
128
129
|
<span
|
|
129
|
-
class="flex items-center gap-1.5 text-
|
|
130
|
+
class="flex items-center gap-1.5 text-2xs font-semibold uppercase tracking-wide text-primary"
|
|
130
131
|
>
|
|
131
132
|
<UIcon name="i-lucide-repeat" class="h-3.5 w-3.5" />
|
|
132
133
|
{{ t('inspector.recurring.title') }}
|
|
@@ -146,13 +147,13 @@ function fmtTime(ms: number) {
|
|
|
146
147
|
</UBadge>
|
|
147
148
|
</div>
|
|
148
149
|
|
|
149
|
-
<p class="text-
|
|
150
|
+
<p class="text-2xs text-muted">
|
|
150
151
|
<span class="text-toned">{{ pipelineName }}</span>
|
|
151
152
|
</p>
|
|
152
153
|
|
|
153
154
|
<!-- On-demand: no cadence, no pause/resume — it fires only when a person triggers it. -->
|
|
154
155
|
<template v-if="schedule.onDemand">
|
|
155
|
-
<p class="text-
|
|
156
|
+
<p class="text-2xs text-dimmed">{{ t('inspector.recurring.onDemandHint') }}</p>
|
|
156
157
|
<div class="flex flex-wrap gap-1.5 pt-1">
|
|
157
158
|
<UButton size="xs" variant="soft" icon="i-lucide-play" :loading="busy" @click="runNow">
|
|
158
159
|
{{ t('inspector.recurring.runNow') }}
|
|
@@ -161,8 +162,8 @@ function fmtTime(ms: number) {
|
|
|
161
162
|
</template>
|
|
162
163
|
|
|
163
164
|
<template v-else-if="!editing">
|
|
164
|
-
<p class="text-
|
|
165
|
-
<p class="text-
|
|
165
|
+
<p class="text-2xs text-muted">{{ describeCadence(schedule.recurrence) }}</p>
|
|
166
|
+
<p class="text-2xs text-dimmed">
|
|
166
167
|
{{ t('inspector.recurring.nextRun', { time: fmtTime(schedule.nextRunAt) }) }}
|
|
167
168
|
</p>
|
|
168
169
|
<div class="flex flex-wrap gap-1.5 pt-1">
|
|
@@ -213,10 +214,10 @@ function fmtTime(ms: number) {
|
|
|
213
214
|
|
|
214
215
|
<!-- run history -->
|
|
215
216
|
<div v-if="runs.length" class="space-y-1 border-t border-default pt-2">
|
|
216
|
-
<
|
|
217
|
+
<SectionLabel as="span">
|
|
217
218
|
{{ t('inspector.recurring.recentRuns') }}
|
|
218
|
-
</
|
|
219
|
-
<div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-
|
|
219
|
+
</SectionLabel>
|
|
220
|
+
<div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-2xs">
|
|
220
221
|
<span :class="RUN_COLOR[run.status] ?? 'text-muted'" class="w-14 shrink-0">
|
|
221
222
|
{{ runStatusLabel(run.status) }}
|
|
222
223
|
</span>
|
|
@@ -135,12 +135,12 @@ const usedBy = computed(() =>
|
|
|
135
135
|
/>
|
|
136
136
|
</div>
|
|
137
137
|
</div>
|
|
138
|
-
<div v-else class="text-
|
|
138
|
+
<div v-else class="text-2xs text-dimmed">
|
|
139
139
|
{{ t('inspector.serviceConnections.empty') }}
|
|
140
140
|
</div>
|
|
141
141
|
|
|
142
142
|
<div v-if="usedBy.length" class="space-y-1" data-testid="service-connections-used-by">
|
|
143
|
-
<span class="text-
|
|
143
|
+
<span class="text-2xs text-muted">{{ t('inspector.serviceConnections.usedBy') }}</span>
|
|
144
144
|
<div class="flex flex-wrap gap-1">
|
|
145
145
|
<UBadge v-for="f in usedBy" :key="f.id" size="sm" variant="soft" color="neutral">
|
|
146
146
|
{{ f.title || f.id }}
|
|
@@ -114,7 +114,7 @@ async function clear() {
|
|
|
114
114
|
<!-- Disabled affordance until an observability integration is connected. -->
|
|
115
115
|
<div
|
|
116
116
|
v-if="!connected"
|
|
117
|
-
class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-
|
|
117
|
+
class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-2xs text-muted"
|
|
118
118
|
>
|
|
119
119
|
<span>{{ t('inspector.releaseHealth.connectPrompt') }}</span>
|
|
120
120
|
<UButton
|
|
@@ -130,7 +130,7 @@ async function clear() {
|
|
|
130
130
|
</div>
|
|
131
131
|
|
|
132
132
|
<div v-else class="space-y-2">
|
|
133
|
-
<p class="text-
|
|
133
|
+
<p class="text-2xs text-dimmed">
|
|
134
134
|
{{ t('inspector.releaseHealth.hint') }}
|
|
135
135
|
</p>
|
|
136
136
|
<div class="grid grid-cols-2 gap-2">
|