feat: per-task image/annotations, annotation editor toolbar, Tailwind compiled
- Add per-task file upload with image preview in task editor - Add dedicated annotation editor page (task_drawing.html) with Fabric.js - Add color picker, stroke width, and line dash controls to annotation toolbar - Apply property changes to selected objects in real-time - Disable style controls until a drawing tool or object is selected - Remove zoom/pan from annotation toolbar (simplified UX) - Auto-switch to select mode after placing annotation elements - Show annotation overlay on task image previews (read-only canvas) - Add file proxy route in measure blueprint for task file access - Add file_path/file_type fields to TaskCreate/TaskUpdate Pydantic schemas - Replace Tailwind CDN with compiled CSS (tailwind.config.js with full shades) - Fix Alpine.js x-init crash: extract annotations JSON to <script> tags (recipe_preview.html, task_execute.html) to avoid HTML attribute breakage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,9 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<script>
|
||||
window.__taskAnnotations = {{ task.annotations_json|default('null')|tojson }};
|
||||
</script>
|
||||
<div class="min-h-[calc(100vh-3.5rem)] flex flex-col"
|
||||
x-data="taskExecute()"
|
||||
x-init="init()"
|
||||
@@ -160,8 +163,8 @@
|
||||
<div class="annotation-container"
|
||||
x-data="annotationViewer()"
|
||||
x-init="
|
||||
imageUrl = '{{ url_for('static', filename='uploads/' ~ task.file_path) }}';
|
||||
annotations = {{ task.annotations_json|default('null')|tojson }};
|
||||
imageUrl = '/measure/api/files/{{ task.file_path }}';
|
||||
annotations = window.__taskAnnotations;
|
||||
$nextTick(() => init());
|
||||
"
|
||||
x-effect="setActiveMarker(currentSubtask?.marker_number || 0)">
|
||||
@@ -171,23 +174,18 @@
|
||||
</div>
|
||||
|
||||
{% elif task.file_path and task.file_type == 'pdf' %}
|
||||
{# PDF placeholder #}
|
||||
<div class="annotation-container flex items-center justify-center">
|
||||
<div class="text-center py-12">
|
||||
<svg class="w-16 h-16 mx-auto text-red-400 mb-3" fill="none" stroke="currentColor" stroke-width="1" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<p class="text-sm font-medium text-[var(--text-secondary)]">{{ _('Visualizzatore PDF') }}</p>
|
||||
<p class="text-xs text-[var(--text-muted)] mt-1">{{ _('In fase di sviluppo') }}</p>
|
||||
<a href="{{ url_for('static', filename='uploads/' ~ task.file_path) }}"
|
||||
target="_blank"
|
||||
class="btn btn-secondary mt-3 text-xs">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
||||
</svg>
|
||||
{{ _('Apri PDF') }}
|
||||
</a>
|
||||
</div>
|
||||
{# PDF inline viewer using PDF.js via annotationViewer #}
|
||||
<div class="annotation-container"
|
||||
x-data="annotationViewer()"
|
||||
x-init="
|
||||
imageUrl = '/measure/api/files/{{ task.file_path }}';
|
||||
annotations = window.__taskAnnotations;
|
||||
$nextTick(() => init());
|
||||
"
|
||||
x-effect="setActiveMarker(currentSubtask?.marker_number || 0)">
|
||||
<canvas x-ref="annotationCanvas"
|
||||
@click="handleClick($event)"
|
||||
class="cursor-pointer"></canvas>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
@@ -518,6 +516,10 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
|
||||
<script>
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
|
||||
</script>
|
||||
<script src="{{ url_for('static', filename='js/numpad.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/annotation-viewer.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/caliper.js') }}"></script>
|
||||
|
||||
Reference in New Issue
Block a user