mirror of
https://github.com/1f349/admin.1f349.com.git
synced 2025-02-22 05:24:57 +00:00
Start working on domain management tab
This commit is contained in:
parent
f55e6c798a
commit
2f6d043b63
53
src/components/domains/ARow.svelte
Normal file
53
src/components/domains/ARow.svelte
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {isAaaaRecord, isARecord, type AaaaRecord, type ARecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<ARecord | AaaaRecord>;
|
||||||
|
let editItem: ARecord & AaaaRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
A: "",
|
||||||
|
AAAA: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">{isARecord(value.data) ? value.data.A : isAaaaRecord(value.data) ? value.data.AAAA : ""}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit {isARecord(value.data) ? 'A' : 'AAAA'} Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
{#if isARecord(value.data)}
|
||||||
|
<div>IPv4 Address</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.A} size={Math.max(20, editItem.A.length + 2)} /></div>
|
||||||
|
{:else if isAaaaRecord(value.data)}
|
||||||
|
<div>IPv6 Address</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.AAAA} size={Math.max(20, editItem.AAAA.length + 2)} /></div>
|
||||||
|
{:else}
|
||||||
|
<div>Pretty sure something is broken. WOMP WOMP!!</div>
|
||||||
|
{/if}
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
45
src/components/domains/CnameRow.svelte
Normal file
45
src/components/domains/CnameRow.svelte
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {CnameRecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<CnameRecord>;
|
||||||
|
let editItem: CnameRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
Target: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">{value.data.Target}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit CNAME Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
<div>Target</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Target} size={Math.max(20, editItem.Target.length + 2)} /></div>
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
49
src/components/domains/MxRow.svelte
Normal file
49
src/components/domains/MxRow.svelte
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {MxRecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<MxRecord>;
|
||||||
|
let editItem: MxRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
Mx: "",
|
||||||
|
Preference: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">{value.data.Mx}</td>
|
||||||
|
<td class="code-font">{value.data.Preference}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit SOA Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
<div>Mail Server</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Mx} size={Math.max(20, editItem.Mx.length + 2)} /></div>
|
||||||
|
<div>Preference</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Preference} size={Math.max(20, editItem.Preference.length + 2)} /></div>
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
45
src/components/domains/NsRow.svelte
Normal file
45
src/components/domains/NsRow.svelte
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {NsRecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<NsRecord>;
|
||||||
|
let editItem: NsRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
Ns: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">{value.data.Ns}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit SOA Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
<div>Nameserver</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Ns} size={Math.max(20, editItem.Ns.length + 2)} /></div>
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
63
src/components/domains/SoaRow.svelte
Normal file
63
src/components/domains/SoaRow.svelte
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {SoaRecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<SoaRecord>;
|
||||||
|
let editItem: SoaRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
Ns: "",
|
||||||
|
Mbox: "",
|
||||||
|
Serial: 0,
|
||||||
|
Refresh: 0,
|
||||||
|
Retry: 0,
|
||||||
|
Expire: 0,
|
||||||
|
Minttl: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">{value.data.Mbox}</td>
|
||||||
|
<td class="code-font">{value.data.Minttl}</td>
|
||||||
|
<td class="code-font">{value.data.Refresh}</td>
|
||||||
|
<td class="code-font">{value.data.Retry}</td>
|
||||||
|
<td class="code-font">{value.data.Expire}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit SOA Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
<div>Mailbox</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Mbox} size={Math.max(20, editItem.Mbox.length + 2)} /></div>
|
||||||
|
<div>Minimum Time-to-Live</div>
|
||||||
|
<div><input type="number" class="code-font" bind:value={editItem.Minttl} size={Math.max(20, editItem.Minttl.length + 2)} /></div>
|
||||||
|
<div>Refresh</div>
|
||||||
|
<div><input type="number" class="code-font" bind:value={editItem.Refresh} size={Math.max(20, editItem.Refresh.length + 2)} /></div>
|
||||||
|
<div>Retry</div>
|
||||||
|
<div><input type="number" class="code-font" bind:value={editItem.Retry} size={Math.max(20, editItem.Retry.length + 2)} /></div>
|
||||||
|
<div>Expire</div>
|
||||||
|
<div><input type="number" class="code-font" bind:value={editItem.Expire} size={Math.max(20, editItem.Expire.length + 2)} /></div>
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
47
src/components/domains/TxtRow.svelte
Normal file
47
src/components/domains/TxtRow.svelte
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type {TxtRecord} from "../../stores/records";
|
||||||
|
import type {RestItem} from "../../utils/rest-table";
|
||||||
|
import ActionMenu from "../ActionMenu.svelte";
|
||||||
|
import ActionPopup from "../ActionPopup.svelte";
|
||||||
|
|
||||||
|
export let value: RestItem<TxtRecord>;
|
||||||
|
let editItem: TxtRecord = {
|
||||||
|
Hdr: {
|
||||||
|
Name: "",
|
||||||
|
Rrtype: 0,
|
||||||
|
Class: 0,
|
||||||
|
Ttl: 0,
|
||||||
|
},
|
||||||
|
Txt: [""],
|
||||||
|
};
|
||||||
|
|
||||||
|
let editPopup: boolean = false;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
value.update(editItem);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="code-font">{value.data.Hdr.Name}</td>
|
||||||
|
<td class="code-font">
|
||||||
|
<span class="cutoff">{value.data.Txt.join("\n")}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu
|
||||||
|
data={value}
|
||||||
|
edit={() => {
|
||||||
|
editItem = JSON.parse(JSON.stringify(value.data));
|
||||||
|
editPopup = true;
|
||||||
|
}}
|
||||||
|
remove={() => value.remove()}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ActionPopup name="Edit TXT Record" bind:show={editPopup} on:save={save}>
|
||||||
|
<div>Name</div>
|
||||||
|
<div class="code-font">{editItem.Hdr.Name}</div>
|
||||||
|
<div>Value</div>
|
||||||
|
<div><input type="text" class="code-font" bind:value={editItem.Txt[0]} size={Math.max(20, editItem.Txt[0].length + 2)} /></div>
|
||||||
|
</ActionPopup>
|
||||||
|
</td>
|
||||||
|
</tr>
|
@ -1,4 +1,12 @@
|
|||||||
import {writable} from "svelte/store";
|
export const DnsTypeSOA = 6;
|
||||||
|
export const DnsTypeNS = 2;
|
||||||
|
export const DnsTypeMX = 15;
|
||||||
|
export const DnsTypeA = 1;
|
||||||
|
export const DnsTypeAAAA = 28;
|
||||||
|
export const DnsTypeCNAME = 5;
|
||||||
|
export const DnsTypeTXT = 16;
|
||||||
|
export const DnsTypeSRV = 33;
|
||||||
|
export const DnsTypeCAA = 257;
|
||||||
|
|
||||||
export interface RecordHeader {
|
export interface RecordHeader {
|
||||||
Name: string;
|
Name: string;
|
||||||
@ -22,72 +30,58 @@ export interface SoaRecord extends UnknownRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isSoaRecord(x: UnknownRecord): x is SoaRecord {
|
export function isSoaRecord(x: UnknownRecord): x is SoaRecord {
|
||||||
return x.Hdr.Rrtype === 6;
|
return x.Hdr.Rrtype === DnsTypeSOA;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const soaRecords = writable<Array<SoaRecord>>([]);
|
|
||||||
|
|
||||||
export interface NsRecord extends UnknownRecord {
|
export interface NsRecord extends UnknownRecord {
|
||||||
Ns: string;
|
Ns: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNsRecord(x: UnknownRecord): x is NsRecord {
|
export function isNsRecord(x: UnknownRecord): x is NsRecord {
|
||||||
return x.Hdr.Rrtype === 2;
|
return x.Hdr.Rrtype === DnsTypeNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const nsRecords = writable<Array<NsRecord>>([]);
|
|
||||||
|
|
||||||
export interface MxRecord extends UnknownRecord {
|
export interface MxRecord extends UnknownRecord {
|
||||||
Preference: number;
|
Preference: number;
|
||||||
Mx: string;
|
Mx: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMxRecord(x: UnknownRecord): x is MxRecord {
|
export function isMxRecord(x: UnknownRecord): x is MxRecord {
|
||||||
return x.Hdr.Rrtype === 15;
|
return x.Hdr.Rrtype === DnsTypeMX;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mxRecords = writable<Array<MxRecord>>([]);
|
|
||||||
|
|
||||||
export interface ARecord extends UnknownRecord {
|
export interface ARecord extends UnknownRecord {
|
||||||
A: string;
|
A: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isARecord(x: UnknownRecord): x is ARecord {
|
export function isARecord(x: UnknownRecord): x is ARecord {
|
||||||
return x.Hdr.Rrtype === 1;
|
return x.Hdr.Rrtype === DnsTypeA;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const aRecords = writable<Array<ARecord>>([]);
|
|
||||||
|
|
||||||
export interface AaaaRecord extends UnknownRecord {
|
export interface AaaaRecord extends UnknownRecord {
|
||||||
AAAA: string;
|
AAAA: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isAaaaRecord(x: UnknownRecord): x is AaaaRecord {
|
export function isAaaaRecord(x: UnknownRecord): x is AaaaRecord {
|
||||||
return x.Hdr.Rrtype === 28;
|
return x.Hdr.Rrtype === DnsTypeAAAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const aaaaRecords = writable<Array<AaaaRecord>>([]);
|
|
||||||
|
|
||||||
export interface CnameRecord extends UnknownRecord {
|
export interface CnameRecord extends UnknownRecord {
|
||||||
Target: string;
|
Target: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCnameRecord(x: UnknownRecord): x is CnameRecord {
|
export function isCnameRecord(x: UnknownRecord): x is CnameRecord {
|
||||||
return x.Hdr.Rrtype === 5;
|
return x.Hdr.Rrtype === DnsTypeCNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cnameRecords = writable<Array<CnameRecord>>([]);
|
|
||||||
|
|
||||||
export interface TxtRecord extends UnknownRecord {
|
export interface TxtRecord extends UnknownRecord {
|
||||||
Txt: Array<string>;
|
Txt: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTxtRecord(x: UnknownRecord): x is TxtRecord {
|
export function isTxtRecord(x: UnknownRecord): x is TxtRecord {
|
||||||
return x.Hdr.Rrtype === 16;
|
return x.Hdr.Rrtype === DnsTypeTXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const txtRecords = writable<Array<TxtRecord>>([]);
|
|
||||||
|
|
||||||
export interface SrvRecord extends UnknownRecord {
|
export interface SrvRecord extends UnknownRecord {
|
||||||
Priority: number;
|
Priority: number;
|
||||||
Weight: number;
|
Weight: number;
|
||||||
@ -96,11 +90,9 @@ export interface SrvRecord extends UnknownRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isSrvRecord(x: UnknownRecord): x is SrvRecord {
|
export function isSrvRecord(x: UnknownRecord): x is SrvRecord {
|
||||||
return x.Hdr.Rrtype === 33;
|
return x.Hdr.Rrtype === DnsTypeSRV;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const srvRecords = writable<Array<SrvRecord>>([]);
|
|
||||||
|
|
||||||
export interface CaaRecord extends UnknownRecord {
|
export interface CaaRecord extends UnknownRecord {
|
||||||
Flag: number;
|
Flag: number;
|
||||||
Tag: string;
|
Tag: string;
|
||||||
@ -108,7 +100,5 @@ export interface CaaRecord extends UnknownRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isCaaRecord(x: UnknownRecord): x is CaaRecord {
|
export function isCaaRecord(x: UnknownRecord): x is CaaRecord {
|
||||||
return x.Hdr.Rrtype === 257;
|
return x.Hdr.Rrtype === DnsTypeCAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const caaRecords = writable<Array<CaaRecord>>([]);
|
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
import {LOGIN} from "../utils/login";
|
import {LOGIN} from "../utils/login";
|
||||||
import {domainOption} from "../stores/domain-option";
|
import {domainOption} from "../stores/domain-option";
|
||||||
import {
|
import {
|
||||||
aRecords,
|
DnsTypeSOA,
|
||||||
aaaaRecords,
|
|
||||||
caaRecords,
|
|
||||||
cnameRecords,
|
|
||||||
isARecord,
|
isARecord,
|
||||||
isAaaaRecord,
|
isAaaaRecord,
|
||||||
isCaaRecord,
|
isCaaRecord,
|
||||||
@ -15,38 +12,50 @@
|
|||||||
isSoaRecord,
|
isSoaRecord,
|
||||||
isSrvRecord,
|
isSrvRecord,
|
||||||
isTxtRecord,
|
isTxtRecord,
|
||||||
mxRecords,
|
type ARecord,
|
||||||
nsRecords,
|
type AaaaRecord,
|
||||||
soaRecords,
|
type CaaRecord,
|
||||||
srvRecords,
|
type CnameRecord,
|
||||||
txtRecords,
|
type MxRecord,
|
||||||
|
type NsRecord,
|
||||||
|
type SoaRecord,
|
||||||
|
type SrvRecord,
|
||||||
|
type TxtRecord,
|
||||||
type UnknownRecord,
|
type UnknownRecord,
|
||||||
} from "../stores/records";
|
} from "../stores/records";
|
||||||
import ActionMenu from "../components/ActionMenu.svelte";
|
import ActionMenu from "../components/ActionMenu.svelte";
|
||||||
|
import PromiseTable from "../components/PromiseTable.svelte";
|
||||||
|
import {RestItem, RestTable} from "../utils/rest-table";
|
||||||
|
import PromiseLike from "../components/PromiseLike.svelte";
|
||||||
|
import SoaRow from "../components/domains/SoaRow.svelte";
|
||||||
|
|
||||||
const apiAzalea = import.meta.env.VITE_API_AZALEA;
|
const apiAzalea = import.meta.env.VITE_API_AZALEA;
|
||||||
|
|
||||||
let promiseForTable: Promise<void> = reloadTable();
|
type AllRecords = SoaRecord | NsRecord | MxRecord | ARecord | AaaaRecord | CnameRecord | TxtRecord | SrvRecord | CaaRecord;
|
||||||
|
|
||||||
async function reloadTable(): Promise<void> {
|
const table = new RestTable<AllRecords>(apiAzalea + "/domains/" + $domainOption + "/records", (item: AllRecords) => item.Hdr.Name);
|
||||||
let f = await LOGIN.clientRequest(apiAzalea + "/domains/" + $domainOption + "/records", {});
|
|
||||||
if (f.status != 200) throw new Error("Unexpected status code: " + f.status);
|
function rowOrdering<T extends UnknownRecord>(
|
||||||
let fJson = await f.json();
|
rows: RestItem<UnknownRecord>[],
|
||||||
let rows = fJson as Array<UnknownRecord>;
|
domain: string,
|
||||||
$soaRecords = rows.filter(isSoaRecord);
|
isTRecord: (t: UnknownRecord) => t is T,
|
||||||
$nsRecords = rows.filter(isNsRecord);
|
): RestItem<T>[] {
|
||||||
$mxRecords = rows.filter(isMxRecord);
|
return rows
|
||||||
$aRecords = rows.filter(isARecord);
|
.filter(x => isTRecord(x.data))
|
||||||
$aaaaRecords = rows.filter(isAaaaRecord);
|
.filter(x => domainFilter(x.data.Hdr.Name, domain))
|
||||||
$cnameRecords = rows.filter(isCnameRecord);
|
.sort((a, b) => a.data.Hdr.Name.localeCompare(b.data.Hdr.Name)) as unknown as RestItem<T>[];
|
||||||
$txtRecords = rows.filter(isTxtRecord);
|
|
||||||
$srvRecords = rows.filter(isSrvRecord);
|
|
||||||
$caaRecords = rows.filter(isCaaRecord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
domainOption.subscribe(x => {
|
function domainFilter(src: string, domain: string) {
|
||||||
promiseForTable = reloadTable();
|
if (domain == "*") return true;
|
||||||
});
|
let n = src.indexOf("/");
|
||||||
|
if (n == -1) n = src.length;
|
||||||
|
let p = src.slice(0, n);
|
||||||
|
if (p == domain) return true;
|
||||||
|
return p.endsWith(domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
domainOption.subscribe(() => table.reload());
|
||||||
|
|
||||||
function getTitleDomain(name: string): string {
|
function getTitleDomain(name: string): string {
|
||||||
if (name.endsWith(".")) {
|
if (name.endsWith(".")) {
|
||||||
@ -54,266 +63,309 @@
|
|||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let soaRecords: SoaRecord[] = [
|
||||||
|
{
|
||||||
|
Hdr: {
|
||||||
|
Name: "example.com.",
|
||||||
|
Rrtype: DnsTypeSOA,
|
||||||
|
Class: 1,
|
||||||
|
Ttl: 300,
|
||||||
|
},
|
||||||
|
Ns: "ns1.example.com.",
|
||||||
|
Mbox: "postmaster.example.com.",
|
||||||
|
Serial: 0,
|
||||||
|
Refresh: 0,
|
||||||
|
Retry: 0,
|
||||||
|
Expire: 0,
|
||||||
|
Minttl: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#await promiseForTable}
|
{#if soaRecords.length >= 1}
|
||||||
<div class="text-padding">
|
<div class="title-row">
|
||||||
<div>Loading...</div>
|
<h1>Domains / {getTitleDomain(soaRecords[0].Hdr.Name)}</h1>
|
||||||
|
<a
|
||||||
|
class="zone-download"
|
||||||
|
href="{import.meta.env.VITE_API_AZALEA}/domains/{getTitleDomain($soaRecords[0].Hdr.Name)}/zone-file"
|
||||||
|
download="{getTitleDomain($soaRecords[0].Hdr.Name)}.zone"
|
||||||
|
>
|
||||||
|
Download DNS Zone File
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{:then}
|
{/if}
|
||||||
{#if $soaRecords.length >= 1}
|
|
||||||
<div class="title-row">
|
|
||||||
<h1>Domains / {getTitleDomain($soaRecords[0].Hdr.Name)}</h1>
|
|
||||||
<a
|
|
||||||
class="zone-download"
|
|
||||||
href="{import.meta.env.VITE_API_AZALEA}/domains/{getTitleDomain($soaRecords[0].Hdr.Name)}/zone-file"
|
|
||||||
download="{getTitleDomain($soaRecords[0].Hdr.Name)}.zone"
|
|
||||||
>
|
|
||||||
Download DNS Zone File
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<h2>SOA Record</h2>
|
<h2>SOA Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains SOA Record">
|
<PromiseTable value={table}>
|
||||||
<thead>
|
<tr slot="headers">
|
||||||
<tr>
|
<th>Primary Domain</th>
|
||||||
<th>Primary Domain</th>
|
<th>Email</th>
|
||||||
<th>Email</th>
|
<th>Default TTL</th>
|
||||||
<th>Default TTL</th>
|
<th>Refresh Rate</th>
|
||||||
<th>Refresh Rate</th>
|
<th>Retry Rate</th>
|
||||||
<th>Retry Rate</th>
|
<th>Expire Time</th>
|
||||||
<th>Expire Time</th>
|
<th></th>
|
||||||
<th></th>
|
</tr>
|
||||||
</tr>
|
|
||||||
</thead>
|
<svelte:fragment slot="rows" let:value>
|
||||||
<tbody>
|
{#each rowOrdering(value.rows, $domainOption, DnsTypeSOA) as item}
|
||||||
{#if $soaRecords.length === 0}
|
<PromiseLike value={item}>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
<tr slot="loading" class="empty-row">
|
||||||
{/if}
|
<td colspan="100">
|
||||||
{#each $soaRecords as record}
|
<div>Loading...</div>
|
||||||
<tr>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.Mbox}</td>
|
|
||||||
<td>{record.Minttl}</td>
|
|
||||||
<td>{record.Refresh}</td>
|
|
||||||
<td>{record.Retry}</td>
|
|
||||||
<td>{record.Expire}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={null} />
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>NS Record</h2>
|
<tr slot="error" let:reason class="empty-row">
|
||||||
<table class="action-table" aria-label="List of Domains NS Record">
|
<td colspan="100">Error loading row for {item.data.Hdr.Name}: {reason}</td>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name Server</th>
|
|
||||||
<th>Subdomain</th>
|
|
||||||
<th>TTL</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{#if $nsRecords.length === 0}
|
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
|
||||||
{#each $nsRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Ns}</td>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>MX Record</h2>
|
<SoaRow slot="ok" let:value {value} />
|
||||||
<table class="action-table" aria-label="List of Domains MX Record">
|
</PromiseLike>
|
||||||
<thead>
|
{/each}
|
||||||
|
</svelte:fragment>
|
||||||
|
</PromiseTable>
|
||||||
|
<table class="action-table" aria-label="List of Domains SOA Record">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Primary Domain</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Default TTL</th>
|
||||||
|
<th>Refresh Rate</th>
|
||||||
|
<th>Retry Rate</th>
|
||||||
|
<th>Expire Time</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $soaRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $soaRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Mail Server</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th>Preference</th>
|
<td>{record.Mbox}</td>
|
||||||
<th>Subdomain</th>
|
<td>{record.Minttl}</td>
|
||||||
<th>TTL</th>
|
<td>{record.Refresh}</td>
|
||||||
<th></th>
|
<td>{record.Retry}</td>
|
||||||
|
<td>{record.Expire}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={null} />
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#if $mxRecords.length === 0}
|
</table>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
|
||||||
{#each $mxRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Mx}</td>
|
|
||||||
<td>{record.Preference}</td>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>A/AAAA Record</h2>
|
<h2>NS Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains A/AAAA Record">
|
<table class="action-table" aria-label="List of Domains NS Record">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name Server</th>
|
||||||
|
<th>Subdomain</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $nsRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $nsRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Hostname</th>
|
<td>{record.Ns}</td>
|
||||||
<th>IP Address</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th>TTL</th>
|
<td>{record.Hdr.Ttl}</td>
|
||||||
<th></th>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#if $aRecords.length === 0 && $aaaaRecords.length === 0}
|
</table>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
|
||||||
{#each $aRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.A}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
{#each $aaaaRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.AAAA}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>CNAME Record</h2>
|
<h2>MX Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains CNAME Record">
|
<table class="action-table" aria-label="List of Domains MX Record">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Mail Server</th>
|
||||||
|
<th>Preference</th>
|
||||||
|
<th>Subdomain</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $mxRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $mxRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Hostname</th>
|
<td>{record.Mx}</td>
|
||||||
<th>Aliases to</th>
|
<td>{record.Preference}</td>
|
||||||
<th>TTL</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th></th>
|
<td>{record.Hdr.Ttl}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#if $cnameRecords.length === 0}
|
</table>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
|
||||||
{#each $cnameRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.Target}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>TXT Record</h2>
|
<h2>A/AAAA Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains TXT Record">
|
<table class="action-table" aria-label="List of Domains A/AAAA Record">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hostname</th>
|
||||||
|
<th>IP Address</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $aRecords.length === 0 && $aaaaRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $aRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Hostname</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th>Value</th>
|
<td>{record.A}</td>
|
||||||
<th>TTL</th>
|
<td>{record.Hdr.Ttl}</td>
|
||||||
<th></th>
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
{#each $aaaaRecords as record}
|
||||||
{#if $txtRecords.length === 0}
|
<tr>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
<td>{record.Hdr.Name}</td>
|
||||||
{/if}
|
<td>{record.AAAA}</td>
|
||||||
{#each $txtRecords as record}
|
<td>{record.Hdr.Ttl}</td>
|
||||||
<tr>
|
<td>
|
||||||
<td>{record.Hdr.Name}</td>
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
<td>{record.Txt.join("\n")}</td>
|
</td>
|
||||||
<td>{record.Hdr.Ttl}</td>
|
</tr>
|
||||||
<td>
|
{/each}
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
</tbody>
|
||||||
</td>
|
</table>
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>SRV Record</h2>
|
<h2>CNAME Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains SRV Record">
|
<table class="action-table" aria-label="List of Domains CNAME Record">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hostname</th>
|
||||||
|
<th>Aliases to</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $cnameRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $cnameRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th>Priority</th>
|
<td>{record.Target}</td>
|
||||||
<th>Weight</th>
|
<td>{record.Hdr.Ttl}</td>
|
||||||
<th>Port</th>
|
<td>
|
||||||
<th>Target</th>
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
<th>TTL</th>
|
</td>
|
||||||
<th></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#if $srvRecords.length === 0}
|
</table>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
|
||||||
{#each $srvRecords as record}
|
|
||||||
<tr>
|
|
||||||
<td>{record.Hdr.Name}</td>
|
|
||||||
<td>{record.Priority}</td>
|
|
||||||
<td>{record.Weight}</td>
|
|
||||||
<td>{record.Port}</td>
|
|
||||||
<td>{record.Target}</td>
|
|
||||||
<td>{record.Hdr.Ttl}</td>
|
|
||||||
<td>
|
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h2>CAA Record</h2>
|
<h2>TXT Record</h2>
|
||||||
<table class="action-table" aria-label="List of Domains CAA Record">
|
<table class="action-table" aria-label="List of Domains TXT Record">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hostname</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $txtRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $txtRecords as record}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<td>{record.Hdr.Name}</td>
|
||||||
<th>Tag</th>
|
<td>
|
||||||
<th>Value</th>
|
<span class="cutoff">{record.Txt.join("\n")}</span>
|
||||||
<th>TTL</th>
|
</td>
|
||||||
<th></th>
|
<td>{record.Hdr.Ttl}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#if $caaRecords.length === 0}
|
</table>
|
||||||
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
|
||||||
{/if}
|
<h2>SRV Record</h2>
|
||||||
{#each $caaRecords as record}
|
<table class="action-table" aria-label="List of Domains SRV Record">
|
||||||
<tr>
|
<thead>
|
||||||
<td>{record.Hdr.Name}</td>
|
<tr>
|
||||||
<td>{record.Tag}</td>
|
<th>Name</th>
|
||||||
<td>{record.Value}</td>
|
<th>Priority</th>
|
||||||
<td>{record.Hdr.Ttl}</td>
|
<th>Weight</th>
|
||||||
<td>
|
<th>Port</th>
|
||||||
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
<th>Target</th>
|
||||||
</td>
|
<th>TTL</th>
|
||||||
</tr>
|
<th></th>
|
||||||
{/each}
|
</tr>
|
||||||
</tbody>
|
</thead>
|
||||||
</table>
|
<tbody>
|
||||||
{/await}
|
{#if $srvRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $srvRecords as record}
|
||||||
|
<tr>
|
||||||
|
<td>{record.Hdr.Name}</td>
|
||||||
|
<td>{record.Priority}</td>
|
||||||
|
<td>{record.Weight}</td>
|
||||||
|
<td>{record.Port}</td>
|
||||||
|
<td>{record.Target}</td>
|
||||||
|
<td>{record.Hdr.Ttl}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>CAA Record</h2>
|
||||||
|
<table class="action-table" aria-label="List of Domains CAA Record">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Tag</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>TTL</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#if $caaRecords.length === 0}
|
||||||
|
<tr class="empty-row"><td colspan="7">No items to display</td></tr>
|
||||||
|
{/if}
|
||||||
|
{#each $caaRecords as record}
|
||||||
|
<tr>
|
||||||
|
<td>{record.Hdr.Name}</td>
|
||||||
|
<td>{record.Tag}</td>
|
||||||
|
<td>{record.Value}</td>
|
||||||
|
<td>{record.Hdr.Ttl}</td>
|
||||||
|
<td>
|
||||||
|
<ActionMenu data={record} edit={t => console.log(t)} remove={t => console.log(t)} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../values.scss";
|
@import "../values.scss";
|
||||||
@ -322,8 +374,29 @@
|
|||||||
@include button-green-highlight;
|
@include button-green-highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
table tbody tr.empty-row td {
|
table tbody tr {
|
||||||
text-align: center;
|
td {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
span.cutoff {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
margin-inline: 15px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 1rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.empty-row td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-row {
|
.title-row {
|
||||||
|
@ -52,6 +52,7 @@ func ssoServer(signer mjwt.Signer) {
|
|||||||
ps := claims.NewPermStorage()
|
ps := claims.NewPermStorage()
|
||||||
ps.Set("violet:route")
|
ps.Set("violet:route")
|
||||||
ps.Set("violet:redirect")
|
ps.Set("violet:redirect")
|
||||||
|
ps.Set("azalea:domains")
|
||||||
ps.Set("domain:owns=example.com")
|
ps.Set("domain:owns=example.com")
|
||||||
ps.Set("domain:owns=example.org")
|
ps.Set("domain:owns=example.org")
|
||||||
accessToken, err := signer.GenerateJwt("81b99bd7-bf74-4cc2-9133-80ed2393dfe6", uuid.NewString(), jwt.ClaimStrings{"b5a9a8df-827c-4925-b1c1-1940abcf356b"}, 15*time.Minute, auth.AccessTokenClaims{
|
accessToken, err := signer.GenerateJwt("81b99bd7-bf74-4cc2-9133-80ed2393dfe6", uuid.NewString(), jwt.ClaimStrings{"b5a9a8df-827c-4925-b1c1-1940abcf356b"}, 15*time.Minute, auth.AccessTokenClaims{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user