From ce09ab446d6c20bea8a5f4ecf520f2769c0afe08 Mon Sep 17 00:00:00 2001 From: Jared Tabor Date: Fri, 11 May 2018 11:29:33 -0700 Subject: [PATCH] Moves scheduler to related tab for projects Signed-off-by: Jared Tabor --- awx/ui/client/features/jobs/index.js | 2 + .../organizations-job-templates.controller.js | 20 --- .../organizations-projects.controller.js | 2 +- .../projects/list/projects-list.controller.js | 2 +- awx/ui/client/src/projects/main.js | 9 + awx/ui/client/src/projects/projects.form.js | 5 + awx/ui/client/src/scheduler/main.js | 158 +----------------- .../src/scheduler/schedulerAdd.controller.js | 2 +- .../src/scheduler/schedulerEdit.controller.js | 2 +- .../src/scheduler/schedulerList.controller.js | 4 +- .../client/src/scheduler/schedules.route.js | 154 ++++++++++++++++- .../list-generator/list-generator.factory.js | 4 + .../src/shared/stateDefinitions.factory.js | 6 +- 13 files changed, 185 insertions(+), 185 deletions(-) diff --git a/awx/ui/client/features/jobs/index.js b/awx/ui/client/features/jobs/index.js index c26f2b9d8f..5c244cd88a 100644 --- a/awx/ui/client/features/jobs/index.js +++ b/awx/ui/client/features/jobs/index.js @@ -1,5 +1,6 @@ import JobsStrings from './jobs.strings'; import jobsRoute from './routes/jobs.route'; +import { jobsSchedulesRoute } from '../../src/scheduler/schedules.route'; const MODULE_NAME = 'at.features.jobs'; @@ -8,6 +9,7 @@ angular .service('JobsStrings', JobsStrings) .run(['$stateExtender', ($stateExtender) => { $stateExtender.addState(jobsRoute); + $stateExtender.addState(jobsSchedulesRoute); }]); export default MODULE_NAME; diff --git a/awx/ui/client/src/organizations/linkout/controllers/organizations-job-templates.controller.js b/awx/ui/client/src/organizations/linkout/controllers/organizations-job-templates.controller.js index 8c58157ab3..67003502ce 100644 --- a/awx/ui/client/src/organizations/linkout/controllers/organizations-job-templates.controller.js +++ b/awx/ui/client/src/organizations/linkout/controllers/organizations-job-templates.controller.js @@ -76,25 +76,5 @@ export default ['$scope', '$rootScope', $scope.scheduleJob = function(id) { $state.go('templates.editJobTemplate.schedules', { id: id }); }; - - // $scope.copyTemplate = function(id) { - // Wait('start'); - // TemplateCopyService.get(id) - // .then((data) => { - // TemplateCopyService.set(data.results) - // .then((results) => { - // Wait('stop'); - // if(results.type && results.type === 'job_template') { - // $state.go('templates.editJobTemplate', {job_template_id: results.id}, {reload: true}); - // } - // }); - // }) - // .catch(({data, status}) => { - // ProcessErrors($rootScope, data, status, null, {hdr: 'Error!', - // msg: 'Call failed. Return status: '+ status}); - // }); - // - // }; - } ]; diff --git a/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js b/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js index 51e753c8a4..48a59a967d 100644 --- a/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js +++ b/awx/ui/client/src/organizations/linkout/controllers/organizations-projects.controller.js @@ -301,7 +301,7 @@ export default ['$scope', '$rootScope', '$log', '$stateParams', 'Rest', 'Alert', $scope.editSchedules = function(id) { var project = Find({ list: $scope.projects, key: 'id', val: id }); if (!(project.scm_type === "Manual" || Empty(project.scm_type)) && !(project.status === 'updating' || project.status === 'running' || project.status === 'pending')) { - $state.go('projectSchedules', { id: id }); + $state.go('projects.edit.schedules', { project_id: id }); } }; 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 bea12bdf0d..c4aa5db6c8 100644 --- a/awx/ui/client/src/projects/list/projects-list.controller.js +++ b/awx/ui/client/src/projects/list/projects-list.controller.js @@ -332,7 +332,7 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert', $scope.editSchedules = function(id) { var project = Find({ list: $scope.projects, key: 'id', val: id }); if (!(project.scm_type === "Manual" || Empty(project.scm_type)) && !(project.status === 'updating' || project.status === 'running' || project.status === 'pending')) { - $state.go('projectSchedules', { id: id }); + $state.go('projects.edit.schedules', { project_id: id }); } }; } diff --git a/awx/ui/client/src/projects/main.js b/awx/ui/client/src/projects/main.js index 8f186e5458..d8aaf9df36 100644 --- a/awx/ui/client/src/projects/main.js +++ b/awx/ui/client/src/projects/main.js @@ -13,6 +13,11 @@ import { N_ } from '../i18n'; import GetProjectPath from './factories/get-project-path.factory'; import GetProjectIcon from './factories/get-project-icon.factory'; import GetProjectToolTip from './factories/get-project-tool-tip.factory'; +import { + projectsSchedulesListRoute, + projectsSchedulesAddRoute, + projectsSchedulesEditRoute +} from '../scheduler/schedules.route'; import ProjectsTemplatesRoute from '~features/templates/routes/projectsTemplatesList.route'; import ProjectsStrings from './projects.strings'; @@ -66,6 +71,7 @@ angular.module('Projects', []) let projectTree = stateDefinitions.generateTree({ parent: 'projects', // top-most node in the generated tree (will replace this state definition) modes: ['add', 'edit'], + generateSchedulerView: true, list: 'ProjectList', form: 'ProjectsForm', controllers: { @@ -99,6 +105,9 @@ angular.module('Projects', []) return result.concat(definition.states); }, [ stateExtender.buildDefinition(ProjectsTemplatesRoute), + stateExtender.buildDefinition(projectsSchedulesListRoute), + stateExtender.buildDefinition(projectsSchedulesAddRoute), + stateExtender.buildDefinition(projectsSchedulesEditRoute) ]) }; }); diff --git a/awx/ui/client/src/projects/projects.form.js b/awx/ui/client/src/projects/projects.form.js index 1862f28722..14afb7e455 100644 --- a/awx/ui/client/src/projects/projects.form.js +++ b/awx/ui/client/src/projects/projects.form.js @@ -285,6 +285,11 @@ export default ['i18n', 'NotificationsList', 'TemplateList', templates: { include: "TemplateList", }, + schedules: { + title: i18n._('Schedules'), + skipGenerator: true, + ngClick: "$state.go('projects.edit.schedules')" + } } }; diff --git a/awx/ui/client/src/scheduler/main.js b/awx/ui/client/src/scheduler/main.js index 76f3b91ad8..0736c2f007 100644 --- a/awx/ui/client/src/scheduler/main.js +++ b/awx/ui/client/src/scheduler/main.js @@ -16,7 +16,6 @@ import SchedulePost from './factories/schedule-post.factory'; import ToggleSchedule from './factories/toggle-schedule.factory'; import SchedulesList from './schedules.list'; import ScheduledJobsList from './scheduled-jobs.list'; -import editScheduleResolve from './editSchedule.resolve'; export default angular.module('scheduler', []) @@ -29,159 +28,4 @@ export default .factory('ToggleSchedule', ToggleSchedule) .factory('SchedulesList', SchedulesList) .factory('ScheduledJobsList', ScheduledJobsList) - .directive('schedulerDatePicker', schedulerDatePicker) - .run(['$stateExtender', function($stateExtender) { - // Inventory sync schedule states registered in: awx/ui/client/src/inventories/manage/groups/main.js - // Scheduled jobs states registered in awx/uiclient/src/job-detail/main.js - - - // projects - $stateExtender.addState({ - searchPrefix: 'schedule', - name: 'projectSchedules', - route: '/projects/:id/schedules', - data: { - activityStream: true, - activityStreamTarget: 'project', - activityStreamId: 'id' - }, - ncyBreadcrumb: { - parent: 'projects.edit({project_id: parentObject.id})', - label: N_('SCHEDULES') - }, - resolve: { - Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', - function(list, qs, $stateParams, GetBasePath) { - let path = `${GetBasePath('projects')}${$stateParams.id}/schedules`; - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - ParentObject: ['$stateParams', 'Rest', 'GetBasePath', function($stateParams, Rest, GetBasePath){ - let path = `${GetBasePath('projects')}${$stateParams.id}`; - Rest.setUrl(path); - return Rest.get(path).then(response => response.data); - }], - UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', - function(Rest, GetBasePath, $stateParams, $q) { - Rest.setUrl(GetBasePath('unified_jobs')); - var val = $q.defer(); - Rest.options() - .then(function(data) { - val.resolve(data.data); - }, function(data) { - val.reject(data); - }); - return val.promise; - }], - ScheduleList: ['SchedulesList', 'GetBasePath', '$stateParams', - (SchedulesList, GetBasePath, $stateParams) => { - let list = _.cloneDeep(SchedulesList); - list.basePath = GetBasePath('projects') + $stateParams.id + '/schedules/'; - return list; - } - ] - }, - views: { - '@': { - templateProvider: function(ScheduleList, generateList, ParentObject, $filter){ - // include name of parent resource in listTitle - ScheduleList.listTitle = `${$filter('sanitize')(ParentObject.name)}
` + N_('SCHEDULES'); - let html = generateList.build({ - list: ScheduleList, - mode: 'edit' - }); - html = generateList.wrapPanel(html); - return generateList.insertFormView() + html; - }, - controller: 'schedulerListController' - } - } - }); - - $stateExtender.addState({ - name: 'projectSchedules.add', - route: '/add', - ncyBreadcrumb: { - label: N_('CREATE SCHEDULE') - }, - views: { - 'form': { - controller: 'schedulerAddController', - templateUrl: templateUrl("scheduler/schedulerForm"), - } - } - }); - $stateExtender.addState({ - name: 'projectSchedules.edit', - route: '/:schedule_id', - ncyBreadcrumb: { - label: '{{schedule_obj.name}}' - }, - views: { - 'form': { - controller: 'schedulerEditController', - templateUrl: templateUrl("scheduler/schedulerForm"), - } - }, - resolve: editScheduleResolve() - }); - // upcoming scheduled jobs - $stateExtender.addState({ - searchPrefix: 'schedule', - name: 'jobs.schedules', - route: '/schedules', - params: { - schedule_search: { - value: { - next_run__isnull: 'false', - order_by: 'unified_job_template__polymorphic_ctype__model' - }, - dynamic: true - } - }, - data: { - activityStream: false, - }, - ncyBreadcrumb: { - parent: 'jobs', - label: N_('SCHEDULED') - }, - resolve: { - ScheduleList: ['ScheduledJobsList', function(list){ - return list; - }], - Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', - function(list, qs, $stateParams, GetBasePath) { - let path = GetBasePath('schedules'); - return qs.search(path, $stateParams[`${list.iterator}_search`]); - } - ], - ParentObject: ['GetBasePath', (GetBasePath) =>{return {endpoint:GetBasePath('schedules')}; }], - UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', - function(Rest, GetBasePath, $stateParams, $q) { - Rest.setUrl(GetBasePath('unified_jobs')); - var val = $q.defer(); - Rest.options() - .then(function(data) { - val.resolve(data.data); - }, function(data) { - val.reject(data); - }); - return val.promise; - }] - }, - views: { - 'schedulesList@jobs': { - templateProvider: function(ScheduleList, generateList){ - let html = generateList.build({ - list: ScheduleList, - mode: 'edit', - title: false - }); - return html; - }, - controller: 'schedulerListController' - } - } - }); - }]); + .directive('schedulerDatePicker', schedulerDatePicker); diff --git a/awx/ui/client/src/scheduler/schedulerAdd.controller.js b/awx/ui/client/src/scheduler/schedulerAdd.controller.js index e8ac324962..2b7256529e 100644 --- a/awx/ui/client/src/scheduler/schedulerAdd.controller.js +++ b/awx/ui/client/src/scheduler/schedulerAdd.controller.js @@ -277,7 +277,7 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait', } if ($state.current.name === 'templates.editWorkflowJobTemplate.schedules.add' || - $state.current.name === 'projectSchedules.add' || + $state.current.name === 'projects.edit.schedules.add' || $state.current.name === 'inventories.edit.inventory_sources.edit.schedules.add' ){ $scope.noVars = true; diff --git a/awx/ui/client/src/scheduler/schedulerEdit.controller.js b/awx/ui/client/src/scheduler/schedulerEdit.controller.js index f7441e0f7f..14fcf921f7 100644 --- a/awx/ui/client/src/scheduler/schedulerEdit.controller.js +++ b/awx/ui/client/src/scheduler/schedulerEdit.controller.js @@ -451,7 +451,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment, // extra_data field is not manifested in the UI when scheduling a Management Job if ($state.current.name !== 'managementJobsList.schedule.add' && $state.current.name !== 'managementJobsList.schedule.edit'){ - if ($state.current.name === 'projectSchedules.edit' || + if ($state.current.name === 'projects.edit.schedules.edit' || $state.current.name === 'inventories.edit.inventory_sources.edit.schedules.edit' || $state.current.name === 'templates.editWorkflowJobTemplate.schedules.add' ){ diff --git a/awx/ui/client/src/scheduler/schedulerList.controller.js b/awx/ui/client/src/scheduler/schedulerList.controller.js index ab4198f3aa..f7f21df662 100644 --- a/awx/ui/client/src/scheduler/schedulerList.controller.js +++ b/awx/ui/client/src/scheduler/schedulerList.controller.js @@ -199,9 +199,9 @@ export default [ case 'project_update': deferred.resolve({ - name: 'projectSchedules.edit', + name: 'projects.edit.schedules.edit', params: { - id: schedule.unified_job_template, + project_id: schedule.unified_job_template, schedule_id: schedule.id } }); diff --git a/awx/ui/client/src/scheduler/schedules.route.js b/awx/ui/client/src/scheduler/schedules.route.js index 2f54060d9f..37658ff9a9 100644 --- a/awx/ui/client/src/scheduler/schedules.route.js +++ b/awx/ui/client/src/scheduler/schedules.route.js @@ -185,11 +185,163 @@ const workflowSchedulesEditRoute = { resolve: editScheduleResolve() }; +const projectsSchedulesListRoute = { + searchPrefix: 'schedule', + name: 'projects.edit.schedules', + route: '/schedules', + data: { + activityStream: true, + activityStreamTarget: 'project', + activityStreamId: 'id' + }, + ncyBreadcrumb: { + parent: 'projects.edit({project_id: parentObject.id})', + label: N_('SCHEDULES') + }, + resolve: { + Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = `${GetBasePath('projects')}${$stateParams.project_id}/schedules`; + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + ParentObject: ['$stateParams', 'Rest', 'GetBasePath', function($stateParams, Rest, GetBasePath){ + let path = `${GetBasePath('projects')}${$stateParams.project_id}`; + Rest.setUrl(path); + return Rest.get(path).then(response => response.data); + }], + UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', + function(Rest, GetBasePath, $stateParams, $q) { + Rest.setUrl(GetBasePath('unified_jobs')); + var val = $q.defer(); + Rest.options() + .then(function(data) { + val.resolve(data.data); + }, function(data) { + val.reject(data); + }); + return val.promise; + }], + ScheduleList: ['SchedulesList', 'GetBasePath', '$stateParams', + (SchedulesList, GetBasePath, $stateParams) => { + let list = _.cloneDeep(SchedulesList); + list.basePath = GetBasePath('projects') + $stateParams.project_id + '/schedules/'; + return list; + } + ] + }, + views: { + related: { + templateProvider: function(ScheduleList, generateList, ParentObject, $filter){ + ScheduleList.title = false; + let html = generateList.build({ + list: ScheduleList, + mode: 'edit' + }); + return html; + }, + controller: 'schedulerListController' + } + } +}; + +const projectsSchedulesAddRoute = { + name: 'projects.edit.schedules.add', + route: '/add', + ncyBreadcrumb: { + label: N_('CREATE SCHEDULE') + }, + views: { + 'scheduler@projects': { + controller: 'schedulerAddController', + templateUrl: templateUrl("scheduler/schedulerForm"), + } + } +}; + +const projectsSchedulesEditRoute = { + name: 'projects.edit.schedules.edit', + route: '/:schedule_id', + ncyBreadcrumb: { + label: '{{schedule_obj.name}}' + }, + views: { + 'scheduler@projects': { + controller: 'schedulerEditController', + templateUrl: templateUrl("scheduler/schedulerForm"), + } + }, + resolve: editScheduleResolve() +}; + +const jobsSchedulesRoute = { + searchPrefix: 'schedule', + name: 'jobs.schedules', + route: '/schedules', + params: { + schedule_search: { + value: { + next_run__isnull: 'false', + order_by: 'unified_job_template__polymorphic_ctype__model' + }, + dynamic: true + } + }, + data: { + activityStream: false, + }, + ncyBreadcrumb: { + parent: 'jobs', + label: N_('SCHEDULED') + }, + resolve: { + ScheduleList: ['ScheduledJobsList', function(list){ + return list; + }], + Dataset: ['ScheduleList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath('schedules'); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + ParentObject: ['GetBasePath', (GetBasePath) =>{return {endpoint:GetBasePath('schedules')}; }], + UnifiedJobsOptions: ['Rest', 'GetBasePath', '$stateParams', '$q', + function(Rest, GetBasePath, $stateParams, $q) { + Rest.setUrl(GetBasePath('unified_jobs')); + var val = $q.defer(); + Rest.options() + .then(function(data) { + val.resolve(data.data); + }, function(data) { + val.reject(data); + }); + return val.promise; + }] + }, + views: { + 'schedulesList@jobs': { + templateProvider: function(ScheduleList, generateList){ + let html = generateList.build({ + list: ScheduleList, + mode: 'edit', + title: false + }); + return html; + }, + controller: 'schedulerListController' + } + } +}; + export { jobTemplatesSchedulesListRoute, jobTemplatesSchedulesAddRoute, jobTemplatesSchedulesEditRoute, workflowSchedulesRoute, workflowSchedulesAddRoute, - workflowSchedulesEditRoute + workflowSchedulesEditRoute, + projectsSchedulesListRoute, + projectsSchedulesAddRoute, + projectsSchedulesEditRoute, + jobsSchedulesRoute }; 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 4e1189095e..a1f7088769 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 @@ -594,6 +594,10 @@ export default ['$compile', 'Attr', 'Icon', insertFormView: function(){ return `
`; + }, + + insertSchedulerView: function(){ + return `
`; } }; } diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 63182fa98f..99dc4f6f99 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -86,7 +86,11 @@ function($injector, $stateExtender, $log, i18n) { }); html = generateList.wrapPanel(html); // generateList.formView() inserts a ui-view="form" inside the list view's hierarchy - return generateList.insertFormView() + html; + html = generateList.insertFormView() + html; + if(params.generateSchedulerView){ + html = generateList.insertSchedulerView() + html; + } + return html; }; } }