PHP Classes

File: app/modules/filter-manager.js

Recommend this page to a friend!
  Packages of DeGraciaMathieu   PHP Dep Dashboard   app/modules/filter-manager.js   Download  
File: app/modules/filter-manager.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP Dep Dashboard
Visualize PHP class dependencies in a Web page
Author: By
Last change:
Date: 16 days ago
Size: 5,450 bytes
 

Contents

Class file image Download
import { emit, on, state } from './state.js'; import { getNamespaceKey } from './data-loader.js'; let filtersEl; let namespaces = []; export function initFilters(data) { filtersEl = document.getElementById('filters'); namespaces = collectNamespaces(data); render(data); bindEvents(); on('data:loaded', (d) => { namespaces = collectNamespaces(d); render(d); }); } function collectNamespaces(data) { const nsSet = new Set(); for (const [, cls] of data.classes) { nsSet.add(cls.namespace); } return [...nsSet].sort(); } function render(data) { const types = ['class', 'interface', 'trait', 'enum']; const confidences = ['certain', 'high', 'medium', 'low']; filtersEl.innerHTML = ` <div class="filter-section"> <h3>Show external</h3> <label class="toggle-label"> <input type="checkbox" id="filter-external"> Show vendor / external classes </label> </div> <div class="filter-section"> <h3>Type</h3> ${types .map( (t) => ` <label class="filter-check"> <input type="checkbox" data-filter="type" value="${t}" checked> <span class="chip chip--${t}">${t}</span> </label>` ) .join('')} </div> <div class="filter-section"> <h3>Confidence</h3> ${confidences .map( (c) => ` <label class="filter-check"> <input type="checkbox" data-filter="confidence" value="${c}" checked> ${c} </label>` ) .join('')} </div> <div class="filter-section"> <h3>Namespace</h3> <div class="namespace-actions"> <button class="btn btn--sm" id="ns-select-all">All</button> <button class="btn btn--sm" id="ns-deselect-all">None</button> </div> <input type="text" id="ns-search" class="ns-search-input" placeholder="Filter namespaces?" autocomplete="off"> <div class="namespace-filters"> ${namespaces .map( (ns) => ` <label class="filter-check"> <input type="checkbox" data-filter="namespace" value="${ns}" checked> ${ns} </label>` ) .join('')} </div> </div> <div class="filter-section"> <h3>Layout</h3> <select id="layout-select"> <option value="fcose" selected>Force-directed (fcose)</option> <option value="cose">CoSE (fallback)</option> </select> </div> `; } function bindEvents() { filtersEl.addEventListener('change', (e) => { const target = e.target; if (target.id === 'filter-external') { toggleExternal(target.checked); return; } if (target.id === 'layout-select') { emit('layout:run', target.value); return; } if (target.dataset.filter) { applyFilters(); } }); filtersEl.addEventListener('click', (e) => { const target = e.target; if (target.id === 'ns-select-all' || target.id === 'ns-deselect-all') { const checked = target.id === 'ns-select-all'; filtersEl .querySelectorAll('input[data-filter="namespace"]') .forEach((cb) => { cb.checked = checked; }); applyFilters(); } }); filtersEl.addEventListener('input', (e) => { if (e.target.id === 'ns-search') { const query = e.target.value.trim().toLowerCase(); filtersEl.querySelectorAll('.namespace-filters .filter-check').forEach((label) => { const ns = label.querySelector('input').value.toLowerCase(); label.style.display = ns.includes(query) ? '' : 'none'; }); } }); } function toggleExternal(show) { const cy = state.cy; if (!cy) return; cy.startBatch(); const externals = cy.nodes('[?external]'); if (show) { externals.show(); } else { externals.hide(); } cy.endBatch(); emit('layout:run', document.getElementById('layout-select').value); } function applyFilters() { const cy = state.cy; if (!cy) return; const activeTypes = getCheckedValues('type'); const activeConfidences = getCheckedValues('confidence'); const activeNamespaces = getCheckedValues('namespace'); const showExternal = document.getElementById('filter-external').checked; cy.startBatch(); // Filter nodes cy.nodes().forEach((node) => { const d = node.data(); // Namespace folder/container nodes are always visible ? they're navigational if (d.nodeType === 'namespace' || d.nodeType === 'namespace-container') { node.show(); return; } const typeMatch = activeTypes.has(d.type); const nsMatch = activeNamespaces.has(d.namespace); const externalMatch = d.external ? showExternal : true; if (typeMatch && nsMatch && externalMatch) { node.show(); } else { node.hide(); } }); // Filter edges by confidence and visibility of endpoints cy.edges().forEach((edge) => { const confMatch = activeConfidences.has(edge.data('confidence')); const srcVisible = edge.source().visible(); const tgtVisible = edge.target().visible(); if (confMatch && srcVisible && tgtVisible) { edge.show(); } else { edge.hide(); } }); cy.endBatch(); state.filtersActive = true; emit('filters:applied'); } function getCheckedValues(filterName) { const checks = filtersEl.querySelectorAll( `input[data-filter="${filterName}"]:checked` ); return new Set([...checks].map((c) => c.value)); }