mirror of
https://github.com/groldsf/obsidian_check_plugin.git
synced 2026-07-22 05:37:48 +00:00
refactor(settings): Implement component save/load logic and remove getDefaultValue
This commit is contained in:
parent
7c78611f1c
commit
d4e23856c1
4 changed files with 76 additions and 47 deletions
|
|
@ -1,10 +1,11 @@
|
|||
import { App, ButtonComponent, DropdownComponent, Notice, PluginSettingTab, Setting, TextComponent, ToggleComponent } from "obsidian";
|
||||
import CheckboxSyncPlugin from "../main";
|
||||
import { CheckboxState, DEFAULT_SETTINGS } from "../types";
|
||||
import { CheckboxState, CheckboxSyncPluginSettings, DEFAULT_SETTINGS } from "../types";
|
||||
import { ConfirmModal, InfoModal, SaveConfirmModal } from "./modals";
|
||||
import { Mutex } from "async-mutex";
|
||||
import { SettingGroup } from "./SettingGroup";
|
||||
import { EnableParentSyncSettingComponent } from "./components/EnableParentSyncSettingComponent";
|
||||
import { ValidationError } from "./validation/types";
|
||||
|
||||
export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||
plugin: CheckboxSyncPlugin;
|
||||
|
|
@ -12,7 +13,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
private uncheckedSymbolsInput: TextComponent;
|
||||
private ignoreSymbolsInput: TextComponent;
|
||||
private unknownPolicyDropdown: DropdownComponent;
|
||||
private parentToggle: ToggleComponent;
|
||||
// private parentToggle: ToggleComponent;
|
||||
private childToggle: ToggleComponent;
|
||||
private enableAutomaticFileSyncToggle: ToggleComponent;
|
||||
|
||||
|
|
@ -307,12 +308,25 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
private resetInputsToSavedSettings() {
|
||||
const settings = this.plugin.settings; // Получаем текущие сохраненные настройки
|
||||
|
||||
for (const group of this.settingGroups) {
|
||||
for (const component of group.components) {
|
||||
const key = component.getSettingKey();
|
||||
if (key in settings) {
|
||||
try {
|
||||
component.setValueInUi(settings[key]);
|
||||
} catch (error) {
|
||||
console.error(`Error resetting UI for component ${key}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Обновляем значения всех полей ввода
|
||||
this.checkedSymbolsInput.setValue(this.arrayToJsonString(settings.checkedSymbols));
|
||||
this.uncheckedSymbolsInput.setValue(this.arrayToJsonString(settings.uncheckedSymbols));
|
||||
this.ignoreSymbolsInput.setValue(this.arrayToJsonString(settings.ignoreSymbols));
|
||||
this.unknownPolicyDropdown.setValue(settings.unknownSymbolPolicy);
|
||||
this.parentToggle.setValue(settings.enableAutomaticParentState);
|
||||
// this.parentToggle.setValue(settings.enableAutomaticParentState);
|
||||
this.childToggle.setValue(settings.enableAutomaticChildState);
|
||||
this.enableAutomaticFileSyncToggle.setValue(settings.enableAutomaticFileSync);
|
||||
|
||||
|
|
@ -396,12 +410,36 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
* Does NOT interact with UI feedback (buttons, notices, error display).
|
||||
*/
|
||||
private async validateAndSaveSettings(): Promise<void> {
|
||||
|
||||
let errors: ValidationError[] = []; // Массив для сбора всех ошибок валидации
|
||||
let newSettingsData: Partial<CheckboxSyncPluginSettings> = {}; // Объект для новых данных
|
||||
|
||||
|
||||
for (const group of this.settingGroups) {
|
||||
for (const component of group.components) {
|
||||
const key = component.getSettingKey();
|
||||
try {
|
||||
const value = component.getValueFromUi();
|
||||
const validationError = component.validate();
|
||||
if (validationError) {
|
||||
errors.push(validationError); // Добавляем ошибку
|
||||
} else {
|
||||
// Если индивидуальная валидация прошла, сохраняем значение
|
||||
newSettingsData[key] = value;
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error(`Error processing component ${key}:`, err);
|
||||
errors.push({ field: key, message: `Failed to read value: ${err.message}` });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Считываем значения из UI
|
||||
const checkedValue = this.checkedSymbolsInput.getValue();
|
||||
const uncheckedValue = this.uncheckedSymbolsInput.getValue();
|
||||
const ignoreValue = this.ignoreSymbolsInput.getValue();
|
||||
const policyValue = this.unknownPolicyDropdown.getValue() as CheckboxState;
|
||||
const parentValue = this.parentToggle.getValue();
|
||||
// const parentValue = this.parentToggle.getValue();
|
||||
const childValue = this.childToggle.getValue();
|
||||
const automaticFileSyncValue = this.enableAutomaticFileSyncToggle.getValue();
|
||||
|
||||
|
|
@ -447,15 +485,23 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
throw new Error("Unchecked symbols list cannot be empty.");
|
||||
}
|
||||
|
||||
newSettingsData.checkedSymbols = checkedSymbolsArray;
|
||||
newSettingsData.uncheckedSymbols = uncheckedSymbolsArray;
|
||||
newSettingsData.ignoreSymbols = ignoreSymbolsArray;
|
||||
newSettingsData.unknownSymbolPolicy = policyValue;
|
||||
newSettingsData.enableAutomaticChildState = childValue;
|
||||
newSettingsData.enableAutomaticFileSync = automaticFileSyncValue;
|
||||
|
||||
if (errors.length > 0) {
|
||||
// Формируем сообщение об ошибке
|
||||
const errorMessage = errors.map(e => `❌ ${e.field ? `[${e.field}]: ` : ''}${e.message}`).join('\n');
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
|
||||
// 6. Вызываем сохранение -> await (может кинуть ошибку)
|
||||
await this.plugin.updateSettings(settings => {
|
||||
settings.checkedSymbols = checkedSymbolsArray;
|
||||
settings.uncheckedSymbols = uncheckedSymbolsArray;
|
||||
settings.ignoreSymbols = ignoreSymbolsArray;
|
||||
settings.unknownSymbolPolicy = policyValue;
|
||||
settings.enableAutomaticParentState = parentValue;
|
||||
settings.enableAutomaticChildState = childValue;
|
||||
settings.enableAutomaticFileSync = automaticFileSyncValue;
|
||||
Object.assign(settings, newSettingsData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -6,10 +6,10 @@ import { ValidationError } from '../validation/types';
|
|||
|
||||
export abstract class BaseSettingComponent implements ISettingComponent {
|
||||
protected setting: Setting; // Инициализируется в render конкретного компонента
|
||||
protected onChangeCallback: () => void = () => {};
|
||||
protected onChangeCallback: () => void = () => { };
|
||||
|
||||
// Конструктор теперь пустой или с минимальными общими зависимостями
|
||||
constructor() {}
|
||||
constructor() { }
|
||||
|
||||
// --- Методы для реализации наследниками ---
|
||||
abstract getSettingKey(): keyof CheckboxSyncPluginSettings;
|
||||
|
|
@ -20,19 +20,7 @@ export abstract class BaseSettingComponent implements ISettingComponent {
|
|||
abstract validate(): ValidationError | null;
|
||||
|
||||
|
||||
public getDefaultValue(): any {
|
||||
const key = this.getSettingKey(); // Получаем ключ от наследника
|
||||
if (key in DEFAULT_SETTINGS) {
|
||||
// Возвращаем значение из импортированного объекта
|
||||
return DEFAULT_SETTINGS[key];
|
||||
} else {
|
||||
// Логируем предупреждение, если ключ не найден (ошибка конфигурации)
|
||||
console.warn(
|
||||
`[${this.constructor.name}] Default value for key "${key}" not found in DEFAULT_SETTINGS. Returning undefined.`
|
||||
);
|
||||
return undefined; // Или null, или выбросить ошибку, но undefined безопаснее
|
||||
}
|
||||
}
|
||||
|
||||
// --- Общая реализация ---
|
||||
public setChangeListener(listener: () => void): void {
|
||||
this.onChangeCallback = listener;
|
||||
|
|
|
|||
|
|
@ -33,15 +33,16 @@ export class EnableParentSyncSettingComponent extends BaseSettingComponent {
|
|||
if (this.toggleComponent) {
|
||||
return this.toggleComponent.getValue();
|
||||
}
|
||||
console.warn(`getValueFromUi called before render for ${this.getSettingKey()}`);
|
||||
// Используем унаследованный getDefaultValue() для консистентности
|
||||
return this.getDefaultValue();
|
||||
// Если toggleComponent все еще не инициализирован (render не вызывался?)
|
||||
// выбрасываем ошибку, сигнализируя о неправильном использовании
|
||||
throw new Error(`[${this.getSettingKey()}] Cannot get value from UI before component is rendered.`);
|
||||
}
|
||||
|
||||
setValueInUi(value: any): void {
|
||||
if (this.toggleComponent) {
|
||||
this.toggleComponent.setValue(value as boolean);
|
||||
}
|
||||
throw new Error(`[${this.getSettingKey()}] Attempted to set value before component is rendered.`);
|
||||
}
|
||||
|
||||
validate(): ValidationError | null {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,6 @@ export interface ISettingComponent {
|
|||
*/
|
||||
getSettingKey(): keyof CheckboxSyncPluginSettings;
|
||||
|
||||
/**
|
||||
* Получает значение по умолчанию для этой настройки.
|
||||
* @returns Значение по умолчанию.
|
||||
*/
|
||||
getDefaultValue(): any;
|
||||
|
||||
/**
|
||||
* Рендерит UI-элементы для этой настройки в указанный контейнер.
|
||||
* @param container - HTML-элемент, куда добавлять настройку.
|
||||
|
|
|
|||
Loading…
Reference in a new issue