diff --git a/py_app/app/__pycache__/routes.cpython-312.pyc b/py_app/app/__pycache__/routes.cpython-312.pyc index 256aa1f..875aeda 100644 Binary files a/py_app/app/__pycache__/routes.cpython-312.pyc and b/py_app/app/__pycache__/routes.cpython-312.pyc differ diff --git a/py_app/app/routes.py b/py_app/app/routes.py index 0da6f38..bb9340f 100644 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -932,6 +932,162 @@ def upload_data(): def print_module(): return render_template('print_module.html') +@bp.route('/download_extension') +def download_extension(): + """Route for downloading the Chrome extension""" + return render_template('download_extension.html') + +@bp.route('/extension_files/') +def extension_files(filename): + """Serve Chrome extension files for download""" + import os + from flask import send_from_directory, current_app + + extension_dir = os.path.join(os.path.dirname(current_app.root_path), 'chrome_extension') + return send_from_directory(extension_dir, filename) + +@bp.route('/create_extension_package', methods=['POST']) +def create_extension_package(): + """Create and serve ZIP package of Chrome extension""" + import os + import zipfile + from flask import current_app, jsonify, send_file + import tempfile + + try: + # Use correct path to chrome_extension directory (it's in py_app, not py_app/app) + extension_dir = os.path.join(os.path.dirname(current_app.root_path), 'chrome_extension') + print(f"Looking for extension files in: {extension_dir}") + + if not os.path.exists(extension_dir): + return jsonify({ + 'success': False, + 'error': f'Extension directory not found: {extension_dir}' + }), 500 + + # List files in extension directory for debugging + all_files = [] + for root, dirs, files in os.walk(extension_dir): + for file in files: + file_path = os.path.join(root, file) + all_files.append(file_path) + + print(f"Found files: {all_files}") + + # Create static directory if it doesn't exist + static_dir = os.path.join(current_app.root_path, 'static') + os.makedirs(static_dir, exist_ok=True) + + zip_filename = 'quality_recticel_print_helper.zip' + zip_path = os.path.join(static_dir, zip_filename) + + # Create ZIP file directly in static directory + with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: + files_added = 0 + + # Add all extension files to ZIP + for root, dirs, files in os.walk(extension_dir): + for file in files: + # Include all relevant files + if file.endswith(('.json', '.js', '.html', '.css', '.png', '.md', '.txt')): + file_path = os.path.join(root, file) + # Create relative path for archive + arcname = os.path.relpath(file_path, extension_dir) + + print(f"Adding file: {file_path} as {arcname}") + zipf.write(file_path, arcname) + files_added += 1 + + # Add a README file with installation instructions + readme_content = """# Quality Recticel Print Helper Chrome Extension + +## Installation Instructions: + +1. Extract this ZIP file to a folder on your computer +2. Open Chrome and go to: chrome://extensions/ +3. Enable "Developer mode" in the top right +4. Click "Load unpacked" and select the extracted folder +5. The extension icon 🖨️ should appear in your toolbar + +## Usage: + +1. Go to the Print Module in the Quality Recticel application +2. Select an order from the table +3. Click the "🖨️ Print Direct" button +4. The label will print automatically to your default printer + +## Troubleshooting: + +- Make sure your default printer is set up correctly +- Click the extension icon to test printer connection +- Check Chrome printer settings: chrome://settings/printing + +For support, contact your system administrator. +""" + zipf.writestr('README.txt', readme_content) + files_added += 1 + + print(f"Total files added to ZIP: {files_added}") + + # Verify ZIP was created and has content + if os.path.exists(zip_path): + zip_size = os.path.getsize(zip_path) + print(f"ZIP file created: {zip_path}, size: {zip_size} bytes") + + if zip_size > 0: + return jsonify({ + 'success': True, + 'download_url': f'/static/{zip_filename}', + 'files_included': files_added, + 'zip_size': zip_size + }) + else: + return jsonify({ + 'success': False, + 'error': 'ZIP file was created but is empty' + }), 500 + else: + return jsonify({ + 'success': False, + 'error': 'Failed to create ZIP file' + }), 500 + + except Exception as e: + print(f"Error creating extension package: {e}") + import traceback + traceback.print_exc() + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 + +@bp.route('/test_extension_files') +def test_extension_files(): + """Test route to check extension files""" + import os + from flask import current_app, jsonify + + extension_dir = os.path.join(os.path.dirname(current_app.root_path), 'chrome_extension') + + result = { + 'extension_dir': extension_dir, + 'dir_exists': os.path.exists(extension_dir), + 'files': [] + } + + if os.path.exists(extension_dir): + for root, dirs, files in os.walk(extension_dir): + for file in files: + file_path = os.path.join(root, file) + file_size = os.path.getsize(file_path) + result['files'].append({ + 'path': file_path, + 'relative_path': os.path.relpath(file_path, extension_dir), + 'size': file_size + }) + + return jsonify(result) + @bp.route('/label_templates') def label_templates(): return render_template('label_templates.html') diff --git a/py_app/app/templates/download_extension.html b/py_app/app/templates/download_extension.html new file mode 100644 index 0000000..45beacc --- /dev/null +++ b/py_app/app/templates/download_extension.html @@ -0,0 +1,144 @@ +{% extends "base.html" %} + +{% block title %}Chrome Extension Download{% endblock %} + +{% block content %} +
+
+
+
+
+

🖨️ Quality Recticel Print Helper - Chrome Extension

+
+
+
+ Direct Printing Solution: This Chrome extension enables direct printing from the Print Module to your default printer without browser dialogs. +
+ +

Features:

+
    +
  • ✅ Print labels directly to default printer
  • +
  • ✅ No browser print dialogs
  • +
  • ✅ Automatic printer detection
  • +
  • ✅ Print status notifications
  • +
  • ✅ Enhanced print button with visual feedback
  • +
+ +

Installation Instructions:

+
    +
  1. Download Extension Files: +
    + +

    +
    + Alternative: Download individual files: +
    + manifest.json | + background.js | + content.js | + popup.html | + popup.js +
    +
    +
  2. + +
  3. Extract Files: +

    Extract the downloaded ZIP file to a folder on your computer (e.g., Desktop/print_extension)

    +
  4. + +
  5. Open Chrome Extensions: +

    In Google Chrome, go to: chrome://extensions/

    +
  6. + +
  7. Enable Developer Mode: +

    Toggle the "Developer mode" switch in the top-right corner

    +
  8. + +
  9. Load Extension: +

    Click "Load unpacked" and select the folder where you extracted the files

    +
  10. + +
  11. Verify Installation: +

    The extension icon 🖨️ should appear in your Chrome toolbar

    +
  12. +
+ +

Usage:

+
    +
  1. Navigate to the Print Module
  2. +
  3. Select an order from the table
  4. +
  5. Click the enhanced "🖨️ Print Direct" button
  6. +
  7. The label will print automatically to your default printer
  8. +
+ +
+ System Requirements: +
    +
  • Google Chrome browser (version 88 or higher)
  • +
  • Default printer configured on your system
  • +
  • Printer drivers installed and working
  • +
+
+ +
+ Troubleshooting: +
    +
  • Click the extension icon 🖨️ to test printer connection
  • +
  • Check Chrome's printer settings: chrome://settings/printing
  • +
  • Ensure your default printer is set correctly
  • +
  • Reload the Print Module page after installing the extension
  • +
