From 94de71140be2d0c80bf6a2e03cb9381b37736ed5 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 06 Feb 2026 17:03:02 +0000
Subject: [PATCH] =Some minor CRUD.js and UploadManager.js tweaks

---
 assets/js/concise/CRUD.js |  124 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 117 insertions(+), 7 deletions(-)

diff --git a/assets/js/concise/CRUD.js b/assets/js/concise/CRUD.js
index d97155b..8c29ab2 100644
--- a/assets/js/concise/CRUD.js
+++ b/assets/js/concise/CRUD.js
@@ -402,7 +402,7 @@
 					keyPath: 'id',
 					endpoint: this.endpoint??'content',	//for taxonomy stores
 					headers: {
-						'action_nonce': window.auth.getNonce('dash'),
+						'X-Action-Nonce': window.auth.getNonce('dash'),
 					},
 					indexes: [
 						{name: 'id', keyPath: 'id'},
@@ -482,16 +482,29 @@
 		// 	}
 		// });
 
+		if (window.jvbUploads) {
+			window.jvbUploads.subscribe((event, data) => {
+				if (event === 'groups_uploaded' && data.content === this.content) {
+					this.handleGroupsUploaded(data);
+				}
+			});
+		}
+
 		this.queue.subscribe((event, data) => {
 			if (['image_upload', 'video_upload', 'document_upload'].includes(data.type)
 				&& event === 'operation-status'
 				&& 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();
 			}
@@ -508,9 +521,7 @@
 				}
 
 				// Get successfully processed post IDs
-				const successfulIds = Object.keys(data.result.posts).filter(id => {
-					return data.result.posts[id]?.success === true;
-				});
+				const successfulIds = Object.keys(data.result.posts);
 
 				if (successfulIds.length === 0) {
 					return;
@@ -752,7 +763,10 @@
 		this.changes.get(itemId)[name] = value;
 
 		this.scheduleBackup();
-		this.scheduleSave();
+		//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')) {
+			this.scheduleSave();
+		}
 	}
 	scheduleBackup() {
 		window.debouncer.schedule(
@@ -1201,7 +1215,7 @@
 		let operation = {
 			endpoint: this.endpoint,
 			headers: {
-				'action_nonce': window.auth.getNonce('dash'),
+				'X-Action-Nonce': window.auth.getNonce('dash'),
 			},
 			data: {
 				posts: allChanges,
@@ -1400,6 +1414,102 @@
 		});
 	}
 	/***************************************************************
+	 UPLOAD GROUP SUPPORT
+	 Handles:
+	  	- immediate UI feedback once the uploaded groups are sent to server
+	***************************************************************/
+	handleGroupsUploaded(data) {
+		const { posts, fieldId } = data;
+		let uploader = window.jvbUploads;
+		let field = uploader.fields.get(fieldId);
+
+
+		console.log(posts);
+		console.log(field);
+
+		let added = [];
+		posts.forEach(post => {
+			const placeholderPost = {
+				id: post.groupId,
+				title: post.fields.post_title || `New ${this.singular}`,
+				status: 'draft',
+				date: new Date().toISOString(),
+				modified: new Date().toISOString(),
+				thumbnail: null,
+				icon: this.content,
+				taxonomies: {},
+				fields: post.fields,
+				images: {},
+			};
+
+			post.images.forEach((uploadId, index) => {
+				let id = uploadId['upload_id'];
+				if (index === 0) {
+					placeholderPost.fields['post_thumbnail'] = uploadId;
+				}
+				let upload = uploader.stores.uploads.get(id);
+				if (upload) {
+					placeholderPost.images[id] = {
+						'image-alt-text': '',
+						'image-caption': '',
+						'image-title': upload.fields.originalName,
+						medium: uploader.createPreviewUrl(uploader.formatFile(upload))
+					};
+				}
+
+			});
+			//
+			// // Add to store (won't persist since it's a fake ID)
+			// this.store.data.set(post.groupId, placeholderPost);
+			//
+			//
+			// // Render immediately
+			// let element;
+			// switch (this.view) {
+			// 	case 'grid':
+			// 		element = this.renderGridItem(placeholderPost);
+			// 		this.ui.grid.prepend(element);
+			// 		break;
+			// 	case 'list':
+			// 		element = this.renderListItem(placeholderPost);
+			// 		this.ui.grid.prepend(element);
+			// 		break;
+			// 	case 'table':
+			// 		element = this.renderTableItem(placeholderPost);
+			// 		if (this.ui.table.body) {
+			// 			this.ui.table.body.prepend(element);
+			// 		}
+			// 		break;
+			// }
+			// element.classList.add('uploading');
+			added.push(placeholderPost);
+		});
+		this.store.saveMany(added).then(() => this.render());
+
+
+		this.a11y.announce(`${posts.length} ${posts.length === 1 ? this.singular : this.plural} created. Waiting for server confirmation...`);
+	}
+
+	handleGroupMappings(mappings) {
+		console.log('[CRUD] Applying group mappings:', mappings);
+		// mappings = { "group_abc123": 456, "group_def456": 789 }
+
+		for (const [groupId, postId] of Object.entries(mappings)) {
+			// Get any pending changes for this temp item
+			let changes = {};
+			if (this.changes.has(groupId)) {
+				changes = this.changes.get(groupId);
+				this.changes.delete(groupId);
+			}
+			let storedChanges = this.changesStore.get(groupId)??{};
+			if (changes.size > 0 || storedChanges.size > 0) {
+				changes = window.deepMerge(storedChanges, changes);
+				this.changes.set(postId, changes);
+				this.scheduleBackup();
+			}
+		}
+	}
+	/***************************************************************
 	 UTILITY
 	***************************************************************/
 	shouldRemoveItemUI(newStatus) {

--
Gitblit v1.10.0