162 lines
4.6 KiB
TypeScript
162 lines
4.6 KiB
TypeScript
|
|
import { App, Modal, Notice, Setting, TFile } from "obsidian";
|
||
|
|
import type { InterviewConfig, InterviewProfile } from "../interview/types";
|
||
|
|
|
||
|
|
export interface ProfileSelectionResult {
|
||
|
|
profile: InterviewProfile;
|
||
|
|
title: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export class ProfileSelectionModal extends Modal {
|
||
|
|
result: ProfileSelectionResult | null = null;
|
||
|
|
onSubmit: (result: ProfileSelectionResult) => void;
|
||
|
|
config: InterviewConfig;
|
||
|
|
initialTitle: string;
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
app: App,
|
||
|
|
config: InterviewConfig,
|
||
|
|
onSubmit: (result: ProfileSelectionResult) => void,
|
||
|
|
initialTitle: string = ""
|
||
|
|
) {
|
||
|
|
super(app);
|
||
|
|
this.config = config;
|
||
|
|
this.onSubmit = onSubmit;
|
||
|
|
this.initialTitle = initialTitle;
|
||
|
|
}
|
||
|
|
|
||
|
|
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;
|
||
|
|
|
||
|
|
// 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();
|
||
|
|
});
|
||
|
|
|
||
|
|
// 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;
|
||
|
|
|
||
|
|
// Log selection
|
||
|
|
console.log("Profile selected", {
|
||
|
|
key: profile.key,
|
||
|
|
label: profile.label,
|
||
|
|
noteType: profile.note_type,
|
||
|
|
stepCount: profile.steps?.length || 0,
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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;
|
||
|
|
|
||
|
|
// Log selection
|
||
|
|
console.log("Profile selected", {
|
||
|
|
key: profile.key,
|
||
|
|
label: profile.label,
|
||
|
|
noteType: profile.note_type,
|
||
|
|
stepCount: profile.steps?.length || 0,
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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(),
|
||
|
|
};
|
||
|
|
this.onSubmit(this.result);
|
||
|
|
this.close();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
onClose(): void {
|
||
|
|
const { contentEl } = this;
|
||
|
|
contentEl.empty();
|
||
|
|
}
|
||
|
|
}
|