refactor(classifier): dedupe seltable CSS + tidy From-a-list scratch edges
- #7 seltable CSS: the classifier carried its own copy of the base seltable rules (diverged from shared/seltable.css — a stale sticky offset + a dead .seltable__filter). Bundle shared/seltable.css and keep only the classifier-specific catalog bits (.seltable__extra, .mdl-rev__input, .fromlist-*, .src-badge, #mdlTree). One source of truth, shared with tables. - #9 Clear list now confirms when it would strand files that still need a revision (on a "pending" leaf) — they stay assigned under By tracking number, but the row to finish them here is going away, so warn first. - #10 serialize() strips the transient row→keys hint (`placed`) — it's rebuilt as drops happen and was needlessly bloating every workspace autosave. (#8, renaming the internal mdl* identifiers to match "From a list", is left as deliberate churn-avoidance — purely cosmetic, spans template/css/js/tests/DOM ids, and the user-facing strings already read "From a list".) Full suite 340 passed / 0 failed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
921713d0a4
commit
51f5947716
4 changed files with 18 additions and 32 deletions
|
|
@ -26,6 +26,7 @@ concat_files \
|
||||||
"../shared/profile-menu.css" \
|
"../shared/profile-menu.css" \
|
||||||
"../shared/logo.css" \
|
"../shared/logo.css" \
|
||||||
"css/base.css" \
|
"css/base.css" \
|
||||||
|
"../shared/seltable.css" \
|
||||||
"css/layout.css" \
|
"css/layout.css" \
|
||||||
"css/spreadsheet.css" \
|
"css/spreadsheet.css" \
|
||||||
> "$css_temp"
|
> "$css_temp"
|
||||||
|
|
|
||||||
|
|
@ -628,36 +628,10 @@ input.tfile__name:focus { border-color: var(--primary); background: var(--bg); o
|
||||||
.scratch-match__tn { font-family: var(--mono, monospace); }
|
.scratch-match__tn { font-family: var(--mono, monospace); }
|
||||||
.scratch-match__conf { color: var(--text-muted); font-size: 0.72rem; width: 3rem; text-align: right; }
|
.scratch-match__conf { color: var(--text-muted); font-size: 0.72rem; width: 3rem; text-align: right; }
|
||||||
|
|
||||||
/* ── Shared selectable + autofilter table (seltable) ────────────────────── */
|
/* The base seltable rules live in shared/seltable.css (bundled by build.sh and
|
||||||
.seltable { display: flex; flex-direction: column; min-height: 0; height: 100%; }
|
shared with the tables tool); only the classifier-specific catalog bits
|
||||||
.seltable__bar { display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); flex: 0 0 auto; }
|
(.seltable__extra, .mdl-rev__input, .fromlist-*, .src-badge, #mdlTree) are
|
||||||
.seltable__filter {
|
here. */
|
||||||
flex: 1; min-width: 8rem; padding: 0.3rem 0.5rem;
|
|
||||||
border: 1px solid var(--border); border-radius: var(--radius);
|
|
||||||
background: var(--bg-secondary, var(--bg)); color: var(--text); font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
.seltable__count { color: var(--text-muted); font-size: 0.78rem; white-space: nowrap; }
|
|
||||||
.seltable__scroll { flex: 1; min-height: 0; overflow: auto; }
|
|
||||||
/* width:auto + nowrap cells → each column shrinks to fit its header/longest cell. */
|
|
||||||
.seltable__table { border-collapse: separate; border-spacing: 0; width: auto; font-size: 0.82rem; }
|
|
||||||
.seltable__table th, .seltable__table td { border-bottom: 1px solid var(--border); padding: 0.25rem 0.5rem; text-align: left; white-space: nowrap; }
|
|
||||||
.seltable__table thead th {
|
|
||||||
position: sticky; top: 0; z-index: 2; background: var(--bg-secondary, var(--bg));
|
|
||||||
color: var(--text-muted); font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
|
|
||||||
}
|
|
||||||
/* Per-column filter inputs: fill the column (min-width:0-ish) so they never
|
|
||||||
force a column wider than its header/cells. */
|
|
||||||
.seltable__table thead tr.seltable__filters th { padding: 0.08rem 0.3rem; }
|
|
||||||
.seltable__colfilter {
|
|
||||||
width: 100%; min-width: 2rem; box-sizing: border-box;
|
|
||||||
padding: 0.1rem 0.3rem; border: 1px solid var(--border); border-radius: var(--radius);
|
|
||||||
background: var(--bg); color: var(--text); font-size: 0.72rem; font-weight: 400; letter-spacing: 0; text-transform: none;
|
|
||||||
}
|
|
||||||
.seltable__row { cursor: pointer; user-select: none; }
|
|
||||||
.seltable__row:hover { background: var(--bg-hover); }
|
|
||||||
.seltable__row.is-selected { background: var(--primary-light, rgba(37,99,235,0.12)); }
|
|
||||||
.seltable__row.is-selected:hover { background: var(--primary-light, rgba(37,99,235,0.18)); }
|
|
||||||
.seltable__row.drop-hover { outline: 2px solid var(--primary); outline-offset: -2px; }
|
|
||||||
|
|
||||||
/* ── Copy destination dialog ────────────────────────────────────────────── */
|
/* ── Copy destination dialog ────────────────────────────────────────────── */
|
||||||
.copy-choice__backdrop {
|
.copy-choice__backdrop {
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,11 @@
|
||||||
transmittalTree: state.transmittalTree,
|
transmittalTree: state.transmittalTree,
|
||||||
outputName: state.outputName,
|
outputName: state.outputName,
|
||||||
config: state.config,
|
config: state.config,
|
||||||
mdlList: state.mdlList,
|
// Strip the transient row→keys hint (`placed`) — it's rebuilt as
|
||||||
|
// drops happen and would otherwise bloat every autosave.
|
||||||
|
mdlList: state.mdlList.map(function (r) {
|
||||||
|
return { id: r.id, party: r.party, trackingNumber: r.trackingNumber, title: r.title, revisionCell: r.revisionCell, source: r.source, archiveRevisions: r.archiveRevisions };
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function load(obj) {
|
function load(obj) {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,14 @@
|
||||||
if (els.pasteRowsBtn) els.pasteRowsBtn.addEventListener('click', function () { openPasteDialog(''); });
|
if (els.pasteRowsBtn) els.pasteRowsBtn.addEventListener('click', function () { openPasteDialog(''); });
|
||||||
if (els.matchNamesBtn) els.matchNamesBtn.addEventListener('click', openMatchDialog);
|
if (els.matchNamesBtn) els.matchNamesBtn.addEventListener('click', openMatchDialog);
|
||||||
if (els.clearListBtn) els.clearListBtn.addEventListener('click', function () {
|
if (els.clearListBtn) els.clearListBtn.addEventListener('click', function () {
|
||||||
if (!C().getMdlList().length) return;
|
var list = C().getMdlList();
|
||||||
|
if (!list.length) return;
|
||||||
|
// Warn before stranding files that still need a revision: they stay
|
||||||
|
// assigned (on a "pending" leaf under By tracking number), but the
|
||||||
|
// row you'd use to finish them here is about to disappear.
|
||||||
|
var pending = 0;
|
||||||
|
list.forEach(function (r) { if (!(r.revisionCell || '').trim()) pending += Object.keys(r.placed || {}).length; });
|
||||||
|
if (pending && !confirm(pending + ' file' + (pending === 1 ? '' : 's') + ' still need a revision. They stay assigned (a “pending” folder under By tracking number), but the list row to finish them here goes away. Clear anyway?')) return;
|
||||||
C().clearMdlList();
|
C().clearMdlList();
|
||||||
window.zddc.toast('List cleared — every assignment is kept (see By tracking number).', 'info');
|
window.zddc.toast('List cleared — every assignment is kept (see By tracking number).', 'info');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue