X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ccbc68b5600790546e073546a31b8123d5693411..HEAD:/resources/js/components/shelf-sort.js diff --git a/resources/js/components/shelf-sort.js b/resources/js/components/shelf-sort.js index 30eda5a21..b56b01980 100644 --- a/resources/js/components/shelf-sort.js +++ b/resources/js/components/shelf-sort.js @@ -1,6 +1,8 @@ -import Sortable from "sortablejs"; +import Sortable from 'sortablejs'; +import {Component} from './component'; +import {buildListActions, sortActionClickListener} from '../services/dual-lists.ts'; -class ShelfSort { +export class ShelfSort extends Component { setup() { this.elem = this.$el; @@ -8,6 +10,9 @@ class ShelfSort { this.shelfBookList = this.$refs.shelfBookList; this.allBookList = this.$refs.allBookList; this.bookSearchInput = this.$refs.bookSearch; + this.sortButtonContainer = this.$refs.sortButtonContainer; + + this.lastSort = null; this.initSortable(); this.setupListeners(); @@ -15,7 +20,7 @@ class ShelfSort { initSortable() { const scrollBoxes = this.elem.querySelectorAll('.scroll-box'); - for (let scrollBox of scrollBoxes) { + for (const scrollBox of scrollBoxes) { new Sortable(scrollBox, { group: 'shelf-books', ghostClass: 'primary-background-light', @@ -27,28 +32,30 @@ class ShelfSort { } setupListeners() { - this.elem.addEventListener('click', event => { - const sortItem = event.target.closest('.scroll-box-item'); - if (sortItem) { - event.preventDefault(); - this.sortItemClick(sortItem); - } - }); + const listActions = buildListActions(this.allBookList, this.shelfBookList); + const sortActionListener = sortActionClickListener(listActions, this.onChange.bind(this)); + this.elem.addEventListener('click', sortActionListener); - this.bookSearchInput.addEventListener('input', event => { + this.bookSearchInput.addEventListener('input', () => { this.filterBooksByName(this.bookSearchInput.value); }); + + this.sortButtonContainer.addEventListener('click', event => { + const button = event.target.closest('button[data-sort]'); + if (button) { + this.sortShelfBooks(button.dataset.sort); + } + }); } /** * @param {String} filterVal */ filterBooksByName(filterVal) { - // Set height on first search, if not already set, to prevent the distraction // of the list height jumping around if (!this.allBookList.style.height) { - this.allBookList.style.height = this.allBookList.getBoundingClientRect().height + 'px'; + this.allBookList.style.height = `${this.allBookList.getBoundingClientRect().height}px`; } const books = this.allBookList.children; @@ -60,24 +67,32 @@ class ShelfSort { } } - /** - * Called when a sort item is clicked. - * @param {Element} sortItem - */ - sortItemClick(sortItem) { - const lists = this.elem.querySelectorAll('.scroll-box'); - const newList = Array.from(lists).filter(list => sortItem.parentElement !== list); - if (newList.length > 0) { - newList[0].appendChild(sortItem); - } - this.onChange(); - } - onChange() { const shelfBookElems = Array.from(this.shelfBookList.querySelectorAll('[data-id]')); this.input.value = shelfBookElems.map(elem => elem.getAttribute('data-id')).join(','); } -} + sortShelfBooks(sortProperty) { + const books = Array.from(this.shelfBookList.children); + const reverse = sortProperty === this.lastSort; + + books.sort((bookA, bookB) => { + const aProp = bookA.dataset[sortProperty].toLowerCase(); + const bProp = bookB.dataset[sortProperty].toLowerCase(); + + if (reverse) { + return bProp.localeCompare(aProp); + } + + return aProp.localeCompare(bProp); + }); -export default ShelfSort; \ No newline at end of file + for (const book of books) { + this.shelfBookList.append(book); + } + + this.lastSort = (this.lastSort === sortProperty) ? null : sortProperty; + this.onChange(); + } + +}