Merge branch 'release_3.0.0' of github.com:ansible/ansible-tower into jshint

This commit is contained in:
Akita Noek 2016-06-01 22:56:31 -04:00
commit 3247fe42c0
41 changed files with 481 additions and 428 deletions

View File

@ -1970,7 +1970,6 @@ tr td button i {
}
.list-actions {
margin-bottom: 20px;
text-align: left;
}
@ -2239,3 +2238,11 @@ a:hover {
.dropdown-menu>li>a {
padding: 3px 10px;
}
#scheduled-jobs-tab .List-header {
display: none;
}
.ui-widget {
font-family: 'Open Sans';
}

View File

@ -173,7 +173,8 @@
}
.Form-formGroup--fullWidth {
max-width: none;
max-width: none !important;
width: 100% !important;
}
.Form-formGroup--checkbox{
@ -289,7 +290,7 @@
}
.Form-dropDown {
height: 30px !important;
min-height: 30px !important;
border-radius: 5px !important;
border:1px solid @field-border!important;
color: @field-input-text!important;
@ -564,3 +565,8 @@ input[type='radio']:checked:before {
padding-right: 50px;
}
}
.action_column {
float: right;
margin-bottom: 20px;
}

View File

@ -7,7 +7,7 @@
export default function() {
return {
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
name: 'teams',
iterator: 'team',
listTitleBadge: false,

View File

@ -7,7 +7,7 @@
export default function() {
return {
searchSize: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
name: 'users',
iterator: 'user',
title: false,

View File

@ -37,7 +37,7 @@
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
border-right: 0;
max-wdith: ~"calc(100% - 23px)";
max-width: ~"calc(100% - 23px)";
margin-right: 5px;
}

View File

@ -21,7 +21,7 @@ export default ['templateUrl', function(templateUrl) {
{label: 'Inventories', value: 'inventory'},
{label: 'Inventory Scripts', value: 'inventory_script'},
{label: 'Job Templates', value: 'job_template'},
{label: 'Management Jobs', value: 'management_job'},
{label: 'Jobs', value: 'job'},
{label: 'Organizations', value: 'organization'},
{label: 'Projects', value: 'project'},
{label: 'Schedules', value: 'schedule'},

View File

@ -1,5 +1,5 @@
export default
[ 'templateUrl', '$state', 'FeaturesService', 'ProcessErrors', 'Store', 'Empty', function(templateUrl, $state, FeaturesService, ProcessErrors, Store, Empty) {
[ 'templateUrl', '$state', 'FeaturesService', 'ProcessErrors', 'Store', 'Empty', '$log', function(templateUrl, $state, FeaturesService, ProcessErrors, Store, Empty, $log) {
return {
restrict: 'E',
templateUrl: templateUrl('bread-crumb/bread-crumb'),
@ -75,6 +75,7 @@ export default
scope.licenseType = licenseInfo ? licenseInfo.license_type : null;
if (!licenseInfo) {
console.warn("License info not loaded correctly"); // jshint ignore:line
$log.error("License info not loaded correctly");
}
})
.catch(function (response) {

View File

@ -21,7 +21,7 @@ export default function(){
basePath: 'unified_jobs',
label: '',
iconOnly: true,
searchable: true,
searchable: false,
searchType: 'select',
nosort: true,
searchOptions: [],

View File

@ -448,13 +448,15 @@ export default
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
searchable: false
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
searchable: false
}
}
}

View File

@ -185,13 +185,15 @@ export default
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
noSearch: true
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
noSearch: true
}
}
}

View File

@ -224,41 +224,6 @@ export default
text: 'Prompt on launch'
}
},
labels: {
label: 'Labels',
type: 'select',
ngOptions: 'label.label for label in labelOptions track by label.value',
multiSelect: true,
addRequired: false,
editRequired: false,
dataTitle: 'Labels',
dataPlacement: 'right',
awPopOver: 'You can add labels to a job template to aid in filtering',
dataContainer: 'body'
},
variables: {
label: 'Extra Variables',
type: 'textarea',
class: 'Form-textAreaLabel Form-formGroup--fullWidth',
rows: 6,
addRequired: false,
editRequired: false,
"default": "---",
column: 2,
awPopOver: "<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter " +
"for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n",
dataTitle: 'Extra Variables',
dataPlacement: 'right',
dataContainer: "body",
subCheckbox: {
variable: 'ask_variables_on_launch',
text: 'Prompt on launch'
}
},
become_enabled: {
label: 'Enable Privilege Escalation',
type: 'checkbox',
@ -309,6 +274,42 @@ export default
dataPlacement: 'right',
dataTitle: "Host Config Key",
dataContainer: "body"
},
labels: {
label: 'Labels',
type: 'select',
class: 'Form-formGroup--fullWidth',
ngOptions: 'label.label for label in labelOptions track by label.value',
multiSelect: true,
addRequired: false,
editRequired: false,
dataTitle: 'Labels',
dataPlacement: 'right',
awPopOver: 'You can add labels to a job template to aid in filtering',
dataContainer: 'body'
},
variables: {
label: 'Extra Variables',
type: 'textarea',
class: 'Form-textAreaLabel Form-formGroup--fullWidth',
rows: 6,
addRequired: false,
editRequired: false,
"default": "---",
column: 2,
awPopOver: "<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter " +
"for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>" +
"JSON:<br />\n" +
"<blockquote>{<br />&emsp;\"somevar\": \"somevalue\",<br />&emsp;\"password\": \"magic\"<br /> }</blockquote>\n" +
"YAML:<br />\n" +
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n",
dataTitle: 'Extra Variables',
dataPlacement: 'right',
dataContainer: "body",
subCheckbox: {
variable: 'ask_variables_on_launch',
text: 'Prompt on launch'
}
}
},
@ -365,13 +366,15 @@ export default
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
searchable: false
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
searchable: false
}
}
},

View File

@ -47,6 +47,7 @@ export default
related: {
permissions: {
basePath: 'organizations/:id/access_list/',
awToolTip: 'Please save before assigning permissions',
dataPlacement: 'top',
type: 'collection',
@ -76,13 +77,15 @@ export default
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
searchable: false
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
searchable: false
}
}
},

View File

@ -243,13 +243,15 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
noSearch: true
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
noSearch: true
}
}
},

View File

@ -90,19 +90,23 @@ export default
label: 'Role',
type: 'role',
noSort: true,
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
searchable: false
},
team_roles: {
label: 'Team Roles',
type: 'team_roles',
noSort: true,
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
searchable: false
}
}
},
roles: {
hideSearchAndActions: true,
dataPlacement: 'top',
awToolTip: 'Please save before assigning permissions',
basePath: 'teams/:id/roles/',
type: 'collection',
title: 'Permissions',
iterator: 'role',

View File

@ -109,6 +109,7 @@ export default
related: {
organizations: {
basePath: 'users/:id/organizations',
awToolTip: 'Please save before assigning to organizations',
dataPlacement: 'top',
type: 'collection',
@ -131,6 +132,7 @@ export default
hideOnSuperuser: true
},
teams: {
basePath: 'users/:id/teams',
awToolTip: 'Please save before assigning to teams',
dataPlacement: 'top',
type: 'collection',

View File

@ -40,8 +40,8 @@ export default
case 'organization':
rtnTitle = 'ORGANIZATIONS';
break;
case 'management_job':
rtnTitle = 'MANAGEMENT JOBS';
case 'job':
rtnTitle = 'JOBS';
break;
case 'inventory_script':
rtnTitle = 'INVENTORY SCRIPTS';

View File

@ -175,25 +175,26 @@
color: @btn-txt;
}
.JobSubmission-revertButton {
background-color: @default-link;
color: @default-bg;
background-color: @default-bg;
color: @default-link;
text-transform: uppercase;
padding-left:15px;
padding-right: 15px;
font-size: 9px;
font-size: 11px;
}
.JobSubmission-revertButton:hover{
background-color: @default-link-hov;
color: @default-bg;
background-color: @default-bg;
color: @default-link-hov;
}
.JobSubmission-selectedItem {
display: flex;
flex: 1 0 auto;
margin-bottom: 15px;
align-items: baseline;
}
.JobSubmission-selectedItemInfo {
display: flex;
flex: 1 0 auto;
flex: 0 0 auto;
}
.JobSubmission-selectedItemRevert {
display: flex;

View File

@ -280,7 +280,14 @@ export default
if($scope.ask_inventory_on_launch) {
var inventory_url = GetBasePath('inventory');
GenerateList.inject(InventoryList, {
var invList = _.cloneDeep(InventoryList);
invList.fields.status.searchable = false;
invList.fields.organization.searchable = false;
invList.fields.has_inventory_sources.searchable = false;
invList.fields.has_active_failures.searchable = false;
invList.fields.inventory_sources_with_failures.searchable = false;
GenerateList.inject(invList, {
mode: 'lookup',
id: 'job-submission-inventory-lookup',
scope: $scope,
@ -320,7 +327,11 @@ export default
if($scope.ask_credential_on_launch) {
var credential_url = GetBasePath('credentials') + '?kind=ssh';
GenerateList.inject(CredentialList, {
var credList = _.cloneDeep(CredentialList);
credList.fields.description.searchable = false;
credList.fields.kind.searchable = false;
GenerateList.inject(credList, {
mode: 'lookup',
id: 'job-submission-credential-lookup',
scope: $scope,
@ -448,7 +459,7 @@ export default
}
}
else if($scope.step === "credential") {
if($scope.selected_credential && $scope.forms.credentialpasswords.$valid) {
if($scope.selected_credential && $scope.forms.credentialpasswords && $scope.forms.credentialpasswords.$valid) {
return false;
}
else {

View File

@ -26,7 +26,7 @@
<span class="JobSubmission-selectedItemNone" ng-show="!selected_inventory">None selected</span>
</div>
<div class="JobSubmission-selectedItemRevert" ng-if="ask_inventory_on_launch && has_default_inventory">
<button class="btn btn-xs JobSubmission-revertButton" ng-disabled="selected_inventory.id === defaults.inventory.id" ng-click="revertToDefaultInventory()">REVERT TO DEFAULT</button>
<button class="btn btn-xs JobSubmission-revertButton" ng-hide="selected_inventory.id === defaults.inventory.id" ng-click="revertToDefaultInventory()">REVERT TO DEFAULT</button>
</div>
</div>
<div id="job-submission-inventory-lookup"></div>
@ -41,7 +41,7 @@
<span class="JobSubmission-selectedItemNone" ng-show="!selected_credential">None selected</span>
</div>
<div class="JobSubmission-selectedItemRevert" ng-if="ask_credential_on_launch && has_default_credential">
<button class="btn btn-xs JobSubmission-revertButton" ng-disabled="selected_credential.id === defaults.credential.id" ng-click="revertToDefaultCredential()">REVERT TO DEFAULT</button>
<button class="btn btn-xs JobSubmission-revertButton" ng-hide="selected_credential.id === defaults.credential.id" ng-click="revertToDefaultCredential()">REVERT TO DEFAULT</button>
</div>
</div>
<div id="job-submission-credential-lookup"></div>

View File

@ -419,25 +419,48 @@ export default
Rest.setUrl('api/v1/labels');
Wait("start");
Rest.get()
.success(function (data) {
$scope.labelOptions = data.results
.map((i) => ({label: i.name, value: i.id}));
$scope.$emit("choicesReady");
.success(function () {
var seeMoreResolve = $q.defer();
var getNext = function(data, arr, resolve) {
Rest.setUrl(data.next);
Rest.get()
.success(function (data) {
if (data.next) {
getNext(data, arr.concat(data.results), resolve);
} else {
resolve.resolve(arr.concat(data.results));
}
});
};
Rest.setUrl(defaultUrl + $state.params.template_id +
"/labels");
Rest.get()
.success(function(data) {
var opts = data.results
.map(i => ({id: i.id + "",
test: i.name}));
CreateSelect2({
element:'#job_templates_labels',
multiple: true,
addNew: true,
opts: opts
if (data.next) {
getNext(data, data.results, seeMoreResolve);
} else {
seeMoreResolve.resolve(data.results);
}
seeMoreResolve.promise.then(function (labels) {
$scope.labelOptions = labels
.map((i) => ({label: i.name, value: i.id}));
$scope.$emit("choicesReady");
var opts = labels
.map(i => ({id: i.id + "",
test: i.name}));
CreateSelect2({
element:'#job_templates_labels',
multiple: true,
addNew: true,
opts: opts
});
Wait("stop");
});
Wait("stop");
});
CreateSelect2({
element:'#job_templates_verbosity',
multiple: false

View File

@ -7,7 +7,8 @@
align-items: flex-start;
}
.LabelList-tagContainer {
.LabelList-tagContainer,
.LabelList-seeMore {
display: flex;
max-width: 100%;
}
@ -16,11 +17,10 @@
border-radius: 5px;
padding: 2px 10px;
margin: 4px 0px;
border: 1px solid @d7grey;
font-size: 12px;
color: @default-interface-txt;
color: @default-bg;
text-transform: uppercase;
background-color: @default-bg;
background-color: @default-link;
margin-right: 5px;
max-width: 100%;
white-space: nowrap;
@ -28,23 +28,36 @@
overflow: hidden;
}
.LabelList-seeMore {
color: @default-link;
margin: 4px 0px;
text-transform: uppercase;
padding: 2px 0px;
cursor: pointer;
border-radius: 5px;
font-size: 11px;
}
.LabelList-seeMore:hover {
color: @default-link-hov;
}
.LabelList-tag--deletable {
margin-right: 0px;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
border-right: 0;
max-wdith: ~"calc(100% - 23px)";
max-width: ~"calc(100% - 23px)";
margin-right: 5px;
}
.LabelList-deleteContainer {
border: 1px solid @d7grey;
border-left-color: @default-bg;
background-color: @default-bg;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
background-color: @default-link;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
color: @default-bg;
padding: 0 5px;
margin: 4px 0px;
margin-right: 5px;
align-items: center;
display: flex;
cursor: pointer;
@ -52,7 +65,7 @@
.LabelList-tagDelete {
font-size: 13px;
color: @default-icon;
color: @default-bg;
}
.LabelList-name {

View File

@ -6,14 +6,50 @@ export default
'GetBasePath',
'ProcessErrors',
'Prompt',
function(templateUrl, Wait, Rest, GetBasePath, ProcessErrors, Prompt) {
'$q',
function(templateUrl, Wait, Rest, GetBasePath, ProcessErrors, Prompt, $q) {
return {
restrict: 'E',
scope: false,
templateUrl: templateUrl('job-templates/labels/labelsList'),
link: function(scope, element, attrs) {
scope.seeMoreInactive = true;
scope.labels = scope.
job_template.summary_fields.labels;
job_template.summary_fields.labels.results;
scope.count = scope.
job_template.summary_fields.labels.count;
var getNext = function(data, arr, resolve) {
Rest.setUrl(data.next);
Rest.get()
.success(function (data) {
if (data.next) {
getNext(data, arr.concat(data.results), resolve);
} else {
resolve.resolve(arr.concat(data.results));
}
});
};
scope.seeMore = function () {
var seeMoreResolve = $q.defer();
Rest.setUrl(scope.job_template.related.labels);
Rest.get()
.success(function(data) {
if (data.next) {
getNext(data, data.results, seeMoreResolve);
} else {
seeMoreResolve.resolve(data.results);
}
});
seeMoreResolve.promise.then(function (labels) {
scope.labels = labels;
scope.seeMoreInactive = false;
});
};
scope.deleteLabel = function(templateId, templateName, labelId, labelName) {
var action = function () {

View File

@ -1,10 +1,11 @@
<div class="LabelList-tagContainer"
ng-repeat="label in labels">
<div class="LabelList-tag LabelList-tag--deletable">
<span class="LabelList-name">{{ label.name }}</span>
</div>
<div class="LabelList-tagContainer" ng-repeat="label in labels">
<div class="LabelList-deleteContainer"
ng-click="deleteLabel(job_template.id, job_template.name, label.id, label.name)">
<i class="fa fa-times LabelList-tagDelete"></i>
</div>
<div class="LabelList-tag LabelList-tag--deletable">
<span class="LabelList-name">{{ label.name }}</span>
</div>
</div>
<div class="LabelList-seeMore" ng-show="count > 10 && seeMoreInactive"
ng-click="seeMore()">View More</div>

View File

@ -37,10 +37,10 @@ export default
searchType: 'select',
nosort: true,
searchOptions: [
{ name: "Success", value: "successful" },
{ name: "Error", value: "error" },
{ name: "Failed", value: "failed" },
{ name: "Canceled", value: "canceled" }
{ label: "Success", value: "successful" },
{ label: "Error", value: "error" },
{ label: "Failed", value: "failed" },
{ label: "Canceled", value: "canceled" }
]
},
id: {
@ -74,7 +74,7 @@ export default
link: false,
columnClass: "col-lg-2 col-md-2 hidden-sm hidden-xs",
columnShow: "showJobType",
searchable: true,
searchOnly: true,
searchType: 'select',
searchOptions: [] // populated via GetChoices() in controller
},

View File

@ -74,8 +74,14 @@ export default
},
inventory_sources_with_failures: {
label: 'Sync failures?',
searchType: 'gtzero',
searchValue: 'true',
searchType: 'select',
searchOptions: [{
label: 'Yes',
value: 'inventory_sources_with_failures__gt=0'
}, {
label: 'No',
value: 'inventory_sources_with_failures__lte=0'
}],
searchOnly: true
}
},

View File

@ -52,7 +52,8 @@ export default
key: true,
ngClick: "groupSelect(group.id)",
columnClass: 'col-lg-3 col-md-3 col-sm-3 col-xs-3',
class: 'InventoryManage-breakWord'
class: 'InventoryManage-breakWord',
searchLabel: 'name'
},
total_groups: {
nosort: true,
@ -61,31 +62,31 @@ export default
ngHide: 'group.total_groups == 0',
noLink: true,
awToolTip: "{{group.name}} contains {{group.total_groups}} {{group.total_groups === 1 ? 'child' : 'children'}}",
searchable: false,
},
source: {
label: 'Source',
searchType: 'select',
searchOptions: [{
name: "Amazon Web Services",
label: "Amazon Web Services",
value: "ec2"
}, {
name: "none",
label: "none",
value: ""
}, {
name: "Rackspace",
label: "Rackspace",
value: "rax"
},{
name: "VMware",
label: "VMware",
value: "vmware"
},{
name: "Google Compute Engine",
label: "Google Compute Engine",
value: "gce"
},{
name: "Microsoft Azure",
label: "Microsoft Azure",
value: "azure"
},{
name: "OpenStack",
label: "OpenStack",
value: "openstack"
}],
sourceModel: 'inventory_source',
@ -94,11 +95,15 @@ export default
},
has_external_source: {
label: 'Has external source?',
searchType: 'in',
searchValue: 'ec2,rax,vmware,azure,gce,openstack',
searchOnly: true,
sourceModel: 'inventory_source',
sourceField: 'source'
searchType: 'select',
searchOptions: [{
label: 'Yes',
value: 'inventory_source__source__in=ec2,rax,vmware,azure,gce,openstack'
}, {
label: 'No',
value: 'not__inventory_source__source__in=ec2,rax,vmware,azure,gce,openstack'
}],
searchOnly: true
},
has_active_failures: {
label: 'Has failed hosts?',

View File

@ -42,6 +42,7 @@ export default
name: {
key: true,
label: 'Hosts',
searchLabel: 'Name',
ngClick: "editHost(host.id)",
ngClass: "{ 'host-disabled-label': !host.enabled }",
columnClass: 'col-lg-6 col-md-8 col-sm-8 col-xs-7',

View File

@ -31,7 +31,7 @@ export default
},
smart_status: {
label: 'Activity',
columnClass: 'List-tableCell col-lg-3 col-md-4 hidden-sm hidden-xs',
columnClass: 'List-tableCell col-lg-2 col-md-2 hidden-sm hidden-xs',
searchable: false,
nosort: true,
ngInclude: "'/static/partials/job-template-smart-status.html'",
@ -41,7 +41,7 @@ export default
label: 'Labels',
type: 'labels',
nosort: true,
columnClass: 'List-tableCell col-lg-3 col-md-3 hidden-sm hidden-xs',
columnClass: 'List-tableCell col-lg-4 col-md-4 hidden-sm hidden-xs',
searchType: 'related',
sourceModel: 'labels',
sourceField: 'name'

View File

@ -51,9 +51,9 @@ export default
searchable: true,
searchType: 'select',
searchOptions: [
{ value: 'inventory source', name: 'Inventory Sync' },
{ value: 'job template', name: 'Playbook Run' },
{ value: 'project', name: 'SCM Update' }
{ value: 'inventory source', label: 'Inventory Sync' },
{ value: 'job template', label: 'Playbook Run' },
{ value: 'project', label: 'SCM Update' }
]
},
next_run: {

View File

@ -37,8 +37,6 @@ export default
ngBindHtml: 'activity.user',
sourceModel: 'actor',
sourceField: 'username',
//awToolTip: "\{\{ userToolTip \}\}",
//dataPlacement: 'top',
searchPlaceholder: 'Username',
searchWidget: 1,
columnClass: 'col-lg-3 col-md-3 col-sm-3 col-xs-3'
@ -53,207 +51,9 @@ export default
actor: {
label: 'System event',
searchOnly: true,
searchType: 'isnull',
searchWidget: 1
},
// The following fields exist to force loading each type of object into the search
// dropdown
all_objects: {
label: 'All',
searchOnly: true,
searchObject: 'all',
searchPlaceholder: 'All resources',
searchWidget: 2
},
credential_search: {
label: 'Credential',
searchOnly: true,
searchObject: 'credential',
searchPlaceholder: 'Credential name',
searchWidget: 2,
searchField: 'object1'
},
custom_inventory_search: {
label: 'Custom Inventory Script',
searchOnly: true,
searchObject: 'custom_inventory_script',
searchPlaceholder: 'Custom inventory script name',
searchWidget: 2,
searchField: 'object1'
},
group_search: {
label: 'Group',
searchOnly: true,
searchObject: 'group',
searchPlaceholder: 'Group name',
searchWidget: 2,
searchField: 'object1'
},
host_search: {
label: 'Host',
searchOnly: true,
searchObject: 'host',
searchPlaceholder: 'Host name',
searchWidget: 2,
searchField: 'object1'
},
inventory_search: {
label: 'Inventory',
searchOnly: true,
searchObject: 'inventory',
searchPlaceholder: 'Inventory name',
searchWidget: 2,
searchField: 'object1'
},
job_template_search: {
label: 'Job Template',
searchOnly: true,
searchObject: 'job_template',
searchPlaceholder: 'Job template name',
searchWidget: 2,
searchField: 'object1'
},
job_search: {
label: 'Job',
searchOnly: true,
searchObject: 'job',
searchPlaceholder: 'Job name',
//searchOnID: true,
searchWidget: 2,
searchField: 'object1'
},
organization_search: {
label: 'Organization',
searchOnly: true,
searchObject: 'organization',
searchPlaceholder: 'Organization name',
searchWidget: 2,
searchField: 'object1'
},
project_search: {
label: 'Project',
searchOnly: true,
searchObject: 'project',
searchPlaceholder: 'Project name',
searchWidget: 2,
searchField: 'object1'
},
schedule_search: {
label: 'Schedule',
searchOnly: true,
searchObject: 'schedule',
searchPlaceholder: 'Schedule name',
searchWidget: 2,
searchField: 'object1'
},
user_search: {
label: 'User',
searchOnly: true,
searchObject: 'user',
searchPlaceholder: 'Primary username',
searchWidget: 2,
searchField: 'object1'
},
// The following fields exist to force loading each type of object into the search
// dropdown
all_objects3: {
label: 'All',
searchOnly: true,
searchObject: 'all',
searchPlaceholder: 'All related resources',
searchWidget: 3,
searchField: 'object2'
},
credential_search3: {
label: 'Credential',
searchOnly: true,
searchObject: 'credential',
searchPlaceholder: 'Related credential name',
searchWidget: 3,
searchField: 'object2'
},
custom_inventory_script_search3: {
label: 'Custom Inventory Script',
searchOnly: true,
searchObject: 'custom_inventory_script',
searchPlaceholder: 'Related custom inventory script name',
searchWidget: 3,
searchField: 'object2'
},
group_search3: {
label: 'Group',
searchOnly: true,
searchObject: 'group',
searchPlaceholder: 'Related group name',
searchWidget: 3,
searchField: 'object2'
},
host_search3: {
label: 'Host',
searchOnly: true,
searchObject: 'host',
searchPlaceholder: 'Related host name',
searchWidget: 3,
searchField: 'object2'
},
inventory_search3: {
label: 'Inventory',
searchOnly: true,
searchObject: 'inventory',
searchPlaceholder: 'Related inventory name',
searchWidget: 3,
searchField: 'object2'
},
job_search3: {
label: 'Job',
searchOnly: true,
searchObject: 'job',
searchPlaceholder: 'Related job name',
//searchOnID: true,
searchWidget: 3,
searchField: 'object2'
},
job_template_search3: {
label: 'Job Template',
searchOnly: true,
searchObject: 'job_template',
searchPlaceholder: 'Related job template name',
searchWidget: 3,
searchField: 'object2'
},
organization_search3: {
label: 'Organization',
searchOnly: true,
searchObject: 'organization',
searchPlaceholder: 'Related organization name',
searchWidget: 3,
searchField: 'object2'
},
project_search3: {
label: 'Project',
searchOnly: true,
searchObject: 'project',
searchPlaceholder: 'Related project name',
searchWidget: 3,
searchField: 'object2'
},
schedule_search3: {
label: 'Schedule',
searchOnly: true,
searchObject: 'schedule',
searchPlaceholder: 'Schedule name',
searchWidget: 3,
searchField: 'object1'
},
user_search3: {
label: 'User',
searchOnly: true,
searchObject: 'user',
searchPlaceholder: 'Related username',
searchWidget: 3,
searchField: 'object2'
searchType: 'boolean',
sourceModel: 'actor',
sourceField: 'isnull'
}
},

View File

@ -31,7 +31,7 @@ export default ['Rest', 'ProcessErrors', 'generateList',
var parent_scope = params.scope,
form = params.form,
list = params.list,
list = _.cloneDeep(params.list),
field = params.field,
instructions = params.instructions,
postAction = params.postAction,
@ -132,6 +132,7 @@ export default ['Rest', 'ProcessErrors', 'generateList',
master[field] = scope[field];
master[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] =
scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField];
list.searchSize = 'col-lg-12 col-md-12 col-sm-12 col-xs-12';
GenerateList.inject(list, {
mode: 'lookup',
id: 'LookupModal-dialog',

View File

@ -13,7 +13,7 @@ export default {
controller: 'managementJobsCardController',
data: {
activityStream: true,
activityStreamTarget: 'management_job'
activityStreamTarget: 'job'
},
ncyBreadcrumb: {
parent: 'setup',

View File

@ -15,7 +15,7 @@ export default function(){
index: false,
hover: false,
emptyListText: 'No Notifications exist',
basePath: 'notifications',
basePath: 'notification_templates',
fields: {
name: {
key: true,

View File

@ -19,6 +19,7 @@ export default [
SchedulesList, Rest, ProcessErrors, ReturnToCaller, ClearScope,
GetBasePath, Wait, Find, LoadSchedulesScope, GetChoices,
$q) {
var schedList = _.cloneDeep(SchedulesList);
ClearScope();
@ -51,16 +52,18 @@ export default [
}
$scope.removeParentLoaded = $scope.$on('ParentLoaded', function() {
url += "schedules/";
SchedulesList.well = true;
schedList.well = true;
// include name of item in listTitle
SchedulesList.listTitle = title ? title : parentObject.name;
SchedulesList.listTitle = `${SchedulesList.listTitle}<div class='List-titleLockup'></div>Schedules`;
schedList.listTitle = title ? title : parentObject.name;
schedList.listTitle = `${schedList.listTitle}<div class='List-titleLockup'></div>Schedules`;
schedList.basePath = parentObject.url + "schedules";
LoadSchedulesScope({
parent_scope: $scope,
scope: $scope,
list: SchedulesList,
list: schedList,
id: 'schedule-list-target',
url: url,
pageSize: 20

View File

@ -29,10 +29,9 @@
display: flex;
white-space: nowrap;
align-items: center;
max-height: 400px;
width: 120px;
cursor: pointer;
text-transform: uppercase;
position: relative;
}
.TagSearch-typeDropdown.is-open {
@ -40,8 +39,6 @@
}
.TagSearch-typeDropdownName {
width: 66px;
text-overflow: ellipsis;
display: block;
overflow: hidden;
}
@ -52,13 +49,14 @@
.TagSearch-dropdownContainer {
position: absolute;
left: 15px;
left: -1px;
top: 34px;
font-size: 14px;
border-radius: 5px;
border: 1px solid @d7grey;
background: white;
padding: 5px 0;
border-top: 0px;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
z-index: 50000;
@ -68,18 +66,18 @@
}
.TagSearch-dropdownContainer--searchTypes {
min-width: 96px;
min-width: ~"calc(100% + 1px)";
}
.TagSearch-dropdownContainer--typeOptions {
right: 15px;
left: initial;
width: ~"calc(100% - 123px)";
right: -1px;
left: -1px;
}
.TagSearch-dropdownItem {
padding: 5px 10px;
cursor: pointer;
text-transform: capitalize;
}
.TagSearch-dropdownItem:hover {
@ -92,13 +90,14 @@
.TagSearch-searchTermContainer {
flex: initial;
width: ~"calc(100% - 70px)";
width: ~"calc(100% - 50px)";
border: 1px solid @d7grey;
border-left: 0px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
display: flex;
background-color: @default-secondary-bg;
background-color: @default-bg;
position: relative;
}
.TagSearch-searchTermContainer.is-open {

View File

@ -42,7 +42,6 @@ export default ['$scope', 'Refresh', 'tagSearchService',
.updateFilteredUrl($scope.endpoint, tags, pageSize);
$scope.$parent[iterator + "_active_search"] = true;
Refresh({
scope: listScope,
set: set,
@ -50,6 +49,12 @@ export default ['$scope', 'Refresh', 'tagSearchService',
url: url
});
listScope.$on('PostRefresh', function() {
if (set === 'notifications') {
$scope.$emit('relatednotifications');
}
});
$scope.currentSearchFilters = tags;
};
@ -69,7 +74,7 @@ export default ['$scope', 'Refresh', 'tagSearchService',
.getCurrentTags($scope
.currentSearchFilters);
if (!tagSearchService.isDuplicate(tags, newTag)) {
if (!tagSearchService.isDuplicate(tags, newTag) && !!newTag.name) {
tags.push(newTag);
$scope.updateSearch(tags);
}

View File

@ -8,16 +8,17 @@
<span class="TagSearch-typeDropdownName" ng-cloak>
{{ currentSearchType.label }}
</span>
<i class="TagSearch-selectDownIcon fa fa-angle-down"></i>
</div>
<div aw-click-off="showTypeDropdown" class="TagSearch-dropdownContainer
TagSearch-dropdownContainer--searchTypes"
ng-show="showTypeDropdown">
<div class="TagSearch-dropdownItem"
ng-repeat="type in searchTypes track by $index"
ng-class="{'is-selected': (currentSearchType.value === type.value)}"
ng-click="setSearchType(type)">
{{ type.label }}
<i class="TagSearch-selectDownIcon fa fa-angle-down"
ng-hide="searchTypes.length === 1"></i>
<div aw-click-off="showTypeDropdown" class="TagSearch-dropdownContainer
TagSearch-dropdownContainer--searchTypes"
ng-show="showTypeDropdown">
<div class="TagSearch-dropdownItem"
ng-repeat="type in searchTypes track by $index"
ng-class="{'is-selected': (currentSearchType.id === type.id)}"
ng-click="setSearchType(type)">
{{ type.label }}
</div>
</div>
</div>
<div class="TagSearch-searchTermContainer"
@ -42,16 +43,16 @@
<i class="TagSearch-selectDownIcon
fa fa-angle-down">
</i>
</div>
<div aw-click-off="showCurrentSearchDropdown"
class="TagSearch-dropdownContainer
TagSearch-dropdownContainer--typeOptions"
ng-show="showCurrentSearchDropdown &&
currentSearchType.type === 'select'">
<div class="TagSearch-dropdownItem"
ng-repeat="type in currentSearchType.typeOptions track by $index"
ng-click="addTag(type)">
{{ type.label }}
<div aw-click-off="showCurrentSearchDropdown"
class="TagSearch-dropdownContainer
TagSearch-dropdownContainer--typeOptions"
ng-show="showCurrentSearchDropdown &&
currentSearchType.type === 'select'">
<div class="TagSearch-dropdownItem"
ng-repeat="type in currentSearchType.typeOptions track by $index"
ng-click="addTag(type)">
{{ type.label }}
</div>
</div>
</div>
</div>

View File

@ -53,6 +53,9 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu
var options = Object
.keys(list)
.filter(function(fieldType) {
return list[fieldType].noSearch !== true;
})
.map(function(key, id) {
return that.buildType(list[key], key, id);
});
@ -177,6 +180,9 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu
if (tag.type === "text") {
tag.url = tag.value + "__icontains=" + textVal;
tag.name = textVal;
} else if (selectVal.value && typeof selectVal.value === 'string' && selectVal.value.indexOf("=") > 0) {
tag.url = selectVal.value;
tag.name = selectVal.label;
} else {
tag.url = tag.value + "=" + selectVal.value;
tag.name = selectVal.label;

View File

@ -1819,7 +1819,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
!(is_superuser && ${hideOnSuperuser})\">
${tagSearch}
</div>
<div class=\"col-lg-4 col-md-4 col-sm-4 col-xs-12\">
<div class=\"col-lg-4 col-md-4 col-sm-4 col-xs-12 action_column\">
<div class=\"list-actions\">
${actionButtons}
</div>
@ -1868,36 +1868,39 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
`;
html += (collection.index === undefined || collection.index !== false) ? "<th class=\"col-xs-1\">#</th>\n" : "";
for (fld in collection.fields) {
html += "<th class=\"List-tableHeader list-header ";
html += (collection.fields[fld].class) ? collection.fields[fld].class : "";
html += "\" id=\"" + collection.iterator + '-' + fld + "-header\" ";
if (!collection.fields[fld].searchOnly) {
if (!collection.fields[fld].noSort) {
html += "ng-click=\"sort('" + collection.iterator + "', '" + fld + "')\">";
} else {
html += ">";
}
html += "<th class=\"List-tableHeader list-header ";
html += (collection.fields[fld].columnClass) ? collection.fields[fld].columnClass : "";
html += "\" id=\"" + collection.iterator + '-' + fld + "-header\" ";
html += collection.fields[fld].label;
if (!collection.fields[fld].noSort) {
html += " <i class=\"";
if (collection.fields[fld].key) {
if (collection.fields[fld].desc) {
html += "fa fa-sort-down";
} else {
html += "fa fa-sort-up";
}
if (!(collection.fields[fld].noSort || collection.fields[fld].nosort)) {
html += "ng-click=\"sort('" + collection.iterator + "', '" + fld + "')\">";
} else {
html += "fa fa-sort";
html += ">";
}
html += "\"></i>";
}
html += "</a></th>\n";
html += collection.fields[fld].label;
if (!(collection.fields[fld].noSort || collection.fields[fld].nosort)) {
html += " <i class=\"";
if (collection.fields[fld].key) {
if (collection.fields[fld].desc) {
html += "fa fa-sort-down";
} else {
html += "fa fa-sort-up";
}
} else {
html += "fa fa-sort";
}
html += "\"></i>";
}
html += "</a></th>\n";
}
}
if (collection.fieldActions) {
html += "<th class=\"List-tableHeader List-tableHeader--actions\">Actions</th>\n";
@ -1920,13 +1923,15 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
base = (collection.base) ? collection.base : itm;
base = base.replace(/^\//, '');
for (fld in collection.fields) {
cnt++;
html += Column({
list: collection,
fld: fld,
options: options,
base: base
});
if (!collection.fields[fld].searchOnly) {
cnt++;
html += Column({
list: collection,
fld: fld,
options: options,
base: base
});
}
}
// Row level actions

View File

@ -4,30 +4,36 @@
* All Rights Reserved
*************************************************/
export default ['$http', function($http) {
export default ['$http', '$q', function($http, $q) {
return {
getInitialPageForList: function(id, url, pageSize) {
// get the name of the object
return $http.get(url + "?id=" + id)
.then(function (data) {
var queryValue, queryType;
if (data.data.results[0].type === "user") {
queryValue = data.data.results[0].username;
queryType = "username";
} else {
queryValue = data.data.results[0].name;
queryType = "name";
}
// get how many results are less than or equal to
// the name
return $http.get(url + "?" + queryType + "__lte=" + queryValue)
.then(function (data) {
// divide by the page size to get what
// page the data should be on
var count = data.data.count;
return Math.ceil(count/parseInt(pageSize));
});
});
if ($.isNumeric(id)) {
return $http.get(url + "?id=" + id)
.then(function (data) {
var queryValue, queryType;
if (data.data.results[0].type === "user") {
queryValue = data.data.results[0].username;
queryType = "username";
} else {
queryValue = data.data.results[0].name;
queryType = "name";
}
// get how many results are less than or equal to
// the name
return $http.get(url + "?" + queryType + "__lte=" + queryValue)
.then(function (data) {
// divide by the page size to get what
// page the data should be on
var count = data.data.count;
return Math.ceil(count/parseInt(pageSize));
});
});
} else {
var defer = $q.defer();
defer.resolve(1);
return(defer.promise);
}
}
};
}];

View File

@ -272,7 +272,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
BuildDescription, FixUrl, BuildUrl, ShowDetail, setStreamHeight) {
return function (params) {
var list = StreamList,
var list = _.cloneDeep(StreamList),
defaultUrl = GetBasePath('activity_stream'),
view = GenerateList,
parent_scope = params.scope,
@ -292,11 +292,109 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
}
else {
// We just have a type
defaultUrl += '?or__object1=' + $state.params.target + '&or__object2=' + $state.params.target;
if ($state.params.target === 'inventory_script') {
defaultUrl += '?or__object1=custom_inventory_script&or__object2=custom_inventory_script';
} else if ($state.params.target === 'management_job') {
defaultUrl += '?or__object1=job&or__object2=job';
} else {
defaultUrl += '?or__object1=' + $state.params.target + '&or__object2=' + $state.params.target;
}
}
}
}
if ($state.params.target === 'credential') {
list.fields.customSearchField = {
label: 'Credential',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'credential',
sourceField: 'name'
};
} else if ($state.params.target === 'host') {
list.fields.customSearchField = {
label: 'Host',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'host',
sourceField: 'name'
};
} else if ($state.params.target === 'inventory') {
list.fields.customSearchField = {
label: 'Inventory',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'inventory',
sourceField: 'name'
};
} else if ($state.params.target === 'inventory_script') {
list.fields.customSearchField = {
label: 'Inventory Script',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'custom_inventory_script',
sourceField: 'name'
};
} else if ($state.params.target === 'job_template') {
list.fields.customSearchField = {
label: 'Job Template',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'job_template',
sourceField: 'name'
};
} else if ($state.params.target === 'job') {
list.fields.customSearchField = {
label: 'Job',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'job',
sourceField: 'name'
};
} else if ($state.params.target === 'organization') {
list.fields.customSearchField = {
label: 'Organization',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'organization',
sourceField: 'name'
};
} else if ($state.params.target === 'project') {
list.fields.customSearchField = {
label: 'Project',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'project',
sourceField: 'name'
};
} else if ($state.params.target === 'schedule') {
list.fields.customSearchField = {
label: 'Schedule',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'schedule',
sourceField: 'name'
};
} else if ($state.params.target === 'team') {
list.fields.customSearchField = {
label: 'Team',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'team',
sourceField: 'name'
};
} else if ($state.params.target === 'user') {
list.fields.customSearchField = {
label: 'User',
searchType: 'text',
searchOnly: 'true',
sourceModel: 'user',
sourceField: 'username'
};
}
list.basePath = defaultUrl;
// Generate the list
view.inject(list, { mode: 'edit', id: 'stream-content', searchSize: 'col-lg-4 col-md-4 col-sm-12 col-xs-12', secondWidget: true, activityStream: true, scope: scope });