]> BookStack Code Mirror - bookstack/commitdiff
Notifications: Extracted watch options, updated UI further
authorDan Brown <redacted>
Mon, 31 Jul 2023 14:23:28 +0000 (15:23 +0100)
committerDan Brown <redacted>
Mon, 31 Jul 2023 14:23:28 +0000 (15:23 +0100)
app/Users/UserWatchOptions.php [new file with mode: 0644]
lang/en/entities.php
resources/js/components/dropdown.js
resources/sass/_layout.scss
resources/sass/_lists.scss
resources/sass/_variables.scss
resources/views/books/show.blade.php
resources/views/entities/meta.blade.php
resources/views/entities/watch-action.blade.php [new file with mode: 0644]
resources/views/entities/watch-controls.blade.php

diff --git a/app/Users/UserWatchOptions.php b/app/Users/UserWatchOptions.php
new file mode 100644 (file)
index 0000000..a835bcf
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+namespace BookStack\Users;
+
+class UserWatchOptions
+{
+    protected static array $levelByOption = [
+        'default' => -1,
+        'ignore' => 0,
+        'new' => 1,
+        'updates' => 2,
+        'comments' => 3,
+    ];
+
+    /**
+     * @return string[]
+     */
+    public static function getAvailableOptionNames(): array
+    {
+        return array_keys(static::$levelByOption);
+    }
+}
index 4fb043aa9d06a4ade958301c7b6eea54c77eb7a0..80b9142f5bf06ec6eed1e4b1f24bdcaa8314ce81 100644 (file)
@@ -403,4 +403,18 @@ return [
     'references' => 'References',
     'references_none' => 'There are no tracked references to this item.',
     'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.',
+
+    // Watch Options
+    'watch' => 'Watch',
+    'watch_title_default' => 'Default Preferences',
+    'watch_desc_default' => 'Revert watching to just your default notification preferences.',
+    'watch_title_ignore' => 'Ignore',
+    'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
+    'watch_title_new' => 'New Pages',
+    'watch_desc_new' => 'Notify when any new page is created within this item.',
+    'watch_title_updates' => 'All Page Updates',
+    'watch_desc_updates' => 'Notify upon all new pages and page changes.',
+    'watch_title_comments' => 'All Page Updates & Comments',
+    'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
+    'watch_change_default' => 'Change default notification preferences',
 ];
