;
};
}
/**
* Círculo de estado que muestra el nivel de compatibilidad del sistema
*
* @element system-status
*
* @prop {SystemRequirements} requirements - Requisitos del sistema a validar
* @prop {Size} size - Tamaño del círculo: 'small', 'medium', 'large'
* @prop {boolean} autoCheck - Si debe verificar automáticamente al cargar
* @prop {boolean} showTooltip - Si debe mostrar tooltip con información
*
* @fires status-change - Se dispara cuando cambia el estado
* @fires click - Se dispara al hacer click en el círculo
*
* @example
* ```html
*
* ```
*/
@customElement('system-status')
export class SystemStatus extends LitElement {
static styles = css`
:host {
display: inline-block;
cursor: pointer;
}
.status-circle {
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
position: relative;
}
.status-circle:hover {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.status-circle.small {
width: 24px;
height: 24px;
}
.status-circle.medium {
width: 48px;
height: 48px;
}
.status-circle.large {
width: 72px;
height: 72px;
}
.status-circle.success {
background: linear-gradient(135deg, #66bb6a, #43a047);
}
.status-circle.warning {
background: linear-gradient(135deg, #ffa726, #fb8c00);
}
.status-circle.error {
background: linear-gradient(135deg, #ef5350, #e53935);
}
.status-circle.checking {
background: linear-gradient(135deg, #78909c, #546e7a);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.6;
}
}
.icon {
color: white;
font-size: 0.6em;
font-weight: bold;
}
.tooltip {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%) translateY(8px);
background: rgba(0, 0, 0, 0.95);
color: white;
padding: 16px;
border-radius: 8px;
font-size: 13px;
white-space: normal;
min-width: 280px;
max-width: 400px;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.tooltip.visible {
opacity: 1;
pointer-events: auto;
}
.tooltip::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom-color: rgba(0, 0, 0, 0.95);
}
.tooltip-header {
font-weight: bold;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.tooltip-section {
margin: 8px 0;
}
.tooltip-label {
font-size: 11px;
opacity: 0.7;
margin-bottom: 4px;
}
.tooltip-value {
font-weight: 500;
}
.tooltip-failure {
color: #ff6b6b;
margin-top: 4px;
font-size: 12px;
}
`;
@property({ type: Object })
requirements: SystemRequirements = {};
@property({ type: String })
size: Size = 'medium';
@property({ type: Boolean })
autoCheck = false;
@property({ type: Boolean })
showTooltip = true;
@state()
private status: StatusLevel = 'checking';
@state()
private message = 'Verificando...';
@state()
private failures: any[] = [];
@state()
private tooltipVisible = false;
@state()
private systemInfo: any = null;
private capabilities = new SystemCapabilities();
async checkSystem() {
this.status = 'checking';
this.message = 'Verificando...';
try {
// Obtener información del sistema
this.systemInfo = this.capabilities.getSummary();
const result = await this.capabilities.checkRequirements(this.requirements, false);
this.failures = result.failures;
if (result.passed) {
this.status = 'success';
this.message = 'Sistema compatible';
} else {
// Determinar si son fallos críticos o advertencias
const criticalFailures = result.failures.filter((f: any) =>
f.category === 'features' || f.category === 'device'
);
if (criticalFailures.length > 0) {
this.status = 'error';
this.message = `${result.failures.length} problema(s) detectado(s)`;
} else {
this.status = 'warning';
this.message = `${result.failures.length} advertencia(s)`;
}
}
this.dispatchEvent(new CustomEvent('status-change', {
detail: {
status: this.status,
failures: this.failures,
message: this.message,
systemInfo: this.systemInfo
},
bubbles: true,
composed: true
}));
} catch (error) {
this.status = 'error';
this.message = 'Error al verificar';
console.error('Error checking system:', error);
}
}
private handleClick(e: Event) {
e.stopPropagation();
this.tooltipVisible = !this.tooltipVisible;
this.dispatchEvent(new CustomEvent('click', {
detail: {
status: this.status,
failures: this.failures,
capabilities: this.capabilities.getCapabilities(),
systemInfo: this.systemInfo
},
bubbles: true,
composed: true
}));
}
private handleClickOutside = (e: Event) => {
if (!this.contains(e.target as Node)) {
this.tooltipVisible = false;
}
}
connectedCallback() {
super.connectedCallback();
if (this.autoCheck) {
this.checkSystem();
}
document.addEventListener('click', this.handleClickOutside);
}
disconnectedCallback() {
super.disconnectedCallback();
document.removeEventListener('click', this.handleClickOutside);
}
private getIcon() {
switch (this.status) {
case 'success':
return '✓';
case 'warning':
return '!';
case 'error':
return '✕';
case 'checking':
return '...';
default:
return '';
}
}
private renderTooltipContent() {
if (!this.systemInfo) return '';
return html`
${this.systemInfo.network.available ? html`
` : ''}
${this.failures.length > 0 ? html`
` : ''}
`;
}
render() {
return html`
${this.getIcon()}
${this.showTooltip ? html`
${this.renderTooltipContent()}
` : ''}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'system-status': SystemStatus;
}
}