Improve aspect of zone page, ensure long domains doesn't extend display

This commit is contained in:
nemunaire 2025-04-22 12:32:22 +02:00
parent dad3e411cd
commit 9be4b48676
8 changed files with 189 additions and 141 deletions

View file

@ -390,8 +390,8 @@
"exporting": "Please wait while we export your zone…",
"formating": "Please wait while we format your zone…",
"importing": "Please wait while we are importing your domain…",
"loading": "Loading the domain…",
"loading-account": "Loading your account …",
"loading": "Loading domain's services …",
"loading-account": "Loading your account…",
"loading-record": "Loading records…",
"retrieving-setting": "Retrieving host settings' form...",
"updating": "Updating your domain name host",

View file

@ -354,9 +354,9 @@
"exporting": "Veuillez patienter pendant l'export de votre domaine…",
"formating": "Veuillez patienter pendant le formattage de votre zone…",
"importing": "Veuillez patienter pendant l'import de votre domaine…",
"loading": "Chargement du domaine",
"loading-account": "Chargement de votre compte",
"loading-record": "Chargement des enregistrements",
"loading": "Chargement des services du domaine.",
"loading-account": "Chargement de votre compte.",
"loading-record": "Chargement des enregistrements.",
"retrieving-setting": "Récupération du formulaire de paramètrage de l'hôte...",
"updating": "Mise à jour de l'hôte de votre domaine",
"validating": "Validation du domaine…",

View file

@ -183,7 +183,7 @@
<Icon name="chevron-left" />
Retour à la zone
</Button>
{:else if $sortedDomains && $sortedDomainsWithIntermediate}
{:else}
<div class="d-flex gap-2 pb-2 sticky-top" style="padding-top: 10px">
<Button
type="button"
@ -191,6 +191,7 @@
outline
size="sm"
class="flex-fill"
disabled={!$sortedDomains}
on:click={() => ctrlNewSubdomain.Open()}
>
<Icon name="server" />
@ -215,7 +216,7 @@
{$t("domains.actions.audit")}
</DropdownItem>
<DropdownItem divider />
<DropdownItem on:click={viewZone}>
<DropdownItem on:click={viewZone} disabled={!$sortedDomains}>
{$t("domains.actions.view")}
</DropdownItem>
<DropdownItem on:click={retrieveZone}>
@ -243,96 +244,115 @@
</DropdownMenu>
</ButtonDropdown>
</div>
<div style="min-height:0; overflow-y: auto;">
{#if isReverseZone(data.domain.domain)}
<SubdomainListTiny domains={$sortedDomains} origin={data.domain} />
<div style="min-height:0; overflow-y: auto;" class="placeholder-glow">
{#if $sortedDomains && $thisZone.id == selectedHistory}
{#if isReverseZone(data.domain.domain)}
<SubdomainListTiny domains={$sortedDomains} origin={data.domain} />
{:else}
<SubdomainListTiny
domains={$sortedDomainsWithIntermediate}
origin={data.domain}
/>
{/if}
{:else}
<SubdomainListTiny
domains={$sortedDomainsWithIntermediate}
origin={data.domain}
/>
<span class="d-block text-truncate font-monospace text-muted">
{data.domain.domain}
</span>
<span class="d-block placeholder ms-3 mb-1">
{data.domain.domain}
</span>
<span class="d-block placeholder ms-3 mb-1">
{data.domain.domain}
</span>
<span class="d-block placeholder ms-4 mb-1">
{data.domain.domain}
</span>
<span class="d-block placeholder ms-4 mb-1">
{data.domain.domain}
</span>
<span class="d-block placeholder ms-3">
{data.domain.domain}
</span>
{/if}
</div>
{/if}
<div class="flex-fill" />
{#if $page.data.isZonePage && data.domain.zone_history && $domains_idx[selectedDomain] && data.domain.id === $domains_idx[selectedDomain].id}
{#if !$sortedDomainsWithIntermediate}
<Button
color="danger"
class="mt-3"
outline
on:click={() => ctrlDomainDelete.Open()}
>
<Icon name="trash" />
{$t("domains.stop")}
</Button>
{:else if $domains_idx[selectedDomain].zone_history && selectedHistory === $domains_idx[selectedDomain].zone_history[0]}
<Button
size="lg"
color="success"
title={$t("domains.actions.propagate")}
on:click={showDiff}
>
<Icon name="cloud-upload" aria-hidden="true" />
{$t("domains.actions.propagate")}
</Button>
<p class="mt-2 mb-1 text-center">
{#key $thisZone}
{#await APIDiffZone(data.domain, "@", selectedHistory)}
{$t("wait.wait")}
{:then zoneDiff}
<DiffSummary {zoneDiff} />
{/await}
{/key}
</p>
{:else}
<Button
size="lg"
color="warning"
title={$t("domains.actions.rollback")}
on:click={showDiff}
>
<Icon name="cloud-upload" aria-hidden="true" />
{$t("domains.actions.rollback")}
</Button>
<p class="mt-2 mb-1 text-center">
{#await getDomain(data.domain.id)}
Chargement des informations de l'historique
{:then domain}
{#if domain.zone_meta && domain.zone_meta[selectedHistory]}
{@const history = domain.zone_meta[selectedHistory]}
<div class="text-truncate">
{#if history.published}
Publiée le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.published))}
{:else if history.commit_date}
Enregistrée le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.commit_date))}
{:else}
Dernière modification le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.last_modified))}
{/if}
</div>
{#if history.commit_message}
<div class="text-truncate" title={history.commit_message}>
{history.commit_message}
</div>
{/if}
{/if}
{#if !($page.data.isZonePage && data.domain.zone_history && $domains_idx[selectedDomain] && data.domain.id === $domains_idx[selectedDomain].id && $sortedDomainsWithIntermediate)}
<Button
color="danger"
class="mt-3"
outline
on:click={() => ctrlDomainDelete.Open()}
>
<Icon name="trash" />
{$t("domains.stop")}
</Button>
{:else if $domains_idx[selectedDomain].zone_history && selectedHistory === $domains_idx[selectedDomain].zone_history[0]}
<Button
size="lg"
color="success"
title={$t("domains.actions.propagate")}
on:click={showDiff}
>
<Icon name="cloud-upload" aria-hidden="true" />
{$t("domains.actions.propagate")}
</Button>
<p class="mt-2 mb-1 text-center">
{#key $thisZone}
{#await APIDiffZone(data.domain, "@", selectedHistory)}
{$t("wait.wait")}
{:then zoneDiff}
<DiffSummary {zoneDiff} />
{/await}
</p>
{/if}
{/key}
</p>
{:else}
<Button
size="lg"
color="warning"
title={$t("domains.actions.rollback")}
on:click={showDiff}
>
<Icon name="cloud-upload" aria-hidden="true" />
{$t("domains.actions.rollback")}
</Button>
<p class="mt-2 mb-1 text-center">
{#await getDomain(data.domain.id)}
Chargement des informations de l'historique
{:then domain}
{#if domain.zone_meta && domain.zone_meta[selectedHistory]}
{@const history = domain.zone_meta[selectedHistory]}
<div class="text-truncate">
{#if history.published}
Publiée le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.published))}
{:else if history.commit_date}
Enregistrée le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.commit_date))}
{:else}
Dernière modification le
{new Intl.DateTimeFormat(undefined, {
dateStyle: "long",
timeStyle: "long",
}).format(new Date(history.last_modified))}
{/if}
</div>
{#if history.commit_message}
<div class="text-truncate" title={history.commit_message}>
{history.commit_message}
</div>
{/if}
{/if}
{/await}
</p>
{/if}
{:else}
<div class="mt-4 text-center">

View file

@ -51,7 +51,7 @@
</script>
<Modal {isOpen} size="lg" {toggle}>
<ModalHeader {toggle}>{$t("domains.removal")}</ModalHeader>
<ModalHeader class="bg-danger-subtle" {toggle}>{$t("domains.removal")}</ModalHeader>
<ModalBody>
{$t("domains.alert.remove")}
</ModalBody>

View file

@ -24,7 +24,7 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { page } from "$app/stores";
import { onDestroy } from 'svelte';
import { onDestroy } from "svelte";
import { Spinner } from "@sveltestrap/sveltestrap";
@ -59,7 +59,10 @@
const unsubscribe = thisZone.subscribe(async (zone) => {
if (zone != null && zone.id != selectedHistory) {
if ($domains_idx[selectedDomain].zone_history.indexOf(zone.id) == -1) {
if (
!$domains_idx[selectedDomain] ||
$domains_idx[selectedDomain].zone_history.indexOf(zone.id) == -1
) {
await refreshDomains();
}
selectedHistory = zone.id;
@ -73,18 +76,25 @@
{#if $thisZone && $thisZone.id == selectedHistory}
<slot />
{:else}
<div class="mt-5 text-center flex-fill">
<Spinner label="Spinning" />
<p>{$t("wait.loading")}</p>
</div>
{/if}
{#if $thisZone}
<NewServicePath origin={data.domain} zone={$thisZone} />
<ServiceModal
origin={data.domain}
zone={$thisZone}
on:update-zone-services={(event) => thisZone.set(event.detail)}
/>
{:else}
<div class="flex-fill d-flex flex-column">
<h2 class="d-flex align-items-center">
<Spinner label="Spinning" type="grow" />
<span class="ms-2 mt-1 font-monospace">
{data.domain.domain}
</span>
</h2>
<div class="mt-4 text-center flex-fill">
<Spinner label="Spinning" />
<p>{$t("wait.loading")}</p>
</div>
</div>
{/if}

View file

@ -29,11 +29,7 @@
import type { Zone } from "$lib/model/zone";
import { domains_idx } from "$lib/stores/domains";
import { servicesSpecs, refreshServicesSpecs } from "$lib/stores/services";
import {
sortedDomains,
sortedDomainsWithIntermediate,
thisZone,
} from "$lib/stores/thiszone";
import { sortedDomains, sortedDomainsWithIntermediate, thisZone } from "$lib/stores/thiszone";
import { t } from "$lib/translations";
if (!$servicesSpecs) refreshServicesSpecs();

View file

@ -80,8 +80,8 @@
{#if services.length === 0}
<div id={dn}>
{#if !reverseZone}
<h2 class="sticky-top bg-light" style="z-index: 1">
<span style="white-space: nowrap">
<h2 class="sticky-top bg-light d-flex align-items-center" style="z-index: 1">
<span class="text-truncate text-muted">
<Icon name="plus-square-dotted" title="Intermediate domain with no service" />
<span class="font-monospace" title={fqdn(dn, origin.domain)}>
{#if reverseZone}
@ -91,23 +91,24 @@
{/if}
</span>
</span>
<div class="flex-fill"></div>
<Button
type="button"
color="primary"
size="sm"
class="ml-2"
class="ms-2"
title={$t("service.add")}
on:click={() => dispatch("new-service")}
>
<Icon name="plus" />
{$t("service.add")}
</Button>
</h2>
{/if}
</div>
{:else if isCNAME(services) || isPTR(services)}
<div id={dn}>
<h2 class="sticky-top bg-light" style="z-index: 1">
<span style="white-space: nowrap">
<h2 class="sticky-top bg-light d-flex align-items-center" style="z-index: 1">
<span class="text-truncate">
{#if isPTR(services)}
<Icon name="signpost" title="PTR" />
{:else}
@ -121,32 +122,23 @@
{/if}
</span>
</span>
<span style="white-space: nowrap">
<span class="text-truncate">
<Icon name="arrow-right" />
<span class="font-monospace">
<span class="font-monospace" title={services[0].Service.Target}>
{services[0].Service.Target}
</span>
</span>
<Button
type="button"
color="primary"
size="sm"
class="ml-2"
on:click={() => dispatch("new-service")}
>
<Icon name="plus" />
{$t("service.add")}
</Button>
<div class="flex-fill"></div>
<Button
type="button"
color="info"
outline
size="sm"
class="ml-2"
class="ms-2"
title={$t("domains.edit-target")}
on:click={() => showServiceModal(services[0])}
>
<Icon name="pencil" />
{$t("domains.edit-target")}
</Button>
<Button
type="button"
@ -154,7 +146,8 @@
disabled={deleteServiceInProgress}
outline
size="sm"
class="ml-2"
class="ms-2"
title={isPTR(services) ? $t("domains.drop-pointer") : $t("domains.drop-alias")}
on:click={deleteCNAME}
>
{#if deleteServiceInProgress}
@ -162,11 +155,16 @@
{:else}
<Icon name="x-circle" />
{/if}
{#if isPTR(services)}
{$t("domains.drop-pointer")}
{:else}
{$t("domains.drop-alias")}
{/if}
</Button>
<Button
type="button"
color="primary"
size="sm"
class="ms-2"
title={$t("service.add")}
on:click={() => dispatch("new-service")}
>
<Icon name="plus" />
</Button>
</h2>
</div>
@ -226,15 +224,16 @@
{/each}
</Popover>
{/if}
<div class="flex-fill"></div>
{#if !showResources || ($userSession && $userSession.settings.zoneview !== ZoneViewGrid)}
<Button
type="button"
color="primary"
size="sm"
title={$t("domains.add-a-service")}
on:click={() => dispatch("new-service")}
>
<Icon name="plus" />
{$t("domains.add-a-service")}
</Button>
{/if}
{#if showResources}
@ -243,10 +242,10 @@
color="primary"
outline
size="sm"
title={$t("domains.add-an-alias")}
on:click={() => dispatch("new-alias")}
>
<Icon name="link" />
{$t("domains.add-an-alias")}
</Button>
{/if}
</div>

View file

@ -41,16 +41,39 @@
);
</script>
<div class="mt-4 text-center flex-fill">
{#await rz}
<Spinner label={$t("common.spinning")} />
<p>{$t("wait.importing")}</p>
{:then}
<p>{$t("wait.wait")}</p>
{:catch main_error}
{#await rz}
<div class="flex-fill d-flex flex-column">
<h2 class="d-flex align-items-center">
<Spinner label="Spinning" type="grow" />
<span class="ms-2 mt-1 font-monospace">
{data.domain.domain}
</span>
</h2>
<div class="mt-4 text-center flex-fill">
<Spinner label={$t("common.spinning")} />
<p>{$t("wait.importing")}</p>
</div>
</div>
{:then}
<div class="flex-fill d-flex flex-column">
<h2 class="d-flex align-items-center">
<Spinner label="Spinning" type="grow" />
<span class="ms-2 mt-1 font-monospace">
{data.domain.domain}
</span>
</h2>
<div class="mt-4 text-center flex-fill">
<Spinner label={$t("common.spinning")} />
<p>{$t("wait.wait")}</p>
</div>
</div>
{:catch main_error}
<div class="mt-4 text-center flex-fill">
<Alert color="danger" fade={false}>
<strong>{$t("errors.domain-import")}</strong>
{main_error}
</Alert>
{/await}
</div>
</div>
{/await}