Initial commit
This commit is contained in:
commit
1d38287f40
15 changed files with 1054 additions and 0 deletions
159
main.ts
Normal file
159
main.ts
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import {
|
||||
App,
|
||||
Editor,
|
||||
getFrontMatterInfo,
|
||||
MarkdownView,
|
||||
Modal,
|
||||
Notice,
|
||||
Plugin,
|
||||
PluginSettingTab, request,
|
||||
Setting,
|
||||
TFile
|
||||
} from 'obsidian';
|
||||
|
||||
interface YoutrackArticlePluginSettings {
|
||||
youtrackEndpoint: string;
|
||||
youtrackToken: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: YoutrackArticlePluginSettings = {
|
||||
youtrackEndpoint: 'https://example.youtrack.cloud',
|
||||
youtrackToken: ''
|
||||
}
|
||||
|
||||
export default class YoutrackArticlePlugin extends Plugin {
|
||||
settings: YoutrackArticlePluginSettings;
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
// Sync command
|
||||
this.addCommand({
|
||||
id: 'sync-current-youtrack-article',
|
||||
name: 'Sync current note',
|
||||
checkCallback: (checking: boolean) => {
|
||||
// Check for markdown view
|
||||
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (markdownView) {
|
||||
if (!checking) {
|
||||
const file= this.app.workspace.getActiveFile();
|
||||
if (file) {
|
||||
this.syncFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
// This command will only show up in Command Palette when the check function returns true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new YoutrackArticleSettingTab(this.app, this));
|
||||
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
console.log('click', evt);
|
||||
});
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
||||
}
|
||||
|
||||
async syncFile(file: TFile) {
|
||||
// Abort if no token set
|
||||
if (!this.settings.youtrackToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not sync files without explicit instructions in frontmatter
|
||||
let publishFlag: boolean = false;
|
||||
let publishId: string;
|
||||
let publishProject: string;
|
||||
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
if (!!frontmatter?.['youtrack-publish']) {
|
||||
publishFlag = true;
|
||||
publishId = frontmatter['youtrack-id'];
|
||||
publishProject = frontmatter['youtrack-project'];
|
||||
}
|
||||
});
|
||||
|
||||
if (publishFlag) {
|
||||
this.app.vault.cachedRead(file).then((data) => {
|
||||
const { frontmatter, contentStart, exists } = getFrontMatterInfo(data);
|
||||
const url = this.settings.youtrackEndpoint + "/api/articles" + (publishId ? '/' + publishId : '');
|
||||
const syncContents = data.slice(contentStart);
|
||||
request({
|
||||
contentType: 'application/json',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.settings.youtrackToken
|
||||
},
|
||||
method: 'POST',
|
||||
url: url,
|
||||
body: JSON.stringify({
|
||||
"content": syncContents,
|
||||
"summary": file.basename,
|
||||
"project": {
|
||||
"shortName": publishProject,
|
||||
}
|
||||
}),
|
||||
throw: true,
|
||||
}).then((responseData) => {
|
||||
const response = JSON.parse(responseData);
|
||||
this.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
frontmatter["youtrack-id"] = response?.["id"];
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
class YoutrackArticleSettingTab extends PluginSettingTab {
|
||||
plugin: YoutrackArticlePlugin;
|
||||
|
||||
constructor(app: App, plugin: YoutrackArticlePlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
const {containerEl} = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('YouTrack Token')
|
||||
.setDesc('Permanent access token')
|
||||
.addText(text => text
|
||||
.setPlaceholder('Enter your token')
|
||||
.setValue(this.plugin.settings.youtrackToken)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.youtrackToken = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('YouTrack Endpoint')
|
||||
.setDesc('Endpoint for your YouTrack instance')
|
||||
.addText(text => text
|
||||
.setPlaceholder('Enter your endpoint')
|
||||
.setValue(this.plugin.settings.youtrackEndpoint)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.youtrackEndpoint = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue