folder rename

This commit is contained in:
gsinghpal
2026-04-16 20:53:53 -04:00
parent 3f3ddcbab4
commit 7c7ef06057
634 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
/** @odoo-module **/
// Fusion Plating -- 3D CAD Viewer (iframe wrapper)
// Copyright 2026 Nexa Systems Inc.
// License OPL-1 (Odoo Proprietary License v1.0)
//
// Simple OWL field widget that embeds the standalone 3D viewer page
// in an iframe. The viewer page uses Online3DViewer (o3dv) which
// supports STEP, IGES, BREP, STL, OBJ, glTF, and 20+ more formats.
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { Dialog } from "@web/core/dialog/dialog";
export class Fp3dViewer extends Component {
static template = "fusion_plating_configurator.Fp3dViewer";
static props = { ...standardFieldProps };
setup() {
this.state = useState({ hasAttachment: false, iframeSrc: "" });
this._updateState();
}
get rawValue() {
return this.props.record.data[this.props.name];
}
get attachmentId() {
const v = this.rawValue;
if (!v) return 0;
if (Array.isArray(v)) return v[0] || 0;
if (typeof v === "object" && v.id) return v.id;
return typeof v === "number" ? v : 0;
}
get attachmentName() {
const v = this.rawValue;
if (!v) return "";
if (Array.isArray(v)) return v[1] || "";
if (typeof v === "object" && v.display_name) return v.display_name;
return "";
}
_updateState() {
const aid = this.attachmentId;
this.state.hasAttachment = !!aid;
if (aid) {
const name = encodeURIComponent(this.attachmentName);
this.state.iframeSrc = `/fp/3d-viewer?id=${aid}&name=${name}`;
}
}
onPatched() {
this._updateState();
}
}
registry.category("fields").add("fp_3d_preview", {
component: Fp3dViewer,
supportedTypes: ["many2one"],
});
// =============================================================================
// 3D Viewer Dialog component (full-screen embedded viewer)
// =============================================================================
export class Fp3dViewerDialog extends Component {
static template = "fusion_plating_configurator.Fp3dViewerDialog";
static components = { Dialog };
static props = {
attachmentId: Number,
name: { type: String, optional: true },
close: { type: Function, optional: true },
};
setup() {
this.state = useState({ isMaximized: true });
}
get iframeSrc() {
const name = encodeURIComponent(this.props.name || "");
return `/fp/3d-viewer?id=${this.props.attachmentId}&name=${name}`;
}
get dialogSize() {
return this.state.isMaximized ? "fullscreen" : "xl";
}
get frameStyle() {
if (this.state.isMaximized) {
return "height: calc(98vh - 100px) !important;";
}
return "height: calc(85vh - 100px) !important;";
}
toggleSize() {
this.state.isMaximized = !this.state.isMaximized;
}
}
registry.category("dialog").add("Fp3dViewerDialog", Fp3dViewerDialog);
// Client action handler — opens the 3D viewer in a dialog within the same window.
// Triggered by Python returning:
// { type: 'ir.actions.client', tag: 'fp_3d_viewer_open',
// params: { attachment_id: N, name: "..." } }
function fp3dViewerOpenAction(env, action) {
const params = action.params || {};
if (!params.attachment_id) return Promise.resolve();
env.services.dialog.add(Fp3dViewerDialog, {
attachmentId: params.attachment_id,
name: params.name || "",
});
return Promise.resolve();
}
registry.category("actions").add("fp_3d_viewer_open", fp3dViewerOpenAction);

View File

