make most basic jira api work;

make jira settings configurabl;e

implement searching real issues;
This commit is contained in:
Johannes Millan 2017-01-05 23:45:30 +01:00
parent f92a839171
commit 7acd8a20bd
12 changed files with 244 additions and 17 deletions

View file

@ -80,6 +80,7 @@ TODO configure more restrictive Content-Security-Policy
<script src="bower_components/angular-moment/angular-moment.js"></script>
<script src="bower_components/ng-sortable/dist/ng-sortable.js"></script>
<script src="bower_components/moment-duration-format/lib/moment-duration-format.js"></script>
<script src="bower_components/angular-base64/angular-base64.js"></script>
<!-- endbower -->
<!-- endbuild -->
@ -115,6 +116,7 @@ TODO configure more restrictive Content-Security-Policy
<script src="scripts/hints/hints-d.js"></script>
<script src="scripts/input-duration/input-duration-d.js"></script>
<script src="scripts/main/global-filters/duration-filter.js"></script>
<script src="scripts/main/global-services/jira-s.js"></script>
<script src="scripts/main/global-services/productivity-tips-s.js"></script>
<script src="scripts/main/global-services/tasks-s.js"></script>
<script src="scripts/main-header/main-header-d.js"></script>

View file

@ -22,11 +22,21 @@
'as.sortable',
'angularMoment'
])
.config(configHttp)
.config(configMdTheme)
.run(initGlobalTaskModel)
.run(initGlobalModels)
.run(initGlobalShortcuts)
.run(showHintsForToday);
function configHttp($httpProvider) {
//delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
}
function configMdTheme($mdThemingProvider) {
$mdThemingProvider.theme('dark-grey').backgroundPalette('grey').dark();
$mdThemingProvider.theme('dark-orange').backgroundPalette('orange').dark();
@ -34,12 +44,14 @@
$mdThemingProvider.theme('dark-blue').backgroundPalette('blue').dark();
}
function initGlobalTaskModel(Tasks, $rootScope) {
function initGlobalModels(Tasks, $rootScope, $localStorage) {
$rootScope.r = {};
$rootScope.r.tasks = Tasks.getToday();
$rootScope.r.backlogTasks = Tasks.getBacklog();
$rootScope.r.currentTask = Tasks.getCurrent();
$rootScope.r.doneBacklogTasks = Tasks.getDoneBacklog();
$rootScope.r.jiraSettings = $localStorage.jiraSettings;
}
function showHintsForToday($rootScope, $localStorage, ProductivityTips) {

View file

@ -8,16 +8,34 @@
</div>
<form ng-submit="vm.addTask()">
<md-input-container class="md-block md-icon-float">
<ng-md-icon icon="mode_edit"></ng-md-icon>
<!--<md-input-container class="md-block md-icon-float">-->
<!--<ng-md-icon icon="mode_edit"></ng-md-icon>-->
<label>Enter a task and press enter to add</label>
<input class="text-input"
tabindex="1"
autofocus
ng-model="vm.newTask">
<!--<label>Enter a task and press enter to add</label>-->
<!--<input class="text-input"-->
<!--tabindex="1"-->
<!--autofocus-->
<!--ng-model="vm.newTask">-->
</md-input-container>
<!--</md-input-container>-->
<!---->
<md-autocomplete
md-selected-item="vm.newTask"
md-search-text="vm.searchText"
md-items="task in vm.taskSuggestions"
md-item-text="task.title"
md-min-length="0"
md-autofocus
placeholder="Select a task to start with">
<md-item-template>
<span md-highlight-text="vm.searchText"
md-highlight-flags="^i">{{task.title}}</span>
</md-item-template>
<md-not-found>
No states matching "{{vm.searchText}}" were found.
<a ng-click="vm.newState(vm.searchText)">Create a new one!</a>
</md-not-found>
</md-autocomplete>
</form>
<div class="done"

View file

@ -25,7 +25,7 @@
}
/* @ngInject */
function DailyPlannerCtrl($scope, $rootScope, Tasks, Dialogs, $state) {
function DailyPlannerCtrl($scope, $rootScope, Tasks, Dialogs, $state, Jira) {
let vm = this;
vm.limitBacklogTo = 3;
@ -34,13 +34,21 @@
vm.backlogTasks = $rootScope.r.backlogTasks;
vm.currentTask = $rootScope.r.currentTask;
vm.noteForToday = $rootScope.r.noteForToday;
vm.taskSuggestions = [];
Jira.getSuggestions().then((res) => {
console.log(res);
vm.taskSuggestions = Jira.transformIssues(res);
});
vm.addTask = () => {
if (vm.newTask) {
Tasks.addToday({
title: vm.newTask
});
vm.newTask = '';
//Tasks.addToday({
// title: vm.newTask
//});
Tasks.addToday( vm.newTask);
vm.newTask = undefined;
}
// if we have already defined enough tasks and the

View file

@ -0,0 +1,91 @@
/**
* @ngdoc service
* @name superProductivity.Jira
* @description
* # Jira
* Service in the superProductivity.
*/
(function () {
'use strict';
angular
.module('superProductivity')
.service('Jira', Jira);
/* @ngInject */
function Jira($q, $localStorage) {
const IPC_JIRA_CB_EVENT = 'JIRA_RESPONSE';
const IPC_JIRA_MAKE_REQUEST_EVENT = 'JIRA';
this.requestsLog = {};
if (angular.isDefined(window.ipcRenderer)) {
window.ipcRenderer.on(IPC_JIRA_CB_EVENT, (ev, res) => {
console.log('RES', res);
if (res.requestId) {
// resolve saved promise
this.requestsLog[res.requestId].resolve(res);
// delete entry for promise afterwards
delete this.requestsLog[res.requestId];
}
});
}
this.getSuggestions = () => {
let testRequest = {
config: $localStorage.jiraSettings,
apiMethod: 'searchJira',
//arguments: [$localStorage.jiraSettings.userName, true],
//arguments: ['assignee = "'+$localStorage.jiraSettings.userName+'" AND resolution = Unresolved ORDER BY updatedDate DESC',false],
arguments: ['assignee = "joschka.decuveland" AND resolution = Unresolved ORDER BY updatedDate DESC', false],
requestId: Math.random().toString(36).substr(2, 10)
};
return this.sendRequest(testRequest);
};
this.transformIssues = (response) => {
let res = response.response;
let tasks = [];
for (let i = 0; i < res.issues.length; i++) {
let issue = res.issues[i];
tasks.push({
title: issue.key + ' ' + issue.fields.summary,
note: issue.fields.description,
originalKey: issue.key,
originalLink: issue.self
});
}
return tasks;
};
this.sendRequest = (request) => {
if (!$localStorage.jiraSettings) {
console.log('NO SETTINGS DEFINED');
return;
}
if (angular.isDefined(window.ipcRenderer)) {
let defer = $q.defer();
// save to request log
this.requestsLog[request.requestId] = defer;
// send to electron
window.ipcRenderer.send(IPC_JIRA_MAKE_REQUEST_EVENT, request);
return defer.promise;
} else {
return $q.when(null);
}
};
this.auth = () => {
};
}
})();

View file

@ -0,0 +1,17 @@
'use strict';
describe('Service: Jira', function() {
// load the service's module
beforeEach(module('superProductivity'));
// instantiate service
var Jira;
beforeEach(inject(function (_Jira_) {
Jira = _Jira_;
}));
it('should be defined', function() {
expect(true).toBe(true);
});
});

View file

@ -1,4 +1,7 @@
<div class="page-settings">
<h2 class="md-title">Make/Restore Backup</h2>
<a class="md-raised md-button md-ink-ripple"
type="button"
download-backup>
@ -8,7 +11,6 @@
Download your tasks and settings
<div class="md-ripple-container"></div>
</a>
<md-button
class="md-raised"
ng-click="vm.showUploadForm=!vm.showUploadForm;">
@ -32,4 +34,33 @@
</md-button>
</form>
<md-divider></md-divider>
<h2 class="md-title">Jira-Setup for Task Suggestion</h2>
<form ng-submit="vm.saveJiraSettings(vm.jiraSettings)">
<md-input-container class="md-block"
flex-gt-sm>
<label>Host</label>
<input type="text"
ng-model="vm.jiraSettings.host">
</md-input-container>
<md-input-container class="md-block"
flex-gt-sm>
<label>Username</label>
<input type="text"
ng-model="vm.jiraSettings.userName">
</md-input-container>
<md-input-container class="md-block"
flex-gt-sm>
<label>Password</label>
<input type="text"
ng-model="vm.jiraSettings.password">
</md-input-container>
<md-button type="submit"
class="md-raised md-primary">Save Config
</md-button>
</form>
</div>

View file

@ -15,7 +15,7 @@
/* @ngInject */
function SettingsCtrl($localStorage, $rootScope) {
var vm = this;
let vm = this;
vm.importSettings = (uploadSettingsTextarea) => {
let settings = JSON.parse(uploadSettingsTextarea);
@ -24,5 +24,14 @@
$rootScope.r.tasks = $localStorage.tasks = settings.tasks;
$rootScope.r.backlogTasks = $localStorage.backlogTasks = settings.backlogTasks;
};
vm.jiraSettings = $rootScope.r.jiraSettings;
console.log(vm.jiraSettings);
vm.saveJiraSettings = (settings) => {
console.log('I am here!', settings);
$rootScope.r.jiraSettings = $localStorage.jiraSettings = settings;
};
}
})();

31
electron/jira.js Normal file
View file

@ -0,0 +1,31 @@
const JiraApi = require('jira').JiraApi;
//request = {
// config: {},
// apiMethod: 'findIssue',
// argument: 'BNGP-1283',
// requestId: Math.random().toString(36).substr(2, 10)
//};
module.exports = (mainWindow, request) => {
console.log(request);
let config = request.config;
let apiMethod = request.apiMethod;
let arguments = request.arguments;
let requestId = request.requestId;
let jira = new JiraApi('https', config.host, config.port, config.userName, config.password, 'latest');
jira[apiMethod](...arguments, (error, res) => {
console.log('JIRA_RESPONSE', error, res);
mainWindow.webContents.send('JIRA_RESPONSE', {
error: error,
response: res,
requestId: requestId
});
});
};

View file

@ -5,6 +5,8 @@ const powerSaveBlocker = require('electron').powerSaveBlocker;
const moment = require('moment');
const idle = require('./idle');
const CONFIG = require('./CONFIG');
const jira = require('./jira');
powerSaveBlocker.start('prevent-app-suspension');
// Module to control application life.
@ -115,6 +117,10 @@ electron.ipcMain.on('SHUTDOWN', () => {
app.quit();
});
electron.ipcMain.on('JIRA', (ev, request) => {
jira(mainWindow, request);
});
function trackTimeFn() {
//let timeSpend = moment.duration({ milliseconds: CONFIG.PING_INTERVAL });

View file

@ -29,6 +29,7 @@ module.exports = function(config) {
'app/bower_components/angular-moment/angular-moment.js',
'app/bower_components/ng-sortable/dist/ng-sortable.js',
'app/bower_components/moment-duration-format/lib/moment-duration-format.js',
'app/bower_components/angular-base64/angular-base64.js',
'app/bower_components/angular-mocks/angular-mocks.js',
// endbower

View file

@ -57,6 +57,7 @@
"dependencies": {
"electron": "^1.4.1",
"electron-inspector": "^0.1.4",
"jira": "^0.9.2",
"moment": "^2.17.1"
}
}