mirror of
https://github.com/alamion/obsidian-jira-sync.git
synced 2026-07-22 05:43:04 +00:00
feat: add "Add comment to Jira" command with editor selection pre-fill
Opens a modal pre-populated with any selected editor text, allowing users to highlight notes in a non-synced section and post them as a Jira comment in one step. Supports API v2 (plain text) and v3 (ADF).
This commit is contained in:
parent
ad11b3e89a
commit
4958fc6a3c
6 changed files with 112 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ import {JiraIssue, JiraTransitionType} from "../interfaces";
|
|||
import {baseRequest, sanitizeObject} from "./base";
|
||||
import {Notice} from "obsidian";
|
||||
import {chunkArray, createLimiter} from "../tools/asyncLimiter";
|
||||
import {markdownToAdf} from "../tools/markdownToAdf";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -257,6 +258,27 @@ export async function addWorkLog(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a comment to a Jira issue
|
||||
*/
|
||||
export async function addComment(
|
||||
plugin: JiraPlugin,
|
||||
issueKey: string,
|
||||
markdownText: string
|
||||
): Promise<any> {
|
||||
let body: any;
|
||||
if (plugin.settings.connection.apiVersion === "3") {
|
||||
body = markdownToAdf(markdownText);
|
||||
} else {
|
||||
body = markdownText;
|
||||
}
|
||||
const payload = JSON.stringify({ body });
|
||||
const response = await baseRequest(plugin, 'post', `/issue/${issueKey}/comment`, payload);
|
||||
new Notice(`Comment added to ${issueKey}`);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
export async function bulkAddWorkLog(
|
||||
plugin: JiraPlugin,
|
||||
worklogs: { issueKey: string, timeSpent: string, startedAt: string, comment: string }[],
|
||||
|
|
|
|||
36
src/commands/addComment.ts
Normal file
36
src/commands/addComment.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import {Editor, MarkdownView, Notice} from "obsidian";
|
||||
import JiraPlugin from "../main";
|
||||
import {IssueCommentModal} from "../modals";
|
||||
import {addComment, validateSettings} from "../api";
|
||||
import {useTranslations} from "../localization/translator";
|
||||
|
||||
const t = useTranslations("commands.add_comment").t;
|
||||
|
||||
export function registerAddCommentCommand(plugin: JiraPlugin): void {
|
||||
plugin.addCommand({
|
||||
id: "add-comment-jira",
|
||||
name: t("name"),
|
||||
editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => {
|
||||
if (!validateSettings(plugin)) return false;
|
||||
if (!view.file) return false;
|
||||
|
||||
const frontmatter = plugin.app.metadataCache.getFileCache(view.file)?.frontmatter;
|
||||
const issueKey = frontmatter?.key;
|
||||
if (!issueKey) return false;
|
||||
|
||||
if (!checking) {
|
||||
const selectedText = editor.getSelection();
|
||||
new IssueCommentModal(plugin.app, selectedText, async (commentText: string) => {
|
||||
try {
|
||||
await addComment(plugin, issueKey, commentText);
|
||||
} catch (error) {
|
||||
new Notice(t("error") + ": " + (error.message || "Unknown error"));
|
||||
console.error(error);
|
||||
}
|
||||
}).open();
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export * from './addComment';
|
||||
export * from './addWorkLogBatch';
|
||||
export * from './addWorkLogManually';
|
||||
export * from './batchFetchIssues';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
registerUpdateIssueCommand, registerUpdateWorkLogManuallyCommand,
|
||||
registerGetCurrentIssueCommand, registerUpdateWorkLogBatchCommand,
|
||||
registerCreateIssueCommand, registerGetIssueCommandWithCustomKey, registerUpdateIssueStatusCommand,
|
||||
registerBatchFetchIssuesCommand
|
||||
registerBatchFetchIssuesCommand, registerAddCommentCommand
|
||||
} from "./commands";
|
||||
import {transform_string_to_functions_mappings} from "./tools/convertFunctionString";
|
||||
import {createJiraSyncExtension} from "./postprocessing/livePreview";
|
||||
|
|
@ -36,6 +36,7 @@ export default class JiraPlugin extends Plugin {
|
|||
|
||||
registerUpdateWorkLogManuallyCommand(this);
|
||||
registerUpdateWorkLogBatchCommand(this);
|
||||
registerAddCommentCommand(this);
|
||||
|
||||
// Add settings tab
|
||||
this.addSettingTab(new JiraSettingTab(this.app, this));
|
||||
|
|
|
|||
50
src/modals/IssueCommentModal.ts
Normal file
50
src/modals/IssueCommentModal.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import {App, Modal, Notice, Setting} from "obsidian";
|
||||
import {useTranslations} from "../localization/translator";
|
||||
|
||||
const t = useTranslations("modals.comment").t;
|
||||
|
||||
/**
|
||||
* Modal for adding a comment to a Jira issue.
|
||||
* Pre-populated with any text that was selected in the editor when the command was invoked.
|
||||
*/
|
||||
export class IssueCommentModal extends Modal {
|
||||
private onSubmit: (commentText: string) => void;
|
||||
private commentText: string;
|
||||
|
||||
constructor(app: App, initialText: string, onSubmit: (commentText: string) => void) {
|
||||
super(app);
|
||||
this.commentText = initialText;
|
||||
this.onSubmit = onSubmit;
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
new Setting(this.contentEl).setName(t("name")).setHeading();
|
||||
|
||||
new Setting(this.contentEl)
|
||||
.setName(t("body.name"))
|
||||
.addTextArea((text) => {
|
||||
text
|
||||
.setValue(this.commentText)
|
||||
.onChange((value) => {
|
||||
this.commentText = value;
|
||||
});
|
||||
text.inputEl.rows = 10;
|
||||
text.inputEl.style.width = "100%";
|
||||
});
|
||||
|
||||
new Setting(this.contentEl)
|
||||
.addButton((btn) =>
|
||||
btn
|
||||
.setButtonText(t("submit"))
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
if (!this.commentText.trim()) {
|
||||
new Notice(t("warns.empty"));
|
||||
return;
|
||||
}
|
||||
this.close();
|
||||
this.onSubmit(this.commentText);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export * from "./IssueCommentModal";
|
||||
export * from "./IssueSearchModal";
|
||||
export * from "./IssueStatusModal";
|
||||
export * from "./IssueTypeModal";
|
||||
|
|
|
|||
Loading…
Reference in a new issue