From fa9cc36ce018200ca45a5c991277bfd527a2564f Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sun, 5 Oct 2025 14:30:34 +0200 Subject: [PATCH] fix --- src/dashboard/Data/Views/Views.react.js | 7 ++- src/lib/ViewPreferencesManager.js | 81 +++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/dashboard/Data/Views/Views.react.js b/src/dashboard/Data/Views/Views.react.js index a7cd42ff4..3b3532b1c 100644 --- a/src/dashboard/Data/Views/Views.react.js +++ b/src/dashboard/Data/Views/Views.react.js @@ -731,7 +731,7 @@ class Views extends TableView { async () => { if (this.viewPreferencesManager) { try { - await this.viewPreferencesManager.saveViews(this.context.applicationId, this.state.views); + await this.viewPreferencesManager.saveView(this.context.applicationId, newView, this.state.views); } catch (error) { console.error('Failed to save views:', error); this.showNote('Failed to save view changes', true); @@ -766,7 +766,7 @@ class Views extends TableView { async () => { if (this.viewPreferencesManager) { try { - await this.viewPreferencesManager.saveViews(this.context.applicationId, this.state.views); + await this.viewPreferencesManager.saveView(this.context.applicationId, view, this.state.views); } catch (error) { console.error('Failed to save views:', error); this.showNote('Failed to save view changes', true); @@ -780,6 +780,7 @@ class Views extends TableView { ); } else if (this.state.deleteIndex !== null) { const name = this.state.views[this.state.deleteIndex]?.name || ''; + const viewToDelete = this.state.views[this.state.deleteIndex]; extras = ( { if (this.viewPreferencesManager) { try { - await this.viewPreferencesManager.saveViews(this.context.applicationId, this.state.views); + await this.viewPreferencesManager.deleteView(this.context.applicationId, viewToDelete.id, this.state.views); } catch (error) { console.error('Failed to save views:', error); this.showNote('Failed to save view changes', true); diff --git a/src/lib/ViewPreferencesManager.js b/src/lib/ViewPreferencesManager.js index 5822deb85..53954c6e4 100644 --- a/src/lib/ViewPreferencesManager.js +++ b/src/lib/ViewPreferencesManager.js @@ -44,24 +44,47 @@ export default class ViewPreferencesManager { } /** - * Saves views to either server or local storage based on configuration and user preference + * Saves a single view to either server or local storage based on configuration and user preference * @param {string} appId - The application ID - * @param {Array} views - Array of views to save + * @param {Object} view - The view to save + * @param {Array} allViews - All views (required for local storage fallback) * @returns {Promise} */ - async saveViews(appId, views) { + async saveView(appId, view, allViews) { // Check if server storage is enabled and user prefers it if (this.serverStorage.isServerConfigEnabled() && prefersServerStorage(appId)) { try { - return await this._saveViewsToServer(appId, views); + return await this._saveViewToServer(appId, view); } catch (error) { - console.error('Failed to save views to server:', error); + console.error('Failed to save view to server:', error); // On error, fallback to local storage } } // Use local storage (either by preference or as fallback) - return this._saveViewsToLocal(appId, views); + return this._saveViewsToLocal(appId, allViews); + } + + /** + * Deletes a single view from either server or local storage based on configuration and user preference + * @param {string} appId - The application ID + * @param {string} viewId - The ID of the view to delete + * @param {Array} allViews - All views (required for local storage fallback) + * @returns {Promise} + */ + async deleteView(appId, viewId, allViews) { + // Check if server storage is enabled and user prefers it + if (this.serverStorage.isServerConfigEnabled() && prefersServerStorage(appId)) { + try { + return await this._deleteViewFromServer(appId, viewId); + } catch (error) { + console.error('Failed to delete view from server:', error); + // On error, fallback to local storage + } + } + + // Use local storage (either by preference or as fallback) + return this._saveViewsToLocal(appId, allViews); } /** @@ -224,6 +247,52 @@ export default class ViewPreferencesManager { } } + /** + * Saves a single view to server storage + * @private + */ + async _saveViewToServer(appId, view) { + try { + const viewId = view.id || this._generateViewId(); + const viewConfig = { ...view }; + delete viewConfig.id; // Don't store ID in the config itself + + // Remove null and undefined values to keep the storage clean + Object.keys(viewConfig).forEach(key => { + if (viewConfig[key] === null || viewConfig[key] === undefined) { + delete viewConfig[key]; + } + }); + + // Stringify the query if it exists and is an array/object + if (viewConfig.query && (Array.isArray(viewConfig.query) || typeof viewConfig.query === 'object')) { + viewConfig.query = JSON.stringify(viewConfig.query); + } + + await this.serverStorage.setConfig( + `views.view.${viewId}`, + viewConfig, + appId + ); + } catch (error) { + console.error('Failed to save view to server:', error); + throw error; + } + } + + /** + * Deletes a single view from server storage + * @private + */ + async _deleteViewFromServer(appId, viewId) { + try { + await this.serverStorage.deleteConfig(`views.view.${viewId}`, appId); + } catch (error) { + console.error('Failed to delete view from server:', error); + throw error; + } + } + /** * Gets views from local storage (original implementation) * @private