Bloqueantes POS: modal-pago, ticket-termico, banner-cliente, fkeys-footer, columnas-costo-margen Componentes nuevos: calculadora-cambio, panel-deslizante, badge-cfdi, arbol-colapsable, tarjeta-metrica, grafica-barras, selector-periodo, etiqueta-codigo-barras Estados: estado-vacio, banner-offline, modal-confirmacion Páginas actualizadas: facturación, contabilidad, dashboard, configuración, reportes
606 lines
24 KiB
HTML
606 lines
24 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="es" data-theme="industrial">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Nexus Autoparts — Árbol Colapsable</title>
|
|
<link rel="stylesheet" href="../tokens/tokens.css">
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: var(--font-body); background: var(--color-bg-base);
|
|
color: var(--color-text-primary); padding: var(--space-8);
|
|
transition: var(--transition-normal);
|
|
}
|
|
.theme-switcher {
|
|
position: sticky; top: 0; z-index: calc(var(--z-modal) + 10);
|
|
display: flex; gap: var(--space-2);
|
|
padding: var(--space-3) var(--space-4);
|
|
background: var(--color-bg-elevated);
|
|
border-bottom: 1px solid var(--color-border);
|
|
margin: calc(-1 * var(--space-8)); margin-bottom: var(--space-8);
|
|
}
|
|
.theme-switcher button {
|
|
padding: var(--space-2) var(--space-4);
|
|
border: 1px solid var(--color-border);
|
|
background: var(--color-bg-base); color: var(--color-text-primary);
|
|
border-radius: var(--radius-md); cursor: pointer;
|
|
font-family: var(--font-body); font-size: var(--text-body-sm);
|
|
transition: var(--transition-fast);
|
|
}
|
|
.theme-switcher button.active {
|
|
background: var(--color-primary); color: var(--color-text-inverse);
|
|
border-color: var(--color-primary);
|
|
}
|
|
h1 { font-family: var(--font-heading); font-size: var(--text-h2);
|
|
font-weight: var(--heading-weight-primary); margin-bottom: var(--space-2);
|
|
color: var(--color-text-accent); }
|
|
.subtitle { color: var(--color-text-muted); font-size: var(--text-body); margin-bottom: var(--space-8); }
|
|
section { margin-bottom: var(--space-10); }
|
|
section > h2 {
|
|
font-family: var(--font-heading); font-size: var(--text-h4);
|
|
font-weight: var(--heading-weight-secondary); color: var(--color-text-secondary);
|
|
margin-bottom: var(--space-4); padding-bottom: var(--space-2);
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
/* Tree controls */
|
|
.tree-controls {
|
|
display: flex;
|
|
gap: var(--space-2);
|
|
margin-bottom: var(--space-4);
|
|
}
|
|
.tree-controls button {
|
|
padding: var(--space-2) var(--space-4);
|
|
font-family: var(--font-body);
|
|
font-size: var(--text-body-sm);
|
|
font-weight: var(--font-weight-semibold);
|
|
background: var(--btn-ghost-bg);
|
|
color: var(--btn-ghost-text);
|
|
border: 1px solid var(--btn-ghost-border);
|
|
border-radius: var(--radius-md);
|
|
cursor: pointer;
|
|
transition: var(--transition-fast);
|
|
}
|
|
.tree-controls button:hover {
|
|
background: var(--color-surface-2);
|
|
color: var(--color-text-primary);
|
|
}
|
|
|
|
/* Tree container */
|
|
.tree-container {
|
|
background: var(--color-bg-elevated);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-lg);
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Tree header */
|
|
.tree-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: var(--space-3) var(--space-5);
|
|
background: var(--color-surface-1);
|
|
border-bottom: 1px solid var(--color-border);
|
|
font-size: var(--text-caption);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-text-muted);
|
|
text-transform: uppercase;
|
|
letter-spacing: var(--tracking-wider);
|
|
}
|
|
|
|
/* Tree node */
|
|
.tree-node {
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
.tree-node:last-child { border-bottom: none; }
|
|
|
|
.tree-row {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: var(--space-3) var(--space-4);
|
|
cursor: pointer;
|
|
transition: var(--transition-fast);
|
|
gap: var(--space-2);
|
|
}
|
|
.tree-row:hover {
|
|
background: var(--color-primary-muted);
|
|
}
|
|
.tree-row.selected {
|
|
background: var(--color-primary-muted);
|
|
border-left: 3px solid var(--color-primary);
|
|
}
|
|
|
|
/* Arrow */
|
|
.tree-arrow {
|
|
width: 20px;
|
|
height: 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
font-size: 12px;
|
|
color: var(--color-text-muted);
|
|
transition: transform var(--duration-fast) var(--ease-out);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
.tree-arrow:hover {
|
|
background: var(--color-surface-3);
|
|
color: var(--color-text-primary);
|
|
}
|
|
.tree-arrow.expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
.tree-arrow.leaf {
|
|
visibility: hidden;
|
|
}
|
|
|
|
/* Account code */
|
|
.tree-code {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-body-sm);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-text-accent);
|
|
min-width: 50px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* Account name */
|
|
.tree-name {
|
|
flex: 1;
|
|
font-size: var(--text-body-sm);
|
|
color: var(--color-text-primary);
|
|
}
|
|
.tree-row.level-0 .tree-name {
|
|
font-weight: var(--font-weight-bold);
|
|
font-size: var(--text-body);
|
|
}
|
|
.tree-row.level-1 .tree-name {
|
|
font-weight: var(--font-weight-semibold);
|
|
}
|
|
|
|
/* Balance */
|
|
.tree-balance {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-body-sm);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-text-secondary);
|
|
text-align: right;
|
|
min-width: 120px;
|
|
flex-shrink: 0;
|
|
}
|
|
.tree-row.level-0 .tree-balance {
|
|
font-weight: var(--font-weight-bold);
|
|
color: var(--color-text-primary);
|
|
font-size: var(--text-body);
|
|
}
|
|
|
|
/* Children container */
|
|
.tree-children {
|
|
overflow: hidden;
|
|
max-height: 0;
|
|
transition: max-height var(--duration-normal) var(--ease-out);
|
|
}
|
|
.tree-children.expanded {
|
|
max-height: 2000px;
|
|
}
|
|
|
|
/* Indentation */
|
|
.tree-row.level-0 { padding-left: var(--space-4); }
|
|
.tree-row.level-1 { padding-left: calc(var(--space-4) + var(--space-6)); }
|
|
.tree-row.level-2 { padding-left: calc(var(--space-4) + var(--space-6) * 2); }
|
|
|
|
/* Level-specific styling */
|
|
.tree-node.level-0 > .tree-row {
|
|
background: var(--color-surface-1);
|
|
}
|
|
.tree-node.level-0 > .tree-row:hover {
|
|
background: var(--color-primary-muted);
|
|
}
|
|
|
|
/* Summary row */
|
|
.tree-summary {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: var(--space-4) var(--space-5);
|
|
background: var(--color-surface-2);
|
|
border-top: 2px solid var(--color-border-accent);
|
|
font-weight: var(--font-weight-bold);
|
|
}
|
|
.tree-summary .label {
|
|
font-family: var(--font-heading);
|
|
font-size: var(--text-body);
|
|
color: var(--color-text-primary);
|
|
text-transform: uppercase;
|
|
letter-spacing: var(--tracking-wide);
|
|
}
|
|
.tree-summary .total {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-body);
|
|
color: var(--color-text-accent);
|
|
}
|
|
|
|
/* Count badge */
|
|
.child-count {
|
|
font-size: var(--text-caption);
|
|
color: var(--color-text-disabled);
|
|
font-family: var(--font-mono);
|
|
margin-left: var(--space-1);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="theme-switcher">
|
|
<button class="active" onclick="document.documentElement.dataset.theme='industrial'; this.classList.add('active'); this.nextElementSibling.classList.remove('active')">🔧 Industrial</button>
|
|
<button onclick="document.documentElement.dataset.theme='modern'; this.classList.add('active'); this.previousElementSibling.classList.remove('active')">⚡ Moderno</button>
|
|
</div>
|
|
|
|
<h1>Árbol Colapsable</h1>
|
|
<p class="subtitle">Catálogo de cuentas SAT con estructura jerárquica colapsable</p>
|
|
|
|
<section>
|
|
<h2>Catálogo de Cuentas</h2>
|
|
|
|
<div class="tree-controls">
|
|
<button onclick="expandAll()">Expandir Todo</button>
|
|
<button onclick="collapseAll()">Colapsar Todo</button>
|
|
</div>
|
|
|
|
<div class="tree-container" id="accountTree">
|
|
<div class="tree-header">
|
|
<span>Cuenta</span>
|
|
<span>Saldo</span>
|
|
</div>
|
|
|
|
<!-- 1000 Activo -->
|
|
<div class="tree-node level-0" data-code="1000">
|
|
<div class="tree-row level-0" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">1000</span>
|
|
<span class="tree-name">Activo <span class="child-count">(3)</span></span>
|
|
<span class="tree-balance">$1,245,800.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<!-- 1100 Bancos -->
|
|
<div class="tree-node level-1" data-code="1100">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">1100</span>
|
|
<span class="tree-name">Bancos <span class="child-count">(3)</span></span>
|
|
<span class="tree-balance">$485,320.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1101</span>
|
|
<span class="tree-name">Banamex Cta. 7845</span>
|
|
<span class="tree-balance">$198,450.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1102</span>
|
|
<span class="tree-name">BBVA Cta. 3021</span>
|
|
<span class="tree-balance">$245,870.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1103</span>
|
|
<span class="tree-name">Banorte Cta. 5590</span>
|
|
<span class="tree-balance">$41,000.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 1200 Inventarios -->
|
|
<div class="tree-node level-1" data-code="1200">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">1200</span>
|
|
<span class="tree-name">Inventarios <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$628,480.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1201</span>
|
|
<span class="tree-name">Almacén General</span>
|
|
<span class="tree-balance">$520,300.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1202</span>
|
|
<span class="tree-name">Mercancía en Tránsito</span>
|
|
<span class="tree-balance">$108,180.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 1300 Cuentas por Cobrar -->
|
|
<div class="tree-node level-1" data-code="1300">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">1300</span>
|
|
<span class="tree-name">Cuentas por Cobrar <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$132,000.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1301</span>
|
|
<span class="tree-name">Clientes Nacionales</span>
|
|
<span class="tree-balance">$118,500.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">1302</span>
|
|
<span class="tree-name">Deudores Diversos</span>
|
|
<span class="tree-balance">$13,500.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 2000 Pasivo -->
|
|
<div class="tree-node level-0" data-code="2000">
|
|
<div class="tree-row level-0" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">2000</span>
|
|
<span class="tree-name">Pasivo <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$389,200.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-1" data-code="2100">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">2100</span>
|
|
<span class="tree-name">Proveedores <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$285,000.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">2101</span>
|
|
<span class="tree-name">Proveedores Nacionales</span>
|
|
<span class="tree-balance">$245,000.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">2102</span>
|
|
<span class="tree-name">Proveedores Extranjeros</span>
|
|
<span class="tree-balance">$40,000.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-1" data-code="2200">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">2200</span>
|
|
<span class="tree-name">Impuestos por Pagar <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$104,200.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">2201</span>
|
|
<span class="tree-name">IVA Trasladado</span>
|
|
<span class="tree-balance">$72,200.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">2202</span>
|
|
<span class="tree-name">ISR por Pagar</span>
|
|
<span class="tree-balance">$32,000.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 3000 Capital -->
|
|
<div class="tree-node level-0" data-code="3000">
|
|
<div class="tree-row level-0" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">3000</span>
|
|
<span class="tree-name">Capital <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$500,000.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-1">
|
|
<div class="tree-row level-1" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">3100</span>
|
|
<span class="tree-name">Capital Social</span>
|
|
<span class="tree-balance">$350,000.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-1">
|
|
<div class="tree-row level-1" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">3200</span>
|
|
<span class="tree-name">Utilidades Acumuladas</span>
|
|
<span class="tree-balance">$150,000.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 4000 Ingresos -->
|
|
<div class="tree-node level-0" data-code="4000">
|
|
<div class="tree-row level-0" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">4000</span>
|
|
<span class="tree-name">Ingresos <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$892,450.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-1" data-code="4100">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">4100</span>
|
|
<span class="tree-name">Ventas <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$845,200.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">4101</span>
|
|
<span class="tree-name">Ventas Mostrador</span>
|
|
<span class="tree-balance">$562,800.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">4102</span>
|
|
<span class="tree-name">Ventas a Crédito</span>
|
|
<span class="tree-balance">$282,400.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-1">
|
|
<div class="tree-row level-1" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">4200</span>
|
|
<span class="tree-name">Otros Ingresos</span>
|
|
<span class="tree-balance">$47,250.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 5000 Gastos -->
|
|
<div class="tree-node level-0" data-code="5000">
|
|
<div class="tree-row level-0" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">5000</span>
|
|
<span class="tree-name">Gastos <span class="child-count">(2)</span></span>
|
|
<span class="tree-balance">$536,050.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-1" data-code="5100">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">5100</span>
|
|
<span class="tree-name">Costo de Ventas <span class="child-count">(1)</span></span>
|
|
<span class="tree-balance">$421,500.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">5101</span>
|
|
<span class="tree-name">Costo Mercancía Vendida</span>
|
|
<span class="tree-balance">$421,500.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-1" data-code="5200">
|
|
<div class="tree-row level-1" onclick="toggleNode(this)">
|
|
<span class="tree-arrow">▶</span>
|
|
<span class="tree-code">5200</span>
|
|
<span class="tree-name">Gastos de Operación <span class="child-count">(3)</span></span>
|
|
<span class="tree-balance">$114,550.00</span>
|
|
</div>
|
|
<div class="tree-children">
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">5201</span>
|
|
<span class="tree-name">Sueldos y Salarios</span>
|
|
<span class="tree-balance">$68,000.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">5202</span>
|
|
<span class="tree-name">Renta Local</span>
|
|
<span class="tree-balance">$28,000.00</span>
|
|
</div>
|
|
</div>
|
|
<div class="tree-node level-2">
|
|
<div class="tree-row level-2" onclick="selectNode(this)">
|
|
<span class="tree-arrow leaf">▶</span>
|
|
<span class="tree-code">5203</span>
|
|
<span class="tree-name">Servicios (Luz, Tel, Internet)</span>
|
|
<span class="tree-balance">$18,550.00</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Summary -->
|
|
<div class="tree-summary">
|
|
<span class="label">Total Activos - Pasivos</span>
|
|
<span class="total">$856,600.00</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
function toggleNode(rowEl) {
|
|
const node = rowEl.parentElement;
|
|
const children = node.querySelector('.tree-children');
|
|
const arrow = rowEl.querySelector('.tree-arrow');
|
|
|
|
if (!children) {
|
|
selectNode(rowEl);
|
|
return;
|
|
}
|
|
|
|
const isExpanded = children.classList.contains('expanded');
|
|
if (isExpanded) {
|
|
children.classList.remove('expanded');
|
|
arrow.classList.remove('expanded');
|
|
} else {
|
|
children.classList.add('expanded');
|
|
arrow.classList.add('expanded');
|
|
}
|
|
|
|
selectNode(rowEl);
|
|
}
|
|
|
|
function selectNode(rowEl) {
|
|
// Remove previous selection
|
|
document.querySelectorAll('.tree-row.selected').forEach(el => el.classList.remove('selected'));
|
|
rowEl.classList.add('selected');
|
|
}
|
|
|
|
function expandAll() {
|
|
document.querySelectorAll('.tree-children').forEach(el => el.classList.add('expanded'));
|
|
document.querySelectorAll('.tree-arrow:not(.leaf)').forEach(el => el.classList.add('expanded'));
|
|
}
|
|
|
|
function collapseAll() {
|
|
document.querySelectorAll('.tree-children').forEach(el => el.classList.remove('expanded'));
|
|
document.querySelectorAll('.tree-arrow').forEach(el => el.classList.remove('expanded'));
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |