feat(entries): Precedent / Suivant parmi les entrees ouvertes
Fleches dans l'en-tete du panneau et Alt+fleches, comme un navigateur : un clic par erreur dans une liste filtree ne force plus a refaire la recherche. Historique en memoire (50), vide au verrouillage ; la navigation repasse par openSlideOver et sa confirmation de modifications non enregistrees. Logique pure testee (history.test.js). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -156,6 +156,8 @@ function loadApp(overrides = {}) {
|
||||
syncIsGitea, giteaUnwrap, syncSnapshotsEqual,
|
||||
// metadata-at-rest
|
||||
withEncryptedMeta, decryptEntryMeta, ENCRYPTED_META_FIELDS,
|
||||
// historique des entrees ouvertes
|
||||
entryHistoryPush, entryHistoryTarget, ENTRY_HISTORY_MAX,
|
||||
};
|
||||
`;
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// Historique Precedent / Suivant des entrees ouvertes (js/app.js).
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { loadApp } = require('./harness.js');
|
||||
|
||||
const T = loadApp().__test;
|
||||
const fresh = () => ({ ids: [], pos: -1 });
|
||||
const all = () => true;
|
||||
|
||||
test('ouvrir A puis B : Precedent vise A, Suivant rien', () => {
|
||||
const h = fresh();
|
||||
T.entryHistoryPush(h, 1); T.entryHistoryPush(h, 2);
|
||||
assert.deepEqual(h.ids, [1, 2]);
|
||||
assert.equal(h.ids[T.entryHistoryTarget(h, -1, all)], 1);
|
||||
assert.equal(T.entryHistoryTarget(h, +1, all), -1);
|
||||
});
|
||||
|
||||
test('meme entree deux fois : pas de doublon', () => {
|
||||
const h = fresh();
|
||||
T.entryHistoryPush(h, 1); T.entryHistoryPush(h, 1);
|
||||
assert.deepEqual(h.ids, [1]);
|
||||
});
|
||||
|
||||
test('revenir puis ouvrir ailleurs oublie les suivants', () => {
|
||||
const h = fresh();
|
||||
[1, 2, 3].forEach(id => T.entryHistoryPush(h, id));
|
||||
h.pos = 0; // revenu sur 1
|
||||
T.entryHistoryPush(h, 4);
|
||||
assert.deepEqual(h.ids, [1, 4]);
|
||||
assert.equal(h.pos, 1);
|
||||
});
|
||||
|
||||
test('une entree supprimee est sautee', () => {
|
||||
const h = fresh();
|
||||
[1, 2, 3].forEach(id => T.entryHistoryPush(h, id));
|
||||
const exists = id => id !== 2;
|
||||
assert.equal(h.ids[T.entryHistoryTarget(h, -1, exists)], 1);
|
||||
assert.equal(T.entryHistoryTarget(h, -1, id => id === 3), -1);
|
||||
});
|
||||
|
||||
test('historique borne', () => {
|
||||
const h = fresh();
|
||||
for (let i = 0; i < T.ENTRY_HISTORY_MAX + 10; i++) T.entryHistoryPush(h, i);
|
||||
assert.equal(h.ids.length, T.ENTRY_HISTORY_MAX);
|
||||
assert.equal(h.pos, T.ENTRY_HISTORY_MAX - 1);
|
||||
});
|
||||
Reference in New Issue
Block a user