ui: Huge modals refactor
This commit is contained in:
parent
f70943cff3
commit
5939df0455
|
@ -0,0 +1,30 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import ServiceSelectorModal, { controls as ctrlServiceSelector } from '$lib/components/domains/ServiceSelectorModal.svelte';
|
||||
import { controls as ctrlService } from '$lib/components/domains/ServiceModal.svelte';
|
||||
import type { Domain, DomainInList } from '$lib/model/domain';
|
||||
import type { ServiceCombined } from '$lib/model/service';
|
||||
import type { Zone } from '$lib/model/zone';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let origin: DomainInList | Domain;
|
||||
export let zone: Zone;
|
||||
|
||||
function Open(domain: string): void {
|
||||
ctrlServiceSelector.Open(domain);
|
||||
}
|
||||
|
||||
controls.Open = Open;
|
||||
</script>
|
||||
|
||||
<ServiceSelectorModal
|
||||
{origin}
|
||||
zservices={zone.services}
|
||||
on:show-next-modal={(event) => ctrlService.Open(event.detail)}
|
||||
/>
|
|
@ -0,0 +1,26 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import NewSubdomainModal, { controls as ctrlNewSubdomainModal } from '$lib/components/domains/NewSubdomainModal.svelte';
|
||||
import { controls as ctrlServicePath } from '$lib/components/NewServicePath.svelte';
|
||||
import type { Domain, DomainInList } from '$lib/model/domain';
|
||||
import type { ServiceCombined } from '$lib/model/service';
|
||||
import type { Zone } from '$lib/model/zone';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let origin: DomainInList | Domain;
|
||||
|
||||
controls.Open = () => {
|
||||
ctrlNewSubdomainModal.Open();
|
||||
}
|
||||
</script>
|
||||
|
||||
<NewSubdomainModal
|
||||
{origin}
|
||||
on:show-next-modal={(event) => ctrlServicePath.Open(event.detail)}
|
||||
/>
|
|
@ -1,3 +1,7 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
|
@ -93,6 +97,13 @@
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
function Open(domain: string): void {
|
||||
dn = domain;
|
||||
isOpen = true;
|
||||
}
|
||||
|
||||
controls.Open = Open;
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
|
@ -22,8 +26,6 @@
|
|||
export let isOpen = false;
|
||||
const toggle = () => (isOpen = !isOpen);
|
||||
|
||||
$: if (isOpen) value = "";
|
||||
|
||||
export let origin: Domain | DomainInList;
|
||||
export let value: string = "";
|
||||
|
||||
|
@ -61,6 +63,13 @@
|
|||
dispatch("show-next-modal", value);
|
||||
}
|
||||
}
|
||||
|
||||
function Open(domain): void {
|
||||
isOpen = true;
|
||||
value = '';
|
||||
}
|
||||
|
||||
controls.Open = Open;
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
|
@ -23,9 +27,10 @@
|
|||
const toggle = () => (isOpen = !isOpen);
|
||||
|
||||
export let origin: Domain | DomainInList;
|
||||
export let service: ServiceCombined;
|
||||
export let zone: Zone;
|
||||
|
||||
let service: ServiceCombined | undefined = undefined;
|
||||
|
||||
let addServiceInProgress = false;
|
||||
let deleteServiceInProgress = false;
|
||||
|
||||
|
@ -64,8 +69,16 @@
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
function Open(svc: ServiceCombined): void {
|
||||
service = svc;
|
||||
isOpen = true;
|
||||
}
|
||||
|
||||
controls.Open = Open;
|
||||
</script>
|
||||
|
||||
{#if service && service._domain !== undefined}
|
||||
<Modal
|
||||
{isOpen}
|
||||
{toggle}
|
||||
|
@ -108,3 +121,4 @@
|
|||
on:delete-service={deleteService}
|
||||
/>
|
||||
</Modal>
|
||||
{/if}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
<script context="module" lang="ts">
|
||||
export const controls = { };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
|
@ -18,12 +22,6 @@
|
|||
export let isOpen = false;
|
||||
const toggle = () => (isOpen = !isOpen);
|
||||
|
||||
$: {
|
||||
if (isOpen) {
|
||||
value = "";
|
||||
}
|
||||
}
|
||||
|
||||
export let dn: string;
|
||||
export let origin: Domain | DomainInList;
|
||||
export let value: string | null = null;
|
||||
|
@ -35,6 +33,14 @@
|
|||
dispatch("show-next-modal", {_svctype: value, _domain: dn, Service: { }});
|
||||
}
|
||||
}
|
||||
|
||||
function Open(domain: string): void {
|
||||
dn = domain;
|
||||
isOpen = true;
|
||||
value = '';
|
||||
}
|
||||
|
||||
controls.Open = Open;
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
export let aliases: Array<string> = [];
|
||||
export let dn: string;
|
||||
export let origin: Domain | DomainInList;
|
||||
export let showSubdomainsList = false;
|
||||
export let services: Array<ServiceCombined>;
|
||||
export let zoneId: string;
|
||||
|
||||
|
@ -179,18 +178,6 @@
|
|||
<Icon name="link" />
|
||||
{$t('domains.add-an-alias')}
|
||||
</Button>
|
||||
{#if !showSubdomainsList && !dn}
|
||||
<Button
|
||||
type="button"
|
||||
color="secondary"
|
||||
outline
|
||||
size="sm"
|
||||
on:click={() => dispatch("new-subdomain")}
|
||||
>
|
||||
<Icon name="server" />
|
||||
{$t('domains.add-a-subdomain')}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if showResources}
|
||||
<div
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
import AliasModal from '$lib/components/domains/AliasModal.svelte';
|
||||
import NewSubdomainModal from '$lib/components/domains/NewSubdomainModal.svelte';
|
||||
import ServiceModal from '$lib/components/domains/ServiceModal.svelte';
|
||||
import ServiceSelectorModal from '$lib/components/domains/ServiceSelectorModal.svelte';
|
||||
import AliasModal, { controls as ctrlAlias } from '$lib/components/domains/AliasModal.svelte';
|
||||
import { controls as ctrlNewService } from '$lib/components/NewServicePath.svelte';
|
||||
import { controls as ctrlService } from '$lib/components/domains/ServiceModal.svelte';
|
||||
import SubdomainItem from '$lib/components/domains/SubdomainItem.svelte';
|
||||
import type { Domain, DomainInList } from '$lib/model/domain';
|
||||
import type { ServiceCombined } from '$lib/model/service';
|
||||
|
@ -13,7 +12,6 @@
|
|||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let origin: DomainInList | Domain;
|
||||
export let showSubdomainsList: boolean;
|
||||
export let sortedDomains: Array<string>;
|
||||
export let zone: Zone;
|
||||
|
||||
|
@ -33,26 +31,18 @@
|
|||
}
|
||||
})
|
||||
}
|
||||
if (tmp['@']) tmp[""] = tmp["@"];
|
||||
|
||||
aliases = tmp;
|
||||
}
|
||||
|
||||
export let newSubdomainModalOpened = false;
|
||||
let subdomainModal = "";
|
||||
let newAliasModalOpened = false;
|
||||
|
||||
let serviceSelectorModalOpened = false;
|
||||
let serviceSelectedModal: string | null = null;
|
||||
function showServiceSelectorModal(subdomain: string) {
|
||||
subdomainModal = subdomain;
|
||||
serviceSelectorModalOpened = true;
|
||||
$: if (newSubdomainModalOpened) {
|
||||
ctrlNewSubdomain.Open();
|
||||
}
|
||||
|
||||
let serviceModalOpened = false;
|
||||
let serviceModalService: ServiceCombined | null = null;
|
||||
function showServiceModal(event: CustomEvent<ServiceCombined>) {
|
||||
serviceModalService = event.detail;
|
||||
serviceModalOpened = true;
|
||||
ctrlService.Open(event.detail);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -61,43 +51,16 @@
|
|||
aliases={aliases[dn]?aliases[dn]:[]}
|
||||
{dn}
|
||||
{origin}
|
||||
{showSubdomainsList}
|
||||
zoneId={zone.id}
|
||||
services={zone.services[dn]?zone.services[dn]:[]}
|
||||
on:new-alias={() => {subdomainModal = dn; newAliasModalOpened = true;}}
|
||||
on:new-service={() => showServiceSelectorModal(dn)}
|
||||
on:new-subdomain={() => newSubdomainModalOpened = true}
|
||||
on:new-alias={() => ctrlAlias.Open(dn)}
|
||||
on:new-service={() => ctrlNewService.Open(dn)}
|
||||
on:show-service={showServiceModal}
|
||||
on:update-zone-services={(event) => dispatch("update-zone-services", event.detail)}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<NewSubdomainModal
|
||||
bind:isOpen={newSubdomainModalOpened}
|
||||
{origin}
|
||||
bind:value={subdomainModal}
|
||||
on:show-next-modal={(event) => showServiceSelectorModal(event.detail)}
|
||||
/>
|
||||
<ServiceSelectorModal
|
||||
bind:isOpen={serviceSelectorModalOpened}
|
||||
dn={subdomainModal}
|
||||
{origin}
|
||||
bind:value={serviceSelectedModal}
|
||||
zservices={zone.services}
|
||||
on:show-next-modal={showServiceModal}
|
||||
/>
|
||||
{#if serviceModalService}
|
||||
<ServiceModal
|
||||
bind:isOpen={serviceModalOpened}
|
||||
{origin}
|
||||
service={serviceModalService}
|
||||
{zone}
|
||||
on:update-zone-services={(event) => dispatch("update-zone-services", event.detail)}
|
||||
/>
|
||||
{/if}
|
||||
<AliasModal
|
||||
bind:isOpen={newAliasModalOpened}
|
||||
dn={subdomainModal}
|
||||
{origin}
|
||||
{zone}
|
||||
on:update-zone-services={(event) => dispatch("update-zone-services", event.detail)}
|
||||
|
|
|
@ -41,3 +41,20 @@ export const domains_idx = derived(
|
|||
return idx;
|
||||
},
|
||||
);
|
||||
|
||||
export const domains_by_groups = derived(
|
||||
domains,
|
||||
($domains: null|Array<DomainInList>) => {
|
||||
const groups: Record<string, Array<DomainInList>> = { };
|
||||
|
||||
for (const domain of $domains) {
|
||||
if (groups[domain.group] === undefined) {
|
||||
groups[domain.group] = [];
|
||||
}
|
||||
|
||||
groups[domain.group].push(domain);
|
||||
}
|
||||
|
||||
return groups;
|
||||
},
|
||||
);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { derived, writable, type Writable } from 'svelte/store';
|
||||
import { domainCompare } from '$lib/dns';
|
||||
import {
|
||||
retrieveZone as APIRetrieveZone,
|
||||
getZone as APIGetZone,
|
||||
} from '$lib/api/zone';
|
||||
import type { Zone } from '$lib/model/zone';
|
||||
import { refreshDomains } from '$lib/stores/domains';
|
||||
|
||||
export const thisZone: Writable<null | Zone> = writable(null);
|
||||
|
||||
export const sortedDomains = derived(
|
||||
thisZone,
|
||||
($thisZone: null|Zone) => {
|
||||
if (!$thisZone) {
|
||||
return null;
|
||||
}
|
||||
if (!$thisZone.services) {
|
||||
return [];
|
||||
}
|
||||
const domains = Object.keys($thisZone.services);
|
||||
domains.sort(domainCompare);
|
||||
return domains;
|
||||
},
|
||||
);
|
||||
|
||||
export async function getZone(domain: string, zoneId: string) {
|
||||
thisZone.set(null);
|
||||
|
||||
const zone = await APIGetZone(domain, zoneId);
|
||||
|
||||
thisZone.set(zone);
|
||||
|
||||
return zone;
|
||||
}
|
||||
|
||||
export async function retrieveZone(domain: string) {
|
||||
const meta = await APIRetrieveZone(domain);
|
||||
await refreshDomains();
|
||||
return meta;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { get_store_value } from 'svelte/internal';
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
|
||||
import { providers, refreshProviders } from '$lib/stores/providers';
|
||||
|
||||
export const load: Load = async({ parent }) => {
|
||||
const data = await parent();
|
||||
|
||||
if (!get_store_value(providers)) await refreshProviders();
|
||||
|
||||
return data;
|
||||
}
|
|
@ -1,15 +1,24 @@
|
|||
import { error } from '@sveltejs/kit';
|
||||
import { get_store_value } from 'svelte/internal';
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
|
||||
import { domains, refreshDomains } from '$lib/stores/domains';
|
||||
import { domains, domains_idx, refreshDomains } from '$lib/stores/domains';
|
||||
|
||||
export const load: Load = async({ parent, params }) => {
|
||||
const data = await parent();
|
||||
|
||||
if (!get_store_value(domains)) await refreshDomains();
|
||||
|
||||
const domain: DomainInList | null = get_store_value(domains_idx)[params.dn];
|
||||
|
||||
if (!domain) {
|
||||
throw error(404, {
|
||||
message: 'Domain not found'
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
domain: params.dn,
|
||||
domain,
|
||||
...data,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { tick } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { goto, invalidateAll } from '$app/navigation';
|
||||
|
||||
// @ts-ignore
|
||||
import { escape } from 'html-escaper';
|
||||
|
@ -24,124 +24,70 @@
|
|||
getDomain as APIGetDomain,
|
||||
deleteDomain as APIDeleteDomain,
|
||||
} from '$lib/api/domains';
|
||||
import {
|
||||
retrieveZone as APIRetrieveZone,
|
||||
} from '$lib/api/zone';
|
||||
import ImgProvider from '$lib/components/providers/ImgProvider.svelte';
|
||||
import ModalDiffZone, { controls as ctrlDiffZone } from '$lib/components/ModalDiffZone.svelte';
|
||||
import ModalDomainDelete, { controls as ctrlDomainDelete } from '$lib/components/ModalDomainDelete.svelte';
|
||||
import ModalUploadZone, { controls as ctrlUploadZone } from '$lib/components/ModalUploadZone.svelte';
|
||||
import ModalViewZone, { controls as ctrlViewZone } from '$lib/components/ModalViewZone.svelte';
|
||||
import NewSubdomainPath, { controls as ctrlNewSubdomain } from '$lib/components/NewSubdomainPath.svelte';
|
||||
import NewServicePath from '$lib/components/NewServicePath.svelte';
|
||||
import NewSubdomainModal from '$lib/components/domains/NewSubdomainModal.svelte';
|
||||
import ServiceModal from '$lib/components/domains/ServiceModal.svelte';
|
||||
import { fqdn } from '$lib/dns';
|
||||
import type { Domain, DomainInList } from '$lib/model/domain';
|
||||
import type { ZoneMeta } from '$lib/model/zone';
|
||||
import { domains, domains_idx, refreshDomains } from '$lib/stores/domains';
|
||||
import { providers, providers_idx, refreshProviders } from '$lib/stores/providers';
|
||||
import { domains, domains_by_groups, domains_idx, refreshDomains } from '$lib/stores/domains';
|
||||
import { retrieveZone as StoreRetrieveZone, sortedDomains, thisZone } from '$lib/stores/thiszone';
|
||||
import { t } from '$lib/translations';
|
||||
|
||||
export let data: {domain: string; history: string;};
|
||||
export let data: {domain: DomainInList; history: string;};
|
||||
|
||||
let selectedDomain = data.domain;
|
||||
$: if (selectedDomain != data.domain) {
|
||||
main_error = null;
|
||||
let selectedDomain = data.domain.domain;
|
||||
$: if (selectedDomain != data.domain.domain) {
|
||||
goto('/domains/' + encodeURIComponent(selectedDomain));
|
||||
}
|
||||
|
||||
if (!$domains) refreshDomains();
|
||||
if (!$providers) refreshProviders();
|
||||
|
||||
let domainsByGroup: Record<string, Array<DomainInList>> = {};
|
||||
$: {
|
||||
if ($domains) {
|
||||
const tmp: Record<string, Array<DomainInList>> = { };
|
||||
|
||||
for (const domain of $domains) {
|
||||
if (tmp[domain.group] === undefined) {
|
||||
tmp[domain.group] = [];
|
||||
}
|
||||
|
||||
tmp[domain.group].push(domain);
|
||||
}
|
||||
|
||||
domainsByGroup = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
let main_error: string | null = null;
|
||||
|
||||
let selectedHistory: string | undefined;
|
||||
$: selectedHistory = data.history;
|
||||
$: if (!data.history && $domains_idx[selectedDomain] && $domains_idx[selectedDomain].zone_history && $domains_idx[selectedDomain].zone_history.length > 0) {
|
||||
selectedHistory = $domains_idx[selectedDomain].zone_history[0] as string;
|
||||
}
|
||||
$: if (selectedHistory && data.history != selectedHistory) {
|
||||
main_error = null;
|
||||
//goto('/domains/' + encodeURIComponent(selectedDomain) + '/' + encodeURIComponent(selectedHistory));
|
||||
goto('/domains/' + encodeURIComponent(selectedDomain) + '/' + encodeURIComponent(selectedHistory));
|
||||
}
|
||||
|
||||
let retrievalInProgress = false;
|
||||
function retrieveZone(): void {
|
||||
if (domain) {
|
||||
retrievalInProgress = true;
|
||||
APIRetrieveZone(domain).then(
|
||||
retrieveZoneDone,
|
||||
(err: any) => {
|
||||
retrievalInProgress = false;
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
async function retrieveZone(): void {
|
||||
retrievalInProgress = true;
|
||||
retrieveZoneDone(await StoreRetrieveZone(data.domain));
|
||||
}
|
||||
|
||||
function retrieveZoneDone(zm: ZoneMeta): void {
|
||||
retrievalInProgress = false;
|
||||
refreshDomains();
|
||||
selectedHistory = zm.id;
|
||||
main_error = null;
|
||||
if (data.history) {
|
||||
selectedHistory = zm.id;
|
||||
} else {
|
||||
invalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
async function getDomain(id: string): Promise<Domain> {
|
||||
return await APIGetDomain(id);
|
||||
}
|
||||
|
||||
let domain: null | Domain = null;
|
||||
$: if ($domains_idx[selectedDomain]) {
|
||||
if (!$domains_idx[selectedDomain].zone_history || $domains_idx[selectedDomain].zone_history.length == 0) {
|
||||
retrievalInProgress = true;
|
||||
APIRetrieveZone($domains_idx[selectedDomain]).then(
|
||||
retrieveZoneDone,
|
||||
(err: any) => {
|
||||
retrievalInProgress = false;
|
||||
|
||||
tick().then(() => {
|
||||
main_error = err.toString();
|
||||
});
|
||||
}
|
||||
)
|
||||
} else {
|
||||
domain = null;
|
||||
getDomain($domains_idx[selectedDomain].id).then(
|
||||
(dn) => {
|
||||
domain = dn;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function viewZone(): void {
|
||||
if (!domain || !selectedHistory) {
|
||||
if (!selectedHistory) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctrlViewZone.Open(domain, selectedHistory);
|
||||
ctrlViewZone.Open(data.domain, selectedHistory);
|
||||
}
|
||||
|
||||
function showDiff(): void {
|
||||
if (!domain || !selectedHistory) {
|
||||
if (!selectedHistory) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctrlDiffZone.Open(domain, selectedHistory);
|
||||
ctrlDiffZone.Open(data.domain, selectedHistory);
|
||||
}
|
||||
|
||||
let deleteInProgress = false;
|
||||
|
@ -187,8 +133,8 @@
|
|||
type="select"
|
||||
bind:value={selectedDomain}
|
||||
>
|
||||
{#each Object.keys(domainsByGroup) as gname}
|
||||
{@const group = domainsByGroup[gname]}
|
||||
{#each Object.keys($domains_by_groups) as gname}
|
||||
{@const group = $domains_by_groups[gname]}
|
||||
<optgroup label={gname=="undefined"?$t("domaingroups.no-group"):gname}>
|
||||
{#each group as domain}
|
||||
<option value={domain.domain}>{domain.domain}</option>
|
||||
|
@ -198,7 +144,7 @@
|
|||
</Input>
|
||||
</div>
|
||||
|
||||
{#if data && data.streamed && data.streamed.sortedDomains}
|
||||
{#if data && data.streamed && $sortedDomains}
|
||||
<div class="d-flex gap-2 pb-2 sticky-top bg-light" style="padding-top: 10px">
|
||||
<Button
|
||||
type="button"
|
||||
|
@ -206,6 +152,7 @@
|
|||
outline
|
||||
size="sm"
|
||||
class="flex-fill"
|
||||
on:click={() => ctrlNewSubdomain.Open()}
|
||||
>
|
||||
<Icon name="server" />
|
||||
{$t('domains.add-a-subdomain')}
|
||||
|
@ -216,19 +163,23 @@
|
|||
outline
|
||||
size="sm"
|
||||
>
|
||||
<Icon name="wrench-adjustable-circle" aria-hidden="true" />
|
||||
{#if retrievalInProgress}
|
||||
<Spinner size="sm" />
|
||||
{:else}
|
||||
<Icon name="wrench-adjustable-circle" aria-hidden="true" />
|
||||
{/if}
|
||||
</DropdownToggle>
|
||||
<DropdownMenu>
|
||||
<DropdownItem header class="font-monospace">
|
||||
{data.selectedDomain.domain}
|
||||
{data.domain.domain}
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
href={`/domains/${data.selectedDomain.domain}/history`}
|
||||
href={`/domains/${data.domain.domain}/history`}
|
||||
>
|
||||
{$t('domains.actions.history')}
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
href={`/domains/${data.selectedDomain.domain}/logs`}
|
||||
href={`/domains/${data.domain.domain}/logs`}
|
||||
>
|
||||
{$t('domains.actions.audit')}
|
||||
</DropdownItem>
|
||||
|
@ -266,16 +217,16 @@
|
|||
</DropdownMenu>
|
||||
</ButtonDropdown>
|
||||
</div>
|
||||
{#await data.streamed.sortedDomains then sortedDomains}
|
||||
{#await data.streamed.zone then z}
|
||||
<div style="min-height:0; overflow-y: auto;">
|
||||
{#each sortedDomains as dn}
|
||||
{#each $sortedDomains as dn}
|
||||
<a
|
||||
href={'#' + (dn?dn:'@')}
|
||||
title={fqdn(dn, data.selectedDomain.domain)}
|
||||
title={fqdn(dn, data.domain.domain)}
|
||||
class="d-block text-truncate font-monospace text-muted text-decoration-none"
|
||||
style={'max-width: none; padding-left: ' + (dn === '' ? 0 : (dn.split('.').length * 10)) + 'px'}
|
||||
>
|
||||
{fqdn(dn, data.selectedDomain.domain)}
|
||||
{fqdn(dn, data.domain.domain)}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -284,7 +235,7 @@
|
|||
|
||||
<div class="flex-fill" />
|
||||
|
||||
{#if domain && domain.zone_history && $domains_idx[selectedDomain] && domain.id === $domains_idx[selectedDomain].id}
|
||||
{#if data.domain.zone_history && $domains_idx[selectedDomain] && data.domain.id === $domains_idx[selectedDomain].id}
|
||||
<ButtonGroup class="mt-2 w-100">
|
||||
{#if $domains_idx[selectedDomain].zone_history && selectedHistory === $domains_idx[selectedDomain].zone_history[0]}
|
||||
<Button
|
||||
|
@ -323,17 +274,7 @@
|
|||
md={9}
|
||||
class="d-flex"
|
||||
>
|
||||
{#if main_error}
|
||||
<div class="d-flex flex-column mt-4">
|
||||
<Alert
|
||||
color="danger"
|
||||
fade={false}
|
||||
>
|
||||
<strong>{$t('errors.domain-import')}</strong>
|
||||
{main_error}
|
||||
</Alert>
|
||||
</div>
|
||||
{:else if data.history == selectedHistory}
|
||||
{#if data.history == selectedHistory}
|
||||
<slot />
|
||||
{:else}
|
||||
<div class="mt-5 text-center flex-fill">
|
||||
|
@ -345,8 +286,23 @@
|
|||
</Row>
|
||||
</Container>
|
||||
|
||||
<NewSubdomainPath
|
||||
origin={data.domain}
|
||||
/>
|
||||
{#await data.streamed.zone then zone}
|
||||
<NewServicePath
|
||||
origin={data.domain}
|
||||
{zone}
|
||||
/>
|
||||
<ServiceModal
|
||||
origin={data.domain}
|
||||
{zone}
|
||||
on:update-zone-services={(event) => thisZone.set(event.detail)}
|
||||
/>
|
||||
{/await}
|
||||
|
||||
<ModalUploadZone
|
||||
{domain}
|
||||
domain={data.domain}
|
||||
{selectedHistory}
|
||||
on:retrieveZoneDone={retrieveZoneDone}
|
||||
/>
|
||||
|
@ -358,7 +314,7 @@
|
|||
<ModalViewZone />
|
||||
|
||||
<ModalDiffZone
|
||||
{domain}
|
||||
domain={data.domain}
|
||||
{selectedHistory}
|
||||
on:retrieveZoneDone={retrieveZoneDone}
|
||||
/>
|
||||
|
|
|
@ -2,29 +2,21 @@ import { get_store_value } from 'svelte/internal';
|
|||
import { error, redirect } from '@sveltejs/kit';
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
|
||||
import { getZone } from '$lib/api/zone';
|
||||
import { domainCompare } from '$lib/dns';
|
||||
import { domains_idx } from '$lib/stores/domains';
|
||||
import { getZone } from '$lib/stores/thiszone';
|
||||
|
||||
export const load: Load = async({ parent, params }) => {
|
||||
const data = await parent();
|
||||
|
||||
const domain: DomainInList | null = get_store_value(domains_idx)[data.domain];
|
||||
const domain = data.domain;
|
||||
|
||||
if (domain === null) {
|
||||
throw error(404, {
|
||||
message: 'Domain not found'
|
||||
});
|
||||
}
|
||||
if (!domain.zone_history || domain.zone_history.length === 0) {
|
||||
throw error(500, {
|
||||
message: 'Domain not initialized'
|
||||
});
|
||||
throw redirect(307, `/domains/${data.domain.domain}/import_zone`);
|
||||
}
|
||||
|
||||
if (!params.historyid) {
|
||||
params.historyid = domain.zone_history[0];
|
||||
//throw redirect(307, `/domains/${data.domain}/${domain.zone_history[0]}`);
|
||||
//throw redirect(307, `/domains/${data.domain.domain}/${domain.zone_history[0]}`);
|
||||
}
|
||||
|
||||
const zhidx = domain.zone_history.indexOf(params.historyid);
|
||||
|
@ -38,22 +30,11 @@ export const load: Load = async({ parent, params }) => {
|
|||
|
||||
const zone = getZone(domain, zoneId);
|
||||
|
||||
const sortedDomains = zone.then((z) => {
|
||||
if (!z.services) {
|
||||
return [];
|
||||
}
|
||||
const domains = Object.keys(z.services);
|
||||
domains.sort(domainCompare);
|
||||
return domains;
|
||||
})
|
||||
|
||||
return {
|
||||
history: params.historyid,
|
||||
selectedDomain: domain,
|
||||
zoneId,
|
||||
streamed: {
|
||||
zone,
|
||||
sortedDomains,
|
||||
},
|
||||
...data,
|
||||
}
|
||||
|
|
|
@ -13,21 +13,20 @@
|
|||
import type { Zone } from '$lib/model/zone';
|
||||
import { domains_idx } from '$lib/stores/domains';
|
||||
import { servicesSpecs, refreshServicesSpecs } from '$lib/stores/services';
|
||||
import { retrieveZone, sortedDomains, thisZone } from '$lib/stores/thiszone';
|
||||
import { t } from '$lib/translations';
|
||||
|
||||
if (!$servicesSpecs) refreshServicesSpecs();
|
||||
|
||||
export let data: {domain: string; selectedDomain: DomainInList; history: string; zoneId: string; streamed: Object};
|
||||
|
||||
export let newSubdomainModalOpened = false;
|
||||
export let data: {domain: DomainInList; history: string; zoneId: string; streamed: Object};
|
||||
</script>
|
||||
|
||||
{#if !data.selectedDomain}
|
||||
{#if !data.domain}
|
||||
<div class="mt-5 text-center flex-fill">
|
||||
<Spinner label="Spinning" />
|
||||
<p>{$t('wait.loading')}</p>
|
||||
</div>
|
||||
{:else if !data.selectedDomain.zone_history || data.selectedDomain.zone_history.length == 0}
|
||||
{:else if !data.domain.zone_history || data.domain.zone_history.length == 0}
|
||||
<div class="mt-4 text-center flex-fill">
|
||||
<Spinner label={$t('common.spinning')} />
|
||||
<p>{$t('wait.importing')}</p>
|
||||
|
@ -39,23 +38,15 @@
|
|||
<p>{$t('wait.loading')}</p>
|
||||
</div>
|
||||
{:then zone}
|
||||
{#if zone}
|
||||
{#await data.streamed.sortedDomains}
|
||||
<div class="mt-4 text-center flex-fill">
|
||||
<Spinner label={$t('common.spinning')} />
|
||||
<p>{$t('wait.loading')}</p>
|
||||
</div>
|
||||
{:then sortedDomains}
|
||||
<div style="max-width: 100%;" class="pt-1">
|
||||
<SubdomainList
|
||||
origin={data.selectedDomain}
|
||||
{sortedDomains}
|
||||
{zone}
|
||||
bind:newSubdomainModalOpened={newSubdomainModalOpened}
|
||||
on:update-zone-services={(event) => zone = event.detail}
|
||||
/>
|
||||
</div>
|
||||
{/await}
|
||||
{#if zone && $sortedDomains}
|
||||
<div style="max-width: 100%;" class="pt-1">
|
||||
<SubdomainList
|
||||
origin={data.domain}
|
||||
sortedDomains={$sortedDomains}
|
||||
zone={$thisZone}
|
||||
on:update-zone-services={(event) => thisZone.set(event.detail)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import {
|
||||
Alert,
|
||||
Icon,
|
||||
Spinner,
|
||||
} from 'sveltestrap';
|
||||
|
||||
import type { DomainInList } from '$lib/model/domain';
|
||||
import { retrieveZone } from '$lib/stores/thiszone';
|
||||
import { t } from '$lib/translations';
|
||||
|
||||
export let data: {domain: DomainInList;};
|
||||
|
||||
let rz = retrieveZone(data.domain);
|
||||
rz.then(() => {
|
||||
goto(`/domains/${encodeURIComponent(data.domain.domain)}`);
|
||||
}, (e) => { })
|
||||
</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}
|
||||
<Alert
|
||||
color="danger"
|
||||
fade={false}
|
||||
>
|
||||
<strong>{$t('errors.domain-import')}</strong>
|
||||
{main_error}
|
||||
</Alert>
|
||||
{/await}
|
||||
</div>
|
Loading…
Reference in New Issue