add other config
This commit is contained in:
@@ -17,6 +17,10 @@ export const getServers = async (event: RequestEvent): Promise<Server[]> => {
|
|||||||
return fetchAPIEvent(event, '/server');
|
return fetchAPIEvent(event, '/server');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getServerById = async (event: RequestEvent, serverId: string): Promise<Server> => {
|
||||||
|
return fetchAPIEvent(event, `/server/${serverId}`);
|
||||||
|
};
|
||||||
|
|
||||||
export const getConfigFiles = async (
|
export const getConfigFiles = async (
|
||||||
event: RequestEvent,
|
event: RequestEvent,
|
||||||
serverId: string
|
serverId: string
|
||||||
|
|||||||
199
src/components/EditorAssistRules.svelte
Normal file
199
src/components/EditorAssistRules.svelte
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
|
import type { AssistRules } from '$models/config';
|
||||||
|
|
||||||
|
const { config, id }: { config: AssistRules; id: string } = $props();
|
||||||
|
const editedConfig = $state({ ...config });
|
||||||
|
let formLoading = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/assistRules"
|
||||||
|
use:enhance={() => {
|
||||||
|
formLoading = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="id" value={id} />
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-7xl">
|
||||||
|
<div class="border-b border-gray-900/10 pb-12">
|
||||||
|
<h2 class="text-base/7 font-semibold text-gray-900">Assist Rules</h2>
|
||||||
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||||
|
<!-- Stability Control Level Max -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Stability Control Level Max:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.stabilityControlLevelMax}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="stabilityControlLevelMax"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Autosteer -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Autosteer:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutosteer}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutosteer"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Lights -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Lights:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoLights}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoLights"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Wiper -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Wiper:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoWiper}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoWiper"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Engine Start -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Engine Start:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoEngineStart}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoEngineStart"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Pit Limiter -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Pit Limiter:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoPitLimiter}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoPitLimiter"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Gear -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Gear:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoGear}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoGear"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Auto Clutch -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Auto Clutch:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableAutoClutch}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableAutoClutch"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Disable Ideal Line -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Disable Ideal Line:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.disableIdealLine}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="disableIdealLine"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||||
|
<label
|
||||||
|
><span class="mx-3">Restart server</span><input
|
||||||
|
type="checkbox"
|
||||||
|
id="restart"
|
||||||
|
name="restart"
|
||||||
|
checked
|
||||||
|
/></label
|
||||||
|
>
|
||||||
|
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
119
src/components/EditorConfiguration.svelte
Normal file
119
src/components/EditorConfiguration.svelte
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
|
import type { Configuration } from '$models/config';
|
||||||
|
|
||||||
|
const { config, id }: { config: Configuration; id: string } = $props();
|
||||||
|
const editedConfig = $state({ ...config });
|
||||||
|
let formLoading = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/configuration"
|
||||||
|
use:enhance={() => {
|
||||||
|
formLoading = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="id" value={id} />
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-7xl">
|
||||||
|
<div class="border-b border-gray-900/10 pb-12">
|
||||||
|
<h2 class="text-base/7 font-semibold text-gray-900">Configuration</h2>
|
||||||
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
UDP Port:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
disabled={formLoading}
|
||||||
|
name="udpPort"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
bind:value={editedConfig.udpPort}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
TCP Port:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
disabled={formLoading}
|
||||||
|
name="tcpPort"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
bind:value={editedConfig.tcpPort}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Max Connections:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
disabled={formLoading}
|
||||||
|
name="maxConnections"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
bind:value={editedConfig.maxConnections}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Lan Discovery:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.lanDiscovery}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="lanDiscovery"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-2">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Register To Lobby:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.registerToLobby}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="registerToLobby"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="configVersion" value={1} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||||
|
<label
|
||||||
|
><span class="mx-3">Restart server</span><input
|
||||||
|
type="checkbox"
|
||||||
|
id="restart"
|
||||||
|
name="restart"
|
||||||
|
checked
|
||||||
|
/></label
|
||||||
|
>
|
||||||
|
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
const { config, tracks, id }: { config: EventConfig; tracks: Track[]; id: string } = $props();
|
const { config, tracks, id }: { config: EventConfig; tracks: Track[]; id: string } = $props();
|
||||||
const editedConfig = $state({ ...config });
|
const editedConfig = $state({ ...config });
|
||||||
let sessions = $state(JSON.stringify(editedConfig.sessions));
|
if (!editedConfig.sessions) editedConfig.sessions = [];
|
||||||
let formLoading = $state(false);
|
let formLoading = $state(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -187,36 +187,156 @@
|
|||||||
<div class="sm:col-span-2">
|
<div class="sm:col-span-2">
|
||||||
<label class="block text-sm/6 font-medium text-gray-900">
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
Is fixed condition qualification:
|
Is fixed condition qualification:
|
||||||
<div class="mt-2">
|
<div class="mt-2 grid grid-cols-1">
|
||||||
<div class="input-block">
|
<select
|
||||||
<input
|
bind:value={editedConfig.isFixedConditionQualification}
|
||||||
disabled={formLoading}
|
disabled={formLoading}
|
||||||
name="isFixedConditionQualification"
|
name="isFixedConditionQualification"
|
||||||
type="number"
|
class="form form-select"
|
||||||
class="form form-input"
|
|
||||||
bind:value={editedConfig.isFixedConditionQualification}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div></label
|
|
||||||
>
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="sm:col-span-6">
|
<div class="sm:col-span-6">
|
||||||
<label class="block text-sm/6 font-medium text-gray-900">
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
Sessions:
|
Sessions:
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<textarea
|
{#each editedConfig.sessions as session, index}
|
||||||
|
<div class="mb-4 rounded-lg border p-4">
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<!-- Hour of Day -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700"
|
||||||
|
>Hour of Day:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={session.hourOfDay}
|
||||||
|
name={`sessions[${index}][hourOfDay]`}
|
||||||
disabled={formLoading}
|
disabled={formLoading}
|
||||||
name="sessions"
|
type="number"
|
||||||
rows="3"
|
class="form form-input"
|
||||||
class="form form-textarea"
|
/>
|
||||||
bind:value={sessions}
|
</div>
|
||||||
></textarea>
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<!-- Day of Weekend -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700"
|
||||||
|
>Day of Weekend:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={session.dayOfWeekend}
|
||||||
|
name={`sessions[${index}][dayOfWeekend]`}
|
||||||
|
disabled={formLoading}
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<!-- Time Multiplier -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700"
|
||||||
|
>Time Multiplier:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={session.timeMultiplier}
|
||||||
|
name={`sessions[${index}][timeMultiplier]`}
|
||||||
|
disabled={formLoading}
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<!-- Session Type -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700"
|
||||||
|
>Session Type:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={session.sessionType}
|
||||||
|
name={`sessions[${index}][sessionType]`}
|
||||||
|
disabled={formLoading}
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value="P">Practice</option>
|
||||||
|
<option value="Q">Qualifying</option>
|
||||||
|
<option value="R">Race</option>
|
||||||
|
</select>
|
||||||
|
</div></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<!-- Session Duration Minutes -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700"
|
||||||
|
>Session Duration (Minutes):
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={session.sessionDurationMinutes}
|
||||||
|
name={`sessions[${index}][sessionDurationMinutes]`}
|
||||||
|
disabled={formLoading}
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
editedConfig.sessions = editedConfig.sessions.filter((_, i) => i !== index);
|
||||||
|
}}
|
||||||
|
class="mt-2 text-sm text-red-600 hover:text-red-800"
|
||||||
|
>
|
||||||
|
Remove Session
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
editedConfig.sessions = [
|
||||||
|
...editedConfig.sessions,
|
||||||
|
{
|
||||||
|
hourOfDay: 14,
|
||||||
|
dayOfWeekend: 1,
|
||||||
|
timeMultiplier: 1,
|
||||||
|
sessionType: 'Practice',
|
||||||
|
sessionDurationMinutes: 60
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}}
|
||||||
|
class="btn btn-blue mt-2"
|
||||||
|
>
|
||||||
|
Add Session
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 flex items-center justify-end gap-x-6">
|
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||||
|
<label
|
||||||
|
><span class="mx-3">Restart server</span><input
|
||||||
|
type="checkbox"
|
||||||
|
id="restart"
|
||||||
|
name="restart"
|
||||||
|
checked
|
||||||
|
/></label
|
||||||
|
>
|
||||||
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
235
src/components/EditorEventRules.svelte
Normal file
235
src/components/EditorEventRules.svelte
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
|
import type { EventRules } from '$models/config';
|
||||||
|
|
||||||
|
const { config, id }: { config: EventRules; id: string } = $props();
|
||||||
|
const editedConfig = $state({ ...config });
|
||||||
|
let formLoading = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/eventRules"
|
||||||
|
use:enhance={() => {
|
||||||
|
formLoading = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="id" value={id} />
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-7xl">
|
||||||
|
<div class="border-b border-gray-900/10 pb-12">
|
||||||
|
<h2 class="text-base/7 font-semibold text-gray-900">Event Rules</h2>
|
||||||
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||||
|
<!-- Qualify Standing Type -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Qualify Standing Type:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.qualifyStandingType}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="qualifyStandingType"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pit Window Length Sec -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Pit Window Length (Sec):
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.pitWindowLengthSec}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="pitWindowLengthSec"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Driver Stint Time Sec -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Driver Stint Time (Sec):
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.driverStintTimeSec}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="driverStintTimeSec"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mandatory Pitstop Count -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Mandatory Pitstop Count:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.mandatoryPitstopCount}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="mandatoryPitstopCount"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Max Total Driving Time -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Max Total Driving Time:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.maxTotalDrivingTime}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="maxTotalDrivingTime"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Refuelling Allowed In Race -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Refuelling Allowed In Race:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isRefuellingAllowedInRace}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isRefuellingAllowedInRace"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Refuelling Time Fixed -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Refuelling Time Fixed:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isRefuellingTimeFixed}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isRefuellingTimeFixed"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Mandatory Pitstop Refuelling Required -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Mandatory Pitstop Refuelling Required:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isMandatoryPitstopRefuellingRequired}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isMandatoryPitstopRefuellingRequired"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Mandatory Pitstop Tyre Change Required -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Mandatory Pitstop Tyre Change Required:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isMandatoryPitstopTyreChangeRequired}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isMandatoryPitstopTyreChangeRequired"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Mandatory Pitstop Swap Driver Required -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Mandatory Pitstop Swap Driver Required:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isMandatoryPitstopSwapDriverRequired}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isMandatoryPitstopSwapDriverRequired"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tyre Set Count -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Tyre Set Count:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.tyreSetCount}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="tyreSetCount"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||||
|
<label
|
||||||
|
><span class="mx-3">Restart server</span><input
|
||||||
|
type="checkbox"
|
||||||
|
id="restart"
|
||||||
|
name="restart"
|
||||||
|
checked
|
||||||
|
/></label
|
||||||
|
>
|
||||||
|
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
348
src/components/EditorSettings.svelte
Normal file
348
src/components/EditorSettings.svelte
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { enhance } from '$app/forms';
|
||||||
|
import type { ServerSettings } from '$models/config';
|
||||||
|
|
||||||
|
const { config, id }: { config: ServerSettings; id: string } = $props();
|
||||||
|
const editedConfig = $state({ ...config });
|
||||||
|
let formLoading = $state(false);
|
||||||
|
const carGroups = ['FreeForAll', 'GT3', 'GT4', 'GT2', 'GTC', 'TCX'];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/settings"
|
||||||
|
use:enhance={() => {
|
||||||
|
formLoading = true;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="id" value={id} />
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-7xl">
|
||||||
|
<div class="border-b border-gray-900/10 pb-12">
|
||||||
|
<h2 class="text-base/7 font-semibold text-gray-900">Settings</h2>
|
||||||
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||||
|
<!-- Server Name -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Server Name:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.serverName}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="serverName"
|
||||||
|
type="text"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Admin Password -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Admin Password:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.adminPassword}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="adminPassword"
|
||||||
|
type="password"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Car Group -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Car Group:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.carGroup}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="carGroup"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
{#each carGroups as group}
|
||||||
|
<option value={group}>{group}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Track Medals Requirement -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Track Medals Requirement:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.trackMedalsRequirement}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="trackMedalsRequirement"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Safety Rating Requirement -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Safety Rating Requirement:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.safetyRatingRequirement}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="safetyRatingRequirement"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Racecraft Rating Requirement -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Racecraft Rating Requirement:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.racecraftRatingRequirement}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="racecraftRatingRequirement"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Password -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Password:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.password}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Spectator Password -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Spectator Password:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.spectatorPassword}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="spectatorPassword"
|
||||||
|
type="password"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Max Car Slots -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Max Car Slots:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.maxCarSlots}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="maxCarSlots"
|
||||||
|
type="number"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dump Leaderboards -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Dump Leaderboards:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.dumpLeaderboards}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="dumpLeaderboards"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Is Race Locked -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Is Race Locked:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.isRaceLocked}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="isRaceLocked"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Randomize Track When Empty -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Randomize Track When Empty:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.randomizeTrackWhenEmpty}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="randomizeTrackWhenEmpty"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Central Entry List Path -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Central Entry List Path:
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="input-block">
|
||||||
|
<input
|
||||||
|
bind:value={editedConfig.centralEntryListPath}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="centralEntryListPath"
|
||||||
|
type="text"
|
||||||
|
class="form form-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Allow Auto DQ -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Allow Auto DQ:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.allowAutoDQ}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="allowAutoDQ"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Short Formation Lap -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Short Formation Lap:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.shortFormationLap}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="shortFormationLap"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Formation Lap Type -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Formation Lap Type:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.formationLapType}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="formationLapType"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>Old Limiter Lap</option>
|
||||||
|
<option value={1}
|
||||||
|
>Free (replaces /manual start), only usable for private servers</option
|
||||||
|
>
|
||||||
|
<option value={3}>Default formation lap with position control and UI</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Ignore Premature Disconnects -->
|
||||||
|
<div class="sm:col-span-6">
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Ignore Premature Disconnects:
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<select
|
||||||
|
bind:value={editedConfig.ignorePrematureDisconnects}
|
||||||
|
disabled={formLoading}
|
||||||
|
name="ignorePrematureDisconnects"
|
||||||
|
class="form form-select"
|
||||||
|
>
|
||||||
|
<option value={0}>No</option>
|
||||||
|
<option value={1}>Yes</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||||
|
<label
|
||||||
|
><span class="mx-3">Restart server</span><input
|
||||||
|
type="checkbox"
|
||||||
|
id="restart"
|
||||||
|
name="restart"
|
||||||
|
checked
|
||||||
|
/></label
|
||||||
|
>
|
||||||
|
<button disabled={formLoading} type="submit" class="btn btn-blue">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<aside
|
<aside class="fixed top-0 left-0 z-40 h-screen w-64">
|
||||||
class="fixed top-0 left-0 z-40 h-screen w-64 -translate-x-full transition-transform sm:translate-x-0"
|
|
||||||
>
|
|
||||||
<div class="h-full overflow-y-auto bg-gray-50 px-3 py-4 dark:bg-gray-800">
|
<div class="h-full overflow-y-auto bg-gray-50 px-3 py-4 dark:bg-gray-800">
|
||||||
<ul class="space-y-2 font-medium">
|
<ul class="space-y-2 font-medium">
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import type { ServerInit } from '@sveltejs/kit';
|
import type { ServerInit } from '@sveltejs/kit';
|
||||||
import { redisSessionManager } from '$stores/redisSessionManager';
|
import { redisSessionManager } from '$stores/redisSessionManager';
|
||||||
|
import type Redis from 'ioredis';
|
||||||
|
|
||||||
|
const redisClient: Redis = redisSessionManager['redisClient'];
|
||||||
export const init: ServerInit = async () => {
|
export const init: ServerInit = async () => {
|
||||||
await redisSessionManager['redisClient'].connect();
|
console.log(redisClient.status);
|
||||||
|
if (redisClient.status == 'connect') return;
|
||||||
|
await redisClient.connect();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
let servers: Server[] = data.servers;
|
let servers: Server[] = data.servers;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>Dashboard</h1>
|
|
||||||
<div class="server-grid">
|
<div class="server-grid">
|
||||||
{#each servers as server}
|
{#each servers as server}
|
||||||
<ServerCard {server} />
|
<ServerCard {server} />
|
||||||
|
|||||||
@@ -1,41 +1,74 @@
|
|||||||
import { updateConfig, getConfigFiles, getEventFile } from '$api/serverService';
|
import { updateConfig, getConfigFiles, getServerById } from '$api/serverService';
|
||||||
import type { Actions } from './$types';
|
import type { Actions } from './$types';
|
||||||
import { checkAuth } from '$api/authService';
|
import { checkAuth } from '$api/authService';
|
||||||
import { getTracks } from '$api/lookupService';
|
import { getTracks } from '$api/lookupService';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
import type { RequestEvent } from '@sveltejs/kit';
|
import type { RequestEvent } from '@sveltejs/kit';
|
||||||
import { configFile } from '$models/config';
|
import { configFile, type Session } from '$models/config';
|
||||||
|
|
||||||
export const load = async (event: RequestEvent) => {
|
export const load = async (event: RequestEvent) => {
|
||||||
const isAuth = await checkAuth(event);
|
const isAuth = await checkAuth(event);
|
||||||
if (!isAuth) return redirect(308, '/login');
|
if (!isAuth) return redirect(308, '/login');
|
||||||
if (!event.params.id) return redirect(308, '/dashboard');
|
if (!event.params.id) return redirect(308, '/dashboard');
|
||||||
const config = await getEventFile(event, event.params.id);
|
const [server, configs, tracks] = await Promise.all([
|
||||||
const tracks = await getTracks(event);
|
getServerById(event, event.params.id),
|
||||||
|
getConfigFiles(event, event.params.id),
|
||||||
|
getTracks(event)
|
||||||
|
]);
|
||||||
return {
|
return {
|
||||||
id: event.params.id,
|
id: event.params.id,
|
||||||
config,
|
configs,
|
||||||
tracks
|
tracks,
|
||||||
|
server
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SessionField =
|
||||||
|
| 'sessionDurationMinutes'
|
||||||
|
| 'sessionType'
|
||||||
|
| 'timeMultiplier'
|
||||||
|
| 'dayOfWeekend'
|
||||||
|
| 'hourOfDay';
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
event: async (event: RequestEvent) => {
|
event: async (event: RequestEvent) => {
|
||||||
const formData = await event.request.formData();
|
const formData = await event.request.formData();
|
||||||
const id = formData.get('id') as string;
|
const id = formData.get('id') as string;
|
||||||
|
const restart = formData.get('restart') === 'true';
|
||||||
const object: any = {};
|
const object: any = {};
|
||||||
|
const sessions: Array<Record<SessionField, string | number>> = [];
|
||||||
|
formData.forEach((value, key) => {
|
||||||
|
const sessionMatch = key.match(/sessions\[(\d+)\]\[(\w+)\]/);
|
||||||
|
if (sessionMatch) {
|
||||||
|
const index = parseInt(sessionMatch[1]);
|
||||||
|
const field = sessionMatch[2] as SessionField;
|
||||||
|
|
||||||
|
if (!sessions[index]) {
|
||||||
|
sessions[index] = {
|
||||||
|
hourOfDay: 0,
|
||||||
|
dayOfWeekend: 0,
|
||||||
|
timeMultiplier: 0,
|
||||||
|
sessionType: '',
|
||||||
|
sessionDurationMinutes: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the value to the corresponding session field
|
||||||
|
sessions[index][field] = value !== '' && !Number.isNaN(+value) ? +value : (value as string);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
object.sessions = sessions;
|
||||||
formData.forEach((value, key) => {
|
formData.forEach((value, key) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'id':
|
case 'id':
|
||||||
return;
|
case 'restart':
|
||||||
case 'sessions':
|
case 'sessions':
|
||||||
object[key] = tryParse(value as string);
|
return;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
object[key] = value != '' && !Number.isNaN(+value) ? +value : value;
|
object[key] = value != '' && !Number.isNaN(+value) ? +value : value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await updateConfig(event, id, configFile.event, object, true, true);
|
await updateConfig(event, id, configFile.event, object, true, restart);
|
||||||
redirect(303, '/dashboard');
|
redirect(303, '/dashboard');
|
||||||
}
|
}
|
||||||
} satisfies Actions;
|
} satisfies Actions;
|
||||||
|
|||||||
@@ -1,11 +1,79 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ConfigEditor from '$components/ConfigEditor.svelte';
|
import EditorAssistRules from '$components/EditorAssistRules.svelte';
|
||||||
|
import EditorConfiguration from '$components/EditorConfiguration.svelte';
|
||||||
|
import EditorEvent from '$components/EditorEvent.svelte';
|
||||||
|
import EditorEventRules from '$components/EditorEventRules.svelte';
|
||||||
|
import EditorSettings from '$components/EditorSettings.svelte';
|
||||||
|
import { configFile } from '$models/config.js';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
const config = data.config;
|
const configs = data.configs;
|
||||||
const tracks = data.tracks;
|
const tracks = data.tracks;
|
||||||
const id = data.id;
|
const id = data.id;
|
||||||
|
const server = data.server;
|
||||||
|
let tab = $state(configFile.event);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>Edit</h1>
|
<aside class="fixed top-0 left-64 z-40 h-screen w-48">
|
||||||
<ConfigEditor {config} {tracks} {id} />
|
<div class="h-full overflow-y-auto bg-gray-50 px-1 py-4 dark:bg-gray-700">
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<h2 class="bold mb-5 text-gray-300">{server.name}</h2>
|
||||||
|
</div>
|
||||||
|
<ul class="space-y-2 font-medium">
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
class="btn btn-sidebar"
|
||||||
|
disabled={tab === configFile.event || !configs.event}
|
||||||
|
onclick={() => (tab = configFile.event)}
|
||||||
|
>
|
||||||
|
<span class="ms-3">Event</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sidebar"
|
||||||
|
disabled={tab === configFile.configuration || !configs.configuration}
|
||||||
|
onclick={() => (tab = configFile.configuration)}
|
||||||
|
>
|
||||||
|
<span class="ms-3">Configuration</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sidebar"
|
||||||
|
disabled={tab === configFile.settings || !configs.settings}
|
||||||
|
onclick={() => (tab = configFile.settings)}
|
||||||
|
>
|
||||||
|
<span class="ms-3">Settings</span>
|
||||||
|
</button>
|
||||||
|
{#if configs.assistRules}
|
||||||
|
<button
|
||||||
|
class="btn btn-sidebar"
|
||||||
|
disabled={tab === configFile.assistRules}
|
||||||
|
onclick={() => (tab = configFile.assistRules)}
|
||||||
|
>
|
||||||
|
<span class="ms-3">Assist Rules</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{#if configs.eventRules}
|
||||||
|
<button
|
||||||
|
class="btn btn-sidebar"
|
||||||
|
disabled={tab === configFile.eventRules}
|
||||||
|
onclick={() => (tab = configFile.eventRules)}
|
||||||
|
>
|
||||||
|
<span class="ms-3">Event Rules</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
<div class="sm:ml-48">
|
||||||
|
{#if tab === configFile.event}
|
||||||
|
<EditorEvent config={configs.event} {tracks} {id} />
|
||||||
|
{:else if tab === configFile.configuration}
|
||||||
|
<EditorConfiguration config={configs.configuration} {id} />
|
||||||
|
{:else if tab === configFile.settings}
|
||||||
|
<EditorSettings config={configs.settings} {id} />
|
||||||
|
{:else if tab === configFile.assistRules}
|
||||||
|
<EditorAssistRules config={configs.assistRules} {id} />
|
||||||
|
{:else if tab === configFile.eventRules}
|
||||||
|
<EditorEventRules config={configs.eventRules} {id} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
.btn {
|
.btn {
|
||||||
@apply mx-1 rounded px-4 py-1 font-bold;
|
@apply px-4 py-1 font-bold;
|
||||||
|
}
|
||||||
|
.btn-sidebar {
|
||||||
|
@apply flex w-full items-center p-2 dark:text-white dark:hover:bg-gray-600;
|
||||||
}
|
}
|
||||||
.btn-blue {
|
.btn-blue {
|
||||||
@apply bg-blue-500 text-white;
|
@apply rounded bg-blue-500 text-white;
|
||||||
}
|
}
|
||||||
.btn-login {
|
.btn-login {
|
||||||
@apply flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600;
|
@apply flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600;
|
||||||
}
|
}
|
||||||
.btn:hover {
|
.btn:hover {
|
||||||
@apply cursor-pointer bg-blue-700;
|
@apply cursor-pointer;
|
||||||
}
|
}
|
||||||
.btn:disabled {
|
.btn:disabled {
|
||||||
@apply cursor-default bg-blue-500 opacity-60;
|
@apply cursor-default opacity-60;
|
||||||
|
}
|
||||||
|
.btn-blue:hover {
|
||||||
|
@apply bg-blue-700;
|
||||||
|
}
|
||||||
|
.btn-sidebar:disabled {
|
||||||
|
@apply bg-gray-600;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user