Commit Graph

40 Commits

Author SHA1 Message Date
Gjermund Høsøien Wiggen
41fb10120c feat: add drag-to-rearrange and resize handles to dashboard widgets
Edit mode now supports:
- Drag handle (grip icon, top-left) to rearrange widgets via HTML5 DnD
  (drops swap widget positions, persists via API)
- Resize handle (corner icon, bottom-right) with mousedown→mousemove→mouseup
  tracking to change widget width/height in grid units, persists via API
- Cursor feedback: grab cursor on draggable widgets, se-resize on handle
- Visual feedback: dragging widget shows 50% opacity

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:41:04 +02:00
Gjermund Høsøien Wiggen
6ca8974eb9 feat: add edit mode toggle to dashboard page
- Edit/Done toggle button in header (pencil icon)
- Widget delete buttons only visible in edit mode
- Add widget button only visible in edit mode
- Empty state prompts to enter edit mode instead of adding directly
- Default is view mode — clean, no accidental deletes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:38:28 +02:00
Gjermund Høsøien Wiggen
9938c7a7ad feat: add team selector to dashboard page header
- Dropdown to assign/unassign dashboard to a team
- Updates immediately via PATCH
- createDashboard and updateDashboard API now accept team_id

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:35:40 +02:00
Gjermund Høsøien Wiggen
3616046b78 feat: add teams/groups with dashboard scoping
Schema:
- teams table (name unique, description)
- team_members table (team_id, user_id, unique constraint)
- team_id column on dashboards

API:
- GET/POST/PATCH/DELETE /teams
- POST /teams/:id/members (add user)
- DELETE /teams/:id/members/:userId (remove user)
- dashboards support team_id on create/update

Frontend:
- Teams tab in admin: CRUD + member management with add/remove
- Sidebar: dashboards filtered to user's teams
  (unassigned dashboards visible to all)
- Compact dashboard picker dropdown in sidebar

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:32:39 +02:00
Gjermund Høsøien Wiggen
c79cd183d4 refactor: replace dashboard sidebar list with compact dropdown
- Single-line select dropdown instead of one list item per dashboard
- Scales to any number of teams without clutter
- "+ New dashboard" as last option in dropdown
- Preserves the create flow with inline name input

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:24:33 +02:00
Gjermund Høsøien Wiggen
35b7f49518 fix: add-filter popover renders via portal to avoid stacking context
- Popover now renders via createPortal into document.body with z-index 9999
- This avoids the header backdrop-blur stacking context trapping it
- Add + button in Dashboards sidebar section to create dashboards
- Inline input on Dashboards section header, Enter to create/Escape to cancel

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:19:22 +02:00
Gjermund Høsøien Wiggen
f7e34f1690 feat: dashboard auto-refresh, collapsible sidebar, error retry
- Dashboard: auto-refresh toggle (30s interval, spins when live)
- Dashboard: responsive grid (6 cols mobile, 12 cols desktop)
- Sidebar: Dashboards, Saved views, Queues sections now collapsible
  with chevron toggle
- Error banner: added Retry button next to error message

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:14:47 +02:00
Gjermund Høsøien Wiggen
6263ce1332 feat: seed dashboard, fix My tickets filter
- Add demo dashboard with 7 widgets to seed script
- Dashboard is_default=true — appears as home page on fresh seed
- Add views/dashboards/dashboardWidgets to seed reset
- Fix My tickets: now filters by first non-system user (not any owner)
- Pass owner param in sidebar My tickets link
- Update page.tsx view=my to respect owner URL param
- Scrip engine already sorts by sort_order (verified)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:09:02 +02:00
Gjermund Høsøien Wiggen
c6c5272e50 feat: SQL filtering, Users admin tab, dashboard polish
- Move ticket filtering from in-memory to SQL WHERE clauses
  (queue_id, status, owner use Drizzle eq/isNull; text search uses ilike;
  custom field filters use EXISTS subqueries)
