# Task Fix: Quotation Template JSON Viewer Overflow & Sheet Refactor
## Status
Planned Fix
## Objective
Fix the Quotation Template settings page layout overflow caused by rendering a full PDFME JSON schema inline.
The page should no longer render large JSON content directly in the main content area. Instead, each template version should expose a compact `View JSON` action that opens a scrollable Sheet viewer.
This fix improves:
* page readability
* button visibility
* layout stability
* JSON review experience
* future maintainability for large PDFME templates
---
## Problem
Current page:
```txt
/dashboard/crm/settings/templates
```
renders full JSON schema inline.
Observed issue:
* full JSON expands vertically and horizontally
* content overflows the visible page
* buttons/actions become hard to find
* page is difficult to operate
* JSON block dominates the whole settings page
Current pattern is likely similar to:
```tsx
{JSON.stringify(schemaJson, null, 2)}
```
or:
```tsx
{JSON.stringify(version.schemaJson, null, 2)}
```
This should be removed from the main page layout.
---
## Screenshot Context
Current UI shows:
```txt
Quotation Templates
Template Configuration Center
ALLA Quotation Standard
Version 1.0
Large inline JSON block
```
The large inline JSON causes the page to become visually noisy and may hide or push important actions away from the viewport.
---
## Mandatory Review
Review before implementation:
```txt
src/app/dashboard/crm/settings/templates/**
src/features/crm/document-templates/**
src/features/crm/quotations/**
src/components/ui/sheet.tsx
src/components/ui/button.tsx
```
Also search for inline JSON rendering:
```bash
rg "JSON.stringify|schemaJson|schema_json|
{JSON.stringify(schemaJson, null, 2)}
```
Correct:
```tsx
```
---
## Scope 2: Create Template JSON Sheet Component
Create component:
```txt
src/features/crm/document-templates/components/template-json-sheet.tsx
```
If the feature folder differs, place it near the current template settings components.
Component props:
```ts
type TemplateJsonSheetProps = {
version: string;
filePath?: string | null;
schemaJson: unknown;
triggerLabel?: string;
};
```
Required behavior:
* client component
* uses shadcn `Sheet`
* trigger button opens Sheet
* formats JSON with `JSON.stringify(schemaJson ?? {}, null, 2)`
* displays JSON inside scrollable area
* includes copy-to-clipboard button
* handles invalid or empty JSON safely
* does not crash if schemaJson is null
---
## Scope 3: Sheet Layout Rules
Use:
```tsx
```
or if project layout requires:
```tsx
```
JSON block should use:
```txt
max-h-[calc(100vh-180px)]
overflow-auto
rounded-lg
border
bg-muted
p-4
font-mono
text-xs
whitespace-pre
```
Important:
* JSON scrolls inside Sheet
* main page does not grow because of JSON
* horizontal JSON overflow is contained inside Sheet
* Sheet remains usable on smaller screens
---
## Scope 4: Copy JSON Action
Add:
```txt
Copy JSON
```
Behavior:
* copy formatted JSON to clipboard
* show success toast if toast utility exists
* if no toast utility exists, copy silently or use existing notification pattern
Recommended:
```tsx
await navigator.clipboard.writeText(formattedJson);
toast.success('Copied JSON');
```
Rules:
* do not import a new toast library if project already has one
* use existing toast/sonner convention
---
## Scope 5: Compact Version Card UI
Refactor version display.
Instead of showing JSON inline, display a compact card section like:
```txt
Version 1.0
src/pdfme_template/ALLA_template_pdfme_fainal3.json
Mappings: 12
Table Columns: 24
Status: Active
[View JSON]
```
If mapping counts are already available, use them.
If not available, show only safe existing metadata.
Do not introduce extra server queries unless necessary.
---
## Scope 6: Empty / Missing JSON State
If `schemaJson` is missing:
Sheet should show:
```txt
No schema JSON available.
```
or:
```json
{}
```
Do not throw runtime error.
---
## Scope 7: Optional JSON Summary
If easy, add small metadata before the button:
```txt
Pages: n
Schemas: n
PDFME Version: x
```
Possible calculation:
```ts
const pageCount = Array.isArray(schemaJson?.schemas)
? schemaJson.schemas.length
: 0;
```
This is optional and should not block the fix.
---
## Scope 8: Accessibility
Requirements:
* button label must be clear
* Sheet title must exist
* code block should be selectable
* copy button should have visible text, not icon only
* no hidden overflow on the whole page
---
## Scope 9: Do Not Change Template Data Model
This is UI-only.
Do not change:
```txt
crm_document_templates
crm_document_template_versions
crm_document_template_mappings
crm_document_template_table_columns
PDFME schema format
template seed behavior
template upload behavior
quotation PDF generation
```
---
## Suggested Component Example
```tsx
'use client';
import { useMemo } from 'react';
import { Copy, Eye } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger
} from '@/components/ui/sheet';
type TemplateJsonSheetProps = {
version: string;
filePath?: string | null;
schemaJson: unknown;
triggerLabel?: string;
};
export function TemplateJsonSheet({
version,
filePath,
schemaJson,
triggerLabel = 'View JSON'
}: TemplateJsonSheetProps) {
const formattedJson = useMemo(() => {
try {
return JSON.stringify(schemaJson ?? {}, null, 2);
} catch {
return '{}';
}
}, [schemaJson]);
const handleCopy = async () => {
await navigator.clipboard.writeText(formattedJson);
toast.success('Copied JSON');
};
return (
Template Schema JSON
Version {version}
{filePath ? ` ยท ${filePath}` : ''}
{formattedJson}
);
}
```
Adjust import paths and formatting to match the project style.
---
## Scope 10: Page-Level Overflow Guard
Review parent containers.
Ensure the templates page does not use layout classes that create viewport overflow unexpectedly.
Recommended:
```txt
space-y-6
overflow-hidden only when intentional
min-w-0 on flex/grid children
```
If cards contain long paths, use:
```txt
truncate
break-all
```
For file paths:
```tsx
{filePath}
```
---
## Verification
Run:
```bash
npm exec tsc --noEmit
npm run build
```
Manual verification:
```txt
Open /dashboard/crm/settings/templates
Page no longer shows full JSON inline
Page does not overflow because of JSON
Template version card remains compact
View JSON button is visible
Click View JSON
Sheet opens from right side
JSON displays formatted
JSON scrolls inside Sheet
Copy JSON works
Close Sheet
No regression in quotation PDF preview/download
```
Search verification:
```bash
rg "JSON.stringify|