Files
Odoo-Modules/fusion_portal/views/portal_pdf_editor.xml
gsinghpal 747c814249 refactor(fusion_portal): rename from fusion_authorizer_portal + modern photo cards on accessibility selector
Rename module fusion_authorizer_portal -> fusion_portal everywhere:
manifest/assets, controllers, models, views, JS (odoo.define + asset URLs),
migration MODULE constants; plus cross-module refs in fusion_schedule,
fusion_repairs, fusion_quotations (depends + inherit_id) and the pdf_filler
import in fusion_claims. Add rename_module.sql for the one-time in-place DB
rename (ir_module_module, ir_model_data, ir_ui_view.key,
ir_module_module_dependency) required on installed envs before -u fusion_portal.
Document the rename gotcha as rule 16 in CLAUDE.md.

Redesign the Accessibility Assessment selector: replace Font Awesome icon tiles
with photo-banner cards using 7 optimized images (1000x750 PNG -> 800x600 JPEG,
~8MB -> 488KB), per-type colour accent bar + centered pill button, hover
lift/zoom. Images ship as module static files so they deploy/sync with the module.

Drop the regenerable graphify-out cache from the module.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 22:38:14 -04:00

185 lines
11 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- ============================================================ -->
<!-- Visual PDF Field Position Editor -->
<!-- Drag field types from sidebar onto PDF, resize on page -->
<!-- ============================================================ -->
<template id="portal_pdf_field_editor" name="PDF Field Editor">
<t t-call="web.frontend_layout">
<t t-set="title">PDF Field Editor</t>
<div class="container-fluid py-3" id="pdf_field_editor"
t-att-data-template-id="template.id"
t-att-data-page-count="template.page_count or 1"
t-att-data-current-page="1"
t-att-data-category="template.category or 'other'">
<!-- Header Bar -->
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<h3 class="mb-0">
<i class="fa fa-pencil-square-o me-2"/>
<t t-esc="template.name"/>
<small class="text-muted ms-2">v<t t-esc="template.version"/></small>
</h3>
<small class="text-muted">
<t t-esc="template.page_count or 0"/> page(s) |
<span id="field_count"><t t-esc="len(fields)"/></span> field(s)
</small>
</div>
<div class="d-flex gap-2">
<button type="button" class="btn btn-outline-info btn-sm" id="btn_preview">
<i class="fa fa-eye me-1"/>Preview PDF
</button>
<a t-att-href="'/web#id=%d&amp;model=fusion.pdf.template&amp;view_type=form' % template.id"
class="btn btn-secondary btn-sm">
<i class="fa fa-arrow-left me-1"/>Back
</a>
</div>
</div>
<!-- Page Navigation -->
<div class="d-flex justify-content-center align-items-center mb-3 gap-3"
t-if="(template.page_count or 1) > 1">
<button type="button" class="btn btn-sm btn-outline-secondary" id="btn_prev_page">
<i class="fa fa-chevron-left"/>
</button>
<span>
Page <strong id="current_page_display">1</strong>
of <strong><t t-esc="template.page_count or 1"/></strong>
</span>
<button type="button" class="btn btn-sm btn-outline-secondary" id="btn_next_page">
<i class="fa fa-chevron-right"/>
</button>
</div>
<div class="row">
<!-- Left Sidebar: Field Type Palette -->
<div class="col-md-2">
<!-- Draggable Field Types -->
<div class="card mb-3">
<div class="card-header bg-dark text-white py-2">
<h6 class="mb-0"><i class="fa fa-th-list me-1"/>Field Types</h6>
</div>
<div class="card-body p-2">
<p class="text-muted small mb-2">Drag a field onto the PDF</p>
<div class="d-grid gap-2">
<div class="pdf-palette-item" draggable="true"
data-field-type="text"
style="padding: 8px 10px; border: 2px solid #3498db; border-radius: 5px;
background: rgba(52,152,219,0.1); cursor: grab; font-size: 13px; font-weight: 600;">
<i class="fa fa-font me-2" style="color: #3498db;"/>Text Field
</div>
<div class="pdf-palette-item" draggable="true"
data-field-type="checkbox"
style="padding: 8px 10px; border: 2px solid #2ecc71; border-radius: 5px;
background: rgba(46,204,113,0.1); cursor: grab; font-size: 13px; font-weight: 600;">
<i class="fa fa-check-square-o me-2" style="color: #2ecc71;"/>Checkbox
</div>
<div class="pdf-palette-item" draggable="true"
data-field-type="date"
style="padding: 8px 10px; border: 2px solid #e67e22; border-radius: 5px;
background: rgba(230,126,34,0.1); cursor: grab; font-size: 13px; font-weight: 600;">
<i class="fa fa-calendar me-2" style="color: #e67e22;"/>Date Field
</div>
<div class="pdf-palette-item" draggable="true"
data-field-type="signature"
style="padding: 8px 10px; border: 2px solid #9b59b6; border-radius: 5px;
background: rgba(155,89,182,0.1); cursor: grab; font-size: 13px; font-weight: 600;">
<i class="fa fa-pencil me-2" style="color: #9b59b6;"/>Signature
</div>
</div>
</div>
</div>
<!-- Data Keys Reference (collapsible, populated by JS) -->
<div class="card">
<div class="card-header py-2" style="cursor: pointer;"
data-bs-toggle="collapse" data-bs-target="#dataKeysCollapse">
<h6 class="mb-0">
<i class="fa fa-key me-1"/>Data Keys
<i class="fa fa-chevron-down float-end mt-1" style="font-size: 10px;"/>
</h6>
</div>
<div id="dataKeysCollapse" class="collapse">
<div class="card-body p-2" id="dataKeysList"
style="max-height: 300px; overflow-y: auto; font-size: 11px;">
</div>
</div>
</div>
</div>
<!-- PDF Page Canvas Area -->
<div class="col-md-7">
<div class="card">
<div class="card-body p-0">
<div id="pdf_canvas_container"
style="position: relative; width: 100%; overflow: hidden;
border: 2px solid #dee2e6; background: #f8f9fa;
min-height: 600px;">
<!-- PDF page image -->
<img id="pdf_page_image"
style="width: 100%; display: block; user-select: none;"
draggable="false"
t-att-src="preview_url or ''"
t-attf-alt="Page #{1}"
t-if="preview_url"/>
<!-- Upload form when no preview exists -->
<div t-if="not preview_url" class="text-center py-5" id="no_preview_placeholder">
<div class="mb-3">
<i class="fa fa-file-image-o fa-3x text-muted"/>
<p class="text-muted mt-2 mb-1">No page preview image yet.</p>
<p class="text-muted small">
Upload a screenshot/photo of the PDF page, or click
"Generate Page Previews" in the backend form.
</p>
</div>
<form t-attf-action="/fusion/pdf-editor/upload-preview"
method="post" enctype="multipart/form-data"
class="d-inline-block">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input type="hidden" name="template_id" t-att-value="template.id"/>
<input type="hidden" name="page" value="1"/>
<div class="input-group" style="max-width: 400px; margin: 0 auto;">
<input type="file" name="preview_image" class="form-control"
accept="image/png,image/jpeg,image/jpg" required="required"/>
<button type="submit" class="btn btn-primary">
<i class="fa fa-upload me-1"/>Upload
</button>
</div>
</form>
</div>
<!-- Field markers rendered by JS -->
</div>
</div>
</div>
</div>
<!-- Right Sidebar: Field Properties -->
<div class="col-md-3">
<div class="card" id="field_properties_panel">
<div class="card-header bg-primary text-white py-2">
<h6 class="mb-0"><i class="fa fa-cog me-1"/>Field Properties</h6>
</div>
<div class="card-body" id="field_props_body">
<p class="text-muted small">Click a field on the PDF to edit its properties.</p>
</div>
</div>
</div>
</div>
</div>
<!-- JavaScript -->
<script type="text/javascript" src="/fusion_portal/static/src/js/pdf_field_editor.js"/>
</t>
</template>
</odoo>