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 @@ 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 @@ + + + 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 @@ 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.') } }