Update button rendering, move css classes to viewdata
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
|
||||||
|
namespace LeafWeb.WebCms.Utility
|
||||||
|
{
|
||||||
|
public static class CssClassUtil
|
||||||
|
{
|
||||||
|
private const string KeyName = "cssClass";
|
||||||
|
public static ViewDataDictionary CreateCssClassDataDictionary(params string[] cssClasses)
|
||||||
|
=> new ViewDataDictionary { { KeyName, cssClasses.ToArray() } };
|
||||||
|
|
||||||
|
public static void AddCssClass(this ViewDataDictionary vdd, string cssClass)
|
||||||
|
{
|
||||||
|
if (!vdd.ContainsKey(KeyName))
|
||||||
|
vdd["cssClass"] = new []{ cssClass };
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var cssClassList = ((string[])vdd[KeyName]).ToList();
|
||||||
|
if (!cssClassList.Contains(cssClass))
|
||||||
|
cssClassList.Add(cssClass);
|
||||||
|
vdd[KeyName] = cssClassList.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetButtonDisabled(this ViewDataDictionary vdd)
|
||||||
|
{
|
||||||
|
vdd.AddCssClass("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsButtonDisabled(this ViewDataDictionary vdd)
|
||||||
|
{
|
||||||
|
return vdd.ContainsKey(KeyName) && ((string[]) vdd[KeyName]).Contains("disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
@using LeafWeb.WebCms.Controllers
|
@using LeafWeb.WebCms.Controllers
|
||||||
|
@using LeafWeb.WebCms.Utility
|
||||||
@model LeafInputDetails
|
@model LeafInputDetails
|
||||||
|
|
||||||
<div class="row pb-3">
|
<div class="row pb-3">
|
||||||
@Html.Partial("DisplayTemplates/_ChartButton", Model.LeafInputId, new ViewDataDictionary {{"Disabled", !Model.HasLeafChart}})
|
|
||||||
|
@ChartLink(Model)
|
||||||
|
|
||||||
<div class="dropdown pl-3">
|
<div class="dropdown pl-3">
|
||||||
<button class="btn btn-outline-secondary dropdown-toggle" id="downloadButton"
|
<button class="btn btn-outline-secondary dropdown-toggle" id="downloadButton"
|
||||||
@@ -64,12 +66,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@helper ChartLink(dynamic item)
|
||||||
|
{
|
||||||
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("btn", "btn-outline-secondary");
|
||||||
|
|
||||||
|
if (!item.HasLeafChart)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
@Html.Partial("DisplayTemplates/_ChartLink", (int)item.LeafInputId, cssClass)
|
||||||
|
}
|
||||||
|
|
||||||
@helper DeleteLink(LeafInputDetails item)
|
@helper DeleteLink(LeafInputDetails item)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_DeleteForm", Tuple.Create(item.LeafInputId, item.Identifier, item.IsDeletable, false))
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("btn", "btn-outline-secondary");
|
||||||
|
if (!item.IsDeletable)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Html.Partial("DisplayTemplates/_DeleteForm", Tuple.Create(item.LeafInputId, item.Identifier), cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper CancelLink(LeafInputDetails item)
|
@helper CancelLink(LeafInputDetails item)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_CancelForm", Tuple.Create(item.LeafInputId, item.Identifier, false))
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("btn", "btn-outline-secondary");
|
||||||
|
if (!item.IsCancellable)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
@Html.Partial("DisplayTemplates/_CancelForm", Tuple.Create(item.LeafInputId, item.Identifier), cssClass)
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
@using ClientDependency.Core.Mvc
|
@using ClientDependency.Core.Mvc
|
||||||
@using LeafWeb.Core.Entities
|
@using LeafWeb.Core.Entities
|
||||||
@using LeafWeb.WebCms.Controllers
|
@using LeafWeb.WebCms.Utility
|
||||||
@model QueueViewModel
|
@model QueueViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
@@ -129,9 +129,9 @@ else
|
|||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<h6 class="dropdown-header">Download</h6>
|
<h6 class="dropdown-header">Download</h6>
|
||||||
@DownloadInput(item)
|
@DownloadInput(item)
|
||||||
<button class="dropdown-item @DisableItem(!item.HasOutputFiles)">@DownloadOutputToUser(item)</button>
|
@DownloadOutputToUser(item)
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<button class="dropdown-item @DisableItem(!item.IsDeletable)">@DeleteLink(item)</button>
|
@DeleteLink(item)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -139,17 +139,20 @@ else
|
|||||||
|
|
||||||
@helper DetailsLink(dynamic item)
|
@helper DetailsLink(dynamic item)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_DetailsLink", (int)item.Id, new ViewDataDictionary {{"cssClass", new[]{"dropdown-item"}}})
|
var cssClass= CssClassUtil.CreateCssClassDataDictionary("dropdown-item");
|
||||||
|
|
||||||
|
@Html.Partial("DisplayTemplates/_DetailsLink", (int)item.Id, cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper ChartLink(dynamic item)
|
@helper ChartLink(dynamic item)
|
||||||
{
|
{
|
||||||
var classes = new[]{"dropdown-item"};
|
var cssClass= CssClassUtil.CreateCssClassDataDictionary("dropdown-item");
|
||||||
|
|
||||||
if (!item.HasLeafChart)
|
if (!item.HasLeafChart)
|
||||||
{
|
{
|
||||||
classes = classes.Concat(new[] {"disabled"}).ToArray();
|
cssClass.SetButtonDisabled();
|
||||||
}
|
}
|
||||||
@Html.Partial("DisplayTemplates/_ChartLink", (int)item.Id, new ViewDataDictionary {{"cssClass", classes}})
|
@Html.Partial("DisplayTemplates/_ChartLink", (int)item.Id, cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper DownloadInput(dynamic item)
|
@helper DownloadInput(dynamic item)
|
||||||
@@ -160,7 +163,7 @@ else
|
|||||||
}
|
}
|
||||||
@helper DownloadOutputToUser(dynamic item)
|
@helper DownloadOutputToUser(dynamic item)
|
||||||
{
|
{
|
||||||
<a href="@Url.Action("DownloadOutputToUser", "Queue", new {id = item.Id})" class="dropdown-item">
|
<a href="@Url.Action("DownloadOutputToUser", "Queue", new {id = item.Id})" class="dropdown-item @DisableItem(!item.HasOutputFiles)">
|
||||||
<span class="fa fa-download"></span> ToUser
|
<span class="fa fa-download"></span> ToUser
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@@ -177,7 +180,10 @@ else
|
|||||||
}
|
}
|
||||||
var summaryText = string.Join(Environment.NewLine, summary);
|
var summaryText = string.Join(Environment.NewLine, summary);
|
||||||
<span class="text-nowrap" title="@summaryText">
|
<span class="text-nowrap" title="@summaryText">
|
||||||
<i class="fa fa-file-o"></i> @leafInput.InputFiles.Count @if(leafInput.InputFiles.Count > 1) {<text>inputs</text>} else { <text>input</text>}
|
<i class="fa fa-file-o"></i> @leafInput.InputFiles.Count @if (leafInput.InputFiles.Count > 1)
|
||||||
|
{<text>inputs</text>}
|
||||||
|
else
|
||||||
|
{ <text>input</text>}
|
||||||
<br />
|
<br />
|
||||||
@if (leafInput.TimeInProgress > TimeSpan.Zero)
|
@if (leafInput.TimeInProgress > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
@@ -202,20 +208,36 @@ else
|
|||||||
}
|
}
|
||||||
@helper DeleteLink(LeafInput item)
|
@helper DeleteLink(LeafInput item)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_DeleteForm", Tuple.Create(item.Id, item.Identifier, item.IsDeletable, true), new ViewDataDictionary {{"cssClass", new[]{"dropdown-item"}}})
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("dropdown-item");
|
||||||
|
if (!item.IsDeletable)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
@Html.Partial("DisplayTemplates/_DeleteForm", Tuple.Create(item.Id, item.Identifier), cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper CancelLink(LeafInput item)
|
@helper CancelLink(LeafInput item)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_CancelForm", Tuple.Create(item.Id, item.Identifier, true), new ViewDataDictionary {{"cssClass", new[]{"dropdown-item"}}})
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("dropdown-item");
|
||||||
|
if (!item.IsCancellable)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
@Html.Partial("DisplayTemplates/_CancelForm", Tuple.Create(item.Id, item.Identifier), cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper PriorityForm(LeafInput item, Priority priority)
|
@helper PriorityForm(LeafInput item, Priority priority)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_PriorityForm", Tuple.Create(item.Id, item.PendingPriority, priority), new ViewDataDictionary {{"cssClass", new[]{"dropdown-item"}}})
|
var cssClass
|
||||||
|
= CssClassUtil.CreateCssClassDataDictionary("dropdown-item");
|
||||||
|
|
||||||
|
@Html.Partial("DisplayTemplates/_PriorityForm", Tuple.Create(item.Id, item.PendingPriority, priority), cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper DisableItem(bool disabled)
|
@helper DisableItem(bool disabled)
|
||||||
{
|
{
|
||||||
if (disabled){<text>disabled</text>}
|
if (disabled)
|
||||||
|
{<text>disabled</text>}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
@using LeafWeb.Core.Entities
|
@using LeafWeb.Core.Entities
|
||||||
|
@using LeafWeb.WebCms.Utility
|
||||||
@model IQueryable<LeafInput>
|
@model IQueryable<LeafInput>
|
||||||
|
|
||||||
@{
|
@{
|
||||||
var grid = new WebGrid(Model, rowsPerPage: 45);
|
var grid = new WebGrid(Model, rowsPerPage: 45);
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,12 @@
|
|||||||
|
|
||||||
@helper ChartLink(LeafInput leafInput)
|
@helper ChartLink(LeafInput leafInput)
|
||||||
{
|
{
|
||||||
@Html.Partial("DisplayTemplates/_ChartButton", leafInput.Id, new ViewDataDictionary { { "Disabled", !leafInput.HasLeafChart }, {"xs", true} })
|
var cssClass = CssClassUtil.CreateCssClassDataDictionary("btn", " btn-outline-secondary", "btn-sm");
|
||||||
|
if (!leafInput.HasLeafChart)
|
||||||
|
{
|
||||||
|
cssClass.SetButtonDisabled();
|
||||||
|
}
|
||||||
|
@Html.Partial("DisplayTemplates/_ChartButton", leafInput.Id, cssClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
@helper Status(LeafInput leafInput)
|
@helper Status(LeafInput leafInput)
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
@model IEnumerable<LeafInputDataSiteViewModel>
|
@model IEnumerable<LeafInputDataSiteViewModel>
|
||||||
@{
|
@{
|
||||||
Layout = "~/Views/Shared/DisplayTemplates/_FieldLayout.cshtml";
|
//Layout = "~/Views/Shared/DisplayTemplates/_FieldLayout.cshtml";
|
||||||
var grid = new WebGrid(Model, rowsPerPage: 45)
|
Rend("Site Id", string.Join(", ", Model.Select(m => m.SiteId).Distinct()));
|
||||||
{
|
Rend("Latitude", string.Join(", ", Model.Select(m => m.Latitude).Distinct()));
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@grid.GetHtml(columns:
|
@helper Rend(string label, string value)
|
||||||
|
{
|
||||||
|
<div class="row pb-lg-2 pb-sm-1 @if (ViewData.Model == null){<text>d-none</text> }">
|
||||||
|
<div class="col-sm-3 text-truncate">
|
||||||
|
@label
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
@value
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@*@grid.GetHtml(columns:
|
||||||
grid.Columns(
|
grid.Columns(
|
||||||
grid.Column("SiteId"),
|
grid.Column("SiteId"),
|
||||||
grid.Column("Latitude"),
|
grid.Column("Latitude"),
|
||||||
@@ -14,4 +26,4 @@
|
|||||||
grid.Column("Elevation")
|
grid.Column("Elevation")
|
||||||
),
|
),
|
||||||
htmlAttributes: new { @class = "table table-sm table-striped table-bordered table-hover" }
|
htmlAttributes: new { @class = "table table-sm table-striped table-bordered table-hover" }
|
||||||
)
|
)*@
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
@using LeafWeb.WebCms.Controllers
|
@using LeafWeb.WebCms.Controllers
|
||||||
@model Tuple<int, string, bool>
|
@using LeafWeb.WebCms.Utility
|
||||||
|
@model Tuple<int, string>
|
||||||
@{
|
@{
|
||||||
var leafInputId = Model.Item1;
|
var leafInputId = Model.Item1;
|
||||||
var identifier = Model.Item2;
|
var identifier = Model.Item2;
|
||||||
// true for a link, false for a button
|
|
||||||
var buttonType = Model.Item3 ? "btn-link" : "btn-outline-secondary";
|
|
||||||
}
|
}
|
||||||
@using (Html.BeginUmbracoForm<QueueController>("Cancel", null,
|
@using (Html.BeginUmbracoForm<QueueController>("Cancel", null,
|
||||||
new { @class = "confirm clearfix", confirm_msg = "Cancelling cannot be undone! Confirm cancelling '" + identifier + "'." }))
|
new { @class = "confirm clearfix", confirm_msg = "Cancelling cannot be undone! Confirm cancelling '" + identifier + "'." }))
|
||||||
{
|
{
|
||||||
<input type="hidden" name="id" value="@leafInputId"/>
|
<input type="hidden" name="id" value="@leafInputId"/>
|
||||||
<button type="submit" class="btn @buttonType">
|
<button type="submit" @Html.Partial("DisplayTemplates/_ViewDataCssClass") @if(ViewData.IsButtonDisabled()) {<text>disabled</text>}>
|
||||||
<span class="fa fa-ban"></span> Cancel
|
<span class="fa fa-ban"></span> Cancel
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
@using LeafWeb.WebCms.Controllers
|
@using LeafWeb.WebCms.Controllers
|
||||||
|
@using LeafWeb.WebCms.Utility
|
||||||
@model int
|
@model int
|
||||||
@{
|
@{
|
||||||
var url = UmbracoContext.Current.UrlProvider.GetUrl(LeafWebPageIds.Chart);
|
var url = UmbracoContext.Current.UrlProvider.GetUrl(LeafWebPageIds.Chart);
|
||||||
var disabled = ViewData.ContainsKey("Disabled") && (bool) ViewData["Disabled"];
|
|
||||||
var xs = ViewData.ContainsKey("xs") && (bool) ViewData["xs"];
|
|
||||||
}
|
}
|
||||||
<a href="@url?leafInputId=@Model"
|
<a href="@url?leafInputId=@Model" @Html.Partial("DisplayTemplates/_ViewDataCssClass") role="button"
|
||||||
class="btn btn-outline-secondary @{if (xs) {<text>btn-sm</text>}} @{if (disabled) {<text>disabled</text>}}"
|
@if (ViewData.IsCssDisabled()) {<text>title="No chart has been generated"</text>} >
|
||||||
role="button"
|
|
||||||
@{if (disabled) {<text>title="No chart has been generated"</text>}} >
|
|
||||||
<span class="fa fa-line-chart" title="Charts"></span>
|
<span class="fa fa-line-chart" title="Charts"></span>
|
||||||
<span class="d-none d-sm-inline">Charts</span>
|
<span class="d-none d-sm-inline">Charts</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
@{
|
@{
|
||||||
var url = UmbracoContext.Current.UrlProvider.GetUrl(LeafWebPageIds.Chart);
|
var url = UmbracoContext.Current.UrlProvider.GetUrl(LeafWebPageIds.Chart);
|
||||||
}
|
}
|
||||||
<a href="@url?leafInputId=@Model" @Html.Partial("DisplayTemplates/_ViewDataCssClass", new [] {"dropdown-item"}, ViewData)>
|
<a href="@url?leafInputId=@Model" @Html.Partial("DisplayTemplates/_ViewDataCssClass")>
|
||||||
<span class="fa fa-line-chart"></span>
|
<span class="fa fa-line-chart"></span> Charts
|
||||||
Chart
|
|
||||||
</a>
|
</a>
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
@using LeafWeb.WebCms.Controllers
|
@using LeafWeb.WebCms.Controllers
|
||||||
@model Tuple<int, string, bool, bool>
|
@using LeafWeb.WebCms.Utility
|
||||||
|
@model Tuple<int, string>
|
||||||
@{
|
@{
|
||||||
var leafInputId = Model.Item1;
|
var leafInputId = Model.Item1;
|
||||||
var identifier = Model.Item2;
|
var identifier = Model.Item2;
|
||||||
var isDeletable = Model.Item3;
|
|
||||||
// true for a link, false for a button
|
|
||||||
var buttonType = Model.Item4 ? "btn-link" : "btn-outline-secondary";
|
|
||||||
}
|
}
|
||||||
@using (Html.BeginUmbracoForm<QueueController>("Delete", null,
|
@using (Html.BeginUmbracoForm<QueueController>("Delete", null,
|
||||||
new { @class = "confirm clearfix", confirm_msg = "Deletion cannot be undone! Confirm deleting '" + identifier + "'." }))
|
new { @class = "confirm clearfix", confirm_msg = "Deletion cannot be undone! Confirm deleting '" + identifier + "'." }))
|
||||||
{
|
{
|
||||||
<input type="hidden" name="id" value="@leafInputId"/>
|
<input type="hidden" name="id" value="@leafInputId"/>
|
||||||
<button type="submit" class="btn @buttonType" @{if (!isDeletable) { <text> disabled="disabled" </text> }}>
|
<button type="submit" @Html.Partial("DisplayTemplates/_ViewDataCssClass") @if(ViewData.IsButtonDisabled()) {<text>disabled</text>}>
|
||||||
<span class="fa fa-remove"></span> Delete
|
<span class="fa fa-remove"></span> Delete
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
@using LeafWeb.Core.Utility
|
@using LeafWeb.Core.Utility
|
||||||
@{
|
@{
|
||||||
Layout = null;
|
Layout = null;
|
||||||
var lowerPropertyName = ViewData.ModelMetadata.PropertyName.ToFirstLower();
|
var meta = ViewData.ModelMetadata;
|
||||||
|
var lowerPropertyName = meta.PropertyName.ToFirstLower();
|
||||||
var displayName =
|
var displayName =
|
||||||
string.IsNullOrEmpty(ViewData.ModelMetadata.DisplayName)
|
string.IsNullOrEmpty(meta.DisplayName)
|
||||||
? ViewData.ModelMetadata.PropertyName.SplitCamelCase()
|
? meta.PropertyName.SplitCamelCase()
|
||||||
: ViewData.ModelMetadata.DisplayName;
|
: meta.DisplayName;
|
||||||
|
|
||||||
// string units = (string)ViewData.ModelMetadata.AdditionalValues.ContainsKey("Units") ? ["Units"];
|
// string units = (string)ViewData.ModelMetadata.AdditionalValues.ContainsKey("Units") ? ["Units"];
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="row @lowerPropertyName @if (ViewData.Model == null){<text>d-none</text> }">
|
<div class="row pb-lg-3 pb-2 @lowerPropertyName @if (ViewData.Model == null){<text>d-none</text> }">
|
||||||
<div class="col-sm-3 text-truncate">
|
<div class="col-sm-3 text-truncate font-weight-bold border-bottom border-right">
|
||||||
@displayName
|
@displayName
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9 border-bottom pl-5 pl-sm-2">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1133,6 +1133,7 @@
|
|||||||
<Compile Include="Utility\QueryFilter.cs" />
|
<Compile Include="Utility\QueryFilter.cs" />
|
||||||
<Compile Include="Utility\RequireRequestValueAttribute.cs" />
|
<Compile Include="Utility\RequireRequestValueAttribute.cs" />
|
||||||
<Compile Include="Utility\Validation.cs" />
|
<Compile Include="Utility\Validation.cs" />
|
||||||
|
<Compile Include="Utility\CssClassUtil.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Core.csproj">
|
<ProjectReference Include="..\Core\Core.csproj">
|
||||||
|
|||||||
Reference in New Issue
Block a user