Browse Source

Intentando que se puedan elegir las imágenes ya cargadas

Celestino Rey 5 months ago
parent
commit
b458ca41e8

+ 1 - 1
K8S/Makefile

@@ -1,5 +1,5 @@
 export REGISTRO=harbor.rancher.lab:30002\/siemensrad
-export IMG_VERSION = alpine-35
+export IMG_VERSION = alpine-37
 export NAMESPACE = trgenerator
 
 # limpia todo

+ 2 - 0
src/doc_generator/settings.py

@@ -171,4 +171,6 @@ TINYMCE_DEFAULT_CONFIG = {
     
     "relative_urls": False,  # Important for correct media URL handling in PDFs
     "remove_script_host": True,  # Important for correct media URL handling in PDFs
+    
+    "file_picker_types": "image",
 }

+ 58 - 0
src/templates/textdocs/base.html

@@ -7,6 +7,64 @@
     {% block form_media %}
         {{ form.media }}
     {% endblock %}
+   <!-- Full TinyMCE configuration with file browser support -->
+    {% block tinymce_config %}
+    <script>
+        document.addEventListener('DOMContentLoaded', function () {
+            // Remove any editors that django-tinymce auto-initialized
+            if (typeof tinymce !== 'undefined' && tinymce.editors.length > 0) {
+                tinymce.remove();
+            }
+
+            // Re-initialize with our full configuration
+            if (typeof tinymce !== 'undefined') {
+                tinymce.init({
+                    selector: 'textarea.tinymce',
+                    height: 320,
+                    width: '100%',
+                    menubar: 'file edit view insert format tools table help',
+                    plugins: [
+                        'advlist autolink lists link image charmap print preview anchor',
+                        'searchreplace visualblocks code fullscreen',
+                        'insertdatetime media table paste code help wordcount'
+                    ],
+                    toolbar: 'undo redo | bold italic underline strikethrough | ' +
+                             'fontselect fontsizeselect formatselect | ' +
+                             'alignleft aligncenter alignright alignjustify | ' +
+                             'outdent indent | numlist bullist | ' +
+                             'forecolor backcolor removeformat | ' +
+                             'pagebreak | charmap emoticons | ' +
+                             'fullscreen preview print | ' +
+                             'image media link anchor | ltr rtl',
+                    custom_undo_redo_levels: 10,
+                    relative_urls: false,
+                    remove_script_host: true,
+                    images_upload_url: '/tinymce/upload/',
+                    file_picker_types: 'image',
+
+                    // THIS is what enables the browse button
+                    file_picker_callback: function (callback, value, meta) {
+                        if (meta.filetype === 'image') {
+                            // Open a custom dialog with an iframe
+                            tinymce.activeEditor.windowManager.openUrl({
+                                title: 'Browse Uploaded Images',
+                                url: '{% url "image_browser" %}',
+                                width: 800,
+                                height: 500,
+                                onMessage: function (api, message) {
+                                    if (message.mceAction === 'selectImage') {
+                                        callback(message.url);
+                                        api.close();
+                                    }
+                                }
+                            });
+                        }
+                    }
+                });
+            }
+        });
+    </script>
+    {% endblock %}
 </head>
 <body>
     <div class="container mt-4">

+ 134 - 0
src/templates/textdocs/image_browser.html

