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

Fix the QueriesDocument and the Queries UI #16402

Merged
merged 56 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3ddb517
save incomplete work
MikeAlhayek Jul 2, 2024
877da6a
Convert everything
MikeAlhayek Jul 3, 2024
d48612f
remove document
MikeAlhayek Jul 3, 2024
22046c8
use required services
MikeAlhayek Jul 3, 2024
ba5b4c9
add release notes
MikeAlhayek Jul 3, 2024
122e843
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 3, 2024
11f8b0a
update release notes
MikeAlhayek Jul 3, 2024
83321f2
cleanup
MikeAlhayek Jul 4, 2024
49118dd
Update 2.0.0.md
MikeAlhayek Jul 4, 2024
4f0e663
Add query manager
MikeAlhayek Jul 6, 2024
3042b4d
fix conflict
MikeAlhayek Jul 6, 2024
09e86bd
fix release notes
MikeAlhayek Jul 6, 2024
42dc553
Fix test
MikeAlhayek Jul 6, 2024
cc60aac
update docs
MikeAlhayek Jul 6, 2024
01a347f
cleanup
MikeAlhayek Jul 6, 2024
254beb0
cleanup
MikeAlhayek Jul 6, 2024
b419e14
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 6, 2024
a4e3e52
cleanup
MikeAlhayek Jul 6, 2024
51a9174
Make more use of the query manager
MikeAlhayek Jul 6, 2024
a2334c2
more cleanup
MikeAlhayek Jul 7, 2024
67a7484
simplify
MikeAlhayek Jul 7, 2024
92f71b9
cleanup
MikeAlhayek Jul 7, 2024
dcf0e04
cleanup
MikeAlhayek Jul 7, 2024
599d986
cleanup namespaces
MikeAlhayek Jul 7, 2024
af477bd
more cleanup
MikeAlhayek Jul 7, 2024
7e90d91
Update QueryDisplayDriver.cs
MikeAlhayek Jul 7, 2024
7c2af96
Introduce handlers, and move back IQueryManager and Query to the abst…
MikeAlhayek Jul 8, 2024
f4419aa
user query manager more
MikeAlhayek Jul 8, 2024
82391bc
remove DefaultQueryManagerSession
MikeAlhayek Jul 8, 2024
97836cf
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 8, 2024
c6072cd
adding docs and fix the build.
MikeAlhayek Jul 8, 2024
ccadfe0
cleanup
MikeAlhayek Jul 8, 2024
f234322
Update src/OrchardCore.Modules/OrchardCore.Queries/Liquid/QueryFilter.cs
MikeAlhayek Jul 9, 2024
0c34fe4
Update src/OrchardCore/OrchardCore.Queries.Abstractions/IQueryHandler.cs
MikeAlhayek Jul 9, 2024
e938646
cleanup
MikeAlhayek Jul 9, 2024
d9fd445
add docs
MikeAlhayek Jul 9, 2024
1c89bd1
Update DefaultQueryManager.cs
MikeAlhayek Jul 9, 2024
061b794
update docs
MikeAlhayek Jul 9, 2024
3bde8db
Use a new document to store the updated indexes
MikeAlhayek Jul 9, 2024
f8ca240
Update the migration helper
MikeAlhayek Jul 9, 2024
4d037a7
Fix concurrency issue
MikeAlhayek Jul 9, 2024
28b261f
cleanup
MikeAlhayek Jul 9, 2024
5304c50
seldfgdf
MikeAlhayek Jul 9, 2024
8b42e0a
fix warnings
MikeAlhayek Jul 9, 2024
464a10e
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 9, 2024
ac20ad6
Update 2.0.0.md
MikeAlhayek Jul 10, 2024
c41fdef
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 11, 2024
1a8f07e
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 12, 2024
7754bdd
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 15, 2024
222b7a7
Update 2.0.0.md
MikeAlhayek Jul 16, 2024
61da4a6
Add AddQuerySource<>() extensions
MikeAlhayek Jul 18, 2024
d0b0a57
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 18, 2024
94f9ec4
Fix query not saving
MikeAlhayek Jul 18, 2024
40ce1f1
rename helper
MikeAlhayek Jul 18, 2024
d020da3
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 18, 2024
e0ca6ec
Merge branch 'main' into ma/fix-query-ui-using-document
MikeAlhayek Jul 18, 2024
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
7 changes: 7 additions & 0 deletions OrchardCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Email.Smtp", "s
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Rules.Core", "src\OrchardCore\OrchardCore.Rules.Core\OrchardCore.Rules.Core.csproj", "{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Queries.Core", "src\OrchardCore\OrchardCore.Queries.Core\OrchardCore.Queries.Core.csproj", "{61B358F2-702C-40AA-9DF7-7121248FE6DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1383,6 +1385,10 @@ Global
{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Release|Any CPU.Build.0 = Release|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1622,6 +1628,7 @@ Global
{C35AB37B-5A09-4896-BEEE-B126B7E7018A} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{E8A1097D-A65A-4B17-A3A2-F50D79552732} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{61B358F2-702C-40AA-9DF7-7121248FE6DE} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46A1D25A-78D1-4476-9CBF-25B75E296341}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using OrchardCore.Admin;
Expand All @@ -16,25 +17,26 @@
using OrchardCore.Navigation;
using OrchardCore.Queries.ViewModels;
using OrchardCore.Routing;
using YesSql.Services;

namespace OrchardCore.Queries.Controllers
{
[Admin("Queries/{action}/{id?}", "Queries{action}")]
public class AdminController : Controller
public sealed class AdminController : Controller
{
private const string _optionsSearch = "Options.Search";

private readonly IAuthorizationService _authorizationService;
private readonly PagerOptions _pagerOptions;
private readonly INotifier _notifier;
private readonly IServiceProvider _serviceProvider;
private readonly IQueryManager _queryManager;
private readonly IEnumerable<IQuerySource> _querySources;
private readonly IDisplayManager<Query> _displayManager;
private readonly IUpdateModelAccessor _updateModelAccessor;
private readonly IShapeFactory _shapeFactory;

protected readonly IStringLocalizer S;
protected readonly IHtmlLocalizer H;
internal readonly IStringLocalizer S;
internal readonly IHtmlLocalizer H;

public AdminController(
IDisplayManager<Query> displayManager,
Expand All @@ -45,14 +47,14 @@ public AdminController(
IHtmlLocalizer<AdminController> htmlLocalizer,
INotifier notifier,
IQueryManager queryManager,
IEnumerable<IQuerySource> querySources,
IServiceProvider serviceProvider,
IUpdateModelAccessor updateModelAccessor)
{
_displayManager = displayManager;
_authorizationService = authorizationService;
_pagerOptions = pagerOptions.Value;
_queryManager = queryManager;
_querySources = querySources;
_serviceProvider = serviceProvider;
_updateModelAccessor = updateModelAccessor;
_shapeFactory = shapeFactory;
_notifier = notifier;
Expand All @@ -69,19 +71,6 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p

var pager = new Pager(pagerParameters, _pagerOptions.GetPageSize());

var queries = await _queryManager.ListQueriesAsync();
queries = queries.OrderBy(x => x.Name);

if (!string.IsNullOrWhiteSpace(options.Search))
{
queries = queries.Where(q => q.Name.Contains(options.Search, StringComparison.OrdinalIgnoreCase));
}

var results = queries
.Skip(pager.GetStartIndex())
.Take(pager.PageSize)
.ToList();

// Maintain previous route data when generating page links.
var routeData = new RouteData();

Expand All @@ -90,15 +79,20 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
routeData.Values.TryAdd(_optionsSearch, options.Search);
}

var result = await _queryManager.PageQueriesAsync(pager.Page, pager.PageSize, new QueryContext()
{
Name = options.Search,
});

var model = new QueriesIndexViewModel
{
Queries = [],
Options = options,
Pager = await _shapeFactory.PagerAsync(pager, queries.Count(), routeData),
QuerySourceNames = _querySources.Select(x => x.Name).ToList()
Pager = await _shapeFactory.PagerAsync(pager, result.Count, routeData),
QuerySourceNames = _serviceProvider.GetServices<IQuerySource>().Select(x => x.Name).ToArray(),
};

foreach (var query in results)
foreach (var query in result.Records)
{
model.Queries.Add(new QueryEntry
{
Expand All @@ -115,7 +109,8 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
return View(model);
}

[HttpPost, ActionName(nameof(Index))]
[HttpPost]
[ActionName(nameof(Index))]
[FormValueRequired("submit.Filter")]
public ActionResult IndexFilterPOST(QueriesIndexViewModel model)
=> RedirectToAction(nameof(Index), new RouteValueDictionary
Expand All @@ -130,7 +125,7 @@ public async Task<IActionResult> Create(string id)
return Forbid();
}

var query = _querySources.FirstOrDefault(x => x.Name == id)?.Create();
var query = await _queryManager.NewAsync(id);

if (query == null)
{
Expand All @@ -139,39 +134,41 @@ public async Task<IActionResult> Create(string id)

var model = new QueriesCreateViewModel
{
Editor = await _displayManager.BuildEditorAsync(query, updater: _updateModelAccessor.ModelUpdater, isNew: true, "", ""),
Editor = await _displayManager.BuildEditorAsync(query, _updateModelAccessor.ModelUpdater, true),
SourceName = id
};

return View(model);
}

[HttpPost, ActionName(nameof(Create))]
[HttpPost]
[ActionName(nameof(Create))]
public async Task<IActionResult> CreatePost(QueriesCreateViewModel model)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageQueries))
{
return Forbid();
}

var query = _querySources.FirstOrDefault(x => x.Name == model.SourceName)?.Create();
var query = await _queryManager.NewAsync(model.SourceName);

if (query == null)
{
return NotFound();
}

var editor = await _displayManager.UpdateEditorAsync(query, updater: _updateModelAccessor.ModelUpdater, isNew: true, "", "");
var editor = await _displayManager.UpdateEditorAsync(query, _updateModelAccessor.ModelUpdater, true);

if (ModelState.IsValid)
{
await _queryManager.SaveQueryAsync(query.Name, query);
await _queryManager.SaveAsync(query);

await _notifier.SuccessAsync(H["Query created successfully."]);

return RedirectToAction(nameof(Index));
}

// If we got this far, something failed, redisplay form
// If we got this far, something failed, redisplay form.
model.Editor = editor;

return View(model);
Expand All @@ -193,43 +190,47 @@ public async Task<IActionResult> Edit(string id)

var model = new QueriesEditViewModel
{
SourceName = query.Source,
Name = query.Name,
Schema = query.Schema,
Editor = await _displayManager.BuildEditorAsync(query, updater: _updateModelAccessor.ModelUpdater, isNew: false, "", "")
Editor = await _displayManager.BuildEditorAsync(query, _updateModelAccessor.ModelUpdater, false)
};

return View(model);
}

[HttpPost, ActionName(nameof(Edit))]
[HttpPost]
[ActionName(nameof(Edit))]
public async Task<IActionResult> EditPost(QueriesEditViewModel model)
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageQueries))
{
return Forbid();
}

var query = await _queryManager.LoadQueryAsync(model.Name);
if (string.IsNullOrEmpty(model.Name))
{
return BadRequest();
}

var query = await _queryManager.GetQueryAsync(model.Name);

if (query == null)
{
return NotFound();
}

var editor = await _displayManager.UpdateEditorAsync(query, updater: _updateModelAccessor.ModelUpdater, isNew: false, string.Empty, string.Empty);
var editor = await _displayManager.UpdateEditorAsync(query, _updateModelAccessor.ModelUpdater, false);

if (ModelState.IsValid)
{
await _queryManager.SaveQueryAsync(model.Name, query);

await _queryManager.UpdateAsync(query);
await _notifier.SuccessAsync(H["Query updated successfully."]);

return RedirectToAction(nameof(Index));
}

model.Editor = editor;

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

Expand All @@ -241,21 +242,18 @@ public async Task<IActionResult> Delete(string id)
return Forbid();
}

var query = await _queryManager.LoadQueryAsync(id);

if (query == null)
if (!await _queryManager.DeleteQueryAsync(id))
{
return NotFound();
}

await _queryManager.DeleteQueryAsync(id);

await _notifier.SuccessAsync(H["Query deleted successfully."]);

return RedirectToAction(nameof(Index));
}

[HttpPost, ActionName(nameof(Index))]
[HttpPost]
[ActionName(nameof(Index))]
[FormValueRequired("submit.BulkAction")]
public async Task<ActionResult> IndexPost(ContentOptions options, IEnumerable<string> itemIds)
{
Expand All @@ -266,21 +264,16 @@ public async Task<ActionResult> IndexPost(ContentOptions options, IEnumerable<st

if (itemIds?.Count() > 0)
{
var queriesList = await _queryManager.ListQueriesAsync();
var checkedContentItems = queriesList.Where(x => itemIds.Contains(x.Name));
switch (options.BulkAction)
{
case ContentsBulkAction.None:
break;
case ContentsBulkAction.Remove:
foreach (var item in checkedContentItems)
{
await _queryManager.DeleteQueryAsync(item.Name);
}
await _queryManager.DeleteQueryAsync(itemIds.ToArray());
await _notifier.SuccessAsync(H["Queries successfully removed."]);
break;
default:
throw new ArgumentOutOfRangeException(options.BulkAction.ToString(), "Invalid bulk action.");
return BadRequest();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace OrchardCore.Queries.Controllers
{
[Route("api/queries")]
[ApiController]
[Authorize(AuthenticationSchemes = "Api"), IgnoreAntiforgeryToken, AllowAnonymous]
public class QueryApiController : ControllerBase
[Authorize(AuthenticationSchemes = "Api")]
[IgnoreAntiforgeryToken]
[AllowAnonymous]
public sealed class QueryApiController : ControllerBase
{
private readonly IAuthorizationService _authorizationService;
private readonly IQueryManager _queryManager;
Expand Down Expand Up @@ -57,6 +59,7 @@ public async Task<IActionResult> Query(
: [];

var result = await _queryManager.ExecuteQueryAsync(query, queryParameters);

return new ObjectResult(result);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlan
return;
}

if (!query.ResultsOfType<ContentItem>())
if (!query.CanReturnContentItems || !query.ReturnContentItems)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using OrchardCore.ContentManagement;
using OrchardCore.Deployment;
using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.DisplayManagement.ModelBinding;
Expand All @@ -15,6 +14,7 @@ namespace OrchardCore.Queries.Deployment
public class QueryBasedContentDeploymentStepDriver : DisplayDriver<DeploymentStep, QueryBasedContentDeploymentStep>
{
private readonly IQueryManager _queryManager;

protected readonly IStringLocalizer S;

public QueryBasedContentDeploymentStepDriver(
Expand All @@ -36,21 +36,22 @@ public override IDisplayResult Display(QueryBasedContentDeploymentStep step)

public override IDisplayResult Edit(QueryBasedContentDeploymentStep step)
{
return Initialize<QueryBasedContentDeploymentStepViewModel>("QueryBasedContentDeploymentStep_Fields_Edit", model =>
return Initialize<QueryBasedContentDeploymentStepViewModel>("QueryBasedContentDeploymentStep_Fields_Edit", async model =>
{
model.QueryName = step.QueryName;
model.QueryParameters = step.QueryParameters;
model.ExportAsSetupRecipe = step.ExportAsSetupRecipe;
model.Queries = await _queryManager.ListQueriesAsync(true);
}).Location("Content");
}

public override async Task<IDisplayResult> UpdateAsync(QueryBasedContentDeploymentStep step, IUpdateModel updater)
{
var queryBasedContentViewModel = new QueryBasedContentDeploymentStepViewModel();
await updater.TryUpdateModelAsync(queryBasedContentViewModel, Prefix, viewModel => viewModel.QueryName, viewModel => viewModel.QueryParameters, viewModel => viewModel.ExportAsSetupRecipe);
var query = await _queryManager.LoadQueryAsync(queryBasedContentViewModel.QueryName);
var query = await _queryManager.GetQueryAsync(queryBasedContentViewModel.QueryName);

if (!query.ResultsOfType<ContentItem>())
if (!query.CanReturnContentItems || !query.ReturnContentItems)
{
updater.ModelState.AddModelError(Prefix, nameof(step.QueryName), S["Your Query is not returning content items."]);
}
Expand Down
Loading