diff --git a/static/src/css/sign_image_field.css b/static/src/css/sign_image_field.css index f00f2b8..854be79 100644 --- a/static/src/css/sign_image_field.css +++ b/static/src/css/sign_image_field.css @@ -40,4 +40,12 @@ div.o_sign_sign_item.o_sign_image_item span.o_placeholder { /* Override any inherited font sizes with maximum specificity */ body div.o_sign_sign_item.o_sign_image_item span.o_placeholder { font-size: 12px !important; +} + +.o_sign_image_item .sign_item_body { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; } \ No newline at end of file diff --git a/static/src/js/sign_image_upload.js b/static/src/js/sign_image_upload.js index 21d6a39..48e8463 100755 --- a/static/src/js/sign_image_upload.js +++ b/static/src/js/sign_image_upload.js @@ -7,16 +7,18 @@ patch(SignablePDFIframe.prototype, { enableCustom(signItem) { super.enableCustom(signItem); if (signItem.data.type === 'image') { + const el = signItem.el; + const data = signItem.data; + // Add data-type attribute for CSS targeting - signItem.el.setAttribute('data-type', 'image'); + el.setAttribute('data-type', 'image'); // Function to adjust font size based on container dimensions const adjustFontSize = () => { - const placeholder = signItem.el.querySelector('.o_placeholder'); + const placeholder = el.querySelector('.o_placeholder'); if (placeholder) { - const containerHeight = signItem.el.offsetHeight; - const containerWidth = signItem.el.offsetWidth; - // Use the smaller dimension to calculate font size, but make it more reasonable + const containerHeight = el.offsetHeight; + const containerWidth = el.offsetWidth; const minDimension = Math.min(containerHeight, containerWidth); const fontSize = Math.max(10, Math.min(16, minDimension * 0.4)); placeholder.style.fontSize = fontSize + 'px !important'; @@ -30,14 +32,14 @@ patch(SignablePDFIframe.prototype, { // Watch for size changes if (window.ResizeObserver) { const resizeObserver = new ResizeObserver(adjustFontSize); - resizeObserver.observe(signItem.el); + resizeObserver.observe(el); } - const input = signItem.el.querySelector('.o_sign_image_upload_input'); + const input = el.querySelector('.o_sign_image_upload_input'); if (!input) return; - signItem.el.addEventListener('click', (e) => { - if (this.readonly || signItem.data.responsible !== this.currentRole) return; + el.addEventListener('click', (e) => { + if (this.readonly || (data.responsible > 0 && data.responsible !== this.currentRole)) return; // Prevent recursive click if clicking the input itself bubbles up if (e.target !== input) { input.click(); @@ -52,12 +54,10 @@ patch(SignablePDFIframe.prototype, { reader.onload = (readerEvent) => { const img = new Image(); img.onload = () => { - // Create a canvas for compression const canvas = document.createElement('canvas'); let width = img.width; let height = img.height; - // Calculate new dimensions (e.g., max width/height 1080 to keep it reasonable) const MAX_SIZE = 1080; if (width > height) { if (width > MAX_SIZE) { @@ -77,41 +77,31 @@ patch(SignablePDFIframe.prototype, { const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, width, height); - // Compress to JPEG with 0.7 quality const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.7); - // Set the value on the element - // Use a specific attribute or just data-value which is used by getSignatureValue - // We also need to add a hidden input or update state if Odoo framework expects it + // Update state and element + data.value = compressedDataUrl; + el.dataset.value = compressedDataUrl; - // Update the internal state which Odoo Sign might be using - signItem.data.value = compressedDataUrl; - signItem.el.dataset.value = compressedDataUrl; - - // Display the image - // Remove placeholder if it exists - const placeholder = signItem.el.querySelector('.o_placeholder'); + // Force immediate display update + const placeholder = el.querySelector('.o_placeholder'); if (placeholder) placeholder.remove(); - // Remove existing image - const existingImg = signItem.el.querySelector('img'); - if (existingImg) existingImg.remove(); + let existingImg = el.querySelector('img'); + if (!existingImg) { + existingImg = document.createElement('img'); + existingImg.style.maxWidth = '100%'; + existingImg.style.maxHeight = '100%'; + existingImg.style.objectFit = 'contain'; + const body = el.querySelector('.sign_item_body') || el; + body.appendChild(existingImg); + } + existingImg.src = compressedDataUrl; - const newImg = document.createElement('img'); - newImg.src = compressedDataUrl; - newImg.style.maxWidth = '100%'; - newImg.style.maxHeight = '100%'; - newImg.style.objectFit = 'contain'; - - // Append to a specific container if needed, or just to el - // sign_item_body is usually where content goes - const body = signItem.el.querySelector('.sign_item_body') || signItem.el; - body.appendChild(newImg); - - // Trigger validation/saving mechanism - // We might need to call a method to notify Odoo that value changed - // In standard sign, usually it listens to input or checks dirty state. - // Setting data-value is what getSignatureValueFromElement checks (based on our other patch) + // Notify Odoo of the value change + if (this.handleInput) { + this.handleInput(); + } }; img.src = readerEvent.target.result; }; diff --git a/static/src/xml/sign_items_image.xml b/static/src/xml/sign_items_image.xml index 29ea977..65fc28c 100755 --- a/static/src/xml/sign_items_image.xml +++ b/static/src/xml/sign_items_image.xml @@ -5,7 +5,7 @@ -
+