@cat-factory/app 0.302.2 → 0.303.1
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 +99 -14
- package/app/app.config.ts +19 -10
- package/app/assets/css/main.css +13 -13
- package/app/assets/css/prose.css +22 -22
- package/app/assets/css/tokens.css +298 -0
- package/app/components/assistant/AssistantModal.vue +22 -22
- package/app/components/auth/AuthGate.vue +1 -1
- package/app/components/auth/BackendMisconfiguredScreen.vue +10 -10
- package/app/components/auth/LoginScreen.vue +34 -36
- package/app/components/auth/ResetPasswordScreen.vue +12 -12
- package/app/components/auth/UserMenu.vue +4 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +27 -25
- package/app/components/binaryOutput/BinaryOutputReport.vue +15 -15
- package/app/components/binaryOutput/StoredAssetView.vue +5 -5
- package/app/components/board/AddTaskModal.vue +17 -20
- package/app/components/board/AgentFailureCard.vue +11 -11
- package/app/components/board/AgentFailureHistory.vue +2 -2
- package/app/components/board/BoardCanvas.vue +6 -5
- package/app/components/board/CreateInitiativeModal.vue +8 -10
- package/app/components/board/DependencyConnectOverlay.vue +1 -1
- package/app/components/board/FailureHistoryList.vue +7 -7
- package/app/components/board/RecurringPipelineModal.vue +17 -17
- package/app/components/board/ReviewFrictionDialog.vue +6 -6
- package/app/components/board/StepExecutionHistory.vue +13 -13
- package/app/components/board/TaskDependencyEdges.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +10 -10
- package/app/components/board/nodes/BlockNode.vue +29 -29
- package/app/components/board/nodes/DecisionBadge.vue +2 -2
- package/app/components/board/nodes/EpicNode.vue +14 -10
- package/app/components/board/nodes/FrameSwimlanes.vue +7 -9
- package/app/components/board/nodes/InitiativeCard.vue +8 -8
- package/app/components/board/nodes/LaneGroup.vue +1 -1
- package/app/components/board/nodes/LaneTask.vue +2 -2
- package/app/components/board/nodes/ResizeGrips.vue +4 -4
- package/app/components/board/nodes/TaskCard.vue +18 -18
- package/app/components/board/nodes/TaskLane.vue +5 -5
- package/app/components/board/nodes/TaskPipelineMini.vue +18 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +29 -26
- package/app/components/bootstrap/BootstrapModal.vue +21 -23
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +30 -33
- package/app/components/bugFishing/BugFishingWindow.vue +49 -49
- package/app/components/clarity/ClarityReviewWindow.vue +30 -30
- package/app/components/common/AsyncViewError.vue +5 -5
- package/app/components/common/ClarificationItem.vue +8 -13
- package/app/components/common/ConfirmDialog.vue +4 -2
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +3 -3
- package/app/components/common/InterviewGateNotice.vue +7 -7
- package/app/components/common/KeyboardShortcutsHelp.vue +1 -1
- package/app/components/common/MarkdownProse.vue +14 -13
- package/app/components/consensus/ConsensusSessionWindow.vue +26 -26
- package/app/components/context/ContextAttachmentFields.vue +17 -17
- package/app/components/docs/DocInterviewWindow.vue +14 -14
- package/app/components/documents/ContextDocumentPicker.vue +17 -17
- package/app/components/documents/DocumentImportModal.vue +7 -7
- package/app/components/documents/DocumentSourceConnectModal.vue +3 -3
- package/app/components/documents/DocumentSyncState.vue +5 -5
- package/app/components/documents/DocumentTemplatesModal.vue +15 -15
- package/app/components/documents/RepoContextDocPicker.vue +5 -5
- package/app/components/documents/SpawnPreviewModal.vue +12 -12
- package/app/components/documents/StartFromDesignModal.vue +11 -11
- package/app/components/documents/TaskContextDocs.vue +5 -5
- package/app/components/environments/EnvSetupStepper.vue +6 -6
- package/app/components/environments/EnvironmentStatusPanel.vue +17 -17
- package/app/components/environments/steps/EnvPickStep.vue +3 -3
- package/app/components/environments/steps/EnvPreflightStep.vue +9 -9
- package/app/components/environments/steps/EnvReviewStep.vue +25 -22
- package/app/components/environments/steps/EnvSaveStep.vue +7 -5
- package/app/components/environments/steps/JourneyStepNav.vue +1 -1
- package/app/components/focus/BlockFocusView.vue +17 -19
- package/app/components/followUp/FollowUpWindow.vue +23 -23
- package/app/components/forkDecision/ForkDecisionWindow.vue +37 -39
- package/app/components/foundational/FoundationalContractSummary.vue +7 -7
- package/app/components/foundational/FoundationalServiceCatalogList.vue +11 -11
- package/app/components/foundational/FoundationalServiceManager.vue +1 -1
- package/app/components/foundational/FoundationalServiceRegistry.vue +13 -13
- package/app/components/foundational/FoundationalServiceSources.vue +13 -13
- package/app/components/foundational/FoundationalSuppressions.vue +7 -7
- package/app/components/foundational/ServiceCatalogConnection.vue +10 -10
- package/app/components/fragments/FragmentLibraryManager.vue +41 -44
- package/app/components/fragments/FragmentSelector.vue +13 -13
- package/app/components/fragments/GitHubDocUrlImport.vue +1 -1
- package/app/components/gates/GateFailingCheckList.vue +5 -5
- package/app/components/gates/GateResultView.vue +50 -47
- package/app/components/github/AddServiceFromRepoModal.vue +14 -14
- package/app/components/github/BranchProtectionPreflight.vue +13 -13
- package/app/components/github/GitHubConnect.vue +7 -7
- package/app/components/github/GitHubOnboarding.vue +7 -7
- package/app/components/github/GitHubPanel.vue +37 -40
- package/app/components/github/RepoTreeBrowser.vue +18 -18
- package/app/components/humanTest/HumanTestWindow.vue +30 -33
- package/app/components/initiative/InitiativePlanNotice.vue +5 -5
- package/app/components/initiative/InitiativePlanReview.vue +27 -29
- package/app/components/initiative/InitiativePlanningWindow.vue +10 -10
- package/app/components/initiative/InitiativeTrackerWindow.vue +71 -65
- package/app/components/inputGate/InputGateNotice.vue +2 -4
- package/app/components/judge/JudgeResultView.vue +30 -32
- package/app/components/kaizen/KaizenPanel.vue +40 -36
- package/app/components/kaizen/KaizenStepStatus.vue +21 -21
- package/app/components/layout/AccountAuditLog.vue +10 -10
- package/app/components/layout/AccountDeploymentSettings.vue +20 -20
- 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 +9 -9
- package/app/components/layout/AccountPlatformAlertSettings.vue +11 -11
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +5 -5
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +23 -15
- package/app/components/layout/AiProvidersBanner.vue +11 -8
- package/app/components/layout/AppearanceSwitcher.vue +108 -0
- package/app/components/layout/BoardSwitcher.vue +8 -11
- package/app/components/layout/BoardToolbar.vue +3 -3
- package/app/components/layout/CommandBar.vue +7 -9
- package/app/components/layout/ConnectionStatusBanner.vue +2 -2
- package/app/components/layout/DefaultTestEnvBanner.vue +5 -5
- package/app/components/layout/GitHubPatBanner.vue +5 -5
- package/app/components/layout/GitHubPatPermissionsBanner.vue +16 -10
- package/app/components/layout/InfraSetupBanner.vue +6 -6
- package/app/components/layout/IntegrationsHub.vue +15 -15
- package/app/components/layout/LanguageSwitcher.vue +5 -5
- package/app/components/layout/ModelProvidersHub.vue +13 -16
- package/app/components/layout/NotificationsInbox.vue +10 -10
- package/app/components/layout/PersonalSetupModal.vue +8 -8
- package/app/components/layout/ProviderConfigBanner.vue +4 -4
- package/app/components/layout/RolePrompt.vue +7 -7
- package/app/components/layout/SideBar.vue +6 -4
- package/app/components/layout/SpendWarningBanner.vue +17 -14
- package/app/components/layout/TranslationWarningBanner.vue +4 -4
- package/app/components/layout/UiModeSwitcher.vue +13 -13
- package/app/components/layout/UiRoleSwitcher.vue +8 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +15 -11
- package/app/components/media/ArtifactLightbox.vue +13 -13
- package/app/components/media/ImageCompare.vue +31 -24
- package/app/components/merge/MergeEffortChips.vue +2 -2
- package/app/components/notifications/NotificationSettingsPanel.vue +14 -12
- package/app/components/observability/OutcomeFilterChips.vue +6 -6
- package/app/components/observability/RunFailureSummary.vue +28 -25
- package/app/components/observability/StepMetricsBar.vue +26 -28
- package/app/components/observability/StepModelActivity.vue +2 -2
- package/app/components/observability/ToolCallList.vue +24 -24
- package/app/components/outcome/OutcomeSummaryWindow.vue +47 -47
- package/app/components/palettes/AgentPalette.vue +8 -8
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +52 -51
- package/app/components/panels/AttemptEntryHeader.vue +4 -6
- package/app/components/panels/DecisionModal.vue +7 -7
- package/app/components/panels/GenericStructuredResultView.vue +7 -7
- package/app/components/panels/InspectorPanel.vue +17 -17
- package/app/components/panels/MergerResultView.vue +19 -19
- package/app/components/panels/ObservabilityPanel.vue +115 -123
- package/app/components/panels/OperatorDashboardPanel.vue +89 -97
- package/app/components/panels/ReportsPanel.vue +69 -66
- package/app/components/panels/ReportsSpendBreakdown.vue +9 -9
- package/app/components/panels/ResultWindowShell.vue +38 -38
- package/app/components/panels/RunDetailLoadState.vue +2 -2
- package/app/components/panels/StepContainerStatus.vue +9 -9
- package/app/components/panels/StepDelegatedStatus.logic.spec.ts +135 -0
- package/app/components/panels/StepDelegatedStatus.logic.ts +160 -0
- package/app/components/panels/StepDelegatedStatus.vue +181 -0
- package/app/components/panels/StepEffortReport.vue +16 -15
- package/app/components/panels/StepFragmentAdherence.vue +14 -10
- package/app/components/panels/StepMetadataCard.vue +74 -45
- package/app/components/panels/StepReproductionReport.vue +25 -21
- package/app/components/panels/StepRunMeta.vue +20 -20
- package/app/components/panels/StepTestReport.logic.spec.ts +8 -3
- package/app/components/panels/StepTestReport.logic.ts +4 -4
- package/app/components/panels/StepTestReport.vue +28 -28
- package/app/components/panels/StepToolServers.vue +14 -11
- package/app/components/panels/StepValidationReport.vue +7 -7
- package/app/components/panels/inspector/ContainerSummary.vue +9 -9
- package/app/components/panels/inspector/DocReferenceRepos.vue +3 -3
- package/app/components/panels/inspector/EnvProbeReport.vue +24 -27
- package/app/components/panels/inspector/EpicChildren.vue +8 -12
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +11 -11
- package/app/components/panels/inspector/FrontendConfig.vue +37 -41
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +6 -6
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +16 -19
- 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 +21 -17
- package/app/components/panels/inspector/ServiceTestConfig.vue +51 -59
- package/app/components/panels/inspector/ServiceTestSecrets.vue +5 -5
- package/app/components/panels/inspector/ServiceTestingContext.vue +3 -3
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +3 -3
- package/app/components/panels/inspector/TaskAprioriBranches.vue +8 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +11 -11
- package/app/components/panels/inspector/TaskExecution.vue +17 -17
- package/app/components/panels/inspector/TaskReviewTarget.vue +2 -2
- package/app/components/panels/inspector/TaskRunSettings.vue +35 -37
- package/app/components/panels/inspector/TaskStructure.vue +3 -3
- package/app/components/pipeline/AgentKindIcon.vue +1 -1
- package/app/components/pipeline/AgentPromptEditor.vue +17 -17
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -56
- package/app/components/pipeline/EstimateThresholdFields.vue +4 -4
- package/app/components/pipeline/GateConfigFields.vue +13 -10
- package/app/components/pipeline/IterationCapPrompt.vue +4 -2
- package/app/components/pipeline/PipelineBuilder.vue +47 -55
- package/app/components/pipeline/PipelineHealthModal.vue +27 -29
- package/app/components/pipeline/PipelinePicker.vue +10 -10
- package/app/components/pipeline/PipelinePreview.vue +10 -10
- package/app/components/pipeline/PipelineProgress.vue +64 -67
- package/app/components/prReview/PrReviewPhaseBadge.vue +7 -7
- package/app/components/prReview/PrReviewWindow.vue +75 -77
- package/app/components/providers/AiPresetMismatchDialog.vue +5 -5
- package/app/components/providers/AiProviderOnboardingModal.vue +9 -9
- package/app/components/providers/ApiKeysSection.vue +13 -13
- package/app/components/providers/PersonalCredentialModal.vue +2 -2
- package/app/components/providers/PersonalSubscriptionSection.vue +10 -10
- package/app/components/providers/SignInRequiredNotice.vue +1 -1
- package/app/components/providers/VendorCredentialsModal.vue +10 -10
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +13 -13
- package/app/components/ralph/RalphLoopResultView.vue +28 -30
- package/app/components/recurring/RecurrenceEditor.vue +2 -2
- package/app/components/requirements/RequirementsReviewWindow.vue +51 -58
- package/app/components/riskPolicy/RiskPolicyPicker.vue +12 -15
- package/app/components/riskPolicy/RiskPolicyPreview.vue +14 -14
- package/app/components/sandbox/SandboxPanel.vue +58 -59
- package/app/components/settings/AccountSettingsPanel.vue +1 -1
- package/app/components/settings/ApiTokensPanel.vue +10 -10
- package/app/components/settings/BudgetSettings.vue +18 -22
- package/app/components/settings/CapabilityCredentialsPanel.vue +15 -15
- package/app/components/settings/CloudflareHandlerSection.vue +20 -20
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +13 -13
- package/app/components/settings/ConnectionTestVerdict.vue +3 -3
- package/app/components/settings/ConnectionWarnings.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +27 -35
- package/app/components/settings/CustomManifestTypeEditor.vue +10 -10
- package/app/components/settings/DefaultProvisionTypeSection.vue +6 -6
- package/app/components/settings/InfraHandlersConfigurator.vue +24 -22
- package/app/components/settings/InfrastructureBackendPicker.vue +6 -6
- package/app/components/settings/InfrastructureWindow.vue +5 -5
- package/app/components/settings/IssueTrackerPanel.vue +29 -23
- package/app/components/settings/KubernetesEngineForm.vue +11 -11
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -4
- package/app/components/settings/LocalContainerPoolSettings.vue +6 -11
- package/app/components/settings/LocalModelEndpointsPanel.vue +20 -18
- package/app/components/settings/McpAuthorizeScreen.vue +13 -15
- package/app/components/settings/McpOAuthCallbackScreen.vue +16 -10
- package/app/components/settings/MergeClassRulesEditor.vue +6 -9
- package/app/components/settings/MergeRolePolicyEditor.vue +16 -16
- package/app/components/settings/ModelConfigurationPanel.vue +23 -30
- package/app/components/settings/ModelPresetHealthModal.vue +15 -13
- package/app/components/settings/ObservabilityConnectionPanel.vue +4 -4
- package/app/components/settings/OpenRouterCatalogPanel.vue +26 -19
- package/app/components/settings/PackageRegistriesPanel.vue +8 -8
- package/app/components/settings/ProviderConnectionTab.vue +8 -11
- package/app/components/settings/ProviderManifestEditor.vue +9 -9
- package/app/components/settings/ProviderPreferenceEditor.vue +8 -8
- package/app/components/settings/RiskPolicyCreateForm.vue +10 -10
- package/app/components/settings/RiskPolicyEditorRow.vue +14 -14
- package/app/components/settings/RiskPolicyHealthModal.vue +15 -13
- package/app/components/settings/RiskPolicyInheritedRow.vue +1 -1
- package/app/components/settings/RiskPolicyPanel.vue +10 -15
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +7 -7
- package/app/components/settings/SharedStacksPanel.vue +9 -12
- package/app/components/settings/TaskSourceCard.vue +4 -4
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +6 -6
- package/app/components/settings/ToolServerChecklist.vue +36 -29
- package/app/components/settings/UsageSettings.vue +15 -15
- package/app/components/settings/UserSecretsSection.vue +9 -12
- package/app/components/settings/WorkspaceMetadataSettings.vue +5 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +47 -47
- package/app/components/skills/ReviewSkillQueue.vue +10 -10
- package/app/components/skills/SkillLibraryManager.vue +23 -20
- package/app/components/slack/SlackPanel.vue +13 -17
- package/app/components/spec/ServiceSpecWindow.vue +45 -42
- package/app/components/tasks/BugHuntModal.vue +24 -27
- package/app/components/tasks/ContextIssuePicker.vue +11 -11
- package/app/components/tasks/TaskContextIssues.vue +3 -3
- package/app/components/tasks/TaskImportModal.vue +7 -7
- package/app/components/tasks/TaskSourceConnectModal.vue +10 -8
- package/app/components/testing/TestReportWindow.vue +99 -82
- package/app/components/theme/ThemeImportModal.vue +115 -0
- package/app/components/tutorial/TutorialCatalogue.vue +9 -9
- package/app/components/tutorial/TutorialNudge.vue +5 -5
- package/app/components/tutorial/TutorialOverlay.vue +12 -12
- package/app/components/tutorial/TutorialPrompt.vue +6 -9
- package/app/components/vcs/GitLabConnect.vue +4 -4
- package/app/components/vcs/VcsConnectSurfaces.vue +2 -2
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +36 -36
- package/app/composables/api/client.ts +6 -1
- package/app/composables/usePipelineErrorToast.ts +17 -0
- package/app/modular/agent-kinds.ts +24 -0
- package/app/pages/index.vue +5 -5
- package/app/plugins/theme.client.ts +125 -0
- package/app/spa-loading-template.html +52 -14
- package/app/stores/agents.ts +1 -1
- package/app/stores/theme.spec.ts +56 -0
- package/app/stores/theme.ts +87 -0
- package/app/types/domain.ts +19 -0
- package/app/types/execution.ts +4 -0
- package/app/utils/agentOutput.ts +1 -1
- package/app/utils/binaryOutput.ts +6 -6
- package/app/utils/bootstrapSteps.ts +14 -14
- package/app/utils/catalog.ts +87 -83
- package/app/utils/colorTint.ts +10 -0
- package/app/utils/failureKinds.ts +1 -0
- package/app/utils/observability.ts +3 -3
- package/app/utils/pipelineRender.ts +13 -17
- package/app/utils/swimlanes.ts +4 -4
- package/app/utils/theme/bootPalette.spec.ts +54 -0
- package/app/utils/theme/bootPalette.ts +108 -0
- package/app/utils/theme/builtins.spec.ts +38 -0
- package/app/utils/theme/builtins.ts +55 -0
- package/app/utils/theme/css.ts +162 -0
- package/app/utils/theme/doc.ts +353 -0
- package/app/utils/theme/link.ts +93 -0
- package/app/utils/theme/presets.ts +509 -0
- package/app/utils/theme/theme.spec.ts +224 -0
- package/i18n/locales/de.json +61 -4
- package/i18n/locales/en.json +70 -4
- package/i18n/locales/es.json +61 -4
- package/i18n/locales/fr.json +61 -4
- package/i18n/locales/he.json +61 -4
- package/i18n/locales/it.json +61 -4
- package/i18n/locales/ja.json +61 -4
- package/i18n/locales/pl.json +61 -4
- package/i18n/locales/tr.json +61 -4
- package/i18n/locales/uk.json +61 -4
- package/nuxt.config.ts +37 -11
- package/package.json +10 -9
|
@@ -11,10 +11,10 @@ const props = defineProps<{
|
|
|
11
11
|
const archetype = computed(() => agentKindMeta(props.step.agentKind))
|
|
12
12
|
|
|
13
13
|
const stateRing: Record<AgentState, string> = {
|
|
14
|
-
pending: 'ring-
|
|
15
|
-
working: 'ring-
|
|
16
|
-
waiting_decision: 'ring-
|
|
17
|
-
done: 'ring-
|
|
14
|
+
pending: 'ring-app-600/60 opacity-60',
|
|
15
|
+
working: 'ring-primary',
|
|
16
|
+
waiting_decision: 'ring-app-warning-400 board-pulse',
|
|
17
|
+
done: 'ring-app-success-400',
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const stateIcon: Record<AgentState, string | null> = {
|
|
@@ -32,27 +32,27 @@ const dim = computed(() => (props.size === 'sm' ? 'h-7 w-7' : 'h-9 w-9'))
|
|
|
32
32
|
<div
|
|
33
33
|
class="relative flex items-center justify-center rounded-full ring-2 transition"
|
|
34
34
|
:class="[dim, stateRing[step.state], active ? 'scale-110' : '']"
|
|
35
|
-
:style="{ backgroundColor: archetype.color
|
|
35
|
+
:style="{ backgroundColor: tint(archetype.color) }"
|
|
36
36
|
>
|
|
37
37
|
<UIcon :name="archetype.icon" class="text-base" :style="{ color: archetype.color }" />
|
|
38
38
|
<span
|
|
39
39
|
v-if="step.state === 'working'"
|
|
40
|
-
class="absolute -bottom-1 -end-1 rounded-full bg-
|
|
40
|
+
class="absolute -bottom-1 -end-1 rounded-full bg-default p-0.5"
|
|
41
41
|
>
|
|
42
|
-
<UIcon :name="stateIcon.working!" class="h-3 w-3 animate-spin text-
|
|
42
|
+
<UIcon :name="stateIcon.working!" class="h-3 w-3 animate-spin text-primary" />
|
|
43
43
|
</span>
|
|
44
44
|
<span
|
|
45
45
|
v-else-if="stateIcon[step.state]"
|
|
46
|
-
class="absolute -bottom-1 -end-1 rounded-full bg-
|
|
46
|
+
class="absolute -bottom-1 -end-1 rounded-full bg-default p-0.5"
|
|
47
47
|
>
|
|
48
48
|
<UIcon
|
|
49
49
|
:name="stateIcon[step.state]!"
|
|
50
50
|
class="h-3 w-3"
|
|
51
|
-
:class="step.state === 'done' ? 'text-
|
|
51
|
+
:class="step.state === 'done' ? 'text-app-success-300' : 'text-app-warning-300'"
|
|
52
52
|
/>
|
|
53
53
|
</span>
|
|
54
54
|
</div>
|
|
55
|
-
<span v-if="size !== 'sm'" class="text-[10px] leading-none text-
|
|
55
|
+
<span v-if="size !== 'sm'" class="text-[10px] leading-none text-toned">
|
|
56
56
|
{{ archetype.label }}
|
|
57
57
|
</span>
|
|
58
58
|
</div>
|
|
@@ -238,21 +238,21 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
238
238
|
shows only the internal id + a "Permission denied" placeholder (never the repo). -->
|
|
239
239
|
<div
|
|
240
240
|
v-if="block?.accessDenied"
|
|
241
|
-
class="w-56 overflow-hidden rounded-xl border border-
|
|
241
|
+
class="w-56 overflow-hidden rounded-xl border border-muted bg-default/90 shadow-xl backdrop-blur"
|
|
242
242
|
:data-block-id="block.id"
|
|
243
243
|
data-testid="frame-access-denied"
|
|
244
244
|
>
|
|
245
|
-
<div class="flex items-center gap-2 border-b border-
|
|
246
|
-
<span class="i-lucide-lock h-4 w-4 shrink-0 text-
|
|
247
|
-
<span class="truncate text-sm font-semibold text-
|
|
245
|
+
<div class="flex items-center gap-2 border-b border-default px-3 py-2">
|
|
246
|
+
<span class="i-lucide-lock h-4 w-4 shrink-0 text-muted" />
|
|
247
|
+
<span class="truncate text-sm font-semibold text-default">{{
|
|
248
248
|
t('board.frame.accessDenied.title')
|
|
249
249
|
}}</span>
|
|
250
250
|
</div>
|
|
251
251
|
<div class="px-3 py-3">
|
|
252
|
-
<p class="text-[11px] leading-snug text-
|
|
252
|
+
<p class="text-[11px] leading-snug text-muted">
|
|
253
253
|
{{ t('board.frame.accessDenied.hint') }}
|
|
254
254
|
</p>
|
|
255
|
-
<code class="mt-2 block truncate font-mono text-[11px] text-
|
|
255
|
+
<code class="mt-2 block truncate font-mono text-[11px] text-dimmed">{{ block.id }}</code>
|
|
256
256
|
</div>
|
|
257
257
|
</div>
|
|
258
258
|
|
|
@@ -291,23 +291,23 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
291
291
|
and a collapsed summary) went with the header's collapse control, since between them they
|
|
292
292
|
held the only render of the "Shared" badge, which now lives in the header below. -->
|
|
293
293
|
<div
|
|
294
|
-
class="relative overflow-visible rounded-2xl border bg-
|
|
295
|
-
:class="[selected ? 'border-
|
|
294
|
+
class="relative overflow-visible rounded-2xl border bg-default/95 shadow-2xl backdrop-blur"
|
|
295
|
+
:class="[selected ? 'border-inverted' : 'border-muted', pulseClass]"
|
|
296
296
|
>
|
|
297
297
|
<div class="h-1.5 w-full rounded-t-2xl" :style="{ backgroundColor: accent }" />
|
|
298
298
|
<!-- bootstrap-in-progress banner -->
|
|
299
299
|
<div
|
|
300
300
|
v-if="bootstrapping"
|
|
301
|
-
class="border-b border-
|
|
301
|
+
class="border-b border-app-warning-900/50 bg-app-warning-950/30 px-4 py-2"
|
|
302
302
|
data-testid="bootstrap-progress"
|
|
303
303
|
>
|
|
304
304
|
<div class="flex items-center gap-1.5 text-xs">
|
|
305
305
|
<UIcon
|
|
306
306
|
name="i-lucide-loader-circle"
|
|
307
|
-
class="h-4 w-4 shrink-0 animate-spin text-
|
|
307
|
+
class="h-4 w-4 shrink-0 animate-spin text-app-warning-400"
|
|
308
308
|
/>
|
|
309
|
-
<span class="text-
|
|
310
|
-
<span v-if="bootstrapSubtasks" class="ms-auto text-
|
|
309
|
+
<span class="text-app-warning-300">{{ t('board.frame.bootstrappingRepository') }}</span>
|
|
310
|
+
<span v-if="bootstrapSubtasks" class="ms-auto text-app-warning-200/80">
|
|
311
311
|
{{
|
|
312
312
|
t('board.frame.bootstrapStepsCount', {
|
|
313
313
|
completed: bootstrapSubtasks.completed,
|
|
@@ -316,9 +316,9 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
316
316
|
}}
|
|
317
317
|
</span>
|
|
318
318
|
</div>
|
|
319
|
-
<div class="mt-1.5 h-1 w-full overflow-hidden rounded bg-
|
|
319
|
+
<div class="mt-1.5 h-1 w-full overflow-hidden rounded bg-app-warning-900/40">
|
|
320
320
|
<div
|
|
321
|
-
class="h-full rounded bg-
|
|
321
|
+
class="h-full rounded bg-app-warning-400 transition-all"
|
|
322
322
|
:style="{ width: bootstrapPct + '%' }"
|
|
323
323
|
/>
|
|
324
324
|
</div>
|
|
@@ -330,18 +330,18 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
330
330
|
class="flex items-start gap-1.5 text-[11px]"
|
|
331
331
|
:class="
|
|
332
332
|
item.status === 'completed'
|
|
333
|
-
? 'text-
|
|
333
|
+
? 'text-app-warning-200/60 line-through'
|
|
334
334
|
: item.status === 'in_progress'
|
|
335
|
-
? 'text-
|
|
336
|
-
: 'text-
|
|
335
|
+
? 'text-app-warning-100'
|
|
336
|
+
: 'text-app-warning-200/80'
|
|
337
337
|
"
|
|
338
338
|
>
|
|
339
339
|
<UIcon
|
|
340
340
|
:name="ITEM_ICON[item.status]"
|
|
341
341
|
class="mt-px h-3 w-3 shrink-0"
|
|
342
342
|
:class="[
|
|
343
|
-
item.status === 'in_progress' ? 'animate-spin text-
|
|
344
|
-
item.status === 'completed' ? 'text-
|
|
343
|
+
item.status === 'in_progress' ? 'animate-spin text-app-warning-400' : '',
|
|
344
|
+
item.status === 'completed' ? 'text-app-success-400' : 'text-app-warning-400/70',
|
|
345
345
|
]"
|
|
346
346
|
/>
|
|
347
347
|
<span>{{ item.label }}</span>
|
|
@@ -368,11 +368,11 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
368
368
|
<!-- parked on a human adoption review: the run is waiting on the viewer, not working -->
|
|
369
369
|
<div
|
|
370
370
|
v-else-if="awaitingReview"
|
|
371
|
-
class="m-3 space-y-2 rounded-md border border-
|
|
371
|
+
class="m-3 space-y-2 rounded-md border border-app-warning-500/40 bg-app-warning-500/5 p-3"
|
|
372
372
|
>
|
|
373
373
|
<div class="flex items-start gap-2">
|
|
374
|
-
<UIcon name="i-lucide-user-check" class="mt-0.5 h-4 w-4 shrink-0 text-
|
|
375
|
-
<p class="text-xs text-
|
|
374
|
+
<UIcon name="i-lucide-user-check" class="mt-0.5 h-4 w-4 shrink-0 text-app-warning-400" />
|
|
375
|
+
<p class="text-xs text-app-warning-200/90">{{ t('bootstrap.adoption.cardPrompt') }}</p>
|
|
376
376
|
</div>
|
|
377
377
|
<BootstrapRunSteps :run-id="awaitingReview.id" />
|
|
378
378
|
<div class="flex justify-end">
|
|
@@ -404,7 +404,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
404
404
|
<div class="flex items-center gap-2">
|
|
405
405
|
<div
|
|
406
406
|
class="flex h-8 w-8 items-center justify-center rounded-lg"
|
|
407
|
-
:style="{ backgroundColor: typeMeta!.accent
|
|
407
|
+
:style="{ backgroundColor: tint(typeMeta!.accent) }"
|
|
408
408
|
>
|
|
409
409
|
<UIcon
|
|
410
410
|
:name="typeMeta!.icon"
|
|
@@ -414,7 +414,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
414
414
|
</div>
|
|
415
415
|
<div>
|
|
416
416
|
<div class="flex items-center gap-1.5">
|
|
417
|
-
<span class="text-sm font-semibold text-
|
|
417
|
+
<span class="text-sm font-semibold text-highlighted">{{ block.title }}</span>
|
|
418
418
|
<!-- Mounted on more than one board in the org. On the title row rather than in
|
|
419
419
|
the action strip, because it qualifies the service's NAME: the work lands in
|
|
420
420
|
a repo another board also drives. -->
|
|
@@ -430,7 +430,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
430
430
|
{{ t('board.frame.shared') }}
|
|
431
431
|
</UBadge>
|
|
432
432
|
</div>
|
|
433
|
-
<div class="text-[11px] text-
|
|
433
|
+
<div class="text-[11px] text-muted">{{ typeMeta!.label }}</div>
|
|
434
434
|
</div>
|
|
435
435
|
</div>
|
|
436
436
|
<div class="flex items-center gap-1">
|
|
@@ -530,13 +530,13 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
530
530
|
stays is what the canvas can't show at a glance. -->
|
|
531
531
|
<div
|
|
532
532
|
v-if="modules.length || prTasks"
|
|
533
|
-
class="flex items-center gap-2 text-[10px] uppercase tracking-wide text-
|
|
533
|
+
class="flex items-center gap-2 text-[10px] uppercase tracking-wide text-dimmed"
|
|
534
534
|
>
|
|
535
535
|
<span v-if="modules.length">{{
|
|
536
536
|
t('board.frame.moduleCount', { count: modules.length }, modules.length)
|
|
537
537
|
}}</span>
|
|
538
538
|
<span v-if="modules.length && prTasks" aria-hidden="true">·</span>
|
|
539
|
-
<span v-if="prTasks" class="text-
|
|
539
|
+
<span v-if="prTasks" class="text-app-success-400">{{
|
|
540
540
|
t('board.frame.prReadyCount', { count: prTasks })
|
|
541
541
|
}}</span>
|
|
542
542
|
</div>
|
|
@@ -549,7 +549,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
549
549
|
through to nothing; each lane body carries the same zone for drops inside it. -->
|
|
550
550
|
<div
|
|
551
551
|
:data-drop-zone="block.id"
|
|
552
|
-
class="nodrag relative rounded-xl bg-
|
|
552
|
+
class="nodrag relative rounded-xl bg-app-950/40 p-2"
|
|
553
553
|
:style="{ width: canvas.w + 'px', minHeight: canvas.h + 'px' }"
|
|
554
554
|
>
|
|
555
555
|
<!-- Initiatives sit in a wrapping band above the lanes: they are containers of work,
|
|
@@ -564,7 +564,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
564
564
|
v-if="!hasTasks && access.canWriteBoard.value"
|
|
565
565
|
type="button"
|
|
566
566
|
data-testid="frame-add-task-empty"
|
|
567
|
-
class="absolute inset-4 flex items-center justify-center gap-1 rounded-lg border border-dashed border-
|
|
567
|
+
class="absolute inset-4 flex items-center justify-center gap-1 rounded-lg border border-dashed border-muted text-[11px] text-dimmed hover:border-app-500 hover:text-toned"
|
|
568
568
|
@click.stop="addTask"
|
|
569
569
|
>
|
|
570
570
|
<UIcon name="i-lucide-plus" class="h-3.5 w-3.5" /> {{ t('board.frame.addFirstTask') }}
|
|
@@ -18,12 +18,12 @@ const displayLabel = computed(() => props.label ?? t('board.decisionBadge.decisi
|
|
|
18
18
|
<template>
|
|
19
19
|
<button
|
|
20
20
|
type="button"
|
|
21
|
-
class="board-pulse flex items-center gap-1 rounded-full bg-
|
|
21
|
+
class="board-pulse flex items-center gap-1 rounded-full bg-app-warning-500 px-2 py-0.5 text-xs font-semibold text-app-warning-50 dark:text-app-warning-950 shadow-lg transition hover:bg-app-warning-400"
|
|
22
22
|
@click.stop="$emit('open')"
|
|
23
23
|
>
|
|
24
24
|
<UIcon :name="icon" class="h-3.5 w-3.5" />
|
|
25
25
|
<span v-if="!compact">{{ displayLabel }}</span>
|
|
26
|
-
<span v-if="count && count > 1" class="rounded-full bg-
|
|
26
|
+
<span v-if="count && count > 1" class="rounded-full bg-app-warning-950/30 px-1">
|
|
27
27
|
{{ count }}
|
|
28
28
|
</span>
|
|
29
29
|
</button>
|
|
@@ -26,30 +26,34 @@ const selected = computed(() => ui.selectedBlockId === props.id)
|
|
|
26
26
|
<div
|
|
27
27
|
v-if="block"
|
|
28
28
|
:data-block-id="block.id"
|
|
29
|
-
class="w-56 cursor-pointer rounded-lg border bg-
|
|
30
|
-
:class="
|
|
29
|
+
class="w-56 cursor-pointer rounded-lg border bg-default/90 px-3 py-2 shadow-lg backdrop-blur transition-colors"
|
|
30
|
+
:class="
|
|
31
|
+
selected
|
|
32
|
+
? 'border-app-secondary-400 ring-1 ring-app-secondary-400/50'
|
|
33
|
+
: 'border-app-secondary-500/40'
|
|
34
|
+
"
|
|
31
35
|
@click="ui.select(block.id)"
|
|
32
36
|
>
|
|
33
37
|
<div class="flex items-center gap-1.5">
|
|
34
|
-
<UIcon name="i-lucide-layers" class="h-3.5 w-3.5 shrink-0 text-
|
|
35
|
-
<span class="text-[10px] font-semibold uppercase tracking-wide text-
|
|
38
|
+
<UIcon name="i-lucide-layers" class="h-3.5 w-3.5 shrink-0 text-app-secondary-400" />
|
|
39
|
+
<span class="text-[10px] font-semibold uppercase tracking-wide text-app-secondary-300">{{
|
|
36
40
|
t('board.epic.label')
|
|
37
41
|
}}</span>
|
|
38
|
-
<span class="ms-auto text-[10px] text-
|
|
42
|
+
<span class="ms-auto text-[10px] text-muted">{{ done }}/{{ total }}</span>
|
|
39
43
|
</div>
|
|
40
|
-
<div class="mt-1 truncate text-sm font-medium text-
|
|
44
|
+
<div class="mt-1 truncate text-sm font-medium text-app-100" :title="block.title">
|
|
41
45
|
{{ block.title }}
|
|
42
46
|
</div>
|
|
43
|
-
<div class="mt-1.5 h-1 w-full overflow-hidden rounded-full bg-
|
|
47
|
+
<div class="mt-1.5 h-1 w-full overflow-hidden rounded-full bg-accented/60">
|
|
44
48
|
<div
|
|
45
|
-
class="h-full rounded-full bg-
|
|
49
|
+
class="h-full rounded-full bg-app-secondary-500"
|
|
46
50
|
:style="{ width: total ? `${Math.round((done / total) * 100)}%` : '0%' }"
|
|
47
51
|
/>
|
|
48
52
|
</div>
|
|
49
|
-
<div v-if="active" class="mt-1 text-[10px] text-
|
|
53
|
+
<div v-if="active" class="mt-1 text-[10px] text-muted">
|
|
50
54
|
{{ t('board.epic.activeCount', { count: active }) }}
|
|
51
55
|
</div>
|
|
52
|
-
<div v-else-if="total === 0" class="mt-1 text-[10px] text-
|
|
56
|
+
<div v-else-if="total === 0" class="mt-1 text-[10px] text-dimmed">
|
|
53
57
|
{{ t('board.epic.noTasksYet') }}
|
|
54
58
|
</div>
|
|
55
59
|
</div>
|
|
@@ -66,39 +66,37 @@ const withheldNote = computed(() => {
|
|
|
66
66
|
<!-- The Done strip. Rendered only once the service HAS finished something: an empty archive
|
|
67
67
|
is the one lane whose emptiness says nothing a reader needs (a new service has merged
|
|
68
68
|
nothing, which its three live lanes already show). -->
|
|
69
|
-
<div v-if="doneLane && doneLane.total > 0" class="rounded-lg bg-
|
|
69
|
+
<div v-if="doneLane && doneLane.total > 0" class="rounded-lg bg-default/40">
|
|
70
70
|
<button
|
|
71
71
|
type="button"
|
|
72
|
-
class="nodrag flex w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left hover:bg-
|
|
72
|
+
class="nodrag flex w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left hover:bg-elevated/40"
|
|
73
73
|
data-testid="done-lane-toggle"
|
|
74
74
|
:aria-expanded="!laneView.doneLaneCollapsed"
|
|
75
75
|
@click.stop="laneView.toggleDoneLane()"
|
|
76
76
|
>
|
|
77
77
|
<UIcon
|
|
78
78
|
:name="laneView.doneLaneCollapsed ? 'i-lucide-chevron-right' : 'i-lucide-chevron-down'"
|
|
79
|
-
class="h-3.5 w-3.5 shrink-0 text-
|
|
79
|
+
class="h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
80
80
|
/>
|
|
81
81
|
<UIcon
|
|
82
82
|
:name="LANE_META.done.icon"
|
|
83
83
|
class="h-3.5 w-3.5 shrink-0"
|
|
84
84
|
:style="{ color: LANE_META.done.color }"
|
|
85
85
|
/>
|
|
86
|
-
<span class="text-[11px] font-semibold text-
|
|
87
|
-
t(LANE_META.done.labelKey)
|
|
88
|
-
}}</span>
|
|
86
|
+
<span class="text-[11px] font-semibold text-default">{{ t(LANE_META.done.labelKey) }}</span>
|
|
89
87
|
<!-- The TOTAL, not what the caps admitted: "this service has finished 312 tasks" is the
|
|
90
88
|
fact the lane carries, and counting only the visible cards would understate it by
|
|
91
89
|
two orders of magnitude. -->
|
|
92
90
|
<span
|
|
93
91
|
class="shrink-0 rounded px-1 text-[10px] font-semibold tabular-nums"
|
|
94
92
|
:style="{
|
|
95
|
-
backgroundColor: LANE_META.done.color
|
|
93
|
+
backgroundColor: tint(LANE_META.done.color),
|
|
96
94
|
color: LANE_META.done.color,
|
|
97
95
|
}"
|
|
98
96
|
data-testid="lane-count-done"
|
|
99
97
|
>{{ doneLane.total }}</span
|
|
100
98
|
>
|
|
101
|
-
<span v-if="withheldNote" class="ms-auto truncate text-[10px] text-
|
|
99
|
+
<span v-if="withheldNote" class="ms-auto truncate text-[10px] text-dimmed">{{
|
|
102
100
|
withheldNote
|
|
103
101
|
}}</span>
|
|
104
102
|
</button>
|
|
@@ -120,7 +118,7 @@ const withheldNote = computed(() => {
|
|
|
120
118
|
has nothing in it rather than looking broken. -->
|
|
121
119
|
<p
|
|
122
120
|
v-if="doneSelection.shown.length === 0"
|
|
123
|
-
class="px-1 text-[10px] leading-snug text-
|
|
121
|
+
class="px-1 text-[10px] leading-snug text-app-600"
|
|
124
122
|
>
|
|
125
123
|
{{ t('board.lanes.done.allWithheld') }}
|
|
126
124
|
</p>
|
|
@@ -66,33 +66,33 @@ function select() {
|
|
|
66
66
|
<div
|
|
67
67
|
data-testid="initiative-card"
|
|
68
68
|
:data-status="status"
|
|
69
|
-
class="cursor-pointer rounded-lg border border-
|
|
69
|
+
class="cursor-pointer rounded-lg border border-primary/60 bg-primary/10 p-3 transition hover:border-primary"
|
|
70
70
|
:class="[
|
|
71
|
-
selected ? 'ring-2 ring-
|
|
71
|
+
selected ? 'ring-2 ring-primary/60' : '',
|
|
72
72
|
awaitingAnswers || attention ? 'board-pulse' : '',
|
|
73
73
|
]"
|
|
74
74
|
@click.stop="select"
|
|
75
75
|
>
|
|
76
76
|
<div class="flex items-start justify-between gap-2">
|
|
77
77
|
<div class="flex items-center gap-2">
|
|
78
|
-
<UIcon name="i-lucide-milestone" class="h-4 w-4 shrink-0 text-
|
|
79
|
-
<div class="text-xs font-semibold text-
|
|
78
|
+
<UIcon name="i-lucide-milestone" class="h-4 w-4 shrink-0 text-primary" />
|
|
79
|
+
<div class="text-xs font-semibold text-highlighted">{{ block.title }}</div>
|
|
80
80
|
</div>
|
|
81
81
|
<UBadge :color="INITIATIVE_STATUS_CHIPS[status]" variant="subtle" size="sm">
|
|
82
82
|
{{ statusLabel }}
|
|
83
83
|
</UBadge>
|
|
84
84
|
</div>
|
|
85
|
-
<div class="mt-1 text-[10px] uppercase tracking-wide text-
|
|
85
|
+
<div class="mt-1 text-[10px] uppercase tracking-wide text-primary/70">
|
|
86
86
|
{{ t('initiative.card.kind') }}
|
|
87
87
|
</div>
|
|
88
88
|
<div v-if="progress" class="mt-2 space-y-1">
|
|
89
|
-
<div class="h-1.5 overflow-hidden rounded bg-
|
|
89
|
+
<div class="h-1.5 overflow-hidden rounded bg-elevated">
|
|
90
90
|
<div
|
|
91
|
-
class="h-full rounded bg-
|
|
91
|
+
class="h-full rounded bg-primary"
|
|
92
92
|
:style="{ width: `${Math.round((progress.settled / progress.total) * 100)}%` }"
|
|
93
93
|
/>
|
|
94
94
|
</div>
|
|
95
|
-
<div class="text-[10px] text-
|
|
95
|
+
<div class="text-[10px] text-muted">
|
|
96
96
|
{{ t('initiative.card.progress', { done: progress.settled, total: progress.total }) }}
|
|
97
97
|
</div>
|
|
98
98
|
</div>
|
|
@@ -75,7 +75,7 @@ const icon = computed(() => {
|
|
|
75
75
|
saying "all of them" would be a row of chrome carrying no information. -->
|
|
76
76
|
<div
|
|
77
77
|
v-if="groupKey !== 'none'"
|
|
78
|
-
class="flex items-center gap-1 px-0.5 text-[10px] uppercase tracking-wide text-
|
|
78
|
+
class="flex items-center gap-1 px-0.5 text-[10px] uppercase tracking-wide text-dimmed"
|
|
79
79
|
>
|
|
80
80
|
<UIcon v-if="icon" :name="icon" class="h-3 w-3 shrink-0" />
|
|
81
81
|
<span class="truncate" :title="label">{{ label }}</span>
|
|
@@ -52,13 +52,13 @@ function onHandle(e: PointerEvent) {
|
|
|
52
52
|
for read-only viewers, for whom the drag is a no-op anyway (see useBlockDrag). -->
|
|
53
53
|
<div
|
|
54
54
|
v-if="access.canWriteBoard.value"
|
|
55
|
-
class="nodrag nopan flex cursor-grab touch-none items-center justify-center rounded-t-lg border border-b-0 border-
|
|
55
|
+
class="nodrag nopan flex cursor-grab touch-none items-center justify-center rounded-t-lg border border-b-0 border-muted bg-elevated/80 py-px active:cursor-grabbing pointer-coarse:py-2"
|
|
56
56
|
:title="t('board.frame.dragTask')"
|
|
57
57
|
@pointerdown="onHandle"
|
|
58
58
|
>
|
|
59
59
|
<UIcon
|
|
60
60
|
name="i-lucide-grip-horizontal"
|
|
61
|
-
class="h-3 w-3 text-
|
|
61
|
+
class="h-3 w-3 text-dimmed pointer-coarse:h-5 pointer-coarse:w-5"
|
|
62
62
|
/>
|
|
63
63
|
</div>
|
|
64
64
|
<TaskCard :task-id="taskId" :class="access.canWriteBoard.value ? '!rounded-t-none' : ''" />
|
|
@@ -90,11 +90,11 @@ const GRIPS: Record<ResizeEdge, GripStyle> = {
|
|
|
90
90
|
// A bar is filled, an L-shaped corner mark is drawn in border colour — so the lit/idle classes
|
|
91
91
|
// differ per shape as well as per tone.
|
|
92
92
|
const TONES = {
|
|
93
|
-
frame: { barLit: 'bg-
|
|
93
|
+
frame: { barLit: 'bg-app-info-400', markLit: 'border-app-info-400', markIdle: 'border-app-500' },
|
|
94
94
|
module: {
|
|
95
|
-
barLit: 'bg-
|
|
96
|
-
markLit: 'border-
|
|
97
|
-
markIdle: 'border-
|
|
95
|
+
barLit: 'bg-app-secondary-300',
|
|
96
|
+
markLit: 'border-app-secondary-300',
|
|
97
|
+
markIdle: 'border-app-secondary-400/60',
|
|
98
98
|
},
|
|
99
99
|
} as const
|
|
100
100
|
|
|
@@ -311,9 +311,9 @@ function selectTask() {
|
|
|
311
311
|
:data-status="task.status"
|
|
312
312
|
:data-task-type="task.taskType"
|
|
313
313
|
data-testid="task-card"
|
|
314
|
-
class="nodrag w-full cursor-pointer rounded-lg border bg-
|
|
314
|
+
class="nodrag w-full cursor-pointer rounded-lg border bg-app-950/70 p-2 text-start transition"
|
|
315
315
|
:class="[
|
|
316
|
-
selected ? 'border-
|
|
316
|
+
selected ? 'border-inverted' : 'border-muted hover:border-app-500',
|
|
317
317
|
task.status === 'pr_ready' ? 'board-pulse-green' : attention ? 'board-pulse' : '',
|
|
318
318
|
]"
|
|
319
319
|
@click.stop="selectTask"
|
|
@@ -328,7 +328,7 @@ function selectTask() {
|
|
|
328
328
|
<span
|
|
329
329
|
v-if="typeBadge"
|
|
330
330
|
class="inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded"
|
|
331
|
-
:style="{ color: typeBadge.color, backgroundColor:
|
|
331
|
+
:style="{ color: typeBadge.color, backgroundColor: tint(typeBadge.color) }"
|
|
332
332
|
:title="typeBadge.label"
|
|
333
333
|
:data-task-type-badge="task.taskType"
|
|
334
334
|
data-testid="task-type-badge"
|
|
@@ -338,7 +338,7 @@ function selectTask() {
|
|
|
338
338
|
<UIcon
|
|
339
339
|
v-if="schedule"
|
|
340
340
|
name="i-lucide-repeat"
|
|
341
|
-
class="h-3 w-3 shrink-0 text-
|
|
341
|
+
class="h-3 w-3 shrink-0 text-primary"
|
|
342
342
|
:title="
|
|
343
343
|
schedule.enabled
|
|
344
344
|
? t('board.task.recurringPipeline')
|
|
@@ -349,12 +349,12 @@ function selectTask() {
|
|
|
349
349
|
class="ms-auto truncate text-[9px] uppercase tracking-wide"
|
|
350
350
|
:class="
|
|
351
351
|
runFailed
|
|
352
|
-
? 'text-
|
|
352
|
+
? 'text-app-error-400'
|
|
353
353
|
: reviewStage
|
|
354
|
-
? 'text-
|
|
354
|
+
? 'text-primary'
|
|
355
355
|
: attention
|
|
356
|
-
? 'text-
|
|
357
|
-
: 'text-
|
|
356
|
+
? 'text-app-warning-400'
|
|
357
|
+
: 'text-dimmed'
|
|
358
358
|
"
|
|
359
359
|
>
|
|
360
360
|
{{ statusText }}
|
|
@@ -362,7 +362,7 @@ function selectTask() {
|
|
|
362
362
|
<!-- drag-to-connect handle: drag onto another task to make it depend on this one -->
|
|
363
363
|
<button
|
|
364
364
|
type="button"
|
|
365
|
-
class="nodrag shrink-0 cursor-crosshair touch-none rounded-full p-0.5 text-
|
|
365
|
+
class="nodrag shrink-0 cursor-crosshair touch-none rounded-full p-0.5 text-dimmed hover:bg-elevated hover:text-app-warning-400 pointer-coarse:p-2.5"
|
|
366
366
|
:title="t('board.task.dragToConnect')"
|
|
367
367
|
@pointerdown.stop="startConnect(task.id, $event)"
|
|
368
368
|
@click.stop
|
|
@@ -379,7 +379,7 @@ function selectTask() {
|
|
|
379
379
|
title is the one always-rendered part of the body that no control can occupy. -->
|
|
380
380
|
<div
|
|
381
381
|
data-testid="task-title"
|
|
382
|
-
class="mt-1 line-clamp-2 break-words text-[11px] font-semibold leading-snug text-
|
|
382
|
+
class="mt-1 line-clamp-2 break-words text-[11px] font-semibold leading-snug text-app-100"
|
|
383
383
|
:title="task.title"
|
|
384
384
|
>
|
|
385
385
|
{{ task.title }}
|
|
@@ -410,13 +410,13 @@ function selectTask() {
|
|
|
410
410
|
<UIcon
|
|
411
411
|
:name="runnable ? 'i-lucide-link' : 'i-lucide-lock'"
|
|
412
412
|
class="h-3 w-3"
|
|
413
|
-
:class="runnable ? 'text-
|
|
413
|
+
:class="runnable ? 'text-dimmed' : 'text-app-warning-400'"
|
|
414
414
|
/>
|
|
415
415
|
<span
|
|
416
416
|
v-for="d in deps"
|
|
417
417
|
:key="d.id"
|
|
418
|
-
class="inline-flex items-center gap-0.5 rounded bg-
|
|
419
|
-
:class="d.status === 'done' ? 'text-
|
|
418
|
+
class="inline-flex items-center gap-0.5 rounded bg-elevated/80 px-1 py-0.5 text-[9px]"
|
|
419
|
+
:class="d.status === 'done' ? 'text-muted' : 'text-app-warning-300'"
|
|
420
420
|
:title="depLabel(d)"
|
|
421
421
|
>
|
|
422
422
|
<UIcon
|
|
@@ -431,7 +431,7 @@ function selectTask() {
|
|
|
431
431
|
<div class="nodrag mt-2 flex flex-wrap items-center gap-1">
|
|
432
432
|
<!-- a reviewer gate folding/re-reviewing in the background: a working indicator,
|
|
433
433
|
NOT a gate — the human is back on the board and summoned only if input is needed -->
|
|
434
|
-
<span v-if="reviewStage" class="inline-flex items-center gap-1 text-[9px] text-
|
|
434
|
+
<span v-if="reviewStage" class="inline-flex items-center gap-1 text-[9px] text-primary">
|
|
435
435
|
<UIcon name="i-lucide-loader-circle" class="h-3 w-3 animate-spin" />
|
|
436
436
|
{{ reviewStageLabel }}
|
|
437
437
|
</span>
|
|
@@ -481,7 +481,7 @@ function selectTask() {
|
|
|
481
481
|
</UButton>
|
|
482
482
|
<span
|
|
483
483
|
v-if="runnable && defaultPipeline"
|
|
484
|
-
class="inline-flex items-center gap-0.5 text-[9px] text-
|
|
484
|
+
class="inline-flex items-center gap-0.5 text-[9px] text-dimmed"
|
|
485
485
|
>
|
|
486
486
|
<UIcon name="i-lucide-workflow" class="h-2.5 w-2.5" />{{ defaultPipeline.name }}
|
|
487
487
|
</span>
|
|
@@ -539,7 +539,7 @@ function selectTask() {
|
|
|
539
539
|
<!-- A merged task is the one people come back to READ, so its result stays openable
|
|
540
540
|
rather than collapsing to a tick the moment it lands. -->
|
|
541
541
|
<template v-else-if="task.status === 'done'">
|
|
542
|
-
<span class="inline-flex items-center gap-1 text-[9px] text-
|
|
542
|
+
<span class="inline-flex items-center gap-1 text-[9px] text-app-success-400">
|
|
543
543
|
<UIcon name="i-lucide-check-check" class="h-3 w-3" /> {{ t('board.task.implemented') }}
|
|
544
544
|
</span>
|
|
545
545
|
<UButton
|
|
@@ -562,10 +562,10 @@ function selectTask() {
|
|
|
562
562
|
cost a row of card height each and add nothing. -->
|
|
563
563
|
<div
|
|
564
564
|
v-if="showModuleChip"
|
|
565
|
-
class="mt-2 flex flex-wrap items-center gap-1 border-t border-
|
|
565
|
+
class="mt-2 flex flex-wrap items-center gap-1 border-t border-default pt-2"
|
|
566
566
|
>
|
|
567
567
|
<span
|
|
568
|
-
class="inline-flex items-center gap-1 rounded bg-
|
|
568
|
+
class="inline-flex items-center gap-1 rounded bg-app-secondary-500/15 px-1.5 py-0.5 text-[9px] text-app-secondary-200"
|
|
569
569
|
:title="t('board.task.module', { name: task.moduleName })"
|
|
570
570
|
>
|
|
571
571
|
<UIcon :name="MODULE_META.icon" class="h-3 w-3" :style="{ color: MODULE_META.color }" />
|
|
@@ -36,20 +36,20 @@ const isEmpty = computed(() => props.rendered.groups.every((g) => g.entries.leng
|
|
|
36
36
|
|
|
37
37
|
<template>
|
|
38
38
|
<div
|
|
39
|
-
class="flex min-w-0 flex-col rounded-lg bg-
|
|
39
|
+
class="flex min-w-0 flex-col rounded-lg bg-default/40"
|
|
40
40
|
:style="{ width: LANE_GEOMETRY.laneWidth + 'px' }"
|
|
41
41
|
:data-lane="rendered.lane"
|
|
42
42
|
>
|
|
43
43
|
<!-- Lane header -->
|
|
44
44
|
<div
|
|
45
45
|
class="flex items-center gap-1.5 rounded-t-lg border-b px-2 py-1.5"
|
|
46
|
-
:style="{ borderColor: meta.color
|
|
46
|
+
:style="{ borderColor: tint(meta.color, 20) }"
|
|
47
47
|
>
|
|
48
48
|
<UIcon :name="meta.icon" class="h-3.5 w-3.5 shrink-0" :style="{ color: meta.color }" />
|
|
49
|
-
<span class="truncate text-[11px] font-semibold text-
|
|
49
|
+
<span class="truncate text-[11px] font-semibold text-default">{{ t(meta.labelKey) }}</span>
|
|
50
50
|
<span
|
|
51
51
|
class="ms-auto shrink-0 rounded px-1 text-[10px] font-semibold tabular-nums"
|
|
52
|
-
:style="{ backgroundColor: meta.color
|
|
52
|
+
:style="{ backgroundColor: tint(meta.color), color: meta.color }"
|
|
53
53
|
:data-testid="`lane-count-${rendered.lane}`"
|
|
54
54
|
>{{ rendered.total }}</span
|
|
55
55
|
>
|
|
@@ -65,7 +65,7 @@ const isEmpty = computed(() => props.rendered.groups.every((g) => g.entries.leng
|
|
|
65
65
|
<!-- An empty lane SAYS it is empty. Left blank, "nothing needs you" and "the lane failed
|
|
66
66
|
to render" look identical, and the first is worth stating: it is the answer a reader
|
|
67
67
|
scanning the needs-you column is hoping for. -->
|
|
68
|
-
<p v-if="isEmpty" class="px-1 pt-2 text-[10px] leading-snug text-
|
|
68
|
+
<p v-if="isEmpty" class="px-1 pt-2 text-[10px] leading-snug text-app-600">
|
|
69
69
|
{{ t(meta.emptyKey) }}
|
|
70
70
|
</p>
|
|
71
71
|
<LaneGroup
|