import { DeesElement, customElement, html, css, cssManager, property, type TemplateResult, } from '@design.estate/dees-element'; import type { ISgAuthProviderDetail, ISgPlatformSettings } from '../interfaces.js'; declare global { interface HTMLElementTagNameMap { 'sg-admin-providers-view': SgAdminProvidersView; } } @customElement('sg-admin-providers-view') export class SgAdminProvidersView extends DeesElement { public static demo = () => html`
`; public static demoGroups = ['Admin']; @property({ type: Array }) public accessor providers: ISgAuthProviderDetail[] = []; @property({ type: Object }) public accessor settings: ISgPlatformSettings = { localAuthEnabled: true, allowUserRegistration: false, sessionDurationMinutes: 1440, }; public static styles = [ cssManager.defaultStyles, css` :host { display: block; color: ${cssManager.bdTheme('#111', '#fff')}; } .container { display: flex; flex-direction: column; gap: 32px; } .page-title { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; } /* Platform settings */ .settings-box { background: ${cssManager.bdTheme('#fff', '#111')}; border: 1px solid ${cssManager.bdTheme('#e5e5e5', '#333')}; padding: 24px; display: flex; flex-direction: column; gap: 16px; } .settings-title { font-size: 16px; font-weight: 600; } .toggle-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; } .toggle-info { display: flex; flex-direction: column; gap: 2px; } .toggle-label { font-size: 14px; font-weight: 500; color: ${cssManager.bdTheme('#111', '#fff')}; } .toggle-hint { font-size: 12px; color: ${cssManager.bdTheme('#888', '#777')}; } .toggle-switch { width: 44px; height: 24px; background: ${cssManager.bdTheme('#ddd', '#333')}; cursor: pointer; position: relative; transition: background 150ms ease; flex-shrink: 0; } .toggle-switch.on { background: #22c55e; } .toggle-switch::after { content: ''; position: absolute; width: 18px; height: 18px; background: #fff; top: 3px; left: 3px; transition: transform 150ms ease; } .toggle-switch.on::after { transform: translateX(20px); } .input-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; gap: 16px; } .input-field { padding: 8px 12px; background: ${cssManager.bdTheme('#fff', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#ddd', '#333')}; font-size: 14px; color: ${cssManager.bdTheme('#111', '#fff')}; outline: none; font-family: 'JetBrains Mono', monospace; width: 100px; text-align: right; } .input-field:focus { border-color: ${cssManager.bdTheme('#111', '#fff')}; } .save-settings-btn { align-self: flex-start; padding: 8px 20px; background: ${cssManager.bdTheme('#111', '#fff')}; border: none; font-size: 13px; font-weight: 600; color: ${cssManager.bdTheme('#fff', '#111')}; cursor: pointer; transition: opacity 150ms ease; } .save-settings-btn:hover { opacity: 0.85; } /* Providers section */ .section-header { display: flex; justify-content: space-between; align-items: center; } .section-title { font-size: 16px; font-weight: 600; } .add-btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; background: ${cssManager.bdTheme('#111', '#fff')}; border: none; font-size: 13px; font-weight: 600; color: ${cssManager.bdTheme('#fff', '#111')}; cursor: pointer; transition: opacity 150ms ease; } .add-btn:hover { opacity: 0.85; } /* Provider list */ .provider-list { display: flex; flex-direction: column; border: 1px solid ${cssManager.bdTheme('#e5e5e5', '#333')}; } .provider-row { display: flex; align-items: center; justify-content: space-between; padding: 16px; background: ${cssManager.bdTheme('#fff', '#111')}; border-bottom: 1px solid ${cssManager.bdTheme('#e5e5e5', '#333')}; } .provider-row:last-child { border-bottom: none; } .provider-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; } .provider-name-row { display: flex; align-items: center; gap: 8px; } .provider-name { font-size: 15px; font-weight: 600; color: ${cssManager.bdTheme('#111', '#fff')}; } .provider-type { font-size: 11px; font-weight: 600; text-transform: uppercase; padding: 1px 6px; letter-spacing: 0.04em; } .provider-type.oidc { background: rgba(59, 130, 246, 0.15); color: #3b82f6; } .provider-type.ldap { background: rgba(168, 85, 247, 0.15); color: #a855f7; } .status-badge { font-size: 11px; font-weight: 600; text-transform: uppercase; padding: 1px 6px; letter-spacing: 0.04em; } .status-badge.active { background: rgba(34, 197, 94, 0.15); color: #22c55e; } .status-badge.disabled { background: rgba(239, 68, 68, 0.15); color: #ef4444; } .status-badge.testing { background: rgba(234, 179, 8, 0.15); color: #eab308; } .provider-meta { display: flex; gap: 12px; font-size: 12px; color: ${cssManager.bdTheme('#888', '#777')}; flex-wrap: wrap; } .test-result { font-weight: 600; } .test-result.success { color: #22c55e; } .test-result.failure { color: #ef4444; } .provider-actions { display: flex; gap: 6px; flex-shrink: 0; } .action-btn { padding: 6px 12px; background: transparent; border: 1px solid ${cssManager.bdTheme('#ddd', '#333')}; font-size: 12px; color: ${cssManager.bdTheme('#666', '#999')}; cursor: pointer; transition: all 150ms ease; } .action-btn:hover { border-color: ${cssManager.bdTheme('#999', '#666')}; color: ${cssManager.bdTheme('#111', '#fff')}; } .action-btn.delete { border-color: rgba(239, 68, 68, 0.3); color: #ef4444; } .action-btn.delete:hover { background: rgba(239, 68, 68, 0.15); } .empty-state { text-align: center; padding: 48px 32px; font-size: 14px; color: ${cssManager.bdTheme('#888', '#777')}; border: 1px solid ${cssManager.bdTheme('#e5e5e5', '#333')}; background: ${cssManager.bdTheme('#fff', '#111')}; } `, ]; public render(): TemplateResult { return html`
Authentication Management
Platform Settings
Local Authentication
Allow users to log in with email and password
{ this.settings = { ...this.settings, localAuthEnabled: !this.settings.localAuthEnabled }; this.requestUpdate(); }} >
User Registration
Allow new users to create accounts
{ this.settings = { ...this.settings, allowUserRegistration: !this.settings.allowUserRegistration }; this.requestUpdate(); }} >
Session Duration
How long sessions remain valid (in minutes)
{ this.settings = { ...this.settings, sessionDurationMinutes: parseInt((e.target as HTMLInputElement).value) || 0 }; }} >
Authentication Providers
${this.providers.length > 0 ? html`
${this.providers.map((provider) => this.renderProvider(provider))}
` : html`
No authentication providers configured. Add an OIDC or LDAP provider to enable external authentication.
`}
`; } private renderProvider(provider: ISgAuthProviderDetail): TemplateResult { return html`
${provider.displayName} ${provider.type} ${provider.status}
Priority: ${provider.priority} Updated ${this.formatDate(provider.updatedAt)} ${provider.lastTestedAt ? html` Last test: ${provider.lastTestResult} ${provider.lastTestError ? html` - ${provider.lastTestError}` : ''} ` : ''}
`; } private handleSaveSettings() { this.dispatchEvent( new CustomEvent('save-settings', { detail: { settings: { ...this.settings } }, bubbles: true, composed: true, }) ); } private formatDate(dateStr: string): string { if (!dateStr) return ''; try { return new Date(dateStr).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); } catch { return dateStr; } } private emitEvent(name: string, detail: Record) { this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true })); } }