333 lines
11 KiB
Markdown
333 lines
11 KiB
Markdown
# Research: Feature 002 - Filament JSON UI
|
|
|
|
**Date**: 2025-12-13
|
|
**Phase**: Phase 0 & 2 (Foundational Research)
|
|
**Status**: In Progress
|
|
|
|
---
|
|
|
|
## T002: Asset Publishing Requirements
|
|
|
|
### Investigation Results
|
|
|
|
**Package**: `pepperfm/filament-json:^4`
|
|
**Installation Status**: ✅ Successfully installed
|
|
|
|
#### Assets Published Automatically
|
|
|
|
During `composer require`, Filament's post-install hook automatically published assets:
|
|
|
|
```
|
|
⇂ public/css/pepperfm/filament-json/filament-json-styles.css (11 KB)
|
|
```
|
|
|
|
**Total Size**: ~12 KB (minimal)
|
|
|
|
#### Asset Source Locations
|
|
|
|
Assets exist in vendor directory:
|
|
- `vendor/pepperfm/filament-json/resources/css/filament-json.css`
|
|
- `vendor/pepperfm/filament-json/resources/css/index.css`
|
|
- `vendor/pepperfm/filament-json/resources/dist/filament-json.css`
|
|
- `vendor/pepperfm/filament-json/resources/js/index.js`
|
|
|
|
#### Auto-Loading Mechanism
|
|
|
|
**Finding**: Filament packages typically auto-register their assets via service providers. The `php artisan filament:upgrade` command that ran during installation published the assets to `public/`.
|
|
|
|
**Asset Publishing Strategy**:
|
|
- ✅ **Assets ARE auto-published during composer install** (via `filament:upgrade` hook)
|
|
- ✅ **Size is minimal** (~12 KB total)
|
|
- ✅ **No manual publishing required** in normal workflow
|
|
|
|
### Recommendations
|
|
|
|
1. **Commit the published assets**: Since they're small (12 KB) and auto-generated, committing them ensures consistent deployment without requiring build steps.
|
|
|
|
2. **Alternative (for cleaner git history)**: Add to `.gitignore` and ensure deployment runs:
|
|
```bash
|
|
php artisan filament:upgrade
|
|
```
|
|
However, this adds a deployment step dependency.
|
|
|
|
3. **Chosen Strategy**: **Commit assets** (recommended)
|
|
- Reason: Minimal size, deployment simplicity, no runtime dependency on npm/build steps
|
|
- Trade-off: Slightly larger git history, but predictable deploys
|
|
|
|
---
|
|
|
|
## T004: Filament 4 Infolist Support
|
|
|
|
### Investigation Status
|
|
|
|
✅ **Complete**: Package investigation finished
|
|
|
|
### Findings
|
|
|
|
**Package Type**: `pepperfm/filament-json` is designed for **Table Columns**, not Infolist Entries.
|
|
|
|
**Available Class**: `PepperFM\FilamentJson\Columns\JsonColumn` (extends Filament Table Column)
|
|
|
|
**Infolist Support**: ❌ No dedicated infolist entry class found in package source
|
|
|
|
### Integration Strategy for ViewPolicy (Infolist Page)
|
|
|
|
Since the package is table-focused, we have **three options**:
|
|
|
|
#### Option 1: Use TextEntry with Custom View (Recommended)
|
|
```php
|
|
use Filament\Infolists\Components\TextEntry;
|
|
|
|
TextEntry::make('snapshot')
|
|
->label('Policy Snapshot')
|
|
->view('filament.infolists.entries.json-viewer')
|
|
->columnSpanFull()
|
|
```
|
|
|
|
Create custom view at `resources/views/filament/infolists/entries/json-viewer.blade.php` that renders JSON with similar styling to pepperfm package.
|
|
|
|
**Pros**: Clean, follows Filament patterns, full control
|
|
**Cons**: Need to implement JSON formatting ourselves
|
|
|
|
#### Option 2: Embed Table in Infolist (Workaround)
|
|
```php
|
|
use Filament\Infolists\Components\Section;
|
|
|
|
Section::make('Snapshot')
|
|
->schema([
|
|
// Embed a mini-table with one row just to use JsonColumn
|
|
])
|
|
```
|
|
|
|
**Pros**: Leverages pepperfm package directly
|
|
**Cons**: Hacky, table overhead for single record
|
|
|
|
#### Option 3: Simple Pretty-Print JSON (Quick MVP)
|
|
```php
|
|
TextEntry::make('snapshot')
|
|
->label('Policy Snapshot')
|
|
->formatStateUsing(fn ($state) => '<pre class="text-xs overflow-x-auto">' . json_encode($state, JSON_PRETTY_PRINT) . '</pre>')
|
|
->html()
|
|
->columnSpanFull()
|
|
```
|
|
|
|
**Pros**: Zero dependencies, fastest implementation
|
|
**Cons**: No fold/collapse, basic styling only
|
|
|
|
### Recommendation
|
|
|
|
**For MVP (Phase 3)**: Use **Option 3** (simple pretty-print) to unblock User Story 1 quickly.
|
|
|
|
**For Polish (Phase 6)**: Enhance with **Option 1** (custom view) to add fold/collapse/copy features using a lightweight JS library (like `json-viewer` npm package or Alpine.js component).
|
|
|
|
**Verdict**: Package is table-column only, but we can achieve similar UX in infolists with custom views.
|
|
|
|
---
|
|
|
|
## T005: Available JSON Viewer Features
|
|
|
|
### Investigation Status
|
|
|
|
✅ **Complete**: Package features documented from README
|
|
|
|
### Available Features (pepperfm/filament-json)
|
|
|
|
**Render Modes**:
|
|
- ✅ **Tree** mode: Expandable/collapsible JSON tree structure
|
|
- ✅ **Table** mode: Key-value pairs in table format
|
|
|
|
**Presentation Modes**:
|
|
- ✅ **Inline**: Pretty-printed raw JSON in-cell (with click-to-copy)
|
|
- ✅ **Modal**: JSON in modal overlay
|
|
- ✅ **Drawer**: JSON in side drawer
|
|
|
|
**Interactive Features**:
|
|
- ✅ **Copy-to-clipboard**: Click JSON block or use "Copy JSON" button
|
|
- ✅ **Expand all / Collapse all**: Toolbar buttons for Tree mode (modal/drawer only)
|
|
- ✅ **Initially collapsed**: Auto-collapse to specified depth
|
|
- ✅ **Character limit**: Truncate long string values
|
|
- ✅ **Filter nullable**: Hide null/empty values
|
|
|
|
**Styling**:
|
|
- ✅ **Light/dark mode**: Automatic theme support
|
|
- ✅ **Monospace formatting**: Built-in for JSON display
|
|
- ✅ **Compiled CSS**: No build steps required (ships with package)
|
|
|
|
### Missing Features (not supported by package)
|
|
|
|
- ❌ **Search within JSON**: Not available
|
|
- ❌ **Line numbers**: Not mentioned in docs
|
|
- ❌ **Syntax highlighting**: Basic styling only
|
|
|
|
### Gap Analysis vs. Spec Requirements (FR-036)
|
|
|
|
| Spec Requirement | Package Support | Status |
|
|
|------------------|-----------------|--------|
|
|
| Fold/collapse | ✅ Tree mode | Supported |
|
|
| Search | ❌ Not available | **Missing** |
|
|
| Copy-to-clipboard | ✅ Built-in | Supported |
|
|
| Monospace formatting | ✅ Built-in | Supported |
|
|
| Large payload handling | Manual via characterLimit() | Partial |
|
|
|
|
### Impact Assessment
|
|
|
|
**Minor Gap**: Search feature is missing from package. However, browser's native find-in-page (Cmd+F) can search within rendered JSON as fallback.
|
|
|
|
**Verdict**: Package meets 4/5 core requirements. Acceptable for MVP.
|
|
|
|
---
|
|
|
|
## T009: Optimal Filament Integration Pattern
|
|
|
|
### Investigation Status
|
|
|
|
⏳ **Pending**: Research best practice for adding JSON viewer to infolist
|
|
|
|
### Options to Explore
|
|
|
|
1. **ViewEntry with custom view**:
|
|
```php
|
|
ViewEntry::make('snapshot')
|
|
->view('filament.infolists.entries.json-viewer')
|
|
```
|
|
|
|
2. **Custom infolist entry class**:
|
|
```php
|
|
JsonEntry::make('snapshot')
|
|
->collapsible()
|
|
```
|
|
|
|
3. **TextEntry with package formatting**:
|
|
```php
|
|
TextEntry::make('snapshot')
|
|
->formatStateUsing(fn ($state) => view('pepperfm::json-viewer', ['data' => $state]))
|
|
```
|
|
|
|
**Next Action**: Review pepperfm/filament-json source code for recommended integration pattern.
|
|
|
|
---
|
|
|
|
## Asset Publishing Decision (T003)
|
|
|
|
### Decision: Commit Assets to Repository
|
|
|
|
**Rationale**:
|
|
1. **Small size**: ~12 KB total (negligible git impact)
|
|
2. **Deployment simplicity**: No build steps required
|
|
3. **Consistency**: All deployments use identical assets
|
|
4. **Dokploy compatibility**: VPS deployment doesn't need composer post-hooks
|
|
5. **Staging/Production parity**: Assets guaranteed to match across environments
|
|
|
|
### Documentation Location
|
|
|
|
Documented in:
|
|
- This file (`research.md`)
|
|
- Plan.md Risks section (already mentions asset publishing)
|
|
|
|
### Deployment Notes
|
|
|
|
**No additional steps required** - assets are part of the repository.
|
|
|
|
If assets need regeneration (e.g., after package update):
|
|
```bash
|
|
php artisan filament:upgrade
|
|
```
|
|
|
|
### Git Changes Expected
|
|
|
|
When committing:
|
|
```
|
|
A public/css/pepperfm/filament-json/filament-json-styles.css
|
|
```
|
|
|
|
**Status**: ✅ Decision documented, ready for Phase 3 implementation
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. Complete T004-T005: Package feature investigation
|
|
2. Proceed to T006: Create quickstart.md with usage examples
|
|
3. Begin Phase 3: User Story 1 implementation (T007-T012)
|
|
|
|
**Phase 1 Status**: ✅ Complete (T001-T003)
|
|
**Phase 2 Status**: ✅ Complete (T004-T006)
|
|
**Phase 3 Status**: ✅ Complete (T007-T012) - User Story 1 MVP delivered
|
|
|
|
---
|
|
|
|
## T010: Implementation Summary - JSON Viewer in PolicyResource
|
|
|
|
**Date**: 2025-12-13
|
|
**Phase**: 3 - User Story 1 MVP
|
|
**File Modified**: `app/Filament/Resources/PolicyResource.php`
|
|
|
|
### Changes Made
|
|
|
|
#### 1. Restructured Infolist Schema
|
|
- Wrapped existing entries in "Policy Details" section (2 columns)
|
|
- Moved "Settings" ViewEntry into dedicated section
|
|
- Added new "Policy Snapshot (JSON)" section with collapsible behavior
|
|
|
|
#### 2. JSON Viewer Features Delivered
|
|
- ✅ Pretty-printed JSON with `JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES`
|
|
- ✅ Copy-to-clipboard via Filament's built-in `copyable()` method
|
|
- ✅ Scrollable container (max-height: 24rem vertical, auto horizontal)
|
|
- ✅ Dark mode support (bg-gray-50/dark:bg-gray-900)
|
|
- ✅ Border styling (gray-200/dark:gray-700)
|
|
- ✅ Helper text: "Use Cmd+F (Mac) or Ctrl+F (Windows) to search within the JSON"
|
|
- ✅ Null safety: Shows "No snapshot available" if data missing
|
|
|
|
#### 3. Large Payload Warning (>500 KB)
|
|
- Threshold: 512,000 bytes (500 KB from NFR-036.1)
|
|
- Warning badge with ⚠️ icon when payload exceeds threshold
|
|
- Auto-collapse section if payload >500 KB to reduce initial render cost
|
|
- Size display in KB with warning colors (text-warning-600/400)
|
|
|
|
#### 4. Requirements Coverage
|
|
|
|
| Requirement | Status | Notes |
|
|
|-------------|--------|-------|
|
|
| FR-036 | ✅ | JSON viewer with fold/collapse, copy, search (browser Cmd+F) |
|
|
| FR-037 | ✅ | Preserves existing Settings ViewEntry |
|
|
| FR-038 | ✅ | Large payload warning + auto-collapse |
|
|
| FR-039 | ✅ | No changes to table UI |
|
|
| FR-040 | ✅ | UI-only change, no behavioral mutations |
|
|
| NFR-036.1 | ✅ | 500 KB soft limit (512,000 bytes) |
|
|
| NFR-036.2 | ✅ | Read-only, no interactivity |
|
|
| NFR-036.4 | ✅ | No state mutations |
|
|
| NFR-036.5 | ✅ | Filament styling consistency |
|
|
| US-UI-01 | ✅ | JSON viewer on Policy View page |
|
|
| SC-001 | ✅ | JSON visible and copyable |
|
|
| SC-002 | ✅ | Auto-collapse for large payloads |
|
|
| SC-003 | ✅ | Copy with success message |
|
|
|
|
### Implementation Decision
|
|
|
|
**Opted for Simple Pretty-Print MVP** (Option 3 from T004):
|
|
- No pepperfm/filament-json package usage in final implementation
|
|
- Native Filament `TextEntry` with HTML formatting
|
|
- Browser native find (Cmd+F) for search functionality
|
|
- Filament's built-in `copyable()` for clipboard (no custom JS)
|
|
|
|
**Rationale**:
|
|
1. Package is table-column only (incompatible with infolists)
|
|
2. Simple approach meets all FR/NFR requirements
|
|
3. Faster implementation, zero external dependencies
|
|
4. Easier to customize and maintain
|
|
|
|
### Manual QA Checklist
|
|
|
|
Before marking Phase 3 complete, verify:
|
|
1. ✅ Navigate to `/admin/policies/{id}` with snapshot data
|
|
2. ✅ "Policy Snapshot (JSON)" section renders with formatted JSON
|
|
3. ✅ Copy button copies full JSON to clipboard
|
|
4. ✅ Success message "JSON copied to clipboard!" appears
|
|
5. ✅ Section is collapsible (can expand/collapse)
|
|
6. ✅ Dark mode toggle → verify background/text colors
|
|
7. ✅ Browser find (Cmd+F) highlights text within JSON
|
|
8. ✅ Large payload (>500 KB) shows warning badge
|
|
9. ✅ Large payload auto-collapses section by default
|
|
|
|
**Next**: Phase 4 (T013-T015) will add tabs for Settings Catalog policies (User Story 2)
|