diff --git a/awx/ui/client/features/applications/add-applications.controller.js b/awx/ui/client/features/applications/add-applications.controller.js
index c848bcd345..4318d29c82 100644
--- a/awx/ui/client/features/applications/add-applications.controller.js
+++ b/awx/ui/client/features/applications/add-applications.controller.js
@@ -1,4 +1,4 @@
-function AddApplicationsController (models, $state, strings) {
+function AddApplicationsController (models, $state, strings, $scope) {
const vm = this || {};
const { application, me, organization } = models;
@@ -62,12 +62,19 @@ function AddApplicationsController (models, $state, strings) {
vm.form.onSaveSuccess = res => {
$state.go('applications.edit', { application_id: res.data.id }, { reload: true });
};
+
+ $scope.$watch('organization', () => {
+ if ($scope.organization) {
+ vm.form.organization._idFromModal = $scope.organization;
+ }
+ });
}
AddApplicationsController.$inject = [
'resolvedModels',
'$state',
- 'ApplicationsStrings'
+ 'ApplicationsStrings',
+ '$scope'
];
export default AddApplicationsController;
diff --git a/awx/ui/client/features/applications/add-edit-applications.view.html b/awx/ui/client/features/applications/add-edit-applications.view.html
index 1b77c009bf..873f75ded0 100644
--- a/awx/ui/client/features/applications/add-edit-applications.view.html
+++ b/awx/ui/client/features/applications/add-edit-applications.view.html
@@ -1,3 +1,4 @@
+
diff --git a/awx/ui/client/features/applications/edit-applications.controller.js b/awx/ui/client/features/applications/edit-applications.controller.js
index 1bf6b8c91b..cf53a1abc3 100644
--- a/awx/ui/client/features/applications/edit-applications.controller.js
+++ b/awx/ui/client/features/applications/edit-applications.controller.js
@@ -43,6 +43,12 @@ function EditApplicationsController (models, $state, strings, $scope) {
}
});
+ $scope.$watch('organization', () => {
+ if ($scope.organization) {
+ vm.form.organization._idFromModal = $scope.organization;
+ }
+ });
+
if (isEditable) {
vm.form = application.createFormSchema('put', { omit });
} else {
diff --git a/awx/ui/client/features/credentials/add-credentials.controller.js b/awx/ui/client/features/credentials/add-credentials.controller.js
index e0b575bf2d..6f99792a89 100644
--- a/awx/ui/client/features/credentials/add-credentials.controller.js
+++ b/awx/ui/client/features/credentials/add-credentials.controller.js
@@ -115,6 +115,18 @@ function AddCredentialsController (models, $state, $scope, strings, componentsSt
return { obj, error };
};
+
+ $scope.$watch('organization', () => {
+ if ($scope.organization) {
+ vm.form.organization._idFromModal = $scope.organization;
+ }
+ });
+
+ $scope.$watch('credential_type', () => {
+ if ($scope.credential_type) {
+ vm.form.credential_type._idFromModal = $scope.credential_type;
+ }
+ });
}
AddCredentialsController.$inject = [
diff --git a/awx/ui/client/features/credentials/add-edit-credentials.view.html b/awx/ui/client/features/credentials/add-edit-credentials.view.html
index 277994cd81..43e56259aa 100644
--- a/awx/ui/client/features/credentials/add-edit-credentials.view.html
+++ b/awx/ui/client/features/credentials/add-edit-credentials.view.html
@@ -1,3 +1,5 @@
+
+
diff --git a/awx/ui/client/features/credentials/edit-credentials.controller.js b/awx/ui/client/features/credentials/edit-credentials.controller.js
index 81b6ebe5fb..560b2605a6 100644
--- a/awx/ui/client/features/credentials/edit-credentials.controller.js
+++ b/awx/ui/client/features/credentials/edit-credentials.controller.js
@@ -32,6 +32,18 @@ function EditCredentialsController (models, $state, $scope, strings, componentsS
}
});
+ $scope.$watch('organization', () => {
+ if ($scope.organization) {
+ vm.form.organization._idFromModal = $scope.organization;
+ }
+ });
+
+ $scope.$watch('credential_type', () => {
+ if ($scope.credential_type) {
+ vm.form.credential_type._idFromModal = $scope.credential_type;
+ }
+ });
+
// Only exists for permissions compatibility
$scope.credential_obj = credential.get();
diff --git a/awx/ui/client/features/users/tokens/users-tokens-add-application.route.js b/awx/ui/client/features/users/tokens/users-tokens-add-application.route.js
index 13197ca11d..20173c260a 100644
--- a/awx/ui/client/features/users/tokens/users-tokens-add-application.route.js
+++ b/awx/ui/client/features/users/tokens/users-tokens-add-application.route.js
@@ -13,8 +13,7 @@ export default {
}
},
data: {
- basePath: 'applications',
- formChildState: true
+ basePath: 'applications'
},
ncyBreadcrumb: {
skip: true
@@ -42,14 +41,19 @@ export default {
name: {
key: true,
label: 'Name',
- columnClass: 'col-lg-4 col-md-6 col-sm-8 col-xs-8',
+ columnClass: 'col-lg-2 col-md-3 col-sm-4 col-xs-4',
awToolTip: '{{application.description | sanitize}}',
dataPlacement: 'top'
},
- },
- actions: {
- },
- fieldActions: {
+ organization: {
+ label: 'Organization',
+ columnClass: 'col-lg-2 col-md-3 col-sm-4 col-xs-4',
+ modalColumnClass: 'col-lg-2 col-md-3 col-sm-4 col-xs-4',
+ key: false,
+ ngBind: 'application.summary_fields.organization.name',
+ sourceModel: 'organization',
+ includeModal: true
+ }
}
})],
Dataset: ['QuerySet', 'GetBasePath', '$stateParams', 'ListDefinition',
diff --git a/awx/ui/client/features/users/tokens/users-tokens-add.controller.js b/awx/ui/client/features/users/tokens/users-tokens-add.controller.js
index 67e15fa0ad..26ce20e5f2 100644
--- a/awx/ui/client/features/users/tokens/users-tokens-add.controller.js
+++ b/awx/ui/client/features/users/tokens/users-tokens-add.controller.js
@@ -1,6 +1,6 @@
function AddTokensController (
models, $state, strings, Rest, Alert, Wait, GetBasePath,
- $filter, ProcessErrors
+ $filter, ProcessErrors, $scope
) {
const vm = this || {};
const { application } = models;
@@ -94,6 +94,12 @@ function AddTokensController (
vm.form.onSaveSuccess = () => {
$state.go('^', { user_id: $state.params.user_id }, { reload: true });
};
+
+ $scope.$watch('application', () => {
+ if ($scope.application) {
+ vm.form.application._idFromModal = $scope.application;
+ }
+ });
}
AddTokensController.$inject = [
@@ -105,7 +111,8 @@ AddTokensController.$inject = [
'Wait',
'GetBasePath',
'$filter',
- 'ProcessErrors'
+ 'ProcessErrors',
+ '$scope'
];
export default AddTokensController;
diff --git a/awx/ui/client/features/users/tokens/users-tokens-add.partial.html b/awx/ui/client/features/users/tokens/users-tokens-add.partial.html
index 4b8343a0ed..25bd01a21a 100644
--- a/awx/ui/client/features/users/tokens/users-tokens-add.partial.html
+++ b/awx/ui/client/features/users/tokens/users-tokens-add.partial.html
@@ -1,3 +1,4 @@
+
@@ -8,7 +9,7 @@
-
+
diff --git a/awx/ui/client/features/users/tokens/users-tokens-add.route.js b/awx/ui/client/features/users/tokens/users-tokens-add.route.js
index 56effe1991..fe9548b79a 100644
--- a/awx/ui/client/features/users/tokens/users-tokens-add.route.js
+++ b/awx/ui/client/features/users/tokens/users-tokens-add.route.js
@@ -16,6 +16,21 @@ TokensDetailResolve.$inject = [
'ApplicationModel'
];
+function isMeResolve ($rootScope, $stateParams, $state) {
+ // The user should not be able to add tokens for users other than
+ // themselves. Adding this redirect so that a user is not able to
+ // visit the add-token URL directly for a different user.
+ if (_.has($stateParams, 'user_id') && Number($stateParams.user_id) !== $rootScope.current_user.id) {
+ $state.go('users');
+ }
+}
+
+isMeResolve.$inject = [
+ '$rootScope',
+ '$stateParams',
+ '$state'
+];
+
export default {
url: '/add-token',
name: 'users.edit.tokens.add',
@@ -30,13 +45,14 @@ export default {
label: N_('CREATE TOKEN')
},
views: {
- 'preFormView@users.edit': {
+ 'preFormView@users': {
templateUrl: addTemplate,
controller: AddController,
controllerAs: 'vm'
}
},
resolve: {
- resolvedModels: TokensDetailResolve
+ resolvedModels: TokensDetailResolve,
+ isMe: isMeResolve
}
};
diff --git a/awx/ui/client/lib/components/input/lookup.directive.js b/awx/ui/client/lib/components/input/lookup.directive.js
index 0447d6b448..13632d8eb3 100644
--- a/awx/ui/client/lib/components/input/lookup.directive.js
+++ b/awx/ui/client/lib/components/input/lookup.directive.js
@@ -34,23 +34,20 @@ function AtInputLookupController (baseInputController, $q, $state) {
}
};
- scope.$watch(scope.state._resource, vm.watchResource);
+ // This should get triggered when the user selects something in the lookup modal and
+ // hits save to close the modal. This won't get triggered when the user types in
+ // a value in the input.
+ scope.$watch('state._idFromModal', () => {
+ if (scope.state._idFromModal &&
+ (scope.state._idFromModal !== scope.state._value)
+ ) {
+ vm.search({ id: scope.state._idFromModal });
+ }
+ });
vm.check();
};
- vm.watchResource = () => {
- if (!scope[scope.state._resource]) {
- return;
- }
-
- if (scope[scope.state._resource] !== scope.state._value) {
- scope.state._displayValue = scope[`${scope.state._resource}_name`];
-
- vm.search();
- }
- };
-
vm.lookup = () => {
const params = {};
@@ -62,6 +59,7 @@ function AtInputLookupController (baseInputController, $q, $state) {
};
vm.reset = () => {
+ scope.state._idFromModal = undefined;
scope.state._value = undefined;
scope[scope.state._resource] = undefined;
};
@@ -80,15 +78,20 @@ function AtInputLookupController (baseInputController, $q, $state) {
vm.searchAfterDebounce();
};
- vm.search = () => {
+ vm.search = (searchParams) => {
scope.state._touched = true;
- if (scope.state._displayValue === '' && !scope.state._required) {
+ if (!scope.state._required &&
+ scope.state._displayValue === '' &&
+ !scope.state._idFromModal
+ ) {
scope.state._value = null;
return vm.check({ isValid: true });
}
- return model.search({ [search.key]: scope.state._displayValue }, search.config)
+ searchParams = searchParams || { [search.key]: scope.state._displayValue };
+
+ return model.search(searchParams, search.config)
.then(found => {
if (!found) {
vm.reset();
@@ -99,6 +102,7 @@ function AtInputLookupController (baseInputController, $q, $state) {
scope[scope.state._resource] = model.get('id');
scope.state._value = model.get('id');
scope.state._displayValue = model.get('name');
+ scope.state._idFromModal = undefined;
})
.catch(() => vm.reset())
.finally(() => {
diff --git a/awx/ui/client/lib/components/input/lookup.partial.html b/awx/ui/client/lib/components/input/lookup.partial.html
index 24cde94edc..5a951cdb31 100644
--- a/awx/ui/client/lib/components/input/lookup.partial.html
+++ b/awx/ui/client/lib/components/input/lookup.partial.html
@@ -30,6 +30,4 @@
-
-
-
+
diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js
index 5aeb590a81..734aafee4e 100644
--- a/awx/ui/client/src/shared/form-generator.js
+++ b/awx/ui/client/src/shared/form-generator.js
@@ -167,7 +167,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
wrapPanel(html, ignorePanel){
if(ignorePanel) {
return `
-
${html}
@@ -176,7 +175,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
}
else {
return `
-
${MessageBar(this.form)}
${html}
diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js
index b529cb2788..92fb28cf71 100644
--- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js
+++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js
@@ -545,22 +545,27 @@ export default ['$compile', 'Attr', 'Icon',
}
}
if (options.mode === 'lookup') {
- let customClass = list.fields.name.modalColumnClass || '';
- html += `
- | `;
+ for (fld in list.fields) {
+ if(fld === 'name' || _.has(list.fields[fld], 'includeModal')){
+ let customClass = list.fields.name.modalColumnClass || '';
+ html += `
+ | `;
+ }
+
+ }
if(list.fields.info) {
- customClass = list.fields.name.modalColumnClass || '';
+ let customClass = list.fields.name.modalColumnClass || '';
const infoHeaderClass = _.get(list.fields.info, 'infoHeaderClass', 'List-tableHeader--info');
html += `