Files
Odoo-Modules/fusion_claims/static/src/xml/document_preview.xml
2026-02-22 01:22:18 -05:00

205 lines
10 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2024-2025 Nexa Systems Inc.
License OPL-1 (Odoo Proprietary License v1.0)
Part of the Fusion Claim Assistant product family.
-->
<templates xml:space="preserve">
<!-- PDF Document Preview Dialog -->
<t t-name="fusion_claims.DocumentPreviewDialog">
<Dialog size="getDialogSize()" footer="false">
<t t-set-slot="header">
<div class="d-flex align-items-center justify-content-between w-100">
<div style="width: 50px"></div>
<h4 class="modal-title text-break fw-normal mb-0">
<i class="fa fa-file-pdf-o me-2 text-danger"/>
<t t-esc="props.title" />
</h4>
<div class="d-flex align-items-center gap-1">
<button type="button" class="btn btn-sm btn-outline-secondary"
t-on-click="toggleMaximize"
t-att-title="state.isMaximized ? 'Exit Fullscreen' : 'Fullscreen'">
<i t-attf-class="fa {{ state.isMaximized ? 'fa-compress' : 'fa-expand' }}" />
</button>
<a t-att-href="getViewerUrl()"
target="_blank"
class="btn btn-sm btn-outline-primary"
title="Open in New Tab">
<i class="fa fa-external-link"/>
</a>
<button type="button" class="btn-close ms-2" t-on-click="props.close"/>
</div>
</div>
</t>
<div class="position-relative bg-secondary">
<!-- Loading spinner -->
<div t-if="state.isLoading"
class="position-absolute w-100 h-100 d-flex justify-content-center align-items-center bg-light"
style="z-index: 10; min-height: 400px;">
<div class="text-center">
<div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
<p class="text-muted mb-0">Loading document...</p>
</div>
</div>
<!-- PDF.js viewer iframe - handles XFA/protected PDFs -->
<iframe t-att-src="getViewerUrl()"
class="border-0"
t-att-style="getFrameStyle()"
t-on-load="onIframeLoad"
allowfullscreen="true" />
</div>
</Dialog>
</t>
<!-- XML Viewer Dialog -->
<t t-name="fusion_claims.XMLViewerDialog">
<Dialog size="getDialogSize()" footer="false">
<t t-set-slot="header">
<div class="d-flex align-items-center justify-content-between w-100">
<div style="width: 50px"></div>
<h4 class="modal-title text-break fw-normal mb-0">
<i class="fa fa-file-code-o me-2 text-info"/>
<t t-esc="props.title" />
</h4>
<div class="d-flex align-items-center gap-1">
<button type="button" class="btn btn-sm btn-outline-secondary"
t-on-click="copyToClipboard"
title="Copy to Clipboard">
<i class="fa fa-clipboard"/>
</button>
<button type="button" class="btn btn-sm btn-outline-secondary"
t-on-click="toggleMaximize"
t-att-title="state.isMaximized ? 'Exit Fullscreen' : 'Fullscreen'">
<i t-attf-class="fa {{ state.isMaximized ? 'fa-compress' : 'fa-expand' }}" />
</button>
<button type="button" class="btn btn-sm btn-outline-primary"
t-on-click="downloadXml"
title="Download XML">
<i class="fa fa-download"/>
</button>
<button type="button" class="btn-close ms-2" t-on-click="props.close"/>
</div>
</div>
</t>
<div class="position-relative">
<!-- Loading spinner -->
<div t-if="state.isLoading"
class="d-flex justify-content-center align-items-center bg-light"
style="min-height: 400px;">
<div class="text-center">
<div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
<p class="text-muted mb-0">Loading XML...</p>
</div>
</div>
<!-- Error message -->
<div t-if="state.error" class="alert alert-danger m-3">
<i class="fa fa-exclamation-triangle me-2"/>
<t t-esc="state.error"/>
</div>
<!-- XML content with syntax highlighting -->
<div t-if="!state.isLoading and !state.error"
class="xml-viewer-content"
t-att-style="state.isMaximized ? 'height: calc(98vh - 120px);' : 'height: calc(85vh - 120px);'">
<pre class="xml-code m-0 p-3"><code t-out="state.formattedXml"/></pre>
</div>
</div>
</Dialog>
</t>
<!-- Image Preview Dialog -->
<t t-name="fusion_claims.ImagePreviewDialog">
<Dialog size="'xl'" footer="false">
<t t-set-slot="header">
<div class="d-flex align-items-center justify-content-between w-100">
<div style="width: 100px">
<span t-if="hasMultiple" class="badge bg-secondary">
<t t-esc="currentPosition"/>
</span>
</div>
<h4 class="modal-title text-break fw-normal mb-0">
<i class="fa fa-image me-2 text-success"/>
<t t-esc="currentImage.name" />
</h4>
<div class="d-flex align-items-center gap-1">
<button type="button" class="btn btn-sm btn-outline-primary"
t-on-click="downloadImage"
title="Download Image">
<i class="fa fa-download"/>
</button>
<button type="button" class="btn-close ms-2" t-on-click="props.close"/>
</div>
</div>
</t>
<div class="position-relative d-flex align-items-center justify-content-center bg-dark"
style="min-height: 500px; max-height: 80vh;">
<!-- Loading spinner -->
<div t-if="state.isLoading"
class="position-absolute w-100 h-100 d-flex justify-content-center align-items-center"
style="z-index: 10;">
<div class="spinner-border text-light" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<!-- Previous button -->
<button t-if="hasMultiple and state.currentIndex > 0"
type="button"
class="btn btn-dark btn-lg position-absolute start-0 ms-3"
style="z-index: 20; opacity: 0.7;"
t-on-click="previousImage">
<i class="fa fa-chevron-left fa-2x"/>
</button>
<!-- Image -->
<img t-att-src="imageUrl"
class="mw-100 mh-100"
style="object-fit: contain; max-height: 75vh;"
t-on-load="onImageLoad"
t-att-alt="currentImage.name"/>
<!-- Next button -->
<button t-if="hasMultiple and state.currentIndex &lt; props.images.length - 1"
type="button"
class="btn btn-dark btn-lg position-absolute end-0 me-3"
style="z-index: 20; opacity: 0.7;"
t-on-click="nextImage">
<i class="fa fa-chevron-right fa-2x"/>
</button>
</div>
<!-- Thumbnail strip for multiple images -->
<div t-if="hasMultiple" class="d-flex justify-content-center gap-2 p-3 bg-secondary">
<t t-foreach="props.images" t-as="img" t-key="img.id">
<div t-att-class="'border-2 rounded overflow-hidden cursor-pointer ' + (img_index === state.currentIndex ? 'border-primary' : 'border-transparent')"
style="width: 60px; height: 60px; cursor: pointer;"
t-on-click="() => { this.state.isLoading = true; this.state.currentIndex = img_index; }">
<img t-att-src="'/web/image/' + img.id + '?height=60'"
class="w-100 h-100"
style="object-fit: cover;"/>
</div>
</t>
</div>
</Dialog>
</t>
<!-- Preview Button Widget (no-save, client-side only) -->
<t t-name="fusion_claims.PreviewButtonWidget">
<button type="button"
class="btn btn-link p-0 border-0"
title="Preview"
t-on-click="onClick">
<i class="fa fa-eye"/>
</button>
</t>
</templates>