index b68f332b6f13a04a2d2db7fd706cfae0d42dc8bd..2c5919a37e755d9fa8e3facc0a8f226612dff468 100644 (file)
@@ -132,6 +132,7 @@ export class Dropdown extends Component {
 
         onSelect(this.toggle, event => {
             event.stopPropagation();
+            event.preventDefault();
             this.show(event);
             if (event instanceof KeyboardEvent) {
                 keyboardNavHandler.focusNext();
index a8604b81b18240edf43f32a2f0965d61b571f3d9..50776ea28143f5dce6cc527c74c16441b1e4f42b 100644 (file)
@@ -353,7 +353,7 @@ body.flexbox {
   margin-inline-end: $-xl;
   grid-template-columns: 1fr 4fr 1fr;
   grid-template-areas: "a b c";
-  grid-column-gap: $-xxl;
+  grid-column-gap: $-xl;
   .tri-layout-right {
     grid-area: c;
     min-width: 0;
@@ -378,6 +378,14 @@ body.flexbox {
     padding-inline-end: $-l;
   }
 }
+@include between($xxl, $xxxl) {
+  .tri-layout-container {
+    grid-template-columns: 1fr calc(940px + (2 * $-m)) 1fr;
+    grid-column-gap: $-s;
+    margin-inline-start: $-m;
+    margin-inline-end: $-m;
+  }
+}
 @include between($l, $xxl) {
   .tri-layout-left {
     position: sticky;
index 64411014db7a0e4c36dd47a1585785ddf59c9389..323551196585fbac2ec961016a53e7ba61a8e668 100644 (file)
@@ -672,7 +672,7 @@ ul.pagination {
   @include lightDark(color, #555, #eee);
   fill: currentColor;
   text-align: start !important;
-  max-height: 500px;
+  max-height: 80vh;
   overflow-y: auto;
   &.anchor-left {
     inset-inline-end: auto;
@@ -683,6 +683,7 @@ ul.pagination {
   }
   &.xl-limited {
     width: 280px;
+    max-width: 100%;
   }
   .text-muted {
     color: #999;
@@ -708,6 +709,11 @@ ul.pagination {
     white-space: nowrap;
     line-height: 1.4;
     cursor: pointer;
+    &.break-text {
+      white-space: normal;
+      word-wrap: break-word;
+      overflow-wrap: break-word;
+    }
     &:hover, &:focus {
       text-decoration: none;
       background-color: var(--color-primary-light);
index a3598e29c4cfee6da16dcb6e82758f38f1cad3a8..35586bf58303cbd3662bff609191b3f14371ade1 100644 (file)
@@ -2,6 +2,7 @@
 ///////////////
 
 // Screen breakpoints
+$xxxl: 1700px;
 $xxl: 1400px;
 $xl: 1100px;
 $l: 1000px;
index f126c62194882671f1b4f578e8d7e448fe8a2623..305a651321b07b6bdc104c7848740f8d1812a3d2 100644 (file)
@@ -67,7 +67,7 @@
 @stop
 
 @section('right')
-    <div class="mb-xl" style="z-index: 1000; opacity: 1;">
+    <div class="mb-xl">
         <h5>{{ trans('common.details') }}</h5>
         <div class="blended-links">
             @include('entities.meta', ['entity' => $book])
             @if(signedInUser())
                 @include('entities.favourite-action', ['entity' => $book])
             @endif
+            @include('entities.watch-action', ['entity' => $book])
             @if(userCan('content-export'))
                 @include('entities.export-menu', ['entity' => $book])
             @endif
index b657d82deaab79a42dd4cce4957a06811c0a04db..0bda1293828e909608b60184d0aca1414f27cd65 100644 (file)
         </a>
     @endif
 
-    <div class="dropdown-container">
-        <div class="entity-meta-item">
+    <div component="dropdown"
+         class="dropdown-container my-xxs">
+        <a refs="dropdown@toggle" href="#" class="entity-meta-item my-none">
             @icon('watch')
             <span>Watching with default preferences</span>
-        </div>
+        </a>
         @include('entities.watch-controls', ['entity' => $entity])
     </div>
 </div>
\ No newline at end of file
diff --git a/resources/views/entities/watch-action.blade.php b/resources/views/entities/watch-action.blade.php
new file mode 100644 (file)
index 0000000..dd626a0
--- /dev/null
@@ -0,0 +1,9 @@
+<form action="{{ $entity->getUrl('/') }}" method="GET">
+    {{ csrf_field() }}
+    <input type="hidden" name="type" value="{{ get_class($entity) }}">
+    <input type="hidden" name="id" value="{{ $entity->id }}">
+    <button type="submit" data-shortcut="favourite" class="icon-list-item text-link">
+        <span>@icon('watch')</span>
+        <span>{{ trans('entities.watch') }}</span>
+    </button>
+</form>
\ No newline at end of file
index ab4af0f77243122a51feec468996e3d65a3a47c5..b6b16a607b25bffaee67adcbe979bf9389f87a18 100644 (file)
@@ -1,71 +1,32 @@
 <form action="{{ $entity->getUrl('/') }}" method="GET">
 {{--    {{ method_field('PUT') }}--}}
+    {{ csrf_field() }}
+    <input type="hidden" name="type" value="{{ get_class($entity) }}">
+    <input type="hidden" name="id" value="{{ $entity->id }}">
 
-    <ul class="dropdown-menu xl-limited anchor-left" style="display: block;">
+    <ul refs="dropdown@menu" class="dropdown-menu xl-limited anchor-left pb-none">
+        @foreach(\BookStack\Users\UserWatchOptions::getAvailableOptionNames() as $option)
         <li>
-            <button name="level" value="default" class="icon-item">
-                <span class="text-pos pt-m">{!!  request()->query('level') === 'default' ? icon('check-circle') : '' !!}</span>
+            <button name="level" value="{{ $option }}" class="icon-item">
+                @if(request()->query('level') === $option)
+                    <span class="text-pos pt-m" title="{{ trans('common.status_active') }}">@icon('check-circle')</span>
+                @else
+                    <span title="{{ trans('common.status_inactive') }}"></span>
+                @endif
                 <div class="break-text">
-                    <div class="mb-xxs"><strong>Default Preferences</strong></div>
+                    <div class="mb-xxs"><strong>{{ trans('entities.watch_title_' . $option) }}</strong></div>
                     <div class="text-muted text-small">
-                        Revert watching to just your default notification preferences.
+                        {{ trans('entities.watch_desc_' . $option) }}
                     </div>
                 </div>
             </button>
         </li>
         <li><hr class="my-none"></li>
+        @endforeach
         <li>
-            <button name="level" value="ignore" class="icon-item">
-                <span class="text-pos pt-m">{!!  request()->query('level') === 'ignore' ? icon('check-circle') : '' !!}</span>
-                <div class="break-text">
-                    <div class="mb-xxs"><strong>Ignore</strong></div>
-                    <div class="text-muted text-small">
-                        Ignore all notifications, including those from user-level preferences.
-                    </div>
-                </div>
-            </button>
-        </li>
-        <li><hr class="my-none"></li>
-        <li>
-            <button name="level" value="new" class="icon-item">
-                <span class="text-pos pt-m">{!!  request()->query('level') === 'new' ? icon('check-circle') : '' !!}</span>
-                <div class="break-text">
-                    <div class="mb-xxs"><strong>New Pages</strong></div>
-                    <div class="text-muted text-small">
-                        Notify when any new page is created within this item.
-                    </div>
-                </div>
-            </button>
-        </li>
-        <li><hr class="my-none"></li>
-        <li>
-            <button name="level" value="updates" class="icon-item">
-                <span class="text-pos pt-m">{!!  request()->query('level') === 'updates' ? icon('check-circle') : '' !!}</span>
-                <div class="break-text">
-                    <div class="mb-xxs"><strong>All Page Updates</strong></div>
-                    <div class="text-muted text-small">
-                        Notify upon all new pages and page changes.
-                    </div>
-                </div>
-            </button>
-        </li>
-        <li><hr class="my-none"></li>
-        <li>
-            <button name="level" value="comments" class="icon-item">
-                <span class="text-pos pt-m">{!!  request()->query('level') === 'comments' ? icon('check-circle') : '' !!}</span>
-                <div class="break-text">
-                    <div class="mb-xxs"><strong>All Page Updates & Comments</strong></div>
-                    <div class="text-muted text-small">
-                        Notify upon all new pages, page changes and new comments.
-                    </div>
-                </div>
-            </button>
-        </li>
-        <li><hr class="my-none"></li>
-        <li>
-            <div class="text-small text-muted px-l pb-xxs pt-xs">
-                <a href="{{ url('/preferences/notifications') }}" target="_blank">Change default notification preferences</a>
-            </div>
+            <a href="{{ url('/preferences/notifications') }}"
+               target="_blank"
+               class="text-item text-muted text-small break-text">{{ trans('entities.watch_change_default') }}</a>
         </li>
     </ul>
 </form>
\ No newline at end of file