diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js index b4b9c2d976..e9e8213236 100644 --- a/awx/ui/static/js/controllers/Credentials.js +++ b/awx/ui/static/js/controllers/Credentials.js @@ -12,7 +12,7 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, CredentialList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait) + ClearScope, ProcessErrors, GetBasePath, SelectionInit, GetChoices, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -74,6 +74,8 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res LoadBreadCrumbs(); + + scope.showActivity = function() { Stream(); } scope.addCredential = function() { $location.path($location.path() + '/add'); @@ -112,7 +114,7 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res CredentialsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'CredentialList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'GetChoices', 'Wait' ]; + 'GetBasePath', 'SelectionInit', 'GetChoices', 'Wait', 'Stream' ]; function CredentialsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, @@ -249,7 +251,7 @@ CredentialsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, CredentialForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, Prompt, GetBasePath, GetChoices, - KindChange, UserList, TeamList, LookUpInit, Empty, OwnerChange, FormSave + KindChange, UserList, TeamList, LookUpInit, Empty, OwnerChange, FormSave, Stream ) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior @@ -390,6 +392,8 @@ function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeP variable: 'credential_kind_options', callback: 'choicesReady' }); + + scope.showActivity = function() { Stream(); } // Save changes to the parent scope.formSave = function() { generator.clearApiErrors(); FormSave({ scope: scope, mode: 'edit' }) }; @@ -488,5 +492,5 @@ function CredentialsEdit ($scope, $rootScope, $compile, $location, $log, $routeP CredentialsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'CredentialForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices', - 'KindChange', 'UserList', 'TeamList', 'LookUpInit', 'Empty', 'OwnerChange', 'FormSave']; + 'KindChange', 'UserList', 'TeamList', 'LookUpInit', 'Empty', 'OwnerChange', 'FormSave', 'Stream']; diff --git a/awx/ui/static/js/controllers/Inventories.js b/awx/ui/static/js/controllers/Inventories.js index 49f441dd03..a2457ae4ec 100644 --- a/awx/ui/static/js/controllers/Inventories.js +++ b/awx/ui/static/js/controllers/Inventories.js @@ -12,7 +12,7 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, InventoryList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, Wait) + ClearScope, ProcessErrors, GetBasePath, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -138,6 +138,8 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res } }); + + scope.showActivity = function() { Stream(); } scope.addInventory = function() { $location.path($location.path() + '/add'); @@ -202,7 +204,7 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res InventoriesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'InventoryList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'Wait' ]; + 'GetBasePath', 'Wait', 'Stream' ]; function InventoriesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, @@ -317,7 +319,8 @@ InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, OrganizationList, - GetBasePath, LoadInventory, ParseTypeChange, EditInventory, SaveInventory, PostLoadInventory + GetBasePath, LoadInventory, ParseTypeChange, EditInventory, SaveInventory, PostLoadInventory, + Stream ) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior @@ -346,6 +349,8 @@ function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeP LoadInventory({ scope: scope, doPostSteps: false }); + scope.showActivity = function() { Stream(); } + // Cancel scope.formReset = function() { generator.reset(); @@ -372,6 +377,6 @@ InventoriesEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$l 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', 'OrganizationList', 'GetBasePath', 'LoadInventory', 'ParseTypeChange', 'EditInventory', - 'SaveInventory', 'PostLoadInventory' + 'SaveInventory', 'PostLoadInventory', 'Stream' ]; diff --git a/awx/ui/static/js/controllers/JobTemplates.js b/awx/ui/static/js/controllers/JobTemplates.js index 287049fe85..31a2a8aeeb 100644 --- a/awx/ui/static/js/controllers/JobTemplates.js +++ b/awx/ui/static/js/controllers/JobTemplates.js @@ -13,7 +13,7 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, PromptPasswords, JobTemplateForm, CredentialList, - LookUpInit, SubmitJob, Wait) + LookUpInit, SubmitJob, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -39,6 +39,8 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Re LoadBreadCrumbs(); + scope.showActivity = function() { Stream(); } + scope.addJobTemplate = function() { $location.path($location.path() + '/add'); } @@ -80,7 +82,7 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Re JobTemplatesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobTemplateList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors','GetBasePath', 'PromptPasswords', 'JobTemplateForm', 'CredentialList', 'LookUpInit', - 'SubmitJob', 'Wait' + 'SubmitJob', 'Wait', 'Stream' ]; function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, @@ -300,7 +302,7 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList, ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, ParseTypeChange, - JobStatusToolTip, FormatDate, Wait) + JobStatusToolTip, FormatDate, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -598,6 +600,8 @@ function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $route } }; + scope.showActivity = function() { Stream(); } + // Cancel scope.formReset = function() { generator.reset(); @@ -651,5 +655,5 @@ JobTemplatesEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$ 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'ParseTypeChange', - 'JobStatusToolTip', 'FormatDate', 'Wait' + 'JobStatusToolTip', 'FormatDate', 'Wait', 'Stream' ]; diff --git a/awx/ui/static/js/controllers/Organizations.js b/awx/ui/static/js/controllers/Organizations.js index 743311cc8f..f9df59c865 100644 --- a/awx/ui/static/js/controllers/Organizations.js +++ b/awx/ui/static/js/controllers/Organizations.js @@ -134,7 +134,7 @@ OrganizationsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$ function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, OrganizationForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait) + RelatedPaginateInit, Prompt, ClearScope, GetBasePath, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -211,6 +211,8 @@ function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $rout }); }; + scope.showActivity = function() { Stream(); } + // Reset the form scope.formReset = function() { $rootScope.flashMessage = null; @@ -264,4 +266,4 @@ function OrganizationsEdit ($scope, $rootScope, $compile, $location, $log, $rout OrganizationsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'Wait']; + 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'Wait', 'Stream']; diff --git a/awx/ui/static/js/controllers/Projects.js b/awx/ui/static/js/controllers/Projects.js index 3b610d4a3e..db71fa08e5 100644 --- a/awx/ui/static/js/controllers/Projects.js +++ b/awx/ui/static/js/controllers/Projects.js @@ -13,7 +13,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, ProjectUpdate, ProjectStatus, - FormatDate, Refresh, Wait) + FormatDate, Refresh, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -67,6 +67,8 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, scope.search(list.iterator); LoadBreadCrumbs(); + + scope.showActivity = function() { Stream(); } scope.addProject = function() { $location.path($location.path() + '/add'); @@ -228,7 +230,7 @@ function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, ProjectsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate', 'Refresh', 'Wait' ]; + 'GetBasePath', 'SelectionInit', 'ProjectUpdate', 'ProjectStatus', 'FormatDate', 'Refresh', 'Wait', 'Stream']; function ProjectsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, @@ -370,7 +372,7 @@ ProjectsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, ProjectsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, Prompt, ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, - Authorization, CredentialList, LookUpInit, GetChoices, Empty, DebugForm, Wait) + Authorization, CredentialList, LookUpInit, GetChoices, Empty, DebugForm, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -542,6 +544,8 @@ function ProjectsEdit ($scope, $rootScope, $compile, $location, $log, $routePara }); }; + scope.showActivity = function() { Stream(); } + // Related set: Add button scope.add = function(set) { $rootScope.flashMessage = null; @@ -600,5 +604,5 @@ ProjectsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log' 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'GetProjectPath', 'Authorization', 'CredentialList', 'LookUpInit', 'GetChoices', 'Empty', - 'DebugForm', 'Wait' + 'DebugForm', 'Wait', 'Stream' ]; diff --git a/awx/ui/static/js/controllers/Teams.js b/awx/ui/static/js/controllers/Teams.js index 9d5279f145..c310086879 100644 --- a/awx/ui/static/js/controllers/Teams.js +++ b/awx/ui/static/js/controllers/Teams.js @@ -12,7 +12,7 @@ function TeamsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, TeamList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, SelectionInit, Wait) + ClearScope, ProcessErrors, SetTeamListeners, GetBasePath, SelectionInit, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -44,6 +44,8 @@ function TeamsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Ale scope.search(list.iterator); LoadBreadCrumbs(); + + scope.showActivity = function() { Stream(); } scope.addTeam = function() { $location.path($location.path() + '/add'); @@ -93,7 +95,7 @@ function TeamsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Ale TeamsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'TeamList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'SetTeamListeners', 'GetBasePath', 'SelectionInit', 'Wait']; + 'SetTeamListeners', 'GetBasePath', 'SelectionInit', 'Wait', 'Stream' ]; function TeamsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, @@ -157,7 +159,7 @@ TeamsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, - GetBasePath, CheckAccess, OrganizationList, Wait) + GetBasePath, CheckAccess, OrganizationList, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -233,6 +235,8 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, { hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.team_id + '. GET status: ' + status }); }); + scope.showActivity = function() { Stream(); } + // Save changes to the parent scope.formSave = function() { generator.clearApiErrors(); @@ -344,6 +348,6 @@ function TeamsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, TeamsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', - 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait' + 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait', 'Stream' ]; diff --git a/awx/ui/static/js/controllers/Users.js b/awx/ui/static/js/controllers/Users.js index a0e73ce685..0df6654ab3 100644 --- a/awx/ui/static/js/controllers/Users.js +++ b/awx/ui/static/js/controllers/Users.js @@ -12,7 +12,7 @@ function UsersList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, UserList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait) + ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -35,6 +35,8 @@ function UsersList ($scope, $rootScope, $location, $log, $routeParams, Rest, Ale var url = (base == 'organizations') ? GetBasePath('organizations') + $routeParams.organization_id + '/users/' : GetBasePath('teams') + $routeParams.team_id + '/users/'; SelectionInit({ scope: scope, list: list, url: url, returnToCaller: 1 }); + + scope.showActivity = function() { Stream(); } scope.addUser = function() { $location.path($location.path() + '/add'); @@ -73,7 +75,7 @@ function UsersList ($scope, $rootScope, $location, $log, $routeParams, Rest, Ale UsersList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'UserList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', - 'GetBasePath', 'SelectionInit', 'Wait' ]; + 'GetBasePath', 'SelectionInit', 'Wait', 'Stream']; function UsersAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, @@ -186,7 +188,7 @@ UsersAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath, Prompt, CheckAccess, - ResetForm, Wait) + ResetForm, Wait, Stream) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -288,6 +290,8 @@ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, }); }; + scope.showActivity = function() { Stream(); } + // Cancel scope.formReset = function() { $rootScope.flashMessage = null; @@ -435,5 +439,5 @@ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, UsersEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'Prompt', 'CheckAccess', - 'ResetForm', 'Wait' ]; + 'ResetForm', 'Wait', 'Stream']; diff --git a/awx/ui/static/js/forms/Credentials.js b/awx/ui/static/js/forms/Credentials.js index 495a557e17..88dd7b4c24 100644 --- a/awx/ui/static/js/forms/Credentials.js +++ b/awx/ui/static/js/forms/Credentials.js @@ -14,7 +14,19 @@ angular.module('CredentialFormDefinition', []) name: 'credential', well: true, forceListeners: true, - + + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { name: { label: 'Name', diff --git a/awx/ui/static/js/forms/Inventories.js b/awx/ui/static/js/forms/Inventories.js index dacf6a9b14..4aad1016ed 100644 --- a/awx/ui/static/js/forms/Inventories.js +++ b/awx/ui/static/js/forms/Inventories.js @@ -15,6 +15,18 @@ angular.module('InventoryFormDefinition', []) name: 'inventory', parseTypeName: 'inventoryParseType', well: true, + + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, navigationLinks: { inventory: { diff --git a/awx/ui/static/js/forms/JobTemplates.js b/awx/ui/static/js/forms/JobTemplates.js index 788883c1ba..6966482b47 100644 --- a/awx/ui/static/js/forms/JobTemplates.js +++ b/awx/ui/static/js/forms/JobTemplates.js @@ -16,6 +16,18 @@ angular.module('JobTemplateFormDefinition', []) twoColumns: true, well: true, + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { name: { label: 'Name', diff --git a/awx/ui/static/js/forms/Organizations.js b/awx/ui/static/js/forms/Organizations.js index 1cc07304cc..cad661817c 100644 --- a/awx/ui/static/js/forms/Organizations.js +++ b/awx/ui/static/js/forms/Organizations.js @@ -15,6 +15,18 @@ angular.module('OrganizationFormDefinition', []) name: 'organization', //entity or model name in singular form well: true, //Wrap the form with TB well/ + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { name: { label: 'Name', diff --git a/awx/ui/static/js/forms/Projects.js b/awx/ui/static/js/forms/Projects.js index 778f7d30ad..c38477326c 100644 --- a/awx/ui/static/js/forms/Projects.js +++ b/awx/ui/static/js/forms/Projects.js @@ -17,6 +17,18 @@ angular.module('ProjectFormDefinition', []) well: true, // Wrap the form with TB well forceListeners: true, + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { name: { label: 'Name', diff --git a/awx/ui/static/js/forms/Teams.js b/awx/ui/static/js/forms/Teams.js index 17056307ab..e93d4f4a87 100644 --- a/awx/ui/static/js/forms/Teams.js +++ b/awx/ui/static/js/forms/Teams.js @@ -19,6 +19,18 @@ angular.module('TeamFormDefinition', []) collapseMode: 'edit', collapseOpen: true, + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { name: { label: 'Name', diff --git a/awx/ui/static/js/forms/Users.js b/awx/ui/static/js/forms/Users.js index ec04dd9326..7d497de179 100644 --- a/awx/ui/static/js/forms/Users.js +++ b/awx/ui/static/js/forms/Users.js @@ -13,13 +13,21 @@ angular.module('UserFormDefinition', []) addTitle: 'Create User', //Legend in add mode editTitle: '{{ username }}', //Legend in edit mode name: 'user', //Form name attribute - well: true, //Wrap the form with TB well - /*collapse: true, - collapseTitle: 'User Settings', - collapseMode: 'edit', - collapseOpen: true,*/ + well: true, //Wrap the form with TB well forceListeners: true, + actions: { + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'edit', + iconSize: 'large' + } + }, + fields: { first_name: { label: 'First Name', diff --git a/awx/ui/static/js/lists/Credentials.js b/awx/ui/static/js/lists/Credentials.js index 004b2be5b5..1f525c15c4 100644 --- a/awx/ui/static/js/lists/Credentials.js +++ b/awx/ui/static/js/lists/Credentials.js @@ -61,6 +61,15 @@ angular.module('CredentialsListDefinition', []) ngClick: 'addCredential()', "class": 'btn-success btn-xs', awToolTip: 'Create a new credential' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/lists/Inventories.js b/awx/ui/static/js/lists/Inventories.js index f81b785a16..1957445812 100644 --- a/awx/ui/static/js/lists/Inventories.js +++ b/awx/ui/static/js/lists/Inventories.js @@ -88,6 +88,15 @@ angular.module('InventoriesListDefinition', []) ngClick: 'addInventory()', "class": 'btn-xs btn-success', awToolTip: 'Create a new inventory' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/lists/JobTemplates.js b/awx/ui/static/js/lists/JobTemplates.js index 05e1ba5e40..18da0b8f76 100644 --- a/awx/ui/static/js/lists/JobTemplates.js +++ b/awx/ui/static/js/lists/JobTemplates.js @@ -37,6 +37,15 @@ angular.module('JobTemplatesListDefinition', []) "class": 'btn-success btn-xs', basePaths: ['job_templates'], awToolTip: 'Create a new template' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js index 64d37e6c91..4add716f30 100644 --- a/awx/ui/static/js/lists/Projects.js +++ b/awx/ui/static/js/lists/Projects.js @@ -80,6 +80,15 @@ angular.module('ProjectsListDefinition', []) awToolTip: "Refresh the page", ngClick: "refresh()", iconSize: 'large' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/lists/Teams.js b/awx/ui/static/js/lists/Teams.js index 02b1b332ab..0b08d352bf 100644 --- a/awx/ui/static/js/lists/Teams.js +++ b/awx/ui/static/js/lists/Teams.js @@ -42,6 +42,15 @@ angular.module('TeamsListDefinition', []) ngClick: 'addTeam()', "class": 'btn-xs btn-success', awToolTip: 'Create a new team' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/lists/Users.js b/awx/ui/static/js/lists/Users.js index 1a37785318..7a398c3245 100644 --- a/awx/ui/static/js/lists/Users.js +++ b/awx/ui/static/js/lists/Users.js @@ -42,6 +42,15 @@ angular.module('UserListDefinition', []) basePaths: ['organizations','users'], // base path must be in list, or action not available "class": 'btn-success btn-xs', awToolTip: 'Create a new user' + }, + stream: { + 'class': "btn-primary btn-xs activity-btn", + ngClick: "showActivity()", + awToolTip: "View Activity Stream", + dataPlacement: "top", + icon: "icon-comments-alt", + mode: 'all', + iconSize: 'large' } }, diff --git a/awx/ui/static/js/widgets/Stream.js b/awx/ui/static/js/widgets/Stream.js index 433a5a0879..bfc15e8858 100644 --- a/awx/ui/static/js/widgets/Stream.js +++ b/awx/ui/static/js/widgets/Stream.js @@ -35,7 +35,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti } }]) - .factory('HideStream', [ function() { + .factory('HideStream', [ 'LoadBreadCrumbs', function(LoadBreadCrumbs) { return function() { // Remove the stream widget @@ -52,6 +52,52 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti stream.unbind(); $('#tab-content-container').css({ 'min-height': 0 }); //let the parent height go back to normal }, 500); + + LoadBreadCrumbs(); + } + }]) + + .factory('StreamBreadCrumbs', ['$rootScope', '$location', function($rootScope, $location) { + return function() { + // Load the breadcrumbs array. We have to do things a bit different than our standing Utilities.LoadBreadcrumbs. + // Rather than botch that all up, we'll do our own thing here. + $rootScope.breadcrumbs = []; + var paths = $location.path().split('/'); + paths.splice(0,1); + var path, title; + for (var i=0; i < paths.length; i++) { + if (/^\d+/.test(paths[i])) { + path=''; + title=''; + for (j=0; j <= i; j++) { + path += '/' + paths[j]; + } + for (j=0; j < $rootScope.crumbCache.length; j++) { + if ($rootScope.crumbCache[j].path == path) { + title = $rootScope.crumbCache[j].title; + break; + } + } + if (!title) { + title = paths[i - 1].substr(0,paths[i - 1].length - 1); + title = (title == 'inventorie') ? 'inventory' : title; + } + } + else { + path=''; + title=''; + if (i > 0) { + for (j=0; j <= i; j++) { + path += '/' + paths[j]; + } + } + else { + path = '/' + paths[i]; + } + title = paths[i]; + } + $rootScope.breadcrumbs.push({ path: path, title: title, ngClick: "closeStream('" + path + "')" }); + } } }]) @@ -184,9 +230,9 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti .factory('Stream', ['$rootScope', '$location', 'Rest', 'GetBasePath', 'ProcessErrors', 'Wait', 'StreamList', 'SearchInit', 'PaginateInit', 'GenerateList', 'FormatDate', 'ShowStream', 'HideStream', 'BuildDescription', 'FixUrl', 'BuildUrl', - 'ShowDetail', 'LoadBreadCrumbs', + 'ShowDetail', 'StreamBreadCrumbs', function($rootScope, $location, Rest, GetBasePath, ProcessErrors, Wait, StreamList, SearchInit, PaginateInit, GenerateList, - FormatDate, ShowStream, HideStream, BuildDescription, FixUrl, BuildUrl, ShowDetail, LoadBreadCrumbs) { + FormatDate, ShowStream, HideStream, BuildDescription, FixUrl, BuildUrl, ShowDetail, StreamBreadCrumbs) { return function(params) { var list = StreamList; @@ -195,22 +241,23 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti var base = $location.path().replace(/^\//,'').split('/')[0]; if (base !== 'home') { + // Restrict what we're looking at based on the path var type = (base == 'inventories') ? 'inventory' : base.replace(/s$/,''); - defaultUrl += '?or__object1=' + type + '&or__object2=' + type; + var paths = $location.path().split('/'); + paths.splice(0,1); + if (paths.length > 1 && /^\d+/.test(paths[1])) { + defaultUrl += '?object1=' + type + '&object1_id=' + paths[i]; + } + else { + defaultUrl += '?or__object1=' + type + '&or__object2=' + type; + } } - - // Push the current page onto browser histor. If user clicks back button, restore current page without - // stream widget - // window.history.pushState({}, "AnsibleWorks AWX", $location.path()); // Add a container for the stream widget $('#tab-content-container').append('
'); - + + StreamBreadCrumbs(); ShowStream(); - if ($rootScope.breadcrumbs.length == 0) { - var title = base.substr(0,1).toUpperCase() + base.substr(1); - $rootScope.breadcrumbs.push({ path: $location.path(), title: title}); - } // Generate the list var scope = view.inject(list, { @@ -218,11 +265,15 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti id: 'stream-content', breadCrumbs: true, searchSize: 'col-lg-3', - secondWidget: true + secondWidget: true, + activityStream: true }); - scope.closeStream = function() { + scope.closeStream = function(inUrl) { HideStream(); + if (inUrl) { + $location.path(inUrl); + } } scope.refreshStream = function() { @@ -288,15 +339,6 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti SearchInit({ scope: scope, set: list.name, list: list, url: defaultUrl }); PaginateInit({ scope: scope, list: list, url: defaultUrl }); scope.search(list.iterator); - - /* - scope.$watch(list.iterator + 'SearchField', function(newVal, oldVal) { - console.log('newVal: ' + newVal); - html += "" - html += "\n"; - });*/ } }]); diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 2746804dd4..6533381c7f 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -22,7 +22,6 @@ @info-color: #3a87ad; @tip-background: #0088CC; -/*rgb(58, 135, 173);*/ @tip-color: #fff; @@ -1378,6 +1377,7 @@ tr td button i { #stream-container { display: none; + border-radius: 8px; } #stream-content { diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js index 604a43bb4d..0a0c4f9d2c 100644 --- a/awx/ui/static/lib/ansible/form-generator.js +++ b/awx/ui/static/lib/ansible/form-generator.js @@ -932,6 +932,33 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities']) return html; }, + getActions: function(options) { + // Use to add things like Activity Stream to a detail page + html = "
\n"; + for (action in this.form.actions) { + if (this.form.actions[action].mode == 'all' || this.form.actions[action].mode == options.mode) { + html += this.button(this.form.actions[action], action); + } + } + html += "
\n"; + return html; + }, + + /* + activityCrumbs: function() { + // Breadcrumbs for activity stream widget + // Make the links clickable using ng-click function so we can first remove the stream widget. + html = ''; + html += "
\n"; + html += "\n
\n"; + return html; + }, + */ + breadCrumbs: function(options, navigation) { var html = ''; @@ -1010,7 +1037,7 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities']) html += this.breadCrumbs(options); } } - + if ((!this.modal && this.form.statusFields)) { // Add status fields section (used in Jobs form) html += "
\n"; @@ -1058,6 +1085,10 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies', 'Utilities']) html += "
\n"; } + if (!this.modal && this.form.actions) { + html += this.getActions(options); + } + // Add a title and optionally a close button (used on Inventory->Groups) if ( (!options.modal) && this.form.showTitle ) { html += "
"; diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index 9fd9e667d7..27e6dae01c 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -112,7 +112,18 @@ angular.module('ListGenerator', ['GeneratorHelpers']) var html = ''; var list = this.list; - if (options.mode != 'lookup' && (options.breadCrumbs == undefined || options.breadCrumbs == true)) { + if (options.activityStream) { + // Breadcrumbs for activity stream widget + // Make the links clickable using ng-click function so we can first remove the stream widget + // before navigation + html += "
\n"; + html += "\n
\n"; + } + else if (options.mode != 'lookup' && (options.breadCrumbs == undefined || options.breadCrumbs == true)) { //Breadcrumbs html += "
\n"; html += "
    \n";