Updated to latest mooncore version. Cleaned up some crud controllers and replaced DataTable with the new DataGrid component
This commit is contained in:
@@ -24,9 +24,9 @@
|
||||
<PackageReference Include="Blazor-ApexCharts" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.8" />
|
||||
<PackageReference Include="MoonCore" Version="1.9.7" />
|
||||
<PackageReference Include="MoonCore" Version="1.9.9" />
|
||||
<PackageReference Include="MoonCore.Blazor" Version="1.3.1" />
|
||||
<PackageReference Include="MoonCore.Blazor.FlyonUi" Version="1.1.9" />
|
||||
<PackageReference Include="MoonCore.Blazor.FlyonUi" Version="1.2.2" />
|
||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -17,21 +17,14 @@ public class ThemeService
|
||||
ApiClient = apiClient;
|
||||
}
|
||||
|
||||
public async Task<PagedData<ThemeResponse>> Get(int page, int pageSize)
|
||||
{
|
||||
return await ApiClient.GetJson<PagedData<ThemeResponse>>(
|
||||
$"api/admin/system/customisation/themes?page={page}&pageSize={pageSize}"
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<ThemeResponse> Get(int id)
|
||||
public async Task<ThemeResponse> GetAsync(int id)
|
||||
{
|
||||
return await ApiClient.GetJson<ThemeResponse>(
|
||||
$"api/admin/system/customisation/themes/{id}"
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<ThemeResponse> Create(CreateThemeRequest request)
|
||||
public async Task<ThemeResponse> CreateAsync(CreateThemeRequest request)
|
||||
{
|
||||
return await ApiClient.PostJson<ThemeResponse>(
|
||||
"api/admin/system/customisation/themes",
|
||||
@@ -39,7 +32,7 @@ public class ThemeService
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<ThemeResponse> Update(int id, UpdateThemeRequest request)
|
||||
public async Task<ThemeResponse> UpdateAsync(int id, UpdateThemeRequest request)
|
||||
{
|
||||
return await ApiClient.PatchJson<ThemeResponse>(
|
||||
$"api/admin/system/customisation/themes/{id}",
|
||||
@@ -47,7 +40,7 @@ public class ThemeService
|
||||
);
|
||||
}
|
||||
|
||||
public async Task Delete(int id)
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
await ApiClient.Delete(
|
||||
$"api/admin/system/customisation/themes/{id}"
|
||||
|
||||
@@ -1,518 +0,0 @@
|
||||
!bg-base-100
|
||||
!border-base-content/40
|
||||
!border-none
|
||||
!flex
|
||||
!font-medium
|
||||
!font-semibold
|
||||
!h-2.5
|
||||
!justify-between
|
||||
!me-1.5
|
||||
!ms-auto
|
||||
!px-2.5
|
||||
!rounded-full
|
||||
!text-sm
|
||||
!w-2.5
|
||||
*:[grid-area:1/1]
|
||||
*:first:rounded-tl-lg
|
||||
*:last:rounded-tr-lg
|
||||
-left-4
|
||||
-ml-4
|
||||
-translate-x-full
|
||||
-translate-y-1/2
|
||||
absolute
|
||||
accordion
|
||||
accordion-bordered
|
||||
accordion-toggle
|
||||
active
|
||||
active-tab:bg-primary
|
||||
active-tab:text-base-content
|
||||
advance-select-menu
|
||||
advance-select-option
|
||||
advance-select-tag
|
||||
advance-select-toggle
|
||||
alert
|
||||
alert-error
|
||||
alert-outline
|
||||
alert-soft
|
||||
align-bottom
|
||||
align-middle
|
||||
animate-bounce
|
||||
animate-ping
|
||||
aria-[current='page']:text-bg-soft-primary
|
||||
avatar
|
||||
avatar-away-bottom
|
||||
avatar-away-top
|
||||
avatar-busy-bottom
|
||||
avatar-busy-top
|
||||
avatar-offline-bottom
|
||||
avatar-offline-top
|
||||
avatar-online-bottom
|
||||
avatar-online-top
|
||||
avatar-placeholder
|
||||
badge
|
||||
badge-error
|
||||
badge-info
|
||||
badge-outline
|
||||
badge-primary
|
||||
badge-soft
|
||||
badge-success
|
||||
bg-background
|
||||
bg-background/60
|
||||
bg-base-100
|
||||
bg-base-150
|
||||
bg-base-200
|
||||
bg-base-200/50
|
||||
bg-base-300
|
||||
bg-base-300/45
|
||||
bg-base-300/50
|
||||
bg-base-300/60
|
||||
bg-error
|
||||
bg-info
|
||||
bg-primary
|
||||
bg-primary/5
|
||||
bg-success
|
||||
bg-transparent
|
||||
bg-warning
|
||||
block
|
||||
blur
|
||||
border
|
||||
border-0
|
||||
border-2
|
||||
border-b
|
||||
border-base-content
|
||||
border-base-content/20
|
||||
border-base-content/25
|
||||
border-base-content/40
|
||||
border-base-content/5
|
||||
border-dashed
|
||||
border-t
|
||||
border-transparent
|
||||
bottom-0
|
||||
bottom-full
|
||||
break-words
|
||||
btn
|
||||
btn-accent
|
||||
btn-active
|
||||
btn-circle
|
||||
btn-disabled
|
||||
btn-error
|
||||
btn-info
|
||||
btn-outline
|
||||
btn-primary
|
||||
btn-secondary
|
||||
btn-sm
|
||||
btn-soft
|
||||
btn-square
|
||||
btn-success
|
||||
btn-text
|
||||
btn-warning
|
||||
card
|
||||
card-alert
|
||||
card-body
|
||||
card-border
|
||||
card-footer
|
||||
card-header
|
||||
card-title
|
||||
carousel
|
||||
carousel-body
|
||||
carousel-next
|
||||
carousel-prev
|
||||
carousel-slide
|
||||
chat
|
||||
chat-avatar
|
||||
chat-bubble
|
||||
chat-footer
|
||||
chat-header
|
||||
chat-receiver
|
||||
chat-sender
|
||||
checkbox
|
||||
checkbox-primary
|
||||
checkbox-xs
|
||||
col-span-1
|
||||
collapse
|
||||
combo-box-selected:block
|
||||
combo-box-selected:dropdown-active
|
||||
complete
|
||||
container
|
||||
contents
|
||||
cursor-default
|
||||
cursor-not-allowed
|
||||
cursor-pointer
|
||||
diff
|
||||
disabled
|
||||
divide-base-150/60
|
||||
divide-y
|
||||
drop-shadow
|
||||
dropdown
|
||||
dropdown-disabled
|
||||
dropdown-item
|
||||
dropdown-menu
|
||||
dropdown-open:opacity-100
|
||||
dropdown-open:rotate-180
|
||||
dropdown-toggle
|
||||
duration-300
|
||||
duration-500
|
||||
ease-in-out
|
||||
ease-linear
|
||||
end-3
|
||||
file-upload-complete:progress-success
|
||||
fill-black
|
||||
filter
|
||||
filter-reset
|
||||
fixed
|
||||
flex
|
||||
flex-1
|
||||
flex-col
|
||||
flex-grow
|
||||
flex-nowrap
|
||||
flex-row
|
||||
flex-shrink-0
|
||||
flex-wrap
|
||||
focus-visible:outline-none
|
||||
focus-within:border-primary
|
||||
focus:border-primary
|
||||
focus:outline-1
|
||||
focus:outline-none
|
||||
focus:outline-primary
|
||||
focus:ring-0
|
||||
font-bold
|
||||
font-inter
|
||||
font-medium
|
||||
font-normal
|
||||
font-semibold
|
||||
gap-0.5
|
||||
gap-1
|
||||
gap-1.5
|
||||
gap-2
|
||||
gap-3
|
||||
gap-4
|
||||
gap-5
|
||||
gap-6
|
||||
gap-x-1
|
||||
gap-x-2
|
||||
gap-x-3
|
||||
gap-y-1
|
||||
gap-y-3
|
||||
grid
|
||||
grid-cols-1
|
||||
grid-flow-col
|
||||
grow
|
||||
grow-0
|
||||
h-12
|
||||
h-2
|
||||
h-32
|
||||
h-64
|
||||
h-8
|
||||
h-auto
|
||||
h-full
|
||||
h-screen
|
||||
helper-text
|
||||
hidden
|
||||
hover:bg-primary/5
|
||||
hover:bg-transparent
|
||||
hover:text-base-content
|
||||
hover:text-base-content/60
|
||||
hover:text-primary
|
||||
image-full
|
||||
inline
|
||||
inline-block
|
||||
inline-flex
|
||||
inline-grid
|
||||
input
|
||||
input-floating
|
||||
input-floating-label
|
||||
input-lg
|
||||
input-md
|
||||
input-sm
|
||||
input-xl
|
||||
inset-0
|
||||
inset-y-0
|
||||
inset-y-2
|
||||
invisible
|
||||
is-invalid
|
||||
is-valid
|
||||
isolate
|
||||
italic
|
||||
items-center
|
||||
items-end
|
||||
items-start
|
||||
join
|
||||
join-item
|
||||
justify-between
|
||||
justify-center
|
||||
justify-end
|
||||
justify-start
|
||||
justify-stretch
|
||||
label-text
|
||||
leading-3
|
||||
leading-3.5
|
||||
leading-6
|
||||
left-0
|
||||
lg:bg-base-100/20
|
||||
lg:flex
|
||||
lg:gap-y-0
|
||||
lg:grid-cols-2
|
||||
lg:hidden
|
||||
lg:justify-end
|
||||
lg:justify-start
|
||||
lg:min-w-0
|
||||
lg:p-10
|
||||
lg:pb-5
|
||||
lg:pl-64
|
||||
lg:pr-3.5
|
||||
lg:pt-5
|
||||
lg:ring-1
|
||||
lg:ring-base-content/10
|
||||
lg:rounded-lg
|
||||
lg:shadow-xs
|
||||
list-disc
|
||||
list-inside
|
||||
loading
|
||||
loading-lg
|
||||
loading-sm
|
||||
loading-spinner
|
||||
loading-xl
|
||||
loading-xs
|
||||
lowercase
|
||||
m-10
|
||||
mask
|
||||
max-h-52
|
||||
max-lg:flex-col
|
||||
max-lg:hidden
|
||||
max-w-7xl
|
||||
max-w-80
|
||||
max-w-full
|
||||
max-w-lg
|
||||
max-w-sm
|
||||
max-w-xl
|
||||
mb-0.5
|
||||
mb-1
|
||||
mb-2
|
||||
mb-3
|
||||
mb-4
|
||||
mb-5
|
||||
md:table-cell
|
||||
md:text-3xl
|
||||
me-1
|
||||
me-1.5
|
||||
me-2
|
||||
me-2.5
|
||||
me-5
|
||||
menu
|
||||
menu-active
|
||||
menu-disabled
|
||||
menu-dropdown
|
||||
menu-dropdown-show
|
||||
menu-focus
|
||||
menu-horizontal
|
||||
menu-title
|
||||
min-h-0
|
||||
min-h-svh
|
||||
min-w-0
|
||||
min-w-28
|
||||
min-w-48
|
||||
min-w-60
|
||||
min-w-[100px]
|
||||
ml-3
|
||||
ml-4
|
||||
modal
|
||||
modal-content
|
||||
modal-dialog
|
||||
modal-middle
|
||||
modal-title
|
||||
mr-4
|
||||
ms-1
|
||||
ms-2
|
||||
ms-3
|
||||
mt-1
|
||||
mt-1.5
|
||||
mt-10
|
||||
mt-12
|
||||
mt-2
|
||||
mt-2.5
|
||||
mt-3
|
||||
mt-4
|
||||
mt-5
|
||||
mt-8
|
||||
mx-1
|
||||
mx-auto
|
||||
my-3
|
||||
my-auto
|
||||
opacity-0
|
||||
opacity-100
|
||||
open
|
||||
origin-top-left
|
||||
outline
|
||||
outline-0
|
||||
overflow-hidden
|
||||
overflow-x-auto
|
||||
overflow-y-auto
|
||||
overlay-open:duration-50
|
||||
overlay-open:opacity-100
|
||||
p-0.5
|
||||
p-1
|
||||
p-2
|
||||
p-3
|
||||
p-4
|
||||
p-5
|
||||
p-6
|
||||
p-8
|
||||
pin-input
|
||||
pin-input-underline
|
||||
placeholder-base-content/60
|
||||
pointer-events-auto
|
||||
pointer-events-none
|
||||
progress
|
||||
progress-bar
|
||||
progress-indeterminate
|
||||
progress-primary
|
||||
pt-0
|
||||
pt-0.5
|
||||
pt-3
|
||||
px-1.5
|
||||
px-2
|
||||
px-2.5
|
||||
px-3
|
||||
px-4
|
||||
px-5
|
||||
py-0.5
|
||||
py-1.5
|
||||
py-2
|
||||
py-2.5
|
||||
py-6
|
||||
radio
|
||||
range
|
||||
relative
|
||||
resize
|
||||
ring-0
|
||||
ring-1
|
||||
ring-white/10
|
||||
rounded-box
|
||||
rounded-field
|
||||
rounded-full
|
||||
rounded-lg
|
||||
rounded-md
|
||||
rounded-t-lg
|
||||
row-active
|
||||
row-hover
|
||||
rtl:!mr-0
|
||||
select
|
||||
select-disabled:opacity-40
|
||||
select-disabled:pointer-events-none
|
||||
select-floating
|
||||
select-floating-label
|
||||
selected
|
||||
selected:select-active
|
||||
shadow-base-300/20
|
||||
shadow-lg
|
||||
shadow-xs
|
||||
shrink-0
|
||||
size-10
|
||||
size-4
|
||||
size-5
|
||||
size-8
|
||||
skeleton
|
||||
skeleton-animated
|
||||
sm:auto-cols-max
|
||||
sm:flex
|
||||
sm:items-center
|
||||
sm:items-end
|
||||
sm:justify-between
|
||||
sm:justify-end
|
||||
sm:max-w-2xl
|
||||
sm:max-w-3xl
|
||||
sm:max-w-4xl
|
||||
sm:max-w-5xl
|
||||
sm:max-w-6xl
|
||||
sm:max-w-7xl
|
||||
sm:max-w-lg
|
||||
sm:max-w-md
|
||||
sm:max-w-xl
|
||||
sm:mb-0
|
||||
sm:mt-5
|
||||
sm:mt-6
|
||||
sm:p-6
|
||||
sm:py-2
|
||||
sm:text-sm/5
|
||||
space-x-1
|
||||
space-y-1
|
||||
space-y-4
|
||||
sr-only
|
||||
static
|
||||
status
|
||||
status-error
|
||||
sticky
|
||||
switch
|
||||
tab
|
||||
tab-active
|
||||
table
|
||||
table-pin-cols
|
||||
table-pin-rows
|
||||
tabs
|
||||
tabs-bordered
|
||||
tabs-lg
|
||||
tabs-lifted
|
||||
tabs-md
|
||||
tabs-sm
|
||||
tabs-xl
|
||||
tabs-xs
|
||||
text-2xl
|
||||
text-4xl
|
||||
text-accent
|
||||
text-base
|
||||
text-base-content
|
||||
text-base-content/40
|
||||
text-base-content/50
|
||||
text-base-content/60
|
||||
text-base-content/70
|
||||
text-base-content/80
|
||||
text-base/6
|
||||
text-center
|
||||
text-error
|
||||
text-error-content
|
||||
text-gray-400
|
||||
text-info
|
||||
text-info-content
|
||||
text-left
|
||||
text-lg
|
||||
text-primary
|
||||
text-primary-content
|
||||
text-sm
|
||||
text-sm/5
|
||||
text-success
|
||||
text-success-content
|
||||
text-warning
|
||||
text-warning-content
|
||||
text-xl
|
||||
text-xs
|
||||
text-xs/5
|
||||
textarea
|
||||
textarea-floating
|
||||
textarea-floating-label
|
||||
theme-controller
|
||||
tooltip
|
||||
tooltip-content
|
||||
top-0
|
||||
top-1/2
|
||||
top-full
|
||||
transform
|
||||
transition
|
||||
transition-all
|
||||
transition-opacity
|
||||
translate-x-0
|
||||
truncate
|
||||
underline
|
||||
uppercase
|
||||
validate
|
||||
w-0
|
||||
w-0.5
|
||||
w-12
|
||||
w-4
|
||||
w-56
|
||||
w-64
|
||||
w-fit
|
||||
w-full
|
||||
whitespace-nowrap
|
||||
z-10
|
||||
z-40
|
||||
z-50
|
||||
@@ -44,6 +44,7 @@ animate-bounce
|
||||
animate-ping
|
||||
aria-[current='page']:text-bg-soft-primary
|
||||
avatar
|
||||
avatar-placeholder
|
||||
badge
|
||||
badge-error
|
||||
badge-info
|
||||
@@ -73,16 +74,23 @@ block
|
||||
blur
|
||||
border
|
||||
border-0
|
||||
border-1
|
||||
border-2
|
||||
border-b
|
||||
border-b-2
|
||||
border-b-base-content/20
|
||||
border-base-content
|
||||
border-base-content/20
|
||||
border-base-content/25
|
||||
border-base-content/40
|
||||
border-base-content/5
|
||||
border-dashed
|
||||
border-error/30
|
||||
border-info/30
|
||||
border-success/30
|
||||
border-t
|
||||
border-transparent
|
||||
border-warning/30
|
||||
bottom-0
|
||||
bottom-full
|
||||
break-words
|
||||
@@ -93,7 +101,6 @@ btn-circle
|
||||
btn-disabled
|
||||
btn-error
|
||||
btn-info
|
||||
btn-outline
|
||||
btn-primary
|
||||
btn-secondary
|
||||
btn-sm
|
||||
@@ -200,7 +207,7 @@ grid-cols-4
|
||||
grid-flow-col
|
||||
grow
|
||||
grow-0
|
||||
h-12
|
||||
h-10
|
||||
h-2
|
||||
h-3
|
||||
h-32
|
||||
@@ -245,11 +252,9 @@ justify-between
|
||||
justify-center
|
||||
justify-end
|
||||
justify-start
|
||||
justify-stretch
|
||||
label-text
|
||||
leading-3
|
||||
leading-3.5
|
||||
leading-6
|
||||
leading-none
|
||||
left-0
|
||||
lg:bg-base-100/20
|
||||
@@ -287,6 +292,9 @@ mask
|
||||
max-h-52
|
||||
max-lg:flex-col
|
||||
max-lg:hidden
|
||||
max-md:flex-wrap
|
||||
max-md:justify-center
|
||||
max-sm:hidden
|
||||
max-w-7xl
|
||||
max-w-80
|
||||
max-w-full
|
||||
@@ -323,6 +331,7 @@ min-w-28
|
||||
min-w-48
|
||||
min-w-60
|
||||
min-w-[100px]
|
||||
min-w-full
|
||||
min-w-sm
|
||||
ml-3
|
||||
ml-4
|
||||
@@ -330,10 +339,10 @@ modal
|
||||
modal-content
|
||||
modal-dialog
|
||||
modal-middle
|
||||
modal-title
|
||||
mr-4
|
||||
ms-0.5
|
||||
ms-1
|
||||
ms-1.5
|
||||
ms-2
|
||||
ms-3
|
||||
ms-auto
|
||||
@@ -368,11 +377,13 @@ p-0.5
|
||||
p-1
|
||||
p-1.5
|
||||
p-2
|
||||
p-2.5
|
||||
p-3
|
||||
p-4
|
||||
p-5
|
||||
p-6
|
||||
p-8
|
||||
pb-1
|
||||
pin-input
|
||||
placeholder-base-content/60
|
||||
pointer-events-auto
|
||||
@@ -383,7 +394,9 @@ progress-indeterminate
|
||||
progress-primary
|
||||
pt-0
|
||||
pt-0.5
|
||||
pt-2
|
||||
pt-3
|
||||
px-0.5
|
||||
px-1.5
|
||||
px-2
|
||||
px-2.5
|
||||
@@ -418,6 +431,7 @@ select-disabled:opacity-40
|
||||
select-disabled:pointer-events-none
|
||||
select-floating
|
||||
select-floating-label
|
||||
select-sm
|
||||
selected
|
||||
selected:select-active
|
||||
shadow-base-300/20
|
||||
@@ -426,6 +440,7 @@ shadow-md
|
||||
shadow-xs
|
||||
shrink-0
|
||||
size-10
|
||||
size-12
|
||||
size-4
|
||||
size-5
|
||||
size-8
|
||||
@@ -448,11 +463,11 @@ sm:max-w-md
|
||||
sm:max-w-xl
|
||||
sm:mb-0
|
||||
sm:mt-5
|
||||
sm:mt-6
|
||||
sm:p-6
|
||||
sm:py-2
|
||||
sm:text-sm/5
|
||||
space-x-1
|
||||
space-x-2.5
|
||||
space-y-1
|
||||
space-y-4
|
||||
sr-only
|
||||
@@ -495,6 +510,7 @@ text-left
|
||||
text-lg
|
||||
text-primary
|
||||
text-primary-content
|
||||
text-right
|
||||
text-sm
|
||||
text-sm/5
|
||||
text-success
|
||||
@@ -525,6 +541,7 @@ validate
|
||||
w-0
|
||||
w-0.5
|
||||
w-12
|
||||
w-13
|
||||
w-4
|
||||
w-56
|
||||
w-64
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@using Moonlight.Shared.Http.Responses.Admin.ApiKeys
|
||||
@using MoonCore.Blazor.FlyonUi.DataTables
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.ToolbarItems
|
||||
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject AlertService AlertService
|
||||
@@ -47,48 +49,72 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5 flex justify-end">
|
||||
<a href="/admin/api/create" class="btn btn-primary">
|
||||
Create
|
||||
</a>
|
||||
</div>
|
||||
<DataGrid @ref="Grid"
|
||||
TGridItem="ApiKeyResponse"
|
||||
ItemsProvider="ItemsProvider"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Description" />
|
||||
<TemplateColumn Sortable="true" Title="Expires At">
|
||||
<td>
|
||||
@Formatter.FormatDate(context.ExpiresAt.UtcDateTime)
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
<TemplateColumn Sortable="true" Title="Created At">
|
||||
<td>
|
||||
@Formatter.FormatDate(context.CreatedAt.UtcDateTime)
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
<TemplateColumn>
|
||||
<td>
|
||||
<div class="flex justify-end">
|
||||
<a href="/admin/api/@(context.Id)" class="text-primary mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-base"></i>
|
||||
</a>
|
||||
|
||||
<DataTable @ref="Table" TItem="ApiKeyResponse">
|
||||
<Configuration>
|
||||
<Pagination TItem="ApiKeyResponse" ItemSource="LoadData" />
|
||||
|
||||
<DataTableColumn TItem="ApiKeyResponse" Field="@(x => x.Id)" Name="Id"/>
|
||||
<DataTableColumn TItem="ApiKeyResponse" Field="@(x => x.Description)" Name="Description"/>
|
||||
<DataTableColumn TItem="ApiKeyResponse" Field="@(x => x.ExpiresAt)" Name="Expires at">
|
||||
<ColumnTemplate>
|
||||
@(Formatter.FormatDate(context.ExpiresAt.UtcDateTime))
|
||||
</ColumnTemplate>
|
||||
</DataTableColumn>
|
||||
<DataTableColumn TItem="ApiKeyResponse">
|
||||
<ColumnTemplate>
|
||||
<div class="flex justify-end">
|
||||
<a href="/admin/api/@(context.Id)" class="text-primary mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-base"></i>
|
||||
</a>
|
||||
|
||||
<a href="#" @onclick="() => Delete(context)" @onclick:preventDefault
|
||||
class="text-error">
|
||||
<i class="icon-trash text-base"></i>
|
||||
</a>
|
||||
</div>
|
||||
</ColumnTemplate>
|
||||
</DataTableColumn>
|
||||
</Configuration>
|
||||
</DataTable>
|
||||
<a href="#" @onclick="() => DeleteAsync(context)" @onclick:preventDefault
|
||||
class="text-error">
|
||||
<i class="icon-trash text-base"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
|
||||
<TemplateToolbarItem>
|
||||
<a href="/admin/api/create" class="btn btn-primary ms-1.5">
|
||||
Create
|
||||
</a>
|
||||
</TemplateToolbarItem>
|
||||
</DataGrid>
|
||||
|
||||
@code
|
||||
{
|
||||
private DataTable<ApiKeyResponse> Table;
|
||||
private DataGrid<ApiKeyResponse> Grid;
|
||||
|
||||
private async Task<IPagedData<ApiKeyResponse>> LoadData(PaginationOptions options)
|
||||
=> await ApiClient.GetJson<PagedData<ApiKeyResponse>>($"api/admin/apikeys?page={options.Page}&pageSize={options.PerPage}");
|
||||
private async Task<DataGridItemResult<ApiKeyResponse>> ItemsProvider(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
|
||||
private async Task Delete(ApiKeyResponse apiKeyResponse)
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<ApiKeyResponse>>($"api/admin/apikeys{query}");
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(ApiKeyResponse apiKeyResponse)
|
||||
{
|
||||
await AlertService.ConfirmDanger(
|
||||
"API Key deletion",
|
||||
@@ -98,7 +124,7 @@
|
||||
await ApiClient.Delete($"api/admin/apikeys/{apiKeyResponse.Id}");
|
||||
await ToastService.Success("Successfully deleted api key");
|
||||
|
||||
await Table.Refresh();
|
||||
await Grid.RefreshAsync();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
@using System.Text.Json
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using MoonCore.Blazor.FlyonUi.DataTables
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.ToolbarItems
|
||||
@using MoonCore.Blazor.FlyonUi.Helpers
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@@ -16,6 +18,7 @@
|
||||
@inject ThemeService ThemeService
|
||||
@inject AlertService AlertService
|
||||
@inject ToastService ToastService
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject DownloadService DownloadService
|
||||
@inject ILogger<Index> Logger
|
||||
|
||||
@@ -25,72 +28,72 @@
|
||||
Themes
|
||||
</PageSeparator>
|
||||
|
||||
<div class="mt-5 flex justify-end">
|
||||
<div>
|
||||
<label for="import-theme" class="btn btn-info me-1">
|
||||
<i class="icon-file-up"></i>
|
||||
Import
|
||||
</label>
|
||||
<InputFile OnChange="Import" id="import-theme" class="hidden" multiple />
|
||||
<a href="/admin/system/customisation/themes/create" class="btn btn-primary">Create</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-8">
|
||||
<DataGrid TGridItem="ThemeResponse"
|
||||
ItemsProvider="ItemsProvider"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
<TemplateColumn Title="Name" Sortable="true">
|
||||
<td>
|
||||
<div class="flex items-center">
|
||||
@context.Name
|
||||
|
||||
<div class="my-2.5">
|
||||
<DataTable @ref="Table" TItem="ThemeResponse">
|
||||
<Configuration>
|
||||
<DataTableColumn TItem="ThemeResponse" Field="@(x => x.Id)" Name="Id"/>
|
||||
<DataTableColumn TItem="ThemeResponse" Field="@(x => x.Name)" Name="Name">
|
||||
<ColumnTemplate>
|
||||
<div class="flex items-center">
|
||||
@context.Name
|
||||
|
||||
@if (context.IsEnabled)
|
||||
{
|
||||
<i class="icon-check text-success ms-2"></i>
|
||||
}
|
||||
</div>
|
||||
</ColumnTemplate>
|
||||
</DataTableColumn>
|
||||
<DataTableColumn TItem="ThemeResponse" Field="@(x => x.Author)" Name="Author"/>
|
||||
<DataTableColumn TItem="ThemeResponse" Field="@(x => x.Version)" Name="Version"/>
|
||||
<DataTableColumn TItem="ThemeResponse">
|
||||
<ColumnTemplate>
|
||||
<div class="flex justify-end">
|
||||
@if (!string.IsNullOrEmpty(context.DonateUrl))
|
||||
{
|
||||
<a href="@context.DonateUrl" target="_blank" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-accent icon-heart me-1"></i>
|
||||
<span class="text-accent">Donate</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrEmpty(context.UpdateUrl))
|
||||
{
|
||||
<a href="#" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-info icon-refresh-cw me-1"></i>
|
||||
<span class="text-info">Update</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
<a @onclick="() => Export(context)" @onclick:preventDefault href="#" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-success icon-download me-1"></i>
|
||||
<span class="text-success">Export</span>
|
||||
</a>
|
||||
|
||||
<a href="/admin/system/customisation/themes/@(context.Id)" class="mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-primary"></i>
|
||||
@if (context.IsEnabled)
|
||||
{
|
||||
<i class="icon-check text-success ms-2"></i>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
<PropertyColumn Field="x => x.Version" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Author" />
|
||||
|
||||
<TemplateColumn>
|
||||
<td>
|
||||
<div class="flex justify-end">
|
||||
@if (!string.IsNullOrEmpty(context.DonateUrl))
|
||||
{
|
||||
<a href="@context.DonateUrl" target="_blank" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-accent icon-heart me-1"></i>
|
||||
<span class="text-accent">Donate</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
<a href="#" @onclick="() => Delete(context)" @onclick:preventDefault>
|
||||
<i class="icon-trash text-error"></i>
|
||||
@if (!string.IsNullOrEmpty(context.UpdateUrl))
|
||||
{
|
||||
<a href="#" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-info icon-refresh-cw me-1"></i>
|
||||
<span class="text-info">Update</span>
|
||||
</a>
|
||||
</div>
|
||||
</ColumnTemplate>
|
||||
</DataTableColumn>
|
||||
<Pagination TItem="ThemeResponse" PageSize="10" ItemSource="LoadItems"/>
|
||||
</Configuration>
|
||||
</DataTable>
|
||||
}
|
||||
|
||||
<a @onclick="() => ExportAsync(context)" @onclick:preventDefault href="#" class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-success icon-download me-1"></i>
|
||||
<span class="text-success">Export</span>
|
||||
</a>
|
||||
|
||||
<a href="/admin/system/customisation/themes/@(context.Id)" class="mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-primary"></i>
|
||||
</a>
|
||||
|
||||
<a href="#" @onclick="() => DeleteAsync(context)" @onclick:preventDefault>
|
||||
<i class="icon-trash text-error"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
|
||||
<TemplateToolbarItem>
|
||||
<label for="import-theme" class="btn btn-info me-1 ms-1.5">
|
||||
<i class="icon-file-up"></i>
|
||||
Import
|
||||
</label>
|
||||
<InputFile OnChange="ImportAsync" id="import-theme" class="hidden" multiple />
|
||||
<a href="/admin/system/customisation/themes/create" class="btn btn-primary">Create</a>
|
||||
</TemplateToolbarItem>
|
||||
</DataGrid>
|
||||
</div>
|
||||
|
||||
<PageSeparator Icon="icon-images">
|
||||
@@ -100,12 +103,31 @@
|
||||
|
||||
@code
|
||||
{
|
||||
private DataTable<ThemeResponse> Table;
|
||||
private DataGrid<ThemeResponse> Grid;
|
||||
|
||||
private async Task<IPagedData<ThemeResponse>> LoadItems(PaginationOptions options)
|
||||
=> await ThemeService.Get(options.Page, options.PerPage);
|
||||
private async Task<DataGridItemResult<ThemeResponse>> ItemsProvider(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<ThemeResponse>>($"api/admin/system/customisation/themes{query}");
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
}
|
||||
|
||||
private async Task Import(InputFileChangeEventArgs eventArgs)
|
||||
private async Task ImportAsync(InputFileChangeEventArgs eventArgs)
|
||||
{
|
||||
if(eventArgs.FileCount < 1)
|
||||
return;
|
||||
@@ -141,7 +163,7 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
var theme = await ThemeService.Create(new CreateThemeRequest()
|
||||
var theme = await ThemeService.CreateAsync(new CreateThemeRequest()
|
||||
{
|
||||
Name = themeTransfer.Name,
|
||||
Author = themeTransfer.Author,
|
||||
@@ -153,7 +175,7 @@
|
||||
|
||||
await ToastService.Success("Successfully imported theme", theme.Name);
|
||||
|
||||
await Table.Refresh();
|
||||
await Grid.RefreshAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -162,7 +184,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Export(ThemeResponse theme)
|
||||
private async Task ExportAsync(ThemeResponse theme)
|
||||
{
|
||||
var transfer = new ThemeTransferModel()
|
||||
{
|
||||
@@ -184,17 +206,17 @@
|
||||
await DownloadService.Download(fileName, json);
|
||||
}
|
||||
|
||||
private async Task Delete(ThemeResponse response)
|
||||
private async Task DeleteAsync(ThemeResponse response)
|
||||
{
|
||||
await AlertService.ConfirmDanger(
|
||||
"Theme deletion",
|
||||
$"Do you really want to delete the theme: {response.Name}",
|
||||
async () =>
|
||||
{
|
||||
await ThemeService.Delete(response.Id);
|
||||
await ThemeService.DeleteAsync(response.Id);
|
||||
|
||||
await ToastService.Success("Successfully deleted theme");
|
||||
await Table.Refresh();
|
||||
await Grid.RefreshAsync();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
private async Task OnValidSubmit()
|
||||
{
|
||||
await ThemeService.Create(Request);
|
||||
await ThemeService.CreateAsync(Request);
|
||||
await ToastService.Success("Successfully created theme");
|
||||
|
||||
NavigationManager.NavigateTo("/admin/system/customisation");
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
private async Task Load(LazyLoader _)
|
||||
{
|
||||
Response = await ThemeService.Get(Id);
|
||||
Response = await ThemeService.GetAsync(Id);
|
||||
|
||||
Request = new()
|
||||
{
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
private async Task OnValidSubmit()
|
||||
{
|
||||
await ThemeService.Update(Id, Request);
|
||||
await ThemeService.UpdateAsync(Id, Request);
|
||||
|
||||
await ToastService.Success("Successfully updated theme");
|
||||
Navigation.NavigateTo("/admin/system/customisation");
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
.ToDictionary(x => x, _ => true);
|
||||
}
|
||||
|
||||
private async Task GenerateDiagnose(WButton _)
|
||||
private async Task GenerateDiagnose(WButton button)
|
||||
{
|
||||
var request = new GenerateDiagnoseRequest();
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@using Moonlight.Shared.Http.Responses.Admin.Users
|
||||
@using MoonCore.Blazor.FlyonUi.DataTables
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject AlertService AlertService
|
||||
@inject ToastService ToastService
|
||||
|
||||
<div class="mb-5">
|
||||
<div class="mb-8">
|
||||
<PageHeader Title="Users">
|
||||
<a href="/admin/users/create" class="btn btn-primary">
|
||||
Create
|
||||
@@ -17,37 +18,57 @@
|
||||
</PageHeader>
|
||||
</div>
|
||||
|
||||
<DataTable @ref="Table" TItem="UserResponse">
|
||||
<Configuration>
|
||||
<Pagination TItem="UserResponse" ItemSource="LoadData" />
|
||||
|
||||
<DataTableColumn TItem="UserResponse" Field="@(x => x.Id)" Name="Id"/>
|
||||
<DataTableColumn TItem="UserResponse" Field="@(x => x.Username)" Name="Username"/>
|
||||
<DataTableColumn TItem="UserResponse" Field="@(x => x.Email)" Name="Email"/>
|
||||
<DataTableColumn TItem="UserResponse">
|
||||
<ColumnTemplate>
|
||||
<div class="flex justify-end">
|
||||
<a href="/admin/users/@(context.Id)" class="mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-primary"></i>
|
||||
</a>
|
||||
<DataGrid @ref="Grid"
|
||||
TGridItem="UserResponse"
|
||||
ItemsProvider="ItemsProvider"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Username" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Email" Sortable="true" />
|
||||
|
||||
<TemplateColumn>
|
||||
<td>
|
||||
<div class="flex justify-end">
|
||||
<a href="/admin/users/@(context.Id)" class="mr-2 sm:mr-3">
|
||||
<i class="icon-pencil text-primary"></i>
|
||||
</a>
|
||||
|
||||
<a href="#" @onclick="() => Delete(context)" @onclick:preventDefault>
|
||||
<i class="icon-trash text-error"></i>
|
||||
</a>
|
||||
</div>
|
||||
</ColumnTemplate>
|
||||
</DataTableColumn>
|
||||
</Configuration>
|
||||
</DataTable>
|
||||
<a href="#" @onclick="() => DeleteAsync(context)" @onclick:preventDefault>
|
||||
<i class="icon-trash text-error"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
</DataGrid>
|
||||
|
||||
@code
|
||||
{
|
||||
private DataTable<UserResponse> Table;
|
||||
private DataGrid<UserResponse> Grid;
|
||||
|
||||
private async Task<IPagedData<UserResponse>> LoadData(PaginationOptions options)
|
||||
=> await ApiClient.GetJson<PagedData<UserResponse>>($"api/admin/users?page={options.Page}&pageSize={options.PerPage}");
|
||||
private async Task<DataGridItemResult<UserResponse>> ItemsProvider(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
|
||||
private async Task Delete(UserResponse response)
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<UserResponse>>($"api/admin/users{query}");
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(UserResponse response)
|
||||
{
|
||||
await AlertService.ConfirmDanger(
|
||||
"User deletion",
|
||||
@@ -57,7 +78,7 @@
|
||||
await ApiClient.Delete($"api/admin/users/{response.Id}");
|
||||
await ToastService.Success("Successfully deleted user");
|
||||
|
||||
await Table.Refresh();
|
||||
await Grid.RefreshAsync();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user