Rétablir l'onglet Génération mémorisé et ignorer le repli du panneau sur téléphone
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@ -1403,3 +1403,17 @@ def test_ui_single_tabbed_panel():
|
|||||||
assert "@media (max-width: 720px)" in _MAP_CSS and "#panel" in _MAP_CSS
|
assert "@media (max-width: 720px)" in _MAP_CSS and "#panel" in _MAP_CSS
|
||||||
for state in ('data-sheet="closed"', 'data-sheet="half"', 'data-sheet="full"'):
|
for state in ('data-sheet="closed"', 'data-sheet="half"', 'data-sheet="full"'):
|
||||||
assert state.split('"')[1] in _MAP_CSS, state
|
assert state.split('"')[1] in _MAP_CSS, state
|
||||||
|
|
||||||
|
|
||||||
|
def test_ui_panel_restores_tab_and_ignores_collapse_on_phone():
|
||||||
|
from lidar_pipeline.mapui import _MAP_JS
|
||||||
|
render = _MAP_JS.split("function panelRender(")[1].split("\nfunction ")[0]
|
||||||
|
# Onglet choisi gardé à part : Génération rétablie une fois /api/status connu
|
||||||
|
assert "PANEL.want = PANEL.tab;" in _MAP_JS
|
||||||
|
assert "PANEL.tab = tabs.includes(PANEL.want) ? PANEL.want : 'view';" in render
|
||||||
|
assert "tab: PANEL.want" in _MAP_JS.split("function panelSave(")[1].split("\n")[0]
|
||||||
|
assert "PANEL.want = PANEL.tab = tab;" in _MAP_JS.split("function openTab(")[1].split("\nfunction ")[0]
|
||||||
|
# Repli en bande d'icônes : ordinateur seulement
|
||||||
|
assert "PANEL.collapsed && !isPhone()" in render
|
||||||
|
assert "toggle('collapsed', PANEL.collapsed)" not in render
|
||||||
|
assert "toggle('panel-collapsed', PANEL.collapsed)" not in render
|
||||||
|
|||||||
@ -1112,6 +1112,10 @@ document.addEventListener('panel:tab', (e) => {
|
|||||||
// --- panneau à onglets --------------------------------------------------------
|
// --- panneau à onglets --------------------------------------------------------
|
||||||
const PANEL_LS = 'lidar-panel';
|
const PANEL_LS = 'lidar-panel';
|
||||||
const PANEL = Object.assign({ tab: 'view', collapsed: false, sheet: 'half' }, lsGet(PANEL_LS, {}));
|
const PANEL = Object.assign({ tab: 'view', collapsed: false, sheet: 'half' }, lsGet(PANEL_LS, {}));
|
||||||
|
// want = onglet choisi (mémorisé) ; tab = onglet affiché. Génération encore
|
||||||
|
// inconnue au démarrage (api/status) : Affichage en attendant, puis l'onglet
|
||||||
|
// choisi revient dès qu'il est proposé.
|
||||||
|
PANEL.want = PANEL.tab;
|
||||||
const phoneQuery = window.matchMedia('(max-width: 720px)');
|
const phoneQuery = window.matchMedia('(max-width: 720px)');
|
||||||
const isPhone = () => phoneQuery.matches;
|
const isPhone = () => phoneQuery.matches;
|
||||||
|
|
||||||
@ -1127,20 +1131,22 @@ function panelVisibleTab() {
|
|||||||
return PANEL.tab;
|
return PANEL.tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function panelSave() { lsSet(PANEL_LS, { tab: PANEL.tab, collapsed: PANEL.collapsed, sheet: PANEL.sheet }); }
|
function panelSave() { lsSet(PANEL_LS, { tab: PANEL.want, collapsed: PANEL.collapsed, sheet: PANEL.sheet }); }
|
||||||
|
|
||||||
function panelRender() {
|
function panelRender() {
|
||||||
const tabs = panelTabs();
|
const tabs = panelTabs();
|
||||||
if (!tabs.includes(PANEL.tab)) PANEL.tab = 'view';
|
PANEL.tab = tabs.includes(PANEL.want) ? PANEL.want : 'view';
|
||||||
el('panelTabs').querySelectorAll('button[data-tab]').forEach(b => {
|
el('panelTabs').querySelectorAll('button[data-tab]').forEach(b => {
|
||||||
b.hidden = !tabs.includes(b.dataset.tab);
|
b.hidden = !tabs.includes(b.dataset.tab);
|
||||||
b.setAttribute('aria-selected', String(b.dataset.tab === PANEL.tab));
|
b.setAttribute('aria-selected', String(b.dataset.tab === PANEL.tab));
|
||||||
});
|
});
|
||||||
for (const t of ['view', 'print', 'gen', 'share']) el('tab-' + t).hidden = t !== PANEL.tab;
|
for (const t of ['view', 'print', 'gen', 'share']) el('tab-' + t).hidden = t !== PANEL.tab;
|
||||||
const panel = el('panel');
|
const panel = el('panel');
|
||||||
panel.classList.toggle('collapsed', PANEL.collapsed);
|
// Repli en bande d'icônes : ordinateur seulement (le téléphone a son volet).
|
||||||
|
const collapsed = PANEL.collapsed && !isPhone();
|
||||||
|
panel.classList.toggle('collapsed', collapsed);
|
||||||
panel.dataset.sheet = PANEL.sheet;
|
panel.dataset.sheet = PANEL.sheet;
|
||||||
document.body.classList.toggle('panel-collapsed', PANEL.collapsed);
|
document.body.classList.toggle('panel-collapsed', collapsed);
|
||||||
// Hauteur couverte par le volet, que l'échelle, l'attribution et les messages
|
// Hauteur couverte par le volet, que l'échelle, l'attribution et les messages
|
||||||
// dégagent ; volet plein : la carte est cachée, rien à dégager (sinon ils
|
// dégagent ; volet plein : la carte est cachée, rien à dégager (sinon ils
|
||||||
// remonteraient en haut de l'écran, sur les outils).
|
// remonteraient en haut de l'écran, sur les outils).
|
||||||
@ -1159,7 +1165,7 @@ function openTab(tab) {
|
|||||||
PANEL.sheet = 'half';
|
PANEL.sheet = 'half';
|
||||||
}
|
}
|
||||||
const resized = isPhone() && PANEL.sheet !== before;
|
const resized = isPhone() && PANEL.sheet !== before;
|
||||||
PANEL.tab = tab;
|
PANEL.want = PANEL.tab = tab;
|
||||||
PANEL.collapsed = false;
|
PANEL.collapsed = false;
|
||||||
panelSave(); panelRender();
|
panelSave(); panelRender();
|
||||||
if (resized) setTimeout(panelRender, 220); // hauteur finale après la transition CSS
|
if (resized) setTimeout(panelRender, 220); // hauteur finale après la transition CSS
|
||||||
|
|||||||
Reference in New Issue
Block a user