]> BookStack Code Mirror - bookstack/commitdiff
Started accessible controls for shelf book sort
authorDan Brown <redacted>
Fri, 17 Feb 2023 15:05:28 +0000 (15:05 +0000)
committerDan Brown <redacted>
Fri, 17 Feb 2023 15:05:28 +0000 (15:05 +0000)
Added buttons and fit to design.
Added new icon variations to support.
Extracted book item to own view and setup for future auto sorts.

app/Http/Controllers/BookshelfController.php
resources/icons/add-small.svg [new file with mode: 0644]
resources/icons/remove.svg [new file with mode: 0644]
resources/sass/_components.scss
resources/sass/styles.scss
resources/views/shelves/parts/form.blade.php
resources/views/shelves/parts/shelf-sort-book-item.blade.php [new file with mode: 0644]

index 537ea915b76130deb086c934b0c22516e070dd07..d4642be786d102fb4528131169661450319c2912 100644 (file)
@@ -64,7 +64,7 @@ class BookshelfController extends Controller
     public function create()
     {
         $this->checkPermission('bookshelf-create-all');
-        $books = Book::visible()->orderBy('name')->get(['name', 'id', 'slug']);
+        $books = Book::visible()->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
         $this->setPageTitle(trans('entities.shelves_create'));
 
         return view('shelves.create', ['books' => $books]);
@@ -140,7 +140,7 @@ class BookshelfController extends Controller
         $this->checkOwnablePermission('bookshelf-update', $shelf);
 
         $shelfBookIds = $shelf->books()->get(['id'])->pluck('id');
-        $books = Book::visible()->whereNotIn('id', $shelfBookIds)->orderBy('name')->get(['name', 'id', 'slug']);
+        $books = Book::visible()->whereNotIn('id', $shelfBookIds)->orderBy('name')->get(['name', 'id', 'slug', 'created_at', 'updated_at']);
 
         $this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $shelf->getShortName()]));
 
diff --git a/resources/icons/add-small.svg b/resources/icons/add-small.svg
new file mode 100644 (file)
index 0000000..81aaf4f
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 13.114h-4.886V18h-2.228v-4.886H6v-2.228h4.886V6h2.228v4.886H18Z" style="stroke-width:.857143"/></svg>
\ No newline at end of file
diff --git a/resources/icons/remove.svg b/resources/icons/remove.svg
new file mode 100644 (file)
index 0000000..088c34a
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.5 7.91 16.09 6.5 12 10.59 7.91 6.5 6.5 7.91 10.59 12 6.5 16.09l1.41 1.41L12 13.41l4.09 4.09 1.41-1.41L13.41 12Z"/></svg>
\ No newline at end of file
index 2150f6d073c9afe81afdedc88cbf0f27a0171285..ac0d913aaf6d23500b6e41740c177b0d636b5908 100644 (file)
@@ -1050,4 +1050,81 @@ $btt-size: 40px;
     vertical-align: top;
     line-height: 2;
   }
