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 { App, ButtonComponent, DropdownComponent, Notice, PluginSettingTab, Setting, TextComponent, ToggleComponent } from "obsidian";
|
||||||
import CheckboxSyncPlugin from "../main";
|
import CheckboxSyncPlugin from "../main";
|
||||||
import { CheckboxState, DEFAULT_SETTINGS } from "../types";
|
import { CheckboxState, CheckboxSyncPluginSettings, DEFAULT_SETTINGS } from "../types";
|
||||||
import { ConfirmModal, InfoModal, SaveConfirmModal } from "./modals";
|
import { ConfirmModal, InfoModal, SaveConfirmModal } from "./modals";
|
||||||
import { Mutex } from "async-mutex";
|
import { Mutex } from "async-mutex";
|
||||||
import { SettingGroup } from "./SettingGroup";
|
import { SettingGroup } from "./SettingGroup";
|
||||||
import { EnableParentSyncSettingComponent } from "./components/EnableParentSyncSettingComponent";
|
import { EnableParentSyncSettingComponent } from "./components/EnableParentSyncSettingComponent";
|
||||||
|
import { ValidationError } from "./validation/types";
|
||||||
|
|
||||||
export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||||
plugin: CheckboxSyncPlugin;
|
plugin: CheckboxSyncPlugin;
|
||||||
|
|
@ -12,7 +13,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||||
private uncheckedSymbolsInput: TextComponent;
|
private uncheckedSymbolsInput: TextComponent;
|
||||||
private ignoreSymbolsInput: TextComponent;
|
private ignoreSymbolsInput: TextComponent;
|
||||||
private unknownPolicyDropdown: DropdownComponent;
|
private unknownPolicyDropdown: DropdownComponent;
|
||||||
private parentToggle: ToggleComponent;
|
// private parentToggle: ToggleComponent;
|
||||||
private childToggle: ToggleComponent;
|
private childToggle: ToggleComponent;
|
||||||
private enableAutomaticFileSyncToggle: ToggleComponent;
|
private enableAutomaticFileSyncToggle: ToggleComponent;
|
||||||
|
|
||||||
|
|
@ -307,12 +308,25 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||||
private resetInputsToSavedSettings() {
|
private resetInputsToSavedSettings() {
|
||||||
const settings = this.plugin.settings; // Получаем текущие сохраненные настройки
|
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.checkedSymbolsInput.setValue(this.arrayToJsonString(settings.checkedSymbols));
|
||||||
this.uncheckedSymbolsInput.setValue(this.arrayToJsonString(settings.uncheckedSymbols));
|
this.uncheckedSymbolsInput.setValue(this.arrayToJsonString(settings.uncheckedSymbols));
|
||||||
this.ignoreSymbolsInput.setValue(this.arrayToJsonString(settings.ignoreSymbols));
|
this.ignoreSymbolsInput.setValue(this.arrayToJsonString(settings.ignoreSymbols));
|
||||||
this.unknownPolicyDropdown.setValue(settings.unknownSymbolPolicy);
|
this.unknownPolicyDropdown.setValue(settings.unknownSymbolPolicy);
|
||||||
this.parentToggle.setValue(settings.enableAutomaticParentState);
|
// this.parentToggle.setValue(settings.enableAutomaticParentState);
|
||||||
this.childToggle.setValue(settings.enableAutomaticChildState);
|
this.childToggle.setValue(settings.enableAutomaticChildState);
|
||||||
this.enableAutomaticFileSyncToggle.setValue(settings.enableAutomaticFileSync);
|
this.enableAutomaticFileSyncToggle.setValue(settings.enableAutomaticFileSync);
|
||||||
|
|
||||||
|
|
@ -396,12 +410,36 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||||
* Does NOT interact with UI feedback (buttons, notices, error display).
|
* Does NOT interact with UI feedback (buttons, notices, error display).
|
||||||
*/
|
*/
|
||||||
private async validateAndSaveSettings(): Promise<void> {
|
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
|
// 1. Считываем значения из UI
|
||||||
const checkedValue = this.checkedSymbolsInput.getValue();
|
const checkedValue = this.checkedSymbolsInput.getValue();
|
||||||
const uncheckedValue = this.uncheckedSymbolsInput.getValue();
|
const uncheckedValue = this.uncheckedSymbolsInput.getValue();
|
||||||
const ignoreValue = this.ignoreSymbolsInput.getValue();
|
const ignoreValue = this.ignoreSymbolsInput.getValue();
|
||||||
const policyValue = this.unknownPolicyDropdown.getValue() as CheckboxState;
|
const policyValue = this.unknownPolicyDropdown.getValue() as CheckboxState;
|
||||||
const parentValue = this.parentToggle.getValue();
|
// const parentValue = this.parentToggle.getValue();
|
||||||
const childValue = this.childToggle.getValue();
|
const childValue = this.childToggle.getValue();
|
||||||
const automaticFileSyncValue = this.enableAutomaticFileSyncToggle.getValue();
|
const automaticFileSyncValue = this.enableAutomaticFileSyncToggle.getValue();
|
||||||
|
|
||||||
|
|
@ -447,15 +485,23 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||||
throw new Error("Unchecked symbols list cannot be empty.");
|
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 (может кинуть ошибку)
|
// 6. Вызываем сохранение -> await (может кинуть ошибку)
|
||||||
await this.plugin.updateSettings(settings => {
|
await this.plugin.updateSettings(settings => {
|
||||||
settings.checkedSymbols = checkedSymbolsArray;
|
Object.assign(settings, newSettingsData);
|
||||||
settings.uncheckedSymbols = uncheckedSymbolsArray;
|
|
||||||
settings.ignoreSymbols = ignoreSymbolsArray;
|
|
||||||
settings.unknownSymbolPolicy = policyValue;
|
|
||||||
settings.enableAutomaticParentState = parentValue;
|
|
||||||
settings.enableAutomaticChildState = childValue;
|
|
||||||
settings.enableAutomaticFileSync = automaticFileSyncValue;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,19 +20,7 @@ export abstract class BaseSettingComponent implements ISettingComponent {
|
||||||
abstract validate(): ValidationError | null;
|
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 {
|
public setChangeListener(listener: () => void): void {
|
||||||
this.onChangeCallback = listener;
|
this.onChangeCallback = listener;
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,16 @@ export class EnableParentSyncSettingComponent extends BaseSettingComponent {
|
||||||
if (this.toggleComponent) {
|
if (this.toggleComponent) {
|
||||||
return this.toggleComponent.getValue();
|
return this.toggleComponent.getValue();
|
||||||
}
|
}
|
||||||
console.warn(`getValueFromUi called before render for ${this.getSettingKey()}`);
|
// Если toggleComponent все еще не инициализирован (render не вызывался?)
|
||||||
// Используем унаследованный getDefaultValue() для консистентности
|
// выбрасываем ошибку, сигнализируя о неправильном использовании
|
||||||
return this.getDefaultValue();
|
throw new Error(`[${this.getSettingKey()}] Cannot get value from UI before component is rendered.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
setValueInUi(value: any): void {
|
setValueInUi(value: any): void {
|
||||||
if (this.toggleComponent) {
|
if (this.toggleComponent) {
|
||||||
this.toggleComponent.setValue(value as boolean);
|
this.toggleComponent.setValue(value as boolean);
|
||||||
}
|
}
|
||||||
|
throw new Error(`[${this.getSettingKey()}] Attempted to set value before component is rendered.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(): ValidationError | null {
|
validate(): ValidationError | null {
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,6 @@ export interface ISettingComponent {
|
||||||
*/
|
*/
|
||||||
getSettingKey(): keyof CheckboxSyncPluginSettings;
|
getSettingKey(): keyof CheckboxSyncPluginSettings;
|
||||||
|
|
||||||
/**
|
|
||||||
* Получает значение по умолчанию для этой настройки.
|
|
||||||
* @returns Значение по умолчанию.
|
|
||||||
*/
|
|
||||||
getDefaultValue(): any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Рендерит UI-элементы для этой настройки в указанный контейнер.
|
* Рендерит UI-элементы для этой настройки в указанный контейнер.
|
||||||
* @param container - HTML-элемент, куда добавлять настройку.
|
* @param container - HTML-элемент, куда добавлять настройку.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue