- 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.
219 lines
7.0 KiB
TypeScript
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();
|
|
}
|
|
}
|