Merge pull request #1679 from leigh-johnson/DashboardHosts

Dashboard Hosts, Form Generator headerFields options
This commit is contained in:
Leigh
2016-04-27 10:46:28 -04:00
19 changed files with 421 additions and 190 deletions

View File

@@ -15,12 +15,25 @@
flex-direction: row; flex-direction: row;
} }
.Form-textArea{
width: 100% !important;
}
.Form-header--fields{
flex: 1 1 auto;
}
.Form-header-field{
margin-left: 10px;
flex: 1 1 auto;
}
.Form-header{ .Form-header{
display: flex; display: flex;
} }
.Form-title{ .Form-title{
flex: 1 0 auto; flex: 0 1 auto;
text-transform: uppercase; text-transform: uppercase;
color: @list-header-txt; color: @list-header-txt;
font-size: 14px; font-size: 14px;

View File

@@ -21,7 +21,7 @@ import './lists';
import './widgets'; import './widgets';
import './help'; import './help';
import './filters'; import './filters';
import {Home, HomeGroups, HomeHosts} from './controllers/Home'; import {Home, HomeGroups} from './controllers/Home';
import {SocketsController} from './controllers/Sockets'; import {SocketsController} from './controllers/Sockets';
import {CredentialsAdd, CredentialsEdit, CredentialsList} from './controllers/Credentials'; import {CredentialsAdd, CredentialsEdit, CredentialsList} from './controllers/Credentials';
import {JobsListController} from './controllers/Jobs'; import {JobsListController} from './controllers/Jobs';
@@ -173,7 +173,6 @@ var tower = angular.module('Tower', [
'CredentialsHelper', 'CredentialsHelper',
'StreamListDefinition', 'StreamListDefinition',
'HomeGroupListDefinition', 'HomeGroupListDefinition',
'HomeHostListDefinition',
'ActivityDetailDefinition', 'ActivityDetailDefinition',
'VariablesHelper', 'VariablesHelper',
'SchedulesListDefinition', 'SchedulesListDefinition',
@@ -267,25 +266,6 @@ var tower = angular.module('Tower', [
} }
}). }).
state('dashboardHosts', {
url: '/home/hosts?has_active_failures&name&id',
templateUrl: urlPrefix + 'partials/subhome.html',
controller: HomeHosts,
data: {
activityStream: true,
activityStreamTarget: 'host'
},
ncyBreadcrumb: {
parent: 'dashboard',
label: "HOSTS"
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}]
}
}).
state('jobs', { state('jobs', {
url: '/jobs', url: '/jobs',
templateUrl: urlPrefix + 'partials/jobs.html', templateUrl: urlPrefix + 'partials/jobs.html',

View File

@@ -1,5 +1,5 @@
/************************************************* /*************************************************
* Copyright (c) 2015 Ansible, Inc. * Copyright (c) 2016 Ansible, Inc.
* *
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
@@ -155,7 +155,6 @@ export function HomeGroups($rootScope, $log, $scope, $filter, $compile, $locatio
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope. //scope.
var generator = GenerateList, var generator = GenerateList,
list = HomeGroupList, list = HomeGroupList,
defaultUrl = GetBasePath('groups'), defaultUrl = GetBasePath('groups'),
@@ -516,112 +515,3 @@ HomeGroups.$inject = ['$rootScope', '$log', '$scope', '$filter', '$compile', '$l
* @description This loads the page for 'home/hosts' * @description This loads the page for 'home/hosts'
* *
*/ */
export function HomeHosts($scope, $location, $stateParams, HomeHostList, GenerateList, ProcessErrors, ReturnToCaller, ClearScope,
GetBasePath, SearchInit, PaginateInit, FormatDate, SetStatus, ToggleHostEnabled, HostsEdit, Find, ShowJobSummary) {
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
var generator = GenerateList,
list = HomeHostList,
defaultUrl = GetBasePath('hosts');
if ($scope.removePostRefresh) {
$scope.removePostRefresh();
}
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
for (var i = 0; i < $scope.hosts.length; i++) {
$scope.hosts[i].inventory_name = $scope.hosts[i].summary_fields.inventory.name;
//SetHostStatus($scope['hosts'][i]);
SetStatus({
$scope: $scope,
host: $scope.hosts[i]
});
}
generator.inject(list, { mode: 'edit', scope: $scope });
});
SearchInit({
scope: $scope,
set: 'hosts',
list: list,
url: defaultUrl
});
PaginateInit({
scope: $scope,
list: list,
url: defaultUrl
});
// Process search params
if ($stateParams.name) {
$scope[HomeHostList.iterator + 'InputDisable'] = false;
$scope[HomeHostList.iterator + 'SearchValue'] = $stateParams.name;
$scope[HomeHostList.iterator + 'SearchField'] = 'name';
$scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields.name.label;
}
if ($stateParams.id) {
$scope[HomeHostList.iterator + 'InputDisable'] = false;
$scope[HomeHostList.iterator + 'SearchValue'] = $stateParams.id;
$scope[HomeHostList.iterator + 'SearchField'] = 'id';
$scope[HomeHostList.iterator + 'SearchFieldLabel'] = list.fields.id.label;
$scope[HomeHostList.iterator + 'SearchSelectValue'] = null;
}
if ($stateParams.has_active_failures) {
$scope[HomeHostList.iterator + 'InputDisable'] = true;
$scope[HomeHostList.iterator + 'SearchValue'] = $stateParams.has_active_failures;
$scope[HomeHostList.iterator + 'SearchField'] = 'has_active_failures';
$scope[HomeHostList.iterator + 'SearchFieldLabel'] = HomeHostList.fields.has_active_failures.label;
$scope[HomeHostList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? { value: 1 } : { value: 0 };
}
$scope.search(list.iterator);
$scope.refreshHosts = function() {
$scope.search(list.iterator);
};
$scope.toggleHostEnabled = function (id, sources) {
ToggleHostEnabled({
host_id: id,
external_source: sources,
host_scope: $scope
});
};
$scope.editHost = function (host_id) {
var host = Find({
list: $scope.hosts,
key: 'id',
val: host_id
});
if (host) {
HostsEdit({
host_scope: $scope,
host_id: host_id,
inventory_id: host.inventory,
group_id: null,
hostsReload: false,
mode: 'edit'
});
}
};
$scope.showJobSummary = function (job_id) {
ShowJobSummary({
job_id: job_id
});
};
}
HomeHosts.$inject = ['$scope', '$location', '$stateParams', 'HomeHostList', 'generateList', 'ProcessErrors', 'ReturnToCaller',
'ClearScope', 'GetBasePath', 'SearchInit', 'PaginateInit', 'FormatDate', 'SetStatus', 'ToggleHostEnabled', 'HostsEdit',
'Find', 'ShowJobSummary'
];

View File

@@ -28,7 +28,6 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
mode = (base === 'projects') ? 'edit' : 'select', mode = (base === 'projects') ? 'edit' : 'select',
url = (base === 'teams') ? GetBasePath('teams') + $stateParams.team_id + '/projects/' : defaultUrl, url = (base === 'teams') ? GetBasePath('teams') + $stateParams.team_id + '/projects/' : defaultUrl,
choiceCount = 0; choiceCount = 0;
view.inject(list, { mode: mode, scope: $scope }); view.inject(list, { mode: mode, scope: $scope });
$rootScope.flashMessage = null; $rootScope.flashMessage = null;

View File

@@ -0,0 +1,50 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$scope', '$state', '$stateParams', 'DashboardHostsForm', 'GenerateForm', 'ParseTypeChange', 'DashboardHostService', 'host',
function($scope, $state, $stateParams, DashboardHostsForm, GenerateForm, ParseTypeChange, DashboardHostService, host){
var generator = GenerateForm,
form = DashboardHostsForm;
$scope.parseType = 'yaml';
$scope.formCancel = function(){
$state.go('^', null, {reload: true});
};
$scope.toggleHostEnabled = function(){
$scope.host.enabled = !$scope.host.enabled;
};
$scope.toggleEnabled = function(){
$scope.host.enabled = !$scope.host.enabled;
};
$scope.formSave = function(){
var host = {
id: $scope.host.id,
variables: $scope.extraVars === '---' || $scope.extraVars === '{}' ? null : $scope.extraVars,
name: $scope.name,
description: $scope.description,
enabled: $scope.host.enabled
};
DashboardHostService.putHost(host).then(function(res){
$state.go('^', null, {reload: true});
});
};
var init = function(){
$scope.host = host;
$scope.extraVars = host.variables === '' ? '---' : host.variables;
generator.inject(form, {mode: 'edit', related: false, scope: $scope});
$scope.extraVars = $scope.host.variables === '' ? '---' : $scope.host.variables;
$scope.name = host.name;
$scope.description = host.description;
ParseTypeChange({
scope: $scope,
field_id: 'host_variables',
variable: 'extraVars',
});
};
init();
}];

View File

@@ -0,0 +1,4 @@
<div class="tab-pane" id="organizations">
<div ui-view></div>
<div ng-cloak id="htmlTemplate" class="Panel"></div>
</div>

View File

@@ -0,0 +1,64 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default
['$scope', '$state', '$stateParams', 'PageRangeSetup', 'GetBasePath', 'DashboardHostsList',
'generateList', 'PaginateInit', 'SetStatus', 'DashboardHostService', 'hosts',
function($scope, $state, $stateParams, PageRangeSetup, GetBasePath, DashboardHostsList, GenerateList, PaginateInit, SetStatus, DashboardHostService, hosts){
var generator = GenerateList,
list = DashboardHostsList,
defaultUrl = GetBasePath('hosts');
$scope.hostPageSize = 10;
$scope.editHost = function(id){
$state.go('dashboardHosts.edit', {id: id});
};
$scope.toggleHostEnabled = function(host){
DashboardHostService.setHostStatus(host, !host.enabled)
.then(function(res){
var index = _.findIndex($scope.hosts, function(o) {return o.id === res.data.id;});
$scope.hosts[index].enabled = res.data.enabled;
});
};
$scope.$on('PostRefresh', function(){
$scope.hosts = _.map($scope.hosts, function(value, key){
value.inventory_name = value.summary_fields.inventory.name;
value.inventory_id = value.summary_fields.inventory.id;
return value;
});
setJobStatus();
});
var setJobStatus = function(){
_.forEach($scope.hosts, function(value, key){
SetStatus({
scope: $scope,
host: value
});
});
};
var init = function(){
$scope.list = list;
$scope.host_active_search = false;
$scope.host_total_rows = hosts.results.length;
$scope.hosts = hosts.results;
setJobStatus();
generator.inject(list, {mode: 'edit', scope: $scope});
PaginateInit({
scope: $scope,
list: list,
url: defaultUrl,
pageSize: 10
});
PageRangeSetup({
scope: $scope,
count: hosts.count,
next: hosts.next,
previous: hosts.previous,
iterator: list.iterator
});
$scope.hostLoading = false;
};
init();
}];

View File

@@ -0,0 +1,4 @@
<div class="tab-pane" id="HomeHosts">
<div ui-view></div>
<div ng-cloak id="htmlTemplate" class="Panel"></div>
</div>

View File

@@ -0,0 +1,77 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
export default function(){
return {
editTitle: '{{host.name}}',
name: 'host',
well: true,
formLabelSize: 'col-lg-3',
formFieldSize: 'col-lg-9',
iterator: 'host',
headerFields:{
enabled: {
//flag: 'host.enabled',
class: 'Form-header-field',
ngClick: 'toggleHostEnabled()',
type: 'toggle',
editRequired: false,
awToolTip: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that " +
"are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled'
}
},
fields: {
name: {
label: 'Host Name',
type: 'text',
editRequired: true,
value: '{{name}}',
awPopOver: "<p>Provide a host name, ip address, or ip address:port. Examples include:</p>" +
"<blockquote>myserver.domain.com<br/>" +
"127.0.0.1<br />" +
"10.1.0.140:25<br />" +
"server.example.com:25" +
"</blockquote>",
dataTitle: 'Host Name',
dataPlacement: 'right',
dataContainer: 'body'
},
description: {
label: 'Description',
type: 'text',
editRequired: false
},
variables: {
label: 'Variables',
type: 'textarea',
editRequired: false,
rows: 6,
class: 'modal-input-xlarge Form-textArea',
dataTitle: 'Host Variables',
dataPlacement: 'right',
dataContainer: 'body',
default: '---',
awPopOver: "<p>Enter variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />\"somevar\": \"somevalue\",<br />\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
}
},
buttons: {
save: {
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: "host_form.$invalid"//true //Disable when $pristine or $invalid, optional and when can_edit = false, for permission reasons
},
cancel: {
ngClick: 'formCancel()'
}
}
};
};

View File

@@ -1,14 +1,12 @@
/************************************************* /*************************************************
* Copyright (c) 2015 Ansible, Inc. * Copyright (c) 2015 Ansible, Inc.
* *
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export default export default function(){
angular.module('HomeHostListDefinition', []) return {
.value('HomeHostList', {
name: 'hosts', name: 'hosts',
iterator: 'host', iterator: 'host',
selectTitle: 'Add Existing Hosts', selectTitle: 'Add Existing Hosts',
@@ -20,38 +18,45 @@ export default
fields: { fields: {
status: { status: {
label: "", basePath: 'unified_jobs',
label: '',
iconOnly: true, iconOnly: true,
icon: "{{ 'icon-job-' + host.active_failures }}", searchable: true,
awToolTip: "{{ host.badgeToolTip }}", searchType: 'select',
awTipPlacement: "right", nosort: true,
dataPlacement: "right", searchOptions: [],
awPopOver: "{{ host.job_status_html }}", searchLabel: 'Job Status',
ngClick:"bob", icon: 'icon-job-{{ host.active_failures }}',
columnClass: "List-staticColumn--smallStatus", awToolTip: '{{ host.badgeToolTip }}',
searchable: false, awTipPlacement: 'right',
nosort: true dataPlacement: 'right',
awPopOver: '{{ host.job_status_html }}',
ngClick:'viewHost(host.id)',
columnClass: 'col-lg-1 col-md-1 col-sm-2 col-xs-2 List-staticColumn--smallStatus'
}, },
name: { name: {
key: true, key: true,
label: 'Name', label: 'Name',
columnClass: 'col-lg-5 col-md-5 col-sm-5 col-xs-8 ellipsis List-staticColumnAdjacent', columnClass: 'col-lg-5 col-md-5 col-sm-5 col-xs-8 ellipsis List-staticColumnAdjacent',
ngClass: "{ 'host-disabled-label': !host.enabled }", ngClick: 'editHost(host.id)'
ngClick: "editHost(host.id)"
}, },
inventory_name: { inventory_name: {
label: 'Inventory', label: 'Inventory',
sourceModel: 'inventory', sourceModel: 'inventory',
sourceField: 'name', sourceField: 'name',
columnClass: 'col-lg-5 col-md-4 col-sm-4 hidden-xs elllipsis', columnClass: 'col-lg-5 col-md-4 col-sm-4 hidden-xs elllipsis',
linkTo: "{{ '/#/inventories/' + host.inventory }}" linkTo: "{{ '/#/inventories/' + host.inventory_id }}",
searchable: false
}, },
enabled: { enabled: {
label: 'Disabled?', label: 'Status',
searchSingleValue: true, columnClass: 'List-staticColumn--toggle',
searchType: 'boolean', type: 'toggle',
searchValue: 'false', ngClick: 'toggleHostEnabled(host)',
searchOnly: true searchable: false,
nosort: true,
awToolTip: "<p>Indicates if a host is available and should be included in running jobs.</p><p>For hosts that are part of an external inventory, this flag cannot be changed. It will be set by the inventory sync process.</p>",
dataTitle: 'Host Enabled',
}, },
has_active_failures: { has_active_failures: {
label: 'Has failed jobs?', label: 'Has failed jobs?',
@@ -66,30 +71,15 @@ export default
searchType: 'boolean', searchType: 'boolean',
searchValue: 'true', searchValue: 'true',
searchOnly: true searchOnly: true
},
id: {
label: 'ID',
searchOnly: true
} }
}, },
fieldActions: { fieldActions: {
columnClass: 'col-lg-2 col-md-3 col-sm-3 col-xs-4', columnClass: 'col-lg-2 col-md-3 col-sm-3 col-xs-4',
/*active_failures: {
//label: 'Job Status',
//ngHref: "\{\{'/#/hosts/' + host.id + '/job_host_summaries/?inventory=' + inventory_id \}\}",
awPopOver: "{{ host.job_status_html }}",
dataTitle: "{{ host.job_status_title }}",
awToolTip: "{{ host.badgeToolTip }}",
awTipPlacement: 'top',
dataPlacement: 'left',
iconClass: "{{ 'fa icon-failures-' + host.has_active_failures }}"
}*/
edit: { edit: {
label: 'Edit', label: 'Edit',
ngClick: "editHost(host.id)", ngClick: 'editHost(host.id)',
icon: 'icon-edit', icon: 'icon-edit',
awToolTip: 'Edit host', awToolTip: 'Edit host',
dataPlacement: 'top' dataPlacement: 'top'
@@ -99,5 +89,5 @@ export default
actions: { actions: {
} }
}
}); };

