Merge pull request #14 from OpenStackweb/development
Development product release
This commit is contained in:
commit
04d17ef9bf
@ -8,35 +8,42 @@ module.exports = function(UserStory) {
|
|||||||
var async = require("async");
|
var async = require("async");
|
||||||
var htmlparser = require("htmlparser");
|
var htmlparser = require("htmlparser");
|
||||||
var cheerio = require('cheerio');
|
var cheerio = require('cheerio');
|
||||||
|
const SPEC_URL = "http://specs.openstack.org/openstack/openstack-user-stories/user-stories/proposed/";
|
||||||
|
|
||||||
|
|
||||||
var blueprintsResume = [];
|
var blueprintsResume = [];
|
||||||
|
|
||||||
|
|
||||||
var getAllfiles = function(getPercentage){
|
var getAllfiles = function(){
|
||||||
|
|
||||||
return fs.readdirSync(route)
|
return fs.readdirSync(route)
|
||||||
.map(function(file){
|
.map(function(file){
|
||||||
var route = "../tracker/" + file ;
|
var route = "../tracker/" + file ;
|
||||||
var data = JSON.parse(fs.readFileSync(route));
|
var userStory = JSON.parse(fs.readFileSync(route));
|
||||||
var parsedData;
|
return userStory;
|
||||||
|
|
||||||
if(getPercentage){
|
|
||||||
parsedData = getTotalPercentage(data);
|
|
||||||
data.blueprintList = parsedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//get completed percentage of all the userstories
|
var getFileById = function(id){
|
||||||
var getTotalPercentage = function(userStory){
|
|
||||||
|
|
||||||
blueprintsResume.completed = 0;
|
//get all files
|
||||||
blueprintsResume.total = 0;
|
var userStories = getAllfiles();
|
||||||
var blueprintList = [];
|
//filter by Id
|
||||||
|
var file = userStories.filter(function(item){
|
||||||
|
return item.id == id;
|
||||||
|
})
|
||||||
|
|
||||||
|
file = (file.length > 0)?file[0]:null;
|
||||||
|
|
||||||
|
return file;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//get all the completed blueprints
|
||||||
|
var getbluePrintResume = function(userStory){
|
||||||
|
var blueprintsResume = {
|
||||||
|
completed: 0,
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
|
|
||||||
userStory.tasks.forEach(function (taskName, index, array) {
|
userStory.tasks.forEach(function (taskName, index, array) {
|
||||||
|
|
||||||
@ -46,7 +53,6 @@ module.exports = function(UserStory) {
|
|||||||
|
|
||||||
var blueprints = task.projects_status[projectName].blueprints;
|
var blueprints = task.projects_status[projectName].blueprints;
|
||||||
var blueprintNames = Object.keys(blueprints);
|
var blueprintNames = Object.keys(blueprints);
|
||||||
blueprintList.push(blueprintNames);
|
|
||||||
|
|
||||||
blueprintNames.forEach(function (blueprintName, index, array) {
|
blueprintNames.forEach(function (blueprintName, index, array) {
|
||||||
|
|
||||||
@ -61,201 +67,64 @@ module.exports = function(UserStory) {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var finalPercentage = Math.round((blueprintsResume.completed*100)/blueprintsResume.total)
|
blueprintsResume.percentage = (blueprintsResume.completed/blueprintsResume.total)*100;
|
||||||
blueprintList.push([{percentage:(finalPercentage)}]);
|
|
||||||
return blueprintList;
|
|
||||||
|
|
||||||
|
return blueprintsResume;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get completed percentage of a User story
|
//get the field lastupdated for a usterStory
|
||||||
var getPercentage = function(blueprints){
|
var getLastUpdated = function(userStory, cb){
|
||||||
var total = blueprints.length;
|
|
||||||
var complete = 0;
|
|
||||||
|
|
||||||
blueprints.forEach(function(element, index, array) {
|
|
||||||
|
|
||||||
if(element == 'completed')
|
|
||||||
complete = complete + 1;
|
|
||||||
})
|
|
||||||
return Math.round((complete*100)/total);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var getFileById = function(id){
|
|
||||||
|
|
||||||
//get all files
|
|
||||||
var userStories = getAllfiles();
|
|
||||||
//filter by Id
|
|
||||||
var file = userStories.filter(function(item){
|
|
||||||
return item.id == id;
|
|
||||||
})
|
|
||||||
|
|
||||||
if(file.length > 0){
|
|
||||||
file = file[0];
|
|
||||||
}else{
|
|
||||||
file = 'The file with id: '+ id +' does not exist.'
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var getDetailedUri = function(source) {
|
|
||||||
var base = 'http://specs.openstack.org/openstack/openstack-user-stories/user-stories/proposed/';
|
|
||||||
|
|
||||||
return base + source + '.html';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var parseUserStory = function(id){
|
|
||||||
var data = [];
|
|
||||||
return function(callback){
|
|
||||||
var file = getFileById(id);
|
|
||||||
|
|
||||||
var Patch = app.models.Patch;
|
var Patch = app.models.Patch;
|
||||||
|
|
||||||
Patch.latestUpdate(file.source, function(err, response) {
|
|
||||||
|
|
||||||
var lastUpdate = '';
|
var lastUpdate = '';
|
||||||
|
|
||||||
if(response){
|
Patch.latestUpdate(userStory.source, function (err, response, next) {
|
||||||
response = JSON.parse(response.substring(5));
|
|
||||||
response.forEach( function each (element){
|
|
||||||
data.push(
|
|
||||||
{
|
|
||||||
latestDate: element.updated,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
data = data.sort();
|
|
||||||
lastUpdate = data.shift();
|
|
||||||
|
|
||||||
if(lastUpdate){
|
|
||||||
lastUpdate = lastUpdate.latestDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var userStory = {
|
|
||||||
title:file.description,
|
|
||||||
description:'',
|
|
||||||
status:file.status,
|
|
||||||
showDetailedUri:getDetailedUri(file.source),
|
|
||||||
submittedBy:file.submitted_by.name,
|
|
||||||
submittedByEmail:file.submitted_by.email,
|
|
||||||
createdOn:file.date,
|
|
||||||
updatedOn:lastUpdate,
|
|
||||||
id:file.id,
|
|
||||||
percentageComplete:''
|
|
||||||
};
|
|
||||||
callback(null, userStory, file.tasks, file.tasks_status);
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var getTaskDescription = function(task, callback){
|
|
||||||
|
|
||||||
var Rst = app.models.Rst;
|
|
||||||
var spec = task['cross-project spec'] + '.rst'
|
|
||||||
|
|
||||||
Rst.list(spec, function(err, data){
|
|
||||||
|
|
||||||
var html_content = markdown.toHTML(data);
|
|
||||||
var $ = cheerio.load(html_content);
|
|
||||||
|
|
||||||
var index = null;
|
|
||||||
//Find the title
|
|
||||||
var description = $('h1').each(function(i, elem) {
|
|
||||||
if(elem.children[0].data == 'Problem description'){
|
|
||||||
index = i;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//get Text description
|
|
||||||
if(index != null){
|
|
||||||
description = $($('h1')[index]).next().text()
|
|
||||||
}else{
|
|
||||||
description = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, description);
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var getUriTask = function(spec){
|
|
||||||
var base = 'https://github.com/openstack/openstack-specs/blob/master/specs/';
|
|
||||||
|
|
||||||
return base + spec + '.rst';
|
|
||||||
}
|
|
||||||
|
|
||||||
var parseTask = function(originalTask, callback){
|
|
||||||
|
|
||||||
getTaskDescription(originalTask, function(err, description){
|
|
||||||
originalTask.description = description;
|
|
||||||
originalTask.url = getUriTask(originalTask['cross-project spec']);
|
|
||||||
originalTask.xp_status = originalTask.xp_status;
|
|
||||||
callback(null, originalTask)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var parseProject = function(originalProject, callback){
|
|
||||||
|
|
||||||
var urlArray = originalProject.spec.split('/');
|
|
||||||
var nameArray = urlArray[urlArray.length-1].split('.')
|
|
||||||
originalProject.spec_name = nameArray[0];
|
|
||||||
|
|
||||||
callback(null, originalProject)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var parseBlueprint = function(originalBlueprint, blueprintName, projectName, callback){
|
|
||||||
var Blueprint = app.models.Blueprint;
|
|
||||||
var Patch = app.models.Patch;
|
|
||||||
|
|
||||||
var status = originalBlueprint;
|
|
||||||
|
|
||||||
Blueprint.url(projectName, blueprintName, function(err, uri){
|
|
||||||
|
|
||||||
blueprintsResume.push(status)
|
|
||||||
|
|
||||||
blueprintsResume.complete = blueprintsResume.total +1 ;
|
|
||||||
|
|
||||||
|
|
||||||
Patch.list(blueprintName, function(err, response) {
|
|
||||||
|
|
||||||
var data = [];
|
|
||||||
|
|
||||||
response = JSON.parse(response.substring(5));
|
response = JSON.parse(response.substring(5));
|
||||||
|
|
||||||
response.forEach(function each(element) {
|
if(response.length > 0){
|
||||||
data.push(
|
lastUpdate = response.map( function each (element){
|
||||||
{
|
return element.updated
|
||||||
url: "https://review.openstack.org/#/c/" + element._number,
|
}).sort().pop();
|
||||||
name: element.subject
|
var arrayLastUpdate = lastUpdate.split(' ');
|
||||||
});
|
lastUpdate = arrayLastUpdate[0];
|
||||||
});
|
|
||||||
|
|
||||||
originalBlueprint = {
|
|
||||||
name: blueprintName.replace(/-/g, " "),
|
|
||||||
uri: uri,
|
|
||||||
status: status,
|
|
||||||
review_link:data
|
|
||||||
}
|
}
|
||||||
callback(null, originalBlueprint)
|
|
||||||
|
|
||||||
})
|
cb(null, lastUpdate)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: APPLY async.waterfall
|
// Parse data from userStory
|
||||||
|
var parseUserStory = function(userStory, callback){
|
||||||
|
|
||||||
|
async.waterfall([function(cb){
|
||||||
|
|
||||||
|
getLastUpdated(userStory, cb)
|
||||||
|
|
||||||
|
},function(lastUpdated, cb){
|
||||||
|
userStory.updatedOn = lastUpdated;
|
||||||
|
userStory.showDetailedUri = SPEC_URL + userStory.source + '.html';
|
||||||
|
userStory.createdOn = userStory.date;
|
||||||
|
userStory.completed = getbluePrintResume(userStory);
|
||||||
|
|
||||||
|
cb(null, userStory);
|
||||||
|
|
||||||
|
},function(userStory, cb){
|
||||||
|
|
||||||
|
var tasksName = userStory.tasks;
|
||||||
|
var tasks = userStory.tasks_status;
|
||||||
|
|
||||||
|
parseTasks(userStory, tasksName, tasks, cb)
|
||||||
|
|
||||||
|
}],function(err,userStory){
|
||||||
|
callback(null, userStory);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//??
|
||||||
var parseTasks = function(userStory, tasksNames, tasks, callback) { //get tasks
|
var parseTasks = function(userStory, tasksNames, tasks, callback) { //get tasks
|
||||||
|
|
||||||
var tmpTasks = {};
|
var tmpTasks = {};
|
||||||
@ -308,7 +177,7 @@ module.exports = function(UserStory) {
|
|||||||
userStory.tasks = tasksNames;
|
userStory.tasks = tasksNames;
|
||||||
userStory.tasks_status = tmpTasks;
|
userStory.tasks_status = tmpTasks;
|
||||||
|
|
||||||
userStory.percentageComplete = getPercentage(blueprintsResume)
|
//userStory.percentageComplete = getPercentage(blueprintsResume)
|
||||||
|
|
||||||
callback(null, userStory);
|
callback(null, userStory);
|
||||||
|
|
||||||
@ -316,104 +185,151 @@ module.exports = function(UserStory) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//?
|
||||||
|
|
||||||
|
var getTaskDescription = function(task, callback){
|
||||||
|
|
||||||
|
var Rst = app.models.Rst;
|
||||||
|
var spec = task['cross-project spec'] + '.rst'
|
||||||
|
|
||||||
|
Rst.list(spec, function(err, data){
|
||||||
|
|
||||||
|
var html_content = markdown.toHTML(data);
|
||||||
|
var $ = cheerio.load(html_content);
|
||||||
|
|
||||||
|
var index = null;
|
||||||
|
//Find the title
|
||||||
|
var description = $('h1').each(function(i, elem) {
|
||||||
|
if(elem.children[0].data == 'Problem description'){
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//get Text description
|
||||||
|
if(index != null){
|
||||||
|
description = $($('h1')[index]).next().text()
|
||||||
|
}else{
|
||||||
|
description = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, description);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
//?
|
||||||
|
var getUriTask = function(spec){
|
||||||
|
var base = 'https://github.com/openstack/openstack-specs/blob/master/specs/';
|
||||||
|
|
||||||
|
return base + spec + '.rst';
|
||||||
|
}
|
||||||
|
//?
|
||||||
|
var parseTask = function(originalTask, callback){
|
||||||
|
|
||||||
|
getTaskDescription(originalTask, function(err, description){
|
||||||
|
originalTask.description = description;
|
||||||
|
originalTask.url = getUriTask(originalTask['cross-project spec']);
|
||||||
|
callback(null, originalTask)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
//?
|
||||||
|
|
||||||
|
var parseProject = function(originalProject, callback){
|
||||||
|
|
||||||
|
var urlArray = originalProject.spec.split('/');
|
||||||
|
var nameArray = urlArray[urlArray.length-1].split('.')
|
||||||
|
originalProject.spec_name = nameArray[0];
|
||||||
|
|
||||||
|
callback(null, originalProject)
|
||||||
|
}
|
||||||
|
|
||||||
|
//?
|
||||||
|
var parseBlueprint = function(originalBlueprint, blueprintName, projectName, callback){
|
||||||
|
var Blueprint = app.models.Blueprint;
|
||||||
|
var Patch = app.models.Patch;
|
||||||
|
|
||||||
|
var status = originalBlueprint;
|
||||||
|
|
||||||
|
Blueprint.url(projectName, blueprintName, function(err, uri){
|
||||||
|
|
||||||
|
blueprintsResume.push(status)
|
||||||
|
|
||||||
|
blueprintsResume.complete = blueprintsResume.total +1 ;
|
||||||
|
|
||||||
|
|
||||||
|
Patch.list(blueprintName, function(err, response) {
|
||||||
|
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
response = JSON.parse(response.substring(5));
|
||||||
|
|
||||||
|
response.forEach(function each(element) {
|
||||||
|
data.push(
|
||||||
|
{
|
||||||
|
url: "https://review.openstack.org/#/c/" + element._number,
|
||||||
|
name: element.subject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
originalBlueprint = {
|
||||||
|
name: blueprintName.replace(/-/g, " "),
|
||||||
|
uri: uri,
|
||||||
|
status: status,
|
||||||
|
review_link:data
|
||||||
|
}
|
||||||
|
callback(null, originalBlueprint)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
UserStory.on('attached',function(){
|
UserStory.on('attached',function(){
|
||||||
|
|
||||||
UserStory.findById = function(id, params, cb){
|
UserStory.findById = function(id, params, cb){
|
||||||
|
|
||||||
async.waterfall([
|
var userStory = getFileById(id);
|
||||||
parseUserStory(id),
|
|
||||||
parseTasks
|
|
||||||
], function (err, result) {
|
|
||||||
cb(null,result)
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
if(userStory){
|
||||||
|
parseUserStory(userStory, cb);
|
||||||
|
}else{
|
||||||
|
cb('File does not exist', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
};//end find by id
|
||||||
|
|
||||||
UserStory.find = function(params, cb){
|
UserStory.find = function(params, cb){
|
||||||
var Patch = app.models.Patch;
|
var userStories = getAllfiles();
|
||||||
//get all files
|
|
||||||
var userStories = getAllfiles(true);
|
|
||||||
var percentage;
|
|
||||||
var blueprintKeys;
|
|
||||||
var dateList = [];
|
|
||||||
//var response = userStories;
|
|
||||||
|
|
||||||
var result;
|
async.mapSeries(userStories, parse, cb);
|
||||||
|
|
||||||
// looking dates
|
function parse(userStory, callback) {
|
||||||
var lookingDates = function (id, blueprintKeys) {
|
|
||||||
blueprintKeys.forEach(function each (key) {
|
|
||||||
var data = [];
|
|
||||||
Patch.latestUpdate(key, function (err, response, next) {
|
|
||||||
|
|
||||||
response = JSON.parse(response.substring(5));
|
async.waterfall([function(cb){
|
||||||
async.waterfall([
|
getLastUpdated(userStory, cb)
|
||||||
function createOutput(next){
|
},function(lastUpdated, cb){
|
||||||
response.forEach( function each (element){
|
|
||||||
data.push(
|
|
||||||
{
|
|
||||||
latestDate: element.updated,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
function sendData (next) {
|
|
||||||
data = data.sort();
|
|
||||||
var lastUpdate = data.shift();
|
|
||||||
if(lastUpdate !== undefined) {
|
|
||||||
dateList.push({
|
|
||||||
id: id,
|
|
||||||
value: lastUpdate.latestDate
|
|
||||||
});
|
|
||||||
}
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
], next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function keysrt(key,asc) {
|
var itemResult = {
|
||||||
return function(a,b){
|
completed: getbluePrintResume(userStory),
|
||||||
return asc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]);
|
dateCreated: userStory.date,
|
||||||
}
|
lastUpdate: lastUpdated,
|
||||||
}
|
userStory: userStory.description,
|
||||||
|
id:userStory.id
|
||||||
|
};
|
||||||
|
|
||||||
async.waterfall ([
|
cb(null, itemResult);
|
||||||
function readStories (next) {
|
|
||||||
userStories.forEach (function eachStory (story, x) {
|
|
||||||
//console.log(story.blueprintList);
|
|
||||||
//TODO change the array of percentage
|
|
||||||
percentage = (story.blueprintList).pop();
|
|
||||||
blueprintKeys = story.blueprintList;
|
|
||||||
result = lookingDates((story.id), blueprintKeys);
|
|
||||||
story.percentage = percentage[0].percentage;
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
function resumeDate (next){
|
|
||||||
setTimeout(function(){
|
|
||||||
dateList = dateList.sort(keysrt('value'));
|
|
||||||
userStories.forEach (function eachStory (story) {
|
|
||||||
dateList.forEach (function eachDate (dateElement){
|
|
||||||
if(dateElement.id === story.id){
|
|
||||||
story.latestUpdate = dateList
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
cb(null,userStories);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
next;
|
}],function(err,result){
|
||||||
},
|
callback( err, result);
|
||||||
function sendResult(next){
|
})
|
||||||
//cb(null,userStories);
|
|
||||||
next;
|
|
||||||
}
|
}
|
||||||
]);
|
};//End find
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -314,7 +314,7 @@ module.exports = function (grunt) {
|
|||||||
development: {
|
development: {
|
||||||
constants: function() {
|
constants: function() {
|
||||||
var config = require('./' + grunt.config.get('ngconstant.options.configPath'))
|
var config = require('./' + grunt.config.get('ngconstant.options.configPath'))
|
||||||
config.apiBaseUrl = 'http://localhost:3004';
|
config.apiBaseUrl = 'http://localhost:3004/api';
|
||||||
return { appConfig : config};
|
return { appConfig : config};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
(function(){
|
(function () {
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
angular.module('dashboardProjectApp')
|
||||||
.controller('projectDetailController', ['$scope','$state', 'UserStory'/*, 'tasksService', 'tasks', 'task'*/,
|
.controller('projectDetailController', ['$scope','$state', 'UserStory', '$location',
|
||||||
function($scope, $state, UserStory/*, tasksService, tasks, task*/) {
|
function($scope, $state, UserStory, $location) {
|
||||||
|
|
||||||
$scope.taskId = $state.params.id;
|
$scope.taskId = $state.params.id;
|
||||||
$scope.openTasks = {};
|
$scope.openTasks = {};
|
||||||
@ -43,19 +43,32 @@
|
|||||||
function success(userStory) {
|
function success(userStory) {
|
||||||
$scope.userStory = userStory;
|
$scope.userStory = userStory;
|
||||||
|
|
||||||
$scope.userStory.updatedOn = moment($scope.userStory.updatedOn).format("MM-DD-YYYY");
|
// Formating User Story name
|
||||||
for(var key in $scope.userStory.tasks_status) {
|
if ((userStory.description).length > 100) {
|
||||||
$scope.actualProject[key] = $scope.userStory.tasks_status[key].projects[0]
|
$scope.userStory.shortDescription = userStory.
|
||||||
|
description.substr(0,50) + " ...";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.userStory.shortDescription = userStory.
|
||||||
|
description;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
$scope.userStory.updatedOn = moment($scope.userStory.
|
||||||
|
updatedOn).format("MM-DD-YYYY");
|
||||||
|
for(var key in $scope.userStory.tasks_status) {
|
||||||
|
$scope.actualProject[key] = $scope.userStory.
|
||||||
|
tasks_status[key].projects[0]
|
||||||
|
}
|
||||||
|
}, function onError(error){
|
||||||
|
$location.path('/projectDetail/notFound/' + $scope.taskId);
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.selectProject = function(keyProject, idTask){
|
$scope.selectProject = function(keyProject, idTask){
|
||||||
$scope.actualProject[idTask] = keyProject
|
$scope.actualProject[idTask] = keyProject
|
||||||
}
|
}
|
||||||
|
|
||||||
getFile();
|
|
||||||
|
|
||||||
$scope.showMore = function(key){
|
$scope.showMore = function(key){
|
||||||
$scope.showText[key] = true;
|
$scope.showText[key] = true;
|
||||||
@ -69,13 +82,16 @@
|
|||||||
window.location.href = "mailto:" + email + "?subject=Mail to " + email;
|
window.location.href = "mailto:" + email + "?subject=Mail to " + email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFile();
|
||||||
|
|
||||||
}])
|
}])
|
||||||
.filter('capitalize', function() {
|
.filter('capitalize', function() {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : '';
|
return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).
|
||||||
|
toLowerCase() : '';
|
||||||
}
|
}
|
||||||
}).filter('removeDashes', function() {
|
})
|
||||||
|
.filter('removeDashes', function() {
|
||||||
return function(string) {
|
return function(string) {
|
||||||
|
|
||||||
if (!angular.isString(string)) {
|
if (!angular.isString(string)) {
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
angular.module('dashboardProjectApp')
|
||||||
.config(function ($stateProvider) {
|
.config(function ($stateProvider, $urlRouterProvider) {
|
||||||
|
|
||||||
|
|
||||||
$stateProvider
|
$stateProvider
|
||||||
|
|
||||||
|
.state('error', {
|
||||||
|
url: '/projectDetail/notFound/:id',
|
||||||
|
templateUrl: 'app/projectDetail/views/notFound.html',
|
||||||
|
controller: function($scope, $state){
|
||||||
|
$scope.id = $state.params.id;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
.state('projectDetail', {
|
.state('projectDetail', {
|
||||||
url: '/projectDetail/:id',
|
url: '/projectDetail/:id',
|
||||||
/* resolve: {
|
|
||||||
userStory: ['userStoryService',
|
|
||||||
function(userStoryService) {
|
|
||||||
return userStoryService.getTasks();
|
|
||||||
}]
|
|
||||||
},*/
|
|
||||||
templateUrl: 'app/projectDetail/views/projectDetail.html',
|
templateUrl: 'app/projectDetail/views/projectDetail.html',
|
||||||
controller: 'projectDetailController'
|
controller: 'projectDetailController'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -42,3 +42,29 @@
|
|||||||
|
|
||||||
table tr.separator { height: 30px; }
|
table tr.separator { height: 30px; }
|
||||||
|
|
||||||
|
.big-title{
|
||||||
|
font-size: 80px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 40px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #767676;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big-subtitle{
|
||||||
|
text-align: center;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #767676;
|
||||||
|
}
|
||||||
|
|
||||||
|
.focus-title{
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #414141;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-subtitle{
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
padding-top: 10px;
|
||||||
|
color: #767676;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<div class="views-details">
|
||||||
|
|
||||||
|
<div class="big-title">
|
||||||
|
404
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="big-subtitle">
|
||||||
|
The Tracker with Id <span class="focus-title">{{id}}</span> does not exist. Are you sure it is spelled correctly?
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="middle-subtitle">
|
||||||
|
You can try return to the <a href="/projectList">list of trackers</a> and look for it
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
|||||||
<div class="well frm-well">
|
<div class="well frm-well">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-11">
|
<div class="col-xs-11">
|
||||||
<div class="dp-title ">
|
<div class="dp-title" data-toggle="tooltip" title="{{userStory.description}}">
|
||||||
{{userStory.title}}
|
{{userStory.shortDescription}}
|
||||||
<span class="dp-label label label-primary dp-label-{{userStory.status}}">
|
<span class="dp-label label label-primary dp-label-{{userStory.status}}">
|
||||||
{{userStory.status | removeDashes | capitalize}}
|
{{userStory.status | removeDashes | capitalize}}
|
||||||
</span>
|
</span>
|
||||||
@ -30,8 +30,8 @@
|
|||||||
<div class="col-xs-3">
|
<div class="col-xs-3">
|
||||||
<i class="fa fa-user" aria-hidden="true"></i>
|
<i class="fa fa-user" aria-hidden="true"></i>
|
||||||
<strong>Submitted by</strong>
|
<strong>Submitted by</strong>
|
||||||
<a href ng-click="mailTo(userStory.submittedByEmail)">
|
<a href ng-click="mailTo(userStory.submitted_by.email)">
|
||||||
{{userStory.submittedBy}}
|
{{userStory.submitted_by.name}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -48,8 +48,8 @@
|
|||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
|
<div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
|
||||||
aria-valuenow="{{userStory.percentageComplete}}" aria-valuemin="0" aria-valuemax="100" style="width: {{userStory.percentageComplete}}%">
|
aria-valuenow="{{userStory.completed.percentage}}" aria-valuemin="0" aria-valuemax="100" style="width: {{userStory.completed.percentage}}%">
|
||||||
<span class="sr-only">{{userStory.percentageComplete}}% Complete</span>
|
<span class="sr-only">{{userStory.completed.completed}} / {{userStory.completed.total}} Blueprints completed</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,20 +12,26 @@ angular.module('dashboardProjectApp').controller('projectListCtrl', function(
|
|||||||
new Promise(function(resolve, reject) {
|
new Promise(function(resolve, reject) {
|
||||||
var stringDate, realDate;
|
var stringDate, realDate;
|
||||||
|
|
||||||
|
|
||||||
userStories.forEach(function each (story) {
|
userStories.forEach(function each (story) {
|
||||||
if(story.latestUpdate !== undefined) {
|
|
||||||
lastUpdate = moment(story.latestUpdate[0].value).format("MM-DD-YYYY");
|
console.log('userStories', story);
|
||||||
|
if(story.lastUpdate !== '') {
|
||||||
|
lastUpdate = moment(story.lastUpdate, "YYYY-MM-DD").format("MM-DD-YYYY");
|
||||||
} else {
|
} else {
|
||||||
lastUpdate = moment(story.date, "DD-MM-YYYY").format("MM-DD-YYYY");
|
lastUpdate = moment(story.dateCreated, "DD-MM-YYYY").format("MM-DD-YYYY");
|
||||||
}
|
}
|
||||||
data.push(
|
data.push(
|
||||||
{
|
{
|
||||||
userStory: story.id+'-'+story.description,
|
userStory: story.id+'-'+story.userStory,
|
||||||
dateCreated: moment(story.date, "DD-MM-YYYY").format("MM-DD-YYYY"),
|
dateCreated: moment(story.dateCreated, "DD-MM-YYYY").format("MM-DD-YYYY"),
|
||||||
lastUpdate: lastUpdate,
|
lastUpdate: lastUpdate,
|
||||||
completed: story.percentage
|
progressPercentage: story.completed.percentage,
|
||||||
|
progressLabel: story.completed.completed + ' / ' + story.completed.total
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
console.log('data', data);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -23,3 +23,9 @@
|
|||||||
.fixed-table-toolbar .bars, .fixed-table-toolbar .search, .fixed-table-toolbar .columns{
|
.fixed-table-toolbar .bars, .fixed-table-toolbar .search, .fixed-table-toolbar .columns{
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
.fixed-table-container tbody td {
|
||||||
|
max-width:200px; /* Customise it accordingly */
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<th data-field="userStory" data-sortable="true" data-formatter="nameFormatter">User Story</th>
|
<th data-field="userStory" data-sortable="true" data-formatter="nameFormatter">User Story</th>
|
||||||
<th data-field="dateCreated" data-sortable="true">Date Created</th>
|
<th data-field="dateCreated" data-sortable="true">Date Created</th>
|
||||||
<th data-field="lastUpdate" data-sortable="true">Last Update</th>
|
<th data-field="lastUpdate" data-sortable="true">Last Update</th>
|
||||||
<th data-field="completed" data-sortable="true" data-formatter="progressBar">% Completed</th>
|
<th data-field="progressPercentage" label="progressLabel" data-sortable="true" data-formatter="progressBar"> Blueprints Completed</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
|
@ -65,13 +65,13 @@
|
|||||||
var story = value.split("-");
|
var story = value.split("-");
|
||||||
return '<a class="dp-link-title" href="projectDetail/'+ story[0] +'">' + story[1] + '</a>';
|
return '<a class="dp-link-title" href="projectDetail/'+ story[0] +'">' + story[1] + '</a>';
|
||||||
}
|
}
|
||||||
function progressBar(value, row) {
|
function progressBar(percentage, row) {
|
||||||
|
|
||||||
return '<div class="progress dp-progress">'+
|
return '<div class="progress dp-progress">'+
|
||||||
'<div class="progress-bar progress-bar-success progress-bar-striped"'+
|
'<div class="progress-bar progress-bar-success progress-bar-striped"'+
|
||||||
'role="progressbar" aria-valuenow="'+value+'" aria-valuemin="0"' +
|
'role="progressbar" aria-valuenow="'+percentage+'" aria-valuemin="0"' +
|
||||||
'aria-valuemax="100" style="width: '+value+'%">'+
|
'aria-valuemax="100" style="width: '+percentage+'%">'+
|
||||||
'<span class="sr-only">'+value+'%</span>' +
|
'<span class="sr-only">'+row.progressLabel+'</span>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user