+}
+
+// Sortable scroll boxes
+.scroll-box {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  max-height: 250px;
+  overflow-y: scroll;
+  border: 1px solid;
+  @include lightDark(border-color, #DDD, #000);
+  border-radius: 3px;
+  min-height: 20px;
+  @include lightDark(background-color, #EEE, #000);
+}
+.scroll-box-item {
+  border-bottom: 1px solid;
+  border-top: 1px solid;
+  @include lightDark(border-color, #DDD, #000);
+  margin-top: -1px;
+  @include lightDark(background-color, #FFF, #222);
+  display: flex;
+  align-items: flex-start;
+  padding: 1px;
+  &:last-child {
+    border-bottom: 0;
+  }
+  &:hover {
+    cursor: pointer;
+    @include lightDark(background-color, #f8f8f8, #333);
+  }
+  .handle {
+    color: #AAA;
+    cursor: grab;
+  }
+  .handle svg {
+    margin: 0;
+  }
+  > * {
+    padding: $-xs $-m;
+  }
+  .handle + * {
+    padding-left: 0;
+  }
+  &:hover .handle {
+    @include lightDark(color, #444, #FFF);
+  }
+  a:hover {
+    text-decoration: none;
+  }
+}
+
+input.scroll-box-search, .scroll-box-header-item {
+  font-size: 0.8rem;
+  padding: $-xs $-m;
+  border: 1px solid;
+  @include lightDark(border-color, #DDD, #000);
+  @include lightDark(background-color, #FFF, #222);
+  margin-bottom: -1px;
+  border-radius: 3px 3px 0 0;
+  width: 100%;
+  max-width: 100%;
+  height: auto;
+  line-height: 1.4;
+  color: #666;
+}
+
+.scroll-box-search + .scroll-box,
+.scroll-box-header-item + .scroll-box {
+  border-radius: 0 0 3px 3px;
+}
+
+.scroll-box[refs="shelf-sort@shelf-book-list"] [data-action="add"] {
+  display: none;
+}
+.scroll-box[refs="shelf-sort@all-book-list"] [data-action="remove"] {
+  display: none;
 }
\ No newline at end of file
index 668cb5c8507cdfb9a3393e453e305e3336829029..0f4ec70417a2a4bce81df7aad3771b8629925e83 100644 (file)
@@ -198,71 +198,6 @@ $loadingSize: 10px;
   }
 }
 
-.scroll-box {
-  max-height: 250px;
-  overflow-y: scroll;
-  border: 1px solid;
-  @include lightDark(border-color, #DDD, #000);
-  border-radius: 3px;
-  min-height: 20px;
-  @include lightDark(background-color, #EEE, #000);
-}
-.scroll-box-item {
-  border-bottom: 1px solid;
-  border-top: 1px solid;
-  @include lightDark(border-color, #DDD, #000);
-  margin-top: -1px;
-  @include lightDark(background-color, #FFF, #222);
-  display: flex;
-  padding: 1px;
-  &:last-child {
-    border-bottom: 0;
-  }
-  &:hover {
-    cursor: pointer;
-    @include lightDark(background-color, #f8f8f8, #333);
-  }
-  .handle {
-    color: #AAA;
-    cursor: grab;
-  }
-  .handle svg {
-    margin: 0;
-  }
-  > * {
-    padding: $-xs $-m;
-  }
-  .handle + * {
-    padding-left: 0;
-  }
-  &:hover .handle {
-    @include lightDark(color, #444, #FFF);
-  }
-  a:hover {
-    text-decoration: none;
-  }
-}
-
-input.scroll-box-search, .scroll-box-header-item {
-  font-size: 0.8rem;
-  padding: $-xs $-m;
-  border: 1px solid;
-  @include lightDark(border-color, #DDD, #000);
-  @include lightDark(background-color, #FFF, #222);
-  margin-bottom: -1px;
-  border-radius: 3px 3px 0 0;
-  width: 100%;
-  max-width: 100%;
-  height: auto;
-  line-height: 1.4;
-  color: #666;
-}
-
-.scroll-box-search + .scroll-box,
-.scroll-box-header-item + .scroll-box {
-  border-radius: 0 0 3px 3px;
-}
-
 .fullscreen {
   border:0;
   position:fixed;
index 364f8e0be14c79153e9135b930e57c393542e83a..02cea64ffd4c8af129a07dd9161688970f75fa94 100644 (file)
         <input refs="shelf-sort@input" type="hidden" name="books"
                value="{{ isset($shelf) ? $shelf->visibleBooks->implode('id', ',') : '' }}">
         <div class="scroll-box-header-item">{{ trans('entities.shelves_drag_books') }}</div>
-        <div refs="shelf-sort@shelf-book-list" class="scroll-box">
-            @if (count($shelf->visibleBooks ?? []) > 0)
-                @foreach ($shelf->visibleBooks as $book)
-                    <div data-id="{{ $book->id }}" class="scroll-box-item">
-                        <div class="handle">@icon('grip')</div>
-                        <a href="{{ $book->getUrl() }}" class="text-book">@icon('book'){{ $book->name }}</a>
-                    </div>
-                @endforeach
-            @endif
-        </div>
+        <ul refs="shelf-sort@shelf-book-list" class="scroll-box">
+            @foreach (($shelf->visibleBooks ?? []) as $book)
+                @include('shelves.parts.shelf-sort-book-item', ['book' => $book])
+            @endforeach
+        </ul>
     </div>
     <div class="form-group">
         <label for="books">{{ trans('entities.shelves_add_books') }}</label>
         <input type="text" refs="shelf-sort@book-search" class="scroll-box-search" placeholder="{{ trans('common.search') }}">
-        <div refs="shelf-sort@all-book-list" class="scroll-box">
+        <ul refs="shelf-sort@all-book-list" class="scroll-box">
             @foreach ($books as $book)
-                <div data-id="{{ $book->id }}" class="scroll-box-item">
-                    <div class="handle">@icon('grip')</div>
-                    <a href="{{ $book->getUrl() }}" class="text-book">@icon('book'){{ $book->name }}</a>
-                </div>
+                @include('shelves.parts.shelf-sort-book-item', ['book' => $book])
             @endforeach
-        </div>
+        </ul>
     </div>
 </div>
 
diff --git a/resources/views/shelves/parts/shelf-sort-book-item.blade.php b/resources/views/shelves/parts/shelf-sort-book-item.blade.php
new file mode 100644 (file)
index 0000000..25aeecd
--- /dev/null
@@ -0,0 +1,18 @@
+<li data-id="{{ $book->id }}"
+     data-name="{{ $book->name }}"
+     data-created="{{ $book->created_at->timestamp }}"
+     data-updated="{{ $book->updated_at->timestamp }}"
+     class="scroll-box-item">
+    <div class="handle px-s">@icon('grip')</div>
+    <a href="{{ $book->getUrl() }}" class="text-book">@icon('book'){{ $book->name }}</a>
+    <div class="buttons flex-container-row items-center ml-auto px-xxs py-xs">
+        <button type="button" data-action="move_up" class="icon-button p-xxs"
+                title="{{ trans('entities.books_sort_move_up') }}">@icon('chevron-up')</button>
+        <button type="button" data-action="move_down" class="icon-button p-xxs"
+                title="{{ trans('entities.books_sort_move_down') }}">@icon('chevron-down')</button>
+        <button type="button" data-action="remove" class="icon-button p-xxs"
+                title="{{ trans('common.remove') }}">@icon('remove')</button>
+        <button type="button" data-action="add" class="icon-button p-xxs"
+                title="{{ trans('common.add') }}">@icon('add-small')</button>
+    </div>
+</li>
\ No newline at end of file