Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hierarchical diagnosis facet metadata in the selection tree #110

Merged
merged 23 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
<symbol viewBox="0 0 26 26" id="close-icon">
<path d="M13 0C5.832 0 0 5.832 0 13s5.832 13 13 13 13-5.832 13-13S20.168 0 13 0zm0 2c6.086 0 11 4.914 11 11s-4.914 11-11 11S2 19.086 2 13 6.914 2 13 2zM9.22 7.78L7.78 9.22 11.563 13l-3.78 3.78 1.437 1.44L13 14.437l3.78 3.78 1.44-1.437L14.437 13l3.78-3.78-1.437-1.44L13 11.563l-3.78-3.78z"></path>
</symbol>
<symbol viewBox="0 0 24 24" id="remove-filter-icon">
<path d="M8.5 9C8.10948 9.39052 8.10948 10.0237 8.5 10.4142L10.3358 12.25L8.5 14.0858C8.10948 14.4763 8.10948 15.1095 8.5 15.5C8.89052 15.8905 9.52369 15.8905 9.91421 15.5L11.75 13.6642L13.5858 15.5C13.9763 15.8905 14.6095 15.8905 15 15.5C15.3905 15.1095 15.3905 14.4763 15 14.0858L13.1642 12.25L15 10.4142C15.3905 10.0237 15.3905 9.39052 15 9C14.6095 8.60948 13.9763 8.60948 13.5858 9L11.75 10.8358L9.91421 9C9.52369 8.60948 8.89052 8.60948 8.5 9Z" fill="#9799A0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12ZM22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" fill="#9799A0"/>"
</symbol>
<symbol viewBox="0 0 26 26" id="diagnosis-icon">
<path d="M11 4L9 6v2H6c-1.142 0-1.864 1-2 2L3 20c-.108 1 .557 2 2 2h16c1.444 0 2.108-1 2-2l-1-10c-.136-1-.955-2-2-2h-3V6l-2-2h-4zm0 2h4v2h-4V6zm1 5h2v3h3v2h-3v3h-2v-3H9v-2h3v-3z"></path>
</symbol>
Expand Down
6 changes: 6 additions & 0 deletions sources/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,10 @@ export default {
MULTI_LESION_TYPE_PRIORITY: {
FIRST: "dermoscopic"
},
DIAGNOSIS_SEPARATOR: ":",
FILTER_ELEMENT_TYPE: {
CHECKBOX: "checkbox",
TREE_CHECKBOX: "treeCheckbox",
RANGE_CHECKBOX: "rangeCheckbox",
},
};
151 changes: 146 additions & 5 deletions sources/models/appliedFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function prepareDataForList() {
switch (filter.view) {
case "checkbox":
case "rangeCheckbox":
case constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX:
{
result.push(webix.copy(filter));
break;
Expand Down Expand Up @@ -98,6 +99,21 @@ function processNewFilter(filter) {
}
break;
}
case constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX: {
const optionId = filter.optionId;
if (filter.remove) {
if (appliedFilters.exists(optionId)) {
appliedFilters.remove(optionId);
}
}
else {
filter.id = optionId;
if (!appliedFilters.exists(optionId)) {
appliedFilters.add(filter);
}
}
break;
}
case "rangeSlider":
{
break;
Expand Down Expand Up @@ -356,6 +372,20 @@ function _groupFiltersByKey() {
});
break;
}
case constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX: {
let itemFromResult = result.find(comparedItem => comparedItem.key === `${item.key}_${item.diagnosisLevel}`, true);
if (!itemFromResult) {
itemFromResult = {
view: item.view,
key: `${item.key}_${item.diagnosisLevel}`,
datatype: item.datatype,
values: []
};
result.push(itemFromResult);
}
itemFromResult.values.push(_prepareOptionNameForApi(item.value, `${item.key}_${item.diagnosisLevel}`));
break;
}
default:
{
break;
Expand All @@ -369,6 +399,7 @@ function _prepareCondition(filter) {
let result = [];
switch (filter.view) {
case "checkbox":
case constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX:
{
_prepareValuesCondition(filter, result);
break;
Expand All @@ -390,15 +421,46 @@ function _prepareCondition(filter) {
function getConditionsForApi() {
const conditions = {};
conditions.operands = [];
const diagnosisRegex = /^diagnosis_\d$/;
const diagnosisFilters = _groupFiltersByKey().filter(f => diagnosisRegex.test(f.key));
const groupedFilters = _groupFiltersByKey()
.filter(groupedFilter => groupedFilter.key !== constants.COLLECTION_KEY);
.filter(groupedFilter => groupedFilter.key !== constants.COLLECTION_KEY
&& !diagnosisRegex.test(groupedFilter.key));
if (diagnosisFilters.length !== 0) {
conditions.operator = diagnosisFilters.length > 1 ? "OR" : "";
diagnosisFilters.forEach((d) => {
conditions.operands.push(...(_prepareCondition(d)));
});
}
let query = diagnosisFilters.length > 0 ? "(" : "";
conditions.operands.forEach((itemOfConditions, paramIndex) => {
if (paramIndex > 0) {
if (itemOfConditions.operator.toUpperCase() === "OR") {
query += itemOfConditions.type === "number" || itemOfConditions.type === "boolean" || itemOfConditions.value.includes("[")
? ` ${itemOfConditions.operator.toUpperCase()} ${itemOfConditions.key}:${itemOfConditions.value}${itemOfConditions.closingBracket}`
: ` ${itemOfConditions.operator.toUpperCase()} ${itemOfConditions.key}:"${itemOfConditions.value}"${itemOfConditions.closingBracket}`;
}
else {
query += itemOfConditions.type === "number" || itemOfConditions.type === "boolean" || itemOfConditions.value.includes("[")
? ` ${conditions.operator.toUpperCase()} ${itemOfConditions.openingBracket}${itemOfConditions.key}:${itemOfConditions.value}`
: ` ${conditions.operator.toUpperCase()} ${itemOfConditions.openingBracket}${itemOfConditions.key}:"${itemOfConditions.value}"`;
}
}
else {
query += itemOfConditions.type === "number" || itemOfConditions.type === "boolean" || itemOfConditions.value.includes("[")
? `${itemOfConditions.openingBracket}${itemOfConditions.key}:${itemOfConditions.value}${itemOfConditions.closingBracket}`
: `${itemOfConditions.openingBracket}${itemOfConditions.key}:"${itemOfConditions.value}"${itemOfConditions.closingBracket}`;
}
});
query += query === "" ? "" : ")";
conditions.operands.length = 0;
if (groupedFilters.length !== 0) {
query += query === "" ? "" : " AND ";
conditions.operator = groupedFilters.length > 1 ? "AND" : "";
groupedFilters.forEach((groupedFilter) => {
conditions.operands.push(...(_prepareCondition(groupedFilter)));
});
}
let query = "";
conditions.operands.forEach((itemOfConditions, paramIndex) => {
if (paramIndex > 0) {
if (itemOfConditions.operator.toUpperCase() === "OR") {
Expand Down Expand Up @@ -446,7 +508,19 @@ function getFiltersFromURL(filtersArray) {
.map((filter) => {
let filterId;
if (typeof filter === "object") {
filterId = filter.id;
if (filter.type === constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX) {
const view = $$(filter.viewId);
const item = view.getItem(filter.optionId);
const treeData = state.filtersTreeData.get(filter.viewId);
const data = getFiltersChangeTreeItemData(
treeData,
item,
item.datatype,
false,
);
return data;
}
return null;
}
else if (filter.includes(constants.COLLECTION_KEY)) {
const pinnedCollections = collectionsModel.getPinnedCollections();
Expand All @@ -470,7 +544,71 @@ function getFiltersFromURL(filtersArray) {
}

function convertAppliedFiltersToParams() {
return JSON.stringify(getFiltersArray().map(filter => filter.id));
return JSON.stringify(getFiltersArray().map((filter) => {
if (filter.view === constants.FILTER_ELEMENT_TYPE.TREE_CHECKBOX) {
return {type: filter.view, viewId: filter.viewId, optionId: filter.optionId};
}
return filter.id;
}));
}

function getAppliedCollectionsForApi() {
const filtersArray = getFiltersArray();
const appliedCollections = filtersArray
.filter(filter => filter.key === constants.COLLECTION_KEY);
const result = appliedCollections.map(collection => collection.optionId);
return result.length > 0 ? result.join(",") : "";
}

/**
* Get filters changed data for checkboxes
* @param {object} data
* @param {object} currentOption
* @param {String} optionName
*/
function getFiltersChangedData(data, currentOption, optionName) {
const filtersChangedData = {};
filtersChangedData.view = data.type;
filtersChangedData.datatype = data.datatype;
filtersChangedData.key = data.id;
filtersChangedData.filterName = data.name;
filtersChangedData.value = optionName;
filtersChangedData.optionId = currentOption.optionId;
filtersChangedData.status = "equals";
if (currentOption && data.type === "rangeCheckbox") {
filtersChangedData.to = currentOption.to;
filtersChangedData.from = currentOption.from;
}
return filtersChangedData;
}

/**
*
* @param {object} data
* @param {object} item
* @param {String} datatype
* @param {boolean} state
*/
function getFiltersChangeTreeItemData(data, item, datatype, remove) {
const filtersChangedData = {};
filtersChangedData.view = data.type;
filtersChangedData.datatype = datatype;
filtersChangedData.key = data.labelId;
filtersChangedData.filterName = data.name;
filtersChangedData.value = getTreeOptionValueById(item.id);
filtersChangedData.status = "equals";
filtersChangedData.treeCheckboxFlag = true;
filtersChangedData.diagnosisLevel = item.$level;
filtersChangedData.optionId = item.id;
filtersChangedData.viewId = `treeTable-${data.id}`;
filtersChangedData.remove = remove;
return filtersChangedData;
}

function getTreeOptionValueById(id) {
const separator = "|";
const array = id.split(separator);
return array.at(array.length - 1);
}

export default {
Expand All @@ -489,7 +627,10 @@ export default {
getFilterValue,
getShowedFiltersCollection,
getFiltersFromURL,
convertAppliedFiltersToParams
convertAppliedFiltersToParams,
getAppliedCollectionsForApi,
getFiltersChangedData,
getFiltersChangeTreeItemData,
};

// TODO: rewrite example
Expand Down
42 changes: 0 additions & 42 deletions sources/models/collectionsModel.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
import constants from "../constants";
import filtersModel from "./appliedFilters";

const allCollections = [];
let allCollectionsNextLink = null;
let allCollectionsPrevLink = null;
const pinnedCollections = [];
let pinnedCollectionsNextLink = null;
let pinnedCollectionsPrevLink = null;

function getAllCollections() {
return allCollections;
}

function getAllCollectionsNextLink() {
return allCollectionsNextLink;
}

function getAllCollectionsPrevLink() {
return allCollectionsPrevLink;
}

function setAllCollectionsData(collectionsData) {
allCollections.push(...collectionsData.results);
allCollectionsNextLink = collectionsData.next;
allCollectionsPrevLink = collectionsData.previous;
}

function clearAllCollections() {
allCollections.length = 0;
}

function getPinnedCollections() {
return pinnedCollections;
}
Expand Down Expand Up @@ -59,25 +31,11 @@ function updateCollections(buckets) {
});
}

function getAppliedCollectionsForApi() {
const appliedFilters = filtersModel.getFiltersArray();
const appliedCollections = appliedFilters
.filter(filter => filter.key === constants.COLLECTION_KEY);
const result = appliedCollections.map(collection => collection.optionId);
return result.length > 0 ? result.join(",") : "";
}

export default {
getAllCollections,
getAllCollectionsNextLink,
getAllCollectionsPrevLink,
setAllCollectionsData,
clearAllCollections,
getPinnedCollections,
getPinnedCollectionsNextLink,
getPinnedCollectionsPrevLink,
setPinnedCollections,
clearPinnedCollections,
updateCollections,
getAppliedCollectionsForApi
};
Loading