gonets/FRONT/DEV/src/store/settings/settingsStore.ts
test ee350c1852
Some checks failed
ci/woodpecker/manual/woodpecker Pipeline failed
Добавление настроек и их функциональности
2025-07-04 15:07:41 +05:00

124 lines
No EOL
4.2 KiB
TypeScript

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import {nodesSettings} from "./config/nodesSettings";
import { networkSettings } from './config/networkSettings';
import {appearanceSettings} from "./config/appearanceSettings";
type SettingValue = any;
type SettingsDictionary = Record<string, SettingValue>;
export type Setting = {
readonly id: string;
readonly type: 'boolean' | 'select' | 'text' | 'number' | 'button' | 'hidden';
readonly label: string;
readonly defaultValue: any;
value?: string;
readonly min?: number;
readonly max?: number;
readonly options?: any;
readonly sectionId: string;
readonly required?: boolean;
readonly action?: () => void;
};
type SettingsState = {
settingsConfig: Setting[];
settingsValues: SettingsDictionary;
activeSection: string | null;
pendingChanges: SettingsDictionary;
setActiveSection: (sectionId: string | null) => void;
updateSetting: (id: string, value: any) => void;
initializeSettings: () => void;
getSetting: (id: string) => Setting & { currentValue: any };
resetSettings: () => void;
applyChanges: () => void;
discardChanges: () => void;
getSettingValue: <T = any>(id: string) => T;
getNumberSetting: (id: string, fallback?: number) => number;
};
const defaultSettings: Setting[] = [
...nodesSettings,
...networkSettings,
...appearanceSettings,
];
export const useSettingsStore = create<SettingsState>()(
persist(
(set, get) => ({
settingsConfig: defaultSettings,
settingsValues: {},
activeSection: null,
pendingChanges: {},
setActiveSection: (sectionId) => set({ activeSection: sectionId }),
updateSetting: (id, value) =>
set((state) => ({
pendingChanges: { ...state.pendingChanges, [id]: value }
})),
applyChanges: () =>
set((state) => ({
settingsValues: { ...state.settingsValues, ...state.pendingChanges },
pendingChanges: {}
})),
discardChanges: () => set({ pendingChanges: {} }),
initializeSettings: () => {
const { settingsValues, settingsConfig } = get();
const newValues = { ...settingsValues };
settingsConfig.forEach(setting => {
if (newValues[setting.id] === undefined) {
newValues[setting.id] = setting.defaultValue;
}
});
set({ settingsValues: newValues });
},
getSetting: (id) => {
const state = get();
const setting = state.settingsConfig.find(s => s.id === id);
if (!setting) throw new Error(`Setting ${id} not found`);
const hasPendingChange = Object.prototype.hasOwnProperty.call(state.pendingChanges, id);
const hasSavedValue = Object.prototype.hasOwnProperty.call(state.settingsValues, id);
const currentValue = hasPendingChange
? state.pendingChanges[id]
: hasSavedValue
? state.settingsValues[id]
: setting.defaultValue;
return {
...setting,
currentValue
};
},
getSettingValue: (id: string) => {
const state = get();
return state.settingsValues[id] ??
state.settingsConfig.find(s => s.id === id)?.defaultValue;
},
getNumberSetting: (id: string, fallback = 0) => {
const value = get().getSettingValue(id);
return Number(value) || fallback;
},
resetSettings: () => set({ settingsValues: {}, pendingChanges: {} }),
}),
{
name: 'app-settings',
partialize: (state) => ({
settingsValues: state.settingsValues
}),
onRehydrateStorage: () => (state) => {
state?.initializeSettings();
}
}
)
);