Added headers and table for records

This commit is contained in:
Magnus Åhall 2026-02-25 16:43:41 +01:00
parent 567133df67
commit ad7bc0345a
2 changed files with 139 additions and 28 deletions

View file

@ -2,9 +2,6 @@
--line-color: #ccc; --line-color: #ccc;
--line-color-record: #eee; --line-color-record: #eee;
--type-background: #ddd;
--type-foreground: #000;
--label-first: #800033; --label-first: #800033;
--label-rest: #666; --label-rest: #666;
@ -12,6 +9,16 @@
--label-border: #ccc; --label-border: #ccc;
--copy-color: #d48700; --copy-color: #d48700;
--header-line: #d0d0d0;
--record-A: #89a02c;
--record-AAAA: #2f4858;
--record-CNAME: #f6ae2d;
--record-FWD: #f26419;
--record-TXT: #86bbd8;
--record-NXDOMAIN: #aa0000;
--record-other: #888;
} }
html { html {
@ -149,18 +156,53 @@ button {
&>.records { &>.records {
padding-left: 30px; padding-left: 30px;
padding-top: 8px;
padding-bottom: 8px;
margin-left: 10px; margin-left: 10px;
display: grid; display: grid;
grid-template-columns: repeat(3, min-content) 1fr; grid-template-columns: repeat(5, min-content);
grid-gap: 4px 10px; width: min-content;
/*grid-gap: 4px 10px;*/
align-items: center; align-items: center;
border-left: 1px solid var(--line-color); border-left: 1px solid var(--line-color);
&>img { .header {
font-weight: bold;
font-size: 0.75em;
background: #eee;
padding: 2px 8px;
border-left: 1px solid var(--header-line);
border-top: 1px solid var(--header-line);
border-bottom: 1px solid var(--header-line);
&:first-child {
grid-column: 1 / 3;
border-top-left-radius: 4px;
}
&.last {
border-right: 1px solid var(--header-line);
border-top-right-radius: 4px;
}
}
&>:not(.header) {
height: 40px;
}
&>.record-icon {
border-left: 1px solid var(--header-line);
align-content: center;
padding-left: 8px;
border-bottom: 1px solid var(--header-line);
img {
display: block; display: block;
padding-left: 4px; padding-left: 4px;
} }
}
.copy { .copy {
color: var(--copy-color) !important; color: var(--copy-color) !important;
@ -174,6 +216,10 @@ button {
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
display: flex; display: flex;
padding: 0 16px 0 8px;
border-bottom: 1px solid var(--header-line);
height: 100%;
align-items: center;
&.created { &.created {
* { * {
@ -202,20 +248,69 @@ button {
} }
.type { .type {
background-color: var(--type-background); padding: 2px 8px;
color: var(--type-foreground); border-bottom: 1px solid var(--header-line);
border-left: 1px solid var(--header-line);
align-content: center;
cursor: pointer;
div {
background-color: var(--record-other);
color: #fff;
padding: 4px 8px; padding: 4px 8px;
border-radius: 4px; border-radius: 4px;
margin-top: 2px;
margin-bottom: 2px;
width: min-content; width: min-content;
height: min-content;
font-weight: bold; font-weight: bold;
font-size: 0.85em; font-size: 0.85em;
} }
&.A div {
background-color: var(--record-A);
}
&.AAAA div {
background-color: var(--record-AAAA);
}
&.CNAME div {
background-color: var(--record-CNAME);
color: #000;
}
&.FWD div {
background-color: var(--record-FWD);
}
&.TXT div {
background-color: var(--record-TXT);
color: #000;
}
&.NXDOMAIN div {
background-color: var(--record-NXDOMAIN);
}
}
.value { .value {
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
border-left: 1px solid var(--header-line);
border-bottom: 1px solid var(--header-line);
padding: 0px 8px;
height: 100%;
align-content: center;
}
.ttl {
cursor: pointer;
border-left: 1px solid var(--header-line);
border-right: 1px solid var(--header-line);
border-bottom: 1px solid var(--header-line);
padding: 0px 8px;
height: 100%;
align-content: center;
} }
.separator { .separator {

View file

@ -232,7 +232,12 @@ class Folder {
<span>${firstLabel}</span><span>${restLabels != '' ? '.' + restLabels : ''}</span> <span>${firstLabel}</span><span>${restLabels != '' ? '.' + restLabels : ''}</span>
</div> </div>
<div class="subfolders"></div> <div class="subfolders"></div>
<div class="records"></div> <div class="records">
<div class="header">FQDN</div>
<div class="header">Type</div>
<div class="header">Value</div>
<div class="header last">TTL</div>
</div>
` `
this.divSubfolders = this.div.querySelector('.subfolders') this.divSubfolders = this.div.querySelector('.subfolders')
this.divRecords = this.div.querySelector('.records') this.divRecords = this.div.querySelector('.records')
@ -249,6 +254,11 @@ class Folder {
this.divSubfolders.append(folder.render()) this.divSubfolders.append(folder.render())
// Records are refreshed. // Records are refreshed.
if (this.records.length == 0)
this.divRecords.querySelectorAll('.header').forEach(h => h.style.display = 'none')
else
this.divRecords.querySelectorAll('.header').forEach(h => h.style.display = 'block')
for (const rec of Array.from(this.records)) for (const rec of Array.from(this.records))
this.divRecords.append(...rec.render()) this.divRecords.append(...rec.render())
@ -274,7 +284,7 @@ class Record {
this.divFQDN = null this.divFQDN = null
this.divType = null this.divType = null
this.divValue = null this.divValue = null
this.divSeparator = null this.divTTL = null
}// }}} }// }}}
id() {// {{{ id() {// {{{
@ -332,18 +342,22 @@ class Record {
}// }}} }// }}}
render() {// {{{ render() {// {{{
if (this.divFQDN === null) { if (this.divFQDN === null) {
this.imgIcon = document.createElement('img') this.imgIcon = document.createElement('div')
this.divFQDN = document.createElement('div') this.divFQDN = document.createElement('div')
this.divType = document.createElement('div') this.divType = document.createElement('div')
this.divValue = document.createElement('div') this.divValue = document.createElement('div')
this.divSeparator = document.createElement('div') this.divTTL = document.createElement('div')
this.imgIcon.innerHTML = `<img src="/images/${_VERSION}/icon_record.svg">`
this.imgIcon.classList.add("record-icon")
this.imgIcon.src = `/images/${_VERSION}/icon_record.svg`
this.divFQDN.classList.add('fqdn') this.divFQDN.classList.add('fqdn')
this.divType.classList.add('type') this.divType.classList.add('type')
this.divType.classList.add(this.type())
this.divValue.classList.add('value') this.divValue.classList.add('value')
this.divSeparator.classList.add('separator') this.divTTL.classList.add('ttl')
this.divType.innerHTML = `<div></div>`
this.divFQDN.innerHTML = ` this.divFQDN.innerHTML = `
<span class="subdomains">*.</span> <span class="subdomains">*.</span>
<span class="first-label"></span> <span class="first-label"></span>
@ -356,13 +370,14 @@ class Record {
else else
this.edit() this.edit()
}) })
this.divValue.addEventListener('click', event => { this.divValue.addEventListener('click', event => {
if (event.shiftKey) if (event.shiftKey)
this.copy(event.target.closest('.value'), this.value()) this.copy(event.target.closest('.value'), this.value())
else else
this.edit() this.edit()
}) })
this.divType.addEventListener('click', () => this.edit())
this.divTTL.addEventListener('click', () => this.edit())
} }
// FQDN is updated. // FQDN is updated.
@ -376,10 +391,11 @@ class Record {
this.divFQDN.querySelector('.first-label').innerText = fl this.divFQDN.querySelector('.first-label').innerText = fl
this.divFQDN.querySelector('.rest-label').innerText = rl != '' ? `.${rl}` : '' this.divFQDN.querySelector('.rest-label').innerText = rl != '' ? `.${rl}` : ''
this.divType.innerText = this.type() this.divType.querySelector('div').innerText = this.type()
this.divValue.innerText = this.value() this.divValue.innerText = this.value()
this.divTTL.innerText = this.ttl()
return [this.imgIcon, this.divFQDN, this.divType, this.divValue, this.divSeparator] return [this.imgIcon, this.divFQDN, this.divType, this.divValue, this.divTTL]
}// }}} }// }}}
save() {// {{{ save() {// {{{
const created = (this.id() == '') const created = (this.id() == '')
@ -505,7 +521,7 @@ class RecordDialog {
class Settings { class Settings {
constructor() {// {{{ constructor() {// {{{
this.settings = new Map([ this.settings = new Map([
['boxed_folders', true], ['boxed_folders', false],
['toplevel_open', true], ['toplevel_open', true],
]) ])