+
+ +
+ + 🖨️ Go to Print Module + + +
+
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/py_app/app/templates/print_module.html b/py_app/app/templates/print_module.html index 0d67043..2d1d575 100644 --- a/py_app/app/templates/print_module.html +++ b/py_app/app/templates/print_module.html @@ -239,6 +239,11 @@ table tbody tr.selected td { +
+ + 🔗 Install Direct Print Extension + +
@@ -349,6 +354,9 @@ document.getElementById('check-db-btn').addEventListener('click', function() { if (data.length > 0) { updateLabelPreview(data[0]); + // Add fallback print functionality if extension is not available + addFallbackPrintHandler(); + // Auto-select first row setTimeout(() => { const firstRow = document.querySelector('.print-module-table tbody tr'); @@ -428,5 +436,81 @@ function updateLabelPreview(order) { // Update barcode with the same prod order data document.getElementById('barcode-text').textContent = prodOrder; } + +// Fallback print handler for when Chrome extension is not available +function addFallbackPrintHandler() { + // Check if Chrome extension modified the button + setTimeout(() => { + const printButton = document.getElementById('print-label-btn'); + + // If button text hasn't changed, extension is not active + if (printButton && !printButton.innerHTML.includes('🖨️ Print Direct')) { + console.log('Chrome extension not detected, adding fallback print handler'); + + // Add fallback event listener + printButton.addEventListener('click', function(e) { + e.preventDefault(); + + const labelPreview = document.getElementById('label-preview'); + if (!labelPreview) { + alert('Please select an order first.'); + return; + } + + // Create a new window for printing + const printWindow = window.open('', '_blank'); + const printContent = ` + + + + Quality Recticel Label + + + + + + + `; + + printWindow.document.write(printContent); + printWindow.document.close(); + + // Wait for content to load, then print + printWindow.onload = function() { + printWindow.focus(); + printWindow.print(); + printWindow.close(); + }; + }); + + // Update button text to indicate fallback mode + printButton.innerHTML = '🖨️ Print (Browser)'; + printButton.title = 'Print using browser dialog - Install Chrome Extension for direct printing'; + } + }, 2000); // Wait 2 seconds for extension to load +} {% endblock %} \ No newline at end of file diff --git a/py_app/chrome_extension/background.js b/py_app/chrome_extension/background.js new file mode 100644 index 0000000..a8f7f23 --- /dev/null +++ b/py_app/chrome_extension/background.js @@ -0,0 +1,185 @@ +// Background service worker for Chrome extension +console.log('Quality Recticel Print Helper - Background script loaded'); + +// Listen for messages from content script +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + console.log('Background received message:', request); + + if (request.action === 'print_label') { + handlePrintLabel(request.data, sendResponse); + return true; // Keep message channel open for async response + } + + if (request.action === 'fallback_print') { + handleFallbackPrint(request.data, sendResponse); + return true; + } + + if (request.action === 'get_printers') { + getPrinters(sendResponse); + return true; + } + + if (request.action === 'check_extension') { + sendResponse({status: 'installed', version: chrome.runtime.getManifest().version}); + return true; + } +}); + +// Function to handle label printing +async function handlePrintLabel(printData, sendResponse) { + try { + console.log('Attempting to print label with data:', printData); + + // Check if printing API is available + if (!chrome.printing || !chrome.printing.getPrinters) { + console.error('Chrome printing API not available'); + sendResponse({ + success: false, + error: 'Chrome printing API not available. Please ensure you are using Chrome 85+ and the extension has proper permissions.' + }); + return; + } + + // Get available printers + const printers = await chrome.printing.getPrinters(); + console.log('Available printers:', printers); + + if (printers.length === 0) { + sendResponse({success: false, error: 'No printers found. Please ensure a printer is installed and set as default.'}); + return; + } + + // Find default printer or use first available + const defaultPrinter = printers.find(p => p.isDefault) || printers[0]; + console.log('Using printer:', defaultPrinter); + + // Create print job + const printJob = { + printerId: defaultPrinter.id, + ticket: { + version: '1.0', + print: { + color: { + type: 'STANDARD_MONOCHROME' + }, + duplex: { + type: 'NO_DUPLEX' + }, + page_orientation: { + type: 'PORTRAIT' + }, + copies: { + copies: 1 + }, + dpi: { + horizontal_dpi: 300, + vertical_dpi: 300 + }, + media_size: { + width_microns: 210000, // A4 width + height_microns: 297000 // A4 height + }, + collate: { + collate: false + } + } + }, + documentBlob: new Blob([printData.html], {type: 'text/html'}) + }; + + // Submit print job + const result = await chrome.printing.submitJob(printJob); + console.log('Print job result:', result); + + if (result.status === 'OK') { + sendResponse({success: true, jobId: result.jobId}); + + // Store successful print in extension storage + chrome.storage.local.set({ + lastPrint: { + timestamp: Date.now(), + jobId: result.jobId, + printer: defaultPrinter.displayName + } + }); + } else { + sendResponse({success: false, error: result.status}); + } + + } catch (error) { + console.error('Print error:', error); + sendResponse({success: false, error: error.message}); + } +} + +// Function to get available printers +async function getPrinters(sendResponse) { + try { + // Check if printing API is available + if (!chrome.printing || !chrome.printing.getPrinters) { + sendResponse({ + success: false, + error: 'Chrome printing API not available' + }); + return; + } + + const printers = await chrome.printing.getPrinters(); + sendResponse({success: true, printers: printers}); + } catch (error) { + console.error('Error getting printers:', error); + sendResponse({success: false, error: error.message}); + } +} + +// Extension installation/startup +chrome.runtime.onInstalled.addListener((details) => { + console.log('Quality Recticel Print Helper installed:', details); + + // Set initial storage values + chrome.storage.local.set({ + extensionVersion: chrome.runtime.getManifest().version, + installDate: Date.now() + }); +}); + +// Fallback print method using tabs API +async function handleFallbackPrint(printData, sendResponse) { + try { + console.log('Using fallback print method'); + + // Create a new tab with the print content + const tab = await chrome.tabs.create({ + url: 'data:text/html,' + encodeURIComponent(printData.html), + active: false + }); + + // Wait for tab to load, then print + setTimeout(async () => { + try { + await chrome.tabs.executeScript(tab.id, { + code: 'window.print();' + }); + + // Close the tab after printing + setTimeout(() => { + chrome.tabs.remove(tab.id); + }, 1000); + + sendResponse({success: true, method: 'fallback'}); + } catch (error) { + sendResponse({success: false, error: 'Fallback print failed: ' + error.message}); + } + }, 1000); + + } catch (error) { + console.error('Fallback print error:', error); + sendResponse({success: false, error: error.message}); + } +} + +// Keep service worker alive +chrome.runtime.onConnect.addListener((port) => { + console.log('Port connected:', port.name); +}); \ No newline at end of file diff --git a/py_app/chrome_extension/content.js b/py_app/chrome_extension/content.js new file mode 100644 index 0000000..71ff214 --- /dev/null +++ b/py_app/chrome_extension/content.js @@ -0,0 +1,272 @@ +// Content script for Quality Recticel Print Helper +console.log('Quality Recticel Print Helper - Content script loaded'); + +// Check if we're on the print module page +if (window.location.pathname.includes('print_module')) { + console.log('Print module page detected, initializing extension features'); + + // Wait for DOM to be ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initializePrintExtension); + } else { + initializePrintExtension(); + } +} + +function initializePrintExtension() { + console.log('Initializing print extension features'); + + // Add extension status indicator + addExtensionStatusIndicator(); + + // Override the print button functionality + overridePrintButton(); + + // Add printer selection dropdown + addPrinterSelection(); + + // Check extension status + checkExtensionStatus(); +} + +function addExtensionStatusIndicator() { + // Create status indicator element + const statusIndicator = document.createElement('div'); + statusIndicator.id = 'extension-status'; + statusIndicator.style.cssText = ` + position: fixed; + top: 10px; + right: 10px; + background: #28a745; + color: white; + padding: 5px 10px; + border-radius: 4px; + font-size: 12px; + z-index: 9999; + box-shadow: 0 2px 4px rgba(0,0,0,0.2); + `; + statusIndicator.textContent = '🖨️ Print Extension Active'; + + document.body.appendChild(statusIndicator); + + // Hide after 3 seconds + setTimeout(() => { + statusIndicator.style.opacity = '0'; + statusIndicator.style.transition = 'opacity 0.5s'; + setTimeout(() => statusIndicator.remove(), 500); + }, 3000); +} + +function overridePrintButton() { + // Find the print button + const printButton = document.getElementById('print-label-btn'); + + if (printButton) { + console.log('Found print button, overriding functionality'); + + // Remove existing event listeners by cloning the element + const newPrintButton = printButton.cloneNode(true); + printButton.parentNode.replaceChild(newPrintButton, printButton); + + // Add new event listener for extension printing + newPrintButton.addEventListener('click', handleExtensionPrint); + + // Update button text to indicate direct printing + newPrintButton.innerHTML = '🖨️ Print Direct'; + newPrintButton.title = 'Print directly to default printer (Chrome Extension)'; + + console.log('Print button override complete'); + } else { + console.log('Print button not found, will retry...'); + // Retry after 1 second if button not found yet + setTimeout(overridePrintButton, 1000); + } +} + +function handleExtensionPrint(event) { + event.preventDefault(); + event.stopPropagation(); + + console.log('Extension print button clicked'); + + // Get the label preview element + const labelPreview = document.getElementById('label-preview'); + + if (!labelPreview) { + alert('Label preview not found. Please select an order first.'); + return; + } + + // Show printing status + showPrintStatus('Preparing to print...', 'info'); + + // Create complete HTML for printing + const printHTML = createPrintableHTML(labelPreview); + + // Try direct printing first, then fallback + chrome.runtime.sendMessage({ + action: 'print_label', + data: { + html: printHTML, + timestamp: Date.now() + } + }, (response) => { + if (response && response.success) { + handlePrintResponse(response); + } else { + console.log('Direct printing failed, trying fallback method'); + showPrintStatus('Direct printing unavailable, using browser print...', 'info'); + + // Try fallback method + chrome.runtime.sendMessage({ + action: 'fallback_print', + data: { + html: printHTML, + timestamp: Date.now() + } + }, handlePrintResponse); + } + }); +} + +function createPrintableHTML(labelElement) { + // Get the computed styles and create a complete HTML document + const styles = ` + + `; + + const bodyContent = ` + + `; + + return ` + + + + + Quality Recticel Label + ${styles} + + + ${bodyContent} + + + `; +} + +function handlePrintResponse(response) { + console.log('Print response:', response); + + if (response && response.success) { + showPrintStatus('✅ Label sent to printer successfully!', 'success'); + + // Update the order status in the table if possible + updateOrderPrintStatus(); + + } else { + const errorMsg = response?.error || 'Unknown error occurred'; + showPrintStatus(`❌ Print failed: ${errorMsg}`, 'error'); + + // Fallback to browser print dialog + setTimeout(() => { + if (confirm('Direct printing failed. Open browser print dialog?')) { + window.print(); + } + }, 2000); + } +} + +function showPrintStatus(message, type) { + // Remove existing status messages + const existingStatus = document.getElementById('print-status-message'); + if (existingStatus) { + existingStatus.remove(); + } + + // Create status message + const statusDiv = document.createElement('div'); + statusDiv.id = 'print-status-message'; + statusDiv.style.cssText = ` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: ${type === 'success' ? '#28a745' : type === 'error' ? '#dc3545' : '#17a2b8'}; + color: white; + padding: 15px 25px; + border-radius: 8px; + font-size: 14px; + z-index: 10000; + box-shadow: 0 4px 8px rgba(0,0,0,0.3); + text-align: center; + min-width: 300px; + `; + statusDiv.textContent = message; + + document.body.appendChild(statusDiv); + + // Auto-remove after 3 seconds for success/info, 5 seconds for errors + const timeout = type === 'error' ? 5000 : 3000; + setTimeout(() => { + statusDiv.style.opacity = '0'; + statusDiv.style.transition = 'opacity 0.5s'; + setTimeout(() => statusDiv.remove(), 500); + }, timeout); +} + +function addPrinterSelection() { + // Get available printers and add selection dropdown + chrome.runtime.sendMessage({action: 'get_printers'}, (response) => { + if (response && response.success && response.printers.length > 0) { + console.log('Available printers:', response.printers); + // Could add printer selection UI here if needed + } + }); +} + +function updateOrderPrintStatus() { + // Find selected row in table and update print status + const selectedRow = document.querySelector('.print-module-table tbody tr.selected'); + if (selectedRow) { + const printStatusCell = selectedRow.querySelector('td:nth-last-child(2)'); // Second to last column + if (printStatusCell) { + printStatusCell.innerHTML = '✓ Yes'; + } + } +} + +function checkExtensionStatus() { + // Verify extension is working + chrome.runtime.sendMessage({action: 'check_extension'}, (response) => { + if (response) { + console.log('Extension status:', response); + } else { + console.error('Extension communication failed'); + } + }); +} + +// Add CSS for extension-specific styling +const extensionStyles = document.createElement('style'); +extensionStyles.textContent = ` + #print-label-btn { + background: linear-gradient(45deg, #28a745, #20c997) !important; + border: none !important; + transition: all 0.3s ease !important; + } + + #print-label-btn:hover { + background: linear-gradient(45deg, #218838, #1ea97c) !important; + transform: translateY(-1px) !important; + box-shadow: 0 4px 8px rgba(0,0,0,0.2) !important; + } +`; +document.head.appendChild(extensionStyles); \ No newline at end of file diff --git a/py_app/chrome_extension/icons/README.md b/py_app/chrome_extension/icons/README.md new file mode 100644 index 0000000..5a5a982 --- /dev/null +++ b/py_app/chrome_extension/icons/README.md @@ -0,0 +1,7 @@ +# Placeholder for icon files - in production, add actual PNG icons: +# - icon16.png (16x16 pixels) +# - icon48.png (48x48 pixels) +# - icon128.png (128x128 pixels) + +# For now, create simple text-based icons using SVG converted to PNG +# These should be replaced with proper icons later \ No newline at end of file diff --git a/py_app/chrome_extension/icons/create_icons.py b/py_app/chrome_extension/icons/create_icons.py new file mode 100644 index 0000000..a051067 --- /dev/null +++ b/py_app/chrome_extension/icons/create_icons.py @@ -0,0 +1,27 @@ +# Simple text-based icons for the Chrome extension +# These are placeholder files - replace with actual PNG icons for production + +# Create simple SVG icons that can be converted to PNG +ICON_16_SVG = ''' + + + 🖨 + +''' + +ICON_48_SVG = ''' + + + 🖨️ + +''' + +ICON_128_SVG = ''' + + + 🖨️ + +''' + +# For now, create simple text placeholders +# In production, convert these SVGs to PNG files \ No newline at end of file diff --git a/py_app/chrome_extension/icons/icon128.txt b/py_app/chrome_extension/icons/icon128.txt new file mode 100644 index 0000000..6b301ee --- /dev/null +++ b/py_app/chrome_extension/icons/icon128.txt @@ -0,0 +1,4 @@ +# Placeholder for 128x128 icon +# This is a text file placeholder +# Replace with actual icon128.png file +🖨️ \ No newline at end of file diff --git a/py_app/chrome_extension/icons/icon16.txt b/py_app/chrome_extension/icons/icon16.txt new file mode 100644 index 0000000..8b2cace --- /dev/null +++ b/py_app/chrome_extension/icons/icon16.txt @@ -0,0 +1,4 @@ +# Placeholder for 16x16 icon +# This is a text file placeholder +# Replace with actual icon16.png file +🖨️ \ No newline at end of file diff --git a/py_app/chrome_extension/icons/icon48.txt b/py_app/chrome_extension/icons/icon48.txt new file mode 100644 index 0000000..521d5ba --- /dev/null +++ b/py_app/chrome_extension/icons/icon48.txt @@ -0,0 +1,4 @@ +# Placeholder for 48x48 icon +# This is a text file placeholder +# Replace with actual icon48.png file +🖨️ \ No newline at end of file diff --git a/py_app/chrome_extension/manifest.json b/py_app/chrome_extension/manifest.json new file mode 100644 index 0000000..5dc6122 --- /dev/null +++ b/py_app/chrome_extension/manifest.json @@ -0,0 +1,44 @@ +{ + "manifest_version": 3, + "name": "Quality Recticel Print Helper", + "version": "1.0", + "description": "Direct printing extension for Quality Recticel label printing system", + "permissions": [ + "activeTab", + "storage", + "tabs" + ], + "optional_permissions": [ + "printing" + ], + "host_permissions": [ + "http://localhost:*/*", + "http://127.0.0.1:*/*", + "*://*/print_module*" + ], + "background": { + "service_worker": "background.js" + }, + "content_scripts": [ + { + "matches": [ + "http://localhost:*/print_module*", + "http://127.0.0.1:*/print_module*", + "*://*/print_module*" + ], + "js": ["content.js"], + "run_at": "document_end" + } + ], + "action": { + "default_popup": "popup.html", + "default_title": "Quality Recticel Print Helper" + }, + + "web_accessible_resources": [ + { + "resources": ["content.js"], + "matches": [""] + } + ] +} \ No newline at end of file diff --git a/py_app/chrome_extension/popup.html b/py_app/chrome_extension/popup.html new file mode 100644 index 0000000..508f951 --- /dev/null +++ b/py_app/chrome_extension/popup.html @@ -0,0 +1,102 @@ + + + + + Quality Recticel Print Helper + + + +
+ +
Quality Recticel Print Helper
+
Version 1.0
+
+ +
+ ✅ Extension Active +
+ +
+ This extension enables direct printing from the Quality Recticel label system to your default printer without browser dialogs. +
+ + + + +
+ Usage: Navigate to the Print Module page and use the enhanced print button for direct printing. +
+ + + + \ No newline at end of file diff --git a/py_app/chrome_extension/popup.js b/py_app/chrome_extension/popup.js new file mode 100644 index 0000000..03b4ed5 --- /dev/null +++ b/py_app/chrome_extension/popup.js @@ -0,0 +1,29 @@ +// Popup script for Quality Recticel Print Helper +document.addEventListener('DOMContentLoaded', function() { + console.log('Popup loaded'); + + // Test print button + document.getElementById('test-print').addEventListener('click', function() { + chrome.runtime.sendMessage({action: 'get_printers'}, function(response) { + if (response && response.success) { + if (response.printers.length > 0) { + alert(`✅ Found ${response.printers.length} printer(s):\n${response.printers.map(p => p.displayName).join('\n')}`); + } else { + alert('⚠️ No printers found. Please ensure a printer is installed and set as default.'); + } + } else { + const error = response?.error || 'Unknown error'; + if (error.includes('Chrome printing API not available')) { + alert('⚠️ Chrome Printing API not available.\n\nThis may be due to:\n• Chrome version too old (need 85+)\n• Extension permissions not granted\n• Corporate/managed Chrome installation\n\nThe extension will use browser print dialog as fallback.'); + } else { + alert('❌ Error getting printers: ' + error); + } + } + }); + }); + + // Settings button + document.getElementById('open-settings').addEventListener('click', function() { + chrome.tabs.create({url: 'chrome://settings/printing'}); + }); +}); \ No newline at end of file