Files
Servers/MoonlightServers.Frontend/Admin/Templates/Update.razor

297 lines
13 KiB
Plaintext

@page "/admin/servers/templates/{Id:int}"
@using System.Net
@using System.Text.Json
@using LucideBlazor
@using Moonlight.Frontend.Helpers
@using MoonlightServers.Shared
@using MoonlightServers.Shared.Admin.Templates
@using ShadcnBlazor.Buttons
@using ShadcnBlazor.Cards
@using ShadcnBlazor.Emptys
@using ShadcnBlazor.Extras.Common
@using ShadcnBlazor.Extras.Forms
@using ShadcnBlazor.Extras.Toasts
@using ShadcnBlazor.Fields
@using ShadcnBlazor.Inputs
@using ShadcnBlazor.Tab
@inject HttpClient HttpClient
@inject NavigationManager Navigation
@inject ToastService ToastService
<LazyLoader Load="LoadAsync">
@if (Template == null)
{
<Empty>
<EmptyHeader>
<EmptyMedia Variant="EmptyMediaVariant.Icon">
<SearchIcon/>
</EmptyMedia>
<EmptyTitle>Template not found</EmptyTitle>
<EmptyDescription>
A template with this id cannot be found
</EmptyDescription>
</EmptyHeader>
</Empty>
}
else
{
<EnhancedEditForm Model="Request" OnValidSubmit="OnSubmitAsync" Context="formContext">
<div class="flex flex-row justify-between">
<div class="flex flex-col">
<h1 class="text-xl font-semibold">Update Template</h1>
<div class="text-muted-foreground">
Update template @Template.Name
</div>
</div>
<div class="flex flex-row gap-x-1.5">
<Button Variant="ButtonVariant.Secondary">
<Slot>
<a href="/admin/servers?tab=templates" @attributes="context">
<ChevronLeftIcon/>
Back
</a>
</Slot>
</Button>
<SubmitButton>
<CheckIcon/>
Continue
</SubmitButton>
</div>
</div>
<div class="mt-8 space-y-5">
<DataAnnotationsValidator/>
<FormValidationSummary/>
<Tabs DefaultValue="meta">
<TabsList ClassName="inline-flex w-full lg:w-fit justify-start overflow-x-auto overflow-y-hidden">
<TabsTrigger Value="meta">
<IdCardIcon/>
Meta
</TabsTrigger>
<TabsTrigger Value="lifecycle">
<PlayIcon/>
Lifecycle
</TabsTrigger>
<TabsTrigger Value="installation">
<SquareTerminalIcon/>
Installation
</TabsTrigger>
<TabsTrigger Value="variables">
<VariableIcon/>
Variables
</TabsTrigger>
<TabsTrigger Value="dockerImages">
<ContainerIcon/>
Docker Images
</TabsTrigger>
<TabsTrigger Value="files">
<FileCogIcon/>
Files
</TabsTrigger>
</TabsList>
<TabsContent Value="meta">
<Card>
<CardContent>
<FieldGroup>
<FieldSet>
<FieldGroup>
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
<Field>
<FieldLabel for="templateName">Name</FieldLabel>
<TextInputField
@bind-Value="Request.Name"
id="templateName"/>
</Field>
<Field>
<FieldLabel for="templateAuthor">Author</FieldLabel>
<TextInputField
@bind-Value="Request.Author"
id="templateAuthor"/>
</Field>
<Field>
<FieldLabel for="templateVersion">Version</FieldLabel>
<TextInputField
@bind-Value="Request.Version"
id="templateVersion"/>
</Field>
<Field ClassName="col-span-1 lg:col-span-2 xl:col-span-3">
<FieldLabel for="templateDescription">Description</FieldLabel>
<TextareaInputField
@bind-Value="Request.Description"
id="templateDescription"/>
</Field>
<Field>
<FieldLabel for="templateDonateUrl">Donate URL</FieldLabel>
<TextInputField
@bind-Value="Request.DonateUrl"
id="templateDonateUrl"/>
</Field>
<Field>
<FieldLabel for="templateUpdateUrl">Update URL</FieldLabel>
<TextInputField
@bind-Value="Request.UpdateUrl"
id="templateUpdateUrl"/>
</Field>
</div>
</FieldGroup>
</FieldSet>
</FieldGroup>
</CardContent>
</Card>
</TabsContent>
<TabsContent Value="lifecycle">
<Card>
<CardContent>
<FieldGroup>
<FieldSet>
<FieldGroup>
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
<Field ClassName="col-span-1 lg:col-span-2">
<FieldLabel>Startup Commands</FieldLabel>
<StartupCommandEditor
@bind-Value="Request.LifecycleConfig.StartupCommands"/>
</Field>
<Field>
<FieldLabel for="templateStopCommand">Stop Command</FieldLabel>
<TextInputField
@bind-Value="Request.LifecycleConfig.StopCommand"
id="templateStopCommand"/>
</Field>
<Field ClassName="col-span-1 lg:col-span-2">
<FieldLabel>Online Texts</FieldLabel>
<OnlineTextEditor
@bind-Value="Request.LifecycleConfig.OnlineLogPatterns"/>
</Field>
</div>
</FieldGroup>
</FieldSet>
</FieldGroup>
</CardContent>
</Card>
</TabsContent>
<TabsContent Value="installation">
<Card>
<CardContent>
<FieldGroup>
<FieldSet>
<FieldGroup>
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
<Field>
<FieldLabel for="templateInstallDockerImage">Docker Image
</FieldLabel>
<TextInputField
@bind-Value="Request.InstallationConfig.DockerImage"
id="templateInstallDockerImage"/>
</Field>
<Field>
<FieldLabel for="templateInstallShell">Shell</FieldLabel>
<TextInputField
@bind-Value="Request.InstallationConfig.Shell"
id="templateInstallShell"/>
</Field>
<Field ClassName="col-span-1 lg:col-span-2 xl:col-span-3">
<FieldLabel>Script</FieldLabel>
<ScriptEditor
@ref="ScriptEditor"
@bind-Value="Request.InstallationConfig.Script"/>
</Field>
</div>
</FieldGroup>
</FieldSet>
</FieldGroup>
</CardContent>
</Card>
</TabsContent>
<TabsContent Value="variables">
<VariableListEditor Template="Template"/>
</TabsContent>
<TabsContent Value="dockerImages">
<DockerImageListEditor Request="Request" Template="Template"/>
</TabsContent>
<TabsContent Value="files">
<ConfigFilesEditor FilesConfig="Request.FilesConfig"/>
</TabsContent>
</Tabs>
</div>
</EnhancedEditForm>
}
</LazyLoader>
@code
{
[Parameter] public int Id { get; set; }
private UpdateTemplateDto Request;
private DetailedTemplateDto? Template;
private ScriptEditor ScriptEditor;
private async Task LoadAsync(LazyLoader _)
{
// Meta
var metaResponse = await HttpClient.GetAsync($"api/admin/servers/templates/{Id}");
if (!metaResponse.IsSuccessStatusCode)
{
if (metaResponse.StatusCode == HttpStatusCode.NotFound)
return;
metaResponse.EnsureSuccessStatusCode();
return;
}
Template = await metaResponse.Content.ReadFromJsonAsync<DetailedTemplateDto>(
SerializationContext.Default.Options
);
if (Template == null)
return;
Request = TemplateMapper.ToRequest(Template);
}
private async Task<bool> OnSubmitAsync(EditContext context, ValidationMessageStore validationMessageStore)
{
await ScriptEditor.SubmitAsync();
var response = await HttpClient.PutAsJsonAsync(
$"/api/admin/servers/templates/{Id}",
Request,
SerializationContext.Default.Options
);
if (!response.IsSuccessStatusCode)
{
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
return false;
}
await ToastService.SuccessAsync(
"Template Update",
$"Successfully updated template {Request.Name}"
);
Navigation.NavigateTo("/admin/servers?tab=templates");
return true;
}
}