From 43ee682d1ffcb94d3d8e0c492f20d878112a7d3d Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 8 Jan 2026 11:39:32 +0800 Subject: [PATCH] Fix #5942: set the next execution time correctly. --- Oqtane.Client/Modules/Admin/Jobs/Edit.razor | 373 +++++++++++------- .../Resources/Modules/Admin/Jobs/Edit.resx | 6 + 2 files changed, 228 insertions(+), 151 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 3a7c3005..0e8edac5 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -5,100 +5,108 @@ @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer -
-
-
- -
- +@if (_initialized) +{ + +
+ @if (!_editable) + { + + } +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
-
- -
- - +
+ +
+ + +
-
-
- -
- +
+ +
+ +
-
-
- -
-
-
- -
-
- +
+ +
+
+
+ +
+
+ +
-
-
- -
-
-
- -
-
- +
+ +
+
+
+ +
+
+ +
-
-
- -
-
-
- -
-
- -
+
+ +
+
-
-
- - @SharedLocalizer["Cancel"] -
-
- - +
+ + @if (!_editable) + { + + } + @SharedLocalizer["Cancel"] +
+
+ + +} @code { private ElementReference form; private bool validated = false; + private bool _initialized = false; + private bool _editable = true; private int _jobId; private string _name = string.Empty; private string _jobType = string.Empty; @@ -113,26 +121,27 @@ private DateTime? _nextDate = null; private DateTime? _nextTime = null; private string createdby; - private DateTime createdon; - private string modifiedby; - private DateTime modifiedon; + private DateTime createdon; + private string modifiedby; + private DateTime modifiedon; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() - { - try - { - _jobId = Int32.Parse(PageState.QueryString["id"]); - Job job = await JobService.GetJobAsync(_jobId); - if (job != null) - { - _name = job.Name; - _jobType = job.JobType; - _isEnabled = job.IsEnabled.ToString(); - _interval = job.Interval.ToString(); - _frequency = job.Frequency; - _startDate = UtcToLocal(job.StartDate); + protected override async Task OnInitializedAsync() + { + try + { + _jobId = Int32.Parse(PageState.QueryString["id"]); + Job job = await JobService.GetJobAsync(_jobId); + if (job != null) + { + _editable = !job.IsEnabled && !job.IsExecuting; + _name = job.Name; + _jobType = job.JobType; + _isEnabled = job.IsEnabled.ToString(); + _interval = job.Interval.ToString(); + _frequency = job.Frequency; + _startDate = UtcToLocal(job.StartDate); _startTime = UtcToLocal(job.StartDate); _endDate = UtcToLocal(job.EndDate); _endTime = UtcToLocal(job.EndDate); @@ -140,70 +149,132 @@ _nextDate = UtcToLocal(job.NextExecution); _nextTime = UtcToLocal(job.NextExecution); createdby = job.CreatedBy; - createdon = job.CreatedOn; - modifiedby = job.ModifiedBy; - modifiedon = job.ModifiedOn; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message); - AddModuleMessage(Localizer["Error.Job.Load"], MessageType.Error); - } - } + createdon = job.CreatedOn; + modifiedby = job.ModifiedBy; + modifiedon = job.ModifiedOn; + } - private async Task SaveJob() - { + _initialized = true; + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message); + AddModuleMessage(Localizer["Error.Job.Load"], MessageType.Error); + } + } + + private async Task SaveJob() + { if (!Utilities.ValidateEffectiveExpiryDates(_startDate, _endDate)) { AddModuleMessage(Localizer["Message.StartEndDateError"], MessageType.Warning); return; } - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - var job = await JobService.GetJobAsync(_jobId); - job.Name = _name; - job.JobType = _jobType; - job.IsEnabled = Boolean.Parse(_isEnabled); - job.Frequency = _frequency; - if (job.Frequency == "O") // once - { - job.Interval = 1; - } - else - { - job.Interval = int.Parse(_interval); - } - job.StartDate = _startDate.HasValue && _startTime.HasValue - ? LocalToUtc(_startDate.GetValueOrDefault().Date.Add(_startTime.GetValueOrDefault().TimeOfDay)) - : null; + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + var job = await JobService.GetJobAsync(_jobId); + job.Name = _name; + job.JobType = _jobType; + var enabledChanged = job.IsEnabled != Boolean.Parse(_isEnabled); + job.IsEnabled = Boolean.Parse(_isEnabled); - job.EndDate = _endDate.HasValue && _endTime.HasValue - ? LocalToUtc(_endDate.GetValueOrDefault().Date.Add(_endTime.GetValueOrDefault().TimeOfDay)) - : null; + if (_editable) + { + job.Frequency = _frequency; + if (job.Frequency == "O") // once + { + job.Interval = 1; + } + else + { + job.Interval = int.Parse(_interval); + } + job.StartDate = _startDate.HasValue && _startTime.HasValue + ? LocalToUtc(_startDate.GetValueOrDefault().Date.Add(_startTime.GetValueOrDefault().TimeOfDay)) + : null; - job.NextExecution = _nextDate.HasValue && _nextTime.HasValue - ? LocalToUtc(_nextDate.GetValueOrDefault().Date.Add(_nextTime.GetValueOrDefault().TimeOfDay)) - : null; - job.RetentionHistory = int.Parse(_retentionHistory); + job.EndDate = _endDate.HasValue && _endTime.HasValue + ? LocalToUtc(_endDate.GetValueOrDefault().Date.Add(_endTime.GetValueOrDefault().TimeOfDay)) + : null; - try - { - job = await JobService.UpdateJobAsync(job); - await logger.LogInformation("Job Updated {Job}", job); - NavigationManager.NavigateTo(NavigateUrl()); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Updating Job {Job} {Error}", job, ex.Message); - AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error); - } - } - else - { - AddModuleMessage(Localizer["Message.Required.JobInfo"], MessageType.Warning); - } - } + job.RetentionHistory = int.Parse(_retentionHistory); + } + + if (!job.IsEnabled) + { + job.NextExecution = null; + } + else if (enabledChanged) + { + job.NextExecution = null; + if(job.StartDate != null && job.StartDate < DateTime.UtcNow) + { + var startDate = DateTime.UtcNow; + if ((job.Frequency == "d" || job.Frequency == "w" || job.Frequency == "M") && job.StartDate.Value.TimeOfDay.TotalSeconds != 0) + { + // set the start time + startDate = startDate.Date.Add(job.StartDate.Value.TimeOfDay); + if(startDate < DateTime.UtcNow) + { + switch (job.Frequency) + { + case "d": + startDate = startDate.AddDays(job.Interval); + break; + case "w": + startDate = startDate.AddDays(job.Interval * 7); + break; + case "M": + startDate = startDate.AddMonths(job.Interval); + break; + } + } + } + + job.StartDate = startDate; + } + } + + await PerformSaveJobAction(job); + NavigationManager.NavigateTo(NavigateUrl()); + } + else + { + AddModuleMessage(Localizer["Message.Required.JobInfo"], MessageType.Warning); + } + } + + private async Task ExecuteJob() + { + var job = await JobService.GetJobAsync(_jobId); + if (job != null) + { + job.NextExecution = null; + + await PerformSaveJobAction(job); + + if(!job.IsStarted) + { + await JobService.StartJobAsync(_jobId); + } + + NavigationManager.NavigateTo(NavigateUrl()); + } + } + + private async Task PerformSaveJobAction(Job job) + { + try + { + job = await JobService.UpdateJobAsync(job); + await logger.LogInformation("Job Updated {Job}", job); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Updating Job {Job} {Error}", job, ex.Message); + AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error); + } + } } diff --git a/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx index 672f5dc9..0ac43748 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx @@ -195,4 +195,10 @@ Start Date cannot be after End Date. + + The job properties is not able to be modified because it's enabled or running in progress. + + + Execute + \ No newline at end of file