From 21e148aa4d1e396a6b3604e58e4c232f8811c3e5 Mon Sep 17 00:00:00 2001 From: Aneurin Barker Snook Date: Fri, 4 Sep 2026 20:14:03 +0100 Subject: [PATCH] Simplify the project view header: drop the back link and description - Remove the '<- All projects' link at the top -- the sidebar's Dashboard link already covers that. - Remove the description textarea and all of its state/save logic (descriptionDraft, saveDescription, patchProject's description field); the backend field and API are untouched. - Drop .project__chrome's 42rem max-width, which existed only to keep the now-gone description prose readable. The header (title + Manage menu) now spans the full wide-layout width, so Manage sits at the true top right instead of a narrower centred column. Co-Authored-By: Claude Sonnet 5 --- web/README.md | 10 ++-- web/src/style.css | 35 ++---------- web/src/views/ProjectView.vue | 105 +++++++++++++--------------------- 3 files changed, 50 insertions(+), 100 deletions(-) diff --git a/web/README.md b/web/README.md index 71e927a..f4310c1 100644 --- a/web/README.md +++ b/web/README.md @@ -80,11 +80,11 @@ under the list adds a card straight to the inbox. ## Project detail `/projects/:id` shows one project. It renders on a **full-width** layout (the -route sets `meta.wide`, which widens `.app__main` in `App.vue`). The title and -description are inline-editable (saved on blur via `PATCH /api/projects/:id`; the -description shows an "Add a description" placeholder when empty). A **Manage** -menu (top right) has a **Delete project** action that opens a confirmation modal; -confirming calls `DELETE /api/projects/:id` and returns to the dashboard. +route sets `meta.wide`, which widens `.app__main` in `App.vue`), so the header +spans the full width and the **Manage** menu sits top right. The title is +inline-editable (saved on blur via `PATCH /api/projects/:id`). Manage has a +**Delete project** action that opens a confirmation modal; confirming calls +`DELETE /api/projects/:id` and returns to the dashboard. Below the header are two tabs (local `activeTab` state, `v-show` so both stay mounted). The tab order is fixed — **All tasks** first, **Kanban** second — but diff --git a/web/src/style.css b/web/src/style.css index 0a8285b..e9af754 100644 --- a/web/src/style.css +++ b/web/src/style.css @@ -473,7 +473,7 @@ h1 { background: var(--bg); } -/* --- project detail: header, inline title/description, manage menu - */ +/* --- project detail: header, inline title, manage menu ----------------- */ .project-head { display: flex; @@ -487,10 +487,11 @@ h1 { margin: 0 0 0.5rem; } -.project-head__title input, -.project-head__desc { +.project-head__title input { width: 100%; font: inherit; + font-size: 1.4rem; + font-weight: 600; color: var(--text); background: transparent; border: 1px solid transparent; @@ -498,31 +499,13 @@ h1 { padding: 0.25rem 0.4rem; } -.project-head__title input { - font-size: 1.4rem; - font-weight: 600; -} - -.project-head__desc { - display: block; - resize: vertical; - min-height: 2.75rem; - font-size: 0.95rem; - color: var(--muted); - margin-bottom: 0.75rem; -} - -.project-head__title input:hover, -.project-head__desc:hover { +.project-head__title input:hover { border-color: var(--border); } -.project-head__title input:focus, -.project-head__desc:focus { - outline: none; +.project-head__title input:focus { color: var(--text); background: var(--bg); - border-color: var(--accent); } .menu { @@ -587,12 +570,6 @@ h1 { color: var(--error); } -/* --- project detail: keep the header/prose readable on the wide layout -- */ - -.project__chrome { - max-width: 42rem; -} - /* --- tabs -------------------------------------------------------------- */ .tabs { diff --git a/web/src/views/ProjectView.vue b/web/src/views/ProjectView.vue index ba2fd65..57bc229 100644 --- a/web/src/views/ProjectView.vue +++ b/web/src/views/ProjectView.vue @@ -31,7 +31,6 @@ const tabs = [ const activeTab = ref<(typeof tabs)[number]['key']>('kanban') const titleDraft = ref('') -const descriptionDraft = ref('') const menuOpen = ref(false) const confirmingDelete = ref(false) @@ -106,10 +105,7 @@ async function onColumnChange(change: ColumnChange, column: Column) { } watch(project, (value) => { - if (value) { - titleDraft.value = value.title - descriptionDraft.value = value.description - } + if (value) titleDraft.value = value.title }) watch(confirmingDelete, async (open) => { @@ -151,7 +147,7 @@ async function load() { } } -async function patchProject(fields: { title?: string; description?: string }) { +async function patchProject(fields: { title?: string }) { actionError.value = null try { const { project: updated } = await apiRequest<{ project: Project }>(`/projects/${projectId}`, { @@ -162,10 +158,7 @@ async function patchProject(fields: { title?: string; description?: string }) { project.value = updated } catch (e) { actionError.value = e instanceof ApiError ? e.message : 'Could not save the change.' - if (project.value) { - titleDraft.value = project.value.title - descriptionDraft.value = project.value.description - } + if (project.value) titleDraft.value = project.value.title } } @@ -179,12 +172,6 @@ function saveTitle() { if (next !== project.value.title) void patchProject({ title: next }) } -function saveDescription() { - if (!project.value) return - const next = descriptionDraft.value.trim() - if (next !== project.value.description) void patchProject({ description: next }) -} - function askDelete() { menuOpen.value = false deleteError.value = null @@ -232,62 +219,48 @@ async function onCreate() {