diff --git a/api/http/handler/edgejobs/edgejob_update.go b/api/http/handler/edgejobs/edgejob_update.go index ef02a3531..3dba17d83 100644 --- a/api/http/handler/edgejobs/edgejob_update.go +++ b/api/http/handler/edgejobs/edgejob_update.go @@ -48,7 +48,7 @@ func (payload *edgeJobUpdatePayload) Validate(r *http.Request) error { // @failure 500 // @failure 400 // @failure 503 "Edge compute features are disabled" -// @router /edge_jobs/{id} [post] +// @router /edge_jobs/{id} [put] func (handler *Handler) edgeJobUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { diff --git a/app/edge/__module.js b/app/edge/__module.js index d507ed391..00919c7da 100644 --- a/app/edge/__module.js +++ b/app/edge/__module.js @@ -106,15 +106,12 @@ angular const edgeJob = { name: 'edge.jobs.job', - url: '/:id', + url: '/:id?tab', views: { 'content@': { - component: 'edgeJobView', + component: 'edgeJobsItemView', }, }, - params: { - tab: 0, - }, }; const edgeJobCreation = { diff --git a/app/edge/components/edge-job-form/edgeJobForm.html b/app/edge/components/edge-job-form/edgeJobForm.html deleted file mode 100644 index 93fd17f9c..000000000 --- a/app/edge/components/edge-job-form/edgeJobForm.html +++ /dev/null @@ -1,206 +0,0 @@ -
diff --git a/app/edge/components/edge-job-form/edgeJobFormController.js b/app/edge/components/edge-job-form/edgeJobFormController.js deleted file mode 100644 index 814eb19bb..000000000 --- a/app/edge/components/edge-job-form/edgeJobFormController.js +++ /dev/null @@ -1,142 +0,0 @@ -import moment from 'moment'; -import { editor, upload } from '@@/BoxSelector/common-options/build-methods'; - -import { cronMethodOptions } from '@/react/edge/edge-jobs/CreateView/cron-method-options'; - -export class EdgeJobFormController { - /* @ngInject */ - constructor($async, $scope) { - this.$scope = $scope; - this.$async = $async; - - this.cronMethods = cronMethodOptions.map((o) => ({ ...o, id: o.id + '-old' })); - this.buildMethods = [editor, upload].map((o) => ({ ...o, id: o.id + '-old' })); - - this.state = { - formValidationError: '', - }; - - this.scheduleValues = [ - { - displayed: 'Every hour', - cron: '0 * * * *', - }, - { - displayed: 'Every 2 hours', - cron: '0 */2 * * *', - }, - { - displayed: 'Every day', - cron: '0 0 * * *', - }, - ]; - - this.formValues = { - datetime: moment(), - scheduleValue: this.scheduleValues[0], - cronMethod: 'basic', - method: 'editor', - }; - - // see https://regexr.com/573i2 - this.cronRegex = - /(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ){4,6}((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*))/; - - this.action = this.action.bind(this); - this.editorUpdate = this.editorUpdate.bind(this); - this.onChangeEnvironments = this.onChangeEnvironments.bind(this); - this.onChangeGroups = this.onChangeGroups.bind(this); - this.onChange = this.onChange.bind(this); - this.onCronMethodChange = this.onCronMethodChange.bind(this); - this.onBuildMethodChange = this.onBuildMethodChange.bind(this); - } - - onChange(values) { - this.$scope.$evalAsync(() => { - this.formValues = { - ...this.formValues, - ...values, - }; - }); - } - - onBuildMethodChange(value) { - this.onChange({ method: value }); - } - - onCronMethodChange(value) { - this.onChange({ cronMethod: value }); - } - - onChangeModel(model) { - const defaultTime = moment().add('hours', 1); - const scheduled = this.scheduleValues.find((v) => v.cron === model.CronExpression); - - this.formValues = { - datetime: model.CronExpression ? cronToDatetime(model.CronExpression, defaultTime) : defaultTime, - scheduleValue: scheduled || this.scheduleValues[0], - cronMethod: model.Recurring && !scheduled ? 'advanced' : 'basic', - method: this.formValues.method, - }; - } - - onChangeGroups(groups) { - return this.$scope.$evalAsync(() => { - this.model.EdgeGroups = groups ? groups : []; - }); - } - - action() { - this.state.formValidationError = ''; - - if (this.formValues.method === 'editor' && this.model.FileContent === '') { - this.state.formValidationError = 'Script file content must not be empty'; - return; - } - - if (this.formValues.cronMethod === 'basic') { - if (!this.model.Recurring && (this.formValues.datetime === undefined || !this.formValues.datetime.isValid())) { - this.state.formValidationError = 'Schedule date must not be empty'; - return; - } else if (!this.model.Recurring) { - this.model.CronExpression = datetimeToCron(this.formValues.datetime); - } else { - this.model.CronExpression = this.formValues.scheduleValue.cron; - } - } else { - this.model.Recurring = true; - } - - this.formAction(this.formValues.method); - } - - editorUpdate(value) { - this.model.FileContent = value; - this.isEditorDirty = true; - } - - onChangeEnvironments(value) { - return this.$scope.$evalAsync(() => { - this.model.Endpoints = value; - }); - } - - $onInit() { - this.onChangeModel(this.model); - } -} - -function cronToDatetime(cron, defaultTime = moment()) { - var strings = cron.split(' '); - if (strings.length > 4) { - strings = strings.slice(0, 4); - } else { - return defaultTime; - } - return moment(cron, 'm H D M'); -} - -function datetimeToCron(datetime) { - var date = moment(datetime); - return [date.minutes(), date.hours(), date.date(), date.month() + 1, '*'].join(' '); -} diff --git a/app/edge/components/edge-job-form/index.js b/app/edge/components/edge-job-form/index.js deleted file mode 100644 index 96dfea138..000000000 --- a/app/edge/components/edge-job-form/index.js +++ /dev/null @@ -1,20 +0,0 @@ -import angular from 'angular'; - -import { EdgeJobFormController } from './edgeJobFormController'; - -angular.module('portainer.edge').component('edgeJobForm', { - templateUrl: './edgeJobForm.html', - controller: EdgeJobFormController, - bindings: { - model: '=', - groups: '<', - tags: '<', - edgeGroups: '<', - addLabelAction: '<', - removeLabelAction: '<', - formAction: '<', - formActionLabel: '@', - actionInProgress: '<', - isEditorDirty: '=', - }, -}); diff --git a/app/edge/react/components/edge-jobs.ts b/app/edge/react/components/edge-jobs.ts deleted file mode 100644 index 0b88bc3d7..000000000 --- a/app/edge/react/components/edge-jobs.ts +++ /dev/null @@ -1,18 +0,0 @@ -import angular from 'angular'; - -import { r2a } from '@/react-tools/react2angular'; -import { withUIRouter } from '@/react-tools/withUIRouter'; -import { ResultsDatatable } from '@/react/edge/edge-jobs/ItemView/ResultsDatatable/ResultsDatatable'; - -export const edgeJobsModule = angular - .module('portainer.edge.react.components.edge-jobs', []) - .component( - 'edgeJobResultsDatatable', - r2a(withUIRouter(ResultsDatatable), [ - 'dataset', - 'onClearLogs', - 'onCollectLogs', - 'onDownloadLogs', - 'onRefresh', - ]) - ).name; diff --git a/app/edge/react/components/index.ts b/app/edge/react/components/index.ts index 916005936..b4913e51c 100644 --- a/app/edge/react/components/index.ts +++ b/app/edge/react/components/index.ts @@ -9,10 +9,8 @@ import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInInt import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm'; import { EdgeGroupsSelector } from '@/react/edge/edge-stacks/components/EdgeGroupsSelector'; -import { edgeJobsModule } from './edge-jobs'; - const ngModule = angular - .module('portainer.edge.react.components', [edgeJobsModule]) + .module('portainer.edge.react.components', []) .component( 'edgeGroupsSelector', diff --git a/app/edge/react/views/jobs.ts b/app/edge/react/views/jobs.ts index 7718cffba..1b3aa26ee 100644 --- a/app/edge/react/views/jobs.ts +++ b/app/edge/react/views/jobs.ts @@ -5,10 +5,15 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser'; import { withUIRouter } from '@/react-tools/withUIRouter'; import { ListView } from '@/react/edge/edge-jobs/ListView'; import { CreateView } from '@/react/edge/edge-jobs/CreateView/CreateView'; +import { ItemView } from '@/react/edge/edge-jobs/ItemView/ItemView'; export const jobsModule = angular .module('portainer.edge.react.views.jobs', []) .component('edgeJobsView', r2a(withUIRouter(withCurrentUser(ListView)), [])) + .component( + 'edgeJobsItemView', + r2a(withUIRouter(withCurrentUser(ItemView)), []) + ) .component( 'edgeJobsCreateView', r2a(withUIRouter(withCurrentUser(CreateView)), []) diff --git a/app/edge/rest/edge-job-results.js b/app/edge/rest/edge-job-results.js deleted file mode 100644 index 3fb3e658f..000000000 --- a/app/edge/rest/edge-job-results.js +++ /dev/null @@ -1,14 +0,0 @@ -angular.module('portainer.edge').factory('EdgeJobResults', EdgeJobResultsFactory); - -function EdgeJobResultsFactory($resource, API_ENDPOINT_EDGE_JOBS) { - return $resource( - API_ENDPOINT_EDGE_JOBS + '/:id/tasks/:taskId/:action', - {}, - { - query: { method: 'GET', isArray: true, params: { id: '@id' } }, - logFile: { method: 'GET', params: { id: '@id', taskId: '@taskId', action: 'logs' } }, - clearLogs: { method: 'DELETE', params: { id: '@id', taskId: '@taskId', action: 'logs' } }, - collectLogs: { method: 'POST', params: { id: '@id', taskId: '@taskId', action: 'logs' } }, - } - ); -} diff --git a/app/edge/rest/edge-jobs.js b/app/edge/rest/edge-jobs.js deleted file mode 100644 index 05a3f48d8..000000000 --- a/app/edge/rest/edge-jobs.js +++ /dev/null @@ -1,17 +0,0 @@ -angular.module('portainer.edge').factory('EdgeJobs', EdgeJobsFactory); - -function EdgeJobsFactory($resource, API_ENDPOINT_EDGE_JOBS) { - return $resource( - API_ENDPOINT_EDGE_JOBS + '/:id/:action', - {}, - { - create: { method: 'POST', params: { id: 'create', action: '@method' } }, - query: { method: 'GET', isArray: true }, - get: { method: 'GET', params: { id: '@id' } }, - update: { method: 'PUT', params: { id: '@id' } }, - remove: { method: 'DELETE', params: { id: '@id' } }, - file: { method: 'GET', params: { id: '@id', action: 'file' } }, - tasks: { method: 'GET', isArray: true, params: { id: '@id', action: 'tasks' } }, - } - ); -} diff --git a/app/edge/services/edge-job.js b/app/edge/services/edge-job.js deleted file mode 100644 index 3eb94d0d3..000000000 --- a/app/edge/services/edge-job.js +++ /dev/null @@ -1,79 +0,0 @@ -import angular from 'angular'; -import _ from 'lodash-es'; - -import { ScheduleCreateRequest, ScheduleUpdateRequest } from '@/portainer/models/schedule'; - -function EdgeJobService(EdgeJobs, EdgeJobResults, FileUploadService) { - var service = {}; - - service.edgeJob = edgeJob; - async function edgeJob(edgeJobId) { - try { - return await EdgeJobs.get({ id: edgeJobId }).$promise; - } catch (err) { - throw { msg: 'Unable to retrieve edgeJob', err: err }; - } - } - - service.edgeJobs = edgeJobs; - async function edgeJobs() { - try { - return await EdgeJobs.query().$promise; - } catch (err) { - throw { msg: 'Unable to retrieve edgeJobs', err: err }; - } - } - - service.jobResults = jobResults; - async function jobResults(edgeJobId) { - try { - const results = await EdgeJobResults.query({ id: edgeJobId }).$promise; - - return _.sortBy(results, ['Id']); - } catch (err) { - throw { msg: 'Unable to retrieve results associated to the edgeJob', err: err }; - } - } - - service.logFile = logFile; - function logFile(id, taskId) { - return EdgeJobResults.logFile({ id, taskId }).$promise; - } - - service.collectLogs = collectLogs; - function collectLogs(id, taskId) { - return EdgeJobResults.collectLogs({ id, taskId }).$promise; - } - - service.clearLogs = clearLogs; - function clearLogs(id, taskId) { - return EdgeJobResults.clearLogs({ id, taskId }).$promise; - } - - service.createEdgeJobFromFileContent = function (model) { - var payload = new ScheduleCreateRequest(model); - return EdgeJobs.create({}, { method: 'string', ...payload }).$promise; - }; - - service.createEdgeJobFromFileUpload = function (model) { - var payload = new ScheduleCreateRequest(model); - return FileUploadService.createSchedule(payload); - }; - - service.updateEdgeJob = function (model) { - var payload = new ScheduleUpdateRequest(model); - return EdgeJobs.update(payload).$promise; - }; - - service.remove = function (edgeJobId) { - return EdgeJobs.remove({ id: edgeJobId }).$promise; - }; - - service.getScriptFile = function (edgeJobId) { - return EdgeJobs.file({ id: edgeJobId }).$promise; - }; - - return service; -} - -angular.module('portainer.edge').factory('EdgeJobService', EdgeJobService); diff --git a/app/edge/views/edge-jobs/edgeJob/edgeJob.html b/app/edge/views/edge-jobs/edgeJob/edgeJob.html deleted file mode 100644 index 152e59094..000000000 --- a/app/edge/views/edge-jobs/edgeJob/edgeJob.html +++ /dev/null @@ -1,46 +0,0 @@ -