Boolean / Smart Search (#3631)

* Part 1: building new search components

Directives: smart-search, column-sort, paginate
Service: QuerySet
Model: DjangoSearchModel

* Part 2: Implementing new search components, de-implementing old search
components

Remove old code:
	* tagSearch directive
	* old pagination strategy
	* old column sorting strategy
	* lookup

Add new directives to list/form generator:
	* smart-search,
	* paginate
	* column-sort

Connect $state + dataset resolution
	* upgrade ui-router lib to v1.0.0-beta3
	* Custom $urlMatcherFactory.type - queryset
	* Render lists, forms, related, lookups in named views
	* Provide html templates in list/form/lookup/related state definitions
	* Provide dataset through resolve block in state definitions

Update utilities
	* isEmpty filter
	* use async validation strategy in awlookup directive

* Part 3: State implementations (might split into per-module commits)

* Support optional state definition flag: squashSearchUrl. *_search params are only URI-encoded if squashSearchUrl is falsey.

* * Fix list badge counts
* Clear search input after search term(s) applied
* Chain of multiple search terms in one submission

* Hook up activity stream

* Hook up portal mode

* Fix pagination range calculations

* Hook up organization sub-list views

* Hook up listDefinition.search defaults

* Fix ng-disabled conditions reflecting RBAC access on form fields

* Fix actively-editing indicator in generated lists

* form generator - fix undefined span, remove dead event listeners

* wrap hosts/groups lists in a panel, fix groups list error

* Smart search directive: clear all search tags

* Search tags - ‘Clear All’ text - 12px
Search key - remove top padding/margin
Search key - reverse bolding of relationship fields / label, add commas
Search tags - remove padding-bottom
Lookup modal - “X” close button styled incorrectly
Lookup modal - List title not rendered
Lookup modal - 20px margin between buttons

* Portal Mode
Fix default column-sort on jobs list
Hide column-oort on job status column
Apply custom search bar sizes

* stateDefinition.factory

Return ES6 Promise instead of $q promise.
$q cannot be safely provided during module.config() phase
Some generated state trees (inventory / inventoryManage) need to be
reduced to one promise. Side-step issues caused by ui-router de-registering ALL registered states that match placeholder state name/url pattern.

e.g. inventories.lazyLoad() would de-register inventoryManage states if
a page refresh occured @ /#/inventories/**

* Combine generated state trees: inventories + inventoryManage
Hook up inventory sync schedule list/form add /form edit views

* Hook up system job schedule list/add/edit states

* Fix breadcrumb of generated states in /setup view
Fix typo in scheduler search prefix

* Remove old search system deritus from list definitions

* Fix breadcrumb definitions in states registered in app.js config block

* Transclude list action buttons in generated form lists

* Lookup Modal passes acceptance criterea:
Modal cancel/exit - don’t update form field’s ng-model
Modal save - do update form field's ng-model
Transclude generated list contents into <lookup-modal> directive
Lookup modal test spec

* Fix typo in merge conflict resolution

* Disable failing unit tests pending revision

* Integrate smart-search architechture into add-permissions modal

* use a semicolon delimiter instead of comma to avoid collision with django __in comparator

* Hook up Dashboard > Hosts states, update Dashboard Inventory/Project counts with new search filters

* Misc bug splat

Add 20px spacing around root ui-view
Fix missing closing div in related views
Remove dupe line in smart-search controller

* Remove defunct LookupHelper code

* Rebuild inventories list status tooltips on updates to dataset

Code cleanup - remove defunct modules
Remove LookupHelper / LookupInit code
Remove pre-RBAC permissions module

* Add mising stateTree / basePath properties to form definitions

* Resolve i18n conflicts in list and form generator
Freeze dependencies

* Integrate sockets

* Final bug splat:
fix jobs > job details and jobs > scheduled routing
fix mis-resolved merge conflicts
swap console.info for $log.debug
This commit is contained in:
Leigh Johnson
2016-10-28 14:28:06 -04:00
committed by GitHub
parent defd271c90
commit a49095bdbc
283 changed files with 9625 additions and 14375 deletions

View File

@@ -18,6 +18,8 @@ export default
addTitle: i18n._('Create Credential'), //Legend in add mode
editTitle: '{{ name }}', //Legend in edit mode
name: 'credential',
// the top-most node of generated state tree
stateTree: 'credentials',
forceListeners: true,
subFormTitles: {
credentialSubForm: i18n._('Type Details'),
@@ -31,24 +33,22 @@ export default
name: {
label: i18n._('Name'),
type: 'text',
addRequired: true,
editRequired: true,
required: true,
autocomplete: false,
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
description: {
label: i18n._('Description'),
type: 'text',
addRequired: false,
editRequired: false,
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
organization: {
addRequired: false,
editRequired: false,
// interpolated with $rootScope
basePath: "{{$rootScope.current_user.is_superuser ? 'api/v1/organizations' : $rootScope.current_user.url + 'admin_of_organizations'}}",
ngShow: 'canShareCredential',
label: i18n._('Organization'),
type: 'lookup',
list: 'OrganizationList',
sourceModel: 'organization',
sourceField: 'name',
ngClick: 'lookUpOrganization()',
@@ -56,7 +56,7 @@ export default
dataTitle: i18n._('Organization') + ' ',
dataPlacement: 'bottom',
dataContainer: "body",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
kind: {
label: i18n._('Type'),
@@ -64,8 +64,7 @@ export default
type: 'select',
ngOptions: 'kind.label for kind in credential_kind_options track by kind.value', // select as label for value in array 'kind.label for kind in credential_kind_options',
ngChange: 'kindChange()',
addRequired: true,
editRequired: true,
required: true,
awPopOver: i18n._('<dl>\n' +
'<dt>Machine</dt>\n' +
'<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
@@ -88,7 +87,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
hasSubForm: true,
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
access_key: {
label: i18n._('Access Key'),
@@ -101,7 +100,7 @@ export default
autocomplete: false,
apiField: 'username',
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
secret_key: {
label: i18n._('Secret Key'),
@@ -130,7 +129,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"host": {
labelBind: 'hostLabel',
@@ -147,7 +146,7 @@ export default
init: false
},
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"subscription": {
label: i18n._("Subscription ID"),
@@ -157,15 +156,15 @@ export default
reqExpression: 'subscription_required',
init: false
},
addRequired: false,
editRequired: false,
autocomplete: false,
awPopOver: i18n._('<p>Subscription ID is an Azure construct, which is mapped to a username.</p>'),
dataTitle: i18n._('Subscription ID'),
dataPlacement: 'right',
dataContainer: "body",
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"username": {
labelBind: 'usernameLabel',
@@ -178,7 +177,7 @@ export default
},
autocomplete: false,
subForm: "credentialSubForm",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"email_address": {
labelBind: 'usernameLabel',
@@ -194,7 +193,7 @@ export default
dataPlacement: 'right',
dataContainer: "body",
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"api_key": {
label: i18n._('API Key'),
@@ -208,7 +207,7 @@ export default
hasShowInputButton: true,
clear: false,
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"password": {
labelBind: 'passwordLabel',
@@ -222,15 +221,13 @@ export default
init: false
},
subForm: "credentialSubForm",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"ssh_password": {
label: i18n._('Password'),
type: 'sensitive',
ngShow: "kind.value == 'ssh'",
ngDisabled: "ssh_password_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
addRequired: false,
editRequired: false,
subCheckbox: {
variable: 'ssh_password_ask',
text: i18n._('Ask at runtime?'),
@@ -251,8 +248,8 @@ export default
},
class: 'Form-textAreaLabel Form-formGroup--fullWidth',
elementClass: 'Form-monospace',
addRequired: false,
editRequired: false,
awDropFile: true,
rows: 10,
awPopOver: i18n._("SSH key description"),
@@ -261,14 +258,12 @@ export default
dataPlacement: 'right',
dataContainer: "body",
subForm: "credentialSubForm",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"ssh_key_unlock": {
label: i18n._('Private Key Passphrase'),
type: 'sensitive',
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
addRequired: false,
editRequired: false,
ngDisabled: "keyEntered === false || ssh_key_unlock_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
subCheckbox: {
variable: 'ssh_key_unlock_ask',
@@ -293,25 +288,23 @@ export default
dataPlacement: 'right',
dataContainer: "body",
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"become_username": {
labelBind: 'becomeUsernameLabel',
type: 'text',
ngShow: "(kind.value == 'ssh' && (become_method && become_method.value)) ",
addRequired: false,
editRequired: false,
autocomplete: false,
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"become_password": {
labelBind: 'becomePasswordLabel',
type: 'sensitive',
ngShow: "(kind.value == 'ssh' && (become_method && become_method.value)) ",
ngDisabled: "become_password_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
addRequired: false,
editRequired: false,
subCheckbox: {
variable: 'become_password_ask',
text: i18n._('Ask at runtime?'),
@@ -326,7 +319,7 @@ export default
label: i18n._('Client ID'),
subForm: 'credentialSubForm',
ngShow: "kind.value === 'azure_rm'",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
secret:{
type: 'sensitive',
@@ -335,14 +328,14 @@ export default
label: i18n._('Client Secret'),
subForm: 'credentialSubForm',
ngShow: "kind.value === 'azure_rm'",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
tenant: {
type: 'text',
label: i18n._('Tenant ID'),
subForm: 'credentialSubForm',
ngShow: "kind.value === 'azure_rm'",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
authorize: {
label: i18n._('Authorize'),
@@ -350,7 +343,7 @@ export default
ngChange: "toggleCallback('host_config_key')",
subForm: 'credentialSubForm',
ngShow: "kind.value === 'net'",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
authorize_password: {
label: i18n._('Authorize Password'),
@@ -359,7 +352,7 @@ export default
autocomplete: false,
subForm: 'credentialSubForm',
ngShow: "authorize && authorize !== 'false'",
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"project": {
labelBind: 'projectLabel',
@@ -370,14 +363,12 @@ export default
dataTitle: i18n._('Project Name'),
dataPlacement: 'right',
dataContainer: "body",
addRequired: false,
editRequired: false,
awRequiredWhen: {
reqExpression: 'project_required',
init: false
},
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
"domain": {
labelBind: 'domainLabel',
@@ -391,18 +382,14 @@ export default
dataTitle: i18n._('Domain Name'),
dataPlacement: 'right',
dataContainer: "body",
addRequired: false,
editRequired: false,
subForm: 'credentialSubForm',
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)',
subForm: 'credentialSubForm'
},
"vault_password": {
label: i18n._("Vault Password"),
type: 'sensitive',
ngShow: "kind.value == 'ssh'",
ngDisabled: "vault_password_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
addRequired: false,
editRequired: false,
subCheckbox: {
variable: 'vault_password_ask',
text: i18n._('Ask at runtime?'),
@@ -417,17 +404,17 @@ export default
buttons: {
cancel: {
ngClick: 'formCancel()',
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
close: {
ngClick: 'formCancel()',
ngShow: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngShow: '!(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
},
save: {
label: 'Save',
ngClick: 'formSave()', //$scope.function to call on click, optional
ngDisabled: true,
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)' //Disable when $pristine or $invalid, optional
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || !canAdd)' //Disable when $pristine or $invalid, optional
}
},
@@ -437,24 +424,25 @@ export default
awToolTip: '{{permissionsTooltip}}',
dataTipWatch: 'permissionsTooltip',
dataPlacement: 'top',
basePath: 'credentials/:id/access_list/',
basePath: 'api/v1/credentials/{{$stateParams.credential_id}}/access_list/',
search: {
order_by: 'username'
},
type: 'collection',
title: i18n._('Permissions'),
iterator: 'permission',
index: false,
open: false,
searchType: 'select',
actions: {
add: {
ngClick: "addPermission",
ngClick: "$state.go('.add')",
label: 'Add',
awToolTip: i18n._('Add a permission'),
actionClass: 'btn List-buttonSubmit',
buttonContent: i18n._('&#43; ADD'),
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || !canAdd)'
}
},
fields: {
username: {
key: true,