mirror of
https://github.com/tekknoman/obsidian-prio-plugin.git
synced 2026-07-22 04:34:13 +00:00
fix(setting-tab): cleanup
This commit is contained in:
parent
f9c7b5fd95
commit
edd77c6a53
5 changed files with 318 additions and 68 deletions
32
main.ts
32
main.ts
|
|
@ -1,11 +1,10 @@
|
|||
import {App, Editor, MarkdownView, Modal, Notice, Plugin} from 'obsidian';
|
||||
import {Editor, MarkdownView, Plugin} from 'obsidian';
|
||||
import {PrioPluginSettings} from "./utils/Settings";
|
||||
import {SettingTab} from "./utils/SettingTab";
|
||||
import {decreasePrio, increasePrio, removePrio, setPrio} from "./utils/Priority";
|
||||
|
||||
|
||||
const DEFAULT_SETTINGS: PrioPluginSettings = {
|
||||
selectedPreset: 'default',
|
||||
levels: 6,
|
||||
levelAliases: [
|
||||
'Major',
|
||||
|
|
@ -38,19 +37,6 @@ export default class PrioPlugin extends Plugin {
|
|||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
// This creates an icon in the left ribbon.
|
||||
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
|
||||
// Called when the user clicks the icon.
|
||||
new Notice('This is a notice!');
|
||||
});
|
||||
// Perform additional things with the ribbon
|
||||
ribbonIconEl.addClass('my-plugin-ribbon-class');
|
||||
|
||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
const statusBarItemEl = this.addStatusBarItem();
|
||||
statusBarItemEl.setText('Status Bar Text');
|
||||
|
||||
|
||||
this.addCommand({
|
||||
id: 'set-prio',
|
||||
name: 'Set priority',
|
||||
|
|
@ -124,20 +110,4 @@ export default class PrioPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
class SampleModal extends Modal {
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.setText('Woah!');
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"id": "obsidian-prio-plugin",
|
||||
"name": "Obsidian Prio Plugin",
|
||||
"id": "prioritize",
|
||||
"name": "Prioritize",
|
||||
"version": "1.0.0",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "A plugin to prioritize your tasks and notes in Obsidian",
|
||||
"description": "Prioritize your tasks and notes in Obsidian.",
|
||||
"author": "EloiMusk",
|
||||
"authorUrl": "https://github.com/EloiMusk/",
|
||||
"fundingUrl": "",
|
||||
"fundingUrl": "https://www.buymeacoffee.com/eloimusk",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
|
|
|
|||
50
styles.css
50
styles.css
|
|
@ -1,7 +1,7 @@
|
|||
/*Preset list setting*/
|
||||
.preset-list {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
border: 1px solid var(--color-base-10);
|
||||
box-shadow: inset var(--shadow-stationary);
|
||||
|
|
@ -87,3 +87,51 @@
|
|||
}
|
||||
|
||||
/*---------------------*/
|
||||
|
||||
/*Preset Modal*/
|
||||
.preset-modal {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.preset-modal-title {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.preset-input {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.preset-save-btn-group {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*---------------------*/
|
||||
|
||||
/*Save confirm modal*/
|
||||
.save-confirm-modal{
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.save-confirm-modal-title {
|
||||
}
|
||||
|
||||
.save-confirm-modal-text {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.save-btn-group {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
/*---------------------*/
|
||||
|
|
|
|||
|
|
@ -6,16 +6,19 @@ import {PrioPluginSettings} from "./Settings";
|
|||
export class SettingTab extends PluginSettingTab {
|
||||
plugin: PrioPlugin;
|
||||
saveConfirm: SaveConfirm;
|
||||
addPresetModal: AddPresetModal;
|
||||
modified = false;
|
||||
|
||||
constructor(app: App, plugin: PrioPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
this.saveConfirm = new SaveConfirm(this);
|
||||
this.addPresetModal = new AddPresetModal(this);
|
||||
}
|
||||
|
||||
hide(): any {
|
||||
hide() {
|
||||
if (this.modified) {
|
||||
this.saveConfirm.setSettingsTab(this);
|
||||
this.saveConfirm.open();
|
||||
return;
|
||||
}
|
||||
|
|
@ -56,11 +59,29 @@ export class SettingTab extends PluginSettingTab {
|
|||
});
|
||||
}
|
||||
|
||||
const presetListContainer = createEl('div', {
|
||||
cls: 'preset-list-container',
|
||||
parent: containerEl
|
||||
})
|
||||
|
||||
const presetList = createEl('ol', {
|
||||
cls: 'preset-list',
|
||||
parent: containerEl
|
||||
parent: presetListContainer
|
||||
});
|
||||
|
||||
const addPresetButton = createEl('button', {
|
||||
text: 'Add Preset',
|
||||
cls: ['mod-cta', 'mod-primary', 'btn'],
|
||||
parent: presetListContainer
|
||||
});
|
||||
|
||||
addPresetButton.addEventListener('click', () => {
|
||||
this.addPresetModal.setPresetsList(presetList);
|
||||
this.addPresetModal.open();
|
||||
});
|
||||
|
||||
this.generatePresetList(presets, presetList);
|
||||
|
||||
const levelSliderSetting = new Setting(containerEl);
|
||||
let levelSlider: SliderComponent;
|
||||
const levelText = createEl('input', {
|
||||
|
|
@ -89,7 +110,6 @@ export class SettingTab extends PluginSettingTab {
|
|||
this.generateLevelAliasList(this.plugin.settings, levelAliasesList, [saveButton]);
|
||||
});
|
||||
|
||||
this.generatePresetList(presets, presetList);
|
||||
|
||||
levelSliderSetting
|
||||
.setName('Levels')
|
||||
|
|
@ -120,7 +140,7 @@ export class SettingTab extends PluginSettingTab {
|
|||
|
||||
containerEl.append(saveButton);
|
||||
saveButton.addEventListener('click', () => {
|
||||
if (!this.isValid(levelAliasesList, [saveButton])) {
|
||||
if (!this.isValid(levelAliasesList)) {
|
||||
return;
|
||||
}
|
||||
this.setAliases(this.plugin.settings, levelAliasesList);
|
||||
|
|
@ -159,6 +179,9 @@ export class SettingTab extends PluginSettingTab {
|
|||
})
|
||||
input.addEventListener('blur', (event) => {
|
||||
const valid = this.validateLevelAlias((event.target as HTMLInputElement).value, parseInt((event.target as HTMLInputElement).parentElement?.textContent ?? '') - 1, settings.levelAliases.slice(0, settings.levels));
|
||||
if (valid) {
|
||||
this.plugin.settings.levelAliases[parseInt((event.target as HTMLInputElement).parentElement?.textContent ?? '') - 1] = (event.target as HTMLInputElement).value;
|
||||
}
|
||||
for (const button of buttons) {
|
||||
button.disabled = !valid;
|
||||
}
|
||||
|
|
@ -169,39 +192,147 @@ export class SettingTab extends PluginSettingTab {
|
|||
return els;
|
||||
}
|
||||
|
||||
generatePresetList = (presets: Preset[], presetList: HTMLOListElement) => (presets || []).map(preset => {
|
||||
const el = createEl('li', {
|
||||
text: preset.name,
|
||||
cls: 'preset-list-item',
|
||||
parent: presetList
|
||||
});
|
||||
const btnGroup = el.createEl('div', {
|
||||
cls: 'btn-group'
|
||||
});
|
||||
generatePresetId = () => {
|
||||
return Date.now().toString(36) + Math.random().toString(36);
|
||||
}
|
||||
|
||||
btnGroup.createEl('button', {
|
||||
text: 'Apply',
|
||||
cls: ['preset-list-item-apply', 'btn', 'btn-primary'],
|
||||
attr: {
|
||||
'onclick': 'alert("Preset Selected")'
|
||||
}
|
||||
})
|
||||
btnGroup.createEl('button', {
|
||||
text: 'Overwrite',
|
||||
cls: ['preset-list-item-save', 'btn', 'btn-primary'],
|
||||
attr: {
|
||||
'onclick': 'alert("Save Preset")'
|
||||
}
|
||||
})
|
||||
return el;
|
||||
});
|
||||
addPreset = (name: string, settings: PrioPluginSettings, presetList: HTMLOListElement) => {
|
||||
if (!name || !settings || !this.presetIsValid(name, settings.presets ?? [], this.plugin.settings.presets?.length ?? 0 - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
isValid = (levelAliasesList: HTMLOListElement, buttons: HTMLButtonElement[]) => {
|
||||
if (this.plugin.settings.presets) {
|
||||
this.plugin.settings.presets.push({
|
||||
id: `${this.generatePresetId()}`,
|
||||
name,
|
||||
settings: {
|
||||
levels: this.plugin.settings.levels,
|
||||
levelAliases: this.plugin.settings.levelAliases.slice(0, this.plugin.settings.levels),
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.plugin.settings.presets = [{
|
||||
id: `${this.generatePresetId()}`,
|
||||
name,
|
||||
settings: {
|
||||
levels: this.plugin.settings.levels,
|
||||
levelAliases: this.plugin.settings.levelAliases.slice(0, this.plugin.settings.levels),
|
||||
}
|
||||
}];
|
||||
}
|
||||
this.generatePresetList(this.plugin.settings.presets, presetList);
|
||||
this.plugin.saveSettings().then(() => {
|
||||
this.plugin.loadSettings().then(() => {
|
||||
new Notice('Preset applied successfully!');
|
||||
});
|
||||
});
|
||||
this.display();
|
||||
}
|
||||
|
||||
applyPreset = (preset: Preset, presetList: HTMLOListElement) => {
|
||||
if (!preset || !presetList) {
|
||||
return;
|
||||
}
|
||||
if (this.plugin.settings.presets) {
|
||||
this.plugin.settings.levels = preset.settings.levels.valueOf();
|
||||
this.plugin.settings.levelAliases = [...preset.settings.levelAliases];
|
||||
}
|
||||
this.generatePresetList(this.plugin.settings.presets ?? [], presetList);
|
||||
this.display();
|
||||
new Notice('Preset applied successfully!');
|
||||
}
|
||||
|
||||
deletePreset = (preset: Preset, presetList: HTMLOListElement) => {
|
||||
if (this.plugin.settings.presets) {
|
||||
this.plugin.settings.presets.remove(preset);
|
||||
}
|
||||
this.generatePresetList(this.plugin.settings.presets ?? [], presetList);
|
||||
this.display();
|
||||
new Notice('Preset deleted successfully!');
|
||||
}
|
||||
|
||||
overwritePreset = (preset: Preset, presetList: HTMLOListElement) => {
|
||||
if (!preset || !presetList) {
|
||||
return;
|
||||
}
|
||||
if (this.plugin.settings.presets) {
|
||||
this.plugin.settings.presets[this.plugin.settings.presets.indexOf(preset)].settings.levels = this.plugin.settings.levels.valueOf();
|
||||
this.plugin.settings.presets[this.plugin.settings.presets.indexOf(preset)].settings.levelAliases = [...this.plugin.settings.levelAliases];
|
||||
}
|
||||
this.generatePresetList(this.plugin.settings.presets ?? [], presetList);
|
||||
this.display();
|
||||
new Notice('Preset overwritten successfully!');
|
||||
}
|
||||
|
||||
generatePresetList = (presets: Preset[], presetList: HTMLOListElement) => {
|
||||
presetList.empty();
|
||||
(presets || []).map(preset => {
|
||||
const el = createEl('li', {
|
||||
cls: 'preset-list-item',
|
||||
parent: presetList
|
||||
});
|
||||
|
||||
const presetListInput = el.createEl('input', {
|
||||
cls: 'preset-list-item-input',
|
||||
value: preset.name
|
||||
});
|
||||
|
||||
presetListInput.addEventListener('change', (event) => {
|
||||
if (
|
||||
presets &&
|
||||
presets.length >= presetList.children.length - 1 &&
|
||||
(event.target as HTMLInputElement).parentElement &&
|
||||
this.presetIsValid(
|
||||
(event.target as HTMLInputElement).value,
|
||||
presets,
|
||||
((event.target as HTMLInputElement).parentElement as HTMLElement).indexOf((event.target as HTMLInputElement)))) {
|
||||
presets[presetList.children.length - 1].name = (event.target as HTMLInputElement).value;
|
||||
}
|
||||
});
|
||||
|
||||
const btnGroup = el.createEl('div', {
|
||||
cls: 'btn-group'
|
||||
});
|
||||
|
||||
const applyButton = btnGroup.createEl('button', {
|
||||
text: 'Apply',
|
||||
cls: ['preset-list-item-apply', 'btn', 'btn-primary'],
|
||||
})
|
||||
const overwriteButton = btnGroup.createEl('button', {
|
||||
text: 'Overwrite',
|
||||
cls: ['preset-list-item-overwrite', 'btn', 'btn-primary'],
|
||||
})
|
||||
const deleteButton = btnGroup.createEl('button', {
|
||||
text: 'Delete',
|
||||
cls: ['preset-list-item-delete', 'btn', 'mod-danger'],
|
||||
})
|
||||
|
||||
applyButton.addEventListener('click', () => {
|
||||
this.applyPreset(preset, presetList);
|
||||
});
|
||||
overwriteButton.addEventListener('click', () => {
|
||||
this.overwritePreset(preset, presetList);
|
||||
});
|
||||
deleteButton.addEventListener('click', () => {
|
||||
this.deletePreset(preset, presetList);
|
||||
});
|
||||
|
||||
return el;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
isValid = (levelAliasesList: HTMLOListElement) => {
|
||||
const inputs = levelAliasesList.querySelectorAll('input');
|
||||
const aliases: string[] = [];
|
||||
inputs.forEach(input => {
|
||||
aliases.push((input as HTMLInputElement).value);
|
||||
});
|
||||
inputs.forEach(input => {
|
||||
if (!this.validateLevelAlias((input as HTMLInputElement).value, aliases.indexOf((input as HTMLInputElement).value), aliases)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (aliases.length !== new Set(aliases).size) {
|
||||
new Notice('Level aliases must be unique.');
|
||||
return false;
|
||||
|
|
@ -228,6 +359,23 @@ export class SettingTab extends PluginSettingTab {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
presetIsValid = (preset: string, presets: Preset[], index: number) => {
|
||||
if (preset.length < 1) {
|
||||
new Notice('Preset name must be at least 1 character long!');
|
||||
return false;
|
||||
}
|
||||
if (preset.match(/[^a-zA-Z0-9]/)) {
|
||||
new Notice('Preset name must only contain alphanumeric characters!');
|
||||
return false;
|
||||
}
|
||||
const searchPreset = presets.find(p => p.name === preset);
|
||||
if (searchPreset && presets.indexOf(searchPreset) !== index && presets.some(p => p.name === preset)) {
|
||||
new Notice('Preset name already exists!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SaveConfirm extends Modal {
|
||||
|
|
@ -238,13 +386,27 @@ class SaveConfirm extends Modal {
|
|||
this.settingsTab = settingsTab;
|
||||
}
|
||||
|
||||
setSettingsTab(settingsTab: SettingTab) {
|
||||
this.settingsTab = settingsTab;
|
||||
}
|
||||
|
||||
open() {
|
||||
super.open();
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.setText('You have unsaved changes. Would you like to save them?');
|
||||
contentEl.classList.add('save-confirm-modal');
|
||||
|
||||
contentEl.createEl('h2', {
|
||||
text: 'Unsaved Changes',
|
||||
cls: 'save-confirm-title'
|
||||
});
|
||||
|
||||
contentEl.createEl('p', {
|
||||
text: 'You have unsaved changes. Would you like to save them?',
|
||||
cls: 'save-confirm-text'
|
||||
})
|
||||
|
||||
const btnGroup = contentEl.createEl('div', {
|
||||
cls: 'save-btn-group'
|
||||
|
|
@ -285,3 +447,74 @@ class SaveConfirm extends Modal {
|
|||
this.settingsTab.modified = false;
|
||||
}
|
||||
}
|
||||
|
||||
class AddPresetModal extends Modal {
|
||||
private settingsTab: SettingTab;
|
||||
private presetsList: HTMLOListElement;
|
||||
|
||||
constructor(settingsTab: SettingTab) {
|
||||
super(settingsTab.app);
|
||||
this.settingsTab = settingsTab;
|
||||
}
|
||||
|
||||
setPresetsList(presetsList: HTMLOListElement) {
|
||||
this.presetsList = presetsList;
|
||||
}
|
||||
|
||||
open() {
|
||||
super.open();
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.classList.add('preset-modal');
|
||||
contentEl.createEl('h2', {
|
||||
text: 'Add Preset',
|
||||
cls: 'preset-modal-title'
|
||||
})
|
||||
let presetName = '';
|
||||
|
||||
const presetNameInput = contentEl.createEl('input', {
|
||||
cls: 'preset-input',
|
||||
placeholder: 'Preset Name'
|
||||
});
|
||||
presetNameInput.addEventListener('input', () => {
|
||||
if (presetNameInput.value.length > 0) {
|
||||
presetNameInput.classList.remove('invalid');
|
||||
presetName = presetNameInput.value;
|
||||
} else {
|
||||
presetNameInput.classList.add('invalid');
|
||||
}
|
||||
});
|
||||
|
||||
const btnGroup = contentEl.createEl('div', {
|
||||
cls: 'preset-save-btn-group'
|
||||
});
|
||||
|
||||
const addButton = createEl('button', {
|
||||
text: 'Add',
|
||||
cls: ['btn', 'mod-cta'],
|
||||
});
|
||||
const cancelButton = createEl('button', {
|
||||
text: 'Cancel',
|
||||
cls: ['btn'],
|
||||
});
|
||||
|
||||
addButton.addEventListener('click', () => {
|
||||
this.settingsTab.addPreset(presetName, this.settingsTab.plugin.settings, this.presetsList);
|
||||
this.close();
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', () => {
|
||||
this.close();
|
||||
});
|
||||
|
||||
btnGroup.append(addButton);
|
||||
btnGroup.append(cancelButton);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import {Preset} from "./Presets";
|
||||
|
||||
export interface PrioPluginSettings {
|
||||
selectedPreset?: string;
|
||||
levels: number;
|
||||
levelAliases: string[];
|
||||
presets?: Preset[];
|
||||
|
|
|
|||
Loading…
Reference in a new issue