Catch up web/README.md and two stale comments to current code
web/README.md's Layout section hadn't been touched since early in the session: it was missing ManageMenu.vue, CardManageMenu.vue, StatusManager.vue, useDialog.ts, and four of the ten views (ProjectExploreView, ProjectKanbanView, CardView, CardConfigureView) entirely, still described CardRow as inline-editable-with-a-delete- button, and still claimed the top-level <RouterView> was keyed by plain route.path (true before this session's Explore/Kanban route split, wrong after -- see App.vue's routeKey). The Inbox section also still gated the post-drag cards refresh on route.name === 'project' alone, from before Explore itself could send a card there. Also fixed two lingering "all tasks" references (the tab's name before it became "Explore") in a stores/cards.ts comment and a style.css one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+44
-25
@@ -29,22 +29,39 @@ build app` from the parent directory.
|
||||
## Layout
|
||||
|
||||
```
|
||||
src/main.ts App bootstrap; resolves the stored session before mount
|
||||
src/router/index.ts Routes + guard (redirects to /login when unauthenticated)
|
||||
src/stores/auth.ts Pinia store: token in localStorage, magic-link + fetchMe
|
||||
src/stores/projects.ts Pinia store: the user's projects (fetch + create)
|
||||
src/stores/cards.ts Pinia store: one project's cards (CRUD; no reordering -- see lib/cardOrder.ts)
|
||||
src/stores/inbox.ts Pinia store: the caller's global inbox (fetch + create)
|
||||
src/lib/api.ts fetch wrapper, bearer token, typed ApiError
|
||||
src/lib/cardOrder.ts reorderColumn() -- PUT /api/cards/order, shared by the sidebar and kanban board
|
||||
src/lib/webauthn.ts base64url <-> ArrayBuffer + the register/login passkey ceremonies
|
||||
src/components/AppSidebar.vue left nav: Dashboard link, project dropdown, Inbox + form
|
||||
src/components/CardRow.vue editable text + status chip + delete, one card
|
||||
src/components/KanbanCard.vue small draggable card for the board columns and the inbox
|
||||
src/main.ts App bootstrap; resolves the stored session before mount
|
||||
src/router/index.ts Routes + guard (redirects to /login when unauthenticated) -- a
|
||||
project's Explore/Kanban are nested children of ProjectView
|
||||
src/stores/auth.ts Pinia store: token in localStorage, magic-link + fetchMe
|
||||
src/stores/projects.ts Pinia store: the user's projects (fetch + create)
|
||||
src/stores/cards.ts Pinia store: one project's cards -- load/add/patch-in-place;
|
||||
delete and reordering happen elsewhere (ManageMenu.vue,
|
||||
lib/cardOrder.ts)
|
||||
src/stores/inbox.ts Pinia store: the caller's global inbox (fetch + create)
|
||||
src/lib/api.ts fetch wrapper, bearer token, typed ApiError, notFoundOr()
|
||||
(a caught error -> a 404-aware user-facing message)
|
||||
src/lib/cardOrder.ts reorderColumn() -- PUT /api/cards/order, shared by the sidebar
|
||||
and kanban board
|
||||
src/lib/webauthn.ts base64url <-> ArrayBuffer + the register/login passkey ceremonies
|
||||
src/composables/useDialog.ts Escape-to-close + focus-on-open for a dialog or menu --
|
||||
shared by ManageMenu.vue and StatusManager's reassign modal
|
||||
src/components/AppSidebar.vue left nav: Dashboard link, project dropdown, Inbox + form
|
||||
src/components/CardRow.vue one row in the Explore list: links to the card's own
|
||||
view + a status chip -- no inline editing, no delete (both
|
||||
live on that view now)
|
||||
src/components/KanbanCard.vue small draggable card, itself a link to the card's own
|
||||
view; used by the kanban board and the inbox
|
||||
src/components/PasskeyNotice.vue dismissible "add a passkey" banner across the top of the page
|
||||
src/components/ProjectManageMenu.vue "Manage" dropdown + delete-project modal, shared by ProjectView and ProjectConfigureView
|
||||
src/views/ DashboardView, ProjectView, ProjectConfigureView, LoginView,
|
||||
ProfileView, VerifyEmailView
|
||||
src/components/ManageMenu.vue generic "Manage" dropdown + delete-confirmation modal,
|
||||
shared by both entity pairs below
|
||||
src/components/ProjectManageMenu.vue / CardManageMenu.vue thin wrappers over
|
||||
ManageMenu.vue supplying what's project-/card-specific: routes,
|
||||
labels, and what deleting actually does
|
||||
src/components/StatusManager.vue a project's status list -- drag to reorder, add, delete
|
||||
with reassignment; used by ProjectConfigureView
|
||||
src/views/ DashboardView, LoginView, ProfileView, VerifyEmailView,
|
||||
ProjectView (layout) + ProjectExploreView + ProjectKanbanView,
|
||||
ProjectConfigureView, CardView, CardConfigureView
|
||||
```
|
||||
|
||||
Signed-in "app" routes (`meta.requiresAuth`) render inside a persistent shell:
|
||||
@@ -54,9 +71,10 @@ divider, a project `<select>`, another divider, then the **Inbox** (see below).
|
||||
The dropdown is a `v-model`-bound writable `computed` (`selectedProjectId`):
|
||||
its getter reads the open project from `route.params.id`, so it tracks
|
||||
whichever project is current; its setter `router.push`es to the chosen one, so
|
||||
it also works as a project switcher from anywhere. `<RouterView
|
||||
:key="route.path">` remounts the view on every path change so switching
|
||||
projects always does a fresh load.
|
||||
it also works as a project switcher from anywhere. `App.vue`'s top-level
|
||||
`<RouterView>` is keyed so switching projects (or cards) always does a fresh
|
||||
load -- see [Project detail](#project-detail) for why that key isn't simply
|
||||
the path.
|
||||
|
||||
Below `768px` (`style.css`'s one layout breakpoint) the sidebar becomes an
|
||||
off-canvas drawer instead of sitting beside the page: `position: fixed`,
|
||||
@@ -117,13 +135,14 @@ handful of conventions worth knowing before adding to it:
|
||||
A card with no project lives in the caller's inbox (`useInboxStore`), rendered
|
||||
in the sidebar under the project list -- not per-project, and not tied to
|
||||
whatever page is open. It's a `vuedraggable` list in the same `"kanban"` drag
|
||||
group as every project's kanban columns (below), so a card can be dragged
|
||||
straight out of the sidebar into any status column of whichever project is
|
||||
currently open, or the other way. `AppSidebar`'s `onInboxChange` persists a
|
||||
drop via `reorderColumn(null, null, ids)`, then reloads the inbox and, if a
|
||||
project view is currently mounted (`route.name === 'project'`), that project's
|
||||
cards too -- either side of a drag could have been the inbox. A small form
|
||||
under the list adds a card straight to the inbox.
|
||||
group as a project's Kanban columns and Explore list (below), so a card can
|
||||
be dragged straight out of the sidebar into any status column of whichever
|
||||
project is currently open (or Explore can send one the other way, though not
|
||||
receive one -- see [Explore](#explore)). `AppSidebar`'s `onInboxChange`
|
||||
persists a drop via `reorderColumn(null, null, ids)`, then reloads the inbox
|
||||
and, if a project's Explore or Kanban route is currently open, that
|
||||
project's cards too -- either side of a drag could have been the inbox. A
|
||||
small form under the list adds a card straight to the inbox.
|
||||
|
||||
Empty (no cards) is shown as a subtle dashed drop-area rather than blank
|
||||
space -- `.kanban__cards:empty` in `style.css`, so it's pure CSS keyed off the
|
||||
|
||||
@@ -7,9 +7,9 @@ type CardPatch = Partial<Pick<Card, 'text' | 'complete'>>
|
||||
|
||||
export const useCardsStore = defineStore('cards', () => {
|
||||
// One project's cards, grouped by status then position. Views re-sort as
|
||||
// needed (the "all tasks" list is alphabetical). Moving a card in or out of
|
||||
// this project (including via the inbox) goes through lib/cardOrder.ts,
|
||||
// not this store -- callers re-load() afterwards.
|
||||
// needed (Explore's list is alphabetical). Moving a card in or out of this
|
||||
// project (including via the inbox) goes through lib/cardOrder.ts, not
|
||||
// this store -- callers re-load() afterwards.
|
||||
const cards = ref<Card[]>([])
|
||||
const projectId = ref<number | null>(null)
|
||||
const loading = ref(false)
|
||||
|
||||
+1
-1
@@ -1036,7 +1036,7 @@ button[type="submit"]:disabled:not(.btn-icon),
|
||||
|
||||
/* A small square icon button, bordered like the compact field it sits
|
||||
beside -- every "add to X" form (a kanban column, the inbox, the status
|
||||
list, the "all tasks" new-card form) used a full "Add" label until there
|
||||
list, Explore's own new-card form) used a full "Add" label until there
|
||||
were enough of them on screen at once to feel cluttered, then a borderless
|
||||
ghost icon on its own looked adrift next to that field. Excluded
|
||||
(":not(.btn-icon)" above and on the .field-row/.kanban__new overrides)
|
||||
|
||||
Reference in New Issue
Block a user