@cat-factory/app 0.261.3 → 0.261.5
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 +40 -0
- package/app/components/board/AddTaskModal.vue +10 -6
- package/app/components/board/AgentStopButton.vue +2 -5
- package/app/components/board/CreateInitiativeModal.vue +2 -7
- package/app/components/board/RecurringPipelineModal.vue +10 -6
- package/app/components/bootstrap/BootstrapModal.vue +5 -24
- package/app/components/brainstorm/BrainstormWindow.vue +7 -15
- package/app/components/clarity/ClarityReviewWindow.vue +7 -15
- package/app/components/documents/DocumentImportModal.vue +2 -6
- package/app/components/documents/DocumentSourceConnectModal.vue +3 -12
- package/app/components/documents/DocumentSyncState.vue +2 -7
- package/app/components/documents/DocumentTemplatesModal.vue +4 -19
- package/app/components/documents/SpawnPreviewModal.vue +3 -12
- package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -11
- package/app/components/foundational/FoundationalServiceRegistry.vue +3 -11
- package/app/components/foundational/FoundationalServiceSources.vue +5 -13
- package/app/components/foundational/FoundationalSuppressions.vue +2 -6
- package/app/components/fragments/FragmentLibraryManager.vue +12 -20
- package/app/components/github/AddServiceFromRepoModal.vue +3 -12
- package/app/components/github/GitHubConnect.vue +4 -12
- package/app/components/github/GitHubPanel.vue +9 -17
- package/app/components/github/RepoTreeBrowser.vue +2 -7
- package/app/components/humanTest/HumanTestWindow.vue +2 -7
- package/app/components/initiative/InitiativeTrackerWindow.vue +2 -3
- package/app/components/layout/AccountAuditLog.vue +2 -7
- package/app/components/layout/AccountDeploymentSettings.vue +11 -51
- package/app/components/layout/AccountModelPolicySettings.vue +2 -5
- package/app/components/layout/AccountPlatformAlertSettings.vue +2 -5
- package/app/components/layout/AccountRunCredentialSettings.vue +2 -5
- package/app/components/layout/AccountTeamSettings.vue +9 -18
- package/app/components/layout/BoardSwitcher.vue +6 -14
- package/app/components/layout/BoardToolbar.vue +3 -10
- package/app/components/layout/NotificationsInbox.vue +3 -13
- package/app/components/layout/WorkspaceMembersSettings.vue +6 -15
- package/app/components/notifications/NotificationSettingsPanel.vue +3 -11
- package/app/components/panels/DecisionModal.vue +2 -7
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +4 -20
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +3 -11
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -11
- package/app/components/panels/inspector/ServiceValidationConfig.vue +4 -12
- package/app/components/pipeline/PipelineBuilder.vue +4 -7
- package/app/components/providers/ApiKeysSection.vue +4 -15
- package/app/components/providers/PersonalCredentialModal.vue +2 -5
- package/app/components/providers/PersonalSubscriptionSection.vue +3 -10
- package/app/components/providers/VendorCredentialsModal.vue +5 -20
- package/app/components/requirements/RequirementsReviewWindow.vue +11 -19
- package/app/components/sandbox/SandboxPanel.vue +4 -18
- package/app/components/settings/ApiTokensPanel.vue +4 -12
- package/app/components/settings/BudgetSettings.vue +2 -5
- package/app/components/settings/CloudflareHandlerSection.vue +3 -12
- package/app/components/settings/ConsensusGroupsSection.vue +3 -12
- package/app/components/settings/CustomManifestTypeEditor.vue +3 -13
- package/app/components/settings/DefaultProvisionTypeSection.vue +2 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +7 -14
- package/app/components/settings/InfrastructureBackendPicker.vue +2 -7
- package/app/components/settings/IssueTrackerPanel.vue +4 -18
- package/app/components/settings/KubernetesEngineForm.vue +71 -26
- package/app/components/settings/KubernetesEnvironmentForm.vue +35 -8
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -6
- package/app/components/settings/LocalModelEndpointsPanel.vue +3 -11
- package/app/components/settings/ModelConfigurationPanel.vue +13 -16
- package/app/components/settings/ModelPresetHealthModal.vue +3 -13
- package/app/components/settings/ObservabilityConnectionPanel.vue +6 -14
- package/app/components/settings/OpenRouterCatalogPanel.vue +3 -12
- package/app/components/settings/PackageRegistriesPanel.vue +4 -12
- package/app/components/settings/ProviderConnectionTab.vue +5 -13
- package/app/components/settings/RiskPolicyHealthModal.vue +2 -7
- package/app/components/settings/RiskPolicyPanel.vue +5 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +2 -7
- package/app/components/settings/SharedStacksPanel.vue +10 -20
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +3 -12
- package/app/components/settings/UserSecretsSection.vue +3 -11
- package/app/components/settings/WorkspaceMetadataSettings.vue +2 -6
- package/app/components/settings/WorkspaceSettingsPanel.vue +2 -6
- package/app/components/skills/SkillLibraryManager.vue +5 -13
- package/app/components/slack/SlackPanel.vue +7 -15
- package/app/components/tasks/BugHuntModal.vue +2 -6
- package/app/components/tasks/TaskImportModal.vue +2 -6
- package/app/components/tasks/TaskSourceConnectModal.vue +4 -18
- package/app/composables/useBlockDeletion.ts +2 -6
- package/app/composables/useCopyToClipboard.ts +7 -1
- package/app/composables/usePipelineErrorToast.spec.ts +76 -16
- package/app/composables/usePipelineErrorToast.ts +109 -50
- package/app/stores/board/context.ts +9 -2
- package/app/stores/board/dependencies.ts +3 -13
- package/app/stores/board/mutations.ts +2 -7
- package/app/stores/board/placement.ts +12 -25
- package/app/stores/board/removal.ts +2 -7
- package/app/stores/board.spec.ts +15 -8
- package/app/stores/board.ts +11 -1
- package/app/stores/recurringPipelines.ts +5 -11
- package/app/stores/ui/k3sDeepLink.spec.ts +43 -1
- package/app/stores/ui/modals.ts +24 -0
- package/i18n/locales/de.json +2 -0
- package/i18n/locales/en.json +2 -0
- package/i18n/locales/es.json +2 -0
- package/i18n/locales/fr.json +2 -0
- package/i18n/locales/he.json +2 -0
- package/i18n/locales/it.json +2 -0
- package/i18n/locales/ja.json +2 -0
- package/i18n/locales/pl.json +2 -0
- package/i18n/locales/tr.json +2 -0
- package/i18n/locales/uk.json +2 -0
- package/package.json +2 -2
|
@@ -70,6 +70,7 @@ const CONCERN_LEVELS = computed<{ value: RequirementConcernLevel; label: string
|
|
|
70
70
|
|
|
71
71
|
const store = useRiskPoliciesStore()
|
|
72
72
|
const toast = useToast()
|
|
73
|
+
const { present } = usePipelineErrorToast()
|
|
73
74
|
const { confirm } = useConfirm()
|
|
74
75
|
|
|
75
76
|
// Local editable copy per preset, kept in sync with the store. Percentages are
|
|
@@ -153,15 +154,6 @@ watch(
|
|
|
153
154
|
|
|
154
155
|
const busy = ref<string | null>(null)
|
|
155
156
|
|
|
156
|
-
function notifyError(title: string, e: unknown) {
|
|
157
|
-
toast.add({
|
|
158
|
-
title,
|
|
159
|
-
description: e instanceof Error ? e.message : String(e),
|
|
160
|
-
icon: 'i-lucide-triangle-alert',
|
|
161
|
-
color: 'error',
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
157
|
async function save(p: RiskPolicy) {
|
|
166
158
|
const d = drafts[p.id]
|
|
167
159
|
if (!d) return
|
|
@@ -188,7 +180,7 @@ async function save(p: RiskPolicy) {
|
|
|
188
180
|
color: 'success',
|
|
189
181
|
})
|
|
190
182
|
} catch (e) {
|
|
191
|
-
|
|
183
|
+
present(e, 'settings.riskPolicy.toast.saveFailed')
|
|
192
184
|
} finally {
|
|
193
185
|
busy.value = null
|
|
194
186
|
}
|
|
@@ -199,7 +191,7 @@ async function makeDefault(p: RiskPolicy) {
|
|
|
199
191
|
try {
|
|
200
192
|
await store.update(p.id, { isDefault: true })
|
|
201
193
|
} catch (e) {
|
|
202
|
-
|
|
194
|
+
present(e, 'settings.riskPolicy.toast.defaultFailed')
|
|
203
195
|
} finally {
|
|
204
196
|
busy.value = null
|
|
205
197
|
}
|
|
@@ -218,7 +210,7 @@ async function remove(p: RiskPolicy) {
|
|
|
218
210
|
try {
|
|
219
211
|
await store.remove(p.id)
|
|
220
212
|
} catch (e) {
|
|
221
|
-
|
|
213
|
+
present(e, 'settings.riskPolicy.toast.deleteFailed')
|
|
222
214
|
} finally {
|
|
223
215
|
busy.value = null
|
|
224
216
|
}
|
|
@@ -274,7 +266,7 @@ async function create() {
|
|
|
274
266
|
color: 'success',
|
|
275
267
|
})
|
|
276
268
|
} catch (e) {
|
|
277
|
-
|
|
269
|
+
present(e, 'settings.riskPolicy.toast.createFailed')
|
|
278
270
|
} finally {
|
|
279
271
|
creating.value = false
|
|
280
272
|
}
|
|
@@ -12,7 +12,7 @@ const { t } = useI18n()
|
|
|
12
12
|
const fragments = useFragmentsStore()
|
|
13
13
|
const defaults = useServiceFragmentDefaultsStore()
|
|
14
14
|
const ui = useUiStore()
|
|
15
|
-
const
|
|
15
|
+
const { present } = usePipelineErrorToast()
|
|
16
16
|
|
|
17
17
|
const busy = ref(false)
|
|
18
18
|
|
|
@@ -36,12 +36,7 @@ async function save(ids: string[]) {
|
|
|
36
36
|
try {
|
|
37
37
|
await defaults.set(ids)
|
|
38
38
|
} catch (e) {
|
|
39
|
-
|
|
40
|
-
title: t('settings.serviceFragmentDefaults.saveFailed'),
|
|
41
|
-
description: e instanceof Error ? e.message : String(e),
|
|
42
|
-
icon: 'i-lucide-triangle-alert',
|
|
43
|
-
color: 'error',
|
|
44
|
-
})
|
|
39
|
+
present(e, 'settings.serviceFragmentDefaults.saveFailed')
|
|
45
40
|
} finally {
|
|
46
41
|
busy.value = false
|
|
47
42
|
}
|
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
const { t } = useI18n()
|
|
17
17
|
const store = useSharedStacksStore()
|
|
18
18
|
const toast = useToast()
|
|
19
|
+
const { present } = usePipelineErrorToast()
|
|
19
20
|
const { confirmAction, toastDone } = useConfirmAction()
|
|
20
21
|
|
|
21
22
|
const stacks = computed(() => store.stacks)
|
|
@@ -169,21 +170,12 @@ async function autodetect() {
|
|
|
169
170
|
color: 'success',
|
|
170
171
|
})
|
|
171
172
|
} catch (e) {
|
|
172
|
-
|
|
173
|
+
present(e, 'settings.sharedStacks.detect.failed')
|
|
173
174
|
} finally {
|
|
174
175
|
detecting.value = false
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
function notifyError(title: string, e: unknown) {
|
|
179
|
-
toast.add({
|
|
180
|
-
title,
|
|
181
|
-
description: e instanceof Error ? e.message : String(e),
|
|
182
|
-
icon: 'i-lucide-triangle-alert',
|
|
183
|
-
color: 'error',
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
179
|
/** Create a new stack, or save edits to the one being edited (same form, mode toggled by `editingId`). */
|
|
188
180
|
async function saveStack() {
|
|
189
181
|
saving.value = true
|
|
@@ -223,13 +215,11 @@ async function saveStack() {
|
|
|
223
215
|
color: 'success',
|
|
224
216
|
})
|
|
225
217
|
} catch (e) {
|
|
226
|
-
|
|
227
|
-
t(
|
|
228
|
-
editing
|
|
229
|
-
? 'settings.sharedStacks.toast.updateFailed'
|
|
230
|
-
: 'settings.sharedStacks.toast.createFailed',
|
|
231
|
-
),
|
|
218
|
+
present(
|
|
232
219
|
e,
|
|
220
|
+
editing
|
|
221
|
+
? 'settings.sharedStacks.toast.updateFailed'
|
|
222
|
+
: 'settings.sharedStacks.toast.createFailed',
|
|
233
223
|
)
|
|
234
224
|
} finally {
|
|
235
225
|
saving.value = false
|
|
@@ -243,10 +233,10 @@ async function start(stack: SharedStack) {
|
|
|
243
233
|
// surface that as an error toast too — not only a thrown transport/unavailable error.
|
|
244
234
|
const updated = await store.ensureUp(stack.id)
|
|
245
235
|
if (updated.status === 'failed') {
|
|
246
|
-
|
|
236
|
+
present(updated.lastError ?? '', 'settings.sharedStacks.toast.startFailed')
|
|
247
237
|
}
|
|
248
238
|
} catch (e) {
|
|
249
|
-
|
|
239
|
+
present(e, 'settings.sharedStacks.toast.startFailed')
|
|
250
240
|
} finally {
|
|
251
241
|
busyId.value = null
|
|
252
242
|
}
|
|
@@ -257,7 +247,7 @@ async function stop(stack: SharedStack) {
|
|
|
257
247
|
try {
|
|
258
248
|
await store.teardown(stack.id)
|
|
259
249
|
} catch (e) {
|
|
260
|
-
|
|
250
|
+
present(e, 'settings.sharedStacks.toast.stopFailed')
|
|
261
251
|
} finally {
|
|
262
252
|
busyId.value = null
|
|
263
253
|
}
|
|
@@ -271,7 +261,7 @@ async function remove(stack: SharedStack) {
|
|
|
271
261
|
await store.remove(stack.id)
|
|
272
262
|
toastDone('remove', noun)
|
|
273
263
|
} catch (e) {
|
|
274
|
-
|
|
264
|
+
present(e, 'settings.sharedStacks.toast.removeFailed')
|
|
275
265
|
} finally {
|
|
276
266
|
busyId.value = null
|
|
277
267
|
}
|
|
@@ -16,7 +16,7 @@ import type { TaskTypeSuppression } from '~/types/domain'
|
|
|
16
16
|
const { t } = useI18n()
|
|
17
17
|
const api = useApi()
|
|
18
18
|
const workspace = useWorkspaceStore()
|
|
19
|
-
const
|
|
19
|
+
const { present } = usePipelineErrorToast()
|
|
20
20
|
|
|
21
21
|
const rows = ref<TaskTypeSuppression[]>([])
|
|
22
22
|
const loading = ref(false)
|
|
@@ -31,7 +31,7 @@ async function load() {
|
|
|
31
31
|
try {
|
|
32
32
|
rows.value = (await api.listTaskTypeSuppressions(workspace.requireId())).taskTypes
|
|
33
33
|
} catch (e) {
|
|
34
|
-
|
|
34
|
+
present(e, 'settings.taskTypeSuppressions.saveFailed')
|
|
35
35
|
} finally {
|
|
36
36
|
loading.value = false
|
|
37
37
|
}
|
|
@@ -52,20 +52,11 @@ async function toggle(row: TaskTypeSuppression, offered: boolean) {
|
|
|
52
52
|
rows.value = result.taskTypes
|
|
53
53
|
await workspace.refresh()
|
|
54
54
|
} catch (e) {
|
|
55
|
-
|
|
55
|
+
present(e, 'settings.taskTypeSuppressions.saveFailed')
|
|
56
56
|
} finally {
|
|
57
57
|
busyId.value = null
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
function fail(e: unknown) {
|
|
62
|
-
toast.add({
|
|
63
|
-
title: t('settings.taskTypeSuppressions.saveFailed'),
|
|
64
|
-
description: e instanceof Error ? e.message : String(e),
|
|
65
|
-
icon: 'i-lucide-triangle-alert',
|
|
66
|
-
color: 'error',
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
60
|
</script>
|
|
70
61
|
|
|
71
62
|
<template>
|
|
@@ -15,6 +15,7 @@ const { t } = useI18n()
|
|
|
15
15
|
const ui = useUiStore()
|
|
16
16
|
const store = useUserSecretsStore()
|
|
17
17
|
const toast = useToast()
|
|
18
|
+
const { present } = usePipelineErrorToast()
|
|
18
19
|
const { confirm } = useConfirm()
|
|
19
20
|
|
|
20
21
|
const open = computed({
|
|
@@ -75,15 +76,6 @@ function buildPayload(): { secret: string; metadata?: Record<string, string> } |
|
|
|
75
76
|
return { secret, ...(Object.keys(metadata).length ? { metadata } : {}) }
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
function notifyError(title: string, e: unknown) {
|
|
79
|
-
toast.add({
|
|
80
|
-
title,
|
|
81
|
-
description: e instanceof Error ? e.message : String(e),
|
|
82
|
-
icon: 'i-lucide-triangle-alert',
|
|
83
|
-
color: 'error',
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
79
|
async function test() {
|
|
88
80
|
const payload = buildPayload()
|
|
89
81
|
if (!payload) return
|
|
@@ -120,7 +112,7 @@ async function save() {
|
|
|
120
112
|
color: 'success',
|
|
121
113
|
})
|
|
122
114
|
} catch (e) {
|
|
123
|
-
|
|
115
|
+
present(e, 'settings.userSecrets.toast.saveFailed')
|
|
124
116
|
} finally {
|
|
125
117
|
busy.value = false
|
|
126
118
|
}
|
|
@@ -143,7 +135,7 @@ async function remove() {
|
|
|
143
135
|
resetDraft()
|
|
144
136
|
toast.add({ title: t('settings.userSecrets.toast.removed'), icon: 'i-lucide-check' })
|
|
145
137
|
} catch (e) {
|
|
146
|
-
|
|
138
|
+
present(e, 'settings.userSecrets.toast.removeFailed')
|
|
147
139
|
} finally {
|
|
148
140
|
busy.value = false
|
|
149
141
|
}
|
|
@@ -22,6 +22,7 @@ const { t } = useI18n()
|
|
|
22
22
|
const slots = useReactiveSlots<AppSlots>()
|
|
23
23
|
const store = useWorkspaceSettingsStore()
|
|
24
24
|
const toast = useToast()
|
|
25
|
+
const { present } = usePipelineErrorToast()
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* The fields to render. A malformed key is dropped (the store would refuse every save) and
|
|
@@ -71,12 +72,7 @@ async function save() {
|
|
|
71
72
|
color: 'success',
|
|
72
73
|
})
|
|
73
74
|
} catch (e) {
|
|
74
|
-
toast.
|
|
75
|
-
title: t('settings.workspaceSettings.toast.saveFailed'),
|
|
76
|
-
description: e instanceof Error ? e.message : String(e),
|
|
77
|
-
icon: 'i-lucide-triangle-alert',
|
|
78
|
-
color: 'error',
|
|
79
|
-
})
|
|
75
|
+
present(e, 'settings.workspaceSettings.toast.saveFailed')
|
|
80
76
|
} finally {
|
|
81
77
|
saving.value = false
|
|
82
78
|
}
|
|
@@ -29,6 +29,7 @@ const store = useWorkspaceSettingsStore()
|
|
|
29
29
|
const workspace = useWorkspaceStore()
|
|
30
30
|
const access = useWorkspaceAccess()
|
|
31
31
|
const toast = useToast()
|
|
32
|
+
const { present } = usePipelineErrorToast()
|
|
32
33
|
const slots = useReactiveSlots<AppSlots>()
|
|
33
34
|
// Whether the deployment registers any reusable operation at all, hidden or not, so the
|
|
34
35
|
// Operations tab exists only where there is something for it to manage. Not the OFFERED catalog:
|
|
@@ -289,12 +290,7 @@ async function save() {
|
|
|
289
290
|
color: 'success',
|
|
290
291
|
})
|
|
291
292
|
} catch (e) {
|
|
292
|
-
toast.
|
|
293
|
-
title: t('settings.workspaceSettings.toast.saveFailed'),
|
|
294
|
-
description: e instanceof Error ? e.message : String(e),
|
|
295
|
-
icon: 'i-lucide-triangle-alert',
|
|
296
|
-
color: 'error',
|
|
297
|
-
})
|
|
293
|
+
present(e, 'settings.workspaceSettings.toast.saveFailed')
|
|
298
294
|
} finally {
|
|
299
295
|
saving.value = false
|
|
300
296
|
}
|
|
@@ -16,6 +16,7 @@ const props = defineProps<{ accountId: string }>()
|
|
|
16
16
|
const library = useSkillLibrary(props.accountId)
|
|
17
17
|
const github = useGitHubStore()
|
|
18
18
|
const toast = useToast()
|
|
19
|
+
const { present } = usePipelineErrorToast()
|
|
19
20
|
const { t, d } = useI18n()
|
|
20
21
|
const { confirm } = useConfirm()
|
|
21
22
|
|
|
@@ -33,15 +34,6 @@ watch(
|
|
|
33
34
|
// the integration is off) the form falls back to manual text entry.
|
|
34
35
|
const githubReady = computed(() => github.available === true && github.connected)
|
|
35
36
|
|
|
36
|
-
function notifyError(title: string, e: unknown) {
|
|
37
|
-
toast.add({
|
|
38
|
-
title,
|
|
39
|
-
description: e instanceof Error ? e.message : String(e),
|
|
40
|
-
icon: 'i-lucide-triangle-alert',
|
|
41
|
-
color: 'error',
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
37
|
// Per-row in-flight tracking so only the control that triggered an action spins.
|
|
46
38
|
const busyRows = reactive(new Set<string>())
|
|
47
39
|
const rowBusy = (key: string) => busyRows.has(key)
|
|
@@ -102,7 +94,7 @@ async function linkSource() {
|
|
|
102
94
|
resetSourceDraft()
|
|
103
95
|
toast.add({ title: t('skills.toast.sourceLinked'), icon: 'i-lucide-git-branch' })
|
|
104
96
|
} catch (e) {
|
|
105
|
-
|
|
97
|
+
present(e, 'skills.toast.linkSourceFailed')
|
|
106
98
|
} finally {
|
|
107
99
|
linkingSource.value = false
|
|
108
100
|
}
|
|
@@ -121,7 +113,7 @@ async function syncSource(id: string) {
|
|
|
121
113
|
color: 'info',
|
|
122
114
|
})
|
|
123
115
|
} catch (e) {
|
|
124
|
-
|
|
116
|
+
present(e, 'skills.toast.syncFailed')
|
|
125
117
|
}
|
|
126
118
|
})
|
|
127
119
|
}
|
|
@@ -135,7 +127,7 @@ async function checkSource(id: string) {
|
|
|
135
127
|
icon: status.changed ? 'i-lucide-bell-dot' : 'i-lucide-check',
|
|
136
128
|
})
|
|
137
129
|
} catch (e) {
|
|
138
|
-
|
|
130
|
+
present(e, 'skills.toast.checkSourceFailed')
|
|
139
131
|
}
|
|
140
132
|
})
|
|
141
133
|
}
|
|
@@ -156,7 +148,7 @@ async function unlinkSource(id: string) {
|
|
|
156
148
|
await library.unlinkSource(id)
|
|
157
149
|
toast.add({ title: t('skills.toast.sourceUnlinked'), icon: 'i-lucide-unplug' })
|
|
158
150
|
} catch (e) {
|
|
159
|
-
|
|
151
|
+
present(e, 'skills.toast.unlinkSourceFailed')
|
|
160
152
|
}
|
|
161
153
|
})
|
|
162
154
|
}
|
|
@@ -20,6 +20,7 @@ import SecretInput from '~/components/common/SecretInput.vue'
|
|
|
20
20
|
const ui = useUiStore()
|
|
21
21
|
const slack = useSlackStore()
|
|
22
22
|
const toast = useToast()
|
|
23
|
+
const { present } = usePipelineErrorToast()
|
|
23
24
|
const { t } = useI18n()
|
|
24
25
|
const { confirm } = useConfirm()
|
|
25
26
|
|
|
@@ -90,15 +91,6 @@ const tokenInput = ref('')
|
|
|
90
91
|
const busy = ref(false)
|
|
91
92
|
const connectingOAuth = ref(false)
|
|
92
93
|
|
|
93
|
-
function notifyError(title: string, e: unknown) {
|
|
94
|
-
toast.add({
|
|
95
|
-
title,
|
|
96
|
-
description: e instanceof Error ? e.message : String(e),
|
|
97
|
-
icon: 'i-lucide-triangle-alert',
|
|
98
|
-
color: 'error',
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
|
|
102
94
|
// Load everything the panel needs whenever it opens and Slack is connected.
|
|
103
95
|
watch(
|
|
104
96
|
() => open.value,
|
|
@@ -112,7 +104,7 @@ watch(
|
|
|
112
104
|
mentionsEnabled.value = slack.settings?.mentionsEnabled ?? false
|
|
113
105
|
mapping.value = slack.memberMapping.map((e) => toMemberRow(e, nextUid()))
|
|
114
106
|
} catch (e) {
|
|
115
|
-
|
|
107
|
+
present(e, 'slack.error.loadSettings')
|
|
116
108
|
}
|
|
117
109
|
},
|
|
118
110
|
// Lazy v-if mount: the panel mounts with `open` already true, so load immediately.
|
|
@@ -127,7 +119,7 @@ async function connectViaOAuth() {
|
|
|
127
119
|
window.location.href = await slack.installUrl()
|
|
128
120
|
} catch (e) {
|
|
129
121
|
connectingOAuth.value = false
|
|
130
|
-
|
|
122
|
+
present(e, 'slack.error.startOAuth')
|
|
131
123
|
}
|
|
132
124
|
}
|
|
133
125
|
|
|
@@ -138,7 +130,7 @@ async function connectWithToken() {
|
|
|
138
130
|
tokenInput.value = ''
|
|
139
131
|
toast.add({ title: t('slack.toast.connected'), icon: 'i-lucide-check', color: 'success' })
|
|
140
132
|
} catch (e) {
|
|
141
|
-
|
|
133
|
+
present(e, 'slack.error.connect')
|
|
142
134
|
}
|
|
143
135
|
}
|
|
144
136
|
|
|
@@ -154,7 +146,7 @@ async function disconnect() {
|
|
|
154
146
|
try {
|
|
155
147
|
await slack.disconnect()
|
|
156
148
|
} catch (e) {
|
|
157
|
-
|
|
149
|
+
present(e, 'slack.error.disconnect')
|
|
158
150
|
}
|
|
159
151
|
}
|
|
160
152
|
|
|
@@ -167,7 +159,7 @@ async function saveRouting() {
|
|
|
167
159
|
})
|
|
168
160
|
toast.add({ title: t('slack.toast.routingSaved'), icon: 'i-lucide-check', color: 'success' })
|
|
169
161
|
} catch (e) {
|
|
170
|
-
|
|
162
|
+
present(e, 'slack.error.saveRouting')
|
|
171
163
|
} finally {
|
|
172
164
|
busy.value = false
|
|
173
165
|
}
|
|
@@ -199,7 +191,7 @@ async function saveMapping() {
|
|
|
199
191
|
mapping.value = slack.memberMapping.map((e) => toMemberRow(e, nextUid()))
|
|
200
192
|
toast.add({ title: t('slack.toast.mapSaved'), icon: 'i-lucide-check', color: 'success' })
|
|
201
193
|
} catch (e) {
|
|
202
|
-
|
|
194
|
+
present(e, 'slack.error.saveMap')
|
|
203
195
|
} finally {
|
|
204
196
|
busy.value = false
|
|
205
197
|
}
|
|
@@ -43,6 +43,7 @@ const ui = useUiStore()
|
|
|
43
43
|
const tasks = useTasksStore()
|
|
44
44
|
const hunt = useBugHuntStore()
|
|
45
45
|
const toast = useToast()
|
|
46
|
+
const { present } = usePipelineErrorToast()
|
|
46
47
|
|
|
47
48
|
const open = computed({
|
|
48
49
|
get: () => ui.bugHunt !== null,
|
|
@@ -212,12 +213,7 @@ async function adopt(candidate: BugHuntCandidate) {
|
|
|
212
213
|
icon: 'i-lucide-bug-play',
|
|
213
214
|
})
|
|
214
215
|
} catch (e) {
|
|
215
|
-
|
|
216
|
-
title: t('bugHunt.adoptFailed'),
|
|
217
|
-
description: e instanceof Error ? e.message : String(e),
|
|
218
|
-
icon: 'i-lucide-triangle-alert',
|
|
219
|
-
color: 'error',
|
|
220
|
-
})
|
|
216
|
+
present(e, 'bugHunt.adoptFailed')
|
|
221
217
|
}
|
|
222
218
|
}
|
|
223
219
|
|
|
@@ -22,6 +22,7 @@ const { t } = useI18n()
|
|
|
22
22
|
const ui = useUiStore()
|
|
23
23
|
const tasks = useTasksStore()
|
|
24
24
|
const toast = useToast()
|
|
25
|
+
const { present } = usePipelineErrorToast()
|
|
25
26
|
|
|
26
27
|
const open = computed({
|
|
27
28
|
get: () => ui.taskImport !== null,
|
|
@@ -112,12 +113,7 @@ async function doSpawnEpic() {
|
|
|
112
113
|
icon: 'i-lucide-layers',
|
|
113
114
|
})
|
|
114
115
|
} catch (e) {
|
|
115
|
-
|
|
116
|
-
title: t('tasks.import.epicFailed'),
|
|
117
|
-
description: e instanceof Error ? e.message : String(e),
|
|
118
|
-
icon: 'i-lucide-triangle-alert',
|
|
119
|
-
color: 'error',
|
|
120
|
-
})
|
|
116
|
+
present(e, 'tasks.import.epicFailed')
|
|
121
117
|
} finally {
|
|
122
118
|
importing.value = false
|
|
123
119
|
}
|
|
@@ -17,6 +17,7 @@ const { t } = useI18n()
|
|
|
17
17
|
const ui = useUiStore()
|
|
18
18
|
const tasks = useTasksStore()
|
|
19
19
|
const toast = useToast()
|
|
20
|
+
const { present } = usePipelineErrorToast()
|
|
20
21
|
const { confirmAction } = useConfirmAction()
|
|
21
22
|
|
|
22
23
|
const source = computed(() => ui.taskConnect?.source ?? null)
|
|
@@ -70,12 +71,7 @@ async function submit() {
|
|
|
70
71
|
// Re-probe so `available`/`enabled` reflect the new connection.
|
|
71
72
|
await tasks.probe()
|
|
72
73
|
} catch (e) {
|
|
73
|
-
|
|
74
|
-
title: t('tasks.connect.connectFailed'),
|
|
75
|
-
description: e instanceof Error ? e.message : String(e),
|
|
76
|
-
icon: 'i-lucide-triangle-alert',
|
|
77
|
-
color: 'error',
|
|
78
|
-
})
|
|
74
|
+
present(e, 'tasks.connect.connectFailed')
|
|
79
75
|
} finally {
|
|
80
76
|
saving.value = false
|
|
81
77
|
}
|
|
@@ -88,12 +84,7 @@ async function startOAuth() {
|
|
|
88
84
|
// Only Linear wires an OAuth flow today; the browser navigates away on success.
|
|
89
85
|
if (source.value === 'linear') await tasks.startLinearOAuth()
|
|
90
86
|
} catch (e) {
|
|
91
|
-
|
|
92
|
-
title: t('tasks.connect.connectFailed'),
|
|
93
|
-
description: e instanceof Error ? e.message : String(e),
|
|
94
|
-
icon: 'i-lucide-triangle-alert',
|
|
95
|
-
color: 'error',
|
|
96
|
-
})
|
|
87
|
+
present(e, 'tasks.connect.connectFailed')
|
|
97
88
|
oauthStarting.value = false
|
|
98
89
|
}
|
|
99
90
|
}
|
|
@@ -117,12 +108,7 @@ async function toggleEnabled(enabled: boolean) {
|
|
|
117
108
|
try {
|
|
118
109
|
await tasks.setEnabled(source.value, enabled)
|
|
119
110
|
} catch (e) {
|
|
120
|
-
|
|
121
|
-
title: t('tasks.connect.updateFailed'),
|
|
122
|
-
description: e instanceof Error ? e.message : String(e),
|
|
123
|
-
icon: 'i-lucide-triangle-alert',
|
|
124
|
-
color: 'error',
|
|
125
|
-
})
|
|
111
|
+
present(e, 'tasks.connect.updateFailed')
|
|
126
112
|
} finally {
|
|
127
113
|
togglingEnabled.value = false
|
|
128
114
|
}
|
|
@@ -16,6 +16,7 @@ export function useBlockDeletion() {
|
|
|
16
16
|
const ui = useUiStore()
|
|
17
17
|
const recurring = useRecurringPipelinesStore()
|
|
18
18
|
const toast = useToast()
|
|
19
|
+
const { present } = usePipelineErrorToast()
|
|
19
20
|
const { confirm } = useConfirm()
|
|
20
21
|
const { t } = useI18n()
|
|
21
22
|
const access = useWorkspaceAccess()
|
|
@@ -57,12 +58,7 @@ export function useBlockDeletion() {
|
|
|
57
58
|
color: 'neutral',
|
|
58
59
|
})
|
|
59
60
|
} catch (e) {
|
|
60
|
-
toast.
|
|
61
|
-
title: t('board.toast.archiveFailed'),
|
|
62
|
-
description: e instanceof Error ? e.message : String(e),
|
|
63
|
-
icon: 'i-lucide-triangle-alert',
|
|
64
|
-
color: 'error',
|
|
65
|
-
})
|
|
61
|
+
present(e, 'board.toast.archiveFailed')
|
|
66
62
|
}
|
|
67
63
|
return true
|
|
68
64
|
}
|
|
@@ -9,7 +9,13 @@
|
|
|
9
9
|
import { useClipboard } from '@vueuse/core'
|
|
10
10
|
|
|
11
11
|
export function useCopyToClipboard() {
|
|
12
|
-
|
|
12
|
+
// Resolved through the Nuxt app's global i18n instance rather than `useI18n()`, which requires an
|
|
13
|
+
// active component instance. This composable is reached from the failure-toast funnel, which is
|
|
14
|
+
// itself instantiated in STORE setup (`stores/execution.ts`, `stores/board.ts`), and a Pinia
|
|
15
|
+
// setup store runs its body on the first `useStore()` anywhere, which is not necessarily a
|
|
16
|
+
// component. `useI18n()` there throws `MUST_BE_CALL_SETUP_TOP`, and a throw in a store body takes
|
|
17
|
+
// the whole app to Nuxt's error page. Same reason, and the same fix, as `usePipelineErrorToast`.
|
|
18
|
+
const { t } = useNuxtApp().$i18n as ReturnType<typeof useI18n>
|
|
13
19
|
const toast = useToast()
|
|
14
20
|
const { copy: writeClipboard, isSupported } = useClipboard()
|
|
15
21
|
|