145 lines
5.4 KiB
Markdown
145 lines
5.4 KiB
Markdown
# Knowledge View Task Consolidation — Design Spec
|
|
|
|
## Goal
|
|
|
|
Consolidate tasks into the Knowledge view as a card type, deprecate the standalone `/notes` and `/tasks` list views, and simplify navigation. The Knowledge view becomes the single hub for all content types: notes, tasks, people, places, and lists.
|
|
|
|
## Architecture
|
|
|
|
The Knowledge view already renders notes, people, places, and lists as typed cards in a filterable grid with a sidebar. Tasks are added as a fifth card type using the same two-tier pagination system (ID pre-fetch → content batch). The backend knowledge endpoints (`/api/knowledge/ids`, `/api/knowledge/batch`, `/api/knowledge/counts`) are extended to include tasks. No changes to the note/task CRUD API.
|
|
|
|
## Task Cards
|
|
|
|
Task cards follow the same layout as other knowledge cards:
|
|
|
|
- **Left accent strip**: distinct color for tasks (e.g. `#a78bfa` purple to differentiate from note indigo)
|
|
- **Type badge**: "Task" in top-right corner
|
|
- **Card body**:
|
|
- Title (2-line clamp)
|
|
- Status badge: `todo` / `in_progress` / `done` / `cancelled` — styled with existing status colors from theme (`--color-status-*`)
|
|
- Priority indicator: shown only when priority is not `none` — uses existing priority colors (`--color-priority-*`)
|
|
- Due date: shown when set, with overdue styling (`--color-overdue`) when past and status is not `done`/`cancelled`
|
|
- **Card footer**: tags (up to 3) + last-modified date — identical to other card types
|
|
|
|
Clicking a task card navigates to `/tasks/:id/edit` (same as today).
|
|
|
|
## Filter Sidebar Changes
|
|
|
|
The type filter section gains a "Tasks" button:
|
|
|
|
```
|
|
Type
|
|
──────────
|
|
[All] 127
|
|
[Notes] 84
|
|
[Tasks] 22
|
|
[People] 8
|
|
[Places] 5
|
|
[Lists] 8
|
|
```
|
|
|
|
The filter value for tasks is `type=task`. The backend already stores tasks as notes with `is_task=True`; the knowledge endpoints need to map the `type=task` filter to `is_task=True`.
|
|
|
|
## New Note Button Interaction
|
|
|
|
Current: click "New note" to create a note; chevron expands a dropdown with Note/Person/Place/List.
|
|
|
|
New behavior:
|
|
|
|
1. **Click "New note"** (when collapsed) → expands to reveal type options: Task, Person, Place, List. The main button label does not change.
|
|
2. **Click "New note"** again (when expanded) → navigates to `/notes/new` (generic note).
|
|
3. **Click any type option** → navigates to `/notes/new?type=<type>` (for task: `/notes/new?type=task`, which is equivalent to `/tasks/new`).
|
|
4. **Click outside** → collapses the dropdown.
|
|
|
|
This replaces the current chevron split-button pattern with a simpler toggle. The dropdown items are: Task, Person, Place, List (no "Note" item in the dropdown — clicking the button itself creates a note).
|
|
|
|
## Route Changes
|
|
|
|
### Redirects
|
|
|
|
| Old route | New behavior |
|
|
|-----------|-------------|
|
|
| `/notes` | 302 redirect → `/` (Knowledge view) |
|
|
| `/tasks` | 302 redirect → `/` (Knowledge view) |
|
|
|
|
### Preserved routes (no change)
|
|
|
|
| Route | Purpose |
|
|
|-------|---------|
|
|
| `/notes/:id` | Note viewer |
|
|
| `/notes/:id/edit` | Note editor |
|
|
| `/notes/new` | New note (with optional `?type=` param) |
|
|
| `/tasks/:id/edit` | Task editor |
|
|
| `/tasks/new` | New task |
|
|
|
|
### Router implementation
|
|
|
|
Add redirect entries in the router config:
|
|
|
|
```ts
|
|
{ path: '/notes', redirect: '/' },
|
|
{ path: '/tasks', redirect: '/' },
|
|
```
|
|
|
|
### Navigation
|
|
|
|
Remove from `AppHeader.vue`:
|
|
- "Tasks" nav link (`<router-link to="/tasks">`)
|
|
- The `/tasks` entry in both desktop nav-center and mobile menu
|
|
|
|
Remove from `AppHeader.vue` (already done — `/notes` was removed in a prior change, but verify).
|
|
|
|
### Deleted files
|
|
|
|
- `frontend/src/views/NotesListView.vue`
|
|
- `frontend/src/views/TasksListView.vue`
|
|
- `frontend/src/stores/notes.ts` (if only used by NotesListView)
|
|
- `frontend/src/stores/tasks.ts` (if only used by TasksListView)
|
|
|
|
Verify no other components import from these before deleting. The note/task viewer and editor screens import from `api/client.ts` directly, not from the list stores.
|
|
|
|
## Backend Changes
|
|
|
|
### `/api/knowledge/ids`
|
|
|
|
Accept `type=task` as a valid filter. When `type=task`, query `notes` table with `is_task = True`. When `type` is not set (all), include tasks in results alongside notes/people/places/lists.
|
|
|
|
### `/api/knowledge/batch`
|
|
|
|
Return task-specific fields for items where `is_task = True`:
|
|
- `status`: todo / in_progress / done / cancelled
|
|
- `priority`: none / low / normal / high
|
|
- `due_date`: ISO date string or null
|
|
|
|
These are already columns on the `Note` model — just include them in the batch response when the item is a task.
|
|
|
|
### `/api/knowledge/counts`
|
|
|
|
Add `task` to the counts response:
|
|
|
|
```json
|
|
{ "note": 84, "task": 22, "person": 8, "place": 5, "list": 8, "total": 127 }
|
|
```
|
|
|
|
### `/api/knowledge/tags`
|
|
|
|
No change — tasks already have tags on the same `Note` model.
|
|
|
|
## Keyboard Shortcuts
|
|
|
|
Remove from `App.vue` `onGlobalKeydown`:
|
|
- `case "t": router.push("/tasks/new")` — keep this, it still works
|
|
- `case "g"` sequence `case "t": router.push("/tasks")` — change to `router.push("/")` (direct navigation, don't rely on redirect)
|
|
|
|
Update shortcuts overlay panel text if it references "Tasks list".
|
|
|
|
## No API Endpoint Changes
|
|
|
|
All existing REST endpoints remain:
|
|
- `GET/POST /api/notes` — notes CRUD
|
|
- `GET/POST /api/tasks` — tasks CRUD
|
|
- `PATCH /api/notes/:id`, `PATCH /api/tasks/:id`
|
|
- `DELETE /api/notes/:id`, `DELETE /api/tasks/:id`
|
|
|
|
MCP tools (`fable_create_task`, `fable_list_tasks`, etc.) are unaffected.
|