@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Browse Uploaded Images</title>
+    <style>
+        * {
+            box-sizing: border-box;
+            margin: 0;
+            padding: 0;
+        }
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+            background-color: #f5f5f5;
+            padding: 20px;
+        }
+        h2 {
+            margin-bottom: 15px;
+            color: #333;
+            font-size: 18px;
+        }
+        .search-bar {
+            width: 100%;
+            padding: 10px 15px;
+            margin-bottom: 20px;
+            border: 1px solid #ccc;
+            border-radius: 5px;
+            font-size: 14px;
+        }
+        .gallery {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+            gap: 15px;
+        }
+        .gallery-item {
+            background: #fff;
+            border: 2px solid transparent;
+            border-radius: 8px;
+            padding: 8px;
+            cursor: pointer;
+            transition: all 0.2s ease;
+            text-align: center;
+            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+        }
+        .gallery-item:hover {
+            border-color: #009999;
+            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+            transform: translateY(-2px);
+        }
+        .gallery-item img {
+            width: 100%;
+            height: 120px;
+            object-fit: contain;
+            border-radius: 4px;
+        }
+        .gallery-item .filename {
+            margin-top: 8px;
+            font-size: 11px;
+            color: #666;
+            word-break: break-all;
+            line-height: 1.3;
+        }
+        .no-images {
+            text-align: center;
+            color: #888;
+            padding: 40px;
+            font-size: 16px;
+        }
+    </style>
+</head>
+<body>
+
+    <h2>Select an Image</h2>
+
+    {% if images %}
+        <input
+            type="text"
+            class="search-bar"
+            id="searchInput"
+            placeholder="Search by filename..."
+            onkeyup="filterImages()"
+        >
+
+        <div class="gallery" id="imageGallery">
+            {% for image in images %}
+                <div class="gallery-item"
+                     onclick="selectImage('{{ image.url }}')"
+                     data-filename="{{ image.filename|lower }}">
+                    <img src="{{ image.url }}"
+                         alt="{{ image.filename }}"
+                         loading="lazy">
+                    <div class="filename">{{ image.filename }}</div>
+                </div>
+            {% endfor %}
+        </div>
+    {% else %}
+        <div class="no-images">
+            <p>No images have been uploaded yet.</p>
+            <p>Use the "Upload" tab in the image dialog to add your first image.</p>
+        </div>
+    {% endif %}
+
+    <script>
+        /**
+         * Sends the selected image URL back to TinyMCE
+         * using postMessage (the correct way for TinyMCE 5+ dialogs).
+         */
+        function selectImage(url) {
+            window.parent.postMessage({
+                mceAction: 'selectImage',
+                url: url
+            }, '*');
+        }
+
+        /**
+         * Filters the gallery based on the search input.
+         */
+        function filterImages() {
+            var searchTerm = document.getElementById('searchInput').value.toLowerCase();
+            var items = document.querySelectorAll('.gallery-item');
+
+            items.forEach(function (item) {
+                var filename = item.getAttribute('data-filename');
+                if (filename.includes(searchTerm)) {
+                    item.style.display = '';
+                } else {
+                    item.style.display = 'none';
+                }
+            });
+        }
+    </script>
+
+</body>
+</html>

+ 4 - 1
src/textdocs/forms.py

@@ -16,4 +16,7 @@ class DocumentVersionForm(forms.ModelForm):
 
 # We also need a simple form for creating the parent document
 class DocumentCreateForm(forms.Form):
-    title = forms.CharField(max_length=255, widget=forms.TextInput(attrs={'class': 'form-control'}))
+    title = forms.CharField(
+        max_length=255, 
+        widget=forms.TextInput(attrs={'class': 'form-control'})
+    )

+ 1 - 0
src/textdocs/urls.py

@@ -15,4 +15,5 @@ urlpatterns = [
     path('document/<int:pk>/delete/', views.document_delete, name='document_delete'),
 
     path('tinymce/upload/', views.tinymce_image_upload, name='tinymce_image_upload'),
+    path('tinymce/browse/', views.image_browser, name='image_browser'),
 ]

+ 23 - 1
src/textdocs/views.py

@@ -11,6 +11,7 @@ from django.http import JsonResponse
 from django.views.decorators.csrf import csrf_exempt
 from django.core.files.storage import default_storage
 import os
+from django.conf import settings
 
 from .models import Document, DocumentVersion # Changed from Document
 from .forms import DocumentVersionForm, DocumentCreateForm # Changed from DocumentForm
@@ -192,4 +193,25 @@ def tinymce_image_upload(request):
     file_url = default_storage.url(file_path)
 
     # Return the URL in the format TinyMCE expects
-    return JsonResponse({'location': file_url})
+    return JsonResponse({'location': file_url})
+
+@login_required
+def image_browser(request):
+    """
+    Displays a gallery of all previously uploaded images.
+    TinyMCE opens this page in a dialog, and clicking an image
+    selects it and closes the dialog.
+    """
+    upload_dir = os.path.join(settings.MEDIA_ROOT, 'tinymce_uploads')
+    images = []
+
+    if os.path.exists(upload_dir):
+        for filename in sorted(os.listdir(upload_dir)):
+            # Only include common image file types
+            if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg')):
+                images.append({
+                    'filename': filename,
+                    'url': f'{settings.MEDIA_URL}tinymce_uploads/{filename}',
+                })
+
+    return render(request, 'textdocs/image_browser.html', {'images': images})