fix(web-ui): improve form field descriptions and align certificate settings with tile components

This commit is contained in:
2026-04-12 19:42:07 +00:00
parent b582d44502
commit 2861511d20
15 changed files with 144 additions and 143 deletions

View File

@@ -80,22 +80,6 @@ export class DnsProviderForm extends DeesElement {
margin-bottom: 12px;
}
.helpText {
font-size: 12px;
opacity: 0.7;
margin-top: -6px;
margin-bottom: 8px;
}
.typeDescription {
font-size: 12px;
opacity: 0.8;
margin: 4px 0 16px;
padding: 8px 12px;
background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
border-radius: 6px;
}
.credentialsHint {
font-size: 12px;
opacity: 0.7;
@@ -130,6 +114,7 @@ export class DnsProviderForm extends DeesElement {
<dees-input-text
.key=${'__type_display'}
.label=${'Type'}
.infoText=${descriptor?.description || ''}
.value=${descriptor?.displayName ?? this.selectedType}
.disabled=${true}
></dees-input-text>
@@ -140,6 +125,7 @@ export class DnsProviderForm extends DeesElement {
<dees-input-dropdown
.key=${'__type'}
.label=${'Provider type'}
.infoText=${descriptor?.description || ''}
.options=${descriptors.map((d) => ({ option: d.displayName, key: d.type }))}
.selectedOption=${descriptor
? { option: descriptor.displayName, key: descriptor.type }
@@ -158,7 +144,6 @@ export class DnsProviderForm extends DeesElement {
`}
${descriptor
? html`
<div class="typeDescription">${descriptor.description}</div>
${this.credentialsHint
? html`<div class="credentialsHint">${this.credentialsHint}</div>`
: ''}
@@ -168,9 +153,9 @@ export class DnsProviderForm extends DeesElement {
<dees-input-text
.key=${f.key}
.label=${f.label}
.description=${f.helpText || ''}
.required=${f.required && !this.lockType}
></dees-input-text>
${f.helpText ? html`<div class="helpText">${f.helpText}</div>` : ''}
</div>
`,
)}

View File

@@ -54,35 +54,31 @@ export class OpsViewCertificates extends DeesElement {
gap: 24px;
}
.acmeCard {
padding: 16px 20px;
background: ${cssManager.bdTheme('#f9fafb', '#111827')};
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
border-radius: 8px;
}
.acmeCard.acmeCardEmpty {
background: ${cssManager.bdTheme('#fffbeb', '#1c1917')};
border-color: ${cssManager.bdTheme('#fde68a', '#78350f')};
}
.acmeCardHeader {
.acmeTileHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
width: 100%;
padding: 8px 12px;
}
.acmeCardTitle {
.acmeTileHeading {
font-size: 14px;
font-weight: 600;
color: ${cssManager.bdTheme('#111827', '#f3f4f6')};
}
.acmeEmptyContent {
padding: 16px;
font-size: 13px;
line-height: 1.5;
color: ${cssManager.bdTheme('#78350f', '#fde68a')};
}
.acmeGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px 24px;
padding: 16px;
}
.acmeField {
@@ -103,13 +99,6 @@ export class OpsViewCertificates extends DeesElement {
color: ${cssManager.bdTheme('#111827', '#f3f4f6')};
}
.acmeEmptyHint {
margin: 0;
font-size: 13px;
line-height: 1.5;
color: ${cssManager.bdTheme('#78350f', '#fde68a')};
}
.statusBadge {
display: inline-flex;
align-items: center;
@@ -226,41 +215,40 @@ export class OpsViewCertificates extends DeesElement {
<dees-heading level="3">Certificates</dees-heading>
<div class="certificatesContainer">
${this.renderAcmeSettingsCard()}
${this.renderStatsTiles(summary)}
${this.renderAcmeSettingsTile()}
${this.renderCertificateTable()}
</div>
`;
}
private renderAcmeSettingsCard(): TemplateResult {
private renderAcmeSettingsTile(): TemplateResult {
const config = this.acmeState.config;
if (!config) {
return html`
<div class="acmeCard acmeCardEmpty">
<div class="acmeCardHeader">
<span class="acmeCardTitle">ACME Settings</span>
<dees-tile .heading=${'ACME Settings'}>
<div slot="header" class="acmeTileHeader">
<span class="acmeTileHeading">ACME Settings</span>
<dees-button
eventName="edit-acme"
@click=${() => this.showEditAcmeDialog()}
.type=${'highlighted'}
>Configure</dees-button>
</div>
<p class="acmeEmptyHint">
<div class="acmeEmptyContent">
No ACME configuration yet. Click <strong>Configure</strong> to set up automated TLS
certificate issuance via Let's Encrypt. You'll also need at least one DNS provider
under <strong>Domains &gt; Providers</strong>.
</p>
</div>
</div>
</dees-tile>
`;
}
return html`
<div class="acmeCard">
<div class="acmeCardHeader">
<span class="acmeCardTitle">ACME Settings</span>
<dees-button eventName="edit-acme" @click=${() => this.showEditAcmeDialog()}>Edit</dees-button>
<dees-tile>
<div slot="header" class="acmeTileHeader">
<span class="acmeTileHeading">ACME Settings</span>
<dees-button @click=${() => this.showEditAcmeDialog()}>Edit</dees-button>
</div>
<div class="acmeGrid">
<div class="acmeField">
@@ -292,7 +280,7 @@ export class OpsViewCertificates extends DeesElement {
<span class="acmeValue">${config.renewThresholdDays} days</span>
</div>
</div>
</div>
</dees-tile>
`;
}
@@ -317,7 +305,8 @@ export class OpsViewCertificates extends DeesElement {
></dees-input-checkbox>
<dees-input-checkbox
.key=${'useProduction'}
.label=${"Use Let's Encrypt production (uncheck for staging)"}
.label=${"Use Let's Encrypt production"}
.description=${'Uncheck to use the staging environment'}
.value=${current?.useProduction ?? true}
></dees-input-checkbox>
<dees-input-checkbox
@@ -327,7 +316,8 @@ export class OpsViewCertificates extends DeesElement {
></dees-input-checkbox>
<dees-input-text
.key=${'renewThresholdDays'}
.label=${'Renewal threshold (days)'}
.label=${'Renewal threshold'}
.description=${'Number of days before expiry to trigger renewal'}
.value=${String(current?.renewThresholdDays ?? 30)}
></dees-input-text>
</dees-form>
@@ -456,11 +446,12 @@ export class OpsViewCertificates extends DeesElement {
content: html`
<dees-form>
<dees-input-fileupload
key="certJsonFile"
label="Certificate JSON (.tsclass.cert.json)"
accept=".json"
.key=${'certJsonFile'}
.label=${'Certificate JSON'}
.description=${'Upload a .tsclass.cert.json file'}
.accept=${'.json'}
.multiple=${false}
required
.required=${true}
></dees-input-fileupload>
</dees-form>
`,

View File

@@ -101,8 +101,8 @@ export class OpsViewDns extends DeesElement {
<dees-heading level="3">DNS Records</dees-heading>
<div class="dnsContainer">
<div class="domainPicker">
<span>Domain:</span>
<dees-input-dropdown
.label=${'Domain'}
.options=${domains.map((d) => ({ option: d.name, key: d.id }))}
.selectedOption=${selectedId
? { option: domains.find((d) => d.id === selectedId)?.name || '', key: selectedId }
@@ -196,7 +196,7 @@ export class OpsViewDns extends DeesElement {
heading: 'Add DNS Record',
content: html`
<dees-form>
<dees-input-text .key=${'name'} .label=${'Name (FQDN)'} .required=${true}></dees-input-text>
<dees-input-text .key=${'name'} .label=${'Name'} .description=${'Fully qualified domain name'} .required=${true}></dees-input-text>
<dees-input-dropdown
.key=${'type'}
.label=${'Type'}
@@ -205,10 +205,11 @@ export class OpsViewDns extends DeesElement {
></dees-input-dropdown>
<dees-input-text
.key=${'value'}
.label=${'Value (for MX use "10 mail.example.com")'}
.label=${'Value'}
.description=${'For MX records use priority format, e.g. "10 mail.example.com"'}
.required=${true}
></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL (seconds)'} .value=${'300'}></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL'} .description=${'Time to live in seconds'} .value=${'300'}></dees-input-text>
</dees-form>
`,
menuOptions: [
@@ -242,9 +243,9 @@ export class OpsViewDns extends DeesElement {
heading: `Edit ${rec.type} ${rec.name}`,
content: html`
<dees-form>
<dees-input-text .key=${'name'} .label=${'Name (FQDN)'} .value=${rec.name}></dees-input-text>
<dees-input-text .key=${'name'} .label=${'Name'} .description=${'Fully qualified domain name'} .value=${rec.name}></dees-input-text>
<dees-input-text .key=${'value'} .label=${'Value'} .value=${rec.value}></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL (seconds)'} .value=${String(rec.ttl)}></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL'} .description=${'Time to live in seconds'} .value=${String(rec.ttl)}></dees-input-text>
</dees-form>
`,
menuOptions: [

View File

@@ -181,8 +181,8 @@ export class OpsViewDomains extends DeesElement {
heading: 'Add DcRouter Domain',
content: html`
<dees-form>
<dees-input-text .key=${'name'} .label=${'FQDN (e.g. example.com)'} .required=${true}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description (optional)'}></dees-input-text>
<dees-input-text .key=${'name'} .label=${'FQDN'} .description=${'e.g. example.com'} .required=${true}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
</dees-form>
<p style="margin-top: 12px; font-size: 12px; opacity: 0.7;">
dcrouter will become the authoritative DNS server for this domain. You'll need to
@@ -235,7 +235,8 @@ export class OpsViewDomains extends DeesElement {
></dees-input-dropdown>
<dees-input-text
.key=${'domainNames'}
.label=${'Comma-separated FQDNs to import (e.g. example.com, foo.com)'}
.label=${'Domain Names'}
.description=${'Comma-separated FQDNs, e.g. example.com, foo.com'}
.required=${true}
></dees-input-text>
</dees-form>