View File

@@ -0,0 +1,64 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import {templateUrl} from '../../shared/template-url/template-url.factory';
import listController from './dashboard-hosts-list.controller';
import editController from './dashboard-hosts-edit.controller';
var dashboardHostsList = {
name: 'dashboardHosts',
url: '/home/hosts',
controller: listController,
templateUrl: templateUrl('dashboard/hosts/dashboard-hosts-list'),
data: {
activityStream: true,
activityStreamTarget: 'host'
},
ncyBreadcrumb: {
parent: 'dashboard',
label: "HOSTS"
},
resolve: {
features: ['FeaturesService', function(FeaturesService) {
return FeaturesService.get();
}],
hosts: ['Rest', 'GetBasePath', function(Rest, GetBasePath){
var defaultUrl = GetBasePath('hosts') + '?page_size=10';
Rest.setUrl(defaultUrl);
return Rest.get().then(function(res){
var results = _.map(res.data.results, function(value, key){
value.inventory_name = value.summary_fields.inventory.name;
value.inventory_id = value.summary_fields.inventory.id;
return value;
});
res.data.results = results;
return res.data
});
}]
}
};
var dashboardHostsEdit = {
name: 'dashboardHosts.edit',
url: '/:id',
controller: editController,
templateUrl: templateUrl('dashboard/hosts/dashboard-hosts-edit'),
ncyBreadcrumb: {
parent: 'dashboardHosts',
label: "{{host.name}}"
},
resolve: {
host: ['$stateParams', 'Rest', 'GetBasePath', function($stateParams, Rest, GetBasePath){
var defaultUrl = GetBasePath('hosts') + '?id=' + $stateParams.id;
Rest.setUrl(defaultUrl);
return Rest.get().then(function(res){
return res.data.results[0];
});
}]
}
};
export {dashboardHostsList, dashboardHostsEdit};

