mirror of
https://github.com/ansible/awx.git
synced 2026-05-06 08:57:35 -02:30
Merge pull request #232 from joefiorini/breadcrumbs-directive
Move breadcrumb rendering into directive
This commit is contained in:
@@ -34,6 +34,7 @@ import dataServices from 'tower/services/_data-services';
|
|||||||
import dashboardGraphs from 'tower/directives/_dashboard-graphs';
|
import dashboardGraphs from 'tower/directives/_dashboard-graphs';
|
||||||
|
|
||||||
import routeExtensions from 'tower/shared/route-extensions/main';
|
import routeExtensions from 'tower/shared/route-extensions/main';
|
||||||
|
import breadcrumbs from 'tower/shared/breadcrumbs/main';
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
import browserData from 'tower/browser-data/main';
|
import browserData from 'tower/browser-data/main';
|
||||||
@@ -78,6 +79,7 @@ var tower = angular.module('Tower', [
|
|||||||
dashboardGraphs.name,
|
dashboardGraphs.name,
|
||||||
routeExtensions.name,
|
routeExtensions.name,
|
||||||
browserData.name,
|
browserData.name,
|
||||||
|
breadcrumbs.name,
|
||||||
'AuthService',
|
'AuthService',
|
||||||
'Utilities',
|
'Utilities',
|
||||||
'LicenseHelper',
|
'LicenseHelper',
|
||||||
|
|||||||
@@ -90,8 +90,6 @@ export function CredentialsList($scope, $rootScope, $location, $log, $routeParam
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
LoadBreadCrumbs();
|
|
||||||
|
|
||||||
$scope.showActivity = function () {
|
$scope.showActivity = function () {
|
||||||
Stream({ scope: $scope });
|
Stream({ scope: $scope });
|
||||||
};
|
};
|
||||||
@@ -148,7 +146,6 @@ export function CredentialsAdd($scope, $rootScope, $compile, $location, $log, $r
|
|||||||
|
|
||||||
generator.inject(form, { mode: 'add', related: false, scope: $scope });
|
generator.inject(form, { mode: 'add', related: false, scope: $scope });
|
||||||
generator.reset();
|
generator.reset();
|
||||||
LoadBreadCrumbs();
|
|
||||||
|
|
||||||
// Load the list of options for Kind
|
// Load the list of options for Kind
|
||||||
GetChoices({
|
GetChoices({
|
||||||
@@ -372,12 +369,10 @@ export function CredentialsEdit($scope, $rootScope, $compile, $location, $log, $
|
|||||||
Rest.get({ params: { id: id } })
|
Rest.get({ params: { id: id } })
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
|
|
||||||
|
$scope.credential_name = data.name;
|
||||||
|
|
||||||
var i, fld;
|
var i, fld;
|
||||||
|
|
||||||
LoadBreadCrumbs({
|
|
||||||
path: '/credentials/' + id,
|
|
||||||
title: data.name
|
|
||||||
});
|
|
||||||
|
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (data[fld] !== null && data[fld] !== undefined) {
|
if (data[fld] !== null && data[fld] !== undefined) {
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ export function InventoriesAdd($scope, $rootScope, $compile, $location, $log, $r
|
|||||||
form.formLabelSize = null;
|
form.formLabelSize = null;
|
||||||
form.formFieldSize = null;
|
form.formFieldSize = null;
|
||||||
|
|
||||||
generator.inject(form, { mode: 'add', related: false, scope: $scope });
|
generator.inject(form, { mode: 'add', related: false, scope: $scope, breadcrumbs: true });
|
||||||
|
|
||||||
generator.reset();
|
generator.reset();
|
||||||
LoadBreadCrumbs();
|
LoadBreadCrumbs();
|
||||||
@@ -480,7 +480,7 @@ export function InventoriesEdit($scope, $rootScope, $compile, $location, $log, $
|
|||||||
form.formLabelSize = null;
|
form.formLabelSize = null;
|
||||||
form.formFieldSize = null;
|
form.formFieldSize = null;
|
||||||
$scope.inventory_id = inventory_id;
|
$scope.inventory_id = inventory_id;
|
||||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
generator.inject(form, { mode: 'edit', related: true, scope: $scope, breadcrumbs: true });
|
||||||
|
|
||||||
generator.reset();
|
generator.reset();
|
||||||
|
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ export function JobTemplatesAdd($scope, $rootScope, $compile, $location, $log, $
|
|||||||
|
|
||||||
CallbackHelpInit({ scope: $scope });
|
CallbackHelpInit({ scope: $scope });
|
||||||
$scope.can_edit = true;
|
$scope.can_edit = true;
|
||||||
generator.inject(form, { mode: 'add', related: false, scope: $scope });
|
generator.inject(form, { mode: 'add', related: false, scope: $scope, breadcrumbs: true });
|
||||||
|
|
||||||
callback = function() {
|
callback = function() {
|
||||||
// Make sure the form controller knows there was a change
|
// Make sure the form controller knows there was a change
|
||||||
@@ -674,7 +674,7 @@ export function JobTemplatesEdit($scope, $rootScope, $compile, $location, $log,
|
|||||||
CallbackHelpInit({ scope: $scope });
|
CallbackHelpInit({ scope: $scope });
|
||||||
|
|
||||||
SchedulesList.well = false;
|
SchedulesList.well = false;
|
||||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
generator.inject(form, { mode: 'edit', related: true, scope: $scope, breadcrumbs: true });
|
||||||
$scope.mode = 'edit';
|
$scope.mode = 'edit';
|
||||||
$scope.parseType = 'yaml';
|
$scope.parseType = 'yaml';
|
||||||
$scope.showJobType = false;
|
$scope.showJobType = false;
|
||||||
|
|||||||
@@ -166,6 +166,8 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
|||||||
id = $routeParams.organization_id,
|
id = $routeParams.organization_id,
|
||||||
relatedSets = {};
|
relatedSets = {};
|
||||||
|
|
||||||
|
$scope.organization_id = id;
|
||||||
|
|
||||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope});
|
generator.inject(form, { mode: 'edit', related: true, scope: $scope});
|
||||||
generator.reset();
|
generator.reset();
|
||||||
|
|
||||||
@@ -186,7 +188,7 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
|||||||
Rest.get()
|
Rest.get()
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
var fld, related, set;
|
var fld, related, set;
|
||||||
LoadBreadCrumbs({ path: '/organizations/' + id, title: data.name });
|
$scope.organization_name = data.name;
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (data[fld]) {
|
if (data[fld]) {
|
||||||
$scope[fld] = data[fld];
|
$scope[fld] = data[fld];
|
||||||
@@ -225,6 +227,7 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
|||||||
Rest.put(params)
|
Rest.put(params)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
|
$scope.organization_name = $scope.name;
|
||||||
master = params;
|
master = params;
|
||||||
$rootScope.flashMessage = "Your changes were successfully saved!";
|
$rootScope.flashMessage = "Your changes were successfully saved!";
|
||||||
})
|
})
|
||||||
@@ -293,4 +296,4 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
|||||||
OrganizationsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', 'GenerateForm',
|
OrganizationsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', 'GenerateForm',
|
||||||
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath',
|
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath',
|
||||||
'Wait', 'Stream'
|
'Wait', 'Stream'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ export function ProjectsAdd($scope, $rootScope, $compile, $location, $log, $rout
|
|||||||
defaultUrl = GetBasePath('projects'),
|
defaultUrl = GetBasePath('projects'),
|
||||||
master = {};
|
master = {};
|
||||||
|
|
||||||
generator.inject(form, { mode: 'add', related: false, scope: $scope });
|
generator.inject(form, { mode: 'add', related: false, scope: $scope, breadcrumbs: true });
|
||||||
generator.reset();
|
generator.reset();
|
||||||
LoadBreadCrumbs();
|
LoadBreadCrumbs();
|
||||||
|
|
||||||
@@ -557,7 +557,8 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log, $rou
|
|||||||
generator.inject(form, {
|
generator.inject(form, {
|
||||||
mode: 'edit',
|
mode: 'edit',
|
||||||
related: true,
|
related: true,
|
||||||
scope: $scope
|
scope: $scope,
|
||||||
|
breadcrumbs: true
|
||||||
});
|
});
|
||||||
generator.reset();
|
generator.reset();
|
||||||
|
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
id = $routeParams.team_id,
|
id = $routeParams.team_id,
|
||||||
relatedSets = {};
|
relatedSets = {};
|
||||||
|
|
||||||
|
$scope.team_id = id;
|
||||||
|
|
||||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
||||||
generator.reset();
|
generator.reset();
|
||||||
|
|
||||||
@@ -234,7 +236,7 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
})
|
})
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
var fld, related, set;
|
var fld, related, set;
|
||||||
LoadBreadCrumbs({ path: '/teams/' + id, title: data.name });
|
$scope.team_name = data.name;
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (data[fld]) {
|
if (data[fld]) {
|
||||||
$scope[fld] = data[fld];
|
$scope[fld] = data[fld];
|
||||||
@@ -296,6 +298,7 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
.success(function () {
|
.success(function () {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
var base = $location.path().replace(/^\//, '').split('/')[0];
|
var base = $location.path().replace(/^\//, '').split('/')[0];
|
||||||
|
$scope.team_name = $scope.name;
|
||||||
if (base === 'teams') {
|
if (base === 'teams') {
|
||||||
ReturnToCaller();
|
ReturnToCaller();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,8 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
Rest.setUrl(defaultUrl + ':id/');
|
Rest.setUrl(defaultUrl + ':id/');
|
||||||
Rest.get({ params: { id: id } })
|
Rest.get({ params: { id: id } })
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
LoadBreadCrumbs({ path: '/users/' + id, title: data.username });
|
$scope.user_id = id;
|
||||||
|
$scope.username_title = data.username;
|
||||||
var fld, related, set;
|
var fld, related, set;
|
||||||
for (fld in form.fields) {
|
for (fld in form.fields) {
|
||||||
if (data[fld]) {
|
if (data[fld]) {
|
||||||
@@ -325,6 +326,7 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
|||||||
Rest.put(data)
|
Rest.put(data)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
|
$scope.username_title = $scope.username;
|
||||||
var base = $location.path().replace(/^\//, '').split('/')[0];
|
var base = $location.path().replace(/^\//, '').split('/')[0];
|
||||||
if (base === 'users') {
|
if (base === 'users') {
|
||||||
ReturnToCaller();
|
ReturnToCaller();
|
||||||
|
|||||||
26
awx/ui/static/js/shared/breadcrumbs/breadcrumb.directive.js
Normal file
26
awx/ui/static/js/shared/breadcrumbs/breadcrumb.directive.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export default function() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
require: '^breadcrumbs',
|
||||||
|
transclude: true,
|
||||||
|
scope: {
|
||||||
|
path: '@',
|
||||||
|
title: '@',
|
||||||
|
current: '@'
|
||||||
|
},
|
||||||
|
link: function(scope, element, attrs, parentController) {
|
||||||
|
var breadcrumb =
|
||||||
|
parentController.addBreadcrumb(scope.title, scope.path, scope.current);
|
||||||
|
|
||||||
|
scope.$watch('title', function(value) {
|
||||||
|
breadcrumb.title = value;
|
||||||
|
|
||||||
|
if (breadcrumb.isCurrent && value) {
|
||||||
|
parentController.setHidden(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
export default
|
||||||
|
[ '$scope',
|
||||||
|
'$rootScope',
|
||||||
|
function($scope, $rootScope) {
|
||||||
|
|
||||||
|
$scope.breadcrumbs = [];
|
||||||
|
|
||||||
|
this.addBreadcrumb = function(title, path) {
|
||||||
|
var breadcrumb =
|
||||||
|
{ title: title,
|
||||||
|
path: path
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($rootScope.enteredPath === path) {
|
||||||
|
breadcrumb.isCurrent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.breadcrumbs =
|
||||||
|
$scope.breadcrumbs.concat(breadcrumb);
|
||||||
|
|
||||||
|
return breadcrumb;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setHidden = function(hidden) {
|
||||||
|
|
||||||
|
if (angular.isUndefined(hidden)) {
|
||||||
|
$scope.isHidden = true;
|
||||||
|
} else {
|
||||||
|
$scope.isHidden = hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}];
|
||||||
32
awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js
Normal file
32
awx/ui/static/js/shared/breadcrumbs/breadcrumbs.directive.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* jshint unused: vars */
|
||||||
|
|
||||||
|
import controller from './breadcrumbs.controller';
|
||||||
|
import 'tower/shared/generator-helpers';
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
controller: controller,
|
||||||
|
transclude: true,
|
||||||
|
templateUrl: '/static/js/shared/breadcrumbs/breadcrumbs.partial.html',
|
||||||
|
scope: {
|
||||||
|
},
|
||||||
|
link: function(scope, element, attrs, controller) {
|
||||||
|
// make breadcrumbs hidden until the current
|
||||||
|
// breadcrumb has a title; this avoids
|
||||||
|
// ugly rendering when an object's title
|
||||||
|
// is fetched via ajax
|
||||||
|
//
|
||||||
|
controller.setHidden();
|
||||||
|
|
||||||
|
scope.$watch('isHidden', function(value) {
|
||||||
|
if (value) {
|
||||||
|
element.hide();
|
||||||
|
} else {
|
||||||
|
element.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<ul class="ansible-breadcrumb" id="breadcrumb-list">
|
||||||
|
<li ng-repeat="crumb in breadcrumbs" ng-class="{active: crumb.isCurrent}">
|
||||||
|
<a href="{{'#' + crumb.path }}">
|
||||||
|
{{crumb.title}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- empty trasncluded div required to make child directives link up -->
|
||||||
|
<div ng-transclude></div>
|
||||||
7
awx/ui/static/js/shared/breadcrumbs/main.js
Normal file
7
awx/ui/static/js/shared/breadcrumbs/main.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import breadcrumbs from './breadcrumbs.directive';
|
||||||
|
import breadcrumb from './breadcrumb.directive';
|
||||||
|
|
||||||
|
export default
|
||||||
|
angular.module('breadcrumbs', [])
|
||||||
|
.directive('breadcrumb', breadcrumb)
|
||||||
|
.directive('breadcrumbs', breadcrumbs);
|
||||||
@@ -1441,7 +1441,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
|||||||
var btn, button, fld, field, html = '', i, section, group,
|
var btn, button, fld, field, html = '', i, section, group,
|
||||||
tab, sectionShow, offset, width,ngDisabled;
|
tab, sectionShow, offset, width,ngDisabled;
|
||||||
|
|
||||||
if (!this.modal && (options.breadCrumbs === undefined || options.breadCrumbs === true)) {
|
if (!this.modal && (options.breadcrumbs === true)) {
|
||||||
if (this.form.navigationLinks) {
|
if (this.form.navigationLinks) {
|
||||||
html += this.breadCrumbs(options, this.form.navigationLinks);
|
html += this.breadCrumbs(options, this.form.navigationLinks);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -346,8 +346,9 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
|||||||
|
|
||||||
// Generate breadcrumbs using the list-generator.js method.
|
// Generate breadcrumbs using the list-generator.js method.
|
||||||
|
|
||||||
var list = params.list,
|
var list = params.list || {},
|
||||||
mode = params.mode,
|
mode = params.mode,
|
||||||
|
title = params.title,
|
||||||
html = '', itm, navigation;
|
html = '', itm, navigation;
|
||||||
|
|
||||||
html += "<ul class=\"ansible-breadcrumb\" id=\"breadcrumb-list\">\n";
|
html += "<ul class=\"ansible-breadcrumb\" id=\"breadcrumb-list\">\n";
|
||||||
@@ -393,7 +394,10 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
|||||||
html += "</div><!-- dropdown -->\n";
|
html += "</div><!-- dropdown -->\n";
|
||||||
} else {
|
} else {
|
||||||
html += "<li class=\"active\"><a href=\"\">";
|
html += "<li class=\"active\"><a href=\"\">";
|
||||||
if (mode === 'select') {
|
// Support usage without a mode by just passing a title option
|
||||||
|
if (title) {
|
||||||
|
html += title;
|
||||||
|
} else if (mode === 'select') {
|
||||||
html += list.selectTitle;
|
html += list.selectTitle;
|
||||||
} else {
|
} else {
|
||||||
html += list.editTitle;
|
html += list.editTitle;
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
<breadcrumbs>
|
||||||
|
<breadcrumb path="/credentials" title="Credentials"></breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/credentials/add"
|
||||||
|
title="Create Credential"
|
||||||
|
ng-if="mode == 'add'">
|
||||||
|
</breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/credentials/{{id}}"
|
||||||
|
title="{{credential_name}}"
|
||||||
|
ng-if="id">
|
||||||
|
</breadcrumb>
|
||||||
|
</breadcrumbs>
|
||||||
|
|
||||||
<div class="tab-pane" id="credentials">
|
<div class="tab-pane" id="credentials">
|
||||||
<div ng-cloak id="htmlTemplate"></div>
|
<div ng-cloak id="htmlTemplate"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
<breadcrumbs>
|
||||||
|
<breadcrumb path="/organizations" title="Organizations"></breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/organizations/add"
|
||||||
|
title="Create Organization"
|
||||||
|
ng-if="mode == 'add'">
|
||||||
|
</breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/organizations/{{organization_id}}"
|
||||||
|
title="{{organization_name}}"
|
||||||
|
ng-if="organization_id">
|
||||||
|
</breadcrumb>
|
||||||
|
</breadcrumbs>
|
||||||
|
|
||||||
<div class="tab-pane" id="organizations">
|
<div class="tab-pane" id="organizations">
|
||||||
<div ng-cloak id="htmlTemplate"></div>
|
<div ng-cloak id="htmlTemplate"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
<breadcrumbs>
|
||||||
|
<breadcrumb path="/teams" title="Teams"></breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/teams/add"
|
||||||
|
title="Create Team"
|
||||||
|
ng-if="mode == 'add'">
|
||||||
|
</breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/teams/{{team_id}}"
|
||||||
|
title="{{team_name}}"
|
||||||
|
ng-if="team_id">
|
||||||
|
</breadcrumb>
|
||||||
|
</breadcrumbs>
|
||||||
|
|
||||||
<div class="tab-pane" id="teams">
|
<div class="tab-pane" id="teams">
|
||||||
<div ng-cloak id="htmlTemplate"></div>
|
<div ng-cloak id="htmlTemplate"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
<breadcrumbs>
|
||||||
|
<breadcrumb path="/users" title="Users"></breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/users/add"
|
||||||
|
title="Create User"
|
||||||
|
ng-if="mode == 'add'">
|
||||||
|
</breadcrumb>
|
||||||
|
<breadcrumb
|
||||||
|
path="/users/{{user_id}}"
|
||||||
|
title="{{username_title}}"
|
||||||
|
ng-if="user_id">
|
||||||
|
</breadcrumb>
|
||||||
|
</breadcrumbs>
|
||||||
|
|
||||||
<div class="tab-pane" id="users">
|
<div class="tab-pane" id="users">
|
||||||
<div ng-cloak id="htmlTemplate"></div>
|
<div ng-cloak id="htmlTemplate"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user