Use shared form controls and enforce UI patterns (Refs #110)
CI / checks (push) Successful in 4m51s
CI / checks (push) Successful in 4m51s
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Field from '$ui/components/primitives/Field.svelte';
|
||||
import Select from '$ui/components/primitives/Select.svelte';
|
||||
import Input from '$ui/components/primitives/Input.svelte';
|
||||
import { onMount, untrack } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { pollVisible } from '$ui/poll.js';
|
||||
@@ -109,21 +112,26 @@
|
||||
>{/if}
|
||||
</div>
|
||||
{#if filtersVisible}<div class="filters">
|
||||
<input
|
||||
type="search"
|
||||
aria-label="Search hosts"
|
||||
placeholder="Search hosts…"
|
||||
bind:value={search}
|
||||
/>
|
||||
<select aria-label="Filter hosts by status" bind:value={status}
|
||||
><option value="">All statuses</option><option value="attention"
|
||||
>Needs attention</option
|
||||
><option value="offline">Offline</option><option value="preparing"
|
||||
>Preparing</option
|
||||
><option value="draining">Draining</option><option value="disabled"
|
||||
>Disabled</option
|
||||
><option value="deleting">Deleting</option><option value="ready">Ready</option
|
||||
></select
|
||||
<Field label="Search hosts" hiddenLabel class="search"
|
||||
><Input
|
||||
type="search"
|
||||
aria-label="Search hosts"
|
||||
placeholder="Search hosts…"
|
||||
bind:value={search}
|
||||
/></Field
|
||||
>
|
||||
<Field label="Filter hosts by status" hiddenLabel
|
||||
><Select aria-label="Filter hosts by status" bind:value={status}
|
||||
><option value="">All statuses</option><option value="attention"
|
||||
>Needs attention</option
|
||||
><option value="offline">Offline</option><option value="preparing"
|
||||
>Preparing</option
|
||||
><option value="draining">Draining</option><option value="disabled"
|
||||
>Disabled</option
|
||||
><option value="deleting">Deleting</option><option value="ready"
|
||||
>Ready</option
|
||||
></Select
|
||||
></Field
|
||||
>
|
||||
{#if search || status}<Button
|
||||
variant="ghost"
|
||||
@@ -170,27 +178,15 @@
|
||||
font: inherit;
|
||||
padding: 4px;
|
||||
}
|
||||
input,
|
||||
select {
|
||||
box-sizing: border-box;
|
||||
padding: 10px 12px;
|
||||
color: var(--text-primary);
|
||||
background: var(--surface-sunken);
|
||||
border: 1px solid var(--border-control);
|
||||
border-radius: var(--radius-sm);
|
||||
font: var(--text-sm) var(--font-body);
|
||||
}
|
||||
input {
|
||||
flex: 1 1 240px;
|
||||
min-width: 0;
|
||||
max-width: 440px;
|
||||
}
|
||||
input:focus-visible,
|
||||
select:focus-visible,
|
||||
|
||||
button:focus-visible {
|
||||
outline: 2px solid var(--accent-primary);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
.filters > :global(.search) {
|
||||
flex: 1 1 240px;
|
||||
max-width: 440px;
|
||||
}
|
||||
.empty {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Input from '$ui/components/primitives/Input.svelte';
|
||||
import Field from '$ui/components/primitives/Field.svelte';
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import RelativeTime from '$ui/components/RelativeTime.svelte';
|
||||
import Breadcrumbs from '$ui/components/primitives/Breadcrumbs.svelte';
|
||||
@@ -468,11 +470,8 @@
|
||||
}}
|
||||
>
|
||||
<fieldset disabled={busy || cleaning}>
|
||||
<label
|
||||
>Plutainer image<input
|
||||
required
|
||||
bind:value={runtimeImage}
|
||||
/></label
|
||||
<Field label="Plutainer image">
|
||||
<Input required bind:value={runtimeImage} /></Field
|
||||
><Button type="submit" disabled={busy || !host.connected}
|
||||
>Pull runtime image</Button
|
||||
>
|
||||
@@ -509,50 +508,43 @@
|
||||
<h2>Host configuration</h2>
|
||||
{#if canManage}<form onsubmit={save}>
|
||||
<fieldset disabled={busy || cleaning}>
|
||||
<label
|
||||
>Friendly name<input
|
||||
required
|
||||
maxlength="200"
|
||||
bind:value={name}
|
||||
/></label
|
||||
<Field label="Friendly name">
|
||||
<Input required maxlength={200} bind:value={name} /></Field
|
||||
>
|
||||
<div class="fields">
|
||||
<label
|
||||
>First game port<input
|
||||
<Field label="First game port">
|
||||
<Input
|
||||
type="number"
|
||||
min="1"
|
||||
max="65535"
|
||||
required
|
||||
bind:value={portMin}
|
||||
/></label
|
||||
><label
|
||||
>Last game port<input
|
||||
/></Field
|
||||
><Field label="Last game port">
|
||||
<Input
|
||||
type="number"
|
||||
min={portMin}
|
||||
max="65535"
|
||||
required
|
||||
bind:value={portMax}
|
||||
/></label
|
||||
/></Field
|
||||
>
|
||||
</div>
|
||||
<label
|
||||
>Local bind address<input
|
||||
required
|
||||
bind:value={bindAddress}
|
||||
/></label
|
||||
><label
|
||||
>Public / NAT address<input
|
||||
<Field label="Local bind address">
|
||||
<Input required bind:value={bindAddress} /></Field
|
||||
><Field label="Public / NAT address">
|
||||
<Input
|
||||
bind:value={publicAddress}
|
||||
placeholder="Optional public hostname or address"
|
||||
/></label
|
||||
><label
|
||||
>Minimum free game storage (GiB)<input
|
||||
/></Field
|
||||
><Field label="Minimum free game storage (GiB)">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.1"
|
||||
required
|
||||
bind:value={minimumFreeGB}
|
||||
/></label
|
||||
/></Field
|
||||
><Button type="submit" disabled={busy}>Save settings</Button>
|
||||
</fieldset>
|
||||
</form>{:else}<dl>
|
||||
@@ -745,20 +737,7 @@
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 10px;
|
||||
color: var(--text-primary);
|
||||
background: var(--surface-sunken);
|
||||
border: 1px solid var(--border-control);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.fields > * {
|
||||
flex: 1;
|
||||
min-width: 120px;
|
||||
|
||||
Reference in New Issue
Block a user