View File

@@ -0,0 +1,30 @@
export default
['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', function($rootScope, Rest, GetBasePath, ProcessErrors){
return {
setHostStatus: function(host, enabled){
var url = GetBasePath('hosts') + host.id;
Rest.setUrl(url);
return Rest.put({enabled: enabled, name: host.name})
.success(function(data){
return data;
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
},
putHost: function(host){
var url = GetBasePath('hosts') + host.id;
Rest.setUrl(url);
return Rest.put(host)
.success(function(data){
return data;
})
.error(function(data, status) {
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
msg: 'Call to ' + url + '. GET returned: ' + status });
});
}
};
}];

View File

@@ -0,0 +1,20 @@
/*************************************************
* Copyright (c) 2016 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
import {dashboardHostsList, dashboardHostsEdit} from './dashboard-hosts.route';
import list from './dashboard-hosts.list';
import form from './dashboard-hosts.form';
import service from './dashboard-hosts.service';
export default
angular.module('dashboardHosts', [])
.service('DashboardHostService', service)
.factory('DashboardHostsList', list)
.factory('DashboardHostsForm', form)
.run(['$stateExtender', function($stateExtender){
$stateExtender.addState(dashboardHostsList);
$stateExtender.addState(dashboardHostsEdit);
}]);

View File

@@ -2,7 +2,8 @@ import dashboardCounts from './counts/main';
import dashboardGraphs from './graphs/main'; import dashboardGraphs from './graphs/main';
import dashboardLists from './lists/main'; import dashboardLists from './lists/main';
import dashboardDirective from './dashboard.directive'; import dashboardDirective from './dashboard.directive';
import dashboardHosts from './hosts/main';
export default export default
angular.module('dashboard', [dashboardCounts.name, dashboardGraphs.name, dashboardLists.name]) angular.module('dashboard', [dashboardHosts.name, dashboardCounts.name, dashboardGraphs.name, dashboardLists.name])
.directive('dashboard', dashboardDirective); .directive('dashboard', dashboardDirective);

View File

@@ -11,7 +11,6 @@ import AllJobs from "./lists/AllJobs";
import Credentials from "./lists/Credentials"; import Credentials from "./lists/Credentials";
import Groups from "./lists/Groups"; import Groups from "./lists/Groups";
import HomeGroups from "./lists/HomeGroups"; import HomeGroups from "./lists/HomeGroups";
import HomeHosts from "./lists/HomeHosts";
import Hosts from "./lists/Hosts"; import Hosts from "./lists/Hosts";
import Inventories from "./lists/Inventories"; import Inventories from "./lists/Inventories";
import InventoryGroups from "./lists/InventoryGroups"; import InventoryGroups from "./lists/InventoryGroups";
@@ -39,7 +38,6 @@ export
Credentials, Credentials,
Groups, Groups,
HomeGroups, HomeGroups,
HomeHosts,
Hosts, Hosts,
Inventories, Inventories,
InventoryGroups, InventoryGroups,

View File

@@ -1,16 +1,21 @@
export default ['GetBasePath', function(GetBasePath) { export default ['GetBasePath', function(GetBasePath) {
// given the list, return the fields that need searching // given the list, return the fields that need searching
this.getList = function(list) { this.getList = function(list) {
var f = _.clone(list.fields); var f = _.cloneDeep(list.fields);
return JSON.stringify(Object return JSON.stringify(Object
.keys(f) .keys(f)
.filter(function(i) { .filter(function(i) {
return (f[i] return (f[i]
.searchable !== false); .searchable !== false);
}).map(function(i) { }).map(function(i) {
// delete any fields which might include AngularJS interpolation tags {{ }}
delete f[i].awToolTip; delete f[i].awToolTip;
delete f[i].awPopover;
delete f[i].linkTo;
delete f[i].dataTitle;
delete f[i].ngClass; delete f[i].ngClass;
delete f[i].ngClick; delete f[i].ngClick;
delete f[i].icon;
return {[i]: f[i]}; return {[i]: f[i]};
}).reduce(function (acc, i) { }).reduce(function (acc, i) {
var key = Object.keys(i); var key = Object.keys(i);

View File

@@ -1,7 +1,7 @@
export default ['$scope', 'Refresh', 'tagSearchService', export default ['$scope', 'Refresh', 'tagSearchService',
function($scope, Refresh, tagSearchService) { function($scope, Refresh, tagSearchService) {
// JSONify passed field elements that can be searched // JSONify passed field elements that can be searched
$scope.list = JSON.parse($scope.list); $scope.list = angular.fromJson($scope.list);
// Access config lines from list spec // Access config lines from list spec
$scope.listConfig = $scope.$parent.list; $scope.listConfig = $scope.$parent.list;
// Grab options for the left-dropdown of the searchbar // Grab options for the left-dropdown of the searchbar

View File

@@ -35,8 +35,7 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu
obj.value = value; obj.value = value;
obj.label = label; obj.label = label;
obj.type = type; obj.type = type;
obj.basePath = field['basePath'] || null;
// return the built option // return the built option
if (type === 'select') { if (type === 'select') {
@@ -79,7 +78,7 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu
if (needsRequest.length) { if (needsRequest.length) {
// make the options request to reutrn the typeOptions // make the options request to reutrn the typeOptions
Rest.setUrl(needsRequest[0].basePath ? needsRequest[0].basePath : basePath); Rest.setUrl(needsRequest[0].basePath ? GetBasePath(needsRequest[0].basePath) : basePath);
Rest.options() Rest.options()
.success(function (data) { .success(function (data) {
try { try {

View File

@@ -230,6 +230,11 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
this.scope[fld + '_field'].name = fld; this.scope[fld + '_field'].name = fld;
} }
for (fld in form.headerFields){
this.scope[fld + '_field'] = form.headerFields[fld];
this.scope[fld + '_field'].name = fld;
}
$compile(element)(this.scope); $compile(element)(this.scope);
if (!options.html) { if (!options.html) {
@@ -606,9 +611,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
return html; return html;
}, },
buildHeaderField: function(key, field, options, form){
var html = '';
// extend these blocks to include elements similarly buildField()
if (field.type === 'toggle'){
html += "<div class=\"Field-header--" + key;
html += (field['class']) ? " " + field['class'] : "";
html += " " + field.columnClass;
html += "\"><div class='ScheduleToggle' ng-class='{\"is-on\": " + form.iterator + ".";
html += (field.flag) ? field.flag : "enabled";
html += "\}' aw-tool-tip='" + field.awToolTip + "' data-placement='" + field.dataPlacement + "' data-tip-watch='" + field.dataTipWatch + "'><div ng-show='" + form.iterator + "." ;
html += (field.flag) ? field.flag : 'enabled';
html += "' class='ScheduleToggle-switch is-on' ng-click='" + field.ngClick + "'>ON</div><div ng-show='!" + form.iterator + "." ;
html += (field.flag) ? field.flag : "enabled";
html += "' class='ScheduleToggle-switch' ng-click='" + field.ngClick + "'>OFF</div></div></div>";
}
return html;
},
buildField: function (fld, field, options, form) { buildField: function (fld, field, options, form) {
var i, fldWidth, offset, html = '', var i, fldWidth, offset, html = '',
horizontal = (this.form.horizontal) ? true : false; horizontal = (this.form.horizontal) ? true : false;
@@ -725,6 +747,18 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
return html; return html;
} }
if (field.type === 'toggle'){
html += "<td class=\"List-tableCell " + fld + "-column";
html += (field['class']) ? " " + field['class'] : "";
html += " " + field.columnClass;
html += "\"><div class='ScheduleToggle' ng-class='{\"is-on\": " + form.iterator + ".";
html += (field.flag) ? field.flag : "enabled";
html += "\}' aw-tool-tip='" + field.awToolTip + "' data-placement='" + field.dataPlacement + "' data-tip-watch='" + field.dataTipWatch + "'><div ng-show='" + form.iterator + "." ;
html += (field.flag) ? field.flag : 'enabled';
html += "' class='ScheduleToggle-switch is-on' ng-click='" + field.ngClick + "'>ON</div><div ng-show='!" + form.iterator + "." ;
html += (field.flag) ? field.flag : "enabled";
html += "' class='ScheduleToggle-switch' ng-click='" + field.ngClick + "'>OFF</div></div></td>";
}
if (field.type === 'alertblock') { if (field.type === 'alertblock') {
html += "<div class=\"row\">\n"; html += "<div class=\"row\">\n";
@@ -1430,17 +1464,26 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
html+= "<span class=\"Form-title--is_superuser\" "+ html+= "<span class=\"Form-title--is_superuser\" "+
"ng-if=is_superuser>Admin</span>"; "ng-if=is_superuser>Admin</span>";
} }
html += "</div>\n"; html += "</div>\n";
html += "<div class=\"Form-header--fields\">";
if(this.form.headerFields){
var that = this;
_.forEach(this.form.headerFields, function(value, key){
html += that.buildHeaderField(key, value, options, that.form);
});
html += "</div>\n";
}
else{ html += "</div>\n"; }
if(this.form.cancelButton !== undefined && this.form.cancelButton === false) { if(this.form.cancelButton !== undefined && this.form.cancelButton === false) {
html += "<div class=\"Form-exitHolder\">"; html += "<div class=\"Form-exitHolder\">";
html += "</div>"; html += "</div></div>";
} else { } else {
html += "<div class=\"Form-exitHolder\">"; html += "<div class=\"Form-exitHolder\">";
html += "<button class=\"Form-exit\" ng-click=\"formCancel()\">"; html += "<button class=\"Form-exit\" ng-click=\"formCancel()\">";
html += "<i class=\"fa fa-times-circle\"></i>"; html += "<i class=\"fa fa-times-circle\"></i>";
html += "</button></div>\n"; html += "</button></div>\n";
} }
html += "</div>\n"; //end of Form-header html += "</div></div>\n"; //end of Form-header
} }
if (!_.isEmpty(this.form.related)) { if (!_.isEmpty(this.form.related)) {