Skip to content

Commit

Permalink
Merge pull request #109 from ImageMarkup/isic-ui-search-dropdown
Browse files Browse the repository at this point in the history
Isic UI search dropdown
  • Loading branch information
neuroelf authored Oct 14, 2024
2 parents b3d0d6b + d5d7d46 commit 1899660
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 10 deletions.
21 changes: 21 additions & 0 deletions sources/models/facets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const facets = {};

function getFacets() {
return facets;
}

function addFacet(id, values) {
facets[id] = values;
}

function getFacetOptions(facet) {
return facet.options;
}

const facetsModel = {
getFacets,
addFacet,
getFacetOptions,
};

export default facetsModel;
3 changes: 2 additions & 1 deletion sources/models/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const state = {
filteredImages: {
isImagesFiltered: false,
filteredImagesCount: 0
}
},
imagesTotalCounts: {},
};

export default state;
36 changes: 32 additions & 4 deletions sources/services/gallery/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import WZoom from "vanilla-js-wheel-zoom";
import constants from "../../constants";
import appliedFilterModel from "../../models/appliedFilters";
import collectionsModel from "../../models/collectionsModel";
import facetsModel from "../../models/facets";
import galleryImagesUrls from "../../models/galleryImagesUrls";
import filtersData from "../../models/imagesFilters";
import lesionsModel from "../../models/lesionsModel";
import selectedImages from "../../models/selectedGalleryImages";
import state from "../../models/state";
import logger from "../../utils/logger";
import util from "../../utils/util";
import filtersFormElements from "../../views/subviews/gallery/parts/filtersFormElements";
import metadataPart from "../../views/subviews/gallery/parts/metadata";
Expand All @@ -17,6 +19,8 @@ import ajax from "../ajaxActions";
import authService from "../auth";
import filterService from "./filter";
import searchButtonModel from "./searchButtonModel";
import searchSuggestService from "./searchSuggest";
import suggestService from "./suggest";

