Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/dashboard/Data/Views/Views.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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 = (
<DeleteViewDialog
name={name}
Expand All @@ -793,7 +794,7 @@ class Views extends TableView {
async () => {
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);
Expand Down
81 changes: 75 additions & 6 deletions src/lib/ViewPreferencesManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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
Expand Down
Loading