Grid Component

features/rewrite/main^2
markosteger 2 years ago
parent bfdbc38cbb
commit 5f8215c5c5

@ -22,4 +22,10 @@
<Watch Remove="..\..\src\**\bin\**" /> <Watch Remove="..\..\src\**\bin\**" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Watch Remove="Pages\ComponentsExamples\DataGridExample.razor" />
<Watch Remove="Pages\ComponentsExamples\DatePickerExample.razor" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,88 @@
@page "/datagrid"
@using Connected.Classes.Grid;
@using Connected.Components;
@using Connected.Enums;
@using Connected.Models.Modal;
@using Connected.Models;
@using Connected.Services;
@using Connected.Utilities;
@using System.Collections.ObjectModel;
@if (loaded)
{
<h1 style="text-align:center;">DATA GRID EXAMPLE</h1>
<Grid Items="Data" Context="number" Options="dataGridOptions">
<RowTemplate>
@number
</RowTemplate>
<RowDetailTemplate>
@(number * 2)
</RowDetailTemplate>
</Grid>
<Grid Items="DData" Context="dummy" Options="dataGridOptions">
<RowTemplate>
@dummy.Value
</RowTemplate>
<RowDetailTemplate>
@dummy.Value
</RowDetailTemplate>
</Grid>
}
else
{
<h4>Data filling...</h4>
}
@code {
bool loaded = false;
DataGridOptions dataGridOptions = new DataGridOptions()
{
ImagePosition = SmScrn_GridImgPos.Top,
ShowImage = true,
Dense = true,
ShowSelect = true,
ItemsPerPage = 10,
SelectedPage = 1,
DataSet_ImgColName = "Img",
};
ObservableCollection<int> Data = new();
ObservableCollection<DummyData> DData = new();
protected override void OnInitialized()
{
if (Data is null) Data = new();
if (DData is null) DData = new();
Random r = new Random();
for (int i = 0; i < 20; i++)
{
//int l = r.Next(50);
Data.Add(r.Next(50));
DData.Add(new DummyData() { Value = r.Next(50) });
}
loaded = true;
StateHasChanged();
}
public string RandomString(int length)
{
Random random = new Random(DateTime.Now.Millisecond);
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
string result = new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
return result;
}
public class DummyData
{
public object Value { get; set; } = null;
public string Img { get; set; } = "https://source.unsplash.com/random?face";
}
}

@ -0,0 +1,23 @@
@page "/datepicker"
@using Connected.Components;
@using Connected.Enums;
@using Connected.Models.Modal;
@using Connected.Models;
@using Connected.Services;
@using Connected.Utilities;
@inject ModalDialogService modalDialog;
<h1 style="text-align:center;">DATE PICKER EXAMPLE</h1>
<DatePicker @bind-SelectedDate=@date></DatePicker>
<h4>Selected date: @date.ToString("dd. MM. yyyy")</h4>
@code {
DateTime date = DateTime.Now;
}

