mirror of
https://github.com/groldsf/obsidian_check_plugin.git
synced 2026-07-22 05:37:48 +00:00
feat(settings): Add UI for file filtering glob patterns
This commit is contained in:
parent
a69f23159a
commit
f3f0685bdc
2 changed files with 101 additions and 0 deletions
|
|
@ -16,6 +16,7 @@ import { ConfirmModal, InfoModal, SaveConfirmModal } from "./modals";
|
|||
import { SettingsValidator } from "./validation/SettingsValidator";
|
||||
import { ValidationError } from "./validation/types";
|
||||
import { EnableConsoleLogSettingComponent } from "./components/devGroup/EnableDebug";
|
||||
import { PathGlobsSettingComponent } from "./components/pathGroup/PathGlobsSettingComponent";
|
||||
|
||||
export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
||||
plugin: CheckboxSyncPlugin;
|
||||
|
|
@ -59,6 +60,14 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
[parentToggleComp, childrenToggleComp, automaticFileSyncToggleComp]
|
||||
);
|
||||
|
||||
const pathGlobsComp = new PathGlobsSettingComponent();
|
||||
|
||||
const filteringGroup = new SettingGroup(
|
||||
"File Scope & Filtering",
|
||||
[pathGlobsComp],
|
||||
"Define rules to include or exclude files/folders from plugin processing."
|
||||
);
|
||||
|
||||
const consoleLog = new EnableConsoleLogSettingComponent();
|
||||
|
||||
const devGroup = new SettingGroup(
|
||||
|
|
@ -70,6 +79,7 @@ export class CheckboxSyncPluginSettingTab extends PluginSettingTab {
|
|||
this.settingGroups = [
|
||||
symbolGroup,
|
||||
behaviorGroup,
|
||||
filteringGroup,
|
||||
devGroup
|
||||
];
|
||||
|
||||
|
|
|
|||
91
src/ui/components/pathGroup/PathGlobsSettingComponent.ts
Normal file
91
src/ui/components/pathGroup/PathGlobsSettingComponent.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { Setting, TextAreaComponent } from 'obsidian';
|
||||
import { CheckboxSyncPluginSettings } from 'src/types';
|
||||
import { BaseSettingComponent } from 'src/ui/basedClasses/BaseSettingComponent';
|
||||
import { ValidationError } from 'src/ui/validation/types';
|
||||
|
||||
export class PathGlobsSettingComponent extends BaseSettingComponent {
|
||||
private textInput: TextAreaComponent;
|
||||
|
||||
getSettingKey(): keyof CheckboxSyncPluginSettings {
|
||||
return 'pathGlobs';
|
||||
}
|
||||
|
||||
private arrayToMultilineString(value: string[] | undefined | null): string {
|
||||
if (Array.isArray(value)) {
|
||||
try {
|
||||
return value.join('\n');
|
||||
} catch (e) {
|
||||
console.error(`[${this.getSettingKey()}] Error joining array to multiline string: `, e);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
render(container: HTMLElement, currentValue: any): void {
|
||||
const multilineStringValue = this.arrayToMultilineString(currentValue as string[] | undefined);
|
||||
|
||||
this.setting = new Setting(container)
|
||||
.setName('Ignored Files & Folders')
|
||||
.setDesc('List files or folders that the plugin should IGNORE. ' +
|
||||
'This uses "glob patterns" (similar to .gitignore syntax) to match paths.\n' +
|
||||
'- Each pattern on a new line. If this list is empty, no files are ignored (plugin processes all).\n' +
|
||||
'- Example to IGNORE: `My Folder/` or `*.log`\n' +
|
||||
'- Example to PROCESS an item within an IGNORED path: `!My Folder/My Important File.md`\n' +
|
||||
'- The last rule that matches a file determines its fate.'
|
||||
)
|
||||
.addTextArea(text => {
|
||||
this.textInput = text;
|
||||
text.setPlaceholder(
|
||||
'# Lines starting with # are comments and will be ignored\n' +
|
||||
'Drafts/\n' +
|
||||
'*.tmp\n' +
|
||||
'!Drafts/ReadyToPublish.md\n\n' +
|
||||
'# To process ONLY files in "Projects" folder:\n' +
|
||||
'*\n' +
|
||||
'!Projects/**'
|
||||
);
|
||||
text.inputEl.setAttr('rows', 10); // Увеличил немного для плейсхолдера
|
||||
text.inputEl.style.width = '100%';
|
||||
|
||||
text.setValue(multilineStringValue);
|
||||
|
||||
text.onChange(() => {
|
||||
this.onChangeCallback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getValueFromUi(): string[] {
|
||||
if (this.textInput) {
|
||||
const rawValue = this.textInput.getValue();
|
||||
return rawValue
|
||||
.split('\n')
|
||||
.map(s => s.trim())
|
||||
.filter(s => s.length > 0 && !s.startsWith('#')); // Игнорируем пустые строки и комментарии
|
||||
}
|
||||
throw new Error(`[${this.getSettingKey()}] Cannot get value from UI: TextArea component not rendered or available.`);
|
||||
}
|
||||
|
||||
setValueInUi(value: any): void {
|
||||
if (this.textInput) {
|
||||
if (value === undefined) {
|
||||
this.textInput.setValue('');
|
||||
return;
|
||||
}
|
||||
// Ожидаем, что value это string[]. Если нет, будет ошибка времени выполнения при .join()
|
||||
this.textInput.setValue((value as string[]).join('\n'));
|
||||
} else {
|
||||
throw new Error(`[${this.getSettingKey()}] Cannot set value in UI: TextArea component not rendered or available.`);
|
||||
}
|
||||
}
|
||||
|
||||
validate(): ValidationError | null {
|
||||
try {
|
||||
this.getValueFromUi();
|
||||
} catch (e: any) {
|
||||
return { field: this.getSettingKey(), message: e.message };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue