mirror of
https://github.com/jonnydeates/obsidian-pivotal-tracker-integration-plugin.git
synced 2026-07-22 07:40:25 +00:00
Compare commits
8 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2eabf49aa0 | ||
|
|
b849e74623 | ||
|
|
14ef5f87e8 | ||
|
|
7229f6c30d | ||
|
|
22dda2c863 | ||
|
|
8921a4378e | ||
|
|
b0e0cdbe25 | ||
|
|
6148bee3a5 |
11 changed files with 1029 additions and 1065 deletions
|
|
@ -9,15 +9,18 @@ Once the plugin is installed, you will need to configure a few things.
|
|||
- This is inside your account settings
|
||||
- Then You need your Tracker Project ID
|
||||
- This can be found at the url of your tracker project.
|
||||
- Finally you need to specify a folder location for the stories to be pulled to
|
||||
- Finally you need to specify a folder location for the stories to be pulled to.
|
||||
|
||||
## How to use
|
||||
|
||||
- Enter settings within the plugin.
|
||||
-
|
||||
- Click the Pull Tracker Stories Ribbon OR click on the command for pulling the stories.
|
||||
- Enjoy!
|
||||
|
||||
## Cloning this Project
|
||||
- Clone this repo.
|
||||
- `npm i` or `yarn` to install dependencies
|
||||
- `npm run dev` to start compilation in watch mode.
|
||||
- `npm run build` to compile for the plugin. It'll generate the main.js
|
||||
|
||||
## Manually installing the plugin
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ esbuild.build({
|
|||
'@lezer/lr',
|
||||
...builtins],
|
||||
format: 'cjs',
|
||||
watch: !prod,
|
||||
target: 'es2018',
|
||||
logLevel: "info",
|
||||
sourcemap: prod ? false : 'inline',
|
||||
|
|
|
|||
62
main.js
62
main.js
|
|
@ -28,7 +28,7 @@ __export(main_exports, {
|
|||
retrieveStories: () => retrieveStories
|
||||
});
|
||||
module.exports = __toCommonJS(main_exports);
|
||||
var import_obsidian3 = require("obsidian");
|
||||
var import_obsidian4 = require("obsidian");
|
||||
|
||||
// src/mappers/storyMapper.ts
|
||||
function mapStory(data) {
|
||||
|
|
@ -124,7 +124,7 @@ function appendLine(content, destination) {
|
|||
return newLine(`${destination + content}`);
|
||||
}
|
||||
function generateTags(type) {
|
||||
return newLine("") + newLine("---") + newLine("tags") + newLine(" - pivotal-tracker") + newLine(" - " + type) + newLine("---");
|
||||
return newLine("") + newLine("") + newLine("tags") + newLine("- #pivotal-tracker") + newLine("- #" + type) + newLine("");
|
||||
}
|
||||
async function generateMarkdown(folderPath, stories) {
|
||||
let storiesIgnored = 0;
|
||||
|
|
@ -142,6 +142,31 @@ async function generateMarkdown(folderPath, stories) {
|
|||
new import_obsidian2.Notice(`${storiesCreated} ${storiesCreated > 1 ? "Stories" : "Story"} Created`);
|
||||
}
|
||||
|
||||
// src/generateFilePath.ts
|
||||
var import_obsidian3 = require("obsidian");
|
||||
async function generateFilePath(folderPath) {
|
||||
let currentFolderPath = "";
|
||||
if (!await this.app.vault.adapter.exists(folderPath)) {
|
||||
let path = folderPath.split("/");
|
||||
if (path[0] === ".") {
|
||||
path = path.slice(1);
|
||||
}
|
||||
for (let folder of path) {
|
||||
if (folder.trim()) {
|
||||
currentFolderPath += folder;
|
||||
if (!await this.app.vault.exists(currentFolderPath)) {
|
||||
await this.app.vault.createFolder(currentFolderPath);
|
||||
}
|
||||
currentFolderPath += "/";
|
||||
}
|
||||
}
|
||||
new import_obsidian3.Notice("Folders Created For Story Output");
|
||||
return currentFolderPath;
|
||||
} else {
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
// main.ts
|
||||
var DEFAULT_SETTINGS = {
|
||||
folderPath: "./stories",
|
||||
|
|
@ -156,23 +181,28 @@ var retrieveStories = async (settings) => {
|
|||
const { trackerUserAPIToken, trackerAppId, folderPath, onlyPointedStories, includeStories, includeChores, includeBugs } = settings;
|
||||
const inclusion = { includeStories, includeChores, includeBugs, pointed: onlyPointedStories };
|
||||
const stories = await getStories(trackerAppId, trackerUserAPIToken, inclusion);
|
||||
await generateMarkdown(folderPath, stories);
|
||||
const newFolderPath = await generateFilePath(folderPath);
|
||||
await generateMarkdown(newFolderPath, stories);
|
||||
};
|
||||
var pullTrackerStories = (settings) => {
|
||||
if (settings.trackerAppId === "") {
|
||||
return new import_obsidian3.Notice("No APP ID Provided.");
|
||||
return new import_obsidian4.Notice("No APP ID Provided.");
|
||||
}
|
||||
if (settings.trackerUserAPIToken === "") {
|
||||
return new import_obsidian3.Notice("No API Token provided.");
|
||||
return new import_obsidian4.Notice("No API Token provided.");
|
||||
}
|
||||
retrieveStories(settings).catch((e) => {
|
||||
new import_obsidian3.Notice(e);
|
||||
new import_obsidian4.Notice(e);
|
||||
});
|
||||
};
|
||||
var MyPlugin = class extends import_obsidian3.Plugin {
|
||||
var MyPlugin = class extends import_obsidian4.Plugin {
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
this.addRibbonIcon("book-open", "Pull Tracker Stories", () => pullTrackerStories(this.settings));
|
||||
this.addRibbonIcon(
|
||||
"book-open",
|
||||
"Pull Tracker Stories",
|
||||
() => pullTrackerStories(this.settings)
|
||||
);
|
||||
this.addCommand({
|
||||
id: "pivotal-tracker-retrieve-stories",
|
||||
name: "Pull Pivotal Tracker Stories",
|
||||
|
|
@ -187,7 +217,7 @@ var MyPlugin = class extends import_obsidian3.Plugin {
|
|||
await this.saveData(this.settings);
|
||||
}
|
||||
};
|
||||
var TrackerIntegrationSettingTab = class extends import_obsidian3.PluginSettingTab {
|
||||
var TrackerIntegrationSettingTab = class extends import_obsidian4.PluginSettingTab {
|
||||
constructor(app, plugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
|
|
@ -196,31 +226,31 @@ var TrackerIntegrationSettingTab = class extends import_obsidian3.PluginSettingT
|
|||
const { containerEl } = this;
|
||||
containerEl.empty();
|
||||
containerEl.createEl("h2", { text: "Settings for Tracker Integration" });
|
||||
new import_obsidian3.Setting(containerEl).setName("Tracker User Token").setDesc('To retrieve this, it can be found in your profile settings under "API KEY"').addText((text) => text.setPlaceholder("Enter your API Key").setValue(this.plugin.settings.trackerUserAPIToken).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Tracker User Token").setDesc('To retrieve this, it can be found in your profile settings under "API KEY"').addText((text) => text.setPlaceholder("Enter your API Key").setValue(this.plugin.settings.trackerUserAPIToken).onChange(async (value) => {
|
||||
this.plugin.settings.trackerUserAPIToken = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Tracker App ID").setDesc("This can be found in the project url bar https://www.pivotaltracker.com/n/projects/<your_project_id>").addText((text) => text.setPlaceholder("Enter your Apps Id").setValue(this.plugin.settings.trackerAppId).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Tracker App ID").setDesc("This can be found in the project url bar https://www.pivotaltracker.com/n/projects/<your_project_id>").addText((text) => text.setPlaceholder("Enter your Apps Id").setValue(this.plugin.settings.trackerAppId).onChange(async (value) => {
|
||||
this.plugin.settings.trackerAppId = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Folder Path").setDesc("This is the folder path to dump the stories it, currently they do NOT get created automatically.").addText((text) => text.setPlaceholder("./Path/Name").setValue(this.plugin.settings.folderPath).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Folder Path").setDesc("This is the folder path to dump the stories it. It will create the folder path for you.").addText((text) => text.setPlaceholder("./Path/Name").setValue(this.plugin.settings.folderPath).onChange(async (value) => {
|
||||
this.plugin.settings.folderPath = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Only Pointed Stories").setDesc("Should only grab pointed stories if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.onlyPointedStories).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Only Pointed Stories").setDesc("Should only grab pointed stories if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.onlyPointedStories).onChange(async (value) => {
|
||||
this.plugin.settings.onlyPointedStories = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Include Stories").setDesc("Should include stories if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeStories).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Include Stories").setDesc("Should include stories if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeStories).onChange(async (value) => {
|
||||
this.plugin.settings.includeStories = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Include Chores").setDesc("Should include chores if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeChores).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Include Chores").setDesc("Should include chores if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeChores).onChange(async (value) => {
|
||||
this.plugin.settings.includeChores = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new import_obsidian3.Setting(containerEl).setName("Include Bugs").setDesc("Should include bugs if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeBugs).onChange(async (value) => {
|
||||
new import_obsidian4.Setting(containerEl).setName("Include Bugs").setDesc("Should include bugs if it is on.").addToggle((ev) => ev.setValue(this.plugin.settings.includeBugs).onChange(async (value) => {
|
||||
this.plugin.settings.includeBugs = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
|
|
|
|||
15
main.ts
15
main.ts
|
|
@ -1,6 +1,7 @@
|
|||
import {App, Notice, Plugin, PluginSettingTab, Setting} from 'obsidian';
|
||||
import getStories from "./src/apiClient";
|
||||
import generateMarkdown from "./src/generateMarkdown";
|
||||
import generateFilePath from "./src/generateFilePath";
|
||||
|
||||
interface PivotalTrackerIntegrationSettings {
|
||||
folderPath: string;
|
||||
|
|
@ -27,7 +28,8 @@ export const retrieveStories = async (settings: PivotalTrackerIntegrationSetting
|
|||
const inclusion = {includeStories, includeChores, includeBugs, pointed: onlyPointedStories};
|
||||
const stories = await getStories(trackerAppId, trackerUserAPIToken, inclusion);
|
||||
|
||||
await generateMarkdown(folderPath, stories);
|
||||
const newFolderPath = await generateFilePath(folderPath);
|
||||
await generateMarkdown(newFolderPath, stories);
|
||||
};
|
||||
|
||||
const pullTrackerStories = (settings: PivotalTrackerIntegrationSettings) => {
|
||||
|
|
@ -64,15 +66,6 @@ export default class MyPlugin extends Plugin {
|
|||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new TrackerIntegrationSettingTab(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));
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
|
|
@ -121,7 +114,7 @@ class TrackerIntegrationSettingTab extends PluginSettingTab {
|
|||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Folder Path')
|
||||
.setDesc('This is the folder path to dump the stories it, currently they do NOT get created automatically.')
|
||||
.setDesc('This is the folder path to dump the stories it. It will create the folder path for you.')
|
||||
.addText(text => text
|
||||
.setPlaceholder('./Path/Name')
|
||||
.setValue(this.plugin.settings.folderPath)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "obsidian-pivotal-tracker-integration-plugin",
|
||||
"id": "pivotal-tracker-integration",
|
||||
"name": "Pivotal Tracker Integration",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.6",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "This is an unofficial pivotal tracker integration plugin for Obsidian. This plugin allows the user to pull stories, chores, bugs from their pivotal counterpart.",
|
||||
"author": "Jon Deates",
|
||||
|
|
|
|||
1954
package-lock.json
generated
1954
package-lock.json
generated
File diff suppressed because it is too large
Load diff
14
package.json
14
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-pivotal-tracker-integration-plugin",
|
||||
"version": "1.0.1",
|
||||
"name": "pivotal-tracker-integration",
|
||||
"version": "1.0.6",
|
||||
"description": "This is an unofficial pivotal tracker integration plugin for Obsidian. (https://obsidian.md)",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
@ -13,12 +13,12 @@
|
|||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||
"@typescript-eslint/parser": "5.29.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.59.9",
|
||||
"@typescript-eslint/parser": "5.59.9",
|
||||
"builtin-modules": "3.3.0",
|
||||
"esbuild": "0.14.47",
|
||||
"esbuild": "0.17.19",
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
"tslib": "2.5.3",
|
||||
"typescript": "5.1.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ function generateConfig(
|
|||
|
||||
return {
|
||||
method: 'GET',
|
||||
url: `${TRACKER_URL}/projects/${projectId}/stories?$nram}`,
|
||||
url: `${TRACKER_URL}/projects/${projectId}/stories?${queryParam}`,
|
||||
headers: {
|
||||
'X-TrackerToken': trackerToken,
|
||||
},
|
||||
|
|
|
|||
24
src/generateFilePath.ts
Normal file
24
src/generateFilePath.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import {Notice} from "obsidian";
|
||||
|
||||
export default async function generateFilePath(folderPath: string): Promise<string> {
|
||||
let currentFolderPath = "";
|
||||
if (!(await this.app.vault.adapter.exists(folderPath))) {
|
||||
let path = folderPath.split('/');
|
||||
if(path[0] === '.'){
|
||||
path = path.slice(1)
|
||||
}
|
||||
for(let folder of path){
|
||||
if(folder.trim()) {
|
||||
currentFolderPath += folder;
|
||||
if (!(await this.app.vault.exists(currentFolderPath))) {
|
||||
await this.app.vault.createFolder(currentFolderPath)
|
||||
}
|
||||
currentFolderPath += '/'
|
||||
}
|
||||
}
|
||||
new Notice('Folders Created For Story Output')
|
||||
return currentFolderPath;
|
||||
} else {
|
||||
return folderPath;
|
||||
}
|
||||
};
|
||||
|
|
@ -31,7 +31,7 @@ function appendLine(content: string, destination: string): string {
|
|||
|
||||
function generateTags(type: "feature" | "bug" | "chore"){
|
||||
|
||||
return newLine("") + newLine("---") + newLine("tags") + newLine(" - pivotal-tracker") + newLine(" - " + type) +newLine("---")
|
||||
return newLine("") + newLine("") + newLine("tags") + newLine("- #pivotal-tracker") + newLine("- #" + type) +newLine("")
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"1.0.0": "0.15.0",
|
||||
"1.0.1": "0.15.0"
|
||||
"1.0.1": "0.15.0",
|
||||
"1.0.2": "0.15.0",
|
||||
"1.0.3": "0.15.0",
|
||||
"1.0.4": "0.15.0",
|
||||
"1.0.5": "0.15.0",
|
||||
"1.0.6": "0.15.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue