From 763416725ca19eda00dd4be637de3ecbba7d31a3 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 31 May 2016 15:43:33 -0400 Subject: [PATCH 1/7] update search widgets across ui --- awx/ui/client/legacy-styles/ansible-ui.less | 5 +- awx/ui/client/legacy-styles/forms.less | 5 + .../permissionsTeams.list.js | 2 +- .../permissionsUsers.list.js | 2 +- .../stream-dropdown-nav.directive.js | 2 +- .../dashboard/hosts/dashboard-hosts.list.js | 2 +- awx/ui/client/src/forms/Credentials.js | 6 +- awx/ui/client/src/forms/Inventories.js | 6 +- awx/ui/client/src/forms/JobTemplates.js | 77 +++---- awx/ui/client/src/forms/Organizations.js | 7 +- awx/ui/client/src/forms/Projects.js | 6 +- awx/ui/client/src/forms/Teams.js | 8 +- awx/ui/client/src/forms/Users.js | 2 + awx/ui/client/src/helpers/ActivityStream.js | 4 +- .../job-submission/job-submission.block.less | 13 +- .../job-submission.controller.js | 17 +- .../job-submission.partial.html | 4 +- awx/ui/client/src/lists/CompletedJobs.js | 10 +- awx/ui/client/src/lists/InventoryGroups.js | 19 +- awx/ui/client/src/lists/InventoryHosts.js | 1 + awx/ui/client/src/lists/ScheduledJobs.js | 6 +- awx/ui/client/src/lists/Streams.js | 206 +----------------- awx/ui/client/src/lookup/lookup.factory.js | 3 +- .../src/management-jobs/card/card.route.js | 2 +- .../src/notifications/notifications.list.js | 2 +- .../src/scheduler/scheduler.controller.js | 11 +- awx/ui/client/src/search/tagSearch.block.less | 8 +- .../client/src/search/tagSearch.controller.js | 7 +- .../client/src/search/tagSearch.partial.html | 5 +- awx/ui/client/src/search/tagSearch.service.js | 5 +- awx/ui/client/src/shared/form-generator.js | 71 +++--- .../shared/pagination/pagination.service.js | 48 ++-- awx/ui/client/src/widgets/Stream.js | 102 ++++++++- 33 files changed, 317 insertions(+), 357 deletions(-) diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index 862bdc8b1d..0805b921a3 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -1970,7 +1970,6 @@ tr td button i { } .list-actions { - margin-bottom: 20px; text-align: left; } @@ -2239,3 +2238,7 @@ a:hover { .dropdown-menu>li>a { padding: 3px 10px; } + +#scheduled-jobs-tab .List-header { + display: none; +} diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 5f69f25d47..85f5bb9bc1 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -564,3 +564,8 @@ input[type='radio']:checked:before { padding-right: 50px; } } + +.action_column { + float: right; + margin-bottom: 20px; +} diff --git a/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsTeams.list.js b/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsTeams.list.js index 61b1c3de46..d12b65beca 100644 --- a/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsTeams.list.js +++ b/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsTeams.list.js @@ -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, diff --git a/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsUsers.list.js b/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsUsers.list.js index c08c45e352..5c0513c8db 100644 --- a/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsUsers.list.js +++ b/awx/ui/client/src/access/addPermissions/addPermissionsList/permissionsUsers.list.js @@ -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, diff --git a/awx/ui/client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js b/awx/ui/client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js index c9047422f4..229c3d4271 100644 --- a/awx/ui/client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js +++ b/awx/ui/client/src/activity-stream/streamDropdownNav/stream-dropdown-nav.directive.js @@ -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'}, diff --git a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js index 7ec32008c8..169ab31c94 100644 --- a/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js +++ b/awx/ui/client/src/dashboard/hosts/dashboard-hosts.list.js @@ -21,7 +21,7 @@ export default function(){ basePath: 'unified_jobs', label: '', iconOnly: true, - searchable: true, + searchable: false, searchType: 'select', nosort: true, searchOptions: [], diff --git a/awx/ui/client/src/forms/Credentials.js b/awx/ui/client/src/forms/Credentials.js index b31c3bed68..1b92b87e85 100644 --- a/awx/ui/client/src/forms/Credentials.js +++ b/awx/ui/client/src/forms/Credentials.js @@ -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 } } } diff --git a/awx/ui/client/src/forms/Inventories.js b/awx/ui/client/src/forms/Inventories.js index 9a4cc3bf7d..6110611265 100644 --- a/awx/ui/client/src/forms/Inventories.js +++ b/awx/ui/client/src/forms/Inventories.js @@ -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 } } } diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js index 7a9065af2b..06ccbe6f39 100644 --- a/awx/ui/client/src/forms/JobTemplates.js +++ b/awx/ui/client/src/forms/JobTemplates.js @@ -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: "

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.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\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: "

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.

" + + "JSON:
\n" + + "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + + "YAML:
\n" + + "
---
somevar: somevalue
password: magic
\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 } } }, diff --git a/awx/ui/client/src/forms/Organizations.js b/awx/ui/client/src/forms/Organizations.js index ce07dfac1e..7c678e09c7 100644 --- a/awx/ui/client/src/forms/Organizations.js +++ b/awx/ui/client/src/forms/Organizations.js @@ -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 } } }, diff --git a/awx/ui/client/src/forms/Projects.js b/awx/ui/client/src/forms/Projects.js index 24f666c0d5..19ceab2305 100644 --- a/awx/ui/client/src/forms/Projects.js +++ b/awx/ui/client/src/forms/Projects.js @@ -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 } } }, diff --git a/awx/ui/client/src/forms/Teams.js b/awx/ui/client/src/forms/Teams.js index 3bea1a81cb..5be609d002 100644 --- a/awx/ui/client/src/forms/Teams.js +++ b/awx/ui/client/src/forms/Teams.js @@ -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', diff --git a/awx/ui/client/src/forms/Users.js b/awx/ui/client/src/forms/Users.js index f1e6aada99..8a79d036e9 100644 --- a/awx/ui/client/src/forms/Users.js +++ b/awx/ui/client/src/forms/Users.js @@ -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', diff --git a/awx/ui/client/src/helpers/ActivityStream.js b/awx/ui/client/src/helpers/ActivityStream.js index 05171b2bdc..215eb00b7e 100644 --- a/awx/ui/client/src/helpers/ActivityStream.js +++ b/awx/ui/client/src/helpers/ActivityStream.js @@ -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'; diff --git a/awx/ui/client/src/job-submission/job-submission.block.less b/awx/ui/client/src/job-submission/job-submission.block.less index 15d93c95cb..60272deda5 100644 --- a/awx/ui/client/src/job-submission/job-submission.block.less +++ b/awx/ui/client/src/job-submission/job-submission.block.less @@ -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; diff --git a/awx/ui/client/src/job-submission/job-submission.controller.js b/awx/ui/client/src/job-submission/job-submission.controller.js index 761e797bd9..6149c74018 100644 --- a/awx/ui/client/src/job-submission/job-submission.controller.js +++ b/awx/ui/client/src/job-submission/job-submission.controller.js @@ -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 { diff --git a/awx/ui/client/src/job-submission/job-submission.partial.html b/awx/ui/client/src/job-submission/job-submission.partial.html index d1f39af9a9..95ca9df877 100644 --- a/awx/ui/client/src/job-submission/job-submission.partial.html +++ b/awx/ui/client/src/job-submission/job-submission.partial.html @@ -26,7 +26,7 @@ None selected
- +
@@ -41,7 +41,7 @@ None selected
- +
diff --git a/awx/ui/client/src/lists/CompletedJobs.js b/awx/ui/client/src/lists/CompletedJobs.js index b6c6efc1e4..7a7e124f1f 100644 --- a/awx/ui/client/src/lists/CompletedJobs.js +++ b/awx/ui/client/src/lists/CompletedJobs.js @@ -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 }, diff --git a/awx/ui/client/src/lists/InventoryGroups.js b/awx/ui/client/src/lists/InventoryGroups.js index 1f12a3af5a..aefbd34a4d 100644 --- a/awx/ui/client/src/lists/InventoryGroups.js +++ b/awx/ui/client/src/lists/InventoryGroups.js @@ -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', diff --git a/awx/ui/client/src/lists/InventoryHosts.js b/awx/ui/client/src/lists/InventoryHosts.js index d99589968e..b26627adbf 100644 --- a/awx/ui/client/src/lists/InventoryHosts.js +++ b/awx/ui/client/src/lists/InventoryHosts.js @@ -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', diff --git a/awx/ui/client/src/lists/ScheduledJobs.js b/awx/ui/client/src/lists/ScheduledJobs.js index 977808bef7..c618c3465b 100644 --- a/awx/ui/client/src/lists/ScheduledJobs.js +++ b/awx/ui/client/src/lists/ScheduledJobs.js @@ -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: { diff --git a/awx/ui/client/src/lists/Streams.js b/awx/ui/client/src/lists/Streams.js index 0842019c4c..85aef53adc 100644 --- a/awx/ui/client/src/lists/Streams.js +++ b/awx/ui/client/src/lists/Streams.js @@ -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' } }, diff --git a/awx/ui/client/src/lookup/lookup.factory.js b/awx/ui/client/src/lookup/lookup.factory.js index 7db6afd894..899a03efda 100644 --- a/awx/ui/client/src/lookup/lookup.factory.js +++ b/awx/ui/client/src/lookup/lookup.factory.js @@ -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', diff --git a/awx/ui/client/src/management-jobs/card/card.route.js b/awx/ui/client/src/management-jobs/card/card.route.js index 90bbebde81..7f92f75908 100644 --- a/awx/ui/client/src/management-jobs/card/card.route.js +++ b/awx/ui/client/src/management-jobs/card/card.route.js @@ -13,7 +13,7 @@ export default { controller: 'managementJobsCardController', data: { activityStream: true, - activityStreamTarget: 'management_job' + activityStreamTarget: 'job' }, ncyBreadcrumb: { parent: 'setup', diff --git a/awx/ui/client/src/notifications/notifications.list.js b/awx/ui/client/src/notifications/notifications.list.js index 066732a9a9..7266299306 100644 --- a/awx/ui/client/src/notifications/notifications.list.js +++ b/awx/ui/client/src/notifications/notifications.list.js @@ -15,7 +15,7 @@ export default function(){ index: false, hover: false, emptyListText: 'No Notifications exist', - basePath: 'notifications', + basePath: 'notification_templates', fields: { name: { key: true, diff --git a/awx/ui/client/src/scheduler/scheduler.controller.js b/awx/ui/client/src/scheduler/scheduler.controller.js index f50376cef0..491465e5e8 100644 --- a/awx/ui/client/src/scheduler/scheduler.controller.js +++ b/awx/ui/client/src/scheduler/scheduler.controller.js @@ -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}
Schedules`; + schedList.listTitle = title ? title : parentObject.name; + schedList.listTitle = `${schedList.listTitle}
Schedules`; + + schedList.basePath = parentObject.url + "schedules"; LoadSchedulesScope({ parent_scope: $scope, scope: $scope, - list: SchedulesList, + list: schedList, id: 'schedule-list-target', url: url, pageSize: 20 diff --git a/awx/ui/client/src/search/tagSearch.block.less b/awx/ui/client/src/search/tagSearch.block.less index 9b342491a2..484c11f147 100644 --- a/awx/ui/client/src/search/tagSearch.block.less +++ b/awx/ui/client/src/search/tagSearch.block.less @@ -30,7 +30,6 @@ white-space: nowrap; align-items: center; max-height: 400px; - width: 120px; cursor: pointer; text-transform: uppercase; } @@ -40,8 +39,6 @@ } .TagSearch-typeDropdownName { - width: 66px; - text-overflow: ellipsis; display: block; overflow: hidden; } @@ -80,6 +77,7 @@ .TagSearch-dropdownItem { padding: 5px 10px; cursor: pointer; + text-transform: capitalize; } .TagSearch-dropdownItem:hover { @@ -92,13 +90,13 @@ .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; } .TagSearch-searchTermContainer.is-open { diff --git a/awx/ui/client/src/search/tagSearch.controller.js b/awx/ui/client/src/search/tagSearch.controller.js index d49e294a5b..52a86238df 100644 --- a/awx/ui/client/src/search/tagSearch.controller.js +++ b/awx/ui/client/src/search/tagSearch.controller.js @@ -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; }; diff --git a/awx/ui/client/src/search/tagSearch.partial.html b/awx/ui/client/src/search/tagSearch.partial.html index 3f1108018d..bc04f137b8 100644 --- a/awx/ui/client/src/search/tagSearch.partial.html +++ b/awx/ui/client/src/search/tagSearch.partial.html @@ -8,14 +8,15 @@ {{ currentSearchType.label }} - +
{{ type.label }}
diff --git a/awx/ui/client/src/search/tagSearch.service.js b/awx/ui/client/src/search/tagSearch.service.js index 84e699fd65..2ccf3cb7e1 100644 --- a/awx/ui/client/src/search/tagSearch.service.js +++ b/awx/ui/client/src/search/tagSearch.service.js @@ -41,7 +41,7 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu if (type === 'select') { obj.typeOptions = typeOptions; } - + return obj; }; @@ -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); }); diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index ad4b10e56a..3ef22859b4 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1819,7 +1819,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat !(is_superuser && ${hideOnSuperuser})\"> ${tagSearch}
-
+
${actionButtons}
@@ -1868,36 +1868,39 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat `; html += (collection.index === undefined || collection.index !== false) ? "#\n" : ""; for (fld in collection.fields) { - html += ""; - } else { - html += ">"; - } + html += ""; } else { - html += "fa fa-sort"; + html += ">"; } - html += "\">"; - } - html += "\n"; + + html += collection.fields[fld].label; + + if (!(collection.fields[fld].noSort || collection.fields[fld].nosort)) { + html += " "; + } + + html += "\n"; + } } if (collection.fieldActions) { html += "Actions\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 diff --git a/awx/ui/client/src/shared/pagination/pagination.service.js b/awx/ui/client/src/shared/pagination/pagination.service.js index 673e93432f..36e87c0807 100644 --- a/awx/ui/client/src/shared/pagination/pagination.service.js +++ b/awx/ui/client/src/shared/pagination/pagination.service.js @@ -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); + } } }; }]; diff --git a/awx/ui/client/src/widgets/Stream.js b/awx/ui/client/src/widgets/Stream.js index 4869606022..021db4df98 100644 --- a/awx/ui/client/src/widgets/Stream.js +++ b/awx/ui/client/src/widgets/Stream.js @@ -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 }); From c5c65adc097e1c51d06884af4292bedf9b91fe7f Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Wed, 1 Jun 2016 14:11:19 -0400 Subject: [PATCH 2/7] fix layout of search dropdowns --- awx/ui/client/legacy-styles/ansible-ui.less | 4 ++ awx/ui/client/src/search/tagSearch.block.less | 12 +++--- .../client/src/search/tagSearch.partial.html | 38 +++++++++---------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/awx/ui/client/legacy-styles/ansible-ui.less b/awx/ui/client/legacy-styles/ansible-ui.less index 0805b921a3..18b44f3788 100644 --- a/awx/ui/client/legacy-styles/ansible-ui.less +++ b/awx/ui/client/legacy-styles/ansible-ui.less @@ -2242,3 +2242,7 @@ a:hover { #scheduled-jobs-tab .List-header { display: none; } + +.ui-widget { + font-family: 'Open Sans'; +} diff --git a/awx/ui/client/src/search/tagSearch.block.less b/awx/ui/client/src/search/tagSearch.block.less index 484c11f147..f242d1b2d1 100644 --- a/awx/ui/client/src/search/tagSearch.block.less +++ b/awx/ui/client/src/search/tagSearch.block.less @@ -29,9 +29,9 @@ display: flex; white-space: nowrap; align-items: center; - max-height: 400px; cursor: pointer; text-transform: uppercase; + position: relative; } .TagSearch-typeDropdown.is-open { @@ -49,7 +49,7 @@ .TagSearch-dropdownContainer { position: absolute; - left: 15px; + left: -1px; top: 34px; font-size: 14px; border-radius: 5px; @@ -65,13 +65,12 @@ } .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 { @@ -97,6 +96,7 @@ border-bottom-right-radius: 5px; display: flex; background-color: @default-bg; + position: relative; } .TagSearch-searchTermContainer.is-open { diff --git a/awx/ui/client/src/search/tagSearch.partial.html b/awx/ui/client/src/search/tagSearch.partial.html index bc04f137b8..0b4b7aa0bf 100644 --- a/awx/ui/client/src/search/tagSearch.partial.html +++ b/awx/ui/client/src/search/tagSearch.partial.html @@ -10,15 +10,15 @@ -
-
-
- {{ type.label }} +
+
+ {{ type.label }} +
-
-
-
- {{ type.label }} +
+
+ {{ type.label }} +
From 857f873f4d1c2e74823747819041ecead64525da Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Wed, 1 Jun 2016 14:32:42 -0400 Subject: [PATCH 3/7] fix external source and sync failure queries on inv groups/invs --- awx/ui/client/src/lists/Inventories.js | 10 ++++++++-- awx/ui/client/src/lists/InventoryGroups.js | 14 +++++++++----- awx/ui/client/src/search/tagSearch.service.js | 5 ++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/awx/ui/client/src/lists/Inventories.js b/awx/ui/client/src/lists/Inventories.js index 60543239c0..6bb9d6f3fa 100644 --- a/awx/ui/client/src/lists/Inventories.js +++ b/awx/ui/client/src/lists/Inventories.js @@ -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 } }, diff --git a/awx/ui/client/src/lists/InventoryGroups.js b/awx/ui/client/src/lists/InventoryGroups.js index aefbd34a4d..546f9c3f6c 100644 --- a/awx/ui/client/src/lists/InventoryGroups.js +++ b/awx/ui/client/src/lists/InventoryGroups.js @@ -95,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?', diff --git a/awx/ui/client/src/search/tagSearch.service.js b/awx/ui/client/src/search/tagSearch.service.js index 2ccf3cb7e1..641c48736b 100644 --- a/awx/ui/client/src/search/tagSearch.service.js +++ b/awx/ui/client/src/search/tagSearch.service.js @@ -41,7 +41,7 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu if (type === 'select') { obj.typeOptions = typeOptions; } - + return obj; }; @@ -180,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.indexOf("=") > 0) { + tag.url = selectVal.value; + tag.name = selectVal.label; } else { tag.url = tag.value + "=" + selectVal.value; tag.name = selectVal.label; From e041fe831621d2b12d7081688085f825d437dc81 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Wed, 1 Jun 2016 14:44:30 -0400 Subject: [PATCH 4/7] fix of tag search type dropdown border and empty tags --- awx/ui/client/src/search/tagSearch.block.less | 1 + awx/ui/client/src/search/tagSearch.controller.js | 2 +- awx/ui/client/src/search/tagSearch.service.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/search/tagSearch.block.less b/awx/ui/client/src/search/tagSearch.block.less index f242d1b2d1..75ccca2938 100644 --- a/awx/ui/client/src/search/tagSearch.block.less +++ b/awx/ui/client/src/search/tagSearch.block.less @@ -56,6 +56,7 @@ 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; diff --git a/awx/ui/client/src/search/tagSearch.controller.js b/awx/ui/client/src/search/tagSearch.controller.js index 52a86238df..3595db3712 100644 --- a/awx/ui/client/src/search/tagSearch.controller.js +++ b/awx/ui/client/src/search/tagSearch.controller.js @@ -74,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); } diff --git a/awx/ui/client/src/search/tagSearch.service.js b/awx/ui/client/src/search/tagSearch.service.js index 641c48736b..be1a24b729 100644 --- a/awx/ui/client/src/search/tagSearch.service.js +++ b/awx/ui/client/src/search/tagSearch.service.js @@ -180,7 +180,7 @@ 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.indexOf("=") > 0) { + } else if (selectVal.value && typeof selectVal.value === 'string' && selectVal.value.indexOf("=") > 0) { tag.url = selectVal.value; tag.name = selectVal.label; } else { From 308fc5ef2ca2b053ca8d2868765fec1fb081f587 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 24 May 2016 13:00:36 -0400 Subject: [PATCH 5/7] support more than label limit on edit and list views --- awx/ui/client/legacy-styles/forms.less | 5 +- awx/ui/client/src/access/roleList.block.less | 2 +- .../src/bread-crumb/bread-crumb.directive.js | 3 +- awx/ui/client/src/forms/JobTemplates.js | 78 ++++++++++--------- .../edit/job-templates-edit.controller.js | 49 ++++++++---- .../labels/labelsList.block.less | 41 ++++++---- .../labels/labelsList.directive.js | 40 +++++++++- .../labels/labelsList.partial.html | 11 +-- 8 files changed, 156 insertions(+), 73 deletions(-) diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 5f69f25d47..aca378c746 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -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; diff --git a/awx/ui/client/src/access/roleList.block.less b/awx/ui/client/src/access/roleList.block.less index 0723c3451d..9b185148b0 100644 --- a/awx/ui/client/src/access/roleList.block.less +++ b/awx/ui/client/src/access/roleList.block.less @@ -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; } diff --git a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js index 180bce2ab9..e74ccfaaf3 100644 --- a/awx/ui/client/src/bread-crumb/bread-crumb.directive.js +++ b/awx/ui/client/src/bread-crumb/bread-crumb.directive.js @@ -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) { diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js index 7a9065af2b..b8ef68962e 100644 --- a/awx/ui/client/src/forms/JobTemplates.js +++ b/awx/ui/client/src/forms/JobTemplates.js @@ -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: "

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.

