Collapse to learn, review, callible into one column
This commit is contained in:
parent
cccfba0712
commit
58c4dc08f3
3 changed files with 51 additions and 34 deletions
46
app.js
46
app.js
|
|
@ -241,9 +241,7 @@ const filters = {
|
|||
modal: null,
|
||||
instrument: null,
|
||||
tuning: null,
|
||||
callable: null,
|
||||
review: null,
|
||||
to_learn: null,
|
||||
status: null,
|
||||
difficulty: null,
|
||||
};
|
||||
|
||||
|
|
@ -251,8 +249,8 @@ const popover = $('filter-popover');
|
|||
const popoverInner = $('filter-popover-inner');
|
||||
let activeFilterKey = null;
|
||||
|
||||
const BOOL_FILTERS = new Set(['modal', 'callable', 'review', 'to_learn']);
|
||||
const DROPDOWN_FILTERS = new Set(['source', 'instrument', 'tuning', 'difficulty']);
|
||||
const BOOL_FILTERS = new Set(['modal']);
|
||||
const DROPDOWN_FILTERS = new Set(['source', 'instrument', 'tuning', 'difficulty', 'status']);
|
||||
|
||||
function openFilterPopover(key, thEl) {
|
||||
if (activeFilterKey === key) { closeFilterPopover(); return; }
|
||||
|
|
@ -267,7 +265,7 @@ function openFilterPopover(key, thEl) {
|
|||
if (filters[key] === true) { cb.checked = true; cb.indeterminate = false; }
|
||||
else if (filters[key] === false) { cb.checked = false; cb.indeterminate = true; }
|
||||
else { cb.checked = false; cb.indeterminate = false; }
|
||||
const names = { modal: 'Modal', callable: 'Callable', review: 'Needs review', to_learn: 'To learn' };
|
||||
const names = { modal: 'Modal' };
|
||||
label.appendChild(cb);
|
||||
label.appendChild(document.createTextNode(names[key] ?? key));
|
||||
popoverInner.appendChild(label);
|
||||
|
|
@ -328,6 +326,7 @@ function buildDropdownOptions(key) {
|
|||
if (key === 'instrument') return [...none, ...allInstruments.map(i => [String(i.id), i.name])];
|
||||
if (key === 'tuning') return [...none, ...allTunings.map(t => [String(t.id), t.name])];
|
||||
if (key === 'difficulty') return [...none, ['easy', 'Easy'], ['hard', 'Hard']];
|
||||
if (key === 'status') return [...none, ['callable', 'Callable'], ['review', 'Needs Review'], ['to_learn', 'To Learn']];
|
||||
return none;
|
||||
}
|
||||
|
||||
|
|
@ -367,9 +366,7 @@ function rowMatchesFilters(tune, entry) {
|
|||
if (filters.instrument && (!entry || String(entry.instrument_id) !== filters.instrument)) return false;
|
||||
if (entry) {
|
||||
if (filters.tuning && String(entry.tuning_id) !== filters.tuning) return false;
|
||||
if (filters.callable !== null && entry.callable !== filters.callable) return false;
|
||||
if (filters.review !== null && entry.review !== filters.review) return false;
|
||||
if (filters.to_learn !== null && entry.to_learn !== filters.to_learn) return false;
|
||||
if (filters.status && entry.status !== filters.status) return false;
|
||||
if (filters.difficulty && entry.difficulty?.toLowerCase() !== filters.difficulty) return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -420,11 +417,7 @@ function renderTable() {
|
|||
? (tune.modal ? `${tune.key} modal` : tune.key)
|
||||
: (tune.modal ? 'modal' : '');
|
||||
const metaRaw = [instStr, keyStr].filter(Boolean).join(' · ');
|
||||
const mobPills = entry ? [
|
||||
`<span class="pill mob-pill ${entry.callable ? 'pill-yes' : 'pill-dim'}">Call</span>`,
|
||||
`<span class="pill mob-pill ${entry.review ? 'pill-warn' : 'pill-dim'}">Rev</span>`,
|
||||
`<span class="pill mob-pill ${entry.to_learn ? 'pill-warn' : 'pill-dim'}">Lrn</span>`,
|
||||
].join('') : '';
|
||||
const mobPills = entry ? pillStatus(entry.status, 'mob-pill') : '';
|
||||
const mobActions = [
|
||||
hasNotes ? `<button class="action-btn btn-notes" data-tune-id="${tune.id}" data-entry-id="${entry?.id ?? ''}">📝</button>` : '',
|
||||
tune.references?.length > 0 ? `<button class="action-btn btn-show-refs" data-tune-id="${tune.id}">🔗</button>` : '',
|
||||
|
|
@ -439,9 +432,7 @@ function renderTable() {
|
|||
<td>${tune.modal ? '<span class="pill pill-yes">Yes</span>' : '<span class="pill" style="background:#222">—</span>'}</td>
|
||||
<td>${esc(entry?.instrument_name ?? '')}</td>
|
||||
<td>${esc(entry?.tuning ?? '')}</td>
|
||||
<td>${pillBool(entry?.callable)}</td>
|
||||
<td>${pillBool(entry?.review, true)}</td>
|
||||
<td>${pillBool(entry?.to_learn, false, true)}</td>
|
||||
<td>${pillStatus(entry?.status)}</td>
|
||||
<td>${hasNotes
|
||||
? `<button class="action-btn btn-notes" data-tune-id="${tune.id}" data-entry-id="${entry?.id ?? ''}">📝</button>`
|
||||
: ''}</td>
|
||||
|
|
@ -486,6 +477,14 @@ function pillBool(val, warnIfTrue = false, neutralIfTrue = false) {
|
|||
return '<span class="pill pill-no">No</span>';
|
||||
}
|
||||
|
||||
function pillStatus(status, extraClass = '') {
|
||||
const c = extraClass ? ' ' + extraClass : '';
|
||||
if (status === 'callable') return `<span class="pill pill-yes${c}">Callable</span>`;
|
||||
if (status === 'review') return `<span class="pill pill-warn${c}">Needs Review</span>`;
|
||||
if (status === 'to_learn') return `<span class="pill pill-to-learn${c}">To Learn</span>`;
|
||||
return `<span class="pill pill-dim${c}">—</span>`;
|
||||
}
|
||||
|
||||
// ── Add / Edit modal ──────────────────────────────────────────
|
||||
btnAddTune.addEventListener('click', openAdd);
|
||||
|
||||
|
|
@ -524,9 +523,7 @@ function openEdit(tuneId, entryId) {
|
|||
tuneForm.elements.inst_tuning.value = entry.tuning ?? '';
|
||||
tuneForm.elements.inst_learned_from.value = entry.learned_from ?? '';
|
||||
tuneForm.elements.inst_date_learned.value = entry.date_learned ?? '';
|
||||
tuneForm.elements.inst_callable.checked = !!entry.callable;
|
||||
tuneForm.elements.inst_review.checked = !!entry.review;
|
||||
tuneForm.elements.inst_to_learn.checked = !!entry.to_learn;
|
||||
tuneForm.elements.inst_status.value = entry.status ?? '';
|
||||
tuneForm.elements.inst_difficulty.value = entry.difficulty ?? '';
|
||||
}
|
||||
|
||||
|
|
@ -657,9 +654,7 @@ async function saveTune() {
|
|||
tuning_id: resolveTuningId(f.inst_tuning.value),
|
||||
learned_from_id: resolveMusicianId(f.inst_learned_from.value),
|
||||
date_learned: f.inst_date_learned.value || null,
|
||||
callable: f.inst_callable.checked,
|
||||
review: f.inst_review.checked,
|
||||
to_learn: f.inst_to_learn.checked,
|
||||
status: f.inst_status.value || null,
|
||||
difficulty: f.inst_difficulty.value || null,
|
||||
} : null;
|
||||
|
||||
|
|
@ -891,7 +886,7 @@ function callGetEntries() {
|
|||
const result = [];
|
||||
for (const tune of allTunes)
|
||||
for (const entry of tune.instruments)
|
||||
if (entry[callMode]) result.push({ tune, entry });
|
||||
if (entry.status === callMode) result.push({ tune, entry });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -986,8 +981,7 @@ function callSelect(value, modal) {
|
|||
callStep = 2;
|
||||
renderCallStep();
|
||||
} else {
|
||||
filters.callable = callMode === 'callable' ? true : null;
|
||||
filters.to_learn = callMode === 'to_learn' ? true : null;
|
||||
filters.status = callMode;
|
||||
filters.instrument = callInstrumentId !== null ? String(callInstrumentId) : null;
|
||||
filters.tuning = callTuningId !== null ? String(callTuningId) : null;
|
||||
filters.key = value;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue