import { customElement, query, state } from "lit/decorators.js"; import { ClientConsumer } from "../ClientConsumer"; import { ServerInfo } from "@labir/server"; import { css, CSSResultGroup, html, nothing } from "lit"; import { TimeFormat } from "@labir/core"; import { t } from "i18next"; import { T } from "../../../translations/Languages"; type HistoryItem = { timestamp: number; success: boolean; code: boolean; message: boolean; method: string; }; @customElement("server-info") export class ServerBar extends ClientConsumer { @state() protected history: HistoryItem[] = []; @state() protected logExpanded: boolean = false; connectedCallback(): void { super.connectedCallback(); this.client?.onResult.set(this.UUID, (timestamp, success, code, message, method) => { this.history.push({ timestamp, success, code, message, method }); this.requestUpdate(); }); } static styles?: CSSResultGroup | undefined = css` :host { display: flex; align-items: flex-start; gap: 0.5em; } .icon { font-size: 1em; width: 1em; height: 1em; } .spinner { width: 1em; height: 1em; display: inline-block; vertical-align: middle; animation: spin 1s linear infinite; color: var(--thermal-primary); } @keyframes spin { 100% { transform: rotate(360deg); } } .dialog-trigger { color: var( --thermal-primary ); cursor: pointer; &:hover, &:focus { text-decoration: underline; } } .history { flex-grow: 1; table { width: 100%; border-collapse: collapse; } td { padding: 0.1em 0.1em; box-sizing: border-box; vertical-align: center; &.time {width: 55px;} &.method, &.code { width: 40px; } &.success, &.error {width: 1em;} &.method, &.code, &.success, &.error { text-align: center; } i { display: inline-block; width: .5em; height: .5em; line-height: 0; border-radius: 50%; margin-bottom: 0.15em; } &.success i { background: var( --thermal-primary ); } &.error i { background: red; } } } .history.collapsed { .history-header { display: none; } transition: all .2s ease-in-out; cursor: pointer; &:hover { color: var( --thermal-foreground ); } } .history.expanded { border: 1px solid var( --thermal-slate ); border-radius: var( --thermal-radius ); overflow: hidden; .history-header { } .history-content { max-height: 150px; overflow-y: scroll; } } .history-header { display: flex; gap: 0.5em; align-items: center; justify-content: space-between; padding: 0.2em 0.5em; background: var( --thermal-slate-dark ); color: var( --thermal-background ); cursor: pointer; transition: all .3s ease-in-out; svg { transition: transform .3s ease-in-out; } &:hover, &:focus { color: var( --thermal-primary-light ); background: var( --thermal-foreground ); svg { transform: scale(1.2); } } h2 { padding: 0; margin: 0; font-size: calc( var( --thermal-fs ) * 0.7 ); text-transform: uppercase; letter-spacing: 0.05em; } } `; protected renderIcon(): unknown { // Pokud probíhá načítání, zobraz spinner if (this.isClientLoading) { // Spinner: oblouk 270°, 90° mezera return html` `; } let col = this.isClientConnecting ? "var(--thermal-primary)" : this.client?.isConnected() ? "var(--thermal-primary)" : "red"; return html``; } protected renderLoading(): unknown { return html`