improve Edit Job UI
This commit is contained in:
@@ -11,26 +11,24 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
@if (!_editable)
|
@if (!_editable)
|
||||||
{
|
{
|
||||||
<div class="alert alert-warning alert-dismissible fade show mb-3 custom" role="alert">
|
<ModuleMessage Message="@Localizer["JobNotEditable"]" Type="MessageType.Warning" />
|
||||||
@Localizer["JobNotEditable"]
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter the job name" ResourceKey="Name">Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="type" HelpText="The fully qualified job type name" ResourceKey="Type">Type: </Label>
|
<Label Class="col-sm-3" For="type" HelpText="The fully qualified job type name" ResourceKey="Type">Type: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="type" class="form-control" @bind="@_jobType" readonly />
|
<input id="type" class="form-control" @bind="@_jobType" required disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="name" HelpText="Enter the job name" ResourceKey="Name">Name: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="name" class="form-control" @bind="@_name" maxlength="200" required disabled="@(!_editable)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="enabled" HelpText="Select whether you want the job enabled or not" ResourceKey="Enabled">Enabled? </Label>
|
<Label Class="col-sm-3" For="enabled" HelpText="Select whether you want the job enabled or not" ResourceKey="Enabled">Enabled? </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="enabled" class="form-select" @bind="@_isEnabled" required>
|
<select id="enabled" class="form-select" @bind="@_isEnabled" required disabled="@(!_editable)">
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -83,17 +81,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="next" HelpText="Optionally modify the date and time when this job should execute next" ResourceKey="NextExecution">Next Execution: </Label>
|
<Label Class="col-sm-3" For="next" HelpText="The date and time when this job will execute next. This value cannot be modified. Use the settings above to control the execution of the job." ResourceKey="NextExecution">Next Execution: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="next" class="form-control" @bind="@_nextDate" readonly />
|
<input id="next" class="form-control" @bind="@_nextDate" disabled />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveJob">@SharedLocalizer["Save"]</button>
|
@if (_editable)
|
||||||
@if (!_editable)
|
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-danger ms-1" @onclick="ExecuteJob">@SharedLocalizer["Execute"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveJob">@SharedLocalizer["Save"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-danger" @onclick="DisableJob">@Localizer["Disable"]</button>
|
||||||
}
|
}
|
||||||
<NavLink class="btn btn-secondary ms-1" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary ms-1" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
<br />
|
<br />
|
||||||
@@ -128,6 +129,11 @@
|
|||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await LoadJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task LoadJob()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -165,23 +171,15 @@
|
|||||||
|
|
||||||
private async Task SaveJob()
|
private async Task SaveJob()
|
||||||
{
|
{
|
||||||
if (!Utilities.ValidateEffectiveExpiryDates(_startDate, _endDate))
|
try
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.StartEndDateError"], MessageType.Warning);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
validated = true;
|
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
var job = await JobService.GetJobAsync(_jobId);
|
var job = await JobService.GetJobAsync(_jobId);
|
||||||
job.Name = _name;
|
job.Name = _name;
|
||||||
job.JobType = _jobType;
|
job.IsEnabled = bool.Parse(_isEnabled);
|
||||||
var enabledChanged = job.IsEnabled != Boolean.Parse(_isEnabled);
|
|
||||||
job.IsEnabled = Boolean.Parse(_isEnabled);
|
|
||||||
|
|
||||||
if (_editable)
|
|
||||||
{
|
|
||||||
job.Frequency = _frequency;
|
job.Frequency = _frequency;
|
||||||
if (job.Frequency == "O") // once
|
if (job.Frequency == "O") // once
|
||||||
{
|
{
|
||||||
@@ -191,6 +189,7 @@
|
|||||||
{
|
{
|
||||||
job.Interval = int.Parse(_interval);
|
job.Interval = int.Parse(_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
job.StartDate = _startDate.HasValue && _startTime.HasValue
|
job.StartDate = _startDate.HasValue && _startTime.HasValue
|
||||||
? LocalToUtc(_startDate.GetValueOrDefault().Date.Add(_startTime.GetValueOrDefault().TimeOfDay))
|
? LocalToUtc(_startDate.GetValueOrDefault().Date.Add(_startTime.GetValueOrDefault().TimeOfDay))
|
||||||
: null;
|
: null;
|
||||||
@@ -200,80 +199,63 @@
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||||
}
|
|
||||||
|
|
||||||
if (!job.IsEnabled)
|
if (!job.IsEnabled || Utilities.ValidateEffectiveExpiryDates(job.StartDate, job.EndDate))
|
||||||
|
{
|
||||||
|
if (!job.IsEnabled || (job.StartDate >= DateTime.UtcNow || job.StartDate == null))
|
||||||
{
|
{
|
||||||
job.NextExecution = null;
|
job.NextExecution = null;
|
||||||
}
|
job = await JobService.UpdateJobAsync(job);
|
||||||
else if (enabledChanged)
|
await logger.LogInformation("Job Updated {Job}", job);
|
||||||
{
|
|
||||||
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());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.StartDateError"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.StartEndDateError"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Required.JobInfo"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Required.JobInfo"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Updating Job {JobId} {Error}", _jobId, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ExecuteJob()
|
private async Task DisableJob()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var job = await JobService.GetJobAsync(_jobId);
|
var job = await JobService.GetJobAsync(_jobId);
|
||||||
if (job != null)
|
if (job != null)
|
||||||
{
|
{
|
||||||
|
if (job.IsExecuting)
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.ExecutingError"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job.IsEnabled = false;
|
||||||
job.NextExecution = 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);
|
job = await JobService.UpdateJobAsync(job);
|
||||||
await logger.LogInformation("Job Updated {Job}", job);
|
await logger.LogInformation("Job Updated {Job}", job);
|
||||||
|
await LoadJob();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Updating Job {Job} {Error}", job, ex.Message);
|
await logger.LogError(ex, "Error Updating Job {JobId} {Error}", _jobId, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@
|
|||||||
<value>Error Updating Job</value>
|
<value>Error Updating Job</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Required.JobInfo" xml:space="preserve">
|
<data name="Message.Required.JobInfo" xml:space="preserve">
|
||||||
<value>You Must Provide The Job Name, Type, Frequency, and Retention</value>
|
<value>You Must Provide The Job Name, Frequency, and Retention</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Name.HelpText" xml:space="preserve">
|
<data name="Name.HelpText" xml:space="preserve">
|
||||||
<value>Enter the job name</value>
|
<value>Enter the job name</value>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<value>Select how often you want the job to run</value>
|
<value>Select how often you want the job to run</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Starting.HelpText" xml:space="preserve">
|
<data name="Starting.HelpText" xml:space="preserve">
|
||||||
<value>Optionally enter the date and time when this job should start executing</value>
|
<value>Optionally enter the date and time when this job should start executing. If no date or time is specified, the job will execute immediately.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Ending.HelpText" xml:space="preserve">
|
<data name="Ending.HelpText" xml:space="preserve">
|
||||||
<value>Optionally enter the date and time when this job should stop executing</value>
|
<value>Optionally enter the date and time when this job should stop executing</value>
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
<value>Number of log entries to retain for this job</value>
|
<value>Number of log entries to retain for this job</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NextExecution.HelpText" xml:space="preserve">
|
<data name="NextExecution.HelpText" xml:space="preserve">
|
||||||
<value>Optionally modify the date and time when this job should execute next</value>
|
<value>The date and time when this job will execute next. This value cannot be modified. Use the settings above to control the execution of the job.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Type.Text" xml:space="preserve">
|
<data name="Type.Text" xml:space="preserve">
|
||||||
<value>Type: </value>
|
<value>Type: </value>
|
||||||
@@ -193,12 +193,15 @@
|
|||||||
<value>Execute Once</value>
|
<value>Execute Once</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.StartEndDateError" xml:space="preserve">
|
<data name="Message.StartEndDateError" xml:space="preserve">
|
||||||
<value>Start Date cannot be after End Date.</value>
|
<value>The Start Date Cannot Be Later Than The End Date</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.StartDateError" xml:space="preserve">
|
||||||
|
<value>The Start Date Cannot Be Prior To The Current Date</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.ExecutingError" xml:space="preserve">
|
||||||
|
<value>The Job Is Currently Executing. You Must Wait Until The Job Has Completed.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="JobNotEditable" xml:space="preserve">
|
<data name="JobNotEditable" xml:space="preserve">
|
||||||
<value>The job properties is not able to be modified because it's enabled or running in progress.</value>
|
<value>The Job Cannot Be Modified As It Is Currently Enabled. You Must Disable The Job To Change Its Settings.</value>
|
||||||
</data>
|
|
||||||
<data name="Execute" xml:space="preserve">
|
|
||||||
<value>Execute</value>
|
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -198,41 +198,27 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
case "m": // minutes
|
case "m": // minutes
|
||||||
nextExecution = nextExecution.AddMinutes(job.Interval);
|
nextExecution = nextExecution.AddMinutes(job.Interval);
|
||||||
|
if (nextExecution < DateTime.UtcNow) nextExecution = DateTime.UtcNow;
|
||||||
break;
|
break;
|
||||||
case "H": // hours
|
case "H": // hours
|
||||||
nextExecution = nextExecution.AddHours(job.Interval);
|
nextExecution = nextExecution.AddHours(job.Interval);
|
||||||
|
if (nextExecution < DateTime.UtcNow) nextExecution = DateTime.UtcNow;
|
||||||
break;
|
break;
|
||||||
case "d": // days
|
case "d": // days
|
||||||
|
nextExecution = DateTime.UtcNow.Date.Add(nextExecution.TimeOfDay); // preserve time of day
|
||||||
nextExecution = nextExecution.AddDays(job.Interval);
|
nextExecution = nextExecution.AddDays(job.Interval);
|
||||||
if (job.StartDate != null && job.StartDate.Value.TimeOfDay.TotalSeconds != 0)
|
|
||||||
{
|
|
||||||
// set the start time
|
|
||||||
nextExecution = nextExecution.Date.Add(job.StartDate.Value.TimeOfDay);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "w": // weeks
|
case "w": // weeks
|
||||||
|
nextExecution = DateTime.UtcNow.Date.Add(nextExecution.TimeOfDay); // preserve time of day
|
||||||
nextExecution = nextExecution.AddDays(job.Interval * 7);
|
nextExecution = nextExecution.AddDays(job.Interval * 7);
|
||||||
if (job.StartDate != null && job.StartDate.Value.TimeOfDay.TotalSeconds != 0)
|
|
||||||
{
|
|
||||||
// set the start time
|
|
||||||
nextExecution = nextExecution.Date.Add(job.StartDate.Value.TimeOfDay);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "M": // months
|
case "M": // months
|
||||||
|
nextExecution = DateTime.UtcNow.Date.Add(nextExecution.TimeOfDay); // preserve time of day
|
||||||
nextExecution = nextExecution.AddMonths(job.Interval);
|
nextExecution = nextExecution.AddMonths(job.Interval);
|
||||||
if (job.StartDate != null && job.StartDate.Value.TimeOfDay.TotalSeconds != 0)
|
|
||||||
{
|
|
||||||
// set the start time
|
|
||||||
nextExecution = nextExecution.Date.Add(job.StartDate.Value.TimeOfDay);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "O": // one time
|
case "O": // one time
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nextExecution < DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
nextExecution = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
return nextExecution;
|
return nextExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user