WIP ui changes to handle services refactoring
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
nemunaire 2025-02-17 11:32:47 +01:00
parent 8c644db42c
commit 18464fac52
8 changed files with 123 additions and 117 deletions

View file

@ -28,3 +28,48 @@ export async function getService(domain: Domain, zoneid: string, subdomain: stri
});
return await handleApiResponse<ServiceCombined>(res);
}
// TODO -- behind this line, not worked on
export async function addServiceRecord(domain: Domain | DomainInList, id: string, service: ServiceCombined, record): Promise<Zone> {
let subdomain = service._domain;
if (subdomain === '') subdomain = '@';
const dnid = encodeURIComponent(domain.id);
id = encodeURIComponent(id);
subdomain = encodeURIComponent(subdomain);
const res = await fetch(`/api/domains/${dnid}/zone/${id}/${subdomain}/services`, {
method: 'POST',
headers: {'Accept': 'application/json'},
body: JSON.stringify(service)
});
return await handleApiResponse<Zone>(res);
}
export async function updateServiceRecord(domain: Domain | DomainInList, id: string, service: ServiceCombined, record): Promise<Zone> {
const dnid = encodeURIComponent(domain.id);
id = encodeURIComponent(id);
const res = await fetch(`/api/domains/${dnid}/zone/${id}`, {
method: 'PATCH',
headers: {'Accept': 'application/json'},
body: JSON.stringify(service),
});
return await handleApiResponse<Zone>(res);
}
export async function deleteServiceRecord(domain: Domain | DomainInList, id: string, service: ServiceMeta, record): Promise<Zone> {
let subdomain = service._domain;
if (subdomain === '') subdomain = '@';
const dnid = encodeURIComponent(domain.id);
id = encodeURIComponent(id);
subdomain = encodeURIComponent(subdomain);
const svcid = service._id?encodeURIComponent(service._id):undefined;
const res = await fetch(`/api/domains/${dnid}/zone/${id}/${subdomain}/services/${svcid}`, {
method: 'DELETE',
headers: {'Accept': 'application/json'}
});
return await handleApiResponse<Zone>(res);
}

View file

@ -22,106 +22,37 @@
-->
<script lang="ts">
import {
Button,
Col,
Icon,
Input,
Row,
} from '@sveltestrap/sveltestrap';
import { createEventDispatcher } from 'svelte';
import { nsclass, nsrrtype, rdatatostr } from '$lib/dns';
import type { ServiceRecord } from '$lib/model/zone';
import { nsrrtype, rdatatostr } from '$lib/dns';
const dispatch = createEventDispatcher();
export { className as class };
let className;
export let actBtn = false;
export let expand: boolean = false;
export let record;
function openRecord() {
dispatch('show-record', record);
}
</script>
{#if !record.edit}
<div
class="d-flex gap-1"
on:click={() => {expand = !expand}}
on:keypress={() => {expand = !expand}}
<div
class="record d-flex gap-1 {className}"
on:click={openRecord}
on:keypress={openRecord}
>
<span
class="font-monospace text-truncate"
title={rdatatostr(record)}
>
<Icon
name={expand ? "chevron-down" : "chevron-right"}
/>
<span
class="font-monospace text-truncate"
title={rdatatostr(record)}
>
{record.Hdr.Name?record.Hdr.Name:'@'} {nsrrtype(record.Hdr.Rrtype)} {rdatatostr(record)}
</span>
</div>
{#if expand}
<div class="grid mr-2">
<dl class="g-col-md-4 grid ms-2 mb-0 mt-1" style="--bs-columns: 2; --bs-gap: 0 .5rem;">
<dt class="text-end">
Class
</dt>
<dd class="text-muted font-monospace mb-1">
{nsclass(record.Hdr.Class)}
</dd>
<dt class="text-end">
TTL
</dt>
<dd class="text-muted font-monospace mb-1">
{record.Hdr.Ttl}
</dd>
<dt class="text-end">
RRType
</dt>
<dd class="text-muted font-monospace mb-1">
{nsrrtype(record.Hdr.Rrtype)} (<span title={record.Hdr.Rrtype}>0x{record.Hdr.Rrtype.toString(16)}</span>)
</dd>
</dl>
<dl class="g-col-md-8 grid me-2" style="--bs-gap: 0 .5rem;">
{#each Object.keys(record) as k}
{#if k != "Hdr"}
{@const v = record[k]}
<dt class="g-col-4 text-end">
{k}
</dt>
<dd
class="g-col-8 text-muted font-monospace text-truncate mb-1"
title={v}
>
{v}
</dd>
{/if}
{/each}
</dl>
</div>
{/if}
{:else}
<form
submit="$emit('save-rr')"
>
<Input
autofocus
class="font-monospace"
bsSize="sm"
bind:value={record.str}
/>
</form>
{/if}
{#if record.edit || actBtn}
{#if record.edit}
<Button
size="sm"
color="success"
click="$emit('save-rr')"
>
<Icon name="check" aria-hidden="true" />
</Button>
{:else if record.rr.Hdr.Rrtype != 6}
<Button
size="sm"
color="danger"
click="$emit('delete-rr')"
>
<Icon name="trash-fill" aria-hidden="true" />
</Button>
{/if}
{/if}
{record.Hdr.Name?record.Hdr.Name:'@'} {nsrrtype(record.Hdr.Rrtype)} {rdatatostr(record)}
</span>
</div>
<style>
.record:hover {
background: #ccc;
}
</style>

View file

@ -66,7 +66,7 @@
let showDetails = false;
function toggleDetails() {
if (component == Card) {
if ($userSession.settings.zoneview === ZoneViewGrid || $userSession.settings.zoneview === ZoneViewRecords) {
dispatch("show-service", service);
} else if (service) {
showDetails = !showDetails;
@ -147,15 +147,16 @@
</CardBody>
{:else if service && ($userSession.settings.zoneview === ZoneViewList || $userSession.settings.zoneview === ZoneViewRecords)}
<ListGroupItem
class="px-2"
on:click={toggleDetails}
>
<strong title={$servicesSpecs[service._svctype].description}>
{$servicesSpecs[service._svctype].name}
</strong>
{#if $servicesSpecs[service._svctype].description}
<span class="text-muted">
<small class="text-muted">
{$servicesSpecs[service._svctype].description}
</span>
</small>
{/if}
{#if $servicesSpecs[service._svctype].categories}
{#each $servicesSpecs[service._svctype].categories as category}
@ -165,7 +166,7 @@
{/each}
{/if}
{#if service._comment}
<span class="float-end text-muted">
<span class="fst-italic float-end text-muted">
{service._comment}
</span>
{/if}
@ -184,7 +185,10 @@
</ListGroupItem>
{:else if $userSession.settings.zoneview === ZoneViewRecords}
<ListGroupItem class="p-0">
<TableRecords service={service.Service} />
<TableRecords
service={service.Service}
on:show-record={(e) => dispatch("show-record", {record: e.detail, service})}
/>
</ListGroupItem>
{/if}
{/if}

View file

@ -78,6 +78,10 @@
);
}
function showRecordModal({record, service}) {
dispatch("show-record", {record, service});
}
function showServiceModal(service: ServiceCombined) {
dispatch("show-service", service);
}
@ -305,6 +309,7 @@
{origin}
{service}
{zoneId}
on:show-record={(event) => showRecordModal(event.detail)}
on:show-service={(event) => showServiceModal(event.detail)}
on:update-zone-services={(event) => dispatch("update-zone-services", event.detail)}
/>

View file

@ -26,6 +26,7 @@
import AliasModal, { controls as ctrlAlias } from '$lib/components/domains/AliasModal.svelte';
import { controls as ctrlNewService } from '$lib/components/NewServicePath.svelte';
import { controls as ctrlRecord } from '$lib/components/domains/RecordModal.svelte';
import { controls as ctrlService } from '$lib/components/domains/ServiceModal.svelte';
import SubdomainItem from '$lib/components/domains/SubdomainItem.svelte';
import type { Domain } from '$lib/model/domain';
@ -65,6 +66,10 @@
ctrlNewSubdomain.Open();
}
function showRecordModal(event) {
ctrlRecord.Open(event.detail);
}
function showServiceModal(event: CustomEvent<ServiceCombined>) {
ctrlService.Open(event.detail);
}
@ -79,6 +84,7 @@
services={zone.services[dn]?zone.services[dn]:[]}
on:new-alias={() => ctrlAlias.Open(dn)}
on:new-service={() => ctrlNewService.Open(dn)}
on:show-record={showRecordModal}
on:show-service={showServiceModal}
on:update-zone-services={(event) => dispatch("update-zone-services", event.detail)}
/>

View file

@ -22,22 +22,12 @@
-->
<script lang="ts">
import {
Badge,
Card,
CardBody,
CardText,
CardTitle,
CardSubtitle,
Icon,
ListGroup,
ListGroupItem,
Table,
Spinner,
} from '@sveltestrap/sveltestrap';
import { createEventDispatcher } from 'svelte';
import Record from '$lib/components/domains/Record.svelte';
const dispatch = createEventDispatcher();
export let service = null;
</script>
@ -53,7 +43,11 @@
class="bg-light p-1 border-1 border-bottom"
style="border-color: darkgray"
>
<Record {record} />
<Record
class="mx-1"
{record}
on:show-record={(e) => dispatch("show-record", e.detail)}
/>
</div>
{:else if record && record.length}
{#each record as r}
@ -61,7 +55,11 @@
class="bg-light p-1 border-1 border-bottom"
style="border-color: darkgray"
>
<Record record={r} />
<Record
class="mx-1"
record={r}
on:show-record={(e) => dispatch("show-record", e.detail)}
/>
</div>
{/each}
{/if}

View file

@ -66,6 +66,7 @@
},
"domains": {
"kind": "domain",
"subdomain": "subdomain",
"actions": {
"audit": "View changes logs",
"do-migration": "Migrate now",
@ -303,6 +304,16 @@
"ttl-long": "Time-To-Live",
"ttl-tip": "0 means default TTL, others values are exprimed in seconds"
},
"records": {
"add": "Add record",
"class": "Class",
"delete": "Delete this record",
"update": "Update this record",
"form-new": "Add a new record to {{domain}}",
"new": "New record",
"rrtype": "type",
"ttl": "Time-to-live"
},
"sessions": {
"close-all": "Terminate all sessions",
"create": "Create API key",

View file

@ -29,6 +29,7 @@
} from '@sveltestrap/sveltestrap';
import NewServicePath from '$lib/components/NewServicePath.svelte';
import RecordModal from '$lib/components/domains/RecordModal.svelte';
import ServiceModal from '$lib/components/domains/ServiceModal.svelte';
import type { Domain } from '$lib/model/domain';
import { domains_idx } from '$lib/stores/domains';
@ -63,6 +64,11 @@
origin={data.domain}
zone={zone}
/>
<RecordModal
origin={data.domain}
zone={zone}
on:update-zone-services={(event) => thisZone.set(event.detail)}
/>
<ServiceModal
origin={data.domain}
zone={zone}