- Add limit param to GET /tickets
- Add POST/PATCH/DELETE /users routes
- Add Users tab to admin page with create/edit/delete
- Smart widget positioning in dashboard (3-column grid fill)
- Show pattern hint below CF inputs in New Ticket dialog

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:04:10 +02:00
Gjermund Høsøien Wiggen
affbbdaa46 feat: add template delete — backend DELETE route, frontend trash button
- DELETE /templates/:id — backend route
- deleteTemplate() API client function
- Trash icon on each template list item (shows on hover)
- Confirms inline, no dialog needed
- Resets builder if the deleted template was being edited

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 12:49:45 +02:00
Gjermund Høsøien Wiggen
7be90684fb fix: replace broken add-filter button with stepped filter builder
- Fixed popover z-index: uses fixed positioning with z-50 above backdrop
- Stepped flow: select field → set operator (is/is_not) → choose/write value → Apply
- Removed old inline CF value inputs (handled inline in the new flow)
- Fixed filter persistence: clear filters when navigating away from saved view
- Fixed home redirect: check for default dashboard on load

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 11:30:17 +02:00
Gjermund Høsøien Wiggen
b70a133ea2 feat: add dashboards — tables, CRUD API, widget data endpoint
- New dashboards table (name, description, layout, is_default)
- New dashboard_widgets table (view_id, title, widget_type, position, config)
- GET/POST/PATCH/DELETE /dashboards
- GET/POST/PATCH/DELETE /dashboards/:id/widgets
- GET /dashboards/:id/widgets/:id/data — runs saved view filters,
  returns pre-aggregated data for count/ticket_list/status_chart/grouped_counts
- is_default uniqueness enforced on PATCH

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 11:26:22 +02:00
Gjermund Høsøien Wiggen
aa90b88991 feat: add saved views — database table, CRUD API, migration
- New views table (id, name, filters jsonb, sort_key, is_public, creator_id)
- GET/POST/PATCH/DELETE /views endpoints
- Register views router in server

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 11:10:25 +02:00
Gjermund Høsøien Wiggen
000e97e1bd feat: implement inline editing for custom fields in ticket sidebar
- Show CF values as read-only text with edit affordance (pencil icon on hover)
- Click to enter edit mode: inline input (free-text) or select (choice fields)
- Save on blur or Enter, cancel on Escape — reverts to original value
- Auto-save for select fields on change
- Loading spinner while saving
- Remove now-unused customFieldValue helper

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:55:45 +02:00
Gjermund Høsøien Wiggen
aa808f1d3f feat: return scrip results on ticket create, update frontend types
- POST /tickets now returns { ticket, scrip_results } matching PATCH pattern
- createTicket API function returns UpdateResult instead of Ticket
- Update call site to use data.ticket.id

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:51:14 +02:00
Gjermund Høsøien Wiggen
06cc7c79a3 feat: enhance frontend UI — command palette, admin redesign, API coverage
Types + API:
- Add User, TemplatePreview, QueueCustomField types
- Add getUsers, getTemplates, createTemplate, updateTemplate,
  previewTemplate, updateQueue, updateLifecycle, updateCustomField API functions

UI:
- Command palette: keyboard-first navigation with fuzzy ticket search
- Admin: comprehensive redesign with tab-based layout (Queues, Lifecycles,
  Scrips, Custom Fields, Templates, Users)
- Ticket list: improved inbox-style rows with quick actions
- Ticket detail: enhanced conversation thread and properties sidebar
- App shell: sidebar visual refinement with active indicator bar
- Theme toggle: smoother transitions

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:43:28 +02:00
Gjermund Høsøien Wiggen
08b52426b0 Implement ticket reply functionality
Backend:
- POST /:id/comment endpoint accepting {body, internal?, creator_id?}
- internal=false → Correspond (public reply), internal=true → Comment
- Runs scrip engine on the new transaction so notifications fire
- CommentSchema zod validation

