|
|
|
|
@@ -258,21 +258,25 @@ function make_entry_row(entry, children_map) {
|
|
|
|
|
|
|
|
|
|
set_text(row, '.task-id', `#${entry.id}`);
|
|
|
|
|
|
|
|
|
|
// Type chip — only shown in "All" view
|
|
|
|
|
// Type chip — always shown, clickable to navigate to that type
|
|
|
|
|
const type_chip = row.querySelector('.entry-type-chip');
|
|
|
|
|
if (!state.active_type) {
|
|
|
|
|
const et = state.entry_types.find(t => t.id === entry.type);
|
|
|
|
|
type_chip.textContent = et ? et.title : entry.type;
|
|
|
|
|
show(type_chip);
|
|
|
|
|
}
|
|
|
|
|
const et = state.entry_types.find(t => t.id === entry.type);
|
|
|
|
|
type_chip.textContent = et ? et.title : entry.type;
|
|
|
|
|
type_chip.classList.add('clickable');
|
|
|
|
|
type_chip.addEventListener('click', (e) => { e.stopPropagation(); navigate('type/' + entry.type); });
|
|
|
|
|
show(type_chip);
|
|
|
|
|
|
|
|
|
|
const status_el = row.querySelector('.task-status');
|
|
|
|
|
status_el.textContent = entry.status;
|
|
|
|
|
status_el.dataset.val = entry.status;
|
|
|
|
|
status_el.classList.add('clickable');
|
|
|
|
|
status_el.addEventListener('click', (e) => { e.stopPropagation(); set_filter('filter_status', entry.status); });
|
|
|
|
|
|
|
|
|
|
const priority_el = row.querySelector('.task-priority');
|
|
|
|
|
priority_el.textContent = entry.priority;
|
|
|
|
|
priority_el.dataset.val = entry.priority;
|
|
|
|
|
priority_el.classList.add('clickable');
|
|
|
|
|
priority_el.addEventListener('click', (e) => { e.stopPropagation(); set_filter('filter_priority', entry.priority); });
|
|
|
|
|
|
|
|
|
|
const main_el = row.querySelector('.task-main');
|
|
|
|
|
main_el.classList.add('clickable');
|
|
|
|
|
@@ -307,8 +311,6 @@ function make_entry_row(entry, children_map) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function render_tree_node(entry, children_map) {
|
|
|
|
|
if (!entry_matches_filter(entry)) { return null; }
|
|
|
|
|
|
|
|
|
|
const children = children_map.get(entry.id) ?? [];
|
|
|
|
|
const node = document.createElement('div');
|
|
|
|
|
node.className = 'task-node';
|
|
|
|
|
@@ -318,8 +320,7 @@ function render_tree_node(entry, children_map) {
|
|
|
|
|
const children_el = document.createElement('div');
|
|
|
|
|
children_el.className = 'task-children';
|
|
|
|
|
for (const child of children) {
|
|
|
|
|
const child_node = render_tree_node(child, children_map);
|
|
|
|
|
if (child_node) { children_el.appendChild(child_node); }
|
|
|
|
|
children_el.appendChild(render_tree_node(child, children_map));
|
|
|
|
|
}
|
|
|
|
|
node.appendChild(children_el);
|
|
|
|
|
}
|
|
|
|
|
@@ -649,11 +650,10 @@ function navigate_new(type, parent_id) {
|
|
|
|
|
|
|
|
|
|
function build_url(hash) {
|
|
|
|
|
const params = new URLSearchParams();
|
|
|
|
|
if (state.filter_status !== 'open') { params.set('status', state.filter_status || 'all'); }
|
|
|
|
|
if (state.filter_priority) { params.set('priority', state.filter_priority); }
|
|
|
|
|
if (state.search) { params.set('search', state.search); }
|
|
|
|
|
const qs = params.toString();
|
|
|
|
|
return (qs ? '?' + qs : '') + '#' + hash;
|
|
|
|
|
params.set('status', state.filter_status || 'all');
|
|
|
|
|
if (state.filter_priority) { params.set('priority', state.filter_priority); }
|
|
|
|
|
if (state.search) { params.set('search', state.search); }
|
|
|
|
|
return '?' + params.toString() + '#' + hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function apply_search() {
|
|
|
|
|
@@ -761,19 +761,22 @@ function render_entry_detail(container) {
|
|
|
|
|
const type_chip = document.createElement('span');
|
|
|
|
|
type_chip.className = 'entry-type-chip';
|
|
|
|
|
type_chip.textContent = et.title;
|
|
|
|
|
type_chip.addEventListener('click', () => navigate('type/' + entry.type));
|
|
|
|
|
meta.appendChild(type_chip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const status_el = document.createElement('span');
|
|
|
|
|
status_el.className = 'task-status';
|
|
|
|
|
status_el.className = 'task-status clickable';
|
|
|
|
|
status_el.textContent = entry.status;
|
|
|
|
|
status_el.dataset.val = entry.status;
|
|
|
|
|
status_el.addEventListener('click', () => { state.filter_status = entry.status; navigate('type/' + entry.type); });
|
|
|
|
|
meta.appendChild(status_el);
|
|
|
|
|
|
|
|
|
|
const priority_el = document.createElement('span');
|
|
|
|
|
priority_el.className = 'task-priority';
|
|
|
|
|
priority_el.className = 'task-priority clickable';
|
|
|
|
|
priority_el.textContent = entry.priority;
|
|
|
|
|
priority_el.dataset.val = entry.priority;
|
|
|
|
|
priority_el.addEventListener('click', () => { state.filter_priority = entry.priority; navigate('type/' + entry.type); });
|
|
|
|
|
meta.appendChild(priority_el);
|
|
|
|
|
|
|
|
|
|
for (const tag of entry.tags) {
|
|
|
|
|
|