mirror of
https://github.com/fazo96/pbs.git
synced 2025-01-09 12:10:06 +01:00
first version on ghpages
This commit is contained in:
commit
e8643ffd3b
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
bower_components/
|
||||||
|
.divshot-cache/
|
||||||
|
divshot-debug-log
|
||||||
|
node_modules/
|
||||||
|
test/
|
||||||
|
testdata/
|
||||||
|
dist/
|
9
README.html
Normal file
9
README.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<h1 id="pbs">PBS</h1><p>PBS is a small web app built to assist in working with Project Breakdown Structures.</p><p>It should be accessible <a href="http://pbsapp.divshot.io">here</a></p><h2 id="features">Features</h2><p>It's still in development.</p><ul><li>can calculate (almost) every info that can be retrieved from the minimum amount of data</li><li>can draw a (almost correct and thorough) pert diagram</li><li>can (almost) draw a timeline of the project</li></ul><h2 id="data-format">Data format</h2><p>This is a valid input document (extra data is ignored but not thrashed):</p><pre><code class="lang-json">[
|
||||||
|
{"id": 0, "duration": 3},
|
||||||
|
{"id": 1, "duration": 1},
|
||||||
|
{"id": 2, "duration": 2, "depends": [0]},
|
||||||
|
{"id": 3, "duration": 5, "depends": [1]},
|
||||||
|
{"id": 4, "duration": 5, "depends": [1]},
|
||||||
|
{"id": 5, "duration": 2, "depends": [2,3,4]}
|
||||||
|
]
|
||||||
|
</code></pre><h2 id="development">Development</h2><ol><li>Clone the repo</li><li>make sure you have <a href="http://gulpjs.com">gulp</a></li><li>run <code>npm install && bower install && gulp</code> to build the project</li><li>the resulting static website is in <code>dist/</code></li></ol><h2 id="license">License</h2><p>MIT</p>
|
1
activities.html
Normal file
1
activities.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<table id="tab" class="table" ng-controller="tableController"><tr><td><b>#</b></td><td><b>ID</b></td><td><b>Duration (days)</b></td><td><b>Start Day</b></td><td><b>Depends On</b></td><td><b>Dependant</b></td><td><b>Resources</b></td><td><b>End Day</b></td><td><b>Free Delay</b></td><td><b>Chained Delay</b></td></tr><tr ng-repeat="item in list"><td>{{$index + 1}}</td><td>{{item.id}}</td><td>{{item.duration}}</td><td>{{item.startDay}}</td><td>{{item.depends.join(', ') || "None"}}</td><td>{{item.dependant.join(', ') || "None"}}</td><td>{{item.assigned.join(', ') || "None"}}</td><td>{{item.endDay}} --- {{item.endDay + (item.permittedDelay || 0) + (item.chainedDelay || 0)}}</td><td>{{item.permittedDelay || 0}}</td><td>{{item.chainedDelay || 0}}</td></tr></table>
|
2
angular-ui-router.js
vendored
Normal file
2
angular-ui-router.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
angular.js
vendored
Normal file
8
angular.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
app.js
Normal file
1
app.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
var pertApp,pertController;pertApp=angular.module("pertApp",["ui.router"]),pertApp.config(function($stateProvider,$urlRouterProvider,$locationProvider){return $urlRouterProvider.otherwise("/"),$locationProvider.html5Mode({enabled:!1,requireBase:!1}),$stateProvider.state("home",{url:"/",templateUrl:"pbs/welcome.html",controller:function($scope){}}),$stateProvider.state("rawedit",{url:"/rawedit",templateUrl:"pbs/rawedit.html",controller:pertController}),$stateProvider.state("edit",{url:"/edit",templateUrl:"pbs/edit.html",controller:pertController}),$stateProvider.state("pert",{url:"/pert",templateUrl:"pbs/pert.html",controller:pertController}),$stateProvider.state("gantt",{url:"/gantt",templateUrl:"pbs/gantt.html",controller:pertController}),$stateProvider.state("activities",{url:"/activities",templateUrl:"pbs/activities.html",controller:pertController}),$stateProvider.state("resources",{url:"/resources",templateUrl:"pbs/resources.html",controller:pertController})}),pertController=function($scope){return $scope.toLocalStorage=function(data,options){var e,error,ref,sdata;if(null==options&&(options={}),null==data&&(data={activities:[],resources:[]}),null==(null!=(ref=data.activities)?ref.push:void 0))return swal("Error","invalid data format. Try resetting","error");try{return sdata=JSON.stringify(data),console.log("Saving: "+sdata),localStorage.setItem("ganttpert",sdata),options.silent||swal("Ok","Data updated","success"),$scope.pbs=new PBS(data).calculate(),$scope.$broadcast("dataChanged")}catch(error){return e=error,swal("Error",e,"error")}},$scope.fromLocalStorage=function(options){var data,e,error,jdata;options=options||{},data=localStorage.getItem(options.name||"ganttpert"),null===data&&(data='{"activities":[], "resources":[]}');try{jdata=JSON.parse(data),null===jdata&&(jdata={activities:[],resources:[]})}catch(error){return e=error,options.silent||swal("JSON Error",e,"error"),{activities:[],resources:[]}}return options.raw?jdata:$scope.pbs=new PBS(jdata).calculate()}};
|
5
bootstrap.css
vendored
Normal file
5
bootstrap.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
bootstrap.js
vendored
Normal file
2
bootstrap.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
collapse.js
Normal file
1
collapse.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
+function($){"use strict";function getTargetFromTrigger($trigger){var href,target=$trigger.attr("data-target")||(href=$trigger.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"");return $(target)}function Plugin(option){return this.each(function(){var $this=$(this),data=$this.data("bs.collapse"),options=$.extend({},Collapse.DEFAULTS,$this.data(),"object"==typeof option&&option);!data&&options.toggle&&/show|hide/.test(option)&&(options.toggle=!1),data||$this.data("bs.collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})}var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},Collapse.DEFAULTS,options),this.$trigger=$('[data-toggle="collapse"][href="#'+element.id+'"],[data-toggle="collapse"][data-target="#'+element.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};Collapse.VERSION="3.3.6",Collapse.TRANSITION_DURATION=350,Collapse.DEFAULTS={toggle:!0},Collapse.prototype.dimension=function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"},Collapse.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var activesData,actives=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(actives&&actives.length&&(activesData=actives.data("bs.collapse"),activesData&&activesData.transitioning))){var startEvent=$.Event("show.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){actives&&actives.length&&(Plugin.call(actives,"hide"),activesData||actives.data("bs.collapse",null));var dimension=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[dimension](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var complete=function(){this.$element.removeClass("collapsing").addClass("collapse in")[dimension](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!$.support.transition)return complete.call(this);var scrollSize=$.camelCase(["scroll",dimension].join("-"));this.$element.one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])}}}},Collapse.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var startEvent=$.Event("hide.bs.collapse");if(this.$element.trigger(startEvent),!startEvent.isDefaultPrevented()){var dimension=this.dimension();this.$element[dimension](this.$element[dimension]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var complete=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return $.support.transition?void this.$element[dimension](0).one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION):complete.call(this)}}},Collapse.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},Collapse.prototype.getParent=function(){return $(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each($.proxy(function(i,element){var $element=$(element);this.addAriaAndCollapsedClass(getTargetFromTrigger($element),$element)},this)).end()},Collapse.prototype.addAriaAndCollapsedClass=function($element,$trigger){var isOpen=$element.hasClass("in");$element.attr("aria-expanded",isOpen),$trigger.toggleClass("collapsed",!isOpen).attr("aria-expanded",isOpen)};var old=$.fn.collapse;$.fn.collapse=Plugin,$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(e){var $this=$(this);$this.attr("data-target")||e.preventDefault();var $target=getTargetFromTrigger($this),data=$target.data("bs.collapse"),option=data?"toggle":$this.data();Plugin.call($target,option)})}(jQuery);
|
1
controllers.js
Normal file
1
controllers.js
Normal file
File diff suppressed because one or more lines are too long
7
divshot.json
Normal file
7
divshot.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "pbsapp",
|
||||||
|
"root": "dist",
|
||||||
|
"routes": {
|
||||||
|
"**": "index.html"
|
||||||
|
}
|
||||||
|
}
|
1
edit.html
Normal file
1
edit.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div ng-controller="editorController" class="pbs-editor"><div class="text-center"><h2>Editor</h2><p class="lead">Dependencies must be a list of IDs separated by space<br>the program does not check cyclic or invalid dependencies for you</p></div><div class="panel panel-default new-activity-panel"><div class="panel-heading"><i class="fa fa-plus"></i> New Activity</div><div class="panel-body"><div class="input-group"><span class="input-group-addon">ID</span> <input class="form-control" placeholder="New Activity" ng-model="actID" id="new-id"></div><div class="input-group duration"><span class="input-group-addon">Duration</span> <input class="form-control" ng-model="actDur" placeholder="(days)"></div><div class="input-group dependencies"><span class="input-group-addon">Dependencies</span> <input class="form-control" placeholder="id1 id2 id3" ng-model="actDeps"></div><button ng-click="addNew(false)" class="btn btn-primary"><i class="fa fa-plus"></i> Add</button></div></div><table id="tab" class="table"><tr><td><b>#</b></td><td><b>ID</b></td><td><b>Duration (days)</b></td><td><b>Dependencies</b></td><td><b>Commands</b></td></tr><tr ng-repeat="item in activities"><td>{{$index + 1}}</td><td>{{item.id}}</td><td>{{item.duration}}</td><td>{{item.depends.join(', ') || "None"}}</td><td><button class="btn btn-info" ng-click="clone(item.id)"><i class="fa fa-copy"></i></button> <button class="btn btn-danger" ng-click="delete($index)"><i class="fa fa-remove"></i></button></td></tr></table><hr><div class="panel panel-default new-activity-panel"><div class="panel-heading"><i class="fa fa-plus"></i> New Resource</div><div class="panel-body"><div class="input-group"><span class="input-group-addon">ID</span> <input class="form-control" placeholder="New Resource" ng-model="resID"></div><div class="input-group duration"><span class="input-group-addon">Name</span> <input class="form-control" ng-model="resName" placeholder="new resource name"></div><div class="input-group dependencies"><span class="input-group-addon">Assigned To</span> <input class="form-control" placeholder="id1 id2 id3" ng-model="resAss"></div><button ng-click="addNew(true)" class="btn btn-primary"><i class="fa fa-plus"></i> Add</button></div></div><table id="tab" class="table"><tr><td><b>#</b></td><td><b>ID</b></td><td><b>Name</b></td><td><b>Assignations</b></td><td><b>Commands</b></td></tr><tr ng-repeat="item in resources"><td>{{$index + 1}}</td><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.assignedTo.join(', ') || "None"}}</td><td><button class="btn btn-info" ng-click="clone(true,item.id)"><i class="fa fa-copy"></i></button> <button class="btn btn-danger" ng-click="delete(true,$index)"><i class="fa fa-remove"></i></button></td></tr></table></div>
|
1
gantt.html
Normal file
1
gantt.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div ng-controller="ganttDiagController"><div class="text-center"><h2>Project Timeline</h2></div><div id="timeline"></div></div>
|
1
index.html
Normal file
1
index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!DOCTYPE html><html ng-app="pertApp"><head><title>PBS Wizard</title><meta charset="utf-8"><link rel="stylesheet" href="vis.min.css"><link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"><link rel="stylesheet" href="bootstrap.css"><link rel="stylesheet" href="style.css"><link rel="stylesheet" href="sweet-alert.css"><script src="jquery.js"></script><script src="sweet-alert.js"></script><script src="angular.js"></script><script src="bootstrap.js"></script><script src="collapse.js"></script><script src="angular-ui-router.js"></script><script src="vis.min.js"></script><script src="moment.js"></script><script src="PBSlib.js"></script><script src="app.js"></script><script src="controllers.js"></script></head><body><nav class="navbar navbar-default navbar-fixed-top"><div class="container-fluid"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-body"><span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span></button> <a class="navbar-brand" href="/"><i class="fa fa-bar-chart"></i> PBS</a></div><div class="collapse navbar-collapse" id="navbar-body"><ul class="nav navbar-nav"><li><a ui-sref="edit">Edit</a></li><li><a ui-sref="rawedit">RawEdit</a></li><li><a ui-sref="activities">Activities</a></li><li><a ui-sref="resources">Resources</a></li><li><a ui-sref="pert">Pert</a></li><li><a ui-sref="gantt">Gantt</a></li><li class="github"><a href="http://github.com/fazo96/pbs">GitHub</a></li></ul><span class="pull-right github"><a href="http://github.com/fazo96/pbs"><i class="fa fa-2x fa-github"></i></a></span></div></div></nav><div class="container" ui-view></div></body></html>
|
4
jquery.js
vendored
Normal file
4
jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
package.json
Normal file
21
package.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "pert",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "^3.8.11",
|
||||||
|
"gulp-clean": "^0.3.1",
|
||||||
|
"gulp-coffee": "^2.3.1",
|
||||||
|
"gulp-markdown": "^1.0.0",
|
||||||
|
"gulp-minify-css": "^1.0.0",
|
||||||
|
"gulp-minify-html": "^1.0.2",
|
||||||
|
"gulp-uglify": "^1.1.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/fazo96/pert.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/fazo96/pert/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/fazo96/pert"
|
||||||
|
}
|
1
pert.html
Normal file
1
pert.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div class="text-center" ng-controller="pertDiagController"><button class="btn btn-primary" ng-click="rebuild()"><i class="fa fa-spinner"></i> Redraw</button><div id="pertDiagram"></div><h2>How to read the Graph</h2><b>Arrow:</b> every arrow is an activity and the ID and duration (in days) are shown over the arrow, like this: <code>activityID (minimumDuration/maximumDuration)</code><hr><p class="lead">The color of the arrow tells the type of the activity:</p><ul><li><b>Red Arrow:</b> critical activity</li><li><b>Green Arrow:</b> free delay of an activity, expressed this way: <code>activityID (freeDelay)</code></li><li><b>Yellow Arrow:</b> activity with a free delay of 0</li><li><b>Blue Arrow:</b> activity with a free delay over 0</li></ul><hr><p class="lead">Every circle represents the day of the start of one or more activities and/or the day of the end of one or more activities.</p></div>
|
1
rawedit.html
Normal file
1
rawedit.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div class="text-center" ng-controller="rawEditorController"><h2>RawEditor</h2><p class="lead">The RawEditor is intended for importing, exporting your data and debugging.<br>Keep backups outside of this application if you rely on your data</p><textarea id="ta" class="form-control" ng-model="taData" rows="10"></textarea> <button class="btn btn-primary" ng-click="saveData(true)"><i class="fa fa-check"></i> Save</button> <button class="btn btn-info" ng-click="reloadData(true)"><i class="fa fa-refresh"></i> Reload</button> <button class="btn btn-warning" ng-click="reset(true)"><i class="fa fa-bomb"></i> Reset</button></div>
|
1
resources.html
Normal file
1
resources.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<table id="tab" class="table" ng-controller="resourceTableController"><tr><td><b>#</b></td><td><b>ID</b></td><td><b>Name</b></td><td><b>Assigned To</b></td></tr><tr ng-repeat="item in list"><td>{{$index + 1}}</td><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.assignedTo.join(', ') || "None"}}</td></tr></table>
|
1
style.css
Normal file
1
style.css
Normal file
@ -0,0 +1 @@
|
|||||||
|
span.github a,span.github a:hover{color:#000;text-decoration:none}#pertDiagram{height:600px;width:100%;border:1px solid #d3d3d3;margin-bottom:1em;margin-top:1em}.container{padding-top:5em}#timeline{margin-top:2em}.new-activity-panel{max-width:50em;margin:0 auto 2em}.input-group.dependencies{margin-bottom:1em}.input-group.duration{margin-top:1em;margin-bottom:1em}span.github{margin-top:.75em}span.github a:hover{cursor:pointer}@media(max-width:765px){span.github{display:none}}@media(min-width:766px){li.github{display:none}}#ta{margin:1em 0}#tab{max-width:60em;margin:0 auto}
|
1
sweet-alert.css
Normal file
1
sweet-alert.css
Normal file
File diff suppressed because one or more lines are too long
1
sweet-alert.js
Normal file
1
sweet-alert.js
Normal file
File diff suppressed because one or more lines are too long
1
vis.min.css
vendored
Normal file
1
vis.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
14
vis.min.js
vendored
Normal file
14
vis.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
welcome.html
Normal file
1
welcome.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h2 id="welcome-to-pbs-wizard">Welcome to PBS Wizard</h2><p>This web application will supposedly help you manage your Project Breakdown Structure.</p><h2 id="what-can-it-do">What can it do</h2><ul><li>You can use the <a href="/rawedit">RawEdit</a>or to import and export your PBS data. This software is still a prototype, so be careful!</li><li>You can use the <a href="/edit">Edit</a>or to more easily edit your Project <strong>Activities</strong> and <strong>Resources</strong>.</li><li>With the <a href="/activities">Activities</a> and <a href="/resources">Resources</a> pages you can view detailed info about your Activities and Resources.</li><li><a href="#/pert">Pert</a> and <a href="#/gantt">Gantt</a> are self-explanatory, try them!</li></ul><p>Made by <a href="http://github.com/fazo96">Enrico Fasoli</a>. This application is <strong>Free Software (free as in Freedom to modify and redistribute)</strong> <a href="http://github.com/fazo96/pbs">available under the <strong>MIT License</strong></a>.</p>
|
Loading…
Reference in New Issue
Block a user