Frontend:
- sendComment() API function in lib/api.ts
- Send button wired with onClick, sending spinner, disabled state
- Error display below reply box, clears on new typing
- Refreshes transaction list after successful send
- Reply/Internal note mode passed as internal flag
2026-06-07 23:28:46 +02:00
Gjermund Høsøien Wiggen
04b4e28d21 Change ticket IDs from UUID to sequential integers
Backend:
- tickets.id: uuid → integer GENERATED ALWAYS AS IDENTITY
- transactions.ticket_id, custom_field_values.ticket_id: uuid → integer
- Routes convert string params to Number() for DB queries
- ScripEngine.prepare takes ticketId: number
- ActionPayload.ticketId: string → number

Frontend:
- Ticket.id: string → number, Transaction.ticket_id: string → number
- API functions accept number params
- formatTicketId() helper returns TKT-0001 format
- Ticket rows display TKT-XXXX, detail page uses formatTicketId

Migration: drops FKs, clears data, alters column types, re-adds FKs
2026-06-07 23:23:05 +02:00
Gjermund Høsøien Wiggen
7da52dfff6 Revert to single-column ticket list with inbox-style rows
- Remove three-column layout, inline detail panel, and properties sidebar
- Click a ticket navigates to /tickets/[id] via router.push
- Redesign TicketRow as inbox-style: status dot, bold subject on top line,
  muted ID/queue/owner meta on second line, time right-aligned
- Cleaner visual hierarchy with increased padding and gap
2026-06-07 23:14:59 +02:00
Gjermund Høsøien Wiggen
86e00b076a Add properties sidebar to inline ticket detail panel
- Two-column layout inside TicketDetailPanel: conversation (left) + sidebar (right)
- Status section: Select dropdown with all statuses, previewTicket + updateTicket flow with Apply/Cancel
- Assignment section: read-only assignee display with avatar initial
- Details section: queue name, created/updated/resolved dates
- Custom fields section: name:value pairs when present
- Sidebar skeleton during loading
- Fetches queue info alongside ticket data for display
2026-06-07 23:13:00 +02:00
Gjermund Høsøien Wiggen
88ab30a7fd Fix transaction_type case mismatch in both ticket pages
Backend returns PascalCase (Create, StatusChange, SetOwner, Comment, Correspond).
Frontend was checking lowercase, causing transaction rendering to fall through to raw type strings.
2026-06-07 23:06:25 +02:00
Gjermund Høsøien Wiggen
737e8942f6 Redesign ticket list to three-column layout with proportional widths
- Replace Sheet slide-over with inline peer detail column
- List column: 40% width (min 360px) when ticket selected, flex-1 otherwise
- Detail column: 60% width (min 480px), slides in from right (300ms)
- Mobile: list hidden when ticket selected, detail becomes full-width
- Subtle border-r divider on list column
- Taller ticket rows (py-4) with smooth hover transitions
- width transition on list column resize
2026-06-07 23:00:45 +02:00
Gjermund Høsøien Wiggen
10962f795f feat: three-column ticket list layout (list + detail as peers, no Sheet)
- Replace Sheet slide-over with persistent right-column detail panel
- Ticket list shrinks to w-80 when ticket selected, detail takes flex-1
- Animated transition (300ms ease-out) when selecting/deselecting
- Kept existing conversation thread, properties sidebar, reply box inline
2026-06-07 22:58:50 +02:00
Gjermund Høsøien Wiggen
784d30acbd fix: wrap TicketListPage in Suspense boundary for useSearchParams 2026-06-07 22:46:34 +02:00
Gjermund Høsøien Wiggen
6f2b0f39f7 feat: breadcrumb nav, grouped properties sidebar, larger status selector, transitions 2026-06-07 22:34:31 +02:00
Gjermund Høsøien Wiggen
8175b05b23 feat: fuzzy ticket search in command palette, improved styling 2026-06-07 22:34:28 +02:00
Gjermund Høsøien Wiggen
b2423f2821 feat: inbox-style ticket rows, Sheet detail slide-over, gradient New Ticket button 2026-06-07 22:34:27 +02:00
Gjermund Høsøien Wiggen
b05eb8b2d4 feat: add sidebar collapse/expand, theme-toggle, theme-aware colors 2026-06-07 22:34:26 +02:00
Gjermund Høsøien Wiggen
10005799fb feat: add theme-toggle component with next-themes sun/moon icons 2026-06-07 22:34:26 +02:00
Gjermund Høsøien Wiggen
87bd6997e3 Add light mode support (next-themes), JetBrains Mono font, OpenType features
- layout.tsx: ThemeProvider from next-themes, light mode DEFAULT, JetBrains_Mono font
- globals.css: font-mono pointing to correct variable, font-feature-settings cv01+ss03 on body
- next-themes package installed
- Build passes with zero errors
2026-06-07 22:29:52 +02:00
Gjermund Høsøien Wiggen
77860eb6c4 Redesign: Linear-inspired dark mode frontend
Complete rewrite of all pages:
- layout.tsx: App shell with 240px sidebar (saved views, queue list, admin link)
- app-shell.tsx: Client sidebar component with route highlighting + counts
- page.tsx: Sleek ticket list with filter chips (All/Open/In progress/Resolved), search bar, status dots, assignee avatars, skeleton loading
- tickets/[id]/page.tsx: Two-panel conversation layout — message thread (left) + properties sidebar (right) with status change, scrip preview, reply box
- admin/page.tsx: Suspense-wrapped admin with tabs in sheet panels
- command-palette.tsx: Cmd+K search with keyboard navigation

Design tokens from Linear:
- bg-[#08090a] canvas, bg-[#0f1011] panels, bg-[#191a1b] cards
- text-[#f7f8f8] primary, text-[#d0d6e0] secondary, text-[#8a8f98] tertiary
- borders: rgba(255,255,255,0.08) standard, rgba(255,255,255,0.05) subtle
- accent: #5e6ad2 primary, #7170ff interactive
- status colors: new=gray, open=indigo, in_progress=amber, resolved=green
- Inter font, weights 400/510/590, no pure white

Fixed: Suspense boundaries for useSearchParams in layout and admin pages
Build: passes with zero errors
2026-06-07 22:16:18 +02:00
Gjermund Høsøien Wiggen
49834f5215 fix: API proxy — strip /api prefix in rewrite (backend routes don't use /api) 2026-06-07 22:05:30 +02:00
Gjermund Høsøien Wiggen
73cf283f06 Add admin page with 4 tabs for managing queues, lifecycles, scrips, and custom fields 2026-06-07 22:02:11 +02:00
Gjermund Høsøien Wiggen
1029176873 Add ticket detail page with transaction timeline and status change 2026-06-07 22:02:08 +02:00
Gjermund Høsøien Wiggen
a49e888011 Add ticket list page with filters, status badges, create dialog 2026-06-07 22:02:06 +02:00
Gjermund Høsøien Wiggen
f69678db4b Add dark theme root layout with Inter font and nav bar 2026-06-07 22:02:03 +02:00
Gjermund Høsøien Wiggen
00dd21f4dd Add typed fetch API client with 15 endpoint functions 2026-06-07 22:02:01 +02:00
Gjermund Høsøien Wiggen
59d66b3392 Add TypeScript interfaces for Tessera domain types 2026-06-07 22:01:58 +02:00
Gjermund Høsøien Wiggen
6b7d8c4aba Fix next.config.ts API proxy, add web pages spec 2026-06-07 21:56:36 +02:00
Gjermund Høsøien Wiggen
9b1af0b7b3 Add Next.js + shadcn/ui scaffold with deps
- Next.js 15 App Router, TypeScript, Tailwind CSS
- shadcn/ui components: button, input, select, textarea, dialog, tabs, table, card, badge, label, separator, dropdown-menu, form, sheet, tooltip
- Runtime deps: @tanstack/react-table, zod, react-hook-form, @hookform/resolvers, lucide-react, date-fns
2026-06-07 21:55:54 +02:00