From 427efb903c2f23c5ddc05ce75d869fdb187d771d Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Wed, 11 Feb 2026 01:55:05 +0000
Subject: [PATCH] =added upload tracking for crud.js

---
 assets/js/concise/CRUD.js |   97 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 80 insertions(+), 17 deletions(-)

diff --git a/assets/js/concise/CRUD.js b/assets/js/concise/CRUD.js
index 8c29ab2..ab60c8d 100644
--- a/assets/js/concise/CRUD.js
+++ b/assets/js/concise/CRUD.js
@@ -12,6 +12,7 @@
 		this.error = window.jvbError;
 		this.populate = window.jvbPopulate;
 		this.cache = new window.jvbCache(this.content);
+		this.uploadedFields = new Set(); //tracks which upload fields are currently uploading; so don't send any of these changes to server
 
 		this.activeItem = null;
 		this.isTimeline = false;
@@ -350,6 +351,21 @@
 						});
 					}
 				}
+
+				if (event === 'sent-to-queue' && data.field) {
+					const fieldName = data.field.config.name;
+					const itemId = data.field.config.itemID;
+					if (itemId && fieldName) {
+						this.uploadedFields.add(`${itemId}_${fieldName}`);
+						if (this.changes.has(itemId)) {
+							delete this.changes.get(itemId)[fieldName];
+						}
+					}
+				}
+
+				if (event === 'upload_complete') {
+					this.uploadedFields.delete(`${data['item_id']}_${data['field']}`);
+				}
 			});
 		}
 		initModals() {
@@ -496,22 +512,19 @@
 				&& data.status === 'completed') {
 				this.store.clearCache();
 			}
-			console.log('CRUD.js queue subscription');
-			console.log(event, data);
+
+
 			if (event === 'operation-status'
 				&& data.status === 'completed'
 				&& data.endpoint === 'uploads/groups') {
-				console.log('Grouped Uploads completed');
 				if (data.result && data.result.group_mappings) {
 					this.handleGroupMappings(data.result.group_mappings);
 				}
-				console.log('Cleared local cache. Refresh to see changes');
 				this.store.clearCache();
 			}
 			if (event === 'operation-status'
 				&& data.status === 'completed'
 				&& data.type === 'content_update') {
-				console.log('Cleared local cache. Refresh to see changes');
 				this.store.clearCache();
 
 				// Check for result data (from ContentExecutor)
@@ -639,14 +652,62 @@
 		const form = e.target;
 		const modal = form.closest('dialog');
 		if (!modal) return;
-		let title = `Saving changes for multiple ${this.plural}`;
-		if (modal.classList.contains('edit')) {
-			title = 'Saving your edits...';
-		} else if (modal.classList.contains('create')) {
-			title = `Creating your new ${this.singular}`;
+
+		if (modal.classList.contains('create')) {
+			this.handleCreateSubmit(modal);
+			return;
 		}
+
+		let title = `Saving changes for multiple ${this.plural}`;
+
 		this.scheduleSave(0);
 	}
+
+	async handleCreateSubmit(modal) {
+		const itemId = modal.dataset.itemId;
+
+		// 1. Flush changes to store
+		if (this.changes.size > 0) {
+			this.cancelBackup();
+			await this.handleBackup();
+		}
+
+		const changes = await this.changesStore.getAll();
+		if (changes.length === 0) return;
+
+		let allChanges = {};
+		changes.forEach(change => {
+			const { id, ...rest } = change;
+			allChanges[id] = rest;
+		});
+
+		// 2. Queue content creation, get operationId
+		let contentOpId = this.queue.addToQueue({
+			endpoint: this.endpoint,
+			headers: {
+				'X-Action-Nonce': window.auth.getNonce('dash'),
+			},
+			data: {
+				posts: allChanges,
+			},
+			popup: `Creating your new ${this.singular}`,
+			title: `Creating your new ${this.singular}`,
+		});
+
+		if (!contentOpId) return;
+
+		// 3. Queue any pending uploads with dependency on content creation
+		const uploadFields = modal.querySelectorAll('[data-upload-field]');
+		for (const fieldEl of uploadFields) {
+			const fieldId = fieldEl.dataset.uploader;
+			if (!fieldId) continue;
+
+			const uploads = window.jvbUploads.stores.uploads.filterByIndex({ field: fieldId });
+			if (uploads.length === 0) continue;
+
+			await window.jvbUploads.queueUploads('uploads', fieldId, contentOpId);
+		}
+	}
 	handleChange(e) {
 		// Early bailout - target must be in an item or be a filter
 		const inItem = e.target.closest('[data-item-id]');
@@ -762,6 +823,13 @@
 		}
 		this.changes.get(itemId)[name] = value;
 
+		for (const key of this.uploadedFields) {
+			const [itemId, fieldName] = key.split('_');
+			if (this.changes.has(itemId)) {
+				delete this.changes.get(itemId)[fieldName];
+			}
+		}
+
 		this.scheduleBackup();
 		//Only send actual itemIds to server. If this is a recently uploaded item, just store changes for now
 		if (typeof itemId === 'number' || !itemId.includes('group')) {
@@ -1137,7 +1205,8 @@
 		this.ui.modals.edit.h2.textContent = `Editing ${item.fields.post_title === '' ? this.singular : item.fields.post_title}`;
 		this.ui.modals.edit.form.dataset.formId = `edit-${itemID}`;
 
-		this.forms.registerForm(this.ui.modals.edit.form, {cache: false});
+		this.forms.registerForm(this.ui.modals.edit.form, {cache: false,
+			autoUpload: true,});
 
 		this.isPopulating = true;
 		this.populate.populate(this.ui.modals.edit.form, item);
@@ -1186,7 +1255,6 @@
 			await this.handleBackup();
 		}
 		const changes = await this.changesStore.getAll();
-		console.log('Saving Changes: ', changes);
 		if (changes.length === 0) return;
 
 		if (title === '') {
@@ -1423,10 +1491,6 @@
 		let uploader = window.jvbUploads;
 		let field = uploader.fields.get(fieldId);
 
-
-		console.log(posts);
-		console.log(field);
-
 		let added = [];
 		posts.forEach(post => {
 			const placeholderPost = {
@@ -1491,7 +1555,6 @@
 	}
 
 	handleGroupMappings(mappings) {
-		console.log('[CRUD] Applying group mappings:', mappings);
 		// mappings = { "group_abc123": 456, "group_def456": 789 }
 
 		for (const [groupId, postId] of Object.entries(mappings)) {

--
Gitblit v1.10.0