maj via codex

This commit is contained in:
2026-02-22 18:34:50 +01:00
parent 20af00d653
commit 55387f4b0e
90 changed files with 9902 additions and 1251 deletions

View File

@@ -1,24 +1,158 @@
/// <reference types="../node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts" />
import { ref } from 'vue';
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { RouterLink, RouterView } from 'vue-router';
import AppHeader from '@/components/AppHeader.vue';
import AppDrawer from '@/components/AppDrawer.vue';
import { meteoApi } from '@/api/meteo';
import { settingsApi } from '@/api/settings';
const drawerOpen = ref(false);
const debugMode = ref(localStorage.getItem('debug_mode') === '1');
const debugStats = ref(null);
let debugTimer = null;
function prefetchMeteoInBackground() {
// Préchargement du chunk route + données pour accélérer l'ouverture de /meteo
void import('@/views/CalendrierView.vue');
void meteoApi.preloadForMeteoView();
}
function toBool(value) {
if (typeof value === 'boolean')
return value;
const s = String(value ?? '').toLowerCase().trim();
return s === '1' || s === 'true' || s === 'yes' || s === 'on';
}
function formatBytes(value) {
if (value == null || Number.isNaN(value))
return '—';
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
let n = value;
let i = 0;
while (n >= 1024 && i < units.length - 1) {
n /= 1024;
i += 1;
}
return `${n.toFixed(n >= 100 ? 0 : n >= 10 ? 1 : 2)}${units[i]}`;
}
const debugCpuLabel = computed(() => {
const pct = debugStats.value?.cpu?.used_pct;
return pct != null ? `${pct.toFixed(1)}%` : '—';
});
const debugMemLabel = computed(() => {
const used = debugStats.value?.memory?.used_bytes;
const pct = debugStats.value?.memory?.used_pct;
if (used == null)
return '—';
return pct != null ? `${formatBytes(used)} (${pct.toFixed(1)}%)` : formatBytes(used);
});
const debugDiskLabel = computed(() => {
const used = debugStats.value?.disk?.used_bytes;
const pct = debugStats.value?.disk?.used_pct;
if (used == null)
return '—';
return pct != null ? `${formatBytes(used)} (${pct.toFixed(1)}%)` : formatBytes(used);
});
async function fetchDebugStats() {
try {
debugStats.value = await settingsApi.getDebugSystemStats();
}
catch {
debugStats.value = null;
}
}
function stopDebugPolling() {
if (debugTimer != null) {
window.clearInterval(debugTimer);
debugTimer = null;
}
}
function startDebugPolling() {
stopDebugPolling();
void fetchDebugStats();
debugTimer = window.setInterval(() => {
void fetchDebugStats();
}, 10000);
}
async function loadDebugModeFromApi() {
try {
const data = await settingsApi.get();
debugMode.value = toBool(data.debug_mode);
localStorage.setItem('debug_mode', debugMode.value ? '1' : '0');
}
catch {
// On garde la valeur locale.
}
}
function handleSettingsUpdated(event) {
const ce = event;
if (!ce.detail || ce.detail.debug_mode == null)
return;
debugMode.value = toBool(ce.detail.debug_mode);
localStorage.setItem('debug_mode', debugMode.value ? '1' : '0');
}
function handleStorage(event) {
if (event.key !== 'debug_mode')
return;
debugMode.value = event.newValue === '1';
}
onMounted(() => {
const ric = window.requestIdleCallback;
if (ric) {
ric(() => prefetchMeteoInBackground(), { timeout: 1500 });
}
else {
window.setTimeout(prefetchMeteoInBackground, 500);
}
void loadDebugModeFromApi();
window.addEventListener('settings-updated', handleSettingsUpdated);
window.addEventListener('storage', handleStorage);
});
watch(debugMode, (enabled) => {
if (enabled)
startDebugPolling();
else {
stopDebugPolling();
debugStats.value = null;
}
}, { immediate: true });
onBeforeUnmount(() => {
stopDebugPolling();
window.removeEventListener('settings-updated', handleSettingsUpdated);
window.removeEventListener('storage', handleStorage);
});
const links = [
{ to: '/', label: 'Dashboard', icon: '🏠' },
{ to: '/jardins', label: 'Jardins', icon: '🪴' },
{ to: '/plantes', label: 'Plantes', icon: '🌱' },
{ to: '/bibliotheque', label: 'Bibliothèque', icon: '📷' },
{ to: '/outils', label: 'Outils', icon: '🔧' },
{ to: '/plantations', label: 'Plantations', icon: '🥕' },
{ to: '/taches', label: 'Tâches', icon: '✅' },
{ to: '/planning', label: 'Planning', icon: '📆' },
{ to: '/calendrier', label: 'Calendrier', icon: '🌙' },
{ to: '/meteo', label: 'Météo', icon: '🌦️' },
{ to: '/astuces', label: 'Astuces', icon: '💡' },
{ to: '/reglages', label: 'Réglages', icon: '⚙️' },
];
debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
const __VLS_ctx = {};
let __VLS_components;
let __VLS_directives;
if (__VLS_ctx.debugMode) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "fixed top-2 right-2 z-[70] bg-bg-hard/95 border border-bg-soft rounded-lg px-3 py-1.5 text-[11px] text-text-muted shadow-lg" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-aqua font-semibold mr-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "mr-2" },
});
(__VLS_ctx.debugCpuLabel);
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "mr-2" },
});
(__VLS_ctx.debugMemLabel);
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({});
(__VLS_ctx.debugDiskLabel);
}
/** @type {[typeof AppHeader, ]} */ ;
// @ts-ignore
const __VLS_0 = __VLS_asFunctionalComponent(AppHeader, new AppHeader({
@@ -119,6 +253,24 @@ const __VLS_22 = {}.RouterView;
// @ts-ignore
const __VLS_23 = __VLS_asFunctionalComponent(__VLS_22, new __VLS_22({}));
const __VLS_24 = __VLS_23({}, ...__VLS_functionalComponentArgsRest(__VLS_23));
/** @type {__VLS_StyleScopedClasses['fixed']} */ ;
/** @type {__VLS_StyleScopedClasses['top-2']} */ ;
/** @type {__VLS_StyleScopedClasses['right-2']} */ ;
/** @type {__VLS_StyleScopedClasses['z-[70]']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg-hard/95']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-lg']} */ ;
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
/** @type {__VLS_StyleScopedClasses['py-1.5']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[11px]']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
/** @type {__VLS_StyleScopedClasses['text-aqua']} */ ;
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
/** @type {__VLS_StyleScopedClasses['mr-2']} */ ;
/** @type {__VLS_StyleScopedClasses['mr-2']} */ ;
/** @type {__VLS_StyleScopedClasses['mr-2']} */ ;
/** @type {__VLS_StyleScopedClasses['lg:hidden']} */ ;
/** @type {__VLS_StyleScopedClasses['lg:flex']} */ ;
/** @type {__VLS_StyleScopedClasses['hidden']} */ ;
@@ -183,6 +335,10 @@ const __VLS_self = (await import('vue')).defineComponent({
AppHeader: AppHeader,
AppDrawer: AppDrawer,
drawerOpen: drawerOpen,
debugMode: debugMode,
debugCpuLabel: debugCpuLabel,
debugMemLabel: debugMemLabel,
debugDiskLabel: debugDiskLabel,
links: links,
};
},