]> BookStack Code Mirror - bookstack/commitdiff
Merge branch 'master' into 2019-design
authorDan Brown <redacted>
Sat, 30 Mar 2019 13:17:29 +0000 (13:17 +0000)
committerDan Brown <redacted>
Sat, 30 Mar 2019 13:17:29 +0000 (13:17 +0000)
163 files changed:
app/Actions/ActivityService.php
app/Auth/Role.php
app/Auth/UserRepo.php
app/Entities/Book.php
app/Entities/Bookshelf.php
app/Entities/Chapter.php
app/Entities/Entity.php
app/Entities/Page.php
app/Entities/PageRevision.php
app/Entities/Repos/EntityRepo.php
app/Http/Controllers/BookController.php
app/Http/Controllers/BookshelfController.php
app/Http/Controllers/ChapterController.php
app/Http/Controllers/Controller.php
app/Http/Controllers/PageController.php
app/Http/Controllers/PermissionController.php
app/Http/Controllers/SearchController.php
app/Http/Controllers/SettingController.php
app/Http/Controllers/UserController.php
app/Http/Middleware/Authenticate.php
app/Settings/SettingService.php
app/helpers.php
package-lock.json
package.json
resources/assets/icons/add.svg
resources/assets/icons/books.svg [new file with mode: 0644]
resources/assets/icons/bookshelf.svg
resources/assets/icons/check.svg [new file with mode: 0644]
resources/assets/icons/chevron-right.svg [new file with mode: 0644]
resources/assets/icons/sort-down.svg [new file with mode: 0644]
resources/assets/icons/sort-up.svg [new file with mode: 0644]
resources/assets/js/components/breadcrumb-listing.js [new file with mode: 0644]
resources/assets/js/components/dropdown.js
resources/assets/js/components/header-mobile-toggle.js [new file with mode: 0644]
resources/assets/js/components/index.js
resources/assets/js/components/list-sort-control.js [new file with mode: 0644]
resources/assets/js/components/page-display.js
resources/assets/js/components/toggle-switch.js
resources/assets/js/components/tri-layout.js [new file with mode: 0644]
resources/assets/js/components/wysiwyg-editor.js
resources/assets/sass/_blocks.scss
resources/assets/sass/_buttons.scss
resources/assets/sass/_colors.scss [new file with mode: 0644]
resources/assets/sass/_forms.scss
resources/assets/sass/_grid.scss
resources/assets/sass/_header.scss
resources/assets/sass/_html.scss
resources/assets/sass/_lists.scss
resources/assets/sass/_mixins.scss
resources/assets/sass/_pages.scss
resources/assets/sass/_tables.scss
resources/assets/sass/_text.scss
resources/assets/sass/_variables.scss
resources/assets/sass/styles.scss
resources/lang/en/common.php
resources/lang/en/entities.php
resources/lang/en/settings.php
resources/views/auth/forms/login/ldap.blade.php
resources/views/auth/forms/login/standard.blade.php
resources/views/auth/login.blade.php
resources/views/auth/passwords/email.blade.php
resources/views/auth/passwords/reset.blade.php
resources/views/auth/register-confirm.blade.php
resources/views/auth/register.blade.php
resources/views/auth/user-unconfirmed.blade.php
resources/views/base.blade.php
resources/views/books/create.blade.php
resources/views/books/delete.blade.php
resources/views/books/edit.blade.php
resources/views/books/form.blade.php
resources/views/books/grid-item.blade.php
resources/views/books/index.blade.php
resources/views/books/list-item.blade.php
resources/views/books/list.blade.php
resources/views/books/permissions.blade.php [new file with mode: 0644]
resources/views/books/restrictions.blade.php [deleted file]
resources/views/books/show.blade.php
resources/views/books/sort-box.blade.php
resources/views/books/sort.blade.php
resources/views/books/view-toggle.blade.php [deleted file]
resources/views/chapters/_breadcrumbs.blade.php [deleted file]
resources/views/chapters/child-menu.blade.php [new file with mode: 0644]
resources/views/chapters/create.blade.php
resources/views/chapters/delete.blade.php
resources/views/chapters/edit.blade.php
resources/views/chapters/form.blade.php
resources/views/chapters/list-item.blade.php
resources/views/chapters/move.blade.php
resources/views/chapters/permissions.blade.php [new file with mode: 0644]
resources/views/chapters/restrictions.blade.php [deleted file]
resources/views/chapters/show.blade.php
resources/views/comments/comments.blade.php
resources/views/common/header.blade.php [new file with mode: 0644]
resources/views/common/home.blade.php
resources/views/components/custom-checkbox.blade.php [new file with mode: 0644]
resources/views/components/entity-selector.blade.php
resources/views/components/image-picker.blade.php
resources/views/components/toggle-switch.blade.php
resources/views/errors/503.blade.php
resources/views/form/checkbox.blade.php
resources/views/form/entity-permissions.blade.php [moved from resources/views/form/restriction-form.blade.php with 60% similarity]
resources/views/form/restriction-checkbox.blade.php
resources/views/form/role-checkboxes.blade.php
resources/views/pages/_breadcrumbs.blade.php [deleted file]
resources/views/pages/copy.blade.php
resources/views/pages/delete.blade.php
resources/views/pages/detailed-listing.blade.php
resources/views/pages/edit.blade.php
resources/views/pages/list-item.blade.php
resources/views/pages/move.blade.php
resources/views/pages/permissions.blade.php [new file with mode: 0644]
resources/views/pages/restrictions.blade.php [deleted file]
resources/views/pages/revision.blade.php
resources/views/pages/revisions.blade.php
resources/views/pages/show.blade.php
resources/views/partials/_header-dropdown.blade.php [deleted file]
resources/views/partials/activity-item.blade.php
resources/views/partials/book-tree.blade.php
resources/views/partials/breadcrumb-listing.blade.php [new file with mode: 0644]
resources/views/partials/breadcrumbs.blade.php [new file with mode: 0644]
resources/views/partials/entity-list-basic.blade.php [new file with mode: 0644]
resources/views/partials/entity-list-item-basic.blade.php [new file with mode: 0644]
resources/views/partials/entity-list-item.blade.php [new file with mode: 0644]
resources/views/partials/entity-list.blade.php
resources/views/partials/sort.blade.php [new file with mode: 0644]
resources/views/partials/view-toggle.blade.php [new file with mode: 0644]
resources/views/public.blade.php [deleted file]
resources/views/search/all.blade.php
resources/views/settings/index.blade.php
resources/views/settings/maintenance.blade.php
resources/views/settings/navbar.blade.php
resources/views/settings/roles/checkbox.blade.php
resources/views/settings/roles/create.blade.php
resources/views/settings/roles/delete.blade.php
resources/views/settings/roles/edit.blade.php
resources/views/settings/roles/form.blade.php
resources/views/settings/roles/index.blade.php
resources/views/shelves/create.blade.php
resources/views/shelves/delete.blade.php
resources/views/shelves/edit.blade.php
resources/views/shelves/form.blade.php
resources/views/shelves/grid-item.blade.php
resources/views/shelves/index.blade.php
resources/views/shelves/list-item.blade.php
resources/views/shelves/list.blade.php
resources/views/shelves/permissions.blade.php [new file with mode: 0644]
resources/views/shelves/restrictions.blade.php [deleted file]
resources/views/shelves/show.blade.php
resources/views/shelves/view-toggle.blade.php [deleted file]
resources/views/sidebar-layout.blade.php
resources/views/simple-layout.blade.php
resources/views/tri-layout.blade.php [new file with mode: 0644]
resources/views/users/create.blade.php
resources/views/users/delete.blade.php
resources/views/users/edit.blade.php
resources/views/users/form.blade.php [new file with mode: 0644]
resources/views/users/forms/ldap.blade.php [deleted file]
resources/views/users/forms/standard.blade.php [deleted file]
resources/views/users/forms/system.blade.php [deleted file]
resources/views/users/index.blade.php
resources/views/users/profile.blade.php
routes/web.php
webpack.config.js

index 37cd0a6a4ca99a2a1f60f682929fefabe5bfb304..11f8b87328ceec432c4f85b62bc6872edae80118 100644 (file)
@@ -103,7 +103,7 @@ class ActivityService
      * @param int $page
      * @return array
      */
-    public function entityActivity($entity, $count = 20, $page = 0)
+    public function entityActivity($entity, $count = 20, $page = 1)
     {
         if ($entity->isA('book')) {
             $query = $this->activity->where('book_id', '=', $entity->id);
@@ -114,7 +114,7 @@ class ActivityService
         
         $activity = $this->permissionService
             ->filterRestrictedEntityRelations($query, 'activities', 'entity_id', 'entity_type')
-            ->orderBy('created_at', 'desc')->with(['entity', 'user.avatar'])->skip($count * $page)->take($count)->get();
+            ->orderBy('created_at', 'desc')->with(['entity', 'user.avatar'])->skip($count * ($page - 1))->take($count)->get();
 
         return $this->filterSimilar($activity);
     }
index c8bb47e4582076ef90769a03a7f72b8e1e605ca4..917d8aa26192c0388fac58fa5970267f3e25969c 100644 (file)
@@ -1,6 +1,7 @@
 <?php namespace BookStack\Auth;
 
 use BookStack\Auth\Permissions\JointPermission;
+use BookStack\Auth\Permissions\RolePermission;
 use BookStack\Model;
 
 class Role extends Model
@@ -13,7 +14,7 @@ class Role extends Model
      */
     public function users()
     {
-        return $this->belongsToMany(User::class);
+        return $this->belongsToMany(User::class)->orderBy('name', 'asc');
     }
 
     /**
@@ -30,7 +31,7 @@ class Role extends Model
      */
     public function permissions()
     {
-        return $this->belongsToMany(Permissions\RolePermission::class, 'permission_role', 'role_id', 'permission_id');
+        return $this->belongsToMany(RolePermission::class, 'permission_role', 'role_id', 'permission_id');
     }
 
     /**
@@ -51,18 +52,18 @@ class Role extends Model
 
     /**
      * Add a permission to this role.
-     * @param \BookStack\Auth\Permissions\RolePermission $permission
+     * @param RolePermission $permission
      */
-    public function attachPermission(Permissions\RolePermission $permission)
+    public function attachPermission(RolePermission $permission)
     {
         $this->permissions()->attach($permission->id);
     }
 
     /**
      * Detach a single permission from this role.
-     * @param \BookStack\Auth\Permissions\RolePermission $permission
+     * @param RolePermission $permission
      */
-    public function detachPermission(Permissions\RolePermission $permission)
+    public function detachPermission(RolePermission $permission)
     {
         $this->permissions()->detach($permission->id);
     }
index 31b91108d2b11e1e28dbb233f4f249dc3092ba38..b2ff0bc58ea90c0d3087ca5323a0b6d24572e4ae 100644 (file)
@@ -256,7 +256,7 @@ class UserRepo
      */
     public function getAllRoles()
     {
-        return $this->role->all();
+        return $this->role->newQuery()->orderBy('name', 'asc')->get();
     }
 
     /**
index 5ab5142c9f097d5c654f5d99e08b8d2efad2d113..e722c4b107dc5dd3ea1262b7672e14bc7f9ef32e 100644 (file)
@@ -38,7 +38,7 @@ class Book extends Entity
      */
     public function getBookCover($width = 440, $height = 250)
     {
-        $default = baseUrl('/book_default_cover.png');
+        $default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
         if (!$this->image_id) {
             return $default;
         }
@@ -69,6 +69,15 @@ class Book extends Entity
         return $this->hasMany(Page::class);
     }
 
+    /**
+     * Get the direct child pages of this book.
+     * @return \Illuminate\Database\Eloquent\Relations\HasMany
+     */
+    public function directPages()
+    {
+        return $this->pages()->where('chapter_id', '=', '0');
+    }
+
     /**
      * Get all chapters within this book.
      * @return \Illuminate\Database\Eloquent\Relations\HasMany
index c37e36b59f8aefb125c827b3fbdff227708c9314..d6a3cf0efec3cbd3f00da5b1b74b29a27b57960e 100644 (file)
@@ -50,7 +50,8 @@ class Bookshelf extends Entity
      */
     public function getBookCover($width = 440, $height = 250)
     {
-        $default = baseUrl('/book_default_cover.png');
+        // TODO - Make generic, focused on books right now, Perhaps set-up a better image
+        $default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
         if (!$this->image_id) {
             return $default;
         }
@@ -64,7 +65,7 @@ class Bookshelf extends Entity
     }
 
     /**
-     * Get the cover image of the book
+     * Get the cover image of the shelf
      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
      */
     public function cover()
index 079105ba92a7a5c0d18bdc4ac31085610c8d4ae2..bdacb7c9d8340ee26a43c9652587594d33afadb6 100644 (file)
@@ -53,9 +53,9 @@ class Chapter extends Entity
      * @param int $length
      * @return string
      */
-    public function getExcerpt($length = 100)
+    public function getExcerpt(int $length = 100)
     {
-        $description = $this->description;
+        $description = $this->text ?? $this->description;
         return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
     }
 
@@ -67,4 +67,13 @@ class Chapter extends Entity
     {
         return "'BookStack\\\\Chapter' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, '' as html, book_id, priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
     }
+
+    /**
+     * Check if this chapter has any child pages.
+     * @return bool
+     */
+    public function hasChildren()
+    {
+        return count($this->pages) > 0;
+    }
 }
index 21d172e708ad48be7a969a5977c3c4897a9cee33..d648f68e45869b1e8c514249a87c513ed88037e7 100644 (file)
@@ -102,6 +102,11 @@ class Entity extends Ownable
         return $this->morphMany(View::class, 'viewable');
     }
 
+    public function viewCountQuery()
+    {
+        return $this->views()->selectRaw('viewable_id, sum(views) as view_count')->groupBy('viewable_id');
+    }
+
     /**
      * Get the Tag models that have been user assigned to this entity.
      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
@@ -218,6 +223,20 @@ class Entity extends Ownable
         return $this->{$this->textField};
     }
 
+    /**
+     * Get an excerpt of this entity's descriptive content to the specified length.
+     * @param int $length
+     * @return mixed
+     */
+    public function getExcerpt(int $length = 100)
+    {
+        $text = $this->getText();
+        if (mb_strlen($text) > $length) {
+            $text = mb_substr($text, 0, $length-3) . '...';
+        }
+        return  trim($text);
+    }
+
     /**
      * Return a generalised, common raw query that can be 'unioned' across entities.
      * @return string
index ea7df16f4021025b048f91dd4e26f50741310e46..1c2cc5cff69c29daa5385d963bc89ab2ad4612ff 100644 (file)
@@ -102,17 +102,6 @@ class Page extends Entity
         return baseUrl('/books/' . urlencode($bookSlug) . $midText . $idComponent);
     }
 
-    /**
-     * Get an excerpt of this page's content to the specified length.
-     * @param int $length
-     * @return mixed
-     */
-    public function getExcerpt($length = 100)
-    {
-        $text = strlen($this->text) > $length ? substr($this->text, 0, $length-3) . '...' : $this->text;
-        return mb_convert_encoding($text, 'UTF-8');
-    }
-
     /**
      * Return a generalised, common raw query that can be 'unioned' across entities.
      * @param bool $withContent
index d30147bfc52b1789f2faf4ecf89d8e3b50345c09..acdec2802bc9a0c0fd922e86bd887939a9effb44 100644 (file)
@@ -62,4 +62,5 @@ class PageRevision extends Model
     {
         return $type === 'revision';
     }
+
 }
index 576ed70f00bdedb45597da098cf85e5c0c15a902..dd9ea8ebf3db7322c83ab456e91d7bdf96e62b37 100644 (file)
@@ -15,6 +15,7 @@ use BookStack\Exceptions\NotFoundException;
 use BookStack\Exceptions\NotifyException;
 use BookStack\Uploads\AttachmentService;
 use DOMDocument;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Collection;
 
@@ -179,11 +180,38 @@ class EntityRepo
      * Get all entities in a paginated format
      * @param $type
      * @param int $count
+     * @param string $sort
+     * @param string $order
+     * @param null|callable $queryAddition
      * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
      */
-    public function getAllPaginated($type, $count = 10)
+    public function getAllPaginated($type, int $count = 10, string $sort = 'name', string $order = 'asc', $queryAddition = null)
     {
-        return $this->entityQuery($type)->orderBy('name', 'asc')->paginate($count);
+        $query = $this->entityQuery($type);
+        $query = $this->addSortToQuery($query, $sort, $order);
+        if ($queryAddition) {
+            $queryAddition($query);
+        }
+        return $query->paginate($count);
+    }
+
+    /**
+     * Add sorting operations to an entity query.
+     * @param Builder $query
+     * @param string $sort
+     * @param string $order
+     * @return Builder
+     */
+    protected function addSortToQuery(Builder $query, string $sort = 'name', string $order = 'asc')
+    {
+        $order = ($order === 'asc') ? 'asc' : 'desc';
+        $propertySorts = ['name', 'created_at', 'updated_at'];
+
+        if (in_array($sort, $propertySorts)) {
+            return $query->orderBy($sort, $order);
+        }
+
+        return $query;
     }
 
     /**
@@ -313,6 +341,18 @@ class EntityRepo
         return $this->permissionService->enforceEntityRestrictions('book', $bookshelf->books())->get();
     }
 
+    /**
+     * Get the direct children of a book.
+     * @param Book $book
+     * @return \Illuminate\Database\Eloquent\Collection
+     */
+    public function getBookDirectChildren(Book $book)
+    {
+        $pages = $this->permissionService->enforceEntityRestrictions('page', $book->directPages())->get();
+        $chapters = $this->permissionService->enforceEntityRestrictions('chapters', $book->chapters())->get();
+        return collect()->concat($pages)->concat($chapters)->sortBy('priority')->sortByDesc('draft');
+    }
+
     /**
      * Get all child objects of a book.
      * Returns a sorted collection of Pages and Chapters.
index 44368a9c4fb66afb47dc2ed62b70f7a51719707e..65f97b8c984e43272e448c49b6b0564e04548e2c 100644 (file)
@@ -36,18 +36,30 @@ class BookController extends Controller
      */
     public function index()
     {
-        $books = $this->entityRepo->getAllPaginated('book', 18);
+        $view = setting()->getUser($this->currentUser, 'books_view_type', config('app.views.books'));
+        $sort = setting()->getUser($this->currentUser, 'books_sort', 'name');
+        $order = setting()->getUser($this->currentUser, 'books_sort_order', 'asc');
+        $sortOptions = [
+            'name' => trans('common.sort_name'),
+            'created_at' => trans('common.sort_created_at'),
+            'updated_at' => trans('common.sort_updated_at'),
+        ];
+
+        $books = $this->entityRepo->getAllPaginated('book', 18, $sort, $order);
         $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false;
         $popular = $this->entityRepo->getPopular('book', 4, 0);
         $new = $this->entityRepo->getRecentlyCreated('book', 4, 0);
-        $booksViewType = setting()->getUser($this->currentUser, 'books_view_type', config('app.views.books', 'list'));
+
         $this->setPageTitle(trans('entities.books'));
         return view('books/index', [
             'books' => $books,
             'recents' => $recents,
             'popular' => $popular,
             'new' => $new,
-            'booksViewType' => $booksViewType
+            'view' => $view,
+            'sort' => $sort,
+            'order' => $order,
+            'sortOptions' => $sortOptions,
         ]);
     }
 
@@ -96,7 +108,7 @@ class BookController extends Controller
             'book' => $book,
             'current' => $book,
             'bookChildren' => $bookChildren,
-            'activity' => Activity::entityActivity($book, 20, 0)
+            'activity' => Activity::entityActivity($book, 20, 1)
         ]);
     }
 
@@ -263,12 +275,12 @@ class BookController extends Controller
      * @param $bookSlug
      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
      */
-    public function showRestrict($bookSlug)
+    public function showPermissions($bookSlug)
     {
         $book = $this->entityRepo->getBySlug('book', $bookSlug);
         $this->checkOwnablePermission('restrictions-manage', $book);
         $roles = $this->userRepo->getRestrictableRoles();
-        return view('books/restrictions', [
+        return view('books.permissions', [
             'book' => $book,
             'roles' => $roles
         ]);
@@ -277,11 +289,12 @@ class BookController extends Controller
     /**
      * Set the restrictions for this book.
      * @param $bookSlug
-     * @param $bookSlug
      * @param Request $request
      * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws \BookStack\Exceptions\NotFoundException
+     * @throws \Throwable
      */
-    public function restrict($bookSlug, Request $request)
+    public function permissions($bookSlug, Request $request)
     {
         $book = $this->entityRepo->getBySlug('book', $bookSlug);
         $this->checkOwnablePermission('restrictions-manage', $book);
index 5c2898786f05d9d81db7e33130c0c6e5856ec2ea..4ac9431191d37e6f6c430d26681d6cfa30d8a5dd 100644 (file)
@@ -36,19 +36,35 @@ class BookshelfController extends Controller
      */
     public function index()
     {
-        $shelves = $this->entityRepo->getAllPaginated('bookshelf', 18);
+
+        $view = setting()->getUser($this->currentUser, 'bookshelves_view_type', config('app.views.bookshelves', 'grid'));
+
+        $sort = setting()->getUser($this->currentUser, 'bookshelves_sort', 'name');
+        $order = setting()->getUser($this->currentUser, 'bookshelves_sort_order', 'asc');
+        $sortOptions = [
+            'name' => trans('common.sort_name'),
+            'created_at' => trans('common.sort_created_at'),
+            'updated_at' => trans('common.sort_updated_at'),
+        ];
+
+        $shelves = $this->entityRepo->getAllPaginated('bookshelf', 18, $sort, $order, function($query) {
+            $query->with(['books']);
+        });
         $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('bookshelf', 4, 0) : false;
         $popular = $this->entityRepo->getPopular('bookshelf', 4, 0);
         $new = $this->entityRepo->getRecentlyCreated('bookshelf', 4, 0);
-        $shelvesViewType = setting()->getUser($this->currentUser, 'bookshelves_view_type', config('app.views.bookshelves', 'grid'));
+
 
         $this->setPageTitle(trans('entities.shelves'));
-        return view('shelves/index', [
+        return view('shelves.index', [
             'shelves' => $shelves,
             'recents' => $recents,
             'popular' => $popular,
             'new' => $new,
-            'shelvesViewType' => $shelvesViewType
+            'view' => $view,
+            'sort' => $sort,
+            'order' => $order,
+            'sortOptions' => $sortOptions,
         ]);
     }
 
@@ -61,7 +77,7 @@ class BookshelfController extends Controller
         $this->checkPermission('bookshelf-create-all');
         $books = $this->entityRepo->getAll('book', false, 'update');
         $this->setPageTitle(trans('entities.shelves_create'));
-        return view('shelves/create', ['books' => $books]);
+        return view('shelves.create', ['books' => $books]);
     }
 
     /**
@@ -100,10 +116,10 @@ class BookshelfController extends Controller
         Views::add($bookshelf);
 
         $this->setPageTitle($bookshelf->getShortName());
-        return view('shelves/show', [
+        return view('shelves.show', [
             'shelf' => $bookshelf,
             'books' => $books,
-            'activity' => Activity::entityActivity($bookshelf, 20, 0)
+            'activity' => Activity::entityActivity($bookshelf, 20, 1)
         ]);
     }
 
@@ -126,7 +142,7 @@ class BookshelfController extends Controller
         });
 
         $this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $bookshelf->getShortName()]));
-        return view('shelves/edit', [
+        return view('shelves.edit', [
             'shelf' => $bookshelf,
             'books' => $books,
             'shelfBooks' => $shelfBooks,
@@ -170,7 +186,7 @@ class BookshelfController extends Controller
         $this->checkOwnablePermission('bookshelf-delete', $bookshelf);
 
         $this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $bookshelf->getShortName()]));
-        return view('shelves/delete', ['shelf' => $bookshelf]);
+        return view('shelves.delete', ['shelf' => $bookshelf]);
     }
 
     /**
@@ -190,31 +206,32 @@ class BookshelfController extends Controller
     }
 
     /**
-     * Show the Restrictions view.
-     * @param $slug
+     * Show the permissions view.
+     * @param string $slug
      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
      * @throws \BookStack\Exceptions\NotFoundException
      */
-    public function showRestrict(string $slug)
+    public function showPermissions(string $slug)
     {
         $bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug);
         $this->checkOwnablePermission('restrictions-manage', $bookshelf);
 
         $roles = $this->userRepo->getRestrictableRoles();
-        return view('shelves.restrictions', [
+        return view('shelves.permissions', [
             'shelf' => $bookshelf,
             'roles' => $roles
         ]);
     }
 
     /**
-     * Set the restrictions for this bookshelf.
-     * @param $slug
+     * Set the permissions for this bookshelf.
+     * @param string $slug
      * @param Request $request
      * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
      * @throws \BookStack\Exceptions\NotFoundException
+     * @throws \Throwable
      */
-    public function restrict(string $slug, Request $request)
+    public function permissions(string $slug, Request $request)
     {
         $bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug);
         $this->checkOwnablePermission('restrictions-manage', $bookshelf);
index 20ab9613318947d962997953d865413f882134cd..45ecbb5d5ec3e131dcdce6aef7ebe27419e2660a 100644 (file)
@@ -214,13 +214,14 @@ class ChapterController extends Controller
      * @param $bookSlug
      * @param $chapterSlug
      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     * @throws \BookStack\Exceptions\NotFoundException
      */
-    public function showRestrict($bookSlug, $chapterSlug)
+    public function showPermissions($bookSlug, $chapterSlug)
     {
         $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
         $this->checkOwnablePermission('restrictions-manage', $chapter);
         $roles = $this->userRepo->getRestrictableRoles();
-        return view('chapters/restrictions', [
+        return view('chapters.permissions', [
             'chapter' => $chapter,
             'roles' => $roles
         ]);
@@ -232,8 +233,10 @@ class ChapterController extends Controller
      * @param $chapterSlug
      * @param Request $request
      * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws \BookStack\Exceptions\NotFoundException
+     * @throws \Throwable
      */
-    public function restrict($bookSlug, $chapterSlug, Request $request)
+    public function permissions($bookSlug, $chapterSlug, Request $request)
     {
         $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
         $this->checkOwnablePermission('restrictions-manage', $chapter);
index 80f567eaa80279e8f49599f9703f5ab29e6276c3..fc4f184fcabdff0bf292b6f6c257912ce6d98a2d 100644 (file)
@@ -123,6 +123,20 @@ abstract class Controller extends BaseController
         return true;
     }
 
+    /**
+     * Check if the current user has a permission or bypass if the provided user
+     * id matches the current user.
+     * @param string $permissionName
+     * @param int $userId
+     * @return bool
+     */
+    protected function checkPermissionOrCurrentUser(string $permissionName, int $userId)
+    {
+        return $this->checkPermissionOr($permissionName, function() use ($userId) {
+            return $userId === $this->currentUser->id;
+        });
+    }
+
     /**
      * Send back a json error message.
      * @param string $messageText
index d95e02470bee10c63d436421ac7a53cdcff6577c..16a7d5a5e45df6df1094bfa14df63fb17cb278f3 100644 (file)
@@ -61,7 +61,7 @@ class PageController extends Controller
 
         // Otherwise show the edit view if they're a guest
         $this->setPageTitle(trans('entities.pages_new'));
-        return view('pages/guest-create', ['parent' => $parent]);
+        return view('pages.guest-create', ['parent' => $parent]);
     }
 
     /**
@@ -110,7 +110,7 @@ class PageController extends Controller
         $this->setPageTitle(trans('entities.pages_edit_draft'));
 
         $draftsEnabled = $this->signedIn;
-        return view('pages/edit', [
+        return view('pages.edit', [
             'page' => $draft,
             'book' => $draft->book,
             'isDraft' => true,
@@ -184,7 +184,7 @@ class PageController extends Controller
 
         Views::add($page);
         $this->setPageTitle($page->getShortName());
-        return view('pages/show', [
+        return view('pages.show', [
             'page' => $page,'book' => $page->book,
             'current' => $page,
             'sidebarTree' => $sidebarTree,
@@ -239,7 +239,7 @@ class PageController extends Controller
         }
 
         $draftsEnabled = $this->signedIn;
-        return view('pages/edit', [
+        return view('pages.edit', [
             'page' => $page,
             'book' => $page->book,
             'current' => $page,
@@ -317,7 +317,7 @@ class PageController extends Controller
         $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
         $this->checkOwnablePermission('page-delete', $page);
         $this->setPageTitle(trans('entities.pages_delete_named', ['pageName'=>$page->getShortName()]));
-        return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
+        return view('pages.delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
     }
 
 
@@ -333,7 +333,7 @@ class PageController extends Controller
         $page = $this->pageRepo->getById('page', $pageId, true);
         $this->checkOwnablePermission('page-update', $page);
         $this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName'=>$page->getShortName()]));
-        return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
+        return view('pages.delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
     }
 
     /**
@@ -377,12 +377,13 @@ class PageController extends Controller
      * @param string $bookSlug
      * @param string $pageSlug
      * @return \Illuminate\View\View
+     * @throws NotFoundException
      */
     public function showRevisions($bookSlug, $pageSlug)
     {
         $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
         $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
-        return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
+        return view('pages.revisions', ['page' => $page, 'current' => $page]);
     }
 
     /**
@@ -403,9 +404,10 @@ class PageController extends Controller
         $page->fill($revision->toArray());
         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
 
-        return view('pages/revision', [
+        return view('pages.revision', [
             'page' => $page,
             'book' => $page->book,
+            'diff' => null,
             'revision' => $revision
         ]);
     }
@@ -432,7 +434,7 @@ class PageController extends Controller
         $page->fill($revision->toArray());
         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
 
-        return view('pages/revision', [
+        return view('pages.revision', [
             'page' => $page,
             'book' => $page->book,
             'diff' => $diff,
@@ -482,12 +484,12 @@ class PageController extends Controller
         // Check if its the latest revision, cannot delete latest revision.
         if (intval($currentRevision->id) === intval($revId)) {
             session()->flash('error', trans('entities.revision_cannot_delete_latest'));
-            return response()->view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page], 400);
+            return response()->view('pages.revisions', ['page' => $page, 'book' => $page->book, 'current' => $page], 400);
         }
 
         $revision->delete();
         session()->flash('success', trans('entities.revision_delete_success'));
-        return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
+        return view('pages.revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
     }
 
     /**
@@ -532,49 +534,20 @@ class PageController extends Controller
         return $this->downloadResponse($pageText, $pageSlug . '.txt');
     }
 
-    /**
-     * Show a listing of recently created pages
-     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
-     */
-    public function showRecentlyCreated()
-    {
-        $pages = $this->pageRepo->getRecentlyCreatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-created'));
-        return view('pages/detailed-listing', [
-            'title' => trans('entities.recently_created_pages'),
-            'pages' => $pages
-        ]);
-    }
-
     /**
      * Show a listing of recently created pages
      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
      */
     public function showRecentlyUpdated()
     {
+        // TODO - Still exist?
         $pages = $this->pageRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated'));
-        return view('pages/detailed-listing', [
+        return view('pages.detailed-listing', [
             'title' => trans('entities.recently_updated_pages'),
             'pages' => $pages
         ]);
     }
 
-    /**
-     * Show the Restrictions view.
-     * @param string $bookSlug
-     * @param string $pageSlug
-     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
-     */
-    public function showRestrict($bookSlug, $pageSlug)
-    {
-        $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
-        $this->checkOwnablePermission('restrictions-manage', $page);
-        $roles = $this->userRepo->getRestrictableRoles();
-        return view('pages/restrictions', [
-            'page'  => $page,
-            'roles' => $roles
-        ]);
-    }
-
     /**
      * Show the view to choose a new parent to move a page into.
      * @param string $bookSlug
@@ -587,7 +560,7 @@ class PageController extends Controller
         $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
         $this->checkOwnablePermission('page-update', $page);
         $this->checkOwnablePermission('page-delete', $page);
-        return view('pages/move', [
+        return view('pages.move', [
             'book' => $page->book,
             'page' => $page
         ]);
@@ -645,7 +618,7 @@ class PageController extends Controller
         $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
         $this->checkOwnablePermission('page-view', $page);
         session()->flashInput(['name' => $page->name]);
-        return view('pages/copy', [
+        return view('pages.copy', [
             'book' => $page->book,
             'page' => $page
         ]);
@@ -690,6 +663,24 @@ class PageController extends Controller
         return redirect($pageCopy->getUrl());
     }
 
+    /**
+     * Show the Permissions view.
+     * @param string $bookSlug
+     * @param string $pageSlug
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     * @throws NotFoundException
+     */
+    public function showPermissions($bookSlug, $pageSlug)
+    {
+        $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
+        $this->checkOwnablePermission('restrictions-manage', $page);
+        $roles = $this->userRepo->getRestrictableRoles();
+        return view('pages.permissions', [
+            'page'  => $page,
+            'roles' => $roles
+        ]);
+    }
+
     /**
      * Set the permissions for this page.
      * @param string $bookSlug
@@ -697,8 +688,9 @@ class PageController extends Controller
      * @param Request $request
      * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
      * @throws NotFoundException
+     * @throws \Throwable
      */
-    public function restrict($bookSlug, $pageSlug, Request $request)
+    public function permissions($bookSlug, $pageSlug, Request $request)
     {
         $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
         $this->checkOwnablePermission('restrictions-manage', $page);
index 9be343c9a76011a5bd5b7a872ad78b1e6a9a8d3c..9893d59935ff6d284d98d5e335e2b452089de15e 100644 (file)
@@ -26,7 +26,7 @@ class PermissionController extends Controller
     {
         $this->checkPermission('user-roles-manage');
         $roles = $this->permissionsRepo->getAllRoles();
-        return view('settings/roles/index', ['roles' => $roles]);
+        return view('settings.roles.index', ['roles' => $roles]);
     }
 
     /**
@@ -36,7 +36,7 @@ class PermissionController extends Controller
     public function createRole()
     {
         $this->checkPermission('user-roles-manage');
-        return view('settings/roles/create');
+        return view('settings.roles.create');
     }
 
     /**
@@ -70,7 +70,7 @@ class PermissionController extends Controller
         if ($role->hidden) {
             throw new PermissionsException(trans('errors.role_cannot_be_edited'));
         }
-        return view('settings/roles/edit', ['role' => $role]);
+        return view('settings.roles.edit', ['role' => $role]);
     }
 
     /**
@@ -106,7 +106,7 @@ class PermissionController extends Controller
         $roles = $this->permissionsRepo->getAllRolesExcept($role);
         $blankRole = $role->newInstance(['display_name' => trans('settings.role_delete_no_migration')]);
         $roles->prepend($blankRole);
-        return view('settings/roles/delete', ['role' => $role, 'roles' => $roles]);
+        return view('settings.roles.delete', ['role' => $role, 'roles' => $roles]);
     }
 
     /**
index d8f2dc4d7eac6a1eec6e7f0a584b893f4a32c9a7..1f4224c792751eef905feed1aae1b23e57c6454a 100644 (file)
@@ -3,6 +3,7 @@
 use BookStack\Actions\ViewService;
 use BookStack\Entities\Repos\EntityRepo;
 use BookStack\Entities\SearchService;
+use BookStack\Exceptions\NotFoundException;
 use Illuminate\Http\Request;
 
 class SearchController extends Controller
@@ -104,4 +105,45 @@ class SearchController extends Controller
 
         return view('search/entity-ajax-list', ['entities' => $entities]);
     }
+
+    /**
+     * Search siblings items in the system.
+     * @param Request $request
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed
+     */
+    public function searchSiblings(Request $request)
+    {
+        $type = $request->get('entity_type', null);
+        $id = $request->get('entity_id', null);
+
+        $entity = $this->entityRepo->getById($type, $id);
+        if (!$entity) {
+            return $this->jsonError(trans('errors.entity_not_found'), 404);
+        }
+
+        $entities = [];
+
+        // Page in chapter
+        if ($entity->isA('page') && $entity->chapter) {
+            $entities = $this->entityRepo->getChapterChildren($entity->chapter);
+        }
+
+        // Page in book or chapter
+        if (($entity->isA('page') && !$entity->chapter) || $entity->isA('chapter')) {
+            $entities = $this->entityRepo->getBookDirectChildren($entity->book);
+        }
+
+        // Book in shelf
+        // TODO - When shelve tracking added, Update below if criteria
+
+        // Book
+        if ($entity->isA('book')) {
+            $entities = $this->entityRepo->getAll('book');
+        }
+
+        // Shelve
+        // TODO - When shelve tracking added
+
+        return view('partials.entity-list-basic', ['entities' => $entities, 'style' => 'compact']);
+    }
 }
index 01fb68fe06e509908bd863671eddf0f2c94ba323..159e19a2bb441d8b8ef3d296ad0ef856471fbe9f 100644 (file)
@@ -1,5 +1,6 @@
 <?php namespace BookStack\Http\Controllers;
 
+use BookStack\Auth\User;
 use BookStack\Uploads\ImageService;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
@@ -19,7 +20,10 @@ class SettingController extends Controller
         // Get application version
         $version = trim(file_get_contents(base_path('version')));
 
-        return view('settings/index', ['version' => $version]);
+        return view('settings.index', [
+            'version' => $version,
+            'guestUser' => User::getDefault()
+        ]);
     }
 
     /**
@@ -57,7 +61,7 @@ class SettingController extends Controller
         // Get application version
         $version = trim(file_get_contents(base_path('version')));
 
-        return view('settings/maintenance', ['version' => $version]);
+        return view('settings.maintenance', ['version' => $version]);
     }
 
     /**
index cc5ada3f283d2bd4e24f01cc9235e637b0ffa9a1..327a5499561a1a9e391e925466c772c3fa399e41 100644 (file)
@@ -251,41 +251,88 @@ class UserController extends Controller
      */
     public function switchBookView($id, Request $request)
     {
-        $this->checkPermissionOr('users-manage', function () use ($id) {
-            return $this->currentUser->id == $id;
-        });
+        return $this->switchViewType($id, $request, 'books');
+    }
+
+    /**
+     * Update the user's preferred shelf-list display setting.
+     * @param $id
+     * @param Request $request
+     * @return \Illuminate\Http\RedirectResponse
+     */
+    public function switchShelfView($id, Request $request)
+    {
+        return $this->switchViewType($id, $request, 'bookshelves');
+    }
+
+    /**
+     * For a type of list, switch with stored view type for a user.
+     * @param integer $userId
+     * @param Request $request
+     * @param string $listName
+     * @return \Illuminate\Http\RedirectResponse
+     */
+    protected function switchViewType($userId, Request $request, string $listName)
+    {
+        $this->checkPermissionOrCurrentUser('users-manage', $userId);
 
         $viewType = $request->get('view_type');
         if (!in_array($viewType, ['grid', 'list'])) {
             $viewType = 'list';
         }
 
-        $user = $this->user->findOrFail($id);
-        setting()->putUser($user, 'books_view_type', $viewType);
+        $user = $this->userRepo->getById($userId);
+        $key = $listName . '_view_type';
+        setting()->putUser($user, $key, $viewType);
 
-        return redirect()->back(302, [], "/settings/users/$id");
+        return redirect()->back(302, [], "/settings/users/$userId");
     }
 
     /**
-     * Update the user's preferred shelf-list display setting.
-     * @param $id
+     * Change the stored sort type for a particular view.
+     * @param string $id
+     * @param string $type
      * @param Request $request
      * @return \Illuminate\Http\RedirectResponse
      */
-    public function switchShelfView($id, Request $request)
+    public function changeSort(string $id, string $type, Request $request)
     {
-        $this->checkPermissionOr('users-manage', function () use ($id) {
-            return $this->currentUser->id == $id;
-        });
+        // TODO - Test this endpoint
+        $validSortTypes = ['books', 'bookshelves'];
+        if (!in_array($type, $validSortTypes)) {
+            return redirect()->back(500);
+        }
+        return $this->changeListSort($id, $request, $type);
+    }
 
-        $viewType = $request->get('view_type');
-        if (!in_array($viewType, ['grid', 'list'])) {
-            $viewType = 'list';
+    /**
+     * Changed the stored preference for a list sort order.
+     * @param int $userId
+     * @param Request $request
+     * @param string $listName
+     * @return \Illuminate\Http\RedirectResponse
+     */
+    protected function changeListSort(int $userId, Request $request, string $listName)
+    {
+        $this->checkPermissionOrCurrentUser('users-manage', $userId);
+
+        $sort = $request->get('sort');
+        if (!in_array($sort, ['name', 'created_at', 'updated_at'])) {
+            $sort = 'name';
         }
 
-        $user = $this->userRepo->getById($id);
-        setting()->putUser($user, 'bookshelves_view_type', $viewType);
+        $order = $request->get('order');
+        if (!in_array($order, ['asc', 'desc'])) {
+            $order = 'asc';
+        }
 
-        return redirect()->back(302, [], "/settings/users/$id");
+        $user = $this->user->findOrFail($userId);
+        $sortKey = $listName . '_sort';
+        $orderKey = $listName . '_sort_order';
+        setting()->putUser($user, $sortKey, $sort);
+        setting()->putUser($user, $orderKey, $order);
+
+        return redirect()->back(302, [], "/settings/users/$userId");
     }
+
 }
index c9b2726e8c4eca4f9148f7567a035433bf216879..1a33843675a97266095cd6c2cb96918369652c9d 100644 (file)
@@ -37,7 +37,7 @@ class Authenticate
             }
         }
 
-        if ($this->auth->guest() && !setting('app-public')) {
+        if (!hasAppAccess()) {
             if ($request->ajax()) {
                 return response('Unauthorized.', 401);
             } else {
index c9491e3eeb4b4c949248680b9d43b1a0e45c3f59..663a6ae3275954a2fa944c3d80fa07d832861038 100644 (file)
@@ -61,6 +61,9 @@ class SettingService
      */
     public function getUser($user, $key, $default = false)
     {
+        if ($user->isDefault()) {
+            return session()->get($key, $default);
+        }
         return $this->get($this->userKey($user->id, $key), $default);
     }
 
@@ -180,6 +183,9 @@ class SettingService
      */
     public function putUser($user, $key, $value)
     {
+        if ($user->isDefault()) {
+            return session()->put($key, $value);
+        }
         return $this->put($this->userKey($user->id, $key), $value);
     }
 
index d9533645de6e31ae1c464b7466f1ee71a498a721..3f7b5e1b1350c1294adfee1b001775fb3a72b62b 100644 (file)
@@ -43,11 +43,19 @@ function user()
  * Check if current user is a signed in user.
  * @return bool
  */
-function signedInUser()
+function signedInUser() : bool
 {
     return auth()->user() && !auth()->user()->isDefault();
 }
 
+/**
+ * Check if the current user has general access.
+ * @return bool
+ */
+function hasAppAccess() : bool {
+    return !auth()->guest() || setting('app-public');
+}
+
 /**
  * Check if the current user has a permission.
  * If an ownable element is passed in the jointPermissions are checked against
index e1d1ace438c9049375aeff29c16c12320fce3ef8..4d779f6f913db64efc2c6babe39075ed587173dc 100644 (file)
       "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=",
       "dev": true
     },
-    "alphanum-sort": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
-      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
-      "dev": true
-    },
     "amdefine": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
       "dev": true
     },
     "autoprefixer": {
-      "version": "8.6.5",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz",
-      "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==",
+      "version": "9.4.7",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.7.tgz",
+      "integrity": "sha512-qS5wW6aXHkm53Y4z73tFGsUhmZu4aMPV9iHXYlF0c/wxjknXNHuj/1cIQb+6YH692DbJGGWcckAXX+VxKvahMA==",
       "dev": true,
       "requires": {
-        "browserslist": "^3.2.8",
-        "caniuse-lite": "^1.0.30000864",
+        "browserslist": "^4.4.1",
+        "caniuse-lite": "^1.0.30000932",
         "normalize-range": "^0.1.2",
         "num2fraction": "^1.2.2",
-        "postcss": "^6.0.23",
-        "postcss-value-parser": "^3.2.3"
+        "postcss": "^7.0.14",
+        "postcss-value-parser": "^3.3.1"
       },
       "dependencies": {
         "browserslist": {
-          "version": "3.2.8",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
-          "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+          "version": "4.4.1",
+          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz",
+          "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==",
+          "dev": true,
+          "requires": {
+            "caniuse-lite": "^1.0.30000929",
+            "electron-to-chromium": "^1.3.103",
+            "node-releases": "^1.1.3"
+          }
+        },
+        "caniuse-lite": {
+          "version": "1.0.30000934",
+          "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000934.tgz",
+          "integrity": "sha512-o7yfZn0R9N+mWAuksDsdLsb1gu9o//XK0QSU0zSSReKNRsXsFc/n/psxi0YSPNiqlKxImp5h4DHnAPdwYJ8nNA==",
+          "dev": true
+        },
+        "electron-to-chromium": {
+          "version": "1.3.112",
+          "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.112.tgz",
+          "integrity": "sha512-FyVLdiRZnLw2WE5ECtveN0JJ7klyiz/HMfKE1/Rjff3l7pe4vfkYtBlcCqTckvR8E7asjJGh0m9gRPR3Anp/UA==",
+          "dev": true
+        },
+        "node-releases": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.7.tgz",
+          "integrity": "sha512-bKdrwaqJUPHqlCzDD7so/R+Nk0jGv9a11ZhLrD9f6i947qGLrGAhU3OxRENa19QQmwzGy/g6zCDEuLGDO8HPvA==",
           "dev": true,
           "requires": {
-            "caniuse-lite": "^1.0.30000844",
-            "electron-to-chromium": "^1.3.47"
+            "semver": "^5.3.0"
           }
         }
       }
         }
       }
     },
-    "babel-code-frame": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
-      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
-      "dev": true,
-      "requires": {
-        "chalk": "^1.1.3",
-        "esutils": "^2.0.2",
-        "js-tokens": "^3.0.2"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
-        }
-      }
-    },
     "babel-loader": {
       "version": "8.0.4",
       "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.4.tgz",
       "dev": true
     },
     "cacache": {
-      "version": "10.0.4",
-      "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
-      "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
-      "dev": true,
-      "requires": {
-        "bluebird": "^3.5.1",
-        "chownr": "^1.0.1",
-        "glob": "^7.1.2",
-        "graceful-fs": "^4.1.11",
-        "lru-cache": "^4.1.1",
-        "mississippi": "^2.0.0",
+      "version": "11.3.2",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
+      "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.3",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.3",
+        "graceful-fs": "^4.1.15",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
         "mkdirp": "^0.5.1",
         "move-concurrently": "^1.0.1",
         "promise-inflight": "^1.0.1",
         "rimraf": "^2.6.2",
-        "ssri": "^5.2.4",
-        "unique-filename": "^1.1.0",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
         "y18n": "^4.0.0"
       },
       "dependencies": {
+        "bluebird": {
+          "version": "3.5.3",
+          "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
+          "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==",
+          "dev": true
+        },
+        "graceful-fs": {
+          "version": "4.1.15",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+          "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+          "dev": true
+        },
+        "lru-cache": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+          "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+          "dev": true,
+          "requires": {
+            "yallist": "^3.0.2"
+          }
+        },
         "y18n": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
           "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
           "dev": true
+        },
+        "yallist": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+          "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+          "dev": true
         }
       }
     },
         "map-obj": "^1.0.0"
       }
     },
-    "caniuse-api": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
-      "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
-      "dev": true,
-      "requires": {
-        "browserslist": "^1.3.6",
-        "caniuse-db": "^1.0.30000529",
-        "lodash.memoize": "^4.1.2",
-        "lodash.uniq": "^4.5.0"
-      },
-      "dependencies": {
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "^1.0.30000639",
-            "electron-to-chromium": "^1.2.7"
-          }
-        }
-      }
-    },
-    "caniuse-db": {
-      "version": "1.0.30000904",
-      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000904.tgz",
-      "integrity": "sha512-iZ36AxtEx7ZiCBKhF2qFL8ED6u9zJGPU7Aq6HwZQYUbetBgYkGZfoPHq9z38jahV2kr8BgDYfXvftA35Ng2AaA==",
-      "dev": true
-    },
     "caniuse-lite": {
       "version": "1.0.30000904",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000904.tgz",
         "safe-buffer": "^5.0.1"
       }
     },
-    "clap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
-      "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
-      "dev": true,
-      "requires": {
-        "chalk": "^1.1.3"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
-        }
-      }
-    },
     "class-utils": {
       "version": "0.3.6",
       "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
         "wrap-ansi": "^2.0.0"
       }
     },
-    "clone": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
-      "dev": true
-    },
     "clone-deep": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
       "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
       "dev": true
     },
-    "coa": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
-      "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
-      "dev": true,
-      "requires": {
-        "q": "^1.1.2"
-      }
-    },
     "code-point-at": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
         "object-visit": "^1.0.0"
       }
     },
-    "color": {
-      "version": "0.11.4",
-      "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
-      "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
-      "dev": true,
-      "requires": {
-        "clone": "^1.0.2",
-        "color-convert": "^1.3.0",
-        "color-string": "^0.3.0"
-      }
-    },
     "color-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
       "dev": true
     },
-    "color-string": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
-      "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
-      "dev": true,
-      "requires": {
-        "color-name": "^1.0.0"
-      }
-    },
-    "colormin": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
-      "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
-      "dev": true,
-      "requires": {
-        "color": "^0.11.0",
-        "css-color-names": "0.0.4",
-        "has": "^1.0.1"
-      }
-    },
-    "colors": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
-      "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
-      "dev": true
-    },
     "combined-stream": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
       }
     },
     "commander": {
-      "version": "2.13.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
-      "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+      "version": "2.17.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
       "dev": true
     },
     "commondir": {
         "require-from-string": "^2.0.1"
       },
       "dependencies": {
-        "esprima": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-          "dev": true
-        },
-        "js-yaml": {
-          "version": "3.12.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
-          "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
-          "dev": true,
-          "requires": {
-            "argparse": "^1.0.7",
-            "esprima": "^4.0.0"
-          }
-        },
         "parse-json": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
         "randomfill": "^1.0.3"
       }
     },
-    "css-color-names": {
-      "version": "0.0.4",
-      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
-      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
-      "dev": true
-    },
     "css-loader": {
-      "version": "0.28.11",
-      "resolved": "http://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz",
-      "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==",
-      "dev": true,
-      "requires": {
-        "babel-code-frame": "^6.26.0",
-        "css-selector-tokenizer": "^0.7.0",
-        "cssnano": "^3.10.0",
-        "icss-utils": "^2.1.0",
-        "loader-utils": "^1.0.2",
-        "lodash.camelcase": "^4.3.0",
-        "object-assign": "^4.1.1",
-        "postcss": "^5.0.6",
-        "postcss-modules-extract-imports": "^1.2.0",
-        "postcss-modules-local-by-default": "^1.2.0",
-        "postcss-modules-scope": "^1.1.0",
-        "postcss-modules-values": "^1.3.0",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.0.tgz",
+      "integrity": "sha512-MoOu+CStsGrSt5K2OeZ89q3Snf+IkxRfAIt9aAKg4piioTrhtP1iEFPu+OVn3Ohz24FO6L+rw9UJxBILiSBw5Q==",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^4.0.0",
+        "loader-utils": "^1.2.1",
+        "lodash": "^4.17.11",
+        "postcss": "^7.0.6",
+        "postcss-modules-extract-imports": "^2.0.0",
+        "postcss-modules-local-by-default": "^2.0.3",
+        "postcss-modules-scope": "^2.0.0",
+        "postcss-modules-values": "^2.0.0",
         "postcss-value-parser": "^3.3.0",
-        "source-list-map": "^2.0.0"
+        "schema-utils": "^1.0.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+        "ajv": {
+          "version": "6.8.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+          "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
           "dev": true,
           "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
           }
         },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+        "big.js": {
+          "version": "5.2.2",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+          "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
           "dev": true
         },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
           "dev": true,
           "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
+            "minimist": "^1.2.0"
           }
         },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+        "loader-utils": {
+          "version": "1.2.3",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+          "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^2.0.0",
+            "json5": "^1.0.1"
+          }
+        },
+        "lodash": {
+          "version": "4.17.11",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
           "dev": true
         },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
           "dev": true,
           "requires": {
-            "has-flag": "^1.0.0"
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
           }
         }
       }
         },
         "regjsgen": {
           "version": "0.2.0",
-          "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
           "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
           "dev": true
         },
       "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
       "dev": true
     },
-    "cssnano": {
-      "version": "3.10.0",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
-      "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
       "dev": true,
       "requires": {
-        "autoprefixer": "^6.3.1",
-        "decamelize": "^1.1.2",
-        "defined": "^1.0.0",
-        "has": "^1.0.1",
-        "object-assign": "^4.0.1",
-        "postcss": "^5.0.14",
-        "postcss-calc": "^5.2.0",
-        "postcss-colormin": "^2.1.8",
-        "postcss-convert-values": "^2.3.4",
-        "postcss-discard-comments": "^2.0.4",
-        "postcss-discard-duplicates": "^2.0.1",
-        "postcss-discard-empty": "^2.0.1",
-        "postcss-discard-overridden": "^0.1.1",
-        "postcss-discard-unused": "^2.2.1",
-        "postcss-filter-plugins": "^2.0.0",
-        "postcss-merge-idents": "^2.1.5",
-        "postcss-merge-longhand": "^2.0.1",
-        "postcss-merge-rules": "^2.0.3",
-        "postcss-minify-font-values": "^1.0.2",
-        "postcss-minify-gradients": "^1.0.1",
-        "postcss-minify-params": "^1.0.4",
-        "postcss-minify-selectors": "^2.0.4",
-        "postcss-normalize-charset": "^1.1.0",
-        "postcss-normalize-url": "^3.0.7",
-        "postcss-ordered-values": "^2.1.0",
-        "postcss-reduce-idents": "^2.2.2",
-        "postcss-reduce-initial": "^1.0.0",
-        "postcss-reduce-transforms": "^1.0.3",
-        "postcss-svgo": "^2.1.1",
-        "postcss-unique-selectors": "^2.0.2",
-        "postcss-value-parser": "^3.2.3",
-        "postcss-zindex": "^2.0.1"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "autoprefixer": {
-          "version": "6.7.7",
-          "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
-          "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
-          "dev": true,
-          "requires": {
-            "browserslist": "^1.7.6",
-            "caniuse-db": "^1.0.30000634",
-            "normalize-range": "^0.1.2",
-            "num2fraction": "^1.2.2",
-            "postcss": "^5.2.16",
-            "postcss-value-parser": "^3.2.3"
-          }
-        },
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "^1.0.30000639",
-            "electron-to-chromium": "^1.2.7"
-          }
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "csso": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
-      "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
-      "dev": true,
-      "requires": {
-        "clap": "^1.0.9",
-        "source-map": "^0.5.3"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        }
-      }
-    },
-    "currently-unhandled": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
-      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
-      "dev": true,
-      "requires": {
-        "array-find-index": "^1.0.1"
-      }
-    },
-    "cyclist": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
-      "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
-      "dev": true
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "date-now": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
-      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
-      "dev": true
-    },
-    "debug": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
-      "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
-      "dev": true,
-      "requires": {
-        "ms": "^2.1.1"
+        "array-find-index": "^1.0.1"
+      }
+    },
+    "cyclist": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+      "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "date-now": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+      "dev": true
+    },
+    "debug": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
+      "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
+      "dev": true,
+      "requires": {
+        "ms": "^2.1.1"
       },
       "dependencies": {
         "ms": {
         }
       }
     },
-    "defined": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
-      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
-      "dev": true
-    },
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
       }
     },
     "esprima": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
       "dev": true
     },
     "esrecurse": {
         "is-extglob": "^1.0.0"
       }
     },
-    "extract-text-webpack-plugin": {
-      "version": "4.0.0-beta.0",
-      "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-4.0.0-beta.0.tgz",
-      "integrity": "sha512-Hypkn9jUTnFr0DpekNam53X47tXn3ucY08BQumv7kdGgeVUBLq3DJHJTi6HNxv4jl9W+Skxjz9+RnK0sJyqqjA==",
-      "dev": true,
-      "requires": {
-        "async": "^2.4.1",
-        "loader-utils": "^1.1.0",
-        "schema-utils": "^0.4.5",
-        "webpack-sources": "^1.1.0"
-      },
-      "dependencies": {
-        "async": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
-          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
-          "dev": true,
-          "requires": {
-            "lodash": "^4.14.0"
-          }
-        }
-      }
-    },
     "extsprintf": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
         "locate-path": "^2.0.0"
       }
     },
-    "flatten": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
-      "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
-      "dev": true
-    },
     "flush-write-stream": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
       "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
       "dev": true
     },
-    "html-comment-regex": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
-      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
-      "dev": true
-    },
     "http-signature": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
       "dev": true
     },
     "icss-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
-      "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.0.0.tgz",
+      "integrity": "sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA==",
       "dev": true,
       "requires": {
-        "postcss": "^6.0.1"
+        "postcss": "^7.0.5"
       }
     },
     "ieee754": {
         "repeating": "^2.0.0"
       }
     },
-    "indexes-of": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
-      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
-      "dev": true
-    },
     "indexof": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
       "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
       "dev": true
     },
-    "is-absolute-url": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
-      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
-      "dev": true
-    },
     "is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
         "kind-of": "^3.0.2"
       }
     },
-    "is-plain-obj": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
-      "dev": true
-    },
     "is-plain-object": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
       "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
       "dev": true
     },
-    "is-svg": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
-      "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
-      "dev": true,
-      "requires": {
-        "html-comment-regex": "^1.1.0"
-      }
-    },
     "is-symbol": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
       "dev": true
     },
     "js-yaml": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
-      "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
+      "version": "3.12.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
+      "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
       "dev": true,
       "requires": {
         "argparse": "^1.0.7",
-        "esprima": "^2.6.0"
+        "esprima": "^4.0.0"
       }
     },
     "jsbn": {
       "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
       "dev": true
     },
-    "lodash.camelcase": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
-      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
-      "dev": true
-    },
     "lodash.clonedeep": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
       "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
       "dev": true
     },
-    "lodash.memoize": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
-      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
-      "dev": true
-    },
     "lodash.mergewith": {
       "version": "4.6.1",
       "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
       "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
       "dev": true
     },
-    "lodash.uniq": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
-      "dev": true
-    },
     "loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
       "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
       "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
     },
-    "math-expression-evaluator": {
-      "version": "1.2.17",
-      "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
-      "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
-      "dev": true
-    },
     "math-random": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
       "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
       "dev": true
     },
+    "mini-css-extract-plugin": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
+      "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^1.0.0",
+        "webpack-sources": "^1.1.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.8.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+          "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
     "minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
       "dev": true
     },
     "mississippi": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
-      "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
       "dev": true,
       "requires": {
         "concat-stream": "^1.5.0",
         "flush-write-stream": "^1.0.0",
         "from2": "^2.1.0",
         "parallel-transform": "^1.1.0",
-        "pump": "^2.0.1",
+        "pump": "^3.0.0",
         "pumpify": "^1.3.3",
         "stream-each": "^1.1.0",
         "through2": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
       }
     },
     "mixin-deep": {
       "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
       "dev": true
     },
-    "normalize-url": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
-      "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
-      "dev": true,
-      "requires": {
-        "object-assign": "^4.0.1",
-        "prepend-http": "^1.0.0",
-        "query-string": "^4.1.0",
-        "sort-keys": "^1.0.0"
-      }
-    },
     "npm-run-all": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
       "dev": true
     },
     "postcss": {
-      "version": "6.0.23",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
-      "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+      "version": "7.0.14",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz",
+      "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==",
       "dev": true,
       "requires": {
-        "chalk": "^2.4.1",
+        "chalk": "^2.4.2",
         "source-map": "^0.6.1",
-        "supports-color": "^5.4.0"
-      }
-    },
-    "postcss-calc": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
-      "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.2",
-        "postcss-message-helpers": "^2.0.0",
-        "reduce-css-calc": "^1.2.6"
+        "supports-color": "^6.1.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
         "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
           },
           "dependencies": {
             "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
+              "version": "5.5.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+              "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
             }
           }
         },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
         "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
           "dev": true,
           "requires": {
-            "has-flag": "^1.0.0"
+            "has-flag": "^3.0.0"
           }
         }
       }
     },
-    "postcss-colormin": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
-      "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
+    "postcss-load-config": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz",
+      "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==",
       "dev": true,
       "requires": {
-        "colormin": "^1.0.5",
-        "postcss": "^5.0.13",
-        "postcss-value-parser": "^3.2.3"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-convert-values": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
-      "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.11",
-        "postcss-value-parser": "^3.1.2"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-comments": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
-      "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.14"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-duplicates": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
-      "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-empty": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
-      "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.14"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-overridden": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
-      "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.16"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-unused": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
-      "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.14",
-        "uniqs": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-filter-plugins": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz",
-      "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-load-config": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz",
-      "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==",
-      "dev": true,
-      "requires": {
-        "cosmiconfig": "^4.0.0",
-        "import-cwd": "^2.0.0"
-      }
-    },
-    "postcss-loader": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz",
-      "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "^1.1.0",
-        "postcss": "^6.0.0",
-        "postcss-load-config": "^2.0.0",
-        "schema-utils": "^0.4.0"
-      }
-    },
-    "postcss-merge-idents": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
-      "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.1",
-        "postcss": "^5.0.10",
-        "postcss-value-parser": "^3.1.1"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-merge-longhand": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
-      "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-merge-rules": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
-      "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
-      "dev": true,
-      "requires": {
-        "browserslist": "^1.5.2",
-        "caniuse-api": "^1.5.2",
-        "postcss": "^5.0.4",
-        "postcss-selector-parser": "^2.2.2",
-        "vendors": "^1.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "^1.0.30000639",
-            "electron-to-chromium": "^1.2.7"
-          }
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-message-helpers": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
-      "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
-      "dev": true
-    },
-    "postcss-minify-font-values": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
-      "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
-      "dev": true,
-      "requires": {
-        "object-assign": "^4.0.1",
-        "postcss": "^5.0.4",
-        "postcss-value-parser": "^3.0.2"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-minify-gradients": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
-      "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.12",
-        "postcss-value-parser": "^3.3.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-minify-params": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
-      "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "^1.0.1",
-        "postcss": "^5.0.2",
-        "postcss-value-parser": "^3.0.2",
-        "uniqs": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-minify-selectors": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
-      "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "^1.0.2",
-        "has": "^1.0.1",
-        "postcss": "^5.0.14",
-        "postcss-selector-parser": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-modules-extract-imports": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz",
-      "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==",
-      "dev": true,
-      "requires": {
-        "postcss": "^6.0.1"
-      }
-    },
-    "postcss-modules-local-by-default": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
-      "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
-      "dev": true,
-      "requires": {
-        "css-selector-tokenizer": "^0.7.0",
-        "postcss": "^6.0.1"
-      }
-    },
-    "postcss-modules-scope": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
-      "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
-      "dev": true,
-      "requires": {
-        "css-selector-tokenizer": "^0.7.0",
-        "postcss": "^6.0.1"
-      }
-    },
-    "postcss-modules-values": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
-      "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
-      "dev": true,
-      "requires": {
-        "icss-replace-symbols": "^1.1.0",
-        "postcss": "^6.0.1"
-      }
-    },
-    "postcss-normalize-charset": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
-      "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.5"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-normalize-url": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
-      "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
-      "dev": true,
-      "requires": {
-        "is-absolute-url": "^2.0.0",
-        "normalize-url": "^1.4.0",
-        "postcss": "^5.0.14",
-        "postcss-value-parser": "^3.2.3"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-ordered-values": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
-      "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4",
-        "postcss-value-parser": "^3.0.1"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-reduce-idents": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
-      "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4",
-        "postcss-value-parser": "^3.0.2"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-reduce-initial": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
-      "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
-      "dev": true,
-      "requires": {
-        "postcss": "^5.0.4"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-reduce-transforms": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
-      "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.1",
-        "postcss": "^5.0.8",
-        "postcss-value-parser": "^3.0.1"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-selector-parser": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
-      "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
-      "dev": true,
-      "requires": {
-        "flatten": "^1.0.2",
-        "indexes-of": "^1.0.1",
-        "uniq": "^1.0.1"
-      }
-    },
-    "postcss-svgo": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
-      "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
-      "dev": true,
-      "requires": {
-        "is-svg": "^2.0.0",
-        "postcss": "^5.0.14",
-        "postcss-value-parser": "^3.2.3",
-        "svgo": "^0.7.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-unique-selectors": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
-      "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "^1.0.1",
-        "postcss": "^5.0.4",
-        "uniqs": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
-          "dev": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^1.0.0"
-          }
-        }
+        "cosmiconfig": "^4.0.0",
+        "import-cwd": "^2.0.0"
       }
     },
-    "postcss-value-parser": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
-      "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
-      "dev": true
-    },
-    "postcss-zindex": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
-      "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.1",
-        "postcss": "^5.0.4",
-        "uniqs": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "5.2.18",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
-          "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+    "postcss-loader": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+      "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "postcss": "^7.0.0",
+        "postcss-load-config": "^2.0.0",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.8.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+          "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
           "dev": true,
           "requires": {
-            "chalk": "^1.1.3",
-            "js-base64": "^2.1.9",
-            "source-map": "^0.5.6",
-            "supports-color": "^3.2.3"
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
           }
         },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
           "dev": true
         },
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
           "dev": true,
           "requires": {
-            "has-flag": "^1.0.0"
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
           }
         }
       }
     },
-    "prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+    "postcss-modules-extract-imports": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+      "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "postcss-modules-local-by-default": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.4.tgz",
+      "integrity": "sha512-WvuSaTKXUqYJbnT7R3YrsNrHv/C5vRfr5VglS4bFOk0MYT4CLBfc/xgExA+x2RftlYgiBDvWmVs191Xv8S8gZQ==",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "^0.7.0",
+        "postcss": "^7.0.6",
+        "postcss-value-parser": "^3.3.1"
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.0.1.tgz",
+      "integrity": "sha512-7+6k9c3/AuZ5c596LJx9n923A/j3nF3ormewYBF1RrIQvjvjXe1xE8V8A1KFyFwXbvnshT6FBZFX0k/F1igneg==",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "^0.7.0",
+        "postcss": "^7.0.6"
+      }
+    },
+    "postcss-modules-values": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz",
+      "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==",
+      "dev": true,
+      "requires": {
+        "icss-replace-symbols": "^1.1.0",
+        "postcss": "^7.0.6"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+      "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
       "dev": true
     },
     "preserve": {
       "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
       "dev": true
     },
-    "q": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
-      "dev": true
-    },
     "qs": {
       "version": "6.5.2",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
       "dev": true
     },
-    "query-string": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
-      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
-      "dev": true,
-      "requires": {
-        "object-assign": "^4.1.0",
-        "strict-uri-encode": "^1.0.0"
-      }
-    },
     "querystring": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
         "strip-indent": "^1.0.1"
       }
     },
-    "reduce-css-calc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
-      "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "^0.4.2",
-        "math-expression-evaluator": "^1.2.14",
-        "reduce-function-call": "^1.0.1"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
-          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
-          "dev": true
-        }
-      }
-    },
-    "reduce-function-call": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
-      "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "^0.4.2"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
-          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
-          "dev": true
-        }
-      }
-    },
     "regenerate": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
         "semver": "^5.5.0"
       }
     },
-    "sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
-    },
     "schema-utils": {
       "version": "0.4.5",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
         "kind-of": "^3.2.0"
       }
     },
-    "sort-keys": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
-      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
-      "dev": true,
-      "requires": {
-        "is-plain-obj": "^1.0.0"
-      }
-    },
     "sortablejs": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.7.0.tgz",
       }
     },
     "ssri": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
-      "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
       "dev": true,
       "requires": {
-        "safe-buffer": "^5.1.1"
+        "figgy-pudding": "^3.5.1"
       }
     },
     "static-extend": {
       "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
       "dev": true
     },
-    "strict-uri-encode": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
-      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
-      "dev": true
-    },
     "string-width": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
       }
     },
     "style-loader": {
-      "version": "0.21.0",
-      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz",
-      "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==",
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
+      "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
       "dev": true,
       "requires": {
         "loader-utils": "^1.1.0",
-        "schema-utils": "^0.4.5"
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.8.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+          "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
       }
     },
     "supports-color": {
         "has-flag": "^3.0.0"
       }
     },
-    "svgo": {
-      "version": "0.7.2",
-      "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
-      "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
-      "dev": true,
-      "requires": {
-        "coa": "~1.0.1",
-        "colors": "~1.1.2",
-        "csso": "~2.3.1",
-        "js-yaml": "~3.7.0",
-        "mkdirp": "~0.5.1",
-        "sax": "~1.2.1",
-        "whet.extend": "~0.9.9"
-      }
-    },
     "tapable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz",
       "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz",
       "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg=="
     },
-    "uglify-es": {
-      "version": "3.3.9",
-      "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
-      "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
+    "uglify-js": {
+      "version": "3.4.9",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+      "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
       "dev": true,
       "requires": {
-        "commander": "~2.13.0",
+        "commander": "~2.17.1",
         "source-map": "~0.6.1"
       }
     },
     "uglifyjs-webpack-plugin": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz",
-      "integrity": "sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.1.1.tgz",
+      "integrity": "sha512-TQEcyMNkObX/H+FfcKjiDgs5RcXX8vW2UUUrDTOfQgg3lrafztfeM5WAwXo+AzqozJK6NP9w98xNpG/dutzSsg==",
       "dev": true,
       "requires": {
-        "cacache": "^10.0.4",
-        "find-cache-dir": "^1.0.0",
-        "schema-utils": "^0.4.5",
+        "cacache": "^11.2.0",
+        "find-cache-dir": "^2.0.0",
+        "schema-utils": "^1.0.0",
         "serialize-javascript": "^1.4.0",
         "source-map": "^0.6.1",
-        "uglify-es": "^3.3.4",
+        "uglify-js": "^3.0.0",
         "webpack-sources": "^1.1.0",
         "worker-farm": "^1.5.2"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.8.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+          "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "find-cache-dir": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
+          "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^1.0.0",
+            "pkg-dir": "^3.0.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
+          "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
+          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
       }
     },
     "ultron": {
         }
       }
     },
-    "uniq": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
-      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
-      "dev": true
-    },
-    "uniqs": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
-      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
-      "dev": true
-    },
     "unique-filename": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
         "spdx-expression-parse": "^3.0.0"
       }
     },
-    "vendors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
-      "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
-      "dev": true
-    },
     "verror": {
       "version": "1.10.0",
       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
         "source-map": "~0.6.1"
       }
     },
-    "whet.extend": {
-      "version": "0.9.9",
-      "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
-      "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
-      "dev": true
-    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
index dc90689d3d86b6406d94b9ee723cb09fd3d63e50..1cbfdb3e9ba9d62eef4801419ac0ebea20e94d45 100644 (file)
     "@babel/core": "^7.1.6",
     "@babel/polyfill": "^7.0.0",
     "@babel/preset-env": "^7.1.6",
-    "autoprefixer": "^8.6.5",
+    "autoprefixer": "^9.4.7",
     "babel-loader": "^8.0.4",
-    "css-loader": "^0.28.11",
-    "extract-text-webpack-plugin": "^4.0.0-beta.0",
+    "css-loader": "^2.1.0",
     "livereload": "^0.7.0",
+    "mini-css-extract-plugin": "^0.5.0",
     "node-sass": "^4.10.0",
     "npm-run-all": "^4.1.5",
-    "postcss-loader": "^2.1.6",
+    "postcss-loader": "^3.0.0",
     "sass-loader": "^7.1.0",
-    "style-loader": "^0.21.0",
-    "uglifyjs-webpack-plugin": "^1.3.0",
+    "style-loader": "^0.23.1",
+    "uglifyjs-webpack-plugin": "^2.1.1",
     "webpack": "^4.26.1",
     "webpack-cli": "^3.1.2"
   },
index 75e3753dc4147668c1c5a1d21b14b036ee9dc948..edd367b2d8c17c8e5d65b7e2ae14e729ac949193 100644 (file)
@@ -1,4 +1 @@
-<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
-    <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
-    <path d="M0 0h24v24H0z" fill="none"/>
-</svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 13.3h-5.7V19h-2.6v-5.7H5v-2.6h5.7V5h2.6v5.7H19z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/resources/assets/icons/books.svg b/resources/assets/icons/books.svg
new file mode 100644 (file)
index 0000000..240201f
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 24 24"
+   version="1.1"
+   id="svg6"
+   sodipodi:docname="books.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs10" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1413"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="19.666667"
+     inkscape:cx="13.076733"
+     inkscape:cy="8.7801453"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg6" />
+  <path
+     d="M0 0h24v24H0z"
+     fill="none"
+     id="path2" />
+  <path
+     d="M 19.252119,1.707627 H 8.6631356 c -0.9706568,0 -1.7648305,0.7941737 -1.7648305,1.7648305 V 17.591101 c 0,0.970657 0.7941737,1.764831 1.7648305,1.764831 H 19.252119 c 0.970656,0 1.76483,-0.794174 1.76483,-1.764831 V 3.4724575 c 0,-0.9706568 -0.794174,-1.7648305 -1.76483,-1.7648305 z M 8.6631356,3.4724575 H 13.075212 V 10.531779 L 10.869173,9.2081571 8.6631356,10.531779 Z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="stroke-width:0.88241524" />
+  <g
+     id="g836"
+     transform="translate(30.610169,3.2033898)">
+    <path
+       id="path822"
+       d="M 0,0 H 24 V 24 H 0 Z"
+       inkscape:connector-curvature="0"
+       style="fill:none" />
+    <path
+       id="path824"
+       d="M -27.644068,3.4067797 V 17.40678 c 0,1.1 0.9,2 2,2 h 14 v -2 h -14 V 3.4067797 Z"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cssccccc" />
+  </g>
+</svg>
index 03da68f9629a049c4e8adde61080eb2fc6e51e00..f1e45eaf99639e344fb6ede008eab2dafb8abf36 100644 (file)
@@ -1,2 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M1.088 2.566h17.42v17.42H1.088z" fill="none"/><path d="M4 20.058h15.892V22H4z"/><path d="M2.902 1.477h17.42v17.42H2.903z" fill="none"/><g><path d="M6.658 3.643V18h-2.38V3.643zM11.326 3.643V18H8.947V3.643zM14.722 3.856l5.613 13.214-2.19.93-5.613-13.214z"/></g></svg>
-
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M1.088 2.566h17.42v17.42H1.088z" fill="none"/><path d="M4 20.058h15.892V22H4z"/><path d="M2.902 1.477h17.42v17.42H2.903z" fill="none"/><g><path d="M6.658 3.643V18h-2.38V3.643zM11.326 3.643V18H8.947V3.643zM14.722 3.856l5.613 13.214-2.19.93-5.613-13.214z"/></g></svg>
\ No newline at end of file
diff --git a/resources/assets/icons/check.svg b/resources/assets/icons/check.svg
new file mode 100644 (file)
index 0000000..93607ef
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.86 4.118l-9.733 9.609-3.951-3.995-2.98 2.966 6.93 7.184L21.805 7.217z"/></svg>
\ No newline at end of file
diff --git a/resources/assets/icons/chevron-right.svg b/resources/assets/icons/chevron-right.svg
new file mode 100644 (file)
index 0000000..96540b9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/resources/assets/icons/sort-down.svg b/resources/assets/icons/sort-down.svg
new file mode 100644 (file)
index 0000000..61fa6c7
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.034l6.57-6.554h-4.927V2.966h-3.286V14.48H5.43z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/resources/assets/icons/sort-up.svg b/resources/assets/icons/sort-up.svg
new file mode 100644 (file)
index 0000000..985cc62
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2.966L5.43 9.52h4.927v11.514h3.286V9.52h4.927z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/resources/assets/js/components/breadcrumb-listing.js b/resources/assets/js/components/breadcrumb-listing.js
new file mode 100644 (file)
index 0000000..e4f4e53
--- /dev/null
@@ -0,0 +1,60 @@
+
+
+class BreadcrumbListing {
+
+    constructor(elem) {
+        this.elem = elem;
+        this.searchInput = elem.querySelector('input');
+        this.loadingElem = elem.querySelector('.loading-container');
+        this.entityListElem = elem.querySelector('.breadcrumb-listing-entity-list');
+        this.toggleElem = elem.querySelector('[dropdown-toggle]');
+
+        // this.loadingElem.style.display = 'none';
+        const entityDescriptor = elem.getAttribute('breadcrumb-listing').split(':');
+        this.entityType = entityDescriptor[0];
+        this.entityId = Number(entityDescriptor[1]);
+
+        this.toggleElem.addEventListener('click', this.onShow.bind(this));
+        this.searchInput.addEventListener('input', this.onSearch.bind(this));
+    }
+
+    onShow() {
+        this.loadEntityView();
+    }
+
+    onSearch() {
+        const input = this.searchInput.value.toLowerCase().trim();
+        const listItems = this.entityListElem.querySelectorAll('.entity-list-item');
+        console.log(listItems);
+        for (let listItem of listItems) {
+            const match = !input || listItem.textContent.toLowerCase().includes(input);
+            console.log(match);
+            listItem.style.display = match ? 'flex' : 'none';
+        }
+    }
+
+    loadEntityView() {
+        this.toggleLoading(true);
+
+        const params = {
+            'entity_id': this.entityId,
+            'entity_type': this.entityType,
+        };
+
+        window.$http.get('/search/entity/siblings', {params}).then(resp => {
+            this.entityListElem.innerHTML = resp.data;
+        }).catch(err => {
+            console.error(err);
+        }).then(() => {
+            this.toggleLoading(false);
+            this.onSearch();
+        });
+    }
+
+    toggleLoading(show = false) {
+        this.loadingElem.style.display = show ? 'block' : 'none';
+    }
+
+}
+
+export default BreadcrumbListing;
\ No newline at end of file
index dda42e868ee6be4d52d761e160d11b624a4fc6bf..400ddb576128bd1f1464700b923d4fc21012c3e5 100644 (file)
@@ -6,7 +6,7 @@ class DropDown {
 
     constructor(elem) {
         this.container = elem;
-        this.menu = elem.querySelector('ul');
+        this.menu = elem.querySelector('ul, [dropdown-menu]');
         this.toggle = elem.querySelector('[dropdown-toggle]');
         this.setupListeners();
     }
diff --git a/resources/assets/js/components/header-mobile-toggle.js b/resources/assets/js/components/header-mobile-toggle.js
new file mode 100644 (file)
index 0000000..eccd4b8
--- /dev/null
@@ -0,0 +1,31 @@
+
+class HeaderMobileToggle {
+
+    constructor(elem) {
+        this.elem = elem;
+        this.toggleButton = elem.querySelector('.mobile-menu-toggle');
+        this.menu = elem.querySelector('.header-links');
+        this.open = false;
+
+        this.toggleButton.addEventListener('click', this.onToggle.bind(this));
+        this.onWindowClick = this.onWindowClick.bind(this);
+    }
+
+    onToggle(event) {
+        this.open = !this.open;
+        this.menu.classList.toggle('show', this.open);
+        if (this.open) {
+            window.addEventListener('click', this.onWindowClick)
+        } else {
+            window.removeEventListener('click', this.onWindowClick)
+        }
+        event.stopPropagation();
+    }
+
+    onWindowClick(event) {
+        this.onToggle(event);
+    }
+
+}
+
+module.exports = HeaderMobileToggle;
\ No newline at end of file
index bf6fbf619701baf82059d294487f3c3ad3f4dcaf..e2749797e0a1b862058fe23e5b7695d6e126e843 100644 (file)
@@ -18,7 +18,10 @@ import toggleSwitch from "./toggle-switch";
 import pageDisplay from "./page-display";
 import shelfSort from "./shelf-sort";
 import homepageControl from "./homepage-control";
-
+import headerMobileToggle from "./header-mobile-toggle";
+import listSortControl from "./list-sort-control";
+import triLayout from "./tri-layout";
+import breadcrumbListing from "./breadcrumb-listing";
 
 const componentMapping = {
     'dropdown': dropdown,
@@ -41,6 +44,10 @@ const componentMapping = {
     'page-display': pageDisplay,
     'shelf-sort': shelfSort,
     'homepage-control': homepageControl,
+    'header-mobile-toggle': headerMobileToggle,
+    'list-sort-control': listSortControl,
+    'tri-layout': triLayout,
+    'breadcrumb-listing': breadcrumbListing,
 };
 
 window.components = {};
@@ -79,4 +86,4 @@ function initAll(parentElement) {
 
 window.components.init = initAll;
 
-export default initAll;
\ No newline at end of file
+export default initAll;
diff --git a/resources/assets/js/components/list-sort-control.js b/resources/assets/js/components/list-sort-control.js
new file mode 100644 (file)
index 0000000..d463ed0
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * ListSortControl
+ * Manages the logic for the control which provides list sorting options.
+ */
+class ListSortControl {
+
+    constructor(elem) {
+        this.elem = elem;
+
+        this.sortInput = elem.querySelector('[name="sort"]');
+        this.orderInput = elem.querySelector('[name="order"]');
+        this.form = elem.querySelector('form');
+
+        this.elem.addEventListener('click', event => {
+            if (event.target.closest('[data-sort-value]') !== null) {
+                this.sortOptionClick(event);
+            }
+            if (event.target.closest('[data-sort-dir]') !== null) {
+                this.sortDirectionClick(event);
+            }
+        })
+
+    }
+
+    sortOptionClick(event) {
+        const sortOption = event.target.closest('[data-sort-value]');
+        this.sortInput.value = sortOption.getAttribute('data-sort-value');
+        event.preventDefault();
+        this.form.submit();
+    }
+
+    sortDirectionClick(event) {
+        const currentDir = this.orderInput.value;
+        const newDir = (currentDir === 'asc') ? 'desc' : 'asc';
+        this.orderInput.value = newDir;
+        event.preventDefault();
+        this.form.submit();
+    }
+
+}
+
+export default ListSortControl;
\ No newline at end of file
index bca641cb6161e65e77b10bf81630bfe95c24e359..1aeeaf248a6df307ee342d9804629447d6639b1d 100644 (file)
@@ -208,8 +208,8 @@ class PageDisplay {
             let pageNavObserver = new IntersectionObserver(headingVisibilityChange, intersectOpts);
 
             // observe each heading
-            for (let i = 0; i !== headings.length; ++i) {
-                pageNavObserver.observe(headings[i]);
+            for (let heading of headings) {
+                pageNavObserver.observe(heading);
             }
         }
 
@@ -221,14 +221,9 @@ class PageDisplay {
         }
 
         function toggleAnchorHighlighting(elementId, shouldHighlight) {
-            let anchorsToHighlight = pageNav.querySelectorAll('a[href="#' + elementId + '"]');
-            for (let i = 0; i < anchorsToHighlight.length; i++) {
-                // Change below to use classList.toggle when IE support is dropped.
-                if (shouldHighlight) {
-                    anchorsToHighlight[i].classList.add('current-heading');
-                } else {
-                    anchorsToHighlight[i].classList.remove('current-heading');
-                }
+            const anchorsToHighlight = pageNav.querySelectorAll('a[href="#' + elementId + '"]');
+            for (let anchor of anchorsToHighlight) {
+                anchor.closest('li').classList.toggle('current-heading', shouldHighlight);
             }
         }
     }
index 957a41642141c398b3016110eb484d05e382ac84..3be67d5dc94afb0f0f10ec6788c6590541ab04f0 100644 (file)
@@ -3,15 +3,15 @@ class ToggleSwitch {
 
     constructor(elem) {
         this.elem = elem;
-        this.input = elem.querySelector('input');
+        this.input = elem.querySelector('input[type=hidden]');
+        this.checkbox = elem.querySelector('input[type=checkbox]');
 
-        this.elem.onclick = this.onClick.bind(this);
+        this.checkbox.addEventListener('change', this.onClick.bind(this));
     }
 
     onClick(event) {
-        let checked = this.input.value !== 'true';
+        let checked = this.checkbox.checked;
         this.input.value = checked ? 'true' : 'false';
-        checked ? this.elem.classList.add('active') : this.elem.classList.remove('active');
     }
 
 }
diff --git a/resources/assets/js/components/tri-layout.js b/resources/assets/js/components/tri-layout.js
new file mode 100644 (file)
index 0000000..d18d37d
--- /dev/null
@@ -0,0 +1,83 @@
+
+class TriLayout {
+
+    constructor(elem) {
+        this.elem = elem;
+        this.middle = elem.querySelector('.tri-layout-middle');
+        this.right = elem.querySelector('.tri-layout-right');
+        this.left = elem.querySelector('.tri-layout-left');
+
+        this.lastLayoutType = 'none';
+        this.onDestroy = null;
+
+
+        this.updateLayout();
+        window.addEventListener('resize', event => {
+            this.updateLayout();
+        });
+    }
+
+    updateLayout() {
+        let newLayout = 'tablet';
+        if (window.innerWidth <= 1000) newLayout =  'mobile';
+        if (window.innerWidth >= 1400) newLayout =  'desktop';
+        if (newLayout === this.lastLayoutType) return;
+
+        if (this.onDestroy) {
+            this.onDestroy();
+            this.onDestroy = null;
+        }
+
+        if (newLayout === 'desktop') {
+            this.setupDesktop();
+        } else if (newLayout === 'mobile') {
+            this.setupMobile();
+        }
+
+        this.lastLayoutType = newLayout;
+    }
+
+    setupMobile() {
+        const mobileSidebarClickBound = this.mobileSidebarClick.bind(this);
+        const mobileContentClickBound = this.mobileContentClick.bind(this);
+        this.left.addEventListener('click', mobileSidebarClickBound);
+        this.right.addEventListener('click', mobileSidebarClickBound);
+        this.middle.addEventListener('click', mobileContentClickBound);
+
+        this.onDestroy = () => {
+            this.left.removeEventListener('click', mobileSidebarClickBound);
+            this.right.removeEventListener('click', mobileSidebarClickBound);
+            this.middle.removeEventListener('click', mobileContentClickBound);
+        }
+    }
+
+    setupDesktop() {
+        //
+    }
+
+    /**
+     * Slide the main content back into view if clicked and
+     * currently slid out of view.
+     * @param event
+     */
+    mobileContentClick(event) {
+        this.elem.classList.remove('mobile-open');
+    }
+
+    /**
+     * On sidebar click, Show the content by sliding the main content out.
+     * @param event
+     */
+    mobileSidebarClick(event) {
+        if (this.elem.classList.contains('mobile-open')) {
+            this.elem.classList.remove('mobile-open');
+        } else {
+            event.preventDefault();
+            event.stopPropagation();
+            this.elem.classList.add('mobile-open');
+        }
+    }
+
+}
+
+export default TriLayout;
\ No newline at end of file
index 9deb1d0a7a0f4e2a9c16945d919fe6e9b61148ff..2767d35c0f80cdf4a68af9a4ad3924080a3b7b89 100644 (file)
@@ -432,7 +432,7 @@ class WysiwygEditor {
             plugins: this.plugins,
             imagetools_toolbar: 'imageoptions',
             toolbar: this.getToolBar(),
-            content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
+            content_style: "html, body {background: #FFF;} body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
             style_formats: [
                 {title: "Header Large", format: "h2"},
                 {title: "Header Medium", format: "h3"},
index c0f02ed7d78f34b48908f02d2ca7be84476e12c6..a52ac71a978caefe96065c515e7925d8b7c4ef26 100644 (file)
@@ -1,56 +1,12 @@
 
 /*
-* This file container all block styling including background shading,
-* margins, paddings & borders.
+* This file container all block styling including margins, paddings & borders.
 */
 
 
-/*
-* Background Shading
-*/
-.shaded {
-  background-color: #f1f1f1;
-  &.pos {
-    background-color: lighten($positive, 40%);
-  }
-  &.neg {
-    background-color: lighten($negative, 20%);
-  }
-  &.primary {
-    background-color: lighten($primary, 40%);
-  }
-  &.secondary {
-    background-color: lighten($secondary, 30%);
-  }
-}
-
-/*
-* Bordering
-*/
-.bordered {
-  border: 1px solid #BBB;
-  &.pos {
-    border-color: $positive;
-  }
-  &.neg {
-    border-color: $negative;
-  }
-  &.primary {
-    border-color: $primary;
-  }
-  &.secondary {
-    border-color: $secondary;
-  }
-  &.thick {
-    border-width: 2px;
-  }
-}
-.rounded {
-  border-radius: 3px;
-}
-
 /*
 * Padding
+* TODO - Remove these older styles
 */
 .nopadding {
   padding: 0;
@@ -94,6 +50,7 @@
 
 /*
 * Margins
+* TODO - Remove these older styles
 */
 .margins {
   margin: $-l;
   }
 }
 
+@mixin spacing($prop, $propLetter) {
+  @each $sizeLetter, $size in $spacing {
+    .#{$propLetter}-#{$sizeLetter} {
+      #{$prop}: $size !important;
+    }
+    .#{$propLetter}x-#{$sizeLetter} {
+      #{$prop}-left: $size !important;
+      #{$prop}-right: $size !important;
+    }
+    .#{$propLetter}y-#{$sizeLetter} {
+      #{$prop}-top: $size !important;
+      #{$prop}-bottom: $size !important;
+    }
+    .#{$propLetter}t-#{$sizeLetter} {
+      #{$prop}-top: $size !important;
+    }
+    .#{$propLetter}r-#{$sizeLetter} {
+      #{$prop}-right: $size !important;
+    }
+    .#{$propLetter}b-#{$sizeLetter} {
+      #{$prop}-bottom: $size !important;
+    }
+    .#{$propLetter}l-#{$sizeLetter} {
+      #{$prop}-left: $size !important;
+    }
+  }
+
+}
+
+@include spacing('margin', 'm')
+@include spacing('padding', 'p')
+
 
 /**
  * Callouts
 }
 
 .card {
-  margin: $-m;
   background-color: #FFF;
-  box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.2);
+  box-shadow: $bs-card;
+  border-radius: 3px;
+  border: 1px solid transparent;
   h3 {
     padding: $-m;
-    border-bottom: 1px solid #E8E8E8;
+    padding-bottom: $-xs;
     margin: 0;
-    font-size: $fs-s;
-    color: #888;
-    fill: #888;
+    font-size: $fs-m;
+    color: #222;
+    fill: #222;
     font-weight: 400;
-    text-transform: uppercase;
   }
   h3 a {
     line-height: 1;
 }
 
 .sidebar .card {
-  h3, .body, .empty-text {
+  .body, .empty-text {
     padding: $-s $-m;
   }
+  h3 + .body {
+    padding-top: $-xs;
+  }
 }
 
 .card.drag-card {
index 2c20c3f41a50eba38ef7b4a957cde2d6140d4f7d..093da80ca7d742548f181fd40bfabb1dabf1efb2 100644 (file)
@@ -28,10 +28,11 @@ $button-border-radius: 2px;
 
 .button-base {
   text-decoration: none;
-  font-size: $fs-m;
+  font-size: 0.85rem;
   line-height: 1.4em;
   padding: $-xs*1.3 $-m;
-  margin: $-xs $-xs $-xs 0;
+  margin-top: $-xs;
+  margin-bottom: $-xs;
   display: inline-block;
   border: none;
   font-weight: 400;
@@ -57,9 +58,15 @@ $button-border-radius: 2px;
   &.muted {
     @include generate-button-colors(#EEE, #AAA);
   }
-  &.muted-light {
-    @include generate-button-colors(#666, #e4e4e4);
-  }
+}
+
+.button + .button {
+  margin-left: $-s;
+}
+
+.button.small {
+  font-size: 0.75rem;
+  padding: $-xs*1.2 $-s;
 }
 
 .button.outline {
@@ -110,6 +117,7 @@ $button-border-radius: 2px;
   margin: 0;
   border: none;
   user-select: none;
+  font-size: 0.75rem;
   &:focus, &:active {
     outline: 0;
   }
@@ -119,6 +127,9 @@ $button-border-radius: 2px;
   &.neg {
     color: $negative;
   }
+  &.muted {
+    color: #666;
+  }
 }
 
 .button-group {
diff --git a/resources/assets/sass/_colors.scss b/resources/assets/sass/_colors.scss
new file mode 100644 (file)
index 0000000..644b6b8
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Text colors
+ */
+p.pos, p .pos, span.pos, .text-pos {
+  color: $positive;
+  fill: $positive;
+  &:hover {
+    color: $positive;
+    fill: $positive;
+  }
+}
+
+p.neg, p .neg, span.neg, .text-neg {
+  color: $negative;
+  fill: $negative;
+  &:hover {
+    color: $negative;
+    fill: $negative;
+  }
+}
+
+p.muted, p .muted, span.muted, .text-muted {
+  color: lighten($text-dark, 26%);
+  fill: lighten($text-dark, 26%);
+  &.small, .small {
+    color: lighten($text-dark, 32%);
+    fill: lighten($text-dark, 32%);
+  }
+}
+
+p.primary, p .primary, span.primary, .text-primary {
+  color: $primary;
+  fill: $primary;
+  &:hover {
+    color: $primary;
+    fill: $primary;
+  }
+}
+
+p.secondary, p .secondary, span.secondary, .text-secondary {
+  color: $secondary;
+  fill: $secondary;
+  &:hover {
+    color: $secondary;
+    fill: $secondary;
+  }
+}
+
+.text-bookshelf {
+  color: $color-bookshelf;
+  fill: $color-bookshelf;
+  &:hover {
+    color: $color-bookshelf;
+    fill: $color-bookshelf;
+  }
+}
+.text-book {
+  color: $color-book;
+  fill: $color-book;
+  &:hover {
+    color: $color-book;
+    fill: $color-book;
+  }
+}
+.text-page {
+  color: $color-page;
+  fill: $color-page;
+  &:hover {
+    color: $color-page;
+    fill: $color-page;
+  }
+  &.draft {
+    color: $color-page-draft;
+    fill: $color-page-draft;
+  }
+  &.draft:hover {
+    color: $color-page-draft;
+    fill: $color-page-draft;
+  }
+}
+.text-chapter {
+  color: $color-chapter;
+  fill: $color-chapter;
+  &:hover {
+    color: $color-chapter;
+    fill: $color-chapter;
+  }
+}
+.faded .text-book:hover {
+  color: $color-book !important;
+  fill: $color-book !important;
+}
+.faded .text-chapter:hover {
+  color: $color-chapter !important;
+  fill: $color-chapter !important;
+}
+.faded .text-page:hover {
+  color: $color-page !important;
+  fill: $color-page !important;
+}
+
+.bg-book {
+  background-color: $color-book;
+}
+.bg-chapter {
+  background-color: $color-chapter;
+}
+.bg-shelf {
+  background-color: $color-bookshelf;
+}
\ No newline at end of file
index 6b3ed381549e3c1c8f3dedfb99b2a1ba06b09566..77ac359633e47973521d0ddaf34d963db5705766 100644 (file)
@@ -98,7 +98,7 @@ label {
   line-height: 1.4em;
   font-size: 0.94em;
   font-weight: 400;
-  color: #999;
+  color: #666;
   padding-bottom: 2px;
   margin-bottom: 0.2em;
   &.inline {
@@ -139,56 +139,77 @@ input[type=date] {
 }
 
 .toggle-switch {
-  display: inline-block;
-  background-color: #BBB;
-  width: 36px;
-  height: 14px;
-  border-radius: 7px;
-  position: relative;
-  transition: all ease-in-out 120ms;
-  cursor: pointer;
   user-select: none;
-  &:after {
-    content: '';
-    display: block;
-    position: relative;
-    left: 0;
-    margin-top: -3px;
-    width: 20px;
-    height: 20px;
-    border-radius: 50%;
-    background-color: #fafafa;
-    border: 1px solid #CCC;
-    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
-    transition: all ease-in-out 120ms;
-  }
-  &.active {
-    background-color: rgba($positive, 0.4);
-    &:after {
-      left: 16px;
-      background-color: $positive;
-      border: darken($positive, 20%);
+  display: inline-grid;
+  grid-template-columns: (16px + $-s) 1fr;
+  align-items: center;
+  margin: $-m 0;
+  .custom-checkbox {
+    width: 16px;
+    height: 16px;
+    border-radius: 2px;
+    display: inline-block;
+    border: 2px solid currentColor;
+    opacity: 0.6;
+    overflow: hidden;
+    fill: currentColor;
+    .svg-icon {
+      width: 100%;
+      height: 100%;
+      margin: 0;
+      bottom: auto;
+      top: -1.5px;
+      left: 0;
+      transition: transform ease-in-out 120ms;
+      transform: scale(0);
+      transform-origin: center center;
     }
   }
+  input[type=checkbox] {
+    display: none;
+  }
+  input[type=checkbox]:checked + .custom-checkbox .svg-icon {
+    transform: scale(1);
+  }
+  .custom-checkbox:hover {
+    background-color: rgba(0, 0, 0, 0.05);
+    opacity: 0.8;
+  }
 }
-.toggle-switch-checkbox {
-  display: none;
-}
-input:checked + .toggle-switch {
-  background-color: rgba($positive, 0.4);
-  &:after {
-    left: 16px;
-    background-color: $positive;
-    border: darken($positive, 20%);
+.toggle-switch-list {
+  .toggle-switch {
+    margin: $-xs 0;
+  }
+  &.compact .toggle-switch {
+    margin: 1px 0;
   }
 }
 
 .form-group {
   margin-bottom: $-s;
-  textarea {
-    display: block;
+}
+
+.setting-list > div {
+  border-bottom: 1px solid #DDD;
+  padding: $-xl 0;
+  &:last-child {
+    border-bottom: none;
+  }
+}
+.setting-list-label {
+  color: #222;
+  font-size: 1rem;
+}
+.setting-list-label + p.small {
+  margin-bottom: 0;
+}
+.setting-list-label + .grid {
+  margin-top: $-m;
+}
+
+.setting-list .grid, .stretch-inputs {
+  input[type=text], input[type=email], input[type=password], select {
     width: 100%;
-    min-height: 64px;
   }
 }
 
@@ -197,6 +218,8 @@ input:checked + .toggle-switch {
   font-family: monospace;
   font-size: 12px;
   min-height: 100px;
+  display: block;
+  width: 100%;
 }
 
 .form-group {
@@ -206,11 +229,9 @@ input:checked + .toggle-switch {
 }
 
 .form-group[collapsible] {
-  margin-left: -$-m;
-  margin-right: -$-m;
   padding: 0 $-m;
-  border-top: 1px solid #DDD;
-  border-bottom: 1px solid #DDD;
+  border: 1px solid #DDD;
+  border-radius: 4px;
   .collapse-title {
     margin-left: -$-m;
     margin-right: -$-m;
@@ -238,9 +259,6 @@ input:checked + .toggle-switch {
   &.open .collapse-title label:before {
     transform: rotate(90deg);
   }
-  &+.form-group[collapsible] {
-    margin-top: -($-s + 1);
-  }
 }
 
 .inline-input-style {
@@ -317,13 +335,6 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
   }
 }
 
-#login-form label[for="remember"] {
-  margin: 0;
-}
-#login-form label.toggle-switch {
-  margin-left: $-xl;
-}
-
 .image-picker img {
   background-color: #BBB;
 }
index 0e1f85ce62cd1e801d006814b4e47ddaabab49d5..7415be73f3d870ff65251ef3f2bba8b1edfe76b9 100644 (file)
@@ -50,102 +50,135 @@ body.flexbox {
   flex: 1;
 }
 
-.flex.sidebar {
-  flex: 1;
-  background-color: #F2F2F2;
-  max-width: 360px;
-  min-height: 90vh;
-  section {
-    margin: $-m;
-  }
-}
-.flex.sidebar + .flex.content {
-  flex: 3;
-  background-color: #FFFFFF;
-  padding: 0 $-l;
-  border-left: 1px solid #DDD;
-  max-width: 100%;
+.dual-column-content {
+  columns: 2;
 }
-.flex.sidebar .sidebar-toggle {
-  display: none;
-}
-
-@include smaller-than($xl) {
-  body.sidebar-layout {
-    padding-left: 30px;
-  }
-  .flex.sidebar {
-    position: fixed;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    z-index: 100;
-    padding-right: 30px;
-    width: 360px;
-    box-shadow: none;
-    transform: translate3d(-330px, 0, 0);
-    transition: transform ease-in-out 120ms;
-    display: flex;
-    flex-direction: column;
+
+@include smaller-than($m) {
+  .dual-column-content {
+    columns: 1;
   }
-  .flex.sidebar.open {
-    box-shadow: 1px 2px 2px 1px rgba(0,0,0,.10);
-    transform: translate3d(0, 0, 0);
-    .sidebar-toggle i {
-      transform: rotate(180deg);
-    }
+}
+
+.content-wrap.card {
+  padding: $-l $-xxl;
+  margin-left: auto;
+  margin-right: auto;
+  margin-bottom: $-xl;
+  overflow: auto;
+  min-height: 60vh;
+  &.auto-height {
+    min-height: 0;
   }
-  .flex.sidebar .sidebar-toggle {
-    display: block;
-    position: absolute;
-    opacity: 0.9;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    width: 30px;
-    fill: #666;
-    font-size: 20px;
-    vertical-align: middle;
-    text-align: center;
-    border: 1px solid #DDD;
-    border-top: 1px solid #BBB;
-    padding-top: $-m;
-    cursor: pointer;
-    svg {
-      opacity: 0.5;
-      transition: all ease-in-out 120ms;
-      margin: 0;
-    }
-    &:hover i {
-      opacity: 1;
+  &.fill-width {
+    width: 100%;
+  }
+}
+
+@include smaller-than($m) {
+  .content-wrap.card {
+    padding: $-m $-l;
+  }
+}
+
+.tri-layout-container {
+  display: grid;
+  grid-template-columns: 1fr minmax(auto, 940px) 1fr;
+  grid-template-areas: "a b c";
+  .tri-layout-right-contents, .tri-layout-left-contents {
+    padding-right: 3vw;
+    padding-left: 3vw;
+    max-width: 460px;
+    margin-left: auto;
+    margin-right: auto;
+  }
+  .tri-layout-right {
+    grid-area: c;
+  }
+  .tri-layout-left {
+    grid-area: a;
+  }
+  .tri-layout-middle {
+    grid-area: b;
+  }
+}
+@include smaller-than($xxl) {
+  .tri-layout-container {
+    grid-template-areas:  "c b b"
+                          "a b b";
+    grid-template-columns: 1fr 3fr;
+    grid-template-rows: max-content min-content;
+    padding-right: $-l;
+    .content-wrap.card {
+      padding: $-l $-l;
     }
   }
-  .sidebar .scroll-body {
-    flex: 1;
+}
+@include larger-than($xxl) {
+  .tri-layout-left-contents, .tri-layout-right-contents {
+    position: sticky;
+    top: $-m;
+    max-height: 100vh;
+    min-height: 50vh;
     overflow-y: scroll;
-  }
-  #sidebar .scroll-body.fixed {
-    width: auto !important;
+    overflow-x: visible;
+    scrollbar-width: none;
+    -ms-overflow-style: none;
+    &::-webkit-scrollbar {
+      display: none;
+    }
   }
 }
 
-@include larger-than($xl) {
-  #sidebar .scroll-body.fixed {
-    z-index: 5;
-    position: fixed;
-    top: 0;
-    padding-right: $-m;
-    width: 30%;
-    left: 0;
-    height: 100%;
-    overflow-y: auto;
-    -ms-overflow-style: none;
-    //background-color: $primary-faded;
-    border-left: 1px solid #DDD;
-    &::-webkit-scrollbar { width: 0 !important }
+@include smaller-than($l) {
+  .tri-layout-container {
+    grid-template-areas:  none;
+    grid-template-columns: 10% 90%;
+    grid-column-gap: 0;
+    .tri-layout-left-contents, .tri-layout-right-contents {
+      padding-left: $-m;
+      padding-right: $-m;
+    }
+    .tri-layout-right-contents > div, .tri-layout-left-contents > div {
+      opacity: 0.6;
+      z-index: 0;
+    }
+    .tri-layout-left > *, .tri-layout-right > * {
+      pointer-events: none;
+    }
+    .tri-layout-right, .tri-layout-left, .tri-layout-middle {
+      grid-area: none;
+      grid-column: 1/3;
+      grid-row: 1;
+    }
+    .tri-layout-middle {
+      grid-row: 1/3;
+      grid-column: 2/3;
+      z-index: 1;
+      transition: transform ease-in-out 240ms;
+    }
+    .tri-layout-left {
+      grid-row: 2;
+    }
+    &.mobile-open {
+      overflow: hidden;
+      .tri-layout-middle {
+        transform: translateX(90%);
+      }
+      .tri-layout-right  > *, .tri-layout-left > * {
+        pointer-events: auto;
+      }
+    }
   }
 }
 
+.tri-layout-left-contents > div, .tri-layout-right-contents > div {
+  opacity: 0.6;
+  transition: opacity ease-in-out 120ms;
+  &:hover {
+    opacity: 1;
+  }
+}
 
 /** Rules for all columns */
 div[class^="col-"] img {
@@ -153,7 +186,7 @@ div[class^="col-"] img {
 }
 
 .container {
-  max-width: $max-width;
+  max-width: $xxl;
   margin-left: auto;
   margin-right: auto;
   padding-left: $-m;
@@ -167,6 +200,9 @@ div[class^="col-"] img {
   &.small {
     max-width: 840px;
   }
+  &.very-small {
+    max-width: 480px;
+  }
   &.nopad {
     padding-left: 0;
     padding-right: 0;
@@ -182,29 +218,46 @@ div[class^="col-"] img {
   display: grid;
   grid-column-gap: $-l;
   grid-row-gap: $-l;
+  &.half {
+    grid-template-columns: 1fr 1fr;
+  }
   &.third {
     grid-template-columns: 1fr 1fr 1fr;
   }
+  &.left-focus {
+    grid-template-columns: 2fr 1fr;
+  }
+  &.right-focus {
+    grid-template-columns: 1fr 2fr;
+  }
+  &.large-gap {
+    grid-column-gap: $-xl;
+    grid-row-gap: $-xl;
+  }
 }
 
 .grid-card {
   display: flex;
   flex-direction: column;
   border: 1px solid #ddd;
+  margin-bottom: $-l;
+  border-radius: 4px;
+  overflow: hidden;
   min-width: 100px;
+  color: $text-dark;
+  transition: border-color ease-in-out 120ms, box-shadow ease-in-out 120ms;
+  &:hover {
+    color: $text-dark;
+    text-decoration: none;
+    box-shadow: $bs-card;
+  }
   h2 {
     width: 100%;
     font-size: 1.5em;
     margin: 0 0 10px;
   }
-  h2 a {
-    display: block;
-    width: 100%;
-    line-height: 1.2;
-    text-decoration: none;
-  }
   p {
-    font-size: .85em;
+    font-size: .7rem;
     margin: 0;
     line-height: 1.6em;
   }
@@ -221,11 +274,6 @@ div[class^="col-"] img {
   }
 }
 
-.book-grid-item .grid-card-content h2 a  {
-    color: $color-book;
-    fill: $color-book;
-}
-
 .bookshelf-grid-item .grid-card-content h2 a  {
   color: $color-bookshelf;
   fill: $color-bookshelf;
@@ -242,6 +290,22 @@ div[class^="col-"] img {
   .grid.third {
     grid-template-columns: 1fr 1fr;
   }
+  .grid.half, .grid.left-focus, .grid.right-focus {
+    grid-template-columns: 1fr;
+  }
+  .grid.half.collapse-xs {
+    grid-template-columns: 1fr 1fr;
+  }
+  .grid.large-gap {
+    grid-column-gap: $-m;
+    grid-row-gap: $-m;
+  }
+  .grid.right-focus.reverse-collapse > *:nth-child(2) {
+    order: 0;
+  }
+  .grid.right-focus.reverse-collapse > *:nth-child(1) {
+    order: 1;
+  }
 }
 
 @include smaller-than($s) {
@@ -250,6 +314,12 @@ div[class^="col-"] img {
   }
 }
 
+@include smaller-than($xs) {
+  .grid.half.collapse-xs {
+    grid-template-columns: 1fr;
+  }
+}
+
 .float {
   float: left;
   &.right {
@@ -270,6 +340,8 @@ div[class^="col-"] img {
   display: inline-block;
 }
 
+
+// TODO - Remove old BS grid system
 .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
   position: relative;
   min-height: 1px;
@@ -908,18 +980,12 @@ div[class^="col-"] img {
 }
 .clearfix:before,
 .clearfix:after,
-.container:before,
-.container:after,
-.container-fluid:before,
-.container-fluid:after,
 .row:before,
 .row:after {
   content: " ";
   display: table;
 }
 .clearfix:after,
-.container:after,
-.container-fluid:after,
 .row:after {
   clear: both;
 }
@@ -928,3 +994,67 @@ div[class^="col-"] img {
   margin-left: auto;
   margin-right: auto;
 }
+
+
+
+
+
+
+.grid {
+  display: grid;
+  grid-column-gap: $-m;
+  grid-row-gap: 0;
+  &.contained {
+    max-width: $xxl;
+    padding-left: $-m;
+    padding-right: $-m;
+    margin-left: auto;
+    margin-right: auto;
+  }
+  &.v-center {
+    align-items: center;
+  }
+}
+
+@each $sizeLetter, $size in $spacing {
+  .grid.contained.space-#{$sizeLetter} {
+    padding-left: $size;
+    padding-right: $size;
+    grid-column-gap: $size;
+  }
+}
+
+@mixin grid-layout($name, $times) {
+  .grid.#{$name} {
+    grid-template-columns: repeat(#{$times}, 1fr);
+  }
+}
+
+@include grid-layout('thirds', 3)
+@include grid-layout('halves', 2)
+
+@each $sizeLetter, $size in $screen-sizes {
+  @include smaller-than($size) {
+    .grid.break-#{$sizeLetter} {
+      grid-template-columns: 1fr;
+    }
+  }
+}
+
+
+/**
+ * Visibility
+ */
+
+@each $sizeLetter, $size in $screen-sizes {
+  @include smaller-than($size) {
+    .hide-under-#{$sizeLetter} {
+      display: none !important;
+    }
+  }
+  @include larger-than($size) {
+    .hide-over-#{$sizeLetter} {
+      display: none !important;
+    }
+  }
+}
\ No newline at end of file
index b66bab394d54ec732e12ec36b75620ffb0fe9ef8..e8667e7193bb0c4dbaa5c67ec429ab91ed89c034 100644 (file)
@@ -2,21 +2,24 @@
  * Includes the main navigation header and the faded toolbar.
  */
 
+header .grid {
+  grid-template-columns: auto min-content auto;
+}
+
 header {
+  position: relative;
   display: block;
   z-index: 2;
   top: 0;
   background-color: $primary-dark;
   color: #fff;
   fill: #fff;
-  .padded {
-    padding: $-m;
-  }
   border-bottom: 1px solid #DDD;
+  box-shadow: $bs-card;
+  padding: $-xxs 0;
   .links {
     display: inline-block;
     vertical-align: top;
-    margin-left: $-m;
   }
   .links a {
     display: inline-block;
@@ -28,15 +31,6 @@ header {
     padding-left: $-m;
     padding-right: 0;
   }
-  @include smaller-than($screen-md) {
-    .links a {
-      padding-left: $-s;
-      padding-right: $-s;
-    }
-    .dropdown-container {
-      padding-left: $-s;
-    }
-  }
   .avatar, .user-name {
     display: inline-block;
   }
@@ -63,27 +57,17 @@ header {
       padding-top: 4px;
       font-size: 18px;
     }
-    @include smaller-than($screen-md) {
+    @include between($l, $xl) {
       padding-left: $-xs;
       .name {
         display: none;
       }
     }
   }
-  @include smaller-than($screen-sm) {
-    text-align: center;
-    .float.right {
-      float: none;
-    }
-    .links a {
-      padding: $-s;
-    }
-    .user-name {
-      padding-top: $-s;
-    }
-  }
 }
 
+
+
 .header-search {
   display: inline-block;
 }
@@ -92,13 +76,16 @@ header .search-box {
   margin-top: 10px;
   input {
     background-color: rgba(0, 0, 0, 0.2);
-    border: 1px solid rgba(255, 255, 255, 0.3);
+    border: 1px solid rgba(255, 255, 255, 0.2);
+    border-radius: 40px;
     color: #EEE;
     z-index: 2;
+    padding-left: 40px;
   }
   button {
     fill: #EEE;
     z-index: 1;
+    left: 16px;
     svg {
       margin-right: 0;
     }
@@ -115,20 +102,11 @@ header .search-box {
   :-moz-placeholder { /* Firefox 18- */
     color: #DDD;
   }
-  @include smaller-than($screen-lg) {
-    max-width: 250px;
-  }
-  @include smaller-than($l) {
+  @include between($l, $xl) {
     max-width: 200px;
   }
 }
 
-@include smaller-than($s) {
-  .header-search {
-    display: block;
-  }
-}
-
 .logo {
   display: inline-block;
   &:hover {
@@ -151,10 +129,141 @@ header .search-box {
   height: 43px;
 }
 
-.breadcrumbs span.sep {
-  color: #aaa;
+.mobile-menu-toggle {
+  color: #FFF;
+  fill: #FFF;
+  font-size: 2em;
+  border: 2px solid rgba(255, 255, 255, 0.8);
+  border-radius: 4px;
   padding: 0 $-xs;
+  position: absolute;
+  right: $-m;
+  top: 8px;
+  line-height: 1;
+  cursor: pointer;
+  user-select: none;
+  svg {
+    margin: 0;
+  }
 }
+
+@include smaller-than($l) {
+  header .header-links {
+    display: none;
+    background-color: #FFF;
+    z-index: 10;
+    right: $-m;
+    border-radius: 4px;
+    overflow: hidden;
+    position: absolute;
+    box-shadow: $bs-hover;
+    margin-top: -$-xs;
+    &.show {
+      display: block;
+    }
+  }
+  header .links a, header .dropdown-container ul li a {
+    text-align: left;
+    display: block;
+    padding: $-s $-m;
+    color: $text-dark;
+    fill: $text-dark;
+    svg {
+      margin-right: $-s;
+    }
+    &:hover {
+      background-color: #EEE;
+      color: #444;
+      fill: #444;
+      text-decoration: none;
+    }
+  }
+  header .dropdown-container {
+    display: block;
+    padding-left: 0;
+  }
+  header .links {
+    display: block;
+  }
+  header .dropdown-container ul {
+    display: block !important;
+    position: relative;
+    background-color: transparent;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    box-shadow: none;
+  }
+}
+
+.breadcrumbs {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: flex-start;
+  flex-wrap: wrap;
+  .icon-list-item {
+    width: auto;
+    padding-top: $-xs;
+    padding-bottom: $-xs;
+    &:not(:hover) {
+      color: #666;
+      fill: #888;
+    }
+  }
+  .separator {
+    display: inline-block;
+    fill: #aaa;
+    font-size: 1.6em;
+    line-height: 0.8;
+    margin: -2px 0 0;
+  }
+}
+
+.breadcrumb-listing {
+  position: relative;
+  .breadcrumb-listing-toggle {
+    padding: 6px;
+    border: 1px solid transparent;
+    border-radius: 4px;
+    &:hover {
+      border-color: #DDD;
+    }
+  }
+  .svg-icon {
+    margin-right: 0;
+  }
+}
+
+.breadcrumb-listing-dropdown {
+  box-shadow: $bs-med;
+  overflow: hidden;
+  min-height: 100px;
+  width: 240px;
+  display: none;
+  position: absolute;
+  z-index: 80;
+  right: -$-m;
+  .breadcrumb-listing-search .svg-icon {
+    position: absolute;
+    left: $-s;
+    top: 11px;
+    fill: #888;
+    pointer-events: none;
+  }
+  .breadcrumb-listing-entity-list {
+    max-height: 400px;
+    overflow-y: scroll;
+    text-align: left;
+  }
+  input {
+    padding-left: $-xl;
+    border-radius: 0;
+    border: 0;
+    border-bottom: 1px solid #DDD;
+  }
+}
+
 .faded {
   a, button, span, span > div {
     color: #666;
@@ -182,13 +291,24 @@ header .search-box {
   background-color: $primary-faded;
 }
 
-.toolbar-container {
-  background-color: #FFF;
+.toolbar {
+  position: relative;
+  > .grid > div {
+    opacity: 0.8;
+    transition: opacity ease-in-out 120ms;
+    &:hover {
+      opacity: 1;
+    }
+  }
+  .text-button {
+    color: #666;
+    fill: #666;
+  }
 }
 
-.breadcrumbs .text-button, .action-buttons .text-button {
+.action-buttons .text-button {
   display: inline-block;
-  padding: $-s;
+  padding: $-xs $-s;
   &:last-child {
     padding-right: 0;
   }
@@ -217,25 +337,12 @@ header .search-box {
 }
 
 @include smaller-than($m) {
-  .breadcrumbs .text-button, .action-buttons .text-button {
+  .action-buttons .text-button {
     padding: $-xs $-xs;
   }
   .action-buttons .dropdown-container:last-child a {
     padding-left: $-xs;
   }
-  .breadcrumbs .text-button {
-    font-size: 0;
-  }
-  .breadcrumbs .text-button svg {
-    font-size: $fs-m;
-  }
-  .breadcrumbs a i {
-    font-size: $fs-m;
-    padding-right: 0;
-  }
-  .breadcrumbs span.sep {
-    padding: 0 $-xxs;
-  }
   .toolbar .col-xs-1:first-child {
     padding-right: 0;
   }
index 65f05a71d5c69370707cca7b45b4510395ff8b05..a89d030a1df5d1bd254f7324b9f377454975f545 100644 (file)
@@ -3,25 +3,20 @@
 }
 
 html {
-  background-color: #FFFFFF;
   height: 100%;
   overflow-y: scroll;
+  background-color: #F2F2F2;
   &.flexbox {
     overflow-y: hidden;
   }
-  &.shaded {
-    background-color: #F2F2F2;
-  }
 }
 
 body {
   font-size: $fs-m;
   line-height: 1.6;
-  color: #616161;
+  color: #444;
   -webkit-font-smoothing: antialiased;
-  &.shaded {
-    background-color: #F2F2F2;
-  }
+  background-color: #F2F2F2;
 }
 
 button {
index 18a7ea9cee0d52b617c8b5784d36f8abbf35b846..8b7027ef2103731c01e723742b6356ef82312b8b 100644 (file)
-.page-list {
-  h4 {
-    margin: $-l 0 $-xs 0;
-    font-size: 1.666em;
-  }
-  a.chapter {
-    color: $color-chapter;
-  }
-  .inset-list {
-    display: none;
-    overflow: hidden;
-  }
-  h5 {
-    display: block;
-    margin: $-s 0 0 0;
-    border-left: 5px solid $color-page;
-    padding: $-xs 0 $-xs $-m;
-    font-size: 1.1em;
-    font-weight: normal;
-    &.draft {
-      border-left-color: $color-page-draft;
-    }
-  }
-  .entity-list-item {
-    margin-bottom: $-m;
-  }
-  hr {
-    margin-top: 0;
+
+.book-contents .entity-list-item {
+  .icon {
+    width: 30px;
+    border-radius: 4px;
+    justify-self: stretch;
+    align-self: stretch;
+    height: auto;
   }
-  .page, .chapter, .book {
-    padding-left: $-l;
+  p {
+    margin-bottom: 0;
   }
-  .page {
-    border-left: 5px solid $color-page;
+  .inner-page {
+    padding-top: 0;
+    padding-bottom: 0;
   }
-  .page.draft {
-    border-left: 5px solid $color-page-draft;
-    .text-page {
-      color: $color-page-draft;
-      fill: $color-page-draft;
+}
+
+.entity-list-item + .chapter-expansion {
+  display: flex;
+  padding: 0 $-m $-m $-m;
+  align-items: center;
+  border: 0;
+  width: 100%;
+  position: relative;
+  > .icon {
+    width: 30px;
+    height: auto;
+    border-radius: 0 0 4px 4px;
+    align-self: stretch;
+    flex-shrink: 0;
+    &:before {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 1px;
+      background-color: currentColor;
+      content: '';
+      opacity: 0.2;
     }
   }
-  .chapter {
-    border-left: 5px solid $color-chapter;
+  > .content {
+    flex: 1;
   }
-  .book {
-    border-left: 5px solid $color-book;
+  .chapter-expansion-toggle {
+    border-radius: 0 4px 4px 0;
+    padding: $-xs $-m;
   }
-  .meta {
-    margin-top: -$-m;
-    font-size: 0.95em;
+  .chapter-expansion-toggle:hover {
+    background-color: rgba(0, 0, 0, 0.06);
   }
-  .meta span {
-    margin-right: $-s;
+
+}
+
+.entity-list-item.has-children {
+  padding-bottom: 0;
+  > .icon {
+    border-radius: 4px 4px 0 0;
   }
 }
 
-@include smaller-than($s) {
-  .page-list h4 {
-    font-size: 1.333em;
+.inset-list {
+  display: none;
+  .entity-list-item-name {
+    font-size: 1rem;
+  }
+  .entity-list-item-children {
+    padding-top: 0;
+    padding-bottom: 0;
   }
 }
 
 .sidebar-page-nav {
-  $nav-indent: $-s;
+  $nav-indent: $-m;
   list-style: none;
   margin: $-s 0 $-m 2px;
-  border-left: 2px dotted #BBB;
+  position: relative;
+  &:after {
+    content: '';
+    display: block;
+    position: absolute;
+    left: 0;
+    background-color: rgba(0, 0, 0, 0.2);
+    width: 2px;
+    top: 5px;
+    bottom: 5px;
+    z-index: 0;
+  }
   li {
-    padding-left: $-s;
     margin-bottom: 4px;
     font-size: 0.95em;
+    position: relative;
   }
   .h1 {
-    margin-left: -2px;
+    padding-left: $nav-indent;
   }
   .h2 {
-    margin-left: -2px;
+    padding-left: $nav-indent;
   }
   .h3 {
-    margin-left: $nav-indent;
+    padding-left: $nav-indent * 2;
   }
   .h4 {
-    margin-left: $nav-indent*2;
+    padding-left: $nav-indent * 2.5;
   }
   .h5 {
-    margin-left: $nav-indent*3;
+    padding-left: $nav-indent*3;
   }
   .h6 {
-    margin-left: $nav-indent*4;
+    padding-left: $nav-indent*3.5;
   }
   .current-heading {
     font-weight: bold;
   }
+  li:not(.current-heading) .sidebar-page-nav-bullet {
+    background-color: #BBB !important;
+  }
+  .sidebar-page-nav-bullet {
+    width: 6px;
+    height: 6px;
+    position: absolute;
+    left: -2px;
+    top: 30%;
+    border-radius: 50%;
+    box-shadow: 0 0 0 6px #F2F2F2;
+    z-index: 1;
+  }
 }
 
 // Sidebar list
-.book-tree {
-  transition: ease-in-out 240ms;
-  transition-property: right, border;
-}
-.book-tree h4 {
-  padding: $-m $-s 0 $-s;
-  i {
-    padding-right: $-s;
+.book-tree .book.entity-list-item {
+  font-size: 0.6rem;
+  h4 {
+    font-size: 1rem;
+    margin: 0;
   }
 }
 .book-tree .sidebar-page-list {
   list-style: none;
   margin: $-xs 0 0;
   padding-left: 0;
-  border-left: 5px solid $color-book;
-  li a {
-    display: block;
-    border-bottom: none;
-    padding: $-xs 0 $-xs $-s;
-    &:hover {
-      text-decoration: none;
-    }
-  }
-  li a i {
-    padding-right: $-xs + 2px;
-  }
-  li, a {
-    display: block;
-  }
-  a.bold {
-    color: #EEE !important;
-    fill: #EEE !important;
-  }
+  padding-right: 0;
+  position: relative;
   ul {
     list-style: none;
-    margin: 0;
+    padding-left: 1rem;
+    padding-right: 0;
   }
-  .book {
-    color: $color-book !important;
-    fill: $color-book !important;
-    &.selected {
-      background-color: rgba($color-book, 0.29);
-    }
+  .entity-icon {
+    font-size: 12px;
+    z-index: 2;
+    background-color: #FFF;
   }
-  .chapter {
-    color: $color-chapter !important;
-    fill: $color-chapter !important;
-    &.selected {
-      background-color: rgba($color-chapter, 0.12);
-    }
+  .entity-list-item-name {
+    font-size: 1em;
+    margin: 0;
   }
-  .page {
-    color: $color-page !important;
-    fill: $color-page !important;
-    border-bottom: none;
-    &.selected {
-      background-color: rgba($color-page, 0.1);
-    }
+  .entity-list-item {
+    font-size: 0.8rem;
   }
-  [chapter-toggle] {
-    padding-left: $-s;
+  .entity-list-item.selected {
+    background-color: #F2F2F2;
   }
-  .list-item-chapter {
-    border-left: 5px solid $color-chapter;
-    margin: 10px 10px;
-    display: block;
+  .chapter-child-menu {
+    font-size: 12px;
+    padding-left: 2rem;
+    margin-top: -.2rem;
   }
-  .list-item-page {
-    border-bottom: none;
-    border-left: 5px solid $color-page;
-    margin: 10px 10px;
+  [chapter-toggle] {
+    padding-left: 1.5rem;
+    padding-bottom: .2rem;
   }
-  .list-item-page.draft {
-    border-left: 5px solid $color-page-draft;
+  .icon {
+    z-index: 2;
   }
-  .page.draft .page, .list-item-page.draft a.page {
-    color: $color-page-draft !important;
-    fill: $color-page-draft !important;
+  &:after, .sub-menu:after {
+    content: '';
+    display: block;
+    position: absolute;
+    left: 1.6rem;
+    top: 1rem;
+    bottom: 1rem;
+    border-left: 2px solid #DDD;
+    opacity: 0.6;
+    z-index: 0;
   }
-  .sub-menu {
+}
+
+.chapter-child-menu {
+  ul.sub-menu {
     display: none;
     padding-left: 0;
+    position: relative;
   }
   [chapter-toggle].open + .sub-menu {
     display: block;
 // Sortable Lists
 .sortable-page-list, .sortable-page-list ul {
   list-style: none;
-  background-color: #FFF;
 }
 .sort-box {
   margin-bottom: $-m;
-  padding: 0 $-l 0 $-l;
-  border-left: 4px solid $color-book;
+  border: 2px solid rgba($color-book, 0.6);
+  padding: $-m $-xl;
+  border-radius: 4px;
+}
+.sort-box-options {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+.sort-box-options .button {
+  margin-left: 0;
 }
 .sortable-page-list {
   margin-left: 0;
+  padding: 0;
+  .entity-list-item > span:first-child {
+    align-self: flex-start;
+  }
+  .entity-list-item > div {
+    display: block;
+    flex: 1;
+  }
   > ul {
     margin-left: 0;
   }
   ul {
-    margin-bottom: 0;
+    margin-bottom: $-m;
     margin-top: 0;
-    box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.1);
+    padding-left: $-m;
   }
   li {
     border: 1px solid #DDD;
-    padding: $-xs $-s;
     margin-top: -1px;
     min-height: 38px;
     &.text-chapter {
 
 .activity-list-item {
   padding: $-s 0;
+  display: grid;
+  grid-template-columns: min-content 1fr;
+  grid-column-gap: $-m;
   color: #888;
   fill: #888;
-  border-bottom: 1px solid #EEE;
   font-size: 0.9em;
-  .left {
-    float: left;
-  }
-  .left + .right {
-    margin-left: 30px + $-s;
-  }
-  &:last-of-type {
-    border-bottom: 0;
+}
+.card .activity-list-item {
+  padding: $-s $-m;
+}
+
+.user-list-item {
+  display: inline-grid;
+  padding: $-s;
+  grid-template-columns: min-content 1fr;
+  grid-column-gap: $-m;
+  font-size: 0.9em;
+  align-items: center;
+  > div:first-child {
+    line-height: 0;
   }
 }
 
@@ -280,10 +318,8 @@ ul.pagination {
   margin: 0;
 }
 
-.entity-list {
-  > div {
-    padding: $-m 0;
-  }
+.entity-list, .icon-list {
+  margin: 0 (-$-m);
   h4 {
     margin: 0;
   }
@@ -302,15 +338,97 @@ ul.pagination {
     color: $color-page-draft;
     fill: $color-page-draft;
   }
+  > .dropdown-container {
+    display: block;
+  }
 }
 
-.card .entity-list-item, .card .activity-list-item {
-  padding-left: $-m;
-  padding-right: $-m;
+.entity-list-item, .icon-list-item {
+  padding: $-s $-m;
+  display: flex;
+  align-items: center;
+  background-color: transparent;
+  border: 0;
+  width: 100%;
+  position: relative;
+  h4 a {
+    color: #666;
+  }
+  > span:first-child {
+    margin-right: $-m;
+    flex-basis: 1.88em;
+    flex: none;
+  }
+  > span:last-child {
+    flex: 1;
+    text-align: left;
+  }
+  &:not(.no-hover) {
+    cursor: pointer;
+  }
+  &:not(.no-hover):hover {
+    text-decoration: none;
+    background-color: #DDD;
+    border-radius: 4px;
+  }
+}
+
+
+.card .entity-list-item:not(.no-hover):hover {
+  background-color: #F2F2F2;
+}
+.card .entity-list-item .entity-list-item:hover {
+  background-color: #EEEEEE;
+}
+
+.entity-list-item-children {
+  padding: $-m;
+  > div {
+    overflow: hidden;
+    padding: $-xs 0;
+    margin-top: -$-xs;
+  }
+  .entity-chip {
+    text-overflow: ellipsis;
+    height: 2.5em;
+    overflow: hidden;
+    text-align: left;
+    display: block;
+    white-space: nowrap;
+  }
+}
+
+.entity-list-item-image {
+  align-self: stretch;
+  width: 140px;
+  flex: none;
+  background-size: cover;
+  background-position: 50% 50%;
+  border-radius: 3px;
+  position: relative;
+  margin-right: $-l;
+
+  .svg-icon {
+    color: #FFF;
+    fill: #FFF;
+    font-size: 1.66rem;
+    margin-right: 0;
+    position: absolute;
+    bottom: $-xs;
+    left: $-xs;
+  }
+
+  @include smaller-than($m) {
+    width: 80px;
+  }
+}
+
+.chapter > .entity-list-item-image {
+  width: 60px;
 }
 
 .entity-list.compact {
-  font-size: 0.6em;
+  font-size: 0.6 * $fs-m;
   h4, a {
     line-height: 1.2;
   }
@@ -331,6 +449,11 @@ ul.pagination {
   hr {
     margin: 0;
   }
+  @include smaller-than($m) {
+    h4 {
+      font-size: 1.666em;
+    }
+  }
 }
 
 .dropdown-container {
@@ -367,6 +490,9 @@ ul.pagination {
     padding: $-xs $-m;
     line-height: 1.2;
   }
+  li.active a {
+    font-weight: 600;
+  }
   a, button {
     display: block;
     padding: $-xs $-m;
@@ -396,7 +522,10 @@ ul.pagination {
 .featured-image-container {
   position: relative;
   overflow: hidden;
-  background: #F2F2F2;
+  min-height: 140px;
+  background-size: cover;
+  background-position: 50% 50%;
+  transition: opacity ease-in-out 240ms;
   a {
     display: block;
   }
@@ -405,11 +534,46 @@ ul.pagination {
     width: 100%;
     max-width: 100%;
     height: auto;
-    transition: all .5s ease-in-out;
   }
-  img:hover {
-    transform: scale(1.15);
-    opacity: .5;
+}
+.featured-image-container-wrap {
+  position: relative;
+  .svg-icon {
+    color: #FFF;
+    fill: #FFF;
+    font-size: 2rem;
+    margin-right: 0;
+    position: absolute;
+    bottom: 10px;
+    left: 6px;
   }
 }
+.grid-card:hover .featured-image-container {
+  opacity: .5;
+}
 
+.action-link-list {
+  //padding: $-s 0;
+}
+.action-link {
+  background: transparent;
+  border: none;
+  color: currentColor;
+  padding: $-m 0;
+}
+
+.active-link-list {
+  a {
+    display: inline-block;
+    padding: $-s;
+  }
+  a:not(.active) {
+    color: #444;
+    fill: #444;
+  }
+  a:hover {
+    background-color: rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    text-decoration: none;
+  }
+}
\ No newline at end of file
index 3d3101ca7130d152d1237976892c08a0d1b2c85b..13c81ae9eeb6da22f9496370c5f797f29545be8a 100644 (file)
@@ -5,6 +5,9 @@
 @mixin larger-than($size) {
     @media screen and (min-width: $size) { @content; }
 }
+@mixin between($min, $max) {
+  @media screen and (min-width: $min) and (max-width: $max) { @content; }
+}
 @mixin clearfix() {
   &:after {
     display: block;
index 84280319debff1d04fd30d4633ca0448b66d6399..427b98c2626e94cd1d5bdb2661d4874f1fc14377 100755 (executable)
@@ -3,6 +3,7 @@
   flex-direction: column;
   align-items: stretch;
   overflow: hidden;
+  background-color: #FFF;
   .faded-small {
     height: auto;
   }
   width: 100%;
   max-width: 840px;
   margin: 0 auto;
-  margin-top: $-xxl;
   overflow-wrap: break-word;
-  &.flex {
-    margin-top: $-m;
-  }
   .align-left {
     text-align: left;
   }
   }
 }
 
-.comments-container {
-  width: 100%;
-  border-top: 1px solid #DDD;
-  margin-top: $-xl;
-  margin-bottom: $-m;
-  h5 {
-    color: #888;
-    font-weight: normal;
-    margin-top: 0.5em;
-  }
+.comments-container h5 {
+  color: #888;
+  font-weight: normal;
+  margin-top: 0.5em;
 }
 
 .comment-editor .CodeMirror, .comment-editor .CodeMirror-scroll {
   .mce-open {
     display: none;
   }
+}
+
+.entity-list-item > span:first-child, .icon-list-item > span:first-child, .chapter-expansion > .icon {
+  font-size: 0.8rem;
+  width: 1.88em;
+  height: 1.88em;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  border-radius: 1em;
+  position: relative;
+  overflow: hidden;
+  svg {
+    margin: 0;
+    bottom: 0;
+  }
+  &:after {
+    content: '';
+    position: absolute;
+    background-color: currentColor;
+    opacity: 0.2;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.entity-chip {
+  display: inline-block;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  font-size: 0.9em;
+  border-radius: 3px;
+  position: relative;
+  overflow: hidden;
+  padding: $-xs $-s;
+  fill: currentColor;
+  opacity: 0.85;
+  transition: opacity ease-in-out 120ms;
+  &:after {
+    content: '';
+    position: absolute;
+    background-color: currentColor;
+    opacity: 0.15;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+  }
+  &:hover {
+    text-decoration: none;
+    opacity: 1;
+  }
 }
\ No newline at end of file
index ec24e2fa64f51be5be1cda6eab84eca656651244..a1a2fef0a44537057b186fdd1969bf7461edb175 100644 (file)
@@ -19,13 +19,13 @@ table {
 
 table.table {
   width: 100%;
-  tr {
-    border-bottom: 1px solid #DDD;
+  tr td, tr th {
+    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
   }
   th, td {
     text-align: left;
     border: none;
-    padding: $-xs $-xs;
+    padding: $-s $-s;
     vertical-align: middle;
     margin: 0;
   }
@@ -44,6 +44,9 @@ table.table {
   td.actions {
     overflow: visible;
   }
+  a {
+    display: inline-block;
+  }
 }
 
 table.no-style {
index 0063c4672cca2c9d257c28e57c449b483c74f499..1a9afd794ccf50b61960e6aed3986bcb31973399 100644 (file)
@@ -42,7 +42,7 @@ h1, h2, h3, h4, h5, h6 {
   font-weight: 400;
   position: relative;
   display: block;
-  color: #555;
+  color: #222;
   .subheader {
     font-size: 0.5em;
     line-height: 1em;
@@ -79,6 +79,14 @@ h5, h6 {
   }
 }
 
+.list-heading {
+  font-size: 2rem;
+}
+
+h2.list-heading {
+  font-size: 1.333rem;
+}
+
 /*
  * Link styling
  */
@@ -141,11 +149,8 @@ em, i, .italic {
 }
 
 small, p.small, span.small, .text-small {
-  font-size: 0.8em;
-  color: lighten($text-dark, 20%);
-  small, p.small, span.small, .text-small {
-    font-size: 1em;
-  }
+  font-size: 0.75rem;
+  color: lighten($text-dark, 10%);
 }
 
 sup, .superscript {
@@ -233,106 +238,6 @@ pre code {
   display: block;
   line-height: 1.6;
 }
-/*
- * Text colors
- */
-p.pos, p .pos, span.pos, .text-pos {
-  color: $positive;
-  fill: $positive;
-  &:hover {
-    color: $positive;
-    fill: $positive;
-  }
-}
-
-p.neg, p .neg, span.neg, .text-neg {
-  color: $negative;
-  fill: $negative;
-  &:hover {
-    color: $negative;
-    fill: $negative;
-  }
-}
-
-p.muted, p .muted, span.muted, .text-muted {
-       color: lighten($text-dark, 26%);
-       fill: lighten($text-dark, 26%);
-    &.small, .small {
-      color: lighten($text-dark, 32%);
-      fill: lighten($text-dark, 32%);
-    }
-}
-
-p.primary, p .primary, span.primary, .text-primary {
-       color: $primary;
-       fill: $primary;
-  &:hover {
-    color: $primary;
-    fill: $primary;
-  }
-}
-
-p.secondary, p .secondary, span.secondary, .text-secondary {
-       color: $secondary;
-       fill: $secondary;
-  &:hover {
-    color: $secondary;
-    fill: $secondary;
-  }
-}
-
-.text-bookshelf {
-  color: $color-bookshelf;
-  fill: $color-bookshelf;
-  &:hover {
-    color: $color-bookshelf;
-    fill: $color-bookshelf;
-  }
-}
-.text-book {
-  color: $color-book;
-  fill: $color-book;
-  &:hover {
-    color: $color-book;
-    fill: $color-book;
-  }
-}
-.text-page {
-  color: $color-page;
-  fill: $color-page;
-  &:hover {
-    color: $color-page;
-    fill: $color-page;
-  }
-  &.draft {
-    color: $color-page-draft;
-    fill: $color-page-draft;
-  }
-  &.draft:hover {
-    color: $color-page-draft;
-    fill: $color-page-draft;
-  }
-}
-.text-chapter {
-  color: $color-chapter;
-  fill: $color-chapter;
-  &:hover {
-    color: $color-chapter;
-    fill: $color-chapter;
-  }
-}
-.faded .text-book:hover {
-  color: $color-book !important;
-  fill: $color-book !important;
-}
-.faded .text-chapter:hover {
-  color: $color-chapter !important;
-  fill: $color-chapter !important;
-}
-.faded .text-page:hover {
-  color: $color-page !important;
-  fill: $color-page !important;
-}
 
 span.highlight {
   //background-color: rgba($primary, 0.2);
@@ -435,10 +340,6 @@ span.sep {
 /**
   * Icons
   */
-i {
-  padding-right: $-xs;
-}
-
 .svg-icon {
   width: 1em;
   height: 1em;
@@ -446,5 +347,6 @@ i {
   position: relative;
   bottom: -0.105em;
   margin-right: $-xs;
+  pointer-events: none;
 }
 
index 006d1b3f08d105b40a54f2dc0f8ee2d11501be67..07820c57e0d6dd4322cd52a610c3fc63e80f7a35 100644 (file)
@@ -1,14 +1,12 @@
 // Variables
 ///////////////
 
-// Sizes
-$max-width: 1400px;
-
 // Screen breakpoints
+$xxl: 1400px;
 $xl: 1100px;
 $ipad-width: 1028px; // Is actually 1024 but we go over to ensure functionality.
 $l: 1000px;
-$m: 800px;
+$m: 880px;
 $s: 600px;
 $xs: 400px;
 $xxs: 360px;
@@ -16,6 +14,8 @@ $screen-lg: 1200px;
 $screen-md: 992px;
 $screen-sm: 768px;
 
+$screen-sizes: (('xxs', $xxs), ('xs', $xs), ('s', $s), ('m', $m), ('l', $l), ('xl', $xl));
+
 // Spacing (Margins+Padding)
 $-xxxl: 64px;
 $-xxl: 48px;
@@ -26,6 +26,8 @@ $-s: 12px;
 $-xs: 6px;
 $-xxs: 3px;
 
+$spacing: (('none', 0), ('xxs', $-xxs), ('xs', $-xs), ('s', $-s), ('m', $-m), ('l', $-l), ('xl', $-xl), ('xxl', $-xxl));
+
 // Fonts
 $text: -apple-system, BlinkMacSystemFont,
 "Segoe UI", "Oxygen", "Ubuntu", "Roboto", "Cantarell",
@@ -33,8 +35,8 @@ $text: -apple-system, BlinkMacSystemFont,
 sans-serif;
 $mono: "Lucida Console", "DejaVu Sans Mono", "Ubunto Mono", Monaco, monospace;
 $heading: $text;
-$fs-m: 15px;
-$fs-s: 14px;
+$fs-m: 14px;
+$fs-s: 12px;
 
 // Colours
 $primary: #0288D1;
@@ -49,7 +51,7 @@ $primary-faded: rgba(21, 101, 192, 0.15);
 // Item Colors
 $color-bookshelf: #af5a5a;
 $color-book: #009688;
-$color-chapter: #ef7c3c;
+$color-chapter: #d7804a;
 $color-page: $primary;
 $color-page-draft: #9A60DA;
 
@@ -60,5 +62,5 @@ $text-light: #EEE;
 // Shadows
 $bs-light: 0 0 4px 1px #CCC;
 $bs-med: 0 1px 3px 1px rgba(76, 76, 76, 0.26);
-$bs-card: 0 1px 3px 1px rgba(76, 76, 76, 0.26), 0 1px 12px 0px rgba(76, 76, 76, 0.2);
+$bs-card: 0 1px 6px -1px rgba(0, 0, 0, 0.1);
 $bs-hover: 0 2px 2px 1px rgba(0,0,0,.13);
\ No newline at end of file
index 49ef77f3938255cf55e45278d19ec2b3a2520c56..7792aee83056ee6b5779786dc845037efddeb7f6 100644 (file)
@@ -3,6 +3,7 @@
 @import "mixins";
 @import "html";
 @import "text";
+@import "colors";
 @import "grid";
 @import "blocks";
 @import "buttons";
@@ -254,3 +255,39 @@ $btt-size: 40px;
   height:100%;
   z-index: 150;
 }
+
+.list-sort-container {
+  display: inline-block;
+  form {
+    display: inline-block;
+  }
+  .list-sort {
+    display: inline-grid;
+    margin-left: $-s;
+    grid-template-columns: 120px 40px;
+    border: 2px solid #DDD;
+    border-radius: 4px;
+  }
+  .list-sort-label {
+    font-weight: bold;
+    display: inline-block;
+    color: #888;
+  }
+  .list-sort-type {
+    text-align: left;
+  }
+  .list-sort-type, .list-sort-dir {
+    padding: $-xs $-s;
+    cursor: pointer;
+  }
+  .list-sort-dir {
+    border-left: 2px solid #DDD;
+    fill: #888;
+    .svg-icon {
+      transition: transform ease-in-out 120ms;
+    }
+    &:hover .svg-icon {
+      transform: rotate(180deg);
+    }
+  }
+}
\ No newline at end of file
index ac2edc621f9256b80eb1c1729b2bf91aafd3bbba..1f71c327238ab3fb3f4bae4489c5a8bda48d4183 100644 (file)
@@ -37,6 +37,11 @@ return [
     'remove' => 'Remove',
     'add' => 'Add',
 
+    // Sort Options
+    'sort_name' => 'Name',
+    'sort_created_at' => 'Created Date',
+    'sort_updated_at' => 'Updated Date',
+
     // Misc
     'deleted_user' => 'Deleted User',
     'no_activity' => 'No activity to show',
@@ -56,4 +61,4 @@ return [
     // Email Content
     'email_action_help' => 'If you’re having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:',
     'email_rights' => 'All rights reserved',
-];
\ No newline at end of file
+];
index 2a64f57a3700c113814faa01ba8e6d6cbf9b95dd..dffea3e755e8c91b13177ea0d6cd7b7458eabd98 100644 (file)
@@ -125,6 +125,11 @@ return [
     'books_navigation' => 'Book Navigation',
     'books_sort' => 'Sort Book Contents',
     'books_sort_named' => 'Sort Book :bookName',
+    'books_sort_name' => 'Sort by Name',
+    'books_sort_created' => 'Sort by Created Date',
+    'books_sort_updated' => 'Sort by Updated Date',
+    'books_sort_chapters_first' => 'Chapters First',
+    'books_sort_chapters_last' => 'Chapters Last',
     'books_sort_show_other' => 'Show Other Books',
     'books_sort_save' => 'Save New Order',
 
@@ -202,6 +207,8 @@ return [
     'pages_revisions_created_by' => 'Created By',
     'pages_revisions_date' => 'Revision Date',
     'pages_revisions_number' => '#',
+    'pages_revisions_numbered' => 'Revision #:id',
+    'pages_revisions_numbered_changes' => 'Revision #:id Changes',
     'pages_revisions_changelog' => 'Changelog',
     'pages_revisions_changes' => 'Changes',
     'pages_revisions_current' => 'Current Version',
index c38068afc00f9fcc67e7272e03dfac575b96934d..e6c24f5a14f57a598d8edd48370981c5ad51b471 100755 (executable)
@@ -12,34 +12,44 @@ return [
     'settings_save_success' => 'Settings saved',
 
     // App Settings
-    'app_settings' => 'App Settings',
-    'app_name' => 'Application name',
-    'app_name_desc' => 'This name is shown in the header and any emails.',
-    'app_name_header' => 'Show Application name in header?',
+    'app_customization' => 'Customization',
+    'app_features_security' => 'Features & Security',
+    'app_name' => 'Application Name',
+    'app_name_desc' => 'This name is shown in the header and in any system-sent emails.',
+    'app_name_header' => 'Show name in header',
+    'app_public_access' => 'Public Access',
+    'app_public_access_desc' => 'Enabling this option will allow visitors, that are not logged-in, to access content in your BookStack instance.',
+    'app_public_access_desc_guest' => 'Access for public visitors can be controlled through the "Guest" user.',
+    'app_public_access_toggle' => 'Allow public access',
     'app_public_viewing' => 'Allow public viewing?',
-    'app_secure_images' => 'Enable higher security image uploads?',
+    'app_secure_images' => 'Higher Security Image Uploads',
+    'app_secure_images_toggle' => 'Enable higher security image uploads',
     'app_secure_images_desc' => 'For performance reasons, all images are public. This option adds a random, hard-to-guess string in front of image urls. Ensure directory indexes are not enabled to prevent easy access.',
-    'app_editor' => 'Page editor',
+    'app_editor' => 'Page Editor',
     'app_editor_desc' => 'Select which editor will be used by all users to edit pages.',
-    'app_custom_html' => 'Custom HTML head content',
+    'app_custom_html' => 'Custom HTML Head Content',
     'app_custom_html_desc' => 'Any content added here will be inserted into the bottom of the <head> section of every page. This is handy for overriding styles or adding analytics code.',
-    'app_logo' => 'Application logo',
+    'app_logo' => 'Application Logo',
     'app_logo_desc' => 'This image should be 43px in height. <br>Large images will be scaled down.',
-    'app_primary_color' => 'Application primary color',
+    'app_primary_color' => 'Application Primary Color',
     'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.',
     'app_homepage' => 'Application Homepage',
     'app_homepage_desc' => 'Select a view to show on the homepage instead of the default view. Page permissions are ignored for selected pages.',
     'app_homepage_select' => 'Select a page',
-    'app_disable_comments' => 'Disable comments',
-    'app_disable_comments_desc' => 'Disable comments across all pages in the application. Existing comments are not shown.',
+    'app_disable_comments' => 'Disable Comments',
+    'app_disable_comments_toggle' => 'Disable comments',
+    'app_disable_comments_desc' => 'Disables comments across all pages in the application. <br> Existing comments are not shown.',
 
     // Registration Settings
-    'reg_settings' => 'Registration Settings',
-    'reg_allow' => 'Allow registration?',
+    'reg_settings' => 'Registration',
+    'reg_enable' => 'Enable Registration',
+    'reg_enable_toggle' => 'Enable registration',
+    'reg_enable_desc' => 'When registration is enabled user will be able to sign themselves up as an application user. Upon registration they are given a single, default user role.',
     'reg_default_role' => 'Default user role after registration',
-    'reg_confirm_email' => 'Require email confirmation?',
-    'reg_confirm_email_desc' => 'If domain restriction is used then email confirmation will be required and the below value will be ignored.',
-    'reg_confirm_restrict_domain' => 'Restrict registration to domain',
+    'reg_email_confirmation' => 'Email Confirmation',
+    'reg_email_confirmation_toggle' => 'Require email confirmation',
+    'reg_confirm_email_desc' => 'If domain restriction is used then email confirmation will be required and this option will be ignored.',
+    'reg_confirm_restrict_domain' => 'Domain Restriction',
     'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.',
     'reg_confirm_restrict_domain_placeholder' => 'No restriction set',
 
@@ -91,9 +101,16 @@ return [
     'user_profile' => 'User Profile',
     'users_add_new' => 'Add New User',
     'users_search' => 'Search Users',
+    'users_details' => 'User Details',
+    'users_details_desc' => 'Set a display name and an email address for this user. The email address will be used for logging into the application.',
+    'users_details_desc_no_email' => 'Set a display name for this user so others can recognise them.',
     'users_role' => 'User Roles',
+    'users_role_desc' => 'Select which roles this user will be assigned to. If a user is assigned to multiple roles the permissions from those roles will stack and they will receive all abilities of the assigned roles.',
+    'users_password' => 'User Password',
+    'users_password_desc' => 'Set a password used to log-in to the application. This must be at least 5 characters long.',
     'users_external_auth_id' => 'External Authentication ID',
-    'users_password_warning' => 'Only fill the below if you would like to change your password:',
+    'users_external_auth_id_desc' => 'This is the ID used to match this user when communicating with your LDAP system.',
+    'users_password_warning' => 'Only fill the below if you would like to change your password.',
     'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.',
     'users_delete' => 'Delete User',
     'users_delete_named' => 'Delete user :userName',
@@ -104,8 +121,9 @@ return [
     'users_edit_profile' => 'Edit Profile',
     'users_edit_success' => 'User successfully updated',
     'users_avatar' => 'User Avatar',
-    'users_avatar_desc' => 'This image should be approx 256px square.',
+    'users_avatar_desc' => 'Select an image to represent this user. This should be approx 256px square.',
     'users_preferred_language' => 'Preferred Language',
+    'users_preferred_language_desc' => 'This option will change the language used for the user-interface of the application. This will not affect any user-created content.',
     'users_social_accounts' => 'Social Accounts',
     'users_social_accounts_info' => 'Here you can connect your other accounts for quicker and easier login. Disconnecting an account here does not previously authorized access. Revoke access from your profile settings on the connected social account.',
     'users_social_connect' => 'Connect Account',
index b52b5f13e9148a497c79248f4e811885da5c7092..ecdda652027285604225e1d0c58e515950d7622e 100644 (file)
@@ -1,12 +1,12 @@
 <div class="form-group">
     <label for="username">{{ trans('auth.username') }}</label>
-    @include('form/text', ['name' => 'username', 'tabindex' => 1])
+    @include('form.text', ['name' => 'username', 'tabindex' => 1])
 </div>
 
 @if(session('request-email', false) === true)
     <div class="form-group">
         <label for="email">{{ trans('auth.email') }}</label>
-        @include('form/text', ['name' => 'email', 'tabindex' => 1])
+        @include('form.text', ['name' => 'email', 'tabindex' => 1])
         <span class="text-neg">
             {{ trans('auth.ldap_email_hint') }}
         </span>
@@ -15,5 +15,5 @@
 
 <div class="form-group">
     <label for="password">{{ trans('auth.password') }}</label>
-    @include('form/password', ['name' => 'password', 'tabindex' => 2])
+    @include('form.password', ['name' => 'password', 'tabindex' => 2])
 </div>
\ No newline at end of file
index 4ea1f35ba2b89c4ff8b34e8839cca16943feb16c..a12fbd7531ce39d4b16f202651ddb7139e4f2a3c 100644 (file)
@@ -1,10 +1,10 @@
 <div class="form-group">
     <label for="email">{{ trans('auth.email') }}</label>
-    @include('form/text', ['name' => 'email', 'tabindex' => 1])
+    @include('form.text', ['name' => 'email', 'tabindex' => 1])
 </div>
 
 <div class="form-group">
     <label for="password">{{ trans('auth.password') }}</label>
-    @include('form/password', ['name' => 'password', 'tabindex' => 2])
-    <span class="block small"><a href="{{ baseUrl('/password/email') }}">{{ trans('auth.forgot_password') }}</a></span>
+    @include('form.password', ['name' => 'password', 'tabindex' => 1])
+    <span class="block small mt-s"><a href="{{ baseUrl('/password/email') }}">{{ trans('auth.forgot_password') }}</a></span>
 </div>
\ No newline at end of file
index f3847bb043a1f5312583f813dab049d4a807ed85..f5d9e998f540df3826d26c56322338f39f76f80f 100644 (file)
@@ -1,44 +1,48 @@
-@extends('public')
-
-@section('header-buttons')
-    @if(setting('registration-enabled', false))
-        <a href="{{ baseUrl("/register") }}">@icon('new-user') {{ trans('auth.sign_up') }}</a>
-    @endif
-@stop
+@extends('simple-layout')
 
 @section('content')
 
-    <div class="text-center">
-        <div class="card center-box">
-            <h3>@icon('login') {{ title_case(trans('auth.log_in')) }}</h3>
+    <div class="container very-small">
 
-            <div class="body">
-                <form action="{{ baseUrl("/login") }}" method="POST" id="login-form">
-                    {!! csrf_field() !!}
+        <div class="my-l">&nbsp;</div>
 
-                    @include('auth/forms/login/' . $authMethod)
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ title_case(trans('auth.log_in')) }}</h1>
 
-                    <div class="form-group">
-                        <label for="remember" class="inline">{{ trans('auth.remember_me') }}</label>
-                        <input type="checkbox" id="remember" name="remember"  class="toggle-switch-checkbox">
-                        <label for="remember" class="toggle-switch"></label>
-                    </div>
+            <form action="{{ baseUrl("/login") }}" method="POST" id="login-form" class="mt-l">
+                {!! csrf_field() !!}
 
-                    <div class="from-group">
-                        <button class="button block pos" tabindex="3">@icon('login') {{ title_case(trans('auth.log_in')) }}</button>
+                <div class="stretch-inputs">
+                    @include('auth/forms/login/' . $authMethod)
+                </div>
+
+                <div class="grid half collapse-xs large-gap v-center">
+                    <div class="text-left ml-xxs">
+                        @include('components.custom-checkbox', [
+                            'name' => 'remember',
+                            'checked' => false,
+                            'value' => 'on',
+                            'label' => trans('auth.remember_me'),
+                        ])
                     </div>
-                </form>
+                    <div class="text-right">
+                        <button class="button primary" tabindex="3">{{ title_case(trans('auth.log_in')) }}</button>
+                    </div>
+                </div>
+
+            </form>
 
-                @if(count($socialDrivers) > 0)
-                    <hr class="margin-top">
-                    @foreach($socialDrivers as $driver => $name)
-                        <a id="social-login-{{$driver}}" class="button block muted-light svg text-left" href="{{ baseUrl("/login/service/" . $driver) }}">
+            @if(count($socialDrivers) > 0)
+                <hr class="my-l">
+                @foreach($socialDrivers as $driver => $name)
+                    <div>
+                        <a id="social-login-{{$driver}}" class="button outline block svg text-left" href="{{ baseUrl("/login/service/" . $driver) }}">
                             @icon('auth/' . $driver)
                             {{ trans('auth.log_in_with', ['socialDriver' => $name]) }}
                         </a>
-                    @endforeach
-                @endif
-            </div>
+                    </div>
+                @endforeach
+            @endif
         </div>
     </div>
 
index 38f5cc07a9d4b14d2f0ffc15f02250bf244cd413..6746904d46514d4d33f15269a0030e7e62f27a02 100644 (file)
@@ -1,37 +1,25 @@
-@extends('public')
-
-@section('header-buttons')
-    <a href="{{ baseUrl("/login") }}">@icon('login') {{ trans('auth.log_in') }}</a>
-    @if(setting('registration-enabled'))
-        <a href="{{ baseUrl("/register") }}">@icon('new-user') {{ trans('auth.sign_up') }}</a>
-    @endif
-@stop
+@extends('simple-layout')
 
 @section('content')
+    <div class="container very-small mt-xl">
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('auth.reset_password') }}</h1>
 
+            <p class="muted small">{{ trans('auth.reset_password_send_instructions') }}</p>
 
-    <div class="text-center">
-        <div class="card center-box">
-            <h3>@icon('permission') {{ trans('auth.reset_password') }}</h3>
-
-            <div class="body">
-                <p class="muted small">{{ trans('auth.reset_password_send_instructions') }}</p>
+            <form action="{{ baseUrl("/password/email") }}" method="POST" class="stretch-inputs">
+                {!! csrf_field() !!}
 
-                <form action="{{ baseUrl("/password/email") }}" method="POST">
-                    {!! csrf_field() !!}
+                <div class="form-group">
+                    <label for="email">{{ trans('auth.email') }}</label>
+                    @include('form/text', ['name' => 'email'])
+                </div>
 
-                    <div class="form-group">
-                        <label for="email">{{ trans('auth.email') }}</label>
-                        @include('form/text', ['name' => 'email'])
-                    </div>
-
-                    <div class="from-group text-right">
-                        <button class="button primary">{{ trans('auth.reset_password_send_button') }}</button>
-                    </div>
-                </form>
-            </div>
+                <div class="from-group text-right mt-m">
+                    <button class="button primary">{{ trans('auth.reset_password_send_button') }}</button>
+                </div>
+            </form>
 
         </div>
     </div>
-
 @stop
\ No newline at end of file
index 0f66bd47360ce63ee106708ef78397cddd0b0015..fa6ad5b9a327b6cd0945709f27c31616a21913f8 100644 (file)
@@ -1,43 +1,34 @@
-@extends('public')
-
-@section('header-buttons')
-    <a href="{{ baseUrl("/login") }}">@icon('login') {{ trans('auth.log_in') }}</a>
-    @if(setting('registration-enabled'))
-        <a href="{{ baseUrl("/register") }}">@icon('new-user') {{ trans('auth.sign_up') }}</a>
-    @endif
-@stop
+@extends('simple-layout')
 
 @section('content')
 
-    <div class="text-center">
-        <div class="card center-box">
-            <h3>@icon('permission') {{ trans('auth.reset_password') }}</h3>
-
-            <div class="body">
-                <form action="{{ baseUrl("/password/reset") }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="token" value="{{ $token }}">
-
-                    <div class="form-group">
-                        <label for="email">{{ trans('auth.email') }}</label>
-                        @include('form/text', ['name' => 'email'])
-                    </div>
-
-                    <div class="form-group">
-                        <label for="password">{{ trans('auth.password') }}</label>
-                        @include('form/password', ['name' => 'password'])
-                    </div>
-
-                    <div class="form-group">
-                        <label for="password_confirmation">{{ trans('auth.password_confirm') }}</label>
-                        @include('form/password', ['name' => 'password_confirmation'])
-                    </div>
-
-                    <div class="from-group text-right">
-                        <button class="button primary">{{ trans('auth.reset_password') }}</button>
-                    </div>
-                </form>
-            </div>
+    <div class="container very-small mt-xl">
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('auth.reset_password') }}</h1>
+
+            <form action="{{ baseUrl("/password/reset") }}" method="POST" class="stretch-inputs">
+                {!! csrf_field() !!}
+                <input type="hidden" name="token" value="{{ $token }}">
+
+                <div class="form-group">
+                    <label for="email">{{ trans('auth.email') }}</label>
+                    @include('form.text', ['name' => 'email'])
+                </div>
+
+                <div class="form-group">
+                    <label for="password">{{ trans('auth.password') }}</label>
+                    @include('form.password', ['name' => 'password'])
+                </div>
+
+                <div class="form-group">
+                    <label for="password_confirmation">{{ trans('auth.password_confirm') }}</label>
+                    @include('form.password', ['name' => 'password_confirmation'])
+                </div>
+
+                <div class="from-group text-right mt-m">
+                    <button class="button primary">{{ trans('auth.reset_password') }}</button>
+                </div>
+            </form>
 
         </div>
     </div>
index 22d0f4acbd9732f429e6e97ebc49a1227a3778c2..8fbf8abbbd7beae0c6d70af0a87d3183c4a57492 100644 (file)
@@ -1,19 +1,11 @@
-@extends('public')
-
-@section('header-buttons')
-    @if(!$signedIn)
-        <a href="{{ baseUrl("/login") }}">@icon('login') {{ trans('auth.log_in') }}</a>
-    @endif
-@stop
+@extends('simple-layout')
 
 @section('content')
 
-    <div class="text-center">
-        <div class="card center-box">
-            <h3>@icon('users') {{ trans('auth.register_thanks') }}</h3>
-            <div class="body">
-                <p>{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}</p>
-            </div>
+    <div class="container very-small mt-xl">
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('auth.register_thanks') }}</h1>
+            <p>{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}</p>
         </div>
     </div>
 
index 900b394e3bf3cc61e3eeff3de6e7ee61d4788ac6..1388472c2a3c40c6334e17984c76eadbf8228c8e 100644 (file)
@@ -1,50 +1,54 @@
-@extends('public')
-
-@section('header-buttons')
-    <a href="{{ baseUrl("/login") }}">@icon('login') {{ trans('auth.log_in') }}</a>
-@stop
+@extends('simple-layout')
 
 @section('content')
+    <div class="container very-small">
 
-    <div class="text-center">
-        <div class="card center-box">
-            <h3>@icon('new-user')  {{ title_case(trans('auth.sign_up')) }}</h3>
-            <div class="body">
-                <form action="{{ baseUrl("/register") }}" method="POST">
-                    {!! csrf_field() !!}
+        <div class="my-l">&nbsp;</div>
 
-                    <div class="form-group">
-                        <label for="email">{{ trans('auth.name') }}</label>
-                        @include('form/text', ['name' => 'name'])
-                    </div>
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ title_case(trans('auth.sign_up')) }}</h1>
 
-                    <div class="form-group">
-                        <label for="email">{{ trans('auth.email') }}</label>
-                        @include('form/text', ['name' => 'email'])
-                    </div>
+            <form action="{{ baseUrl("/register") }}" method="POST" class="mt-l stretch-inputs">
+                {!! csrf_field() !!}
 
-                    <div class="form-group">
-                        <label for="password">{{ trans('auth.password') }}</label>
-                        @include('form/password', ['name' => 'password', 'placeholder' => trans('auth.password_hint')])
-                    </div>
+                <div class="form-group">
+                    <label for="email">{{ trans('auth.name') }}</label>
+                    @include('form/text', ['name' => 'name'])
+                </div>
+
+                <div class="form-group">
+                    <label for="email">{{ trans('auth.email') }}</label>
+                    @include('form/text', ['name' => 'email'])
+                </div>
+
+                <div class="form-group">
+                    <label for="password">{{ trans('auth.password') }}</label>
+                    @include('form/password', ['name' => 'password', 'placeholder' => trans('auth.password_hint')])
+                </div>
 
-                    <div class="from-group">
-                        <button class="button block pos">{{ trans('auth.create_account') }}</button>
+                <div class="grid half collapse-xs large-gap v-center mt-m">
+                    <div class="text-small">
+                        <a href="{{ baseUrl('/login') }}">Already have an account?</a>
                     </div>
-                </form>
+                    <div class="from-group text-right">
+                        <button class="button primary">{{ trans('auth.create_account') }}</button>
+                    </div>
+                </div>
+
+
+            </form>
 
-                @if(count($socialDrivers) > 0)
-                    <hr class="margin-top">
-                    @foreach($socialDrivers as $driver => $name)
-                        <a id="social-register-{{$driver}}" class="button block muted-light svg text-left" href="{{ baseUrl("/register/service/" . $driver) }}">
+            @if(count($socialDrivers) > 0)
+                <hr class="my-l">
+                @foreach($socialDrivers as $driver => $name)
+                    <div>
+                        <a id="social-register-{{$driver}}" class="button block outline svg text-left" href="{{ baseUrl("/register/service/" . $driver) }}">
                             @icon('auth/' . $driver)
                             {{ trans('auth.sign_up_with', ['socialDriver' => $name]) }}
                         </a>
-                    @endforeach
-                @endif
-            </div>
+                    </div>
+                @endforeach
+            @endif
         </div>
     </div>
-
-
 @stop
index b02d45d22e97f24c011e7ac891501cebb8c96d54..536397eaf06cfbf9daac2c585d2458ac408b4e07 100644 (file)
@@ -1,34 +1,34 @@
-@extends('public')
+@extends('simple-layout')
 
 @section('content')
 
-    <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('users') {{ trans('auth.email_not_confirmed') }}</h3>
-            <div class="body">
-                <p class="text-muted">{{ trans('auth.email_not_confirmed_text') }}<br>
-                    {{ trans('auth.email_not_confirmed_click_link') }} <br>
-                    {{ trans('auth.email_not_confirmed_resend') }}
-                </p>
-                <hr>
-                <form action="{{ baseUrl("/register/confirm/resend") }}" method="POST">
-                    {!! csrf_field() !!}
-                    <div class="form-group">
-                        <label for="email">{{ trans('auth.email') }}</label>
-                        @if(auth()->check())
-                            @include('form/text', ['name' => 'email', 'model' => auth()->user()])
-                        @else
-                            @include('form/text', ['name' => 'email'])
-                        @endif
-                    </div>
-                    <div class="form-group">
-                        <button type="submit" class="button pos">{{ trans('auth.email_not_confirmed_resend_button') }}</button>
-                    </div>
-                </form>
-            </div>
-        </div>
+    <div class="container very-small mt-xl">
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('auth.email_not_confirmed') }}</h1>
+
+            <p>{{ trans('auth.email_not_confirmed_text') }}<br>
+                {{ trans('auth.email_not_confirmed_click_link') }}
+            </p>
+            <p>
+                {{ trans('auth.email_not_confirmed_resend') }}
+            </p>
 
+            <form action="{{ baseUrl("/register/confirm/resend") }}" method="POST" class="stretch-inputs">
+                {!! csrf_field() !!}
+                <div class="form-group">
+                    <label for="email">{{ trans('auth.email') }}</label>
+                    @if(auth()->check())
+                        @include('form/text', ['name' => 'email', 'model' => auth()->user()])
+                    @else
+                        @include('form/text', ['name' => 'email'])
+                    @endif
+                </div>
+                <div class="form-group text-right mt-m">
+                    <button type="submit" class="button primary">{{ trans('auth.email_not_confirmed_resend_button') }}</button>
+                </div>
+            </form>
+
+        </div>
     </div>
 
 @stop
index fdd248091d9dfcf29ddd3d819f27c75daa63d597..bc139e17fa8c389f07ea79373c3ea893d52f29f3 100644 (file)
     <script src="{{ baseUrl('/translations') }}"></script>
 
     @yield('head')
-
-    @include('partials/custom-styles')
-
+    @include('partials.custom-styles')
     @include('partials.custom-head')
-</head>
-<body class="@yield('body-class')" ng-app="bookStack">
-
-    @include('partials/notifications')
 
-    <header id="header">
-        <div class="container fluid">
-            <div class="row">
-                <div class="col-sm-4 col-md-3">
-                    <a href="{{ baseUrl('/') }}" class="logo">
-                        @if(setting('app-logo', '') !== 'none')
-                            <img class="logo-image" src="{{ setting('app-logo', '') === '' ? baseUrl('/logo.png') : baseUrl(setting('app-logo', '')) }}" alt="Logo">
-                        @endif
-                        @if (setting('app-name-header'))
-                            <span class="logo-text">{{ setting('app-name') }}</span>
-                        @endif
-                    </a>
-                </div>
-                <div class="col-sm-8 col-md-9">
-                    <div class="float right">
-                        <div class="header-search">
-                            <form action="{{ baseUrl('/search') }}" method="GET" class="search-box">
-                                <button id="header-search-box-button" type="submit">@icon('search') </button>
-                                <input id="header-search-box-input" type="text" name="term" tabindex="2" placeholder="{{ trans('common.search') }}" value="{{ isset($searchTerm) ? $searchTerm : '' }}">
-                            </form>
-                        </div>
-                        <div class="links text-center">
-                            @if(userCanOnAny('view', \BookStack\Entities\Bookshelf::class) || userCan('bookshelf-view-own'))
-                                <a href="{{ baseUrl('/shelves') }}">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
-                            @endif
-                            <a href="{{ baseUrl('/books') }}">@icon('book'){{ trans('entities.books') }}</a>
-                            @if(signedInUser() && userCan('settings-manage'))
-                                <a href="{{ baseUrl('/settings') }}">@icon('settings'){{ trans('settings.settings') }}</a>
-                            @endif
-                            @if(signedInUser() && userCan('users-manage') && !userCan('settings-manage'))
-                                <a href="{{ baseUrl('/settings/users') }}">@icon('users'){{ trans('settings.users') }}</a>
-                            @endif
-                            @if(!signedInUser())
-                                @if(setting('registration-enabled', false))
-                                    <a href="{{ baseUrl("/register") }}">@icon('new-user') {{ trans('auth.sign_up') }}</a>
-                                @endif
-                                <a href="{{ baseUrl('/login') }}">@icon('login') {{ trans('auth.log_in') }}</a>
-                            @endif
-                        </div>
-                        @if(signedInUser())
-                            @include('partials._header-dropdown', ['currentUser' => user()])
-                        @endif
+</head>
+<body class="@yield('body-class')">
 
-                    </div>
-                </div>
-            </div>
-        </div>
-    </header>
+    @include('partials.notifications')
+    @include('common.header')
 
     <section id="content" class="block">
         @yield('content')
             @icon('chevron-up') <span>{{ trans('common.back_to_top') }}</span>
         </div>
     </div>
-@yield('bottom')
-<script src="{{ versioned_asset('dist/app.js') }}"></script>
-@yield('scripts')
+
+    @yield('bottom')
+    <script src="{{ versioned_asset('dist/app.js') }}"></script>
+    @yield('scripts')
+
 </body>
 </html>
index 2d5e6c4558ebfd37332316774777bcbfdfbea9db..db93c3d1ed32891e337b56cd658447a6d4539c20 100644 (file)
@@ -1,28 +1,27 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-8 faded">
-        <div class="breadcrumbs">
-            <a href="{{ baseUrl('/books') }}" class="text-button">@icon('book'){{ trans('entities.books') }}</a>
-            <span class="sep">&raquo;</span>
-            <a href="{{ baseUrl('/create-book') }}" class="text-button">@icon('add'){{ trans('entities.books_create') }}</a>
-        </div>
-    </div>
-@stop
-
 @section('body')
+    <div class="container small">
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                '/books' => [
+                    'text' => trans('entities.books'),
+                    'icon' => 'book'
+                ],
+                '/create-book' => [
+                    'text' => trans('entities.books_create'),
+                    'icon' => 'add'
+                ]
+            ]])
+        </div>
 
-<div class="container small">
-    <p>&nbsp;</p>
-    <div class="card">
-        <h3>@icon('add') {{ trans('entities.books_create') }}</h3>
-        <div class="body">
+        <div class="content-wrap card">
+            <h1 class="list-heading">{{ trans('entities.books_create') }}</h1>
             <form action="{{ baseUrl("/books") }}" method="POST" enctype="multipart/form-data">
                 @include('books/form')
             </form>
         </div>
     </div>
-</div>
-<p class="margin-top large"><br></p>
+
     @include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index 0ac98e8956708babedacff60b39abf207e9aa3c8..2860e8bcdf15a63dbb2dec9cee399c4f39020ea0 100644 (file)
@@ -1,28 +1,30 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('books._breadcrumbs', ['book' => $book])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ trans('entities.books_delete') }}</h3>
-            <div class="body">
-                <p>{{ trans('entities.books_delete_explain', ['bookName' => $book->name]) }}</p>
-                <p class="text-neg">{{ trans('entities.books_delete_confirmation') }}</p>
 
-                <form action="{{$book->getUrl()}}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="DELETE">
-                    <a href="{{$book->getUrl()}}" class="button outline">{{ trans('common.cancel') }}</a>
-                    <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
-                </form>
-            </div>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $book->getUrl('/delete') => [
+                    'text' => trans('entities.books_delete'),
+                    'icon' => 'delete',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('entities.books_delete') }}</h1>
+            <p>{{ trans('entities.books_delete_explain', ['bookName' => $book->name]) }}</p>
+            <p class="text-neg"><strong>{{ trans('entities.books_delete_confirmation') }}</strong></p>
+
+            <form action="{{$book->getUrl()}}" method="POST" class="text-right">
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="DELETE">
+                <a href="{{$book->getUrl()}}" class="button outline">{{ trans('common.cancel') }}</a>
+                <button type="submit" class="button primary">{{ trans('common.confirm') }}</button>
+            </form>
         </div>
 
     </div>
index cb1ffc461035eab044f670583b196a0dbe4dbfbb..caeae9175d021d8646e75cd54ae67329dbbce180 100644 (file)
@@ -1,24 +1,27 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('books._breadcrumbs', ['book' => $book])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('edit') {{ trans('entities.books_edit') }}</h3>
-            <div class="body">
-                <form action="{{ $book->getUrl() }}" method="POST">
-                    <input type="hidden" name="_method" value="PUT">
-                    @include('books/form', ['model' => $book])
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $book->getUrl('/edit') => [
+                    'text' => trans('entities.books_edit'),
+                    'icon' => 'edit',
+                ]
+            ]])
+        </div>
+
+        <div class="content-wrap card">
+            <h1 class="list-heading">{{ trans('entities.books_edit') }}</h1>
+            <form action="{{ $book->getUrl() }}" method="POST">
+                <input type="hidden" name="_method" value="PUT">
+                @include('books/form', ['model' => $book])
+            </form>
         </div>
     </div>
-@include('components.image-manager', ['imageType' => 'cover'])
+
+    @include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index bf94b5b076ed189a3dc723ad6ce5013522daf049..97ddd9681341284d7323a50cc506bf52c5cf5f09 100644 (file)
@@ -41,5 +41,5 @@
 
 <div class="form-group text-right">
     <a href="{{ isset($book) ? $book->getUrl() : baseUrl('/books') }}" class="button outline">{{ trans('common.cancel') }}</a>
-    <button type="submit" class="button pos">{{ trans('entities.books_save') }}</button>
+    <button type="submit" class="button primary">{{ trans('entities.books_save') }}</button>
 </div>
\ No newline at end of file
index 9bbf691006822cdd4935dc6c9f46c3b93c850e5c..e1d37753a12afef67aeb527fff0d23c809cdb176 100644 (file)
@@ -1,18 +1,19 @@
-<div class="book-grid-item grid-card"  data-entity-type="book" data-entity-id="{{$book->id}}">
-    <div class="featured-image-container">
-        <a href="{{$book->getUrl()}}" title="{{$book->name}}">
-            <img src="{{$book->getBookCover()}}" alt="{{$book->name}}">
-        </a>
+<a href="{{$book->getUrl()}}" class="grid-card"  data-entity-type="book" data-entity-id="{{$book->id}}">
+    <div class="bg-book featured-image-container-wrap">
+        <div class="featured-image-container" @if($book->cover) style="background-image: url('{{ $book->getBookCover() }}')"@endif>
+        </div>
+        @icon('book')
     </div>
     <div class="grid-card-content">
-        <h2><a class="break-text" href="{{$book->getUrl()}}" title="{{$book->name}}">{{$book->getShortName(35)}}</a></h2>
+        <h2>{{$book->getShortName(35)}}</h2>
         @if(isset($book->searchSnippet))
-            <p >{!! $book->searchSnippet !!}</p>
+            <p class="text-muted">{!! $book->searchSnippet !!}</p>
         @else
-            <p >{{ $book->getExcerpt(130) }}</p>
+            <p class="text-muted">{{ $book->getExcerpt(130) }}</p>
         @endif
     </div>
-    <div class="grid-card-footer text-muted text-small">
-        <span>@include('partials.entity-meta', ['entity' => $book])</span>
+    <div class="grid-card-footer text-muted ">
+        <p>@icon('star')<span title="{{$book->created_at->toDayDateTimeString()}}">{{ trans('entities.meta_created', ['timeLength' => $book->created_at->diffForHumans()]) }}</span></p>
+        <p>@icon('edit')<span title="{{ $book->updated_at->toDayDateTimeString() }}">{{ trans('entities.meta_updated', ['timeLength' => $book->updated_at->diffForHumans()]) }}</span></p>
     </div>
-</div>
\ No newline at end of file
+</a>
\ No newline at end of file
index 84150203f081e2345f466a0f0b3399da3acb2298..e106b37041abffbf19036233b320fe73fd8aabf1 100644 (file)
@@ -1,41 +1,28 @@
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-xs-6">
-        <div class="action-buttons text-left">
-            @include('books/view-toggle', ['booksViewType' => $booksViewType])
-        </div>
-    </div>
-    <div class="col-xs-6 faded">
-        <div class="action-buttons">
-            @if($currentUser->can('book-create-all'))
-                <a href="{{ baseUrl("/create-book") }}" class="text-pos text-button">@icon('add'){{ trans('entities.books_create') }}</a>
-            @endif
-        </div>
-    </div>
-@stop
+@section('container-classes', 'mt-xl')
 
-@section('sidebar')
+@section('left')
     @if($recents)
-        <div id="recents" class="card">
-            <h3>@icon('view') {{ trans('entities.recently_viewed') }}</h3>
-            @include('partials/entity-list', ['entities' => $recents, 'style' => 'compact'])
+        <div id="recents" class="mb-xl">
+            <h5>{{ trans('entities.recently_viewed') }}</h5>
+            @include('partials.entity-list', ['entities' => $recents, 'style' => 'compact'])
         </div>
     @endif
 
-    <div id="popular" class="card">
-        <h3>@icon('popular') {{ trans('entities.books_popular') }}</h3>
+    <div id="popular" class="mb-xl">
+        <h5>{{ trans('entities.books_popular') }}</h5>
         @if(count($popular) > 0)
-            @include('partials/entity-list', ['entities' => $popular, 'style' => 'compact'])
+            @include('partials.entity-list', ['entities' => $popular, 'style' => 'compact'])
         @else
             <div class="body text-muted">{{ trans('entities.books_popular_empty') }}</div>
         @endif
     </div>
 
-    <div id="new" class="card">
-        <h3>@icon('star-circle') {{ trans('entities.books_new') }}</h3>
+    <div id="new" class="mb-xl">
+        <h5>{{ trans('entities.books_new') }}</h5>
         @if(count($popular) > 0)
-            @include('partials/entity-list', ['entities' => $new, 'style' => 'compact'])
+            @include('partials.entity-list', ['entities' => $new, 'style' => 'compact'])
         @else
             <div class="body text-muted">{{ trans('entities.books_new_empty') }}</div>
         @endif
 @stop
 
 @section('body')
-    @include('books/list', ['books' => $books, 'bookViewType' => $booksViewType])
+    @include('books.list', ['books' => $books, 'view' => $view])
+@stop
+
+@section('right')
+
+    <div class="actions mb-xl">
+        <h5>{{ trans('common.actions') }}</h5>
+        <div class="icon-list text-primary">
+            @include('partials.view-toggle', ['view' => $view, 'type' => 'book'])
+            @if($currentUser->can('book-create-all'))
+                <a href="{{ baseUrl("/create-book") }}" class="icon-list-item">
+                    <span>@icon('add')</span>
+                    <span>{{ trans('entities.books_create') }}</span>
+                </a>
+            @endif
+        </div>
+    </div>
+
 @stop
\ No newline at end of file
index 05d7e90ef73a9846a8ba7bb48ddc6b50bc6cf951..17cf4c71f9878117471b6afef38f3eccff615331 100644 (file)
@@ -1,10 +1,11 @@
-<div class="book entity-list-item"  data-entity-type="book" data-entity-id="{{$book->id}}">
-    <h4 class="text-book"><a class="text-book entity-list-item-link" href="{{$book->getUrl()}}">@icon('book')<span class="entity-list-item-name break-text">{{$book->name}}</span></a></h4>
-    <div class="entity-item-snippet">
-        @if(isset($book->searchSnippet))
-            <p class="text-muted break-text">{!! $book->searchSnippet !!}</p>
-        @else
-            <p class="text-muted break-text">{{ $book->getExcerpt() }}</p>
-        @endif
+<a href="{{ $book->getUrl() }}" class="book entity-list-item" data-entity-type="book" data-entity-id="{{$book->id}}">
+    <div class="entity-list-item-image bg-book" style="background-image: url('{{ $book->getBookCover() }}')">
+        @icon('book')
     </div>
-</div>
\ No newline at end of file
+    <div class="content">
+        <h4 class="entity-list-item-name break-text">{{ $book->name }}</h4>
+        <div class="entity-item-snippet">
+            <p class="text-muted break-text mb-s">{{ $book->getExcerpt() }}</p>
+        </div>
+    </div>
+</a>
\ No newline at end of file
index 9459cc0088b9864c6badfa5a44246565b47e84ab..6e0cc1fd6205be6949f14623b6d8052febe56cf7 100644 (file)
@@ -1,23 +1,30 @@
 
-<div class="container{{ $booksViewType === 'list' ? ' small' : '' }}">
-    <h1>{{ trans('entities.books') }}</h1>
+<div class="content-wrap card">
+    <div class="grid half v-center">
+        <h1 class="list-heading">{{ trans('entities.books') }}</h1>
+        <div class="text-right">
+
+            @include('partials.sort', ['options' => $sortOptions, 'order' => $order, 'sort' => $sort, 'type' => 'books'])
+
+        </div>
+    </div>
     @if(count($books) > 0)
-        @if($booksViewType === 'list')
-            @foreach($books as $book)
-                @include('books/list-item', ['book' => $book])
-                <hr>
-            @endforeach
-            {!! $books->render() !!}
+        @if($view === 'list')
+            <div class="entity-list">
+                @foreach($books as $book)
+                    @include('books.list-item', ['book' => $book])
+                @endforeach
+            </div>
         @else
              <div class="grid third">
                 @foreach($books as $key => $book)
-                        @include('books/grid-item', ['book' => $book])
+                    @include('books.grid-item', ['book' => $book])
                 @endforeach
              </div>
-            <div>
-                {!! $books->render() !!}
-            </div>
         @endif
+        <div>
+            {!! $books->render() !!}
+        </div>
     @else
         <p class="text-muted">{{ trans('entities.books_empty') }}</p>
         @if(userCan('books-create-all'))
diff --git a/resources/views/books/permissions.blade.php b/resources/views/books/permissions.blade.php
new file mode 100644 (file)
index 0000000..64322cf
--- /dev/null
@@ -0,0 +1,23 @@
+@extends('simple-layout')
+
+@section('body')
+
+    <div class="container">
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $book->getUrl('/permissions') => [
+                    'text' => trans('entities.books_permissions'),
+                    'icon' => 'lock',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.books_permissions') }}</h1>
+            @include('form.entity-permissions', ['model' => $book])
+        </div>
+    </div>
+
+@stop
diff --git a/resources/views/books/restrictions.blade.php b/resources/views/books/restrictions.blade.php
deleted file mode 100644 (file)
index 2a6eb0b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-@extends('simple-layout')
-
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('books._breadcrumbs', ['book' => $book])
-    </div>
-@stop
-
-@section('body')
-
-    <div class="container">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('lock') {{ trans('entities.books_permissions') }}</h3>
-            <div class="body">
-                @include('form/restriction-form', ['model' => $book])
-            </div>
-        </div>
-    </div>
-
-@stop
index e5845b4956ba0b9db8a3349dd613f5342f8d83e8..3a4a2c1928fe092720e679d82b30f9a2e9258837 100644 (file)
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-sm-6 col-xs-1  faded">
-        @include('books._breadcrumbs', ['book' => $book])
+@section('container-attrs')
+    id="entity-dashboard"
+    entity-id="{{ $book->id }}"
+    entity-type="book"
+@stop
+
+@section('body')
+
+    <div class="mb-s">
+        @include('partials.breadcrumbs', ['crumbs' => [
+            $book,
+        ]])
+    </div>
+
+    <div class="content-wrap card">
+        <h1 class="break-text" v-pre>{{$book->name}}</h1>
+        <div class="book-content" v-show="!searching">
+            <p class="text-muted" v-pre>{!! nl2br(e($book->description)) !!}</p>
+            @if(count($bookChildren) > 0)
+                <div class="entity-list book-contents" v-pre>
+                    @foreach($bookChildren as $childElement)
+                        @if($childElement->isA('chapter'))
+                            @include('chapters.list-item', ['chapter' => $childElement])
+                        @else
+                            @include('pages.list-item', ['page' => $childElement])
+                        @endif
+                    @endforeach
+                </div>
+            @else
+                <div class="well">
+                    {{--TODO--}}
+                    <p class="text-muted italic">{{ trans('entities.books_empty_contents') }}</p>
+                    @if(userCan('page-create', $book))
+                        <a href="{{ $book->getUrl('/create-page') }}" class="button outline page">@icon('page'){{ trans('entities.books_empty_create_page') }}</a>
+                    @endif
+                    @if(userCan('page-create', $book) && userCan('chapter-create', $book))
+                        &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
+                    @endif
+                    @if(userCan('chapter-create', $book))
+                        <a href="{{ $book->getUrl('/create-chapter') }}" class="button outline chapter">@icon('chapter'){{ trans('entities.books_empty_add_chapter') }}</a>
+                    @endif
+                </div>
+            @endif
+        </div>
+
+        <div class="search-results" v-cloak v-show="searching">
+            {{--TODO--}}
+            <h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small">@icon('close'){{ trans('entities.search_clear') }}</a></h3>
+            <div v-if="!searchResults">
+                @include('partials.loading-icon')
+            </div>
+            <div v-html="searchResults"></div>
+        </div>
     </div>
-    <div class="col-sm-6 col-xs-11">
-        <div class="action-buttons faded">
-            <span dropdown class="dropdown-container">
-                <div dropdown-toggle class="text-button text-primary">@icon('export'){{ trans('entities.export') }}</div>
+
+@stop
+
+
+@section('right')
+
+    <div class="actions mb-xl">
+        <h5>{{ trans('common.actions') }}</h5>
+        <div class="icon-list text-primary">
+            <div dropdown class="dropdown-container">
+                <div dropdown-toggle class="icon-list-item">
+                    <span>@icon('export')</span>
+                    <span>{{ trans('entities.export') }}</span>
+                </div>
                 <ul class="wide">
                     <li><a href="{{ $book->getUrl('/export/html') }}" target="_blank">{{ trans('entities.export_html') }} <span class="text-muted float right">.html</span></a></li>
                     <li><a href="{{ $book->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.export_pdf') }} <span class="text-muted float right">.pdf</span></a></li>
                     <li><a href="{{ $book->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.export_text') }} <span class="text-muted float right">.txt</span></a></li>
                 </ul>
-            </span>
+            </div>
+
             @if(userCan('page-create', $book))
-                <a href="{{ $book->getUrl('/create-page') }}" class="text-pos text-button">@icon('add'){{ trans('entities.pages_new') }}</a>
+                <a href="{{ $book->getUrl('/create-page') }}" class="icon-list-item">
+                    <span>@icon('add')</span>
+                    <span>{{ trans('entities.pages_new') }}</span>
+                </a>
             @endif
             @if(userCan('chapter-create', $book))
-                <a href="{{ $book->getUrl('/create-chapter') }}" class="text-pos text-button">@icon('add'){{ trans('entities.chapters_new') }}</a>
+                <a href="{{ $book->getUrl('/create-chapter') }}" class="icon-list-item">
+                    <span>@icon('add')</span>
+                    <span>{{ trans('entities.chapters_new') }}</span>
+                </a>
             @endif
-            @if(userCan('book-update', $book) || userCan('restrictions-manage', $book) || userCan('book-delete', $book))
-                <div dropdown class="dropdown-container">
-                    <a dropdown-toggle class="text-primary text-button">@icon('more'){{ trans('common.more') }}</a>
-                    <ul>
-                        @if(userCan('book-update', $book))
-                            <li><a href="{{ $book->getUrl('/edit') }}" class="text-primary">@icon('edit'){{ trans('common.edit') }}</a></li>
-                            <li><a href="{{ $book->getUrl('/sort') }}" class="text-primary">@icon('sort'){{ trans('common.sort') }}</a></li>
-                        @endif
-                        @if(userCan('restrictions-manage', $book))
-                            <li><a href="{{ $book->getUrl('/permissions') }}" class="text-primary">@icon('lock'){{ trans('entities.permissions') }}</a></li>
-                        @endif
-                        @if(userCan('book-delete', $book))
-                            <li><a href="{{ $book->getUrl('/delete') }}" class="text-neg">@icon('delete'){{ trans('common.delete') }}</a></li>
-                        @endif
-                    </ul>
-                </div>
+            @if(userCan('book-update', $book))
+                <a href="{{ $book->getUrl('/edit') }}" class="icon-list-item">
+                    <span>@icon('edit')</span>
+                    <span>{{ trans('common.edit') }}</span>
+                </a>
+                <a href="{{ $book->getUrl('/sort') }}" class="icon-list-item">
+                    <span>@icon('sort')</span>
+                    <span>{{ trans('common.sort') }}</span>
+                </a>
+            @endif
+            @if(userCan('restrictions-manage', $book))
+                <a href="{{ $book->getUrl('/permissions') }}" class="icon-list-item">
+                    <span>@icon('lock')</span>
+                    <span>{{ trans('entities.permissions') }}</span>
+                </a>
+            @endif
+            @if(userCan('book-delete', $book))
+                <a href="{{ $book->getUrl('/delete') }}" class="icon-list-item">
+                    <span>@icon('delete')</span>
+                    <span>{{ trans('common.delete') }}</span>
+                </a>
             @endif
         </div>
     </div>
+
 @stop
 
-@section('sidebar')
+@section('left')
 
     @if($book->tags->count() > 0)
-        <section>
+        <div class="mb-xl">
             @include('components.tag-list', ['entity' => $book])
-        </section>
+        </div>
     @endif
 
-    <div class="card">
-        <div class="body">
-            <form v-on:submit.prevent="searchBook" class="search-box">
-                <input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
-                <button type="submit">@icon('search')</button>
-                <button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button">@icon('close')</button>
-            </form>
-        </div>
+    <div class="mb-xl">
+        <form v-on:submit.prevent="searchBook" class="search-box">
+            <input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
+            <button type="submit">@icon('search')</button>
+            <button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button">@icon('close')</button>
+        </form>
     </div>
 
-    <div class="card entity-details">
-        <h3>@icon('info') {{ trans('common.details') }}</h3>
-        <div class="body text-small text-muted blended-links">
+    <div class="mb-xl">
+        <h5>{{ trans('common.details') }}</h5>
+        <div class="text-small text-muted blended-links">
             @include('partials.entity-meta', ['entity' => $book])
             @if($book->restricted)
                 <div class="active-restriction">
     </div>
 
     @if(count($activity) > 0)
-        <div class="activity card">
-            <h3>@icon('time') {{ trans('entities.recent_activity') }}</h3>
-            @include('partials/activity-list', ['activity' => $activity])
+        <div class="mb-xl">
+            <h5>{{ trans('entities.recent_activity') }}</h5>
+            @include('partials.activity-list', ['activity' => $activity])
         </div>
     @endif
 @stop
 
-@section('container-attrs')
-    id="entity-dashboard"
-    entity-id="{{ $book->id }}"
-    entity-type="book"
-@stop
-
-@section('body')
-
-    <div class="container small nopad">
-        <h1 class="break-text" v-pre>{{$book->name}}</h1>
-        <div class="book-content" v-show="!searching">
-            <p class="text-muted" v-pre>{!! nl2br(e($book->description)) !!}</p>
-            @if(count($bookChildren) > 0)
-            <div class="page-list" v-pre>
-                <hr>
-                @foreach($bookChildren as $childElement)
-                    @if($childElement->isA('chapter'))
-                        @include('chapters/list-item', ['chapter' => $childElement])
-                    @else
-                        @include('pages/list-item', ['page' => $childElement])
-                    @endif
-                    <hr>
-                @endforeach
-            </div>
-            @else
-                <div class="well">
-                    <p class="text-muted italic">{{ trans('entities.books_empty_contents') }}</p>
-                        @if(userCan('page-create', $book))
-                            <a href="{{ $book->getUrl('/create-page') }}" class="button outline page">@icon('page'){{ trans('entities.books_empty_create_page') }}</a>
-                        @endif
-                        @if(userCan('page-create', $book) && userCan('chapter-create', $book))
-                            &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
-                        @endif
-                        @if(userCan('chapter-create', $book))
-                            <a href="{{ $book->getUrl('/create-chapter') }}" class="button outline chapter">@icon('chapter'){{ trans('entities.books_empty_add_chapter') }}</a>
-                        @endif
-                </div>
-            @endif
-
-        </div>
-        <div class="search-results" v-cloak v-show="searching">
-            <h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small">@icon('close'){{ trans('entities.search_clear') }}</a></h3>
-            <div v-if="!searchResults">
-                @include('partials/loading-icon')
-            </div>
-            <div v-html="searchResults"></div>
-        </div>
-    </div>
-
-@stop
index cff3c8984384b878096ca74798dd61cdbfe5db72..98f0af87eeeaa711408a6c010956bb68d9c273a3 100644 (file)
@@ -1,20 +1,48 @@
 <div class="sort-box" data-type="book" data-id="{{ $book->id }}">
-    <h3 class="text-book">@icon('book'){{ $book->name }}</h3>
+    <h5 class="text-book entity-list-item no-hover py-xs pl-none">
+        <span>@icon('book')</span>
+        <span>{{ $book->name }}</span>
+    </h5>
+    <div class="sort-box-options pb-sm">
+        <a href="#" data-sort="name" class="button outline small">{{ trans('entities.books_sort_name') }}</a>
+        <a href="#" data-sort="created" class="button outline small">{{ trans('entities.books_sort_created') }}</a>
+        <a href="#" data-sort="updated" class="button outline small">{{ trans('entities.books_sort_updated') }}</a>
+        <a href="#" data-sort="chaptersFirst" class="button outline small">{{ trans('entities.books_sort_chapters_first') }}</a>
+        <a href="#" data-sort="chaptersLast" class="button outline small">{{ trans('entities.books_sort_chapters_last') }}</a>
+    </div>
     <ul class="sortable-page-list sort-list">
+
         @foreach($bookChildren as $bookChild)
-            <li data-id="{{$bookChild->id}}" data-type="{{ $bookChild->getClassName() }}" class="text-{{ $bookChild->getClassName() }}">
-                @icon($bookChild->isA('chapter') ? 'chapter' : 'page'){{ $bookChild->name }}
+            <li class="text-{{ $bookChild->getClassName() }}"
+                data-id="{{$bookChild->id}}" data-type="{{ $bookChild->getClassName() }}"
+                data-name="{{ $bookChild->name }}" data-created="{{ $bookChild->created_at->timestamp }}"
+                data-updated="{{ $bookChild->updated_at->timestamp }}">
+                <div class="entity-list-item">
+                    <span>@icon($bookChild->getType()) </span>
+                    <div>
+                        {{ $bookChild->name }}
+                        <div>
+
+                        </div>
+                    </div>
+                </div>
                 @if($bookChild->isA('chapter'))
                     <ul>
                         @foreach($bookChild->pages as $page)
-                            <li data-id="{{$page->id}}" class="text-page" data-type="page">
-                                @icon('page')
-                                {{ $page->name }}
+                            <li class="text-page"
+                                data-id="{{$page->id}}" data-type="page"
+                                data-name="{{ $page->name }}" data-created="{{ $page->created_at->timestamp }}"
+                                data-updated="{{ $page->updated_at->timestamp }}">
+                                <div class="entity-list-item">
+                                    <span>@icon('page')</span>
+                                    <span>{{ $page->name }}</span>
+                                </div>
                             </li>
                         @endforeach
                     </ul>
                 @endif
             </li>
         @endforeach
+
     </ul>
 </div>
\ No newline at end of file
index 77e95448f37292c40593257a342f8ca317bb2c11..771a68fcbc2ce2504f574df0daa7366e608d921a 100644 (file)
@@ -1,53 +1,59 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('books._breadcrumbs', ['book' => $book])
-    </div>
-@stop
+{{--TODO - Load books in via selector interface--}}
 
 @section('body')
 
     <div class="container">
 
-        <div class="row">
-            <div class="col-md-8">
-                <div class="card">
-                    <h3>@icon('sort') {{ trans('entities.books_sort') }}</h3>
-                    <div class="body">
-                        <div id="sort-boxes">
-                            @include('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren])
-                        </div>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $book->getUrl('/sort') => [
+                    'text' => trans('entities.books_sort'),
+                    'icon' => 'sort',
+                ]
+            ]])
+        </div>
 
-                        <form action="{{ $book->getUrl('/sort') }}" method="POST">
-                            {!! csrf_field() !!}
-                            <input type="hidden" name="_method" value="PUT">
-                            <input type="hidden" id="sort-tree-input" name="sort-tree">
-                            <div class="list">
-                                <a href="{{ $book->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                                <button class="button pos" type="submit">{{ trans('entities.books_sort_save') }}</button>
-                            </div>
-                        </form>
+        <div class="grid left-focus large-gap">
+            <div>
+                <div class="card content-wrap">
+                    <h1 class="list-heading">{{ trans('entities.books_sort') }}</h1>
+                    <div id="sort-boxes">
+                        @include('books.sort-box', ['book' => $book, 'bookChildren' => $bookChildren])
                     </div>
+
+                    <form action="{{ $book->getUrl('/sort') }}" method="POST">
+                        {!! csrf_field() !!}
+                        <input type="hidden" name="_method" value="PUT">
+                        <input type="hidden" id="sort-tree-input" name="sort-tree">
+                        <div class="list text-right">
+                            <a href="{{ $book->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
+                            <button class="button primary" type="submit">{{ trans('entities.books_sort_save') }}</button>
+                        </div>
+                    </form>
                 </div>
             </div>
-            @if(count($books) > 1)
-            <div class="col-md-4">
-                <div class="card">
-                    <h3>@icon('book') {{ trans('entities.books_sort_show_other') }}</h3>
-                    <div class="body" id="additional-books">
-                        @foreach($books as $otherBook)
-                            @if($otherBook->id !== $book->id)
-                                <div>
-                                    <a href="{{ $otherBook->getUrl('/sort-item') }}" class="text-book">@icon('book'){{ $otherBook->name }}</a>
-                                </div>
-                            @endif
-                        @endforeach
+
+            <div>
+                @if(count($books) > 1)
+                    <div class="card content-wrap">
+                        <h2 class="list-heading">{{ trans('entities.books_sort_show_other') }}</h2>
+                        <div id="additional-books">
+                            @foreach($books as $otherBook)
+                                @if($otherBook->id !== $book->id)
+                                    <div>
+                                        <a href="{{ $otherBook->getUrl('/sort-item') }}" class="text-book">@icon('book'){{ $otherBook->name }}</a>
+                                    </div>
+                                @endif
+                            @endforeach
+                        </div>
                     </div>
-                </div>
+                @endif
             </div>
-            @endif
         </div>
+
     </div>
 
 @stop
     <script>
         $(document).ready(function() {
 
-            var sortableOptions = {
+            const $container = $('#sort-boxes');
+
+            // Sortable options
+            const sortableOptions = {
                 group: 'serialization',
-                onDrop: function($item, container, _super) {
-                    var pageMap = buildEntityMap();
-                    $('#sort-tree-input').val(JSON.stringify(pageMap));
+                containerSelector: 'ul',
+                itemPath: '',
+                itemSelector: 'li',
+                onDrop: function ($item, container, _super) {
+                    updateMapInput();
                     _super($item, container);
                 },
-                isValidTarget: function  ($item, container) {
+                isValidTarget: function ($item, container) {
                     // Prevent nested chapters
-                    return !($item.is('[data-type="chapter"]') && container.target.closest('li').attr('data-type') == 'chapter');
+                    return !($item.is('[data-type="chapter"]') && container.target.closest('li').attr('data-type') === 'chapter');
                 }
             };
 
-            var group = $('.sort-list').sortable(sortableOptions);
+            // Create our sortable group
+            let group = $('.sort-list').sortable(sortableOptions);
 
+            // Add additional books into the view on select.
             $('#additional-books').on('click', 'a', function(e) {
                 e.preventDefault();
-                var $link = $(this);
-                var url = $link.attr('href');
+
+                const $link = $(this);
+                const url = $link.attr('href');
                 $.get(url, function(data) {
-                    $('#sort-boxes').append(data);
+                    $container.append(data);
                     group.sortable("destroy");
-                    $('.sort-list').sortable(sortableOptions);
+                    group = $('.sort-list').sortable(sortableOptions);
                 });
                 $link.remove();
             });
 
+            /**
+             * Update the input with our sort data.
+             */
+            function updateMapInput() {
+                const pageMap = buildEntityMap();
+                $('#sort-tree-input').val(JSON.stringify(pageMap));
+            }
+
             /**
              * Build up a mapping of entities with their ordering and nesting.
              * @returns {Array}
              */
             function buildEntityMap() {
-                var entityMap = [];
-                var $lists = $('.sort-list');
+                const entityMap = [];
+                const $lists = $('.sort-list');
                 $lists.each(function(listIndex) {
-                    var list = $(this);
-                    var bookId = list.closest('[data-type="book"]').attr('data-id');
-                    var $directChildren = list.find('> [data-type="page"], > [data-type="chapter"]');
+                    const $list = $(this);
+                    const bookId = $list.closest('[data-type="book"]').attr('data-id');
+                    const $directChildren = $list.find('> [data-type="page"], > [data-type="chapter"]');
                     $directChildren.each(function(directChildIndex) {
-                        var $childElem = $(this);
-                        var type = $childElem.attr('data-type');
-                        var parentChapter = false;
-                        var childId = $childElem.attr('data-id');
+                        const $childElem = $(this);
+                        const type = $childElem.attr('data-type');
+                        const parentChapter = false;
+                        const childId = $childElem.attr('data-id');
+
                         entityMap.push({
                             id: childId,
                             sort: directChildIndex,
                             type: type,
                             book: bookId
                         });
-                        $chapterChildren = $childElem.find('[data-type="page"]').each(function(pageIndex) {
-                            var $chapterChild = $(this);
+
+                        $childElem.find('[data-type="page"]').each(function(pageIndex) {
+                            const $chapterChild = $(this);
                             entityMap.push({
                                 id: $chapterChild.attr('data-id'),
                                 sort: pageIndex,
                                 book: bookId
                             });
                         });
+
                     });
                 });
                 return entityMap;
             }
 
+
+            // Auto sort control
+            const sortOperations = {
+                name: function(a, b) {
+                    const aName = a.getAttribute('data-name').trim().toLowerCase();
+                    const bName = b.getAttribute('data-name').trim().toLowerCase();
+                    return aName.localeCompare(bName);
+                },
+                created: function(a, b) {
+                    const aTime = Number(a.getAttribute('data-created'));
+                    const bTime = Number(b.getAttribute('data-created'));
+                    return bTime - aTime;
+                },
+                updated: function(a, b) {
+                    const aTime = Number(a.getAttribute('data-update'));
+                    const bTime = Number(b.getAttribute('data-update'));
+                    return bTime - aTime;
+                },
+                chaptersFirst: function(a, b) {
+                    const aType = a.getAttribute('data-type');
+                    const bType = b.getAttribute('data-type');
+                    if (aType === bType) {
+                        return 0;
+                    }
+                    return (aType === 'chapter' ? -1 : 1);
+                },
+                chaptersLast: function(a, b) {
+                    const aType = a.getAttribute('data-type');
+                    const bType = b.getAttribute('data-type');
+                    if (aType === bType) {
+                        return 0;
+                    }
+                    return (aType === 'chapter' ? 1 : -1);
+                },
+            };
+
+            let lastSort = '';
+            let reverse = false;
+            const reversableTypes = ['name', 'created', 'updated'];
+
+            $container.on('click', '.sort-box-options [data-sort]', function(event) {
+                event.preventDefault();
+                const $sortLists = $(this).closest('.sort-box').find('ul');
+                const sort = $(this).attr('data-sort');
+
+                reverse = (lastSort === sort) ? !reverse : false;
+                let sortFunction = sortOperations[sort];
+                if (reverse && reversableTypes.includes(sort)) {
+                   sortFunction = function(a, b) {
+                       return 0 - sortOperations[sort](a, b)
+                   };
+                }
+
+                $sortLists.each(function() {
+                    const $list = $(this);
+                    $list.children('li').sort(sortFunction).appendTo($list);
+                });
+
+                lastSort = sort;
+                updateMapInput();
+            });
+
         });
     </script>
 @stop
diff --git a/resources/views/books/view-toggle.blade.php b/resources/views/books/view-toggle.blade.php
deleted file mode 100644 (file)
index 63eb9b9..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<form action="{{ baseUrl("/settings/users/{$currentUser->id}/switch-book-view") }}" method="POST" class="inline">
-    {!! csrf_field() !!}
-    {!! method_field('PATCH') !!}
-    <input type="hidden" value="{{ $booksViewType === 'list'? 'grid' : 'list' }}" name="view_type">
-    @if ($booksViewType === 'list')
-        <button type="submit" class="text-pos text-button">@icon('grid'){{ trans('common.grid_view') }}</button>
-    @else
-        <button type="submit" class="text-pos text-button">@icon('list'){{ trans('common.list_view') }}</button>
-    @endif
-</form>
\ No newline at end of file
diff --git a/resources/views/chapters/_breadcrumbs.blade.php b/resources/views/chapters/_breadcrumbs.blade.php
deleted file mode 100644 (file)
index 279f1c1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<div class="breadcrumbs">
-    @if (userCan('view', $chapter->book))
-    <a href="{{ $chapter->book->getUrl() }}" class="text-book text-button">@icon('book'){{ $chapter->book->getShortName() }}</a>
-    <span class="sep">&raquo;</span>
-    @endif
-    <a href="{{ $chapter->getUrl() }}" class="text-chapter text-button">@icon('chapter'){{$chapter->getShortName()}}</a>
-</div>
\ No newline at end of file
diff --git a/resources/views/chapters/child-menu.blade.php b/resources/views/chapters/child-menu.blade.php
new file mode 100644 (file)
index 0000000..36c7f9a
--- /dev/null
@@ -0,0 +1,12 @@
+<div class="chapter-child-menu">
+    <p chapter-toggle class="text-muted @if($bookChild->matchesOrContains($current)) open @endif">
+        @icon('caret-right') @icon('page') <span>{{ trans_choice('entities.x_pages', $bookChild->pages->count()) }}</span>
+    </p>
+    <ul class="sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
+        @foreach($bookChild->pages as $childPage)
+            <li class="list-item-page {{ $childPage->isA('page') && $childPage->draft ? 'draft' : '' }}">
+                @include('partials.entity-list-item-basic', ['entity' => $childPage, 'classes' => $current->matches($childPage)? 'selected' : '' ])
+            </li>
+        @endforeach
+    </ul>
+</div>
\ No newline at end of file
index 765756055c2392008698ed932ebad4cc7acd271c..8953eb0ccac6528b024f9f4d2fe7da3f4db214c2 100644 (file)
@@ -1,26 +1,24 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        <div class="breadcrumbs">
-            <a href="{{ $book->getUrl() }}" class="text-book text-button">@icon('book'){{ $book->getShortName() }}</a>
-            <span class="sep">&raquo;</span>
-            <a href="{{ $book->getUrl('/create-chapter')}}" class="text-button">@icon('add'){{ trans('entities.chapters_create') }}</a>
-        </div>
-    </div>
-@stop
-
 @section('body')
-
     <div class="container small">
-        <div class="card">
-            <h3>@icon('add') {{ trans('entities.chapters_create') }}</h3>
-            <div class="body">
-                <form action="{{ $book->getUrl('/create-chapter') }}" method="POST">
-                    @include('chapters/form')
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $book->getUrl('create-chapter') => [
+                    'text' => trans('entities.chapters_create'),
+                    'icon' => 'add',
+                ]
+            ]])
+        </div>
+
+        <div class="content-wrap card">
+            <h1 class="list-heading">{{ trans('entities.chapters_create') }}</h1>
+            <form action="{{ $book->getUrl('/create-chapter') }}" method="POST">
+                @include('chapters/form')
+            </form>
         </div>
-    </div>
 
+    </div>
 @stop
\ No newline at end of file
index 727b4c9bb2b1771b62ec631f54670cf04b6f22d9..3444ee0fb19271f242352621d4c5ea3cd5799607 100644 (file)
@@ -1,29 +1,35 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('chapters._breadcrumbs', ['chapter' => $chapter])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ trans('entities.chapters_delete') }}</h3>
 
-            <div class="body">
-                <p>{{ trans('entities.chapters_delete_explain', ['chapterName' => $chapter->name]) }}</p>
-                <p class="text-neg">{{ trans('entities.chapters_delete_confirm') }}</p>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $chapter->book,
+                $chapter,
+                $chapter->getUrl('/delete') => [
+                    'text' => trans('entities.chapters_delete'),
+                    'icon' => 'delete',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('entities.chapters_delete') }}</h1>
+            <p>{{ trans('entities.chapters_delete_explain', ['chapterName' => $chapter->name]) }}</p>
+            <p class="text-neg"><strong>{{ trans('entities.chapters_delete_confirm') }}</strong></p>
+
+            <form action="{{ $chapter->getUrl() }}" method="POST">
+
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="DELETE">
 
-                <form action="{{ $chapter->getUrl() }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="DELETE">
+                <div class="text-right">
                     <a href="{{ $chapter->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                    <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
-                </form>
-            </div>
+                    <button type="submit" class="button primary">{{ trans('common.confirm') }}</button>
+                </div>
+            </form>
         </div>
     </div>
 
index 04c5aa724e17be000bfe6397b033ba2ae5adac41..570182344a0b17a35cf0e2c6ab11556a0ecaff10 100644 (file)
@@ -1,24 +1,28 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('chapters._breadcrumbs', ['chapter' => $chapter])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('edit') {{ trans('entities.chapters_edit') }}</h3>
-            <div class="body">
-                <form action="{{  $chapter->getUrl() }}" method="POST">
-                    <input type="hidden" name="_method" value="PUT">
-                    @include('chapters/form', ['model' => $chapter])
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $book,
+                $chapter,
+                $chapter->getUrl('/edit') => [
+                    'text' => trans('entities.chapters_edit'),
+                    'icon' => 'edit'
+                ]
+            ]])
         </div>
+
+        <div class="content-wrap card">
+            <h1 class="list-heading">{{ trans('entities.chapters_edit') }}</h1>
+            <form action="{{  $chapter->getUrl() }}" method="POST">
+                <input type="hidden" name="_method" value="PUT">
+                @include('chapters/form', ['model' => $chapter])
+            </form>
+        </div>
+
     </div>
 
 @stop
\ No newline at end of file
index fde46084449d31ec0fd732ad4d7043ee9fc6bedf..014caf2d3e99a3608e8e18479637141a80d598ad 100644 (file)
@@ -22,5 +22,5 @@
 
 <div class="form-group text-right">
     <a href="{{ isset($chapter) ? $chapter->getUrl() : $book->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-    <button type="submit" class="button pos">{{ trans('entities.chapters_save') }}</button>
+    <button type="submit" class="button primary">{{ trans('entities.chapters_save') }}</button>
 </div>
index e5d8b207c85d76797d06c8f000a3c72910dea8ce..e342ea6a3a1a0a04ab4cc68233d3377efd384589 100644 (file)
@@ -1,31 +1,22 @@
-<div class="chapter entity-list-item" data-entity-type="chapter" data-entity-id="{{$chapter->id}}">
-    <h4>
-        @if (isset($showPath) && $showPath)
-            <a href="{{ $chapter->book->getUrl() }}" class="text-book">
-                @icon('book'){{ $chapter->book->getShortName() }}
-            </a>
-            <span class="text-muted">&nbsp;&nbsp;&raquo;&nbsp;&nbsp;</span>
-        @endif
-        <a href="{{ $chapter->getUrl() }}" class="text-chapter entity-list-item-link">
-            @icon('chapter')<span class="entity-list-item-name break-text">{{ $chapter->name }}</span>
-        </a>
-    </h4>
-
-    <div class="entity-item-snippet">
-        @if(isset($chapter->searchSnippet))
-            <p class="text-muted break-text">{!! $chapter->searchSnippet !!}</p>
-        @else
-            <p class="text-muted break-text">{{ $chapter->getExcerpt() }}</p>
-        @endif
+<a href="{{ $chapter->getUrl() }}" class="chapter entity-list-item @if($chapter->hasChildren()) has-children @endif" data-entity-type="chapter" data-entity-id="{{$chapter->id}}">
+    <span class="icon text-chapter">@icon('chapter')</span>
+    <div class="content">
+        <h4 class="entity-list-item-name break-text">{{ $chapter->name }}</h4>
+        <div class="entity-item-snippet">
+            <p class="text-muted break-text mb-s">{{ $chapter->getExcerpt() }}</p>
+        </div>
     </div>
-
-
-    @if(!isset($hidePages) && count($chapter->pages) > 0)
-        <p chapter-toggle class="text-muted">@icon('caret-right') @icon('page') <span>{{ trans_choice('entities.x_pages', $chapter->pages->count()) }}</span></p>
-        <div class="inset-list">
-            @foreach($chapter->pages as $page)
-                <h5 class="@if($page->draft) draft @endif"><a href="{{ $page->getUrl() }}" class="text-page @if($page->draft) draft @endif">@icon('page'){{$page->name}}</a></h5>
-            @endforeach
+</a>
+@if ($chapter->hasChildren())
+    <div class="chapter chapter-expansion">
+        <span class="icon text-chapter">@icon('page')</span>
+        <div class="content">
+            <div chapter-toggle class="text-muted chapter-expansion-toggle">@icon('caret-right') <span>{{ trans_choice('entities.x_pages', $chapter->pages->count()) }}</span></div>
+            <div class="inset-list">
+                <div class="entity-list-item-children">
+                    @include('partials.entity-list-basic', ['entities' => $chapter->pages])
+                </div>
+            </div>
         </div>
-    @endif
-</div>
\ No newline at end of file
+    </div>
+@endif
\ No newline at end of file
index 0efc18adf3c02cb28a9be16c6ff2b64d41189466..7f3de1322bdcaf94200ef5dfbeddbb358f190bf3 100644 (file)
@@ -1,30 +1,36 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('chapters._breadcrumbs', ['chapter' => $chapter])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
 
-        <div class="card">
-            <h3>@icon('folder') {{ trans('entities.chapters_move') }}</h3>
-            <div class="body">
-                <form action="{{ $chapter->getUrl('/move') }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="PUT">
-
-                    @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book', 'entityPermission' => 'chapter-create'])
-
-                    <div class="form-group text-right">
-                        <a href="{{ $chapter->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button type="submit" class="button pos">{{ trans('entities.chapters_move') }}</button>
-                    </div>
-                </form>
-            </div>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $chapter->book,
+                $chapter,
+                $chapter->getUrl('/move') => [
+                    'text' => trans('entities.chapters_move'),
+                    'icon' => 'folder',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.chapters_move') }}</h1>
+
+            <form action="{{ $chapter->getUrl('/move') }}" method="POST">
+
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="PUT">
+
+                @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book', 'entityPermission' => 'chapter-create'])
+
+                <div class="form-group text-right">
+                    <a href="{{ $chapter->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    <button type="submit" class="button primary">{{ trans('entities.chapters_move') }}</button>
+                </div>
+            </form>
+
         </div>
 
 
diff --git a/resources/views/chapters/permissions.blade.php b/resources/views/chapters/permissions.blade.php
new file mode 100644 (file)
index 0000000..cb5808e
--- /dev/null
@@ -0,0 +1,24 @@
+@extends('simple-layout')
+
+@section('body')
+
+    <div class="container">
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $chapter->book,
+                $chapter,
+                $chapter->getUrl('/permissions') => [
+                    'text' => trans('entities.chapters_permissions'),
+                    'icon' => 'lock',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.chapters_permissions') }}</h1>
+            @include('form.entity-permissions', ['model' => $chapter])
+        </div>
+    </div>
+
+@stop
diff --git a/resources/views/chapters/restrictions.blade.php b/resources/views/chapters/restrictions.blade.php
deleted file mode 100644 (file)
index 70eb224..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-@extends('simple-layout')
-
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('chapters._breadcrumbs', ['chapter' => $chapter])
-    </div>
-@stop
-
-@section('body')
-
-    <div class="container">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('lock') {{ trans('entities.chapters_permissions') }}</h3>
-            <div class="body">
-                @include('form/restriction-form', ['model' => $chapter])
-            </div>
-        </div>
-    </div>
-
-@stop
index f5f9901450fc6aa41f2f4c4ed5558b5e2c242617..397d75254b58af87217feeda4d6cd613bae1cd80 100644 (file)
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-sm-6 col-xs-3 faded" v-pre>
-        @include('chapters._breadcrumbs', ['chapter' => $chapter])
+@section('container-attrs')
+    id="entity-dashboard"
+    entity-id="{{ $chapter->id }}"
+    entity-type="chapter"
+@stop
+
+@section('body')
+
+    <div class="mb-m">
+        @include('partials.breadcrumbs', ['crumbs' => [
+            $chapter->book,
+            $chapter,
+        ]])
     </div>
-    <div class="col-sm-6 col-xs-9 faded">
-        <div class="action-buttons">
-            <span dropdown class="dropdown-container">
-                <div dropdown-toggle class="text-button text-primary">@icon('export'){{ trans('entities.export') }}</div>
+
+    <div class="content-wrap card">
+        <h1 class="break-text" v-pre>{{ $chapter->name }}</h1>
+        <div class="chapter-content" v-show="!searching">
+            <p v-pre class="text-muted break-text">{!! nl2br(e($chapter->description)) !!}</p>
+            @if(count($pages) > 0)
+                <div v-pre class="entity-list book-contents">
+                    @foreach($pages as $page)
+                        @include('pages.list-item', ['page' => $page])
+                    @endforeach
+                </div>
+            @else
+                {{--TODO--}}
+                <div v-pre class="well">
+                    <p class="text-muted italic">{{ trans('entities.chapters_empty') }}</p>
+                    <p>
+                        @if(userCan('page-create', $chapter))
+                            <a href="{{ $chapter->getUrl('/create-page') }}" class="button outline page">@icon('page'){{ trans('entities.books_empty_create_page') }}</a>
+                        @endif
+                        @if(userCan('page-create', $chapter) && userCan('book-update', $book))
+                            &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp; &nbsp;
+                        @endif
+                        @if(userCan('book-update', $book))
+                            <a href="{{ $book->getUrl('/sort') }}" class="button outline book">@icon('book'){{ trans('entities.books_empty_sort_current_book') }}</a>
+                        @endif
+                    </p>
+                </div>
+            @endif
+        </div>
+
+        <div class="search-results" v-cloak v-show="searching">
+            {{--TODO--}}
+            <h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" @click="clearSearch()" class="text-small">@icon('close'){{ trans('entities.search_clear') }}</a></h3>
+            <div v-if="!searchResults">
+                @include('partials/loading-icon')
+            </div>
+            <div v-html="searchResults"></div>
+        </div>
+    </div>
+
+@stop
+
+@section('right')
+
+    <div class="actions mb-xl">
+        <h5>{{ trans('common.actions') }}</h5>
+        <div class="icon-list text-primary">
+
+            <div dropdown class="dropdown-container">
+                <div dropdown-toggle class="icon-list-item">
+                    <span>@icon('export')</span>
+                    <span>{{ trans('entities.export') }}</span>
+                </div>
                 <ul class="wide">
                     <li><a href="{{ $chapter->getUrl('/export/html') }}" target="_blank">{{ trans('entities.export_html') }} <span class="text-muted float right">.html</span></a></li>
                     <li><a href="{{ $chapter->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.export_pdf') }} <span class="text-muted float right">.pdf</span></a></li>
                     <li><a href="{{ $chapter->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.export_text') }} <span class="text-muted float right">.txt</span></a></li>
                 </ul>
-            </span>
+            </div>
+
             @if(userCan('page-create', $chapter))
-                <a href="{{ $chapter->getUrl('/create-page') }}" class="text-pos text-button">@icon('add'){{ trans('entities.pages_new') }}</a>
+                <a href="{{ $chapter->getUrl('/create-page') }}" class="icon-list-item">
+                    <span>@icon('add')</span>
+                    <span>{{ trans('entities.pages_new') }}</span>
+                </a>
             @endif
             @if(userCan('chapter-update', $chapter))
-                <a href="{{ $chapter->getUrl('/edit') }}" class="text-primary text-button">@icon('edit'){{ trans('common.edit') }}</a>
+                <a href="{{ $chapter->getUrl('/edit') }}" class="icon-list-item">
+                    <span>@icon('edit')</span>
+                    <span>{{ trans('common.edit') }}</span>
+                </a>
             @endif
-            @if((userCan('chapter-update', $chapter) && userCan('chapter-delete', $chapter) )|| userCan('restrictions-manage', $chapter) || userCan('chapter-delete', $chapter))
-                <div dropdown class="dropdown-container">
-                    <a dropdown-toggle class="text-primary text-button">@icon('more') {{ trans('common.more') }}</a>
-                    <ul>
-                        @if(userCan('chapter-update', $chapter) && userCan('chapter-delete', $chapter))
-                            <li><a href="{{ $chapter->getUrl('/move') }}" class="text-primary">@icon('folder'){{ trans('common.move') }}</a></li>
-                        @endif
-                        @if(userCan('restrictions-manage', $chapter))
-                            <li><a href="{{ $chapter->getUrl('/permissions') }}" class="text-primary">@icon('lock'){{ trans('entities.permissions') }}</a></li>
-                        @endif
-                        @if(userCan('chapter-delete', $chapter))
-                            <li><a href="{{ $chapter->getUrl('/delete') }}" class="text-neg">@icon('delete'){{ trans('common.delete') }}</a></li>
-                        @endif
-                    </ul>
-                </div>
+            @if(userCan('chapter-update', $chapter) && userCan('chapter-delete', $chapter))
+                <a href="{{ $chapter->getUrl('/move') }}" class="icon-list-item">
+                    <span>@icon('folder')</span>
+                    <span>{{ trans('common.move') }}</span>
+                </a>
+            @endif
+            @if(userCan('restrictions-manage', $chapter))
+                <a href="{{ $chapter->getUrl('/permissions') }}" class="icon-list-item">
+                    <span>@icon('lock')</span>
+                    <span>{{ trans('entities.permissions') }}</span>
+                </a>
             @endif
+            @if(userCan('chapter-delete', $chapter))
+                <a href="{{ $chapter->getUrl('/delete') }}" class="icon-list-item">
+                    <span>@icon('delete')</span>
+                    <span>{{ trans('common.delete') }}</span>
+                </a>
+            @endif
+
+            {{--@if(userCan('page-create', $book))--}}
+                {{--<a href="{{ $book->getUrl('/create-page') }}" class="icon-list-item">--}}
+                    {{--<span>@icon('add')</span>--}}
+                    {{--<span>{{ trans('entities.pages_new') }}</span>--}}
+                {{--</a>--}}
+            {{--@endif--}}
         </div>
     </div>
-@stop
 
-@section('container-attrs')
-    id="entity-dashboard"
-    entity-id="{{ $chapter->id }}"
-    entity-type="chapter"
+    <div class="col-sm-6 col-xs-9 faded">
+        <div class="action-buttons">
+
+        </div>
+    </div>
 @stop
 
-@section('sidebar')
+
+
+@section('left')
 
     @if($chapter->tags->count() > 0)
-        <section>
+        <div class="mb-xl">
             @include('components.tag-list', ['entity' => $chapter])
-        </section>
+        </div>
     @endif
 
-    <div class="card">
-        <div class="body">
-            <form @submit.prevent="searchBook" class="search-box">
-                <input v-model="searchTerm" @change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
-                <button type="submit">@icon('search')</button>
-                <button v-if="searching" v-cloak class="text-neg" @click="clearSearch()" type="button">@icon('close')</button>
-            </form>
-        </div>
+    <div class="mb-xl">
+        <form @submit.prevent="searchBook" class="search-box">
+            <input v-model="searchTerm" @change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
+            <button type="submit">@icon('search')</button>
+            <button v-if="searching" v-cloak class="text-neg" @click="clearSearch()" type="button">@icon('close')</button>
+        </form>
     </div>
 
-    <div class="card entity-details">
-        <h3>@icon('info') {{ trans('common.details') }}</h3>
-        <div class="body blended-links text-small text-muted">
+    <div class="mb-xl">
+        <h5>{{ trans('common.details') }}</h5>
+        <div class="blended-links text-small text-muted">
             @include('partials.entity-meta', ['entity' => $chapter])
 
             @if($book->restricted)
     @include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
 @stop
 
-@section('body')
-
-    <div class="container small nopad">
-        <h1 class="break-text" v-pre>{{ $chapter->name }}</h1>
-        <div class="chapter-content" v-show="!searching">
-            <p v-pre class="text-muted break-text">{!! nl2br(e($chapter->description)) !!}</p>
 
-            @if(count($pages) > 0)
-                <div v-pre class="page-list">
-                    <hr>
-                    @foreach($pages as $page)
-                        @include('pages/list-item', ['page' => $page])
-                        <hr>
-                    @endforeach
-                </div>
-            @else
-                <div v-pre class="well">
-                    <p class="text-muted italic">{{ trans('entities.chapters_empty') }}</p>
-                    <p>
-                        @if(userCan('page-create', $chapter))
-                            <a href="{{ $chapter->getUrl('/create-page') }}" class="button outline page">@icon('page'){{ trans('entities.books_empty_create_page') }}</a>
-                        @endif
-                        @if(userCan('page-create', $chapter) && userCan('book-update', $book))
-                            &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp; &nbsp;
-                        @endif
-                        @if(userCan('book-update', $book))
-                            <a href="{{ $book->getUrl('/sort') }}" class="button outline book">@icon('book'){{ trans('entities.books_empty_sort_current_book') }}</a>
-                        @endif
-                    </p>
-                </div>
-            @endif
-        </div>
-
-        <div class="search-results" v-cloak v-show="searching">
-            <h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" @click="clearSearch()" class="text-small">@icon('close'){{ trans('entities.search_clear') }}</a></h3>
-            <div v-if="!searchResults">
-                @include('partials/loading-icon')
-            </div>
-            <div v-html="searchResults"></div>
-        </div>
-    </div>
-
-@stop
index 5d3aafa1005244eda4706bf644f4f306b8ed2101..1e5a4231cb98b83fa34accbc5af5eb65d59b2eed 100644 (file)
@@ -1,3 +1,4 @@
+{{--TODO--}}
 <div page-comments page-id="{{ $page->id }}" class="comments-list">
   <h5 comments-title class="float left">{{ trans_choice('entities.comment_count', count($page->comments), ['count' => count($page->comments)]) }}</h5>
 
diff --git a/resources/views/common/header.blade.php b/resources/views/common/header.blade.php
new file mode 100644 (file)
index 0000000..89aa107
--- /dev/null
@@ -0,0 +1,73 @@
+<header id="header" header-mobile-toggle>
+    <div class="grid break-l mx-l">
+
+        <div>
+            <a href="{{ baseUrl('/') }}" class="logo">
+                @if(setting('app-logo', '') !== 'none')
+                    <img class="logo-image" src="{{ setting('app-logo', '') === '' ? baseUrl('/logo.png') : baseUrl(setting('app-logo', '')) }}" alt="Logo">
+                @endif
+                @if (setting('app-name-header'))
+                    <span class="logo-text">{{ setting('app-name') }}</span>
+                @endif
+            </a>
+            <div class="mobile-menu-toggle hide-over-l">@icon('more')</div>
+        </div>
+
+        <div class="header-search hide-under-l">
+            @if (hasAppAccess())
+            <form action="{{ baseUrl('/search') }}" method="GET" class="search-box">
+                <button id="header-search-box-button" type="submit">@icon('search') </button>
+                <input id="header-search-box-input" type="text" name="term" tabindex="2" placeholder="{{ trans('common.search') }}" value="{{ isset($searchTerm) ? $searchTerm : '' }}">
+            </form>
+            @endif
+        </div>
+
+        <div class="text-right">
+            <div class="header-links">
+                <div class="links text-center">
+                    @if (hasAppAccess())
+                        <a class="hide-over-l" href="{{ baseUrl('/search') }}">@icon('search'){{ trans('common.search') }}</a>
+                        @if(userCanOnAny('view', \BookStack\Entities\Bookshelf::class) || userCan('bookshelf-view-all') || userCan('bookshelf-view-own'))
+                            <a href="{{ baseUrl('/shelves') }}">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
+                        @endif
+                        <a href="{{ baseUrl('/books') }}">@icon('books'){{ trans('entities.books') }}</a>
+                        @if(signedInUser() && userCan('settings-manage'))
+                            <a href="{{ baseUrl('/settings') }}">@icon('settings'){{ trans('settings.settings') }}</a>
+                        @endif
+                        @if(signedInUser() && userCan('users-manage') && !userCan('settings-manage'))
+                            <a href="{{ baseUrl('/settings/users') }}">@icon('users'){{ trans('settings.users') }}</a>
+                        @endif
+                    @endif
+
+                    @if(!signedInUser())
+                        @if(setting('registration-enabled', false))
+                            <a href="{{ baseUrl("/register") }}">@icon('new-user') {{ trans('auth.sign_up') }}</a>
+                        @endif
+                        <a href="{{ baseUrl('/login') }}">@icon('login') {{ trans('auth.log_in') }}</a>
+                    @endif
+                </div>
+                @if(signedInUser())
+                    <?php $currentUser = user(); ?>
+                    <div class="dropdown-container" dropdown>
+                        <span class="user-name hide-under-l" dropdown-toggle>
+                            <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
+                            <span class="name">{{ $currentUser->getShortName(9) }}</span> @icon('caret-down')
+                        </span>
+                        <ul>
+                            <li>
+                                <a href="{{ baseUrl("/user/{$currentUser->id}") }}" class="text-primary">@icon('user'){{ trans('common.view_profile') }}</a>
+                            </li>
+                            <li>
+                                <a href="{{ baseUrl("/settings/users/{$currentUser->id}") }}" class="text-primary">@icon('edit'){{ trans('common.edit_profile') }}</a>
+                            </li>
+                            <li>
+                                <a href="{{ baseUrl('/logout') }}" class="text-neg">@icon('logout'){{ trans('auth.logout') }}</a>
+                            </li>
+                        </ul>
+                    </div>
+                @endif
+            </div>
+        </div>
+
+    </div>
+</header>
\ No newline at end of file
index cc20fc68e2d91d97a7dc89236bb82e052f86fb9b..bc7778fe57c428e8f7bac68531725db8c88dbe66 100644 (file)
@@ -1,57 +1,57 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-6 faded">
-        <div class="action-buttons text-left">
-            <a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button">@icon('expand-text'){{ trans('common.toggle_details') }}</a>
-        </div>
-    </div>
-@stop
 
 @section('body')
 
-    <div class="container" id="home-default">
-        <div class="row">
+    <div class="container px-xl py-l">
+        <a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-muted">@icon('expand-text'){{ trans('common.toggle_details') }}</a>
+    </div>
 
-            <div class="col-sm-4">
-                @if(count($draftPages) > 0)
-                    <div id="recent-drafts" class="card">
-                        <h3>@icon('edit') {{ trans('entities.my_recent_drafts') }}</h3>
+    <div class="grid contained third large-gap" id="home-default">
+        <div>
+            @if(count($draftPages) > 0)
+                <div id="recent-drafts" class="card mb-xl">
+                    <h3>{{ trans('entities.my_recent_drafts') }}</h3>
+                    <div class="px-m">
                         @include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
                     </div>
-                @endif
+                </div>
+            @endif
 
-                <div class="card">
-                    <h3>@icon($signedIn ? 'view' : 'star-circle') {{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
+            <div id="{{ $signedIn ? 'recently-viewed' : 'recent-books' }}" class="card mb-xl">
+                <h3>{{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
+                <div class="px-m">
                     @include('partials/entity-list', [
-                        'entities' => $recents,
-                        'style' => 'compact',
-                        'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
-                        ])
+                    'entities' => $recents,
+                    'style' => 'compact',
+                    'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
+                    ])
                 </div>
             </div>
+        </div>
 
-            <div class="col-sm-4">
-                <div class="card">
-                    <h3>@icon('file') <a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
-                    <div id="recently-updated-pages">
-                        @include('partials/entity-list', [
-                        'entities' => $recentlyUpdatedPages,
-                        'style' => 'compact',
-                        'emptyText' => trans('entities.no_pages_recently_updated')
-                        ])
-                    </div>
+        <div>
+            <div id="recent-pages" class="card mb-xl">
+                <h3><a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
+                <div id="recently-updated-pages" class="px-m">
+                    @include('partials/entity-list', [
+                    'entities' => $recentlyUpdatedPages,
+                    'style' => 'compact',
+                    'emptyText' => trans('entities.no_pages_recently_updated')
+                    ])
                 </div>
             </div>
+        </div>
 
-            <div class="col-sm-4" id="recent-activity">
-                <div class="card">
-                    <h3>@icon('time') {{ trans('entities.recent_activity') }}</h3>
+        <div>
+            <div id="recent-activity">
+                <div class="card mb-xl">
+                    <h3>{{ trans('entities.recent_activity') }}</h3>
                     @include('partials/activity-list', ['activity' => $activity])
                 </div>
             </div>
-
         </div>
+
     </div>
 
 
diff --git a/resources/views/components/custom-checkbox.blade.php b/resources/views/components/custom-checkbox.blade.php
new file mode 100644 (file)
index 0000000..57ab134
--- /dev/null
@@ -0,0 +1,11 @@
+{{--
+$name
+$value
+$checked
+$label
+--}}
+<label class="toggle-switch @if($errors->has($name)) neg @endif">
+    <input type="checkbox" name="{{$name}}" value="{{ $value }}" @if($checked) checked="checked" @endif>
+    <span class="custom-checkbox text-primary">@icon('check')</span>
+    <span class="label">{{$label}}</span>
+</label>
\ No newline at end of file
index 89c574c28c0f3090868cc43ef1f3c6794f7b6d4c..c85bf8fca8c440d397cc7221e1b7c07f0d4e0242 100644 (file)
@@ -5,4 +5,5 @@
         <div class="text-center loading" entity-selector-loading>@include('partials.loading-icon')</div>
         <div entity-selector-results></div>
     </div>
-</div>
\ No newline at end of file
+</div>
+{{--TODO--}}
\ No newline at end of file
index 034b65cc5f64389541f13ac323f12e0dd39604b1..630006d8283991523ce40621344f767458b4bbc9 100644 (file)
@@ -1,17 +1,20 @@
 <div class="image-picker" image-picker="{{$name}}" data-default-image="{{ $defaultImage }}" data-resize-height="{{ $resizeHeight }}" data-resize-width="{{ $resizeWidth }}" data-current-id="{{ $currentId or '' }}" data-resize-crop="{{ $resizeCrop or '' }}">
 
-    <div>
-        <img @if($currentImage && $currentImage !== 'none') src="{{$currentImage}}" @else src="{{$defaultImage}}" @endif  class="{{$imageClass}} @if($currentImage=== 'none') none @endif" alt="{{ trans('components.image_preview') }}">
-    </div>
-
-    <button class="button" type="button" data-action="show-image-manager">{{ trans('components.image_select_image') }}</button>
-    <br>
-    <button class="text-button" data-action="reset-image" type="button">{{ trans('common.reset') }}</button>
+    <div class="grid half">
+        <div class="text-center">
+            <img @if($currentImage && $currentImage !== 'none') src="{{$currentImage}}" @else src="{{$defaultImage}}" @endif  class="{{$imageClass}} @if($currentImage=== 'none') none @endif" alt="{{ trans('components.image_preview') }}">
+        </div>
+        <div class="text-center">
+            <button class="button outline small" type="button" data-action="show-image-manager">{{ trans('components.image_select_image') }}</button>
+            <br>
+            <button class="text-button muted" data-action="reset-image" type="button">{{ trans('common.reset') }}</button>
 
-    @if ($showRemove)
-        <span class="sep">|</span>
-        <button class="text-button neg" data-action="remove-image" type="button">{{ trans('common.remove') }}</button>
-    @endif
+            @if ($showRemove)
+                <span class="sep">|</span>
+                <button class="text-button muted" data-action="remove-image" type="button">{{ trans('common.remove') }}</button>
+            @endif
+        </div>
+    </div>
 
     <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== 0 && $currentId !== false) ? $currentId : $currentImage}}">
 </div>
\ No newline at end of file
index c5a30a60f9dae1842a75fcbc9ee3418b52584d18..84a8a3083716972b1a1a53a6302aec62d3ed6256 100644 (file)
@@ -1,4 +1,6 @@
-<div toggle-switch="{{$name}}" class="toggle-switch @if($value) active @endif">
+<label toggle-switch="{{$name}}" class="toggle-switch">
     <input type="hidden" name="{{$name}}" value="{{$value?'true':'false'}}"/>
-    <div class="switch-handle"></div>
-</div>
\ No newline at end of file
+    <input type="checkbox" @if($value) checked="checked" @endif>
+    <span class="custom-checkbox text-primary">@icon('check')</span>
+    <span class="label">{{ $label }}</span>
+</label>
\ No newline at end of file
index f58856ced4d0f052129acfc8e2245574cb5d6557..29364606b97d24f58cc977d7adc012fd6bb3a788 100644 (file)
@@ -1,13 +1,11 @@
-@extends('public')
+@extends('simple-layout')
 
 @section('content')
 
-    <div class="container small">
-        <div class="card">
-            <div class="body">
-                <h4 class="text-muted">@icon('danger') {{ trans('errors.app_down', ['appName' => setting('app-name')]) }}</h4>
-                <p>{{ trans('errors.back_soon') }}</p>
-            </div>
+    <div class="container small mt-xl">
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('errors.app_down', ['appName' => setting('app-name')]) }}</h1>
+            <p>{{ trans('errors.back_soon') }}</p>
         </div>
     </div>
 
index 25589690600860350c08073891d83e82826b2cd4..255b591aa9ff790ffef3158dedbd477c48101716 100644 (file)
@@ -1,11 +1,15 @@
-
-<label>
-    <input value="true" id="{{$name}}" type="checkbox" name="{{$name}}"
-           @if($errors->has($name)) class="neg" @endif
-           @if(old($name) || (!old() && isset($model) && $model->$name)) checked="checked" @endif
-    >
-    {{ $label }}
-</label>
+{{--
+$name
+$label
+$errors?
+$model?
+--}}
+@include('components.custom-checkbox', [
+    'name' => $name,
+    'label' => $label,
+    'value' => 'true',
+    'checked' => old($name) || (!old() && isset($model) && $model->$name)
+])
 
 @if($errors->has($name))
     <div class="text-neg text-small">{{ $errors->first($name) }}</div>
similarity index 60%
rename from resources/views/form/restriction-form.blade.php
rename to resources/views/form/entity-permissions.blade.php
index c32fe005a087cb18384e8969e5300441b9e805a3..bb7d992f7356082e42786b26615b4bd4f2943815 100644 (file)
@@ -2,14 +2,18 @@
     {!! csrf_field() !!}
     <input type="hidden" name="_method" value="PUT">
 
-    <p>{{ trans('entities.permissions_intro') }}</p>
+    <p class="mb-none">{{ trans('entities.permissions_intro') }}</p>
 
     <div class="form-group">
-        @include('form/checkbox', ['name' => 'restricted', 'label' => trans('entities.permissions_enable')])
+        @include('form.checkbox', [
+            'name' => 'restricted',
+            'label' => trans('entities.permissions_enable'),
+        ])
     </div>
 
+    {{--TODO - Add global and role "Select All" options--}}
 
-    <table class="table">
+    <table class="table toggle-switch-list">
         <tr>
             <th>{{ trans('common.role') }}</th>
             <th @if($model->isA('page')) colspan="3" @else colspan="4" @endif>{{ trans('common.actions') }}</th>
         @foreach($roles as $role)
             <tr>
                 <td>{{ $role->display_name }}</td>
-                <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.view'), 'action' => 'view'])</td>
+                <td>@include('form.restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.view'), 'action' => 'view'])</td>
                 @if(!$model->isA('page'))
-                    <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.create'), 'action' => 'create'])</td>
+                    <td>@include('form.restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.create'), 'action' => 'create'])</td>
                 @endif
-                <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.update'), 'action' => 'update'])</td>
-                <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.delete'), 'action' => 'delete'])</td>
+                <td>@include('form.restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.update'), 'action' => 'update'])</td>
+                <td>@include('form.restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.delete'), 'action' => 'delete'])</td>
             </tr>
         @endforeach
     </table>
 
     <div class="text-right">
         <a href="{{ $model->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-        <button type="submit" class="button pos">{{ trans('entities.permissions_save') }}</button>
+        <button type="submit" class="button primary">{{ trans('entities.permissions_save') }}</button>
     </div>
 </form>
\ No newline at end of file
index 5a8662b56a964430fbdcdc2937264db7b0344bf2..65a94239e78d83d5b9faadd8b7eafcaa627aaac3 100644 (file)
@@ -1,6 +1,13 @@
-
-<label>
-    <input value="true" id="{{$name}}[{{$role->id}}][{{$action}}]" type="checkbox" name="{{$name}}[{{$role->id}}][{{$action}}]"
-           @if(isset($model) && $model->hasRestriction($role->id, $action)) checked="checked" @endif>
-    {{ $label }}
-</label>
\ No newline at end of file
+{{--
+$name
+$label
+$role
+$action
+$model?
+--}}
+@include('components.custom-checkbox', [
+    'name' => $name . '[' . $role->id . '][' . $action . ']',
+    'label' => $label,
+    'value' => 'true',
+    'checked' => isset($model) && $model->hasRestriction($role->id, $action)
+])
\ No newline at end of file
index df868ee98055939f160d0485b3e13748c0a7ad5b..ab62652640c10fd89a6ec1daf42432c340f7ec16 100644 (file)
@@ -1,13 +1,16 @@
 
-@foreach($roles as $role)
-    <label>
-        <input value="{{ $role->id }}" id="{{$name}}-{{$role->name}}" type="checkbox" name="{{$name}}[{{$role->name}}]"
-               @if($errors->has($name)) class="neg" @endif
-               @if(old($name . '.' . $role->name) || (!old('name') && isset($model) && $model->hasRole($role->name))) checked="checked" @endif
-        >
-        {{ $role->display_name }}
-    </label>
-@endforeach
+<div class="toggle-switch-list dual-column-content">
+    @foreach($roles as $role)
+        <div>
+            @include('components.custom-checkbox', [
+                'name' => $name . '[' . $role->name . ']',
+                'label' => $role->display_name,
+                'value' => $role->id,
+                'checked' => old($name . '.' . $role->name) || (!old('name') && isset($model) && $model->hasRole($role->name))
+            ])
+        </div>
+    @endforeach
+</div>
 
 @if($errors->has($name))
     <div class="text-neg text-small">{{ $errors->first($name) }}</div>
diff --git a/resources/views/pages/_breadcrumbs.blade.php b/resources/views/pages/_breadcrumbs.blade.php
deleted file mode 100644 (file)
index 19bab40..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<div class="breadcrumbs">
-    @if (userCan('view', $page->book))
-        <a href="{{ $page->book->getUrl() }}" class="text-book text-button">@icon('book'){{ $page->book->getShortName() }}</a>
-        <span class="sep">&raquo;</span>
-    @endif
-    @if($page->hasChapter() && userCan('view', $page->chapter))
-        <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
-            @icon('chapter')
-            {{ $page->chapter->getShortName() }}
-        </a>
-        <span class="sep">&raquo;</span>
-    @endif
-    <a href="{{ $page->getUrl() }}" class="text-page text-button">@icon('page'){{ $page->getShortName() }}</a>
-</div>
\ No newline at end of file
index eb6afcad2ebf9010ebd5d81ab8eca9810e61251a..8bb9859cf7ea4e7ce542e19c29884611ca5046b8 100644 (file)
@@ -1,42 +1,48 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('copy') {{ trans('entities.pages_copy') }}</h3>
-            <div class="body">
-                <form action="{{ $page->getUrl('/copy') }}" method="POST">
-                    {!! csrf_field() !!}
-
-                    <div class="form-group title-input">
-                        <label for="name">{{ trans('common.name') }}</label>
-                        @include('form/text', ['name' => 'name'])
-                    </div>
 
-                    <div class="form-group" collapsible>
-                        <div class="collapse-title text-primary" collapsible-trigger>
-                            <label for="entity_selection">{{ trans('entities.pages_copy_desination') }}</label>
-                        </div>
-                        <div class="collapse-content" collapsible-content>
-                            @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
-                        </div>
-                    </div>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $page->book,
+                $page->chapter,
+                $page,
+                $page->getUrl('/copy') => [
+                    'text' => trans('entities.pages_copy'),
+                    'icon' => 'copy',
+                ]
+            ]])
+        </div>
 
+        <div class="card content-wrap auto-height">
 
-                    <div class="form-group text-right">
-                        <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button type="submit" class="button pos">{{ trans('entities.pages_copy') }}</button>
+            <h1 class="list-heading">{{ trans('entities.pages_copy') }}</h1>
+
+            <form action="{{ $page->getUrl('/copy') }}" method="POST">
+                {!! csrf_field() !!}
+
+                <div class="form-group title-input">
+                    <label for="name">{{ trans('common.name') }}</label>
+                    @include('form/text', ['name' => 'name'])
+                </div>
+
+                <div class="form-group" collapsible>
+                    <div class="collapse-title text-primary" collapsible-trigger>
+                        <label for="entity_selection">{{ trans('entities.pages_copy_desination') }}</label>
                     </div>
-                </form>
-            </div>
+                    <div class="collapse-content" collapsible-content>
+                        @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
+                    </div>
+                </div>
+
+                <div class="form-group text-right">
+                    <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    <button type="submit" class="button primary">{{ trans('entities.pages_copy') }}</button>
+                </div>
+            </form>
+
         </div>
     </div>
 
index 901ea182c3ee5886d656cc6d339da83594f6eb9c..a72157a83c45ef6a3dab3d7ab467dc786df2fe10 100644 (file)
@@ -1,28 +1,43 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ $page->draft ? trans('entities.pages_delete_draft') : trans('entities.pages_delete') }}</h3>
-            <div class="body">
-                <p class="text-neg">{{ $page->draft ? trans('entities.pages_delete_draft_confirm'): trans('entities.pages_delete_confirm') }}</p>
 
-                <form action="{{ $page->getUrl() }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="DELETE">
-                    <div class="form-group">
-                        <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
-                    </div>
-                </form>
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $page->book,
+                $page->chapter,
+                $page,
+                $page->getUrl('/delete') => [
+                    'text' => trans('entities.pages_delete'),
+                    'icon' => 'delete',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ $page->draft ? trans('entities.pages_delete_draft') : trans('entities.pages_delete') }}</h1>
+
+
+            <div class="grid half v-center">
+                <div>
+                    <p class="text-neg">
+                        <strong>
+                            {{ $page->draft ? trans('entities.pages_delete_draft_confirm'): trans('entities.pages_delete_confirm') }}
+                        </strong>
+                    </p>
+                </div>
+                <div>
+                    <form action="{{ $page->getUrl() }}" method="POST">
+                        {!! csrf_field() !!}
+                        <input type="hidden" name="_method" value="DELETE">
+                        <div class="form-group text-right">
+                            <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
+                            <button type="submit" class="button primary">{{ trans('common.confirm') }}</button>
+                        </div>
+                    </form>
+                </div>
             </div>
         </div>
     </div>
index b4991d79d2f035f6a91a2d267b2fdc86248a2e87..eb2fab94cb3076602b909499ee5a29656c7fe257 100644 (file)
@@ -1,15 +1,17 @@
 @extends('simple-layout')
 
 @section('body')
-    <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>{{ $title }}</h3>
-            @include('partials/entity-list', ['entities' => $pages, 'style' => 'detailed'])
-            <div class="body text-center">
+    <div class="container small pt-xl">
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ $title }}</h1>
+
+            <div class="book-contents">
+                @include('partials.entity-list', ['entities' => $pages, 'style' => 'detailed'])
+            </div>
+
+            <div class="text-center">
                 {!! $pages->links() !!}
             </div>
         </div>
-
     </div>
 @stop
\ No newline at end of file
index e818e996ec7e8d40d8765baffa1cf0d75e3b78f7..3dbb5d3bbae84e3560c1816e287db48e52a67b69 100644 (file)
@@ -13,8 +13,8 @@
             @if(!isset($isDraft))
                 <input type="hidden" name="_method" value="PUT">
             @endif
-            @include('pages/form', ['model' => $page])
-            @include('pages/form-toolbox')
+            @include('pages.form', ['model' => $page])
+            @include('pages.form-toolbox')
         </form>
     </div>
     
index b13bb0f120211dda32f3f60fc1c7acaa5cda059f..1e26cf1d546227566cd2798cd2f305ebbfab8148 100644 (file)
@@ -1,44 +1,5 @@
-<div class="page {{$page->draft ? 'draft' : ''}} entity-list-item" data-entity-type="page" data-entity-id="{{$page->id}}">
-    <h4>
-        @if (isset($showPath) && $showPath)
-            <a href="{{ $page->book->getUrl() }}" class="text-book">
-                @icon('book'){{ $page->book->getShortName() }}
-            </a>
-            <span class="text-muted">&nbsp;&nbsp;&raquo;&nbsp;&nbsp;</span>
-            @if($page->chapter)
-                <a href="{{ $page->chapter->getUrl() }}" class="text-chapter">
-                    @icon('chapter'){{ $page->chapter->getShortName() }}
-                </a>
-                <span class="text-muted">&nbsp;&nbsp;&raquo;&nbsp;&nbsp;</span>
-            @endif
-        @endif
-        <a href="{{ $page->getUrl() }}" class="text-page entity-list-item-link">@icon('page')<span class="entity-list-item-name break-text">{{ $page->name }}</span></a>
-    </h4>
-
+@component('partials.entity-list-item-basic', ['entity' => $page])
     <div class="entity-item-snippet">
-        @if(isset($page->searchSnippet))
-            <p class="text-muted break-text">{!! $page->searchSnippet !!}</p>
-        @else
-            <p class="text-muted break-text">{{ $page->getExcerpt() }}</p>
-        @endif
+        <p class="text-muted break-text">{{ $page->getExcerpt() }}</p>
     </div>
-
-    @if(isset($style) && $style === 'detailed')
-        <div class="row meta text-muted text-small">
-            <div class="col-md-6">
-                @include('partials.entity-meta', ['entity' => $page])
-            </div>
-            <div class="col-md-6">
-                <a class="text-book" href="{{ $page->book->getUrl() }}">@icon('book'){{ $page->book->getShortName(30) }}</a>
-                <br>
-                @if($page->chapter)
-                    <a class="text-chapter" href="{{ $page->chapter->getUrl() }}">@icon('chapter'){{ $page->chapter->getShortName(30) }}</a>
-                @else
-                    @icon('chapter') {{ trans('entities.pages_not_in_chapter') }}
-                @endif
-            </div>
-        </div>
-    @endif
-
-
-</div>
\ No newline at end of file
+@endcomponent
\ No newline at end of file
index 5a5c7e3f93c9b5ff76c7f1ebc9b04ca1870dcfb8..83421be934b4e169076285d8dc79721a7af23e51 100644 (file)
@@ -1,30 +1,36 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('folder') {{ trans('entities.pages_move') }}</h3>
-            <div class="body">
-                <form action="{{ $page->getUrl('/move') }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="PUT">
-
-                    @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
-
-                    <div class="form-group text-right">
-                        <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button type="submit" class="button pos">{{ trans('entities.pages_move') }}</button>
-                    </div>
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $page->book,
+                $page->chapter,
+                $page,
+                $page->getUrl('/move') => [
+                    'text' => trans('entities.pages_move'),
+                    'icon' => 'folder',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.pages_move') }}</h1>
+
+            <form action="{{ $page->getUrl('/move') }}" method="POST">
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="PUT">
+
+                @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
+
+                <div class="form-group text-right">
+                    <a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    <button type="submit" class="button primary">{{ trans('entities.pages_move') }}</button>
+                </div>
+            </form>
+
         </div>
     </div>
 
diff --git a/resources/views/pages/permissions.blade.php b/resources/views/pages/permissions.blade.php
new file mode 100644 (file)
index 0000000..260f0e4
--- /dev/null
@@ -0,0 +1,25 @@
+@extends('simple-layout')
+
+@section('body')
+
+    <div class="container">
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $page->book,
+                $page->chapter,
+                $page,
+                $page->getUrl('/permissions') => [
+                    'text' => trans('entities.pages_permissions'),
+                    'icon' => 'lock',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.pages_permissions') }}</h1>
+            @include('form.entity-permissions', ['model' => $page])
+        </div>
+    </div>
+
+@stop
diff --git a/resources/views/pages/restrictions.blade.php b/resources/views/pages/restrictions.blade.php
deleted file mode 100644 (file)
index a7a1e18..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-@extends('simple-layout')
-
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
-    </div>
-@stop
-
-@section('body')
-    <div class="container">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('lock') {{ trans('entities.pages_permissions') }}</h3>
-            <div class="body">
-                @include('form.restriction-form', ['model' => $page])
-            </div>
-        </div>
-    </div>
-@stop
index f2d181fa16123c0e7b5b5cf00542e8bef221fc74..3ce5b349f1afc8c79645e3bcd16e500bc95e1ca3 100644 (file)
@@ -1,8 +1,8 @@
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('sidebar')
-    <div class="card">
-        <h3>@icon('info') {{ trans('common.details') }}</h3>
+@section('left')
+    <div id="revision-details" class="entity-details mb-xl">
+        <h5>{{ trans('common.details') }}</h5>
         <div class="body text-small text-muted">
             @include('partials.entity-meta', ['entity' => $revision])
         </div>
 
 @section('body')
 
-    <div class="container">
-        <div class="row">
-            <div class="col-md-9">
-                <div class="page-content page-revision">
-                    @include('pages.page-display')
-                </div>
-            </div>
-        </div>
+    <div class="mb-m">
+        @include('partials.breadcrumbs', ['crumbs' => [
+            $page->$book,
+            $page->chapter,
+            $page,
+            $page->getUrl('/revisions') => [
+                'text' => trans('entities.pages_revisions'),
+                'icon' => 'history',
+            ],
+            $revision->getUrl('/changes') => $diff ? trans('entities.pages_revisions_numbered_changes', ['id' => $revision->id]) : null,
+            $revision->getUrl() => !$diff ? trans('entities.pages_revisions_numbered', ['id' => $revision->id]) : null,
+        ]])
     </div>
 
-@stop
+    <div class="card content-wrap">
+        <div class="page-content page-revision">
+            @include('pages.page-display')
+        </div>
+    </div>
 
-@section('scripts')
-    <script>
-        setupPageShow(null);
-    </script>
 @stop
\ No newline at end of file
index 990b4fca2b8496bd3d62d43da55dff330331dbf8..134b8f5c27bd4156606592333b284d117ebaeb3e 100644 (file)
@@ -1,76 +1,79 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
-    </div>
-@stop
-
 @section('body')
     <div class="container">
-        <p>&nbsp;</p>
 
-        <div class="card">
-            <h3>@icon('history') {{ trans('entities.pages_revisions') }}</h3>
-            <div class="body">
-                @if(count($page->revisions) > 0)
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $page->book,
+                $page->chapter,
+                $page,
+                $page->getUrl('/revisions') => [
+                    'text' => trans('entities.pages_revisions'),
+                    'icon' => 'history',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.pages_revisions') }}</h1>
+            @if(count($page->revisions) > 0)
 
-                    <table class="table">
+                <table class="table">
+                    <tr>
+                        <th width="3%">{{ trans('entities.pages_revisions_number') }}</th>
+                        <th width="23%">{{ trans('entities.pages_name') }}</th>
+                        <th colspan="2" width="8%">{{ trans('entities.pages_revisions_created_by') }}</th>
+                        <th width="15%">{{ trans('entities.pages_revisions_date') }}</th>
+                        <th width="25%">{{ trans('entities.pages_revisions_changelog') }}</th>
+                        <th width="20%">{{ trans('common.actions') }}</th>
+                    </tr>
+                    @foreach($page->revisions as $index => $revision)
                         <tr>
-                            <th width="3%">{{ trans('entities.pages_revisions_number') }}</th>
-                            <th width="23%">{{ trans('entities.pages_name') }}</th>
-                            <th colspan="2" width="8%">{{ trans('entities.pages_revisions_created_by') }}</th>
-                            <th width="15%">{{ trans('entities.pages_revisions_date') }}</th>
-                            <th width="25%">{{ trans('entities.pages_revisions_changelog') }}</th>
-                            <th width="20%">{{ trans('common.actions') }}</th>
-                        </tr>
-                        @foreach($page->revisions as $index => $revision)
-                            <tr>
-                                <td>{{ $revision->revision_number == 0 ? '' : $revision->revision_number }}</td>
-                                <td>{{ $revision->name }}</td>
-                                <td style="line-height: 0;">
-                                    @if($revision->createdBy)
-                                        <img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}">
-                                    @endif
-                                </td>
-                                <td> @if($revision->createdBy) {{ $revision->createdBy->name }} @else {{ trans('common.deleted_user') }} @endif</td>
-                                <td><small>{{ $revision->created_at->formatLocalized('%e %B %Y %H:%M:%S') }} <br> ({{ $revision->created_at->diffForHumans() }})</small></td>
-                                <td>{{ $revision->summary }}</td>
-                                <td class="actions">
-                                    <a href="{{ $revision->getUrl('changes') }}" target="_blank">{{ trans('entities.pages_revisions_changes') }}</a>
-                                    <span class="text-muted">&nbsp;|&nbsp;</span>
+                            <td>{{ $revision->revision_number == 0 ? '' : $revision->revision_number }}</td>
+                            <td>{{ $revision->name }}</td>
+                            <td style="line-height: 0;">
+                                @if($revision->createdBy)
+                                    <img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}">
+                                @endif
+                            </td>
+                            <td> @if($revision->createdBy) {{ $revision->createdBy->name }} @else {{ trans('common.deleted_user') }} @endif</td>
+                            <td><small>{{ $revision->created_at->formatLocalized('%e %B %Y %H:%M:%S') }} <br> ({{ $revision->created_at->diffForHumans() }})</small></td>
+                            <td>{{ $revision->summary }}</td>
+                            <td class="actions">
+                                <a href="{{ $revision->getUrl('changes') }}" target="_blank">{{ trans('entities.pages_revisions_changes') }}</a>
+                                <span class="text-muted">&nbsp;|&nbsp;</span>
 
 
-                                    @if ($index === 0)
-                                        <a target="_blank" href="{{ $page->getUrl() }}"><i>{{ trans('entities.pages_revisions_current') }}</i></a>
-                                    @else
-                                        <a href="{{ $revision->getUrl() }}" target="_blank">{{ trans('entities.pages_revisions_preview') }}</a>
-                                        <span class="text-muted">&nbsp;|&nbsp;</span>
-                                        <a href="{{ $revision->getUrl('restore') }}">{{ trans('entities.pages_revisions_restore') }}</a>
-                                        <span class="text-muted">&nbsp;|&nbsp;</span>
-                                        <div dropdown class="dropdown-container">
-                                            <a dropdown-toggle>{{ trans('common.delete') }}</a>
-                                            <ul>
-                                                <li class="padded"><small class="text-muted">{{trans('entities.revision_delete_confirm')}}</small></li>
-                                                <li>
-                                                    <form action="{{ $revision->getUrl('/delete/') }}" method="POST">
-                                                        {!! csrf_field() !!}
-                                                        <input type="hidden" name="_method" value="DELETE">
-                                                        <button type="submit" class="text-button neg">@icon('delete'){{ trans('common.delete') }}</button>
-                                                    </form>
-                                                </li>
-                                            </ul>
-                                        </div>
-                                    @endif
-                                </td>
-                            </tr>
-                        @endforeach
-                    </table>
+                                @if ($index === 0)
+                                    <a target="_blank" href="{{ $page->getUrl() }}"><i>{{ trans('entities.pages_revisions_current') }}</i></a>
+                                @else
+                                    <a href="{{ $revision->getUrl() }}" target="_blank">{{ trans('entities.pages_revisions_preview') }}</a>
+                                    <span class="text-muted">&nbsp;|&nbsp;</span>
+                                    <a href="{{ $revision->getUrl('restore') }}">{{ trans('entities.pages_revisions_restore') }}</a>
+                                    <span class="text-muted">&nbsp;|&nbsp;</span>
+                                    <div dropdown class="dropdown-container">
+                                        <a dropdown-toggle>{{ trans('common.delete') }}</a>
+                                        <ul>
+                                            <li class="padded"><small class="text-muted">{{trans('entities.revision_delete_confirm')}}</small></li>
+                                            <li>
+                                                <form action="{{ $revision->getUrl('/delete/') }}" method="POST">
+                                                    {!! csrf_field() !!}
+                                                    <input type="hidden" name="_method" value="DELETE">
+                                                    <button type="submit" class="text-button neg">@icon('delete'){{ trans('common.delete') }}</button>
+                                                </form>
+                                            </li>
+                                        </ul>
+                                    </div>
+                                @endif
+                            </td>
+                        </tr>
+                    @endforeach
+                </table>
 
-                @else
-                    <p>{{ trans('entities.pages_revisions_none') }}</p>
-                @endif
-            </div>
+            @else
+                <p>{{ trans('entities.pages_revisions_none') }}</p>
+            @endif
         </div>
 
     </div>
index db2f1462e3d05bedbea27fef66c9677c5efc599c..6858661c412b2d6af3f9d6bc1c9584ad8332b3da 100644 (file)
@@ -1,50 +1,45 @@
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-sm-8 col-xs-5 faded">
-        @include('pages._breadcrumbs', ['page' => $page])
+@section('body')
+
+    <div class="mb-m">
+        @include('partials.breadcrumbs', ['crumbs' => [
+            $page->book,
+            $page->hasChapter() ? $page->chapter : null,
+            $page,
+        ]])
     </div>
-    <div class="col-sm-4 col-xs-7 faded">
-        <div class="action-buttons">
-            <span dropdown class="dropdown-container">
-                <div dropdown-toggle class="text-button text-primary">@icon('export'){{ trans('entities.export') }}</div>
-                <ul class="wide">
-                    <li><a href="{{ $page->getUrl('/export/html') }}" target="_blank">{{ trans('entities.export_html') }} <span class="text-muted float right">.html</span></a></li>
-                    <li><a href="{{ $page->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.export_pdf') }} <span class="text-muted float right">.pdf</span></a></li>
-                    <li><a href="{{ $page->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.export_text') }} <span class="text-muted float right">.txt</span></a></li>
-                </ul>
-            </span>
-            @if(userCan('page-update', $page))
-                <a href="{{ $page->getUrl('/edit') }}" class="text-primary text-button" >@icon('edit'){{ trans('common.edit') }}</a>
-            @endif
-            @if((userCan('page-view', $page) && userCanOnAny('page-create')) || userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page))
-                <div dropdown class="dropdown-container">
-                    <a dropdown-toggle class="text-primary text-button">@icon('more') {{ trans('common.more') }}</a>
-                    <ul>
-                        @if(userCanOnAny('page-create'))
-                            <li><a href="{{ $page->getUrl('/copy') }}" class="text-primary" >@icon('copy'){{ trans('common.copy') }}</a></li>
-                        @endif
-                        @if(userCan('page-delete', $page) && userCan('page-update', $page))
-                            <li><a href="{{ $page->getUrl('/move') }}" class="text-primary" >@icon('folder'){{ trans('common.move') }}</a></li>
-                        @endif
-                        @if(userCan('page-update', $page))
-                            <li><a href="{{ $page->getUrl('/revisions') }}" class="text-primary">@icon('history'){{ trans('entities.revisions') }}</a></li>
-                        @endif
-                        @if(userCan('restrictions-manage', $page))
-                            <li><a href="{{ $page->getUrl('/permissions') }}" class="text-primary">@icon('lock'){{ trans('entities.permissions') }}</a></li>
-                        @endif
-                        @if(userCan('page-delete', $page))
-                            <li><a href="{{ $page->getUrl('/delete') }}" class="text-neg">@icon('delete'){{ trans('common.delete') }}</a></li>
-                        @endif
-                    </ul>
+
+    <div class="content-wrap card">
+        <div class="page-content flex" page-display="{{ $page->id }}">
+
+            <div class="pointer-container" id="pointer">
+                <div class="pointer anim {{ userCan('page-update', $page) ? 'is-page-editable' : ''}}" >
+                    <span class="icon text-primary">@icon('link') @icon('include', ['style' => 'display:none;'])</span>
+                    <span class="input-group">
+                    <input readonly="readonly" type="text" id="pointer-url" placeholder="url">
+                    <button class="button icon" data-clipboard-target="#pointer-url" type="button" title="{{ trans('entities.pages_copy_link') }}">@icon('copy')</button>
+                </span>
+                    @if(userCan('page-update', $page))
+                        <a href="{{ $page->getUrl('/edit') }}" id="pointer-edit" data-edit-href="{{ $page->getUrl('/edit') }}"
+                           class="button icon heading-edit-icon" title="{{ trans('entities.pages_edit_content_link')}}">@icon('edit')</a>
+                    @endif
                 </div>
-            @endif
+            </div>
 
+            @include('pages.page-display')
         </div>
     </div>
+
+    @if ($commentsEnabled)
+        <div class="container small nopad comments-container mb-l">
+            @include('comments.comments', ['page' => $page])
+            <div class="clearfix"></div>
+        </div>
+    @endif
 @stop
 
-@section('sidebar')
+@section('left')
 
     @if($page->tags->count() > 0)
         <section>
@@ -53,8 +48,8 @@
     @endif
 
     @if ($page->attachments->count() > 0)
-        <div class="card">
-            <h3>@icon('attach') {{ trans('entities.pages_attachments') }}</h3>
+        <div id="page-attachments" class="mb-xl">
+            <h5>{{ trans('entities.pages_attachments') }}</h5>
             <div class="body">
                 @foreach($page->attachments as $attachment)
                     <div class="attachment">
     @endif
 
     @if (isset($pageNav) && count($pageNav))
-        <div class="card">
-            <h3>@icon('open-book') {{ trans('entities.pages_navigation') }}</h3>
+        <div id="page-navigation" class="mb-xl">
+            <h5>{{ trans('entities.pages_navigation') }}</h5>
             <div class="body">
                 <div class="sidebar-page-nav menu">
                     @foreach($pageNav as $navItem)
                         <li class="page-nav-item h{{ $navItem['level'] }}">
                             <a href="{{ $navItem['link'] }}">{{ $navItem['text'] }}</a>
+                            <div class="primary-background sidebar-page-nav-bullet"></div>
                         </li>
                     @endforeach
                 </div>
@@ -80,8 +76,8 @@
         </div>
     @endif
 
-    <div class="card entity-details">
-        <h3>@icon('info') {{ trans('common.details') }}</h3>
+    <div id="page-details" class="entity-details mb-xl">
+        <h5>{{ trans('common.details') }}</h5>
         <div class="body text-muted text-small blended-links">
             @include('partials.entity-meta', ['entity' => $page])
 
         </div>
     </div>
 
-    @include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
-
+    @include('partials.book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
 @stop
 
-@section('body-wrap-classes', 'flex-fill columns')
+@section('right')
+    <div class="actions mb-xl">
+        <h5>Actions</h5>
 
-@section('body')
-
-    <div class="page-content flex" page-display="{{ $page->id }}">
+        <div class="icon-list text-primary">
+            {{--Export--}}
+            <div dropdown class="dropdown-container block">
+                <div dropdown-toggle class="icon-list-item">
+                    <span>@icon('export')</span>
+                    <span>{{ trans('entities.export') }}</span>
+                </div>
+                <ul class="wide">
+                    <li><a href="{{ $page->getUrl('/export/html') }}" target="_blank">{{ trans('entities.export_html') }} <span class="text-muted float right">.html</span></a></li>
+                    <li><a href="{{ $page->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.export_pdf') }} <span class="text-muted float right">.pdf</span></a></li>
+                    <li><a href="{{ $page->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.export_text') }} <span class="text-muted float right">.txt</span></a></li>
+                </ul>
+            </div>
 
-        <div class="pointer-container" id="pointer">
-            <div class="pointer anim {{ userCan('page-update', $page) ? 'is-page-editable' : ''}}" >
-                <span class="icon text-primary">@icon('link') @icon('include', ['style' => 'display:none;'])</span>
-                <span class="input-group">
-                    <input readonly="readonly" type="text" id="pointer-url" placeholder="url">
-                    <button class="button icon" data-clipboard-target="#pointer-url" type="button" title="{{ trans('entities.pages_copy_link') }}">@icon('copy')</button>
-                </span>
-                @if(userCan('page-update', $page))
-                    <a href="{{ $page->getUrl('/edit') }}" id="pointer-edit" data-edit-href="{{ $page->getUrl('/edit') }}"
-                        class="button icon heading-edit-icon" title="{{ trans('entities.pages_edit_content_link')}}">@icon('edit')</a>
+            {{--User Actions--}}
+            @if(userCan('page-update', $page))
+                <a href="{{ $page->getUrl('/edit') }}" class="icon-list-item">
+                    <span>@icon('edit')</span>
+                    <span>{{ trans('common.edit') }}</span>
+                </a>
+            @endif
+            @if(userCanOnAny('page-create'))
+                <a href="{{ $page->getUrl('/copy') }}" class="icon-list-item">
+                    <span>@icon('copy')</span>
+                    <span>{{ trans('common.copy') }}</span>
+                </a>
+            @endif
+            @if(userCan('page-update', $page))
+                @if(userCan('page-delete', $page))
+                       <a href="{{ $page->getUrl('/move') }}" class="icon-list-item">
+                           <span>@icon('folder')</span>
+                           <span>{{ trans('common.move') }}</span>
+                       </a>
                 @endif
-            </div>
+                <a href="{{ $page->getUrl('/revisions') }}" class="icon-list-item">
+                    <span>@icon('history')</span>
+                    <span>{{ trans('entities.revisions') }}</span>
+                </a>
+            @endif
+            @if(userCan('restrictions-manage', $page))
+                <a href="{{ $page->getUrl('/permissions') }}" class="icon-list-item">
+                    <span>@icon('lock')</span>
+                    <span>{{ trans('entities.permissions') }}</span>
+                </a>
+            @endif
+            @if(userCan('page-delete', $page))
+                <a href="{{ $page->getUrl('/delete') }}" class="icon-list-item">
+                    <span>@icon('delete')</span>
+                    <span>{{ trans('common.delete') }}</span>
+                </a>
+            @endif
         </div>
 
-        @include('pages/page-display')
     </div>
-
-    @if ($commentsEnabled)
-      <div class="container small nopad comments-container">
-          @include('comments/comments', ['page' => $page])
-      </div>
-    @endif
 @stop
diff --git a/resources/views/partials/_header-dropdown.blade.php b/resources/views/partials/_header-dropdown.blade.php
deleted file mode 100644 (file)
index 176e007..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<div class="dropdown-container" dropdown>
-    <span class="user-name" dropdown-toggle>
-        <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
-        <span class="name">{{ $currentUser->getShortName(9) }}</span> @icon('caret-down')
-    </span>
-    <ul>
-        <li>
-            <a href="{{ baseUrl("/user/{$currentUser->id}") }}" class="text-primary">@icon('user') {{ trans('common.view_profile') }}</a>
-        </li>
-        <li>
-            <a href="{{ baseUrl("/settings/users/{$currentUser->id}") }}" class="text-primary">@icon('edit') {{ trans('common.edit_profile') }}</a>
-        </li>
-        <li>
-            <a href="{{ baseUrl('/logout') }}" class="text-neg">@icon('logout') {{ trans('auth.logout') }}</a>
-        </li>
-    </ul>
-</div>
\ No newline at end of file
index 1dbfc9de81f1e00a705ff97d763b53f0e29e546f..39fb35fe2728c4c50c2ee5392414f9dfdee0a5c8 100644 (file)
@@ -1,13 +1,13 @@
 
 {{--Requires an Activity item with the name $activity passed in--}}
 
-@if($activity->user)
-    <div class="left">
-        <img class="avatar" src="{{ $activity->user->getAvatar(30) }}" alt="{{ $activity->user->name }}">
-    </div>
-@endif
+<div>
+    @if($activity->user)
+    <img class="avatar" src="{{ $activity->user->getAvatar(30) }}" alt="{{ $activity->user->name }}">
+    @endif
+</div>
 
-<div class="right" v-pre>
+<div v-pre>
     @if($activity->user)
         <a href="{{ $activity->user->getProfileUrl() }}">{{ $activity->user->name }}</a>
     @else
index 0f895cf59fed2d620f79d21b9fcad47fc4ce2306..360162b2fd185b31f1c40e9194249a180f01b16f 100644 (file)
@@ -1,36 +1,22 @@
-<div class="card book-tree" v-pre>
-    <h3>@icon('book') {{ trans('entities.books_navigation') }}</h3>
-    <div class="body">
-        <ul class="sidebar-page-list menu">
+<div id="book-tree" class="book-tree mb-xl" v-pre>
+    <h5>{{ trans('entities.books_navigation') }}</h5>
+    @if (userCan('view', $book))
+        <div class="entity-list">
+            @include('partials.entity-list-item-basic', ['entity' => $book, 'classes' => ($current->matches($book)? 'selected' : '')])
+        </div>
+    @endif
 
-            @if (userCan('view', $book))
-                <li class="book-header"><a href="{{ $book->getUrl() }}" class="book {{ $current->matches($book)? 'selected' : '' }}">@icon('book'){{$book->name}}</a></li>
-            @endif
+    <ul class="sidebar-page-list menu entity-list">
 
-            @foreach($sidebarTree as $bookChild)
-                <li class="list-item-{{ $bookChild->getClassName() }} {{ $bookChild->getClassName() }} {{ $bookChild->isA('page') && $bookChild->draft ? 'draft' : '' }}">
-                    <a href="{{ $bookChild->getUrl() }}" class="{{ $bookChild->getClassName() }} {{ $current->matches($bookChild)? 'selected' : '' }}">
-                        @if($bookChild->isA('chapter'))@icon('chapter')@else @icon('page')@endif{{ $bookChild->name }}
-                    </a>
+        @foreach($sidebarTree as $bookChild)
+            <li class="list-item-{{ $bookChild->getClassName() }} {{ $bookChild->getClassName() }} {{ $bookChild->isA('page') && $bookChild->draft ? 'draft' : '' }}">
+                @include('partials.entity-list-item-basic', ['entity' => $bookChild, 'classes' => $current->matches($bookChild)? 'selected' : ''])
 
-                    @if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
-                        <p chapter-toggle class="text-muted @if($bookChild->matchesOrContains($current)) open @endif">
-                            @icon('caret-right') @icon('page') <span>{{ trans_choice('entities.x_pages', $bookChild->pages->count()) }}</span>
-                        </p>
-                        <ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
-                            @foreach($bookChild->pages as $childPage)
-                                <li class="list-item-page {{ $childPage->isA('page') && $childPage->draft ? 'draft' : '' }}">
-                                    <a href="{{ $childPage->getUrl() }}" class="page {{ $current->matches($childPage)? 'selected' : '' }}">
-                                        @icon('page') {{ $childPage->name }}
-                                    </a>
-                                </li>
-                            @endforeach
-                        </ul>
-                    @endif
+                @if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
+                    @include('chapters.child-menu', ['chapter' => $bookChild, 'current' => $current])
+                @endif
 
-
-                </li>
-            @endforeach
-        </ul>
-    </div>
+            </li>
+        @endforeach
+    </ul>
 </div>
\ No newline at end of file
diff --git a/resources/views/partials/breadcrumb-listing.blade.php b/resources/views/partials/breadcrumb-listing.blade.php
new file mode 100644 (file)
index 0000000..3dea320
--- /dev/null
@@ -0,0 +1,13 @@
+<div class="breadcrumb-listing" dropdown breadcrumb-listing="{{ $entity->getType() }}:{{ $entity->id }}">
+    <div class="breadcrumb-listing-toggle" dropdown-toggle>
+        <div class="separator">@icon('chevron-right')</div>
+    </div>
+    <div dropdown-menu class="breadcrumb-listing-dropdown card">
+        <div class="breadcrumb-listing-search">
+            @icon('search')
+            <input autocomplete="off" type="text" name="entity-search">
+        </div>
+        @include('partials.loading-icon')
+        <div class="breadcrumb-listing-entity-list px-m"></div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/resources/views/partials/breadcrumbs.blade.php b/resources/views/partials/breadcrumbs.blade.php
new file mode 100644 (file)
index 0000000..bf77a40
--- /dev/null
@@ -0,0 +1,45 @@
+<div class="breadcrumbs text-center">
+    <?php $breadcrumbCount = 0; ?>
+
+    {{--Show top level item--}}
+    @if (count($crumbs) > 0 && array_first($crumbs) instanceof  \BookStack\Entities\Book)
+        <a href="{{  baseUrl('/books')  }}" class="icon-list-item">
+            <span>@icon('books')</span>
+            <span>{{ trans('entities.books') }}</span>
+        </a>
+        <?php $breadcrumbCount++; ?>
+    @endif
+
+    @foreach($crumbs as $key => $crumb)
+        <?php $isEntity = ($crumb instanceof \BookStack\Entities\Entity); ?>
+
+        @if (is_null($crumb))
+            <?php continue; ?>
+        @endif
+        @if ($breadcrumbCount !== 0 && !$isEntity)
+            <div class="separator">@icon('chevron-right')</div>
+        @endif
+
+        @if (is_string($crumb))
+            <a href="{{  baseUrl($key)  }}">
+                {{ $crumb }}
+            </a>
+        @elseif (is_array($crumb))
+            <a href="{{  baseUrl($key)  }}" class="icon-list-item">
+                <span>@icon($crumb['icon'])</span>
+                <span>{{ $crumb['text'] }}</span>
+            </a>
+        @elseif($isEntity && userCan('view', $crumb))
+            @if($breadcrumbCount > 0)
+                @include('partials.breadcrumb-listing', ['entity' => $crumb])
+            @endif
+            <a href="{{ $crumb->getUrl() }}" class="text-{{$crumb->getType()}} icon-list-item">
+                <span>@icon($crumb->getType())</span>
+                <span>
+                    {{ $crumb->getShortName() }}
+                </span>
+            </a>
+        @endif
+        <?php $breadcrumbCount++; ?>
+    @endforeach
+</div>
\ No newline at end of file
diff --git a/resources/views/partials/entity-list-basic.blade.php b/resources/views/partials/entity-list-basic.blade.php
new file mode 100644 (file)
index 0000000..dc5c3f3
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="entity-list {{ $style ?? '' }}">
+    @if(count($entities) > 0)
+        @foreach($entities as $index => $entity)
+            @include('partials.entity-list-item-basic', ['entity' => $entity])
+        @endforeach
+    @else
+        <p class="text-muted empty-text">
+            {{ $emptyText ?? trans('common.no_items') }}
+        </p>
+    @endif
+</div>
\ No newline at end of file
diff --git a/resources/views/partials/entity-list-item-basic.blade.php b/resources/views/partials/entity-list-item-basic.blade.php
new file mode 100644 (file)
index 0000000..c4942c7
--- /dev/null
@@ -0,0 +1,8 @@
+<?php $type = $entity->getType(); ?>
+<a href="{{ $entity->getUrl() }}" class="{{$type}} {{$type === 'page' && $entity->draft ? 'draft' : ''}} {{$classes ?? ''}} entity-list-item" data-entity-type="{{$type}}" data-entity-id="{{$entity->id}}">
+    <span class="icon text-{{$type}}">@icon($type)</span>
+    <div class="content">
+            <h4 class="entity-list-item-name break-text">{{ $entity->name }}</h4>
+            {{ $slot ?? '' }}
+    </div>
+</a>
\ No newline at end of file
diff --git a/resources/views/partials/entity-list-item.blade.php b/resources/views/partials/entity-list-item.blade.php
new file mode 100644 (file)
index 0000000..d971ae0
--- /dev/null
@@ -0,0 +1,5 @@
+@component('partials.entity-list-item-basic', ['entity' => $entity])
+<div class="entity-item-snippet">
+    <p class="text-muted break-text">{{ $entity->getExcerpt() }}</p>
+</div>
+@endcomponent
\ No newline at end of file
index 371f38d71c6b5e0c7a9de5a09d1c5e61f7ec38cc..b2a26f1e497465169c5ccdb30fbdc25c66f6a678 100644 (file)
@@ -1,25 +1,12 @@
 
-<div class="entity-list @if(isset($style)){{ $style }}@endif">
+<div class="entity-list {{ $style ?? '' }}">
     @if(count($entities) > 0)
         @foreach($entities as $index => $entity)
-            @if($entity->isA('page'))
-                @include('pages/list-item', ['page' => $entity])
-            @elseif($entity->isA('book'))
-                @include('books/list-item', ['book' => $entity])
-            @elseif($entity->isA('chapter'))
-                @include('chapters/list-item', ['chapter' => $entity, 'hidePages' => true])
-            @elseif($entity->isA('bookshelf'))
-                @include('shelves/list-item', ['bookshelf' => $entity])
-            @endif
-
-            @if($index !== count($entities) - 1)
-                <hr>
-            @endif
-
+            @include('partials.entity-list-item', ['entity' => $entity])
         @endforeach
     @else
         <p class="text-muted empty-text">
-            {{ $emptyText or trans('common.no_items') }}
+            {{ $emptyText ?? trans('common.no_items') }}
         </p>
     @endif
 </div>
\ No newline at end of file
diff --git a/resources/views/partials/sort.blade.php b/resources/views/partials/sort.blade.php
new file mode 100644 (file)
index 0000000..d7ed4d9
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+    $selectedSort = (isset($sort) && array_key_exists($sort, $options)) ? $sort : array_keys($options)[0];
+    $order = (isset($order) && in_array($order, ['asc', 'desc'])) ? $order : 'asc';
+?>
+<div class="list-sort-container" list-sort-control>
+    <div class="list-sort-label">{{ trans('common.sort') }}</div>
+    <form action="{{ baseUrl("/settings/users/{$currentUser->id}/change-sort/{$type}") }}" method="post">
+
+        {!! csrf_field() !!}
+        {!! method_field('PATCH') !!}
+        <input type="hidden" value="{{ $selectedSort }}" name="sort">
+        <input type="hidden" value="{{ $order }}" name="order">
+
+        <div class="list-sort">
+            <div class="list-sort-type dropdown-container" dropdown>
+                <div dropdown-toggle>{{ $options[$selectedSort] }}</div>
+                <ul>
+                    @foreach($options as $key => $label)
+                        <li @if($key === $selectedSort) class="active" @endif><a href="#" data-sort-value="{{$key}}">{{ $label }}</a></li>
+                    @endforeach
+                </ul>
+            </div>
+            <div class="list-sort-dir" data-sort-dir>
+                @if($order === 'desc')
+                    @icon('sort-up')
+                @else
+                    @icon('sort-down')
+                @endif
+            </div>
+        </div>
+    </form>
+</div>
\ No newline at end of file
diff --git a/resources/views/partials/view-toggle.blade.php b/resources/views/partials/view-toggle.blade.php
new file mode 100644 (file)
index 0000000..9eb00e1
--- /dev/null
@@ -0,0 +1,18 @@
+<div>
+    <form action="{{ baseUrl("/settings/users/{$currentUser->id}/switch-${type}-view") }}" method="POST" class="inline">
+        {!! csrf_field() !!}
+        {!! method_field('PATCH') !!}
+        <input type="hidden" value="{{ $view === 'list'? 'grid' : 'list' }}" name="view_type">
+        @if ($view === 'list')
+            <button type="submit" class="icon-list-item text-primary">
+                <span class="icon">@icon('grid')</span>
+                <span>{{ trans('common.grid_view') }}</span>
+            </button>
+        @else
+            <button type="submit" class="icon-list-item text-primary">
+                <span>@icon('list')</span>
+                <span>{{ trans('common.list_view') }}</span>
+            </button>
+        @endif
+    </form>
+</div>
\ No newline at end of file
diff --git a/resources/views/public.blade.php b/resources/views/public.blade.php
deleted file mode 100644 (file)
index f6135cd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<!DOCTYPE html>
-<html class="shaded">
-<head>
-    <title>{{ setting('app-name') }}</title>
-
-    <!-- Meta -->
-    <meta name="viewport" content="width=device-width">
-    <meta name="token" content="{{ csrf_token() }}">
-    <meta name="base-url" content="{{ baseUrl('/') }}">
-    <meta charset="utf-8">
-
-    <!-- Styles and Fonts -->
-    <link rel="stylesheet" href="{{ versioned_asset('dist/styles.css') }}">
-    <link rel="stylesheet" media="print" href="{{ versioned_asset('dist/print-styles.css') }}">
-
-    <!-- Scripts -->
-    @include('partials/custom-styles')
-
-    <!-- Custom user content -->
-    @if(setting('app-custom-head'))
-        {!! setting('app-custom-head') !!}
-    @endif
-</head>
-<body class="@yield('body-class')">
-
-@include('partials.notifications')
-
-<header id="header">
-    <div class="container fluid">
-        <div class="row">
-            <div class="col-sm-6">
-
-                <a href="{{ baseUrl('/') }}" class="logo">
-                    @if(setting('app-logo', '') !== 'none')
-                        <img class="logo-image" src="{{ setting('app-logo', '') === '' ? baseUrl('/logo.png') : baseUrl(setting('app-logo', '')) }}" alt="Logo">
-                    @endif
-                    @if (setting('app-name-header'))
-                        <span class="logo-text">{{ setting('app-name') }}</span>
-                    @endif
-                </a>
-            </div>
-            <div class="col-sm-6">
-                <div class="float right">
-                    <div class="links text-center">
-                        @yield('header-buttons')
-                    </div>
-                    @if(isset($signedIn) && $signedIn)
-                        @include('partials._header-dropdown', ['currentUser' => $currentUser])
-                    @endif
-                </div>
-            </div>
-        </div>
-    </div>
-</header>
-
-<section class="container">
-    @yield('content')
-</section>
-
-<script src="{{ versioned_asset('dist/app.js') }}"></script>
-</body>
-</html>
index a952079d566453b3893603cbfc81fd39ddce4103..6a6c9d198d10248b30003fdb4442f047a0fde817 100644 (file)
-@extends('sidebar-layout')
+@extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        <div class="breadcrumbs">
-            <a href="{{ baseUrl("/search?term=" . urlencode($searchTerm)) }}" class="text-button">@icon('search'){{ trans('entities.search_for_term', ['term' => $searchTerm]) }}</a>
-        </div>
-    </div>
-@stop
-
-@section('container-attrs')
-    id="search-system"
-@stop
+@section('body')
+    <input type="hidden" name="searchTerm" value="{{$searchTerm}}">
 
-@section('sidebar')
-    <div class="card">
-        <h3>{{ trans('entities.search_filters') }}</h3>
-
-        <div class="body">
-            <form v-on:submit="updateSearch" v-cloak class="v-cloak anim fadeIn">
-                <h6 class="text-muted">{{ trans('entities.search_content_type') }}</h6>
-                <div class="form-group">
-                    <label class="inline checkbox text-page"><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page">{{ trans('entities.page') }}</label>
-                    <label class="inline checkbox text-chapter"><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter">{{ trans('entities.chapter') }}</label>
-                    <br>
-                    <label class="inline checkbox text-book"><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book">{{ trans('entities.book') }}</label>
-                    <label class="inline checkbox text-bookshelf"><input type="checkbox" v-on:change="typeChange" v-model="search.type.bookshelf" value="bookshelf">{{ trans('entities.shelf') }}</label>
-                </div>
+    <div class="container" id="search-system">
 
-                <h6 class="text-muted">{{ trans('entities.search_exact_matches') }}</h6>
-                <table cellpadding="0" cellspacing="0" border="0" class="no-style">
-                    <tr v-for="(term, i) in search.exactTerms">
-                        <td style="padding: 0 12px 6px 0;">
-                            <input class="exact-input outline" v-on:input="exactChange" type="text" v-model="search.exactTerms[i]"></td>
-                        <td>
-                            <button type="button" class="text-neg text-button" v-on:click="removeExact(i)">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td colspan="2">
-                            <button type="button" class="text-button" v-on:click="addExact">
-                                @icon('add-circle'){{ trans('common.add') }}
-                            </button>
-                        </td>
-                    </tr>
-                </table>
-
-                <h6 class="text-muted">{{ trans('entities.search_tags') }}</h6>
-                <table cellpadding="0" cellspacing="0" border="0" class="no-style">
-                    <tr v-for="(term, i) in search.tagTerms">
-                        <td style="padding: 0 12px 6px 0;">
-                            <input class="tag-input outline" v-on:input="tagChange" type="text" v-model="search.tagTerms[i]"></td>
-                        <td>
-                            <button type="button" class="text-neg text-button" v-on:click="removeTag(i)">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td colspan="2">
-                            <button type="button" class="text-button" v-on:click="addTag">
-                                @icon('add-circle'){{ trans('common.add') }}
-                            </button>
-                        </td>
-                    </tr>
-                </table>
-
-               @if(signedInUser())
-                    <h6 class="text-muted">{{ trans('entities.search_options') }}</h6>
-                    <label class="checkbox">
-                        <input type="checkbox" v-on:change="optionChange('viewed_by_me')"
-                               v-model="search.option.viewed_by_me" value="page">
-                        {{ trans('entities.search_viewed_by_me') }}
-                    </label>
-                    <label class="checkbox">
-                        <input type="checkbox" v-on:change="optionChange('not_viewed_by_me')"
-                               v-model="search.option.not_viewed_by_me" value="page">
-                        {{ trans('entities.search_not_viewed_by_me') }}
-                    </label>
-                    <label class="checkbox">
-                        <input type="checkbox" v-on:change="optionChange('is_restricted')"
-                               v-model="search.option.is_restricted" value="page">
-                        {{ trans('entities.search_permissions_set') }}
-                    </label>
-                    <label class="checkbox">
-                        <input type="checkbox" v-on:change="optionChange('created_by:me')"
-                               v-model="search.option['created_by:me']" value="page">
-                        {{ trans('entities.search_created_by_me') }}
-                    </label>
-                    <label class="checkbox">
-                        <input type="checkbox" v-on:change="optionChange('updated_by:me')"
-                               v-model="search.option['updated_by:me']" value="page">
-                        {{ trans('entities.search_updated_by_me') }}
-                    </label>
-                @endif
-
-                <h6 class="text-muted">{{ trans('entities.search_date_options') }}</h6>
-                <table cellpadding="0" cellspacing="0" border="0" class="no-style form-table">
-                    <tr>
-                        <td width="200">{{ trans('entities.search_updated_after') }}</td>
-                        <td width="80">
-                            <button type="button" class="text-button" v-if="!search.dates.updated_after"
-                                    v-on:click="enableDate('updated_after')">{{ trans('entities.search_set_date') }}</button>
-
-                        </td>
-                    </tr>
-                    <tr v-if="search.dates.updated_after">
-                        <td>
-                            <input v-if="search.dates.updated_after" class="tag-input"
-                                   v-on:input="dateChange('updated_after')" type="date" v-model="search.dates.updated_after"
-                                   pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
-                        </td>
-                        <td>
-                            <button v-if="search.dates.updated_after" type="button" class="text-neg text-button"
-                                    v-on:click="dateRemove('updated_after')">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td>{{ trans('entities.search_updated_before') }}</td>
-                        <td>
-                            <button type="button" class="text-button" v-if="!search.dates.updated_before"
-                                    v-on:click="enableDate('updated_before')">{{ trans('entities.search_set_date') }}</button>
-
-                        </td>
-                    </tr>
-                    <tr v-if="search.dates.updated_before">
-                        <td>
-                            <input v-if="search.dates.updated_before" class="tag-input"
-                                   v-on:input="dateChange('updated_before')" type="date" v-model="search.dates.updated_before"
-                                   pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
-                        </td>
-                        <td>
-                            <button v-if="search.dates.updated_before" type="button" class="text-neg text-button"
-                                    v-on:click="dateRemove('updated_before')">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td>{{ trans('entities.search_created_after') }}</td>
-                        <td>
-                            <button type="button" class="text-button" v-if="!search.dates.created_after"
-                                    v-on:click="enableDate('created_after')">{{ trans('entities.search_set_date') }}</button>
-
-                        </td>
-                    </tr>
-                    <tr v-if="search.dates.created_after">
-                        <td>
-                            <input v-if="search.dates.created_after" class="tag-input"
-                                   v-on:input="dateChange('created_after')" type="date" v-model="search.dates.created_after"
-                                   pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
-                        </td>
-                        <td>
-                            <button v-if="search.dates.created_after" type="button" class="text-neg text-button"
-                                    v-on:click="dateRemove('created_after')">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                    <tr>
-                        <td>{{ trans('entities.search_created_before') }}</td>
-                        <td>
-                            <button type="button" class="text-button" v-if="!search.dates.created_before"
-                                    v-on:click="enableDate('created_before')">{{ trans('entities.search_set_date') }}</button>
-
-                        </td>
-                    </tr>
-                    <tr v-if="search.dates.created_before">
-                        <td>
-                            <input v-if="search.dates.created_before" class="tag-input"
-                                   v-on:input="dateChange('created_before')" type="date" v-model="search.dates.created_before"
-                                   pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
-                        </td>
-                        <td>
-                            <button v-if="search.dates.created_before" type="button" class="text-neg text-button"
-                                    v-on:click="dateRemove('created_before')">
-                                @icon('close')
-                            </button>
-                        </td>
-                    </tr>
-                </table>
-
-
-                <button type="submit" class="button primary">{{ trans('entities.search_update') }}</button>
-            </form>
+        <div class="my-s">
+            &nbsp;
         </div>
 
-    </div>
-@stop
-
-@section('body')
+        <div class="grid right-focus reverse-collapse large-gap">
+            <div>
+                <div>
+                    <h5>{{ trans('entities.search_filters') }}</h5>
+
+                    <form v-on:submit="updateSearch" v-cloak class="v-cloak anim fadeIn">
+                        <h6 class="text-muted">{{ trans('entities.search_content_type') }}</h6>
+                        <div class="form-group">
+                            <label class="inline checkbox text-page"><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page">{{ trans('entities.page') }}</label>
+                            <label class="inline checkbox text-chapter"><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter">{{ trans('entities.chapter') }}</label>
+                            <br>
+                            <label class="inline checkbox text-book"><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book">{{ trans('entities.book') }}</label>
+                            <label class="inline checkbox text-bookshelf"><input type="checkbox" v-on:change="typeChange" v-model="search.type.bookshelf" value="bookshelf">{{ trans('entities.shelf') }}</label>
+                        </div>
+
+                        <h6 class="text-muted">{{ trans('entities.search_exact_matches') }}</h6>
+                        <table cellpadding="0" cellspacing="0" border="0" class="no-style">
+                            <tr v-for="(term, i) in search.exactTerms">
+                                <td style="padding: 0 12px 6px 0;">
+                                    <input class="exact-input outline" v-on:input="exactChange" type="text" v-model="search.exactTerms[i]"></td>
+                                <td>
+                                    <button type="button" class="text-neg text-button" v-on:click="removeExact(i)">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td colspan="2">
+                                    <button type="button" class="text-button" v-on:click="addExact">
+                                        @icon('add-circle'){{ trans('common.add') }}
+                                    </button>
+                                </td>
+                            </tr>
+                        </table>
+
+                        <h6 class="text-muted">{{ trans('entities.search_tags') }}</h6>
+                        <table cellpadding="0" cellspacing="0" border="0" class="no-style">
+                            <tr v-for="(term, i) in search.tagTerms">
+                                <td style="padding: 0 12px 6px 0;">
+                                    <input class="tag-input outline" v-on:input="tagChange" type="text" v-model="search.tagTerms[i]"></td>
+                                <td>
+                                    <button type="button" class="text-neg text-button" v-on:click="removeTag(i)">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td colspan="2">
+                                    <button type="button" class="text-button" v-on:click="addTag">
+                                        @icon('add-circle'){{ trans('common.add') }}
+                                    </button>
+                                </td>
+                            </tr>
+                        </table>
+
+                        @if(signedInUser())
+                            <h6 class="text-muted">{{ trans('entities.search_options') }}</h6>
+                            <label class="checkbox">
+                                <input type="checkbox" v-on:change="optionChange('viewed_by_me')"
+                                       v-model="search.option.viewed_by_me" value="page">
+                                {{ trans('entities.search_viewed_by_me') }}
+                            </label>
+                            <label class="checkbox">
+                                <input type="checkbox" v-on:change="optionChange('not_viewed_by_me')"
+                                       v-model="search.option.not_viewed_by_me" value="page">
+                                {{ trans('entities.search_not_viewed_by_me') }}
+                            </label>
+                            <label class="checkbox">
+                                <input type="checkbox" v-on:change="optionChange('is_restricted')"
+                                       v-model="search.option.is_restricted" value="page">
+                                {{ trans('entities.search_permissions_set') }}
+                            </label>
+                            <label class="checkbox">
+                                <input type="checkbox" v-on:change="optionChange('created_by:me')"
+                                       v-model="search.option['created_by:me']" value="page">
+                                {{ trans('entities.search_created_by_me') }}
+                            </label>
+                            <label class="checkbox">
+                                <input type="checkbox" v-on:change="optionChange('updated_by:me')"
+                                       v-model="search.option['updated_by:me']" value="page">
+                                {{ trans('entities.search_updated_by_me') }}
+                            </label>
+                        @endif
+
+                        <h6 class="text-muted">{{ trans('entities.search_date_options') }}</h6>
+                        <table cellpadding="0" cellspacing="0" border="0" class="no-style form-table">
+                            <tr>
+                                <td width="200">{{ trans('entities.search_updated_after') }}</td>
+                                <td width="80">
+                                    <button type="button" class="text-button" v-if="!search.dates.updated_after"
+                                            v-on:click="enableDate('updated_after')">{{ trans('entities.search_set_date') }}</button>
+
+                                </td>
+                            </tr>
+                            <tr v-if="search.dates.updated_after">
+                                <td>
+                                    <input v-if="search.dates.updated_after" class="tag-input"
+                                           v-on:input="dateChange('updated_after')" type="date" v-model="search.dates.updated_after"
+                                           pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
+                                </td>
+                                <td>
+                                    <button v-if="search.dates.updated_after" type="button" class="text-neg text-button"
+                                            v-on:click="dateRemove('updated_after')">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>{{ trans('entities.search_updated_before') }}</td>
+                                <td>
+                                    <button type="button" class="text-button" v-if="!search.dates.updated_before"
+                                            v-on:click="enableDate('updated_before')">{{ trans('entities.search_set_date') }}</button>
+
+                                </td>
+                            </tr>
+                            <tr v-if="search.dates.updated_before">
+                                <td>
+                                    <input v-if="search.dates.updated_before" class="tag-input"
+                                           v-on:input="dateChange('updated_before')" type="date" v-model="search.dates.updated_before"
+                                           pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
+                                </td>
+                                <td>
+                                    <button v-if="search.dates.updated_before" type="button" class="text-neg text-button"
+                                            v-on:click="dateRemove('updated_before')">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>{{ trans('entities.search_created_after') }}</td>
+                                <td>
+                                    <button type="button" class="text-button" v-if="!search.dates.created_after"
+                                            v-on:click="enableDate('created_after')">{{ trans('entities.search_set_date') }}</button>
+
+                                </td>
+                            </tr>
+                            <tr v-if="search.dates.created_after">
+                                <td>
+                                    <input v-if="search.dates.created_after" class="tag-input"
+                                           v-on:input="dateChange('created_after')" type="date" v-model="search.dates.created_after"
+                                           pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
+                                </td>
+                                <td>
+                                    <button v-if="search.dates.created_after" type="button" class="text-neg text-button"
+                                            v-on:click="dateRemove('created_after')">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>{{ trans('entities.search_created_before') }}</td>
+                                <td>
+                                    <button type="button" class="text-button" v-if="!search.dates.created_before"
+                                            v-on:click="enableDate('created_before')">{{ trans('entities.search_set_date') }}</button>
+
+                                </td>
+                            </tr>
+                            <tr v-if="search.dates.created_before">
+                                <td>
+                                    <input v-if="search.dates.created_before" class="tag-input"
+                                           v-on:input="dateChange('created_before')" type="date" v-model="search.dates.created_before"
+                                           pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
+                                </td>
+                                <td>
+                                    <button v-if="search.dates.created_before" type="button" class="text-neg text-button"
+                                            v-on:click="dateRemove('created_before')">
+                                        @icon('close')
+                                    </button>
+                                </td>
+                            </tr>
+                        </table>
+
+
+                        <button type="submit" class="button primary">{{ trans('entities.search_update') }}</button>
+                    </form>
 
-    <div class="container small" v-pre>
-        <input type="hidden" name="searchTerm" value="{{$searchTerm}}">
+                </div>
+            </div>
+            <div>
+                <div v-pre class="card content-wrap">
+                    <h1 class="list-heading">{{ trans('entities.search_results') }}</h1>
+                    <h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
+                    <div class="book-contents">
+                        @include('partials.entity-list', ['entities' => $entities])
+                    </div>
+                    @if($hasNextPage)
+                        <div class="text-right mt-m">
+                            <a href="{{ $nextPageLink }}" class="button outline">{{ trans('entities.search_more') }}</a>
+                        </div>
+                    @endif
+                </div>
+            </div>
+        </div>
 
-        <h1>{{ trans('entities.search_results') }}</h1>
-        <h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
-        @include('partials/entity-list', ['entities' => $entities])
-        @if ($hasNextPage)
-            <a href="{{ $nextPageLink }}" class="button">{{ trans('entities.search_more') }}</a>
-        @endif
     </div>
 @stop
index 26b81899e8bdb775c43ae9e6bd5dd1a576f66c9e..d063539ea69c80a9a44df6d3e6086d7486e2d767 100644 (file)
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'settings'])
-@stop
-
 @section('body')
-<div class="container small">
+    <div class="container small">
 
-    <div class="text-right text-muted container">
-        <br>
-        BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
-    </div>
+        <div class="grid left-focus v-center">
+            <div class="py-m">
+                @include('settings.navbar', ['selected' => 'settings'])
+            </div>
+            <div class="text-right mb-l px-m">
+                <br>
+                BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
+            </div>
+        </div>
 
-    <div class="card">
-        <h3>@icon('settings') {{ trans('settings.app_settings') }}</h3>
-        <div class="body">
+        <div class="card content-wrap auto-height">
+            <h2 class="list-heading">{{ trans('settings.app_features_security') }}</h2>
             <form action="{{ baseUrl("/settings") }}" method="POST">
-            {!! csrf_field() !!}
-                <div class="row">
+                {!! csrf_field() !!}
 
-                    <div class="col-md-6">
-                        <div class="form-group">
-                            <label for="setting-app-name">{{ trans('settings.app_name') }}</label>
-                            <p class="small">{{ trans('settings.app_name_desc') }}</p>
-                            <input type="text" value="{{ setting('app-name', 'BookStack') }}" name="setting-app-name" id="setting-app-name">
-                        </div>
-                        <div class="form-group">
-                            <label>{{ trans('settings.app_name_header') }}</label>
-                            @include('components.toggle-switch', ['name' => 'setting-app-name-header', 'value' => setting('app-name-header')])
+                <div class="setting-list">
+
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label for="setting-app-public" class="setting-list-label">{{ trans('settings.app_public_access') }}</label>
+                            <p class="small">{!! trans('settings.app_public_access_desc') !!}</p>
+                            @if(userCan('users-manage'))
+                                <p class="small mb-none">
+                                    <a href="{{ baseUrl($guestUser->getEditUrl()) }}">{!! trans('settings.app_public_access_desc_guest') !!}</a>
+                                </p>
+                            @endif
                         </div>
-                        <div class="form-group">
-                            <label for="setting-app-public">{{ trans('settings.app_public_viewing') }}</label>
-                            @include('components.toggle-switch', ['name' => 'setting-app-public', 'value' => setting('app-public')])
+                        <div>
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-app-public',
+                                'value' => setting('app-public'),
+                                'label' => trans('settings.app_public_access_toggle'),
+                            ])
                         </div>
-                        <div class="form-group">
-                            <label>{{ trans('settings.app_secure_images') }}</label>
+                    </div>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.app_secure_images') }}</label>
                             <p class="small">{{ trans('settings.app_secure_images_desc') }}</p>
-                            @include('components.toggle-switch', ['name' => 'setting-app-secure-images', 'value' => setting('app-secure-images')])
                         </div>
-                        <div class="form-group">
-                            <label>{{ trans('settings.app_disable_comments') }}</label>
-                            <p class="small">{{ trans('settings.app_disable_comments_desc') }}</p>
-                            @include('components.toggle-switch', ['name' => 'setting-app-disable-comments', 'value' => setting('app-disable-comments')])
+                        <div>
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-app-secure-images',
+                                'value' => setting('app-secure-images'),
+                                'label' => trans('settings.app_secure_images_toggle'),
+                            ])
+                        </div>
+                    </div>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.app_disable_comments') }}</label>
+                            <p class="small">{!! trans('settings.app_disable_comments_desc') !!}</p>
+                        </div>
+                        <div>
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-app-disable-comments',
+                                'value' => setting('app-disable-comments'),
+                                'label' => trans('settings.app_disable_comments_toggle'),
+                            ])
+                        </div>
+                    </div>
+
+
+                </div>
+
+                <div class="form-group text-right">
+                    <button type="submit" class="button primary">{{ trans('settings.settings_save') }}</button>
+                </div>
+            </form>
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h2 class="list-heading">{{ trans('settings.app_customization') }}</h2>
+            <form action="{{ baseUrl("/settings") }}" method="POST">
+                {!! csrf_field() !!}
+
+                <div class="setting-list">
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label for="setting-app-name" class="setting-list-label">{{ trans('settings.app_name') }}</label>
+                            <p class="small">{{ trans('settings.app_name_desc') }}</p>
+                        </div>
+                        <div>
+                            <input type="text" value="{{ setting('app-name', 'BookStack') }}" name="setting-app-name" id="setting-app-name">
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-app-name-header',
+                                'value' => setting('app-name-header'),
+                                'label' => trans('settings.app_name_header'),
+                            ])
                         </div>
-                        <div class="form-group">
-                            <label for="setting-app-editor">{{ trans('settings.app_editor') }}</label>
+                    </div>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.app_editor') }}</label>
                             <p class="small">{{ trans('settings.app_editor_desc') }}</p>
+                        </div>
+                        <div>
                             <select name="setting-app-editor" id="setting-app-editor">
                                 <option @if(setting('app-editor') === 'wysiwyg') selected @endif value="wysiwyg">WYSIWYG</option>
                                 <option @if(setting('app-editor') === 'markdown') selected @endif value="markdown">Markdown</option>
                         </div>
                     </div>
 
-                    <div class="col-md-6">
-                        <div class="form-group" id="logo-control">
-                            <label for="setting-app-logo">{{ trans('settings.app_logo') }}</label>
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.app_logo') }}</label>
                             <p class="small">{!! trans('settings.app_logo_desc') !!}</p>
-
+                        </div>
+                        <div>
                             @include('components.image-picker', [
-                                'resizeHeight' => '43',
-                                'resizeWidth' => '200',
-                                'showRemove' => true,
-                                'defaultImage' => baseUrl('/logo.png'),
-                                'currentImage' => setting('app-logo'),
-                                'name' => 'setting-app-logo',
-                                'imageClass' => 'logo-image',
-                                'currentId' => false
-                            ])
-
+                                     'resizeHeight' => '43',
+                                     'resizeWidth' => '200',
+                                     'showRemove' => true,
+                                     'defaultImage' => baseUrl('/logo.png'),
+                                     'currentImage' => setting('app-logo'),
+                                     'name' => 'setting-app-logo',
+                                     'imageClass' => 'logo-image',
+                                     'currentId' => false
+                                 ])
                         </div>
-                        <div class="form-group" id="color-control">
-                            <label for="setting-app-color">{{ trans('settings.app_primary_color') }}</label>
+                    </div>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.app_primary_color') }}</label>
                             <p class="small">{!! trans('settings.app_primary_color_desc') !!}</p>
+                        </div>
+                        <div>
                             <input type="text" value="{{ setting('app-color') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
                             <input type="hidden" value="{{ setting('app-color-light') }}" name="setting-app-color-light" id="setting-app-color-light">
                         </div>
-                        <div homepage-control class="form-group" id="homepage-control">
-                            <label for="setting-app-homepage">{{ trans('settings.app_homepage') }}</label>
-                            <p class="small">{{ trans('settings.app_homepage_desc') }}</p>
+                    </div>
 
+                    <div homepage-control id="homepage-control" class="grid half large-gap">
+                        <div>
+                            <label for="setting-app-homepage" class="setting-list-label">{{ trans('settings.app_homepage') }}</label>
+                            <p class="small">{{ trans('settings.app_homepage_desc') }}</p>
+                        </div>
+                        <div>
                             <select name="setting-app-homepage-type" id="setting-app-homepage-type">
                                 <option @if(setting('app-homepage-type') === 'default') selected @endif value="default">{{ trans('common.default') }}</option>
                                 <option @if(setting('app-homepage-type') === 'books') selected @endif value="books">{{ trans('entities.books') }}</option>
                                 <option @if(setting('app-homepage-type') === 'page') selected @endif value="page">{{ trans('entities.pages_specific') }}</option>
                             </select>
 
-                            <br><br>
-
-                            <div page-picker-container style="display: none;">
+                            <div page-picker-container style="display: none;" class="mt-m">
                                 @include('components.page-picker', ['name' => 'setting-app-homepage', 'placeholder' => trans('settings.app_homepage_select'), 'value' => setting('app-homepage')])
                             </div>
                         </div>
                     </div>
 
-                </div>
 
-                <div class="form-group">
-                    <label for="setting-app-custom-head">{{ trans('settings.app_custom_html') }}</label>
-                    <p class="small">{{ trans('settings.app_custom_html_desc') }}</p>
-                    <textarea class="simple-code-input" name="setting-app-custom-head" id="setting-app-custom-head">{{ setting('app-custom-head', '') }}</textarea>
+                    <div>
+                        <label for="setting-app-custom-head" class="setting-list-label">{{ trans('settings.app_custom_html') }}</label>
+                        <p class="small">{{ trans('settings.app_custom_html_desc') }}</p>
+                        <textarea name="setting-app-custom-head" id="setting-app-custom-head" class="simple-code-input mt-m">{{ setting('app-custom-head', '') }}</textarea>
+                    </div>
+
+
                 </div>
 
                 <div class="form-group text-right">
-                    <button type="submit" class="button pos">{{ trans('settings.settings_save') }}</button>
+                    <button type="submit" class="button primary">{{ trans('settings.settings_save') }}</button>
                 </div>
             </form>
         </div>
-    </div>
-
-    <p>&nbsp;</p>
 
-    <div class="card">
-        <h3>@icon('users-add') {{ trans('settings.reg_settings') }}</h3>
-        <div class="body">
+        <div class="card content-wrap auto-height">
+            <h2 class="list-heading">{{ trans('settings.reg_settings') }}</h2>
             <form action="{{ baseUrl("/settings") }}" method="POST">
                 {!! csrf_field() !!}
 
-                <div class="row">
-                    <div class="col-md-6">
-                        <div class="form-group">
-                            <label for="setting-registration-enabled">{{ trans('settings.reg_allow') }}</label>
-                            @include('components.toggle-switch', ['name' => 'setting-registration-enabled', 'value' => setting('registration-enabled')])
+                <div class="setting-list">
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.reg_enable') }}</label>
+                            <p class="small">{!! trans('settings.reg_enable_desc') !!}</p>
                         </div>
-                        <div class="form-group">
+                        <div>
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-registration-enabled',
+                                'value' => setting('registration-enabled'),
+                                'label' => trans('settings.reg_enable_toggle')
+                            ])
+
                             <label for="setting-registration-role">{{ trans('settings.reg_default_role') }}</label>
                             <select id="setting-registration-role" name="setting-registration-role" @if($errors->has('setting-registration-role')) class="neg" @endif>
                                 @foreach(\BookStack\Auth\Role::all() as $role)
                                 @endforeach
                             </select>
                         </div>
-                        <div class="form-group">
-                            <label for="setting-registration-confirmation">{{ trans('settings.reg_confirm_email') }}</label>
-                            <p class="small">{{ trans('settings.reg_confirm_email_desc') }}</p>
-                            @include('components.toggle-switch', ['name' => 'setting-registration-confirmation', 'value' => setting('registration-confirmation')])
-                        </div>
                     </div>
-                    <div class="col-md-6">
-                        <div class="form-group">
-                            <label for="setting-registration-restrict">{{ trans('settings.reg_confirm_restrict_domain') }}</label>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label for="setting-registration-restrict" class="setting-list-label">{{ trans('settings.reg_confirm_restrict_domain') }}</label>
                             <p class="small">{!! trans('settings.reg_confirm_restrict_domain_desc') !!}</p>
+                        </div>
+                        <div>
                             <input type="text" id="setting-registration-restrict" name="setting-registration-restrict" placeholder="{{ trans('settings.reg_confirm_restrict_domain_placeholder') }}" value="{{ setting('registration-restrict', '') }}">
                         </div>
                     </div>
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label class="setting-list-label">{{ trans('settings.reg_email_confirmation') }}</label>
+                            <p class="small">{{ trans('settings.reg_confirm_email_desc') }}</p>
+                        </div>
+                        <div>
+                            @include('components.toggle-switch', [
+                                'name' => 'setting-registration-confirmation',
+                                'value' => setting('registration-confirmation'),
+                                'label' => trans('settings.reg_email_confirmation_toggle')
+                            ])
+                        </div>
+                    </div>
+
                 </div>
 
                 <div class="form-group text-right">
-                    <button type="submit" class="button pos">{{ trans('settings.settings_save') }}</button>
+                    <button type="submit" class="button primary">{{ trans('settings.settings_save') }}</button>
                 </div>
             </form>
         </div>
-    </div>
-
 
-</div>
-
-@include('components.image-manager', ['imageType' => 'system'])
-@include('components.entity-selector-popup', ['entityTypes' => 'page'])
+    </div>
 
+    @include('components.image-manager', ['imageType' => 'system'])
+    @include('components.entity-selector-popup', ['entityTypes' => 'page'])
 @stop
 
 @section('scripts')
         $('#setting-app-color').colorPicker({
             opacity: false,
             renderCallback: function($elm, toggled) {
-                var hexVal = '#' + this.color.colors.HEX;
-                var rgb = this.color.colors.RND.rgb;
-                var rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')';
+                const hexVal = '#' + this.color.colors.HEX;
+                const rgb = this.color.colors.RND.rgb;
+                const rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')';
 
                 // Set textbox color to hex color code.
-                var isEmpty = $.trim($elm.val()).length === 0;
+                const isEmpty = $.trim($elm.val()).length === 0;
                 if (!isEmpty) $elm.val(hexVal);
                 $('#setting-app-color-light').val(isEmpty ? '' : rgbLightVal);
 
-                var customStyles = document.getElementById('custom-styles');
-                var oldColor = customStyles.getAttribute('data-color');
-                var oldColorLight = customStyles.getAttribute('data-color-light');
+                const customStyles = document.getElementById('custom-styles');
+                const oldColor = customStyles.getAttribute('data-color');
+                const oldColorLight = customStyles.getAttribute('data-color-light');
 
                 customStyles.innerHTML = customStyles.innerHTML.split(oldColor).join(hexVal);
                 customStyles.innerHTML = customStyles.innerHTML.split(oldColorLight).join(rgbLightVal);
index abf793adec9ea6640bcb9a93f671e9178eca5af6..6e408d1f4836270be35cc9bbee12cc627c57962f 100644 (file)
@@ -1,46 +1,45 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'maintenance'])
-@stop
-
 @section('body')
 <div class="container small">
 
-    <div class="text-right text-muted container">
-        <br>
-        BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
+    <div class="grid left-focus v-center">
+        <div class="py-m">
+            @include('settings/navbar', ['selected' => 'maintenance'])
+        </div>
+        <div class="text-right mb-l px-m">
+            <br>
+            BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
+        </div>
     </div>
 
 
-    <div class="card" id="image-cleanup">
-        <h3>@icon('images') {{ trans('settings.maint_image_cleanup') }}</h3>
-        <div class="body">
-            <div class="row">
-                <div class="col-sm-6">
-                    <p class="small muted">{{ trans('settings.maint_image_cleanup_desc') }}</p>
-                </div>
-                <div class="col-sm-6">
-                    <form method="POST" action="{{ baseUrl('/settings/maintenance/cleanup-images') }}">
-                        {!! csrf_field()  !!}
-                        <input type="hidden" name="_method" value="DELETE">
-                        <div>
-                            @if(session()->has('cleanup-images-warning'))
-                                <p class="text neg">
-                                    {{ session()->get('cleanup-images-warning') }}
-                                </p>
-                                <input type="hidden" name="ignore_revisions" value="{{ session()->getOldInput('ignore_revisions', 'false') }}">
-                                <input type="hidden" name="confirm" value="true">
-                            @else
-                                <label>
-                                    <input type="checkbox" name="ignore_revisions" value="true">
-                                    {{ trans('settings.maint_image_cleanup_ignore_revisions') }}
-                                </label>
-                            @endif
-                        </div>
-                        <button class="button outline">{{ trans('settings.maint_image_cleanup_run') }}</button>
-                    </form>
-                </div>
+    <div id="image-cleanup" class="card content-wrap auto-height">
+        <h2 class="list-heading">{{ trans('settings.maint_image_cleanup') }}</h2>
+        <div class="grid half large-gap">
+            <div>
+                <p class="small muted">{{ trans('settings.maint_image_cleanup_desc') }}</p>
+            </div>
+            <div>
+                <form method="POST" action="{{ baseUrl('/settings/maintenance/cleanup-images') }}">
+                    {!! csrf_field()  !!}
+                    <input type="hidden" name="_method" value="DELETE">
+                    <div>
+                        @if(session()->has('cleanup-images-warning'))
+                            <p class="text neg">
+                                {{ session()->get('cleanup-images-warning') }}
+                            </p>
+                            <input type="hidden" name="ignore_revisions" value="{{ session()->getOldInput('ignore_revisions', 'false') }}">
+                            <input type="hidden" name="confirm" value="true">
+                        @else
+                            <label>
+                                <input type="checkbox" name="ignore_revisions" value="true">
+                                {{ trans('settings.maint_image_cleanup_ignore_revisions') }}
+                            </label>
+                        @endif
+                    </div>
+                    <button class="button outline">{{ trans('settings.maint_image_cleanup_run') }}</button>
+                </form>
             </div>
         </div>
     </div>
index f9db96894cf0b19bcb0d93b41b9b270697956f55..ddbaa3f2a865db53fea0cfd47c0ce1d33133f9dc 100644 (file)
@@ -1,13 +1,13 @@
 
-<div class="col-md-12 setting-nav nav-tabs">
+<div class="active-link-list">
     @if($currentUser->can('settings-manage'))
-        <a href="{{ baseUrl('/settings') }}" @if($selected == 'settings') class="selected text-button" @endif>@icon('settings'){{ trans('settings.settings') }}</a>
-        <a href="{{ baseUrl('/settings/maintenance') }}" @if($selected == 'maintenance') class="selected text-button" @endif>@icon('spanner'){{ trans('settings.maint') }}</a>
+        <a href="{{ baseUrl('/settings') }}" @if($selected == 'settings') class="active" @endif>@icon('settings'){{ trans('settings.settings') }}</a>
+        <a href="{{ baseUrl('/settings/maintenance') }}" @if($selected == 'maintenance') class="active" @endif>@icon('spanner'){{ trans('settings.maint') }}</a>
     @endif
     @if($currentUser->can('users-manage'))
-        <a href="{{ baseUrl('/settings/users') }}" @if($selected == 'users') class="selected text-button" @endif>@icon('users'){{ trans('settings.users') }}</a>
+        <a href="{{ baseUrl('/settings/users') }}" @if($selected == 'users') class="active" @endif>@icon('users'){{ trans('settings.users') }}</a>
     @endif
     @if($currentUser->can('user-roles-manage'))
-        <a href="{{ baseUrl('/settings/roles') }}" @if($selected == 'roles') class="selected text-button" @endif>@icon('lock-open'){{ trans('settings.roles') }}</a>
+        <a href="{{ baseUrl('/settings/roles') }}" @if($selected == 'roles') class="active" @endif>@icon('lock-open'){{ trans('settings.roles') }}</a>
     @endif
 </div>
\ No newline at end of file
index 4dfba1f0b5f10eedfbb2fc95f8cec6280c5b5bfa..98201da8fc7d82af4ad69c867f159531530c2647 100644 (file)
@@ -1,3 +1,7 @@
-<input type="checkbox" name="permissions[{{ $permission }}]"
-       @if(old('permissions'.$permission, false)|| (!old('display_name', false) && (isset($role) && $role->hasPermission($permission)))) checked="checked" @endif
-       value="true">
\ No newline at end of file
+
+@include('components.custom-checkbox', [
+       'name' => 'permissions[' . $permission . ']',
+       'value' => 'true',
+       'checked' => old('permissions'.$permission, false)|| (!old('display_name', false) && (isset($role) && $role->hasPermission($permission))),
+       'label' => $label
+])
\ No newline at end of file
index e61922da609096327383052c17ec5e8ac5db08b0..80a6fc3820d1bffb5c671652d02e0e56f409d391 100644 (file)
@@ -1,17 +1,16 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'roles'])
-@stop
-
 @section('body')
 
-    <form action="{{ baseUrl("/settings/roles/new") }}" method="POST">
-        <div class="container">
-            <div class="row">
-                @include('settings/roles/form', ['title' => trans('settings.role_create'), 'icon' => 'plus'])
-            </div>
+    <div class="container small">
+
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'roles'])
         </div>
-    </form>
+
+        <form action="{{ baseUrl("/settings/roles/new") }}" method="POST">
+            @include('settings.roles.form', ['title' => trans('settings.role_create')])
+        </form>
+    </div>
 
 @stop
index 6e447c3797b50965502a0f1e0aa27031e39318de..29087c471beb0674f42774035fea4cbce0a8e523 100644 (file)
@@ -1,35 +1,44 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'roles'])
-@stop
-
 @section('body')
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ trans('settings.role_delete') }}</h3>
-            <div class="body">
-                <p>{{ trans('settings.role_delete_confirm', ['roleName' => $role->display_name]) }}</p>
-
-                <form action="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="DELETE">
-
-                    @if($role->users->count() > 0)
-                        <div class="form-group">
-                            <p>{{ trans('settings.role_delete_users_assigned', ['userCount' => $role->users->count()]) }}</p>
-                            @include('form/role-select', ['options' => $roles, 'name' => 'migration_role_id'])
-                        </div>
-                    @endif
 
-                    <p class="text-neg">{{ trans('settings.role_delete_sure') }}</p>
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'roles'])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading"> {{ trans('settings.role_delete') }}</h1>
+
+            <p>{{ trans('settings.role_delete_confirm', ['roleName' => $role->display_name]) }}</p>
+
+            <form action="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" method="POST">
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="DELETE">
+
+                @if($role->users->count() > 0)
                     <div class="form-group">
-                        <a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
+                        <p>{{ trans('settings.role_delete_users_assigned', ['userCount' => $role->users->count()]) }}</p>
+                        @include('form/role-select', ['options' => $roles, 'name' => 'migration_role_id'])
+                    </div>
+                @endif
+
+                <div class="grid half v-center">
+                    <div>
+                        <p class="text-neg">
+                            <strong>{{ trans('settings.role_delete_sure') }}</strong>
+                        </p>
                     </div>
-                </form>
-            </div>
+                    <div>
+                        <div class="form-group text-right">
+                            <a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
+                            <button type="submit" class="button primary">{{ trans('common.confirm') }}</button>
+                        </div>
+                    </div>
+                </div>
+
+
+            </form>
         </div>
 
     </div>
index 01ba53383595282cc8ceba368c912db01106e462..a7b81322977c59eb48780d4fd8a8b13a2e23e3ea 100644 (file)
@@ -1,17 +1,16 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'roles'])
-@stop
-
 @section('body')
 
-    <form action="{{ baseUrl("/settings/roles/{$role->id}") }}" method="POST">
-        <input type="hidden" name="_method" value="PUT">
-        <div class="container">
-            <div class="row">
-                @include('settings/roles/form', ['model' => $role, 'title' => trans('settings.role_edit'), 'icon' => 'edit'])
-            </div>
+    <div class="container small">
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'roles'])
         </div>
-    </form>
+
+        <form action="{{ baseUrl("/settings/roles/{$role->id}") }}" method="POST">
+            <input type="hidden" name="_method" value="PUT">
+            @include('settings.roles.form', ['model' => $role, 'title' => trans('settings.role_edit'), 'icon' => 'edit'])
+        </form>
+    </div>
+
 @stop
index 619229a655067328ae4f088f745550ed1dbbd761..f16706dd11bb637865b9afd48287ce60701b85a5 100644 (file)
 {!! csrf_field() !!}
 
-<div class="col-md-9">
-    <div class="card">
-        <h3>@icon($icon) {{$title}}</h3>
-        <div class="body">
-            <div class="row">
-                <div class="col-md-5">
-                    <h5>{{ trans('settings.role_details') }}</h5>
-                    <div class="form-group">
-                        <label for="name">{{ trans('settings.role_name') }}</label>
-                        @include('form/text', ['name' => 'display_name'])
-                    </div>
-                    <div class="form-group">
-                        <label for="name">{{ trans('settings.role_desc') }}</label>
-                        @include('form/text', ['name' => 'description'])
-                    </div>
+{{--TODO - Add select-all shortcuts--}}
 
-                    @if(config('auth.method') === 'ldap')
-                        <div class="form-group">
-                            <label for="name">{{ trans('settings.role_external_auth_id') }}</label>
-                            @include('form/text', ['name' => 'external_auth_id'])
-                        </div>
-                    @endif
+<div class="card content-wrap">
+    <h1 class="list-heading">{{ $title }}</h1>
 
-                    <h5>{{ trans('settings.role_system') }}</h5>
-                    <label>@include('settings/roles/checkbox', ['permission' => 'users-manage']) {{ trans('settings.role_manage_users') }}</label>
-                    <label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) {{ trans('settings.role_manage_roles') }}</label>
-                    <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) {{ trans('settings.role_manage_entity_permissions') }}</label>
-                    <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-own']) {{ trans('settings.role_manage_own_entity_permissions') }}</label>
-                    <label>@include('settings/roles/checkbox', ['permission' => 'settings-manage']) {{ trans('settings.role_manage_settings') }}</label>
-                </div>
-
-                <div class="col-md-6">
+    <div class="setting-list">
 
-                    <h5>{{ trans('settings.role_asset') }}</h5>
-                    <p>{{ trans('settings.role_asset_desc') }}</p>
+        <div class="grid half">
+            <div>
+                <label class="setting-list-label">{{ trans('settings.role_details') }}</label>
+            </div>
+            <div>
+                <div class="form-group">
+                    <label for="name">{{ trans('settings.role_name') }}</label>
+                    @include('form.text', ['name' => 'display_name'])
+                </div>
+                <div class="form-group">
+                    <label for="name">{{ trans('settings.role_desc') }}</label>
+                    @include('form.text', ['name' => 'description'])
+                </div>
 
-                    @if (isset($role) && $role->system_name === 'admin')
-                        <p>{{ trans('settings.role_asset_admins') }}</p>
-                    @endif
+                @if(config('auth.method') === 'ldap')
+                    <div class="form-group">
+                        <label for="name">{{ trans('settings.role_external_auth_id') }}</label>
+                        @include('form.text', ['name' => 'external_auth_id'])
+                    </div>
+                @endif
+            </div>
+        </div>
 
-                    <table class="table">
-                        <tr>
-                            <th width="20%"></th>
-                            <th width="20%">{{ trans('common.create') }}</th>
-                            <th width="20%">{{ trans('common.view') }}</th>
-                            <th width="20%">{{ trans('common.edit') }}</th>
-                            <th width="20%">{{ trans('common.delete') }}</th>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.shelves_long') }}</td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-create-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-view-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-view-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'bookshelf-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.books') }}</td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-create-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-view-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-view-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.chapters') }}</td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.pages') }}</td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-create-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-create-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-view-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-view-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.images') }}</td>
-                            <td>@include('settings/roles/checkbox', ['permission' => 'image-create-all'])</td>
-                            <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'image-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'image-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.attachments') }}</td>
-                            <td>@include('settings/roles/checkbox', ['permission' => 'attachment-create-all'])</td>
-                            <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>{{ trans('entities.comments') }}</td>
-                            <td>@include('settings/roles/checkbox', ['permission' => 'comment-create-all'])</td>
-                            <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'comment-update-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'comment-update-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                            <td>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'comment-delete-own']) {{ trans('settings.role_own') }}</label>
-                                <label>@include('settings/roles/checkbox', ['permission' => 'comment-delete-all']) {{ trans('settings.role_all') }}</label>
-                            </td>
-                        </tr>
-                    </table>
-                </div>
+        <div class="grid half">
+            <div>
+                <label class="setting-list-label">{{ trans('settings.role_system') }}</label>
             </div>
-            <div class="form-group text-right">
-                <a href="{{ baseUrl("/settings/roles") }}" class="button outline">{{ trans('common.cancel') }}</a>
-                @if (isset($role) && $role->id)
-                    <a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button neg">{{ trans('settings.role_delete') }}</a>
-                @endif
-                <button type="submit" class="button pos">{{ trans('settings.role_save') }}</button>
+            <div class="toggle-switch-list">
+                <div>@include('settings.roles.checkbox', ['permission' => 'users-manage', 'label' => trans('settings.role_manage_users')])</div>
+                <div>@include('settings.roles.checkbox', ['permission' => 'user-roles-manage', 'label' => trans('settings.role_manage_roles')])</div>
+                <div>@include('settings.roles.checkbox', ['permission' => 'restrictions-manage-all', 'label' => trans('settings.role_manage_entity_permissions')])</div>
+                <div>@include('settings.roles.checkbox', ['permission' => 'restrictions-manage-own', 'label' => trans('settings.role_manage_own_entity_permissions')])</div>
+                <div>@include('settings.roles.checkbox', ['permission' => 'settings-manage', 'label' => trans('settings.role_manage_settings')])</div>
             </div>
         </div>
+
+        <div>
+            <label class="setting-list-label">{{ trans('settings.role_asset') }}</label>
+            <p>{{ trans('settings.role_asset_desc') }}</p>
+
+            @if (isset($role) && $role->system_name === 'admin')
+                <p class="text-secondary">{{ trans('settings.role_asset_admins') }}</p>
+            @endif
+
+            <table class="table toggle-switch-list compact">
+                <tr>
+                    <th width="20%"></th>
+                    <th width="20%">{{ trans('common.create') }}</th>
+                    <th width="20%">{{ trans('common.view') }}</th>
+                    <th width="20%">{{ trans('common.edit') }}</th>
+                    <th width="20%">{{ trans('common.delete') }}</th>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.shelves_long') }}</td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-create-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-view-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-view-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'bookshelf-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.books') }}</td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'book-create-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'book-view-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'book-view-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'book-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'book-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'book-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'book-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.chapters') }}</td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-create-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-create-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-view-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-view-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'chapter-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.pages') }}</td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'page-create-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'page-create-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'page-view-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'page-view-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'page-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'page-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'page-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'page-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.images') }}</td>
+                    <td>@include('settings.roles.checkbox', ['permission' => 'image-create-all', 'label' => ''])</td>
+                    <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'image-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'image-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'image-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'image-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.attachments') }}</td>
+                    <td>@include('settings.roles.checkbox', ['permission' => 'attachment-create-all', 'label' => ''])</td>
+                    <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'attachment-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'attachment-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'attachment-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'attachment-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+                <tr>
+                    <td>{{ trans('entities.comments') }}</td>
+                    <td>@include('settings.roles.checkbox', ['permission' => 'comment-create-all', 'label' => ''])</td>
+                    <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'comment-update-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'comment-update-all', 'label' => trans('settings.role_all')])
+                    </td>
+                    <td>
+                        @include('settings.roles.checkbox', ['permission' => 'comment-delete-own', 'label' => trans('settings.role_own')])
+                        <br>
+                        @include('settings.roles.checkbox', ['permission' => 'comment-delete-all', 'label' => trans('settings.role_all')])
+                    </td>
+                </tr>
+            </table>
+        </div>
+    </div>
+
+    <div class="form-group text-right">
+        <a href="{{ baseUrl("/settings/roles") }}" class="button outline">{{ trans('common.cancel') }}</a>
+        @if (isset($role) && $role->id)
+            <a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button outline">{{ trans('settings.role_delete') }}</a>
+        @endif
+        <button type="submit" class="button primary">{{ trans('settings.role_save') }}</button>
     </div>
+
 </div>
-<div class="col-md-3">
-    <div class="card">
-        <h3>@icon('users') {{ trans('settings.role_users') }}</h3>
-        <div class="body">
-            @if(isset($role) && count($role->users) > 0)
-                <table class="list-table">
-                    @foreach($role->users as $user)
-                        <tr>
-                            <td style="line-height: 0;"><img class="avatar small" src="{{ $user->getAvatar(40) }}" alt="{{ $user->name }}"></td>
-                            <td>
-                                @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    <a href="{{ baseUrl("/settings/users/{$user->id}") }}">
-                                        @endif
-                                        {{ $user->name }}
-                                        @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    </a>
+
+<div class="card content-wrap auto-height">
+    <h2 class="list-heading">{{ trans('settings.role_users') }}</h2>
+    @if(isset($role) && count($role->users) > 0)
+        <div class="grid third">
+            @foreach($role->users as $user)
+                <div class="user-list-item">
+                    <div>
+                        <img class="avatar small" src="{{ $user->getAvatar(40) }}" alt="{{ $user->name }}">
+                    </div>
+                    <div>
+                        @if(userCan('users-manage') || $currentUser->id == $user->id)
+                            <a href="{{ baseUrl("/settings/users/{$user->id}") }}">
                                 @endif
-                            </td>
-                        </tr>
-                    @endforeach
-                </table>
-            @else
-                <p class="text-muted">
-                    {{ trans('settings.role_users_none') }}
-                </p>
-            @endif
+                                {{ $user->name }}
+                                @if(userCan('users-manage') || $currentUser->id == $user->id)
+                            </a>
+                        @endif
+                    </div>
+                </div>
+            @endforeach
         </div>
-    </div>
+    @else
+        <p class="text-muted">
+            {{ trans('settings.role_users_none') }}
+        </p>
+    @endif
 </div>
\ No newline at end of file
index 147d04bd17a642c6e7f470135fbd66f22c9fcf86..6cfef7c671bb9cbc294de63aedffebb657154508 100644 (file)
@@ -1,35 +1,39 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'roles'])
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('lock-open') {{ trans('settings.role_user_roles') }}</h3>
-            <div class="body">
-                <table class="table">
-                    <tr>
-                        <th>{{ trans('settings.role_name') }}</th>
-                        <th></th>
-                        <th class="text-center">{{ trans('settings.users') }}</th>
-                    </tr>
-                    @foreach($roles as $role)
-                        <tr>
-                            <td><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{ $role->display_name }}</a></td>
-                            <td>{{ $role->description }}</td>
-                            <td class="text-center">{{ $role->users->count() }}</td>
-                        </tr>
-                    @endforeach
-                </table>
-
-                <div class="form-group">
-                    <a href="{{ baseUrl("/settings/roles/new") }}" class="button pos">{{ trans('settings.role_create') }}</a>
+
+        <div class="py-m">
+            @include('settings/navbar', ['selected' => 'roles'])
+        </div>
+
+        <div class="card content-wrap auto-height">
+
+            <div class="grid half v-center">
+                <h1 class="list-heading">{{ trans('settings.role_user_roles') }}</h1>
+
+                <div class="text-right">
+                    <a href="{{ baseUrl("/settings/roles/new") }}" class="button outline">{{ trans('settings.role_create') }}</a>
                 </div>
             </div>
+
+            <table class="table">
+                <tr>
+                    <th>{{ trans('settings.role_name') }}</th>
+                    <th></th>
+                    <th class="text-center">{{ trans('settings.users') }}</th>
+                </tr>
+                @foreach($roles as $role)
+                    <tr>
+                        <td><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{ $role->display_name }}</a></td>
+                        <td>{{ $role->description }}</td>
+                        <td class="text-center">{{ $role->users->count() }}</td>
+                    </tr>
+                @endforeach
+            </table>
+
+
         </div>
     </div>
 
index 32e40a4ae5271e51788e3c554eafa8947f43e6d8..72bf904fea1a7ec372e86aae2081b8c12a38c9b7 100644 (file)
@@ -1,30 +1,30 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-8 faded">
-        <div class="breadcrumbs">
-            <a href="{{ baseUrl('/shelves') }}" class="text-button">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
-            <span class="sep">&raquo;</span>
-            <a href="{{ baseUrl('/create-shelf') }}" class="text-button">@icon('add'){{ trans('entities.shelves_create') }}</a>
-        </div>
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('add') {{ trans('entities.shelves_create') }}</h3>
-            <div class="body">
-                <form action="{{ baseUrl("/shelves") }}" method="POST" enctype="multipart/form-data">
-                    @include('shelves/form', ['shelf' => null, 'books' => $books])
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                '/shelves' => [
+                    'text' => trans('entities.shelves'),
+                    'icon' => 'bookshelf',
+                ],
+                '/create-shelf' => [
+                    'text' => trans('entities.shelves_create'),
+                    'icon' => 'add',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.shelves_create') }}</h1>
+            <form action="{{ baseUrl("/shelves") }}" method="POST" enctype="multipart/form-data">
+                @include('shelves.form', ['shelf' => null, 'books' => $books])
+            </form>
         </div>
-    </div>
 
-    <p class="margin-top large"><br></p>
+    </div>
 
     @include('components.image-manager', ['imageType' => 'cover'])
 
index f3ad62456b18aa04003333ce0bed421260fee012..2a78227bda656ffd611c21dd5570b96c1e8ea3ac 100644 (file)
@@ -1,22 +1,29 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('shelves._breadcrumbs', ['shelf' => $shelf])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ trans('entities.shelves_delete') }}</h3>
-            <div class="body">
-                <p>{{ trans('entities.shelves_delete_explain', ['name' => $shelf->name]) }}</p>
-                <p class="text-neg">{{ trans('entities.shelves_delete_confirmation') }}</p>
-
-                <form action="{{ $shelf->getUrl() }}" method="POST">
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $shelf,
+                $shelf->getUrl('/delete') => [
+                    'text' => trans('entities.shelves_delete'),
+                    'icon' => 'delete',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('entities.shelves_delete') }}</h1>
+            <p>{{ trans('entities.shelves_delete_explain', ['name' => $shelf->name]) }}</p>
+
+            <div class="grid half">
+                <p class="text-neg">
+                    <strong>{{ trans('entities.shelves_delete_confirmation') }}</strong>
+                </p>
+
+                <form action="{{ $shelf->getUrl() }}" method="POST" class="text-right">
                     {!! csrf_field() !!}
                     <input type="hidden" name="_method" value="DELETE">
 
@@ -24,6 +31,8 @@
                     <button type="submit" class="button">{{ trans('common.confirm') }}</button>
                 </form>
             </div>
+
+
         </div>
     </div>
 
index ab88051e5b18b616b495fa4e9b5cd894b3429274..81f4846a30694783b81479972534197defd2bc1d 100644 (file)
@@ -1,24 +1,27 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('shelves._breadcrumbs', ['shelf' => $shelf])
-    </div>
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('edit') {{ trans('entities.shelves_edit') }}</h3>
-            <div class="body">
-                <form action="{{ $shelf->getUrl() }}" method="POST">
-                    <input type="hidden" name="_method" value="PUT">
-                    @include('shelves/form', ['model' => $shelf])
-                </form>
-            </div>
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $shelf,
+                $shelf->getUrl('/edit') => [
+                    'text' => trans('entities.shelves_edit'),
+                    'icon' => 'edit',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.shelves_edit') }}</h1>
+            <form action="{{ $shelf->getUrl() }}" method="POST">
+                <input type="hidden" name="_method" value="PUT">
+                @include('shelves/form', ['model' => $shelf])
+            </form>
         </div>
     </div>
-@include('components.image-manager', ['imageType' => 'cover'])
+
+    @include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index fb6fee1151682ab77aeb4bcc2fb58dfb80b5eb99..f7f5c47287983bdcb3a3eebace27c0bff69fc49c 100644 (file)
@@ -1,5 +1,5 @@
-
 {{ csrf_field() }}
+
 <div class="form-group title-input">
     <label for="name">{{ trans('common.name') }}</label>
     @include('form/text', ['name' => 'name'])
@@ -80,5 +80,5 @@
 
 <div class="form-group text-right">
     <a href="{{ isset($shelf) ? $shelf->getUrl() : baseUrl('/shelves') }}" class="button outline">{{ trans('common.cancel') }}</a>
-    <button type="submit" class="button pos">{{ trans('entities.shelves_save') }}</button>
+    <button type="submit" class="button primary">{{ trans('entities.shelves_save') }}</button>
 </div>
\ No newline at end of file
index b70b5166ed57c84ab890e68d54244f5e4c0571e6..25b35b9efab4ff624c19a27b77010790d38309f6 100644 (file)
@@ -1,18 +1,21 @@
-<div class="bookshelf-grid-item grid-card"  data-entity-type="bookshelf" data-entity-id="{{$bookshelf->id}}">
-    <div class="featured-image-container">
-        <a href="{{$bookshelf->getUrl()}}" title="{{$bookshelf->name}}">
-            <img src="{{$bookshelf->getBookCover()}}" alt="{{$bookshelf->name}}">
-        </a>
+<a href="{{$shelf->getUrl()}}" class="bookshelf-grid-item grid-card"
+   data-entity-type="bookshelf" data-entity-id="{{$shelf->id}}">
+    <div class="bg-shelf featured-image-container-wrap">
+        <div class="featured-image-container" @if($shelf->cover) style="background-image: url('{{ $shelf->getBookCover() }}')"@endif>
+        </div>
+        @icon('bookshelf')
     </div>
     <div class="grid-card-content">
-        <h2><a class="break-text" href="{{$bookshelf->getUrl()}}" title="{{$bookshelf->name}}">{{$bookshelf->getShortName(35)}}</a></h2>
-        @if(isset($bookshelf->searchSnippet))
-            <p >{!! $bookshelf->searchSnippet !!}</p>
+        <h2>{{$shelf->getShortName(35)}}</h2>
+        @if(isset($shelf->searchSnippet))
+            <p class="text-muted">{!! $shelf->searchSnippet !!}</p>
         @else
-            <p >{{ $bookshelf->getExcerpt(130) }}</p>
+            <p class="text-muted">{{ $shelf->getExcerpt(130) }}</p>
         @endif
     </div>
     <div class="grid-card-footer text-muted text-small">
-        <span>@include('partials.entity-meta', ['entity' => $bookshelf])</span>
+        @icon('star')<span title="{{$shelf->created_at->toDayDateTimeString()}}">{{ trans('entities.meta_created', ['timeLength' => $shelf->created_at->diffForHumans()]) }}</span>
+        <br>
+        @icon('edit')<span title="{{ $shelf->updated_at->toDayDateTimeString() }}">{{ trans('entities.meta_updated', ['timeLength' => $shelf->updated_at->diffForHumans()]) }}</span>
     </div>
-</div>
\ No newline at end of file
+</a>
\ No newline at end of file
index a887a843e578e518ef08bb0d23a03d53aa9ec683..eeb579de6c913fe5e5e631d47c1baf4177987bee 100644 (file)
@@ -1,48 +1,49 @@
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-xs-6 faded">
-        <div class="action-buttons text-left">
-            @include('shelves/view-toggle', ['shelvesViewType' => $shelvesViewType])
-        </div>
-    </div>
-    <div class="col-xs-6 faded">
-        <div class="action-buttons">
+@section('body')
+    @include('shelves.list', ['shelves' => $shelves, 'view' => $view])
+@stop
+
+@section('right')
+
+    <div class="actions mb-xl">
+        <h5>{{ trans('common.actions') }}</h5>
+        <div class="icon-list text-primary">
+            @include('partials.view-toggle', ['view' => $view, 'type' => 'shelf'])
             @if($currentUser->can('bookshelf-create-all'))
-                <a href="{{ baseUrl("/create-shelf") }}" class="text-pos text-button">@icon('add'){{ trans('entities.shelves_create') }}</a>
+                <a href="{{ baseUrl("/create-shelf") }}" class="icon-list-item">
+                    <span>@icon('add')</span>
+                    <span>{{ trans('entities.shelves_create') }}</span>
+                </a>
             @endif
         </div>
     </div>
+
 @stop
 
-@section('sidebar')
+@section('left')
     @if($recents)
-        <div id="recents" class="card">
-            <h3>@icon('view') {{ trans('entities.recently_viewed') }}</h3>
-            @include('partials/entity-list', ['entities' => $recents, 'style' => 'compact'])
+        <div id="recents" class="mb-xl">
+            <h5>{{ trans('entities.recently_viewed') }}</h5>
+            @include('partials.entity-list', ['entities' => $recents, 'style' => 'compact'])
         </div>
     @endif
 
-    <div id="popular" class="card">
-        <h3>@icon('popular') {{ trans('entities.shelves_popular') }}</h3>
+    <div id="popular" class="mb-xl">
+        <h5>{{ trans('entities.shelves_popular') }}</h5>
         @if(count($popular) > 0)
-            @include('partials/entity-list', ['entities' => $popular, 'style' => 'compact'])
+            @include('partials.entity-list', ['entities' => $popular, 'style' => 'compact'])
         @else
-            <div class="body text-muted">{{ trans('entities.shelves_popular_empty') }}</div>
+            <div class="text-muted">{{ trans('entities.shelves_popular_empty') }}</div>
         @endif
     </div>
 
-    <div id="new" class="card">
-        <h3>@icon('star-circle') {{ trans('entities.shelves_new') }}</h3>
+    <div id="new" class="mb-xl">
+        <h5>{{ trans('entities.shelves_new') }}</h5>
         @if(count($new) > 0)
-            @include('partials/entity-list', ['entities' => $new, 'style' => 'compact'])
+            @include('partials.entity-list', ['entities' => $new, 'style' => 'compact'])
         @else
-            <div class="body text-muted">{{ trans('entities.shelves_new_empty') }}</div>
+            <div class="text-muted">{{ trans('entities.shelves_new_empty') }}</div>
         @endif
     </div>
-@stop
-
-@section('body')
-    @include('shelves/list', ['shelves' => $shelves, 'shelvesViewType' => $shelvesViewType])
-    <p><br></p>
 @stop
\ No newline at end of file
index 0b8e79fe549122331868e15baf9355b89851960b..5766ca75590ef5cf79f4c0fcfc641085c7a22569 100644 (file)
@@ -1,10 +1,21 @@
-<div class="shelf entity-list-item"  data-entity-type="bookshelf" data-entity-id="{{$bookshelf->id}}">
-    <h4 class="text-shelf"><a class="text-bookshelf entity-list-item-link" href="{{$bookshelf->getUrl()}}">@icon('bookshelf')<span class="entity-list-item-name break-text">{{$bookshelf->name}}</span></a></h4>
-    <div class="entity-item-snippet">
-        @if(isset($bookshelf->searchSnippet))
-            <p class="text-muted break-text">{!! $bookshelf->searchSnippet !!}</p>
-        @else
-            <p class="text-muted break-text">{{ $bookshelf->getExcerpt() }}</p>
-        @endif
+<a href="{{ $shelf->getUrl() }}" class="shelf entity-list-item" data-entity-type="bookshelf" data-entity-id="{{$shelf->id}}">
+    <div class="entity-list-item-image bg-shelf @if($shelf->image_id) has-image @endif" style="background-image: url('{{ $shelf->getBookCover() }}')">
+        @icon('bookshelf')
     </div>
+    <div class="content py-xs">
+        <h4 class="entity-list-item-name break-text">{{ $shelf->name }}</h4>
+        <div class="entity-item-snippet">
+            <p class="text-muted break-text mb-none">{{ $shelf->getExcerpt() }}</p>
+        </div>
+    </div>
+</a>
+<div class="entity-shelf-books grid third entity-list-item-children">
+    @foreach($shelf->books as $book)
+        <div>
+            <a href="{{ $book->getUrl() }}" class="entity-chip text-book">
+                @icon('book')
+                {{ $book->name }}
+            </a>
+        </div>
+    @endforeach
 </div>
\ No newline at end of file
index ff11d2d67934b78965e68fbfe7fd2635188eee49..84a0ded0ddfd792628c5641cc8f3c0ba4cc3933e 100644 (file)
@@ -1,18 +1,30 @@
 
-<div class="container{{ $shelvesViewType === 'list' ? ' small' : '' }}">
-    <h1>{{ trans('entities.shelves') }}</h1>
+<div class="content-wrap card">
+    {{--TODO - Create unique list item--}}
+
+    <div class="grid half v-center">
+        <h1 class="list-heading">{{ trans('entities.shelves') }}</h1>
+        <div class="text-right">
+            @include('partials.sort', ['options' => $sortOptions, 'order' => $order, 'sort' => $sort, 'type' => 'bookshelves'])
+        </div>
+    </div>
+
     @if(count($shelves) > 0)
-        @if($shelvesViewType === 'grid')
+        @if($view === 'list')
+            <div class="entity-list">
+                @foreach($shelves as $index => $shelf)
+                    @if ($index !== 0)
+                        <hr class="my-m">
+                    @endif
+                    @include('shelves.list-item', ['shelf' => $shelf])
+                @endforeach
+            </div>
+        @else
             <div class="grid third">
                 @foreach($shelves as $key => $shelf)
-                    @include('shelves/grid-item', ['bookshelf' => $shelf])
+                    @include('shelves.grid-item', ['shelf' => $shelf])
                 @endforeach
             </div>
-        @else
-            @foreach($shelves as $shelf)
-                @include('shelves/list-item', ['bookshelf' => $shelf])
-                <hr>
-            @endforeach
         @endif
         <div>
             {!! $shelves->render() !!}
@@ -23,4 +35,5 @@
             <a href="{{ baseUrl("/create-shelf") }}" class="button outline">@icon('edit'){{ trans('entities.create_now') }}</a>
         @endif
     @endif
-</div>
\ No newline at end of file
+
+</div>
diff --git a/resources/views/shelves/permissions.blade.php b/resources/views/shelves/permissions.blade.php
new file mode 100644 (file)
index 0000000..df50be8
--- /dev/null
@@ -0,0 +1,32 @@
+@extends('simple-layout')
+
+@section('body')
+
+    <div class="container small">
+
+        <div class="my-s">
+            @include('partials.breadcrumbs', ['crumbs' => [
+                $shelf,
+                $shelf->getUrl('/permissions') => [
+                    'text' => trans('entities.shelves_permissions'),
+                    'icon' => 'lock',
+                ]
+            ]])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('entities.shelves_permissions') }}</h1>
+            @include('form.entity-permissions', ['model' => $shelf])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h2 class="list-heading">{{ trans('entities.shelves_copy_permissions_to_books') }}</h2>
+            <p>{{ trans('entities.shelves_copy_permissions_explain') }}</p>
+            <form action="{{ $shelf->getUrl('/copy-permissions') }}" method="post" class="text-right">
+                {{ csrf_field() }}
+                <button class="button">{{ trans('entities.shelves_copy_permissions') }}</button>
+            </form>
+        </div>
+    </div>
+
+@stop
diff --git a/resources/views/shelves/restrictions.blade.php b/resources/views/shelves/restrictions.blade.php
deleted file mode 100644 (file)
index 472078a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-@extends('simple-layout')
-
-@section('toolbar')
-    <div class="col-sm-12 faded">
-        @include('shelves._breadcrumbs', ['shelf' => $shelf])
-    </div>
-@stop
-
-@section('body')
-
-    <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('lock') {{ trans('entities.shelves_permissions') }}</h3>
-            <div class="body">
-                @include('form/restriction-form', ['model' => $shelf])
-            </div>
-        </div>
-
-        <p>&nbsp;</p>
-
-        <div class="card">
-            <h3>@icon('copy') {{ trans('entities.shelves_copy_permissions_to_books') }}</h3>
-            <div class="body">
-                <p>{{ trans('entities.shelves_copy_permissions_explain') }}</p>
-                <form action="{{ $shelf->getUrl('/copy-permissions') }}" method="post" class="text-right">
-                    {{ csrf_field() }}
-                    <button class="button">{{ trans('entities.shelves_copy_permissions') }}</button>
-                </form>
-            </div>
-        </div>
-    </div>
-
-@stop
index 2aae2c6ff3dbd27cdca72ae20162374a5c54b184..afe56d577bb996c65e853d65b88cdf21780893b7 100644 (file)
@@ -1,42 +1,43 @@
-@extends('sidebar-layout')
+@extends('tri-layout')
 
-@section('toolbar')
-    <div class="col-sm-6 col-xs-1  faded">
-        @include('shelves._breadcrumbs', ['shelf' => $shelf])
-    </div>
-    <div class="col-sm-6 col-xs-11">
-        <div class="action-buttons faded">
-            @if(userCan('bookshelf-update', $shelf))
-                <a href="{{ $shelf->getUrl('/edit') }}" class="text-button text-primary">@icon('edit'){{ trans('common.edit') }}</a>
-            @endif
-            @if(userCan('restrictions-manage', $shelf) || userCan('bookshelf-delete', $shelf))
-                <div dropdown class="dropdown-container">
-                    <a dropdown-toggle class="text-primary text-button">@icon('more'){{ trans('common.more') }}</a>
-                    <ul>
-                        @if(userCan('restrictions-manage', $shelf))
-                            <li><a href="{{ $shelf->getUrl('/permissions') }}" class="text-primary">@icon('lock'){{ trans('entities.permissions') }}</a></li>
-                        @endif
-                        @if(userCan('bookshelf-delete', $shelf))
-                            <li><a href="{{ $shelf->getUrl('/delete') }}" class="text-neg">@icon('delete'){{ trans('common.delete') }}</a></li>
-                        @endif
-                    </ul>
+@section('body')
+
+    <div class="card content-wrap">
+        <h1 class="break-text">{{$shelf->name}}</h1>
+        <div class="book-content">
+            <p class="text-muted">{!! nl2br(e($shelf->description)) !!}</p>
+            @if(count($books) > 0)
+                <div class="entity-list">
+                    @foreach($books as $book)
+                        @include('books/list-item', ['book' => $book])
+                    @endforeach
                 </div>
+            @else
+                <p>
+                    <hr>
+                    <span class="text-muted italic">{{ trans('entities.shelves_empty_contents') }}</span>
+                    @if(userCan('bookshelf-create', $shelf))
+                        <br/>
+                        <a href="{{ $shelf->getUrl('/edit') }}" class="button outline bookshelf">{{ trans('entities.shelves_edit_and_assign') }}</a>
+                    @endif
+                </p>
             @endif
         </div>
     </div>
+
 @stop
 
-@section('sidebar')
+@section('left')
 
     @if($shelf->tags->count() > 0)
-        <section>
+        <div id="tags" class="mb-xl">
             @include('components.tag-list', ['entity' => $shelf])
-        </section>
+        </div>
     @endif
 
-    <div class="card entity-details">
-        <h3>@icon('info') {{ trans('common.details') }}</h3>
-        <div class="body text-small text-muted blended-links">
+    <div id="details" class="mb-xl">
+        <h5>{{ trans('common.details') }}</h5>
+        <div class="text-small text-muted blended-links">
             @include('partials.entity-meta', ['entity' => $shelf])
             @if($shelf->restricted)
                 <div class="active-restriction">
     </div>
 
     @if(count($activity) > 0)
-        <div class="activity card">
-            <h3>@icon('time') {{ trans('entities.recent_activity') }}</h3>
-            @include('partials/activity-list', ['activity' => $activity])
+        <div class="mb-xl">
+            <h5>{{ trans('entities.recent_activity') }}</h5>
+            @include('partials.activity-list', ['activity' => $activity])
         </div>
     @endif
 @stop
 
-@section('body')
+@section('right')
+    <div class="actions mb-xl">
+        <h5>{{ trans('common.actions') }}</h5>
+        <div class="icon-list text-primary">
 
-    <div class="container small nopad">
-        <h1 class="break-text">{{$shelf->name}}</h1>
-        <div class="book-content">
-            <p class="text-muted">{!! nl2br(e($shelf->description)) !!}</p>
-            @if(count($books) > 0)
-            <div class="page-list">
-                <hr>
-                @foreach($books as $book)
-                    @include('books/list-item', ['book' => $book])
-                    <hr>
-                @endforeach
-            </div>
-            @else
-            <p>
-                <hr>
-                <span class="text-muted italic">{{ trans('entities.shelves_empty_contents') }}</span>
-                @if(userCan('bookshelf-create', $shelf))
-                    <br>
-                    <a href="{{ $shelf->getUrl('/edit') }}" class="button outline bookshelf">{{ trans('entities.shelves_edit_and_assign') }}</a>
-                @endif
-            </p>
+            @if(userCan('bookshelf-update', $shelf))
+                <a href="{{ $shelf->getUrl('/edit') }}" class="icon-list-item">
+                    <span>@icon('edit')</span>
+                    <span>{{ trans('common.edit') }}</span>
+                </a>
             @endif
 
-    </div>
+            @if(userCan('restrictions-manage', $shelf))
+                <a href="{{ $shelf->getUrl('/permissions') }}" class="icon-list-item">
+                    <span>@icon('lock')</span>
+                    <span>{{ trans('entities.permissions') }}</span>
+                </a>
+            @endif
 
+            @if(userCan('bookshelf-delete', $shelf))
+                <a href="{{ $shelf->getUrl('/delete') }}" class="icon-list-item">
+                    <span>@icon('delete')</span>
+                    <span>{{ trans('common.delete') }}</span>
+                </a>
+            @endif
+
+        </div>
+    </div>
 @stop
+
+
+
+
diff --git a/resources/views/shelves/view-toggle.blade.php b/resources/views/shelves/view-toggle.blade.php
deleted file mode 100644 (file)
index 785e8ca..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<form action="{{ baseUrl("/settings/users/{$currentUser->id}/switch-shelf-view") }}" method="POST" class="inline">
-    {!! csrf_field() !!}
-    {!! method_field('PATCH') !!}
-    <input type="hidden" value="{{ $shelvesViewType === 'list'? 'grid' : 'list' }}" name="view_type">
-    @if ($shelvesViewType === 'list')
-        <button type="submit" class="text-pos text-button">@icon('grid'){{ trans('common.grid_view') }}</button>
-    @else
-        <button type="submit" class="text-pos text-button">@icon('list'){{ trans('common.list_view') }}</button>
-    @endif
-</form>
\ No newline at end of file
index bf853c09ef44505910bf54fdef2a4296ad9ac271..512b64e91fc87664dbb55c9b6af49c1a7fc4b0f7 100644 (file)
@@ -4,14 +4,8 @@
 
 @section('content')
 
-    <div class="toolbar-container">
-        <div class="faded-small toolbar">
-            <div class="container fluid">
-                <div class="row">
-                    @yield('toolbar')
-                </div>
-            </div>
-        </div>
+    <div class="toolbar px-xl py-m">
+        @yield('toolbar')
     </div>
 
 
         <div sidebar class="sidebar flex print-hidden" id="sidebar">
             <div class="sidebar-toggle primary-background-light">@icon('caret-right-circle')
             </div>
-            <div class="scroll-body">
+            <div class="scroll-body px-xl">
                 @yield('sidebar')
             </div>
         </div>
 
-        <div class="content flex @yield('body-wrap-classes')">
+        <div class="mr-xl flex @yield('body-wrap-classes')">
             @yield('body')
         </div>
     </div>
index eeb4129e0497f32132b9d8c6915bec2d9def7307..27ba079659ccdc4651db22963ad9bef51e254c45 100644 (file)
@@ -5,16 +5,9 @@
 @section('content')
 
     <div class="toolbar-container">
-        <div class="faded-small toolbar">
-            <div class="container fluid">
-                <div class="row">
-                    @yield('toolbar')
-                </div>
-            </div>
-        </div>
+        @yield('toolbar')
     </div>
 
-
     <div class="flex-fill flex">
         <div class="content flex">
             <div class="scroll-body">
diff --git a/resources/views/tri-layout.blade.php b/resources/views/tri-layout.blade.php
new file mode 100644 (file)
index 0000000..5f3d381
--- /dev/null
@@ -0,0 +1,31 @@
+@extends('base')
+
+@section('body-class', 'tri-layout')
+
+@section('content')
+
+    {{--<div class="toolbar px-xl">--}}
+        {{--@yield('toolbar')--}}
+    {{--</div>--}}
+    {{--TODO - Cleanup toolbar usage--}}
+
+    <div class="tri-layout-container mt-m" tri-layout @yield('container-attrs') >
+
+        <div class="tri-layout-left print-hidden pt-m" id="sidebar">
+            <div class="tri-layout-left-contents">
+                @yield('left')
+            </div>
+        </div>
+
+        <div class="@yield('body-wrap-classes') tri-layout-middle">
+            @yield('body')
+        </div>
+
+        <div class="tri-layout-right print-hidden pt-m">
+            <div class="tri-layout-right-contents">
+                @yield('right')
+            </div>
+        </div>
+    </div>
+
+@stop
index d42ca9f51e91da14ab37d07bf9e72eccb6fcfbe7..cd5d75f8fb9b9da6a7d3e0c0569cab7485c7fb7d 100644 (file)
@@ -1,25 +1,30 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'users'])
-@stop
-
 @section('body')
 
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('users-add') {{ trans('settings.users_add_new') }}</h3>
-            <div class="body">
-                <form action="{{ baseUrl("/settings/users/create") }}" method="post">
-                    {!! csrf_field() !!}
-                    @include('users/forms/' . $authMethod)
-                    <div class="form-group text-right">
-                        <a href="{{  baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        <button class="button pos" type="submit">{{ trans('common.save') }}</button>
-                    </div>
-                </form>
-            </div>
+
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'users'])
+        </div>
+
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ trans('settings.users_add_new') }}</h1>
+
+            <form action="{{ baseUrl("/settings/users/create") }}" method="post">
+                {!! csrf_field() !!}
+
+                <div class="setting-list">
+                    @include('users.form')
+                </div>
+
+                <div class="form-group text-right">
+                    <a href="{{  baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    <button class="button primary" type="submit">{{ trans('common.save') }}</button>
+                </div>
+
+            </form>
+
         </div>
     </div>
 
index 39cd12200bf454ef8c283089cda42de0e864d275..15ad7a9ec66df6678ed3777f261bb55f7e6dedf2 100644 (file)
@@ -1,27 +1,30 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'users'])
-@stop
-
 @section('body')
-
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('delete') {{ trans('settings.users_delete') }}</h3>
-            <div class="body">
-                <p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
-                <p class="text-neg">{{ trans('settings.users_delete_confirm') }}</p>
 
-                <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="POST">
-                    {!! csrf_field() !!}
-                    <input type="hidden" name="_method" value="DELETE">
-                    <a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
-                    <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
-                </form>
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'users'])
+        </div>
+
+        <div class="card content-wrap auto-height">
+            <h1 class="list-heading">{{ trans('settings.users_delete') }}</h1>
+
+            <p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
+
+            <div class="grid half">
+                <p class="text-neg"><strong>{{ trans('settings.users_delete_confirm') }}</strong></p>
+                <div>
+                    <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="POST" class="text-right">
+                        {!! csrf_field() !!}
+
+                        <input type="hidden" name="_method" value="DELETE">
+                        <a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
+                        <button type="submit" class="button primary">{{ trans('common.confirm') }}</button>
+                    </form>
+                </div>
             </div>
+
         </div>
     </div>
-
 @stop
index 1b0514f9cdc4de07a3cfcee151e3abb62c2ff44e..e6e66665f08bb97e2d1e0edc95d1197ba011324a 100644 (file)
@@ -1,91 +1,91 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'users'])
-@stop
-
 @section('body')
-
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('edit') {{ $user->id === $currentUser->id ? trans('settings.users_edit_profile') : trans('settings.users_edit') }}</h3>
-            <div class="body">
-                <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="post">
-                    <div class="row">
-                        <div class="col-sm-6">
-                            {!! csrf_field() !!}
-                            <input type="hidden" name="_method" value="put">
-                            @include('users.forms.' . $authMethod, ['model' => $user])
 
-                        </div>
-                        <div class="col-sm-6">
-                            <div class="form-group" id="logo-control">
-                                <label for="user-avatar">{{ trans('settings.users_avatar') }}</label>
-                                <p class="small">{{ trans('settings.users_avatar_desc') }}</p>
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'users'])
+        </div>
 
-                                @include('components.image-picker', [
-                                      'resizeHeight' => '512',
-                                      'resizeWidth' => '512',
-                                      'showRemove' => false,
-                                      'defaultImage' => baseUrl('/user_avatar.png'),
-                                      'currentImage' => $user->getAvatar(80),
-                                      'currentId' => $user->image_id,
-                                      'name' => 'image_id',
-                                      'imageClass' => 'avatar large'
-                                  ])
-                            </div>
-                            <div class="form-group">
-                                <label for="user-language">{{ trans('settings.users_preferred_language') }}</label>
-                                <select name="setting[language]" id="user-language">
+        <div class="card content-wrap">
+            <h1 class="list-heading">{{ $user->id === $currentUser->id ? trans('settings.users_edit_profile') : trans('settings.users_edit') }}</h1>
+            <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="post">
+                {!! csrf_field() !!}
+                <input type="hidden" name="_method" value="PUT">
 
-                                    @foreach(trans('settings.language_select') as $lang => $label)
-                                        <option @if(setting()->getUser($user, 'language', config('app.default_locale')) === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
-                                    @endforeach
-                                </select>
-                            </div>
+                <div class="setting-list">
+                    @include('users.form', ['model' => $user, 'authMethod' => $authMethod])
+
+                    <div class="grid half large-gap">
+                        <div>
+                            <label for="user-avatar" class="setting-list-label">{{ trans('settings.users_avatar') }}</label>
+                            <p class="small">{{ trans('settings.users_avatar_desc') }}</p>
+                        </div>
+                        <div>
+                            @include('components.image-picker', [
+                                'resizeHeight' => '512',
+                                'resizeWidth' => '512',
+                                'showRemove' => false,
+                                'defaultImage' => baseUrl('/user_avatar.png'),
+                                'currentImage' => $user->getAvatar(80),
+                                'currentId' => $user->image_id,
+                                'name' => 'image_id',
+                                'imageClass' => 'avatar large'
+                            ])
                         </div>
                     </div>
-                    <div class="form-group text-right">
-                        <a href="{{  baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
-                        @if($authMethod !== 'system')
-                            <a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="neg button">{{ trans('settings.users_delete') }}</a>
-                        @endif
-                        <button class="button pos" type="submit">{{ trans('common.save') }}</button>
+
+                    <div class="grid half large-gap v-center">
+                        <div>
+                            <label for="user-language" class="setting-list-label">{{ trans('settings.users_preferred_language') }}</label>
+                            <p class="small">
+                                {{ trans('settings.users_preferred_language_desc') }}
+                            </p>
+                        </div>
+                        <div>
+                            <select name="setting[language]" id="user-language">
+                                @foreach(trans('settings.language_select') as $lang => $label)
+                                    <option @if(setting()->getUser($user, 'language', config('app.default_locale')) === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
+                                @endforeach
+                            </select>
+                        </div>
                     </div>
-                </form>
-            </div>
+
+                </div>
+
+                <div class="text-right">
+                    <a href="{{  baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
+                    @if($authMethod !== 'system')
+                        <a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="button outline">{{ trans('settings.users_delete') }}</a>
+                    @endif
+                    <button class="button primary" type="submit">{{ trans('common.save') }}</button>
+                </div>
+            </form>
         </div>
 
         @if($currentUser->id === $user->id && count($activeSocialDrivers) > 0)
-            <div class="card">
-                <h3>@icon('login')  {{ trans('settings.users_social_accounts') }}</h3>
-                <div class="body">
-                    <p class="text-muted">{{ trans('settings.users_social_accounts_info') }}</p>
-                    <div class="container">
-                        <div class="row">
-                            @foreach($activeSocialDrivers as $driver => $enabled)
-                                <div class="col-sm-4 col-xs-6 text-center">
-                                    <div>@icon('auth/'. $driver, ['style' => 'width: 56px;height: 56px;'])</div>
-                                    <div>
-                                        @if($user->hasSocialAccount($driver))
-                                            <a href="{{ baseUrl("/login/service/{$driver}/detach") }}" class="button neg">{{ trans('settings.users_social_disconnect') }}</a>
-                                        @else
-                                            <a href="{{ baseUrl("/login/service/{$driver}") }}" class="button pos">{{ trans('settings.users_social_connect') }}</a>
-                                        @endif
-                                    </div>
-                                    <div>&nbsp;</div>
+            <div class="card content-wrap auto-height">
+                <h2 class="list-heading">{{ trans('settings.users_social_accounts') }}</h2>
+                <p class="text-muted">{{ trans('settings.users_social_accounts_info') }}</p>
+                <div class="container">
+                    <div class="grid third">
+                        @foreach($activeSocialDrivers as $driver => $enabled)
+                            <div class="text-center mb-m">
+                                <div>@icon('auth/'. $driver, ['style' => 'width: 56px;height: 56px;'])</div>
+                                <div>
+                                    @if($user->hasSocialAccount($driver))
+                                        <a href="{{ baseUrl("/login/service/{$driver}/detach") }}" class="button small outline">{{ trans('settings.users_social_disconnect') }}</a>
+                                    @else
+                                        <a href="{{ baseUrl("/login/service/{$driver}") }}" class="button small outline">{{ trans('settings.users_social_connect') }}</a>
+                                    @endif
                                 </div>
-                            @endforeach
-                        </div>
+                            </div>
+                        @endforeach
                     </div>
                 </div>
             </div>
         @endif
-
-
     </div>
 
-    <p class="margin-top large"><br></p>
     @include('components.image-manager', ['imageType' => 'user'])
-@stop
\ No newline at end of file
+@stop
diff --git a/resources/views/users/form.blade.php b/resources/views/users/form.blade.php
new file mode 100644 (file)
index 0000000..2459626
--- /dev/null
@@ -0,0 +1,70 @@
+
+@if($authMethod === 'system' && $user->system_name == 'public')
+    <p class="mb-none text-secondary">{{ trans('settings.users_system_public') }}</p>
+@endif
+
+<div class="pt-m">
+    <label class="setting-list-label">{{ trans('settings.users_details') }}</label>
+    @if($authMethod === 'standard')
+        <p class="small">{{ trans('settings.users_details_desc') }}</p>
+    @endif
+    @if($authMethod === 'ldap' || $authMethod === 'system')
+        <p class="small">{{ trans('settings.users_details_desc_no_email') }}</p>
+    @endif
+    <div class="grid half mt-m large-gap">
+        <div>
+            <label for="name">{{ trans('auth.name') }}</label>
+            @include('form.text', ['name' => 'name'])
+        </div>
+        <div>
+            @if($authMethod !== 'ldap' || userCan('users-manage'))
+                <label for="email">{{ trans('auth.email') }}</label>
+                @include('form.text', ['name' => 'email'])
+            @endif
+        </div>
+    </div>
+</div>
+
+@if($authMethod === 'ldap' && userCan('users-manage'))
+    <div class="grid half large-gap v-center">
+        <div>
+            <label class="setting-list-label">{{ trans('settings.users_external_auth_id') }}</label>
+            <p class="small">{{ trans('settings.users_external_auth_id_desc') }}</p>
+        </div>
+        <div>
+            @include('form.text', ['name' => 'external_auth_id'])
+        </div>
+    </div>
+@endif
+
+@if(userCan('users-manage'))
+    <div>
+        <label for="role" class="setting-list-label">{{ trans('settings.users_role') }}</label>
+        <p class="small">{{ trans('settings.users_role_desc') }}</p>
+        <div class="mt-m">
+            @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
+        </div>
+    </div>
+@endif
+
+@if($authMethod === 'standard')
+    <div>
+        <label class="setting-list-label">{{ trans('settings.users_password') }}</label>
+        <p class="small">{{ trans('settings.users_password_desc') }}</p>
+        @if(isset($model))
+            <p class="small">
+                {{ trans('settings.users_password_warning') }}
+            </p>
+        @endif
+        <div class="grid half mt-m large-gap">
+            <div>
+                <label for="password">{{ trans('auth.password') }}</label>
+                @include('form.password', ['name' => 'password'])
+            </div>
+            <div>
+                <label for="password-confirm">{{ trans('auth.password_confirm') }}</label>
+                @include('form.password', ['name' => 'password-confirm'])
+            </div>
+        </div>
+    </div>
+@endif
\ No newline at end of file
diff --git a/resources/views/users/forms/ldap.blade.php b/resources/views/users/forms/ldap.blade.php
deleted file mode 100644 (file)
index f6e8b4c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<div class="form-group">
-    <label for="name">{{ trans('auth.name') }}</label>
-    @include('form.text', ['name' => 'name'])
-</div>
-
-@if(userCan('users-manage'))
-<div class="form-group">
-    <label for="email">{{ trans('auth.email') }}</label>
-    @include('form.text', ['name' => 'email'])
-</div>
-@endif
-
-@if(userCan('users-manage'))
-    <div class="form-group">
-        <label for="role">{{ trans('settings.users_role') }}</label>
-        @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
-    </div>
-@endif
-
-@if(userCan('users-manage'))
-    <div class="form-group">
-        <label for="external_auth_id">{{ trans('settings.users_external_auth_id') }}</label>
-        @include('form.text', ['name' => 'external_auth_id'])
-    </div>
-@endif
\ No newline at end of file
diff --git a/resources/views/users/forms/standard.blade.php b/resources/views/users/forms/standard.blade.php
deleted file mode 100644 (file)
index fa71236..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<div class="form-group">
-    <label for="name">{{ trans('auth.name') }}</label>
-    @include('form.text', ['name' => 'name'])
-</div>
-
-<div class="form-group">
-    <label for="email">{{ trans('auth.email') }}</label>
-    @include('form.text', ['name' => 'email'])
-</div>
-
-@if(userCan('users-manage'))
-    <div class="form-group">
-        <label for="role">{{ trans('settings.users_role') }}</label>
-        @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
-    </div>
-@endif
-
-@if(isset($model))
-    <div class="form-group">
-        <span class="text-muted">
-            {{ trans('settings.users_password_warning') }}
-        </span>
-    </div>
-@endif
-
-<div class="form-group">
-    <label for="password">{{ trans('auth.password') }}</label>
-    @include('form.password', ['name' => 'password'])
-</div>
-
-<div class="form-group">
-    <label for="password-confirm">{{ trans('auth.password_confirm') }}</label>
-    @include('form.password', ['name' => 'password-confirm'])
-</div>
\ No newline at end of file
diff --git a/resources/views/users/forms/system.blade.php b/resources/views/users/forms/system.blade.php
deleted file mode 100644 (file)
index 6243010..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-@if($user->system_name == 'public')
-    <p>{{ trans('settings.users_system_public') }}</p>
-@endif
-
-<div class="form-group">
-    <label for="name">{{ trans('auth.name') }}</label>
-    @include('form.text', ['name' => 'name'])
-</div>
-
-<div class="form-group">
-    <label for="email">{{ trans('auth.email') }}</label>
-    @include('form.text', ['name' => 'email'])
-</div>
-
-@if(userCan('users-manage'))
-    <div class="form-group">
-        <label for="role">{{ trans('settings.users_role') }}</label>
-        @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
-    </div>
-@endif
-
index fd05a7a15cac196970e4c3f8e8cf10b109269a93..af6b4d4f93e70d25c81a7dfff0af76e2479503c1 100644 (file)
@@ -1,74 +1,66 @@
 @extends('simple-layout')
 
-@section('toolbar')
-    @include('settings/navbar', ['selected' => 'users'])
-@stop
-
 @section('body')
     <div class="container small">
-        <p>&nbsp;</p>
-        <div class="card">
-            <h3>@icon('users') {{ trans('settings.users') }}</h3>
-            <div class="body">
-                <div class="container">
-                    <div class="row">
-                        <div class="col-sm-4">
-                            <form method="get" action="{{ baseUrl("/settings/users") }}">
-                                @foreach(collect($listDetails)->except('search') as $name => $val)
-                                    <input type="hidden" name="{{ $name }}" value="{{ $val }}">
-                                @endforeach
-                                <input type="text" name="search" placeholder="{{ trans('settings.users_search') }}" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
-                            </form>
-                        </div>
-                        <div class="col-sm-8 text-right">
-                            @if(userCan('users-manage'))
-                                <a href="{{ baseUrl("/settings/users/create") }}" style="margin-top: 0;" class="pos button">{{ trans('settings.users_add_new') }}</a>
-                            @endif
-                        </div>
+
+        <div class="py-m">
+            @include('settings.navbar', ['selected' => 'users'])
+        </div>
+
+        <div class="card content-wrap">
+
+            <div class="grid right-focus v-center">
+                <h1 class="list-heading">{{ trans('settings.users') }}</h1>
+
+                <div class="text-right">
+                    <div class="block inline mr-s">
+                        <form method="get" action="{{ baseUrl("/settings/users") }}">
+                            @foreach(collect($listDetails)->except('search') as $name => $val)
+                                <input type="hidden" name="{{ $name }}" value="{{ $val }}">
+                            @endforeach
+                            <input type="text" name="search" placeholder="{{ trans('settings.users_search') }}" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
+                        </form>
                     </div>
+                    @if(userCan('users-manage'))
+                        <a href="{{ baseUrl("/settings/users/create") }}" style="margin-top: 0;" class="outline button">{{ trans('settings.users_add_new') }}</a>
+                    @endif
                 </div>
+            </div>
 
-                <table class="table">
+            {{--TODO - Add last login--}}
+            <table class="table">
+                <tr>
+                    <th></th>
+                    <th>
+                        <a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'name']) }}">{{ trans('auth.name') }}</a>
+                        /
+                        <a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'email']) }}">{{ trans('auth.email') }}</a>
+                    </th>
+                    <th>{{ trans('settings.role_user_roles') }}</th>
+                </tr>
+                @foreach($users as $user)
                     <tr>
-                        <th></th>
-                        <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'name']) }}">{{ trans('auth.name') }}</a></th>
-                        <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'email']) }}">{{ trans('auth.email') }}</a></th>
-                        <th>{{ trans('settings.role_user_roles') }}</th>
+                        <td class="text-center" style="line-height: 0;"><img class="avatar med" src="{{ $user->getAvatar(40)}}" alt="{{ $user->name }}"></td>
+                        <td>
+                            @if(userCan('users-manage') || $currentUser->id == $user->id)
+                                <a href="{{ baseUrl("/settings/users/{$user->id}") }}">
+                                    @endif
+                                    {{ $user->name }} <br> <span class="text-muted">{{ $user->email }}</span>
+                                    @if(userCan('users-manage') || $currentUser->id == $user->id)
+                                </a>
+                            @endif
+                        </td>
+                        <td>
+                            @foreach($user->roles as $index => $role)
+                                <small><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{$role->display_name}}</a>@if($index !== count($user->roles) -1),@endif</small>
+                            @endforeach
+                        </td>
                     </tr>
-                    @foreach($users as $user)
-                        <tr>
-                            <td style="line-height: 0;"><img class="avatar med" src="{{ $user->getAvatar(40)}}" alt="{{ $user->name }}"></td>
-                            <td>
-                                @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    <a href="{{ baseUrl("/settings/users/{$user->id}") }}">
-                                        @endif
-                                        {{ $user->name }}
-                                        @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    </a>
-                                @endif
-                            </td>
-                            <td>
-                                @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    <a href="{{ baseUrl("/settings/users/{$user->id}") }}">
-                                        @endif
-                                        {{ $user->email }}
-                                        @if(userCan('users-manage') || $currentUser->id == $user->id)
-                                    </a>
-                                @endif
-                            </td>
-                            <td>
-                                @foreach($user->roles as $index => $role)
-                                    <small><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{$role->display_name}}</a>@if($index !== count($user->roles) -1),@endif</small>
-                                @endforeach
-                            </td>
-                        </tr>
-                    @endforeach
-                </table>
-
-                <div>
-                    {{ $users->links() }}
-                </div>
+                @endforeach
+            </table>
 
+            <div>
+                {{ $users->links() }}
             </div>
         </div>
 
index 4f67f1be2a59ba90b880988425a942cb4d21b7ee..f41754498628d7909cab6f5d19d02efd7085e62b 100644 (file)
@@ -1,84 +1,88 @@
-@extends('sidebar-layout')
+@extends('simple-layout')
 
-@section('toolbar')
-    <div class="col-sm-6 col-xs-1 faded">
-        <div class="breadcrumbs">
-            <a href="{{ $user->getProfileUrl() }}" class="text-button">@icon('user'){{ $user->name }}</a>
-        </div>
-    </div>
-@stop
-
-@section('sidebar')
-    <div class="card" id="recent-activity">
-        <h3>@icon('time') {{ trans('entities.recent_activity') }}</h3>
-        @include('partials/activity-list', ['activity' => $activity])
-    </div>
-@stop
+{{--TODO - Include links to search based on this user being the creator for each entity type--}}
+{{--Linking either the "Created content" items or as "View All" links next to headers--}}
+{{--TODO - Add shelves?--}}
 
 @section('body')
 
-    <div class="container small">
+    <div class="container pt-xl">
 
-        <div class="padded-top large"></div>
+        <div class="grid right-focus reverse-collapse">
 
-        <div class="row">
-            <div class="col-md-7">
-                <div class="clearfix">
-                    <div class="padded-right float left">
-                        <img class="avatar square huge" src="{{ $user->getAvatar(120) }}" alt="{{ $user->name }}">
-                    </div>
-                    <div>
-                        <h3 style="margin-top: 0;">{{ $user->name }}</h3>
-                        <p class="text-muted">
-                            {{ trans('entities.profile_user_for_x', ['time' => $user->created_at->diffForHumans(null, true)]) }}
-                        </p>
-                    </div>
+            <div>
+                <div id="recent-user-activity" class="mb-xl">
+                    <h5>{{ trans('entities.recent_activity') }}</h5>
+                    @include('partials/activity-list', ['activity' => $activity])
                 </div>
             </div>
-            <div class="col-md-5 text-bigger" id="content-counts">
-                <div class="text-muted">{{ trans('entities.profile_created_content') }}</div>
-                <a href="#recent-books">
-                    <div class="text-book">
-                        @icon('book')  {{ trans_choice('entities.x_books', $assetCounts['books']) }}
-                    </div>
-                </a>
-                <a href="#recent-chapters">
-                    <div class="text-chapter">
-                        @icon('chapter') {{ trans_choice('entities.x_chapters', $assetCounts['chapters']) }}
-                    </div>
-                </a>
-                <a href="#recent-pages">
-                    <div class="text-page">
-                        @icon('page') {{ trans_choice('entities.x_pages', $assetCounts['pages']) }}
+
+            <div>
+                <div class="card content-wrap auto-height">
+                    <div class="grid left-focus v-center">
+                        <div>
+                            <div class="mr-m float left">
+                                <img class="avatar square huge" src="{{ $user->getAvatar(120) }}" alt="{{ $user->name }}">
+                            </div>
+                            <div>
+                                <h4 class="mt-md">{{ $user->name }}</h4>
+                                <p class="text-muted">
+                                    {{ trans('entities.profile_user_for_x', ['time' => $user->created_at->diffForHumans(null, true)]) }}
+                                </p>
+                            </div>
+                        </div>
+                        <div id="content-counts">
+                            <div class="text-muted">{{ trans('entities.profile_created_content') }}</div>
+                            <div class="icon-list">
+                                <a href="#recent-books" class="text-book icon-list-item">
+                                    <span>@icon('book')</span>
+                                    <span>{{ trans_choice('entities.x_books', $assetCounts['books']) }}</span>
+                                </a>
+                                <a href="#recent-chapters" class="text-chapter icon-list-item">
+                                    <span>@icon('chapter')</span>
+                                    <span>{{ trans_choice('entities.x_chapters', $assetCounts['chapters']) }}</span>
+                                </a>
+                                <a href="#recent-pages" class="text-page icon-list-item">
+                                    <span>@icon('page')</span>
+                                    <span>{{ trans_choice('entities.x_pages', $assetCounts['pages']) }}</span>
+                                </a>
+                            </div>
+
+                        </div>
                     </div>
-                </a>
-            </div>
-        </div>
+                </div>
+
+                <div class="card content-wrap auto-height book-contents">
+                    <h2 id="recent-pages" class="list-heading">{{ trans('entities.recently_created_pages') }}</h2>
+                    @if (count($recentlyCreated['pages']) > 0)
+                        @include('partials/entity-list', ['entities' => $recentlyCreated['pages']])
+                    @else
+                        <p class="text-muted">{{ trans('entities.profile_not_created_pages', ['userName' => $user->name]) }}</p>
+                    @endif
+                </div>
 
+                <div class="card content-wrap auto-height book-contents">
+                    <h2 id="recent-chapters" class="list-heading">{{ trans('entities.recently_created_chapters') }}</h2>
+                    @if (count($recentlyCreated['chapters']) > 0)
+                        @include('partials/entity-list', ['entities' => $recentlyCreated['chapters']])
+                    @else
+                        <p class="text-muted">{{ trans('entities.profile_not_created_chapters', ['userName' => $user->name]) }}</p>
+                    @endif
+                </div>
 
-        <hr class="even">
-        <h3 id="recent-pages">{{ trans('entities.recently_created_pages') }}</h3>
-        @if (count($recentlyCreated['pages']) > 0)
-            @include('partials/entity-list', ['entities' => $recentlyCreated['pages']])
-        @else
-            <p class="text-muted">{{ trans('entities.profile_not_created_pages', ['userName' => $user->name]) }}</p>
-        @endif
+                <div class="card content-wrap auto-height book-contents">
+                    <h2 id="recent-books" class="list-heading">{{ trans('entities.recently_created_books') }}</h2>
+                    @if (count($recentlyCreated['books']) > 0)
+                        @include('partials/entity-list', ['entities' => $recentlyCreated['books']])
+                    @else
+                        <p class="text-muted">{{ trans('entities.profile_not_created_books', ['userName' => $user->name]) }}</p>
+                    @endif
+                </div>
+            </div>
+
+        </div>
 
-        <hr class="even">
-        <h3 id="recent-chapters">{{ trans('entities.recently_created_chapters') }}</h3>
-        @if (count($recentlyCreated['chapters']) > 0)
-            @include('partials/entity-list', ['entities' => $recentlyCreated['chapters']])
-        @else
-            <p class="text-muted">{{ trans('entities.profile_not_created_chapters', ['userName' => $user->name]) }}</p>
-        @endif
 
-        <hr class="even">
-        <h3 id="recent-books">{{ trans('entities.recently_created_books') }}</h3>
-        @if (count($recentlyCreated['books']) > 0)
-            @include('partials/entity-list', ['entities' => $recentlyCreated['books']])
-        @else
-            <p class="text-muted">{{ trans('entities.profile_not_created_books', ['userName' => $user->name]) }}</p>
-        @endif
     </div>
 
 
index d3c5f46d3ccdce717e167d4e545b4f19639feb68..41da967d9000cd44fe2ce907db7d53cd58c76dec 100644 (file)
@@ -10,7 +10,6 @@ Route::group(['middleware' => 'auth'], function () {
         ->where('path', '.*$');
 
     Route::group(['prefix' => 'pages'], function() {
-        Route::get('/recently-created', 'PageController@showRecentlyCreated');
         Route::get('/recently-updated', 'PageController@showRecentlyUpdated');
     });
 
@@ -24,8 +23,8 @@ Route::group(['middleware' => 'auth'], function () {
         Route::get('/{slug}', 'BookshelfController@show');
         Route::put('/{slug}', 'BookshelfController@update');
         Route::delete('/{slug}', 'BookshelfController@destroy');
-        Route::get('/{slug}/permissions', 'BookshelfController@showRestrict');
-        Route::put('/{slug}/permissions', 'BookshelfController@restrict');
+        Route::get('/{slug}/permissions', 'BookshelfController@showPermissions');
+        Route::put('/{slug}/permissions', 'BookshelfController@permissions');
         Route::post('/{slug}/copy-permissions', 'BookshelfController@copyPermissions');
     });
 
@@ -40,8 +39,8 @@ Route::group(['middleware' => 'auth'], function () {
         Route::delete('/{id}', 'BookController@destroy');
         Route::get('/{slug}/sort-item', 'BookController@getSortItem');
         Route::get('/{slug}', 'BookController@show');
-        Route::get('/{bookSlug}/permissions', 'BookController@showRestrict');
-        Route::put('/{bookSlug}/permissions', 'BookController@restrict');
+        Route::get('/{bookSlug}/permissions', 'BookController@showPermissions');
+        Route::put('/{bookSlug}/permissions', 'BookController@permissions');
         Route::get('/{slug}/delete', 'BookController@showDelete');
         Route::get('/{bookSlug}/sort', 'BookController@sort');
         Route::put('/{bookSlug}/sort', 'BookController@saveSort');
@@ -65,8 +64,8 @@ Route::group(['middleware' => 'auth'], function () {
         Route::post('/{bookSlug}/page/{pageSlug}/copy', 'PageController@copy');
         Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
         Route::get('/{bookSlug}/draft/{pageId}/delete', 'PageController@showDeleteDraft');
-        Route::get('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@showRestrict');
-        Route::put('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@restrict');
+        Route::get('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@showPermissions');
+        Route::put('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@permissions');
         Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
         Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy');
         Route::delete('/{bookSlug}/draft/{pageId}', 'PageController@destroyDraft');
@@ -88,11 +87,11 @@ Route::group(['middleware' => 'auth'], function () {
         Route::get('/{bookSlug}/chapter/{chapterSlug}/move', 'ChapterController@showMove');
         Route::put('/{bookSlug}/chapter/{chapterSlug}/move', 'ChapterController@move');
         Route::get('/{bookSlug}/chapter/{chapterSlug}/edit', 'ChapterController@edit');
-        Route::get('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@showRestrict');
+        Route::get('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@showPermissions');
         Route::get('/{bookSlug}/chapter/{chapterSlug}/export/pdf', 'ChapterController@exportPdf');
         Route::get('/{bookSlug}/chapter/{chapterSlug}/export/html', 'ChapterController@exportHtml');
         Route::get('/{bookSlug}/chapter/{chapterSlug}/export/plaintext', 'ChapterController@exportPlainText');
-        Route::put('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@restrict');
+        Route::put('/{bookSlug}/chapter/{chapterSlug}/permissions', 'ChapterController@permissions');
         Route::get('/{bookSlug}/chapter/{chapterSlug}/delete', 'ChapterController@showDelete');
         Route::delete('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@destroy');
     });
@@ -155,6 +154,7 @@ Route::group(['middleware' => 'auth'], function () {
     Route::get('/search', 'SearchController@search');
     Route::get('/search/book/{bookId}', 'SearchController@searchBook');
     Route::get('/search/chapter/{bookId}', 'SearchController@searchChapter');
+    Route::get('/search/entity/siblings', 'SearchController@searchSiblings');
 
     // Other Pages
     Route::get('/', 'HomeController@index');
@@ -176,6 +176,7 @@ Route::group(['middleware' => 'auth'], function () {
         Route::get('/users/{id}/delete', 'UserController@delete');
         Route::patch('/users/{id}/switch-book-view', 'UserController@switchBookView');
         Route::patch('/users/{id}/switch-shelf-view', 'UserController@switchShelfView');
+        Route::patch('/users/{id}/change-sort/{type}', 'UserController@changeSort');
         Route::post('/users/create', 'UserController@store');
         Route::get('/users/{id}', 'UserController@edit');
         Route::put('/users/{id}', 'UserController@update');
index 5c0501e3ba627136916f1052e53f59e7bb30dc8a..4eae9b9be34683eec0f4efd08f039762e556c6ac 100644 (file)
@@ -2,7 +2,7 @@ const path = require('path');
 const dev = process.env.NODE_ENV !== 'production';
 
 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const ExtractTextPlugin = require("extract-text-webpack-plugin");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
 
 const config = {
     target: 'web',
@@ -35,12 +35,15 @@ const config = {
             },
             {
                 test: /\.scss$/,
-                use: ExtractTextPlugin.extract({
-                    fallback: "style-loader",
-                    use: [{
+                use: [
+                    {
+                        loader: MiniCssExtractPlugin.loader,
+                        options: {}
+                    },
+                    {
                         loader: "css-loader", options: {
-                            sourceMap: dev
-                        }
+                        sourceMap: dev
+                    }
                     }, {
                         loader: 'postcss-loader',
                         options: {
@@ -54,13 +57,15 @@ const config = {
                         loader: "sass-loader", options: {
                             sourceMap: dev
                         }
-                    }]
-                })
+                    }
+                ]
             }
         ]
     },
     plugins: [
-        new ExtractTextPlugin("[name].css"),
+        new MiniCssExtractPlugin({
+            filename: "[name].css",
+        }),
     ]
 };