@@ -549,14 +481,16 @@
/**
* Task Execute - Main Alpine.js component
* Manages measurement workflow state, save logic, and navigation.
+ * Layout: 3-column (marker sidebar | image center | info+numpad right)
*/
function taskExecute() {
return {
// ---- Data from server ----
- task: {{ task|tojson }},
- subtasks: {{ task.subtasks|tojson if task.subtasks else '[]' }},
+ task: window.__taskData,
+ subtasks: window.__taskSubtasks,
lotNumber: '{{ lot_number or '' }}',
serialNumber: '{{ serial_number or '' }}',
+ recipeImagePath: window.__recipeImagePath || '',
// ---- Measurement state ----
currentIndex: 0,
@@ -568,6 +502,17 @@ function taskExecute() {
// ---- Value from numpad / caliper ----
currentValue: null,
+ // ---- Image switching logic ----
+ get currentSubtaskImage() {
+ return this.currentSubtask?.image_path || null;
+ },
+ get showSubtaskImage() {
+ return !!this.currentSubtaskImage;
+ },
+ get showTaskImage() {
+ return !this.currentSubtaskImage && !!this.task.file_path;
+ },
+
// ---- Computed properties ----
get currentSubtask() {
return this.subtasks[this.currentIndex] || null;
@@ -635,7 +580,6 @@ function taskExecute() {
// ---- Init ----
init() {
- // Sort subtasks by order_index to ensure correct order
this.subtasks.sort((a, b) => (a.order_index || 0) - (b.order_index || 0));
},
@@ -661,14 +605,13 @@ function taskExecute() {
this.currentValue = value;
this.errorMessage = '';
- // Compute pass/fail before saving
const pf = this.passFailStatus;
const dev = this.deviation;
this.saving = true;
try {
- const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '';
+ const csrfToken = document.querySelector('meta[name=csrf-token]')?.content || '';
const response = await fetch('{{ url_for("measure.save_measurement") }}', {
method: 'POST',
@@ -694,7 +637,7 @@ function taskExecute() {
return;
}
- // Record measurement locally (replace if already measured)
+ // Record measurement locally
const existingIdx = this.measurements.findIndex(m => m.subtask_id === this.currentSubtask.id);
const mEntry = { subtask_id: this.currentSubtask.id, value, pass_fail: pf, deviation: dev };
if (existingIdx !== -1) {
@@ -705,25 +648,21 @@ function taskExecute() {
this.saving = false;
- // Pause 1s to let user see the result (pass/fail/warning)
+ // Pause to show result feedback
await new Promise(r => setTimeout(r, 1000));
// Check if all done
if (this.completedCount >= this.totalSubtasks) {
- // Auto-advance to next task, or show overlay on last task
const taskIds = window.__allTaskIds || [];
const currentIdx = taskIds.indexOf(this.task.id);
if (currentIdx >= 0 && currentIdx < taskIds.length - 1) {
- // Navigate to next task
window.location.href = '{{ url_for("measure.task_execute", task_id=0) }}'.replace('/0', '/' + taskIds[currentIdx + 1]);
} else {
- // Last task (or unknown): show completion overlay
this.showCompletionOverlay = true;
}
return;
}
- // Advance to next unmeasured subtask
this.advanceToNext();
} catch (err) {
@@ -737,15 +676,12 @@ function taskExecute() {
advanceToNext() {
this.currentValue = null;
- // First try the next sequential subtask
for (let i = this.currentIndex + 1; i < this.totalSubtasks; i++) {
if (!this.isMeasured(this.subtasks[i].id)) {
this.currentIndex = i;
return;
}
}
-
- // Wrap around from beginning
for (let i = 0; i < this.currentIndex; i++) {
if (!this.isMeasured(this.subtasks[i].id)) {
this.currentIndex = i;