+
+
+
+
+
+
SysCmd
+
+ Référence de commandes multi-plateforme. Cliquez sur un OS pour voir ses commandes.
+
+
+ Données disponibles
+ Catégorie
+ À venir
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/script.js b/script.js
index 9e85510..e279ad7 100644
--- a/script.js
+++ b/script.js
@@ -1,7 +1,8 @@
-/* SYSCMD — arbre avec sections en sous-niveaux */
+/* SYSCMD — arbre avec sections en sous-niveaux + page d'accueil */
function t(fr, en) { return { fr: fr, en: en }; }
let currentNode = null;
+let currentSection = null;
const TREE = {
id: 'root', label: t('OS', 'OS'),
@@ -35,26 +36,25 @@ const TREE = {
]
};
-// ── SECTIONS ──
const SEC = {};
-SEC.sys = { label: t('syst\u00e8me', 'system'), commands: [
+SEC.sys = { label: t('système', 'system'), commands: [
{ d: t('Version du noyau', 'Kernel version'), c: 'uname -r' },
{ d: t('Version OS', 'OS version'), c: 'lsb_release -a' },
- { d: t('Memoire dispo', 'Memory available'), c: 'free -h' },
- { d: t("Nom d'hote", 'Hostname'), c: 'hostnamectl' },
+ { d: t('Mémoire dispo', 'Memory available'), c: 'free -h' },
+ { d: t("Nom d'hôte", 'Hostname'), c: 'hostnamectl' },
{ d: t('Uptime', 'Uptime'), c: 'uptime' },
{ d: t('Infos CPU', 'CPU info'), c: 'lscpu' },
{ d: t('Date / heure', 'Date / time'), c: 'timedatectl' },
]};
SEC.apt = { label: t('APT', 'APT'), commands: [
- { d: t('Synchro depots', 'Sync repos'), c: 'sudo apt update' },
- { d: t('Mise a jour', 'Full upgrade'), c: 'sudo apt full-upgrade -y' },
+ { d: t('Synchro dépôts', 'Sync repos'), c: 'sudo apt update' },
+ { d: t('Mise à jour', 'Full upgrade'), c: 'sudo apt full-upgrade -y' },
{ d: t('Installer', 'Install'), c: 'sudo apt install [package]' },
{ d: t('Purge', 'Purge'), c: 'sudo apt purge [package]' },
{ d: t('Chercher', 'Search'), c: 'apt search [keyword]' },
- { d: t('Paquets installes', 'Installed'), c: 'apt list --installed' },
+ { d: t('Paquets installés', 'Installed'), c: 'apt list --installed' },
{ d: t('Fichiers fournis', 'Package files'), c: 'dpkg -L [package]' },
]};
@@ -75,7 +75,7 @@ SEC.systemd = { label: t('systemd', 'systemd'), commands: [
{ d: t('Purger logs', 'Purge logs'), c: 'sudo journalctl --vacuum-time=7d' },
]};
-SEC['win-sys'] = { label: t('systeme', 'system'), commands: [
+SEC['win-sys'] = { label: t('système', 'system'), commands: [
{ d: t('(CMD) Version', '(CMD) Version'), c: 'ver' },
{ d: t('(CMD) systeminfo', '(CMD) systeminfo'), c: 'systeminfo' },
{ d: t('(PS) Get-ComputerInfo', '(PS) Get-ComputerInfo'), c: 'Get-ComputerInfo' },
@@ -93,7 +93,7 @@ SEC['win-process'] = { label: t('processus', 'processes'), commands: [
{ d: t('(PS) Get-Process', '(PS) Get-Process'), c: 'Get-Process' },
]};
-SEC['win-network'] = { label: t('reseau', 'network'), commands: [
+SEC['win-network'] = { label: t('réseau', 'network'), commands: [
{ d: t('(CMD) ipconfig', '(CMD) ipconfig'), c: 'ipconfig /all' },
{ d: t('(CMD) netstat', '(CMD) netstat'), c: 'netstat -an | findstr LISTEN' },
{ d: t('(PS) Test-NetConnection', '(PS) Test-NetConnection'), c: 'Test-NetConnection [ip] -Port [port]' },
@@ -151,109 +151,140 @@ SEC['solaris-zones'] = { label: t('Zones', 'Zones'), commands: [
{ d: t('Console', 'Console'), c: 'sudo zlogin -C [zone]' },
]};
+// ── COLLECT ALL COMMANDS (for global search) ──
+var ALL_COMMANDS = [];
+(function() {
+ var seen = {};
+ for (var k in SEC) {
+ if (SEC.hasOwnProperty(k)) {
+ SEC[k].commands.forEach(function(cmd) {
+ var key = cmd.c;
+ if (!seen[key]) { seen[key] = true; ALL_COMMANDS.push(cmd); }
+ });
+ }
+ }
+})();
+
+// ── HELPERS ──
+function findNode(tree, id) {
+ if (tree.id === id) return tree;
+ for (var i = 0; i < (tree.children || []).length; i++) {
+ var f = findNode(tree.children[i], id);
+ if (f) return f;
+ }
+ return null;
+}
+
+function collectLeafNodes(node, out) {
+ if (node.children) {
+ for (var i = 0; i < node.children.length; i++) collectLeafNodes(node.children[i], out);
+ } else {
+ out.push(node);
+ }
+ return out;
+}
+
+function countNodeCmds(node) {
+ if (node.sectionIds) {
+ var n = 0;
+ for (var i = 0; i < node.sectionIds.length; i++) {
+ if (SEC[node.sectionIds[i]]) n += SEC[node.sectionIds[i]].commands.length;
+ }
+ return n;
+ }
+ return 0;
+}
+
// ── RENDER TREE ──
function renderTree() {
- const el = document.getElementById('tree');
+ var el = document.getElementById('tree');
el.innerHTML = '';
renderNode(el, TREE, 0);
}
function renderNode(container, node, depth) {
- const isBranch = node.children && node.children.length > 0;
- const isVersion = !!node.sectionIds;
- const isEmpty = !isBranch && !isVersion;
-
- const div = document.createElement('div');
+ var isBranch = node.children && node.children.length > 0;
+ var isVersion = !!node.sectionIds;
+ var div = document.createElement('div');
if (depth === 0) {
- const label = document.createElement('div');
+ var label = document.createElement('div');
label.className = 'group-label';
label.textContent = node.label.fr;
div.appendChild(label);
} else {
- const row = document.createElement('div');
- let cls = 'sidebar-link';
+ var row = document.createElement('div');
+ var cls = 'sidebar-link';
if (depth === 2) cls += ' sidebar-link-3';
if (depth === 3) cls += ' sidebar-link-4';
if (node === currentNode) cls += ' active';
row.className = cls;
- // Toggle or spacer
if (isBranch) {
- const tgl = document.createElement('span');
+ var tgl = document.createElement('span');
tgl.className = 'tree-toggle open';
tgl.innerHTML = '
';
row.appendChild(tgl);
} else {
- const sp = document.createElement('span');
+ var sp = document.createElement('span');
sp.style.cssText = 'width:16px;flex-shrink:0;display:inline-block';
row.appendChild(sp);
}
- // Dot
- const dot = document.createElement('span');
- if (isVersion || (node._parent && node._parent.sectionIds)) dot.className = 'dot-green';
+ var dot = document.createElement('span');
+ if (isVersion || node._parent) dot.className = 'dot-green';
else if (isBranch) dot.className = 'dot-orange';
else dot.className = 'dot-gray';
row.appendChild(dot);
- // Label
- const lbl = document.createElement('span');
+ var lbl = document.createElement('span');
lbl.textContent = node.label.fr;
row.appendChild(lbl);
- // Count (only for non-section leaves that have data)
- let cnt = 0;
- if (node.sectionIds) {
- cnt = node.sectionIds.reduce(function(a, id) { return a + (SEC[id] ? SEC[id].commands.length : 0); }, 0);
- }
+ var cnt = countNodeCmds(node) || (node._parent && node._parent.sectionIds ? SEC[node._sectionId] ? SEC[node._sectionId].commands.length : 0 : 0);
if (cnt > 0) {
- const b = document.createElement('span');
+ var b = document.createElement('span');
b.className = 'ml-auto text-[0.625rem] text-[#94a3b8]';
b.textContent = '' + cnt;
row.appendChild(b);
}
- // Click
row.onclick = function(e) {
if (isBranch && (e.target.closest('.tree-toggle') || e.target.closest('[data-toggle]'))) {
- const tg = row.querySelector('.tree-toggle');
+ var tg = row.querySelector('.tree-toggle');
if (tg) { tg.classList.toggle('open'); row.nextElementSibling.classList.toggle('open'); e.stopPropagation(); }
return;
}
+ if (isBranch) return; // only leaf nodes select
selectNode(node);
};
div.appendChild(row);
}
- // Enfants
if (isBranch) {
- const kids = document.createElement('div');
+ var kids = document.createElement('div');
kids.className = 'tree-children open';
- for (const ch of node.children) {
- ch._parent = node;
- renderNode(kids, ch, depth + 1);
+ for (var i = 0; i < node.children.length; i++) {
+ node.children[i]._parent = node;
+ renderNode(kids, node.children[i], depth + 1);
}
div.appendChild(kids);
}
- // Si c'est une version avec sectionIds, on ajoute les sections comme enfants
if (isVersion && node.sectionIds) {
- const kids = document.createElement('div');
+ var kids = document.createElement('div');
kids.className = 'tree-children';
-
- // On déplie si c'est le noeud actif
if (node === currentNode || (currentNode && currentNode._parent === node)) {
kids.className = 'tree-children open';
}
-
- node.sectionIds.forEach(function(sid) {
- const sec = SEC[sid];
- if (!sec) return;
- const snode = { id: node.id + '-' + sid, label: sec.label, _sectionId: sid, _parent: node };
+ for (var j = 0; j < node.sectionIds.length; j++) {
+ var sid = node.sectionIds[j];
+ var sec = SEC[sid];
+ if (!sec) continue;
+ var snode = { id: node.id + '-' + sid, label: sec.label, _sectionId: sid, _parent: node };
renderNode(kids, snode, depth + 1);
- });
+ }
div.appendChild(kids);
}
@@ -263,85 +294,192 @@ function renderNode(container, node, depth) {
// ── SELECT NODE ──
function selectNode(node) {
currentNode = node;
+ currentSection = null;
renderTree();
- const titleEl = document.getElementById('os-title');
- const subEl = document.getElementById('os-sub');
- const cmdsEl = document.getElementById('cmds');
- const searchEl = document.getElementById('search');
- searchEl.value = '';
+ document.getElementById('search').value = '';
+ hideHome();
+ document.getElementById('home-btn').style.display = 'flex';
+
+ var titleEl = document.getElementById('os-title');
+ var subEl = document.getElementById('os-sub');
+ var cmdsEl = document.getElementById('cmds');
- // Cas 1: c'est une section (a _sectionId)
if (node._sectionId) {
- const sec = SEC[node._sectionId];
+ var sec = SEC[node._sectionId];
if (sec) {
- titleEl.textContent = sec.label.fr;
+ titleEl.textContent = node._parent.label.fr + ' > ' + sec.label.fr;
subEl.textContent = sec.commands.length + ' commandes';
showCmds(sec.commands);
}
return;
}
- // Cas 2: c'est une version ou OS avec sectionIds (on affiche la première section)
if (node.sectionIds && node.sectionIds.length > 0) {
- const sid = node.sectionIds[0];
- const sec = SEC[sid];
+ var sid = node.sectionIds[0];
+ var sec = SEC[sid];
if (sec) {
titleEl.textContent = node.label.fr;
- subEl.textContent = sec.commands.length + ' commandes';
+ subEl.textContent = node.sectionIds.length + ' sections · ' + countNodeCmds(node) + ' commandes';
showCmds(sec.commands);
}
return;
}
- // Cas 3: pas de données
titleEl.textContent = node.label.fr;
- subEl.textContent = 'Aucune donnee';
+ subEl.textContent = 'Aucune donnée';
cmdsEl.innerHTML = '
' + node.label.fr + '
Pas encore de commandes pour cet OS.
';
}
-function showCmds(commands) {
- const el = document.getElementById('cmds');
- const sv = document.getElementById('search').value.trim().toLowerCase();
+// ── SHOW/HIDE HOME ──
+function showHome() {
+ currentSection = null;
+ currentNode = null;
+ renderTree();
+ document.getElementById('search').value = '';
+ document.getElementById('filter-info').textContent = 'Aucun filtre';
+ document.getElementById('home-content').style.display = 'block';
+ document.getElementById('tabs').style.display = 'none';
+ document.getElementById('stats-bar').style.display = 'none';
+ document.getElementById('cmds-container').style.display = 'none';
+ document.getElementById('home-btn').style.display = 'none';
+ document.getElementById('os-title').textContent = 'SysCmd';
+ document.getElementById('os-sub').textContent = '';
+ document.getElementById('breadcrumb').innerHTML = '';
+ document.getElementById('footer-hint').textContent = 'Cliquez sur un OS pour explorer ses commandes';
+ renderHome();
+}
- let cmds = commands;
+function hideHome() {
+ document.getElementById('home-content').style.display = 'none';
+ document.getElementById('tabs').style.display = 'flex';
+ document.getElementById('stats-bar').style.display = 'flex';
+ document.getElementById('cmds-container').style.display = 'block';
+ document.getElementById('footer-hint').textContent = 'Cliquez sur une commande pour la copier';
+}
+
+// ── RENDER HOME ──
+function renderHome() {
+ renderStats();
+ renderCards();
+}
+
+function renderStats() {
+ var totalCmds = ALL_COMMANDS.length;
+ var totalSections = 0;
+ for (var k in SEC) if (SEC.hasOwnProperty(k)) totalSections++;
+ var totalOS = 0;
+ var leaves = collectLeafNodes(TREE, []);
+ for (var i = 0; i < leaves.length; i++) if (leaves[i].sectionIds) totalOS++;
+
+ var el = document.getElementById('stats-row');
+ el.innerHTML =
+ '
' + totalCmds + '
commandes
' +
+ '
' + totalSections + '
sections
' +
+ '
' + totalOS + '
OS renseignés
' +
+ '
' + (leaves.length - totalOS) + '
placeholders
';
+}
+
+var OS_CARDS = [
+ { id: 'debian', label: 'Debian', icon: 'D', color: '#0f172a', desc: t('Distribution stable de référence', 'Stable reference distribution') },
+ { id: 'ubuntu', label: 'Ubuntu', icon: 'U', color: '#dc2626', desc: t('Basé sur Debian avec versions LTS', 'Debian-based with LTS releases'), isGroup: true },
+ { id: 'oracle', label: 'Oracle Linux', icon: 'O', color: '#b9141e', desc: t('Linux Oracle avec UEK + SELinux', 'Oracle Linux with UEK + SELinux') },
+ { id: 'windows', label: 'Windows', icon: 'W', color: '#0078d4', desc: t('CMD + PowerShell client/server', 'CMD + PowerShell client/server'), isGroup: true },
+ { id: 'solaris', label: 'Solaris', icon: 'S', color: '#b46400', desc: t('Solaris / illumos avec ZFS + DTrace', 'Solaris / illumos with ZFS + DTrace') },
+ { id: 'rhel', label: 'RHEL / CentOS', icon: 'R', color: '#94a3b8', desc: t('Enterprise Linux (à venir)', 'Enterprise Linux (pending)'), placeholder: true },
+ { id: 'fedora', label: 'Fedora', icon: 'F', color: '#94a3b8', desc: t('Basé sur RHEL (à venir)', 'RHEL-based (pending)'), placeholder: true },
+ { id: 'freebsd', label: 'FreeBSD', icon: 'B', color: '#94a3b8', desc: t('BSD Unix (à venir)', 'BSD Unix (pending)'), placeholder: true },
+ { id: 'macos', label: 'macOS', icon: 'M', color: '#94a3b8', desc: t('macOS (à venir)', 'macOS (pending)'), placeholder: true },
+ { id: 'docker', label: 'Docker', icon: 'D', color: '#94a3b8', desc: t('Containers et orchestration (à venir)', 'Containers and orchestration (pending)'), placeholder: true },
+ { id: 'cisco', label: 'Cisco IOS', icon: 'C', color: '#94a3b8', desc: t('Réseau Cisco (à venir)', 'Cisco networking (pending)'), placeholder: true },
+ { id: 'mysql', label: 'MySQL / MariaDB', icon: 'S', color: '#94a3b8', desc: t('Bases de données SQL (à venir)', 'SQL databases (pending)'), placeholder: true },
+];
+
+function renderCards() {
+ var el = document.getElementById('card-grid');
+ el.innerHTML = '';
+ OS_CARDS.forEach(function(card) {
+ var div = document.createElement('div');
+ var isPlaceholder = card.placeholder;
+ var node = findNode(TREE, card.id);
+ var cnt = node ? countNodeCmds(node) : 0;
+ if (cnt > 0) isPlaceholder = false;
+
+ div.className = 'os-card' + (isPlaceholder ? ' placeholder-card' : '');
+
+ var iconBg = isPlaceholder ? 'bg-[#e2e8f0] text-[#94a3b8]' : 'text-white';
+ div.innerHTML =
+ '
' +
+ '
' +
+ '' + card.icon + '' +
+ '
' +
+ '
' +
+ '
' + (card.isGroup ? card.label + ' →' : card.label) + '
' +
+ '
' + card.desc.fr + '
' +
+ '
' +
+ '
' +
+ '
' +
+ (cnt > 0 ? '' + cnt + 'commandes' : '' + (isPlaceholder ? 'À venir' : 'via sidebar') + '') +
+ '
';
+
+ div.onclick = function() {
+ if (card.isGroup) {
+ // Expand group in sidebar
+ var n = findNode(TREE, card.id);
+ if (n && n.children && n.children.length > 0) {
+ selectNode(n.children[0]);
+ }
+ } else if (node) {
+ selectNode(node);
+ }
+ };
+
+ el.appendChild(div);
+ });
+}
+
+// ── SHOW COMMANDS ──
+function showCmds(commands) {
+ var el = document.getElementById('cmds');
+ var sv = document.getElementById('search').value.trim().toLowerCase();
+
+ var cmds = commands;
if (sv) {
cmds = cmds.filter(function(x) {
- return x.d.fr.toLowerCase().includes(sv) || x.d.en.toLowerCase().includes(sv) || x.c.toLowerCase().includes(sv);
+ return x.d.fr.toLowerCase().indexOf(sv) !== -1 || x.d.en.toLowerCase().indexOf(sv) !== -1 || x.c.toLowerCase().indexOf(sv) !== -1;
});
}
document.getElementById('shown').textContent = '' + cmds.length;
if (cmds.length === 0) {
- el.innerHTML = '
Aucune commande trouvee
';
+ el.innerHTML = '
Aucune commande trouvée
';
return;
}
el.innerHTML = '';
- cmds.forEach(function(x, i) {
- const row = document.createElement('div');
+ for (var i = 0; i < cmds.length; i++) {
+ var x = cmds[i];
+ var row = document.createElement('div');
row.className = 'cmd-row' + (i % 2 === 0 ? ' bg-[#fafbfc]' : '');
row.innerHTML = '
' + x.d.fr + '
';
- row.querySelector('.cmd-text').onclick = function() {
- navigator.clipboard.writeText(x.c).then(function() {
- var icon = row.querySelector('.copy-icon');
- icon.innerHTML = '
';
- setTimeout(function() { icon.innerHTML = '
'; }, 1200);
- });
- };
+ row.querySelector('.cmd-text').onclick = (function(cmd) {
+ return function() {
+ navigator.clipboard.writeText(cmd).then(function() {
+ var icon = row.querySelector('.copy-icon');
+ icon.innerHTML = '
';
+ setTimeout(function() { icon.innerHTML = '
'; }, 1200);
+ });
+ };
+ })(x.c);
el.appendChild(row);
- });
+ }
}
// ── SEARCH ──
function filterCommands(val) {
- const el = document.getElementById('filter-info');
- if (val.trim()) {
- el.textContent = 'Filtre: "' + val + '"';
- } else {
- el.textContent = 'Aucun filtre';
- }
+ var el = document.getElementById('filter-info');
+ el.textContent = val.trim() ? 'Filtre: "' + val + '"' : 'Aucun filtre';
if (currentNode && currentNode._sectionId) {
showCmds(SEC[currentNode._sectionId].commands);
} else if (currentNode && currentNode.sectionIds && currentNode.sectionIds.length > 0) {
@@ -349,15 +487,62 @@ function filterCommands(val) {
}
}
+// ── GLOBAL SEARCH ──
+function globalSearch(val) {
+ var el = document.getElementById('global-search-results');
+ var cmdsEl = document.getElementById('global-cmds');
+ var sv = val.trim().toLowerCase();
+
+ if (!sv) {
+ el.style.display = 'none';
+ document.getElementById('card-grid').style.display = 'grid';
+ document.getElementById('stats-row').style.display = 'grid';
+ return;
+ }
+
+ el.style.display = 'block';
+ document.getElementById('card-grid').style.display = 'none';
+ document.getElementById('stats-row').style.display = 'none';
+
+ // Search across all commands
+ var results = [];
+ for (var i = 0; i < ALL_COMMANDS.length; i++) {
+ var x = ALL_COMMANDS[i];
+ if (x.d.fr.toLowerCase().indexOf(sv) !== -1 || x.d.en.toLowerCase().indexOf(sv) !== -1 || x.c.toLowerCase().indexOf(sv) !== -1) {
+ results.push(x);
+ }
+ }
+
+ cmdsEl.innerHTML = '';
+ if (results.length === 0) {
+ cmdsEl.innerHTML = '
Aucune commande trouvée
';
+ return;
+ }
+
+ // Header stat
+ var header = document.createElement('div');
+ header.className = 'px-4 py-2 text-xs text-[#94a3b8] border-b border-[#f1f5f9]';
+ header.textContent = results.length + ' résultat(s) dans toutes les sections';
+ cmdsEl.appendChild(header);
+
+ for (var j = 0; j < results.length; j++) {
+ var x = results[j];
+ var row = document.createElement('div');
+ row.className = 'cmd-row' + (j % 2 === 0 ? ' bg-[#fafbfc]' : '');
+ row.innerHTML = '
' + x.d.fr + '
';
+ row.querySelector('.cmd-text').onclick = (function(cmd) {
+ return function() {
+ navigator.clipboard.writeText(cmd).then(function() {
+ var icon = row.querySelector('.copy-icon');
+ icon.innerHTML = '
';
+ setTimeout(function() { icon.innerHTML = '
'; }, 1200);
+ });
+ };
+ })(x.c);
+ cmdsEl.appendChild(row);
+ }
+}
+
// ── INIT ──
renderTree();
-selectNode(findNode(TREE, 'ubuntu-2004'));
-
-function findNode(tree, id) {
- if (tree.id === id) return tree;
- for (const c of (tree.children || [])) {
- const f = findNode(c, id);
- if (f) return f;
- }
- return null;
-}
+showHome();