Difference between revisions of "Widget:DCTList"
From LINKS Community Center
(25 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | <noinclude> | + | <noinclude>DCT list widget.<br><span style="color: red; font-weight: bold;">Currently in use – do not modify!</span></noinclude> |
− | |||
<includeonly> | <includeonly> | ||
− | <link href="/resources/assets/tabulator.min.css" rel="stylesheet"> | + | <link href="/resources/assets/tabulator/dist/css/tabulator.min.css" rel="stylesheet"> |
− | <script type="text/javascript" src="/resources/assets/tabulator.min.js"></script> | + | <script type="text/javascript" src="/resources/assets/tabulator/dist/js/tabulator.min.js"></script> |
<style> | <style> | ||
Line 283: | Line 282: | ||
* @property {FuncData} functions | * @property {FuncData} functions | ||
* @property {string} usedByDmo | * @property {string} usedByDmo | ||
+ | * @property {string} archived | ||
* @property {string} hasUC | * @property {string} hasUC | ||
* @property {string} logo | * @property {string} logo | ||
Line 367: | Line 367: | ||
const DMO_PROP = 'Used by Practitioners'; | const DMO_PROP = 'Used by Practitioners'; | ||
const UC_PROP = 'Use Cases available'; | const UC_PROP = 'Use Cases available'; | ||
+ | const ARCHIVED = 'Is Archived'; | ||
const dctQuery = '[[Category:Disaster Community Technology]]' | const dctQuery = '[[Category:Disaster Community Technology]]' | ||
− | + '[[Is Archived::No]]' | + | // + '[[Is Archived::No]]' |
+ '|limit=500' | + '|limit=500' | ||
+ | + '|?' + ARCHIVED | ||
+ '|?' + IMG_PROP | + '|?' + IMG_PROP | ||
+ '|?' + DATASRC_PROP | + '|?' + DATASRC_PROP | ||
Line 391: | Line 393: | ||
dct.usedByDmo = dctResult.printouts[DMO_PROP][0] === 't' ? 'yes' : 'no'; // not quite, but we only care about yes | dct.usedByDmo = dctResult.printouts[DMO_PROP][0] === 't' ? 'yes' : 'no'; // not quite, but we only care about yes | ||
dct.hasUC = dctResult.printouts[UC_PROP][0] === 't' ? 'yes' : 'no'; // not quite, but we only care about yes | dct.hasUC = dctResult.printouts[UC_PROP][0] === 't' ? 'yes' : 'no'; // not quite, but we only care about yes | ||
+ | dct.archived = dctResult.printouts[ARCHIVED][0] === 't' ? 'yes' : 'no'; // not quite, but we only care about yes | ||
dct.functions = new Map(); | dct.functions = new Map(); | ||
Line 434: | Line 437: | ||
functionsCheck = checkEmpty && checkNonempty; | functionsCheck = checkEmpty && checkNonempty; | ||
+ | // TODO: Empty should no longer exist, once every category is fully listed in the filter. | ||
+ | // TODO: The filtering of functions therefore should be reduced to nonempty only. | ||
} | } | ||
Line 448: | Line 453: | ||
? filterState.hasUC === dct.hasUC | ? filterState.hasUC === dct.hasUC | ||
: true; | : true; | ||
− | return sourcesCheck && functionsCheck && businessModelCheck && dmUseCheck && ucCheck; | + | const archivedCheck = filterState.showArchived |
+ | ? true | ||
+ | : dct.archived !== 'yes'; | ||
+ | |||
+ | return sourcesCheck && functionsCheck && businessModelCheck && dmUseCheck && ucCheck && archivedCheck; | ||
} | } | ||
Line 460: | Line 469: | ||
} | } | ||
− | |||
const filterState = {}; | const filterState = {}; | ||
Line 489: | Line 497: | ||
if (document.getElementById('used-by-practitioners').checked) filterState.usedByDmo = 'yes'; | if (document.getElementById('used-by-practitioners').checked) filterState.usedByDmo = 'yes'; | ||
if (document.getElementById('has-use-case').checked) filterState.hasUC = 'yes'; | if (document.getElementById('has-use-case').checked) filterState.hasUC = 'yes'; | ||
+ | if (document.getElementById('show-archived').checked) filterState.showArchived = 'yes'; | ||
table.setFilter(dctFilter, filterState); | table.setFilter(dctFilter, filterState); | ||
Line 501: | Line 510: | ||
Array.from(functionsData).forEach(([fnCat, fnInfo], index) => { | Array.from(functionsData).forEach(([fnCat, fnInfo], index) => { | ||
const identifier = 'func-filter-' + escapeAttr(fnCat); | const identifier = 'func-filter-' + escapeAttr(fnCat); | ||
− | funcFilterHtml += | + | funcFilterHtml += |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
`<div class="func-filter-block"> | `<div class="func-filter-block"> | ||
<div> | <div> | ||
<input type="checkbox" id="${identifier}" value="${fnCat}" class="func-cat"> | <input type="checkbox" id="${identifier}" value="${fnCat}" class="func-cat"> | ||
<label for="${identifier}" title="${fnInfo[DESC_KEY]}"><img src="${fnImages[fnCat]}"> ${fnCat}</label> | <label for="${identifier}" title="${fnInfo[DESC_KEY]}"><img src="${fnImages[fnCat]}"> ${fnCat}</label> | ||
− | </div>` | + | </div>`; |
// add subfunctions | // add subfunctions | ||
− | + | funcFilterHtml += '<div class="subfunc-filter-block">'; | |
− | + | for (const func of fnInfo.functions) { | |
− | + | const subfuncId = 'subfunc-filter-' + escapeAttr(func); | |
− | + | funcFilterHtml += | |
− | + | `<div> | |
− | + | <input type="checkbox" id="${subfuncId}" value="${func}"> | |
− | + | <label for="${subfuncId}">${func}</label> | |
− | + | </div>`; | |
− | |||
− | |||
− | |||
} | } | ||
+ | funcFilterHtml += '</div>'; | ||
+ | |||
funcFilterHtml += '</div>'; | funcFilterHtml += '</div>'; | ||
}); | }); | ||
Line 583: | Line 581: | ||
field: 'name', | field: 'name', | ||
minWidth: 300, // required for responsiveness when using fitColumns | minWidth: 300, // required for responsiveness when using fitColumns | ||
+ | widthGrow: 2, | ||
formatter: function (cell) { | formatter: function (cell) { | ||
/** @type {DCT} */ | /** @type {DCT} */ | ||
const dct = cell.getData(); | const dct = cell.getData(); | ||
− | let out = '<a href="' + dct.url + '">' + dct.name + '</a><br>'; | + | let out = '<a href="' + dct.url + '" translate="no">' + dct.name + '</a><br>'; |
+ | if (dct.archived.toLowerCase() === 'yes') { | ||
+ | out += '<small><span class="badge lcc-badge-grey">Archived</span></small> '; | ||
+ | } | ||
if (dct.businessModel.includes(FREE_KEY)) { | if (dct.businessModel.includes(FREE_KEY)) { | ||
− | out += '<small><span class="badge badge- | + | out += '<small><span class="badge lcc-badge-green">' + FREE_KEY + '</span></small> '; |
} | } | ||
if (dct.businessModel.includes(FREE_PLAN_KEY)) { | if (dct.businessModel.includes(FREE_PLAN_KEY)) { | ||
− | out += '<small><span class="badge badge- | + | out += '<small><span class="badge lcc-badge-green">' + FREE_PLAN_KEY + '</span></small> '; |
} | } | ||
if (dct.usedByDmo.toLowerCase() === 'yes') { | if (dct.usedByDmo.toLowerCase() === 'yes') { | ||
− | out += '<small><span class="badge badge- | + | out += '<small><span class="badge lcc-badge-red">Used by practitioners</span></small> '; |
} | } | ||
if (dct.hasUC.toLowerCase() === 'yes') { | if (dct.hasUC.toLowerCase() === 'yes') { | ||
− | out += '<small><span class="badge badge- | + | out += '<small><span class="badge lcc-badge-purple">Use case available</span></small> '; |
} | } | ||
Line 606: | Line 608: | ||
title: 'Functions', | title: 'Functions', | ||
field: 'functions', | field: 'functions', | ||
− | minWidth: | + | minWidth: 200, // required for responsiveness when using fitColumns |
cssClass: 'functions-cell', | cssClass: 'functions-cell', | ||
formatter: function (cell) { | formatter: function (cell) { | ||
Line 657: | Line 659: | ||
tabulator.setData(dcts); | tabulator.setData(dcts); | ||
table = tabulator; | table = tabulator; | ||
+ | |||
+ | // Set up the table if parameter was passed. | ||
+ | const params = new URLSearchParams(window.location.search); | ||
+ | const encoded = params.get('do'); | ||
+ | |||
+ | if (encoded) { | ||
+ | const actions = JSON.parse(decodeURIComponent(atob(encoded))); | ||
+ | |||
+ | const filter = actions.filter; | ||
+ | if (filter) { | ||
+ | // Functions filter | ||
+ | const functions = filter.functions; | ||
+ | if (functions) { | ||
+ | Object.keys(functions).forEach(subfun => { | ||
+ | const subfunEl = document.getElementById('subfunc-filter-' + escapeAttr(subfun)); | ||
+ | subfunEl.checked = !!functions[subfun]; | ||
+ | subfunEl.dispatchEvent(new Event('change', { bubbles: true })); | ||
+ | }); | ||
+ | |||
+ | document.getElementById('functions-filter').closest('.filter-wrapper').classList.toggle('open'); | ||
+ | } | ||
+ | |||
+ | // Further filters | ||
+ | // ... | ||
+ | |||
+ | applyFilters(); | ||
+ | toggleFilter(); | ||
+ | } | ||
+ | |||
+ | // Further actions (e.g. open filter panel, etc.) | ||
+ | // ... | ||
+ | } | ||
+ | |||
+ | applyFilters(); | ||
}); | }); | ||
Line 737: | Line 773: | ||
// Listen for changes in filter checkbox state. | // Listen for changes in filter checkbox state. | ||
document.getElementById('functions-filter').addEventListener('change', event => { | document.getElementById('functions-filter').addEventListener('change', event => { | ||
− | |||
const filterBlock = event.target.closest('.func-filter-block'); | const filterBlock = event.target.closest('.func-filter-block'); | ||
const category = filterBlock.querySelector('input.func-cat'); | const category = filterBlock.querySelector('input.func-cat'); | ||
Line 818: | Line 853: | ||
) { filterPane.classList.remove('open'); } | ) { filterPane.classList.remove('open'); } | ||
}, { passive: true }); | }, { passive: true }); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</script> | </script> | ||
Line 916: | Line 919: | ||
</div> | </div> | ||
− | < | + | <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 2.5rem;"> |
+ | <h2 style="margin-bottom: 0;">Results: <span id="result-count"></span></h2> | ||
+ | <div><a href="/index.php/Form:Disaster_Community_Technology" style="color: var(--links-blue); font-size: 1.5em; font-variant:small-caps">Add new technology</a></div> | ||
+ | </div> | ||
<div id="dct-filters"> | <div id="dct-filters"> | ||
Line 993: | Line 999: | ||
<input type="checkbox" id="has-use-case" value="yes"> | <input type="checkbox" id="has-use-case" value="yes"> | ||
<label for="has-use-case">Use case available</label> | <label for="has-use-case">Use case available</label> | ||
+ | </div> | ||
+ | <div> | ||
+ | <input type="checkbox" id="show-archived" value="yes"> | ||
+ | <label for="show-archived">Show archived</label> | ||
</div> | </div> | ||
</div> | </div> |
Latest revision as of 15:30, 19 December 2023
DCT list widget.
Currently in use – do not modify!