Skip to content

Commit 34fc135

Browse files
Make features of entity picker configurable (#211)
1 parent 67aeae8 commit 34fc135

File tree

7 files changed

+102
-15
lines changed

7 files changed

+102
-15
lines changed

examples/RapidCMS.Example.Shared/Collections/PersonCollection.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ public static void AddPersonCollection(this ICmsConfig config)
153153
// so this field will allow the user to select an entity that is one level deeper in the person-tree
154154
section.AddField(x => x.FavouriteChildId)
155155
.SetName("Favorite child")
156-
.SetType(EditorType.Select)
156+
.SetType(EditorType.EntityPicker)
157+
// use the Picker configuration class to configure EntityPicker and EntitiesPicker editors
158+
.SetConfiguration(new Picker(PageSize: 3))
157159
.VisibleWhen((person, state) => state == EntityState.IsExisting)
158160
.SetCollectionRelation<Person>("person", config =>
159161
{
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace RapidCMS.Core.Models.Configuration;
2+
3+
public record Picker(
4+
bool EnableSelectAll = false,
5+
bool EnableUnselectAll = false,
6+
bool EnableReset = false,
7+
int PageSize = 25);

src/RapidCMS.Core/Providers/CollectionDataProvider.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using RapidCMS.Core.Forms;
1313
using RapidCMS.Core.Models.Data;
1414
using RapidCMS.Core.Models.EventArgs.Mediators;
15-
using RapidCMS.Core.Models.Setup;
1615

1716
namespace RapidCMS.Core.Providers;
1817

@@ -156,13 +155,19 @@ public async Task<IReadOnlyList<IElement>> GetRelatedElementsAsync()
156155
return elements.Where(x => _relatedIds.Contains(x.Id)).ToList();
157156
}
158157

159-
public void AddElement(object id) => _relatedIds.Add(id);
158+
public void AddElement(object id)
159+
{
160+
if (!_relatedIds.Contains(id))
161+
{
162+
_relatedIds.Add(id);
163+
}
164+
}
160165

161166
public void RemoveElement(object id) => _relatedIds.Remove(id);
162167

163168
public bool IsRelated(object id) => _relatedIds.Any(x => x.Equals(id));
164169

165-
public IReadOnlyList<object> GetCurrentRelatedElementIds() => _relatedIds;
170+
public IReadOnlyList<object> GetCurrentRelatedElementIds() => _relatedIds.ToList();
166171

167172
public Type GetRelatedEntityType() => _relatedEntityType ?? typeof(object);
168173

src/RapidCMS.UI/Components/Editors/BasePicker.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
using Microsoft.AspNetCore.Components;
77
using Microsoft.JSInterop;
88
using RapidCMS.Core.Abstractions.Data;
9+
using RapidCMS.Core.Abstractions.UI;
10+
using RapidCMS.Core.Models.Configuration;
911
using RapidCMS.Core.Models.Data;
12+
using RapidCMS.UI.Extensions;
1013

1114
namespace RapidCMS.UI.Components.Editors;
1215

13-
public abstract class BasePicker : BaseDataEditor
16+
public abstract class BasePicker : BaseDataEditor, IWantConfiguration<Picker>
1417
{
1518
protected string? _searchTerm;
1619
protected int _currentPage = 1;
@@ -25,15 +28,19 @@ public abstract class BasePicker : BaseDataEditor
2528

2629
protected virtual bool IsMultiple { get; set; }
2730

31+
protected Picker Config { get; set; }
32+
2833
[Inject]
2934
private IJSRuntime JsRuntime { get; set; } = null!;
3035

3136
private IRelationDataCollection RelationDataCollection
32-
=> DataCollection as IRelationDataCollection
37+
=> DataCollection as IRelationDataCollection
3338
?? throw new InvalidOperationException("Incorrect DataCollection assigned to Entity/iesPicker");
3439

3540
protected override async Task OnInitializedAsync()
3641
{
42+
Config = await this.GetConfigAsync() ?? new();
43+
3744
if (DataCollection != null)
3845
{
3946
DataCollection.OnDataChange += UpdateOptionsAsync;
@@ -83,14 +90,62 @@ protected async Task ResetViewAsync()
8390
await UpdateOptionsAsync();
8491
}
8592

93+
protected async Task SelectAllAsync()
94+
{
95+
if (RelationDataCollection == null)
96+
{
97+
return;
98+
}
99+
100+
var page = 1;
101+
do
102+
{
103+
var view = View.Create(Config.PageSize, page, null, null);
104+
var data = await RelationDataCollection.GetAvailableElementsAsync(view);
105+
106+
foreach (var item in data)
107+
{
108+
RelationDataCollection.AddElement(item.Id);
109+
}
110+
111+
if (data.Count < Config.PageSize)
112+
{
113+
break;
114+
}
115+
else
116+
{
117+
page++;
118+
}
119+
}
120+
while (true);
121+
122+
StateHasChanged();
123+
}
124+
125+
protected async Task UnselectAllAsync()
126+
{
127+
if (RelationDataCollection == null)
128+
{
129+
return;
130+
}
131+
132+
var items = RelationDataCollection.GetCurrentRelatedElementIds();
133+
foreach (var item in items)
134+
{
135+
RelationDataCollection.RemoveElement(item);
136+
}
137+
138+
StateHasChanged();
139+
}
140+
86141
private async Task UpdateOptionsAsync()
87142
{
88143
if (DataCollection == null)
89144
{
90145
return;
91146
}
92147

93-
var view = View.Create(25, _currentPage, _searchTerm, default);
148+
var view = View.Create(Config.PageSize, _currentPage, _searchTerm, default);
94149
_options = await DataCollection.GetAvailableElementsAsync(view);
95150

96151
if (view.MoreDataAvailable)

src/RapidCMS.UI/Components/Editors/EntitiesPicker.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
@inherits BaseMultiplePickerEditor
22
@attribute [Relation(RelationType.Many)]
33

4-
@if (_options != null)
4+
@if (_options != null && Config != null)
55
{
66
var index = 0;
77

88
<div class="form-control form-control-select-list @(CssHelper.GetDisplayModifier(DisplayType)) @(CssHelper.GetValidationClass(State))" id=@ElementId>
9-
<SearchBar OnResetView="ResetViewAsync" OnSearch="SearchAsync" />
9+
<SearchBar OnResetView="ResetViewAsync" OnSelectAll="SelectAllAsync" OnUnselectAll="UnselectAllAsync" OnSearch="SearchAsync" Config="Config" />
1010

1111
@foreach (var option in _options)
1212
{

src/RapidCMS.UI/Components/Editors/EntityPicker.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
@inherits BasePicker
22
@attribute [Relation(RelationType.One)]
33

4-
@if (_options != null)
4+
@if (_options != null && Config != null)
55
{
66
var index = 0;
77

88
<div class="form-control form-control-select-list @(CssHelper.GetDisplayModifier(DisplayType)) @(CssHelper.GetValidationClass(State))" id=@ElementId>
9-
<SearchBar OnResetView="ResetViewAsync" OnSearch="SearchAsync" />
9+
<SearchBar OnResetView="ResetViewAsync" OnSearch="SearchAsync" Config="Config" />
1010

1111
@foreach (var option in _options)
1212
{

src/RapidCMS.UI/Components/Editors/Parts/SearchBar.razor

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
<ul class="nav nav-tabs">
2-
<li class="nav-item">
3-
<button type="button" class="btn btn-light" @onclick="@(async (x) => await OnResetView.InvokeAsync())"><Icon Name="Refresh" /> Reset</button>
4-
</li>
2+
@if (Config.EnableSelectAll)
3+
{
4+
<li class="nav-item">
5+
<button type="button" class="btn btn-light" @onclick="@(async (x) => await OnSelectAll.InvokeAsync())"><Icon Name="MultiSelect" /> Select all</button>
6+
</li>
7+
}
8+
@if (Config.EnableUnselectAll)
9+
{
10+
<li class="nav-item">
11+
<button type="button" class="btn btn-light" @onclick="@(async (x) => await OnUnselectAll.InvokeAsync())"><Icon Name="RemoveFilter" /> Unselect all</button>
12+
</li>
13+
}
14+
@if (Config.EnableReset)
15+
{
16+
<li class="nav-item">
17+
<button type="button" class="btn btn-light" @onclick="@(async (x) => await OnResetView.InvokeAsync())"><Icon Name="Refresh" /> Reset</button>
18+
</li>
19+
}
520

621
<li class="nav-item search">
722
<div class="input-group">
@@ -24,5 +39,8 @@
2439
private string? _searchTerm;
2540

2641
[Parameter] public EventCallback OnResetView { get; set; } = default!;
42+
[Parameter] public EventCallback OnSelectAll { get; set; } = default!;
43+
[Parameter] public EventCallback OnUnselectAll { get; set; } = default!;
2744
[Parameter] public EventCallback<string> OnSearch { get; set; } = default!;
28-
}
45+
[Parameter] public Picker Config { get; set; } = default!;
46+
}

0 commit comments

Comments
 (0)