mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 15:20:48 -05:00
add "advanced" search functionality
This commit is contained in:
39
WebfrontCore/Views/Client/Find/AdvancedFind.cshtml
Normal file
39
WebfrontCore/Views/Client/Find/AdvancedFind.cshtml
Normal file
@ -0,0 +1,39 @@
|
||||
@model IEnumerable<WebfrontCore.QueryHelpers.Models.ClientResourceResponse>
|
||||
@{
|
||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||
}
|
||||
|
||||
<div class="content mt-0">
|
||||
<h2 class="content-title mt-20">@loc["WEBFRONT_SEARCH_RESULTS_TITLE"]</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="bg-primary text-light d-none d-md-table-row">
|
||||
<td>@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_NAME_FULL"]</td>
|
||||
<td>@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_IP"]</td>
|
||||
<td>@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_COUNTRY"]</td>
|
||||
<td>@loc["WEBFRONT_PROFILE_LEVEL"]</td>
|
||||
<td>@loc["WEBFRONT_ADVANCED_SEARCH_LABEL_GAME"]</td>
|
||||
<td class="text-right">@loc["WEBFRONT_SEARCH_LAST_CONNECTED"]</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="searchResultContainer">
|
||||
<partial name="Find/_AdvancedFindList" model="@Model"/>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="text-center">
|
||||
<i id="loaderLoad" class="oi oi-chevron-bottom loader-load-more text-primary" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section scripts {
|
||||
<script>
|
||||
initLoader('/Client/AdvancedFind', '#searchResultContainer', 30, 30, () => {
|
||||
return $('#advancedSearchDropdownContentFullDesktop').serializeArray()
|
||||
|| $('#advancedSearchDropdownContentCompactDesktop').serializeArray()
|
||||
|| $('#advancedSearchDropdownContentFullMobile').serializeArray()
|
||||
|| $('#advancedSearchDropdownContentCompactMobile').serializeArray()
|
||||
});
|
||||
</script>
|
||||
}
|
107
WebfrontCore/Views/Client/Find/_AdvancedFindContent.cshtml
Normal file
107
WebfrontCore/Views/Client/Find/_AdvancedFindContent.cshtml
Normal file
@ -0,0 +1,107 @@
|
||||
@using WebfrontCore.QueryHelpers.Models
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@using WebfrontCore.Permissions
|
||||
@using Data.Models.Client
|
||||
@model WebfrontCore.QueryHelpers.Models.ClientResourceResponse
|
||||
|
||||
@{
|
||||
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||
var client = Model;
|
||||
|
||||
string FormatNameChange(ClientResourceResponse clientResponse)
|
||||
{
|
||||
return clientResponse.CurrentClientName.StripColors() != clientResponse.MatchedClientName?.StripColors()
|
||||
? $"{clientResponse.CurrentClientName} [{clientResponse.MatchedClientName}{(clientResponse.MatchedClientIp is null && clientResponse.MatchedClientIp != clientResponse.CurrentClientIp ? "" : $"/{clientResponse.MatchedClientIp.ConvertIPtoString()}")}]"
|
||||
: clientResponse.CurrentClientName;
|
||||
}
|
||||
|
||||
var canSeeLevel = (ViewBag.PermissionsSet as IEnumerable<string>).HasPermission(WebfrontEntity.ClientLevel, WebfrontPermission.Read);
|
||||
var canSeeIp = (ViewBag.PermissionsSet as IEnumerable<string>).HasPermission(WebfrontEntity.ClientIPAddress, WebfrontPermission.Read);
|
||||
string ClassForLevel(EFClient.Permission permission) => !canSeeLevel ? "level-color-user" : $"level-color-{permission.ToString().ToLower()}";
|
||||
string FormatIpForPermission(int? ip) => canSeeIp && ip is not null ? ip.ConvertIPtoString() : "-";
|
||||
}
|
||||
|
||||
<tr class="bg-dark-dm bg-light-lm d-none d-md-table-row">
|
||||
<td class="col-3">
|
||||
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId">
|
||||
<color-code value="@FormatNameChange(client)"></color-code>
|
||||
</a>
|
||||
</td>
|
||||
<td class="col-2">
|
||||
@FormatIpForPermission(client.CurrentClientIp)
|
||||
</td>
|
||||
<td class="col-2">
|
||||
<div class="d-flex">
|
||||
@if (string.IsNullOrEmpty(client.ClientCountryCode))
|
||||
{
|
||||
<div class="d-flex">
|
||||
<i class="oi oi-question-mark ml-5 mr-20"></i>
|
||||
<div class="font-size-12 font-weight-light">Unknown</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<img src="https://flagcdn.com/32x24/@(client.ClientCountryCode.ToLower()).png" class="mr-10 rounded align-self-center" alt="@client.ClientCountryDisplayName"/>
|
||||
}
|
||||
<div class="font-size-12 font-weight-light">@client.ClientCountryDisplayName</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="col-2 @ClassForLevel(client.ClientLevelValue)">@(canSeeLevel ? client.ClientLevel : "-")</td>
|
||||
<td>
|
||||
<div data-toggle="tooltip" data-title="@ViewBag.Localization["GAME_" + client.Game]">
|
||||
<span class="badge">@Utilities.MakeAbbreviation(ViewBag.Localization["GAME_" + client.Game])</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="col-3">
|
||||
<div class="float-right">
|
||||
<div data-toggle="tooltip" data-title="@client.LastConnection.ToShortDateString()" data-placement="left">
|
||||
<span class="text-muted">@client.LastConnection.HumanizeForCurrentCulture()</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="d-flex d-block d-md-none">
|
||||
<td class="bg-primary text-light w-half">
|
||||
<div class="pb-5">@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_NAME"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_ALIAS"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_IP"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_ADVANCED_SEARCH_CONTENT_TABLE_COUNTRY"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_PROFILE_LEVEL"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_ADVANCED_SEARCH_LABEL_GAME"]</div>
|
||||
<div class="pb-5">@loc["WEBFRONT_SEARCH_LAST_CONNECTED"]</div>
|
||||
</td>
|
||||
<td class="w-half bg-dark">
|
||||
<div class="pb-5">
|
||||
<a asp-controller="Client" asp-action="Profile" asp-route-id="@client.ClientId" class="no-decoration @ClassForLevel(client.ClientLevelValue)">
|
||||
<color-code value="@client.CurrentClientName"></color-code>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pb-5">
|
||||
<color-code value="@client.MatchedClientName"></color-code>
|
||||
@if (client.MatchedClientIp != client.CurrentClientIp)
|
||||
{
|
||||
<span>/ @client.MatchedClientIp.ConvertIPtoString()</span>
|
||||
}
|
||||
</div>
|
||||
<div class="text-muted pb-5">
|
||||
@FormatIpForPermission(client.CurrentClientIp)
|
||||
</div>
|
||||
<div class="d-flex pb-5">
|
||||
@if (string.IsNullOrEmpty(client.ClientCountryCode))
|
||||
{
|
||||
<div class="mr-5">Unknown</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="mr-5">@client.ClientCountryDisplayName</div>
|
||||
<img src="https://flagcdn.com/24x18/@(client.ClientCountryCode.ToLower()).png" class="rounded align-self-center" alt="@client.ClientCountryDisplayName"/>
|
||||
}
|
||||
</div>
|
||||
<div class="pb-5 @ClassForLevel(client.ClientLevelValue)">@(canSeeLevel ? client.ClientLevel : "-")</div>
|
||||
<div data-toggle="tooltip" data-title="@ViewBag.Localization["GAME_" + client.Game]">
|
||||
<span class="badge font-size-12 mt-5 mb-5">@Utilities.MakeAbbreviation(ViewBag.Localization["GAME_" + client.Game])</span>
|
||||
</div>
|
||||
<div class="text-muted pb-5">@client.LastConnection.HumanizeForCurrentCulture()</div>
|
||||
</td>
|
||||
</tr>
|
6
WebfrontCore/Views/Client/Find/_AdvancedFindList.cshtml
Normal file
6
WebfrontCore/Views/Client/Find/_AdvancedFindList.cshtml
Normal file
@ -0,0 +1,6 @@
|
||||
@model IEnumerable<WebfrontCore.QueryHelpers.Models.ClientResourceResponse>
|
||||
|
||||
@foreach (var client in Model)
|
||||
{
|
||||
<partial name="Find/_AdvancedFindContent" model="@client"/>
|
||||
}
|
125
WebfrontCore/Views/Shared/Partials/_SearchResourceFilter.cshtml
Normal file
125
WebfrontCore/Views/Shared/Partials/_SearchResourceFilter.cshtml
Normal file
@ -0,0 +1,125 @@
|
||||
@using Data.Models.Client
|
||||
@using SharedLibraryCore.Dtos
|
||||
@using WebfrontCore.QueryHelpers.Models
|
||||
@using Data.Models
|
||||
@model string
|
||||
@{
|
||||
var existingClientFilter = ViewBag.ClientResourceRequest as ClientResourceRequest;
|
||||
}
|
||||
<h6 class="dropdown-header">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_TITLE"]</h6>
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="dropdown-content">
|
||||
<form asp-controller="Client" asp-action="AdvancedFind" method="get" id="advancedSearchDropdownContent@(Model)" onsubmit="showLoader()">
|
||||
<div class="form-group">
|
||||
<label for="searchType@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_FOR"]</label>
|
||||
<br/>
|
||||
<select class="form-control" id="searchType@(Model)" name="searchType" disabled="disabled">
|
||||
<option value="client">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_SELECT_TYPE_PLAYERS"]</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientName@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_NAME"]</label>
|
||||
<div class="d-flex">
|
||||
<input type="text" class="form-control" name="clientName" id="clientName@(Model)"
|
||||
placeholder="Unknown Soldier" value="@existingClientFilter?.ClientName"/>
|
||||
<div class="custom-control ml-10 align-self-center">
|
||||
<div class="custom-switch">
|
||||
@if (existingClientFilter?.IsExactClientName ?? false)
|
||||
{
|
||||
<input type="checkbox" id="isExactClientName@(Model)" name="isExactClientName" value="true"
|
||||
checked="checked">
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="checkbox" id="isExactClientName@(Model)" name="isExactClientName" value="true">
|
||||
}
|
||||
<label for="isExactClientName@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_EXACT"]</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientIP@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_IP"]</label>
|
||||
<div class="d-flex">
|
||||
<input type="text" class="form-control" name="clientIP" id="clientIP@(Model)" placeholder="1.1.1.1"
|
||||
value="@existingClientFilter?.ClientIp">
|
||||
<div class="custom-control ml-10 align-self-center">
|
||||
<div class="custom-switch">
|
||||
@if (existingClientFilter?.IsExactClientIp ?? false)
|
||||
{
|
||||
<input type="checkbox" id="isExactClientIP@(Model)" name="isExactClientIP" value="true"
|
||||
checked="checked">
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="checkbox" id="isExactClientIP@(Model)" name="isExactClientIP" value="true">
|
||||
}
|
||||
<label for="isExactClientIP@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_EXACT"]</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientGuid@(Model)">GUID <span class="text-primary">•</span> XUID <span class="text-primary">•</span> NetworkID</label>
|
||||
<input type="text" class="form-control" name="clientGuid" id="clientGuid@(Model)"
|
||||
placeholder="110000100000001" value="@existingClientFilter?.ClientGuid"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientLevel@(Model)" class="w-half">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_PERMISSION"]</label>
|
||||
<label for="clientGameName@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_GAME"]</label>
|
||||
|
||||
<div class="d-flex">
|
||||
<select class="form-control w-half" id="clientLevel@(Model)" name="clientLevel">
|
||||
<option value="">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_SELECT_PERMISSIONS_ANY"]</option>
|
||||
@foreach (EFClient.Permission permission in Enum.GetValues(typeof(EFClient.Permission)))
|
||||
{
|
||||
<option value="@((int)permission)" selected="@(permission == existingClientFilter?.ClientLevel)">
|
||||
@permission.ToLocalizedLevelName()
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<select class="form-control w-half ml-10" id="clientGameName@(Model)" name="gameName">
|
||||
<option value="">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_SELECT_PERMISSIONS_ANY"]</option>
|
||||
@foreach (Reference.Game game in Enum.GetValues(typeof(Reference.Game)))
|
||||
{
|
||||
<option value="@((int)game)" selected="@(game == existingClientFilter?.GameName)">
|
||||
@ViewBag.Localization["GAME_" + game]
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="clientConnected@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_CONNECTED_SINCE"]</label>
|
||||
<div class="d-flex">
|
||||
@{ var oneYearAgo = DateTime.UtcNow.AddYears(-1).ToShortDateString(); }
|
||||
<input type="text" class="form-control date-picker-input w-half" name="clientConnected"
|
||||
id="clientConnected@(Model)" data-date="@oneYearAgo"
|
||||
value="@(existingClientFilter?.ClientConnected?.ToShortDateString() ?? oneYearAgo)"/>
|
||||
|
||||
<div class="custom-control ml-10 align-self-center">
|
||||
<div class="custom-switch">
|
||||
@if (existingClientFilter?.Direction is SortDirection.Descending)
|
||||
{
|
||||
<input type="checkbox" id="resultOrder@(Model)" name="direction"
|
||||
value="@((int)SortDirection.Ascending)">
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="checkbox" id="resultOrder@(Model)" name="direction"
|
||||
value="@((int)SortDirection.Ascending)" checked="checked">
|
||||
}
|
||||
<label for="resultOrder@(Model)">@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_LABEL_OLDEST_FIRST"]</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="@ViewBag.Localization["WEBFRONT_ADVANCED_SEARCH_BUTTON_SUBMIT"]"/>
|
||||
</form>
|
||||
</div>
|
@ -126,7 +126,7 @@
|
||||
<i class="oi oi-moon"></i>
|
||||
</div>
|
||||
<div class="d-none d-md-block ">
|
||||
<partial name="_SearchResourceForm"/>
|
||||
<partial name="_SearchResourceForm" model="@("Full")"/>
|
||||
</div>
|
||||
<div class="d-flex d-lg-none">
|
||||
<a href="#" onclick="halfmoon.toggleModal('contextMenuModal')">
|
||||
@ -158,6 +158,7 @@
|
||||
<script type="text/javascript" src="~/lib/moment-timezone/moment-timezone.js"></script>
|
||||
<script type="text/javascript" src="~/lib/chart.js/dist/Chart.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="~/lib/halfmoon/js/halfmoon.js"></script>
|
||||
<script type="text/javascript" src="~/lib/vanillajs-datepicker/dist/js/datepicker.js"></script>
|
||||
<script type="text/javascript" src="~/js/action.js"></script>
|
||||
<script type="text/javascript" src="~/js/loader.js"></script>
|
||||
<script type="text/javascript" src="~/js/search.js"></script>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="sidebar-menu list">
|
||||
<div class="sidebar-content m-0">
|
||||
<div class="pr-20 pl-20 mb-20 d-block d-lg-none">
|
||||
<partial name="_SearchResourceForm"/>
|
||||
<partial name="_SearchResourceForm" model="@("Compact")"/>
|
||||
</div>
|
||||
<span class="sidebar-title">@ViewBag.Localization["WEBFRONT_NAV_TITLE_MAIN"]</span>
|
||||
<div class="sidebar-divider"></div>
|
||||
|
@ -1,12 +1,40 @@
|
||||
<form class="form-inline ml-auto" method="get" asp-controller="Client" asp-action="Find">
|
||||
@model string
|
||||
<div class="ml-auto d-inline-flex w-full">
|
||||
<div class="input-group">
|
||||
<input id="client_search_mobile" name="clientName" class="form-control" type="text" placeholder="@ViewBag.Localization["WEBFRONT_NAV_SEARCH"]" required="required"/>
|
||||
<has-permission entity="AdvancedSearch" required-permission="Read">
|
||||
<div class="input-group-prepend dropdown with-arrow d-block d-md-none">
|
||||
<button class="btn" type="button" data-toggle="dropdown">
|
||||
<i class="oi oi-chevron-bottom"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu w-300">
|
||||
<partial name="Partials/_SearchResourceFilter" model="@(Model + "Mobile")"/>
|
||||
</div>
|
||||
</div>
|
||||
</has-permission>
|
||||
|
||||
<form asp-controller="Client" asp-action="AdvancedFind" method="get" asp-route-isLegacyQuery="true"
|
||||
id="basicSearchForm@(Model)" class="flex-fill">
|
||||
<input name="clientName" class="form-control" type="text"
|
||||
placeholder="@ViewBag.Localization["WEBFRONT_NAV_SEARCH"]" required="required"/>
|
||||
</form>
|
||||
|
||||
<has-permission entity="AdvancedSearch" required-permission="Read">
|
||||
<div class="input-group-append dropdown dropleft with-arrow d-md-block d-none">
|
||||
<button class="btn" type="button" data-toggle="dropdown">
|
||||
<i class="oi oi-chevron-bottom"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu w-400">
|
||||
<partial name="Partials/_SearchResourceFilter" model="@(Model + "Desktop")"/>
|
||||
</div>
|
||||
</div>
|
||||
</has-permission>
|
||||
|
||||
<div class="input-group-append">
|
||||
<button class="btn" type="submit">
|
||||
<button class="btn" form="basicSearchForm@(Model)" type="submit">
|
||||
<i class="oi oi-magnifying-glass"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
</form>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user