retire featuretracker
This repository is not used anymore, retire it. Depends-On: https://review.openstack.org/597370 Change-Id: I92693b9cbacf9abd7fef39a5dbfdf90815966f16
This commit is contained in:
parent
d3aa7532f9
commit
17421dcf8d
|
@ -1,5 +0,0 @@
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
.vagrant
|
|
||||||
.idea
|
|
||||||
.idea/*
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptLibraryMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$/dashboard-project-api" libraries="{userstory.openstack.org/dashboard-project-api/node_modules}" />
|
|
||||||
<file url="file://$PROJECT_DIR$/dashboard-project-app" libraries="{userstory.openstack.org/dashboard-project-app/node_modules}" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
58
README.md
58
README.md
|
@ -1,58 +0,0 @@
|
||||||
# OpenStack Cross-project Dashboard
|
|
||||||
The OpenStack Cross-project Dashboard provides a centralized dashboard in the community to track multi-project initiatives (which may even take multiple releases).
|
|
||||||
This dashboard will leverage user story trackers to associate cross-project specs with the concepts they are crafted to deliver.
|
|
||||||
|
|
||||||
## Technologies
|
|
||||||
* Angular.js
|
|
||||||
* Express
|
|
||||||
* Node.js
|
|
||||||
* MongoDB (coming soon!)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
##### Install MongoDB
|
|
||||||
https://docs.mongodb.org/manual/installation/
|
|
||||||
|
|
||||||
##### Install Node.js and npm
|
|
||||||
https://nodejs.org/en/download/
|
|
||||||
|
|
||||||
For Ubuntu:
|
|
||||||
```
|
|
||||||
$ sudo apt-get install nodejs
|
|
||||||
$ sudo apt-get install nodejs-legacy
|
|
||||||
$ sudo apt-get install npm
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Install Strongloop + Grunt + Bower
|
|
||||||
```
|
|
||||||
$ sudo npm install -g strongloop
|
|
||||||
$ sudo npm install -g grunt-cli
|
|
||||||
$ sudo npm install -g bower
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Clone the repository
|
|
||||||
```
|
|
||||||
$ git clone https://github.com/OpenStackweb/userstory.openstack.org.git
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Running the API
|
|
||||||
```
|
|
||||||
$ cd dashboard-project-api/
|
|
||||||
$ npm install
|
|
||||||
$ npm run build-sdk
|
|
||||||
$ node .
|
|
||||||
```
|
|
||||||
You should get something like this:
|
|
||||||
```
|
|
||||||
Browse your REST API at http://0.0.0.0:3004/explorer
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Running the application
|
|
||||||
```
|
|
||||||
$ cd dashboard-project-app/
|
|
||||||
$ chmod +x install.sh
|
|
||||||
$ sh install.sh
|
|
||||||
$ sh build-sdk.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, the explorer will open automatically on port 9000.
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
This project is no longer maintained.
|
||||||
|
|
||||||
|
The contents of this repository are still available in the Git
|
||||||
|
source code management system. To see the contents of this
|
||||||
|
repository before it reached its end of life, please check out the
|
||||||
|
previous commit with "git checkout HEAD^1".
|
||||||
|
|
||||||
|
For any further questions, please email
|
||||||
|
openstack-dev@lists.openstack.org or join #openstack-dev on
|
||||||
|
Freenode.
|
|
@ -1,78 +0,0 @@
|
||||||
# -*- mode: ruby -*-
|
|
||||||
# vi: set ft=ruby :
|
|
||||||
|
|
||||||
required_plugins = %w( vagrant-vbguest vagrant-hosts vagrant-hostsupdater )
|
|
||||||
required_plugins.each do |plugin|
|
|
||||||
system "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
|
|
||||||
end
|
|
||||||
|
|
||||||
# All Vagrant configuration is done below. The "2" in Vagrant.configure
|
|
||||||
# configures the configuration version (we support older styles for
|
|
||||||
# backwards compatibility). Please don't change it unless you know what
|
|
||||||
# you're doing.
|
|
||||||
Vagrant.configure(2) do |config|
|
|
||||||
# The most common configuration options are documented and commented below.
|
|
||||||
# For a complete reference, please see the online documentation at
|
|
||||||
# https://docs.vagrantup.com.
|
|
||||||
|
|
||||||
# Every Vagrant development environment requires a box. You can search for
|
|
||||||
# boxes at https://atlas.hashicorp.com/search.
|
|
||||||
config.vm.box = "ubuntu/trusty64"
|
|
||||||
config.vm.box_url = "https://atlas.hashicorp.com/ubuntu/trusty64"
|
|
||||||
config.vm.hostname = "local.userstory.openstack.org"
|
|
||||||
|
|
||||||
# Create a private network, which allows host-only access to the machine
|
|
||||||
# using a specific IP.
|
|
||||||
config.vm.network "private_network", ip: "192.168.33.10"
|
|
||||||
# Create a public network, which generally matched to bridged network.
|
|
||||||
# Bridged networks make the machine appear as another physical device on
|
|
||||||
# your network.
|
|
||||||
# config.vm.network "public_network"
|
|
||||||
|
|
||||||
# Share an additional folder to the guest VM. The first argument is
|
|
||||||
# the path on the host to the actual folder. The second argument is
|
|
||||||
# the path on the guest to mount the folder. And the optional third
|
|
||||||
# argument is a set of non-required options.
|
|
||||||
# config.vm.synced_folder "../data", "/vagrant_data"
|
|
||||||
config.vm.synced_folder("puppet", "/etc/puppet/modules/site")
|
|
||||||
# Provider-specific configuration so you can fine-tune various
|
|
||||||
# backing providers for Vagrant. These expose provider-specific options.
|
|
||||||
# Example for VirtualBox:
|
|
||||||
#
|
|
||||||
config.vm.provider "virtualbox" do |vb|
|
|
||||||
vb.memory = "4096"
|
|
||||||
vb.name = "local.userstory.openstack.org"
|
|
||||||
vb.cpus = 2
|
|
||||||
end
|
|
||||||
|
|
||||||
# use https://github.com/oscar-stack/vagrant-hosts
|
|
||||||
# vagrant plugin install vagrant-hosts
|
|
||||||
config.vm.provision :hosts do |provisioner|
|
|
||||||
provisioner.add_host '127.0.0.1', ['local.userstory.openstack.org']
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision "bootstrap", type:"shell" do |s|
|
|
||||||
s.path = "scripts/bootstrap.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision "puppetbuild", type: "puppet" do |puppet|
|
|
||||||
puppet.manifests_path = "puppet"
|
|
||||||
puppet.manifest_file = "site.pp"
|
|
||||||
#puppet.hiera_config_path = "puppet/hiera/hiera.yaml"
|
|
||||||
#puppet.working_directory = "/etc/puppet/data"
|
|
||||||
#puppet.options = "--verbose --debug"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision "install_api", type:"shell" do |s|
|
|
||||||
s.path = "scripts/install_api.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision "install_app", type:"shell" do |s|
|
|
||||||
s.path = "scripts/install_app.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision "run_apps", type:"shell" do |s|
|
|
||||||
s.path = "scripts/run_apps.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,13 +0,0 @@
|
||||||
# EditorConfig helps developers define and maintain consistent
|
|
||||||
# coding styles between different editors and IDEs
|
|
||||||
# http://editorconfig.org
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
|
@ -1,20 +0,0 @@
|
||||||
*.csv
|
|
||||||
*.dat
|
|
||||||
*.iml
|
|
||||||
*.log
|
|
||||||
*.out
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.sublime-*
|
|
||||||
*.swo
|
|
||||||
*.swp
|
|
||||||
*.tgz
|
|
||||||
*.xml
|
|
||||||
.DS_Store
|
|
||||||
.idea
|
|
||||||
.project
|
|
||||||
.strong-pm
|
|
||||||
coverage
|
|
||||||
node_modules
|
|
||||||
npm-debug.log
|
|
||||||
js/
|
|
|
@ -1,2 +0,0 @@
|
||||||
/client/
|
|
||||||
/node_modules/
|
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"node": true,
|
|
||||||
"esnext": true,
|
|
||||||
"bitwise": true,
|
|
||||||
"camelcase": true,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"eqnull": true,
|
|
||||||
"immed": true,
|
|
||||||
"indent": 2,
|
|
||||||
"latedef": "nofunc",
|
|
||||||
"newcap": true,
|
|
||||||
"nonew": true,
|
|
||||||
"noarg": true,
|
|
||||||
"quotmark": "single",
|
|
||||||
"regexp": true,
|
|
||||||
"undef": true,
|
|
||||||
"unused": false,
|
|
||||||
"trailing": true,
|
|
||||||
"sub": true,
|
|
||||||
"maxlen": 80
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"generator-loopback": {}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# My Application
|
|
||||||
|
|
||||||
The project is generated by [LoopBack](http://loopback.io).
|
|
|
@ -1,3 +0,0 @@
|
||||||
## Client
|
|
||||||
|
|
||||||
This is the place for your application front-end files.
|
|
|
@ -1,19 +0,0 @@
|
||||||
module.exports = function(Blueprint) {
|
|
||||||
|
|
||||||
Blueprint.url = function(projectName, blueprintName, cb) {
|
|
||||||
var url = 'https://blueprints.launchpad.net/' + projectName + '/+spec/' + blueprintName;
|
|
||||||
cb(null, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
Blueprint.remoteMethod(
|
|
||||||
'url',
|
|
||||||
{
|
|
||||||
accepts: [
|
|
||||||
{arg: 'projectName', type: 'string', required: true},
|
|
||||||
{arg: 'blueprintName', type: 'string', required: true}
|
|
||||||
],
|
|
||||||
http: {verb: 'get'},
|
|
||||||
returns: {arg: 'url', type: 'string'}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Blueprint",
|
|
||||||
"base": "PersistedModel",
|
|
||||||
"idInjection": true,
|
|
||||||
"options": {},
|
|
||||||
"properties": {
|
|
||||||
"url": {
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"validations": [],
|
|
||||||
"relations": {},
|
|
||||||
"acls": [],
|
|
||||||
"methods": {}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
'strict mode';
|
|
||||||
var async = require('async');
|
|
||||||
|
|
||||||
module.exports = function(Patch) {
|
|
||||||
Patch.afterRemote('list', function (ctx, response, next) {
|
|
||||||
var data = [];
|
|
||||||
|
|
||||||
response = JSON.parse(response.substring(5));
|
|
||||||
async.waterfall([
|
|
||||||
function createOutput(next){
|
|
||||||
response.forEach( function each (element){
|
|
||||||
data.push(
|
|
||||||
{
|
|
||||||
url: "https://review.openstack.org/#/c/" + element._number,
|
|
||||||
name: element.subject
|
|
||||||
});
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
function sendData (next) {
|
|
||||||
ctx.result = data;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
], next);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
Patch.afterRemote('latestUpdate', function (ctx, response, next) {
|
|
||||||
var data = [];
|
|
||||||
|
|
||||||
response = JSON.parse(response.substring(5));
|
|
||||||
async.waterfall([
|
|
||||||
function createOutput(next){
|
|
||||||
response.forEach( function each (element){
|
|
||||||
data.push(
|
|
||||||
{
|
|
||||||
latestDate: element.updated,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
function sendData (next) {
|
|
||||||
data = data.sort();
|
|
||||||
var lastUpdate = data.shift();
|
|
||||||
ctx.result = lastUpdate;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
], next);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Patch",
|
|
||||||
"base": "PersistedModel",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"patchValues": {
|
|
||||||
"type": "object"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"validations": [],
|
|
||||||
"relations": {},
|
|
||||||
"acls": [],
|
|
||||||
"methods": {}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
'strict mode';
|
|
||||||
var async = require('async');
|
|
||||||
|
|
||||||
module.exports = function(Rst) {
|
|
||||||
|
|
||||||
Rst.afterRemote('list', function (ctx, response, next) {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Rst",
|
|
||||||
"plural": "Rsts",
|
|
||||||
"base": "PersistedModel",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"patchValues": {
|
|
||||||
"type": "object"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"validations": [],
|
|
||||||
"relations": {},
|
|
||||||
"acls": [],
|
|
||||||
"methods": {}
|
|
||||||
}
|
|
|
@ -1,327 +0,0 @@
|
||||||
module.exports = function(UserStory) {
|
|
||||||
var fs = require("fs");
|
|
||||||
var route = '../tracker';
|
|
||||||
var app = require('../../server/server');
|
|
||||||
var markdown = require("markdown").markdown;
|
|
||||||
var async = require("async");
|
|
||||||
var cheerio = require('cheerio');
|
|
||||||
var xssFilters = require("xss-filters");
|
|
||||||
const SPEC_URL = "http://specs.openstack.org/openstack/openstack-user-stories/user-stories/proposed/";
|
|
||||||
|
|
||||||
|
|
||||||
var blueprintsResume = [];
|
|
||||||
|
|
||||||
var getAllfiles = function(){
|
|
||||||
return fs.readdirSync(route)
|
|
||||||
.map(function(file){
|
|
||||||
var route = "../tracker/" + file ;
|
|
||||||
var userStory = JSON.parse(fs.readFileSync(route));
|
|
||||||
return userStory;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var getFileById = function(id){
|
|
||||||
|
|
||||||
//get all files
|
|
||||||
var userStories = getAllfiles();
|
|
||||||
//filter by Id
|
|
||||||
var file = userStories.filter(function(item){
|
|
||||||
// VALIDATE IF A VALID ID IS COMING!
|
|
||||||
return item.id == xssFilters.inHTMLData(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) {
|
|
||||||
|
|
||||||
var task = userStory.tasks_status[taskName];
|
|
||||||
|
|
||||||
task.projects.forEach(function (projectName) {
|
|
||||||
//VALIDATE projectName EXISTS
|
|
||||||
var blueprints = task.projects_status[xssFilters.inHTMLData(projectName)].blueprints;
|
|
||||||
var blueprintNames = Object.keys(blueprints);
|
|
||||||
|
|
||||||
blueprintNames.forEach(function (blueprintName) {
|
|
||||||
// VALIDATE PROPERLY if this statement is not true
|
|
||||||
if (blueprints[xssFilters.inHTMLData(blueprintName)] == 'completed')
|
|
||||||
blueprintsResume.completed = blueprintsResume.completed + 1;
|
|
||||||
|
|
||||||
blueprintsResume.total = blueprintsResume.total + 1;
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
blueprintsResume.percentage = (blueprintsResume.completed/blueprintsResume.total)*100;
|
|
||||||
|
|
||||||
return blueprintsResume;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the field lastupdated for a usterStory
|
|
||||||
var getLastUpdated = function(userStory, cb){
|
|
||||||
var Patch = app.models.Patch;
|
|
||||||
var lastUpdate = '';
|
|
||||||
|
|
||||||
Patch.latestUpdate(userStory.source, function (err, response) {
|
|
||||||
response = JSON.parse(response.substring(5));
|
|
||||||
|
|
||||||
if(response.length > 0){
|
|
||||||
lastUpdate = response.map( function each (element){
|
|
||||||
return element.updated
|
|
||||||
}).sort().pop();
|
|
||||||
var arrayLastUpdate = lastUpdate.split(' ');
|
|
||||||
lastUpdate = arrayLastUpdate[0];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(null, lastUpdate)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//getting task description
|
|
||||||
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;
|
|
||||||
var description;
|
|
||||||
//Find the title
|
|
||||||
$('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';
|
|
||||||
}
|
|
||||||
|
|
||||||
//parsing task
|
|
||||||
var parseTask = function(originalTask, callback){
|
|
||||||
|
|
||||||
getTaskDescription(originalTask, function(err, description){
|
|
||||||
originalTask.description = description;
|
|
||||||
originalTask.url = getUriTask(originalTask['cross-project spec']);
|
|
||||||
callback(null, originalTask)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//parsing project
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
//parsing blueprints
|
|
||||||
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)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//parsing tasks
|
|
||||||
var parseTasks = function(userStory, tasksNames, tasks, callback) { //get tasks
|
|
||||||
|
|
||||||
var tmpTasks = {};
|
|
||||||
async.each(tasksNames, function(taskName, callbackInner) {
|
|
||||||
|
|
||||||
parseTask(tasks[taskName], function(err, parsedTask){
|
|
||||||
|
|
||||||
tmpTasks[taskName] = parsedTask;
|
|
||||||
|
|
||||||
var tmpProjects = {};
|
|
||||||
async.each(tmpTasks[taskName].projects, function(projectName, callbackInner2) {
|
|
||||||
|
|
||||||
parseProject(tmpTasks[taskName].projects_status[projectName], function(err, parsedProject){
|
|
||||||
tmpProjects[projectName] = parsedProject;
|
|
||||||
|
|
||||||
//Bluprints
|
|
||||||
var blueprintNames = Object.keys(tmpProjects[projectName].blueprints);
|
|
||||||
|
|
||||||
async.map(blueprintNames, function(blueprintName, callbackInner3) {
|
|
||||||
|
|
||||||
parseBlueprint(tmpProjects[projectName].blueprints[blueprintName], blueprintName, projectName, function(err, parsedBlueprint){
|
|
||||||
// tmpProjects[projectName].blueprints[blueprintName] = parsedBlueprint
|
|
||||||
callbackInner3(null, parsedBlueprint)
|
|
||||||
})
|
|
||||||
|
|
||||||
}, function(err, blueprints) {
|
|
||||||
|
|
||||||
tmpProjects[projectName].blueprints = blueprints;
|
|
||||||
|
|
||||||
var project = {};
|
|
||||||
project[projectName] = tmpProjects[projectName];
|
|
||||||
|
|
||||||
callbackInner2(null)
|
|
||||||
|
|
||||||
});
|
|
||||||
//fin blueprints
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}, function() {
|
|
||||||
tmpTasks[taskName].projects_status = tmpProjects;
|
|
||||||
callbackInner(null)
|
|
||||||
});
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}, function() {
|
|
||||||
userStory.tasks = tasksNames;
|
|
||||||
userStory.tasks_status = tmpTasks;
|
|
||||||
|
|
||||||
//userStory.percentageComplete = getPercentage(blueprintsResume)
|
|
||||||
|
|
||||||
callback(null, userStory);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//?
|
|
||||||
UserStory.on('attached',function(){
|
|
||||||
|
|
||||||
UserStory.findById = function(id, params, cb){
|
|
||||||
|
|
||||||
var userStory = getFileById(id);
|
|
||||||
|
|
||||||
if(userStory){
|
|
||||||
parseUserStory(userStory, cb);
|
|
||||||
}else{
|
|
||||||
cb('File does not exist', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
};//end find by id
|
|
||||||
|
|
||||||
UserStory.find = function(params, cb){
|
|
||||||
var userStories = getAllfiles();
|
|
||||||
|
|
||||||
async.mapSeries(userStories, parse, cb);
|
|
||||||
|
|
||||||
function parse(userStory, callback) {
|
|
||||||
|
|
||||||
async.waterfall([function(cb){
|
|
||||||
getLastUpdated(userStory, cb)
|
|
||||||
},function(lastUpdated, cb){
|
|
||||||
|
|
||||||
var itemResult = {
|
|
||||||
completed: getbluePrintResume(userStory),
|
|
||||||
dateCreated: xssFilters.inHTMLData(userStory.date),
|
|
||||||
lastUpdate: xssFilters.inHTMLData(lastUpdated),
|
|
||||||
userStory: xssFilters.inHTMLData(userStory.description),
|
|
||||||
id:xssFilters.inHTMLData(userStory.id)
|
|
||||||
};
|
|
||||||
|
|
||||||
cb(null, itemResult);
|
|
||||||
|
|
||||||
}],function(err,result){
|
|
||||||
callback( err, result);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};//End find
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"name": "UserStory",
|
|
||||||
"base": "PersistedModel",
|
|
||||||
"idInjection": false,
|
|
||||||
"options": {},
|
|
||||||
"properties": {
|
|
||||||
"UserStory": {
|
|
||||||
"type": "array",
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"validations": [],
|
|
||||||
"relations": {},
|
|
||||||
"acls": [],
|
|
||||||
"methods": {}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"name": "dashboard-project-api",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "server/server.js",
|
|
||||||
"scripts": {
|
|
||||||
"start": "node .",
|
|
||||||
"build-sdk": "mkdir -p js; lb-ng server/server.js js/lbServices.js",
|
|
||||||
"pretest": "jshint .",
|
|
||||||
"posttest": "nsp check"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"async": "^2.0.0-rc.3",
|
|
||||||
"cheerio": "^0.0.3",
|
|
||||||
"compression": "^1.0.3",
|
|
||||||
"cors": "^2.5.2",
|
|
||||||
"helmet": "~0.14.0",
|
|
||||||
"htmlparser": "^1.7.7",
|
|
||||||
"loopback": "^2.22.0",
|
|
||||||
"loopback-boot": "^2.6.5",
|
|
||||||
"loopback-component-explorer": "^2.4.0",
|
|
||||||
"loopback-connector-rest": "^1.5.0",
|
|
||||||
"loopback-datasource-juggler": "^2.39.0",
|
|
||||||
"markdown": "^0.5.0",
|
|
||||||
"serve-favicon": "^2.0.1",
|
|
||||||
"underscore": "^1.8.3",
|
|
||||||
"xss-filters": "^1.2.7"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"jshint": "^2.5.6",
|
|
||||||
"nsp": "^2.1.0"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "",
|
|
||||||
"url": ""
|
|
||||||
},
|
|
||||||
"license": "UNLICENSED",
|
|
||||||
"description": "dashboard-project-api"
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"name" : "dashboard-api",
|
|
||||||
"script" : "server/server.js",
|
|
||||||
"watch" : true,
|
|
||||||
"env_production" : {
|
|
||||||
"NODE_ENV": "production"
|
|
||||||
},
|
|
||||||
"env_local" : {
|
|
||||||
"NODE_ENV": "production"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = function enableAuthentication(server) {
|
|
||||||
// enable authentication
|
|
||||||
server.enableAuth();
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
module.exports = function(server) {
|
|
||||||
// Install a `/` route that returns server status
|
|
||||||
var router = server.loopback.Router();
|
|
||||||
router.get('/', server.loopback.status());
|
|
||||||
server.use(router);
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"loopback-component-explorer": {
|
|
||||||
"mountPath": "/explorer"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"restApiRoot": "/api",
|
|
||||||
"host": "0.0.0.0",
|
|
||||||
"port": 3004,
|
|
||||||
"remoting": {
|
|
||||||
"context": {
|
|
||||||
"enableHttpContext": false
|
|
||||||
},
|
|
||||||
"rest": {
|
|
||||||
"normalizeHttpPath": false,
|
|
||||||
"xml": false
|
|
||||||
},
|
|
||||||
"json": {
|
|
||||||
"strict": false,
|
|
||||||
"limit": "100kb"
|
|
||||||
},
|
|
||||||
"urlencoded": {
|
|
||||||
"extended": true,
|
|
||||||
"limit": "100kb"
|
|
||||||
},
|
|
||||||
"cors": false,
|
|
||||||
"errorHandler": {
|
|
||||||
"disableStackTrace": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"legacyExplorer": false
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
{
|
|
||||||
"db": {
|
|
||||||
"name": "db",
|
|
||||||
"connector": "memory"
|
|
||||||
},
|
|
||||||
"Patch": {
|
|
||||||
"name": "Patch",
|
|
||||||
"connector": "rest",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"template": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "https://review.openstack.org/changes/?q=topic:{topic}",
|
|
||||||
"headers": {
|
|
||||||
"accepts": "application/json",
|
|
||||||
"content-type": "application/json"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"functions": {
|
|
||||||
"list": [
|
|
||||||
"topic"
|
|
||||||
],
|
|
||||||
"latestUpdate": [
|
|
||||||
"topic"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Rst": {
|
|
||||||
"name": "Rst",
|
|
||||||
"connector": "rest",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"template": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "https://raw.githubusercontent.com/openstack/openstack-specs/master/specs/{file}"
|
|
||||||
},
|
|
||||||
"functions": {
|
|
||||||
"list": [
|
|
||||||
"file"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"initial:before": {
|
|
||||||
"loopback#favicon": {}
|
|
||||||
},
|
|
||||||
"initial": {
|
|
||||||
"compression": {},
|
|
||||||
"cors": {
|
|
||||||
"params": {
|
|
||||||
"origin": true,
|
|
||||||
"credentials": true,
|
|
||||||
"maxAge": 86400
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"helmet#xssFilter": {},
|
|
||||||
"helmet#frameguard": {
|
|
||||||
"params": [
|
|
||||||
"deny"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"helmet#hsts": {
|
|
||||||
"params": {
|
|
||||||
"maxAge": 0,
|
|
||||||
"includeSubdomains": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"helmet#hidePoweredBy": {},
|
|
||||||
"helmet#ieNoOpen": {},
|
|
||||||
"helmet#noSniff": {},
|
|
||||||
"helmet#noCache": {
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"session": {},
|
|
||||||
"auth": {},
|
|
||||||
"parse": {},
|
|
||||||
"routes": {
|
|
||||||
"loopback#rest": {
|
|
||||||
"paths": [
|
|
||||||
"${restApiRoot}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": {},
|
|
||||||
"final": {
|
|
||||||
"loopback#urlNotFound": {}
|
|
||||||
},
|
|
||||||
"final:after": {
|
|
||||||
"loopback#errorHandler": {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"final:after": {
|
|
||||||
"loopback#errorHandler": {
|
|
||||||
"params": {
|
|
||||||
"includeStack": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"sources": [
|
|
||||||
"loopback/common/models",
|
|
||||||
"loopback/server/models",
|
|
||||||
"../common/models",
|
|
||||||
"./models"
|
|
||||||
],
|
|
||||||
"mixins": [
|
|
||||||
"loopback/common/mixins",
|
|
||||||
"loopback/server/mixins",
|
|
||||||
"../common/mixins",
|
|
||||||
"./mixins"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"UserStory": {
|
|
||||||
"dataSource": "db"
|
|
||||||
},
|
|
||||||
"AccessToken": {
|
|
||||||
"dataSource": "db",
|
|
||||||
"public": false
|
|
||||||
},
|
|
||||||
"ACL": {
|
|
||||||
"dataSource": "db",
|
|
||||||
"public": false
|
|
||||||
},
|
|
||||||
"RoleMapping": {
|
|
||||||
"dataSource": "db",
|
|
||||||
"public": false
|
|
||||||
},
|
|
||||||
"Role": {
|
|
||||||
"dataSource": "db",
|
|
||||||
"public": false
|
|
||||||
},
|
|
||||||
"Blueprint": {
|
|
||||||
"dataSource": "db",
|
|
||||||
"public": true
|
|
||||||
},
|
|
||||||
"Patch": {
|
|
||||||
"dataSource": "Patch",
|
|
||||||
"public": true
|
|
||||||
},
|
|
||||||
"Rst": {
|
|
||||||
"dataSource": "Rst",
|
|
||||||
"public": true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
var loopback = require('loopback');
|
|
||||||
var boot = require('loopback-boot');
|
|
||||||
|
|
||||||
var app = module.exports = loopback();
|
|
||||||
|
|
||||||
app.start = function() {
|
|
||||||
// start the web server
|
|
||||||
return app.listen(function() {
|
|
||||||
app.emit('started');
|
|
||||||
var baseUrl = app.get('url').replace(/\/$/, '');
|
|
||||||
console.log('Web server listening at: %s', baseUrl);
|
|
||||||
if (app.get('loopback-component-explorer')) {
|
|
||||||
var explorerPath = app.get('loopback-component-explorer').mountPath;
|
|
||||||
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bootstrap the application, configure models, datasources and middleware.
|
|
||||||
// Sub-apps like REST API are mounted via boot scripts.
|
|
||||||
boot(app, __dirname, function(err) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
// start the server if `$ node server.js`
|
|
||||||
if (require.main === module)
|
|
||||||
app.start();
|
|
||||||
});
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"presets": ["es2015"],
|
|
||||||
"plugins": ["transform-class-properties"]
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"directory": "client/bower_components"
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# EditorConfig helps developers define and maintain consistent
|
|
||||||
# coding styles between different editors and IDEs
|
|
||||||
# editorconfig.org
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
|
|
||||||
[*]
|
|
||||||
|
|
||||||
# Change these settings to your own preference
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# We recommend you to keep these unchanged
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
|
@ -1,43 +0,0 @@
|
||||||
* text=auto
|
|
||||||
|
|
||||||
# These files are text and should be normalized (Convert crlf => lf)
|
|
||||||
*.php text
|
|
||||||
*.css text
|
|
||||||
*.js text
|
|
||||||
*.htm text
|
|
||||||
*.html text
|
|
||||||
*.xml text
|
|
||||||
*.txt text
|
|
||||||
*.ini text
|
|
||||||
*.inc text
|
|
||||||
.htaccess text
|
|
||||||
|
|
||||||
# Denote all files that are truly binary and should not be modified.
|
|
||||||
# (binary is a macro for -text -diff)
|
|
||||||
*.png binary
|
|
||||||
*.jpg binary
|
|
||||||
*.jpeg binary
|
|
||||||
*.gif binary
|
|
||||||
*.ico binary
|
|
||||||
*.mov binary
|
|
||||||
*.mp4 binary
|
|
||||||
*.mp3 binary
|
|
||||||
*.flv binary
|
|
||||||
*.fla binary
|
|
||||||
*.swf binary
|
|
||||||
*.gz binary
|
|
||||||
*.zip binary
|
|
||||||
*.7z binary
|
|
||||||
*.ttf binary
|
|
||||||
|
|
||||||
# Documents
|
|
||||||
*.doc diff=astextplain
|
|
||||||
*.DOC diff=astextplain
|
|
||||||
*.docx diff=astextplain
|
|
||||||
*.DOCX diff=astextplain
|
|
||||||
*.dot diff=astextplain
|
|
||||||
*.DOT diff=astextplain
|
|
||||||
*.pdf diff=astextplain
|
|
||||||
*.PDF diff=astextplain
|
|
||||||
*.rtf diff=astextplain
|
|
||||||
*.RTF diff=astextplain
|
|
|
@ -1,14 +0,0 @@
|
||||||
node_modules
|
|
||||||
public
|
|
||||||
.tmp
|
|
||||||
.idea
|
|
||||||
client/bower_components
|
|
||||||
dist
|
|
||||||
/server/config/local.env.js
|
|
||||||
npm-debug.log
|
|
||||||
coverage
|
|
||||||
.DS_Store
|
|
||||||
/client/.DS_Store
|
|
||||||
/client/app/.DS_Store
|
|
||||||
/client/components/sdk/
|
|
||||||
../.idea
|
|
|
@ -1,48 +0,0 @@
|
||||||
{
|
|
||||||
"excludeFiles": [
|
|
||||||
"client/app/app.constant.js"
|
|
||||||
],
|
|
||||||
"esnext": true,
|
|
||||||
"maximumLineLength": {
|
|
||||||
"value": 100,
|
|
||||||
"allowComments": true,
|
|
||||||
"allowRegex": true
|
|
||||||
},
|
|
||||||
"disallowMixedSpacesAndTabs": true,
|
|
||||||
"disallowMultipleLineStrings": true,
|
|
||||||
"disallowNewlineBeforeBlockStatements": true,
|
|
||||||
"disallowSpaceAfterObjectKeys": true,
|
|
||||||
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
|
|
||||||
"disallowSpaceBeforeBinaryOperators": [","],
|
|
||||||
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
|
|
||||||
"disallowSpacesInAnonymousFunctionExpression": {
|
|
||||||
"beforeOpeningRoundBrace": true
|
|
||||||
},
|
|
||||||
"disallowSpacesInFunctionDeclaration": {
|
|
||||||
"beforeOpeningRoundBrace": true
|
|
||||||
},
|
|
||||||
"disallowSpacesInNamedFunctionExpression": {
|
|
||||||
"beforeOpeningRoundBrace": true
|
|
||||||
},
|
|
||||||
"disallowSpacesInsideArrayBrackets": true,
|
|
||||||
"disallowSpacesInsideParentheses": true,
|
|
||||||
"disallowTrailingComma": true,
|
|
||||||
"disallowTrailingWhitespace": true,
|
|
||||||
"requireCommaBeforeLineBreak": true,
|
|
||||||
"requireLineFeedAtFileEnd": true,
|
|
||||||
"requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
|
|
||||||
"requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
|
|
||||||
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
|
|
||||||
"requireSpaceBeforeBlockStatements": true,
|
|
||||||
"requireSpacesInConditionalExpression": {
|
|
||||||
"afterTest": true,
|
|
||||||
"beforeConsequent": true,
|
|
||||||
"afterConsequent": true,
|
|
||||||
"beforeAlternate": true
|
|
||||||
},
|
|
||||||
"requireSpacesInFunction": {
|
|
||||||
"beforeOpeningCurlyBrace": true
|
|
||||||
},
|
|
||||||
"validateLineBreaks": "LF",
|
|
||||||
"validateParameterSeparator": ", "
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- 4.2.3
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
allow_failures:
|
|
||||||
- node_js: 5.1.1
|
|
||||||
before_script:
|
|
||||||
- npm install -g bower grunt-cli
|
|
||||||
- bower install
|
|
||||||
services: mongodb
|
|
|
@ -1,67 +0,0 @@
|
||||||
{
|
|
||||||
"generator-angular-fullstack": {
|
|
||||||
"generatorVersion": "3.5.0",
|
|
||||||
"endpointDirectory": "server/api/",
|
|
||||||
"insertRoutes": true,
|
|
||||||
"registerRoutesFile": "server/routes.js",
|
|
||||||
"routesNeedle": "// Insert routes below",
|
|
||||||
"routesBase": "/api/",
|
|
||||||
"pluralizeRoutes": true,
|
|
||||||
"insertSockets": true,
|
|
||||||
"registerSocketsFile": "server/config/socketio.js",
|
|
||||||
"socketsNeedle": "// Insert sockets below",
|
|
||||||
"insertModels": true,
|
|
||||||
"registerModelsFile": "server/sqldb/index.js",
|
|
||||||
"modelsNeedle": "// Insert models below",
|
|
||||||
"filters": {
|
|
||||||
"js": true,
|
|
||||||
"babel": true,
|
|
||||||
"html": true,
|
|
||||||
"css": true,
|
|
||||||
"uirouter": true,
|
|
||||||
"bootstrap": true,
|
|
||||||
"uibootstrap": true,
|
|
||||||
"models": true,
|
|
||||||
"mongooseModels": true,
|
|
||||||
"mongoose": true,
|
|
||||||
"grunt": true,
|
|
||||||
"mocha": true,
|
|
||||||
"jasmine": false,
|
|
||||||
"should": false,
|
|
||||||
"expect": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"generator-ng-component": {
|
|
||||||
"routeDirectory": "client/app/",
|
|
||||||
"directiveDirectory": "client/app/",
|
|
||||||
"componentDirectory": "app/components/",
|
|
||||||
"filterDirectory": "client/app/",
|
|
||||||
"serviceDirectory": "client/app/",
|
|
||||||
"basePath": "client",
|
|
||||||
"moduleName": "",
|
|
||||||
"modulePrompt": true,
|
|
||||||
"filters": [
|
|
||||||
"uirouter",
|
|
||||||
"mocha",
|
|
||||||
"expect",
|
|
||||||
"uirouter",
|
|
||||||
"es6"
|
|
||||||
],
|
|
||||||
"extensions": [
|
|
||||||
"babel",
|
|
||||||
"js",
|
|
||||||
"html",
|
|
||||||
"css"
|
|
||||||
],
|
|
||||||
"directiveSimpleTemplates": "",
|
|
||||||
"directiveComplexTemplates": "",
|
|
||||||
"filterTemplates": "",
|
|
||||||
"serviceTemplates": "",
|
|
||||||
"factoryTemplates": "",
|
|
||||||
"controllerTemplates": "",
|
|
||||||
"componentTemplates": "",
|
|
||||||
"decoratorTemplates": "",
|
|
||||||
"providerTemplates": "",
|
|
||||||
"routeTemplates": ""
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,809 +0,0 @@
|
||||||
// Generated on 2016-03-29 using generator-angular-fullstack 3.5.0
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = function (grunt) {
|
|
||||||
var localConfig;
|
|
||||||
try {
|
|
||||||
localConfig = require('./server/config/local.env');
|
|
||||||
} catch(e) {
|
|
||||||
localConfig = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load grunt tasks automatically, when needed
|
|
||||||
require('jit-grunt')(grunt, {
|
|
||||||
express: 'grunt-express-server',
|
|
||||||
useminPrepare: 'grunt-usemin',
|
|
||||||
ngtemplates: 'grunt-angular-templates',
|
|
||||||
cdnify: 'grunt-google-cdn',
|
|
||||||
protractor: 'grunt-protractor-runner',
|
|
||||||
buildcontrol: 'grunt-build-control',
|
|
||||||
istanbul_check_coverage: 'grunt-mocha-istanbul',
|
|
||||||
ngconstant: 'grunt-ng-constant'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Time how long tasks take. Can help when optimizing build times
|
|
||||||
require('time-grunt')(grunt);
|
|
||||||
|
|
||||||
// Define the configuration for all the tasks
|
|
||||||
grunt.initConfig({
|
|
||||||
|
|
||||||
// Project settings
|
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
|
||||||
yeoman: {
|
|
||||||
// configurable paths
|
|
||||||
client: require('./bower.json').appPath || 'client',
|
|
||||||
server: 'server',
|
|
||||||
dist: 'dist'
|
|
||||||
},
|
|
||||||
express: {
|
|
||||||
options: {
|
|
||||||
port: process.env.PORT || 9000
|
|
||||||
},
|
|
||||||
dev: {
|
|
||||||
options: {
|
|
||||||
script: '<%= yeoman.server %>',
|
|
||||||
debug: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prod: {
|
|
||||||
options: {
|
|
||||||
script: '<%= yeoman.dist %>/<%= yeoman.server %>'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
open: {
|
|
||||||
server: {
|
|
||||||
url: 'http://localhost:<%= express.options.port %>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
babel: {
|
|
||||||
files: ['<%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js'],
|
|
||||||
tasks: ['newer:babel:client']
|
|
||||||
},
|
|
||||||
ngconstant: {
|
|
||||||
files: ['<%= yeoman.server %>/config/environment/shared.js'],
|
|
||||||
tasks: ['ngconstant']
|
|
||||||
},
|
|
||||||
injectJS: {
|
|
||||||
files: [
|
|
||||||
'<%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js',
|
|
||||||
'!<%= yeoman.client %>/app/app.js'
|
|
||||||
],
|
|
||||||
tasks: ['injector:scripts']
|
|
||||||
},
|
|
||||||
injectCss: {
|
|
||||||
files: ['<%= yeoman.client %>/{app,components}/**/*.css'],
|
|
||||||
tasks: ['injector:css']
|
|
||||||
},
|
|
||||||
mochaTest: {
|
|
||||||
files: ['<%= yeoman.server %>/**/*.{spec,integration}.js'],
|
|
||||||
tasks: ['env:test', 'mochaTest']
|
|
||||||
},
|
|
||||||
jsTest: {
|
|
||||||
files: ['<%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js'],
|
|
||||||
tasks: ['newer:jshint:all', 'wiredep:test', 'karma']
|
|
||||||
},
|
|
||||||
gruntfile: {
|
|
||||||
files: ['Gruntfile.js']
|
|
||||||
},
|
|
||||||
livereload: {
|
|
||||||
files: [
|
|
||||||
'{.tmp,<%= yeoman.client %>}/{app,components}/**/*.{css,html}',
|
|
||||||
'{.tmp,<%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).js',
|
|
||||||
'<%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
|
|
||||||
],
|
|
||||||
options: {
|
|
||||||
livereload: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
express: {
|
|
||||||
files: ['<%= yeoman.server %>/**/*.{js,json}'],
|
|
||||||
tasks: ['express:dev', 'wait'],
|
|
||||||
options: {
|
|
||||||
livereload: true,
|
|
||||||
spawn: false //Without this option specified express won't be reloaded
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bower: {
|
|
||||||
files: ['bower.json'],
|
|
||||||
tasks: ['wiredep']
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Make sure code styles are up to par and there are no obvious mistakes
|
|
||||||
jshint: {
|
|
||||||
options: {
|
|
||||||
jshintrc: '<%= yeoman.client %>/.jshintrc',
|
|
||||||
reporter: require('jshint-stylish')
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
options: {
|
|
||||||
jshintrc: '<%= yeoman.server %>/.jshintrc'
|
|
||||||
},
|
|
||||||
src: ['<%= yeoman.server %>/**/!(*.spec|*.integration).js']
|
|
||||||
},
|
|
||||||
serverTest: {
|
|
||||||
options: {
|
|
||||||
jshintrc: '<%= yeoman.server %>/.jshintrc-spec'
|
|
||||||
},
|
|
||||||
src: ['<%= yeoman.server %>/**/*.{spec,integration}.js']
|
|
||||||
},
|
|
||||||
all: ['<%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock|app.constant).js'],
|
|
||||||
test: {
|
|
||||||
src: ['<%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
jscs: {
|
|
||||||
options: {
|
|
||||||
config: ".jscsrc"
|
|
||||||
},
|
|
||||||
main: {
|
|
||||||
files: {
|
|
||||||
src: [
|
|
||||||
'<%= yeoman.client %>/app/**/*.js',
|
|
||||||
'<%= yeoman.server %>/**/*.js'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Empties folders to start fresh
|
|
||||||
clean: {
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
dot: true,
|
|
||||||
src: [
|
|
||||||
'.tmp',
|
|
||||||
'<%= yeoman.dist %>/!(.git*|.openshift|Procfile)**'
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
server: '.tmp'
|
|
||||||
},
|
|
||||||
|
|
||||||
// Add vendor prefixed styles
|
|
||||||
postcss: {
|
|
||||||
options: {
|
|
||||||
map: true,
|
|
||||||
processors: [
|
|
||||||
require('autoprefixer')({browsers: ['last 2 version']})
|
|
||||||
]
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '.tmp/',
|
|
||||||
src: '{,*/}*.css',
|
|
||||||
dest: '.tmp/'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Debugging with node inspector
|
|
||||||
'node-inspector': {
|
|
||||||
custom: {
|
|
||||||
options: {
|
|
||||||
'web-host': 'localhost'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Use nodemon to run server in debug mode with an initial breakpoint
|
|
||||||
nodemon: {
|
|
||||||
debug: {
|
|
||||||
script: '<%= yeoman.server %>',
|
|
||||||
options: {
|
|
||||||
nodeArgs: ['--debug-brk'],
|
|
||||||
env: {
|
|
||||||
PORT: process.env.PORT || 9000
|
|
||||||
},
|
|
||||||
callback: function (nodemon) {
|
|
||||||
nodemon.on('log', function (event) {
|
|
||||||
console.log(event.colour);
|
|
||||||
});
|
|
||||||
|
|
||||||
// opens browser on initial server start
|
|
||||||
nodemon.on('config:update', function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
require('open')('http://localhost:8080/debug?port=5858');
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Automatically inject Bower components into the app and karma.conf.js
|
|
||||||
wiredep: {
|
|
||||||
options: {
|
|
||||||
exclude: [
|
|
||||||
/bootstrap.js/,
|
|
||||||
'/json3/',
|
|
||||||
'/es5-shim/'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
client: {
|
|
||||||
src: '<%= yeoman.client %>/index.html',
|
|
||||||
ignorePath: '<%= yeoman.client %>/',
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
src: './karma.conf.js',
|
|
||||||
devDependencies: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Renames files for browser caching purposes
|
|
||||||
filerev: {
|
|
||||||
dist: {
|
|
||||||
src: [
|
|
||||||
'<%= yeoman.dist %>/<%= yeoman.client %>/!(bower_components){,*/}*.{js,css}',
|
|
||||||
'<%= yeoman.dist %>/<%= yeoman.client %>/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Reads HTML for usemin blocks to enable smart builds that automatically
|
|
||||||
// concat, minify and revision files. Creates configurations in memory so
|
|
||||||
// additional tasks can operate on them
|
|
||||||
useminPrepare: {
|
|
||||||
html: ['<%= yeoman.client %>/index.html'],
|
|
||||||
options: {
|
|
||||||
dest: '<%= yeoman.dist %>/<%= yeoman.client %>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Performs rewrites based on rev and the useminPrepare configuration
|
|
||||||
usemin: {
|
|
||||||
html: ['<%= yeoman.dist %>/<%= yeoman.client %>/{,!(bower_components)/**/}*.html'],
|
|
||||||
css: ['<%= yeoman.dist %>/<%= yeoman.client %>/!(bower_components){,*/}*.css'],
|
|
||||||
js: ['<%= yeoman.dist %>/<%= yeoman.client %>/!(bower_components){,*/}*.js'],
|
|
||||||
options: {
|
|
||||||
assetsDirs: [
|
|
||||||
'<%= yeoman.dist %>/<%= yeoman.client %>',
|
|
||||||
'<%= yeoman.dist %>/<%= yeoman.client %>/assets/images'
|
|
||||||
],
|
|
||||||
// This is so we update image references in our ng-templates
|
|
||||||
patterns: {
|
|
||||||
css: [
|
|
||||||
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the CSS to reference our revved images']
|
|
||||||
],
|
|
||||||
js: [
|
|
||||||
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// The following *-min tasks produce minified files in the dist folder
|
|
||||||
imagemin: {
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '<%= yeoman.client %>/assets/images',
|
|
||||||
src: '{,*/}*.{png,jpg,jpeg,gif,svg}',
|
|
||||||
dest: '<%= yeoman.dist %>/<%= yeoman.client %>/assets/images'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Allow the use of non-minsafe AngularJS files. Automatically makes it
|
|
||||||
// minsafe compatible so Uglify does not destroy the ng references
|
|
||||||
ngAnnotate: {
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '.tmp/concat',
|
|
||||||
src: '**/*.js',
|
|
||||||
dest: '.tmp/concat'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Dynamically generate angular constant `appConfig` from
|
|
||||||
// `server/config/environment/shared.js`
|
|
||||||
ngconstant: {
|
|
||||||
options: {
|
|
||||||
name: 'dashboardProjectApp.constants',
|
|
||||||
dest: '<%= yeoman.client %>/app/app.constant.js',
|
|
||||||
deps: [],
|
|
||||||
wrap: true,
|
|
||||||
configPath: '<%= yeoman.server %>/config/environment/shared'
|
|
||||||
},
|
|
||||||
development: {
|
|
||||||
constants: function() {
|
|
||||||
var config = require('./' + grunt.config.get('ngconstant.options.configPath'))
|
|
||||||
config.apiBaseUrl = 'http://localhost:3004/api';
|
|
||||||
return { appConfig : config};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
local: {
|
|
||||||
constants: function() {
|
|
||||||
var config = require('./' + grunt.config.get('ngconstant.options.configPath'))
|
|
||||||
config.apiBaseUrl = 'http://local.userstory.openstack.org/api';
|
|
||||||
return { appConfig : config};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
production: {
|
|
||||||
constants: function() {
|
|
||||||
var config = require('./' + grunt.config.get('ngconstant.options.configPath'))
|
|
||||||
config.apiBaseUrl = 'http://featuretracker.openstack.org/api';
|
|
||||||
return { appConfig : config};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Package all the html partials into a single javascript payload
|
|
||||||
ngtemplates: {
|
|
||||||
options: {
|
|
||||||
// This should be the name of your apps angular module
|
|
||||||
module: 'dashboardProjectApp',
|
|
||||||
htmlmin: {
|
|
||||||
collapseBooleanAttributes: true,
|
|
||||||
collapseWhitespace: true,
|
|
||||||
removeAttributeQuotes: true,
|
|
||||||
removeEmptyAttributes: true,
|
|
||||||
removeRedundantAttributes: true,
|
|
||||||
removeScriptTypeAttributes: true,
|
|
||||||
removeStyleLinkTypeAttributes: true
|
|
||||||
},
|
|
||||||
usemin: 'app/app.js'
|
|
||||||
},
|
|
||||||
main: {
|
|
||||||
cwd: '<%= yeoman.client %>',
|
|
||||||
src: ['{app,components}/**/*.html'],
|
|
||||||
dest: '.tmp/templates.js'
|
|
||||||
},
|
|
||||||
tmp: {
|
|
||||||
cwd: '.tmp',
|
|
||||||
src: ['{app,components}/**/*.html'],
|
|
||||||
dest: '.tmp/tmp-templates.js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Replace Google CDN references
|
|
||||||
cdnify: {
|
|
||||||
dist: {
|
|
||||||
html: ['<%= yeoman.dist %>/<%= yeoman.client %>/*.html']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Copies remaining files to places other tasks can use
|
|
||||||
copy: {
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
dot: true,
|
|
||||||
cwd: '<%= yeoman.client %>',
|
|
||||||
dest: '<%= yeoman.dist %>/<%= yeoman.client %>',
|
|
||||||
src: [
|
|
||||||
'*.{ico,png,txt}',
|
|
||||||
'.htaccess',
|
|
||||||
'bower_components/**/*',
|
|
||||||
'assets/images/{,*/}*.{webp}',
|
|
||||||
'assets/fonts/**/*',
|
|
||||||
'index.html',
|
|
||||||
'app/**/*'
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
expand: true,
|
|
||||||
cwd: '.tmp/images',
|
|
||||||
dest: '<%= yeoman.dist %>/<%= yeoman.client %>/assets/images',
|
|
||||||
src: ['generated/*']
|
|
||||||
}, {
|
|
||||||
expand: true,
|
|
||||||
dest: '<%= yeoman.dist %>',
|
|
||||||
src: [
|
|
||||||
'package.json',
|
|
||||||
'process.json',
|
|
||||||
'<%= yeoman.server %>/**/*',
|
|
||||||
'!<%= yeoman.server %>/config/local.env.sample.js'
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
expand: true,
|
|
||||||
cwd: '<%= yeoman.client %>',
|
|
||||||
dest: '.tmp/',
|
|
||||||
src: ['{app,components}/**/*.css']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
buildcontrol: {
|
|
||||||
options: {
|
|
||||||
dir: '<%= yeoman.dist %>',
|
|
||||||
commit: true,
|
|
||||||
push: true,
|
|
||||||
connectCommits: false,
|
|
||||||
message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
|
|
||||||
},
|
|
||||||
heroku: {
|
|
||||||
options: {
|
|
||||||
remote: 'heroku',
|
|
||||||
branch: 'master'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openshift: {
|
|
||||||
options: {
|
|
||||||
remote: 'openshift',
|
|
||||||
branch: 'master'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Run some tasks in parallel to speed up the build process
|
|
||||||
concurrent: {
|
|
||||||
pre:[
|
|
||||||
|
|
||||||
],
|
|
||||||
server: [
|
|
||||||
'newer:babel:client',
|
|
||||||
],
|
|
||||||
test: [
|
|
||||||
'newer:babel:client',
|
|
||||||
],
|
|
||||||
debug: {
|
|
||||||
tasks: [
|
|
||||||
'nodemon',
|
|
||||||
'node-inspector'
|
|
||||||
],
|
|
||||||
options: {
|
|
||||||
logConcurrentOutput: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dist: [
|
|
||||||
'newer:babel:client',
|
|
||||||
'imagemin'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Test settings
|
|
||||||
karma: {
|
|
||||||
unit: {
|
|
||||||
configFile: 'karma.conf.js',
|
|
||||||
singleRun: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mochaTest: {
|
|
||||||
options: {
|
|
||||||
reporter: 'spec',
|
|
||||||
require: 'mocha.conf.js',
|
|
||||||
timeout: 5000 // set default mocha spec timeout
|
|
||||||
},
|
|
||||||
unit: {
|
|
||||||
src: ['<%= yeoman.server %>/**/*.spec.js']
|
|
||||||
},
|
|
||||||
integration: {
|
|
||||||
src: ['<%= yeoman.server %>/**/*.integration.js']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mocha_istanbul: {
|
|
||||||
unit: {
|
|
||||||
options: {
|
|
||||||
excludes: ['**/*.{spec,mock,integration}.js'],
|
|
||||||
reporter: 'spec',
|
|
||||||
require: ['mocha.conf.js'],
|
|
||||||
mask: '**/*.spec.js',
|
|
||||||
coverageFolder: 'coverage/server/unit'
|
|
||||||
},
|
|
||||||
src: '<%= yeoman.server %>'
|
|
||||||
},
|
|
||||||
integration: {
|
|
||||||
options: {
|
|
||||||
excludes: ['**/*.{spec,mock,integration}.js'],
|
|
||||||
reporter: 'spec',
|
|
||||||
require: ['mocha.conf.js'],
|
|
||||||
mask: '**/*.integration.js',
|
|
||||||
coverageFolder: 'coverage/server/integration'
|
|
||||||
},
|
|
||||||
src: '<%= yeoman.server %>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
istanbul_check_coverage: {
|
|
||||||
default: {
|
|
||||||
options: {
|
|
||||||
coverageFolder: 'coverage/**',
|
|
||||||
check: {
|
|
||||||
lines: 80,
|
|
||||||
statements: 80,
|
|
||||||
branches: 80,
|
|
||||||
functions: 80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
protractor: {
|
|
||||||
options: {
|
|
||||||
configFile: 'protractor.conf.js'
|
|
||||||
},
|
|
||||||
chrome: {
|
|
||||||
options: {
|
|
||||||
args: {
|
|
||||||
browser: 'chrome'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
env: {
|
|
||||||
test: {
|
|
||||||
NODE_ENV: 'test'
|
|
||||||
},
|
|
||||||
prod: {
|
|
||||||
NODE_ENV: 'production'
|
|
||||||
},
|
|
||||||
all: localConfig
|
|
||||||
},
|
|
||||||
|
|
||||||
// Compiles ES6 to JavaScript using Babel
|
|
||||||
babel: {
|
|
||||||
options: {
|
|
||||||
sourceMap: true
|
|
||||||
},
|
|
||||||
client: {
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '<%= yeoman.client %>',
|
|
||||||
src: ['{app,components}/**/!(*.spec).js'],
|
|
||||||
dest: '.tmp'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
server: {
|
|
||||||
options: {
|
|
||||||
plugins: [
|
|
||||||
'transform-class-properties',
|
|
||||||
'transform-runtime'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
cwd: '<%= yeoman.server %>',
|
|
||||||
src: [
|
|
||||||
'**/*.js',
|
|
||||||
'!config/local.env.sample.js'
|
|
||||||
],
|
|
||||||
dest: '<%= yeoman.dist %>/<%= yeoman.server %>'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
injector: {
|
|
||||||
options: {},
|
|
||||||
// Inject application script files into index.html (doesn't include bower)
|
|
||||||
scripts: {
|
|
||||||
options: {
|
|
||||||
transform: function(filePath) {
|
|
||||||
var yoClient = grunt.config.get('yeoman.client');
|
|
||||||
filePath = filePath.replace('/' + yoClient + '/', '');
|
|
||||||
filePath = filePath.replace('/.tmp/', '');
|
|
||||||
return '<script src="' + filePath + '"></script>';
|
|
||||||
},
|
|
||||||
sort: function(a, b) {
|
|
||||||
var module = /\.module\.(js|ts)$/;
|
|
||||||
var aMod = module.test(a);
|
|
||||||
var bMod = module.test(b);
|
|
||||||
// inject *.module.js first
|
|
||||||
return (aMod === bMod) ? 0 : (aMod ? -1 : 1);
|
|
||||||
},
|
|
||||||
starttag: '<!-- injector:js -->',
|
|
||||||
endtag: '<!-- endinjector -->'
|
|
||||||
},
|
|
||||||
files: {
|
|
||||||
'<%= yeoman.client %>/index.html': [
|
|
||||||
[
|
|
||||||
'<%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js',
|
|
||||||
'!{.tmp,<%= yeoman.client %>}/app/app.{js,ts}'
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Inject component css into index.html
|
|
||||||
css: {
|
|
||||||
options: {
|
|
||||||
transform: function(filePath) {
|
|
||||||
var yoClient = grunt.config.get('yeoman.client');
|
|
||||||
filePath = filePath.replace('/' + yoClient + '/', '');
|
|
||||||
filePath = filePath.replace('/.tmp/', '');
|
|
||||||
return '<link rel="stylesheet" href="' + filePath + '">';
|
|
||||||
},
|
|
||||||
starttag: '<!-- injector:css -->',
|
|
||||||
endtag: '<!-- endinjector -->'
|
|
||||||
},
|
|
||||||
files: {
|
|
||||||
'<%= yeoman.client %>/index.html': [
|
|
||||||
'<%= yeoman.client %>/{app,components}/**/*.css'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Used for delaying livereload until after server has restarted
|
|
||||||
grunt.registerTask('wait', function () {
|
|
||||||
grunt.log.ok('Waiting for server reload...');
|
|
||||||
|
|
||||||
var done = this.async();
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
grunt.log.writeln('Done waiting!');
|
|
||||||
done();
|
|
||||||
}, 1500);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('express-keepalive', 'Keep grunt running', function() {
|
|
||||||
this.async();
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('serve', function (target) {
|
|
||||||
|
|
||||||
if (target === 'dist') {
|
|
||||||
return grunt.task.run(['build:production', 'env:all', 'env:prod', 'express:prod', 'wait', 'open', 'express-keepalive']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target === 'debug') {
|
|
||||||
return grunt.task.run([
|
|
||||||
// 'clean:server',
|
|
||||||
'env:all',
|
|
||||||
'concurrent:pre',
|
|
||||||
'concurrent:server',
|
|
||||||
'injector',
|
|
||||||
'wiredep:client',
|
|
||||||
'postcss',
|
|
||||||
'concurrent:debug'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
grunt.task.run([
|
|
||||||
// 'clean:server',
|
|
||||||
'ngconstant:development',
|
|
||||||
'env:all',
|
|
||||||
'concurrent:pre',
|
|
||||||
'concurrent:server',
|
|
||||||
'injector',
|
|
||||||
'wiredep:client',
|
|
||||||
'postcss',
|
|
||||||
'express:dev',
|
|
||||||
'wait',
|
|
||||||
'open',
|
|
||||||
'watch'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('server', function () {
|
|
||||||
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
|
|
||||||
grunt.task.run(['serve']);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('test', function(target, option) {
|
|
||||||
if (target === 'server') {
|
|
||||||
return grunt.task.run([
|
|
||||||
'env:all',
|
|
||||||
'env:test',
|
|
||||||
'mochaTest:unit',
|
|
||||||
'mochaTest:integration'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (target === 'client') {
|
|
||||||
return grunt.task.run([
|
|
||||||
// 'clean:server',
|
|
||||||
'env:all',
|
|
||||||
'concurrent:pre',
|
|
||||||
'concurrent:test',
|
|
||||||
'injector',
|
|
||||||
'postcss',
|
|
||||||
'wiredep:test',
|
|
||||||
'karma'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (target === 'e2e') {
|
|
||||||
|
|
||||||
if (option === 'prod') {
|
|
||||||
return grunt.task.run([
|
|
||||||
'build:production',
|
|
||||||
'env:all',
|
|
||||||
'env:prod',
|
|
||||||
'express:prod',
|
|
||||||
'protractor'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
return grunt.task.run([
|
|
||||||
// 'clean:server',
|
|
||||||
'env:all',
|
|
||||||
'env:test',
|
|
||||||
'concurrent:pre',
|
|
||||||
'concurrent:test',
|
|
||||||
'injector',
|
|
||||||
'wiredep:client',
|
|
||||||
'postcss',
|
|
||||||
'express:dev',
|
|
||||||
'protractor'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (target === 'coverage') {
|
|
||||||
|
|
||||||
if (option === 'unit') {
|
|
||||||
return grunt.task.run([
|
|
||||||
'env:all',
|
|
||||||
'env:test',
|
|
||||||
'mocha_istanbul:unit'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (option === 'integration') {
|
|
||||||
return grunt.task.run([
|
|
||||||
'env:all',
|
|
||||||
'env:test',
|
|
||||||
'mocha_istanbul:integration'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (option === 'check') {
|
|
||||||
return grunt.task.run([
|
|
||||||
'istanbul_check_coverage'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
return grunt.task.run([
|
|
||||||
'env:all',
|
|
||||||
'env:test',
|
|
||||||
'mocha_istanbul',
|
|
||||||
'istanbul_check_coverage'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else grunt.task.run([
|
|
||||||
'test:server',
|
|
||||||
'test:client'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('build', function (target) {
|
|
||||||
|
|
||||||
if(typeof(target) == 'undefined')
|
|
||||||
target = 'development';
|
|
||||||
|
|
||||||
var tasks = [
|
|
||||||
'clean:dist',
|
|
||||||
'ngconstant:'+target,
|
|
||||||
'concurrent:pre',
|
|
||||||
'concurrent:dist',
|
|
||||||
'injector',
|
|
||||||
'wiredep:client',
|
|
||||||
'useminPrepare',
|
|
||||||
'postcss',
|
|
||||||
'ngtemplates',
|
|
||||||
'concat',
|
|
||||||
'ngAnnotate',
|
|
||||||
'copy:dist',
|
|
||||||
'babel:server',
|
|
||||||
'cdnify',
|
|
||||||
'cssmin',
|
|
||||||
'uglify',
|
|
||||||
'filerev',
|
|
||||||
'usemin'
|
|
||||||
]
|
|
||||||
|
|
||||||
return grunt.task.run(tasks);
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('default', [
|
|
||||||
'newer:jshint',
|
|
||||||
'test',
|
|
||||||
'build'
|
|
||||||
]);
|
|
||||||
};
|
|
|
@ -1,31 +0,0 @@
|
||||||
# dashboard-project
|
|
||||||
|
|
||||||
This project was generated with the [Angular Full-Stack Generator](https://github.com/DaftMonk/generator-angular-fullstack) version 3.5.0.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- [Git](https://git-scm.com/)
|
|
||||||
- [Node.js and npm](nodejs.org) Node ^4.2.3, npm ^2.14.7
|
|
||||||
- [Bower](bower.io) (`npm install --global bower`)
|
|
||||||
- [Grunt](http://gruntjs.com/) (`npm install --global grunt-cli`)
|
|
||||||
- [MongoDB](https://www.mongodb.org/) - Keep a running daemon with `mongod`
|
|
||||||
|
|
||||||
### Developing
|
|
||||||
|
|
||||||
1. Run `npm install` to install server dependencies.
|
|
||||||
|
|
||||||
2. Run `bower install` to install front-end dependencies.
|
|
||||||
|
|
||||||
3. Run `mongod` in a separate shell to keep an instance of the MongoDB Daemon running
|
|
||||||
|
|
||||||
4. Run `grunt serve` to start the development server. It should automatically open the client in your browser when ready.
|
|
||||||
|
|
||||||
## Build & development
|
|
||||||
|
|
||||||
Run `grunt build` for building and `grunt serve` for preview.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
Running `npm test` will run the unit tests with karma.
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"name": "dashboard-project",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"dependencies": {
|
|
||||||
"angular": "~1.5.0",
|
|
||||||
"json3": "~3.3.1",
|
|
||||||
"es5-shim": "~3.0.1",
|
|
||||||
"bootstrap": "~3.1.1",
|
|
||||||
"angular-resource": "~1.5.0",
|
|
||||||
"angular-cookies": "~1.5.0",
|
|
||||||
"angular-sanitize": "~1.5.0",
|
|
||||||
"angular-bootstrap": "~1.1.2",
|
|
||||||
"font-awesome": ">=4.1.0",
|
|
||||||
"lodash": "~2.4.1",
|
|
||||||
"angular-ui-router": "~0.2.15",
|
|
||||||
"bootstrap-table": "^1.10.1",
|
|
||||||
"moment": "^2.13.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"angular-mocks": "~1.5.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir client/components/sdk
|
|
||||||
cp ../dashboard-project-api/js/lbServices.js client/components/sdk/
|
|
||||||
grunt serve
|
|
|
@ -1,543 +0,0 @@
|
||||||
# Apache Configuration File
|
|
||||||
|
|
||||||
# (!) Using `.htaccess` files slows down Apache, therefore, if you have access
|
|
||||||
# to the main server config file (usually called `httpd.conf`), you should add
|
|
||||||
# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html.
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # CROSS-ORIGIN RESOURCE SHARING (CORS) #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Cross-domain AJAX requests |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Enable cross-origin AJAX requests.
|
|
||||||
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
|
|
||||||
# http://enable-cors.org/
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set Access-Control-Allow-Origin "*"
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | CORS-enabled images |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Send the CORS header for images when browsers request it.
|
|
||||||
# https://developer.mozilla.org/en/CORS_Enabled_Image
|
|
||||||
# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
|
|
||||||
# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
|
|
||||||
|
|
||||||
<IfModule mod_setenvif.c>
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
<FilesMatch "\.(gif|ico|jpe?g|png|svg|svgz|webp)$">
|
|
||||||
SetEnvIf Origin ":" IS_CORS
|
|
||||||
Header set Access-Control-Allow-Origin "*" env=IS_CORS
|
|
||||||
</FilesMatch>
|
|
||||||
</IfModule>
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Web fonts access |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Allow access from all domains for web fonts
|
|
||||||
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
<FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
|
|
||||||
Header set Access-Control-Allow-Origin "*"
|
|
||||||
</FilesMatch>
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # ERRORS #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | 404 error prevention for non-existing redirected folders |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Prevent Apache from returning a 404 error for a rewrite if a directory
|
|
||||||
# with the same name does not exist.
|
|
||||||
# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews
|
|
||||||
# http://www.webmasterworld.com/apache/3808792.htm
|
|
||||||
|
|
||||||
Options -MultiViews
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Custom error messages / pages |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# You can customize what Apache returns to the client in case of an error (see
|
|
||||||
# http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.:
|
|
||||||
|
|
||||||
ErrorDocument 404 /404.html
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # INTERNET EXPLORER #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Better website experience |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Force IE to render pages in the highest available mode in the various
|
|
||||||
# cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf.
|
|
||||||
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
Header set X-UA-Compatible "IE=edge"
|
|
||||||
# `mod_headers` can't match based on the content-type, however, we only
|
|
||||||
# want to send this header for HTML pages and not for the other resources
|
|
||||||
<FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
|
|
||||||
Header unset X-UA-Compatible
|
|
||||||
</FilesMatch>
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Cookie setting from iframes |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Allow cookies to be set from iframes in IE.
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Screen flicker |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Stop screen flicker in IE on CSS rollovers (this only works in
|
|
||||||
# combination with the `ExpiresByType` directives for images from below).
|
|
||||||
|
|
||||||
# BrowserMatch "MSIE" brokenvary=1
|
|
||||||
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
|
|
||||||
# BrowserMatch "Opera" !brokenvary
|
|
||||||
# SetEnvIf brokenvary 1 force-no-vary
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # MIME TYPES AND ENCODING #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Proper MIME types for all files |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
<IfModule mod_mime.c>
|
|
||||||
|
|
||||||
# Audio
|
|
||||||
AddType audio/mp4 m4a f4a f4b
|
|
||||||
AddType audio/ogg oga ogg
|
|
||||||
|
|
||||||
# JavaScript
|
|
||||||
# Normalize to standard type (it's sniffed in IE anyways):
|
|
||||||
# http://tools.ietf.org/html/rfc4329#section-7.2
|
|
||||||
AddType application/javascript js jsonp
|
|
||||||
AddType application/json json
|
|
||||||
|
|
||||||
# Video
|
|
||||||
AddType video/mp4 mp4 m4v f4v f4p
|
|
||||||
AddType video/ogg ogv
|
|
||||||
AddType video/webm webm
|
|
||||||
AddType video/x-flv flv
|
|
||||||
|
|
||||||
# Web fonts
|
|
||||||
AddType application/font-woff woff
|
|
||||||
AddType application/vnd.ms-fontobject eot
|
|
||||||
|
|
||||||
# Browsers usually ignore the font MIME types and sniff the content,
|
|
||||||
# however, Chrome shows a warning if other MIME types are used for the
|
|
||||||
# following fonts.
|
|
||||||
AddType application/x-font-ttf ttc ttf
|
|
||||||
AddType font/opentype otf
|
|
||||||
|
|
||||||
# Make SVGZ fonts work on iPad:
|
|
||||||
# https://twitter.com/FontSquirrel/status/14855840545
|
|
||||||
AddType image/svg+xml svg svgz
|
|
||||||
AddEncoding gzip svgz
|
|
||||||
|
|
||||||
# Other
|
|
||||||
AddType application/octet-stream safariextz
|
|
||||||
AddType application/x-chrome-extension crx
|
|
||||||
AddType application/x-opera-extension oex
|
|
||||||
AddType application/x-shockwave-flash swf
|
|
||||||
AddType application/x-web-app-manifest+json webapp
|
|
||||||
AddType application/x-xpinstall xpi
|
|
||||||
AddType application/xml atom rdf rss xml
|
|
||||||
AddType image/webp webp
|
|
||||||
AddType image/x-icon ico
|
|
||||||
AddType text/cache-manifest appcache manifest
|
|
||||||
AddType text/vtt vtt
|
|
||||||
AddType text/x-component htc
|
|
||||||
AddType text/x-vcard vcf
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | UTF-8 encoding |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
|
|
||||||
AddDefaultCharset utf-8
|
|
||||||
|
|
||||||
# Force UTF-8 for certain file formats.
|
|
||||||
<IfModule mod_mime.c>
|
|
||||||
AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # URL REWRITES #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Rewrite engine |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Turning on the rewrite engine and enabling the `FollowSymLinks` option is
|
|
||||||
# necessary for the following directives to work.
|
|
||||||
|
|
||||||
# If your web host doesn't allow the `FollowSymlinks` option, you may need to
|
|
||||||
# comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the
|
|
||||||
# performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks
|
|
||||||
|
|
||||||
# Also, some cloud hosting services require `RewriteBase` to be set:
|
|
||||||
# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site
|
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
Options +FollowSymlinks
|
|
||||||
# Options +SymLinksIfOwnerMatch
|
|
||||||
RewriteEngine On
|
|
||||||
# RewriteBase /
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Suppressing / Forcing the "www." at the beginning of URLs |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The same content should never be available under two different URLs especially
|
|
||||||
# not with and without "www." at the beginning. This can cause SEO problems
|
|
||||||
# (duplicate content), therefore, you should choose one of the alternatives and
|
|
||||||
# redirect the other one.
|
|
||||||
|
|
||||||
# By default option 1 (no "www.") is activated:
|
|
||||||
# http://no-www.org/faq.php?q=class_b
|
|
||||||
|
|
||||||
# If you'd prefer to use option 2, just comment out all the lines from option 1
|
|
||||||
# and uncomment the ones from option 2.
|
|
||||||
|
|
||||||
# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Option 1: rewrite www.example.com → example.com
|
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
RewriteCond %{HTTPS} !=on
|
|
||||||
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
|
|
||||||
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Option 2: rewrite example.com → www.example.com
|
|
||||||
|
|
||||||
# Be aware that the following might not be a good idea if you use "real"
|
|
||||||
# subdomains for certain parts of your website.
|
|
||||||
|
|
||||||
# <IfModule mod_rewrite.c>
|
|
||||||
# RewriteCond %{HTTPS} !=on
|
|
||||||
# RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
|
|
||||||
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # SECURITY #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Content Security Policy (CSP) |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# You can mitigate the risk of cross-site scripting and other content-injection
|
|
||||||
# attacks by setting a Content Security Policy which whitelists trusted sources
|
|
||||||
# of content for your site.
|
|
||||||
|
|
||||||
# The example header below allows ONLY scripts that are loaded from the current
|
|
||||||
# site's origin (no inline scripts, no CDN, etc). This almost certainly won't
|
|
||||||
# work as-is for your site!
|
|
||||||
|
|
||||||
# To get all the details you'll need to craft a reasonable policy for your site,
|
|
||||||
# read: http://html5rocks.com/en/tutorials/security/content-security-policy (or
|
|
||||||
# see the specification: http://w3.org/TR/CSP).
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
|
|
||||||
# <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
|
|
||||||
# Header unset Content-Security-Policy
|
|
||||||
# </FilesMatch>
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | File access |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Block access to directories without a default document.
|
|
||||||
# Usually you should leave this uncommented because you shouldn't allow anyone
|
|
||||||
# to surf through every directory on your server (which may includes rather
|
|
||||||
# private places like the CMS's directories).
|
|
||||||
|
|
||||||
<IfModule mod_autoindex.c>
|
|
||||||
Options -Indexes
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Block access to hidden files and directories.
|
|
||||||
# This includes directories used by version control systems such as Git and SVN.
|
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
RewriteCond %{SCRIPT_FILENAME} -d [OR]
|
|
||||||
RewriteCond %{SCRIPT_FILENAME} -f
|
|
||||||
RewriteRule "(^|/)\." - [F]
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Block access to backup and source files.
|
|
||||||
# These files may be left by some text editors and can pose a great security
|
|
||||||
# danger when anyone has access to them.
|
|
||||||
|
|
||||||
<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
|
|
||||||
Order allow,deny
|
|
||||||
Deny from all
|
|
||||||
Satisfy All
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Secure Sockets Layer (SSL) |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Rewrite secure requests properly to prevent SSL certificate warnings, e.g.:
|
|
||||||
# prevent `https://www.example.com` when your certificate only allows
|
|
||||||
# `https://secure.example.com`.
|
|
||||||
|
|
||||||
# <IfModule mod_rewrite.c>
|
|
||||||
# RewriteCond %{SERVER_PORT} !^443
|
|
||||||
# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L]
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Force client-side SSL redirection.
|
|
||||||
|
|
||||||
# If a user types "example.com" in his browser, the above rule will redirect him
|
|
||||||
# to the secure version of the site. That still leaves a window of opportunity
|
|
||||||
# (the initial HTTP connection) for an attacker to downgrade or redirect the
|
|
||||||
# request. The following header ensures that browser will ONLY connect to your
|
|
||||||
# server via HTTPS, regardless of what the users type in the address bar.
|
|
||||||
# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set Strict-Transport-Security max-age=16070400;
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Server software information |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Avoid displaying the exact Apache version number, the description of the
|
|
||||||
# generic OS-type and the information about Apache's compiled-in modules.
|
|
||||||
|
|
||||||
# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`!
|
|
||||||
|
|
||||||
# ServerTokens Prod
|
|
||||||
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# # WEB PERFORMANCE #
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Compression |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
<IfModule mod_deflate.c>
|
|
||||||
|
|
||||||
# Force compression for mangled headers.
|
|
||||||
# http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
|
|
||||||
<IfModule mod_setenvif.c>
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
|
|
||||||
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
|
|
||||||
</IfModule>
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# Compress all output labeled with one of the following MIME-types
|
|
||||||
# (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
|
|
||||||
# and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
|
|
||||||
# as `AddOutputFilterByType` is still in the core directives).
|
|
||||||
<IfModule mod_filter.c>
|
|
||||||
AddOutputFilterByType DEFLATE application/atom+xml \
|
|
||||||
application/javascript \
|
|
||||||
application/json \
|
|
||||||
application/rss+xml \
|
|
||||||
application/vnd.ms-fontobject \
|
|
||||||
application/x-font-ttf \
|
|
||||||
application/x-web-app-manifest+json \
|
|
||||||
application/xhtml+xml \
|
|
||||||
application/xml \
|
|
||||||
font/opentype \
|
|
||||||
image/svg+xml \
|
|
||||||
image/x-icon \
|
|
||||||
text/css \
|
|
||||||
text/html \
|
|
||||||
text/plain \
|
|
||||||
text/x-component \
|
|
||||||
text/xml
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Content transformations |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Prevent some of the mobile network providers from modifying the content of
|
|
||||||
# your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5.
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set Cache-Control "no-transform"
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | ETag removal |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Since we're sending far-future expires headers (see below), ETags can
|
|
||||||
# be removed: http://developer.yahoo.com/performance/rules.html#etags.
|
|
||||||
|
|
||||||
# `FileETag None` is not enough for every server.
|
|
||||||
<IfModule mod_headers.c>
|
|
||||||
Header unset ETag
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
FileETag None
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Expires headers (for better cache control) |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The following expires headers are set pretty far in the future. If you don't
|
|
||||||
# control versioning with filename-based cache busting, consider lowering the
|
|
||||||
# cache time for resources like CSS and JS to something like 1 week.
|
|
||||||
|
|
||||||
<IfModule mod_expires.c>
|
|
||||||
|
|
||||||
ExpiresActive on
|
|
||||||
ExpiresDefault "access plus 1 month"
|
|
||||||
|
|
||||||
# CSS
|
|
||||||
ExpiresByType text/css "access plus 1 year"
|
|
||||||
|
|
||||||
# Data interchange
|
|
||||||
ExpiresByType application/json "access plus 0 seconds"
|
|
||||||
ExpiresByType application/xml "access plus 0 seconds"
|
|
||||||
ExpiresByType text/xml "access plus 0 seconds"
|
|
||||||
|
|
||||||
# Favicon (cannot be renamed!)
|
|
||||||
ExpiresByType image/x-icon "access plus 1 week"
|
|
||||||
|
|
||||||
# HTML components (HTCs)
|
|
||||||
ExpiresByType text/x-component "access plus 1 month"
|
|
||||||
|
|
||||||
# HTML
|
|
||||||
ExpiresByType text/html "access plus 0 seconds"
|
|
||||||
|
|
||||||
# JavaScript
|
|
||||||
ExpiresByType application/javascript "access plus 1 year"
|
|
||||||
|
|
||||||
# Manifest files
|
|
||||||
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
|
|
||||||
ExpiresByType text/cache-manifest "access plus 0 seconds"
|
|
||||||
|
|
||||||
# Media
|
|
||||||
ExpiresByType audio/ogg "access plus 1 month"
|
|
||||||
ExpiresByType image/gif "access plus 1 month"
|
|
||||||
ExpiresByType image/jpeg "access plus 1 month"
|
|
||||||
ExpiresByType image/png "access plus 1 month"
|
|
||||||
ExpiresByType video/mp4 "access plus 1 month"
|
|
||||||
ExpiresByType video/ogg "access plus 1 month"
|
|
||||||
ExpiresByType video/webm "access plus 1 month"
|
|
||||||
|
|
||||||
# Web feeds
|
|
||||||
ExpiresByType application/atom+xml "access plus 1 hour"
|
|
||||||
ExpiresByType application/rss+xml "access plus 1 hour"
|
|
||||||
|
|
||||||
# Web fonts
|
|
||||||
ExpiresByType application/font-woff "access plus 1 month"
|
|
||||||
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
|
|
||||||
ExpiresByType application/x-font-ttf "access plus 1 month"
|
|
||||||
ExpiresByType font/opentype "access plus 1 month"
|
|
||||||
ExpiresByType image/svg+xml "access plus 1 month"
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Filename-based cache busting |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# If you're not using a build process to manage your filename version revving,
|
|
||||||
# you might want to consider enabling the following directives to route all
|
|
||||||
# requests such as `/css/style.12345.css` to `/css/style.css`.
|
|
||||||
|
|
||||||
# To understand why this is important and a better idea than `*.css?v231`, read:
|
|
||||||
# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring
|
|
||||||
|
|
||||||
# <IfModule mod_rewrite.c>
|
|
||||||
# RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
# RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | File concatenation |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Allow concatenation from within specific CSS and JS files, e.g.:
|
|
||||||
# Inside of `script.combined.js` you could have
|
|
||||||
# <!--#include file="libs/jquery.js" -->
|
|
||||||
# <!--#include file="plugins/jquery.idletimer.js" -->
|
|
||||||
# and they would be included into this single file.
|
|
||||||
|
|
||||||
# <IfModule mod_include.c>
|
|
||||||
# <FilesMatch "\.combined\.js$">
|
|
||||||
# Options +Includes
|
|
||||||
# AddOutputFilterByType INCLUDES application/javascript application/json
|
|
||||||
# SetOutputFilter INCLUDES
|
|
||||||
# </FilesMatch>
|
|
||||||
# <FilesMatch "\.combined\.css$">
|
|
||||||
# Options +Includes
|
|
||||||
# AddOutputFilterByType INCLUDES text/css
|
|
||||||
# SetOutputFilter INCLUDES
|
|
||||||
# </FilesMatch>
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# | Persistent connections |
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Allow multiple requests to be sent over the same TCP connection:
|
|
||||||
# http://httpd.apache.org/docs/current/en/mod/core.html#keepalive.
|
|
||||||
|
|
||||||
# Enable if you serve a lot of static content but, be aware of the
|
|
||||||
# possible disadvantages!
|
|
||||||
|
|
||||||
# <IfModule mod_headers.c>
|
|
||||||
# Header set Connection Keep-Alive
|
|
||||||
# </IfModule>
|
|
|
@ -1,39 +0,0 @@
|
||||||
{
|
|
||||||
"node": true,
|
|
||||||
"browser": true,
|
|
||||||
"esnext": true,
|
|
||||||
"bitwise": true,
|
|
||||||
"camelcase": true,
|
|
||||||
"curly": true,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"immed": true,
|
|
||||||
"latedef": true,
|
|
||||||
"newcap": true,
|
|
||||||
"noarg": true,
|
|
||||||
"quotmark": "single",
|
|
||||||
"undef": true,
|
|
||||||
"unused": true,
|
|
||||||
"strict": true,
|
|
||||||
"trailing": true,
|
|
||||||
"smarttabs": true,
|
|
||||||
"ignoreDelimiters": [
|
|
||||||
{ "start": "start-non-standard", "end": "end-non-standard" }
|
|
||||||
],
|
|
||||||
"globals": {
|
|
||||||
"jQuery": true,
|
|
||||||
"angular": true,
|
|
||||||
"console": true,
|
|
||||||
"$": true,
|
|
||||||
"_": true,
|
|
||||||
"moment": true,
|
|
||||||
"describe": true,
|
|
||||||
"beforeEach": true,
|
|
||||||
"module": true,
|
|
||||||
"inject": true,
|
|
||||||
"it": true,
|
|
||||||
"expect": true,
|
|
||||||
"browser": true,
|
|
||||||
"element": true,
|
|
||||||
"by": true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
(function(angular, undefined) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp.constants', [])
|
|
||||||
|
|
||||||
.constant('appConfig', {userRoles:['guest','user','admin'],apiBaseUrl:'http://local.userstory.openstack.org/api'})
|
|
||||||
|
|
||||||
;
|
|
||||||
})(angular);
|
|
|
@ -1,135 +0,0 @@
|
||||||
|
|
||||||
/**
|
|
||||||
* Bootstrap Fonts
|
|
||||||
*/
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Glyphicons Halflings';
|
|
||||||
src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot');
|
|
||||||
src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
|
|
||||||
url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
|
|
||||||
url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*Font Awesome Fonts
|
|
||||||
*/
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'FontAwesome';
|
|
||||||
src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.1.0');
|
|
||||||
src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),
|
|
||||||
url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),
|
|
||||||
url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),
|
|
||||||
url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General font
|
|
||||||
**/
|
|
||||||
@font-face {
|
|
||||||
font-family:'OpenSans-Regular';
|
|
||||||
src: url('../assets/fonts/open-sans/OpenSans-Regular.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family:'OpenSans-Bold';
|
|
||||||
src: url('../assets/fonts/open-sans/OpenSans-Bold.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family:'OpenSans-Light';
|
|
||||||
src: url('../assets/fonts/open-sans/OpenSans-Light.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* App-wide Styles
|
|
||||||
*/
|
|
||||||
|
|
||||||
.browserupgrade {
|
|
||||||
margin: 0.2em 0;
|
|
||||||
background: #ccc;
|
|
||||||
color: #000;
|
|
||||||
padding: 0.2em 0;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family:"OpenSans-Regular", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
padding-left: 0px;
|
|
||||||
border-bottom: 2px solid #e1e1e1;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-family: "OpenSans-Bold", Helvetica, Arial, sans-serif;
|
|
||||||
color: #2A4E68;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-title {
|
|
||||||
font-family: "OpenSans-Bold", Helvetica, Arial, sans-serif;
|
|
||||||
color: #2A4E68;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
.dp-label{
|
|
||||||
font-size: 12px;
|
|
||||||
top: -5px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-label-completed{
|
|
||||||
background-color: #58B957;
|
|
||||||
}
|
|
||||||
.dp-label-in-progress{
|
|
||||||
background-color: #0D5B9D;
|
|
||||||
}
|
|
||||||
.dp-label-none{
|
|
||||||
background-color: #999999;
|
|
||||||
}
|
|
||||||
.dp-label-pending{
|
|
||||||
background-color: #EFAC43;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-link-title {
|
|
||||||
color:#2E729A;
|
|
||||||
}
|
|
||||||
.dp-link-title:hover {
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-margin-top{
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.dp-hr{
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-subtitle{
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus{
|
|
||||||
background-color: #0D5B9D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar .sr-only{
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar[aria-valuenow="0"] {
|
|
||||||
color: #000;
|
|
||||||
min-width: 100%;
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compress-text{
|
|
||||||
max-height: 63px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uncompress-text{
|
|
||||||
max-height: none !important;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp', [
|
|
||||||
'dashboardProjectApp.constants',
|
|
||||||
'ngCookies',
|
|
||||||
'ngResource',
|
|
||||||
'ngSanitize',
|
|
||||||
'ui.router',
|
|
||||||
'ui.bootstrap',
|
|
||||||
'lbServices'
|
|
||||||
])
|
|
||||||
.config(function($urlRouterProvider, $locationProvider, LoopBackResourceProvider, appConfig) {
|
|
||||||
LoopBackResourceProvider.setUrlBase(appConfig.apiBaseUrl);
|
|
||||||
//$urlRouterProvider.otherwise('/');
|
|
||||||
|
|
||||||
$locationProvider.html5Mode(true);
|
|
||||||
})
|
|
||||||
.run(function($rootScope, $state) {
|
|
||||||
$state.go("projectList")
|
|
||||||
});
|
|
|
@ -1,113 +0,0 @@
|
||||||
'use strict';
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.controller('projectDetailController', ['$scope','$state', 'UserStory', '$location',
|
|
||||||
function($scope, $state, UserStory, $location) {
|
|
||||||
|
|
||||||
$scope.taskId = $state.params.id;
|
|
||||||
$scope.openTasks = {};
|
|
||||||
$scope.showText = {}
|
|
||||||
|
|
||||||
$scope.closeTask = function(task){
|
|
||||||
$scope.openTasks[task] = !$scope.openTasks[task];
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.getProjectIcon = function(key){
|
|
||||||
|
|
||||||
if(key == 'nova')
|
|
||||||
return 'fa fa-cogs';
|
|
||||||
|
|
||||||
if(key == 'cinder')
|
|
||||||
return 'fa fa-archive'
|
|
||||||
|
|
||||||
if(key == 'keystone')
|
|
||||||
return 'fa fa-key';
|
|
||||||
|
|
||||||
if(key == 'swift')
|
|
||||||
return 'fa fa-object-group';
|
|
||||||
|
|
||||||
if(key == 'neutron')
|
|
||||||
return 'fa fa-cloud-upload';
|
|
||||||
|
|
||||||
if(key == 'glance')
|
|
||||||
return 'fa fa-key';
|
|
||||||
|
|
||||||
return 'fa fa-cog';
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.actualProject = {};
|
|
||||||
|
|
||||||
function getFile() {
|
|
||||||
UserStory.findById({id:$scope.taskId},
|
|
||||||
function success(userStory) {
|
|
||||||
$scope.userStory = userStory;
|
|
||||||
|
|
||||||
// Formating User Story name
|
|
||||||
if ((userStory.description).length > 100) {
|
|
||||||
$scope.userStory.shortDescription = userStory.
|
|
||||||
description.substr(0,50) + " ...";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$scope.userStory.shortDescription = userStory.
|
|
||||||
description;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.userStory.createdOn = moment($scope.userStory.
|
|
||||||
createdOn, "DD-MM-YYYY").format("MM-DD-YYYY");
|
|
||||||
|
|
||||||
if($scope.userStory.updatedOn !=='') {
|
|
||||||
$scope.userStory.updatedOn = moment($scope.userStory.
|
|
||||||
updatedOn, "YYYY-MM-DD").format("MM-DD-YYYY");
|
|
||||||
} else {
|
|
||||||
$scope.userStory.updatedOn = $scope.userStory.createdOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var key in $scope.userStory.tasks_status) {
|
|
||||||
$scope.actualProject[key] = $scope.userStory.
|
|
||||||
tasks_status[key].projects[0]
|
|
||||||
}
|
|
||||||
}, function onError(){
|
|
||||||
$location.path('/projectDetail/notFound/' + $scope.taskId);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.selectProject = function(keyProject, idTask){
|
|
||||||
$scope.actualProject[idTask] = keyProject
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$scope.showMore = function(key){
|
|
||||||
$scope.showText[key] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.showLess = function(key){
|
|
||||||
$scope.showText[key] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.mailTo = function(user, email){
|
|
||||||
window.location.href = "mailto:" + email + "?subject=Mail to " + email;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFile();
|
|
||||||
|
|
||||||
}])
|
|
||||||
.filter('capitalize', function() {
|
|
||||||
return function(input) {
|
|
||||||
return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).
|
|
||||||
toLowerCase() : '';
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter('removeDashes', function() {
|
|
||||||
return function(string) {
|
|
||||||
|
|
||||||
if (!angular.isString(string)) {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.replace(/-/g, ' ');
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,25 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.config(function ($stateProvider, $urlRouterProvider) {
|
|
||||||
|
|
||||||
|
|
||||||
$stateProvider
|
|
||||||
|
|
||||||
.state('error', {
|
|
||||||
url: '/projectDetail/notFound/:id',
|
|
||||||
templateUrl: 'app/projectDetail/views/notFound.html',
|
|
||||||
controller: function($scope, $state){
|
|
||||||
$scope.id = $state.params.id;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
.state('projectDetail', {
|
|
||||||
url: '/projectDetail/:id',
|
|
||||||
templateUrl: 'app/projectDetail/views/projectDetail.html',
|
|
||||||
controller: 'projectDetailController'
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,18 +0,0 @@
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.service('UserStoryService', ['$http','UserStory', function($http, UserStory) {
|
|
||||||
|
|
||||||
this.searchTask = function(query) {
|
|
||||||
//return $http.get('/tasks/search/' + query);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getUserStory = function getFiles() {
|
|
||||||
|
|
||||||
console.log('aaaaaaa')
|
|
||||||
return UserStory.findById({id:$scope.taskId});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getTask = function(name) {
|
|
||||||
//return $http.get('/tasks/' + name);
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
}]);
|
|
|
@ -1,70 +0,0 @@
|
||||||
|
|
||||||
.frm-well{
|
|
||||||
border: 0px;
|
|
||||||
border-radius: 0px;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tasks{
|
|
||||||
background-color: #EDF2F7;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-resume{
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress{
|
|
||||||
background-color: #DEDEDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dp-panel{
|
|
||||||
border-top: 6px solid #DA6359;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-open-icon{
|
|
||||||
font-size: 30px;
|
|
||||||
top: 4px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
-ms-transform: rotate(-90deg);
|
|
||||||
-webkit-transform: rotate(-90deg);
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-open-icon.down{
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
describe('Component: ProjectDetailComponent', function () {
|
|
||||||
|
|
||||||
// load the controller's module
|
|
||||||
beforeEach(module('dashboardProjectApp'));
|
|
||||||
|
|
||||||
var ProjectDetailComponent, scope;
|
|
||||||
|
|
||||||
// Initialize the controller and a mock scope
|
|
||||||
beforeEach(inject(function ($componentController, $rootScope) {
|
|
||||||
scope = $rootScope.$new();
|
|
||||||
$componentController('ProjectDetailComponent', {
|
|
||||||
$scope: scope
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should ...', function () {
|
|
||||||
expect(1).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,18 +0,0 @@
|
||||||
<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>
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<div class="views-details">
|
|
||||||
<div ng-include="'/app/projectDetail/views/quickResume.html'"></div>
|
|
||||||
<div class="tasks container-fluid">
|
|
||||||
<div class="container">
|
|
||||||
<div ng-repeat="(key, task) in userStory.tasks_status"
|
|
||||||
ng-include="'/app/projectDetail/views/task.html'"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
<div class="quick-resume">
|
|
||||||
<div class="container">
|
|
||||||
<div class="well frm-well">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-11">
|
|
||||||
<div class="dp-title" data-toggle="tooltip" title="{{userStory.description}}">
|
|
||||||
{{userStory.shortDescription}}
|
|
||||||
<span class="dp-label label label-primary dp-label-{{userStory.status}}">
|
|
||||||
{{userStory.status | removeDashes | capitalize}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-1">
|
|
||||||
<div class="pull-right">
|
|
||||||
<strong> ID: {{userStory.id}}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<a ng-href="{{userStory.showDetailedUri}}"
|
|
||||||
target="_blank"
|
|
||||||
class="dp-link-title">
|
|
||||||
<i class="fa fa-external-link"></i>
|
|
||||||
Show detailed user history
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row add-margin-top">
|
|
||||||
<div class="col-xs-3">
|
|
||||||
<i class="fa fa-user" aria-hidden="true"></i>
|
|
||||||
<strong>Submitted by</strong>
|
|
||||||
<a href ng-click="mailTo(userStory.submitted_by.email)">
|
|
||||||
{{userStory.submitted_by.name}}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-3">
|
|
||||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
|
||||||
<strong> Created on</strong> {{userStory.createdOn}}
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-3">
|
|
||||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
|
||||||
<strong>Updated on</strong> {{userStory.updatedOn}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row add-margin-top">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="progress">
|
|
||||||
<div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar"
|
|
||||||
aria-valuenow="{{userStory.completed.percentage}}" aria-valuemin="0" aria-valuemax="100" style="width: {{userStory.completed.percentage}}%">
|
|
||||||
<span class="sr-only">{{userStory.completed.completed}} / {{userStory.completed.total}} Blueprints completed</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,139 +0,0 @@
|
||||||
<div class="panel dp-panel">
|
|
||||||
<div class="panel-body">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="dp-title">
|
|
||||||
<h4>
|
|
||||||
<i class="fa fa-sort-desc task-open-icon"
|
|
||||||
ng-class="{'down': openTasks[key]}"
|
|
||||||
ng-click="closeTask(key)" aria-hidden="true"></i>
|
|
||||||
{{key}}
|
|
||||||
<span class="dp-label label label-primary dp-label-{{task.xp_status}}">
|
|
||||||
{{task.xp_status | removeDashes | capitalize}}
|
|
||||||
</span>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<a ng-href="{{task.url}}"
|
|
||||||
target="_blank"
|
|
||||||
class="dp-link-title">
|
|
||||||
<i class="fa fa-external-link"></i>
|
|
||||||
Show detailed task history
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<p class="compress-text"
|
|
||||||
ng-class="{'uncompress-text': showText[key]}">
|
|
||||||
{{task.description}}
|
|
||||||
</p>
|
|
||||||
<a ng-href=""
|
|
||||||
ng-click="showMore(key)"
|
|
||||||
class="dp-link-title"
|
|
||||||
ng-hide="showText[key] || task.description.length < 420">
|
|
||||||
Show More
|
|
||||||
</a>
|
|
||||||
<a ng-href=""
|
|
||||||
ng-click="showLess(key)"
|
|
||||||
class="dp-link-title"
|
|
||||||
ng-show="showText[key]">
|
|
||||||
Show Less
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="dp-hr" ng-show="openTasks[key]">
|
|
||||||
<h5 class="dp-subtitle text-center" ng-show="openTasks[key]">
|
|
||||||
Projects
|
|
||||||
</h5>
|
|
||||||
|
|
||||||
<div class="row" ng-show="openTasks[key]">
|
|
||||||
<div class="col-xs-3">
|
|
||||||
<ul class="dp-nav-pills nav nav-pills nav-stacked">
|
|
||||||
<li role="{{actualProject.key}}"
|
|
||||||
ng-repeat="(keyProject, project) in task.projects_status"
|
|
||||||
ng-class="{'active': actualProject[key] == keyProject}"
|
|
||||||
ng-click="selectProject(keyProject, key)">
|
|
||||||
<a href="">
|
|
||||||
<i class="{{getProjectIcon(keyProject)}}"
|
|
||||||
aria-hidden="true"></i>
|
|
||||||
{{keyProject | capitalize | capitalize}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-9">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="dp-subtitle">Spec</th>
|
|
||||||
<th class="dp-subtitle">Status</th>
|
|
||||||
<th ></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>{{task.projects_status[actualProject[key]].spec_name | removeDashes | capitalize}}</th>
|
|
||||||
<td>
|
|
||||||
<span class="label label-primary dp-label-{{task.projects_status[actualProject[key]].spec_status}}">
|
|
||||||
{{task.projects_status[actualProject[key]].spec_status | removeDashes | capitalize}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a ng-href="{{task.projects_status[actualProject[key]].spec}}"
|
|
||||||
target="_blank"
|
|
||||||
class="dp-link-title">
|
|
||||||
<i class="fa fa-external-link"></i>
|
|
||||||
Show details
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
<thead>
|
|
||||||
<tr class="separator" />
|
|
||||||
<tr>
|
|
||||||
<th class="dp-subtitle">Blueprints</th>
|
|
||||||
<th class="dp-subtitle">Status</th>
|
|
||||||
<th class="dp-subtitle">Review Links</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr ng-repeat="blueprint in task.projects_status[actualProject[key]].blueprints">
|
|
||||||
<td>
|
|
||||||
<a href="{{blueprint.uri}}" class="dp-link-title" target="_blank">
|
|
||||||
{{blueprint.name | capitalize | capitalize}}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="label label-primary dp-label-{{blueprint.status}}">
|
|
||||||
{{blueprint.status | removeDashes | capitalize}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="review_link in blueprint.review_link">
|
|
||||||
<a ng-href="{{review_link.url}}"
|
|
||||||
class="dp-link-title"
|
|
||||||
target="_blank">
|
|
||||||
<i class="fa fa-external-link"></i>
|
|
||||||
{{review_link.name}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,48 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp').controller('projectListCtrl', function (
|
|
||||||
$scope,
|
|
||||||
UserStory
|
|
||||||
) {
|
|
||||||
var data = [];
|
|
||||||
var lastUpdate;
|
|
||||||
function getFiles() {
|
|
||||||
UserStory.find(
|
|
||||||
function success(userStories) {
|
|
||||||
new Promise(function(resolve) {
|
|
||||||
|
|
||||||
userStories.forEach(function each (story) {
|
|
||||||
|
|
||||||
if(story.lastUpdate !== '') {
|
|
||||||
lastUpdate = moment(story.lastUpdate,
|
|
||||||
"YYYY-MM-DD").format("MM-DD-YYYY");
|
|
||||||
} else {
|
|
||||||
lastUpdate = moment(story.dateCreated,
|
|
||||||
"DD-MM-YYYY").format("MM-DD-YYYY");
|
|
||||||
}
|
|
||||||
data.push(
|
|
||||||
{
|
|
||||||
userStory: story.id+'-'+story.userStory,
|
|
||||||
dateCreated: moment(story.dateCreated,
|
|
||||||
"DD-MM-YYYY").format("MM-DD-YYYY"),
|
|
||||||
lastUpdate: lastUpdate,
|
|
||||||
progressPercentage: story.completed.percentage,
|
|
||||||
progressLabel: story.completed.completed + ' / '
|
|
||||||
+ story.completed.total
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
resolve(data);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function() {
|
|
||||||
$(function () {
|
|
||||||
$('#table').bootstrapTable({
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getFiles();
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp').config(function ($stateProvider) {
|
|
||||||
$stateProvider
|
|
||||||
.state('projectList', {
|
|
||||||
url: '/projectList',
|
|
||||||
templateUrl: 'app/projectList/views/projectList.html',
|
|
||||||
controller: 'projectListCtrl'
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Dashboard project classes "dp"
|
|
||||||
*/
|
|
||||||
.dp-top-alignment {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
.dp-progress {
|
|
||||||
margin-bottom: 0px;
|
|
||||||
background-color: #E6E6E6;
|
|
||||||
}
|
|
||||||
.pagination-detail {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.search {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.fixed-table-container tbody td {
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
.fixed-table-container thead th{
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
.fixed-table-toolbar .bars, .fixed-table-toolbar .search, .fixed-table-toolbar .columns{
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
.fixed-table-container tbody td {
|
|
||||||
max-width:200px; /* Customise it accordingly */
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
describe('Component: ProjectListComponent', function () {
|
|
||||||
|
|
||||||
// load the controller's module
|
|
||||||
beforeEach(module('dashboardProjectApp'));
|
|
||||||
|
|
||||||
var ProjectListComponent, scope;
|
|
||||||
|
|
||||||
// Initialize the controller and a mock scope
|
|
||||||
beforeEach(inject(function ($componentController, $rootScope) {
|
|
||||||
scope = $rootScope.$new();
|
|
||||||
$componentController('ProjectListComponent', {
|
|
||||||
$scope: scope
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should ...', function () {
|
|
||||||
expect(1).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,27 +0,0 @@
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="row dp-top-alignment">
|
|
||||||
<div class="container">
|
|
||||||
<div id="toolbar">
|
|
||||||
<div>
|
|
||||||
<Label class="dp-title">OpenStack Cross-project Dashboard</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<table id="table"
|
|
||||||
data-pagination="true"
|
|
||||||
data-search="true"
|
|
||||||
data-toolbar="#toolbar"
|
|
||||||
data-sort-name="lastUpdate"
|
|
||||||
data-sort-order="desc"
|
|
||||||
data-row-style="rowStyle">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<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="lastUpdate" data-sortable="true">Last Update</th>
|
|
||||||
<th data-field="progressPercentage" label="progressLabel" data-sortable="true" data-formatter="progressBar"> Blueprints Completed</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
|
@ -1,6 +0,0 @@
|
||||||
footer.footer {
|
|
||||||
text-align: center;
|
|
||||||
padding: 30px 0;
|
|
||||||
margin-top: 70px;
|
|
||||||
border-top: 1px solid #E5E5E5;
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.directive('footer', function() {
|
|
||||||
return {
|
|
||||||
templateUrl: 'components/footer/footer.html',
|
|
||||||
restrict: 'E',
|
|
||||||
link: function(scope, element) {
|
|
||||||
element.addClass('footer');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
<div class="container">
|
|
||||||
<p>Angular Fullstack v3.5.0 |
|
|
||||||
<a href="https://twitter.com/tyhenkel">@tyhenkel</a> |
|
|
||||||
<a href="https://github.com/DaftMonk/generator-angular-fullstack/issues?state=open">Issues</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
.modal-primary .modal-header,
|
|
||||||
.modal-info .modal-header,
|
|
||||||
.modal-success .modal-header,
|
|
||||||
.modal-warning .modal-header,
|
|
||||||
.modal-danger .modal-header {
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
}
|
|
||||||
.modal-primary .modal-header {
|
|
||||||
background: #428bca;
|
|
||||||
}
|
|
||||||
.modal-info .modal-header {
|
|
||||||
background: #5bc0de;
|
|
||||||
}
|
|
||||||
.modal-success .modal-header {
|
|
||||||
background: #5cb85c;
|
|
||||||
}
|
|
||||||
.modal-warning .modal-header {
|
|
||||||
background: #f0ad4e;
|
|
||||||
}
|
|
||||||
.modal-danger .modal-header {
|
|
||||||
background: #d9534f;
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
<div class="modal-header">
|
|
||||||
<button ng-if="modal.dismissable" type="button" ng-click="$dismiss()" class="close">×</button>
|
|
||||||
<h4 ng-if="modal.title" ng-bind="modal.title" class="modal-title"></h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p ng-if="modal.text" ng-bind="modal.text"></p>
|
|
||||||
<div ng-if="modal.html" ng-bind-html="modal.html"></div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button ng-repeat="button in modal.buttons" ng-class="button.classes" ng-click="button.click($event)" ng-bind="button.text" class="btn"></button>
|
|
||||||
</div>
|
|
|
@ -1,73 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.factory('Modal', function($rootScope, $uibModal) {
|
|
||||||
/**
|
|
||||||
* Opens a modal
|
|
||||||
* @param {Object} scope - an object to be merged with modal's scope
|
|
||||||
* @param {String} modalClass - (optional) class(es) to be applied to the modal
|
|
||||||
* @return {Object} - the instance $uibModal.open() returns
|
|
||||||
*/
|
|
||||||
function openModal(scope = {}, modalClass = 'modal-default') {
|
|
||||||
var modalScope = $rootScope.$new();
|
|
||||||
|
|
||||||
angular.extend(modalScope, scope);
|
|
||||||
|
|
||||||
return $uibModal.open({
|
|
||||||
templateUrl: 'components/modal/modal.html',
|
|
||||||
windowClass: modalClass,
|
|
||||||
scope: modalScope
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public API here
|
|
||||||
return {
|
|
||||||
|
|
||||||
/* Confirmation modals */
|
|
||||||
confirm: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a function to open a delete confirmation modal (ex. ng-click='myModalFn(name, arg1, arg2...)')
|
|
||||||
* @param {Function} del - callback, ran when delete is confirmed
|
|
||||||
* @return {Function} - the function to open the modal (ex. myModalFn)
|
|
||||||
*/
|
|
||||||
delete(del = angular.noop) {
|
|
||||||
/**
|
|
||||||
* Open a delete confirmation modal
|
|
||||||
* @param {String} name - name or info to show on modal
|
|
||||||
* @param {All} - any additional args are passed straight to del callback
|
|
||||||
*/
|
|
||||||
return function() {
|
|
||||||
var args = Array.prototype.slice.call(arguments),
|
|
||||||
name = args.shift(),
|
|
||||||
deleteModal;
|
|
||||||
|
|
||||||
deleteModal = openModal({
|
|
||||||
modal: {
|
|
||||||
dismissable: true,
|
|
||||||
title: 'Confirm Delete',
|
|
||||||
html: '<p>Are you sure you want to delete <strong>' + name + '</strong> ?</p>',
|
|
||||||
buttons: [{
|
|
||||||
classes: 'btn-danger',
|
|
||||||
text: 'Delete',
|
|
||||||
click: function(e) {
|
|
||||||
deleteModal.close(e);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
classes: 'btn-default',
|
|
||||||
text: 'Cancel',
|
|
||||||
click: function(e) {
|
|
||||||
deleteModal.dismiss(e);
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}, 'modal-danger');
|
|
||||||
|
|
||||||
deleteModal.result.then(function(event) {
|
|
||||||
del.apply(event, args);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,18 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
class NavbarController {
|
|
||||||
//start-non-standard
|
|
||||||
menu = [{
|
|
||||||
'title': 'Home',
|
|
||||||
'state': 'main'
|
|
||||||
}];
|
|
||||||
|
|
||||||
isCollapsed = true;
|
|
||||||
//end-non-standard
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.controller('NavbarController', NavbarController);
|
|
|
@ -1,9 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp')
|
|
||||||
.directive('navbar', () => ({
|
|
||||||
templateUrl: 'components/navbar/navbar.html',
|
|
||||||
restrict: 'E',
|
|
||||||
controller: 'NavbarController',
|
|
||||||
controllerAs: 'nav'
|
|
||||||
}));
|
|
|
@ -1,20 +0,0 @@
|
||||||
<div class="navbar navbar-default navbar-static-top" ng-controller="NavbarController">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button class="navbar-toggle" type="button" ng-click="nav.isCollapsed = !nav.isCollapsed">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a href="/" class="navbar-brand">dashboard-project</a>
|
|
||||||
</div>
|
|
||||||
<div uib-collapse="nav.isCollapsed" class="navbar-collapse collapse" id="navbar-main">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
<li ng-repeat="item in nav.menu" ui-sref-active="active">
|
|
||||||
<a ui-sref="{{item.state}}">{{item.title}}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,34 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('stateMock', []);
|
|
||||||
angular.module('stateMock').service('$state', function($q) {
|
|
||||||
this.expectedTransitions = [];
|
|
||||||
|
|
||||||
this.transitionTo = function(stateName) {
|
|
||||||
if (this.expectedTransitions.length > 0) {
|
|
||||||
var expectedState = this.expectedTransitions.shift();
|
|
||||||
if (expectedState !== stateName) {
|
|
||||||
throw Error('Expected transition to state: ' + expectedState + ' but transitioned to ' + stateName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw Error('No more transitions were expected! Tried to transition to ' + stateName);
|
|
||||||
}
|
|
||||||
console.log('Mock transition to: ' + stateName);
|
|
||||||
var deferred = $q.defer();
|
|
||||||
var promise = deferred.promise;
|
|
||||||
deferred.resolve();
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.go = this.transitionTo;
|
|
||||||
|
|
||||||
this.expectTransitionTo = function(stateName) {
|
|
||||||
this.expectedTransitions.push(stateName);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.ensureAllTransitionsHappened = function() {
|
|
||||||
if (this.expectedTransitions.length > 0) {
|
|
||||||
throw Error('Not all transitions happened!');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp.util', []);
|
|
|
@ -1,65 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Util service is for thin, globally reusable, utility functions
|
|
||||||
*/
|
|
||||||
function UtilService($window) {
|
|
||||||
var Util = {
|
|
||||||
/**
|
|
||||||
* Return a callback or noop function
|
|
||||||
*
|
|
||||||
* @param {Function|*} cb - a 'potential' function
|
|
||||||
* @return {Function}
|
|
||||||
*/
|
|
||||||
safeCb(cb) {
|
|
||||||
return (angular.isFunction(cb)) ? cb : angular.noop;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a given url with the use of an anchor element
|
|
||||||
*
|
|
||||||
* @param {String} url - the url to parse
|
|
||||||
* @return {Object} - the parsed url, anchor element
|
|
||||||
*/
|
|
||||||
urlParse(url) {
|
|
||||||
var a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
|
|
||||||
// Special treatment for IE, see http://stackoverflow.com/a/13405933 for details
|
|
||||||
if (a.host === '') {
|
|
||||||
a.href = a.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test whether or not a given url is same origin
|
|
||||||
*
|
|
||||||
* @param {String} url - url to test
|
|
||||||
* @param {String|String[]} [origins] - additional origins to test against
|
|
||||||
* @return {Boolean} - true if url is same origin
|
|
||||||
*/
|
|
||||||
isSameOrigin(url, origins) {
|
|
||||||
url = Util.urlParse(url);
|
|
||||||
origins = (origins && [].concat(origins)) || [];
|
|
||||||
origins = origins.map(Util.urlParse);
|
|
||||||
origins.push($window.location);
|
|
||||||
origins = origins.filter(function(o) {
|
|
||||||
return url.hostname === o.hostname &&
|
|
||||||
url.port === o.port &&
|
|
||||||
url.protocol === o.protocol;
|
|
||||||
});
|
|
||||||
return (origins.length >= 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Util;
|
|
||||||
}
|
|
||||||
|
|
||||||
angular.module('dashboardProjectApp.util')
|
|
||||||
.factory('Util', UtilService);
|
|
||||||
|
|
||||||
})();
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.6 KiB |
|
@ -1,127 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
|
||||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
|
||||||
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
|
|
||||||
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
||||||
<base href="/">
|
|
||||||
<title>OpenStack Cross-project Dashboard</title>
|
|
||||||
<meta name="description" content="">
|
|
||||||
<meta name="viewport" content="width=device-width">
|
|
||||||
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
|
|
||||||
<!-- build:css(client) app/vendor.css -->
|
|
||||||
<!-- bower:css -->
|
|
||||||
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
|
|
||||||
<link rel="stylesheet" href="bower_components/bootstrap-table/src/bootstrap-table.css" />
|
|
||||||
<!-- endbower -->
|
|
||||||
<!-- endbuild -->
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css" />
|
|
||||||
|
|
||||||
<!-- build:css({.tmp,client}) app/app.css -->
|
|
||||||
<link rel="stylesheet" href="app/app.css">
|
|
||||||
<!-- injector:css -->
|
|
||||||
<link rel="stylesheet" href="app/app.css">
|
|
||||||
<link rel="stylesheet" href="app/projectDetail/styles/projectDetail.css">
|
|
||||||
<link rel="stylesheet" href="app/projectList/styles/projectList.css">
|
|
||||||
<link rel="stylesheet" href="components/footer/footer.css">
|
|
||||||
<link rel="stylesheet" href="components/modal/modal.css">
|
|
||||||
<!-- endinjector -->
|
|
||||||
<!-- endbuild -->
|
|
||||||
</head>
|
|
||||||
<body ng-app="dashboardProjectApp">
|
|
||||||
<!--[if lt IE 7]>
|
|
||||||
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<!-- Add your site or application content here -->
|
|
||||||
<header>
|
|
||||||
<div class="container" style="padding-left:0px;">
|
|
||||||
<a href="/projectList">
|
|
||||||
<img src="../../assets/images/openstack-logo-full.png" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="container-fluid main-wrapper">
|
|
||||||
<div ui-view="" class="row"></div>
|
|
||||||
</div>
|
|
||||||
<!--<footer></footer>-->
|
|
||||||
|
|
||||||
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
|
|
||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-XXXXX-X');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function nameFormatter(value) {
|
|
||||||
var story = value.split("-");
|
|
||||||
return '<a class="dp-link-title" href="projectDetail/'+ story[0] +'">' + story[1] + '</a>';
|
|
||||||
}
|
|
||||||
function progressBar(percentage, row) {
|
|
||||||
|
|
||||||
return '<div class="progress dp-progress">'+
|
|
||||||
'<div class="progress-bar progress-bar-success progress-bar-striped"'+
|
|
||||||
'role="progressbar" aria-valuenow="'+percentage+'" aria-valuemin="0"' +
|
|
||||||
'aria-valuemax="100" style="width: '+percentage+'%">'+
|
|
||||||
'<span class="sr-only">'+row.progressLabel+'</span>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function rowStyle(row, index) {
|
|
||||||
var classes = ['active', 'active'];
|
|
||||||
if (index % 2 === 0 && index/2 < classes.length) {
|
|
||||||
return {
|
|
||||||
classes: classes[index/2]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="bower_components/es5-shim/es5-shim.js"></script>
|
|
||||||
<script src="bower_components/json3/lib/json3.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
<!-- build:js({client,node_modules}) app/vendor.js -->
|
|
||||||
<!-- bower:js -->
|
|
||||||
<script src="bower_components/jquery/dist/jquery.js"></script>
|
|
||||||
<script src="bower_components/angular/angular.js"></script>
|
|
||||||
<script src="bower_components/angular-resource/angular-resource.js"></script>
|
|
||||||
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
|
|
||||||
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
|
|
||||||
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
|
|
||||||
<script src="bower_components/lodash/dist/lodash.compat.js"></script>
|
|
||||||
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
|
|
||||||
<script src="bower_components/bootstrap-table/src/bootstrap-table.js"></script>
|
|
||||||
<script src="bower_components/moment/moment.js"></script>
|
|
||||||
<!-- endbower -->
|
|
||||||
<!-- endbuild -->
|
|
||||||
<!-- build:js(.tmp) app/app.js -->
|
|
||||||
<script src="app/app.js"></script>
|
|
||||||
<!-- injector:js -->
|
|
||||||
<script src="components/util/util.module.js"></script>
|
|
||||||
<script src="components/footer/footer.directive.js"></script>
|
|
||||||
<script src="app/projectDetail/projectDetail.js"></script>
|
|
||||||
<script src="app/projectDetail/services/userStoryService.js"></script>
|
|
||||||
<script src="app/projectList/controllers/projectList.controller.js"></script>
|
|
||||||
<script src="app/projectList/projectList.js"></script>
|
|
||||||
<script src="app/projectDetail/controllers/projectDetail.controller.js"></script>
|
|
||||||
<script src="components/modal/modal.service.js"></script>
|
|
||||||
<script src="components/navbar/navbar.controller.js"></script>
|
|
||||||
<script src="components/navbar/navbar.directive.js"></script>
|
|
||||||
<script src="components/sdk/lbServices.js"></script>
|
|
||||||
<script src="app/app.constant.js"></script>
|
|
||||||
<script src="components/util/util.service.js"></script>
|
|
||||||
<!-- endinjector -->
|
|
||||||
<!-- endbuild -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,3 +0,0 @@
|
||||||
# robotstxt.org
|
|
||||||
|
|
||||||
User-agent: *
|
|
|
@ -1,14 +0,0 @@
|
||||||
/**
|
|
||||||
* This file uses the Page Object pattern to define the main page for tests
|
|
||||||
* https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var NavbarComponent = function() {
|
|
||||||
this.navbar = element(by.css('.navbar'));
|
|
||||||
this.navbarHeader = this.navbar.element(by.css('.navbar-header'));
|
|
||||||
this.navbarNav = this.navbar.element(by.css('#navbar-main .nav.navbar-nav:not(.navbar-right)'));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = new NavbarComponent();
|
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* This file uses the Page Object pattern to define the main page for tests
|
|
||||||
* https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var MainPage = function() {
|
|
||||||
this.heroEl = element(by.css('.hero-unit'));
|
|
||||||
this.h1El = this.heroEl.element(by.css('h1'));
|
|
||||||
this.imgEl = this.heroEl.element(by.css('img'));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = new MainPage();
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var config = browser.params;
|
|
||||||
|
|
||||||
describe('Main View', function() {
|
|
||||||
var page;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
let promise = browser.get(config.baseUrl + '/');
|
|
||||||
page = require('./main.po');
|
|
||||||
return promise;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include jumbotron with correct data', function() {
|
|
||||||
expect(page.h1El.getText()).to.eventually.equal('\'Allo, \'Allo!');
|
|
||||||
expect(page.imgEl.getAttribute('src')).to.eventually.match(/yeoman.png$/);
|
|
||||||
expect(page.imgEl.getAttribute('alt')).to.eventually.equal('I\'m Yeoman');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
cd ../dashboard-project-api;
|
|
||||||
npm install;
|
|
||||||
cd ../dashboard-project-app
|
|
||||||
npm install;
|
|
||||||
bower install;
|
|
|
@ -1,94 +0,0 @@
|
||||||
// Karma configuration
|
|
||||||
// http://karma-runner.github.io/0.10/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function(config) {
|
|
||||||
config.set({
|
|
||||||
// base path, that will be used to resolve files and exclude
|
|
||||||
basePath: '',
|
|
||||||
|
|
||||||
// testing framework to use (jasmine/mocha/qunit/...)
|
|
||||||
frameworks: ['mocha', 'chai', 'sinon-chai', 'chai-as-promised', 'chai-things'],
|
|
||||||
|
|
||||||
client: {
|
|
||||||
mocha: {
|
|
||||||
timeout: 5000 // set default mocha spec timeout
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// list of files / patterns to load in the browser
|
|
||||||
files: [
|
|
||||||
// bower:js
|
|
||||||
'client/bower_components/jquery/dist/jquery.js',
|
|
||||||
'client/bower_components/angular/angular.js',
|
|
||||||
'client/bower_components/angular-resource/angular-resource.js',
|
|
||||||
'client/bower_components/angular-cookies/angular-cookies.js',
|
|
||||||
'client/bower_components/angular-sanitize/angular-sanitize.js',
|
|
||||||
'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
|
|
||||||
'client/bower_components/lodash/dist/lodash.compat.js',
|
|
||||||
'client/bower_components/angular-ui-router/release/angular-ui-router.js',
|
|
||||||
'client/bower_components/angular-mocks/angular-mocks.js',
|
|
||||||
// endbower
|
|
||||||
'client/app/app.js',
|
|
||||||
'client/{app,components}/**/*.module.js',
|
|
||||||
'client/{app,components}/**/*.js',
|
|
||||||
'client/{app,components}/**/*.html'
|
|
||||||
],
|
|
||||||
|
|
||||||
preprocessors: {
|
|
||||||
'**/*.html': 'ng-html2js',
|
|
||||||
'client/{app,components}/**/*.js': 'babel'
|
|
||||||
},
|
|
||||||
|
|
||||||
ngHtml2JsPreprocessor: {
|
|
||||||
stripPrefix: 'client/'
|
|
||||||
},
|
|
||||||
|
|
||||||
babelPreprocessor: {
|
|
||||||
options: {
|
|
||||||
sourceMap: 'inline'
|
|
||||||
},
|
|
||||||
filename: function (file) {
|
|
||||||
return file.originalPath.replace(/\.js$/, '.es5.js');
|
|
||||||
},
|
|
||||||
sourceFileName: function (file) {
|
|
||||||
return file.originalPath;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// list of files / patterns to exclude
|
|
||||||
exclude: [],
|
|
||||||
|
|
||||||
// web server port
|
|
||||||
port: 8080,
|
|
||||||
|
|
||||||
// level of logging
|
|
||||||
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
|
|
||||||
// reporter types:
|
|
||||||
// - dots
|
|
||||||
// - progress (default)
|
|
||||||
// - spec (karma-spec-reporter)
|
|
||||||
// - junit
|
|
||||||
// - growl
|
|
||||||
// - coverage
|
|
||||||
reporters: ['spec'],
|
|
||||||
|
|
||||||
// enable / disable watching file and executing tests whenever any file changes
|
|
||||||
autoWatch: false,
|
|
||||||
|
|
||||||
// Start these browsers, currently available:
|
|
||||||
// - Chrome
|
|
||||||
// - ChromeCanary
|
|
||||||
// - Firefox
|
|
||||||
// - Opera
|
|
||||||
// - Safari (only Mac)
|
|
||||||
// - PhantomJS
|
|
||||||
// - IE (only Windows)
|
|
||||||
browsers: ['PhantomJS'],
|
|
||||||
|
|
||||||
// Continuous Integration mode
|
|
||||||
// if true, it capture browsers, run tests and exit
|
|
||||||
singleRun: false
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// Register the Babel require hook
|
|
||||||
require('babel-core/register');
|
|
||||||
|
|
||||||
var chai = require('chai');
|
|
||||||
|
|
||||||
// Load Chai assertions
|
|
||||||
global.expect = chai.expect;
|
|
||||||
global.assert = chai.assert;
|
|
||||||
chai.should();
|
|
||||||
|
|
||||||
// Load Sinon
|
|
||||||
global.sinon = require('sinon');
|
|
||||||
|
|
||||||
// Initialize Chai plugins
|
|
||||||
chai.use(require('sinon-chai'));
|
|
||||||
chai.use(require('chai-as-promised'));
|
|
||||||
chai.use(require('chai-things'))
|
|
|
@ -1,105 +0,0 @@
|
||||||
{
|
|
||||||
"name": "dashboard-project",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"main": "server/app.js",
|
|
||||||
"dependencies": {
|
|
||||||
"babel-polyfill": "^6.7.2",
|
|
||||||
"babel-runtime": "^6.6.1",
|
|
||||||
"bluebird": "^3.3.3",
|
|
||||||
"body-parser": "^1.13.3",
|
|
||||||
"composable-middleware": "^0.3.0",
|
|
||||||
"compression": "^1.5.2",
|
|
||||||
"connect-mongo": "^0.8.1",
|
|
||||||
"cookie-parser": "^1.3.5",
|
|
||||||
"ejs": "^2.3.3",
|
|
||||||
"errorhandler": "^1.4.2",
|
|
||||||
"express": "^4.13.3",
|
|
||||||
"express-session": "^1.11.3",
|
|
||||||
"lodash": "^4.6.1",
|
|
||||||
"lusca": "^1.3.0",
|
|
||||||
"method-override": "^2.3.5",
|
|
||||||
"mongoose": "^4.1.2",
|
|
||||||
"morgan": "~1.7.0",
|
|
||||||
"serve-favicon": "^2.3.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"autoprefixer": "^6.0.0",
|
|
||||||
"babel-core": "^6.6.5",
|
|
||||||
"babel-plugin-transform-class-properties": "^6.6.0",
|
|
||||||
"babel-plugin-transform-runtime": "^6.6.0",
|
|
||||||
"babel-preset-es2015": "^6.6.0",
|
|
||||||
"babel-register": "^6.6.5",
|
|
||||||
"chai": "^3.2.0",
|
|
||||||
"chai-as-promised": "^5.1.0",
|
|
||||||
"chai-things": "^0.2.0",
|
|
||||||
"connect-livereload": "^0.5.3",
|
|
||||||
"grunt": "~0.4.5",
|
|
||||||
"grunt-angular-templates": "^1.0.3",
|
|
||||||
"grunt-babel": "~6.0.0",
|
|
||||||
"grunt-build-control": "^0.6.0",
|
|
||||||
"grunt-concurrent": "^2.0.1",
|
|
||||||
"grunt-contrib-clean": "^1.0.0",
|
|
||||||
"grunt-contrib-concat": "^1.0.0",
|
|
||||||
"grunt-contrib-copy": "^1.0.0",
|
|
||||||
"grunt-contrib-cssmin": "^1.0.0",
|
|
||||||
"grunt-contrib-imagemin": "^1.0.1",
|
|
||||||
"grunt-contrib-jshint": "^1.0.0",
|
|
||||||
"grunt-contrib-uglify": "^1.0.0",
|
|
||||||
"grunt-contrib-watch": "~0.6.1",
|
|
||||||
"grunt-dom-munger": "^3.4.0",
|
|
||||||
"grunt-env": "~0.4.1",
|
|
||||||
"grunt-express-server": "^0.5.1",
|
|
||||||
"grunt-filerev": "^2.3.1",
|
|
||||||
"grunt-google-cdn": "~0.4.0",
|
|
||||||
"grunt-injector": "^0.6.0",
|
|
||||||
"grunt-jscs": "^2.1.0",
|
|
||||||
"grunt-karma": "~0.12.0",
|
|
||||||
"grunt-mocha-istanbul": "^3.0.1",
|
|
||||||
"grunt-mocha-test": "~0.12.7",
|
|
||||||
"grunt-newer": "^1.1.1",
|
|
||||||
"grunt-ng-annotate": "^2.0.1",
|
|
||||||
"grunt-ng-constant": "^2.0.1",
|
|
||||||
"grunt-node-inspector": "^0.4.1",
|
|
||||||
"grunt-nodemon": "^0.4.0",
|
|
||||||
"grunt-open": "~0.2.3",
|
|
||||||
"grunt-postcss": "~0.8.0",
|
|
||||||
"grunt-protractor-runner": "^2.0.0",
|
|
||||||
"grunt-usemin": "^3.0.0",
|
|
||||||
"grunt-wiredep": "^2.0.0",
|
|
||||||
"istanbul": "~0.4.1",
|
|
||||||
"jit-grunt": "~0.10.0",
|
|
||||||
"jshint-stylish": "~2.1.0",
|
|
||||||
"karma": "~0.13.3",
|
|
||||||
"karma-babel-preprocessor": "^6.0.1",
|
|
||||||
"karma-chai-plugins": "~0.7.0",
|
|
||||||
"karma-chrome-launcher": "~0.2.0",
|
|
||||||
"karma-firefox-launcher": "~0.1.6",
|
|
||||||
"karma-jade-preprocessor": "0.0.11",
|
|
||||||
"karma-mocha": "^0.2.0",
|
|
||||||
"karma-ng-html2js-preprocessor": "~0.2.0",
|
|
||||||
"karma-ng-scenario": "~0.1.0",
|
|
||||||
"karma-phantomjs-launcher": "~1.0.0",
|
|
||||||
"karma-requirejs": "~0.2.2",
|
|
||||||
"karma-script-launcher": "~0.1.0",
|
|
||||||
"karma-spec-reporter": "~0.0.20",
|
|
||||||
"mocha": "^2.2.5",
|
|
||||||
"open": "~0.0.4",
|
|
||||||
"phantomjs-prebuilt": "^2.1.4",
|
|
||||||
"proxyquire": "^1.0.1",
|
|
||||||
"requirejs": "~2.1.11",
|
|
||||||
"sinon": "^1.16.1",
|
|
||||||
"sinon-chai": "^2.8.0",
|
|
||||||
"supertest": "^1.1.0",
|
|
||||||
"time-grunt": "^1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^4.4.0",
|
|
||||||
"npm": "^2.14.20"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "node server",
|
|
||||||
"test": "grunt test",
|
|
||||||
"update-webdriver": "node node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager update"
|
|
||||||
},
|
|
||||||
"private": true
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue