refactor(ui): ensure types, resolve ci warning

This commit is contained in:
Edouard Vanbelle
2026-06-16 14:18:37 +02:00
parent 2ee0f7d74d
commit 9519c1fee2
5 changed files with 34 additions and 11 deletions
+17
View File
@@ -19,11 +19,19 @@ const state = {
}; };
/** Click an element by selector (no-op if absent). */ /** Click an element by selector (no-op if absent). */
/**
*
* @param {String} selector
*/
function click(selector) { function click(selector) {
/** @type {HTMLElement | null} */ (document.querySelector(selector))?.click(); /** @type {HTMLElement | null} */ (document.querySelector(selector))?.click();
} }
/** Activate the sidebar nav button whose label key matches `nav.<section>`. */ /** Activate the sidebar nav button whose label key matches `nav.<section>`. */
/**
*
* @param {String} section
*/
function navTo(section) { function navTo(section) {
document.querySelectorAll('.nav-item').forEach((it) => { document.querySelectorAll('.nav-item').forEach((it) => {
const key = it.querySelector('span[data-i18n]')?.getAttribute('data-i18n'); const key = it.querySelector('span[data-i18n]')?.getAttribute('data-i18n');
@@ -76,6 +84,10 @@ function render() {
.join(''); .join('');
} }
/**
*
* @param {String} query
*/
function filter(query) { function filter(query) {
const q = query.trim().toLowerCase(); const q = query.trim().toLowerCase();
state.filtered = q ? state.items.filter((c) => c.label.toLowerCase().includes(q)) : state.items.slice(); state.filtered = q ? state.items.filter((c) => c.label.toLowerCase().includes(q)) : state.items.slice();
@@ -83,6 +95,11 @@ function filter(query) {
render(); render();
} }
/**
*
* @param {number} delta
* @returns
*/
function move(delta) { function move(delta) {
if (!state.filtered.length) return; if (!state.filtered.length) return;
state.index = (state.index + delta + state.filtered.length) % state.filtered.length; state.index = (state.index + delta + state.filtered.length) % state.filtered.length;
+8 -2
View File
@@ -1011,8 +1011,14 @@ const ui = {
// Let ui.js delegation handle this container again // Let ui.js delegation handle this container again
delete filesList.dataset.managedBy; delete filesList.dataset.managedBy;
// A clickable, flat-sorting column header (Drive-style). The arrow is /**
// shown only on the active column; direction toggles on re-click. * A clickable, flat-sorting column header (Drive-style). The arrow is
* shown only on the active column; direction toggles on re-click.
* @param {String} field
* @param {String} key
* @param {String} label
* @returns {String}
*/
const sortCol = (field, key, label) => const sortCol = (field, key, label) =>
`<button type="button" class="list-header-sort" data-sort-field="${field}">` + `<button type="button" class="list-header-sort" data-sort-field="${field}">` +
`<span data-i18n="${key}">${label}</span>` + `<span data-i18n="${key}">${label}</span>` +
+1 -1
View File
@@ -50,7 +50,7 @@ function gridMetaDate(value) {
const date = value instanceof Date ? value : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value); const date = value instanceof Date ? value : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value);
if (Number.isNaN(date.getTime())) return ''; if (Number.isNaN(date.getTime())) return '';
const ageDays = (Date.now() - date.getTime()) / 86_400_000; const ageDays = (Date.now() - date.getTime()) / 86_400_000;
return ageDays > 30 ? formatDateShort(value) : formatRelativeTime(value); return ageDays > 30 ? formatDateShort(date) : formatRelativeTime(date);
} }
/** /**
+7 -7
View File
@@ -69,6 +69,13 @@ function _applyPhoto(avatar, photoUrl, name) {
// ── Component ────────────────────────────────────────────────────────────────── // ── Component ──────────────────────────────────────────────────────────────────
// Tracks the hover-tooltip cleanup for each vignette so a caller that
// re-renders the vignette (e.g. replaceChildren on a storage update) can
// dispose the previous tooltip — otherwise its body-portalled popover orphans
// and, if it was visible at re-render time, stays stuck on screen.
/** @type {WeakMap<HTMLElement, () => void>} */
const _tooltipCleanups = new WeakMap();
/** /**
* Available sizes. Each maps to a `.user-vignette--{size}` CSS modifier: * Available sizes. Each maps to a `.user-vignette--{size}` CSS modifier:
* xs → 20 px (chip avatar, small inline contexts) * xs → 20 px (chip avatar, small inline contexts)
@@ -112,13 +119,6 @@ function _applyPhoto(avatar, photoUrl, name) {
* @param {VignetteOptions} [options] * @param {VignetteOptions} [options]
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
// Tracks the hover-tooltip cleanup for each vignette so a caller that
// re-renders the vignette (e.g. replaceChildren on a storage update) can
// dispose the previous tooltip — otherwise its body-portalled popover orphans
// and, if it was visible at re-render time, stays stuck on screen.
/** @type {WeakMap<HTMLElement, () => void>} */
const _tooltipCleanups = new WeakMap();
export function createUserVignette(userId, size = 'sm', { showName = true, showEmail = false, showOrigin = true, noTooltip = false } = {}) { export function createUserVignette(userId, size = 'sm', { showName = true, showEmail = false, showOrigin = true, noTooltip = false } = {}) {
const colorIdx = _colorIndex(userId); const colorIdx = _colorIndex(userId);
+1 -1
View File
@@ -45,7 +45,7 @@ function formatQuotaSize(bytes) {
/** /**
* *
* @param {Date | number| null} value * @param {Date | string | number| null} value
* @returns {string} * @returns {string}
*/ */
function formatDateTime(value) { function formatDateTime(value) {