@ -6,19 +6,16 @@
@using Connected.Services; @using Connected.Services;
@using Connected.Utilities; @using Connected.Utilities;
@inject ModalDialogService modalDialog; @inject ModalDialogService modalDialog
<h1 style="text-align:center;">MODAL DIALOG EXAMPLE</h1> <h1 style="text-align:center;">MODAL DIALOG EXAMPLE</h1>
<Button OnClick="OpenModalDialog">Open dialog</Button> <Button OnClick="OpenModalDialog">Open dialog</Button>
<p>Modal result: @test_modal_result</p> <p>Modal result: @test_modal_result</p>
<h4>Value: @value.ToString()</h4> <h4>Value: @value.ToString()</h4>
@code { @code {
int value = 0; int value = 0;

@ -1,71 +1,31 @@
@page "/" @page "/"
@using Connected.Enums;
@using Connected.Models; @using Connected.Models;
@using Connected.Components; @using Connected.Components;
@using Connected.Services;
@using Connected.Utilities;
<h1 style="text-align:center;">Component Sandbox</h1>
@if (loaded)
<Grid> {
@for (int i = 0; i < 5; i++) <h1 style="text-align:center;">Component Example page</h1>
{
int num = i; <ul>
<GridRow> <li><Link Class="m-1" Url="modal" Text="Modal dialog" Target="Target.Self" /></li>
<GridRowContent> <li><Link Class="m-1" Url="button" Text="Button" Target="Target.Self" /></li>
Fixed content @num.ToString() <li><Link Class="m-1" Url="datepicker" Text="Date picker" Target="Target.Self" /></li>
</GridRowContent> <li><Link Class="m-1" Url="datagrid" Text="Data Grid" Target="Target.Self" /></li>
<GridRowContent Collapsable=true> </ul>
Collapsable content @num.ToString() } else
</GridRowContent> {
</GridRow> <h3>Loading...</h3>
} }
</Grid>
<p>Izbran datum je: @date</p>
<FormWizard Id="Wizard1">
<FormWizardStep Name="Step1">
Step1
</FormWizardStep>
<FormWizardStep Name="Step2">
Step2
</FormWizardStep>
<FormWizardStep Name="Step3">
Step3
</FormWizardStep>
<FormWizardStep Name="Step4">
Step4
</FormWizardStep>
</FormWizard>
<DatePicker @bind-SelectedDate=@date>
</DatePicker>
<NumberStepper @bind-Value=number ></NumberStepper>
<Button OnClick="ChangeErrorText" >Error text</Button>
<NumberInput @bind-Value=@dnumber Step=0.03 DecimalPlaces=2 HelperText="Helper text" ErrorText="@ErrorText" Clearable=true></NumberInput>
<p>Selected date is @date.ToString()</p>
<p>Number is: @number.ToString()</p>
<p>DNumber is: @dnumber.ToString()</p>
@code { @code {
DateTime date = DateTime.Today; bool loaded = false;
double dnumber = 0;
int number = 0;
string ErrorText = "";
public void ChangeErrorText() protected override void OnInitialized()
{ {
if (string.IsNullOrEmpty(ErrorText)) loaded=true;
ErrorText = "Test string: Error has ocurred!"; StateHasChanged();
else
ErrorText = string.Empty;
//StateHasChanged();
} }
} }

@ -0,0 +1,67 @@
namespace Connected.Classes.Grid;
public class DataGridOptions
{
/// <summary>
/// Determine if images will be shown inside the row. If row has no image then it is ignored
/// </summary>
public bool ShowImage = true;
public SmScrn_GridImgPos ImagePosition = SmScrn_GridImgPos.Left;
public bool Collapsible = true;
public bool Dense = true;
public bool ShowSelect = true;
public int ItemsPerPage = 10;
public int SelectedPage = 1;
public string DataSet_ImgColName = string.Empty;
public int Offset
{
get
{
return (SelectedPage - 1) * ItemsPerPage;
}
}
public DataGridOptions()
{
ShowImage = false;
ImagePosition = SmScrn_GridImgPos.Left;
Collapsible = true;
Dense = true;
ShowSelect = true;
ItemsPerPage = 10;
SelectedPage = 1;
DataSet_ImgColName = string.Empty;
}
public DataGridOptions(DataGridOptions options)
{
ShowImage = options.ShowImage;
ImagePosition = options.ImagePosition;
Collapsible = options.Collapsible;
Dense = options.Dense;
ShowSelect = options.ShowSelect;
ItemsPerPage = options.ItemsPerPage;
SelectedPage = options.SelectedPage;
DataSet_ImgColName = options.DataSet_ImgColName;
}
public DataGridOptions(
bool ShowImage = false,
SmScrn_GridImgPos ImagePosition = SmScrn_GridImgPos.Left,
bool Collapsible = true,
bool Dense = true,
bool ShowSelect = true,
int ItemsPerPage = 10,
int SelectedPage = 1,
string DataSet_ImgColName = "")
{
this.ShowImage = ShowImage;
this.ImagePosition = ImagePosition;
this.Collapsible = Collapsible;
this.Dense = Dense;
this.ShowSelect = ShowSelect;
this.ItemsPerPage = ItemsPerPage;
this.SelectedPage = SelectedPage;
this.DataSet_ImgColName = DataSet_ImgColName;
}
}

@ -1,5 +1,18 @@
<CascadingValue Value="this"> @attribute [CascadingTypeParameter(nameof(DataType))]
<div class="@GridClass"> @typeparam DataType
@ChildContent
<CascadingValue Value="this">
<div class="@GridClassList.ToString()">
@foreach (var Item in ItemsToShow)
{
<GridRow DataType="DataType" Item="@Item" ImgSrc="" >
<FixedContent>
@RowTemplate(Item)
</FixedContent>
<CollapsibleContent>
@RowDetailTemplate(Item)
</CollapsibleContent>
</GridRow>
}
</div> </div>
</CascadingValue> </CascadingValue>

@ -1,40 +1,78 @@
using Connected.Utilities; using Connected.Classes.Grid;
using Connected.Utilities;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using System.Collections.ObjectModel;
namespace Connected.Components; namespace Connected.Components;
public partial class Grid: ComponentBase public partial class Grid<DataType> : ComponentBase
{ {
public List<GridRow> Rows { get; set; } = new();
[Parameter] [Parameter]
public RenderFragment? ChildContent { get; set; } public ObservableCollection<DataType>? Items { get; set; }
[Parameter] private List<DataType>? ItemsToShow { get; set; }
public bool Dense { get; set; } = true;
[Parameter] [Parameter]
public bool ContainsImage { get; set; } = true; public RenderFragment<DataType>? RowTemplate { get; set; }
[Parameter] [Parameter]
public bool ShowSelect { get; set; } = true; public RenderFragment<DataType>? RowDetailTemplate { get; set; }
[Parameter]
public RenderFragment? Img { get; set; }
[Parameter] [Parameter]
public bool Collapsable { get; set; } = true; public DataGridOptions? Options { get; set; } = null;
[Parameter] [Parameter]
public string Class { get; set; } = string.Empty; public List<string>? SearchFilters { get; set; } = null;
private string GridClass public int Count
{
get
{
return Items?.Count ?? 0;
}
}
[Parameter]
public string GridClass { get; set; } = string.Empty;
private CssBuilder GridClassList
{ {
get get
{ {
return new CssBuilder("data-grid") return new CssBuilder("data-grid")
.AddClass("dense", Dense) .AddClass("dense", Options?.Dense ?? true)
.AddClass("image", ContainsImage) .AddClass("image", Options?.ShowImage ?? true)
.AddClass("select", ShowSelect) .AddClass("select", Options?.ShowSelect ?? true)
.AddClass("collapse", Collapsable) .AddClass("collapse", Options?.Collapsible ?? true)
.AddClass(Class) .AddClass(GridClass);
.Build();
} }
} }
public void GetItems()
{
/*
Web API call for item fetch include SearchFilters
*/
SetItemsToShow();
}
private void OnPageChange(int page)
{
Options.SelectedPage=page;
//SetItemsToShow();
}
private void SetItemsToShow()
{
ItemsToShow= Items?.Skip(Options.Offset).Take(Options.ItemsPerPage).ToList() ?? new();
}
protected override async Task OnInitializedAsync()
{
SetItemsToShow();
await base.OnInitializedAsync();
}
} }

@ -1,19 +1,32 @@
<CascadingValue Value="this"> @typeparam DataType
<div class="@GridRowClass" id="@Guid.NewGuid()">
<div class="data-grid-select" > <CascadingValue Value="this">
<div class="@GridRowClass.ToString()" id="@Guid.NewGuid()">
<div class="data-grid-select">
<label class="toggle-group m-0" for="@SwitchButtonId"> <label class="toggle-group m-0" for="@SwitchButtonId">
<input class="toggle-input" id="@SwitchButtonId" name="toggle" type="checkbox" @onchange="(args=>SwitchButtonChange(args))"> <input class="toggle-input" id="@SwitchButtonId" name="toggle" type="checkbox" @onchange="(args=>SwitchButtonChange(args))">
<div class="toggle-fill"></div> <div class="toggle-fill"></div>
</label> </label>
</div> </div>
<div class="data-grid-img"> <div class="data-grid-container @ImageClass.ToString()">
<img class="img-fluid" src="https://source.unsplash.com/random?face" /> @if (ShowImageBlock())
</div> {
<div class="data-grid-img"><img class="img-fluid" src="@ImgSrc" /></div>
}
<div class="data-grid-wrapper">
<!-- Nova verzija-->
<div class="row">
<!-- Fiksna vsebina -->
@FixedContent(Item)
</div>
<div class="row collapsed @CollapsedClass.ToString()">
@CollapsibleContent(Item)
</div>
<!-- Row content --> </div>
<div class="data-grid-container">
@ChildContent
</div> </div>
<div class="data-grid-collapse-cta" @onclick="ToggleNav"> <div class="data-grid-collapse-cta" @onclick="ToggleNav">

@ -2,16 +2,23 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace Connected.Components; namespace Connected.Components;
public partial class GridRow : ComponentBase public partial class GridRow<DataType> : ComponentBase
{ {
[CascadingParameter] [CascadingParameter]
public Grid Parent { get; set; } public Grid<DataType> Parent { get; set; }
public List<GridRowContent> Children { get; set; } [Parameter]
public RenderFragment<DataType>? FixedContent { get; set; }
[Parameter]
public RenderFragment<DataType>? CollapsibleContent { get; set; }
[Parameter] [Parameter]
public RenderFragment? ChildContent { get; set; } public string? ImgSrc { get; set; } = null;
[Parameter]
public DataType? Item { get; set; }
[Parameter] [Parameter]
public bool CollapsedItemShown { get; set; } = false; public bool CollapsedItemShown { get; set; } = false;
@ -22,19 +29,43 @@ public partial class GridRow : ComponentBase
} }
[Parameter] [Parameter]
public string Class { get; set; } = string.Empty; public string RowClass { get; set; } = string.Empty;
private CssBuilder GridRowClass
{
get
{
return new CssBuilder("data-grid-row-content")
.AddClass("show", CollapsedItemShown)
.AddClass(RowClass);
}
}
[Parameter] private CssBuilder CollapsedClass
public GridRowTemplate? Template { get; set; } = null; {
get
{
return new CssBuilder()
.AddClass("show", CollapsedItemShown)
.AddClass(RowClass);
}
}
private string GridRowClass private bool ShowImageBlock()
{
if (string.IsNullOrEmpty(ImgSrc)) return false;
bool result = Parent.Options?.ShowImage ?? true;
return result;
}
private CssBuilder ImageClass
{ {
get get
{ {
return new CssBuilder("data-grid-row-content") return new CssBuilder()
.AddClass("show",CollapsedItemShown) .AddClass("show-image-vertical", Parent.Options.ImagePosition==SmScrn_GridImgPos.Top)
.AddClass(Class) .AddClass("show-image", Parent.Options.ImagePosition == SmScrn_GridImgPos.Left)
.Build();
.AddClass(RowClass);
} }
} }
@ -46,13 +77,19 @@ public partial class GridRow : ComponentBase
await SwitchButtonChangeEvent.InvokeAsync(args); await SwitchButtonChangeEvent.InvokeAsync(args);
} }
private string SwitchButtonId = Guid.NewGuid().ToString(); private void SetImgSrc()
{
var colname = Parent.Options.DataSet_ImgColName;
var property = typeof(DataType).GetProperty(colname);
ImgSrc = property?.GetValue(Item)?.ToString() ?? "";
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
if (Parent.Rows is null) Parent.Rows = new(); SetImgSrc();
Parent.Rows.Add(this);
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
private string SwitchButtonId = Guid.NewGuid().ToString();
} }

