diff --git a/web/src/components/CardManageMenu.vue b/web/src/components/CardManageMenu.vue index 2d7d7d2..51cf96d 100644 --- a/web/src/components/CardManageMenu.vue +++ b/web/src/components/CardManageMenu.vue @@ -1,124 +1,44 @@ - - - Manage ▾ - - - - - - - - Configure - - - - - Delete card - - - - - - - - - - Delete this card? - “{{ cardText }}” will be permanently deleted. - {{ deleteError }} - - - Cancel - - - {{ deleting ? 'Deleting…' : 'Delete card' }} - - - - + “{{ cardText }}” will be permanently deleted. + diff --git a/web/src/components/ManageMenu.vue b/web/src/components/ManageMenu.vue new file mode 100644 index 0000000..4f70e26 --- /dev/null +++ b/web/src/components/ManageMenu.vue @@ -0,0 +1,114 @@ + + + + + + Manage ▾ + + + + + + + + Configure + + + + + {{ deleteLabel }} + + + + + + + + + + {{ confirmTitle }} + + {{ deleteError }} + + + Cancel + + + {{ deleting ? 'Deleting…' : deleteLabel }} + + + + + diff --git a/web/src/components/ProjectManageMenu.vue b/web/src/components/ProjectManageMenu.vue index cb26afd..2368e66 100644 --- a/web/src/components/ProjectManageMenu.vue +++ b/web/src/components/ProjectManageMenu.vue @@ -1,121 +1,40 @@ - - - Manage ▾ - - - - - - - - Configure - - - - - Delete project - - - - - - - - - - Delete this project? - - “{{ projectTitle }}” and its {{ cardCount }} - card{{ cardCount === 1 ? '' : 's' }} will be permanently deleted. - - {{ deleteError }} - - - Cancel - - - {{ deleting ? 'Deleting…' : 'Delete project' }} - - - - + “{{ projectTitle }}” and its {{ cardCount }} + card{{ cardCount === 1 ? '' : 's' }} will be permanently deleted. + diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index d4d4e96..7c2ca99 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -38,6 +38,17 @@ export class ApiError extends Error { } } +/** + * A message for a caught error: a fixed one for "not found" (404), the + * server's own message for any other API error, and a fallback for + * anything else (e.g. a network failure) -- the shape every view's initial + * load uses to turn a failed fetch into what it shows the user. + */ +export function notFoundOr(e: unknown, notFoundMessage: string, fallbackMessage: string): string { + if (e instanceof ApiError && e.status === 404) return notFoundMessage + return e instanceof ApiError ? e.message : fallbackMessage +} + interface RequestOptions { method?: string body?: unknown diff --git a/web/src/views/CardConfigureView.vue b/web/src/views/CardConfigureView.vue index 400d400..9d976c5 100644 --- a/web/src/views/CardConfigureView.vue +++ b/web/src/views/CardConfigureView.vue @@ -2,7 +2,7 @@ import { onMounted, ref } from 'vue' import { useRoute } from 'vue-router' import CardManageMenu from '../components/CardManageMenu.vue' -import { ApiError, apiRequest } from '../lib/api' +import { ApiError, apiRequest, notFoundOr } from '../lib/api' import { useCardsStore } from '../stores/cards' import { useInboxStore } from '../stores/inbox' import type { Card } from '../types' @@ -24,11 +24,7 @@ async function load() { card.value = fetched textDraft.value = fetched.text } catch (e) { - if (e instanceof ApiError && e.status === 404) { - loadError.value = 'That card does not exist.' - } else { - loadError.value = e instanceof ApiError ? e.message : 'Could not load the card.' - } + loadError.value = notFoundOr(e, 'That card does not exist.', 'Could not load the card.') } } diff --git a/web/src/views/CardView.vue b/web/src/views/CardView.vue index a01e825..a3f923b 100644 --- a/web/src/views/CardView.vue +++ b/web/src/views/CardView.vue @@ -2,7 +2,7 @@ import { computed, onMounted, ref } from 'vue' import { useRoute, type RouteLocationRaw } from 'vue-router' import CardManageMenu from '../components/CardManageMenu.vue' -import { ApiError, apiRequest } from '../lib/api' +import { apiRequest, notFoundOr } from '../lib/api' import type { Card } from '../types' const route = useRoute() @@ -19,11 +19,7 @@ async function load() { const { card: fetched } = await apiRequest<{ card: Card }>(`/cards/${cardId}`, { auth: true }) card.value = fetched } catch (e) { - if (e instanceof ApiError && e.status === 404) { - loadError.value = 'That card does not exist.' - } else { - loadError.value = e instanceof ApiError ? e.message : 'Could not load the card.' - } + loadError.value = notFoundOr(e, 'That card does not exist.', 'Could not load the card.') } } diff --git a/web/src/views/ProjectConfigureView.vue b/web/src/views/ProjectConfigureView.vue index 2463030..607d59d 100644 --- a/web/src/views/ProjectConfigureView.vue +++ b/web/src/views/ProjectConfigureView.vue @@ -3,7 +3,7 @@ import { onMounted, ref } from 'vue' import { useRoute } from 'vue-router' import ProjectManageMenu from '../components/ProjectManageMenu.vue' import StatusManager from '../components/StatusManager.vue' -import { ApiError, apiRequest } from '../lib/api' +import { ApiError, apiRequest, notFoundOr } from '../lib/api' import { useProjectsStore } from '../stores/projects' import type { Project } from '../types' @@ -23,11 +23,7 @@ async function load() { project.value = fetched nameDraft.value = fetched.title } catch (e) { - if (e instanceof ApiError && e.status === 404) { - loadError.value = 'That project does not exist.' - } else { - loadError.value = e instanceof ApiError ? e.message : 'Could not load the project.' - } + loadError.value = notFoundOr(e, 'That project does not exist.', 'Could not load the project.') } } diff --git a/web/src/views/ProjectView.vue b/web/src/views/ProjectView.vue index 8058d6a..e3a5b61 100644 --- a/web/src/views/ProjectView.vue +++ b/web/src/views/ProjectView.vue @@ -2,7 +2,7 @@ import { onMounted, ref } from 'vue' import { useRoute } from 'vue-router' import ProjectManageMenu from '../components/ProjectManageMenu.vue' -import { ApiError, apiRequest } from '../lib/api' +import { apiRequest, notFoundOr } from '../lib/api' import { useCardsStore } from '../stores/cards' import type { Project } from '../types' @@ -30,11 +30,7 @@ async function load() { cards.load(projectId), ]) } catch (e) { - if (e instanceof ApiError && e.status === 404) { - loadError.value = 'That project does not exist.' - } else { - loadError.value = e instanceof ApiError ? e.message : 'Could not load the project.' - } + loadError.value = notFoundOr(e, 'That project does not exist.', 'Could not load the project.') } }
“{{ cardText }}” will be permanently deleted.
{{ deleteError }}
- “{{ projectTitle }}” and its {{ cardCount }} - card{{ cardCount === 1 ? '' : 's' }} will be permanently deleted. -