const layoutHeightAfterHide = 1;
const layoutHeightAfterShow = 32;
Expand Down Expand Up @@ -58,7 +62,8 @@ class GalleryService {
imageWindowTemplateWithoutControls,
enlargeContextMenu,
portraitClearAllFiltersTemplate,
landscapeClearAllFiltersTemplate
landscapeClearAllFiltersTemplate,
searchSuggest,
) {
this._view = view;
this._pager = pager;
Expand Down Expand Up @@ -91,6 +96,7 @@ class GalleryService {
this._enlargeContextMenu = enlargeContextMenu;
this._portraitClearAllFiltersTemplate = portraitClearAllFiltersTemplate;
this._landscapeClearAllFiltersTemplate = landscapeClearAllFiltersTemplate;
this._searchSuggest = searchSuggest;
this._init();
}

Expand Down Expand Up @@ -201,6 +207,7 @@ class GalleryService {
_init() {
const self = this;
webix.extend(this._imagesDataview, webix.OverlayBox);
this._searchInput.disable();
this._createStudyButton = this._view.$scope.getCreateStudyButton();
this._dataviewYCountSelection = this._view.$scope.getDataviewYCountSelection();
this._imageTemplate = $$(imageWindow.getViewerId());
Expand Down Expand Up @@ -313,9 +320,15 @@ class GalleryService {
}
});

this._searchInput.attachEvent("onAfterRender", () => {

});
// Suggest start
if (this._searchSuggest) {
searchSuggestService.attachEvents(
this._searchSuggest,
this._searchInput,
this._leftPanelToggleButton
);
}
// Suggest end

let dataviewSelectionId = util.getDataviewSelectionId()
? util.getDataviewSelectionId() : constants.DEFAULT_DATAVIEW_COLUMNS;
Expand Down Expand Up @@ -454,6 +467,7 @@ class GalleryService {
state.imagesOffset = offset;
}
catch (error) {
logger.error(error);
if (!this._view.$destructed) {
webix.message("DataRequest: Something went wrong");
}
Expand Down Expand Up @@ -616,6 +630,7 @@ class GalleryService {
}
}
catch (error) {
logger.error(error);
if (!this._view.$destructed) {
webix.message("ShowMetadata: Something went wrong");
}
Expand Down Expand Up @@ -1113,7 +1128,17 @@ class GalleryService {
});
});
}
const facetValues = state.imagesTotalCounts[id].map(
f => f.key
);
facetsModel.addFacet(id, facetValues);
});
if (this._searchSuggest) {
await suggestService.buildSuggestionsForFilter(this._searchSuggest);
const suggestions = suggestService.getSuggestionsForFilter();
this._searchSuggest.getList().parse(suggestions);
}
this._searchInput.enable();
let appliedFiltersArray = appliedFilterModel.getFiltersArray();
const paramFilters = this._view.$scope.getParam("filter");
if (appliedFiltersArray.length) {
Expand Down Expand Up @@ -1157,6 +1182,7 @@ class GalleryService {
if (!paramFilters && !appliedFiltersArray.length) this._reload();
}
catch (error) {
logger.error(error);
if (!this._view.$destructed) {
webix.message("Load: Something went wrong");
}
Expand Down Expand Up @@ -1204,6 +1230,7 @@ class GalleryService {
filterService.updateFiltersCounts(facets);
}
catch (error) {
logger.error(error);
if (!this._view.$destructed) {
webix.message("UpdateCount: Something went wrong");
}
Expand Down Expand Up @@ -1353,6 +1380,7 @@ class GalleryService {
this._updatePagerCount(images.count);
}
catch (error) {
logger.error(error);
if (!this._view.$destructed) {
this._view.hideProgress();
}
Expand Down
84 changes: 84 additions & 0 deletions sources/services/gallery/searchSuggest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import constants from "../../constants";
import appliedFiltersModel from "../../models/appliedFilters";
import util from "../../utils/util";

function attachEvents(searchSuggest, searchInput, toggleButton) {
const suggestList = searchSuggest.getList();

const foundCountTemplateID = webix.uid();

const foundCountTemplateConfig = {
view: "template",
css: "gallery__filter_suggest_result-template",
id: foundCountTemplateID,
template: obj => `Match ${obj.count} values`,
};

const foundCountPopup = webix.ui({
view: "popup",
css: "gallery__filter_suggest_result-popup",
id: webix.uid(),
width: searchSuggest.config.width,
height: 50,
body: foundCountTemplateConfig,
});

const foundCountTemplate = webix.$$(foundCountTemplateID);

searchSuggest.attachEvent("onBeforeShow", () => {
const searchValue = searchInput.getValue();
if (searchValue.length < 3 || toggleButton.getValue() === 1) {
searchSuggest.hide();
return false;
}
return true;
});


suggestList.detachEvent("onItemClick");

suggestList.attachEvent("onItemClick", (id, event) => {
const item = suggestList.getItem(id);
const controlId = util.getOptionId(item.key, item.value);
/** @type {webix.ui.checkbox} */
const control = $$(controlId);
if (control) {
const controlValue = control.getValue();
control.setValue(!controlValue);
}
if (!event.metaKey && !event.ctrlKey) {
suggestList.hide();
}
});

searchSuggest.attachEvent("onShow", () => {
const filters = appliedFiltersModel.getFiltersArray();
const suggestData = suggestList.serialize();
const selectedItems = [];
filters.forEach((f) => {
const found = suggestData.find((item) => {
if (f.id === item.id) {
return true;
}
return false;
});
if (found) {
selectedItems.push(f.id);
}
});
suggestList.blockEvent();
suggestList.select(selectedItems);
suggestList.unblockEvent();
foundCountTemplate.parse({count: suggestList.count()});
foundCountPopup.define("width", searchSuggest.config.width);
foundCountPopup.resize();
foundCountPopup.show(searchSuggest.getNode());
searchInput.focus();
});
}

const searchSuggestService = {
attachEvents,
};

export default searchSuggestService;
51 changes: 51 additions & 0 deletions sources/services/gallery/suggest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import constants from "../../constants";
import collectionsModel from "../../models/collectionsModel";
import facetsModel from "../../models/facets";
import imagesFilters from "../../models/imagesFilters";

const filterSuggestions = [];

function getSuggestionsForFilter() {
return filterSuggestions;
}

async function buildSuggestionsForFilter() {
const facets = facetsModel.getFacets();
const collections = collectionsModel.getPinnedCollections();
const newSuggestions = [];
const filtersData = await imagesFilters.getFiltersData();
const filterArray = [];
filterArray.push(...filtersData.map(f => f.data).flat(Infinity));
const facetsKeys = filterArray.map(f => f.id);
facetsKeys.forEach((key) => {
const values = facets[key].map((v) => {
if (key === constants.COLLECTION_KEY) {
const item = collections.find(c => c.id === v);
return {
id: `${key}|${v}`,
key,
value: item?.name ?? "",
optionId: v,
isCollection: true,
};
}
return {
id: `${key}|${v}`,
key,
value: v,
};
}).flat();
newSuggestions.push(...values);
});
if (newSuggestions.length > 0) {
filterSuggestions.length = 0;
filterSuggestions.push(...newSuggestions);
}
}

const suggestService = {
buildSuggestionsForFilter,
getSuggestionsForFilter,
};

export default suggestService;
4 changes: 3 additions & 1 deletion sources/styles/app.less
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@

@import "newstudy.less";

@import "apidocumentation.less";
@import "apidocumentation.less";

@import "suggest.less";
8 changes: 8 additions & 0 deletions sources/styles/suggest.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.gallery__filter_suggest_result-template {
font-size: large;
background-color: @btn;
color: @white-txt;
.webix_template {
text-align: center;
}
}
7 changes: 6 additions & 1 deletion sources/utils/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,10 @@ function isSafari() {
return navigator.userAgent.indexOf("Safari") > -1;
}

function isMacintosh() {
return webix.env.isMac;
}

export default {
openInNewTab,
openImageInNewTab,
Expand Down Expand Up @@ -592,6 +596,7 @@ export default {
shareFile,
isPortrait,
getFilterLabelId,
isSafari
isSafari,
isMacintosh,
};

4 changes: 3 additions & 1 deletion sources/views/subviews/gallery/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export default class GalleryView extends JetView {
const imageWindowZoomButtons = $$(imageWindow.getZoomButtonTemplateId());
const imageWindowTemplate = $$(imageWindow.getViewerId());
const imageWindowTemplateWithoutControls = $$(imageWindow.getViewerWithoutControlsId());
const searchSuggest = $$(filterPanel.getSearchSuggestID());
this._galleryService = new GalleryService(
view,
$$(ID_PAGER),
Expand Down Expand Up @@ -384,7 +385,8 @@ export default class GalleryView extends JetView {
imageWindowTemplateWithoutControls,
this.enlargeContextMenu,
null, // portraitClearAllFiltersTemplate
null // landscapeClearAllFiltersTemplate
null, // landscapeClearAllFiltersTemplate
searchSuggest,
);

// multi lesion
Expand Down
3 changes: 2 additions & 1 deletion sources/views/subviews/gallery/galleryMobile.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ export default class GalleryMobileView extends JetView {
this.imageWindowTemplate,
this.enlargeContextMenu,
portraitClearAllFiltersTemplate,
landscapeClearAllFiltersTemplate
landscapeClearAllFiltersTemplate,
null, // searchSuggest
);

this.heaaderService = new MobileHeaderService(
Expand Down
Loading

0 comments on commit 1899660

Please sign in to comment.