@cat-factory/app 0.302.2 → 0.303.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 +16 -0
- 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 +23 -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 +9 -8
|
@@ -261,13 +261,13 @@ const hasOverrides = computed(
|
|
|
261
261
|
<section
|
|
262
262
|
v-if="store.available !== false"
|
|
263
263
|
data-testid="account-platform-alerts"
|
|
264
|
-
class="space-y-3 border-t border-
|
|
264
|
+
class="space-y-3 border-t border-default pt-6"
|
|
265
265
|
>
|
|
266
266
|
<div>
|
|
267
|
-
<h4 class="text-sm font-semibold text-
|
|
267
|
+
<h4 class="text-sm font-semibold text-default">
|
|
268
268
|
{{ t('settings.platformAlerts.title') }}
|
|
269
269
|
</h4>
|
|
270
|
-
<p class="text-[11px] text-
|
|
270
|
+
<p class="text-[11px] text-muted">{{ t('settings.platformAlerts.description') }}</p>
|
|
271
271
|
</div>
|
|
272
272
|
|
|
273
273
|
<!--
|
|
@@ -282,11 +282,11 @@ const hasOverrides = computed(
|
|
|
282
282
|
:label="t('settings.platformAlerts.muteLabel')"
|
|
283
283
|
data-testid="platform-alerts-mute"
|
|
284
284
|
/>
|
|
285
|
-
<p class="ps-6 text-[11px] text-
|
|
285
|
+
<p class="ps-6 text-[11px] text-muted">{{ t('settings.platformAlerts.muteHint') }}</p>
|
|
286
286
|
</div>
|
|
287
287
|
|
|
288
288
|
<div class="space-y-1">
|
|
289
|
-
<label class="text-[11px] font-medium text-
|
|
289
|
+
<label class="text-[11px] font-medium text-toned">
|
|
290
290
|
{{ t('settings.platformAlerts.windowLabel') }}
|
|
291
291
|
</label>
|
|
292
292
|
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
|
@@ -298,17 +298,17 @@ const hasOverrides = computed(
|
|
|
298
298
|
data-testid="platform-alerts-window"
|
|
299
299
|
/>
|
|
300
300
|
</div>
|
|
301
|
-
<p class="text-[11px] text-
|
|
301
|
+
<p class="text-[11px] text-muted">{{ t('settings.platformAlerts.windowHint') }}</p>
|
|
302
302
|
</div>
|
|
303
303
|
|
|
304
304
|
<div class="space-y-2">
|
|
305
|
-
<label class="text-[11px] font-medium text-
|
|
305
|
+
<label class="text-[11px] font-medium text-toned">
|
|
306
306
|
{{ t('settings.platformAlerts.thresholdsLabel') }}
|
|
307
307
|
</label>
|
|
308
|
-
<p class="text-[11px] text-
|
|
308
|
+
<p class="text-[11px] text-muted">{{ t('settings.platformAlerts.inheritHint') }}</p>
|
|
309
309
|
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
310
310
|
<div v-for="th in THRESHOLDS" :key="th.field" class="space-y-1">
|
|
311
|
-
<label class="block text-[11px] text-
|
|
311
|
+
<label class="block text-[11px] text-toned" :for="`platform-alert-${th.field}`">
|
|
312
312
|
{{ thresholdLabels[th.field] }}
|
|
313
313
|
</label>
|
|
314
314
|
<UInput
|
|
@@ -320,7 +320,7 @@ const hasOverrides = computed(
|
|
|
320
320
|
:placeholder="t('settings.platformAlerts.inheritPlaceholder')"
|
|
321
321
|
:data-testid="`platform-alert-${th.field}`"
|
|
322
322
|
/>
|
|
323
|
-
<p class="text-[11px] leading-snug text-
|
|
323
|
+
<p class="text-[11px] leading-snug text-dimmed">{{ thresholdHints[th.field] }}</p>
|
|
324
324
|
</div>
|
|
325
325
|
</div>
|
|
326
326
|
</div>
|
|
@@ -334,7 +334,7 @@ const hasOverrides = computed(
|
|
|
334
334
|
-->
|
|
335
335
|
<p
|
|
336
336
|
v-if="!loaded"
|
|
337
|
-
class="rounded-lg border border-
|
|
337
|
+
class="rounded-lg border border-app-warning-800/60 bg-app-warning-950/30 px-3 py-2 text-xs text-app-warning-200"
|
|
338
338
|
data-testid="account-platform-alerts-unloaded"
|
|
339
339
|
>
|
|
340
340
|
{{ t('settings.platformAlerts.notLoaded') }}
|
|
@@ -99,9 +99,9 @@ async function create(input: CreateRiskPolicyInput) {
|
|
|
99
99
|
|
|
100
100
|
<template>
|
|
101
101
|
<div class="space-y-4 text-sm" data-testid="account-risk-policy-panel">
|
|
102
|
-
<p class="text-[11px] text-
|
|
102
|
+
<p class="text-[11px] text-muted">{{ t('layout.accountRiskPolicies.intro') }}</p>
|
|
103
103
|
|
|
104
|
-
<p v-if="!store.loading && policies.length === 0" class="text-[11px] text-
|
|
104
|
+
<p v-if="!store.loading && policies.length === 0" class="text-[11px] text-dimmed">
|
|
105
105
|
{{ t('layout.accountRiskPolicies.empty') }}
|
|
106
106
|
</p>
|
|
107
107
|
|
|
@@ -59,22 +59,22 @@ async function save() {
|
|
|
59
59
|
|
|
60
60
|
<template>
|
|
61
61
|
<div v-if="store.available !== false" class="space-y-2" data-testid="account-run-credential">
|
|
62
|
-
<h3 class="text-sm font-semibold text-
|
|
62
|
+
<h3 class="text-sm font-semibold text-default">
|
|
63
63
|
{{ t('settings.runCredentialPolicy.heading') }}
|
|
64
64
|
</h3>
|
|
65
|
-
<p class="text-[11px] text-
|
|
65
|
+
<p class="text-[11px] text-muted">{{ t('settings.runCredentialPolicy.body') }}</p>
|
|
66
66
|
|
|
67
67
|
<label class="flex items-center gap-2">
|
|
68
68
|
<USwitch v-model="forbid" size="sm" data-testid="account-forbid-initiator-pat" />
|
|
69
|
-
<span class="text-sm text-
|
|
69
|
+
<span class="text-sm text-default">{{ t('settings.runCredentialPolicy.toggle') }}</span>
|
|
70
70
|
</label>
|
|
71
71
|
|
|
72
72
|
<!-- What the choice actually costs, stated at the point of choosing rather than discovered
|
|
73
73
|
later: attribution is a real feature, and turning this on is what trades it away. -->
|
|
74
|
-
<p v-if="forbid" class="text-[11px] text-
|
|
74
|
+
<p v-if="forbid" class="text-[11px] text-app-warning-300">
|
|
75
75
|
{{ t('settings.runCredentialPolicy.onHint') }}
|
|
76
76
|
</p>
|
|
77
|
-
<p v-else class="text-[11px] text-
|
|
77
|
+
<p v-else class="text-[11px] text-dimmed">
|
|
78
78
|
{{ t('settings.runCredentialPolicy.offHint') }}
|
|
79
79
|
</p>
|
|
80
80
|
|
|
@@ -12,7 +12,7 @@ const { t } = useI18n()
|
|
|
12
12
|
<template>
|
|
13
13
|
<div class="space-y-6 text-sm">
|
|
14
14
|
<section>
|
|
15
|
-
<p class="mb-3 text-[11px] text-
|
|
15
|
+
<p class="mb-3 text-[11px] text-muted">
|
|
16
16
|
{{ t('layout.accountSkills.intro') }}
|
|
17
17
|
</p>
|
|
18
18
|
<SkillLibraryManager :account-id="props.accountId" />
|
|
@@ -200,9 +200,11 @@ async function disconnectEmail() {
|
|
|
200
200
|
<template>
|
|
201
201
|
<div class="space-y-6 text-sm">
|
|
202
202
|
<!-- personal-account CTA: members/roles/invitations need an organization -->
|
|
203
|
-
<section v-if="!isOrg" class="rounded-md border border-
|
|
204
|
-
<h3 class="mb-1 font-semibold text-
|
|
205
|
-
|
|
203
|
+
<section v-if="!isOrg" class="rounded-md border border-default bg-elevated/40 p-4">
|
|
204
|
+
<h3 class="mb-1 font-semibold text-highlighted">
|
|
205
|
+
{{ t('layout.accountTeam.org.ctaTitle') }}
|
|
206
|
+
</h3>
|
|
207
|
+
<p class="mb-3 text-muted">
|
|
206
208
|
{{ t('layout.accountTeam.org.ctaBody') }}
|
|
207
209
|
</p>
|
|
208
210
|
<form class="flex gap-2" @submit.prevent="createOrganization">
|
|
@@ -219,12 +221,14 @@ async function disconnectEmail() {
|
|
|
219
221
|
|
|
220
222
|
<!-- members -->
|
|
221
223
|
<section v-if="isOrg">
|
|
222
|
-
<h3 class="mb-2 font-semibold text-
|
|
224
|
+
<h3 class="mb-2 font-semibold text-highlighted">
|
|
225
|
+
{{ t('layout.accountTeam.members.title') }}
|
|
226
|
+
</h3>
|
|
223
227
|
<ul class="space-y-1">
|
|
224
228
|
<li
|
|
225
229
|
v-for="m in accounts.members"
|
|
226
230
|
:key="m.userId"
|
|
227
|
-
class="flex items-center justify-between rounded-md bg-
|
|
231
|
+
class="flex items-center justify-between rounded-md bg-elevated/40 px-2 py-1"
|
|
228
232
|
>
|
|
229
233
|
<span class="truncate">{{ m.name || m.email || m.userId }}</span>
|
|
230
234
|
<USelect
|
|
@@ -236,7 +240,7 @@ async function disconnectEmail() {
|
|
|
236
240
|
class="w-44"
|
|
237
241
|
@update:model-value="(r: AccountRole[]) => updateMemberRoles(m.userId, r)"
|
|
238
242
|
/>
|
|
239
|
-
<span v-else class="text-xs uppercase tracking-wide text-
|
|
243
|
+
<span v-else class="text-xs uppercase tracking-wide text-muted">
|
|
240
244
|
{{ m.roles.join(', ') }}
|
|
241
245
|
</span>
|
|
242
246
|
<!-- Offboarding: end every session this member holds, leaving their membership and
|
|
@@ -254,7 +258,7 @@ async function disconnectEmail() {
|
|
|
254
258
|
@click="revokeSessions(m.userId, m.name || m.email || m.userId)"
|
|
255
259
|
/>
|
|
256
260
|
</li>
|
|
257
|
-
<li v-if="accounts.members.length === 0" class="text-
|
|
261
|
+
<li v-if="accounts.members.length === 0" class="text-dimmed">
|
|
258
262
|
{{ t('layout.accountTeam.members.empty') }}
|
|
259
263
|
</li>
|
|
260
264
|
</ul>
|
|
@@ -262,7 +266,9 @@ async function disconnectEmail() {
|
|
|
262
266
|
|
|
263
267
|
<!-- invitations -->
|
|
264
268
|
<section v-if="isOrg">
|
|
265
|
-
<h3 class="mb-2 font-semibold text-
|
|
269
|
+
<h3 class="mb-2 font-semibold text-highlighted">
|
|
270
|
+
{{ t('layout.accountTeam.invite.title') }}
|
|
271
|
+
</h3>
|
|
266
272
|
<form class="flex gap-2" @submit.prevent="sendInvite">
|
|
267
273
|
<UInput
|
|
268
274
|
v-model="inviteEmail"
|
|
@@ -280,11 +286,11 @@ async function disconnectEmail() {
|
|
|
280
286
|
<li
|
|
281
287
|
v-for="inv in accounts.invitations"
|
|
282
288
|
:key="inv.id"
|
|
283
|
-
class="flex items-center justify-between rounded-md bg-
|
|
289
|
+
class="flex items-center justify-between rounded-md bg-elevated/40 px-2 py-1"
|
|
284
290
|
>
|
|
285
291
|
<span class="truncate">{{ inv.email }}</span>
|
|
286
292
|
<span class="flex items-center gap-2 text-xs">
|
|
287
|
-
<span class="uppercase tracking-wide text-
|
|
293
|
+
<span class="uppercase tracking-wide text-muted">
|
|
288
294
|
{{ invitationStatusLabel(inv.status) }}
|
|
289
295
|
</span>
|
|
290
296
|
<UButton
|
|
@@ -303,14 +309,14 @@ async function disconnectEmail() {
|
|
|
303
309
|
|
|
304
310
|
<!-- email sender -->
|
|
305
311
|
<section>
|
|
306
|
-
<h3 class="mb-2 font-semibold text-
|
|
307
|
-
<p v-if="!accounts.emailConfigured" class="text-
|
|
312
|
+
<h3 class="mb-2 font-semibold text-highlighted">{{ t('layout.accountTeam.email.title') }}</h3>
|
|
313
|
+
<p v-if="!accounts.emailConfigured" class="text-dimmed">
|
|
308
314
|
{{ t('layout.accountTeam.email.notEnabled') }}
|
|
309
315
|
</p>
|
|
310
316
|
<template v-else>
|
|
311
317
|
<div
|
|
312
318
|
v-if="accounts.emailConnection"
|
|
313
|
-
class="flex items-center justify-between rounded-md bg-
|
|
319
|
+
class="flex items-center justify-between rounded-md bg-elevated/40 px-2 py-1.5"
|
|
314
320
|
>
|
|
315
321
|
<i18n-t keypath="layout.accountTeam.email.connectedAs" tag="span" scope="global">
|
|
316
322
|
<template #provider>
|
|
@@ -344,9 +350,11 @@ async function disconnectEmail() {
|
|
|
344
350
|
|
|
345
351
|
<!-- account-wide provider API keys (admin-only): direct vendors + proxy gateways -->
|
|
346
352
|
<section v-if="isAdmin" class="space-y-6">
|
|
347
|
-
<h3 class="mb-2 font-semibold text-
|
|
353
|
+
<h3 class="mb-2 font-semibold text-highlighted">
|
|
354
|
+
{{ t('layout.accountTeam.apiKeys.title') }}
|
|
355
|
+
</h3>
|
|
348
356
|
<ProvidersApiKeysSection :account-id="accountId" category="direct" />
|
|
349
|
-
<div class="border-t border-
|
|
357
|
+
<div class="border-t border-default pt-6">
|
|
350
358
|
<ProvidersApiKeysSection :account-id="accountId" category="proxy" />
|
|
351
359
|
</div>
|
|
352
360
|
</section>
|
|
@@ -24,14 +24,14 @@ const show = computed(() => showSetup.value || showPreset.value)
|
|
|
24
24
|
<!-- (1) No usable AI source -->
|
|
25
25
|
<div
|
|
26
26
|
v-if="showSetup"
|
|
27
|
-
class="w-full max-w-3xl rounded-2xl border-2 border-
|
|
27
|
+
class="w-full max-w-3xl rounded-2xl border-2 border-app-warning-500/70 bg-app-warning-950/95 p-5 shadow-2xl backdrop-blur"
|
|
28
28
|
role="alert"
|
|
29
29
|
>
|
|
30
30
|
<div class="flex items-start gap-4">
|
|
31
|
-
<UIcon name="i-lucide-cpu" class="mt-0.5 h-9 w-9 shrink-0 text-
|
|
31
|
+
<UIcon name="i-lucide-cpu" class="mt-0.5 h-9 w-9 shrink-0 text-app-warning-400" />
|
|
32
32
|
<div class="min-w-0 flex-1">
|
|
33
33
|
<div class="flex items-start justify-between gap-3">
|
|
34
|
-
<h2 class="text-lg font-semibold text-
|
|
34
|
+
<h2 class="text-lg font-semibold text-app-warning-100">
|
|
35
35
|
{{ t('layout.aiProvidersBanner.setup.title') }}
|
|
36
36
|
</h2>
|
|
37
37
|
<UButton
|
|
@@ -43,7 +43,7 @@ const show = computed(() => showSetup.value || showPreset.value)
|
|
|
43
43
|
@click="ui.dismissAiSetup()"
|
|
44
44
|
/>
|
|
45
45
|
</div>
|
|
46
|
-
<p class="mt-1 text-sm text-
|
|
46
|
+
<p class="mt-1 text-sm text-app-warning-200/90">
|
|
47
47
|
{{ t('layout.aiProvidersBanner.setup.body') }}
|
|
48
48
|
</p>
|
|
49
49
|
<div class="mt-4">
|
|
@@ -63,14 +63,17 @@ const show = computed(() => showSetup.value || showPreset.value)
|
|
|
63
63
|
<!-- (2) Default preset references unavailable models -->
|
|
64
64
|
<div
|
|
65
65
|
v-else
|
|
66
|
-
class="w-full max-w-3xl rounded-2xl border border-
|
|
66
|
+
class="w-full max-w-3xl rounded-2xl border border-app-warning-500/50 bg-app-warning-950/90 p-4 shadow-xl backdrop-blur"
|
|
67
67
|
role="alert"
|
|
68
68
|
>
|
|
69
69
|
<div class="flex items-start gap-3">
|
|
70
|
-
<UIcon
|
|
70
|
+
<UIcon
|
|
71
|
+
name="i-lucide-triangle-alert"
|
|
72
|
+
class="mt-0.5 h-7 w-7 shrink-0 text-app-warning-400"
|
|
73
|
+
/>
|
|
71
74
|
<div class="min-w-0 flex-1">
|
|
72
75
|
<div class="flex items-start justify-between gap-3">
|
|
73
|
-
<h2 class="text-sm font-semibold text-
|
|
76
|
+
<h2 class="text-sm font-semibold text-app-warning-100">
|
|
74
77
|
{{ t('layout.aiProvidersBanner.preset.title') }}
|
|
75
78
|
</h2>
|
|
76
79
|
<UButton
|
|
@@ -82,7 +85,7 @@ const show = computed(() => showSetup.value || showPreset.value)
|
|
|
82
85
|
@click="ui.dismissAiPresetMismatch()"
|
|
83
86
|
/>
|
|
84
87
|
</div>
|
|
85
|
-
<p class="mt-1 text-[13px] text-
|
|
88
|
+
<p class="mt-1 text-[13px] text-app-warning-200/90">
|
|
86
89
|
{{ t('layout.aiProvidersBanner.preset.body') }}
|
|
87
90
|
</p>
|
|
88
91
|
<div class="mt-3">
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { DropdownMenuItem } from '@nuxt/ui'
|
|
3
|
+
import { computed, ref } from 'vue'
|
|
4
|
+
import ThemeImportModal from '~/components/theme/ThemeImportModal.vue'
|
|
5
|
+
import { useThemeStore } from '~/stores/theme'
|
|
6
|
+
|
|
7
|
+
// Appearance picker, shown at the sidebar bottom beside the language switcher: colour MODE
|
|
8
|
+
// (system / light / dark) and THEME (the built-ins plus anything the user imported from the Nuxt
|
|
9
|
+
// UI theme editor) in one dropdown, because they are two halves of one question ("what does the
|
|
10
|
+
// app look like") and each on its own would cost a footer row for a control used once.
|
|
11
|
+
//
|
|
12
|
+
// Mode is `@nuxtjs/color-mode`'s preference (its own persisted storage); theme is the theme store.
|
|
13
|
+
// Neither is a deployment setting or an RBAC matter, so the row shows for every tier and role.
|
|
14
|
+
//
|
|
15
|
+
// `collapsed` renders the icon-only rail variant; the dropdown itself is unchanged.
|
|
16
|
+
withDefaults(defineProps<{ collapsed?: boolean }>(), { collapsed: false })
|
|
17
|
+
|
|
18
|
+
const { t } = useI18n()
|
|
19
|
+
const colorMode = useColorMode()
|
|
20
|
+
const theme = useThemeStore()
|
|
21
|
+
const importOpen = ref(false)
|
|
22
|
+
|
|
23
|
+
type ModePreference = 'system' | 'light' | 'dark'
|
|
24
|
+
const MODES: readonly ModePreference[] = ['system', 'light', 'dark']
|
|
25
|
+
// Static literal keys, one per mode, so the typed-message-keys check sees them.
|
|
26
|
+
const MODE_LABELS: Record<ModePreference, string> = {
|
|
27
|
+
system: 'appearance.mode.system',
|
|
28
|
+
light: 'appearance.mode.light',
|
|
29
|
+
dark: 'appearance.mode.dark',
|
|
30
|
+
}
|
|
31
|
+
const MODE_ICONS: Record<ModePreference, string> = {
|
|
32
|
+
system: 'i-lucide-monitor',
|
|
33
|
+
light: 'i-lucide-sun',
|
|
34
|
+
dark: 'i-lucide-moon',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isMode(value: string): value is ModePreference {
|
|
38
|
+
return (MODES as readonly string[]).includes(value)
|
|
39
|
+
}
|
|
40
|
+
const preference = computed<ModePreference>(() =>
|
|
41
|
+
isMode(colorMode.preference) ? colorMode.preference : 'system',
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
const summary = computed(() => `${theme.active.name} · ${t(MODE_LABELS[preference.value])}`)
|
|
45
|
+
|
|
46
|
+
const items = computed<DropdownMenuItem[][]>(() => [
|
|
47
|
+
MODES.map((mode) => ({
|
|
48
|
+
label: t(MODE_LABELS[mode]),
|
|
49
|
+
icon: MODE_ICONS[mode],
|
|
50
|
+
type: 'checkbox' as const,
|
|
51
|
+
checked: preference.value === mode,
|
|
52
|
+
onSelect: () => {
|
|
53
|
+
colorMode.preference = mode
|
|
54
|
+
},
|
|
55
|
+
})),
|
|
56
|
+
[
|
|
57
|
+
{ label: t('appearance.theme.section'), type: 'label' as const },
|
|
58
|
+
...theme.themes.map((candidate) => ({
|
|
59
|
+
label: candidate.name,
|
|
60
|
+
type: 'checkbox' as const,
|
|
61
|
+
checked: theme.current === candidate.id,
|
|
62
|
+
onSelect: () => theme.select(candidate.id),
|
|
63
|
+
})),
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
{
|
|
67
|
+
label: t('appearance.theme.import'),
|
|
68
|
+
icon: 'i-lucide-palette',
|
|
69
|
+
onSelect: () => {
|
|
70
|
+
importOpen.value = true
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
...(theme.isCustom
|
|
74
|
+
? [
|
|
75
|
+
{
|
|
76
|
+
label: t('appearance.theme.remove'),
|
|
77
|
+
icon: 'i-lucide-trash-2',
|
|
78
|
+
color: 'error' as const,
|
|
79
|
+
onSelect: () => theme.removeCustom(theme.current),
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
: []),
|
|
83
|
+
],
|
|
84
|
+
])
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<template>
|
|
88
|
+
<UDropdownMenu :items="items" :content="{ side: 'top', align: 'start' }">
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
data-testid="appearance-switcher"
|
|
92
|
+
:aria-label="t('appearance.switcher')"
|
|
93
|
+
:title="collapsed ? `${t('appearance.switcher')}: ${summary}` : undefined"
|
|
94
|
+
class="flex w-full items-center gap-2 rounded-lg border border-default bg-default/60 p-2 text-start transition hover:bg-elevated/60"
|
|
95
|
+
:class="collapsed ? 'justify-center' : ''"
|
|
96
|
+
>
|
|
97
|
+
<UIcon :name="MODE_ICONS[preference]" class="h-4 w-4 shrink-0 text-muted" />
|
|
98
|
+
<div v-if="!collapsed" class="min-w-0 flex-1">
|
|
99
|
+
<div class="truncate text-[10px] uppercase tracking-wide text-dimmed">
|
|
100
|
+
{{ t('appearance.switcher') }}
|
|
101
|
+
</div>
|
|
102
|
+
<div class="truncate text-xs font-medium text-highlighted">{{ summary }}</div>
|
|
103
|
+
</div>
|
|
104
|
+
<UIcon v-if="!collapsed" name="i-lucide-chevron-up" class="h-4 w-4 shrink-0 text-dimmed" />
|
|
105
|
+
</button>
|
|
106
|
+
</UDropdownMenu>
|
|
107
|
+
<ThemeImportModal v-model:open="importOpen" />
|
|
108
|
+
</template>
|
|
@@ -258,20 +258,17 @@ async function submitPrompt() {
|
|
|
258
258
|
>
|
|
259
259
|
<button
|
|
260
260
|
type="button"
|
|
261
|
-
class="flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-start transition hover:bg-
|
|
261
|
+
class="flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-start transition hover:bg-elevated/60"
|
|
262
262
|
:disabled="busy"
|
|
263
263
|
>
|
|
264
264
|
<UIcon
|
|
265
265
|
:name="accounts.activeAccount?.type === 'org' ? 'i-lucide-users' : 'i-lucide-user'"
|
|
266
|
-
class="h-3.5 w-3.5 shrink-0 text-
|
|
266
|
+
class="h-3.5 w-3.5 shrink-0 text-muted"
|
|
267
267
|
/>
|
|
268
|
-
<span class="truncate text-[11px] font-medium uppercase tracking-wide text-
|
|
268
|
+
<span class="truncate text-[11px] font-medium uppercase tracking-wide text-muted">
|
|
269
269
|
{{ accounts.activeAccount?.name ?? t('layout.boardSwitcher.accountFallback') }}
|
|
270
270
|
</span>
|
|
271
|
-
<UIcon
|
|
272
|
-
name="i-lucide-chevrons-up-down"
|
|
273
|
-
class="ms-auto h-3.5 w-3.5 shrink-0 text-slate-600"
|
|
274
|
-
/>
|
|
271
|
+
<UIcon name="i-lucide-chevrons-up-down" class="ms-auto h-3.5 w-3.5 shrink-0 text-app-600" />
|
|
275
272
|
</button>
|
|
276
273
|
</UDropdownMenu>
|
|
277
274
|
|
|
@@ -284,20 +281,20 @@ async function submitPrompt() {
|
|
|
284
281
|
? (workspace.activeWorkspace?.name ?? t('layout.boardSwitcher.boardFallback'))
|
|
285
282
|
: undefined
|
|
286
283
|
"
|
|
287
|
-
class="flex w-full items-center gap-2 rounded-lg border border-
|
|
284
|
+
class="flex w-full items-center gap-2 rounded-lg border border-default bg-default/60 px-2.5 py-1.5 text-start transition hover:bg-elevated/60"
|
|
288
285
|
:class="collapsed ? 'justify-center' : ''"
|
|
289
286
|
:disabled="busy"
|
|
290
287
|
data-testid="board-switcher"
|
|
291
288
|
:data-board-id="workspace.workspaceId ?? ''"
|
|
292
289
|
>
|
|
293
|
-
<UIcon name="i-lucide-layout-dashboard" class="h-4 w-4 shrink-0 text-
|
|
294
|
-
<span v-if="!collapsed" class="truncate text-sm font-medium text-
|
|
290
|
+
<UIcon name="i-lucide-layout-dashboard" class="h-4 w-4 shrink-0 text-primary" />
|
|
291
|
+
<span v-if="!collapsed" class="truncate text-sm font-medium text-highlighted">
|
|
295
292
|
{{ workspace.activeWorkspace?.name ?? t('layout.boardSwitcher.boardFallback') }}
|
|
296
293
|
</span>
|
|
297
294
|
<UIcon
|
|
298
295
|
v-if="!collapsed"
|
|
299
296
|
name="i-lucide-chevron-down"
|
|
300
|
-
class="ms-auto h-4 w-4 shrink-0 text-
|
|
297
|
+
class="ms-auto h-4 w-4 shrink-0 text-dimmed"
|
|
301
298
|
/>
|
|
302
299
|
</button>
|
|
303
300
|
</UDropdownMenu>
|
|
@@ -132,7 +132,7 @@ const decisionItems = computed(() =>
|
|
|
132
132
|
the board's top overlay region; this renders only the pill and re-enables pointer events
|
|
133
133
|
on it. Self-anchoring here is what let a banner cover the toolbar outright. -->
|
|
134
134
|
<div
|
|
135
|
-
class="pointer-events-auto flex max-w-full items-center gap-1 overflow-x-auto rounded-full border border-
|
|
135
|
+
class="pointer-events-auto flex max-w-full items-center gap-1 overflow-x-auto rounded-full border border-muted bg-default/90 px-2 py-1.5 shadow-xl backdrop-blur"
|
|
136
136
|
>
|
|
137
137
|
<!-- zoom controls -->
|
|
138
138
|
<IconButton
|
|
@@ -153,14 +153,14 @@ const decisionItems = computed(() =>
|
|
|
153
153
|
drops on narrow viewports) so the zoom level is never a mystery. -->
|
|
154
154
|
<button
|
|
155
155
|
type="button"
|
|
156
|
-
class="w-16 rounded text-center text-xs tabular-nums text-
|
|
156
|
+
class="w-16 rounded text-center text-xs tabular-nums text-toned hover:bg-elevated focus-visible:ring-2 focus-visible:ring-app-400/60 sm:w-20"
|
|
157
157
|
:title="t('board.toolbar.resetZoom')"
|
|
158
158
|
:aria-label="t('board.toolbar.resetZoom')"
|
|
159
159
|
data-testid="board-zoom-reset"
|
|
160
160
|
@click="resetZoom()"
|
|
161
161
|
>
|
|
162
162
|
{{ zoomPct }}%
|
|
163
|
-
<span class="hidden text-[9px] uppercase tracking-wide text-
|
|
163
|
+
<span class="hidden text-[9px] uppercase tracking-wide text-dimmed sm:block">{{
|
|
164
164
|
lodLabel
|
|
165
165
|
}}</span>
|
|
166
166
|
</button>
|
|
@@ -256,8 +256,8 @@ function indexOf(cmd: Command) {
|
|
|
256
256
|
<UModal v-model:open="open" :ui="{ content: 'max-w-xl' }">
|
|
257
257
|
<template #content>
|
|
258
258
|
<div class="flex flex-col" data-testid="command-bar" @keydown="onKeydown">
|
|
259
|
-
<div class="flex items-center gap-2 border-b border-
|
|
260
|
-
<UIcon name="i-lucide-search" class="h-4 w-4 shrink-0 text-
|
|
259
|
+
<div class="flex items-center gap-2 border-b border-default px-3">
|
|
260
|
+
<UIcon name="i-lucide-search" class="h-4 w-4 shrink-0 text-dimmed" />
|
|
261
261
|
<UInput
|
|
262
262
|
ref="inputRef"
|
|
263
263
|
v-model="query"
|
|
@@ -271,14 +271,12 @@ function indexOf(cmd: Command) {
|
|
|
271
271
|
</div>
|
|
272
272
|
|
|
273
273
|
<div class="max-h-80 overflow-y-auto p-1.5">
|
|
274
|
-
<p v-if="filtered.length === 0" class="px-3 py-6 text-center text-sm text-
|
|
274
|
+
<p v-if="filtered.length === 0" class="px-3 py-6 text-center text-sm text-dimmed">
|
|
275
275
|
{{ t('layout.commandBar.noMatches') }}
|
|
276
276
|
</p>
|
|
277
277
|
|
|
278
278
|
<div v-for="group in groups" :key="group.name" class="mb-1">
|
|
279
|
-
<p
|
|
280
|
-
class="px-2 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-slate-500"
|
|
281
|
-
>
|
|
279
|
+
<p class="px-2 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-dimmed">
|
|
282
280
|
{{ group.name }}
|
|
283
281
|
</p>
|
|
284
282
|
<button
|
|
@@ -289,13 +287,13 @@ function indexOf(cmd: Command) {
|
|
|
289
287
|
class="flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-start text-sm transition"
|
|
290
288
|
:class="
|
|
291
289
|
indexOf(cmd) === activeIndex
|
|
292
|
-
? 'bg-
|
|
293
|
-
: 'text-
|
|
290
|
+
? 'bg-elevated text-app-100'
|
|
291
|
+
: 'text-toned hover:bg-elevated/60'
|
|
294
292
|
"
|
|
295
293
|
@mousemove="activeIndex = indexOf(cmd)"
|
|
296
294
|
@click="run(cmd)"
|
|
297
295
|
>
|
|
298
|
-
<UIcon :name="cmd.icon" class="h-4 w-4 shrink-0 text-
|
|
296
|
+
<UIcon :name="cmd.icon" class="h-4 w-4 shrink-0 text-muted" />
|
|
299
297
|
<span class="truncate">{{ cmd.label }}</span>
|
|
300
298
|
</button>
|
|
301
299
|
</div>
|
|
@@ -65,7 +65,7 @@ onBeforeUnmount(clearTimer)
|
|
|
65
65
|
<div v-if="reconnecting || offline" class="pointer-events-none flex w-full justify-center">
|
|
66
66
|
<div
|
|
67
67
|
v-if="reconnecting"
|
|
68
|
-
class="pointer-events-auto flex items-center gap-2 rounded-full border border-
|
|
68
|
+
class="pointer-events-auto flex items-center gap-2 rounded-full border border-app-warning-500/60 bg-app-warning-950/90 px-3 py-1.5 text-xs text-app-warning-100 shadow-lg backdrop-blur"
|
|
69
69
|
role="status"
|
|
70
70
|
aria-live="polite"
|
|
71
71
|
data-testid="stream-reconnecting"
|
|
@@ -75,7 +75,7 @@ onBeforeUnmount(clearTimer)
|
|
|
75
75
|
</div>
|
|
76
76
|
<div
|
|
77
77
|
v-else
|
|
78
|
-
class="pointer-events-auto flex items-center gap-2 rounded-full border border-
|
|
78
|
+
class="pointer-events-auto flex items-center gap-2 rounded-full border border-app-error-500/60 bg-app-error-950/90 px-3 py-1.5 text-xs text-app-error-100 shadow-lg backdrop-blur"
|
|
79
79
|
role="status"
|
|
80
80
|
aria-live="polite"
|
|
81
81
|
data-testid="stream-offline"
|
|
@@ -52,16 +52,16 @@ function openConfig(event: MouseEvent) {
|
|
|
52
52
|
<Transition name="fade">
|
|
53
53
|
<div
|
|
54
54
|
v-if="show"
|
|
55
|
-
class="pointer-events-auto w-full max-w-3xl rounded-2xl border border-
|
|
55
|
+
class="pointer-events-auto w-full max-w-3xl rounded-2xl border border-app-info-500/50 bg-app-info-950/90 p-4 shadow-xl backdrop-blur"
|
|
56
56
|
role="status"
|
|
57
57
|
aria-live="polite"
|
|
58
58
|
data-testid="default-test-env-banner"
|
|
59
59
|
>
|
|
60
60
|
<div class="flex items-start gap-3">
|
|
61
|
-
<UIcon name="i-lucide-flask-conical" class="mt-0.5 h-7 w-7 shrink-0 text-
|
|
61
|
+
<UIcon name="i-lucide-flask-conical" class="mt-0.5 h-7 w-7 shrink-0 text-app-info-400" />
|
|
62
62
|
<div class="min-w-0 flex-1">
|
|
63
63
|
<div class="flex items-start justify-between gap-3">
|
|
64
|
-
<h2 class="text-sm font-semibold text-
|
|
64
|
+
<h2 class="text-sm font-semibold text-app-info-100">
|
|
65
65
|
{{ t('layout.defaultTestEnvBanner.title') }}
|
|
66
66
|
</h2>
|
|
67
67
|
<UButton
|
|
@@ -74,7 +74,7 @@ function openConfig(event: MouseEvent) {
|
|
|
74
74
|
@click="ui.dismissDefaultProvision()"
|
|
75
75
|
/>
|
|
76
76
|
</div>
|
|
77
|
-
<p class="mt-1 text-[13px] text-
|
|
77
|
+
<p class="mt-1 text-[13px] text-app-info-200/90">
|
|
78
78
|
{{ t('layout.defaultTestEnvBanner.body') }}
|
|
79
79
|
</p>
|
|
80
80
|
<div class="mt-3 flex flex-wrap items-center gap-x-3 gap-y-2">
|
|
@@ -92,7 +92,7 @@ function openConfig(event: MouseEvent) {
|
|
|
92
92
|
<!-- The URL itself, shown so it can be read and copied, not just clicked. -->
|
|
93
93
|
<a
|
|
94
94
|
:href="configUrl"
|
|
95
|
-
class="min-w-0 truncate font-mono text-[11px] text-
|
|
95
|
+
class="min-w-0 truncate font-mono text-[11px] text-app-info-300/80 underline decoration-dotted underline-offset-2 hover:text-app-info-200"
|
|
96
96
|
data-testid="default-test-env-url"
|
|
97
97
|
@click="openConfig"
|
|
98
98
|
>
|
|
@@ -20,14 +20,14 @@ const show = computed(() => !!setupUrl.value && !dismissed.value)
|
|
|
20
20
|
re-enables pointer events on it. -->
|
|
21
21
|
<div v-if="show" class="pointer-events-auto w-full max-w-3xl">
|
|
22
22
|
<div
|
|
23
|
-
class="w-full max-w-3xl rounded-2xl border-2 border-
|
|
23
|
+
class="w-full max-w-3xl rounded-2xl border-2 border-app-warning-500/70 bg-app-warning-950/95 p-5 shadow-2xl backdrop-blur"
|
|
24
24
|
role="alert"
|
|
25
25
|
>
|
|
26
26
|
<div class="flex items-start gap-4">
|
|
27
|
-
<UIcon name="i-lucide-key-round" class="mt-0.5 h-9 w-9 shrink-0 text-
|
|
27
|
+
<UIcon name="i-lucide-key-round" class="mt-0.5 h-9 w-9 shrink-0 text-app-warning-400" />
|
|
28
28
|
<div class="min-w-0 flex-1">
|
|
29
29
|
<div class="flex items-start justify-between gap-3">
|
|
30
|
-
<h2 class="text-lg font-semibold text-
|
|
30
|
+
<h2 class="text-lg font-semibold text-app-warning-100">
|
|
31
31
|
{{ t('layout.githubPatBanner.title') }}
|
|
32
32
|
</h2>
|
|
33
33
|
<UButton
|
|
@@ -43,7 +43,7 @@ const show = computed(() => !!setupUrl.value && !dismissed.value)
|
|
|
43
43
|
"
|
|
44
44
|
/>
|
|
45
45
|
</div>
|
|
46
|
-
<p class="mt-1 text-sm text-
|
|
46
|
+
<p class="mt-1 text-sm text-app-warning-200/90">
|
|
47
47
|
{{ t('layout.githubPatBanner.body') }}
|
|
48
48
|
</p>
|
|
49
49
|
|
|
@@ -59,7 +59,7 @@ const show = computed(() => !!setupUrl.value && !dismissed.value)
|
|
|
59
59
|
>
|
|
60
60
|
{{ t('layout.githubPatBanner.createToken') }}
|
|
61
61
|
</UButton>
|
|
62
|
-
<p class="mt-2 text-xs text-
|
|
62
|
+
<p class="mt-2 text-xs text-app-warning-300/70">
|
|
63
63
|
<i18n-t keypath="layout.githubPatBanner.thenSet" tag="span" scope="global">
|
|
64
64
|
<template #envVar>
|
|
65
65
|
<code class="font-mono">GITHUB_PAT</code>
|