Release 0.2.0 #4
@@ -63,15 +63,19 @@ export class AgentInboxPage extends I18nMixin(InboxMixin(LightElement)) {
|
||||
|
||||
return html`
|
||||
<div class="page-panel">
|
||||
<div class="page-panel-header">
|
||||
<h5 class="mb-0">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">
|
||||
${t('nav.inbox')}
|
||||
${total > 0 ? html`<span class="badge bg-danger ms-2">${total}</span>` : nothing}
|
||||
</h5>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="inbox-refresh-btn" title="Refresh" @click=${() => this._loadInbox()}>
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
${this._renderInboxSection()}
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -285,10 +285,13 @@ export class AgentsPage extends LightElement {
|
||||
${this._detail
|
||||
? this._renderDetail()
|
||||
: html`
|
||||
<div class="agents-page-header">
|
||||
<h2 class="llm-page-title">${t('agents.title')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">${t('agents.title')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="agents-body">
|
||||
<div class="agent-info-banner">
|
||||
<div class="agent-info-banner-icon"><i class="bi bi-info-circle-fill"></i></div>
|
||||
<div class="agent-info-banner-body">
|
||||
@@ -298,6 +301,7 @@ export class AgentsPage extends LightElement {
|
||||
</div>
|
||||
|
||||
${this._renderList()}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -356,12 +356,14 @@ export class ApprovalGroupsPage extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="apr-page">
|
||||
<div class="apr-header">
|
||||
<h2 class="apr-title">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">
|
||||
<i class="bi bi-shield-check me-2"></i>${t('security.title')}
|
||||
</h2>
|
||||
<div class="apr-header-right">
|
||||
<span class="apr-header-count">${this._groups.length === 1 ? t('security.group_count', { n: this._groups.length }) : t('security.group_count_plural', { n: this._groups.length })}</span>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${this._groups.length === 1 ? t('security.group_count', { n: this._groups.length }) : t('security.group_count_plural', { n: this._groups.length })}</span>
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._startNewGroup()}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('security.new_group')}
|
||||
</button>
|
||||
|
||||
@@ -1042,20 +1042,21 @@ export class ApprovalRulesPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="apr-page">
|
||||
<div class="apr-header">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button
|
||||
class="btn btn-sm btn-outline-secondary"
|
||||
style="flex-shrink:0"
|
||||
class="btn btn-sm btn-outline-secondary page-header-back"
|
||||
@click=${() => this._goBack()}
|
||||
>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="apr-title">
|
||||
<h2 class="page-header-title">
|
||||
${isDefault ? html`<span class="apr-group-default-badge" style="vertical-align:middle">${t('approval.header.default_badge')}</span>` : nothing}
|
||||
${group.name}
|
||||
</h2>
|
||||
<div class="apr-header-right">
|
||||
<span class="apr-header-count">${totalRules === 1 ? t('approval.header.rule_count', { n: totalRules }) : t('approval.header.rule_count_plural', { n: totalRules })}</span>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${totalRules === 1 ? t('approval.header.rule_count', { n: totalRules }) : t('approval.header.rule_count_plural', { n: totalRules })}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -116,10 +116,13 @@ export class ConfigPage extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="config-page">
|
||||
<div class="config-page-header">
|
||||
<h2 class="llm-page-title">${t('config.title')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">${t('config.title')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-body">
|
||||
${this._error ? html`
|
||||
<div class="alert alert-danger">${this._error}</div>` : nothing}
|
||||
|
||||
@@ -156,6 +159,7 @@ export class ConfigPage extends LightElement {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,12 +399,12 @@ export class ConnectorDetailPage extends LightElement {
|
||||
_renderHeader() {
|
||||
const title = this._entry?.friendly_name || this._glob?.friendly_name || this._name || 'Connector';
|
||||
return html`
|
||||
<div class="um-header">
|
||||
<div class="d-flex align-items-center gap-2" style="min-width:0">
|
||||
<button class="btn btn-sm btn-outline-secondary" title=${t('connectors.detail.back')} @click=${() => this._back()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('connectors.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="um-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">${title}</h2>
|
||||
<h2 class="page-header-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">${title}</h2>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -344,9 +344,11 @@ export class ConnectorsPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-plug me-2"></i>${t('connectors.title')}</h2>
|
||||
<div class="um-header-right">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-plug me-2"></i>${t('connectors.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
${this._isAdmin ? html`
|
||||
<button class="btn btn-sm btn-outline-secondary" @click=${() => this._openProviders()}>
|
||||
<i class="bi bi-key me-1"></i>${t('connectors.btn.signin_providers')}
|
||||
@@ -498,12 +500,12 @@ export class ConnectorsPage extends LightElement {
|
||||
const isScript = f.source === 'local_script';
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<div class="d-flex align-items-center gap-2" style="min-width:0">
|
||||
<button class="btn btn-sm btn-outline-secondary" title=${t('connectors.new.back')} @click=${() => this._closeNew()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('connectors.new.back')} @click=${() => this._closeNew()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="um-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
<h2 class="page-header-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
<i class="bi bi-pencil me-2"></i>${t('connectors.new.title')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -57,12 +57,12 @@ export class FileViewerPage extends FileViewerBase {
|
||||
if (!this._open) return nothing;
|
||||
return html`
|
||||
<div class="llm-page fv-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('fv.back')} @click=${() => this._back()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('fv.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="llm-page-title fv-title" title=${this._path ?? ''}><bdi>${this._path ?? ''}</bdi></h2>
|
||||
<h2 class="page-header-title fv-title" title=${this._path ?? ''}><bdi>${this._path ?? ''}</bdi></h2>
|
||||
</div>
|
||||
<div class="fv-header-actions">
|
||||
${this._renderModeToggle('btn btn-sm btn-outline-secondary fv-download-btn')}
|
||||
|
||||
@@ -307,14 +307,17 @@ export class LlmProvidersPage extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="pv-page">
|
||||
<div class="pv-header">
|
||||
<h2 class="pv-title">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">
|
||||
<i class="bi bi-plug me-2"></i>${t('providers.title')}
|
||||
</h2>
|
||||
<div class="pv-header-right">
|
||||
<span class="pv-header-count">${t('providers.count', { n: this._providers.length })}</span>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${t('providers.count', { n: this._providers.length })}</span>
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('providers.add')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -540,11 +540,13 @@ export class LlmRequestDetail extends LightElement {
|
||||
render() {
|
||||
if (this._loading) return html`
|
||||
<div class="llmr-page">
|
||||
<div class="llmr-detail-back">
|
||||
<button class="btn btn-sm btn-outline-secondary" @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i> ${t('llmr.detail.back')}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('llmr.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="llmr-state">
|
||||
<div class="spinner-border spinner-border-sm text-secondary" role="status"></div>
|
||||
<span>${t('llmr.detail.loading')}</span>
|
||||
@@ -554,11 +556,13 @@ export class LlmRequestDetail extends LightElement {
|
||||
|
||||
if (this._error) return html`
|
||||
<div class="llmr-page">
|
||||
<div class="llmr-detail-back">
|
||||
<button class="btn btn-sm btn-outline-secondary" @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i> ${t('llmr.detail.back')}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('llmr.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="llmr-state llmr-state--error">
|
||||
<i class="bi bi-exclamation-circle"></i>
|
||||
<span>${this._error}</span>
|
||||
@@ -586,15 +590,16 @@ export class LlmRequestDetail extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="llmr-page">
|
||||
<div class="llmr-detail-back">
|
||||
<button class="btn btn-sm btn-outline-secondary" @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i> ${t('llmr.detail.back')}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('llmr.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<span class="llmr-detail-title">
|
||||
<i class="bi bi-journal-code"></i> ${t('llmr.detail.request')} <span class="llmr-detail-id">#${d.id}</span>
|
||||
</span>
|
||||
<h2 class="page-header-title"><i class="bi bi-journal-code"></i> ${t('llmr.detail.request')} <span class="llmr-detail-id">#${d.id}</span></h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="llmr-body">
|
||||
${this._renderStatBar(d)}
|
||||
|
||||
${payloadMissing ? html`
|
||||
@@ -644,6 +649,7 @@ export class LlmRequestDetail extends LightElement {
|
||||
`
|
||||
) : nothing}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,14 +283,20 @@ export class LlmRequestsPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="llmr-page">
|
||||
<div class="llmr-header">
|
||||
<h2 class="llmr-title"><i class="bi bi-journal-code"></i> ${t('llmr.title')}</h2>
|
||||
<span class="llmr-total-badge">${t('llmr.total', { n: this._total })}</span>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-journal-code"></i> ${t('llmr.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${t('llmr.total', { n: this._total })}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="llmr-body">
|
||||
${this._renderFilters()}
|
||||
${this._renderTable()}
|
||||
${this._renderPagination()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,9 +145,11 @@ export class MarketplacePage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-shop me-2"></i>${t('marketplace.title')}</h2>
|
||||
<div class="um-header-right">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-shop me-2"></i>${t('marketplace.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-outline-primary" @click=${() => this._goConnectors()}>
|
||||
<i class="bi bi-arrow-left me-1"></i>${t('marketplace.btn.connectors')}
|
||||
</button>
|
||||
|
||||
@@ -126,7 +126,12 @@ export class ModelsHubPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="models-hub">
|
||||
<h2 class="llm-page-title">${t('models.hub.title')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title">${t('models.hub.title')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="models-hub-body">
|
||||
<p class="text-muted" style="font-size:0.88rem;margin-top:0.25rem">
|
||||
${t('models.hub.subtitle')}
|
||||
</p>
|
||||
@@ -145,6 +150,7 @@ export class ModelsHubPage extends LightElement {
|
||||
`)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,22 +298,24 @@ export class ModelsImageSection extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="llm-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
${this.onback ? html`
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('models.back')} @click=${this.onback}>
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('models.back')} @click=${this.onback}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
<div>
|
||||
<h2 class="llm-page-title">${t('models.image.title')}</h2>
|
||||
<span class="llm-page-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
<h2 class="page-header-title">${t('models.image.title')}</h2>
|
||||
<span class="page-header-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()} ?disabled=${!canAdd}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('models.add')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${!canAdd ? html`
|
||||
<div class="agent-info-banner">
|
||||
|
||||
@@ -762,23 +762,25 @@ export class ModelsLlmSection extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="llm-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
${this.onback ? html`
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('models.back')} @click=${this.onback}>
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('models.back')} @click=${this.onback}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
<div>
|
||||
<h2 class="llm-page-title">${t('models.llm.title')}</h2>
|
||||
<span class="llm-page-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
<h2 class="page-header-title">${t('models.llm.title')}</h2>
|
||||
<span class="page-header-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()}
|
||||
?disabled=${this._providers.length === 0}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('models.add')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${this._providers.length === 0 ? html`
|
||||
<div class="agent-info-banner">
|
||||
|
||||
@@ -361,19 +361,21 @@ export class ModelsTranscribeSection extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="llm-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
${this.onback ? html`
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('models.back')} @click=${this.onback}>
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('models.back')} @click=${this.onback}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
<h2 class="llm-page-title">${t('models.transcribe.title')}</h2>
|
||||
<h2 class="page-header-title">${t('models.transcribe.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()} ?disabled=${!canAdd}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('models.add')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${!canAdd ? html`
|
||||
<div class="agent-info-banner">
|
||||
|
||||
@@ -424,22 +424,24 @@ export class ModelsTtsSection extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="llm-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
${this.onback ? html`
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('models.back')} @click=${this.onback}>
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('models.back')} @click=${this.onback}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
` : ''}
|
||||
<div>
|
||||
<h2 class="llm-page-title">${t('models.tts.title')}</h2>
|
||||
<span class="llm-page-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
<h2 class="page-header-title">${t('models.tts.title')}</h2>
|
||||
<span class="page-header-count">${t('models.hub.count.many', { n: this._models.length })}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()} ?disabled=${!canAdd}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('models.add')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${!canAdd ? html`
|
||||
<div class="agent-info-banner">
|
||||
|
||||
@@ -95,8 +95,10 @@ export class PluginCatalogPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-puzzle-fill me-2"></i>${t('nav.plugins')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-puzzle-fill me-2"></i>${t('nav.plugins')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${this._error ? html`
|
||||
|
||||
@@ -198,12 +198,12 @@ export class PluginDetailPage extends LightElement {
|
||||
|
||||
_renderHeader() {
|
||||
return html`
|
||||
<div class="um-header">
|
||||
<div class="d-flex align-items-center gap-2" style="min-width:0">
|
||||
<button class="btn btn-sm btn-outline-secondary" title=${t('plugins.detail.back')} @click=${() => this._back()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('plugins.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="um-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
<h2 class="page-header-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
${this._plugin?.name || this._id || 'Plugin'}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@@ -136,8 +136,10 @@ export class ProfilePage extends I18nMixin(LightElement) {
|
||||
|
||||
return html`
|
||||
<div class="um-page" style="display:flex">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-person-circle me-2"></i>${t('profile.title')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-person-circle me-2"></i>${t('profile.title')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:0 24px 48px;max-width:480px">
|
||||
|
||||
|
||||
@@ -246,19 +246,19 @@ export class ProjectBoardSection extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="project-page">
|
||||
<div class="project-page-header">
|
||||
<div style="display:flex;align-items:center;gap:12px">
|
||||
<button class="btn btn-sm btn-outline-secondary" @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left me-1"></i>${t('project_board.back')}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('project_board.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="project-page-title">
|
||||
<h2 class="page-header-title">
|
||||
<i class="bi bi-folder2"></i>${this._project.name}
|
||||
</h2>
|
||||
${this._project.is_owner
|
||||
? html`<span class="badge text-bg-light"><i class="bi bi-person me-1"></i>${t('projects.badge.owned')}</span>`
|
||||
: html`<span class="badge text-bg-light"><i class="bi bi-people me-1"></i>${t('projects.badge.shared_by', { name: this._project.owner_name })}</span>`}
|
||||
</div>
|
||||
<div style="display:flex;gap:0.5rem">
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-outline-primary" @click=${() => this._openChat()}>
|
||||
<i class="bi bi-chat-dots me-1"></i>${t('project_board.open_chat')}
|
||||
</button>
|
||||
|
||||
@@ -194,12 +194,16 @@ export class ProjectListSection extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="project-page">
|
||||
<div class="project-page-header">
|
||||
<h2 class="project-page-title"><i class="bi bi-kanban"></i> ${t('projects.title')}</h2>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-kanban"></i> ${t('projects.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openAdd()}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('projects.btn.new')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${this._error ? html`
|
||||
<div class="alert alert-danger py-2 mx-3 mt-3 mb-0" style="font-size:0.85rem">${this._error}</div>
|
||||
|
||||
@@ -282,10 +282,12 @@ export class RolesPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-tags me-2"></i>${t('roles.title')}</h2>
|
||||
<div class="um-header-right">
|
||||
<span class="um-header-count">${roles.length === 1 ? t('roles.count', { n: roles.length }) : t('roles.count_plural', { n: roles.length })}</span>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-tags me-2"></i>${t('roles.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${roles.length === 1 ? t('roles.count', { n: roles.length }) : t('roles.count_plural', { n: roles.length })}</span>
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openCreate()}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('roles.new_role')}
|
||||
</button>
|
||||
|
||||
@@ -185,10 +185,12 @@ export class SharedFoldersPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-folder-symlink me-2"></i>${t('sf.title')}</h2>
|
||||
<div class="um-header-right">
|
||||
<span class="um-header-count">
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-folder-symlink me-2"></i>${t('sf.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">
|
||||
${folders.length === 1 ? t('sf.count', { n: folders.length }) : t('sf.count_plural', { n: folders.length })}
|
||||
</span>
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openCreate()}>
|
||||
|
||||
@@ -294,21 +294,27 @@ export class SystemAgentsPage extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="sa-page">
|
||||
<div class="sa-header">
|
||||
<h2 class="sa-title"><i class="bi bi-robot"></i> ${t('system_agents.title')}</h2>
|
||||
<span class="sa-total-badge">${t('system_agents.total', { n: this._total })}</span>
|
||||
<button class="btn btn-sm btn-outline-secondary sa-refresh-btn"
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-robot"></i> ${t('system_agents.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${t('system_agents.total', { n: this._total })}</span>
|
||||
<button class="btn btn-sm btn-outline-secondary"
|
||||
?disabled=${this._loading}
|
||||
@click=${() => this._loadAll()}>
|
||||
<i class="bi bi-arrow-clockwise"></i> ${t('system_agents.refresh')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sa-body">
|
||||
<p class="sa-subtitle">${t('system_agents.subtitle')}</p>
|
||||
${this._renderTabs()}
|
||||
${this._renderAgentPanel()}
|
||||
${this._renderTable()}
|
||||
${this._renderPagination()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,10 +122,12 @@ export class CronJobsSection extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="task-page">
|
||||
<div class="task-page-header">
|
||||
<h2 class="task-page-title"><i class="bi bi-repeat"></i> ${t('cron.title')}</h2>
|
||||
<div style="font-size:0.82rem;color:var(--bs-secondary-color)">
|
||||
${t(this._jobs.length === 1 ? 'cron.count_one' : 'cron.count_other', { n: this._jobs.length })}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-repeat"></i> ${t('cron.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${t(this._jobs.length === 1 ? 'cron.count_one' : 'cron.count_other', { n: this._jobs.length })}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -83,10 +83,12 @@ export class TaskHistorySection extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="task-page">
|
||||
<div class="task-page-header">
|
||||
<h2 class="task-page-title"><i class="bi bi-journal-text"></i> History</h2>
|
||||
<div style="font-size:0.82rem;color:var(--bs-secondary-color)">
|
||||
${this._runs.length} run${this._runs.length !== 1 ? 's' : ''}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-journal-text"></i> History</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${this._runs.length} run${this._runs.length !== 1 ? 's' : ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -124,10 +124,12 @@ export class RunningTasksSection extends LightElement {
|
||||
void this._tick; // drives re-render every second for live elapsed time
|
||||
return html`
|
||||
<div class="task-page">
|
||||
<div class="task-page-header">
|
||||
<h2 class="task-page-title"><i class="bi bi-activity"></i> Running Tasks</h2>
|
||||
<div style="font-size:0.82rem;color:var(--bs-secondary-color)">
|
||||
${this._jobs.length} running
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-activity"></i> Running Tasks</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${this._jobs.length} running</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -99,10 +99,12 @@ export class ScheduledTasksSection extends LightElement {
|
||||
render() {
|
||||
return html`
|
||||
<div class="task-page">
|
||||
<div class="task-page-header">
|
||||
<h2 class="task-page-title"><i class="bi bi-clock"></i> Scheduled Tasks</h2>
|
||||
<div style="font-size:0.82rem;color:var(--bs-secondary-color)">
|
||||
${this._jobs.length} task${this._jobs.length !== 1 ? 's' : ''}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-clock"></i> Scheduled Tasks</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${this._jobs.length} task${this._jobs.length !== 1 ? 's' : ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -74,12 +74,12 @@ export class ToolDetailPage extends LightElement {
|
||||
const si = tl ? (STATUS_ICON[tl.status] || STATUS_ICON.done) : null;
|
||||
return html`
|
||||
<div class="llm-page tool-detail-page">
|
||||
<div class="llm-page-header">
|
||||
<div class="llm-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary back-btn" title=${t('fv.back')} @click=${() => this._back()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('fv.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<h2 class="llm-page-title">
|
||||
<h2 class="page-header-title">
|
||||
${tl ? html`
|
||||
${si ? html`<i class="bi ${si.glyph} ${si.cls} me-2"></i>` : nothing}
|
||||
${tl.display_name || tl.name}
|
||||
|
||||
@@ -342,10 +342,12 @@ export class UsersPage extends LightElement {
|
||||
|
||||
return html`
|
||||
<div class="um-page">
|
||||
<div class="um-header">
|
||||
<h2 class="um-title"><i class="bi bi-people-fill me-2"></i>${t('users.title')}</h2>
|
||||
<div class="um-header-right">
|
||||
<span class="um-header-count">${t(users.length === 1 ? 'users.count_one' : 'users.count_other', { n: users.length })}</span>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2 class="page-header-title"><i class="bi bi-people-fill me-2"></i>${t('users.title')}</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
<span class="page-header-count">${t(users.length === 1 ? 'users.count_one' : 'users.count_other', { n: users.length })}</span>
|
||||
<button class="btn btn-sm btn-primary" @click=${() => this._openCreate()}>
|
||||
<i class="bi bi-plus-lg me-1"></i>${t('users.btn.new')}
|
||||
</button>
|
||||
@@ -433,9 +435,9 @@ export class UsersPage extends LightElement {
|
||||
|
||||
_renderDetailHeader(u) {
|
||||
return html`
|
||||
<div class="um-header">
|
||||
<div class="d-flex align-items-center gap-2" style="min-width:0">
|
||||
<button class="btn btn-sm btn-outline-secondary" title=${t('users.detail.back')} @click=${() => this._back()}>
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<button class="btn btn-sm btn-outline-secondary page-header-back" title=${t('users.detail.back')} @click=${() => this._back()}>
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
${u ? html`
|
||||
@@ -443,7 +445,7 @@ export class UsersPage extends LightElement {
|
||||
${(u.display_name || u.username).charAt(0).toUpperCase()}
|
||||
</span>
|
||||
<div style="min-width:0">
|
||||
<h2 class="um-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
<h2 class="page-header-title" style="min-width:0;overflow:hidden;text-overflow:ellipsis">
|
||||
${u.display_name || u.username}</h2>
|
||||
<div class="d-flex align-items-center gap-2" style="font-size:.72rem">
|
||||
<code class="text-muted">${u.username}</code>
|
||||
@@ -452,7 +454,7 @@ export class UsersPage extends LightElement {
|
||||
${u.active ? nothing : html`<span class="um-badge um-badge-inactive">${t('users.badge.inactive')}</span>`}
|
||||
</div>
|
||||
</div>`
|
||||
: html`<h2 class="um-title">${t('users.title')}</h2>`}
|
||||
: html`<h2 class="page-header-title">${t('users.title')}</h2>`}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -16,26 +16,6 @@ agent-inbox-page {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.page-panel-header h5 {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ── Refresh button ── */
|
||||
|
||||
.inbox-refresh-btn {
|
||||
@@ -118,11 +98,6 @@ agent-inbox-page {
|
||||
/* ── Mobile tweaks ── */
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.page-panel-header {
|
||||
padding: 12px 14px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.inbox-grid {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 12px;
|
||||
|
||||
+2
-6
@@ -5,7 +5,6 @@ agents-page {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 1.5rem 2rem;
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
@@ -15,11 +14,8 @@ agents-page {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.agents-page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.75rem;
|
||||
.agents-body {
|
||||
padding: 1.5rem 2rem;
|
||||
}
|
||||
|
||||
/* ── Info banner ─────────────────────────────────────────────────────────── */
|
||||
|
||||
@@ -35,39 +35,6 @@ approval-groups-page {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.apr-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.apr-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.apr-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.apr-header-count {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 500;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
/* ── Card list ── */
|
||||
|
||||
.apr-card-list {
|
||||
@@ -417,11 +384,6 @@ approval-groups-page {
|
||||
/* ── Mobile ── */
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.apr-header {
|
||||
padding: 10px 14px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.apr-card-list {
|
||||
padding: 10px 12px;
|
||||
gap: 8px;
|
||||
|
||||
+4
-5
@@ -3,7 +3,6 @@ config-page {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 1.5rem 2rem;
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
@@ -13,11 +12,11 @@ config-page {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.config-page-header {
|
||||
.config-body {
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.75rem;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.config-sets {
|
||||
|
||||
@@ -8,39 +8,6 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.pv-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.pv-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pv-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.pv-header-count {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 500;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
/* ── Card list ── */
|
||||
|
||||
.pv-card-list {
|
||||
@@ -297,11 +264,6 @@
|
||||
/* ── Mobile ── */
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.pv-header {
|
||||
padding: 10px 14px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.pv-card-list {
|
||||
padding: 10px 12px;
|
||||
gap: 8px;
|
||||
|
||||
@@ -10,44 +10,19 @@ llm-requests-page {
|
||||
}
|
||||
|
||||
.llmr-page {
|
||||
padding: 1.5rem 2rem;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.llmr-body {
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
/* ── Header ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
.llmr-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.llmr-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.llmr-title i { color: var(--bs-secondary-color); }
|
||||
|
||||
.llmr-total-badge {
|
||||
margin-left: auto;
|
||||
font-size: 0.78rem;
|
||||
color: var(--bs-secondary-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
padding: 2px 10px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
/* ── Filters ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
.llmr-filters {
|
||||
@@ -197,24 +172,7 @@ llm-requests-page {
|
||||
.llmr-row--clickable { cursor: pointer; }
|
||||
.llmr-row--clickable:hover td { background: var(--bs-tertiary-bg); }
|
||||
|
||||
/* ── Detail — back bar ───────────────────────────────────────────────────────── */
|
||||
|
||||
.llmr-detail-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
}
|
||||
|
||||
.llmr-detail-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--bs-body-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
/* ── Detail ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
.llmr-detail-id {
|
||||
font-family: var(--bs-font-monospace);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* ── Models hub landing page ────────────────────────────────────────────────── */
|
||||
|
||||
.models-hub {
|
||||
padding: 2rem 2.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.models-hub-body {
|
||||
padding: 2rem 2.5rem;
|
||||
}
|
||||
|
||||
.models-hub-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
|
||||
@@ -10,56 +10,6 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.llm-page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.llm-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0 !important;
|
||||
border-radius: 6px !important;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.back-btn i {
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.llm-page-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.llm-page-count {
|
||||
font-size: 0.76rem;
|
||||
color: var(--bs-secondary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── Card list ── */
|
||||
|
||||
.llm-card-list {
|
||||
@@ -291,11 +241,6 @@
|
||||
/* ── Mobile tweaks ── */
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.llm-page-header {
|
||||
padding: 10px 14px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.llm-card-list {
|
||||
padding: 10px 12px;
|
||||
gap: 8px;
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* ── Shared page header bar ─────────────────────────────────────────────────
|
||||
The one canonical header for every full-page view: optional back button,
|
||||
title, right-side actions. Replaces the former per-page duplicates
|
||||
(.page-panel-header, .project-page-header, .task-page-header,
|
||||
.llm-page-header, .um-header top bars, .apr-header, .llmr-header,
|
||||
.pv-header, .sa-header, .config-page-header, .agents-page-header).
|
||||
|
||||
Markup contract:
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
[<button class="btn btn-sm btn-outline-secondary page-header-back">…</button>]
|
||||
<h2 class="page-header-title">…</h2>
|
||||
</div>
|
||||
<div class="page-header-actions">
|
||||
[<span class="page-header-count">…</span>] [buttons…]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Sticky so it stays pinned on pages whose container scrolls. */
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.page-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.page-header-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0 !important;
|
||||
border-radius: 6px !important;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.page-header-back i {
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.page-header-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.page-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.page-header-count {
|
||||
font-size: 0.82rem;
|
||||
color: var(--bs-secondary-color);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.page-header {
|
||||
padding: 10px 14px;
|
||||
min-height: 50px;
|
||||
}
|
||||
}
|
||||
@@ -8,26 +8,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.project-page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.project-page-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ── Grid ── */
|
||||
|
||||
.project-grid {
|
||||
|
||||
@@ -9,29 +9,11 @@
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
padding: 1.5rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.sa-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.35rem;
|
||||
.sa-body {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.sa-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
.sa-total-badge {
|
||||
font-size: 0.75rem;
|
||||
color: var(--bs-secondary-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: 1rem;
|
||||
padding: 0.1rem 0.6rem;
|
||||
}
|
||||
.sa-refresh-btn { margin-left: auto; }
|
||||
.sa-subtitle {
|
||||
font-size: 0.85rem;
|
||||
color: var(--bs-secondary-color);
|
||||
|
||||
@@ -8,26 +8,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.task-page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
min-height: 54px;
|
||||
border-bottom: 1px solid var(--bs-border-color);
|
||||
background: var(--bs-tertiary-bg);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.task-page-title {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
font-size: 1.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ── Empty state ── */
|
||||
|
||||
.task-empty {
|
||||
|
||||
@@ -21,18 +21,6 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.um-header-right {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.um-header-count {
|
||||
font-size: .82rem;
|
||||
color: var(--placeholder-color);
|
||||
}
|
||||
|
||||
.um-table-wrap {
|
||||
padding: 0 24px 24px;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<link rel="stylesheet" href="css/copilot-input.css" />
|
||||
<link rel="stylesheet" href="css/dialogs.css" />
|
||||
<link rel="stylesheet" href="css/page-shell.css" />
|
||||
<link rel="stylesheet" href="css/page-header.css" />
|
||||
<link rel="stylesheet" href="css/connectors.css" />
|
||||
<link rel="stylesheet" href="css/models-hub.css" />
|
||||
<link rel="stylesheet" href="css/tasks/base.css" />
|
||||
|
||||
Reference in New Issue
Block a user