Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add title to background tasks and improve the UI #13046

Merged
merged 7 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

namespace OrchardCore.ArchiveLater.Services;

[BackgroundTask(Schedule = "* * * * *", Description = "Archives content items when their scheduled archive date time arrives.")]
[BackgroundTask(
Title = "Content Items Archiver",
Schedule = "* * * * *",
Description = "Archives content items when their scheduled archive date time arrives.")]
public class ScheduledArchivingBackgroundTask : IBackgroundTask
{
private readonly ILogger<ScheduledArchivingBackgroundTask> _logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

namespace OrchardCore.AuditTrail.Services
{
[BackgroundTask(Schedule = "0 0 * * *",
Description = "A background task that regularly deletes old Audit Trail Events.",
[BackgroundTask(
Title = "Audit Trail Events Purger",
Schedule = "0 0 * * *",
Description = "Regularly purges old Audit Trail events.",
LockTimeout = 3_000, LockExpiration = 30_000)]

public class AuditTrailBackgroundTask : IBackgroundTask
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,165 +4,139 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using OrchardCore.Admin;
using OrchardCore.BackgroundTasks.Models;
using OrchardCore.BackgroundTasks.Services;
using OrchardCore.BackgroundTasks.ViewModels;
using OrchardCore.DisplayManagement;
using OrchardCore.Environment.Shell;
using OrchardCore.DisplayManagement.Notify;
using OrchardCore.Navigation;
using OrchardCore.Routing;

namespace OrchardCore.BackgroundTasks.Controllers
{
[Admin]
public class BackgroundTaskController : Controller
{
private readonly string _tenant;
private readonly IAuthorizationService _authorizationService;
private readonly IEnumerable<IBackgroundTask> _backgroundTasks;
private readonly BackgroundTaskManager _backgroundTaskManager;
private readonly PagerOptions _pagerOptions;
private readonly IStringLocalizer S;
private readonly INotifier _notifier;
private readonly dynamic New;
private readonly IStringLocalizer S;
private readonly IHtmlLocalizer H;

public BackgroundTaskController(
ShellSettings shellSettings,
IAuthorizationService authorizationService,
IEnumerable<IBackgroundTask> backgroundTasks,
BackgroundTaskManager backgroundTaskManager,
IShapeFactory shapeFactory,
IOptions<PagerOptions> pagerOptions,
IStringLocalizer<BackgroundTaskController> stringLocalizer)
IShapeFactory shapeFactory,
IHtmlLocalizer<BackgroundTaskController> htmlLocalizer,
IStringLocalizer<BackgroundTaskController> stringLocalizer,
INotifier notifier)
{
_tenant = shellSettings.Name;
_authorizationService = authorizationService;
_backgroundTasks = backgroundTasks;
_backgroundTaskManager = backgroundTaskManager;
_pagerOptions = pagerOptions.Value;
_notifier = notifier;

New = shapeFactory;
S = stringLocalizer;
H = htmlLocalizer;
}

public async Task<IActionResult> Index(PagerParameters pagerParameters)
public async Task<IActionResult> Index(AdminIndexOptions options, PagerParameters pagerParameters)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageBackgroundTasks))
{
return Forbid();
}

var pager = new Pager(pagerParameters, _pagerOptions.GetPageSize());
var document = await _backgroundTaskManager.GetDocumentAsync();

var taskEntries = _backgroundTasks.Select(t =>
{
if (!document.Settings.TryGetValue(t.GetTaskName(), out var settings))
{
settings = t.GetDefaultSettings();
}

return new BackgroundTaskEntry() { Settings = settings };
})
.OrderBy(entry => entry.Settings.Name)
.Skip(pager.GetStartIndex())
.Take(pager.PageSize)
.ToList();

var pagerShape = (await New.Pager(pager)).TotalItemCount(_backgroundTasks.Count());

var model = new BackgroundTaskIndexViewModel
{
Tasks = taskEntries,
Pager = pagerShape
};

return View(model);
}
var items = _backgroundTasks.Select(task => new BackgroundTaskEntry() { Settings = GetSettings(task, document) });

public async Task<IActionResult> Create(string name)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageBackgroundTasks))
if (!String.IsNullOrWhiteSpace(options.Search))
{
return Forbid();
items = items.Where(x => x.Settings.Title.Contains(options.Search, StringComparison.OrdinalIgnoreCase)
|| (x.Settings.Description != null && x.Settings.Description.Contains(options.Search, StringComparison.OrdinalIgnoreCase))
);
}

var model = new BackgroundTaskViewModel() { Name = name };

var task = _backgroundTasks.GetTaskByName(name);

if (task != null)
if (String.Equals(options.Status, "enabled", StringComparison.OrdinalIgnoreCase))
{
var settings = task.GetDefaultSettings();

model.Enable = settings.Enable;
model.Schedule = settings.Schedule;
model.DefaultSchedule = settings.Schedule;
model.Description = settings.Description;
model.LockTimeout = settings.LockTimeout;
model.LockExpiration = settings.LockExpiration;
items = items.Where(x => x.Settings.Enable);
}

return View(model);
}

[HttpPost, ActionName("Create")]
public async Task<IActionResult> CreatePost(BackgroundTaskViewModel model)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageBackgroundTasks))
else if (String.Equals(options.Status, "disabled", StringComparison.OrdinalIgnoreCase))
{
return Forbid();
items = items.Where(x => !x.Settings.Enable);
}

if (ModelState.IsValid)
options.Statuses = new List<SelectListItem>()
{
if (String.IsNullOrWhiteSpace(model.Name))
{
ModelState.AddModelError(nameof(BackgroundTaskViewModel.Name), S["The name is mandatory."]);
}
}
new SelectListItem() { Text = S["Enabled"], Value = "enabled" },
new SelectListItem() { Text = S["Disabled"], Value = "disabled" }
};

if (ModelState.IsValid)
{
var settings = new BackgroundTaskSettings
{
Name = model.Name,
Enable = model.Enable,
Schedule = model.Schedule?.Trim(),
Description = model.Description,
LockTimeout = model.LockTimeout,
LockExpiration = model.LockExpiration
};
var taskItems = items.ToList();
var routeData = new RouteData();
routeData.Values.Add($"{nameof(BackgroundTaskIndexViewModel.Options)}.{nameof(options.Search)}", options.Search);
routeData.Values.Add($"{nameof(BackgroundTaskIndexViewModel.Options)}.{nameof(options.Status)}", options.Status);

await _backgroundTaskManager.UpdateAsync(model.Name, settings);
var pager = new Pager(pagerParameters, _pagerOptions.GetPageSize());
var pagerShape = (await New.Pager(pager)).TotalItemCount(taskItems.Count).RouteData(routeData);

return RedirectToAction(nameof(Index));
}
var model = new BackgroundTaskIndexViewModel
{
Tasks = taskItems.OrderBy(entry => entry.Settings.Title).Skip(pager.GetStartIndex()).Take(pager.PageSize).ToList(),
Pager = pagerShape,
Options = options,
};

return View(model);
}

[HttpPost, ActionName(nameof(Index))]
[FormValueRequired("submit.Filter")]
public ActionResult IndexFilterPOST(BackgroundTaskIndexViewModel model)
{
return RedirectToAction(nameof(Index), new RouteValueDictionary {
{ $"{nameof(model.Options)}.{nameof(AdminIndexOptions.Search)}", model.Options.Search },
{ $"{nameof(model.Options)}.{nameof(AdminIndexOptions.Status)}", model.Options.Status },
});
}

public async Task<IActionResult> Edit(string name)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageBackgroundTasks))
{
return Forbid();
}

var document = await _backgroundTaskManager.GetDocumentAsync();
var task = _backgroundTasks.GetTaskByName(name);

if (!document.Settings.ContainsKey(name))
if (task == null)
{
return RedirectToAction(nameof(Create), new { name });
return NotFound();
}

var task = _backgroundTasks.GetTaskByName(name);
var document = await _backgroundTaskManager.GetDocumentAsync();

var settings = document.Settings[name];
var settings = GetSettings(task, document);

var model = new BackgroundTaskViewModel
{
Name = name,
Title = settings.Title,
Enable = settings.Enable,
Schedule = settings.Schedule,
DefaultSchedule = task?.GetDefaultSettings().Schedule,
Expand All @@ -182,32 +156,30 @@ public async Task<IActionResult> Edit(BackgroundTaskViewModel model)
return Forbid();
}

if (ModelState.IsValid)
var task = _backgroundTasks.GetTaskByName(model.Name);

if (task == null)
{
if (String.IsNullOrWhiteSpace(model.Name))
{
ModelState.AddModelError(nameof(BackgroundTaskViewModel.Name), S["The name is mandatory."]);
}
return NotFound();
}

if (ModelState.IsValid)
{
var settings = new BackgroundTaskSettings
{
Name = model.Name,
Enable = model.Enable,
Schedule = model.Schedule?.Trim(),
Description = model.Description,
LockTimeout = model.LockTimeout,
LockExpiration = model.LockExpiration
};
var document = await _backgroundTaskManager.LoadDocumentAsync();

var settings = GetSettings(task, document);

settings.Schedule = model.Schedule?.Trim();
settings.LockTimeout = model.LockTimeout;
settings.LockExpiration = model.LockExpiration;

await _backgroundTaskManager.UpdateAsync(model.Name, settings);

await _notifier.SuccessAsync(H["The task has been updated."]);

return RedirectToAction(nameof(Index));
}

// If we got this far, something failed, redisplay form
return View(model);
}

Expand All @@ -219,6 +191,11 @@ public async Task<IActionResult> Delete(string name)
return Forbid();
}

if (String.IsNullOrWhiteSpace(name))
{
return NotFound();
}

var document = await _backgroundTaskManager.LoadDocumentAsync();

if (!document.Settings.ContainsKey(name))
Expand All @@ -228,6 +205,8 @@ public async Task<IActionResult> Delete(string name)

await _backgroundTaskManager.RemoveAsync(name);

await _notifier.SuccessAsync(H["The task has been deleted."]);

return RedirectToAction(nameof(Index));
}

Expand All @@ -239,18 +218,22 @@ public async Task<IActionResult> Enable(string name)
return Forbid();
}

var document = await _backgroundTaskManager.LoadDocumentAsync();
var task = _backgroundTasks.GetTaskByName(name);

if (!document.Settings.TryGetValue(name, out var settings))
if (task == null)
{
settings = _backgroundTasks.GetTaskByName(name)?.GetDefaultSettings();
return NotFound();
}

if (settings != null)
{
settings.Enable = true;
await _backgroundTaskManager.UpdateAsync(name, settings);
}
var document = await _backgroundTaskManager.LoadDocumentAsync();

var settings = GetSettings(task, document);

settings.Enable = true;

await _backgroundTaskManager.UpdateAsync(name, settings);

await _notifier.SuccessAsync(H["The task has been enabled."]);

return RedirectToAction(nameof(Index));
}
Expand All @@ -263,20 +246,36 @@ public async Task<IActionResult> Disable(string name)
return Forbid();
}

var document = await _backgroundTaskManager.LoadDocumentAsync();
var task = _backgroundTasks.GetTaskByName(name);

if (!document.Settings.TryGetValue(name, out var settings))
if (task == null)
{
settings = _backgroundTasks.GetTaskByName(name)?.GetDefaultSettings();
return NotFound();
}

if (settings != null)
var document = await _backgroundTaskManager.LoadDocumentAsync();

var settings = GetSettings(task, document);

settings.Enable = false;

await _backgroundTaskManager.UpdateAsync(name, settings);

await _notifier.SuccessAsync(H["The task has been disabled."]);

return RedirectToAction(nameof(Index));
}

private static BackgroundTaskSettings GetSettings(IBackgroundTask task, BackgroundTaskDocument document)
{
var name = task.GetTaskName();

if (document.Settings.ContainsKey(name))
{
settings.Enable = false;
await _backgroundTaskManager.UpdateAsync(name, settings);
return document.Settings[name];
}

return RedirectToAction(nameof(Index));
return task.GetDefaultSettings();
}
}
}
Loading