mirror of
https://github.com/forketyfork/obsidian-youtrack-fetcher.git
synced 2026-07-22 12:30:26 +00:00
124 lines
3.3 KiB
TypeScript
124 lines
3.3 KiB
TypeScript
import { App, Modal, TextComponent, normalizePath } from "obsidian";
|
|
import type YouTrackPlugin from "./YouTrackPlugin";
|
|
export default class YouTrackIssueModal extends Modal {
|
|
plugin: YouTrackPlugin;
|
|
issueId: string;
|
|
statusEl: HTMLElement;
|
|
loadingIndicator: HTMLElement;
|
|
|
|
constructor(app: App, plugin: YouTrackPlugin) {
|
|
super(app);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
onOpen() {
|
|
const { contentEl } = this;
|
|
contentEl.createEl("h2", { text: "Fetch YouTrack issue" });
|
|
|
|
// Create input field for issue ID
|
|
const inputContainer = contentEl.createDiv({ cls: "youtrack-input-container" });
|
|
const input = new TextComponent(inputContainer)
|
|
.setPlaceholder("Issue URL or ID (e.g., ABC-123)")
|
|
.setValue(this.issueId || "")
|
|
.onChange(value => {
|
|
this.issueId = value;
|
|
// Clear any previous error messages
|
|
if (this.statusEl) {
|
|
this.statusEl.setText("");
|
|
}
|
|
});
|
|
input.inputEl.addClass("youtrack-input");
|
|
|
|
// Create status element for messages
|
|
this.statusEl = contentEl.createEl("p", { cls: "youtrack-status" });
|
|
|
|
// Create loading indicator (hidden by default)
|
|
this.loadingIndicator = contentEl.createEl("div", {
|
|
cls: "youtrack-loading",
|
|
text: "Fetching issue...",
|
|
});
|
|
|
|
// Focus the input field and select all text
|
|
setTimeout(() => {
|
|
input.inputEl.focus();
|
|
input.inputEl.select();
|
|
}, 0);
|
|
|
|
// Create buttons container
|
|
const buttonsContainer = contentEl.createDiv({
|
|
cls: "youtrack-modal-button-container",
|
|
});
|
|
|
|
// Add cancel button
|
|
buttonsContainer.createEl("button", { text: "Cancel" }).addEventListener("click", () => {
|
|
this.close();
|
|
});
|
|
|
|
// Add fetch button
|
|
const fetchButton = buttonsContainer.createEl("button", {
|
|
text: "Fetch issue",
|
|
cls: "mod-cta",
|
|
});
|
|
|
|
const fetchIssue = async () => {
|
|
if (!this.issueId) {
|
|
this.statusEl.setText("Please enter an issue ID or URL");
|
|
this.statusEl.addClass("error-message");
|
|
return;
|
|
}
|
|
|
|
const parsedId = this.plugin.parseIssueId(this.issueId);
|
|
if (!parsedId) {
|
|
this.statusEl.setText("Invalid issue ID or URL (must match your YouTrack URL)");
|
|
this.statusEl.addClass("error-message");
|
|
return;
|
|
}
|
|
|
|
if (this.plugin.settings.templatePath) {
|
|
const normalizedPath = normalizePath(this.plugin.settings.templatePath);
|
|
const exists = await this.plugin.app.vault.adapter.exists(normalizedPath);
|
|
|
|
if (!exists) {
|
|
this.statusEl.setText(
|
|
`Template file not found: ${normalizedPath}. Please check the template path in settings.`
|
|
);
|
|
this.statusEl.addClass("error-message");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Show loading indicator
|
|
this.loadingIndicator.classList.add("visible");
|
|
this.statusEl.setText("");
|
|
|
|
try {
|
|
await this.plugin.importIssue(parsedId);
|
|
this.close();
|
|
} catch (error) {
|
|
// Hide loading indicator
|
|
this.loadingIndicator.classList.remove("visible");
|
|
|
|
// Show error message
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
this.statusEl.setText(`Error: ${errorMessage}`);
|
|
this.statusEl.addClass("error-message");
|
|
}
|
|
};
|
|
|
|
fetchButton.addEventListener("click", () => {
|
|
fetchIssue().catch(console.error);
|
|
});
|
|
|
|
// Handle Enter key press
|
|
input.inputEl.addEventListener("keypress", event => {
|
|
if (event.key === "Enter") {
|
|
fetchIssue().catch(console.error);
|
|
}
|
|
});
|
|
}
|
|
|
|
onClose() {
|
|
const { contentEl } = this;
|
|
contentEl.empty();
|
|
}
|
|
}
|