From a3e7e754b94a77e6608e1bd35316f849c514a8e5 Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Fri, 27 Jan 2023 11:16:17 +0000 Subject: [PATCH] Improves sortable ux - Fixes multi-select functionality. - Updated other books to be sticky. - Added some general intro/desc text. - Updated sort boxes to be collapsible. - Cleaned up other books styling. --- resources/js/components/book-sort.js | 12 +++++++----- resources/lang/en/entities.php | 2 ++ resources/sass/_layout.scss | 5 +++++ resources/sass/_lists.scss | 14 ++++++++++++++ resources/sass/styles.scss | 3 +++ .../views/books/parts/sort-box.blade.php | 19 +++++++++++++------ resources/views/books/sort.blade.php | 11 +++++++---- 7 files changed, 51 insertions(+), 15 deletions(-) diff --git a/resources/js/components/book-sort.js b/resources/js/components/book-sort.js index 3ffadf991..2722eb586 100644 --- a/resources/js/components/book-sort.js +++ b/resources/js/components/book-sort.js @@ -1,4 +1,4 @@ -import Sortable from "sortablejs"; +import Sortable, {MultiDrag} from "sortablejs"; import {Component} from "./component"; import {htmlToDom} from "../services/dom"; @@ -44,6 +44,8 @@ export class BookSort extends Component { this.sortContainer = this.$refs.sortContainer; this.input = this.$refs.input; + Sortable.mount(new MultiDrag()); + const initialSortBox = this.container.querySelector('.sort-box'); this.setupBookSortable(initialSortBox); this.setupSortPresets(); @@ -104,7 +106,7 @@ export class BookSort extends Component { } /** - * Setup the given book container element to have sortable items. + * Set up the given book container element to have sortable items. * @param {Element} bookContainer */ setupBookSortable(bookContainer) { @@ -125,8 +127,8 @@ export class BookSort extends Component { } }; - for (let sortElem of sortElems) { - new Sortable(sortElem, { + for (const sortElem of sortElems) { + Sortable.create(sortElem, { group: sortElem.classList.contains('sort-list') ? bookGroupConfig : chapterGroupConfig, animation: 150, fallbackOnBody: true, @@ -135,7 +137,7 @@ export class BookSort extends Component { dragClass: 'bg-white', ghostClass: 'primary-background-light', multiDrag: true, - multiDragKey: 'CTRL', + multiDragKey: 'Control', selectedClass: 'sortable-selected', }); } diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index fa2586f8d..5b019e848 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -141,6 +141,7 @@ return [ 'books_search_this' => 'Search this book', 'books_navigation' => 'Book Navigation', 'books_sort' => 'Sort Book Contents', + 'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books.', 'books_sort_named' => 'Sort Book :bookName', 'books_sort_name' => 'Sort by Name', 'books_sort_created' => 'Sort by Created Date', @@ -148,6 +149,7 @@ return [ 'books_sort_chapters_first' => 'Chapters First', 'books_sort_chapters_last' => 'Chapters Last', 'books_sort_show_other' => 'Show Other Books', + 'books_sort_show_other_desc' => 'Add other books here to include them in the sort operation, and allow easy cross-book reorganisation.', 'books_sort_save' => 'Save New Order', 'books_copy' => 'Copy Book', 'books_copy_success' => 'Book successfully copied', diff --git a/resources/sass/_layout.scss b/resources/sass/_layout.scss index 4c7de600b..3fc419046 100644 --- a/resources/sass/_layout.scss +++ b/resources/sass/_layout.scss @@ -268,6 +268,11 @@ body.flexbox { } } +.sticky-top-m { + position: sticky; + top: $-m; +} + /** * Visibility */ diff --git a/resources/sass/_lists.scss b/resources/sass/_lists.scss index 86a89051f..1ae801267 100644 --- a/resources/sass/_lists.scss +++ b/resources/sass/_lists.scss @@ -302,6 +302,20 @@ .sortable-page-list li.placeholder:before { position: absolute; } +.sort-box summary { + list-style: none; + font-size: .9rem; + cursor: pointer; +} +.sort-box summary::-webkit-details-marker { + display: none; +} +details.sort-box summary .caret-container svg { + transition: transform ease-in-out 120ms; +} +details.sort-box[open] summary .caret-container svg { + transform: rotate(90deg); +} .activity-list-item { padding: $-s 0; diff --git a/resources/sass/styles.scss b/resources/sass/styles.scss index 23959d1f8..398d16fac 100644 --- a/resources/sass/styles.scss +++ b/resources/sass/styles.scss @@ -199,6 +199,9 @@ $loadingSize: 10px; .entity-item-snippet { display: none; } + h4 { + font-size: 14px; + } } } diff --git a/resources/views/books/parts/sort-box.blade.php b/resources/views/books/parts/sort-box.blade.php index ef9929e46..819f1e063 100644 --- a/resources/views/books/parts/sort-box.blade.php +++ b/resources/views/books/parts/sort-box.blade.php @@ -1,8 +1,15 @@ -<div class="sort-box" data-type="book" data-id="{{ $book->id }}"> - <h5 class="text-book entity-list-item no-hover py-xs pl-none"> - <span>@icon('book')</span> - <span>{{ $book->name }}</span> - </h5> +<details class="sort-box" data-type="book" data-id="{{ $book->id }}" open> + <summary> + <h5 class="flex-container-row items-center justify-flex-start gap-xs"> + <div class="text-book text-bigger caret-container"> + @icon('caret-right') + </div> + <div class="entity-list-item no-hover py-s text-book px-none"> + <span>@icon('book')</span> + <span>{{ $book->name }}</span> + </div> + </h5> + </summary> <div class="sort-box-options pb-sm"> <button type="button" data-sort="name" class="button outline small">{{ trans('entities.books_sort_name') }}</button> <button type="button" data-sort="created" class="button outline small">{{ trans('entities.books_sort_created') }}</button> @@ -45,4 +52,4 @@ @endforeach </ul> -</div> \ No newline at end of file +</details> \ No newline at end of file diff --git a/resources/views/books/sort.blade.php b/resources/views/books/sort.blade.php index 077da101d..b778398a8 100644 --- a/resources/views/books/sort.blade.php +++ b/resources/views/books/sort.blade.php @@ -16,8 +16,10 @@ <div class="grid left-focus gap-xl"> <div> - <div component="book-sort" class="card content-wrap"> - <h1 class="list-heading mb-l">{{ trans('entities.books_sort') }}</h1> + <div component="book-sort" class="card content-wrap auto-height"> + <h1 class="list-heading">{{ trans('entities.books_sort') }}</h1> + <p class="text-muted">{{ trans('entities.books_sort_desc') }}</p> + <div refs="book-sort@sortContainer"> @include('books.parts.sort-box', ['book' => $book, 'bookChildren' => $bookChildren]) </div> @@ -35,8 +37,9 @@ </div> <div> - <main class="card content-wrap"> - <h2 class="list-heading mb-m">{{ trans('entities.books_sort_show_other') }}</h2> + <main class="card content-wrap auto-height sticky-top-m"> + <h2 class="list-heading">{{ trans('entities.books_sort_show_other') }}</h2> + <p class="text-muted">{{ trans('entities.books_sort_show_other_desc') }}</p> @include('entities.selector', ['name' => 'books_list', 'selectorSize' => 'compact', 'entityTypes' => 'book', 'entityPermission' => 'update', 'showAdd' => true])