diff --git a/awx/ui/client/features/templates/templatesList.controller.js b/awx/ui/client/features/templates/templatesList.controller.js
index f2058d0376..e22f146e92 100644
--- a/awx/ui/client/features/templates/templatesList.controller.js
+++ b/awx/ui/client/features/templates/templatesList.controller.js
@@ -22,7 +22,8 @@ function ListTemplatesController(
strings,
Wait,
qs,
- GetBasePath
+ GetBasePath,
+ ngToast
) {
const vm = this || {};
const [jobTemplate, workflowTemplate] = resolvedModels;
@@ -57,7 +58,7 @@ function ListTemplatesController(
};
vm.dataset = Dataset.data;
vm.templates = Dataset.data.results;
-
+
$scope.$watch('vm.dataset.count', () => {
$scope.$emit('updateCount', vm.dataset.count, 'templates');
});
@@ -201,9 +202,21 @@ function ListTemplatesController(
jobTemplate
.create('get', template.id)
.then(model => model.copy())
- .then(({ id }) => {
- const params = { job_template_id: id };
- $state.go('templates.editJobTemplate', params, { reload: true });
+ .then((copiedJT) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${strings.get('SUCCESSFUL_CREATION', copiedJT.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(createErrorHandler('copy job template', 'POST'))
.finally(() => Wait('stop'));
@@ -219,9 +232,21 @@ function ListTemplatesController(
$('#prompt-modal').modal('hide');
Wait('start');
model.copy()
- .then(({ id }) => {
- const params = { workflow_job_template_id: id };
- $state.go('templates.editWorkflowJobTemplate', params, { reload: true });
+ .then((copiedWFJT) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${strings.get('SUCCESSFUL_CREATION', copiedWFJT.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(createErrorHandler('copy workflow', 'POST'))
.finally(() => Wait('stop'));
@@ -360,7 +385,8 @@ ListTemplatesController.$inject = [
'TemplatesStrings',
'Wait',
'QuerySet',
- 'GetBasePath'
+ 'GetBasePath',
+ 'ngToast'
];
export default ListTemplatesController;
diff --git a/awx/ui/client/legacy/styles/ansible-ui.less b/awx/ui/client/legacy/styles/ansible-ui.less
index 1717e2a7a6..dcd4a9bcce 100644
--- a/awx/ui/client/legacy/styles/ansible-ui.less
+++ b/awx/ui/client/legacy/styles/ansible-ui.less
@@ -2349,3 +2349,14 @@ body {
margin-top: .3em;
margin-bottom: .3em;
}
+
+.Toast-wrapper {
+ display: flex;
+ max-width: 250px;
+}
+
+.Toast-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/awx/ui/client/lib/services/base-string.service.js b/awx/ui/client/lib/services/base-string.service.js
index 2362339192..649f33a486 100644
--- a/awx/ui/client/lib/services/base-string.service.js
+++ b/awx/ui/client/lib/services/base-string.service.js
@@ -72,6 +72,7 @@ function BaseStringService (namespace) {
this.COPY = t.s('COPY');
this.YES = t.s('YES');
this.CLOSE = t.s('CLOSE');
+ this.SUCCESSFUL_CREATION = resource => t.s('{{ resource }} successfully created', { resource });
this.deleteResource = {
HEADER: t.s('Delete'),
diff --git a/awx/ui/client/src/credentials/list/credentials-list.controller.js b/awx/ui/client/src/credentials/list/credentials-list.controller.js
index 1f088dbcdc..37d4bd4441 100644
--- a/awx/ui/client/src/credentials/list/credentials-list.controller.js
+++ b/awx/ui/client/src/credentials/list/credentials-list.controller.js
@@ -6,10 +6,10 @@
export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ProcessErrors', 'GetBasePath',
'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'credentialType', 'i18n',
- 'CredentialModel', 'CredentialsStrings',
+ 'CredentialModel', 'CredentialsStrings', 'ngToast',
function($scope, Rest, CredentialList, Prompt,
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset,
- credentialType, i18n, Credential, CredentialsStrings) {
+ credentialType, i18n, Credential, CredentialsStrings, ngToast) {
const credential = new Credential();
@@ -93,9 +93,21 @@ export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ProcessErrors', '
Wait('start');
new Credential('get', credential.id)
.then(model => model.copy())
- .then(({ id }) => {
- const params = { credential_id: id };
- $state.go('credentials.edit', params, { reload: true });
+ .then((copiedCred) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${CredentialsStrings.get('SUCCESSFUL_CREATION', copiedCred.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };
diff --git a/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js b/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js
index 4a4b5d3e7f..0c085d793e 100644
--- a/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js
+++ b/awx/ui/client/src/inventories-hosts/inventories/list/inventory-list.controller.js
@@ -13,7 +13,8 @@
function InventoriesList($scope,
$filter, Rest, InventoryList, Prompt,
ProcessErrors, GetBasePath, Wait, $state,
- Dataset, canAdd, i18n, Inventory, InventoryHostsStrings) {
+ Dataset, canAdd, i18n, Inventory, InventoryHostsStrings,
+ ngToast) {
let inventory = new Inventory();
@@ -82,7 +83,22 @@ function InventoriesList($scope,
Wait('start');
new Inventory('get', inventory.id)
.then(model => model.copy())
- .then(copy => $scope.editInventory(copy, true))
+ .then(copiedInv => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${InventoryHostsStrings.get('SUCCESSFUL_CREATION', copiedInv.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
+ })
.catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };
ProcessErrors($scope, data, status, null, params);
@@ -182,5 +198,5 @@ export default ['$scope',
'$filter', 'Rest', 'InventoryList', 'Prompt',
'ProcessErrors', 'GetBasePath', 'Wait',
'$state', 'Dataset', 'canAdd', 'i18n', 'InventoryModel',
- 'InventoryHostsStrings', InventoriesList
+ 'InventoryHostsStrings', 'ngToast', InventoriesList
];
diff --git a/awx/ui/client/src/inventory-scripts/list/list.controller.js b/awx/ui/client/src/inventory-scripts/list/list.controller.js
index 96c15c31d8..4202a07f5e 100644
--- a/awx/ui/client/src/inventory-scripts/list/list.controller.js
+++ b/awx/ui/client/src/inventory-scripts/list/list.controller.js
@@ -7,12 +7,12 @@
export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList',
'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state', '$filter',
'Dataset', 'rbacUiControlService', 'InventoryScriptModel', 'InventoryScriptsStrings',
- 'i18n',
+ 'i18n', 'ngToast',
function(
$rootScope, $scope, Wait, InventoryScriptsList,
GetBasePath, Rest, ProcessErrors, Prompt, $state, $filter,
Dataset, rbacUiControlService, InventoryScript, InventoryScriptsStrings,
- i18n
+ i18n, ngToast
) {
let inventoryScript = new InventoryScript();
var defaultUrl = GetBasePath('inventory_scripts'),
@@ -51,9 +51,21 @@ export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList',
Wait('start');
new InventoryScript('get', inventoryScript.id)
.then(model => model.copy())
- .then(({ id }) => {
- const params = { inventory_script_id: id };
- $state.go('inventoryScripts.edit', params, { reload: true });
+ .then((copiedInvScript) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${InventoryScriptsStrings.get('SUCCESSFUL_CREATION', copiedInvScript.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };
diff --git a/awx/ui/client/src/notifications/notification-templates-list/list.controller.js b/awx/ui/client/src/notifications/notification-templates-list/list.controller.js
index f471a2aac6..2fd571a740 100644
--- a/awx/ui/client/src/notifications/notification-templates-list/list.controller.js
+++ b/awx/ui/client/src/notifications/notification-templates-list/list.controller.js
@@ -7,12 +7,12 @@
export default ['$scope', 'Wait', 'NotificationTemplatesList',
'GetBasePath', 'Rest', 'ProcessErrors', 'Prompt', '$state',
'ngToast', '$filter', 'Dataset', 'rbacUiControlService',
- 'i18n', 'NotificationTemplate',
+ 'i18n', 'NotificationTemplate', 'AppStrings',
function(
$scope, Wait, NotificationTemplatesList,
GetBasePath, Rest, ProcessErrors, Prompt, $state,
ngToast, $filter, Dataset, rbacUiControlService,
- i18n, NotificationTemplate) {
+ i18n, NotificationTemplate, AppStrings) {
var defaultUrl = GetBasePath('notification_templates'),
list = NotificationTemplatesList;
@@ -92,12 +92,21 @@
Wait('start');
new NotificationTemplate('get', notificationTemplate.id)
.then(model => model.copy())
- .then(({ id }) => {
- const params = {
- notification_template_id: id,
- notification_template: this.notification_templates
- };
- $state.go('notifications.edit', params, { reload: true });
+ .then((copiedNotification) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${AppStrings.get('SUCCESSFUL_CREATION', copiedNotification.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };
diff --git a/awx/ui/client/src/projects/list/projects-list.controller.js b/awx/ui/client/src/projects/list/projects-list.controller.js
index 79adc91b41..a6136bc39a 100644
--- a/awx/ui/client/src/projects/list/projects-list.controller.js
+++ b/awx/ui/client/src/projects/list/projects-list.controller.js
@@ -8,11 +8,11 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert',
'ProjectList', 'Prompt', 'ProcessErrors', 'GetBasePath', 'ProjectUpdate',
'Wait', 'Empty', 'Find', 'GetProjectIcon', 'GetProjectToolTip', '$filter',
'$state', 'rbacUiControlService', 'Dataset', 'i18n', 'QuerySet', 'ProjectModel',
- 'ProjectsStrings',
+ 'ProjectsStrings', 'ngToast',
function($scope, $rootScope, $log, Rest, Alert, ProjectList,
Prompt, ProcessErrors, GetBasePath, ProjectUpdate, Wait, Empty, Find,
GetProjectIcon, GetProjectToolTip, $filter, $state, rbacUiControlService,
- Dataset, i18n, qs, Project, ProjectsStrings) {
+ Dataset, i18n, qs, Project, ProjectsStrings, ngToast) {
let project = new Project();
@@ -156,9 +156,21 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert',
Wait('start');
new Project('get', project.id)
.then(model => model.copy())
- .then(({ id }) => {
- const params = { project_id: id };
- $state.go('projects.edit', params, { reload: true });
+ .then((copiedProj) => {
+ ngToast.success({
+ content: `
+
+
+
+
+
+ ${ProjectsStrings.get('SUCCESSFUL_CREATION', copiedProj.name)}
+
+
`,
+ dismissButton: false,
+ dismissOnTimeout: true
+ });
+ $state.go('.', null, { reload: true });
})
.catch(({ data, status }) => {
const params = { hdr: 'Error!', msg: `Call to copy failed. Return status: ${status}` };