diff --git a/README.md b/README.md
index 2966f0a..718b0f8 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/TAMULib/ProjectManagementUI.svg?branch=master)](https://travis-ci.org/TAMULib/ProjectManagementUI)
-[![Coverage Status](https://coveralls.io/repos/github/TAMULib/ProjectManagementUI/badge.svg?branch=master)](https://coveralls.io/github/TAMULib/ProjectManagementUI?branch=master)
+[![Build Status](https://travis-ci.org/TAMULib/ProductManagementUI.svg?branch=master)](https://travis-ci.org/TAMULib/ProductManagementUI)
+[![Coverage Status](https://coveralls.io/repos/github/TAMULib/ProductManagementUI/badge.svg?branch=master)](https://coveralls.io/github/TAMULib/ProductManagementUI?branch=master)
-# Project Management UI
+# Product Management UI
diff --git a/app/.htaccess b/app/.htaccess
index a58e764..78fc7d0 100644
--- a/app/.htaccess
+++ b/app/.htaccess
@@ -1,7 +1,7 @@
RewriteEngine On
- RewriteBase /projects/
+ RewriteBase /products/
RewriteCond %{HTTP:X-Requested-With} !XMLHttpRequest$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.html [L]
-
\ No newline at end of file
+
diff --git a/app/config/apiMapping.js b/app/config/apiMapping.js
index 45ec0dc..eb0bcb5 100644
--- a/app/config/apiMapping.js
+++ b/app/config/apiMapping.js
@@ -1,166 +1,233 @@
// CONVENTION: must match model name, case sensitive
var apiMapping = {
- Project: {
- validations: true,
- lazy: true,
- channel: '/channel/projects',
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'projects',
- 'method': '',
- 'httpMethod': 'GET'
- },
- create: {
- 'endpoint': '/private/queue',
- 'controller': 'projects',
- 'method': '',
- 'httpMethod': 'POST'
- },
- update: {
- 'endpoint': '/private/queue',
- 'controller': 'projects',
- 'method': '',
- 'httpMethod': 'PUT'
- },
- remove: {
- 'endpoint': '/private/queue',
- 'controller': 'projects',
- 'method': '',
- 'httpMethod': 'DELETE'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'projects'
- }
- },
- User: {
- lazy: true,
- channel: '/channel/users',
- instantiate: {
- 'endpoint': '/private/queue',
- 'controller': 'users',
- 'method': 'credentials'
- },
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'users'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'users'
- },
- update: {
- 'endpoint': '/private/queue',
- 'controller': 'users',
- 'method': 'update'
- }
- },
- RemoteProjectManager: {
- validations: true,
- lazy: true,
- channel: '/channel/remote-project-manager',
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'remote-project-manager',
- 'method': '',
- 'httpMethod': 'GET'
- },
- create: {
- 'endpoint': '/private/queue',
- 'controller': 'remote-project-manager',
- 'method': '',
- 'httpMethod': 'POST'
- },
- update: {
- 'endpoint': '/private/queue',
- 'controller': 'remote-project-manager',
- 'method': '',
- 'httpMethod': 'PUT'
- },
- remove: {
- 'endpoint': '/private/queue',
- 'controller': 'remote-project-manager',
- 'method': '',
- 'httpMethod': 'DELETE'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'remote-project-manager'
- },
- types: {
- 'endpoint': '/channel',
- 'controller': 'remote-project-manager',
- 'method': 'types/',
- 'httpMethod': 'GET'
- },
- scaffolding: {
- 'endpoint': '/channel',
- 'controller': 'remote-project-manager',
- 'method': 'scaffolding/:type/',
- 'httpMethod': 'GET'
- }
- },
- Status: {
- validations: true,
- lazy: true,
- channel: '/channel/status',
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'status',
- 'method': '',
- 'httpMethod': 'GET'
- },
- create: {
- 'endpoint': '/private/queue',
- 'controller': 'status',
- 'method': '',
- 'httpMethod': 'POST'
- },
- update: {
- 'endpoint': '/private/queue',
- 'controller': 'status',
- 'method': '',
- 'httpMethod': 'PUT'
- },
- remove: {
- 'endpoint': '/private/queue',
- 'controller': 'status',
- 'method': '',
- 'httpMethod': 'DELETE'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'status'
- }
- },
- RemoteProjects: {
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'projects/remote'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'projects/remote'
- }
- },
- ProjectsStats: {
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'projects/stats'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'projects/stats'
- }
- },
- ActiveSprints: {
- all: {
- 'endpoint': '/private/queue',
- 'controller': 'sprints/active'
- },
- listen: {
- 'endpoint': '/channel',
- 'controller': 'sprints/active'
- }
+ Product: {
+ validations: true,
+ lazy: true,
+ channel: '/channel/products',
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products',
+ 'method': '',
+ 'httpMethod': 'GET'
+ },
+ create: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products',
+ 'method': '',
+ 'httpMethod': 'POST'
+ },
+ update: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products',
+ 'method': '',
+ 'httpMethod': 'PUT'
+ },
+ remove: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products',
+ 'method': '',
+ 'httpMethod': 'DELETE'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'products'
+ }
+ },
+ FeatureRequest: {
+ validations: false,
+ channel: '/channel/internal/request',
+ push: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': 'push/:requestId/:productId/:rpmId',
+ 'httpMethod': 'PUT'
+ },
+ stats: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': 'stats',
+ 'httpMethod': 'GET'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'internal/request'
+ }
+ },
+ InternalRequest: {
+ validations: true,
+ lazy: true,
+ channel: '/channel/internal/request',
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': '',
+ 'httpMethod': 'GET'
+ },
+ create: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': '',
+ 'httpMethod': 'POST'
+ },
+ update: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': '',
+ 'httpMethod': 'PUT'
+ },
+ submitFeatureProposal: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': '',
+ 'httpMethod': 'PUT'
+ },
+ remove: {
+ 'endpoint': '/private/queue',
+ 'controller': 'internal/request',
+ 'method': '',
+ 'httpMethod': 'DELETE'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'internal/request',
+ 'method': ''
+ }
+ },
+ User: {
+ lazy: true,
+ channel: '/channel/users',
+ instantiate: {
+ 'endpoint': '/private/queue',
+ 'controller': 'users',
+ 'method': 'credentials'
+ },
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'users'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'users'
+ },
+ update: {
+ 'endpoint': '/private/queue',
+ 'controller': 'users',
+ 'method': 'update'
+ }
+ },
+ RemoteProjectManager: {
+ validations: true,
+ lazy: true,
+ channel: '/channel/remote-project-manager',
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'remote-project-manager',
+ 'method': '',
+ 'httpMethod': 'GET'
+ },
+ create: {
+ 'endpoint': '/private/queue',
+ 'controller': 'remote-project-manager',
+ 'method': '',
+ 'httpMethod': 'POST'
+ },
+ update: {
+ 'endpoint': '/private/queue',
+ 'controller': 'remote-project-manager',
+ 'method': '',
+ 'httpMethod': 'PUT'
+ },
+ remove: {
+ 'endpoint': '/private/queue',
+ 'controller': 'remote-project-manager',
+ 'method': '',
+ 'httpMethod': 'DELETE'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'remote-project-manager'
+ },
+ types: {
+ 'endpoint': '/channel',
+ 'controller': 'remote-project-manager',
+ 'method': 'types/',
+ 'httpMethod': 'GET'
+ },
+ scaffolding: {
+ 'endpoint': '/channel',
+ 'controller': 'remote-project-manager',
+ 'method': 'scaffolding/:type/',
+ 'httpMethod': 'GET'
+ }
+ },
+ Status: {
+ validations: true,
+ lazy: true,
+ channel: '/channel/status',
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'status',
+ 'method': '',
+ 'httpMethod': 'GET'
+ },
+ create: {
+ 'endpoint': '/private/queue',
+ 'controller': 'status',
+ 'method': '',
+ 'httpMethod': 'POST'
+ },
+ update: {
+ 'endpoint': '/private/queue',
+ 'controller': 'status',
+ 'method': '',
+ 'httpMethod': 'PUT'
+ },
+ remove: {
+ 'endpoint': '/private/queue',
+ 'controller': 'status',
+ 'method': '',
+ 'httpMethod': 'DELETE'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'status'
+ }
+ },
+ RemoteProjects: {
+ lazy: true,
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'projects/remote'
+ },
+ byProduct: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products',
+ 'method': 'remote-projects/:productId',
+ 'httpMethod': 'GET'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'projects/remote'
+ }
+ },
+ ProductsStats: {
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'products/stats'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'products/stats'
+ }
+ },
+ ActiveSprints: {
+ all: {
+ 'endpoint': '/private/queue',
+ 'controller': 'sprints/active'
+ },
+ listen: {
+ 'endpoint': '/channel',
+ 'controller': 'sprints/active'
}
-};
\ No newline at end of file
+ }
+};
diff --git a/app/config/routes.js b/app/config/routes.js
index 612db6b..7e15694 100644
--- a/app/config/routes.js
+++ b/app/config/routes.js
@@ -1,7 +1,7 @@
app.config(function ($routeProvider) {
$routeProvider.
when('/management', {
- redirectTo: '/management/projects'
+ redirectTo: '/management/products'
}).
when('/management/:tab', {
templateUrl: 'views/management.html',
@@ -31,4 +31,4 @@ app.config(function ($routeProvider) {
otherwise({
redirectTo: '/error/404'
});
-});
\ No newline at end of file
+});
diff --git a/app/controllers/activeSprintsController.js b/app/controllers/activeSprintsController.js
index d32855c..bd9fc41 100644
--- a/app/controllers/activeSprintsController.js
+++ b/app/controllers/activeSprintsController.js
@@ -19,7 +19,7 @@ app.controller('ActiveSprintsController', function ($controller, $sce, $scope, A
};
$scope.kanbanHeader = function () {
- return $scope.getSelectedSprint() ? $scope.getSelectedSprint().project + ": " + $scope.getSelectedSprint().name : "Select Sprint Above";
+ return $scope.getSelectedSprint() ? $scope.getSelectedSprint().product + ": " + $scope.getSelectedSprint().name : "Select Sprint Above";
};
$scope.getSprintEstimateTotal = function (sprint) {
@@ -76,4 +76,4 @@ app.controller('ActiveSprintsController', function ($controller, $sce, $scope, A
}
});
-});
\ No newline at end of file
+});
diff --git a/app/controllers/internalRequestController.js b/app/controllers/internalRequestController.js
new file mode 100644
index 0000000..f80dc31
--- /dev/null
+++ b/app/controllers/internalRequestController.js
@@ -0,0 +1,171 @@
+app.controller('InternalRequestController', function ($controller, $scope, ApiResponseActions, InternalRequestRepo, InternalRequestsService, ProductRepo, ProductsService, WsApi) {
+
+ angular.extend(this, $controller('AbstractController', {
+ $scope: $scope
+ }));
+
+ if ($scope.isManager() || $scope.isAdmin()) {
+ $scope.internalRequests = InternalRequestRepo.getAll();
+
+ $scope.internalRequestToCreate = InternalRequestRepo.getScaffold();
+ $scope.internalRequestToEdit = {};
+ $scope.internalRequestToDelete = {};
+
+ $scope.featureRequestToPush = {};
+
+ $scope.resetInternalRequestForms = function () {
+ InternalRequestRepo.clearValidationResults();
+
+ for (var key in $scope.internalRequestForms) {
+ if ($scope.internalRequestForms[key] !== undefined && !$scope.internalRequestForms[key].$pristine && $scope.internalRequestForms[key].$setPristine) {
+ $scope.internalRequestForms[key].$setPristine();
+ }
+ }
+
+ $scope.closeModal();
+ };
+
+ $scope.resetInternalRequestForms();
+
+ $scope.selectRemoteProjects = function () {
+ if ($scope.featureRequestToPush.product && $scope.featureRequestToPush.product.id) {
+ if (!$scope.remoteProjects[$scope.featureRequestToPush.product.id]) {
+ $scope.refreshRemoteProjectsForProduct($scope.featureRequestToPush.product.id);
+ }
+ }
+ };
+
+ $scope.refreshRemoteProjectsForProduct = function (productId) {
+ if (productId && !$scope.remoteProjectsLoading[productId]) {
+ ProductsService.refreshRemoteProjectsForProduct(productId);
+ }
+ };
+
+ $scope.addInternalRequest = function () {
+ if (!$scope.productsLoading) {
+ ProductsService.refreshProducts();
+ }
+
+ $scope.openModal('#addInternalRequestModal');
+ };
+
+ $scope.createInternalRequest = function () {
+ $scope.internalRequestToCreate.createdOn = new Date().getTime();
+
+ if (!$scope.productsLoading) {
+ ProductsService.refreshProducts();
+ }
+
+ InternalRequestRepo.create($scope.internalRequestToCreate).then(function (res) {
+ if (angular.fromJson(res.body).meta.status === 'SUCCESS') {
+ $scope.resetCreateInternalRequest();
+ }
+ });
+ };
+
+ $scope.resetCreateInternalRequest = function () {
+ angular.extend($scope.internalRequestToCreate, InternalRequestRepo.getScaffold());
+ $scope.resetInternalRequestForms();
+ };
+
+ $scope.pushInternalRequest = function (internalRequest) {
+ $scope.featureRequestToPush = {
+ id: internalRequest.id,
+ title: internalRequest.title,
+ description: internalRequest.description,
+ rpmId: null,
+ product: internalRequest.product,
+ scopeId: null
+ };
+
+ if (!$scope.productsLoading) {
+ ProductsService.refreshProducts();
+ }
+
+ $scope.openModal('#pushInternalRequestModal');
+ };
+
+ $scope.pushFeatureRequest = function () {
+ for (var key in $scope.products) {
+ if ($scope.products[key].id == $scope.featureRequestToPush.product.id) {
+ for (var k in $scope.products[key].remoteProjectInfo) {
+ if ($scope.products[key].remoteProjectInfo[k].scopeId == $scope.featureRequestToPush.scopeId) {
+ $scope.featureRequestToPush.rpmId = $scope.products[key].remoteProjectInfo[k].remoteProjectManager.id;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ InternalRequestsService.pushFeatureRequest($scope.featureRequestToPush).then(function (res) {
+ $scope.cancelPushFeatureRequest();
+ }).catch(function() {
+ $scope.cancelPushFeatureRequest();
+ });
+ };
+
+ $scope.cancelPushFeatureRequest = function () {
+ $scope.featureRequestToPush = {};
+ $scope.resetInternalRequestForms();
+ };
+
+ $scope.editInternalRequest = function (internalRequest) {
+ $scope.internalRequestToEdit = angular.copy(internalRequest);
+
+ if (!$scope.productsLoading) {
+ ProductsService.refreshProducts();
+ }
+
+ $scope.openModal('#editInternalRequestModal');
+ };
+
+ $scope.updateInternalRequest = function () {
+ $scope.internalRequestToEdit.dirty(true);
+ $scope.internalRequestToEdit.save().then(function () {
+ $scope.cancelEditInternalRequest();
+ });
+ };
+
+ $scope.cancelEditInternalRequest = function () {
+ $scope.internalRequestToEdit.refresh();
+ $scope.resetInternalRequestForms();
+ };
+
+ $scope.confirmDeleteInternalRequest = function (internalRequest) {
+ $scope.internalRequestToDelete = angular.copy(internalRequest);
+ $scope.openModal('#deleteInternalRequestModal');
+ };
+
+ $scope.cancelDeleteInternalRequest = function () {
+ $scope.internalRequestToDelete = {};
+ $scope.closeModal();
+ };
+
+ $scope.deleteInternalRequest = function (internalRequest) {
+ InternalRequestRepo.delete(internalRequest).then(function (res) {
+ if (angular.fromJson(res.body).meta.status === "SUCCESS") {
+ $scope.cancelDeleteInternalRequest();
+ }
+ });
+ };
+
+ ProductsService.ready.then(null, null, function () {
+ $scope.products = ProductsService.getProducts();
+ $scope.productsLoading = ProductsService.getProductsLoading();
+ $scope.remoteProjects = ProductsService.getRemoteProjects();
+ $scope.remoteProjectsLoading = ProductsService.getRemoteProjectsLoading();
+ });
+
+ InternalRequestRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () {
+ $scope.internalRequests.length = 0;
+
+ var internalRequests = InternalRequestRepo.getAll();
+ for (var i in internalRequests) {
+ $scope.internalRequests.push(internalRequests[i]);
+ }
+ });
+ }
+
+});
diff --git a/app/controllers/internalStatsController.js b/app/controllers/internalStatsController.js
new file mode 100644
index 0000000..5a902b5
--- /dev/null
+++ b/app/controllers/internalStatsController.js
@@ -0,0 +1,9 @@
+app.controller('InternalStatsController', function ($controller, $scope, ApiResponseActions, InternalRequestRepo, InternalStatsService) {
+
+ angular.extend(this, $controller('AbstractController', {
+ $scope: $scope
+ }));
+
+ $scope.stats = InternalStatsService.getStats();
+
+});
diff --git a/app/controllers/productController.js b/app/controllers/productController.js
new file mode 100644
index 0000000..0a8cfea
--- /dev/null
+++ b/app/controllers/productController.js
@@ -0,0 +1,148 @@
+app.controller('ProductController', function ($controller, $scope, ApiResponseActions, ProductRepo, RemoteProjectManagerRepo, RemoteProjectsService) {
+
+ angular.extend(this, $controller('AbstractController', {
+ $scope: $scope
+ }));
+
+ $scope.products = ProductRepo.getAll();
+
+ $scope.productToCreate = ProductRepo.getScaffold();
+
+ $scope.productToDelete = {};
+
+ $scope.addingRemoteProjectInfo = false;
+ $scope.remoteProjectInfoChanged = false;
+
+ $scope.remoteProjectInfoToAdd = {
+ remoteProjectManager: null,
+ scopeId: null
+ };
+
+ $scope.productForms = {
+ validations: ProductRepo.getValidations(),
+ getResults: ProductRepo.getValidationResults
+ };
+
+ $scope.closeAddRemoteProjectInfo = function() {
+ $scope.addingRemoteProjectInfo = false;
+ $scope.remoteProjectInfoToAdd = {
+ remoteProjectManager: null,
+ scopeId: null
+ };
+ };
+
+ $scope.resetProductForms = function () {
+ ProductRepo.clearValidationResults();
+ for (var key in $scope.productForms) {
+ if ($scope.productForms[key] !== undefined && !$scope.productForms[key].$pristine && $scope.productForms[key].$setPristine) {
+ $scope.productForms[key].$setPristine();
+ }
+ }
+ $scope.closeAddRemoteProjectInfo();
+ $scope.remoteProjectInfoChanged = false;
+ $scope.closeModal();
+ };
+
+ $scope.resetProductForms();
+
+ $scope.createProduct = function () {
+ ProductRepo.create($scope.productToCreate).then(function (res) {
+ if (angular.fromJson(res.body).meta.status === 'SUCCESS') {
+ $scope.resetCreateProduct();
+ }
+ });
+ };
+
+ $scope.resetCreateProduct = function () {
+ angular.extend($scope.productToCreate, ProductRepo.getScaffold());
+ $scope.resetProductForms();
+ };
+
+ $scope.editProduct = function (product) {
+ $scope.productToEdit = product;
+ $scope.openModal('#editProductModal');
+ };
+
+ $scope.updateProduct = function () {
+ $scope.productToEdit.dirty(true);
+ $scope.productToEdit.save().then(function () {
+ $scope.cancelEditProduct();
+ });
+ };
+
+ $scope.cancelEditProduct = function () {
+ $scope.productToEdit.refresh();
+ $scope.productToEdit = {};
+ $scope.resetProductForms();
+ };
+
+ $scope.confirmDeleteProduct = function (product) {
+ $scope.productToDelete = product;
+ $scope.openModal('#deleteProductModal');
+ };
+
+ $scope.cancelDeleteProduct = function () {
+ $scope.productToDelete = {};
+ $scope.closeModal();
+ };
+
+ $scope.deleteProduct = function (product) {
+ ProductRepo.delete(product).then(function (res) {
+ if (angular.fromJson(res.body).meta.status === "SUCCESS") {
+ $scope.cancelDeleteProduct();
+ }
+ });
+ };
+
+ $scope.openAddRemoteProjectInfo = function() {
+ $scope.addingRemoteProjectInfo = true;
+ };
+
+ $scope.addRemoteProjectInfo = function(remoteProjectInfo, remoteProject) {
+ remoteProjectInfo.push(remoteProject);
+ $scope.remoteProjectInfoChanged = true;
+ $scope.closeAddRemoteProjectInfo();
+ };
+
+ $scope.removeRemoteProjectInfo = function(remoteProjectInfo, remoteProject) {
+ remoteProjectInfo.splice(remoteProjectInfo.indexOf(remoteProject), 1);
+ $scope.remoteProjectInfoChanged = true;
+ };
+
+ if ($scope.isManager() || $scope.isAdmin()) {
+ $scope.remoteProjectManagers = RemoteProjectManagerRepo.getAll();
+
+ $scope.remoteProjectInfo = RemoteProjectsService.getRemoteProjectInfo();
+
+ $scope.getRemoteProjectManagerRemoteProjects = function (remoteProjectManagerId) {
+ return $scope.remoteProjectInfo[remoteProjectManagerId];
+ };
+
+ $scope.getRemoteProjectByRemoteProjectInfo = function(remoteProjectInfo) {
+ if (angular.isDefined(remoteProjectInfo.remoteProjectManager.id)) {
+ if (angular.isDefined($scope.remoteProjectInfo[remoteProjectInfo.remoteProjectManager.id])) {
+ return $scope.remoteProjectInfo[remoteProjectInfo.remoteProjectManager.id].filter(function(rp) {
+ return rp.id === remoteProjectInfo.scopeId;
+ })[0];
+ }
+ }
+ };
+
+ RemoteProjectManagerRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () {
+ $scope.remoteProjectManagers.length = 0;
+ var remoteProjectManagers = RemoteProjectManagerRepo.getAll();
+ for (var i in remoteProjectManagers) {
+ $scope.remoteProjectManagers.push(remoteProjectManagers[i]);
+ }
+ });
+ }
+
+ ProductRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () {
+ $scope.products.length = 0;
+ var products = ProductRepo.getAll();
+ for (var i in products) {
+ $scope.products.push(products[i]);
+ }
+ });
+
+});
diff --git a/app/controllers/projectController.js b/app/controllers/projectController.js
deleted file mode 100644
index e37d08c..0000000
--- a/app/controllers/projectController.js
+++ /dev/null
@@ -1,105 +0,0 @@
-app.controller('ProjectController', function ($controller, $scope, ApiResponseActions, ProjectRepo, RemoteProjectManagerRepo, RemoteProjectsService) {
-
- angular.extend(this, $controller('AbstractController', {
- $scope: $scope
- }));
-
- $scope.projects = ProjectRepo.getAll();
-
- $scope.projectToCreate = ProjectRepo.getScaffold();
-
- $scope.projectToDelete = {};
-
- $scope.projectForms = {
- validations: ProjectRepo.getValidations(),
- getResults: ProjectRepo.getValidationResults
- };
-
- $scope.resetProjectForms = function () {
- ProjectRepo.clearValidationResults();
- for (var key in $scope.projectForms) {
- if ($scope.projectForms[key] !== undefined && !$scope.projectForms[key].$pristine && $scope.projectForms[key].$setPristine) {
- $scope.projectForms[key].$setPristine();
- }
- }
- $scope.closeModal();
- };
-
- $scope.resetProjectForms();
-
- $scope.createProject = function () {
- ProjectRepo.create($scope.projectToCreate).then(function (res) {
- if (angular.fromJson(res.body).meta.status === 'SUCCESS') {
- $scope.resetCreateProject();
- }
- });
- };
-
- $scope.resetCreateProject = function () {
- angular.extend($scope.projectToCreate, ProjectRepo.getScaffold());
- $scope.resetProjectForms();
- };
-
- $scope.editProject = function (project) {
- $scope.projectToEdit = project;
- $scope.openModal('#editProjectModal');
- };
-
- $scope.updateProject = function () {
- $scope.projectToEdit.dirty(true);
- $scope.projectToEdit.save().then(function () {
- $scope.cancelEditProject();
- });
- };
-
- $scope.cancelEditProject = function () {
- $scope.projectToEdit.refresh();
- $scope.projectToEdit = {};
- $scope.resetProjectForms();
- };
-
- $scope.confirmDeleteProject = function (project) {
- $scope.projectToDelete = project;
- $scope.openModal('#deleteProjectModal');
- };
-
- $scope.cancelDeleteProject = function () {
- $scope.projectToDelete = {};
- $scope.closeModal();
- };
-
- $scope.deleteProject = function (project) {
- ProjectRepo.delete(project).then(function (res) {
- if (angular.fromJson(res.body).meta.status === "SUCCESS") {
- $scope.cancelDeleteProject();
- }
- });
- };
-
- if ($scope.isManager() || $scope.isAdmin()) {
- $scope.remoteProjectManagers = RemoteProjectManagerRepo.getAll();
-
- $scope.remoteProjects = RemoteProjectsService.getRemoteProjects();
-
- $scope.getRemoteProjectManagerRemoteProjects = function (remoteProjectManagerId) {
- return $scope.remoteProjects[remoteProjectManagerId];
- };
-
- RemoteProjectManagerRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () {
- $scope.remoteProjectManagers.length = 0;
- var remoteProjectManagers = RemoteProjectManagerRepo.getAll();
- for (var i in remoteProjectManagers) {
- $scope.remoteProjectManagers.push(remoteProjectManagers[i]);
- }
- });
- }
-
- ProjectRepo.listen([ApiResponseActions.CREATE, ApiResponseActions.DELETE, ApiResponseActions.UPDATE], function () {
- $scope.projects.length = 0;
- var projects = ProjectRepo.getAll();
- for (var i in projects) {
- $scope.projects.push(projects[i]);
- }
- });
-
-});
\ No newline at end of file
diff --git a/app/controllers/remoteProjectManagerController.js b/app/controllers/remoteProjectManagerController.js
index affc44a..39cb559 100644
--- a/app/controllers/remoteProjectManagerController.js
+++ b/app/controllers/remoteProjectManagerController.js
@@ -31,6 +31,11 @@ app.controller('RemoteProjectManagerController', function ($controller, $scope,
$scope.closeModal();
};
+ $scope.addRemoteProjectManager = function () {
+ $scope.resetCreateRemoteProjectManager();
+ $scope.openModal('#addRemoteProjectManagerModal');
+ };
+
$scope.createRemoteProjectManager = function () {
RemoteProjectManagerRepo.create($scope.remoteProjectManagerToCreate).then(function (res) {
if (angular.fromJson(res.body).meta.status === 'SUCCESS') {
@@ -98,4 +103,4 @@ app.controller('RemoteProjectManagerController', function ($controller, $scope,
}
});
-});
\ No newline at end of file
+});
diff --git a/app/directives/remoteProjectManagerFormDirective.js b/app/directives/remoteProjectManagerFormDirective.js
index 7cdf011..771b4a5 100644
--- a/app/directives/remoteProjectManagerFormDirective.js
+++ b/app/directives/remoteProjectManagerFormDirective.js
@@ -55,4 +55,4 @@ app.directive('remoteProjectManagerForm', function () {
};
}
};
-});
\ No newline at end of file
+});
diff --git a/app/filters/availableRemoteProjectFilter.js b/app/filters/availableRemoteProjectFilter.js
new file mode 100644
index 0000000..5af75f3
--- /dev/null
+++ b/app/filters/availableRemoteProjectFilter.js
@@ -0,0 +1,14 @@
+app.filter('availableRemoteProject', function() {
+ return function(input, usedRPs) {
+ if (!input) return false;
+ return input.filter(function(val) {
+ if (usedRPs) {
+ return !usedRPs.some(function(rp) {
+ return rp.scopeId === val.id;
+ });
+ } else {
+ return true;
+ }
+ });
+ };
+});
diff --git a/app/index.html b/app/index.html
index 7782293..d3155db 100644
--- a/app/index.html
+++ b/app/index.html
@@ -7,7 +7,7 @@
-
+
@@ -15,7 +15,7 @@
- Project Management :: Texas A&M Libraries
+ Product Management :: Texas A&M Libraries
@@ -38,7 +38,7 @@
-
+
@@ -196,29 +196,37 @@
-
-
+
+
+
+
+
+
-
+
+
-
+
+
-
+
+
+
@@ -246,4 +254,4 @@
-