Compare commits

..

1 Commits

Author SHA1 Message Date
jkunz 7fe63541b3 fix: align delegate routing settings UI
Release / build-and-release (push) Successful in 2m44s
2026-05-08 19:32:40 +00:00
5 changed files with 39 additions and 67 deletions
+7
View File
@@ -1,5 +1,12 @@
# Changelog # Changelog
## 2026-05-08 - 1.24.7 - fix(web-ui)
align Delegate Routing settings with the Dees catalog control and theme conventions
- replace raw Delegate Routing inputs and save button with `dees-input-text` and `dees-button`
- style the Delegate Routing card with explicit `cssManager.bdTheme(...)` colors
## 2026-05-08 - 1.24.6 - fix(auth) ## 2026-05-08 - 1.24.6 - fix(auth)
avoid bcrypt worker crashes in compiled binaries during login and password creation avoid bcrypt worker crashes in compiled binaries during login and password creation
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/onebox", "name": "@serve.zone/onebox",
"version": "1.24.6", "version": "1.24.7",
"exports": "./mod.ts", "exports": "./mod.ts",
"tasks": { "tasks": {
"test": "deno test --allow-all test/", "test": "deno test --allow-all test/",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/onebox", "name": "@serve.zone/onebox",
"version": "1.24.6", "version": "1.24.7",
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers", "description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
"main": "mod.ts", "main": "mod.ts",
"type": "module", "type": "module",
+1 -1
View File
File diff suppressed because one or more lines are too long
+29 -64
View File
@@ -49,27 +49,29 @@ export class ObViewSettings extends DeesElement {
css` css`
.gateway-card { .gateway-card {
margin-bottom: 24px; margin-bottom: 24px;
border: 1px solid var(--dees-color-border-subtle); border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
border-radius: 12px; border-radius: 12px;
background: var(--dees-color-background, #ffffff); background: ${cssManager.bdTheme('#ffffff', '#09090b')};
overflow: hidden; overflow: hidden;
box-shadow: 0 1px 2px ${cssManager.bdTheme('rgba(0,0,0,0.04)', 'rgba(0,0,0,0.2)')};
} }
.gateway-header { .gateway-header {
padding: 16px 20px; padding: 16px 20px;
border-bottom: 1px solid var(--dees-color-border-subtle); border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#27272a')};
background: ${cssManager.bdTheme('#fafafa', '#101013')};
} }
.gateway-title { .gateway-title {
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
color: var(--dees-color-text-primary); color: ${cssManager.bdTheme('#18181b', '#fafafa')};
} }
.gateway-subtitle { .gateway-subtitle {
margin-top: 4px; margin-top: 4px;
font-size: 13px; font-size: 13px;
color: var(--dees-color-text-muted); color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
} }
.gateway-content { .gateway-content {
@@ -83,34 +85,8 @@ export class ObViewSettings extends DeesElement {
grid-column: 1 / -1; grid-column: 1 / -1;
} }
.field-label { dees-input-text {
display: block;
margin-bottom: 6px;
font-size: 13px;
font-weight: 500;
color: var(--dees-color-text-secondary);
}
input {
width: 100%; width: 100%;
box-sizing: border-box;
padding: 10px 12px;
border: 1px solid var(--dees-color-border-subtle);
border-radius: 8px;
background: transparent;
color: var(--dees-color-text-primary);
font-size: 14px;
}
input:focus {
outline: none;
border-color: #3b82f6;
}
.field-hint {
margin-top: 5px;
font-size: 12px;
color: var(--dees-color-text-muted);
} }
.gateway-footer { .gateway-footer {
@@ -119,21 +95,6 @@ export class ObViewSettings extends DeesElement {
padding: 0 20px 20px; padding: 0 20px 20px;
} }
.save-button {
border: none;
border-radius: 8px;
background: #2563eb;
color: white;
cursor: pointer;
font-size: 13px;
font-weight: 600;
padding: 9px 14px;
}
.save-button:hover {
background: #1d4ed8;
}
@media (max-width: 700px) { @media (max-width: 700px) {
.gateway-content { .gateway-content {
grid-template-columns: 1fr; grid-template-columns: 1fr;
@@ -190,18 +151,23 @@ export class ObViewSettings extends DeesElement {
return html` return html`
<section class="gateway-card"> <section class="gateway-card">
<div class="gateway-header"> <div class="gateway-header">
<div class="gateway-title">External dcrouter Gateway</div> <div class="gateway-title">Delegate Routing</div>
<div class="gateway-subtitle">Delegate public WorkApp routing, DNS, and certificates to a dcrouter edge authority.</div> <div class="gateway-subtitle">Delegate public WorkApp routing, DNS, and certificates to a dcrouter edge authority.</div>
</div> </div>
<div class="gateway-content"> <div class="gateway-content">
${this.renderGatewayInput('dcrouterGatewayUrl', 'Gateway URL', settings?.dcrouterGatewayUrl || '', 'https://edge.example.com', 'Base URL of the dcrouter OpsServer.')} ${this.renderGatewayInput('dcrouterGatewayUrl', 'Gateway URL', settings?.dcrouterGatewayUrl || '', 'Base URL of the dcrouter OpsServer.')}
${this.renderGatewayInput('dcrouterGatewayApiToken', 'API Token', settings?.dcrouterGatewayApiToken || '', 'dcrouter API token', 'Requires workhosters and certificates scopes.', 'password')} ${this.renderGatewayInput('dcrouterGatewayApiToken', 'API Token', settings?.dcrouterGatewayApiToken || '', 'Requires workhosters and certificates scopes.', true)}
${this.renderGatewayInput('dcrouterWorkHosterId', 'WorkHoster ID', settings?.dcrouterWorkHosterId || '', 'optional stable owner ID', 'Leave empty to let Onebox create a stable ID.')} ${this.renderGatewayInput('dcrouterWorkHosterId', 'WorkHoster ID', settings?.dcrouterWorkHosterId || '', 'Leave empty to let Onebox create a stable ID.')}
${this.renderGatewayInput('dcrouterTargetHost', 'Target Host', settings?.dcrouterTargetHost || '', 'public or private host/IP', 'Defaults to the configured server IP when empty.')} ${this.renderGatewayInput('dcrouterTargetHost', 'Target Host', settings?.dcrouterTargetHost || '', 'Defaults to the configured server IP when empty.')}
${this.renderGatewayInput('dcrouterTargetPort', 'Target Port', String(settings?.dcrouterTargetPort || 80), '80', 'Internal HTTP port dcrouter forwards to.', 'number')} ${this.renderGatewayInput('dcrouterTargetPort', 'Target Port', String(settings?.dcrouterTargetPort || 80), 'Internal HTTP port dcrouter forwards to.')}
</div> </div>
<div class="gateway-footer"> <div class="gateway-footer">
<button class="save-button" @click=${() => this.saveExternalGatewaySettings()}>Save Gateway Settings</button> <dees-button
.text=${'Save Gateway Settings'}
.type=${'default'}
.icon=${'lucide:Save'}
@click=${() => this.saveExternalGatewaySettings()}
></dees-button>
</div> </div>
</section> </section>
`; `;
@@ -211,21 +177,20 @@ export class ObViewSettings extends DeesElement {
key: keyof NonNullable<appstate.ISettingsState['settings']>, key: keyof NonNullable<appstate.ISettingsState['settings']>,
label: string, label: string,
value: string, value: string,
placeholder: string,
hint: string, hint: string,
type: 'text' | 'password' | 'number' = 'text', isPassword = false,
): TemplateResult { ): TemplateResult {
return html` return html`
<label class="gateway-field ${key === 'dcrouterGatewayUrl' ? 'full' : ''}"> <div class="gateway-field ${key === 'dcrouterGatewayUrl' ? 'full' : ''}">
<span class="field-label">${label}</span> <dees-input-text
<input .key=${key}
type=${type} .label=${label}
.value=${value} .value=${value}
placeholder=${placeholder} .description=${hint}
.isPasswordBool=${isPassword}
@input=${(event: Event) => this.updateGatewayDraft(key, (event.target as HTMLInputElement).value)} @input=${(event: Event) => this.updateGatewayDraft(key, (event.target as HTMLInputElement).value)}
/> ></dees-input-text>
<span class="field-hint">${hint}</span> </div>
</label>
`; `;
} }