DylanVolz closed pull request #2481: TP: adds the ability to crud api endpoints 
for roles/capabilities management
URL: https://github.com/apache/trafficcontrol/pull/2481
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/traffic_portal/app/src/app.js b/traffic_portal/app/src/app.js
index e72a3f373..7805968b2 100644
--- a/traffic_portal/app/src/app.js
+++ b/traffic_portal/app/src/app.js
@@ -131,6 +131,10 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./modules/private/divisions/list').name,
         require('./modules/private/divisions/new').name,
         require('./modules/private/divisions/regions').name,
+        require('./modules/private/endpoints').name,
+        require('./modules/private/endpoints/edit').name,
+        require('./modules/private/endpoints/list').name,
+        require('./modules/private/endpoints/new').name,
         require('./modules/private/iso').name,
         require('./modules/private/jobs').name,
         require('./modules/private/jobs/list').name,
@@ -232,12 +236,12 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/release').name,
 
         // forms
-        require('./common/modules/form/cacheGroup').name,
-        require('./common/modules/form/cacheGroup/edit').name,
-        require('./common/modules/form/cacheGroup/new').name,
         require('./common/modules/form/asn').name,
         require('./common/modules/form/asn/edit').name,
         require('./common/modules/form/asn/new').name,
+        require('./common/modules/form/cacheGroup').name,
+        require('./common/modules/form/cacheGroup/edit').name,
+        require('./common/modules/form/cacheGroup/new').name,
         require('./common/modules/form/capability').name,
         require('./common/modules/form/capability/edit').name,
         require('./common/modules/form/capability/new').name,
@@ -269,6 +273,9 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/form/division').name,
         require('./common/modules/form/division/edit').name,
         require('./common/modules/form/division/new').name,
+        require('./common/modules/form/endpoint').name,
+        require('./common/modules/form/endpoint/edit').name,
+        require('./common/modules/form/endpoint/new').name,
         require('./common/modules/form/federation').name,
         require('./common/modules/form/federation/edit').name,
         require('./common/modules/form/federation/new').name,
@@ -311,6 +318,7 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/form/user/register').name,
 
         // tables
+        require('./common/modules/table/asns').name,
         require('./common/modules/table/cacheGroups').name,
         require('./common/modules/table/cacheGroupAsns').name,
         require('./common/modules/table/cacheGroupParameters').name,
@@ -320,7 +328,6 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/table/capabilityEndpoints').name,
         require('./common/modules/table/capabilityUsers').name,
         require('./common/modules/table/changeLogs').name,
-        require('./common/modules/table/asns').name,
         require('./common/modules/table/cdns').name,
         require('./common/modules/table/cdnDeliveryServices').name,
         require('./common/modules/table/cdnFederations').name,
@@ -341,6 +348,7 @@ var trafficPortal = angular.module('trafficPortal', [
         require('./common/modules/table/deliveryServiceUsers').name,
         require('./common/modules/table/divisions').name,
         require('./common/modules/table/divisionRegions').name,
+        require('./common/modules/table/endpoints').name,
         require('./common/modules/table/jobs').name,
         require('./common/modules/table/origins').name,
         require('./common/modules/table/physLocations').name,
diff --git a/traffic_portal/app/src/common/api/EndpointService.js 
b/traffic_portal/app/src/common/api/EndpointService.js
index 49d498342..162a86b53 100644
--- a/traffic_portal/app/src/common/api/EndpointService.js
+++ b/traffic_portal/app/src/common/api/EndpointService.js
@@ -17,13 +17,55 @@
  * under the License.
  */
 
-var EndpointService = function(Restangular) {
+var EndpointService = function(Restangular, locationUtils, messageModel) {
 
        this.getEndpoints = function(queryParams) {
                return Restangular.all('api_capabilities').getList(queryParams);
        };
 
+       this.getEndpoint = function(id) {
+               return Restangular.one("api_capabilities", id).get();
+       };
+
+       this.createEndpoint = function(endpoint) {
+               return Restangular.service('api_capabilities').post(endpoint)
+                       .then(
+                               function() {
+                                       messageModel.setMessages([ { level: 
'success', text: 'Endpoint created' } ], true);
+                                       
locationUtils.navigateToPath('/endpoints');
+                               },
+                               function(fault) {
+                                       
messageModel.setMessages(fault.data.alerts, false);
+                               }
+                       );
+       };
+
+       this.updateEndpoint = function(endpoint) {
+               return endpoint.put()
+                       .then(
+                               function() {
+                                       messageModel.setMessages([ { level: 
'success', text: 'Endpoint updated' } ], false);
+                               },
+                               function(fault) {
+                                       
messageModel.setMessages(fault.data.alerts, false);
+                               }
+                       );
+       };
+
+       this.deleteEndpoint = function(id) {
+               return Restangular.one("api_capabilities", id).remove()
+                       .then(
+                               function() {
+                                       messageModel.setMessages([ { level: 
'success', text: 'Endpoint deleted' } ], true);
+                               },
+                               function(fault) {
+                                       
messageModel.setMessages(fault.data.alerts, true);
+                               }
+                       );
+       };
+
+
 };
 
-EndpointService.$inject = ['Restangular'];
+EndpointService.$inject = ['Restangular', 'locationUtils', 'messageModel'];
 module.exports = EndpointService;
diff --git 
a/traffic_portal/app/src/common/modules/form/endpoint/FormEndpointController.js 
b/traffic_portal/app/src/common/modules/form/endpoint/FormEndpointController.js
new file mode 100644
index 000000000..11dcebb6c
--- /dev/null
+++ 
b/traffic_portal/app/src/common/modules/form/endpoint/FormEndpointController.js
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var FormEndpointController = function(endpoint, $scope, formUtils, 
locationUtils, capabilityService) {
+
+       var getCapabilities = function() {
+               capabilityService.getCapabilities({ orderby: 'name' })
+                       .then(function(result) {
+                               $scope.capabilities = result;
+                       });
+       };
+
+       $scope.endpoint = endpoint;
+
+       $scope.methods = [
+               { value: 'GET', label: 'GET' },
+               { value: 'POST', label: 'POST' },
+               { value: 'PUT', label: 'PUT' },
+               { value: 'PATCH', label: 'PATCH' },
+               { value: 'DELETE', label: 'DELETE' }
+       ];
+
+       $scope.navigateToPath = locationUtils.navigateToPath;
+
+       $scope.hasError = formUtils.hasError;
+
+       $scope.hasPropertyError = formUtils.hasPropertyError;
+
+       var init = function () {
+               getCapabilities();
+       };
+       init();
+
+};
+
+FormEndpointController.$inject = ['endpoint', '$scope', 'formUtils', 
'locationUtils', 'capabilityService'];
+module.exports = FormEndpointController;
diff --git 
a/traffic_portal/app/src/common/modules/form/endpoint/edit/FormEditEndpointController.js
 
b/traffic_portal/app/src/common/modules/form/endpoint/edit/FormEditEndpointController.js
new file mode 100644
index 000000000..bcb52468a
--- /dev/null
+++ 
b/traffic_portal/app/src/common/modules/form/endpoint/edit/FormEditEndpointController.js
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var FormEditEndpointController = function(endpoint, $scope, $controller, 
$uibModal, $anchorScroll, locationUtils, endpointService) {
+
+       // extends the FormEndpointController to inherit common methods
+       angular.extend(this, $controller('FormEndpointController', { endpoint: 
endpoint, $scope: $scope }));
+
+       var deleteEndpoint = function(endpoint) {
+               endpointService.deleteEndpoint(endpoint.id)
+                       .then(function() {
+                               locationUtils.navigateToPath('/endpoints');
+                       });
+       };
+
+       $scope.endpointName = angular.copy(endpoint.httpMethod) + ' ' + 
angular.copy(endpoint.httpRoute);
+
+       $scope.settings = {
+               isNew: false,
+               saveLabel: 'Update'
+       };
+
+       $scope.save = function(endpoint) {
+               endpointService.updateEndpoint(endpoint).
+               then(function() {
+                       $scope.endpointName = angular.copy(endpoint.httpMethod) 
+ ' ' + angular.copy(endpoint.httpRoute);
+                       $anchorScroll(); // scrolls window to top
+               });
+       };
+
+       $scope.confirmDelete = function(endpoint) {
+               var params = {
+                       title: 'Delete Endpoint: ' + endpoint.httpMethod + ' ' 
+ endpoint.httpRoute,
+                       key: endpoint.httpMethod + ' ' + endpoint.httpRoute
+               };
+               var modalInstance = $uibModal.open({
+                       templateUrl: 
'common/modules/dialog/delete/dialog.delete.tpl.html',
+                       controller: 'DialogDeleteController',
+                       size: 'md',
+                       resolve: {
+                               params: function () {
+                                       return params;
+                               }
+                       }
+               });
+               modalInstance.result.then(function() {
+                       deleteEndpoint(endpoint);
+               }, function () {
+                       // do nothing
+               });
+       };
+
+};
+
+FormEditEndpointController.$inject = ['endpoint', '$scope', '$controller', 
'$uibModal', '$anchorScroll', 'locationUtils', 'endpointService'];
+module.exports = FormEditEndpointController;
diff --git a/traffic_portal/app/src/common/modules/form/endpoint/edit/index.js 
b/traffic_portal/app/src/common/modules/form/endpoint/edit/index.js
new file mode 100644
index 000000000..591cd4135
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/form/endpoint/edit/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.form.endpoint.edit', [])
+       .controller('FormEditEndpointController', 
require('./FormEditEndpointController'));
diff --git 
a/traffic_portal/app/src/common/modules/form/endpoint/form.endpoint.tpl.html 
b/traffic_portal/app/src/common/modules/form/endpoint/form.endpoint.tpl.html
new file mode 100644
index 000000000..d7791a16d
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/form/endpoint/form.endpoint.tpl.html
@@ -0,0 +1,64 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div class="x_panel">
+    <div class="x_title">
+        <ol class="breadcrumb">
+            <li><a ng-click="navigateToPath('/endpoints')">API 
Endpoints</a></li>
+            <li class="active">{{endpointName}}</li>
+        </ol>
+        <div class="clearfix"></div>
+    </div>
+    <div class="x_content">
+        <br>
+        <form name="endpointForm" class="form-horizontal form-label-left" 
novalidate>
+            <div class="form-group" ng-class="{'has-error': 
hasError(endpointForm.httpMethod), 'has-feedback': 
hasError(endpointForm.httpMethod)}">
+                <label class="control-label col-md-2 col-sm-2 col-xs-12">HTTP 
Method *</label>
+                <div class="col-md-10 col-sm-10 col-xs-12">
+                    <select name="httpMethod" class="form-control" 
ng-model="endpoint.httpMethod" ng-options="m.value as m.label for m in methods" 
required>
+                        <option value="">Select...</option>
+                    </select>
+                    <small class="input-error" 
ng-show="hasPropertyError(endpointForm.httpMethod, 'required')">Required</small>
+                </div>
+            </div>
+            <div class="form-group" ng-class="{'has-error': 
hasError(endpointForm.httpRoute), 'has-feedback': 
hasError(endpointForm.httpRoute)}">
+                <label class="control-label col-md-2 col-sm-2 col-xs-12">HTTP 
Route *</label>
+                <div class="col-md-10 col-sm-10 col-xs-12">
+                    <input name="httpRoute" type="text" class="form-control" 
placeholder="foos/*" ng-model="endpoint.httpRoute" ng-pattern="/^\S*$/" 
required autofocus>
+                    <small class="input-error" 
ng-show="hasPropertyError(endpointForm.httpRoute, 'required')">Required</small>
+                    <small class="input-error" 
ng-show="hasPropertyError(endpointForm.httpRoute, 'pattern')">No spaces</small>
+                    <span ng-show="hasError(endpointForm.httpRoute)" 
class="form-control-feedback"><i class="fa fa-times"></i></span>
+                </div>
+            </div>
+            <div class="form-group" ng-class="{'has-error': 
hasError(endpointForm.capability), 'has-feedback': 
hasError(endpointForm.capability)}">
+                <label class="control-label col-md-2 col-sm-2 
col-xs-12">Required Capability *</label>
+                <div class="col-md-10 col-sm-10 col-xs-12">
+                    <select name="capability" class="form-control" 
ng-model="endpoint.capability" ng-options="c.name as c.name for c in 
capabilities" required>
+                        <option value="">Select...</option>
+                    </select>
+                    <small class="input-error" 
ng-show="hasPropertyError(endpointForm.capability, 'required')">Required</small>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-danger" 
ng-show="!settings.isNew" ng-click="confirmDelete(endpoint)">Delete</button>
+                <button type="button" class="btn btn-success" 
ng-disabled="endpointForm.$pristine || endpointForm.$invalid" 
ng-click="save(endpoint)">{{settings.saveLabel}}</button>
+            </div>
+        </form>
+    </div>
+</div>
diff --git a/traffic_portal/app/src/common/modules/form/endpoint/index.js 
b/traffic_portal/app/src/common/modules/form/endpoint/index.js
new file mode 100644
index 000000000..b35959088
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/form/endpoint/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.form.endpoint', [])
+       .controller('FormEndpointController', 
require('./FormEndpointController'));
diff --git 
a/traffic_portal/app/src/common/modules/form/endpoint/new/FormNewEndpointController.js
 
b/traffic_portal/app/src/common/modules/form/endpoint/new/FormNewEndpointController.js
new file mode 100644
index 000000000..8a7d56e89
--- /dev/null
+++ 
b/traffic_portal/app/src/common/modules/form/endpoint/new/FormNewEndpointController.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var FormNewEndpointController = function(endpoint, $scope, $controller, 
endpointService) {
+
+       // extends the FormEndpointController to inherit common methods
+       angular.extend(this, $controller('FormEndpointController', { endpoint: 
endpoint, $scope: $scope }));
+
+       $scope.endpointName = 'New';
+
+       $scope.settings = {
+               isNew: true,
+               saveLabel: 'Create'
+       };
+
+       $scope.save = function(endpoint) {
+               endpointService.createEndpoint(endpoint);
+       };
+
+};
+
+FormNewEndpointController.$inject = ['endpoint', '$scope', '$controller', 
'endpointService'];
+module.exports = FormNewEndpointController;
diff --git a/traffic_portal/app/src/common/modules/form/endpoint/new/index.js 
b/traffic_portal/app/src/common/modules/form/endpoint/new/index.js
new file mode 100644
index 000000000..7d168d902
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/form/endpoint/new/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.form.endpoint.new', [])
+       .controller('FormNewEndpointController', 
require('./FormNewEndpointController'));
diff --git 
a/traffic_portal/app/src/common/modules/form/role/edit/FormEditRoleController.js
 
b/traffic_portal/app/src/common/modules/form/role/edit/FormEditRoleController.js
index cbcc5721b..2d90c4685 100644
--- 
a/traffic_portal/app/src/common/modules/form/role/edit/FormEditRoleController.js
+++ 
b/traffic_portal/app/src/common/modules/form/role/edit/FormEditRoleController.js
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-var FormEditRoleController = function(roles, useCapabilities, $scope, 
$controller, $uibModal, $anchorScroll, $location, locationUtils, roleService, 
messageModel) {
+var FormEditRoleController = function(roles, $scope, $controller, $uibModal, 
$anchorScroll, $location, locationUtils, roleService, messageModel, 
propertiesModel) {
 
        // extends the FormRoleController to inherit common methods
        angular.extend(this, $controller('FormRoleController', { roles: roles, 
$scope: $scope }));
@@ -39,7 +39,7 @@ var FormEditRoleController = function(roles, useCapabilities, 
$scope, $controlle
                        });
        };
 
-       $scope.useCapabilities = (useCapabilities[0]) ? 
useCapabilities[0].value : 0;
+       $scope.enforceCapabilities = 
propertiesModel.properties.enforceCapabilities;
 
        $scope.roleName = angular.copy($scope.role.name);
 
@@ -103,5 +103,5 @@ var FormEditRoleController = function(roles, 
useCapabilities, $scope, $controlle
 
 };
 
-FormEditRoleController.$inject = ['roles', 'useCapabilities', '$scope', 
'$controller', '$uibModal', '$anchorScroll', '$location', 'locationUtils', 
'roleService', 'messageModel'];
+FormEditRoleController.$inject = ['roles', '$scope', '$controller', 
'$uibModal', '$anchorScroll', '$location', 'locationUtils', 'roleService', 
'messageModel', 'propertiesModel'];
 module.exports = FormEditRoleController;
diff --git a/traffic_portal/app/src/common/modules/form/role/form.role.tpl.html 
b/traffic_portal/app/src/common/modules/form/role/form.role.tpl.html
index bc425be90..3ce2e37ae 100644
--- a/traffic_portal/app/src/common/modules/form/role/form.role.tpl.html
+++ b/traffic_portal/app/src/common/modules/form/role/form.role.tpl.html
@@ -24,7 +24,7 @@
             <li class="active">{{roleName}}</li>
         </ol>
         <div class="pull-right" role="group" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="View Capabilities" 
ng-if="useCapabilities == '1'" ng-click="viewCapabilities()">View 
Capabilities</button>
+            <button class="btn btn-primary" title="View Capabilities" 
ng-show="enforceCapabilities" ng-click="viewCapabilities()">View 
Capabilities</button>
             <!--<button class="btn btn-primary" title="View Users" 
ng-click="viewUsers()">View Users</button>-->
         </div>
         <div class="clearfix"></div>
diff --git 
a/traffic_portal/app/src/common/modules/navigation/NavigationController.js 
b/traffic_portal/app/src/common/modules/navigation/NavigationController.js
index e20273373..d993b4b81 100644
--- a/traffic_portal/app/src/common/modules/navigation/NavigationController.js
+++ b/traffic_portal/app/src/common/modules/navigation/NavigationController.js
@@ -21,6 +21,8 @@ var NavigationController = function($scope, $log, $state, 
$location, $window, $t
 
     $scope.appName = propertiesModel.properties.name;
 
+    $scope.enforceCapabilities = 
propertiesModel.properties.enforceCapabilities;
+
     $scope.customMenu = propertiesModel.properties.customMenu;
 
     $scope.showCacheChecks = propertiesModel.properties.cacheChecks.show;
diff --git 
a/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html 
b/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
index fe619ba97..5a2fd2b24 100644
--- a/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
+++ b/traffic_portal/app/src/common/modules/navigation/navigation.tpl.html
@@ -70,6 +70,8 @@
                         <li class="side-menu-category-item" 
ng-if="hasCapability('users-read')" ng-class="{'current-page': 
isState('trafficPortal.private.users')}"><a href="/#!/users">Users</a></li>
                         <li class="side-menu-category-item" 
ng-if="hasCapability('tenants-read')" ng-class="{'current-page': 
isState('trafficPortal.private.tenants')}"><a 
href="/#!/tenants">Tenants</a></li>
                         <li class="side-menu-category-item" 
ng-if="hasCapability('roles-read')" ng-class="{'current-page': 
isState('trafficPortal.private.roles')}"><a href="/#!/roles">Roles</a></li>
+                        <li class="side-menu-category-item" 
ng-if="enforceCapabilities && hasCapability('capabilities-read')" 
ng-class="{'current-page': isState('trafficPortal.private.capabilities')}"><a 
href="/#!/capabilities">Capabilities</a></li>
+                        <li class="side-menu-category-item" 
ng-if="enforceCapabilities && hasCapability('api-endpoints-read')" 
ng-class="{'current-page': isState('trafficPortal.private.endpoints')}"><a 
href="/#!/endpoints">API Endpoints</a></li>
                     </ul>
                 </li>
                 <li class="side-menu-category" ng-if="customMenu.items.length 
> 0"><a href="javascript:void(0);"><i class="fa fa-sm fa-chevron-right"></i> 
{{::customMenu.name}}</span></a>
diff --git 
a/traffic_portal/app/src/common/modules/table/endpoints/TableEndpointsController.js
 
b/traffic_portal/app/src/common/modules/table/endpoints/TableEndpointsController.js
new file mode 100644
index 000000000..2f10760a4
--- /dev/null
+++ 
b/traffic_portal/app/src/common/modules/table/endpoints/TableEndpointsController.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+var TableEndpointsController = function(endpoints, $scope, $state, 
locationUtils) {
+
+       $scope.endpoints = endpoints;
+
+       $scope.editEndpoint = function(id) {
+               locationUtils.navigateToPath('/endpoints/' + id);
+       };
+
+       $scope.createEndpoint = function() {
+               locationUtils.navigateToPath('/endpoints/new');
+       };
+
+       $scope.refresh = function() {
+               $state.reload(); // reloads all the resolves for the view
+       };
+
+       angular.element(document).ready(function () {
+               $('#endpointsTable').dataTable({
+                       "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, 
"All"]],
+                       "iDisplayLength": 25,
+                       "aaSorting": []
+               });
+       });
+
+};
+
+TableEndpointsController.$inject = ['endpoints', '$scope', '$state', 
'locationUtils'];
+module.exports = TableEndpointsController;
diff --git a/traffic_portal/app/src/common/modules/table/endpoints/index.js 
b/traffic_portal/app/src/common/modules/table/endpoints/index.js
new file mode 100644
index 000000000..169035a61
--- /dev/null
+++ b/traffic_portal/app/src/common/modules/table/endpoints/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.table.endpoints', [])
+       .controller('TableEndpointsController', 
require('./TableEndpointsController'));
diff --git 
a/traffic_portal/app/src/common/modules/table/endpoints/table.endpoints.tpl.html
 
b/traffic_portal/app/src/common/modules/table/endpoints/table.endpoints.tpl.html
new file mode 100644
index 000000000..44eef782d
--- /dev/null
+++ 
b/traffic_portal/app/src/common/modules/table/endpoints/table.endpoints.tpl.html
@@ -0,0 +1,51 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div class="x_panel">
+    <div class="x_title">
+        <ol class="breadcrumb pull-left">
+            <li class="active">API Endpoints</li>
+        </ol>
+        <div class="pull-right" role="group" ng-show="!settings.isNew">
+            <button class="btn btn-primary" title="Create Endpoint" 
ng-click="createEndpoint()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-default" title="Refresh" 
ng-click="refresh()"><i class="fa fa-refresh"></i></button>
+        </div>
+        <div class="clearfix"></div>
+    </div>
+    <div class="x_content">
+        <br>
+        <table id="endpointsTable" class="table responsive-utilities 
jambo_table">
+            <thead>
+            <tr class="headings">
+                <th>HTTP Method</th>
+                <th>HTTP Route</th>
+                <th>Required Capability</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr ng-click="editEndpoint(e.id)" ng-repeat="e in ::endpoints">
+                <td data-search="^{{::e.httpMethod}}$">{{::e.httpMethod}}</td>
+                <td data-search="^{{::e.httpRoute}}$">{{::e.httpRoute}}</td>
+                <td data-search="^{{::e.capability}}$">{{::e.capability}}</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
diff --git a/traffic_portal/app/src/modules/private/endpoints/edit/index.js 
b/traffic_portal/app/src/modules/private/endpoints/edit/index.js
new file mode 100644
index 000000000..868dfab97
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/endpoints/edit/index.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.endpoints.edit', [])
+       .config(function($stateProvider, $urlRouterProvider) {
+               $stateProvider
+                       .state('trafficPortal.private.endpoints.edit', {
+                               url: '/{endpointId:[0-9]{1,8}}',
+                               views: {
+                                       endpointsContent: {
+                                               templateUrl: 
'common/modules/form/endpoint/form.endpoint.tpl.html',
+                                               controller: 
'FormEditEndpointController',
+                                               resolve: {
+                                                       endpoint: 
function($stateParams, endpointService) {
+                                                               return 
endpointService.getEndpoint($stateParams.endpointId);
+                                                       }
+                                               }
+                                       }
+                               }
+                       })
+               ;
+               $urlRouterProvider.otherwise('/');
+       });
diff --git 
a/traffic_portal/app/src/modules/private/endpoints/endpoints.tpl.html 
b/traffic_portal/app/src/modules/private/endpoints/endpoints.tpl.html
new file mode 100644
index 000000000..080e642be
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/endpoints/endpoints.tpl.html
@@ -0,0 +1,22 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<div id="endpointsContainer">
+    <div ui-view="endpointsContent"></div>
+</div>
diff --git a/traffic_portal/app/src/modules/private/endpoints/index.js 
b/traffic_portal/app/src/modules/private/endpoints/index.js
new file mode 100644
index 000000000..f32e82346
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/endpoints/index.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.endpoints', [])
+       .config(function($stateProvider, $urlRouterProvider) {
+               $stateProvider
+                       .state('trafficPortal.private.endpoints', {
+                               url: 'endpoints',
+                               abstract: true,
+                               views: {
+                                       privateContent: {
+                                               templateUrl: 
'modules/private/endpoints/endpoints.tpl.html'
+                                       }
+                               }
+                       })
+               ;
+               $urlRouterProvider.otherwise('/');
+       });
diff --git a/traffic_portal/app/src/modules/private/endpoints/list/index.js 
b/traffic_portal/app/src/modules/private/endpoints/list/index.js
new file mode 100644
index 000000000..fb4003e36
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/endpoints/list/index.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.endpoints.list', [])
+       .config(function($stateProvider, $urlRouterProvider) {
+               $stateProvider
+                       .state('trafficPortal.private.endpoints.list', {
+                               url: '',
+                               views: {
+                                       endpointsContent: {
+                                               templateUrl: 
'common/modules/table/endpoints/table.endpoints.tpl.html',
+                                               controller: 
'TableEndpointsController',
+                                               resolve: {
+                                                       endpoints: 
function(endpointService) {
+                                                               return 
endpointService.getEndpoints();
+                                                       }
+                                               }
+                                       }
+                               }
+                       })
+               ;
+               $urlRouterProvider.otherwise('/');
+       });
diff --git a/traffic_portal/app/src/modules/private/endpoints/new/index.js 
b/traffic_portal/app/src/modules/private/endpoints/new/index.js
new file mode 100644
index 000000000..89cf783fd
--- /dev/null
+++ b/traffic_portal/app/src/modules/private/endpoints/new/index.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+module.exports = angular.module('trafficPortal.private.endpoints.new', [])
+       .config(function($stateProvider, $urlRouterProvider) {
+               $stateProvider
+                       .state('trafficPortal.private.endpoints.new', {
+                               url: '/new',
+                               views: {
+                                       endpointsContent: {
+                                               templateUrl: 
'common/modules/form/endpoint/form.endpoint.tpl.html',
+                                               controller: 
'FormNewEndpointController',
+                                               resolve: {
+                                                       endpoint: function() {
+                                                               return {};
+                                                       }
+                                               }
+                                       }
+                               }
+                       })
+               ;
+               $urlRouterProvider.otherwise('/');
+       });
diff --git a/traffic_portal/app/src/modules/private/roles/edit/index.js 
b/traffic_portal/app/src/modules/private/roles/edit/index.js
index 64eeb38b6..df12cc625 100644
--- a/traffic_portal/app/src/modules/private/roles/edit/index.js
+++ b/traffic_portal/app/src/modules/private/roles/edit/index.js
@@ -29,9 +29,6 @@ module.exports = 
angular.module('trafficPortal.private.roles.edit', [])
                                                resolve: {
                                                        roles: 
function($stateParams, roleService) {
                                                                return 
roleService.getRoles({ id: $stateParams.roleId });
-                                                       },
-                                                       useCapabilities: 
function(parameterService) {
-                                                               return 
parameterService.getParameters({ name: 'use_capabilities', configFile: 'global' 
});
                                                        }
                                                }
                                        }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to