diff --git a/ui/media/js/searchable-models.js b/ui/media/js/searchable-models.js index 1e02cb98..86c5c068 100644 --- a/ui/media/js/searchable-models.js +++ b/ui/media/js/searchable-models.js @@ -495,44 +495,11 @@ class ModelDropdown return { width, height } } - flattenModelList(models, path) { - models.forEach(entry => { - if (Array.isArray(entry)) { - this.flattenModelList(entry[1], path + '/' + entry[0]) - } - else - { - this.flatModelList.push(path == '' ? entry : path + '/' + entry) - } - }) - } - - // sort models - getFolder(model) { - return model.substring(0, model.lastIndexOf('/') + 1) - } - - sortModels(models) { - // sort the models in alphabetical order, root folder models last - models.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())) - - /* - // sort the models in alphabetical order, root folder models first - models = models.sort() - let found - do { - found = false - for (let i = 0; i < models.length - 1; i++) { - if ( - (this.getFolder(models[i]) === this.getFolder(models[i+1]) && models[i].toLowerCase().localeCompare(models[i+1].toLowerCase()) > 0) // same folder, sort by alphabetical order - || (this.getFolder(models[i]).toLowerCase().localeCompare(this.getFolder(models[i+1]).toLowerCase()) > 0) // L1 folder > L2 folder - ) { - [models[i], models[i+1]] = [models[i+1], models[i]] - found = true - } - } - } while (found) - */ + /** + * @param {Array} models + */ + sortStringArray(models) { + models.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })) } populateModels() { @@ -550,12 +517,16 @@ class ModelDropdown } createDropdown() { - // prepare to sort the models - this.flattenModelList(this.inputModels, '') - this.sortModels(this.flatModelList) - // create dropdown entries - this.modelFilter.insertAdjacentHTML('afterend', this.parseModels(this.flatModelList)) + this.modelFilter.insertAdjacentElement('afterend', this.createRootModelList(this.inputModels)) + this.modelFilter.insertAdjacentElement( + 'afterend', + this.createElement( + 'i', + { id: `${this.modelFilter.id}-model-filter-arrow` }, + ['model-selector-arrow', 'fa-solid', 'fa-angle-down'], + ), + ) this.modelFilter.classList.add('model-selector') this.modelFilterArrow = document.querySelector(`#${this.modelFilter.id}-model-filter-arrow`) // if (this.modelFilterArrow) { @@ -581,47 +552,122 @@ class ModelDropdown this.selectEntry(this.activeModel) } - parseModels(models) { - let html = ` - ' + + const childFolderNames = Array.from(foldersMap.keys()) + this.sortStringArray(childFolderNames) + const folderElements = childFolderNames.map(name => foldersMap.get(name)) + + const modelNames = Array.from(modelsMap.keys()) + this.sortStringArray(modelNames) + const modelElements = modelNames.map(name => modelsMap.get(name)) + + if (modelElements.length && folderName) { + listElement.appendChild(this.createElement('li', undefined, ['model-folder'], folderName)) } - - html += ` - - - - ` - return html + + const allModelElements = isRootFolder ? [...folderElements, ...modelElements] : [...modelElements, ...folderElements] + allModelElements.forEach(e => listElement.appendChild(e)) + return listElement + } + + /** + * @param {object} modelTree + * @returns {HTMLElement} + */ + createRootModelList(modelTree) { + const rootList = this.createElement( + 'ul', + { id: `${this.modelFilter.id}-model-list` }, + ['model-list'], + ) + rootList.appendChild( + this.createElement( + 'li', + { id: `${this.modelFilter.id}-model-no-result` }, + ['model-no-result'], + 'No result' + ), + ) + + if (this.noneEntry) { + rootList.appendChild( + this.createElement( + 'li', + { 'data-path': '' }, + ['model-file', 'in-root-folder'], + this.noneEntry, + ), + ) + } + + const containerListItem = this.createElement( + 'li', + { id: `${this.modelFilter.id}-model-result` }, + ['model-result'], + ) + containerListItem.appendChild(this.createModelNodeList(undefined, modelTree, true)) + rootList.appendChild(containerListItem) + + return rootList } }