" + - "JSON:
\n" + - "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + - "YAML:
\n" + - "
---
somevar: somevalue
password: magic
\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,49 @@ export default dataPlacement: 'right', dataTitle: "Host Config Key", dataContainer: "body" + }, + survey: { + type: 'custom', + column: 2, + ngHide: "job_type.value === 'scan'" , + control: ''+ + '' + }, + 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: "

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.

" + + "JSON:
\n" + + "
{
 \"somevar\": \"somevalue\",
 \"password\": \"magic\"
}
\n" + + "YAML:
\n" + + "
---
somevar: somevalue
password: magic
\n", + dataTitle: 'Extra Variables', + dataPlacement: 'right', + dataContainer: "body", + subCheckbox: { + variable: 'ask_variables_on_launch', + text: 'Prompt on launch' + } } }, diff --git a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js index 89c9425a2e..b6cfed90b6 100644 --- a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js +++ b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js @@ -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 diff --git a/awx/ui/client/src/job-templates/labels/labelsList.block.less b/awx/ui/client/src/job-templates/labels/labelsList.block.less index 4e99567eaa..f7abaf79a7 100644 --- a/awx/ui/client/src/job-templates/labels/labelsList.block.less +++ b/awx/ui/client/src/job-templates/labels/labelsList.block.less @@ -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 { diff --git a/awx/ui/client/src/job-templates/labels/labelsList.directive.js b/awx/ui/client/src/job-templates/labels/labelsList.directive.js index 6df8b36025..4fb8225f3b 100644 --- a/awx/ui/client/src/job-templates/labels/labelsList.directive.js +++ b/awx/ui/client/src/job-templates/labels/labelsList.directive.js @@ -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 () { diff --git a/awx/ui/client/src/job-templates/labels/labelsList.partial.html b/awx/ui/client/src/job-templates/labels/labelsList.partial.html index 901ff98109..0ad0a00eda 100644 --- a/awx/ui/client/src/job-templates/labels/labelsList.partial.html +++ b/awx/ui/client/src/job-templates/labels/labelsList.partial.html @@ -1,10 +1,11 @@ -
-
- {{ label.name }} -
+
+
+ {{ label.name }} +
+
View More
From 2915b8665055ad6c567d8fbffe0c8211e4647b75 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 24 May 2016 13:01:05 -0400 Subject: [PATCH 6/7] fix limit for summary_fields of labels --- awx/ui/client/src/job-templates/labels/labelsList.partial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/ui/client/src/job-templates/labels/labelsList.partial.html b/awx/ui/client/src/job-templates/labels/labelsList.partial.html index 0ad0a00eda..8c2f08f712 100644 --- a/awx/ui/client/src/job-templates/labels/labelsList.partial.html +++ b/awx/ui/client/src/job-templates/labels/labelsList.partial.html @@ -7,5 +7,5 @@ {{ label.name }}
-
View More
From 2e9aa3bb8f5e5c0b89a9e997a135a5461f3c44d8 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Thu, 26 May 2016 16:24:00 -0400 Subject: [PATCH 7/7] update list column sizes --- awx/ui/client/src/lists/JobTemplates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/lists/JobTemplates.js b/awx/ui/client/src/lists/JobTemplates.js index 5217ad42c9..cd61344686 100644 --- a/awx/ui/client/src/lists/JobTemplates.js +++ b/awx/ui/client/src/lists/JobTemplates.js @@ -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'