mindnet_obsidian/src/ui/ProfileSelectionModal.ts
Lars 556145e76d
Some checks are pending
Node.js build / build (20.x) (push) Waiting to run
Node.js build / build (22.x) (push) Waiting to run
Update ProfileSelectionModal to change button text and remove folder creation functionality
- Changed the button text from "Pick…" to "Anpassen" for better localization.
- Removed the folder creation button and its associated functionality to streamline the modal interface.
2026-01-17 09:12:22 +01:00

219 lines
7.0 KiB
TypeScript

import { App, Modal, Notice, Setting, TFile } from "obsidian";
import type { InterviewConfig, InterviewProfile } from "../interview/types";
import { FolderTreeModal, type FolderTreeResult } from "./FolderTreeModal";
import { NoteIndex } from "../entityPicker/noteIndex";
export interface ProfileSelectionResult {
profile: InterviewProfile;
title: string;
folderPath: string; // Vault-relative path, empty string for root
}
export class ProfileSelectionModal extends Modal {
result: ProfileSelectionResult | null = null;
onSubmit: (result: ProfileSelectionResult) => void;
config: InterviewConfig;
initialTitle: string;
defaultFolderPath: string;
private noteIndex: NoteIndex;
constructor(
app: App,
config: InterviewConfig,
onSubmit: (result: ProfileSelectionResult) => void,
initialTitle: string = "",
defaultFolderPath: string = ""
) {
super(app);
this.config = config;
this.onSubmit = onSubmit;
this.initialTitle = initialTitle;
this.defaultFolderPath = defaultFolderPath;
this.noteIndex = new NoteIndex(app);
}
onOpen(): void {
const { contentEl } = this;
contentEl.empty();
contentEl.createEl("h2", { text: "Create Note from Profile" });
// Group profiles by group
const grouped = new Map<string, InterviewProfile[]>();
const ungrouped: InterviewProfile[] = [];
for (const profile of this.config.profiles) {
if (profile.group) {
if (!grouped.has(profile.group)) {
grouped.set(profile.group, []);
}
const groupProfiles = grouped.get(profile.group);
if (groupProfiles) {
groupProfiles.push(profile);
}
} else {
ungrouped.push(profile);
}
}
let selectedProfile: InterviewProfile | null = null;
let titleInput: string = this.initialTitle;
let folderPath: string = this.defaultFolderPath;
// Title input
const titleSetting = new Setting(contentEl)
.setName("Title")
.setDesc("Note title")
.addText((text) => {
text.setValue(this.initialTitle).onChange((value) => {
titleInput = value;
});
text.inputEl.focus();
text.inputEl.select();
});
// Folder selection
const folderDisplay = contentEl.createEl("div", { cls: "folder-display" });
folderDisplay.style.marginBottom = "1em";
folderDisplay.style.padding = "0.5em";
folderDisplay.style.backgroundColor = "var(--background-secondary)";
folderDisplay.style.borderRadius = "4px";
const folderLabel = folderDisplay.createEl("span", {
text: "Folder: ",
cls: "folder-label",
});
const folderPathSpan = folderDisplay.createEl("span", {
text: folderPath || "(root)",
cls: "folder-path",
});
folderPathSpan.style.fontWeight = "bold";
const folderButtonContainer = folderDisplay.createEl("div");
folderButtonContainer.style.display = "flex";
folderButtonContainer.style.gap = "0.5em";
folderButtonContainer.style.marginTop = "0.5em";
const pickFolderBtn = folderButtonContainer.createEl("button", {
text: "Anpassen",
});
pickFolderBtn.onclick = async () => {
const folderModal = new FolderTreeModal(this.app, this.noteIndex, folderPath);
const result = await folderModal.show();
if (result) {
folderPath = result.folderPath;
folderPathSpan.textContent = folderPath || "(root)";
}
};
// Profile selection (grouped)
for (const [groupName, profiles] of grouped.entries()) {
contentEl.createEl("h3", { text: groupName });
for (const profile of profiles) {
const setting = new Setting(contentEl)
.setName(profile.label)
.setDesc(`Type: ${profile.note_type}`)
.addButton((button) => {
button.setButtonText("Select").onClick(() => {
// Clear previous selection
contentEl.querySelectorAll(".profile-selected").forEach((el) => {
if (el instanceof HTMLElement) {
el.removeClass("profile-selected");
}
});
// Mark as selected
setting.settingEl.addClass("profile-selected");
selectedProfile = profile;
// Update folder path from profile defaults
const profileFolder = (profile.defaults?.folder as string) || this.defaultFolderPath || "";
folderPath = profileFolder;
folderPathSpan.textContent = folderPath || "(root)";
// Log selection
console.log("Profile selected", {
key: profile.key,
label: profile.label,
noteType: profile.note_type,
stepCount: profile.steps?.length || 0,
defaultFolder: profileFolder,
});
});
});
}
}
// Ungrouped profiles
if (ungrouped.length > 0) {
if (grouped.size > 0) {
contentEl.createEl("h3", { text: "Other" });
}
for (const profile of ungrouped) {
const setting = new Setting(contentEl)
.setName(profile.label)
.setDesc(`Type: ${profile.note_type}`)
.addButton((button) => {
button.setButtonText("Select").onClick(() => {
// Clear previous selection
contentEl.querySelectorAll(".profile-selected").forEach((el) => {
if (el instanceof HTMLElement) {
el.removeClass("profile-selected");
}
});
// Mark as selected
setting.settingEl.addClass("profile-selected");
selectedProfile = profile;
// Update folder path from profile defaults
const profileFolder = (profile.defaults?.folder as string) || this.defaultFolderPath || "";
folderPath = profileFolder;
folderPathSpan.textContent = folderPath || "(root)";
// Log selection
console.log("Profile selected", {
key: profile.key,
label: profile.label,
noteType: profile.note_type,
stepCount: profile.steps?.length || 0,
defaultFolder: profileFolder,
});
});
});
}
}
// Submit button
new Setting(contentEl).addButton((button) => {
button
.setButtonText("Create Note")
.setCta()
.onClick(() => {
if (!selectedProfile) {
new Notice("Please select a profile");
return;
}
if (!titleInput.trim()) {
new Notice("Please enter a title");
return;
}
this.result = {
profile: selectedProfile,
title: titleInput.trim(),
folderPath: folderPath.trim(),
};
this.onSubmit(this.result);
this.close();
});
});
}
onClose(): void {
const { contentEl } = this;
contentEl.empty();
}
}