@ -1,3 +0,0 @@
<div class="@GeneratedRowContentClass">
@ChildContent
</div>

@ -1,53 +0,0 @@
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
namespace Connected.Components;
public partial class GridRowContent : ComponentBase
{
[CascadingParameter]
public GridRow? Parent { get; set; }
/// <summary>
/// Text shown inside the button
/// Options: any string variable
/// Default: string.Empty
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }
/// <summary>
/// Disabled or enabled.
/// Default: false
/// </summary>
[Parameter]
public bool Collapsable { get; set; } = false;
private string GeneratedRowContentClass
{
get
{
CssBuilder cssBuilder = new CssBuilder("row");
cssBuilder.AddClass("collapsed", Collapsable);
if (Parent is not null)
{
cssBuilder.AddClass("show", (Collapsable ? Parent.CollapsedItemShown : false));
}
return cssBuilder.Build();
}
}
protected override async Task OnInitializedAsync()
{
if (Parent is not null)
{
if (Parent.Children is null) Parent.Children = new();
Parent.Children.Add(this);
}
await base.OnInitializedAsync();
}
}

@ -15,3 +15,9 @@ public enum Position
Start, Start,
End End
} }
public enum SmScrn_GridImgPos
{
Top,
Left,
}

Loading…
Cancel
Save