5575 lines
313 KiB
HTML
5575 lines
313 KiB
HTML
|
||
<!doctype html>
|
||
<html lang="en" class="no-js">
|
||
<head>
|
||
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
||
<meta name="description" content="OpenWrt LuCI Security & Management Suite">
|
||
|
||
|
||
<meta name="author" content="CyberMind.fr">
|
||
|
||
|
||
<link rel="canonical" href="https://gkerma.github.io/secubox-openwrt/development-guidelines/">
|
||
|
||
|
||
<link rel="prev" href="../repository-guidelines/">
|
||
|
||
|
||
<link rel="next" href="../code-templates/">
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="icon" href="../assets/images/favicon.png">
|
||
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
|
||
|
||
|
||
|
||
<title>Development Guidelines - SecuBox Documentation</title>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
|
||
|
||
|
||
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../stylesheets/extra.css">
|
||
|
||
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
||
|
||
|
||
|
||
|
||
|
||
</head>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="purple">
|
||
|
||
|
||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
||
<label class="md-overlay" for="__drawer"></label>
|
||
<div data-md-component="skip">
|
||
|
||
|
||
<a href="#secubox-system-hub-development-guidelines" class="md-skip">
|
||
Skip to content
|
||
</a>
|
||
|
||
</div>
|
||
<div data-md-component="announce">
|
||
|
||
</div>
|
||
|
||
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
|
||
<nav class="md-header__inner md-grid" aria-label="Header">
|
||
<a href=".." title="SecuBox Documentation" class="md-header__button md-logo" aria-label="SecuBox Documentation" data-md-component="logo">
|
||
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
||
|
||
</a>
|
||
<label class="md-header__button md-icon" for="__drawer">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
||
</label>
|
||
<div class="md-header__title" data-md-component="header-title">
|
||
<div class="md-header__ellipsis">
|
||
<div class="md-header__topic">
|
||
<span class="md-ellipsis">
|
||
SecuBox Documentation
|
||
</span>
|
||
</div>
|
||
<div class="md-header__topic" data-md-component="header-topic">
|
||
<span class="md-ellipsis">
|
||
|
||
Development Guidelines
|
||
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<form class="md-header__option" data-md-component="palette">
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="purple" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
|
||
</label>
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="purple" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
|
||
</label>
|
||
|
||
|
||
</form>
|
||
|
||
|
||
|
||
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-header__button md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
</label>
|
||
<div class="md-search" data-md-component="search" role="dialog">
|
||
<label class="md-search__overlay" for="__search"></label>
|
||
<div class="md-search__inner" role="search">
|
||
<form class="md-search__form" name="search">
|
||
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
||
<label class="md-search__icon md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
||
</label>
|
||
<nav class="md-search__options" aria-label="Search">
|
||
|
||
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
||
|
||
</form>
|
||
<div class="md-search__output">
|
||
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
||
<div class="md-search-result" data-md-component="search-result">
|
||
<div class="md-search-result__meta">
|
||
Initializing search
|
||
</div>
|
||
<ol class="md-search-result__list" role="presentation"></ol>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-header__source">
|
||
<a href="https://github.com/gkerma/secubox-openwrt" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
gkerma/secubox-openwrt
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
|
||
<div class="md-grid">
|
||
<ul class="md-tabs__list">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href=".." class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
Home
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../quick-start/" class="md-tabs__link">
|
||
|
||
|
||
|
||
Getting Started
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item md-tabs__item--active">
|
||
<a href="./" class="md-tabs__link">
|
||
|
||
|
||
|
||
Development
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../claude/" class="md-tabs__link">
|
||
|
||
|
||
|
||
Reference
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../module-status/" class="md-tabs__link">
|
||
|
||
|
||
|
||
Modules
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../todo-analyse/" class="md-tabs__link">
|
||
|
||
|
||
|
||
Tools & Roadmap
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../archive/" class="md-tabs__link">
|
||
|
||
|
||
|
||
Archive
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
</header>
|
||
|
||
<div class="md-container" data-md-component="container">
|
||
|
||
|
||
|
||
|
||
<main class="md-main" data-md-component="main">
|
||
<div class="md-main__inner md-grid">
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
|
||
<label class="md-nav__title" for="__drawer">
|
||
<a href=".." title="SecuBox Documentation" class="md-nav__button md-logo" aria-label="SecuBox Documentation" data-md-component="logo">
|
||
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
||
|
||
</a>
|
||
SecuBox Documentation
|
||
</label>
|
||
|
||
<div class="md-nav__source">
|
||
<a href="https://github.com/gkerma/secubox-openwrt" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
gkerma/secubox-openwrt
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href=".." class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Home
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Getting Started
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Getting Started
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../quick-start/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Quick Start
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../documentation-index/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Documentation Index
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../repository-guidelines/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Repository Guidelines
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Development
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_3">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Development
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active">
|
||
|
||
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__link md-nav__link--active" for="__toc">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Development Guidelines
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<a href="./" class="md-nav__link md-nav__link--active">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Development Guidelines
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Table of contents
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#table-des-matieres" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Table des matières
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#design-system-ui-guidelines" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Design System & UI Guidelines
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Design System & UI Guidelines">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#color-palette-demo-inspired" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Color Palette (Demo-inspired)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Color Palette (Demo-inspired)">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#dark-mode-primary-recommended" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Dark Mode (Primary - Recommended)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#light-mode-secondary" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Light Mode (Secondary)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#typography" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Typography
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Typography">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#fonts-stack" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Fonts Stack
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#font-sizes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Font Sizes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#component-patterns" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Component Patterns
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Component Patterns">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#component-hierarchy" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Component Hierarchy
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-page-header-standard" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. Page Header (Standard)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-stats-badges" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Stats Badges
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-cards-avec-bordure-coloree" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Cards avec bordure colorée
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-buttons" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Buttons
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-filter-tabs" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Filter Tabs
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#grid-systems" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Grid Systems
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Grid Systems">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#stats-overview-compact" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Stats Overview (Compact)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#metric-cards-medium" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Metric Cards (Medium)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#info-cards-large" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Info Cards (Large)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-effects" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Effects
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Gradient Effects">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-text-titles" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Text (Titles)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-backgrounds-buttons-badges" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Backgrounds (Buttons, Badges)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-borders-top" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Borders (Top)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#animation-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Animation Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Animation Standards">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#hover-effects" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Hover Effects
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#shadow-progression" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Shadow Progression
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#architecture-naming-conventions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Architecture & Naming Conventions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Architecture & Naming Conventions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#system-architecture-overview" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
System Architecture Overview
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#critical-rpcd-script-naming" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CRITICAL: RPCD Script Naming
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CRITICAL: RPCD Script Naming">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#correct" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
✅ CORRECT:
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#incorrect-causes-derreur-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
❌ INCORRECT (Causes d'erreur -32000):
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#menu-path-conventions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Menu Path Conventions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Menu Path Conventions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#correct_1" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
✅ CORRECT:
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#incorrect-causes-404" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
❌ INCORRECT (Causes 404):
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#prefixes-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Prefixes Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#file-structure-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
File Structure Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-ubus-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD & ubus Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="RPCD & ubus Best Practices">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-script-template-shell" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD Script Template (Shell)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-script-validation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD Script Validation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#testing-rpcd-scripts" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Testing RPCD Scripts
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-rpcd-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common RPCD Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common RPCD Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-object-not-found-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Object not found" (-32000)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-method-not-found-32601" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Method not found" (-32601)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-invalid-json-returned" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: Invalid JSON returned
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-permissions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL & Permissions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="ACL & Permissions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-file-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL File Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-acl-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common ACL Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common ACL Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-access-denied" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Access denied"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-uci-config-not-accessible" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "UCI config not accessible"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#javascript-patterns" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
JavaScript Patterns
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="JavaScript Patterns">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-module-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Module Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#view-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
View Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#event-handling-pattern" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Event Handling Pattern
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-javascript-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common JavaScript Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common JavaScript Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-object-htmlbuttonelement-affiche" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "[object HTMLButtonElement]" affiché
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-cannot-read-property-of-undefined" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Cannot read property of undefined"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-poll-callback-failed" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "poll callback failed"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#cssstyling-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS/Styling Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CSS/Styling Standards">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#file-organization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
File Organization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-file-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS File Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CSS Best Practices">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-toujours-utiliser-les-variables-css" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. TOUJOURS utiliser les variables CSS
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-prefix-classes-par-module" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Prefix classes par module
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-transitions-coherentes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Transitions cohérentes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-responsive-breakpoints" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Responsive breakpoints
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-dark-mode-obligatoire" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Dark mode OBLIGATOIRE
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#z-index-scale" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Z-index Scale
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-errors-solutions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common Errors & Solutions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common Errors & Solutions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-rpcd-object-not-found-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. RPCD Object Not Found (-32000)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-view-not-found-404" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. View Not Found (404)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-css-not-loading-403-forbidden" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. CSS Not Loading (403 Forbidden)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-invalid-json-from-rpcd" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Invalid JSON from RPCD
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-browser-cache-issues" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Browser Cache Issues
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#6-acl-access-denied" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
6. ACL Access Denied
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#validation-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Validation Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Validation Checklist">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-commit-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Pre-Commit Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-deploy-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Pre-Deploy Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-deploy-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Post-Deploy Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#deployment-procedures" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Deployment Procedures
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Deployment Procedures">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#deployment-workflow" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Deployment Workflow
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-deployment-checks-critical" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
⚠️ Pre-Deployment Checks (CRITICAL)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="⚠️ Pre-Deployment Checks (CRITICAL)">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-verification-de-lespace-disque" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. Vérification de l'Espace Disque
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-verification-des-permissions-critique-pour-eviter-erreurs-403" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Vérification des Permissions (Critique pour Éviter Erreurs 403)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-post-deployment-verification" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Post-Deployment Verification
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-common-deployment-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Common Deployment Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-emergency-disk-space-recovery" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Emergency Disk Space Recovery
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#standard-deployment-script-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Standard Deployment Script Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rollback-procedure" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Rollback Procedure
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#version-control" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Version Control
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quick Reference">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#essential-commands" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Essential Commands
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-classes-quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS Classes Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#color-variables-quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Color Variables Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#ai-assistant-context-files" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
AI Assistant Context Files
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#conclusion" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Conclusion
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../code-templates/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Code Templates
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../module-implementation-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Module Implementation
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Reference
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_4">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Reference
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../claude/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
RPCD & Architecture
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../validation-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Validation Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../permissions-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Permissions Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../luci-development-reference/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
LuCI Development
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../codex/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Codex Manual
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Modules
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_5">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Modules
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../module-status/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Module Status
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../feature-regeneration-prompts/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Feature Prompts
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Tools & Roadmap
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_6">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Tools & Roadmap
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../todo-analyse/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
TODO Roadmap
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_7" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Archive
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_7">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Archive
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../archive/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Archive Index
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../archive/build-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Build Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../archive/completion-report/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Completion Report
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../archive/module-enable-disable-design/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Module Enable/Disable
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Table of contents
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#table-des-matieres" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Table des matières
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#design-system-ui-guidelines" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Design System & UI Guidelines
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Design System & UI Guidelines">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#color-palette-demo-inspired" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Color Palette (Demo-inspired)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Color Palette (Demo-inspired)">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#dark-mode-primary-recommended" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Dark Mode (Primary - Recommended)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#light-mode-secondary" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Light Mode (Secondary)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#typography" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Typography
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Typography">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#fonts-stack" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Fonts Stack
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#font-sizes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Font Sizes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#component-patterns" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Component Patterns
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Component Patterns">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#component-hierarchy" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Component Hierarchy
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-page-header-standard" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. Page Header (Standard)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-stats-badges" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Stats Badges
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-cards-avec-bordure-coloree" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Cards avec bordure colorée
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-buttons" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Buttons
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-filter-tabs" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Filter Tabs
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#grid-systems" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Grid Systems
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Grid Systems">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#stats-overview-compact" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Stats Overview (Compact)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#metric-cards-medium" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Metric Cards (Medium)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#info-cards-large" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Info Cards (Large)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-effects" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Effects
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Gradient Effects">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-text-titles" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Text (Titles)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-backgrounds-buttons-badges" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Backgrounds (Buttons, Badges)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gradient-borders-top" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Gradient Borders (Top)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#animation-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Animation Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Animation Standards">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#hover-effects" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Hover Effects
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#shadow-progression" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Shadow Progression
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#architecture-naming-conventions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Architecture & Naming Conventions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Architecture & Naming Conventions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#system-architecture-overview" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
System Architecture Overview
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#critical-rpcd-script-naming" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CRITICAL: RPCD Script Naming
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CRITICAL: RPCD Script Naming">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#correct" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
✅ CORRECT:
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#incorrect-causes-derreur-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
❌ INCORRECT (Causes d'erreur -32000):
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#menu-path-conventions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Menu Path Conventions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Menu Path Conventions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#correct_1" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
✅ CORRECT:
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#incorrect-causes-404" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
❌ INCORRECT (Causes 404):
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#prefixes-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Prefixes Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#file-structure-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
File Structure Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-ubus-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD & ubus Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="RPCD & ubus Best Practices">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-script-template-shell" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD Script Template (Shell)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rpcd-script-validation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
RPCD Script Validation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#testing-rpcd-scripts" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Testing RPCD Scripts
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-rpcd-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common RPCD Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common RPCD Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-object-not-found-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Object not found" (-32000)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-method-not-found-32601" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Method not found" (-32601)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-invalid-json-returned" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: Invalid JSON returned
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-permissions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL & Permissions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="ACL & Permissions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-file-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL File Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#acl-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
ACL Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-acl-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common ACL Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common ACL Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-access-denied" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Access denied"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-uci-config-not-accessible" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "UCI config not accessible"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#javascript-patterns" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
JavaScript Patterns
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="JavaScript Patterns">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-module-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Module Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#view-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
View Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#event-handling-pattern" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Event Handling Pattern
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-javascript-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common JavaScript Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common JavaScript Errors">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-object-htmlbuttonelement-affiche" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "[object HTMLButtonElement]" affiché
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-cannot-read-property-of-undefined" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "Cannot read property of undefined"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#error-poll-callback-failed" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Error: "poll callback failed"
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#cssstyling-standards" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS/Styling Standards
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CSS/Styling Standards">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#file-organization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
File Organization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-file-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS File Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-best-practices" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS Best Practices
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="CSS Best Practices">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-toujours-utiliser-les-variables-css" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. TOUJOURS utiliser les variables CSS
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-prefix-classes-par-module" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Prefix classes par module
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-transitions-coherentes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Transitions cohérentes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-responsive-breakpoints" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Responsive breakpoints
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-dark-mode-obligatoire" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Dark mode OBLIGATOIRE
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#z-index-scale" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Z-index Scale
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#common-errors-solutions" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Common Errors & Solutions
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Common Errors & Solutions">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-rpcd-object-not-found-32000" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. RPCD Object Not Found (-32000)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-view-not-found-404" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. View Not Found (404)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-css-not-loading-403-forbidden" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. CSS Not Loading (403 Forbidden)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-invalid-json-from-rpcd" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Invalid JSON from RPCD
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-browser-cache-issues" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Browser Cache Issues
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#6-acl-access-denied" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
6. ACL Access Denied
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#validation-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Validation Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Validation Checklist">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-commit-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Pre-Commit Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-deploy-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Pre-Deploy Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-deploy-checklist" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Post-Deploy Checklist
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#deployment-procedures" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Deployment Procedures
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Deployment Procedures">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#deployment-workflow" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Deployment Workflow
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#pre-deployment-checks-critical" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
⚠️ Pre-Deployment Checks (CRITICAL)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="⚠️ Pre-Deployment Checks (CRITICAL)">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-verification-de-lespace-disque" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
1. Vérification de l'Espace Disque
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-verification-des-permissions-critique-pour-eviter-erreurs-403" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
2. Vérification des Permissions (Critique pour Éviter Erreurs 403)
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-post-deployment-verification" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
3. Post-Deployment Verification
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-common-deployment-errors" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
4. Common Deployment Errors
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#5-emergency-disk-space-recovery" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
5. Emergency Disk Space Recovery
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#standard-deployment-script-template" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Standard Deployment Script Template
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#rollback-procedure" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Rollback Procedure
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#version-control" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Version Control
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quick Reference">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#essential-commands" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Essential Commands
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#css-classes-quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
CSS Classes Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#color-variables-quick-reference" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Color Variables Quick Reference
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#ai-assistant-context-files" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
AI Assistant Context Files
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#conclusion" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Conclusion
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-content" data-md-component="content">
|
||
|
||
<article class="md-content__inner md-typeset">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<h1 id="secubox-system-hub-development-guidelines">SecuBox & System Hub - Development Guidelines<a class="headerlink" href="#secubox-system-hub-development-guidelines" title="Permanent link">¶</a></h1>
|
||
<p><strong>Version:</strong> 1.0.0<br />
|
||
<strong>Last Updated:</strong> 2025-12-28<br />
|
||
<strong>Status:</strong> Active<br />
|
||
<strong>Audience:</strong> Développeurs, IA assistants, mainteneurs</p>
|
||
<p>Ce document définit les standards, bonnes pratiques et validations obligatoires pour le développement de modules SecuBox et System Hub dans l'écosystème OpenWrt LuCI.</p>
|
||
<hr />
|
||
<h2 id="table-des-matieres">Table des matières<a class="headerlink" href="#table-des-matieres" title="Permanent link">¶</a></h2>
|
||
<ol>
|
||
<li><a href="#design-system-ui-guidelines">Design System & UI Guidelines</a></li>
|
||
<li><a href="#architecture-naming-conventions">Architecture & Naming Conventions</a></li>
|
||
<li><a href="#rpcd-ubus-best-practices">RPCD & ubus Best Practices</a></li>
|
||
<li><a href="#acl-permissions">ACL & Permissions</a></li>
|
||
<li><a href="#javascript-patterns">JavaScript Patterns</a></li>
|
||
<li><a href="#cssstyling-standards">CSS/Styling Standards</a></li>
|
||
<li><a href="#common-errors-solutions">Common Errors & Solutions</a></li>
|
||
<li><a href="#validation-checklist">Validation Checklist</a></li>
|
||
<li><a href="#deployment-procedures">Deployment Procedures</a></li>
|
||
<li><a href="#ai-assistant-context-files">AI Assistant Context Files</a></li>
|
||
</ol>
|
||
<hr />
|
||
<h2 id="design-system-ui-guidelines">Design System & UI Guidelines<a class="headerlink" href="#design-system-ui-guidelines" title="Permanent link">¶</a></h2>
|
||
<h3 id="color-palette-demo-inspired">Color Palette (Demo-inspired)<a class="headerlink" href="#color-palette-demo-inspired" title="Permanent link">¶</a></h3>
|
||
<p><strong>IMPORTANT:</strong> Toujours utiliser la palette définie dans <code>system-hub/common.css</code></p>
|
||
<h4 id="dark-mode-primary-recommended">Dark Mode (Primary - Recommended)<a class="headerlink" href="#dark-mode-primary-recommended" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nt">--sh-text-primary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">fafafa</span><span class="o">;</span>
|
||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="nt">--sh-text-secondary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">a0a0b0</span><span class="o">;</span>
|
||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="nt">--sh-bg-primary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">0a0a0f</span><span class="o">;</span><span class="w"> </span><span class="c">/* Fond principal (noir profond) */</span>
|
||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="nt">--sh-bg-secondary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">12121a</span><span class="o">;</span><span class="w"> </span><span class="c">/* Fond cartes/sections */</span>
|
||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a><span class="nt">--sh-bg-tertiary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">1a1a24</span><span class="o">;</span><span class="w"> </span><span class="c">/* Fond hover/actif */</span>
|
||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a><span class="nt">--sh-bg-card</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">12121a</span><span class="o">;</span>
|
||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a><span class="nt">--sh-border</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">2a2a35</span><span class="o">;</span>
|
||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a><span class="nt">--sh-primary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">6366f1</span><span class="o">;</span><span class="w"> </span><span class="c">/* Indigo */</span>
|
||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="nt">--sh-primary-end</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">8b5cf6</span><span class="o">;</span><span class="w"> </span><span class="c">/* Violet (pour dégradés) */</span>
|
||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a><span class="nt">--sh-success</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">22c55e</span><span class="o">;</span><span class="w"> </span><span class="c">/* Vert */</span>
|
||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a><span class="nt">--sh-danger</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">ef4444</span><span class="o">;</span><span class="w"> </span><span class="c">/* Rouge */</span>
|
||
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="nt">--sh-warning</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">f59e0b</span><span class="o">;</span><span class="w"> </span><span class="c">/* Orange */</span>
|
||
</code></pre></div>
|
||
<h4 id="light-mode-secondary">Light Mode (Secondary)<a class="headerlink" href="#light-mode-secondary" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="nt">--sh-text-primary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">0f172a</span><span class="o">;</span>
|
||
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="nt">--sh-text-secondary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">475569</span><span class="o">;</span>
|
||
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="nt">--sh-bg-primary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">ffffff</span><span class="o">;</span>
|
||
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="nt">--sh-bg-secondary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">f8fafc</span><span class="o">;</span>
|
||
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="nt">--sh-bg-tertiary</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">f1f5f9</span><span class="o">;</span>
|
||
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="nt">--sh-bg-card</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">ffffff</span><span class="o">;</span>
|
||
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="nt">--sh-border</span><span class="o">:</span><span class="w"> </span><span class="p">#</span><span class="nn">e2e8f0</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<p><strong>✅ TOUJOURS utiliser les CSS variables</strong> - Ne JAMAIS hardcoder les couleurs.</p>
|
||
<h3 id="typography">Typography<a class="headerlink" href="#typography" title="Permanent link">¶</a></h3>
|
||
<h4 id="fonts-stack">Fonts Stack<a class="headerlink" href="#fonts-stack" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="c">/* Texte général */</span>
|
||
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="nt">font-family</span><span class="o">:</span><span class="w"> </span><span class="s1">'Inter'</span><span class="o">,</span><span class="w"> </span><span class="nt">-apple-system</span><span class="o">,</span><span class="w"> </span><span class="nt">BlinkMacSystemFont</span><span class="o">,</span><span class="w"> </span><span class="nt">sans-serif</span><span class="o">;</span>
|
||
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a>
|
||
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="c">/* Valeurs numériques, IDs, code */</span>
|
||
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="nt">font-family</span><span class="o">:</span><span class="w"> </span><span class="s1">'JetBrains Mono'</span><span class="o">,</span><span class="w"> </span><span class="s1">'Courier New'</span><span class="o">,</span><span class="w"> </span><span class="nt">monospace</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<p><strong>Import requis</strong> (ajouté dans common.css):
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">@</span><span class="k">import</span><span class="w"> </span><span class="nt">url</span><span class="o">(</span><span class="s1">'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap'</span><span class="o">)</span><span class="p">;</span>
|
||
</code></pre></div></p>
|
||
<h4 id="font-sizes">Font Sizes<a class="headerlink" href="#font-sizes" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="c">/* Titres */</span>
|
||
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="nt">--sh-title-xl</span><span class="o">:</span><span class="w"> </span><span class="nt">28px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Page titles */</span>
|
||
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="nt">--sh-title-lg</span><span class="o">:</span><span class="w"> </span><span class="nt">20px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Card titles */</span>
|
||
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="nt">--sh-title-md</span><span class="o">:</span><span class="w"> </span><span class="nt">16px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Section headers */</span>
|
||
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a>
|
||
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="c">/* Texte */</span>
|
||
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="nt">--sh-text-base</span><span class="o">:</span><span class="w"> </span><span class="nt">14px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Body text */</span>
|
||
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="nt">--sh-text-sm</span><span class="o">:</span><span class="w"> </span><span class="nt">13px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Labels, meta */</span>
|
||
<a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="nt">--sh-text-xs</span><span class="o">:</span><span class="w"> </span><span class="nt">11px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Uppercase labels */</span>
|
||
<a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a>
|
||
<a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="c">/* Valeurs */</span>
|
||
<a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="nt">--sh-value-xl</span><span class="o">:</span><span class="w"> </span><span class="nt">40px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Large metrics */</span>
|
||
<a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="nt">--sh-value-lg</span><span class="o">:</span><span class="w"> </span><span class="nt">32px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Stats overview */</span>
|
||
<a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a><span class="nt">--sh-value-md</span><span class="o">:</span><span class="w"> </span><span class="nt">28px</span><span class="o">;</span><span class="w"> </span><span class="c">/* Badges */</span>
|
||
</code></pre></div>
|
||
<h3 id="component-patterns">Component Patterns<a class="headerlink" href="#component-patterns" title="Permanent link">¶</a></h3>
|
||
<h4 id="component-hierarchy">Component Hierarchy<a class="headerlink" href="#component-hierarchy" title="Permanent link">¶</a></h4>
|
||
<p>The following diagram shows the standard page structure and component relationships:</p>
|
||
<pre class="mermaid"><code>graph TB
|
||
PAGE[Page Container<br/>.module-dashboard] --> HEADER[sh-page-header]
|
||
PAGE --> CONTENT[sh-content]
|
||
|
||
HEADER --> TITLE_SECTION[Title Section<br/>div]
|
||
HEADER --> STATS[sh-stats-grid]
|
||
|
||
TITLE_SECTION --> TITLE[sh-page-title<br/>gradient text]
|
||
TITLE_SECTION --> SUBTITLE[sh-page-subtitle]
|
||
|
||
STATS --> BADGE1[sh-stat-badge]
|
||
STATS --> BADGE2[sh-stat-badge]
|
||
STATS --> BADGE3[...]
|
||
|
||
BADGE1 --> VALUE1[sh-stat-value<br/>monospace font]
|
||
BADGE1 --> LABEL1[sh-stat-label<br/>uppercase]
|
||
|
||
CONTENT --> TABS[sh-filter-tabs]
|
||
CONTENT --> CARD_GRID[Card Grid<br/>grid layout]
|
||
|
||
TABS --> TAB1[sh-filter-tab<br/>active]
|
||
TABS --> TAB2[sh-filter-tab]
|
||
|
||
CARD_GRID --> CARD1[sh-card]
|
||
CARD_GRID --> CARD2[sh-card-success]
|
||
CARD_GRID --> CARD3[sh-card-danger]
|
||
|
||
CARD1 --> CH1[sh-card-header]
|
||
CARD1 --> CB1[sh-card-body]
|
||
|
||
CH1 --> CT1[sh-card-title]
|
||
CT1 --> ICON1[sh-card-title-icon]
|
||
|
||
CB1 --> BUTTONS[Button Group]
|
||
CB1 --> INFO[Info Rows]
|
||
|
||
BUTTONS --> BTN1[sh-btn<br/>sh-btn-primary]
|
||
BUTTONS --> BTN2[sh-btn<br/>sh-btn-secondary]
|
||
|
||
style PAGE fill:#0a0a0f,color:#fafafa,stroke:#6366f1,stroke-width:3px
|
||
style HEADER fill:#12121a,color:#fafafa,stroke:#6366f1,stroke-width:2px
|
||
style CONTENT fill:#12121a,color:#fafafa,stroke:#6366f1,stroke-width:2px
|
||
style CARD1 fill:#12121a,color:#fafafa,stroke:#6366f1,stroke-width:2px
|
||
style CARD2 fill:#12121a,color:#fafafa,stroke:#22c55e,stroke-width:2px
|
||
style CARD3 fill:#12121a,color:#fafafa,stroke:#ef4444,stroke-width:2px
|
||
style TITLE fill:#6366f1,color:#fff
|
||
style BTN1 fill:#6366f1,color:#fff
|
||
style VALUE1 fill:#8b5cf6,color:#fff</code></pre>
|
||
<p><strong>Component Categories:</strong>
|
||
1. <strong>Layout Containers:</strong> Page wrapper, header, content sections
|
||
2. <strong>Typography:</strong> Titles with gradient effects, subtitles, labels
|
||
3. <strong>Data Display:</strong> Stat badges with monospace values, cards with borders
|
||
4. <strong>Navigation:</strong> Filter tabs, nav tabs (sticky)
|
||
5. <strong>Interactive:</strong> Buttons with gradients and hover effects</p>
|
||
<p><strong>Styling Rules:</strong>
|
||
- <strong>Cards:</strong> 3px top border (gradient on hover, or colored for status)
|
||
- <strong>Stat Badges:</strong> Minimum 130px width, monospace font for values
|
||
- <strong>Buttons:</strong> Gradient backgrounds, shadow on hover, smooth transitions
|
||
- <strong>Tabs:</strong> Active state with gradient background and glow
|
||
- <strong>Grid Layouts:</strong> Auto-fit with minimums (130px, 240px, or 300px)</p>
|
||
<hr />
|
||
<h4 id="1-page-header-standard">1. Page Header (Standard)<a class="headerlink" href="#1-page-header-standard" title="Permanent link">¶</a></h4>
|
||
<p><strong>REQUIREMENT:</strong> Every module view MUST begin with this compact <code>.sh-page-header</code>. Do not introduce bespoke hero sections or oversized banners; the header keeps height predictable (title + subtitle on the left, stats on the right) and guarantees consistency across SecuBox dashboards. If no stats are needed, keep the container but supply an empty <code>.sh-stats-grid</code> for future metrics.</p>
|
||
<p><strong>Slim variant:</strong> When the page only needs 2‑3 metrics, use <code>.sh-page-header-lite</code> + <code>.sh-header-chip</code> (see <code>luci-app-vhost-manager</code> and <code>luci-app-secubox</code> settings). Chips carry an emoji/icon, a tiny label, and the value; colors (<code>.success</code>, <code>.danger</code>, <code>.warn</code>) communicate state. This variant replaces the bulky hero blocks from older demos.</p>
|
||
<p><strong>Version chip:</strong> Always expose the package version from the RPC backend (read from <code>/usr/lib/opkg/info/<pkg>.control</code>) and display it as the first chip (<code>icon: 🏷️</code>). That keeps the UI and <code>PKG_VERSION</code> in sync without hunting for hard-coded strings.</p>
|
||
<p><strong>HTML Structure:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-page-header'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'h2'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-page-title'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'span'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-page-title-icon'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'🎯'</span><span class="p">),</span>
|
||
<a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a><span class="w"> </span><span class="s1">'Page Title'</span>
|
||
<a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a><span class="w"> </span><span class="p">]),</span>
|
||
<a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'p'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-page-subtitle'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Description of the page'</span><span class="p">)</span>
|
||
<a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="w"> </span><span class="p">]),</span>
|
||
<a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-stats-grid'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a><span class="w"> </span><span class="c1">// Stats badges here</span>
|
||
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a><span class="w"> </span><span class="p">])</span>
|
||
<a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a><span class="p">])</span>
|
||
</code></pre></div></p>
|
||
<p><strong>CSS Classes:</strong>
|
||
- <code>.sh-page-header</code> - Container with flex layout
|
||
- <code>.sh-page-title</code> - Gradient text effect
|
||
- <code>.sh-page-title-icon</code> - Icon (no gradient)
|
||
- <code>.sh-page-subtitle</code> - Secondary text
|
||
- <code>.sh-stats-grid</code> - Grid pour badges (130px min)</p>
|
||
<h4 id="2-stats-badges">2. Stats Badges<a class="headerlink" href="#2-stats-badges" title="Permanent link">¶</a></h4>
|
||
<p><strong>RÈGLE:</strong> Minimum 130px, police monospace pour valeurs</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-stat-badge'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-stat-value'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'92'</span><span class="p">),</span>
|
||
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-stat-label'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'CPU %'</span><span class="p">)</span>
|
||
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="p">])</span>
|
||
</code></pre></div>
|
||
<p><strong>Grid Layout:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">.</span><span class="nc">sh-stats-grid</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="k">grid</span><span class="p">;</span>
|
||
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="k">grid-template-columns</span><span class="p">:</span><span class="w"> </span><span class="nf">repeat</span><span class="p">(</span><span class="kc">auto</span><span class="nv">-fit</span><span class="p">,</span><span class="w"> </span><span class="nf">minmax</span><span class="p">(</span><span class="mi">130</span><span class="kt">px</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="n">fr</span><span class="p">));</span>
|
||
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="k">gap</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span><span class="kt">px</span><span class="p">;</span>
|
||
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="p">}</span>
|
||
</code></pre></div></p>
|
||
<h4 id="3-cards-avec-bordure-coloree">3. Cards avec bordure colorée<a class="headerlink" href="#3-cards-avec-bordure-coloree" title="Permanent link">¶</a></h4>
|
||
<p><strong>OBLIGATOIRE:</strong> Toutes les cards doivent avoir une bordure top de 3px</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-card sh-card-success'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-card-header'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'h3'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-card-title'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'span'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-card-title-icon'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'⚙️'</span><span class="p">),</span>
|
||
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="s1">'Card Title'</span>
|
||
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="p">])</span>
|
||
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a><span class="w"> </span><span class="p">]),</span>
|
||
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-card-body'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="w"> </span><span class="c1">// Content</span>
|
||
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="w"> </span><span class="p">])</span>
|
||
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="p">])</span>
|
||
</code></pre></div>
|
||
<p><strong>Variants de bordure:</strong>
|
||
- <code>.sh-card</code> - Bordure gradient (visible au hover)
|
||
- <code>.sh-card-success</code> - Bordure verte permanente
|
||
- <code>.sh-card-danger</code> - Bordure rouge permanente
|
||
- <code>.sh-card-warning</code> - Bordure orange permanente</p>
|
||
<h4 id="4-buttons">4. Buttons<a class="headerlink" href="#4-buttons" title="Permanent link">¶</a></h4>
|
||
<p><strong>Gradient buttons (preferred):</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'button'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-btn sh-btn-primary'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Primary Action'</span><span class="p">)</span>
|
||
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'button'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-btn sh-btn-success'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Success Action'</span><span class="p">)</span>
|
||
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'button'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-btn sh-btn-danger'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Danger Action'</span><span class="p">)</span>
|
||
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'button'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-btn sh-btn-secondary'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Secondary Action'</span><span class="p">)</span>
|
||
</code></pre></div></p>
|
||
<p><strong>Tous les buttons doivent avoir:</strong>
|
||
- Shadow effect (déjà dans CSS)
|
||
- Hover animation (translateY(-2px))
|
||
- Transition smooth (0.3s cubic-bezier)</p>
|
||
<h4 id="5-filter-tabs">5. Filter Tabs<a class="headerlink" href="#5-filter-tabs" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-filter-tabs'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-filter-tab active'</span><span class="p">,</span>
|
||
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span><span class="s1">'data-filter'</span><span class="o">:</span><span class="w"> </span><span class="s1">'all'</span>
|
||
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'span'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-tab-icon'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'📋'</span><span class="p">),</span>
|
||
<a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'span'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-tab-label'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'All'</span><span class="p">)</span>
|
||
<a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a><span class="w"> </span><span class="p">])</span>
|
||
<a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a><span class="p">])</span>
|
||
</code></pre></div>
|
||
<p><strong>Active tab styling:</strong>
|
||
- Background: gradient indigo-violet
|
||
- Color: white
|
||
- Box-shadow avec glow</p>
|
||
<h3 id="grid-systems">Grid Systems<a class="headerlink" href="#grid-systems" title="Permanent link">¶</a></h3>
|
||
<h4 id="stats-overview-compact">Stats Overview (Compact)<a class="headerlink" href="#stats-overview-compact" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="nt">grid-template-columns</span><span class="o">:</span><span class="w"> </span><span class="nt">repeat</span><span class="o">(</span><span class="nt">auto-fit</span><span class="o">,</span><span class="w"> </span><span class="nt">minmax</span><span class="o">(</span><span class="nt">130px</span><span class="o">,</span><span class="w"> </span><span class="nt">1fr</span><span class="o">));</span>
|
||
<a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="nt">gap</span><span class="o">:</span><span class="w"> </span><span class="nt">16px</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<h4 id="metric-cards-medium">Metric Cards (Medium)<a class="headerlink" href="#metric-cards-medium" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="nt">grid-template-columns</span><span class="o">:</span><span class="w"> </span><span class="nt">repeat</span><span class="o">(</span><span class="nt">auto-fit</span><span class="o">,</span><span class="w"> </span><span class="nt">minmax</span><span class="o">(</span><span class="nt">240px</span><span class="o">,</span><span class="w"> </span><span class="nt">1fr</span><span class="o">));</span>
|
||
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="nt">gap</span><span class="o">:</span><span class="w"> </span><span class="nt">20px</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<h4 id="info-cards-large">Info Cards (Large)<a class="headerlink" href="#info-cards-large" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="nt">grid-template-columns</span><span class="o">:</span><span class="w"> </span><span class="nt">repeat</span><span class="o">(</span><span class="nt">auto-fit</span><span class="o">,</span><span class="w"> </span><span class="nt">minmax</span><span class="o">(</span><span class="nt">300px</span><span class="o">,</span><span class="w"> </span><span class="nt">1fr</span><span class="o">));</span>
|
||
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="nt">gap</span><span class="o">:</span><span class="w"> </span><span class="nt">20px</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<h3 id="gradient-effects">Gradient Effects<a class="headerlink" href="#gradient-effects" title="Permanent link">¶</a></h3>
|
||
<h4 id="gradient-text-titles">Gradient Text (Titles)<a class="headerlink" href="#gradient-text-titles" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="nt">background</span><span class="o">:</span><span class="w"> </span><span class="nt">linear-gradient</span><span class="o">(</span><span class="nt">135deg</span><span class="o">,</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary</span><span class="o">),</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary-end</span><span class="o">));</span>
|
||
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="nt">-webkit-background-clip</span><span class="o">:</span><span class="w"> </span><span class="nt">text</span><span class="o">;</span>
|
||
<a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="nt">-webkit-text-fill-color</span><span class="o">:</span><span class="w"> </span><span class="nt">transparent</span><span class="o">;</span>
|
||
<a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="nt">background-clip</span><span class="o">:</span><span class="w"> </span><span class="nt">text</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<p><strong>Utiliser:</strong> <code>.sh-gradient-text</code> class ou <code>.sh-page-title</code></p>
|
||
<h4 id="gradient-backgrounds-buttons-badges">Gradient Backgrounds (Buttons, Badges)<a class="headerlink" href="#gradient-backgrounds-buttons-badges" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="nt">background</span><span class="o">:</span><span class="w"> </span><span class="nt">linear-gradient</span><span class="o">(</span><span class="nt">135deg</span><span class="o">,</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary</span><span class="o">),</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary-end</span><span class="o">));</span>
|
||
</code></pre></div>
|
||
<h4 id="gradient-borders-top">Gradient Borders (Top)<a class="headerlink" href="#gradient-borders-top" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c">/* 3px top border avec dégradé */</span>
|
||
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="p">.</span><span class="nc">element</span><span class="p">::</span><span class="nd">before</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="w"> </span><span class="k">content</span><span class="p">:</span><span class="w"> </span><span class="s1">''</span><span class="p">;</span>
|
||
<a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="w"> </span><span class="k">position</span><span class="p">:</span><span class="w"> </span><span class="kc">absolute</span><span class="p">;</span>
|
||
<a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a><span class="w"> </span><span class="k">top</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||
<a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="w"> </span><span class="k">left</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||
<a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a><span class="w"> </span><span class="k">right</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||
<a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a><span class="w"> </span><span class="k">height</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="kt">px</span><span class="p">;</span>
|
||
<a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a><span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nb">linear-gradient</span><span class="p">(</span><span class="mi">90</span><span class="kt">deg</span><span class="p">,</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-primary</span><span class="p">),</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-primary-end</span><span class="p">));</span>
|
||
<a id="__codelineno-16-10" name="__codelineno-16-10" href="#__codelineno-16-10"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h3 id="animation-standards">Animation Standards<a class="headerlink" href="#animation-standards" title="Permanent link">¶</a></h3>
|
||
<h4 id="hover-effects">Hover Effects<a class="headerlink" href="#hover-effects" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="nt">transition</span><span class="o">:</span><span class="w"> </span><span class="nt">all</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">3s</span><span class="w"> </span><span class="nt">cubic-bezier</span><span class="o">(</span><span class="nt">0</span><span class="p">.</span><span class="nc">4</span><span class="o">,</span><span class="w"> </span><span class="nt">0</span><span class="o">,</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">2</span><span class="o">,</span><span class="w"> </span><span class="nt">1</span><span class="o">);</span>
|
||
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="nt">transform</span><span class="o">:</span><span class="w"> </span><span class="nt">translateY</span><span class="o">(</span><span class="nt">-3px</span><span class="o">);</span><span class="w"> </span><span class="c">/* Cards */</span>
|
||
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="nt">transform</span><span class="o">:</span><span class="w"> </span><span class="nt">translateY</span><span class="o">(</span><span class="nt">-2px</span><span class="o">);</span><span class="w"> </span><span class="c">/* Buttons, badges */</span>
|
||
</code></pre></div>
|
||
<h4 id="shadow-progression">Shadow Progression<a class="headerlink" href="#shadow-progression" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="c">/* Default */</span>
|
||
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="nt">box-shadow</span><span class="o">:</span><span class="w"> </span><span class="nt">none</span><span class="o">;</span>
|
||
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a>
|
||
<a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="c">/* Hover - Subtle */</span>
|
||
<a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a><span class="nt">box-shadow</span><span class="o">:</span><span class="w"> </span><span class="nt">0</span><span class="w"> </span><span class="nt">8px</span><span class="w"> </span><span class="nt">20px</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-shadow</span><span class="o">);</span>
|
||
<a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a>
|
||
<a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a><span class="c">/* Hover - Pronounced */</span>
|
||
<a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a><span class="nt">box-shadow</span><span class="o">:</span><span class="w"> </span><span class="nt">0</span><span class="w"> </span><span class="nt">12px</span><span class="w"> </span><span class="nt">28px</span><span class="w"> </span><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-hover-shadow</span><span class="o">);</span>
|
||
<a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a>
|
||
<a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a><span class="c">/* Button Hover */</span>
|
||
<a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a><span class="nt">box-shadow</span><span class="o">:</span><span class="w"> </span><span class="nt">0</span><span class="w"> </span><span class="nt">8px</span><span class="w"> </span><span class="nt">20px</span><span class="w"> </span><span class="nt">rgba</span><span class="o">(</span><span class="nt">99</span><span class="o">,</span><span class="w"> </span><span class="nt">102</span><span class="o">,</span><span class="w"> </span><span class="nt">241</span><span class="o">,</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">5</span><span class="o">);</span>
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="architecture-naming-conventions">Architecture & Naming Conventions<a class="headerlink" href="#architecture-naming-conventions" title="Permanent link">¶</a></h2>
|
||
<h3 id="system-architecture-overview">System Architecture Overview<a class="headerlink" href="#system-architecture-overview" title="Permanent link">¶</a></h3>
|
||
<p>The following diagram illustrates the complete data flow from browser JavaScript to system backend:</p>
|
||
<pre class="mermaid"><code>graph TB
|
||
subgraph "Browser"
|
||
UI[JavaScript View<br/>view/module/overview.js]
|
||
API[API Module<br/>module/api.js]
|
||
end
|
||
|
||
subgraph "LuCI Framework"
|
||
RPC[RPC Layer<br/>L.rpc.declare]
|
||
UHTTPD[uhttpd<br/>Web Server]
|
||
end
|
||
|
||
subgraph "Backend Services"
|
||
RPCD[RPCD Daemon]
|
||
SCRIPT[RPCD Script<br/>/usr/libexec/rpcd/luci.module-name]
|
||
UBUS[ubus Message Bus]
|
||
end
|
||
|
||
subgraph "System Layer"
|
||
UCI[UCI Configuration]
|
||
SYS[System Services<br/>init.d scripts]
|
||
FS[Filesystem<br/>proc, sys, etc]
|
||
end
|
||
|
||
UI -->|"API.getStatus()"| API
|
||
API -->|"rpc.declare({ object: 'luci.module' })"| RPC
|
||
RPC -->|"HTTP POST /ubus"| UHTTPD
|
||
UHTTPD -->|"call method"| RPCD
|
||
RPCD -->|"execute script"| SCRIPT
|
||
SCRIPT -->|"ubus call"| UBUS
|
||
UBUS -->|"read/write"| UCI
|
||
UBUS -->|"control"| SYS
|
||
SCRIPT -->|"read metrics"| FS
|
||
|
||
style UI fill:#6366f1,color:#fff,stroke:#4f46e5
|
||
style API fill:#8b5cf6,color:#fff,stroke:#7c3aed
|
||
style SCRIPT fill:#22c55e,color:#fff,stroke:#16a34a
|
||
style RPCD fill:#f59e0b,color:#fff,stroke:#d97706
|
||
style UCI fill:#ef4444,color:#fff,stroke:#dc2626</code></pre>
|
||
<p><strong>Key Components:</strong>
|
||
1. <strong>Browser Layer:</strong> JavaScript views and API modules handle UI and data requests
|
||
2. <strong>LuCI Framework:</strong> RPC layer translates JavaScript calls to ubus protocol
|
||
3. <strong>Backend Services:</strong> RPCD executes shell scripts via ubus message bus
|
||
4. <strong>System Layer:</strong> UCI configs, system services, and filesystem provide data</p>
|
||
<p><strong>Critical Naming Rule:</strong> The RPCD script name <strong>MUST</strong> match the <code>object</code> parameter in JavaScript's <code>rpc.declare()</code>.</p>
|
||
<hr />
|
||
<h3 id="critical-rpcd-script-naming">CRITICAL: RPCD Script Naming<a class="headerlink" href="#critical-rpcd-script-naming" title="Permanent link">¶</a></h3>
|
||
<p><strong>RÈGLE ABSOLUE:</strong> Le nom du fichier RPCD DOIT correspondre EXACTEMENT au nom de l'objet ubus dans JavaScript.</p>
|
||
<h4 id="correct">✅ CORRECT:<a class="headerlink" href="#correct" title="Permanent link">¶</a></h4>
|
||
<p><strong>JavaScript:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="kd">var</span><span class="w"> </span><span class="nx">callStatus</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">rpc</span><span class="p">.</span><span class="nx">declare</span><span class="p">({</span>
|
||
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="w"> </span><span class="nx">object</span><span class="o">:</span><span class="w"> </span><span class="s1">'luci.system-hub'</span><span class="p">,</span><span class="w"> </span><span class="c1">// ← Nom objet</span>
|
||
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="nx">method</span><span class="o">:</span><span class="w"> </span><span class="s1">'getHealth'</span>
|
||
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="p">});</span>
|
||
</code></pre></div></p>
|
||
<p><strong>Fichier RPCD:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a>root/usr/libexec/rpcd/luci.system-hub<span class="w"> </span><span class="c1"># ← EXACT MATCH</span>
|
||
</code></pre></div></p>
|
||
<h4 id="incorrect-causes-derreur-32000">❌ INCORRECT (Causes d'erreur -32000):<a class="headerlink" href="#incorrect-causes-derreur-32000" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="c1"># Mauvais - manque le préfixe</span>
|
||
<a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>root/usr/libexec/rpcd/system-hub
|
||
<a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
|
||
<a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="c1"># Mauvais - underscore au lieu de tiret</span>
|
||
<a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a>root/usr/libexec/rpcd/luci.system_hub
|
||
<a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a>
|
||
<a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a><span class="c1"># Mauvais - nom différent</span>
|
||
<a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a>root/usr/libexec/rpcd/systemhub
|
||
</code></pre></div>
|
||
<h3 id="menu-path-conventions">Menu Path Conventions<a class="headerlink" href="#menu-path-conventions" title="Permanent link">¶</a></h3>
|
||
<p><strong>RÈGLE:</strong> Les chemins dans menu.d/*.json doivent correspondre EXACTEMENT aux fichiers de vue.</p>
|
||
<h4 id="correct_1">✅ CORRECT:<a class="headerlink" href="#correct_1" title="Permanent link">¶</a></h4>
|
||
<p><strong>Menu JSON:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="p">{</span>
|
||
<a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="w"> </span><span class="nt">"action"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="w"> </span><span class="nt">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"view"</span><span class="p">,</span>
|
||
<a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="w"> </span><span class="nt">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"system-hub/overview"</span>
|
||
<a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="p">}</span>
|
||
</code></pre></div></p>
|
||
<p><strong>Fichier de vue:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a>htdocs/luci-static/resources/view/system-hub/overview.js
|
||
</code></pre></div></p>
|
||
<h4 id="incorrect-causes-404">❌ INCORRECT (Causes 404):<a class="headerlink" href="#incorrect-causes-404" title="Permanent link">¶</a></h4>
|
||
<p>Menu: <code>"path": "system-hub/overview"</code> mais fichier: <code>view/systemhub/overview.js</code></p>
|
||
<h3 id="prefixes-standards">Prefixes Standards<a class="headerlink" href="#prefixes-standards" title="Permanent link">¶</a></h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Prefix</th>
|
||
<th>Exemple</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>ubus objects</td>
|
||
<td><code>luci.</code></td>
|
||
<td><code>luci.system-hub</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>CSS classes</td>
|
||
<td><code>sh-</code> (System Hub) ou <code>sb-</code> (SecuBox)</td>
|
||
<td><code>.sh-page-header</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>CSS variables</td>
|
||
<td><code>--sh-</code></td>
|
||
<td><code>--sh-primary</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>JavaScript modules</td>
|
||
<td>Nom du module</td>
|
||
<td><code>system-hub/api.js</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="file-structure-template">File Structure Template<a class="headerlink" href="#file-structure-template" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a>luci-app-<module-name>/
|
||
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>├── Makefile
|
||
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>├── README.md
|
||
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>├── htdocs/luci-static/resources/
|
||
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a>│ ├── view/<module-name>/
|
||
<a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a>│ │ ├── overview.js # Page principale
|
||
<a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a>│ │ ├── settings.js # Configuration
|
||
<a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-8"></a>│ │ └── *.js # Autres vues
|
||
<a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a>│ └── <module-name>/
|
||
<a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-10"></a>│ ├── api.js # RPC client
|
||
<a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a>│ ├── theme.js # Theme helpers (optionnel)
|
||
<a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-12"></a>│ ├── common.css # Styles partagés
|
||
<a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-13"></a>│ └── *.css # Styles spécifiques
|
||
<a id="__codelineno-24-14" name="__codelineno-24-14" href="#__codelineno-24-14"></a>└── root/
|
||
<a id="__codelineno-24-15" name="__codelineno-24-15" href="#__codelineno-24-15"></a> ├── usr/
|
||
<a id="__codelineno-24-16" name="__codelineno-24-16" href="#__codelineno-24-16"></a> │ ├── libexec/rpcd/
|
||
<a id="__codelineno-24-17" name="__codelineno-24-17" href="#__codelineno-24-17"></a> │ │ └── luci.<module-name> # ⚠️ MUST match ubus object
|
||
<a id="__codelineno-24-18" name="__codelineno-24-18" href="#__codelineno-24-18"></a> │ └── share/
|
||
<a id="__codelineno-24-19" name="__codelineno-24-19" href="#__codelineno-24-19"></a> │ ├── luci/menu.d/
|
||
<a id="__codelineno-24-20" name="__codelineno-24-20" href="#__codelineno-24-20"></a> │ │ └── luci-app-<module-name>.json
|
||
<a id="__codelineno-24-21" name="__codelineno-24-21" href="#__codelineno-24-21"></a> │ └── rpcd/acl.d/
|
||
<a id="__codelineno-24-22" name="__codelineno-24-22" href="#__codelineno-24-22"></a> │ └── luci-app-<module-name>.json
|
||
<a id="__codelineno-24-23" name="__codelineno-24-23" href="#__codelineno-24-23"></a> └── etc/config/<module-name> (optionnel)
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="rpcd-ubus-best-practices">RPCD & ubus Best Practices<a class="headerlink" href="#rpcd-ubus-best-practices" title="Permanent link">¶</a></h2>
|
||
<h3 id="rpcd-script-template-shell">RPCD Script Template (Shell)<a class="headerlink" href="#rpcd-script-template-shell" title="Permanent link">¶</a></h3>
|
||
<p><strong>Fichier:</strong> <code>root/usr/libexec/rpcd/luci.<module-name></code></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="ch">#!/bin/sh</span>
|
||
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="c1"># RPCD backend for <module-name></span>
|
||
<a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="c1"># ubus object: luci.<module-name></span>
|
||
<a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a>
|
||
<a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a><span class="k">case</span><span class="w"> </span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span><span class="w"> </span><span class="k">in</span>
|
||
<a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a><span class="w"> </span>list<span class="o">)</span>
|
||
<a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-7"></a><span class="w"> </span><span class="c1"># Liste des méthodes disponibles</span>
|
||
<a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s1">'{</span>
|
||
<a id="__codelineno-25-9" name="__codelineno-25-9" href="#__codelineno-25-9"></a><span class="s1"> "getStatus": {},</span>
|
||
<a id="__codelineno-25-10" name="__codelineno-25-10" href="#__codelineno-25-10"></a><span class="s1"> "getHealth": {},</span>
|
||
<a id="__codelineno-25-11" name="__codelineno-25-11" href="#__codelineno-25-11"></a><span class="s1"> "getServices": {}</span>
|
||
<a id="__codelineno-25-12" name="__codelineno-25-12" href="#__codelineno-25-12"></a><span class="s1"> }'</span>
|
||
<a id="__codelineno-25-13" name="__codelineno-25-13" href="#__codelineno-25-13"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-14" name="__codelineno-25-14" href="#__codelineno-25-14"></a><span class="w"> </span>call<span class="o">)</span>
|
||
<a id="__codelineno-25-15" name="__codelineno-25-15" href="#__codelineno-25-15"></a><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s2">"</span><span class="nv">$2</span><span class="s2">"</span><span class="w"> </span><span class="k">in</span>
|
||
<a id="__codelineno-25-16" name="__codelineno-25-16" href="#__codelineno-25-16"></a><span class="w"> </span>getStatus<span class="o">)</span>
|
||
<a id="__codelineno-25-17" name="__codelineno-25-17" href="#__codelineno-25-17"></a><span class="w"> </span><span class="c1"># TOUJOURS retourner du JSON valide</span>
|
||
<a id="__codelineno-25-18" name="__codelineno-25-18" href="#__codelineno-25-18"></a><span class="w"> </span><span class="nb">printf</span><span class="w"> </span><span class="s1">'{"enabled": true, "version": "1.0.0"}\n'</span>
|
||
<a id="__codelineno-25-19" name="__codelineno-25-19" href="#__codelineno-25-19"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-20" name="__codelineno-25-20" href="#__codelineno-25-20"></a><span class="w"> </span>getHealth<span class="o">)</span>
|
||
<a id="__codelineno-25-21" name="__codelineno-25-21" href="#__codelineno-25-21"></a><span class="w"> </span><span class="c1"># Lire les métriques système</span>
|
||
<a id="__codelineno-25-22" name="__codelineno-25-22" href="#__codelineno-25-22"></a><span class="w"> </span><span class="nv">cpu_usage</span><span class="o">=</span><span class="k">$(</span>top<span class="w"> </span>-bn1<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s2">"CPU:"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>awk<span class="w"> </span><span class="s1">'{print $2}'</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span><span class="s1">'s/%//'</span><span class="k">)</span>
|
||
<a id="__codelineno-25-23" name="__codelineno-25-23" href="#__codelineno-25-23"></a><span class="w"> </span><span class="nv">mem_total</span><span class="o">=</span><span class="k">$(</span>free<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>Mem<span class="w"> </span><span class="p">|</span><span class="w"> </span>awk<span class="w"> </span><span class="s1">'{print $2}'</span><span class="k">)</span>
|
||
<a id="__codelineno-25-24" name="__codelineno-25-24" href="#__codelineno-25-24"></a><span class="w"> </span><span class="nv">mem_used</span><span class="o">=</span><span class="k">$(</span>free<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>Mem<span class="w"> </span><span class="p">|</span><span class="w"> </span>awk<span class="w"> </span><span class="s1">'{print $3}'</span><span class="k">)</span>
|
||
<a id="__codelineno-25-25" name="__codelineno-25-25" href="#__codelineno-25-25"></a>
|
||
<a id="__codelineno-25-26" name="__codelineno-25-26" href="#__codelineno-25-26"></a><span class="w"> </span><span class="nb">printf</span><span class="w"> </span><span class="s1">'{</span>
|
||
<a id="__codelineno-25-27" name="__codelineno-25-27" href="#__codelineno-25-27"></a><span class="s1"> "cpu": {"usage": %s},</span>
|
||
<a id="__codelineno-25-28" name="__codelineno-25-28" href="#__codelineno-25-28"></a><span class="s1"> "memory": {"total_kb": %s, "used_kb": %s}</span>
|
||
<a id="__codelineno-25-29" name="__codelineno-25-29" href="#__codelineno-25-29"></a><span class="s1"> }\n'</span><span class="w"> </span><span class="s2">"</span><span class="nv">$cpu_usage</span><span class="s2">"</span><span class="w"> </span><span class="s2">"</span><span class="nv">$mem_total</span><span class="s2">"</span><span class="w"> </span><span class="s2">"</span><span class="nv">$mem_used</span><span class="s2">"</span>
|
||
<a id="__codelineno-25-30" name="__codelineno-25-30" href="#__codelineno-25-30"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-31" name="__codelineno-25-31" href="#__codelineno-25-31"></a><span class="w"> </span>getServices<span class="o">)</span>
|
||
<a id="__codelineno-25-32" name="__codelineno-25-32" href="#__codelineno-25-32"></a><span class="w"> </span><span class="c1"># Exemple avec services</span>
|
||
<a id="__codelineno-25-33" name="__codelineno-25-33" href="#__codelineno-25-33"></a><span class="w"> </span><span class="nv">services</span><span class="o">=</span><span class="s1">'[]'</span>
|
||
<a id="__codelineno-25-34" name="__codelineno-25-34" href="#__codelineno-25-34"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span>service<span class="w"> </span><span class="k">in</span><span class="w"> </span>/etc/init.d/*<span class="p">;</span><span class="w"> </span><span class="k">do</span>
|
||
<a id="__codelineno-25-35" name="__codelineno-25-35" href="#__codelineno-25-35"></a><span class="w"> </span><span class="c1"># Build JSON array</span>
|
||
<a id="__codelineno-25-36" name="__codelineno-25-36" href="#__codelineno-25-36"></a><span class="w"> </span>:
|
||
<a id="__codelineno-25-37" name="__codelineno-25-37" href="#__codelineno-25-37"></a><span class="w"> </span><span class="k">done</span>
|
||
<a id="__codelineno-25-38" name="__codelineno-25-38" href="#__codelineno-25-38"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"</span><span class="nv">$services</span><span class="s2">"</span>
|
||
<a id="__codelineno-25-39" name="__codelineno-25-39" href="#__codelineno-25-39"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-40" name="__codelineno-25-40" href="#__codelineno-25-40"></a><span class="w"> </span>*<span class="o">)</span>
|
||
<a id="__codelineno-25-41" name="__codelineno-25-41" href="#__codelineno-25-41"></a><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s1">'{"error": "Method not found"}'</span>
|
||
<a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a><span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
|
||
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a><span class="w"> </span><span class="k">esac</span>
|
||
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a><span class="w"> </span><span class="p">;;</span>
|
||
<a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a><span class="k">esac</span>
|
||
</code></pre></div>
|
||
<h3 id="rpcd-script-validation">RPCD Script Validation<a class="headerlink" href="#rpcd-script-validation" title="Permanent link">¶</a></h3>
|
||
<p><strong>CHECKLIST OBLIGATOIRE:</strong></p>
|
||
<ol>
|
||
<li>✅ Fichier exécutable: <code>chmod +x root/usr/libexec/rpcd/luci.<module-name></code></li>
|
||
<li>✅ Shebang présent: <code>#!/bin/sh</code></li>
|
||
<li>✅ Structure case/esac correcte</li>
|
||
<li>✅ Méthode <code>list</code> retourne JSON avec toutes les méthodes</li>
|
||
<li>✅ Méthode <code>call</code> gère tous les cas</li>
|
||
<li>✅ Toujours retourner du JSON valide</li>
|
||
<li>✅ Pas de <code>echo</code> de debug (commentés en prod)</li>
|
||
<li>✅ Gestion d'erreur pour méthodes inconnues</li>
|
||
</ol>
|
||
<h3 id="testing-rpcd-scripts">Testing RPCD Scripts<a class="headerlink" href="#testing-rpcd-scripts" title="Permanent link">¶</a></h3>
|
||
<p><strong>Sur le routeur:</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="c1"># Test direct</span>
|
||
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>/usr/libexec/rpcd/luci.system-hub<span class="w"> </span>list
|
||
<a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>
|
||
<a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="c1"># Via ubus</span>
|
||
<a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>ubus<span class="w"> </span>list<span class="w"> </span>luci.system-hub
|
||
<a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a>ubus<span class="w"> </span>call<span class="w"> </span>luci.system-hub<span class="w"> </span>getStatus
|
||
<a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a>
|
||
<a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a><span class="c1"># Restart RPCD après modification</span>
|
||
<a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-9"></a>/etc/init.d/rpcd<span class="w"> </span>restart
|
||
</code></pre></div>
|
||
<h3 id="common-rpcd-errors">Common RPCD Errors<a class="headerlink" href="#common-rpcd-errors" title="Permanent link">¶</a></h3>
|
||
<h4 id="error-object-not-found-32000">Error: "Object not found" (-32000)<a class="headerlink" href="#error-object-not-found-32000" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Nom du fichier RPCD ne correspond pas à l'objet ubus</p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="c1"># Vérifier le nom dans JS</span>
|
||
<a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>grep<span class="w"> </span>-r<span class="w"> </span><span class="s2">"object:"</span><span class="w"> </span>htdocs/luci-static/resources/view/<span class="w"> </span>--include<span class="o">=</span><span class="s2">"*.js"</span>
|
||
<a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
|
||
<a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="c1"># Renommer le fichier RPCD pour correspondre</span>
|
||
<a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>mv<span class="w"> </span>root/usr/libexec/rpcd/wrong-name<span class="w"> </span>root/usr/libexec/rpcd/luci.correct-name
|
||
</code></pre></div></p>
|
||
<h4 id="error-method-not-found-32601">Error: "Method not found" (-32601)<a class="headerlink" href="#error-method-not-found-32601" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Méthode non déclarée dans <code>list</code> ou non implémentée dans <code>call</code></p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="c1"># Vérifier que la méthode est dans les deux blocs</span>
|
||
<a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>grep<span class="w"> </span><span class="s2">"getStatus"</span><span class="w"> </span>root/usr/libexec/rpcd/luci.*
|
||
</code></pre></div></p>
|
||
<h4 id="error-invalid-json-returned">Error: Invalid JSON returned<a class="headerlink" href="#error-invalid-json-returned" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Output RPCD n'est pas du JSON valide</p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="c1"># Tester le JSON</span>
|
||
<a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>/usr/libexec/rpcd/luci.module-name<span class="w"> </span>call<span class="w"> </span>getStatus<span class="w"> </span><span class="p">|</span><span class="w"> </span>jsonlint
|
||
<a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a>
|
||
<a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a><span class="c1"># Utiliser printf au lieu de echo pour le JSON</span>
|
||
<a id="__codelineno-29-5" name="__codelineno-29-5" href="#__codelineno-29-5"></a><span class="nb">printf</span><span class="w"> </span><span class="s1">'{"key": "%s"}\n'</span><span class="w"> </span><span class="s2">"</span><span class="nv">$value</span><span class="s2">"</span>
|
||
</code></pre></div></p>
|
||
<hr />
|
||
<h2 id="acl-permissions">ACL & Permissions<a class="headerlink" href="#acl-permissions" title="Permanent link">¶</a></h2>
|
||
<h3 id="acl-file-template">ACL File Template<a class="headerlink" href="#acl-file-template" title="Permanent link">¶</a></h3>
|
||
<p><strong>Fichier:</strong> <code>root/usr/share/rpcd/acl.d/luci-app-<module-name>.json</code></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="p">{</span>
|
||
<a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="w"> </span><span class="nt">"luci-app-<module-name>"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="w"> </span><span class="nt">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Grant access to <Module Name>"</span><span class="p">,</span>
|
||
<a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a><span class="w"> </span><span class="nt">"read"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a><span class="w"> </span><span class="nt">"ubus"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-6"></a><span class="w"> </span><span class="nt">"luci.<module-name>"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-30-7" name="__codelineno-30-7" href="#__codelineno-30-7"></a><span class="w"> </span><span class="s2">"getStatus"</span><span class="p">,</span>
|
||
<a id="__codelineno-30-8" name="__codelineno-30-8" href="#__codelineno-30-8"></a><span class="w"> </span><span class="s2">"getHealth"</span><span class="p">,</span>
|
||
<a id="__codelineno-30-9" name="__codelineno-30-9" href="#__codelineno-30-9"></a><span class="w"> </span><span class="s2">"getServices"</span>
|
||
<a id="__codelineno-30-10" name="__codelineno-30-10" href="#__codelineno-30-10"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-30-11" name="__codelineno-30-11" href="#__codelineno-30-11"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-30-12" name="__codelineno-30-12" href="#__codelineno-30-12"></a><span class="w"> </span><span class="nt">"uci"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-30-13" name="__codelineno-30-13" href="#__codelineno-30-13"></a><span class="w"> </span><span class="s2">"<module-name>"</span>
|
||
<a id="__codelineno-30-14" name="__codelineno-30-14" href="#__codelineno-30-14"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-30-15" name="__codelineno-30-15" href="#__codelineno-30-15"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-30-16" name="__codelineno-30-16" href="#__codelineno-30-16"></a><span class="w"> </span><span class="nt">"write"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-30-17" name="__codelineno-30-17" href="#__codelineno-30-17"></a><span class="w"> </span><span class="nt">"ubus"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-30-18" name="__codelineno-30-18" href="#__codelineno-30-18"></a><span class="w"> </span><span class="nt">"luci.<module-name>"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-30-19" name="__codelineno-30-19" href="#__codelineno-30-19"></a><span class="w"> </span><span class="s2">"setConfig"</span><span class="p">,</span>
|
||
<a id="__codelineno-30-20" name="__codelineno-30-20" href="#__codelineno-30-20"></a><span class="w"> </span><span class="s2">"restartService"</span>
|
||
<a id="__codelineno-30-21" name="__codelineno-30-21" href="#__codelineno-30-21"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-30-22" name="__codelineno-30-22" href="#__codelineno-30-22"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-30-23" name="__codelineno-30-23" href="#__codelineno-30-23"></a><span class="w"> </span><span class="nt">"uci"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-30-24" name="__codelineno-30-24" href="#__codelineno-30-24"></a><span class="w"> </span><span class="s2">"<module-name>"</span>
|
||
<a id="__codelineno-30-25" name="__codelineno-30-25" href="#__codelineno-30-25"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-30-26" name="__codelineno-30-26" href="#__codelineno-30-26"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-30-27" name="__codelineno-30-27" href="#__codelineno-30-27"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-30-28" name="__codelineno-30-28" href="#__codelineno-30-28"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h3 id="acl-best-practices">ACL Best Practices<a class="headerlink" href="#acl-best-practices" title="Permanent link">¶</a></h3>
|
||
<ol>
|
||
<li><strong>Séparation read/write:</strong> Ne donnez que les permissions nécessaires</li>
|
||
<li><strong>Liste explicite:</strong> Listez toutes les méthodes ubus utilisées</li>
|
||
<li><strong>UCI access:</strong> Ajoutez les configs UCI dans <code>read</code> et <code>write</code></li>
|
||
<li><strong>Validation JSON:</strong> Toujours valider avec <code>jsonlint</code></li>
|
||
</ol>
|
||
<h3 id="common-acl-errors">Common ACL Errors<a class="headerlink" href="#common-acl-errors" title="Permanent link">¶</a></h3>
|
||
<h4 id="error-access-denied">Error: "Access denied"<a class="headerlink" href="#error-access-denied" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Méthode ubus pas dans ACL</p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="p">{</span>
|
||
<a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a><span class="w"> </span><span class="nt">"read"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a><span class="w"> </span><span class="nt">"ubus"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a><span class="w"> </span><span class="nt">"luci.system-hub"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a><span class="w"> </span><span class="s2">"getHealth"</span><span class="w"> </span><span class="c1">// ← Ajouter la méthode manquante</span>
|
||
<a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-31-9" name="__codelineno-31-9" href="#__codelineno-31-9"></a><span class="p">}</span>
|
||
</code></pre></div></p>
|
||
<h4 id="error-uci-config-not-accessible">Error: "UCI config not accessible"<a class="headerlink" href="#error-uci-config-not-accessible" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Config UCI pas dans ACL</p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="p">{</span>
|
||
<a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a><span class="w"> </span><span class="nt">"read"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a><span class="w"> </span><span class="nt">"uci"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="w"> </span><span class="s2">"system-hub"</span><span class="w"> </span><span class="c1">// ← Ajouter le config</span>
|
||
<a id="__codelineno-32-5" name="__codelineno-32-5" href="#__codelineno-32-5"></a><span class="w"> </span><span class="p">]</span>
|
||
<a id="__codelineno-32-6" name="__codelineno-32-6" href="#__codelineno-32-6"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-32-7" name="__codelineno-32-7" href="#__codelineno-32-7"></a><span class="p">}</span>
|
||
</code></pre></div></p>
|
||
<hr />
|
||
<h2 id="javascript-patterns">JavaScript Patterns<a class="headerlink" href="#javascript-patterns" title="Permanent link">¶</a></h2>
|
||
<h3 id="api-module-template">API Module Template<a class="headerlink" href="#api-module-template" title="Permanent link">¶</a></h3>
|
||
<p><strong>Fichier:</strong> <code>htdocs/luci-static/resources/<module-name>/api.js</code></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="s1">'use strict'</span><span class="p">;</span>
|
||
<a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a><span class="s1">'require rpc'</span><span class="p">;</span>
|
||
<a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a><span class="s1">'require uci'</span><span class="p">;</span>
|
||
<a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a>
|
||
<a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a><span class="k">return</span><span class="w"> </span><span class="nx">L</span><span class="p">.</span><span class="nx">Class</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
|
||
<a id="__codelineno-33-6" name="__codelineno-33-6" href="#__codelineno-33-6"></a><span class="w"> </span><span class="c1">// Déclarer les appels RPC</span>
|
||
<a id="__codelineno-33-7" name="__codelineno-33-7" href="#__codelineno-33-7"></a><span class="w"> </span><span class="nx">callGetStatus</span><span class="o">:</span><span class="w"> </span><span class="nx">rpc</span><span class="p">.</span><span class="nx">declare</span><span class="p">({</span>
|
||
<a id="__codelineno-33-8" name="__codelineno-33-8" href="#__codelineno-33-8"></a><span class="w"> </span><span class="nx">object</span><span class="o">:</span><span class="w"> </span><span class="s1">'luci.<module-name>'</span><span class="p">,</span>
|
||
<a id="__codelineno-33-9" name="__codelineno-33-9" href="#__codelineno-33-9"></a><span class="w"> </span><span class="nx">method</span><span class="o">:</span><span class="w"> </span><span class="s1">'getStatus'</span><span class="p">,</span>
|
||
<a id="__codelineno-33-10" name="__codelineno-33-10" href="#__codelineno-33-10"></a><span class="w"> </span><span class="nx">expect</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-33-11" name="__codelineno-33-11" href="#__codelineno-33-11"></a><span class="w"> </span><span class="p">}),</span>
|
||
<a id="__codelineno-33-12" name="__codelineno-33-12" href="#__codelineno-33-12"></a>
|
||
<a id="__codelineno-33-13" name="__codelineno-33-13" href="#__codelineno-33-13"></a><span class="w"> </span><span class="nx">callGetHealth</span><span class="o">:</span><span class="w"> </span><span class="nx">rpc</span><span class="p">.</span><span class="nx">declare</span><span class="p">({</span>
|
||
<a id="__codelineno-33-14" name="__codelineno-33-14" href="#__codelineno-33-14"></a><span class="w"> </span><span class="nx">object</span><span class="o">:</span><span class="w"> </span><span class="s1">'luci.<module-name>'</span><span class="p">,</span>
|
||
<a id="__codelineno-33-15" name="__codelineno-33-15" href="#__codelineno-33-15"></a><span class="w"> </span><span class="nx">method</span><span class="o">:</span><span class="w"> </span><span class="s1">'getHealth'</span><span class="p">,</span>
|
||
<a id="__codelineno-33-16" name="__codelineno-33-16" href="#__codelineno-33-16"></a><span class="w"> </span><span class="nx">expect</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-33-17" name="__codelineno-33-17" href="#__codelineno-33-17"></a><span class="w"> </span><span class="p">}),</span>
|
||
<a id="__codelineno-33-18" name="__codelineno-33-18" href="#__codelineno-33-18"></a>
|
||
<a id="__codelineno-33-19" name="__codelineno-33-19" href="#__codelineno-33-19"></a><span class="w"> </span><span class="c1">// Méthodes wrapper avec gestion d'erreur</span>
|
||
<a id="__codelineno-33-20" name="__codelineno-33-20" href="#__codelineno-33-20"></a><span class="w"> </span><span class="nx">getStatus</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-21" name="__codelineno-33-21" href="#__codelineno-33-21"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">callGetStatus</span><span class="p">().</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-22" name="__codelineno-33-22" href="#__codelineno-33-22"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to get status:'</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">);</span>
|
||
<a id="__codelineno-33-23" name="__codelineno-33-23" href="#__codelineno-33-23"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">enabled</span><span class="o">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="o">:</span><span class="w"> </span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="w"> </span><span class="p">};</span>
|
||
<a id="__codelineno-33-24" name="__codelineno-33-24" href="#__codelineno-33-24"></a><span class="w"> </span><span class="p">});</span>
|
||
<a id="__codelineno-33-25" name="__codelineno-33-25" href="#__codelineno-33-25"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-33-26" name="__codelineno-33-26" href="#__codelineno-33-26"></a>
|
||
<a id="__codelineno-33-27" name="__codelineno-33-27" href="#__codelineno-33-27"></a><span class="w"> </span><span class="nx">getHealth</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-28" name="__codelineno-33-28" href="#__codelineno-33-28"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">callGetHealth</span><span class="p">().</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-29" name="__codelineno-33-29" href="#__codelineno-33-29"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to get health:'</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">);</span>
|
||
<a id="__codelineno-33-30" name="__codelineno-33-30" href="#__codelineno-33-30"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-31" name="__codelineno-33-31" href="#__codelineno-33-31"></a><span class="w"> </span><span class="nx">cpu</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">usage</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-33-32" name="__codelineno-33-32" href="#__codelineno-33-32"></a><span class="w"> </span><span class="nx">memory</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">usage</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-33-33" name="__codelineno-33-33" href="#__codelineno-33-33"></a><span class="w"> </span><span class="nx">error</span><span class="o">:</span><span class="w"> </span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span>
|
||
<a id="__codelineno-33-34" name="__codelineno-33-34" href="#__codelineno-33-34"></a><span class="w"> </span><span class="p">};</span>
|
||
<a id="__codelineno-33-35" name="__codelineno-33-35" href="#__codelineno-33-35"></a><span class="w"> </span><span class="p">});</span>
|
||
<a id="__codelineno-33-36" name="__codelineno-33-36" href="#__codelineno-33-36"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-33-37" name="__codelineno-33-37" href="#__codelineno-33-37"></a>
|
||
<a id="__codelineno-33-38" name="__codelineno-33-38" href="#__codelineno-33-38"></a><span class="w"> </span><span class="c1">// Utilitaires</span>
|
||
<a id="__codelineno-33-39" name="__codelineno-33-39" href="#__codelineno-33-39"></a><span class="w"> </span><span class="nx">formatBytes</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">bytes</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-33-40" name="__codelineno-33-40" href="#__codelineno-33-40"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">bytes</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s1">'0 B'</span><span class="p">;</span>
|
||
<a id="__codelineno-33-41" name="__codelineno-33-41" href="#__codelineno-33-41"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1024</span><span class="p">;</span>
|
||
<a id="__codelineno-33-42" name="__codelineno-33-42" href="#__codelineno-33-42"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">sizes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s1">'B'</span><span class="p">,</span><span class="w"> </span><span class="s1">'KB'</span><span class="p">,</span><span class="w"> </span><span class="s1">'MB'</span><span class="p">,</span><span class="w"> </span><span class="s1">'GB'</span><span class="p">];</span>
|
||
<a id="__codelineno-33-43" name="__codelineno-33-43" href="#__codelineno-33-43"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">bytes</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">k</span><span class="p">));</span>
|
||
<a id="__codelineno-33-44" name="__codelineno-33-44" href="#__codelineno-33-44"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">parseFloat</span><span class="p">((</span><span class="nx">bytes</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">pow</span><span class="p">(</span><span class="nx">k</span><span class="p">,</span><span class="w"> </span><span class="nx">i</span><span class="p">)).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">2</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s1">' '</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">sizes</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
|
||
<a id="__codelineno-33-45" name="__codelineno-33-45" href="#__codelineno-33-45"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-33-46" name="__codelineno-33-46" href="#__codelineno-33-46"></a><span class="p">});</span>
|
||
</code></pre></div>
|
||
<h3 id="view-template">View Template<a class="headerlink" href="#view-template" title="Permanent link">¶</a></h3>
|
||
<p><strong>Fichier:</strong> <code>htdocs/luci-static/resources/view/<module-name>/overview.js</code></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="s1">'use strict'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="s1">'require view'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="s1">'require ui'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="s1">'require dom'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="s1">'require poll'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a><span class="s1">'require <module-name>/api as API'</span><span class="p">;</span>
|
||
<a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a>
|
||
<a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a><span class="k">return</span><span class="w"> </span><span class="nx">view</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
|
||
<a id="__codelineno-34-9" name="__codelineno-34-9" href="#__codelineno-34-9"></a><span class="w"> </span><span class="c1">// State</span>
|
||
<a id="__codelineno-34-10" name="__codelineno-34-10" href="#__codelineno-34-10"></a><span class="w"> </span><span class="nx">healthData</span><span class="o">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||
<a id="__codelineno-34-11" name="__codelineno-34-11" href="#__codelineno-34-11"></a><span class="w"> </span><span class="nx">sysInfo</span><span class="o">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||
<a id="__codelineno-34-12" name="__codelineno-34-12" href="#__codelineno-34-12"></a>
|
||
<a id="__codelineno-34-13" name="__codelineno-34-13" href="#__codelineno-34-13"></a><span class="w"> </span><span class="c1">// Load data</span>
|
||
<a id="__codelineno-34-14" name="__codelineno-34-14" href="#__codelineno-34-14"></a><span class="w"> </span><span class="nx">load</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-15" name="__codelineno-34-15" href="#__codelineno-34-15"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
|
||
<a id="__codelineno-34-16" name="__codelineno-34-16" href="#__codelineno-34-16"></a><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getStatus</span><span class="p">(),</span>
|
||
<a id="__codelineno-34-17" name="__codelineno-34-17" href="#__codelineno-34-17"></a><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getHealth</span><span class="p">()</span>
|
||
<a id="__codelineno-34-18" name="__codelineno-34-18" href="#__codelineno-34-18"></a><span class="w"> </span><span class="p">]);</span>
|
||
<a id="__codelineno-34-19" name="__codelineno-34-19" href="#__codelineno-34-19"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-34-20" name="__codelineno-34-20" href="#__codelineno-34-20"></a>
|
||
<a id="__codelineno-34-21" name="__codelineno-34-21" href="#__codelineno-34-21"></a><span class="w"> </span><span class="c1">// Render UI</span>
|
||
<a id="__codelineno-34-22" name="__codelineno-34-22" href="#__codelineno-34-22"></a><span class="w"> </span><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-23" name="__codelineno-34-23" href="#__codelineno-34-23"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">self</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">;</span>
|
||
<a id="__codelineno-34-24" name="__codelineno-34-24" href="#__codelineno-34-24"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">sysInfo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">data</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{};</span>
|
||
<a id="__codelineno-34-25" name="__codelineno-34-25" href="#__codelineno-34-25"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">data</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{};</span>
|
||
<a id="__codelineno-34-26" name="__codelineno-34-26" href="#__codelineno-34-26"></a>
|
||
<a id="__codelineno-34-27" name="__codelineno-34-27" href="#__codelineno-34-27"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">container</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'<module>-dashboard'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-34-28" name="__codelineno-34-28" href="#__codelineno-34-28"></a><span class="w"> </span><span class="c1">// Link CSS files</span>
|
||
<a id="__codelineno-34-29" name="__codelineno-34-29" href="#__codelineno-34-29"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'link'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'rel'</span><span class="o">:</span><span class="w"> </span><span class="s1">'stylesheet'</span><span class="p">,</span><span class="w"> </span><span class="s1">'href'</span><span class="o">:</span><span class="w"> </span><span class="nx">L</span><span class="p">.</span><span class="nx">resource</span><span class="p">(</span><span class="s1">'<module>/common.css'</span><span class="p">)</span><span class="w"> </span><span class="p">}),</span>
|
||
<a id="__codelineno-34-30" name="__codelineno-34-30" href="#__codelineno-34-30"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'link'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'rel'</span><span class="o">:</span><span class="w"> </span><span class="s1">'stylesheet'</span><span class="p">,</span><span class="w"> </span><span class="s1">'href'</span><span class="o">:</span><span class="w"> </span><span class="nx">L</span><span class="p">.</span><span class="nx">resource</span><span class="p">(</span><span class="s1">'<module>/overview.css'</span><span class="p">)</span><span class="w"> </span><span class="p">}),</span>
|
||
<a id="__codelineno-34-31" name="__codelineno-34-31" href="#__codelineno-34-31"></a>
|
||
<a id="__codelineno-34-32" name="__codelineno-34-32" href="#__codelineno-34-32"></a><span class="w"> </span><span class="c1">// Header</span>
|
||
<a id="__codelineno-34-33" name="__codelineno-34-33" href="#__codelineno-34-33"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">renderHeader</span><span class="p">(),</span>
|
||
<a id="__codelineno-34-34" name="__codelineno-34-34" href="#__codelineno-34-34"></a>
|
||
<a id="__codelineno-34-35" name="__codelineno-34-35" href="#__codelineno-34-35"></a><span class="w"> </span><span class="c1">// Content</span>
|
||
<a id="__codelineno-34-36" name="__codelineno-34-36" href="#__codelineno-34-36"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">renderContent</span><span class="p">()</span>
|
||
<a id="__codelineno-34-37" name="__codelineno-34-37" href="#__codelineno-34-37"></a><span class="w"> </span><span class="p">]);</span>
|
||
<a id="__codelineno-34-38" name="__codelineno-34-38" href="#__codelineno-34-38"></a>
|
||
<a id="__codelineno-34-39" name="__codelineno-34-39" href="#__codelineno-34-39"></a><span class="w"> </span><span class="c1">// Setup auto-refresh</span>
|
||
<a id="__codelineno-34-40" name="__codelineno-34-40" href="#__codelineno-34-40"></a><span class="w"> </span><span class="nx">poll</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">L</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-41" name="__codelineno-34-41" href="#__codelineno-34-41"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
|
||
<a id="__codelineno-34-42" name="__codelineno-34-42" href="#__codelineno-34-42"></a><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getStatus</span><span class="p">(),</span>
|
||
<a id="__codelineno-34-43" name="__codelineno-34-43" href="#__codelineno-34-43"></a><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getHealth</span><span class="p">()</span>
|
||
<a id="__codelineno-34-44" name="__codelineno-34-44" href="#__codelineno-34-44"></a><span class="w"> </span><span class="p">]).</span><span class="nx">then</span><span class="p">(</span><span class="nx">L</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">refreshData</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-45" name="__codelineno-34-45" href="#__codelineno-34-45"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">sysInfo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">refreshData</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{};</span>
|
||
<a id="__codelineno-34-46" name="__codelineno-34-46" href="#__codelineno-34-46"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">refreshData</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{};</span>
|
||
<a id="__codelineno-34-47" name="__codelineno-34-47" href="#__codelineno-34-47"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">updateDashboard</span><span class="p">();</span>
|
||
<a id="__codelineno-34-48" name="__codelineno-34-48" href="#__codelineno-34-48"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="k">this</span><span class="p">));</span>
|
||
<a id="__codelineno-34-49" name="__codelineno-34-49" href="#__codelineno-34-49"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="k">this</span><span class="p">),</span><span class="w"> </span><span class="mf">30</span><span class="p">);</span><span class="w"> </span><span class="c1">// Refresh every 30s</span>
|
||
<a id="__codelineno-34-50" name="__codelineno-34-50" href="#__codelineno-34-50"></a>
|
||
<a id="__codelineno-34-51" name="__codelineno-34-51" href="#__codelineno-34-51"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">container</span><span class="p">;</span>
|
||
<a id="__codelineno-34-52" name="__codelineno-34-52" href="#__codelineno-34-52"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-34-53" name="__codelineno-34-53" href="#__codelineno-34-53"></a>
|
||
<a id="__codelineno-34-54" name="__codelineno-34-54" href="#__codelineno-34-54"></a><span class="w"> </span><span class="nx">renderHeader</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-55" name="__codelineno-34-55" href="#__codelineno-34-55"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-page-header'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-34-56" name="__codelineno-34-56" href="#__codelineno-34-56"></a><span class="w"> </span><span class="c1">// Header content</span>
|
||
<a id="__codelineno-34-57" name="__codelineno-34-57" href="#__codelineno-34-57"></a><span class="w"> </span><span class="p">]);</span>
|
||
<a id="__codelineno-34-58" name="__codelineno-34-58" href="#__codelineno-34-58"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-34-59" name="__codelineno-34-59" href="#__codelineno-34-59"></a>
|
||
<a id="__codelineno-34-60" name="__codelineno-34-60" href="#__codelineno-34-60"></a><span class="w"> </span><span class="nx">renderContent</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-61" name="__codelineno-34-61" href="#__codelineno-34-61"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-content'</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-34-62" name="__codelineno-34-62" href="#__codelineno-34-62"></a><span class="w"> </span><span class="c1">// Main content</span>
|
||
<a id="__codelineno-34-63" name="__codelineno-34-63" href="#__codelineno-34-63"></a><span class="w"> </span><span class="p">]);</span>
|
||
<a id="__codelineno-34-64" name="__codelineno-34-64" href="#__codelineno-34-64"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-34-65" name="__codelineno-34-65" href="#__codelineno-34-65"></a>
|
||
<a id="__codelineno-34-66" name="__codelineno-34-66" href="#__codelineno-34-66"></a><span class="w"> </span><span class="nx">updateDashboard</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-67" name="__codelineno-34-67" href="#__codelineno-34-67"></a><span class="w"> </span><span class="c1">// Update existing DOM elements</span>
|
||
<a id="__codelineno-34-68" name="__codelineno-34-68" href="#__codelineno-34-68"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">element</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s1">'.my-element'</span><span class="p">);</span>
|
||
<a id="__codelineno-34-69" name="__codelineno-34-69" href="#__codelineno-34-69"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">element</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-34-70" name="__codelineno-34-70" href="#__codelineno-34-70"></a><span class="w"> </span><span class="nx">dom</span><span class="p">.</span><span class="nx">content</span><span class="p">(</span><span class="nx">element</span><span class="p">,</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">renderContent</span><span class="p">());</span>
|
||
<a id="__codelineno-34-71" name="__codelineno-34-71" href="#__codelineno-34-71"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-34-72" name="__codelineno-34-72" href="#__codelineno-34-72"></a><span class="w"> </span><span class="p">},</span>
|
||
<a id="__codelineno-34-73" name="__codelineno-34-73" href="#__codelineno-34-73"></a>
|
||
<a id="__codelineno-34-74" name="__codelineno-34-74" href="#__codelineno-34-74"></a><span class="w"> </span><span class="c1">// Required stubs for LuCI</span>
|
||
<a id="__codelineno-34-75" name="__codelineno-34-75" href="#__codelineno-34-75"></a><span class="w"> </span><span class="nx">handleSaveApply</span><span class="o">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||
<a id="__codelineno-34-76" name="__codelineno-34-76" href="#__codelineno-34-76"></a><span class="w"> </span><span class="nx">handleSave</span><span class="o">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
|
||
<a id="__codelineno-34-77" name="__codelineno-34-77" href="#__codelineno-34-77"></a><span class="w"> </span><span class="nx">handleReset</span><span class="o">:</span><span class="w"> </span><span class="kc">null</span>
|
||
<a id="__codelineno-34-78" name="__codelineno-34-78" href="#__codelineno-34-78"></a><span class="p">});</span>
|
||
</code></pre></div>
|
||
<h3 id="event-handling-pattern">Event Handling Pattern<a class="headerlink" href="#event-handling-pattern" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="c1">// ✅ CORRECT: Bind events après render</span>
|
||
<a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a><span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">container</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'button'</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-35-5" name="__codelineno-35-5" href="#__codelineno-35-5"></a><span class="w"> </span><span class="s1">'id'</span><span class="o">:</span><span class="w"> </span><span class="s1">'my-button'</span><span class="p">,</span>
|
||
<a id="__codelineno-35-6" name="__codelineno-35-6" href="#__codelineno-35-6"></a><span class="w"> </span><span class="s1">'class'</span><span class="o">:</span><span class="w"> </span><span class="s1">'sh-btn sh-btn-primary'</span>
|
||
<a id="__codelineno-35-7" name="__codelineno-35-7" href="#__codelineno-35-7"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="s1">'Click Me'</span><span class="p">)</span>
|
||
<a id="__codelineno-35-8" name="__codelineno-35-8" href="#__codelineno-35-8"></a><span class="w"> </span><span class="p">]);</span>
|
||
<a id="__codelineno-35-9" name="__codelineno-35-9" href="#__codelineno-35-9"></a>
|
||
<a id="__codelineno-35-10" name="__codelineno-35-10" href="#__codelineno-35-10"></a><span class="w"> </span><span class="c1">// Ajouter l'événement après le container est créé</span>
|
||
<a id="__codelineno-35-11" name="__codelineno-35-11" href="#__codelineno-35-11"></a><span class="w"> </span><span class="nx">container</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">ev</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-35-12" name="__codelineno-35-12" href="#__codelineno-35-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">ev</span><span class="p">.</span><span class="nx">target</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">ev</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">'my-button'</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-35-13" name="__codelineno-35-13" href="#__codelineno-35-13"></a><span class="w"> </span><span class="nx">self</span><span class="p">.</span><span class="nx">handleButtonClick</span><span class="p">();</span>
|
||
<a id="__codelineno-35-14" name="__codelineno-35-14" href="#__codelineno-35-14"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-35-15" name="__codelineno-35-15" href="#__codelineno-35-15"></a><span class="w"> </span><span class="p">});</span>
|
||
<a id="__codelineno-35-16" name="__codelineno-35-16" href="#__codelineno-35-16"></a>
|
||
<a id="__codelineno-35-17" name="__codelineno-35-17" href="#__codelineno-35-17"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">container</span><span class="p">;</span>
|
||
<a id="__codelineno-35-18" name="__codelineno-35-18" href="#__codelineno-35-18"></a><span class="p">},</span>
|
||
<a id="__codelineno-35-19" name="__codelineno-35-19" href="#__codelineno-35-19"></a>
|
||
<a id="__codelineno-35-20" name="__codelineno-35-20" href="#__codelineno-35-20"></a><span class="nx">handleButtonClick</span><span class="o">:</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-35-21" name="__codelineno-35-21" href="#__codelineno-35-21"></a><span class="w"> </span><span class="nx">ui</span><span class="p">.</span><span class="nx">addNotification</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="nx">E</span><span class="p">(</span><span class="s1">'p'</span><span class="p">,</span><span class="w"> </span><span class="s1">'Button clicked!'</span><span class="p">),</span><span class="w"> </span><span class="s1">'info'</span><span class="p">);</span>
|
||
<a id="__codelineno-35-22" name="__codelineno-35-22" href="#__codelineno-35-22"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h3 id="common-javascript-errors">Common JavaScript Errors<a class="headerlink" href="#common-javascript-errors" title="Permanent link">¶</a></h3>
|
||
<h4 id="error-object-htmlbuttonelement-affiche">Error: "[object HTMLButtonElement]" affiché<a class="headerlink" href="#error-object-htmlbuttonelement-affiche" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Array imbriqué quand E() attend un array simple</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="c1">// ❌ INCORRECT</span>
|
||
<a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="p">[</span>
|
||
<a id="__codelineno-36-3" name="__codelineno-36-3" href="#__codelineno-36-3"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">renderButtons</span><span class="p">()</span><span class="w"> </span><span class="c1">// renderButtons retourne déjà un array</span>
|
||
<a id="__codelineno-36-4" name="__codelineno-36-4" href="#__codelineno-36-4"></a><span class="p">])</span>
|
||
<a id="__codelineno-36-5" name="__codelineno-36-5" href="#__codelineno-36-5"></a>
|
||
<a id="__codelineno-36-6" name="__codelineno-36-6" href="#__codelineno-36-6"></a><span class="c1">// ✅ CORRECT</span>
|
||
<a id="__codelineno-36-7" name="__codelineno-36-7" href="#__codelineno-36-7"></a><span class="nx">E</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span><span class="w"> </span><span class="p">{},</span>
|
||
<a id="__codelineno-36-8" name="__codelineno-36-8" href="#__codelineno-36-8"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">renderButtons</span><span class="p">()</span><span class="w"> </span><span class="c1">// Pas de [ ] supplémentaire</span>
|
||
<a id="__codelineno-36-9" name="__codelineno-36-9" href="#__codelineno-36-9"></a><span class="p">)</span>
|
||
</code></pre></div>
|
||
<h4 id="error-cannot-read-property-of-undefined">Error: "Cannot read property of undefined"<a class="headerlink" href="#error-cannot-read-property-of-undefined" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Données API non disponibles</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="c1">// ❌ INCORRECT</span>
|
||
<a id="__codelineno-37-2" name="__codelineno-37-2" href="#__codelineno-37-2"></a><span class="kd">var</span><span class="w"> </span><span class="nx">cpuUsage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="p">.</span><span class="nx">cpu</span><span class="p">.</span><span class="nx">usage</span><span class="p">;</span>
|
||
<a id="__codelineno-37-3" name="__codelineno-37-3" href="#__codelineno-37-3"></a>
|
||
<a id="__codelineno-37-4" name="__codelineno-37-4" href="#__codelineno-37-4"></a><span class="c1">// ✅ CORRECT (avec optional chaining)</span>
|
||
<a id="__codelineno-37-5" name="__codelineno-37-5" href="#__codelineno-37-5"></a><span class="kd">var</span><span class="w"> </span><span class="nx">cpuUsage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="p">.</span><span class="nx">cpu</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="p">.</span><span class="nx">cpu</span><span class="p">.</span><span class="nx">usage</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
|
||
<a id="__codelineno-37-6" name="__codelineno-37-6" href="#__codelineno-37-6"></a><span class="c1">// ou</span>
|
||
<a id="__codelineno-37-7" name="__codelineno-37-7" href="#__codelineno-37-7"></a><span class="kd">var</span><span class="w"> </span><span class="nx">cpuUsage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">healthData</span><span class="p">.</span><span class="nx">cpu</span><span class="o">?</span><span class="p">.</span><span class="nx">usage</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="c1">// ES2020</span>
|
||
</code></pre></div>
|
||
<h4 id="error-poll-callback-failed">Error: "poll callback failed"<a class="headerlink" href="#error-poll-callback-failed" title="Permanent link">¶</a></h4>
|
||
<p><strong>Cause:</strong> Promise non retournée dans poll.add</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="c1">// ❌ INCORRECT</span>
|
||
<a id="__codelineno-38-2" name="__codelineno-38-2" href="#__codelineno-38-2"></a><span class="nx">poll</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-38-3" name="__codelineno-38-3" href="#__codelineno-38-3"></a><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getHealth</span><span class="p">();</span><span class="w"> </span><span class="c1">// Pas de return!</span>
|
||
<a id="__codelineno-38-4" name="__codelineno-38-4" href="#__codelineno-38-4"></a><span class="p">},</span><span class="w"> </span><span class="mf">30</span><span class="p">);</span>
|
||
<a id="__codelineno-38-5" name="__codelineno-38-5" href="#__codelineno-38-5"></a>
|
||
<a id="__codelineno-38-6" name="__codelineno-38-6" href="#__codelineno-38-6"></a><span class="c1">// ✅ CORRECT</span>
|
||
<a id="__codelineno-38-7" name="__codelineno-38-7" href="#__codelineno-38-7"></a><span class="nx">poll</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-38-8" name="__codelineno-38-8" href="#__codelineno-38-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">API</span><span class="p">.</span><span class="nx">getHealth</span><span class="p">().</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-38-9" name="__codelineno-38-9" href="#__codelineno-38-9"></a><span class="w"> </span><span class="c1">// Update UI</span>
|
||
<a id="__codelineno-38-10" name="__codelineno-38-10" href="#__codelineno-38-10"></a><span class="w"> </span><span class="p">});</span>
|
||
<a id="__codelineno-38-11" name="__codelineno-38-11" href="#__codelineno-38-11"></a><span class="p">},</span><span class="w"> </span><span class="mf">30</span><span class="p">);</span>
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="cssstyling-standards">CSS/Styling Standards<a class="headerlink" href="#cssstyling-standards" title="Permanent link">¶</a></h2>
|
||
<h3 id="file-organization">File Organization<a class="headerlink" href="#file-organization" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><module-name>/
|
||
<a id="__codelineno-39-2" name="__codelineno-39-2" href="#__codelineno-39-2"></a>├── common.css # Shared components (headers, buttons, cards, tabs)
|
||
<a id="__codelineno-39-3" name="__codelineno-39-3" href="#__codelineno-39-3"></a>├── overview.css # Overview page specific
|
||
<a id="__codelineno-39-4" name="__codelineno-39-4" href="#__codelineno-39-4"></a>├── services.css # Services page specific
|
||
<a id="__codelineno-39-5" name="__codelineno-39-5" href="#__codelineno-39-5"></a>└── *.css # Other page-specific styles
|
||
</code></pre></div>
|
||
<h3 id="css-file-template">CSS File Template<a class="headerlink" href="#css-file-template" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a><span class="c">/**</span>
|
||
<a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a><span class="c"> * Module Name - Page/Component Styles</span>
|
||
<a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a><span class="c"> * Description of what this file styles</span>
|
||
<a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a><span class="c"> * Version: X.Y.Z</span>
|
||
<a id="__codelineno-40-5" name="__codelineno-40-5" href="#__codelineno-40-5"></a><span class="c"> */</span>
|
||
<a id="__codelineno-40-6" name="__codelineno-40-6" href="#__codelineno-40-6"></a>
|
||
<a id="__codelineno-40-7" name="__codelineno-40-7" href="#__codelineno-40-7"></a><span class="c">/* === Import shared styles (if needed) === */</span>
|
||
<a id="__codelineno-40-8" name="__codelineno-40-8" href="#__codelineno-40-8"></a><span class="c">/* Not required if loaded in HTML */</span>
|
||
<a id="__codelineno-40-9" name="__codelineno-40-9" href="#__codelineno-40-9"></a>
|
||
<a id="__codelineno-40-10" name="__codelineno-40-10" href="#__codelineno-40-10"></a><span class="c">/* === Page-specific variables (if needed) === */</span>
|
||
<a id="__codelineno-40-11" name="__codelineno-40-11" href="#__codelineno-40-11"></a><span class="p">:</span><span class="nd">root</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-40-12" name="__codelineno-40-12" href="#__codelineno-40-12"></a><span class="w"> </span><span class="nv">--page-specific-var</span><span class="p">:</span><span class="w"> </span><span class="n">value</span><span class="p">;</span>
|
||
<a id="__codelineno-40-13" name="__codelineno-40-13" href="#__codelineno-40-13"></a><span class="p">}</span>
|
||
<a id="__codelineno-40-14" name="__codelineno-40-14" href="#__codelineno-40-14"></a>
|
||
<a id="__codelineno-40-15" name="__codelineno-40-15" href="#__codelineno-40-15"></a><span class="c">/* === Layout === */</span>
|
||
<a id="__codelineno-40-16" name="__codelineno-40-16" href="#__codelineno-40-16"></a><span class="p">.</span><span class="nc">module-page-container</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-40-17" name="__codelineno-40-17" href="#__codelineno-40-17"></a><span class="w"> </span><span class="c">/* Layout styles */</span>
|
||
<a id="__codelineno-40-18" name="__codelineno-40-18" href="#__codelineno-40-18"></a><span class="p">}</span>
|
||
<a id="__codelineno-40-19" name="__codelineno-40-19" href="#__codelineno-40-19"></a>
|
||
<a id="__codelineno-40-20" name="__codelineno-40-20" href="#__codelineno-40-20"></a><span class="c">/* === Components === */</span>
|
||
<a id="__codelineno-40-21" name="__codelineno-40-21" href="#__codelineno-40-21"></a><span class="p">.</span><span class="nc">module-component</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-40-22" name="__codelineno-40-22" href="#__codelineno-40-22"></a><span class="w"> </span><span class="c">/* Component styles */</span>
|
||
<a id="__codelineno-40-23" name="__codelineno-40-23" href="#__codelineno-40-23"></a><span class="p">}</span>
|
||
<a id="__codelineno-40-24" name="__codelineno-40-24" href="#__codelineno-40-24"></a>
|
||
<a id="__codelineno-40-25" name="__codelineno-40-25" href="#__codelineno-40-25"></a><span class="c">/* === Responsive === */</span>
|
||
<a id="__codelineno-40-26" name="__codelineno-40-26" href="#__codelineno-40-26"></a><span class="p">@</span><span class="k">media</span><span class="w"> </span><span class="o">(</span><span class="nt">max-width</span><span class="o">:</span><span class="w"> </span><span class="nt">768px</span><span class="o">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-40-27" name="__codelineno-40-27" href="#__codelineno-40-27"></a><span class="w"> </span><span class="c">/* Mobile styles */</span>
|
||
<a id="__codelineno-40-28" name="__codelineno-40-28" href="#__codelineno-40-28"></a><span class="p">}</span>
|
||
<a id="__codelineno-40-29" name="__codelineno-40-29" href="#__codelineno-40-29"></a>
|
||
<a id="__codelineno-40-30" name="__codelineno-40-30" href="#__codelineno-40-30"></a><span class="c">/* === Dark Mode Overrides === */</span>
|
||
<a id="__codelineno-40-31" name="__codelineno-40-31" href="#__codelineno-40-31"></a><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="s2">"dark"</span><span class="o">]</span><span class="w"> </span><span class="p">.</span><span class="nc">module-component</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-40-32" name="__codelineno-40-32" href="#__codelineno-40-32"></a><span class="w"> </span><span class="c">/* Dark mode specific */</span>
|
||
<a id="__codelineno-40-33" name="__codelineno-40-33" href="#__codelineno-40-33"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h3 id="css-best-practices">CSS Best Practices<a class="headerlink" href="#css-best-practices" title="Permanent link">¶</a></h3>
|
||
<h4 id="1-toujours-utiliser-les-variables-css">1. TOUJOURS utiliser les variables CSS<a class="headerlink" href="#1-toujours-utiliser-les-variables-css" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="c">/* ❌ INCORRECT */</span>
|
||
<a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a><span class="p">.</span><span class="nc">my-card</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a><span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="mh">#12121a</span><span class="p">;</span>
|
||
<a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a><span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="mh">#fafafa</span><span class="p">;</span>
|
||
<a id="__codelineno-41-5" name="__codelineno-41-5" href="#__codelineno-41-5"></a><span class="p">}</span>
|
||
<a id="__codelineno-41-6" name="__codelineno-41-6" href="#__codelineno-41-6"></a>
|
||
<a id="__codelineno-41-7" name="__codelineno-41-7" href="#__codelineno-41-7"></a><span class="c">/* ✅ CORRECT */</span>
|
||
<a id="__codelineno-41-8" name="__codelineno-41-8" href="#__codelineno-41-8"></a><span class="p">.</span><span class="nc">my-card</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-41-9" name="__codelineno-41-9" href="#__codelineno-41-9"></a><span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-bg-card</span><span class="p">);</span>
|
||
<a id="__codelineno-41-10" name="__codelineno-41-10" href="#__codelineno-41-10"></a><span class="w"> </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-text-primary</span><span class="p">);</span>
|
||
<a id="__codelineno-41-11" name="__codelineno-41-11" href="#__codelineno-41-11"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h4 id="2-prefix-classes-par-module">2. Prefix classes par module<a class="headerlink" href="#2-prefix-classes-par-module" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="c">/* System Hub */</span>
|
||
<a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a><span class="p">.</span><span class="nc">sh-page-header</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a><span class="p">.</span><span class="nc">sh-card</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a><span class="p">.</span><span class="nc">sh-btn</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-5" name="__codelineno-42-5" href="#__codelineno-42-5"></a>
|
||
<a id="__codelineno-42-6" name="__codelineno-42-6" href="#__codelineno-42-6"></a><span class="c">/* SecuBox */</span>
|
||
<a id="__codelineno-42-7" name="__codelineno-42-7" href="#__codelineno-42-7"></a><span class="p">.</span><span class="nc">sb-module-grid</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-8" name="__codelineno-42-8" href="#__codelineno-42-8"></a><span class="p">.</span><span class="nc">sb-dashboard</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-9" name="__codelineno-42-9" href="#__codelineno-42-9"></a>
|
||
<a id="__codelineno-42-10" name="__codelineno-42-10" href="#__codelineno-42-10"></a><span class="c">/* Module spécifique */</span>
|
||
<a id="__codelineno-42-11" name="__codelineno-42-11" href="#__codelineno-42-11"></a><span class="p">.</span><span class="nc">netdata-chart</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-42-12" name="__codelineno-42-12" href="#__codelineno-42-12"></a><span class="p">.</span><span class="nc">crowdsec-alert</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h4 id="3-transitions-coherentes">3. Transitions cohérentes<a class="headerlink" href="#3-transitions-coherentes" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="c">/* Standard transition */</span>
|
||
<a id="__codelineno-43-2" name="__codelineno-43-2" href="#__codelineno-43-2"></a><span class="nt">transition</span><span class="o">:</span><span class="w"> </span><span class="nt">all</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">3s</span><span class="w"> </span><span class="nt">cubic-bezier</span><span class="o">(</span><span class="nt">0</span><span class="p">.</span><span class="nc">4</span><span class="o">,</span><span class="w"> </span><span class="nt">0</span><span class="o">,</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">2</span><span class="o">,</span><span class="w"> </span><span class="nt">1</span><span class="o">);</span>
|
||
<a id="__codelineno-43-3" name="__codelineno-43-3" href="#__codelineno-43-3"></a>
|
||
<a id="__codelineno-43-4" name="__codelineno-43-4" href="#__codelineno-43-4"></a><span class="c">/* Quick transition (hover states) */</span>
|
||
<a id="__codelineno-43-5" name="__codelineno-43-5" href="#__codelineno-43-5"></a><span class="nt">transition</span><span class="o">:</span><span class="w"> </span><span class="nt">all</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">2s</span><span class="w"> </span><span class="nt">ease</span><span class="o">;</span>
|
||
<a id="__codelineno-43-6" name="__codelineno-43-6" href="#__codelineno-43-6"></a>
|
||
<a id="__codelineno-43-7" name="__codelineno-43-7" href="#__codelineno-43-7"></a><span class="c">/* Smooth transition (large movements) */</span>
|
||
<a id="__codelineno-43-8" name="__codelineno-43-8" href="#__codelineno-43-8"></a><span class="nt">transition</span><span class="o">:</span><span class="w"> </span><span class="nt">all</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">5s</span><span class="w"> </span><span class="nt">ease</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<h4 id="4-responsive-breakpoints">4. Responsive breakpoints<a class="headerlink" href="#4-responsive-breakpoints" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a><span class="c">/* Mobile */</span>
|
||
<a id="__codelineno-44-2" name="__codelineno-44-2" href="#__codelineno-44-2"></a><span class="p">@</span><span class="k">media</span><span class="w"> </span><span class="o">(</span><span class="nt">max-width</span><span class="o">:</span><span class="w"> </span><span class="nt">768px</span><span class="o">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-44-3" name="__codelineno-44-3" href="#__codelineno-44-3"></a><span class="w"> </span><span class="p">.</span><span class="nc">sh-stats-grid</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-44-4" name="__codelineno-44-4" href="#__codelineno-44-4"></a><span class="w"> </span><span class="k">grid-template-columns</span><span class="p">:</span><span class="w"> </span><span class="nf">repeat</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="n">fr</span><span class="p">);</span>
|
||
<a id="__codelineno-44-5" name="__codelineno-44-5" href="#__codelineno-44-5"></a><span class="w"> </span><span class="p">}</span>
|
||
<a id="__codelineno-44-6" name="__codelineno-44-6" href="#__codelineno-44-6"></a><span class="p">}</span>
|
||
<a id="__codelineno-44-7" name="__codelineno-44-7" href="#__codelineno-44-7"></a>
|
||
<a id="__codelineno-44-8" name="__codelineno-44-8" href="#__codelineno-44-8"></a><span class="c">/* Tablet */</span>
|
||
<a id="__codelineno-44-9" name="__codelineno-44-9" href="#__codelineno-44-9"></a><span class="p">@</span><span class="k">media</span><span class="w"> </span><span class="o">(</span><span class="nt">min-width</span><span class="o">:</span><span class="w"> </span><span class="nt">769px</span><span class="o">)</span><span class="w"> </span><span class="nt">and</span><span class="w"> </span><span class="o">(</span><span class="nt">max-width</span><span class="o">:</span><span class="w"> </span><span class="nt">1024px</span><span class="o">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-44-10" name="__codelineno-44-10" href="#__codelineno-44-10"></a><span class="w"> </span><span class="c">/* Tablet specific */</span>
|
||
<a id="__codelineno-44-11" name="__codelineno-44-11" href="#__codelineno-44-11"></a><span class="p">}</span>
|
||
<a id="__codelineno-44-12" name="__codelineno-44-12" href="#__codelineno-44-12"></a>
|
||
<a id="__codelineno-44-13" name="__codelineno-44-13" href="#__codelineno-44-13"></a><span class="c">/* Desktop */</span>
|
||
<a id="__codelineno-44-14" name="__codelineno-44-14" href="#__codelineno-44-14"></a><span class="p">@</span><span class="k">media</span><span class="w"> </span><span class="o">(</span><span class="nt">min-width</span><span class="o">:</span><span class="w"> </span><span class="nt">1025px</span><span class="o">)</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-44-15" name="__codelineno-44-15" href="#__codelineno-44-15"></a><span class="w"> </span><span class="c">/* Desktop specific */</span>
|
||
<a id="__codelineno-44-16" name="__codelineno-44-16" href="#__codelineno-44-16"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h4 id="5-dark-mode-obligatoire">5. Dark mode OBLIGATOIRE<a class="headerlink" href="#5-dark-mode-obligatoire" title="Permanent link">¶</a></h4>
|
||
<p><strong>Toujours fournir des styles dark mode:</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a><span class="c">/* Light mode (default) */</span>
|
||
<a id="__codelineno-45-2" name="__codelineno-45-2" href="#__codelineno-45-2"></a><span class="p">.</span><span class="nc">my-component</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-45-3" name="__codelineno-45-3" href="#__codelineno-45-3"></a><span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-bg-card</span><span class="p">);</span>
|
||
<a id="__codelineno-45-4" name="__codelineno-45-4" href="#__codelineno-45-4"></a><span class="w"> </span><span class="k">border</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">px</span><span class="w"> </span><span class="kc">solid</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-border</span><span class="p">);</span>
|
||
<a id="__codelineno-45-5" name="__codelineno-45-5" href="#__codelineno-45-5"></a><span class="p">}</span>
|
||
<a id="__codelineno-45-6" name="__codelineno-45-6" href="#__codelineno-45-6"></a>
|
||
<a id="__codelineno-45-7" name="__codelineno-45-7" href="#__codelineno-45-7"></a><span class="c">/* Dark mode override */</span>
|
||
<a id="__codelineno-45-8" name="__codelineno-45-8" href="#__codelineno-45-8"></a><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="s2">"dark"</span><span class="o">]</span><span class="w"> </span><span class="p">.</span><span class="nc">my-component</span><span class="w"> </span><span class="p">{</span>
|
||
<a id="__codelineno-45-9" name="__codelineno-45-9" href="#__codelineno-45-9"></a><span class="w"> </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-bg-card</span><span class="p">);</span>
|
||
<a id="__codelineno-45-10" name="__codelineno-45-10" href="#__codelineno-45-10"></a><span class="w"> </span><span class="k">border-color</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--sh-border</span><span class="p">);</span>
|
||
<a id="__codelineno-45-11" name="__codelineno-45-11" href="#__codelineno-45-11"></a><span class="p">}</span>
|
||
</code></pre></div>
|
||
<h3 id="z-index-scale">Z-index Scale<a class="headerlink" href="#z-index-scale" title="Permanent link">¶</a></h3>
|
||
<p><strong>Respecter cette échelle:</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a><span class="nt">--z-base</span><span class="o">:</span><span class="w"> </span><span class="nt">0</span><span class="o">;</span>
|
||
<a id="__codelineno-46-2" name="__codelineno-46-2" href="#__codelineno-46-2"></a><span class="nt">--z-dropdown</span><span class="o">:</span><span class="w"> </span><span class="nt">100</span><span class="o">;</span>
|
||
<a id="__codelineno-46-3" name="__codelineno-46-3" href="#__codelineno-46-3"></a><span class="nt">--z-sticky</span><span class="o">:</span><span class="w"> </span><span class="nt">200</span><span class="o">;</span>
|
||
<a id="__codelineno-46-4" name="__codelineno-46-4" href="#__codelineno-46-4"></a><span class="nt">--z-fixed</span><span class="o">:</span><span class="w"> </span><span class="nt">300</span><span class="o">;</span>
|
||
<a id="__codelineno-46-5" name="__codelineno-46-5" href="#__codelineno-46-5"></a><span class="nt">--z-modal-backdrop</span><span class="o">:</span><span class="w"> </span><span class="nt">400</span><span class="o">;</span>
|
||
<a id="__codelineno-46-6" name="__codelineno-46-6" href="#__codelineno-46-6"></a><span class="nt">--z-modal</span><span class="o">:</span><span class="w"> </span><span class="nt">500</span><span class="o">;</span>
|
||
<a id="__codelineno-46-7" name="__codelineno-46-7" href="#__codelineno-46-7"></a><span class="nt">--z-popover</span><span class="o">:</span><span class="w"> </span><span class="nt">600</span><span class="o">;</span>
|
||
<a id="__codelineno-46-8" name="__codelineno-46-8" href="#__codelineno-46-8"></a><span class="nt">--z-tooltip</span><span class="o">:</span><span class="w"> </span><span class="nt">700</span><span class="o">;</span>
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="common-errors-solutions">Common Errors & Solutions<a class="headerlink" href="#common-errors-solutions" title="Permanent link">¶</a></h2>
|
||
<h3 id="1-rpcd-object-not-found-32000">1. RPCD Object Not Found (-32000)<a class="headerlink" href="#1-rpcd-object-not-found-32000" title="Permanent link">¶</a></h3>
|
||
<p><strong>Erreur complète:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a>RPC call to luci.system-hub/getHealth failed with error -32000: Object not found
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a><span class="c1"># 1. Vérifier que le fichier RPCD existe</span>
|
||
<a id="__codelineno-48-2" name="__codelineno-48-2" href="#__codelineno-48-2"></a>ls<span class="w"> </span>-la<span class="w"> </span>/usr/libexec/rpcd/luci.system-hub
|
||
<a id="__codelineno-48-3" name="__codelineno-48-3" href="#__codelineno-48-3"></a>
|
||
<a id="__codelineno-48-4" name="__codelineno-48-4" href="#__codelineno-48-4"></a><span class="c1"># 2. Vérifier qu'il est exécutable</span>
|
||
<a id="__codelineno-48-5" name="__codelineno-48-5" href="#__codelineno-48-5"></a>chmod<span class="w"> </span>+x<span class="w"> </span>/usr/libexec/rpcd/luci.system-hub
|
||
<a id="__codelineno-48-6" name="__codelineno-48-6" href="#__codelineno-48-6"></a>
|
||
<a id="__codelineno-48-7" name="__codelineno-48-7" href="#__codelineno-48-7"></a><span class="c1"># 3. Lister les objets ubus</span>
|
||
<a id="__codelineno-48-8" name="__codelineno-48-8" href="#__codelineno-48-8"></a>ubus<span class="w"> </span>list<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>system-hub
|
||
<a id="__codelineno-48-9" name="__codelineno-48-9" href="#__codelineno-48-9"></a>
|
||
<a id="__codelineno-48-10" name="__codelineno-48-10" href="#__codelineno-48-10"></a><span class="c1"># 4. Si absent, redémarrer RPCD</span>
|
||
<a id="__codelineno-48-11" name="__codelineno-48-11" href="#__codelineno-48-11"></a>/etc/init.d/rpcd<span class="w"> </span>restart
|
||
<a id="__codelineno-48-12" name="__codelineno-48-12" href="#__codelineno-48-12"></a>ubus<span class="w"> </span>list<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>system-hub
|
||
</code></pre></div></p>
|
||
<p><strong>Solutions:</strong>
|
||
1. Renommer le fichier RPCD pour correspondre exactement
|
||
2. Vérifier permissions (755 ou rwxr-xr-x)
|
||
3. Redémarrer rpcd</p>
|
||
<h3 id="2-view-not-found-404">2. View Not Found (404)<a class="headerlink" href="#2-view-not-found-404" title="Permanent link">¶</a></h3>
|
||
<p><strong>Erreur:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a>HTTP error 404 while loading class file '/luci-static/resources/view/system-hub/overview.js'
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-50-1" name="__codelineno-50-1" href="#__codelineno-50-1"></a><span class="c1"># 1. Vérifier que le fichier existe</span>
|
||
<a id="__codelineno-50-2" name="__codelineno-50-2" href="#__codelineno-50-2"></a>ls<span class="w"> </span>-la<span class="w"> </span>/www/luci-static/resources/view/system-hub/overview.js
|
||
<a id="__codelineno-50-3" name="__codelineno-50-3" href="#__codelineno-50-3"></a>
|
||
<a id="__codelineno-50-4" name="__codelineno-50-4" href="#__codelineno-50-4"></a><span class="c1"># 2. Vérifier le chemin dans menu.d</span>
|
||
<a id="__codelineno-50-5" name="__codelineno-50-5" href="#__codelineno-50-5"></a>grep<span class="w"> </span><span class="s2">"path"</span><span class="w"> </span>/usr/share/luci/menu.d/luci-app-system-hub.json
|
||
</code></pre></div></p>
|
||
<p><strong>Solutions:</strong>
|
||
1. Vérifier que le path dans menu JSON correspond au fichier
|
||
2. Vérifier permissions du fichier (644)
|
||
3. Nettoyer cache: <code>rm -f /tmp/luci-indexcache /tmp/luci-modulecache/*</code></p>
|
||
<h3 id="3-css-not-loading-403-forbidden">3. CSS Not Loading (403 Forbidden)<a class="headerlink" href="#3-css-not-loading-403-forbidden" title="Permanent link">¶</a></h3>
|
||
<p><strong>Erreur:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-51-1" name="__codelineno-51-1" href="#__codelineno-51-1"></a>GET /luci-static/resources/system-hub/common.css 403 Forbidden
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-52-1" name="__codelineno-52-1" href="#__codelineno-52-1"></a><span class="c1"># Vérifier permissions</span>
|
||
<a id="__codelineno-52-2" name="__codelineno-52-2" href="#__codelineno-52-2"></a>ls<span class="w"> </span>-la<span class="w"> </span>/www/luci-static/resources/system-hub/common.css
|
||
</code></pre></div></p>
|
||
<p><strong>Solution:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-53-1" name="__codelineno-53-1" href="#__codelineno-53-1"></a><span class="c1"># Corriger permissions</span>
|
||
<a id="__codelineno-53-2" name="__codelineno-53-2" href="#__codelineno-53-2"></a>chmod<span class="w"> </span><span class="m">644</span><span class="w"> </span>/www/luci-static/resources/system-hub/*.css
|
||
</code></pre></div></p>
|
||
<h3 id="4-invalid-json-from-rpcd">4. Invalid JSON from RPCD<a class="headerlink" href="#4-invalid-json-from-rpcd" title="Permanent link">¶</a></h3>
|
||
<p><strong>Erreur dans browser console:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-54-1" name="__codelineno-54-1" href="#__codelineno-54-1"></a>SyntaxError: Unexpected token in JSON at position X
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-55-1" name="__codelineno-55-1" href="#__codelineno-55-1"></a><span class="c1"># Tester le JSON directement</span>
|
||
<a id="__codelineno-55-2" name="__codelineno-55-2" href="#__codelineno-55-2"></a>/usr/libexec/rpcd/luci.system-hub<span class="w"> </span>call<span class="w"> </span>getHealth<span class="w"> </span><span class="p">|</span><span class="w"> </span>jsonlint
|
||
<a id="__codelineno-55-3" name="__codelineno-55-3" href="#__codelineno-55-3"></a>
|
||
<a id="__codelineno-55-4" name="__codelineno-55-4" href="#__codelineno-55-4"></a><span class="c1"># Ou avec jq</span>
|
||
<a id="__codelineno-55-5" name="__codelineno-55-5" href="#__codelineno-55-5"></a>/usr/libexec/rpcd/luci.system-hub<span class="w"> </span>call<span class="w"> </span>getHealth<span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span>.
|
||
</code></pre></div></p>
|
||
<p><strong>Solutions courantes:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-56-1" name="__codelineno-56-1" href="#__codelineno-56-1"></a><span class="c1"># ❌ INCORRECT - Quote simple non échappée</span>
|
||
<a id="__codelineno-56-2" name="__codelineno-56-2" href="#__codelineno-56-2"></a><span class="nb">echo</span><span class="w"> </span><span class="s1">'{"error": "can'</span>t<span class="w"> </span>process<span class="s2">"}'</span>
|
||
<a id="__codelineno-56-3" name="__codelineno-56-3" href="#__codelineno-56-3"></a>
|
||
<a id="__codelineno-56-4" name="__codelineno-56-4" href="#__codelineno-56-4"></a><span class="s2"># ✅ CORRECT - Utiliser printf et doubles quotes</span>
|
||
<a id="__codelineno-56-5" name="__codelineno-56-5" href="#__codelineno-56-5"></a><span class="s2">printf '{"</span>error<span class="s2">": "</span>cannot<span class="w"> </span>process<span class="s2">"}\n'</span>
|
||
<a id="__codelineno-56-6" name="__codelineno-56-6" href="#__codelineno-56-6"></a>
|
||
<a id="__codelineno-56-7" name="__codelineno-56-7" href="#__codelineno-56-7"></a><span class="s2"># ❌ INCORRECT - Variable non quotée</span>
|
||
<a id="__codelineno-56-8" name="__codelineno-56-8" href="#__codelineno-56-8"></a><span class="s2">echo "</span><span class="o">{</span><span class="se">\"</span>value<span class="se">\"</span>:<span class="w"> </span><span class="nv">$var</span><span class="o">}</span><span class="s2">"</span>
|
||
<a id="__codelineno-56-9" name="__codelineno-56-9" href="#__codelineno-56-9"></a>
|
||
<a id="__codelineno-56-10" name="__codelineno-56-10" href="#__codelineno-56-10"></a><span class="s2"># ✅ CORRECT - Variable quotée</span>
|
||
<a id="__codelineno-56-11" name="__codelineno-56-11" href="#__codelineno-56-11"></a><span class="s2">printf '{"</span>value<span class="s2">": "</span>%s<span class="s2">"}\n' "</span><span class="nv">$var</span><span class="s2">"</span>
|
||
</code></pre></div></p>
|
||
<h3 id="5-browser-cache-issues">5. Browser Cache Issues<a class="headerlink" href="#5-browser-cache-issues" title="Permanent link">¶</a></h3>
|
||
<p><strong>Symptômes:</strong>
|
||
- Changements CSS/JS non visibles
|
||
- Anciennes données affichées
|
||
- Code mis à jour mais interface identique</p>
|
||
<p><strong>Solutions:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-57-1" name="__codelineno-57-1" href="#__codelineno-57-1"></a><span class="c1"># 1. Côté serveur - nettoyer cache LuCI</span>
|
||
<a id="__codelineno-57-2" name="__codelineno-57-2" href="#__codelineno-57-2"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"rm -f /tmp/luci-indexcache /tmp/luci-modulecache/* && /etc/init.d/uhttpd restart"</span>
|
||
<a id="__codelineno-57-3" name="__codelineno-57-3" href="#__codelineno-57-3"></a>
|
||
<a id="__codelineno-57-4" name="__codelineno-57-4" href="#__codelineno-57-4"></a><span class="c1"># 2. Côté client - hard refresh</span>
|
||
<a id="__codelineno-57-5" name="__codelineno-57-5" href="#__codelineno-57-5"></a>Ctrl<span class="w"> </span>+<span class="w"> </span>Shift<span class="w"> </span>+<span class="w"> </span>R<span class="w"> </span><span class="o">(</span>Chrome/Firefox<span class="o">)</span>
|
||
<a id="__codelineno-57-6" name="__codelineno-57-6" href="#__codelineno-57-6"></a>Ctrl<span class="w"> </span>+<span class="w"> </span>F5<span class="w"> </span><span class="o">(</span>Windows<span class="o">)</span>
|
||
<a id="__codelineno-57-7" name="__codelineno-57-7" href="#__codelineno-57-7"></a>Cmd<span class="w"> </span>+<span class="w"> </span>Shift<span class="w"> </span>+<span class="w"> </span>R<span class="w"> </span><span class="o">(</span>Mac<span class="o">)</span>
|
||
<a id="__codelineno-57-8" name="__codelineno-57-8" href="#__codelineno-57-8"></a>
|
||
<a id="__codelineno-57-9" name="__codelineno-57-9" href="#__codelineno-57-9"></a><span class="c1"># 3. Mode privé/incognito pour test</span>
|
||
<a id="__codelineno-57-10" name="__codelineno-57-10" href="#__codelineno-57-10"></a>Ctrl<span class="w"> </span>+<span class="w"> </span>Shift<span class="w"> </span>+<span class="w"> </span>N<span class="w"> </span><span class="o">(</span>Chrome<span class="o">)</span>
|
||
<a id="__codelineno-57-11" name="__codelineno-57-11" href="#__codelineno-57-11"></a>Ctrl<span class="w"> </span>+<span class="w"> </span>Shift<span class="w"> </span>+<span class="w"> </span>P<span class="w"> </span><span class="o">(</span>Firefox<span class="o">)</span>
|
||
</code></pre></div></p>
|
||
<h3 id="6-acl-access-denied">6. ACL Access Denied<a class="headerlink" href="#6-acl-access-denied" title="Permanent link">¶</a></h3>
|
||
<p><strong>Erreur:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-58-1" name="__codelineno-58-1" href="#__codelineno-58-1"></a>Access to path '/admin/secubox/system/system-hub' denied
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-59-1" name="__codelineno-59-1" href="#__codelineno-59-1"></a><span class="c1"># Vérifier ACL</span>
|
||
<a id="__codelineno-59-2" name="__codelineno-59-2" href="#__codelineno-59-2"></a>cat<span class="w"> </span>/usr/share/rpcd/acl.d/luci-app-system-hub.json<span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span>.
|
||
<a id="__codelineno-59-3" name="__codelineno-59-3" href="#__codelineno-59-3"></a>
|
||
<a id="__codelineno-59-4" name="__codelineno-59-4" href="#__codelineno-59-4"></a><span class="c1"># Vérifier que méthodes ubus sont listées</span>
|
||
<a id="__codelineno-59-5" name="__codelineno-59-5" href="#__codelineno-59-5"></a>grep<span class="w"> </span><span class="s2">"getHealth"</span><span class="w"> </span>/usr/share/rpcd/acl.d/luci-app-system-hub.json
|
||
</code></pre></div></p>
|
||
<p><strong>Solution:</strong>
|
||
Ajouter la méthode manquante dans ACL et redémarrer rpcd.</p>
|
||
<hr />
|
||
<h2 id="validation-checklist">Validation Checklist<a class="headerlink" href="#validation-checklist" title="Permanent link">¶</a></h2>
|
||
<h3 id="pre-commit-checklist">Pre-Commit Checklist<a class="headerlink" href="#pre-commit-checklist" title="Permanent link">¶</a></h3>
|
||
<p>Avant chaque commit, vérifier:</p>
|
||
<ul class="task-list">
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>RPCD Script:</strong></li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Nom fichier correspond à objet ubus</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Exécutable (chmod +x)</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Structure list/call correcte</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Retourne JSON valide</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Toutes méthodes implémentées</p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Menu & ACL:</strong></p>
|
||
</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Path menu correspond au fichier vue</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> ACL liste toutes les méthodes ubus</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> JSON valide (jsonlint)</p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>JavaScript:</strong></p>
|
||
</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> 'use strict' en première ligne</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Imports requis présents</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Pas de console.log en prod</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Gestion d'erreur sur API calls</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Event handlers bindés correctement</p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>CSS:</strong></p>
|
||
</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Variables CSS utilisées (pas de hardcode)</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Classes prefixées (sh-, sb-, module-)</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Dark mode supporté</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Responsive (max-width: 768px)</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Transitions cohérentes</p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Makefile:</strong></p>
|
||
</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> PKG_VERSION incrémenté</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> LUCI_DEPENDS correct</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Include path correct (../../luci.mk)</li>
|
||
</ul>
|
||
<h3 id="pre-deploy-checklist">Pre-Deploy Checklist<a class="headerlink" href="#pre-deploy-checklist" title="Permanent link">¶</a></h3>
|
||
<p>Avant déploiement sur routeur:</p>
|
||
<ul class="task-list">
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Validation scripts:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-60-1" name="__codelineno-60-1" href="#__codelineno-60-1"></a>./secubox-tools/validate-modules.sh
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Test RPCD local:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-61-1" name="__codelineno-61-1" href="#__codelineno-61-1"></a>/usr/libexec/rpcd/luci.module-name<span class="w"> </span>list
|
||
<a id="__codelineno-61-2" name="__codelineno-61-2" href="#__codelineno-61-2"></a>/usr/libexec/rpcd/luci.module-name<span class="w"> </span>call<span class="w"> </span>getStatus
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Test JSON:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-62-1" name="__codelineno-62-1" href="#__codelineno-62-1"></a>find<span class="w"> </span>.<span class="w"> </span>-name<span class="w"> </span><span class="s2">"*.json"</span><span class="w"> </span>-exec<span class="w"> </span>jsonlint<span class="w"> </span><span class="o">{}</span><span class="w"> </span><span class="se">\;</span>
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Shellcheck:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-63-1" name="__codelineno-63-1" href="#__codelineno-63-1"></a>shellcheck<span class="w"> </span>root/usr/libexec/rpcd/*
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Permissions:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-64-1" name="__codelineno-64-1" href="#__codelineno-64-1"></a><span class="c1"># RPCD scripts</span>
|
||
<a id="__codelineno-64-2" name="__codelineno-64-2" href="#__codelineno-64-2"></a>chmod<span class="w"> </span><span class="m">755</span><span class="w"> </span>root/usr/libexec/rpcd/*
|
||
<a id="__codelineno-64-3" name="__codelineno-64-3" href="#__codelineno-64-3"></a>
|
||
<a id="__codelineno-64-4" name="__codelineno-64-4" href="#__codelineno-64-4"></a><span class="c1"># CSS/JS files</span>
|
||
<a id="__codelineno-64-5" name="__codelineno-64-5" href="#__codelineno-64-5"></a>chmod<span class="w"> </span><span class="m">644</span><span class="w"> </span>htdocs/luci-static/resources/**/*
|
||
</code></pre></div></p>
|
||
</li>
|
||
</ul>
|
||
<h3 id="post-deploy-checklist">Post-Deploy Checklist<a class="headerlink" href="#post-deploy-checklist" title="Permanent link">¶</a></h3>
|
||
<p>Après déploiement:</p>
|
||
<ul class="task-list">
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Services:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-65-1" name="__codelineno-65-1" href="#__codelineno-65-1"></a>/etc/init.d/rpcd<span class="w"> </span>status
|
||
<a id="__codelineno-65-2" name="__codelineno-65-2" href="#__codelineno-65-2"></a>/etc/init.d/uhttpd<span class="w"> </span>status
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>ubus objects:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-66-1" name="__codelineno-66-1" href="#__codelineno-66-1"></a>ubus<span class="w"> </span>list<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>luci.module-name
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Fichiers présents:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-67-1" name="__codelineno-67-1" href="#__codelineno-67-1"></a>ls<span class="w"> </span>-la<span class="w"> </span>/www/luci-static/resources/view/module-name/
|
||
<a id="__codelineno-67-2" name="__codelineno-67-2" href="#__codelineno-67-2"></a>ls<span class="w"> </span>-la<span class="w"> </span>/www/luci-static/resources/module-name/
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Permissions correctes:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-68-1" name="__codelineno-68-1" href="#__codelineno-68-1"></a>ls<span class="w"> </span>-la<span class="w"> </span>/usr/libexec/rpcd/luci.module-name
|
||
<a id="__codelineno-68-2" name="__codelineno-68-2" href="#__codelineno-68-2"></a>ls<span class="w"> </span>-la<span class="w"> </span>/www/luci-static/resources/module-name/*.css
|
||
</code></pre></div></p>
|
||
</li>
|
||
<li class="task-list-item">
|
||
<p><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Test navigateur:</strong></p>
|
||
</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Ouvrir en mode privé</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Vérifier console (F12) - pas d'erreurs</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Vérifier Network tab - tous les fichiers chargent (200)</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Tester dark/light mode</li>
|
||
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> Tester responsive (mobile view)</li>
|
||
</ul>
|
||
<hr />
|
||
<h2 id="deployment-procedures">Deployment Procedures<a class="headerlink" href="#deployment-procedures" title="Permanent link">¶</a></h2>
|
||
<h3 id="deployment-workflow">Deployment Workflow<a class="headerlink" href="#deployment-workflow" title="Permanent link">¶</a></h3>
|
||
<p>The following flowchart illustrates the complete deployment process with validation checkpoints:</p>
|
||
<pre class="mermaid"><code>flowchart TD
|
||
START([Start Deployment]) --> LOCAL_VAL{Local Validation<br/>Passed?}
|
||
LOCAL_VAL -->|No| FIX_LOCAL[Fix Issues Locally]
|
||
FIX_LOCAL --> LOCAL_VAL
|
||
LOCAL_VAL -->|Yes| CHECK_DISK{Disk Space<br/>< 90%?}
|
||
|
||
CHECK_DISK -->|No| CLEAN_DISK[Clean Temp Files<br/>& Old Backups]
|
||
CLEAN_DISK --> CHECK_DISK
|
||
CHECK_DISK -->|Yes| FIX_PERM_LOCAL[Fix Permissions<br/>Local Source]
|
||
|
||
FIX_PERM_LOCAL --> COPY[Copy Files to Router<br/>scp JS/CSS/RPCD]
|
||
COPY --> FIX_PERM_REMOTE[Fix Permissions<br/>Remote Files<br/>755 RPCD / 644 CSS-JS]
|
||
FIX_PERM_REMOTE --> CLEAR[Clear LuCI Cache<br/>/tmp/luci-*]
|
||
CLEAR --> RESTART[Restart Services<br/>rpcd + uhttpd]
|
||
|
||
RESTART --> V1{ubus Object<br/>Available?}
|
||
V1 -->|No| DEBUG1[Debug RPCD Script<br/>Check naming & permissions]
|
||
DEBUG1 --> FIX_PERM_REMOTE
|
||
|
||
V1 -->|Yes| V2{Files<br/>Accessible?}
|
||
V2 -->|403 Error| DEBUG2[Fix File Permissions<br/>chmod 644]
|
||
DEBUG2 --> FIX_PERM_REMOTE
|
||
|
||
V2 -->|Yes| V3{Menu Path<br/>Matches View?}
|
||
V3 -->|404 Error| DEBUG3[Fix Menu JSON Path]
|
||
DEBUG3 --> COPY
|
||
|
||
V3 -->|Yes| V4{UI Loads<br/>Correctly?}
|
||
V4 -->|Errors| DEBUG4[Check Browser Console<br/>Fix JavaScript Errors]
|
||
DEBUG4 --> COPY
|
||
|
||
V4 -->|Yes| TEST[Browser Testing<br/>Private Mode<br/>Dark/Light Mode<br/>Responsive]
|
||
TEST --> SUCCESS([✅ Deployment Success])
|
||
|
||
style START fill:#6366f1,color:#fff,stroke:#4f46e5
|
||
style SUCCESS fill:#22c55e,color:#fff,stroke:#16a34a
|
||
style DEBUG1 fill:#ef4444,color:#fff,stroke:#dc2626
|
||
style DEBUG2 fill:#ef4444,color:#fff,stroke:#dc2626
|
||
style DEBUG3 fill:#ef4444,color:#fff,stroke:#dc2626
|
||
style DEBUG4 fill:#ef4444,color:#fff,stroke:#dc2626
|
||
style CHECK_DISK fill:#f59e0b,color:#fff,stroke:#d97706
|
||
style LOCAL_VAL fill:#8b5cf6,color:#fff,stroke:#7c3aed</code></pre>
|
||
<p><strong>Deployment Stages:</strong>
|
||
1. <strong>Local Validation:</strong> Run <code>validate-modules.sh</code> and <code>fix-permissions.sh --local</code>
|
||
2. <strong>Pre-Flight Checks:</strong> Disk space and permission verification
|
||
3. <strong>File Transfer:</strong> Copy JavaScript, CSS, and RPCD scripts
|
||
4. <strong>Remote Setup:</strong> Fix permissions and clear caches
|
||
5. <strong>Service Restart:</strong> Reload rpcd and uhttpd daemons
|
||
6. <strong>Validation:</strong> Multi-stage verification (ubus, files, menu, UI)
|
||
7. <strong>Testing:</strong> Browser testing in private mode</p>
|
||
<p><strong>Common Error Recovery Paths:</strong>
|
||
- <strong>Object not found (-32000):</strong> Check RPCD script naming and permissions
|
||
- <strong>403 Forbidden:</strong> Fix file permissions to 644 for CSS/JS
|
||
- <strong>404 Not Found:</strong> Verify menu path matches view file location
|
||
- <strong>JavaScript errors:</strong> Check browser console and fix code issues</p>
|
||
<hr />
|
||
<h3 id="pre-deployment-checks-critical">⚠️ Pre-Deployment Checks (CRITICAL)<a class="headerlink" href="#pre-deployment-checks-critical" title="Permanent link">¶</a></h3>
|
||
<p><strong>TOUJOURS exécuter ces vérifications AVANT tout déploiement:</strong></p>
|
||
<h4 id="1-verification-de-lespace-disque">1. Vérification de l'Espace Disque<a class="headerlink" href="#1-verification-de-lespace-disque" title="Permanent link">¶</a></h4>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-69-1" name="__codelineno-69-1" href="#__codelineno-69-1"></a><span class="c1"># Sur le routeur cible</span>
|
||
<a id="__codelineno-69-2" name="__codelineno-69-2" href="#__codelineno-69-2"></a>ssh<span class="w"> </span>root@192.168.8.191<span class="w"> </span><span class="s2">"df -h | grep overlay"</span>
|
||
<a id="__codelineno-69-3" name="__codelineno-69-3" href="#__codelineno-69-3"></a>
|
||
<a id="__codelineno-69-4" name="__codelineno-69-4" href="#__codelineno-69-4"></a><span class="c1"># Vérifier que l'utilisation est < 90%</span>
|
||
<a id="__codelineno-69-5" name="__codelineno-69-5" href="#__codelineno-69-5"></a><span class="c1"># Exemple OK:</span>
|
||
<a id="__codelineno-69-6" name="__codelineno-69-6" href="#__codelineno-69-6"></a><span class="c1"># /dev/loop0 98.8M 45.2M 53.6M 46% /overlay</span>
|
||
<a id="__codelineno-69-7" name="__codelineno-69-7" href="#__codelineno-69-7"></a>
|
||
<a id="__codelineno-69-8" name="__codelineno-69-8" href="#__codelineno-69-8"></a><span class="c1"># Exemple CRITIQUE (STOP deployment):</span>
|
||
<a id="__codelineno-69-9" name="__codelineno-69-9" href="#__codelineno-69-9"></a><span class="c1"># /dev/loop0 98.8M 98.8M 0 100% /overlay ← PLEIN!</span>
|
||
</code></pre></div>
|
||
<p><strong>Si l'overlay est plein (≥95%):</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-70-1" name="__codelineno-70-1" href="#__codelineno-70-1"></a><span class="c1"># Libérer de l'espace avant déploiement</span>
|
||
<a id="__codelineno-70-2" name="__codelineno-70-2" href="#__codelineno-70-2"></a>ssh<span class="w"> </span>root@192.168.8.191<span class="w"> </span><span class="s"><< 'EOF'</span>
|
||
<a id="__codelineno-70-3" name="__codelineno-70-3" href="#__codelineno-70-3"></a><span class="s"># Supprimer fichiers temporaires</span>
|
||
<a id="__codelineno-70-4" name="__codelineno-70-4" href="#__codelineno-70-4"></a><span class="s">rm -rf /tmp/*.ipk /tmp/luci-* 2>/dev/null</span>
|
||
<a id="__codelineno-70-5" name="__codelineno-70-5" href="#__codelineno-70-5"></a>
|
||
<a id="__codelineno-70-6" name="__codelineno-70-6" href="#__codelineno-70-6"></a><span class="s"># Supprimer anciens backups (>7 jours)</span>
|
||
<a id="__codelineno-70-7" name="__codelineno-70-7" href="#__codelineno-70-7"></a><span class="s">find /root -name '*.backup-*' -type f -mtime +7 -delete 2>/dev/null</span>
|
||
<a id="__codelineno-70-8" name="__codelineno-70-8" href="#__codelineno-70-8"></a>
|
||
<a id="__codelineno-70-9" name="__codelineno-70-9" href="#__codelineno-70-9"></a><span class="s"># Vérifier packages inutilisés</span>
|
||
<a id="__codelineno-70-10" name="__codelineno-70-10" href="#__codelineno-70-10"></a><span class="s">opkg list-installed | grep -E 'netdata|unused'</span>
|
||
<a id="__codelineno-70-11" name="__codelineno-70-11" href="#__codelineno-70-11"></a>
|
||
<a id="__codelineno-70-12" name="__codelineno-70-12" href="#__codelineno-70-12"></a><span class="s"># Après nettoyage, vérifier l'espace libéré</span>
|
||
<a id="__codelineno-70-13" name="__codelineno-70-13" href="#__codelineno-70-13"></a><span class="s">df -h | grep overlay</span>
|
||
<a id="__codelineno-70-14" name="__codelineno-70-14" href="#__codelineno-70-14"></a><span class="s">EOF</span>
|
||
</code></pre></div></p>
|
||
<p><strong>Tailles typiques à surveiller:</strong>
|
||
- Netdata web UI: ~22MB (considérer suppression si non utilisé)
|
||
- Modules LuCI: ~1-2MB chacun
|
||
- Fichiers CSS/JS: ~10-50KB chacun</p>
|
||
<h4 id="2-verification-des-permissions-critique-pour-eviter-erreurs-403">2. Vérification des Permissions (Critique pour Éviter Erreurs 403)<a class="headerlink" href="#2-verification-des-permissions-critique-pour-eviter-erreurs-403" title="Permanent link">¶</a></h4>
|
||
<p><strong>Permissions OBLIGATOIRES:</strong></p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Permission</th>
|
||
<th>Octal</th>
|
||
<th>Raison</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>RPCD scripts</strong></td>
|
||
<td><code>rwxr-xr-x</code></td>
|
||
<td><code>755</code></td>
|
||
<td>Exécutable par system</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>CSS files</strong></td>
|
||
<td><code>rw-r--r--</code></td>
|
||
<td><code>644</code></td>
|
||
<td>Lecture web server</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>JS files</strong></td>
|
||
<td><code>rw-r--r--</code></td>
|
||
<td><code>644</code></td>
|
||
<td>Lecture web server</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>JSON files</strong></td>
|
||
<td><code>rw-r--r--</code></td>
|
||
<td><code>644</code></td>
|
||
<td>Lecture rpcd</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><strong>Erreur commune:</strong> Fichiers créés avec <code>600</code> (rw-------) au lieu de <code>644</code></p>
|
||
<p><strong>Symptôme:</strong> HTTP 403 Forbidden lors du chargement de fichiers JS/CSS</p>
|
||
<p><strong>Exemple d'erreur:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-71-1" name="__codelineno-71-1" href="#__codelineno-71-1"></a>NetworkError: HTTP error 403 while loading class file
|
||
<a id="__codelineno-71-2" name="__codelineno-71-2" href="#__codelineno-71-2"></a>"/luci-static/resources/view/netdata-dashboard/dashboard.js"
|
||
</code></pre></div></p>
|
||
<p><strong>Diagnostic rapide:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-72-1" name="__codelineno-72-1" href="#__codelineno-72-1"></a><span class="c1"># Vérifier permissions des fichiers déployés</span>
|
||
<a id="__codelineno-72-2" name="__codelineno-72-2" href="#__codelineno-72-2"></a>ssh<span class="w"> </span>root@192.168.8.191<span class="w"> </span><span class="s2">"ls -la /www/luci-static/resources/view/MODULE_NAME/"</span>
|
||
<a id="__codelineno-72-3" name="__codelineno-72-3" href="#__codelineno-72-3"></a>
|
||
<a id="__codelineno-72-4" name="__codelineno-72-4" href="#__codelineno-72-4"></a><span class="c1"># Chercher fichiers avec permissions incorrectes (600)</span>
|
||
<a id="__codelineno-72-5" name="__codelineno-72-5" href="#__codelineno-72-5"></a>ssh<span class="w"> </span>root@192.168.8.191<span class="w"> </span><span class="s2">"find /www/luci-static/resources/view/ -type f -name '*.js' -perm 600"</span>
|
||
<a id="__codelineno-72-6" name="__codelineno-72-6" href="#__codelineno-72-6"></a>
|
||
<a id="__codelineno-72-7" name="__codelineno-72-7" href="#__codelineno-72-7"></a><span class="c1"># MAUVAIS (cause 403):</span>
|
||
<a id="__codelineno-72-8" name="__codelineno-72-8" href="#__codelineno-72-8"></a><span class="c1"># -rw------- 1 root root 9763 dashboard.js ← 600 = pas lisible par web!</span>
|
||
<a id="__codelineno-72-9" name="__codelineno-72-9" href="#__codelineno-72-9"></a>
|
||
<a id="__codelineno-72-10" name="__codelineno-72-10" href="#__codelineno-72-10"></a><span class="c1"># BON:</span>
|
||
<a id="__codelineno-72-11" name="__codelineno-72-11" href="#__codelineno-72-11"></a><span class="c1"># -rw-r--r-- 1 root root 9763 dashboard.js ← 644 = OK</span>
|
||
</code></pre></div></p>
|
||
<p><strong>Correction immédiate:</strong>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-73-1" name="__codelineno-73-1" href="#__codelineno-73-1"></a><span class="c1"># Corriger TOUS les fichiers CSS/JS</span>
|
||
<a id="__codelineno-73-2" name="__codelineno-73-2" href="#__codelineno-73-2"></a>ssh<span class="w"> </span>root@192.168.8.191<span class="w"> </span><span class="s"><< 'EOF'</span>
|
||
<a id="__codelineno-73-3" name="__codelineno-73-3" href="#__codelineno-73-3"></a><span class="s">find /www/luci-static/resources/ -name '*.css' -exec chmod 644 {} \;</span>
|
||
<a id="__codelineno-73-4" name="__codelineno-73-4" href="#__codelineno-73-4"></a><span class="s">find /www/luci-static/resources/ -name '*.js' -exec chmod 644 {} \;</span>
|
||
<a id="__codelineno-73-5" name="__codelineno-73-5" href="#__codelineno-73-5"></a><span class="s">find /usr/libexec/rpcd/ -name 'luci.*' -exec chmod 755 {} \;</span>
|
||
<a id="__codelineno-73-6" name="__codelineno-73-6" href="#__codelineno-73-6"></a><span class="s">EOF</span>
|
||
</code></pre></div></p>
|
||
<p><strong>⚡ Correction Automatique (Recommandé):</strong></p>
|
||
<p>Utiliser le script automatique qui vérifie et corrige toutes les permissions:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-74-1" name="__codelineno-74-1" href="#__codelineno-74-1"></a><span class="c1"># Corriger permissions locales (source code)</span>
|
||
<a id="__codelineno-74-2" name="__codelineno-74-2" href="#__codelineno-74-2"></a>./secubox-tools/fix-permissions.sh<span class="w"> </span>--local
|
||
<a id="__codelineno-74-3" name="__codelineno-74-3" href="#__codelineno-74-3"></a>
|
||
<a id="__codelineno-74-4" name="__codelineno-74-4" href="#__codelineno-74-4"></a><span class="c1"># Corriger permissions sur routeur</span>
|
||
<a id="__codelineno-74-5" name="__codelineno-74-5" href="#__codelineno-74-5"></a>./secubox-tools/fix-permissions.sh<span class="w"> </span>--remote
|
||
<a id="__codelineno-74-6" name="__codelineno-74-6" href="#__codelineno-74-6"></a>
|
||
<a id="__codelineno-74-7" name="__codelineno-74-7" href="#__codelineno-74-7"></a><span class="c1"># Corriger les deux (local + remote)</span>
|
||
<a id="__codelineno-74-8" name="__codelineno-74-8" href="#__codelineno-74-8"></a>./secubox-tools/fix-permissions.sh
|
||
</code></pre></div>
|
||
<p>Le script <code>fix-permissions.sh</code> effectue automatiquement:
|
||
- ✅ Fixe tous les RPCD scripts à 755
|
||
- ✅ Fixe tous les CSS à 644
|
||
- ✅ Fixe tous les JS à 644
|
||
- ✅ Vérifie qu'aucun fichier 600 ne reste
|
||
- ✅ Clear cache et restart services (remote mode)
|
||
- ✅ Affiche un rapport complet des changements</p>
|
||
<p><strong>🔍 Validation Automatique des Permissions:</strong></p>
|
||
<p>Le script <code>validate-modules.sh</code> inclut maintenant un Check 7 qui vérifie automatiquement les permissions:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-75-1" name="__codelineno-75-1" href="#__codelineno-75-1"></a>./secubox-tools/validate-modules.sh
|
||
<a id="__codelineno-75-2" name="__codelineno-75-2" href="#__codelineno-75-2"></a>
|
||
<a id="__codelineno-75-3" name="__codelineno-75-3" href="#__codelineno-75-3"></a><span class="c1"># Check 7 validera:</span>
|
||
<a id="__codelineno-75-4" name="__codelineno-75-4" href="#__codelineno-75-4"></a><span class="c1"># ✓ Tous les RPCD sont 755</span>
|
||
<a id="__codelineno-75-5" name="__codelineno-75-5" href="#__codelineno-75-5"></a><span class="c1"># ✓ Tous les CSS sont 644</span>
|
||
<a id="__codelineno-75-6" name="__codelineno-75-6" href="#__codelineno-75-6"></a><span class="c1"># ✓ Tous les JS sont 644</span>
|
||
<a id="__codelineno-75-7" name="__codelineno-75-7" href="#__codelineno-75-7"></a><span class="c1"># ❌ Affichera erreurs si permissions incorrectes</span>
|
||
</code></pre></div>
|
||
<p><strong>Workflow recommandé:</strong>
|
||
1. Développer/modifier code
|
||
2. <code>./secubox-tools/fix-permissions.sh --local</code> (avant commit)
|
||
3. <code>./secubox-tools/validate-modules.sh</code> (vérifier tout)
|
||
4. Commit & push
|
||
5. Deploy sur routeur
|
||
6. <code>./secubox-tools/fix-permissions.sh --remote</code> (après deploy)</p>
|
||
<h4 id="3-post-deployment-verification">3. Post-Deployment Verification<a class="headerlink" href="#3-post-deployment-verification" title="Permanent link">¶</a></h4>
|
||
<p><strong>Checklist après déploiement:</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-76-1" name="__codelineno-76-1" href="#__codelineno-76-1"></a><span class="ch">#!/bin/bash</span>
|
||
<a id="__codelineno-76-2" name="__codelineno-76-2" href="#__codelineno-76-2"></a><span class="nv">ROUTER</span><span class="o">=</span><span class="s2">"root@192.168.8.191"</span>
|
||
<a id="__codelineno-76-3" name="__codelineno-76-3" href="#__codelineno-76-3"></a><span class="nv">MODULE</span><span class="o">=</span><span class="s2">"module-name"</span>
|
||
<a id="__codelineno-76-4" name="__codelineno-76-4" href="#__codelineno-76-4"></a>
|
||
<a id="__codelineno-76-5" name="__codelineno-76-5" href="#__codelineno-76-5"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"🔍 Post-Deployment Verification"</span>
|
||
<a id="__codelineno-76-6" name="__codelineno-76-6" href="#__codelineno-76-6"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-76-7" name="__codelineno-76-7" href="#__codelineno-76-7"></a>
|
||
<a id="__codelineno-76-8" name="__codelineno-76-8" href="#__codelineno-76-8"></a><span class="c1"># 1. Vérifier espace disque</span>
|
||
<a id="__codelineno-76-9" name="__codelineno-76-9" href="#__codelineno-76-9"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"1. Espace disque restant:"</span>
|
||
<a id="__codelineno-76-10" name="__codelineno-76-10" href="#__codelineno-76-10"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"df -h | grep overlay | awk '{print \$5}'"</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"❌ FAIL"</span>
|
||
<a id="__codelineno-76-11" name="__codelineno-76-11" href="#__codelineno-76-11"></a>
|
||
<a id="__codelineno-76-12" name="__codelineno-76-12" href="#__codelineno-76-12"></a><span class="c1"># 2. Vérifier permissions CSS/JS</span>
|
||
<a id="__codelineno-76-13" name="__codelineno-76-13" href="#__codelineno-76-13"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"2. Permissions CSS/JS:"</span>
|
||
<a id="__codelineno-76-14" name="__codelineno-76-14" href="#__codelineno-76-14"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"find /www/luci-static/resources/</span><span class="nv">$MODULE</span><span class="s2"> -type f \( -name '*.css' -o -name '*.js' \) ! -perm 644"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="se">\</span>
|
||
<a id="__codelineno-76-15" name="__codelineno-76-15" href="#__codelineno-76-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-z<span class="w"> </span><span class="s2">"</span><span class="k">$(</span>cat<span class="k">)</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ OK"</span><span class="p">;</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"❌ FAIL - Permissions incorrectes"</span><span class="p">;</span><span class="w"> </span><span class="k">fi</span>
|
||
<a id="__codelineno-76-16" name="__codelineno-76-16" href="#__codelineno-76-16"></a>
|
||
<a id="__codelineno-76-17" name="__codelineno-76-17" href="#__codelineno-76-17"></a><span class="c1"># 3. Vérifier permissions RPCD</span>
|
||
<a id="__codelineno-76-18" name="__codelineno-76-18" href="#__codelineno-76-18"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"3. Permissions RPCD:"</span>
|
||
<a id="__codelineno-76-19" name="__codelineno-76-19" href="#__codelineno-76-19"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"ls -l /usr/libexec/rpcd/luci.</span><span class="nv">$MODULE</span><span class="s2"> | grep -q rwxr-xr-x"</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ OK"</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"❌ FAIL"</span>
|
||
<a id="__codelineno-76-20" name="__codelineno-76-20" href="#__codelineno-76-20"></a>
|
||
<a id="__codelineno-76-21" name="__codelineno-76-21" href="#__codelineno-76-21"></a><span class="c1"># 4. Vérifier ubus object</span>
|
||
<a id="__codelineno-76-22" name="__codelineno-76-22" href="#__codelineno-76-22"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"4. ubus object disponible:"</span>
|
||
<a id="__codelineno-76-23" name="__codelineno-76-23" href="#__codelineno-76-23"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"ubus list | grep -q luci.</span><span class="nv">$MODULE</span><span class="s2">"</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ OK"</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"❌ FAIL"</span>
|
||
<a id="__codelineno-76-24" name="__codelineno-76-24" href="#__codelineno-76-24"></a>
|
||
<a id="__codelineno-76-25" name="__codelineno-76-25" href="#__codelineno-76-25"></a><span class="c1"># 5. Vérifier fichiers accessibles (HTTP)</span>
|
||
<a id="__codelineno-76-26" name="__codelineno-76-26" href="#__codelineno-76-26"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"5. Fichiers web accessibles:"</span>
|
||
<a id="__codelineno-76-27" name="__codelineno-76-27" href="#__codelineno-76-27"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"test -r /www/luci-static/resources/</span><span class="nv">$MODULE</span><span class="s2">/common.css"</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ OK"</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"⚠️ common.css non trouvé"</span>
|
||
<a id="__codelineno-76-28" name="__codelineno-76-28" href="#__codelineno-76-28"></a>
|
||
<a id="__codelineno-76-29" name="__codelineno-76-29" href="#__codelineno-76-29"></a><span class="c1"># 6. Vérifier cache cleared</span>
|
||
<a id="__codelineno-76-30" name="__codelineno-76-30" href="#__codelineno-76-30"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"6. Cache LuCI cleared:"</span>
|
||
<a id="__codelineno-76-31" name="__codelineno-76-31" href="#__codelineno-76-31"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"test ! -f /tmp/luci-indexcache"</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ OK"</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"⚠️ Cache encore présent"</span>
|
||
<a id="__codelineno-76-32" name="__codelineno-76-32" href="#__codelineno-76-32"></a>
|
||
<a id="__codelineno-76-33" name="__codelineno-76-33" href="#__codelineno-76-33"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-76-34" name="__codelineno-76-34" href="#__codelineno-76-34"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ Vérification terminée"</span>
|
||
</code></pre></div>
|
||
<h4 id="4-common-deployment-errors">4. Common Deployment Errors<a class="headerlink" href="#4-common-deployment-errors" title="Permanent link">¶</a></h4>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Erreur</th>
|
||
<th>Cause</th>
|
||
<th>Solution Rapide</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>HTTP 403 Forbidden</strong></td>
|
||
<td>Permissions 600 au lieu de 644</td>
|
||
<td><code>chmod 644 *.js *.css</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>No space left on device</strong></td>
|
||
<td>Overlay plein</td>
|
||
<td>Nettoyer /tmp, supprimer anciens backups</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Object not found -32000</strong></td>
|
||
<td>RPCD pas exécutable ou mal nommé</td>
|
||
<td><code>chmod 755 rpcd/luci.*</code> + vérifier nom</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Module not appearing</strong></td>
|
||
<td>Cache LuCI pas cleared</td>
|
||
<td><code>rm /tmp/luci-*</code> + restart services</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Changes not visible</strong></td>
|
||
<td>Cache navigateur</td>
|
||
<td>Mode privé + Ctrl+Shift+R</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h4 id="5-emergency-disk-space-recovery">5. Emergency Disk Space Recovery<a class="headerlink" href="#5-emergency-disk-space-recovery" title="Permanent link">¶</a></h4>
|
||
<p><strong>Si le déploiement échoue avec "No space left on device":</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-77-1" name="__codelineno-77-1" href="#__codelineno-77-1"></a><span class="ch">#!/bin/bash</span>
|
||
<a id="__codelineno-77-2" name="__codelineno-77-2" href="#__codelineno-77-2"></a><span class="nv">ROUTER</span><span class="o">=</span><span class="s2">"root@192.168.8.191"</span>
|
||
<a id="__codelineno-77-3" name="__codelineno-77-3" href="#__codelineno-77-3"></a>
|
||
<a id="__codelineno-77-4" name="__codelineno-77-4" href="#__codelineno-77-4"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"🚨 Emergency Disk Space Recovery"</span>
|
||
<a id="__codelineno-77-5" name="__codelineno-77-5" href="#__codelineno-77-5"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-77-6" name="__codelineno-77-6" href="#__codelineno-77-6"></a>
|
||
<a id="__codelineno-77-7" name="__codelineno-77-7" href="#__codelineno-77-7"></a><span class="c1"># 1. Analyser l'utilisation</span>
|
||
<a id="__codelineno-77-8" name="__codelineno-77-8" href="#__codelineno-77-8"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"Top 10 consumers:"</span>
|
||
<a id="__codelineno-77-9" name="__codelineno-77-9" href="#__codelineno-77-9"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"du -k /overlay/upper 2>/dev/null | sort -rn | head -10"</span>
|
||
<a id="__codelineno-77-10" name="__codelineno-77-10" href="#__codelineno-77-10"></a>
|
||
<a id="__codelineno-77-11" name="__codelineno-77-11" href="#__codelineno-77-11"></a><span class="c1"># 2. Nettoyer temporaires</span>
|
||
<a id="__codelineno-77-12" name="__codelineno-77-12" href="#__codelineno-77-12"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-77-13" name="__codelineno-77-13" href="#__codelineno-77-13"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"Cleaning temp files..."</span>
|
||
<a id="__codelineno-77-14" name="__codelineno-77-14" href="#__codelineno-77-14"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"rm -rf /tmp/*.ipk /tmp/luci-* /root/*.ipk 2>/dev/null"</span>
|
||
<a id="__codelineno-77-15" name="__codelineno-77-15" href="#__codelineno-77-15"></a>
|
||
<a id="__codelineno-77-16" name="__codelineno-77-16" href="#__codelineno-77-16"></a><span class="c1"># 3. Supprimer anciens backups</span>
|
||
<a id="__codelineno-77-17" name="__codelineno-77-17" href="#__codelineno-77-17"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"Removing old backups (>7 days)..."</span>
|
||
<a id="__codelineno-77-18" name="__codelineno-77-18" href="#__codelineno-77-18"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"find /root -name '*.backup-*' -mtime +7 -delete 2>/dev/null"</span>
|
||
<a id="__codelineno-77-19" name="__codelineno-77-19" href="#__codelineno-77-19"></a>
|
||
<a id="__codelineno-77-20" name="__codelineno-77-20" href="#__codelineno-77-20"></a><span class="c1"># 4. Option: Supprimer Netdata Web UI (libère ~22MB)</span>
|
||
<a id="__codelineno-77-21" name="__codelineno-77-21" href="#__codelineno-77-21"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-77-22" name="__codelineno-77-22" href="#__codelineno-77-22"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"⚠️ Option: Remove Netdata Web UI (saves ~22MB)?"</span>
|
||
<a id="__codelineno-77-23" name="__codelineno-77-23" href="#__codelineno-77-23"></a><span class="nb">read</span><span class="w"> </span>-p<span class="w"> </span><span class="s2">"Continue? (y/N) "</span><span class="w"> </span>-n<span class="w"> </span><span class="m">1</span><span class="w"> </span>-r
|
||
<a id="__codelineno-77-24" name="__codelineno-77-24" href="#__codelineno-77-24"></a><span class="k">if</span><span class="w"> </span><span class="o">[[</span><span class="w"> </span><span class="nv">$REPLY</span><span class="w"> </span><span class="o">=</span>~<span class="w"> </span>^<span class="o">[</span>Yy<span class="o">]</span>$<span class="w"> </span><span class="o">]]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||
<a id="__codelineno-77-25" name="__codelineno-77-25" href="#__codelineno-77-25"></a><span class="w"> </span>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"opkg remove netdata-web 2>/dev/null || rm -rf /usr/share/netdata/web/*"</span>
|
||
<a id="__codelineno-77-26" name="__codelineno-77-26" href="#__codelineno-77-26"></a><span class="k">fi</span>
|
||
<a id="__codelineno-77-27" name="__codelineno-77-27" href="#__codelineno-77-27"></a>
|
||
<a id="__codelineno-77-28" name="__codelineno-77-28" href="#__codelineno-77-28"></a><span class="c1"># 5. Vérifier espace libéré</span>
|
||
<a id="__codelineno-77-29" name="__codelineno-77-29" href="#__codelineno-77-29"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-77-30" name="__codelineno-77-30" href="#__codelineno-77-30"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"Space after cleanup:"</span>
|
||
<a id="__codelineno-77-31" name="__codelineno-77-31" href="#__codelineno-77-31"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"df -h | grep overlay"</span>
|
||
</code></pre></div>
|
||
<h3 id="standard-deployment-script-template">Standard Deployment Script Template<a class="headerlink" href="#standard-deployment-script-template" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-78-1" name="__codelineno-78-1" href="#__codelineno-78-1"></a><span class="ch">#!/bin/bash</span>
|
||
<a id="__codelineno-78-2" name="__codelineno-78-2" href="#__codelineno-78-2"></a><span class="c1"># Deploy <Module Name></span>
|
||
<a id="__codelineno-78-3" name="__codelineno-78-3" href="#__codelineno-78-3"></a>
|
||
<a id="__codelineno-78-4" name="__codelineno-78-4" href="#__codelineno-78-4"></a><span class="nv">ROUTER</span><span class="o">=</span><span class="s2">"root@192.168.8.191"</span>
|
||
<a id="__codelineno-78-5" name="__codelineno-78-5" href="#__codelineno-78-5"></a><span class="nv">MODULE</span><span class="o">=</span><span class="s2">"<module-name>"</span>
|
||
<a id="__codelineno-78-6" name="__codelineno-78-6" href="#__codelineno-78-6"></a><span class="nv">LOCAL_DIR</span><span class="o">=</span><span class="s2">"/path/to/luci-app-</span><span class="nv">$MODULE</span><span class="s2">/htdocs/luci-static/resources"</span>
|
||
<a id="__codelineno-78-7" name="__codelineno-78-7" href="#__codelineno-78-7"></a><span class="nv">REMOTE_DIR</span><span class="o">=</span><span class="s2">"/www/luci-static/resources"</span>
|
||
<a id="__codelineno-78-8" name="__codelineno-78-8" href="#__codelineno-78-8"></a>
|
||
<a id="__codelineno-78-9" name="__codelineno-78-9" href="#__codelineno-78-9"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"📦 Déploiement </span><span class="nv">$MODULE</span><span class="s2">"</span>
|
||
<a id="__codelineno-78-10" name="__codelineno-78-10" href="#__codelineno-78-10"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-78-11" name="__codelineno-78-11" href="#__codelineno-78-11"></a>
|
||
<a id="__codelineno-78-12" name="__codelineno-78-12" href="#__codelineno-78-12"></a><span class="c1"># 1. Deploy JS files</span>
|
||
<a id="__codelineno-78-13" name="__codelineno-78-13" href="#__codelineno-78-13"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"1. Copie des fichiers JS..."</span>
|
||
<a id="__codelineno-78-14" name="__codelineno-78-14" href="#__codelineno-78-14"></a>scp<span class="w"> </span><span class="s2">"</span><span class="nv">$LOCAL_DIR</span><span class="s2">/view/</span><span class="nv">$MODULE</span><span class="s2">/"</span>*.js<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">:</span><span class="nv">$REMOTE_DIR</span><span class="s2">/view/</span><span class="nv">$MODULE</span><span class="s2">/"</span>
|
||
<a id="__codelineno-78-15" name="__codelineno-78-15" href="#__codelineno-78-15"></a>scp<span class="w"> </span><span class="s2">"</span><span class="nv">$LOCAL_DIR</span><span class="s2">/</span><span class="nv">$MODULE</span><span class="s2">/api.js"</span><span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">:</span><span class="nv">$REMOTE_DIR</span><span class="s2">/</span><span class="nv">$MODULE</span><span class="s2">/"</span>
|
||
<a id="__codelineno-78-16" name="__codelineno-78-16" href="#__codelineno-78-16"></a>
|
||
<a id="__codelineno-78-17" name="__codelineno-78-17" href="#__codelineno-78-17"></a><span class="c1"># 2. Deploy CSS files</span>
|
||
<a id="__codelineno-78-18" name="__codelineno-78-18" href="#__codelineno-78-18"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"2. Copie des fichiers CSS..."</span>
|
||
<a id="__codelineno-78-19" name="__codelineno-78-19" href="#__codelineno-78-19"></a>scp<span class="w"> </span><span class="s2">"</span><span class="nv">$LOCAL_DIR</span><span class="s2">/</span><span class="nv">$MODULE</span><span class="s2">/"</span>*.css<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">:</span><span class="nv">$REMOTE_DIR</span><span class="s2">/</span><span class="nv">$MODULE</span><span class="s2">/"</span>
|
||
<a id="__codelineno-78-20" name="__codelineno-78-20" href="#__codelineno-78-20"></a>
|
||
<a id="__codelineno-78-21" name="__codelineno-78-21" href="#__codelineno-78-21"></a><span class="c1"># 3. Deploy RPCD backend</span>
|
||
<a id="__codelineno-78-22" name="__codelineno-78-22" href="#__codelineno-78-22"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"3. Copie du backend RPCD..."</span>
|
||
<a id="__codelineno-78-23" name="__codelineno-78-23" href="#__codelineno-78-23"></a>scp<span class="w"> </span><span class="s2">"root/usr/libexec/rpcd/luci.</span><span class="nv">$MODULE</span><span class="s2">"</span><span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">:/usr/libexec/rpcd/"</span>
|
||
<a id="__codelineno-78-24" name="__codelineno-78-24" href="#__codelineno-78-24"></a>
|
||
<a id="__codelineno-78-25" name="__codelineno-78-25" href="#__codelineno-78-25"></a><span class="c1"># 4. Fix permissions</span>
|
||
<a id="__codelineno-78-26" name="__codelineno-78-26" href="#__codelineno-78-26"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"4. Correction des permissions..."</span>
|
||
<a id="__codelineno-78-27" name="__codelineno-78-27" href="#__codelineno-78-27"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"chmod 755 /usr/libexec/rpcd/luci.</span><span class="nv">$MODULE</span><span class="s2">"</span>
|
||
<a id="__codelineno-78-28" name="__codelineno-78-28" href="#__codelineno-78-28"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"chmod 644 </span><span class="nv">$REMOTE_DIR</span><span class="s2">/</span><span class="nv">$MODULE</span><span class="s2">/*.css"</span>
|
||
<a id="__codelineno-78-29" name="__codelineno-78-29" href="#__codelineno-78-29"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"chmod 644 </span><span class="nv">$REMOTE_DIR</span><span class="s2">/view/</span><span class="nv">$MODULE</span><span class="s2">/*.js"</span>
|
||
<a id="__codelineno-78-30" name="__codelineno-78-30" href="#__codelineno-78-30"></a>
|
||
<a id="__codelineno-78-31" name="__codelineno-78-31" href="#__codelineno-78-31"></a><span class="c1"># 5. Clear cache</span>
|
||
<a id="__codelineno-78-32" name="__codelineno-78-32" href="#__codelineno-78-32"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"5. Nettoyage du cache..."</span>
|
||
<a id="__codelineno-78-33" name="__codelineno-78-33" href="#__codelineno-78-33"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"rm -f /tmp/luci-indexcache /tmp/luci-modulecache/* 2>/dev/null"</span>
|
||
<a id="__codelineno-78-34" name="__codelineno-78-34" href="#__codelineno-78-34"></a>
|
||
<a id="__codelineno-78-35" name="__codelineno-78-35" href="#__codelineno-78-35"></a><span class="c1"># 6. Restart services</span>
|
||
<a id="__codelineno-78-36" name="__codelineno-78-36" href="#__codelineno-78-36"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"6. Redémarrage des services..."</span>
|
||
<a id="__codelineno-78-37" name="__codelineno-78-37" href="#__codelineno-78-37"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"/etc/init.d/rpcd restart"</span>
|
||
<a id="__codelineno-78-38" name="__codelineno-78-38" href="#__codelineno-78-38"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"/etc/init.d/uhttpd restart"</span>
|
||
<a id="__codelineno-78-39" name="__codelineno-78-39" href="#__codelineno-78-39"></a>
|
||
<a id="__codelineno-78-40" name="__codelineno-78-40" href="#__codelineno-78-40"></a><span class="c1"># 7. Verify</span>
|
||
<a id="__codelineno-78-41" name="__codelineno-78-41" href="#__codelineno-78-41"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-78-42" name="__codelineno-78-42" href="#__codelineno-78-42"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"7. Vérification..."</span>
|
||
<a id="__codelineno-78-43" name="__codelineno-78-43" href="#__codelineno-78-43"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"ubus list | grep luci.</span><span class="nv">$MODULE</span><span class="s2">"</span>
|
||
<a id="__codelineno-78-44" name="__codelineno-78-44" href="#__codelineno-78-44"></a>
|
||
<a id="__codelineno-78-45" name="__codelineno-78-45" href="#__codelineno-78-45"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-78-46" name="__codelineno-78-46" href="#__codelineno-78-46"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"✅ Déploiement terminé!"</span>
|
||
<a id="__codelineno-78-47" name="__codelineno-78-47" href="#__codelineno-78-47"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">""</span>
|
||
<a id="__codelineno-78-48" name="__codelineno-78-48" href="#__codelineno-78-48"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">"🌐 Testez (mode privé):"</span>
|
||
<a id="__codelineno-78-49" name="__codelineno-78-49" href="#__codelineno-78-49"></a><span class="nb">echo</span><span class="w"> </span><span class="s2">" https://192.168.8.191/cgi-bin/luci/admin/secubox/path/to/</span><span class="nv">$MODULE</span><span class="s2">"</span>
|
||
</code></pre></div>
|
||
<h3 id="rollback-procedure">Rollback Procedure<a class="headerlink" href="#rollback-procedure" title="Permanent link">¶</a></h3>
|
||
<p>En cas de problème:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-79-1" name="__codelineno-79-1" href="#__codelineno-79-1"></a><span class="ch">#!/bin/bash</span>
|
||
<a id="__codelineno-79-2" name="__codelineno-79-2" href="#__codelineno-79-2"></a><span class="c1"># Rollback to previous version</span>
|
||
<a id="__codelineno-79-3" name="__codelineno-79-3" href="#__codelineno-79-3"></a>
|
||
<a id="__codelineno-79-4" name="__codelineno-79-4" href="#__codelineno-79-4"></a><span class="nv">ROUTER</span><span class="o">=</span><span class="s2">"root@192.168.8.191"</span>
|
||
<a id="__codelineno-79-5" name="__codelineno-79-5" href="#__codelineno-79-5"></a><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">"/root/luci-backups/</span><span class="k">$(</span>date<span class="w"> </span>+%Y%m%d<span class="k">)</span><span class="s2">"</span>
|
||
<a id="__codelineno-79-6" name="__codelineno-79-6" href="#__codelineno-79-6"></a>
|
||
<a id="__codelineno-79-7" name="__codelineno-79-7" href="#__codelineno-79-7"></a><span class="c1"># 1. Créer backup avant deploy</span>
|
||
<a id="__codelineno-79-8" name="__codelineno-79-8" href="#__codelineno-79-8"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"mkdir -p </span><span class="nv">$BACKUP_DIR</span><span class="s2">"</span>
|
||
<a id="__codelineno-79-9" name="__codelineno-79-9" href="#__codelineno-79-9"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"cp -r /www/luci-static/resources/module-name </span><span class="nv">$BACKUP_DIR</span><span class="s2">/"</span>
|
||
<a id="__codelineno-79-10" name="__codelineno-79-10" href="#__codelineno-79-10"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"cp /usr/libexec/rpcd/luci.module-name </span><span class="nv">$BACKUP_DIR</span><span class="s2">/"</span>
|
||
<a id="__codelineno-79-11" name="__codelineno-79-11" href="#__codelineno-79-11"></a>
|
||
<a id="__codelineno-79-12" name="__codelineno-79-12" href="#__codelineno-79-12"></a><span class="c1"># 2. En cas de problème, restore</span>
|
||
<a id="__codelineno-79-13" name="__codelineno-79-13" href="#__codelineno-79-13"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"cp -r </span><span class="nv">$BACKUP_DIR</span><span class="s2">/module-name /www/luci-static/resources/"</span>
|
||
<a id="__codelineno-79-14" name="__codelineno-79-14" href="#__codelineno-79-14"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"cp </span><span class="nv">$BACKUP_DIR</span><span class="s2">/luci.module-name /usr/libexec/rpcd/"</span>
|
||
<a id="__codelineno-79-15" name="__codelineno-79-15" href="#__codelineno-79-15"></a>ssh<span class="w"> </span><span class="s2">"</span><span class="nv">$ROUTER</span><span class="s2">"</span><span class="w"> </span><span class="s2">"/etc/init.d/rpcd restart && /etc/init.d/uhttpd restart"</span>
|
||
</code></pre></div>
|
||
<h3 id="version-control">Version Control<a class="headerlink" href="#version-control" title="Permanent link">¶</a></h3>
|
||
<p><strong>Toujours incrémenter les versions:</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-80-1" name="__codelineno-80-1" href="#__codelineno-80-1"></a><span class="c"># Makefile</span>
|
||
<a id="__codelineno-80-2" name="__codelineno-80-2" href="#__codelineno-80-2"></a><span class="nv">PKG_VERSION</span><span class="o">:=</span><span class="m">0</span>.3.0
|
||
<a id="__codelineno-80-3" name="__codelineno-80-3" href="#__codelineno-80-3"></a><span class="nv">PKG_RELEASE</span><span class="o">:=</span><span class="m">1</span>
|
||
</code></pre></div>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-81-1" name="__codelineno-81-1" href="#__codelineno-81-1"></a><span class="c">/* CSS files */</span>
|
||
<a id="__codelineno-81-2" name="__codelineno-81-2" href="#__codelineno-81-2"></a><span class="c">/**</span>
|
||
<a id="__codelineno-81-3" name="__codelineno-81-3" href="#__codelineno-81-3"></a><span class="c"> * Module - Styles</span>
|
||
<a id="__codelineno-81-4" name="__codelineno-81-4" href="#__codelineno-81-4"></a><span class="c"> * Version: 0.3.0</span>
|
||
<a id="__codelineno-81-5" name="__codelineno-81-5" href="#__codelineno-81-5"></a><span class="c"> */</span>
|
||
</code></pre></div>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-82-1" name="__codelineno-82-1" href="#__codelineno-82-1"></a><span class="c1">// JavaScript</span>
|
||
<a id="__codelineno-82-2" name="__codelineno-82-2" href="#__codelineno-82-2"></a><span class="c1">// Version: 0.3.0</span>
|
||
</code></pre></div>
|
||
<p><strong>Semantic Versioning:</strong>
|
||
- MAJOR.MINOR.PATCH (1.2.3)
|
||
- MAJOR: Breaking changes
|
||
- MINOR: New features (backward compatible)
|
||
- PATCH: Bug fixes</p>
|
||
<hr />
|
||
<h2 id="quick-reference">Quick Reference<a class="headerlink" href="#quick-reference" title="Permanent link">¶</a></h2>
|
||
<h3 id="essential-commands">Essential Commands<a class="headerlink" href="#essential-commands" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-83-1" name="__codelineno-83-1" href="#__codelineno-83-1"></a><span class="c1"># Validation</span>
|
||
<a id="__codelineno-83-2" name="__codelineno-83-2" href="#__codelineno-83-2"></a>./secubox-tools/validate-modules.sh
|
||
<a id="__codelineno-83-3" name="__codelineno-83-3" href="#__codelineno-83-3"></a>
|
||
<a id="__codelineno-83-4" name="__codelineno-83-4" href="#__codelineno-83-4"></a><span class="c1"># Build (local)</span>
|
||
<a id="__codelineno-83-5" name="__codelineno-83-5" href="#__codelineno-83-5"></a>./secubox-tools/local-build.sh<span class="w"> </span>build<span class="w"> </span>luci-app-module-name
|
||
<a id="__codelineno-83-6" name="__codelineno-83-6" href="#__codelineno-83-6"></a>
|
||
<a id="__codelineno-83-7" name="__codelineno-83-7" href="#__codelineno-83-7"></a><span class="c1"># Deploy files</span>
|
||
<a id="__codelineno-83-8" name="__codelineno-83-8" href="#__codelineno-83-8"></a>scp<span class="w"> </span>file.js<span class="w"> </span>root@router:/www/luci-static/resources/
|
||
<a id="__codelineno-83-9" name="__codelineno-83-9" href="#__codelineno-83-9"></a>
|
||
<a id="__codelineno-83-10" name="__codelineno-83-10" href="#__codelineno-83-10"></a><span class="c1"># Fix permissions</span>
|
||
<a id="__codelineno-83-11" name="__codelineno-83-11" href="#__codelineno-83-11"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"chmod 644 /www/luci-static/resources/**/*.css"</span>
|
||
<a id="__codelineno-83-12" name="__codelineno-83-12" href="#__codelineno-83-12"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"chmod 755 /usr/libexec/rpcd/luci.*"</span>
|
||
<a id="__codelineno-83-13" name="__codelineno-83-13" href="#__codelineno-83-13"></a>
|
||
<a id="__codelineno-83-14" name="__codelineno-83-14" href="#__codelineno-83-14"></a><span class="c1"># Clear cache</span>
|
||
<a id="__codelineno-83-15" name="__codelineno-83-15" href="#__codelineno-83-15"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"rm -f /tmp/luci-indexcache /tmp/luci-modulecache/*"</span>
|
||
<a id="__codelineno-83-16" name="__codelineno-83-16" href="#__codelineno-83-16"></a>
|
||
<a id="__codelineno-83-17" name="__codelineno-83-17" href="#__codelineno-83-17"></a><span class="c1"># Restart services</span>
|
||
<a id="__codelineno-83-18" name="__codelineno-83-18" href="#__codelineno-83-18"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"/etc/init.d/rpcd restart && /etc/init.d/uhttpd restart"</span>
|
||
<a id="__codelineno-83-19" name="__codelineno-83-19" href="#__codelineno-83-19"></a>
|
||
<a id="__codelineno-83-20" name="__codelineno-83-20" href="#__codelineno-83-20"></a><span class="c1"># Test ubus</span>
|
||
<a id="__codelineno-83-21" name="__codelineno-83-21" href="#__codelineno-83-21"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"ubus list | grep luci"</span>
|
||
<a id="__codelineno-83-22" name="__codelineno-83-22" href="#__codelineno-83-22"></a>ssh<span class="w"> </span>root@router<span class="w"> </span><span class="s2">"ubus call luci.module-name getStatus"</span>
|
||
<a id="__codelineno-83-23" name="__codelineno-83-23" href="#__codelineno-83-23"></a>
|
||
<a id="__codelineno-83-24" name="__codelineno-83-24" href="#__codelineno-83-24"></a><span class="c1"># Validate JSON</span>
|
||
<a id="__codelineno-83-25" name="__codelineno-83-25" href="#__codelineno-83-25"></a>jsonlint<span class="w"> </span>file.json
|
||
<a id="__codelineno-83-26" name="__codelineno-83-26" href="#__codelineno-83-26"></a>jq<span class="w"> </span>.<span class="w"> </span>file.json
|
||
</code></pre></div>
|
||
<h3 id="css-classes-quick-reference">CSS Classes Quick Reference<a class="headerlink" href="#css-classes-quick-reference" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-84-1" name="__codelineno-84-1" href="#__codelineno-84-1"></a><span class="c">/* Layout */</span>
|
||
<a id="__codelineno-84-2" name="__codelineno-84-2" href="#__codelineno-84-2"></a><span class="p">.</span><span class="nc">sh-page-header</span><span class="w"> </span><span class="c">/* Page header container */</span>
|
||
<a id="__codelineno-84-3" name="__codelineno-84-3" href="#__codelineno-84-3"></a><span class="p">.</span><span class="nc">sh-page-title</span><span class="w"> </span><span class="c">/* Page title (gradient text) */</span>
|
||
<a id="__codelineno-84-4" name="__codelineno-84-4" href="#__codelineno-84-4"></a><span class="p">.</span><span class="nc">sh-page-subtitle</span><span class="w"> </span><span class="c">/* Page subtitle */</span>
|
||
<a id="__codelineno-84-5" name="__codelineno-84-5" href="#__codelineno-84-5"></a>
|
||
<a id="__codelineno-84-6" name="__codelineno-84-6" href="#__codelineno-84-6"></a><span class="c">/* Stats */</span>
|
||
<a id="__codelineno-84-7" name="__codelineno-84-7" href="#__codelineno-84-7"></a><span class="p">.</span><span class="nc">sh-stats-grid</span><span class="w"> </span><span class="c">/* Grid for stat badges (130px min) */</span>
|
||
<a id="__codelineno-84-8" name="__codelineno-84-8" href="#__codelineno-84-8"></a><span class="p">.</span><span class="nc">sh-stat-badge</span><span class="w"> </span><span class="c">/* Stat badge container */</span>
|
||
<a id="__codelineno-84-9" name="__codelineno-84-9" href="#__codelineno-84-9"></a><span class="p">.</span><span class="nc">sh-stat-value</span><span class="w"> </span><span class="c">/* Stat value (monospace) */</span>
|
||
<a id="__codelineno-84-10" name="__codelineno-84-10" href="#__codelineno-84-10"></a><span class="p">.</span><span class="nc">sh-stat-label</span><span class="w"> </span><span class="c">/* Stat label (uppercase) */</span>
|
||
<a id="__codelineno-84-11" name="__codelineno-84-11" href="#__codelineno-84-11"></a>
|
||
<a id="__codelineno-84-12" name="__codelineno-84-12" href="#__codelineno-84-12"></a><span class="c">/* Cards */</span>
|
||
<a id="__codelineno-84-13" name="__codelineno-84-13" href="#__codelineno-84-13"></a><span class="p">.</span><span class="nc">sh-card</span><span class="w"> </span><span class="c">/* Card container (with gradient border on hover) */</span>
|
||
<a id="__codelineno-84-14" name="__codelineno-84-14" href="#__codelineno-84-14"></a><span class="p">.</span><span class="nc">sh-card-success</span><span class="w"> </span><span class="c">/* Card with green border */</span>
|
||
<a id="__codelineno-84-15" name="__codelineno-84-15" href="#__codelineno-84-15"></a><span class="p">.</span><span class="nc">sh-card-danger</span><span class="w"> </span><span class="c">/* Card with red border */</span>
|
||
<a id="__codelineno-84-16" name="__codelineno-84-16" href="#__codelineno-84-16"></a><span class="p">.</span><span class="nc">sh-card-warning</span><span class="w"> </span><span class="c">/* Card with orange border */</span>
|
||
<a id="__codelineno-84-17" name="__codelineno-84-17" href="#__codelineno-84-17"></a><span class="p">.</span><span class="nc">sh-card-header</span><span class="w"> </span><span class="c">/* Card header */</span>
|
||
<a id="__codelineno-84-18" name="__codelineno-84-18" href="#__codelineno-84-18"></a><span class="p">.</span><span class="nc">sh-card-title</span><span class="w"> </span><span class="c">/* Card title */</span>
|
||
<a id="__codelineno-84-19" name="__codelineno-84-19" href="#__codelineno-84-19"></a><span class="p">.</span><span class="nc">sh-card-body</span><span class="w"> </span><span class="c">/* Card content */</span>
|
||
<a id="__codelineno-84-20" name="__codelineno-84-20" href="#__codelineno-84-20"></a>
|
||
<a id="__codelineno-84-21" name="__codelineno-84-21" href="#__codelineno-84-21"></a><span class="c">/* Buttons */</span>
|
||
<a id="__codelineno-84-22" name="__codelineno-84-22" href="#__codelineno-84-22"></a><span class="p">.</span><span class="nc">sh-btn</span><span class="w"> </span><span class="c">/* Base button */</span>
|
||
<a id="__codelineno-84-23" name="__codelineno-84-23" href="#__codelineno-84-23"></a><span class="p">.</span><span class="nc">sh-btn-primary</span><span class="w"> </span><span class="c">/* Primary button (gradient) */</span>
|
||
<a id="__codelineno-84-24" name="__codelineno-84-24" href="#__codelineno-84-24"></a><span class="p">.</span><span class="nc">sh-btn-success</span><span class="w"> </span><span class="c">/* Success button (green) */</span>
|
||
<a id="__codelineno-84-25" name="__codelineno-84-25" href="#__codelineno-84-25"></a><span class="p">.</span><span class="nc">sh-btn-danger</span><span class="w"> </span><span class="c">/* Danger button (red) */</span>
|
||
<a id="__codelineno-84-26" name="__codelineno-84-26" href="#__codelineno-84-26"></a><span class="p">.</span><span class="nc">sh-btn-secondary</span><span class="w"> </span><span class="c">/* Secondary button (outline) */</span>
|
||
<a id="__codelineno-84-27" name="__codelineno-84-27" href="#__codelineno-84-27"></a>
|
||
<a id="__codelineno-84-28" name="__codelineno-84-28" href="#__codelineno-84-28"></a><span class="c">/* Tabs */</span>
|
||
<a id="__codelineno-84-29" name="__codelineno-84-29" href="#__codelineno-84-29"></a><span class="p">.</span><span class="nc">sh-filter-tabs</span><span class="w"> </span><span class="c">/* Filter tabs container */</span>
|
||
<a id="__codelineno-84-30" name="__codelineno-84-30" href="#__codelineno-84-30"></a><span class="p">.</span><span class="nc">sh-filter-tab</span><span class="w"> </span><span class="c">/* Filter tab */</span>
|
||
<a id="__codelineno-84-31" name="__codelineno-84-31" href="#__codelineno-84-31"></a><span class="p">.</span><span class="nc">sh-filter-tab</span><span class="p">.</span><span class="nc">active</span><span class="w"> </span><span class="c">/* Active filter tab (gradient) */</span>
|
||
<a id="__codelineno-84-32" name="__codelineno-84-32" href="#__codelineno-84-32"></a><span class="p">.</span><span class="nc">sh-nav-tabs</span><span class="w"> </span><span class="c">/* Navigation tabs (sticky) */</span>
|
||
<a id="__codelineno-84-33" name="__codelineno-84-33" href="#__codelineno-84-33"></a><span class="p">.</span><span class="nc">sh-nav-tab</span><span class="w"> </span><span class="c">/* Navigation tab */</span>
|
||
<a id="__codelineno-84-34" name="__codelineno-84-34" href="#__codelineno-84-34"></a><span class="p">.</span><span class="nc">sh-nav-tab</span><span class="p">.</span><span class="nc">active</span><span class="w"> </span><span class="c">/* Active nav tab (underline) */</span>
|
||
<a id="__codelineno-84-35" name="__codelineno-84-35" href="#__codelineno-84-35"></a>
|
||
<a id="__codelineno-84-36" name="__codelineno-84-36" href="#__codelineno-84-36"></a><span class="c">/* Utilities */</span>
|
||
<a id="__codelineno-84-37" name="__codelineno-84-37" href="#__codelineno-84-37"></a><span class="p">.</span><span class="nc">sh-gradient-text</span><span class="w"> </span><span class="c">/* Gradient text effect */</span>
|
||
<a id="__codelineno-84-38" name="__codelineno-84-38" href="#__codelineno-84-38"></a><span class="p">.</span><span class="nc">sh-id-display</span><span class="w"> </span><span class="c">/* Monospace ID display */</span>
|
||
<a id="__codelineno-84-39" name="__codelineno-84-39" href="#__codelineno-84-39"></a><span class="p">.</span><span class="nc">sh-empty-state</span><span class="w"> </span><span class="c">/* Empty state placeholder */</span>
|
||
</code></pre></div>
|
||
<h3 id="color-variables-quick-reference">Color Variables Quick Reference<a class="headerlink" href="#color-variables-quick-reference" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-85-1" name="__codelineno-85-1" href="#__codelineno-85-1"></a><span class="c">/* Text */</span>
|
||
<a id="__codelineno-85-2" name="__codelineno-85-2" href="#__codelineno-85-2"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-text-primary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Main text */</span>
|
||
<a id="__codelineno-85-3" name="__codelineno-85-3" href="#__codelineno-85-3"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-text-secondary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Secondary text */</span>
|
||
<a id="__codelineno-85-4" name="__codelineno-85-4" href="#__codelineno-85-4"></a>
|
||
<a id="__codelineno-85-5" name="__codelineno-85-5" href="#__codelineno-85-5"></a><span class="c">/* Backgrounds */</span>
|
||
<a id="__codelineno-85-6" name="__codelineno-85-6" href="#__codelineno-85-6"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-bg-primary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Main background */</span>
|
||
<a id="__codelineno-85-7" name="__codelineno-85-7" href="#__codelineno-85-7"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-bg-secondary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Secondary background */</span>
|
||
<a id="__codelineno-85-8" name="__codelineno-85-8" href="#__codelineno-85-8"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-bg-tertiary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Tertiary background */</span>
|
||
<a id="__codelineno-85-9" name="__codelineno-85-9" href="#__codelineno-85-9"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-bg-card</span><span class="o">)</span><span class="w"> </span><span class="c">/* Card background */</span>
|
||
<a id="__codelineno-85-10" name="__codelineno-85-10" href="#__codelineno-85-10"></a>
|
||
<a id="__codelineno-85-11" name="__codelineno-85-11" href="#__codelineno-85-11"></a><span class="c">/* Borders */</span>
|
||
<a id="__codelineno-85-12" name="__codelineno-85-12" href="#__codelineno-85-12"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-border</span><span class="o">)</span><span class="w"> </span><span class="c">/* Border color */</span>
|
||
<a id="__codelineno-85-13" name="__codelineno-85-13" href="#__codelineno-85-13"></a>
|
||
<a id="__codelineno-85-14" name="__codelineno-85-14" href="#__codelineno-85-14"></a><span class="c">/* Colors */</span>
|
||
<a id="__codelineno-85-15" name="__codelineno-85-15" href="#__codelineno-85-15"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary</span><span class="o">)</span><span class="w"> </span><span class="c">/* Indigo #6366f1 */</span>
|
||
<a id="__codelineno-85-16" name="__codelineno-85-16" href="#__codelineno-85-16"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-primary-end</span><span class="o">)</span><span class="w"> </span><span class="c">/* Violet #8b5cf6 */</span>
|
||
<a id="__codelineno-85-17" name="__codelineno-85-17" href="#__codelineno-85-17"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-success</span><span class="o">)</span><span class="w"> </span><span class="c">/* Green #22c55e */</span>
|
||
<a id="__codelineno-85-18" name="__codelineno-85-18" href="#__codelineno-85-18"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-danger</span><span class="o">)</span><span class="w"> </span><span class="c">/* Red #ef4444 */</span>
|
||
<a id="__codelineno-85-19" name="__codelineno-85-19" href="#__codelineno-85-19"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-warning</span><span class="o">)</span><span class="w"> </span><span class="c">/* Orange #f59e0b */</span>
|
||
<a id="__codelineno-85-20" name="__codelineno-85-20" href="#__codelineno-85-20"></a>
|
||
<a id="__codelineno-85-21" name="__codelineno-85-21" href="#__codelineno-85-21"></a><span class="c">/* Effects */</span>
|
||
<a id="__codelineno-85-22" name="__codelineno-85-22" href="#__codelineno-85-22"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-shadow</span><span class="o">)</span><span class="w"> </span><span class="c">/* Box shadow */</span>
|
||
<a id="__codelineno-85-23" name="__codelineno-85-23" href="#__codelineno-85-23"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-hover-shadow</span><span class="o">)</span><span class="w"> </span><span class="c">/* Hover shadow */</span>
|
||
<a id="__codelineno-85-24" name="__codelineno-85-24" href="#__codelineno-85-24"></a><span class="nt">var</span><span class="o">(</span><span class="nt">--sh-hover-bg</span><span class="o">)</span><span class="w"> </span><span class="c">/* Hover background */</span>
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="ai-assistant-context-files">AI Assistant Context Files<a class="headerlink" href="#ai-assistant-context-files" title="Permanent link">¶</a></h2>
|
||
<p>SecuBox work is shared between Claude and Codex assistants. Keep the context folders synchronized so any agent can resume work quickly:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Directory</th>
|
||
<th>File</th>
|
||
<th>Usage</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>.claude/</code></td>
|
||
<td><code>HISTORY.md</code></td>
|
||
<td>Chronological log of UI/theme changes and major deployments</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>.claude/</code></td>
|
||
<td><code>TODO.md</code></td>
|
||
<td>High-level backlog (UX polish, docs, automation ideas)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>.claude/</code></td>
|
||
<td><code>WIP.md</code></td>
|
||
<td>Active tasks, risks, and immediate next steps</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>.codex/</code></td>
|
||
<td><code>HISTORY.md</code></td>
|
||
<td>Mirrors the development timeline for Codex sessions</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>.codex/</code></td>
|
||
<td><code>TODO.md</code></td>
|
||
<td>Tooling-focused tasks (linting, scripts, build automation)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>.codex/</code></td>
|
||
<td><code>WIP.md</code></td>
|
||
<td>Status tracker for ongoing Codex efforts</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><strong>Maintenance rules</strong></p>
|
||
<ol>
|
||
<li><strong>Update after each session:</strong> When finishing work, append a short bullet to HISTORY and adjust WIP/TODO so they reflect the new state.</li>
|
||
<li><strong>Reference deployment scripts:</strong> Note which <code>secubox-tools/*.sh</code> script was used (dashboard vs. full deploy) so the next assistant knows how to reproduce it.</li>
|
||
<li><strong>Keep entries concise:</strong> A single paragraph or bullet per update is enough; detailed specs remain in DOCS.</li>
|
||
<li><strong>Cross-check before big changes:</strong> Read both folders before starting work to avoid conflicts or duplicate efforts.</li>
|
||
</ol>
|
||
<p>Treat these files as living handoff notes—if they drift, onboarding a new AI/teammate becomes significantly slower.</p>
|
||
<hr />
|
||
<h2 id="conclusion">Conclusion<a class="headerlink" href="#conclusion" title="Permanent link">¶</a></h2>
|
||
<p>Ce guide doit être consulté <strong>AVANT</strong> de:
|
||
1. Créer un nouveau module
|
||
2. Modifier des styles existants
|
||
3. Ajouter des méthodes RPCD
|
||
4. Déployer sur un routeur
|
||
5. Débugger des erreurs</p>
|
||
<p><strong>En cas de doute, TOUJOURS:</strong>
|
||
1. Consulter ce guide
|
||
2. Exécuter validate-modules.sh
|
||
3. Tester en mode privé
|
||
4. Vérifier la console browser (F12)</p>
|
||
<p><strong>Ressources supplémentaires:</strong>
|
||
- CLAUDE.md - Architecture et build
|
||
- secubox-tools/validate-modules.sh - Validation automatique
|
||
- Templates/ - Templates de code</p>
|
||
<hr />
|
||
<p><strong>Dernière mise à jour:</strong> 2025-12-26
|
||
<strong>Maintenu par:</strong> CyberMind Studio
|
||
<strong>Version du guide:</strong> 1.0.0</p>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</article>
|
||
</div>
|
||
|
||
|
||
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
||
</div>
|
||
|
||
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
|
||
Back to top
|
||
</button>
|
||
|
||
</main>
|
||
|
||
<footer class="md-footer">
|
||
|
||
<div class="md-footer-meta md-typeset">
|
||
<div class="md-footer-meta__inner md-grid">
|
||
<div class="md-copyright">
|
||
|
||
|
||
Made with
|
||
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
||
Material for MkDocs
|
||
</a>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="md-social">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://github.com/gkerma/secubox-openwrt" target="_blank" rel="noopener" title="github.com" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://secubox.cybermood.eu" target="_blank" rel="noopener" title="secubox.cybermood.eu" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M351.9 280H161c2.9 64.5 17.2 123.9 37.5 167.4 11.4 24.5 23.7 41.8 35.1 52.4 11.2 10.5 18.9 12.2 22.9 12.2s11.7-1.7 22.9-12.2c11.4-10.6 23.7-28 35.1-52.4 20.3-43.5 34.6-102.9 37.5-167.4zm-191-48h190.9c-2.8-64.5-17.1-123.9-37.4-167.4-11.4-24.4-23.7-41.8-35.1-52.4C268.1 1.7 260.4 0 256.4 0s-11.7 1.7-22.9 12.2c-11.4 10.6-23.7 28-35.1 52.4-20.3 43.5-34.6 102.9-37.5 167.4m-48 0c3.5-85.6 25.6-165.1 57.9-217.3C78.7 47.3 10.9 131.2 1.5 232zM1.5 280c9.4 100.8 77.2 184.7 169.3 217.3-32.3-52.2-54.4-131.7-57.9-217.3zm398.4 0c-3.5 85.6-25.6 165.1-57.9 217.3 92.1-32.7 159.9-116.5 169.3-217.3zm111.4-48C501.9 131.2 434.1 47.3 342 14.7c32.3 52.2 54.4 131.7 57.9 217.3z"/></svg>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
<div class="md-dialog" data-md-component="dialog">
|
||
<div class="md-dialog__inner md-typeset"></div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.tabs.sticky", "navigation.sections", "navigation.expand", "navigation.top", "search.suggest", "search.highlight", "content.code.copy", "content.code.annotate"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
|
||
|
||
|
||
<script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
|
||
|
||
|
||
</body>
|
||
</html> |