feat(documents): universal upload-with-fields UI wiring (B3 #11)
Backend foundations were already in place ('generic' CustomDocumentType,
storage-path routing). This wires the UI surface across Documents Hub +
entity file tabs.
- UploadForSigningDialog: interestId now string | null; new entity?,
folderId?, onCreated? props. Generic path POSTs to new endpoint
/api/v1/upload-for-signing; interest-scoped paths unchanged.
- uploadDocumentForSigning service: interestId nullable; skips interest
lookup, pipeline-stage advance, doc-status flip on the generic path.
Routes file FK + auto-filed folder via either interest.clientId or the
caller-supplied entity. Validation enforces the matching invariant
(generic must be interestId=null, type-specific must carry one).
- New menu item in NewDocumentMenu ("Upload & send for signature") on
Documents Hub root + folder views.
- Upload & send-for-signature button on ClientFilesTab + CompanyFilesTab,
gated by documents.send_for_signing.
Existing unit tests for the service still pass (validation paths unchanged).
This commit is contained in:
@@ -688,6 +688,7 @@ _New UI surfaces, new endpoints, schema migrations, multi-step flows._
|
||||
10. **Comprehensive admin-settings IA audit + regroup** — _src/app/(dashboard)/[portSlug]/admin/_ — 41 admin pages today, organically grown: `ai`, `audit`, `backup`, `berths/bulk-add`, `berths/reconcile`, `branding`, `brochures`, `custom-fields`, `documenso`, `duplicates`, `email-templates`, `email`, `errors`, `forms`, `import`, `inquiries`, `invitations`, `monitoring`, `ocr`, `onboarding`, `pipeline-rules`, `ports`, `pulse`, `qualification-criteria`, `reminders`, `reports`, `residential-stages`, `roles`, `sends`, `settings`, `storage`, `tags`, `templates`, `users`, `vocabularies`, `webhooks`, `website-analytics`. Settings are scattered — e.g. test-email lives on Branding, SMTP test on Email, password-reset copy probably in `email-templates`, but the rep has to guess. Audit each page for: (a) what settings live there now, (b) which settings logically belong elsewhere ("right home" test — Documenso send mode currently lives on Documenso, makes sense; per-port email signature would make more sense under Branding than Email), (c) duplicates (vocabularies vs custom-fields vs qualification-criteria overlap on enum tuning). Then propose a regrouped IA — likely fewer top-level pages with clear domain headers (Configuration → Branding, Email, Documenso, Storage, Webhooks; Workflows → Pipeline rules, Reminders, Auto-stage advancement; Catalog → Vocabularies, Tags, Custom fields, Qualification criteria; Operations → Monitoring, Pulse, Audit log, Errors, Backup; Data → Import, Duplicates, Bulk berth tools; Identity → Users, Roles, Invitations, Onboarding). Pair with a new admin index page that groups by domain instead of a flat alphabetical list. Effort: ~1.5-2 days — audit pass + IA proposal review + actual file moves + nav updates + redirect shims for old URLs. Captured 2026-05-22.
|
||||
- **SHIPPED in this session (Phase 1 + Phase 2):** Full audit + proposal at `docs/admin-ia-proposal.md`. Final IA = 7 domains, 38 pages (down from 41 via three deletes). `admin-sections-browser.tsx` rewritten to the new domain shape (Brand & Communication, Sales workflow, Catalog, Identity & access, Inbox & data quality, Integrations, System & observability). Deleted with redirects: `/admin/ocr` → `/admin/ai`, `/admin/reports` → `/[portSlug]/dashboard`, `/admin/invitations` → `/admin/users` (this last one was already a redirect). Renamed: "Documenso & EOI" → "Signing service (Documenso)". New: `/admin/berths` index page surfacing bulk-add + reconcile sub-tools (which were previously discoverable only via deep links). `<EmailPreviewCard>` on Branding cross-links to `/admin/email` per-template tester. Search-nav-catalog updated (ocr entry removed, berths entry added). tsc clean.
|
||||
11. **B3 #9 follow-up — UI wiring for universal upload-with-fields** — _src/components/documents/upload-for-signing-dialog.tsx_ (`<FieldPlacementStep>` lives inside this monolith — needs extraction into a standalone component the other upload modals can mount conditionally), _src/components/documents/new-document-menu.tsx_ + _src/components/documents/documents-hub.tsx_ + _src/components/files/file-upload-zone.tsx_ + entity-tab upload sites (client/yacht/company doc tabs). **Backend foundations SHIPPED 2026-05-22**: `CustomDocumentType` union now includes `'generic'`; `uploadDocumentForSigning` skips pipeline-stage advance + doc-status flip when generic; route validator accepts the new value; storage path category routes to `signed-source/`. **UI half deferred** to a paired session — needs careful surgery to each upload modal to add the "Send for signature?" toggle + mount the extracted field-placement step. Effort for UI wiring: ~5-7h. Captured 2026-05-22.
|
||||
- **SHIPPED in this session:** `UploadForSigningDialog` now accepts `interestId: string | null`, `entity?: { type, id }`, `folderId?` and `onCreated?` callback. When `interestId` is null + `documentType='generic'`, the dialog POSTs to a new generic endpoint `/api/v1/upload-for-signing` instead of the interest-scoped one. The service was refactored to accept `interestId: string | null` and an optional `entity` arg, skips the pipeline-stage advance + doc-status flip + interest lookup on the generic path, and routes the file row's FK + auto-filed folder via either the interest's client or the caller-supplied entity. New menu item in `NewDocumentMenu` ("Upload & send for signature") appears on both Documents Hub root + folder views; new buttons under `FileUploadZone` on `ClientFilesTab` + `CompanyFilesTab`. Permission gated by `documents.send_for_signing`. Service-level validation enforces the invariant that generic-type uploads MUST come without interestId and vice-versa.
|
||||
12. **Time-period PDF report + chart rendering + deeper data** — _src/lib/pdf/reports/dashboard-report.tsx_, _src/lib/services/dashboard-report-data.service.ts_, _src/lib/pdf/reports/types.ts_, new _src/lib/pdf/reports/charts.tsx_, _src/components/reports/export-dashboard-pdf-button.tsx_ (date-range picker). Today's PDF report ignores dateFrom/dateTo for most sections and renders every chart-style widget as a table. User wants: (a) **time-range filter** that scopes EVERY section to a chosen window — new clients in the window, new interests in the window, active interests touching the window, in-progress berths (sold/under-offer transitions in the window), pipeline counts at the start vs end of window, etc.; (b) **chart rendering** — react-pdf supports SVG, so build small SVG generators (`<PipelineFunnel data>`, `<OccupancyTimeline data>`, `<SourceMixDonut data>`) inline OR pre-render via vega-lite/d3-node to PNG and embed; (c) **deeper data per section** — add berths-in-flight (status changes within window), client+interest cohort tables, contact-cadence histogram, document-signing throughput. Shape: extend `DashboardReportData` with `window: {from, to}` and new sub-sections; extend the export-PDF dialog to take a date-range; route handler propagates the window to every per-section resolver. Effort: ~8-12h depending on chart-rendering approach (inline SVG is ~6h, vega-lite pre-render is ~10h with a worker round-trip). Captured 2026-05-22.
|
||||
- **SHIPPED in this session:** Catalog expanded from 5 ids to 25 — chart variants (pipeline funnel bar, berth status donut, source conversion bar, lead source donut, occupancy timeline line) + period cohorts (new clients/interests, berths sold, deposits received, documents/contracts signed) + value views (pipeline value breakdown, revenue forecast, avg sales cycle, berth demand, country distribution, deal pulse distribution, recent activity). Hand-rolled SVG chart primitives in `src/lib/pdf/reports/charts.tsx` (HorizontalBarChart, DonutChart, LineChart) using @react-pdf/renderer's native Svg/Path/Rect support. Export-dialog grew a date-range picker with Last-30/90-days quick presets, defaults to last 30 days. Route + service plumbing carries dateFrom/dateTo. 11 of 16 pending resolvers landed (new_clients_period, new_interests_period, berths_sold_period via audit log, deposits_received_period, signed_documents_period, contracts_signed_period, berth_demand_ranking, lead_source_donut, client_country_distribution, recent_activity, pipeline_value_breakdown, revenue_forecast, avg_sales_cycle). Still pending (in this session's PENDING_RESOLVER_IDS set): stage_conversion_rates, occupancy_timeline_chart (needs daily buckets), inquiry_inbox_summary, reminders_summary, deal_pulse_distribution (requires the pulse service's dynamic computation, not a simple column query — left as follow-up). Also shipped: PDF logo absolutize for server-side fetch (was empty because @react-pdf/renderer can't fetch path-only URLs server-side), "Dashboard report" → "Report" default name, section-orphan fix (`wrap={false}` + `minPresenceAhead`).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user