From e9967fa22781d922ba4eb8fb44fe72d200ac4b14 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 10 Nov 2025 21:04:10 +0000
Subject: [PATCH] =IconsManager.php update
---
assets/js/concise/UploadManager.js | 126 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 120 insertions(+), 6 deletions(-)
diff --git a/assets/js/concise/UploadManager.js b/assets/js/concise/UploadManager.js
index 7144428..b59101c 100644
--- a/assets/js/concise/UploadManager.js
+++ b/assets/js/concise/UploadManager.js
@@ -38,6 +38,8 @@
],
});
+ window.jvbUploadBlobs = this.uploadStore;
+
// Subscribe to store events
this.fieldStore.subscribe(this.handleFieldStoreEvent.bind(this));
this.uploadStore.subscribe(this.handleUploadStoreEvent.bind(this));
@@ -48,7 +50,6 @@
// Core data structures
this.fields = new Map();
this.uploads = new Map();
- this.uploadBlobs = new Map();
this.groups = new Map();
this.selected = new Map();
this.selectionHandlers = new Map();
@@ -98,6 +99,20 @@
'failed_permanent': 'Upload failed permanently'
};
+ // Sortable configuration
+ this.sortableInstances = new Map();
+ this.sortableConfig = {
+ animation: 150,
+ draggable: '.item',
+ handle: '.select-item-label, img', // Can drag by image or checkbox label
+ ghostClass: 'sortable-ghost',
+ chosenClass: 'sortable-chosen',
+ dragClass: 'sortable-drag',
+ onEnd: (evt) => {
+ this.handleReorder(evt);
+ }
+ };
+
this.init();
}
@@ -209,6 +224,9 @@
if (config.destination === 'post_group' && !this.dragController) {
this.initGroupFeatures();
}
+ if (config.type !== 'single') {
+ this.initSortable(field);
+ }
return fieldId;
}
@@ -355,6 +373,76 @@
});
}
+ initSortable(field) {
+ if (!window.Sortable) return;
+
+ // Main grid
+ const mainGrid = field.element.querySelector('.item-grid:not(.group)');
+ if (mainGrid) {
+ this.sortableInstances.set(`${field.id}-main`,
+ new Sortable(mainGrid, {
+ ...this.sortableConfig,
+ group: {
+ name: field.id,
+ pull: true,
+ put: true
+ }
+ })
+ );
+ }
+
+ // Group grids (for selection mode with grouping)
+ const groupGrids = field.element.querySelectorAll('.item-grid.group');
+ groupGrids.forEach((grid, index) => {
+ this.sortableInstances.set(`${field.id}-group-${index}`,
+ new Sortable(grid, {
+ ...this.sortableConfig,
+ group: {
+ name: field.id,
+ pull: true,
+ put: true
+ }
+ })
+ );
+ });
+ }
+
+// Add reorder handler
+ handleReorder(evt) {
+ const grid = evt.to;
+ const fieldWrapper = grid.closest('.field, .upload');
+ if (!fieldWrapper) return;
+
+ const form = fieldWrapper.closest('form');
+ if (!form) return;
+
+ // Get form config if available
+ const formId = form.dataset.formId;
+ if (formId && window.jvbForms) {
+ const formConfig = window.jvbForms.forms?.get(formId);
+ if (formConfig?.options.autosave) {
+ // Trigger autosave after reordering
+ window.jvbForms.scheduleSave(formConfig, 1000);
+ }
+ }
+
+ // Announce for accessibility
+ if (window.jvbA11y) {
+ window.jvbA11y.announce('Item reordered');
+ }
+
+ // Trigger custom event
+ fieldWrapper.dispatchEvent(new CustomEvent('jvb-items-reordered', {
+ detail: {
+ from: evt.from,
+ to: evt.to,
+ oldIndex: evt.oldIndex,
+ newIndex: evt.newIndex
+ },
+ bubbles: true
+ }));
+ }
+
/*******************************************************************************
* EXTERNAL FILE DROP HANDLERS (for new uploads from desktop)
*******************************************************************************/
@@ -1750,6 +1838,9 @@
formData.append('posts', JSON.stringify(posts));
formData.append('upload_ids', JSON.stringify(uploadMap));
+ for (const [key, value] of formData.entries()) {
+ console.log(key, value);
+ }
const operation = {
endpoint: 'uploads/groups',
method: 'POST',
@@ -2861,11 +2952,14 @@
}
}
async saveUpload(upload) {
- // Handle blob data separately
- if (upload.file instanceof File || upload.file instanceof Blob) {
- await this.uploadStore.saveBlob(upload.id, upload.file);
- // Don't store the file in the main store
- const { file, originalFile, ...cleanUpload } = upload;
+ // Use the processed file if available, otherwise original
+ const fileToStore = upload.processedFile || upload.originalFile || upload.file;
+
+ if (fileToStore instanceof File || fileToStore instanceof Blob) {
+ await this.uploadStore.saveBlob(upload.id, fileToStore);
+
+ // Don't store file objects in main store
+ const { file, originalFile, processedFile, ...cleanUpload } = upload;
await this.uploadStore.save(cleanUpload);
} else {
await this.uploadStore.save(upload);
@@ -2929,6 +3023,12 @@
this.selectionHandlers.clear();
this.cleanupAllPreviewUrls();
+ this.sortableInstances.forEach(instance => {
+ if (instance?.destroy) {
+ instance.destroy();
+ }
+ });
+ this.sortableInstances.clear();
// Clear data
this.fields.clear();
@@ -2938,6 +3038,20 @@
this.subscribers.clear();
}
+ destroySortable(fieldName) {
+ // Destroy all sortable instances for this field
+ const instances = Array.from(this.sortableInstances.keys())
+ .filter(key => key.startsWith(fieldName));
+
+ instances.forEach(key => {
+ const instance = this.sortableInstances.get(key);
+ if (instance?.destroy) {
+ instance.destroy();
+ }
+ this.sortableInstances.delete(key);
+ });
+ }
+
cleanupRestore() {
this.restoreModal.handleClose();
this.restoreSelection.destroy();
--
Gitblit v1.10.0