- Rebrand: new app/agent icons, SKALD.md, warm "paper" CSS palette (terracotta accent, --radius tokens, WCAG contrast, reduced-motion), updated favicon, tray icon, skaldkonur asset - i18n: backend crate (i18n.rs, locale column, ui_locale config), frontend library (web/lib/i18n.js, I18nMixin, t(key)), translation files (web/i18n/), every component wired - Dashboard: <dashboard-page> replaces old home-page content; <app-copilot> becomes the landing page (full/dock layout modes) - Shared folders: API endpoints (shared_folders.rs), frontend page, can_write membership, container mount topology, user_fs routing - Role capabilities: new db table & authorization seam (data not enums), roles.attrs JSON for ui_mode / interface select - Setup: skald-setup prompts for language + password, sets ui_locale - General: components migrated to CSS variables, Lit conventions cleanup, connectors/catalog/marketplace/approval refactoring
74 lines
1.9 KiB
JavaScript
74 lines
1.9 KiB
JavaScript
import { html, nothing } from 'lit';
|
|
import { LightElement } from '../lib/base.js';
|
|
import { InboxMixin } from '../lib/inbox-mixin.js';
|
|
import { t, I18nMixin } from '../lib/i18n.js';
|
|
|
|
export class AgentInboxPage extends I18nMixin(InboxMixin(LightElement)) {
|
|
|
|
static get properties() {
|
|
return {
|
|
...super.properties,
|
|
_open: { state: true },
|
|
};
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this._open = false;
|
|
this._pollTimer = null;
|
|
}
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
window.addEventListener('llm-page-change', (e) => {
|
|
this._open = e.detail.page === 'inbox';
|
|
this.style.display = this._open ? 'flex' : 'none';
|
|
if (this._open) {
|
|
this._loadInbox();
|
|
this._startPolling();
|
|
} else {
|
|
this._stopPolling();
|
|
}
|
|
});
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
super.disconnectedCallback();
|
|
this._stopPolling();
|
|
}
|
|
|
|
_startPolling() {
|
|
this._stopPolling();
|
|
this._pollTimer = setInterval(() => this._loadInbox(), 8000);
|
|
}
|
|
|
|
_stopPolling() {
|
|
if (this._pollTimer) {
|
|
clearInterval(this._pollTimer);
|
|
this._pollTimer = null;
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const approvals = this._inboxData?.approvals ?? [];
|
|
const clarifications = this._inboxData?.clarifications ?? [];
|
|
const elicitations = this._inboxData?.elicitations ?? [];
|
|
const total = approvals.length + clarifications.length + elicitations.length;
|
|
|
|
return html`
|
|
<div class="page-panel">
|
|
<div class="page-panel-header">
|
|
<h5 class="mb-0">
|
|
${t('nav.inbox')}
|
|
${total > 0 ? html`<span class="badge bg-danger ms-2">${total}</span>` : nothing}
|
|
</h5>
|
|
<button class="inbox-refresh-btn" title="Refresh" @click=${() => this._loadInbox()}>
|
|
<i class="bi bi-arrow-clockwise"></i>
|
|
</button>
|
|
</div>
|
|
${this._renderInboxSection()}
|
|
</div>
|
|
`;
|
|
}
|
|
}
|