@@ -0,0 +1,81 @@
/** @odoo-module **/
// Fusion Plating -- PDF Drawing Preview Widget
// Copyright 2026 Nexa Systems Inc.
// License OPL-1
//
// Custom many2many_binary widget that opens PDFs in the fusion_pdf_preview
// dialog instead of downloading them.
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import {
Many2ManyBinaryField,
many2ManyBinaryField,
} from "@web/views/fields/many2many_binary/many2many_binary_field";
export class FpPdfPreviewBinary extends Many2ManyBinaryField {
static template = "fusion_plating_configurator.FpPdfPreviewBinary";
setup() {
super.setup();
this.dialogService = useService("dialog");
}
onFileClick(ev, file) {
const isPdf = (file.mimetype === "application/pdf") ||
(file.name || "").toLowerCase().endsWith(".pdf");
const dialogs = registry.category("dialog");
if (isPdf && dialogs.contains("PDFViewerDialog")) {
ev.preventDefault();
ev.stopPropagation();
const PDFViewerDialog = dialogs.get("PDFViewerDialog");
const url = `/web/content/${file.id}?download=false`;
this.dialogService.add(PDFViewerDialog, {
url: url,
title: file.name || "Drawing",
reportName: "",
recordIds: "",
modelName: "ir.attachment",
});
}
// For non-PDF or when preview not available, default browser behavior
// (the <a href> with download attribute) kicks in because we don't
// prevent default.
}
}
export const fpPdfPreviewBinary = {
...many2ManyBinaryField,
component: FpPdfPreviewBinary,
};
registry.category("fields").add("fp_pdf_preview_binary", fpPdfPreviewBinary);
// Client action handler: open a PDF attachment in the fusion_pdf_preview dialog.
// Triggered by Python methods returning:
// { type: 'ir.actions.client', tag: 'fp_pdf_preview_open',
// params: { attachment_id: N, title: "..." } }
function fpPdfPreviewOpenAction(env, action) {
const params = action.params || {};
const attId = params.attachment_id;
if (!attId) return Promise.resolve();
const dialogs = registry.category("dialog");
const PDFViewerDialog = dialogs.contains("PDFViewerDialog") ? dialogs.get("PDFViewerDialog") : null;
if (!PDFViewerDialog) {
window.open(`/web/content/${attId}?download=false`, '_blank');
return Promise.resolve();
}
const url = `/web/content/${attId}?download=false`;
env.services.dialog.add(PDFViewerDialog, {
url: url,
title: params.title || 'Document',
reportName: '',
recordIds: '',
modelName: 'ir.attachment',
});
return Promise.resolve();
}
registry.category("actions").add("fp_pdf_preview_open", fpPdfPreviewOpenAction);

View File

@@ -0,0 +1,80 @@
/** @odoo-module **/
// Fusion Plating -- Inline PDF Preview field widget
// Copyright 2026 Nexa Systems Inc.
// License OPL-1
//
// Field widget for Many2one(ir.attachment) fields that embeds the
// PDF.js viewer inline at a fixed height (one page at a time).
// A "Full Screen" button below opens the fusion_pdf_preview dialog.
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
export class FpPdfInlinePreview extends Component {
static template = "fusion_plating_configurator.FpPdfInlinePreview";
static props = { ...standardFieldProps };
setup() {
this.dialogService = useService("dialog");
this.state = useState({ hasAttachment: false, iframeSrc: "", attId: 0, name: "" });
this._updateState();
}
get rawValue() {
return this.props.record.data[this.props.name];
}
_updateState() {
const v = this.rawValue;
let attId = 0;
let name = "";
if (v) {
if (Array.isArray(v)) {
attId = v[0] || 0;
name = v[1] || "";
} else if (typeof v === "object" && v.id) {
attId = v.id;
name = v.display_name || "";
} else if (typeof v === "number") {
attId = v;
}
}
this.state.hasAttachment = !!attId;
this.state.attId = attId;
this.state.name = name;
if (attId) {
const fileUrl = `/web/content/${attId}?download=false`;
// PDF.js URL params: zoom=page-fit, no thumbs sidebar, single-page mode
this.state.iframeSrc =
`/fusion_pdf_preview/static/lib/pdfjs/web/viewer.html` +
`?file=${encodeURIComponent(fileUrl)}` +
`#zoom=page-fit&pagemode=none&scrollmode=3`;
}
}
onPatched() {
this._updateState();
}
openFullScreen() {
if (!this.state.attId) return;
const dialogs = registry.category("dialog");
if (!dialogs.contains("PDFViewerDialog")) return;
const PDFViewerDialog = dialogs.get("PDFViewerDialog");
const url = `/web/content/${this.state.attId}?download=false`;
this.dialogService.add(PDFViewerDialog, {
url: url,
title: this.state.name || "Drawing",
reportName: "",
recordIds: "",
modelName: "ir.attachment",
});
}
}
registry.category("fields").add("fp_pdf_inline_preview", {
component: FpPdfInlinePreview,
supportedTypes: ["many2one"],
});