@cat-factory/app 0.311.2 → 0.312.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 +92 -4
- package/app/app.config.ts +7 -0
- package/app/components/assistant/AssistantModal.vue +2 -5
- package/app/components/auth/AuthGate.vue +2 -1
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +14 -15
- package/app/components/binaryOutput/StoredAssetView.vue +1 -3
- package/app/components/board/AddTaskModal.vue +3 -10
- package/app/components/board/AgentFailureCard.vue +4 -5
- package/app/components/board/AgentStopButton.vue +5 -7
- package/app/components/board/BoardCanvas.vue +31 -30
- package/app/components/board/CreateInitiativeModal.vue +2 -4
- package/app/components/board/RecurringPipelineModal.vue +2 -7
- package/app/components/board/nodes/AgentChip.vue +3 -2
- package/app/components/board/nodes/BlockNode.vue +14 -11
- package/app/components/board/nodes/InitiativeCard.vue +6 -3
- package/app/components/board/nodes/TaskCard.vue +45 -212
- package/app/components/bootstrap/AdoptionReviewModal.vue +2 -5
- package/app/components/bootstrap/BootstrapModal.vue +6 -15
- package/app/components/bootstrap/BootstrapRunSteps.vue +3 -1
- package/app/components/brainstorm/BrainstormWindow.vue +32 -26
- package/app/components/bugFishing/BugFishingWindow.vue +15 -13
- package/app/components/clarity/ClarityReviewWindow.vue +31 -26
- package/app/components/common/ClarificationItem.vue +3 -1
- package/app/components/common/EmptyState.vue +41 -19
- package/app/components/common/InterviewGateNotice.vue +3 -1
- package/app/components/common/Spinner.vue +28 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +5 -5
- package/app/components/docs/DocInterviewWindow.vue +6 -6
- package/app/components/documents/ContextDocumentPicker.vue +2 -2
- package/app/components/documents/DocumentImportModal.vue +9 -8
- package/app/components/documents/DocumentSourceConnectModal.vue +10 -10
- package/app/components/documents/DocumentTemplatesModal.vue +13 -7
- package/app/components/documents/RepoContextDocPicker.vue +2 -2
- package/app/components/documents/SpawnPreviewModal.vue +4 -6
- package/app/components/documents/StartFromDesignModal.vue +2 -1
- package/app/components/documents/TaskContextDocs.vue +4 -5
- package/app/components/environments/EnvironmentStatusPanel.vue +11 -8
- package/app/components/environments/steps/EnvPickStep.vue +7 -3
- package/app/components/environments/steps/EnvPreflightStep.vue +6 -5
- package/app/components/focus/BlockFocusView.vue +6 -5
- package/app/components/followUp/FollowUpWindow.vue +7 -9
- package/app/components/forkDecision/ForkDecisionWindow.vue +9 -8
- package/app/components/foundational/FoundationalServiceCatalogList.vue +9 -5
- package/app/components/foundational/FoundationalServiceRegistry.vue +11 -7
- package/app/components/foundational/FoundationalServiceSources.vue +20 -22
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/foundational/ServiceCatalogConnection.vue +15 -15
- package/app/components/fragments/FragmentLibraryManager.vue +36 -34
- package/app/components/fragments/FragmentSelector.vue +7 -3
- package/app/components/gates/GateResultView.vue +6 -9
- package/app/components/github/AddServiceFromRepoModal.vue +6 -10
- package/app/components/github/GitHubConnect.vue +10 -17
- package/app/components/github/GitHubPanel.vue +44 -47
- package/app/components/github/RepoTreeBrowser.vue +9 -5
- package/app/components/guidedReview/GuidedReviewModal.vue +16 -6
- package/app/components/guidedReview/GuidedReviewOverview.vue +2 -1
- package/app/components/guidedReview/GuidedReviewPicker.vue +10 -7
- package/app/components/guidedReview/GuidedReviewThread.vue +9 -4
- package/app/components/humanTest/HumanTestWindow.vue +2 -1
- package/app/components/initiative/InitiativePlanningWindow.vue +6 -6
- package/app/components/initiative/InitiativeTrackerWindow.vue +11 -11
- package/app/components/judge/JudgeResultView.vue +2 -7
- package/app/components/kaizen/KaizenPanel.vue +20 -5
- package/app/components/kaizen/KaizenStepStatus.vue +2 -1
- package/app/components/layout/AccountAuditLog.vue +11 -3
- package/app/components/layout/AccountDeploymentSettings.vue +17 -62
- package/app/components/layout/AccountFailureKindRules.vue +6 -5
- package/app/components/layout/AccountModelPolicySettings.vue +2 -6
- package/app/components/layout/AccountPlatformAlertSettings.vue +5 -13
- package/app/components/layout/AccountRiskPolicySettings.vue +13 -14
- package/app/components/layout/AccountRunCredentialSettings.vue +2 -2
- package/app/components/layout/AccountTeamSettings.vue +12 -9
- package/app/components/layout/BoardSwitcher.vue +2 -2
- package/app/components/layout/BoardToolbar.vue +27 -37
- package/app/components/layout/BoardTopOverlays.vue +8 -2
- package/app/components/layout/CommandBar.vue +7 -3
- package/app/components/layout/ConnectionStatusBanner.vue +2 -1
- package/app/components/layout/IntegrationsHub.vue +7 -3
- package/app/components/layout/ModelProvidersHub.vue +7 -3
- package/app/components/layout/NotificationsInbox.vue +3 -11
- package/app/components/layout/SideBar.vue +5 -0
- package/app/components/layout/WorkViewSwitcher.vue +64 -0
- package/app/components/layout/WorkspaceMembersSettings.vue +12 -5
- package/app/components/media/ArtifactLightbox.vue +4 -3
- package/app/components/notifications/NotificationSettingsPanel.vue +4 -11
- package/app/components/observability/ToolCallList.vue +12 -17
- package/app/components/panels/AgentStepDetail.vue +5 -5
- package/app/components/panels/GenericStructuredResultView.vue +6 -9
- package/app/components/panels/InspectorPanel.vue +2 -1
- package/app/components/panels/MergerResultView.vue +5 -6
- package/app/components/panels/ObservabilityPanel.vue +26 -41
- package/app/components/panels/OperatorDashboardPanel.vue +29 -17
- package/app/components/panels/ReportsPanel.vue +17 -11
- package/app/components/panels/ReportsSpendBreakdown.vue +7 -3
- package/app/components/panels/RunDetailLoadState.vue +4 -3
- package/app/components/panels/StepContainerStatus.vue +4 -3
- package/app/components/panels/StepDelegatedStatus.vue +3 -2
- package/app/components/panels/StepMetadataCard.vue +6 -8
- package/app/components/panels/StepRunMeta.vue +2 -5
- package/app/components/panels/inspector/ContainerSummary.vue +7 -1
- package/app/components/panels/inspector/EpicChildren.vue +7 -3
- package/app/components/panels/inspector/FrontendConfig.vue +7 -3
- package/app/components/panels/inspector/InitiativeInspector.vue +5 -2
- package/app/components/panels/inspector/ServiceConnections.vue +7 -3
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -6
- package/app/components/panels/inspector/ServiceTestSecrets.vue +2 -6
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -6
- package/app/components/panels/inspector/ServiceValidationConfig.vue +38 -39
- package/app/components/panels/inspector/TaskExecution.vue +5 -6
- package/app/components/panels/inspector/TaskRunSettings.vue +7 -3
- package/app/components/panels/inspector/TaskStructure.vue +0 -1
- package/app/components/pipeline/AgentPromptEditor.vue +25 -18
- package/app/components/pipeline/PipelineBuilder.vue +14 -24
- package/app/components/pipeline/PipelineProgress.vue +16 -17
- package/app/components/prReview/PrReviewPhaseBadge.vue +3 -2
- package/app/components/prReview/PrReviewWindow.vue +16 -20
- package/app/components/providers/ApiKeysSection.vue +2 -6
- package/app/components/providers/PersonalCredentialModal.vue +2 -6
- package/app/components/providers/PersonalSubscriptionSection.vue +3 -7
- package/app/components/providers/VendorCredentialsModal.vue +2 -6
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -6
- package/app/components/queue/QueueCard.vue +269 -0
- package/app/components/queue/QueueView.vue +192 -0
- package/app/components/ralph/RalphLoopResultView.vue +2 -7
- package/app/components/requirements/RequirementsReviewWindow.vue +44 -39
- package/app/components/sandbox/SandboxPanel.vue +37 -25
- package/app/components/settings/AccountSettingsPanel.vue +6 -3
- package/app/components/settings/ApiTokensPanel.vue +2 -6
- package/app/components/settings/BudgetSettings.vue +2 -2
- package/app/components/settings/CapabilityCredentialsPanel.vue +2 -6
- package/app/components/settings/CloudflareHandlerSection.vue +3 -7
- package/app/components/settings/ConsensusGroupsSection.vue +7 -3
- package/app/components/settings/CustomManifestTypeEditor.vue +7 -3
- package/app/components/settings/DefaultProvisionTypeSection.vue +2 -2
- package/app/components/settings/InfraHandlersConfigurator.vue +8 -11
- package/app/components/settings/IssueTrackerPanel.vue +9 -9
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -6
- package/app/components/settings/LocalModelEndpointsPanel.vue +5 -7
- package/app/components/settings/McpAuthorizeScreen.vue +8 -3
- package/app/components/settings/McpOAuthCallbackScreen.vue +2 -1
- package/app/components/settings/ModelConfigurationPanel.vue +45 -17
- package/app/components/settings/ObservabilityConnectionPanel.vue +4 -15
- package/app/components/settings/OpenRouterCatalogPanel.vue +8 -24
- package/app/components/settings/PackageRegistriesPanel.vue +2 -6
- package/app/components/settings/ProviderConnectionTab.vue +3 -7
- package/app/components/settings/RiskPolicyPanel.vue +4 -16
- package/app/components/settings/SharedStacksPanel.vue +8 -18
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +10 -6
- package/app/components/settings/UsageSettings.vue +11 -2
- package/app/components/settings/UserSecretsSection.vue +5 -7
- package/app/components/settings/WorkspaceMetadataSettings.vue +9 -9
- package/app/components/settings/WorkspaceSettingsPanel.vue +3 -11
- package/app/components/skills/ReviewSkillQueue.vue +7 -3
- package/app/components/skills/SkillLibraryManager.vue +20 -18
- package/app/components/slack/SlackPanel.vue +5 -8
- package/app/components/spec/ServiceSpecWindow.vue +32 -29
- package/app/components/tasks/BugHuntModal.vue +23 -19
- package/app/components/tasks/ContextIssuePicker.vue +2 -2
- package/app/components/tasks/TaskContextIssues.vue +4 -5
- package/app/components/tasks/TaskImportModal.vue +10 -8
- package/app/components/tasks/TaskSourceConnectModal.vue +11 -11
- package/app/components/testing/TestReportWindow.vue +6 -12
- package/app/components/tutorial/TutorialCatalogue.vue +7 -3
- package/app/components/tutorial/TutorialOverlay.vue +2 -1
- package/app/components/tutorial/TutorialPrompt.vue +7 -3
- package/app/components/vcs/GitLabConnect.vue +2 -6
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +9 -4
- package/app/composables/toastTitleKeys.spec.ts +143 -0
- package/app/composables/useActionToast.spec.ts +71 -0
- package/app/composables/useActionToast.ts +101 -0
- package/app/composables/useBlockDeletion.ts +3 -6
- package/app/composables/useConfirmAction.ts +5 -3
- package/app/composables/useContextLinking.spec.ts +3 -0
- package/app/composables/useContextLinking.ts +11 -16
- package/app/composables/useCopyToClipboard.ts +4 -3
- package/app/composables/useFrameLanes.ts +6 -82
- package/app/composables/useNavContributions.ts +6 -5
- package/app/composables/usePipelineErrorToast.spec.ts +24 -0
- package/app/composables/usePipelineErrorToast.ts +26 -2
- package/app/composables/usePipelineLibraryActions.ts +8 -9
- package/app/composables/useTaskActions.ts +254 -0
- package/app/composables/useTaskLaneClassifier.ts +88 -0
- package/app/modular/nav-contributions.spec.ts +4 -0
- package/app/modular/nav-contributions.ts +31 -0
- package/app/modular/tutorial-tours.ts +10 -0
- package/app/pages/index.vue +42 -8
- package/app/stores/board/context.ts +4 -3
- package/app/stores/board/placement.ts +8 -20
- package/app/stores/board/removal.ts +4 -13
- package/app/stores/board.spec.ts +10 -1
- package/app/stores/board.ts +3 -2
- package/app/stores/workView.ts +51 -0
- package/app/stores/workspaceQueue.ts +148 -0
- package/app/utils/bootstrapSteps.ts +11 -2
- package/app/utils/pipelineRender.ts +21 -8
- package/app/utils/queueSections.spec.ts +111 -0
- package/app/utils/queueSections.ts +117 -0
- package/app/utils/workView.spec.ts +16 -0
- package/app/utils/workView.ts +25 -0
- package/i18n/locales/de.json +73 -32
- package/i18n/locales/en.json +73 -32
- package/i18n/locales/es.json +73 -32
- package/i18n/locales/fr.json +73 -32
- package/i18n/locales/he.json +73 -32
- package/i18n/locales/it.json +73 -32
- package/i18n/locales/ja.json +73 -32
- package/i18n/locales/pl.json +73 -32
- package/i18n/locales/tr.json +73 -32
- package/i18n/locales/uk.json +73 -32
- package/package.json +1 -1
|
@@ -18,10 +18,11 @@ import type {
|
|
|
18
18
|
} from '~/types/sandbox'
|
|
19
19
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
20
20
|
import IconButton from '~/components/common/IconButton.vue'
|
|
21
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
21
22
|
|
|
22
23
|
const ui = useUiStore()
|
|
23
24
|
const store = useSandboxStore()
|
|
24
|
-
const
|
|
25
|
+
const actionToast = useActionToast()
|
|
25
26
|
const { present } = usePipelineErrorToast()
|
|
26
27
|
const { t } = useI18n()
|
|
27
28
|
|
|
@@ -82,13 +83,9 @@ async function promote(version: SandboxPromptVersion) {
|
|
|
82
83
|
promoting.value = version.id
|
|
83
84
|
try {
|
|
84
85
|
await store.promotePrompt(version)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
icon: 'i-lucide-rocket',
|
|
89
|
-
})
|
|
90
|
-
} catch {
|
|
91
|
-
toast.add({ title: t('sandbox.prompts.promoteFailed'), color: 'error' })
|
|
86
|
+
actionToast.success('sandbox.prompts.promoted', { params: { agent: version.agentKind } })
|
|
87
|
+
} catch (error) {
|
|
88
|
+
present(error, 'sandbox.prompts.promoteFailed')
|
|
92
89
|
} finally {
|
|
93
90
|
promoting.value = null
|
|
94
91
|
}
|
|
@@ -193,9 +190,9 @@ async function createAndRun() {
|
|
|
193
190
|
},
|
|
194
191
|
})
|
|
195
192
|
name.value = ''
|
|
196
|
-
|
|
193
|
+
actionToast.info('sandbox.toast.running')
|
|
197
194
|
await store.launch(created.id)
|
|
198
|
-
|
|
195
|
+
actionToast.success('sandbox.toast.complete')
|
|
199
196
|
} catch (e) {
|
|
200
197
|
present(e, 'sandbox.toast.runFailed')
|
|
201
198
|
}
|
|
@@ -255,7 +252,7 @@ async function saveVersion() {
|
|
|
255
252
|
savingPrompt.value = true
|
|
256
253
|
try {
|
|
257
254
|
await store.saveVersion(editing.value.id, editText.value)
|
|
258
|
-
|
|
255
|
+
actionToast.success('sandbox.toast.versionSaved')
|
|
259
256
|
editing.value = null
|
|
260
257
|
} catch (e) {
|
|
261
258
|
present(e, 'sandbox.toast.saveFailed')
|
|
@@ -282,8 +279,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
282
279
|
:ui="{ content: 'max-w-5xl' }"
|
|
283
280
|
>
|
|
284
281
|
<template #body>
|
|
285
|
-
<div v-if="store.loading" class="
|
|
286
|
-
<
|
|
282
|
+
<div v-if="store.loading" class="space-y-4">
|
|
283
|
+
<USkeleton class="h-8 w-full" />
|
|
284
|
+
<div class="grid gap-4 lg:grid-cols-2">
|
|
285
|
+
<USkeleton class="h-80 w-full rounded-lg" />
|
|
286
|
+
<USkeleton class="h-80 w-full rounded-lg" />
|
|
287
|
+
</div>
|
|
287
288
|
</div>
|
|
288
289
|
|
|
289
290
|
<div
|
|
@@ -405,9 +406,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
405
406
|
/>
|
|
406
407
|
<span class="truncate">{{ m.label }}</span>
|
|
407
408
|
</label>
|
|
408
|
-
<
|
|
409
|
-
|
|
410
|
-
|
|
409
|
+
<EmptyState
|
|
410
|
+
v-if="!store.selectableModels.length"
|
|
411
|
+
compact
|
|
412
|
+
icon="i-lucide-cpu"
|
|
413
|
+
:title="t('sandbox.builder.noModels')"
|
|
414
|
+
/>
|
|
411
415
|
</div>
|
|
412
416
|
</div>
|
|
413
417
|
|
|
@@ -429,9 +433,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
429
433
|
/>
|
|
430
434
|
<span class="truncate">{{ f.name }}</span>
|
|
431
435
|
</label>
|
|
432
|
-
<
|
|
433
|
-
|
|
434
|
-
|
|
436
|
+
<EmptyState
|
|
437
|
+
v-if="!kindFixtures.length"
|
|
438
|
+
compact
|
|
439
|
+
icon="i-lucide-clipboard-list"
|
|
440
|
+
:title="t('sandbox.builder.noFixtures')"
|
|
441
|
+
/>
|
|
435
442
|
</div>
|
|
436
443
|
</div>
|
|
437
444
|
|
|
@@ -577,9 +584,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
577
584
|
<span class="truncate text-toned">{{ x.name }}</span>
|
|
578
585
|
<UBadge variant="soft" size="xs">{{ EXPERIMENT_STATUS_LABEL[x.status] }}</UBadge>
|
|
579
586
|
</UButton>
|
|
580
|
-
<
|
|
581
|
-
|
|
582
|
-
|
|
587
|
+
<EmptyState
|
|
588
|
+
v-if="!store.experiments.length"
|
|
589
|
+
compact
|
|
590
|
+
icon="i-lucide-flask-conical"
|
|
591
|
+
:title="t('sandbox.results.empty')"
|
|
592
|
+
/>
|
|
583
593
|
</div>
|
|
584
594
|
</div>
|
|
585
595
|
</div>
|
|
@@ -718,9 +728,11 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
718
728
|
}}
|
|
719
729
|
</p>
|
|
720
730
|
</div>
|
|
721
|
-
<
|
|
722
|
-
|
|
723
|
-
|
|
731
|
+
<EmptyState
|
|
732
|
+
v-if="!store.fixtures.length"
|
|
733
|
+
icon="i-lucide-clipboard-list"
|
|
734
|
+
:title="t('sandbox.fixtures.empty')"
|
|
735
|
+
/>
|
|
724
736
|
</div>
|
|
725
737
|
</div>
|
|
726
738
|
</template>
|
|
@@ -11,6 +11,7 @@ import AccountFragmentSettings from '~/components/layout/AccountFragmentSettings
|
|
|
11
11
|
import AccountSkillSettings from '~/components/layout/AccountSkillSettings.vue'
|
|
12
12
|
import AccountFoundationalSettings from '~/components/layout/AccountFoundationalSettings.vue'
|
|
13
13
|
import AccountRiskPolicySettings from '~/components/layout/AccountRiskPolicySettings.vue'
|
|
14
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
14
15
|
|
|
15
16
|
const { t } = useI18n()
|
|
16
17
|
const ui = useUiStore()
|
|
@@ -60,9 +61,11 @@ const tabs = computed(() => [
|
|
|
60
61
|
<template>
|
|
61
62
|
<UModal v-model:open="open" :title="t('settings.account.title')" :ui="{ content: 'max-w-3xl' }">
|
|
62
63
|
<template #body>
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
<EmptyState
|
|
65
|
+
v-if="!accounts.activeAccountId"
|
|
66
|
+
icon="i-lucide-building-2"
|
|
67
|
+
:title="t('settings.account.noAccount')"
|
|
68
|
+
/>
|
|
66
69
|
<UTabs
|
|
67
70
|
v-else
|
|
68
71
|
v-model="activeTab"
|
|
@@ -74,7 +74,7 @@ function boundLabel(key: PublicApiKey): string | null {
|
|
|
74
74
|
? t('settings.apiTokens.list.boundToYou')
|
|
75
75
|
: t('settings.apiTokens.list.boundToOther', { user: key.actsAsUserId })
|
|
76
76
|
}
|
|
77
|
-
const
|
|
77
|
+
const actionToast = useActionToast()
|
|
78
78
|
const { present } = usePipelineErrorToast()
|
|
79
79
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
80
80
|
|
|
@@ -152,11 +152,7 @@ async function createToken() {
|
|
|
152
152
|
label.value = ''
|
|
153
153
|
scope.value = 'write'
|
|
154
154
|
identity.value = 'system'
|
|
155
|
-
toast.
|
|
156
|
-
title: t('settings.apiTokens.toast.created'),
|
|
157
|
-
icon: 'i-lucide-check',
|
|
158
|
-
color: 'success',
|
|
159
|
-
})
|
|
155
|
+
actionToast.success('settings.apiTokens.toast.created')
|
|
160
156
|
} catch (e) {
|
|
161
157
|
present(e, 'settings.apiTokens.toast.createFailed')
|
|
162
158
|
} finally {
|
|
@@ -8,7 +8,7 @@ import { computed, reactive, ref, watch, type Ref } from 'vue'
|
|
|
8
8
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
9
9
|
|
|
10
10
|
const { t, n } = useI18n()
|
|
11
|
-
const
|
|
11
|
+
const actionToast = useActionToast()
|
|
12
12
|
const { present } = usePipelineErrorToast()
|
|
13
13
|
|
|
14
14
|
const settingsStore = useWorkspaceSettingsStore()
|
|
@@ -32,7 +32,7 @@ async function runSave(saving: Ref<boolean>, save: () => Promise<unknown>) {
|
|
|
32
32
|
saving.value = true
|
|
33
33
|
try {
|
|
34
34
|
await save()
|
|
35
|
-
|
|
35
|
+
actionToast.success('settings.workspaceSettings.toast.budgetSaved')
|
|
36
36
|
try {
|
|
37
37
|
await useWorkspaceStore().refresh()
|
|
38
38
|
} catch {
|
|
@@ -20,7 +20,7 @@ import ToolServerChecklist from '~/components/settings/ToolServerChecklist.vue'
|
|
|
20
20
|
|
|
21
21
|
const { t, d } = useI18n()
|
|
22
22
|
const store = useCapabilityCredentialsStore()
|
|
23
|
-
const
|
|
23
|
+
const actionToast = useActionToast()
|
|
24
24
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
25
25
|
|
|
26
26
|
// Which declaring capability wants a key. An exhaustive Record over the wire union, so a new
|
|
@@ -85,11 +85,7 @@ async function saveKey(key: string) {
|
|
|
85
85
|
try {
|
|
86
86
|
await store.save(key, value)
|
|
87
87
|
drafts[key] = ''
|
|
88
|
-
toast.
|
|
89
|
-
title: t('settings.capabilityCredentials.toast.saved', { key }),
|
|
90
|
-
icon: 'i-lucide-check',
|
|
91
|
-
color: 'success',
|
|
92
|
-
})
|
|
88
|
+
actionToast.success('settings.capabilityCredentials.toast.saved', { params: { key } })
|
|
93
89
|
} catch (e) {
|
|
94
90
|
present(e, 'settings.capabilityCredentials.toast.saveFailed')
|
|
95
91
|
} finally {
|
|
@@ -18,7 +18,7 @@ type CloudflareConfig = CloudflareHandlerConfig['cloudflare']
|
|
|
18
18
|
|
|
19
19
|
const { t } = useI18n()
|
|
20
20
|
const infra = useInfraConfigStore()
|
|
21
|
-
const
|
|
21
|
+
const actionToast = useActionToast()
|
|
22
22
|
const { present } = usePipelineErrorToast()
|
|
23
23
|
const { confirmAction } = useConfirmAction()
|
|
24
24
|
|
|
@@ -101,11 +101,7 @@ async function save() {
|
|
|
101
101
|
})
|
|
102
102
|
token.value = ''
|
|
103
103
|
editing.value = false
|
|
104
|
-
|
|
105
|
-
title: t('settings.infrastructure.handler.saved'),
|
|
106
|
-
icon: 'i-lucide-check',
|
|
107
|
-
color: 'success',
|
|
108
|
-
})
|
|
104
|
+
actionToast.success('settings.infrastructure.handler.saved')
|
|
109
105
|
} catch (e) {
|
|
110
106
|
present(e, 'settings.infrastructure.handler.saveFailed')
|
|
111
107
|
} finally {
|
|
@@ -133,7 +129,7 @@ async function remove() {
|
|
|
133
129
|
busy.value = true
|
|
134
130
|
try {
|
|
135
131
|
await infra.unregisterHandler('cloudflare')
|
|
136
|
-
|
|
132
|
+
actionToast.success('settings.infrastructure.handler.removed')
|
|
137
133
|
} catch (e) {
|
|
138
134
|
present(e, 'settings.infrastructure.handler.saveFailed')
|
|
139
135
|
} finally {
|
|
@@ -15,6 +15,7 @@ import { isSelectable } from '~/stores/models'
|
|
|
15
15
|
import { uid } from '~/utils/catalog'
|
|
16
16
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
17
17
|
import IconButton from '~/components/common/IconButton.vue'
|
|
18
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
18
19
|
|
|
19
20
|
const { t } = useI18n()
|
|
20
21
|
const groups = useConsensusGroupsStore()
|
|
@@ -291,9 +292,12 @@ async function remove(group: ConsensusGroup) {
|
|
|
291
292
|
</div>
|
|
292
293
|
</div>
|
|
293
294
|
</div>
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
<EmptyState
|
|
296
|
+
v-else
|
|
297
|
+
compact
|
|
298
|
+
icon="i-lucide-users"
|
|
299
|
+
:title="t('settings.consensusGroups.list.empty')"
|
|
300
|
+
/>
|
|
297
301
|
</template>
|
|
298
302
|
|
|
299
303
|
<!-- ===== editor ===== -->
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { computed, reactive, ref } from 'vue'
|
|
8
8
|
import type { CustomManifestType } from '@cat-factory/contracts'
|
|
9
9
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
10
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
10
11
|
|
|
11
12
|
const { t } = useI18n()
|
|
12
13
|
const infra = useInfraConfigStore()
|
|
@@ -140,9 +141,12 @@ async function remove(type: CustomManifestType) {
|
|
|
140
141
|
</div>
|
|
141
142
|
</li>
|
|
142
143
|
</ul>
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
<EmptyState
|
|
145
|
+
v-else
|
|
146
|
+
compact
|
|
147
|
+
icon="i-lucide-boxes"
|
|
148
|
+
:title="t('settings.infrastructure.customType.empty')"
|
|
149
|
+
/>
|
|
146
150
|
|
|
147
151
|
<!-- Add / edit a workspace-defined type. -->
|
|
148
152
|
<div class="space-y-2 border-t border-default pt-3">
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
const { t } = useI18n()
|
|
25
25
|
const infra = useInfraConfigStore()
|
|
26
26
|
const settingsStore = useWorkspaceSettingsStore()
|
|
27
|
-
const
|
|
27
|
+
const actionToast = useActionToast()
|
|
28
28
|
const { present } = usePipelineErrorToast()
|
|
29
29
|
|
|
30
30
|
onMounted(() => {
|
|
@@ -90,7 +90,7 @@ async function save() {
|
|
|
90
90
|
defaultProvisionType: selection.value.type,
|
|
91
91
|
defaultProvisionManifestId: selection.value.manifestId,
|
|
92
92
|
})
|
|
93
|
-
|
|
93
|
+
actionToast.success('settings.defaultProvision.saved')
|
|
94
94
|
} catch (e) {
|
|
95
95
|
present(e, 'settings.defaultProvision.saveFailed')
|
|
96
96
|
} finally {
|
|
@@ -36,7 +36,7 @@ const { t } = useI18n()
|
|
|
36
36
|
const infra = useInfraConfigStore()
|
|
37
37
|
const auth = useAuthStore()
|
|
38
38
|
const ui = useUiStore()
|
|
39
|
-
const
|
|
39
|
+
const actionToast = useActionToast()
|
|
40
40
|
const { present } = usePipelineErrorToast()
|
|
41
41
|
const { confirmAction } = useConfirmAction()
|
|
42
42
|
|
|
@@ -403,20 +403,16 @@ async function removeCustom() {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
function toastSaved() {
|
|
406
|
-
|
|
407
|
-
title: t('settings.infrastructure.handler.saved'),
|
|
408
|
-
icon: 'i-lucide-check',
|
|
409
|
-
color: 'success',
|
|
410
|
-
})
|
|
406
|
+
actionToast.success('settings.infrastructure.handler.saved')
|
|
411
407
|
}
|
|
412
408
|
function toastRemoved() {
|
|
413
|
-
|
|
409
|
+
actionToast.success('settings.infrastructure.handler.removed')
|
|
414
410
|
}
|
|
415
411
|
</script>
|
|
416
412
|
|
|
417
413
|
<template>
|
|
418
414
|
<!-- Only render the configurator once the handler bundle has actually resolved (available
|
|
419
|
-
=== true). While it's still being probed (null) show
|
|
415
|
+
=== true). While it's still being probed (null) show skeleton sections instead of flashing
|
|
420
416
|
the full form, and render nothing when the integration is off (false). -->
|
|
421
417
|
<div v-if="infra.available === true" class="space-y-5">
|
|
422
418
|
<p class="text-xs text-muted">{{ t('settings.infrastructure.handler.intro') }}</p>
|
|
@@ -629,7 +625,8 @@ function toastRemoved() {
|
|
|
629
625
|
</div>
|
|
630
626
|
</section>
|
|
631
627
|
</div>
|
|
632
|
-
<
|
|
633
|
-
|
|
634
|
-
|
|
628
|
+
<div v-else-if="infra.available === null" class="space-y-5">
|
|
629
|
+
<USkeleton class="h-4 w-2/3" />
|
|
630
|
+
<USkeleton v-for="n in 3" :key="n" class="h-24 w-full rounded-lg" />
|
|
631
|
+
</div>
|
|
635
632
|
</template>
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
18
18
|
import type { TaskSourceKind, TaskSourceState, TrackerKind } from '~/types/domain'
|
|
19
19
|
import TaskSourceCard from '~/components/settings/TaskSourceCard.vue'
|
|
20
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
20
21
|
|
|
21
22
|
const { t } = useI18n()
|
|
22
23
|
const tracker = useTrackerStore()
|
|
23
24
|
const tasks = useTasksStore()
|
|
24
25
|
const ui = useUiStore()
|
|
25
|
-
const
|
|
26
|
+
const actionToast = useActionToast()
|
|
26
27
|
const { present } = usePipelineErrorToast()
|
|
27
28
|
|
|
28
29
|
// --- filing tracker + writeback (one Save, persisted on tracker settings) -----
|
|
@@ -114,11 +115,7 @@ async function save() {
|
|
|
114
115
|
writebackResolveOnMerge: resolveOnMerge.value,
|
|
115
116
|
writebackQuestionsOnPark: questionsOnPark.value,
|
|
116
117
|
})
|
|
117
|
-
toast.
|
|
118
|
-
title: t('settings.issueTracker.toast.saved'),
|
|
119
|
-
icon: 'i-lucide-check',
|
|
120
|
-
color: 'success',
|
|
121
|
-
})
|
|
118
|
+
actionToast.success('settings.issueTracker.toast.saved')
|
|
122
119
|
} catch (e) {
|
|
123
120
|
present(e, 'settings.issueTracker.toast.saveFailed')
|
|
124
121
|
} finally {
|
|
@@ -379,9 +376,12 @@ async function checkSetup(source: TaskSourceKind) {
|
|
|
379
376
|
@remedy="openRemedy(source)"
|
|
380
377
|
/>
|
|
381
378
|
|
|
382
|
-
<
|
|
383
|
-
|
|
384
|
-
|
|
379
|
+
<EmptyState
|
|
380
|
+
v-if="tasks.sources.length === 0"
|
|
381
|
+
compact
|
|
382
|
+
icon="i-lucide-list-todo"
|
|
383
|
+
:title="t('settings.issueTracker.linking.none')"
|
|
384
|
+
/>
|
|
385
385
|
</section>
|
|
386
386
|
|
|
387
387
|
<!-- 3. Writeback ---------------------------------------------------------->
|
|
@@ -13,7 +13,7 @@ import { reactive, ref, watch } from 'vue'
|
|
|
13
13
|
|
|
14
14
|
const { t } = useI18n()
|
|
15
15
|
const store = useLocalSettingsStore()
|
|
16
|
-
const
|
|
16
|
+
const actionToast = useActionToast()
|
|
17
17
|
const { present } = usePipelineErrorToast()
|
|
18
18
|
|
|
19
19
|
const saving = ref(false)
|
|
@@ -60,11 +60,7 @@ async function save() {
|
|
|
60
60
|
},
|
|
61
61
|
checkout: { workspaceRoot: draft.workspaceRoot.trim() || '/workspace', cleanKeep },
|
|
62
62
|
})
|
|
63
|
-
toast.
|
|
64
|
-
title: t('settings.localMode.toast.saved'),
|
|
65
|
-
icon: 'i-lucide-check',
|
|
66
|
-
color: 'success',
|
|
67
|
-
})
|
|
63
|
+
actionToast.success('settings.localMode.toast.saved')
|
|
68
64
|
} catch (e) {
|
|
69
65
|
present(e, 'settings.localMode.toast.saveFailed')
|
|
70
66
|
} finally {
|
|
@@ -23,7 +23,7 @@ import IconButton from '~/components/common/IconButton.vue'
|
|
|
23
23
|
const { t } = useI18n()
|
|
24
24
|
const ui = useUiStore()
|
|
25
25
|
const store = useLocalModelsStore()
|
|
26
|
-
const
|
|
26
|
+
const actionToast = useActionToast()
|
|
27
27
|
const { present } = usePipelineErrorToast()
|
|
28
28
|
const { confirm } = useConfirm()
|
|
29
29
|
|
|
@@ -230,12 +230,10 @@ async function save() {
|
|
|
230
230
|
models: selected.value.map((id) => ({ id, ...modalityOf(imageInput.value[id]) })),
|
|
231
231
|
})
|
|
232
232
|
apiKey.value = ''
|
|
233
|
-
toast.
|
|
234
|
-
|
|
233
|
+
actionToast.success('settings.localModelEndpoints.toast.saved', {
|
|
234
|
+
params: {
|
|
235
235
|
name: LOCAL_RUNNER_LABELS[provider.value],
|
|
236
|
-
}
|
|
237
|
-
icon: 'i-lucide-check',
|
|
238
|
-
color: 'success',
|
|
236
|
+
},
|
|
239
237
|
})
|
|
240
238
|
} catch (e) {
|
|
241
239
|
present(e, 'settings.localModelEndpoints.toast.saveFailed')
|
|
@@ -261,7 +259,7 @@ async function remove(p: LocalRunner) {
|
|
|
261
259
|
// The row is gone from the store, so re-seeding the draft it was showing yields the
|
|
262
260
|
// fresh-runner defaults: the same reset, without a second copy of what a reset means.
|
|
263
261
|
if (provider.value === p) seedDraft(p)
|
|
264
|
-
|
|
262
|
+
actionToast.success('settings.localModelEndpoints.toast.removed')
|
|
265
263
|
} catch (e) {
|
|
266
264
|
present(e, 'settings.localModelEndpoints.toast.removeFailed')
|
|
267
265
|
} finally {
|
|
@@ -145,9 +145,14 @@ function backToApp() {
|
|
|
145
145
|
data-testid="mcp-authorize"
|
|
146
146
|
>
|
|
147
147
|
<div class="w-full max-w-md rounded-xl border border-default bg-default/80 p-8 backdrop-blur">
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
|
|
148
|
+
<div v-if="screen === 'loading'" class="flex flex-col items-center">
|
|
149
|
+
<USkeleton class="mb-3 h-10 w-10 rounded-full" />
|
|
150
|
+
<USkeleton class="mb-2 h-6 w-3/4" />
|
|
151
|
+
<USkeleton class="mb-6 h-4 w-full" />
|
|
152
|
+
<USkeleton class="mb-4 h-8 w-full" />
|
|
153
|
+
<USkeleton class="mb-6 h-16 w-full" />
|
|
154
|
+
<USkeleton class="h-8 w-full" />
|
|
155
|
+
</div>
|
|
151
156
|
|
|
152
157
|
<template v-else-if="screen === 'failed'">
|
|
153
158
|
<UIcon name="i-lucide-alert-triangle" class="mx-auto mb-3 h-10 w-10 text-app-error-400" />
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { onMounted, ref } from 'vue'
|
|
3
|
+
import Spinner from '~/components/common/Spinner.vue'
|
|
3
4
|
|
|
4
5
|
// Where a vendor's authorization server sends the operator's browser back to after they approve a
|
|
5
6
|
// remote MCP tool server (`/mcp-oauth-callback?code=…&state=…`).
|
|
@@ -69,7 +70,7 @@ function backToApp() {
|
|
|
69
70
|
class="w-full max-w-sm rounded-xl border border-default bg-default/80 p-8 text-center backdrop-blur"
|
|
70
71
|
>
|
|
71
72
|
<template v-if="state === 'working'">
|
|
72
|
-
<
|
|
73
|
+
<Spinner class="mx-auto mb-3 h-10 w-10 text-primary" />
|
|
73
74
|
<h1 class="mb-1 text-lg font-semibold text-highlighted">
|
|
74
75
|
{{ t('settings.toolServers.oauth.callback.working') }}
|
|
75
76
|
</h1>
|
|
@@ -24,6 +24,7 @@ import ProviderPreferenceEditor from '~/components/settings/ProviderPreferenceEd
|
|
|
24
24
|
import { showOverrideField } from '~/utils/uiMode'
|
|
25
25
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
26
26
|
import IconButton from '~/components/common/IconButton.vue'
|
|
27
|
+
import EmptyState from '~/components/common/EmptyState.vue'
|
|
27
28
|
import { FULL_BLEED_TAKEOVER_CLASS } from '~/utils/safeArea'
|
|
28
29
|
|
|
29
30
|
const { t } = useI18n()
|
|
@@ -36,7 +37,7 @@ const agentTier = useAgentTierStore()
|
|
|
36
37
|
const creds = useVendorCredentialsStore()
|
|
37
38
|
const workspace = useWorkspaceStore()
|
|
38
39
|
const { present } = usePipelineErrorToast()
|
|
39
|
-
const
|
|
40
|
+
const actionToast = useActionToast()
|
|
40
41
|
const { confirm } = useConfirm()
|
|
41
42
|
|
|
42
43
|
const open = computed({
|
|
@@ -93,13 +94,25 @@ const hiddenByTier = computed(() =>
|
|
|
93
94
|
filter.value.trim() ? 0 : configurableKinds.value.length - tieredKinds.value.length,
|
|
94
95
|
)
|
|
95
96
|
|
|
97
|
+
// Set when the catalog read rejects, so the preset list states the failure instead of holding a
|
|
98
|
+
// skeleton that never resolves (`models.loaded` stays false after a failed read).
|
|
99
|
+
const catalogFailed = ref(false)
|
|
100
|
+
|
|
101
|
+
function loadCatalog() {
|
|
102
|
+
catalogFailed.value = false
|
|
103
|
+
models.ensureLoaded(workspace.workspaceId ?? undefined).catch((error) => {
|
|
104
|
+
catalogFailed.value = true
|
|
105
|
+
present(error, 'settings.modelConfiguration.toast.catalogFailed')
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
96
109
|
watch(
|
|
97
110
|
open,
|
|
98
111
|
(isOpen) => {
|
|
99
112
|
if (isOpen) {
|
|
100
113
|
editor.value = null
|
|
101
114
|
filter.value = ''
|
|
102
|
-
|
|
115
|
+
loadCatalog()
|
|
103
116
|
if (workspace.workspaceId) void creds.load(workspace.workspaceId)
|
|
104
117
|
}
|
|
105
118
|
},
|
|
@@ -258,11 +271,8 @@ async function save() {
|
|
|
258
271
|
// NOT through `present`: that funnel classifies a BACKEND failure, and a synthesized local
|
|
259
272
|
// `Error` carries no envelope and no status, so it lands on the network-fault description and
|
|
260
273
|
// tells the user the server could not be reached about a check that never left the browser.
|
|
261
|
-
toast.
|
|
262
|
-
title: t('settings.modelConfiguration.toast.nameRequiredTitle'),
|
|
274
|
+
actionToast.error('settings.modelConfiguration.toast.nameRequiredTitle', {
|
|
263
275
|
description: t('settings.modelConfiguration.toast.nameRequiredBody'),
|
|
264
|
-
color: 'warning',
|
|
265
|
-
icon: 'i-lucide-triangle-alert',
|
|
266
276
|
})
|
|
267
277
|
return
|
|
268
278
|
}
|
|
@@ -372,9 +382,25 @@ async function save() {
|
|
|
372
382
|
</UButton>
|
|
373
383
|
</div>
|
|
374
384
|
|
|
375
|
-
<
|
|
376
|
-
|
|
377
|
-
|
|
385
|
+
<UAlert
|
|
386
|
+
v-if="catalogFailed"
|
|
387
|
+
color="error"
|
|
388
|
+
variant="subtle"
|
|
389
|
+
icon="i-lucide-triangle-alert"
|
|
390
|
+
:title="t('settings.modelConfiguration.list.catalogFailed')"
|
|
391
|
+
:actions="[
|
|
392
|
+
{
|
|
393
|
+
label: t('common.retry'),
|
|
394
|
+
color: 'neutral',
|
|
395
|
+
variant: 'outline',
|
|
396
|
+
onClick: loadCatalog,
|
|
397
|
+
},
|
|
398
|
+
]"
|
|
399
|
+
/>
|
|
400
|
+
|
|
401
|
+
<div v-else-if="!models.loaded" class="space-y-3">
|
|
402
|
+
<USkeleton v-for="n in 3" :key="n" class="h-20 w-full rounded-lg" />
|
|
403
|
+
</div>
|
|
378
404
|
|
|
379
405
|
<div v-else class="space-y-3">
|
|
380
406
|
<div
|
|
@@ -443,9 +469,11 @@ async function save() {
|
|
|
443
469
|
</span>
|
|
444
470
|
</div>
|
|
445
471
|
</div>
|
|
446
|
-
<
|
|
447
|
-
|
|
448
|
-
|
|
472
|
+
<EmptyState
|
|
473
|
+
v-if="sortedPresets.length === 0"
|
|
474
|
+
icon="i-lucide-sliders-horizontal"
|
|
475
|
+
:title="t('settings.modelConfiguration.list.empty')"
|
|
476
|
+
/>
|
|
449
477
|
</div>
|
|
450
478
|
|
|
451
479
|
<!-- The consensus-GROUP library: which model PANELS review the workspace's heavier
|
|
@@ -549,12 +577,12 @@ async function save() {
|
|
|
549
577
|
</UButton>
|
|
550
578
|
</UDropdownMenu>
|
|
551
579
|
</div>
|
|
552
|
-
<
|
|
580
|
+
<EmptyState
|
|
553
581
|
v-if="filteredKinds.length === 0"
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
582
|
+
compact
|
|
583
|
+
icon="i-lucide-search-x"
|
|
584
|
+
:title="t('settings.modelConfiguration.editor.noAgentsMatch', { filter })"
|
|
585
|
+
/>
|
|
558
586
|
</div>
|
|
559
587
|
</div>
|
|
560
588
|
|
|
@@ -12,7 +12,7 @@ import SecretInput from '~/components/common/SecretInput.vue'
|
|
|
12
12
|
const { t } = useI18n()
|
|
13
13
|
const ui = useUiStore()
|
|
14
14
|
const store = useReleaseHealthStore()
|
|
15
|
-
const
|
|
15
|
+
const actionToast = useActionToast()
|
|
16
16
|
const { present } = usePipelineErrorToast()
|
|
17
17
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
18
18
|
|
|
@@ -66,21 +66,14 @@ async function saveIncident() {
|
|
|
66
66
|
}
|
|
67
67
|
if (incidentIo.apiKey.trim()) input.incidentIo = { apiKey: incidentIo.apiKey.trim() }
|
|
68
68
|
if (!input.pagerDuty && !input.incidentIo) {
|
|
69
|
-
toast.
|
|
70
|
-
title: t('settings.observabilityConnection.toast.incidentCredsRequired'),
|
|
71
|
-
color: 'error',
|
|
72
|
-
})
|
|
69
|
+
actionToast.error('settings.observabilityConnection.toast.incidentCredsRequired')
|
|
73
70
|
return
|
|
74
71
|
}
|
|
75
72
|
await store.saveIncident(input)
|
|
76
73
|
pagerDuty.apiToken = ''
|
|
77
74
|
pagerDuty.fromEmail = ''
|
|
78
75
|
incidentIo.apiKey = ''
|
|
79
|
-
toast.
|
|
80
|
-
title: t('settings.observabilityConnection.toast.incidentSaved'),
|
|
81
|
-
icon: 'i-lucide-check',
|
|
82
|
-
color: 'success',
|
|
83
|
-
})
|
|
76
|
+
actionToast.success('settings.observabilityConnection.toast.incidentSaved')
|
|
84
77
|
} catch (e) {
|
|
85
78
|
present(e, 'settings.observabilityConnection.toast.incidentSaveFailed')
|
|
86
79
|
} finally {
|
|
@@ -111,11 +104,7 @@ async function saveConnection() {
|
|
|
111
104
|
})
|
|
112
105
|
datadog.apiKey = ''
|
|
113
106
|
datadog.appKey = ''
|
|
114
|
-
toast.
|
|
115
|
-
title: t('settings.observabilityConnection.toast.connected'),
|
|
116
|
-
icon: 'i-lucide-check',
|
|
117
|
-
color: 'success',
|
|
118
|
-
})
|
|
107
|
+
actionToast.success('settings.observabilityConnection.toast.connected')
|
|
119
108
|
} catch (e) {
|
|
120
109
|
present(e, 'settings.observabilityConnection.toast.connectFailed')
|
|
121
110
|
} finally {
|