farmcontrol-ws/src/usersettings/usersettingsmanager.js
Tom Butcher 7b4bedeee4
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
Add sortSidebarVisibility to user settings schema and manager
- Introduced a new field `sortSidebarVisibility` in the user settings schema to manage sidebar visibility preferences.
- Updated the user settings manager to include `sortSidebarVisibility` in the settings categories and default settings structure, ensuring proper normalization and handling of this new setting.
2026-08-09 20:55:04 +01:00

117 lines
2.9 KiB
JavaScript

import { userSettingsModel } from '../database/schemas/misc/usersettings.schema.js';
const SETTINGS_CATEGORIES = [
'viewMode',
'filterSidebarVisibility',
'sortSidebarVisibility',
'columnVisibility',
'collapseState'
];
const createEmptySettings = () => ({
viewMode: {},
filterSidebarVisibility: {},
sortSidebarVisibility: {},
columnVisibility: {},
collapseState: {}
});
const normalizeCategory = category =>
category && typeof category === 'object' && !Array.isArray(category)
? category
: {};
const normalizeSettings = (defaults = {}) => ({
viewMode: normalizeCategory(defaults?.viewMode),
filterSidebarVisibility: normalizeCategory(defaults?.filterSidebarVisibility),
sortSidebarVisibility: normalizeCategory(defaults?.sortSidebarVisibility),
columnVisibility: normalizeCategory(defaults?.columnVisibility),
collapseState: normalizeCategory(defaults?.collapseState)
});
const isSafeSettingsKey = key =>
typeof key === 'string' &&
key.length > 0 &&
key.length <= 128 &&
!key.includes('.') &&
!key.includes('$') &&
!key.includes('\0');
export class UserSettingsManager {
constructor(socketClient) {
this.socketClient = socketClient;
}
getUserId() {
const userId = this.socketClient.user?._id;
if (!this.socketClient.authenticated || !userId) {
throw new Error('User is not authenticated');
}
return userId;
}
async getUserSettings() {
const userId = this.getUserId();
const userSettings = await userSettingsModel
.findOne({ user: userId })
.select('defaults')
.lean();
return normalizeSettings(userSettings?.defaults);
}
async updateUserSettings({ category, key, value } = {}) {
const userId = this.getUserId();
if (!SETTINGS_CATEGORIES.includes(category)) {
throw new Error('Invalid user settings category');
}
if (!isSafeSettingsKey(key)) {
throw new Error('Invalid user settings key');
}
if (value === undefined) {
throw new Error('User settings value is required');
}
const update = {
$set: {
[`defaults.${category}.${key}`]: value,
updatedAt: new Date()
},
$setOnInsert: {
user: userId,
createdAt: new Date()
}
};
let userSettings;
try {
userSettings = await userSettingsModel
.findOneAndUpdate({ user: userId }, update, {
new: true,
upsert: true,
setDefaultsOnInsert: true
})
.select('defaults')
.lean();
} catch (error) {
if (error?.code !== 11000) {
throw error;
}
userSettings = await userSettingsModel
.findOneAndUpdate(
{ user: userId },
{ $set: update.$set },
{ new: true }
)
.select('defaults')
.lean();
}
return normalizeSettings(userSettings?.defaults);
}
}
export { SETTINGS_CATEGORIES, createEmptySettings, isSafeSettingsKey };