Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
89be30f
Started on a design update
ssddanbrown Oct 16, 2018
0e395b1
Started reworking of page-show design
ssddanbrown Oct 21, 2018
c356612
Added sidebar layout size tweaks
ssddanbrown Nov 4, 2018
4a87201
Merge branch 'master' into 2019-design
ssddanbrown Nov 11, 2018
4df1170
Updated book-tree design and abstracted breadcrumb template
ssddanbrown Nov 11, 2018
d39fc84
Merge branch 'master' into 2019-design
ssddanbrown Dec 1, 2018
aabd4c0
Started looking at the books listing design
ssddanbrown Dec 1, 2018
2a882a4
Updated books listing to three column layout design
ssddanbrown Dec 1, 2018
0b976d9
Added list sorting styles, Yet to add functionality
ssddanbrown Dec 1, 2018
4c574c2
Implemented functionality to make books sort function
ssddanbrown Dec 7, 2018
e147419
Added responsive functionality to tri-layout view.
ssddanbrown Dec 8, 2018
8fd8652
Added tri-layout desktop sticky-scroll
ssddanbrown Dec 9, 2018
ff0b900
Cleaned existing grid view up a little
ssddanbrown Dec 9, 2018
7f95b51
Rolled tri-layout to page edit and book-create
ssddanbrown Dec 9, 2018
163a57c
Merge branch 'master' into 2019-design
ssddanbrown Jan 13, 2019
0efed43
Converted more views to new layout and made breadcrumbs more flexible
ssddanbrown Jan 13, 2019
3260336
Updated a bunch of book views
ssddanbrown Jan 31, 2019
2098896
Migrated a whole load more page/chapter/shelf views
ssddanbrown Feb 2, 2019
880d4f3
Started the migration of the setting views
ssddanbrown Feb 2, 2019
138f5d5
Updated user and shelf views to new design
ssddanbrown Feb 3, 2019
5325870
Updated auth pages to new design, Removed public layout
ssddanbrown Feb 3, 2019
49deab3
Fixed page edit to have white background
ssddanbrown Feb 3, 2019
67d4fa0
Updated npm packages and migrated webpack css plugin
ssddanbrown Feb 3, 2019
3286f29
Merge branch 'master' into 2019-design
ssddanbrown Feb 9, 2019
a112c11
Re-ordered and updated main settings page
ssddanbrown Feb 16, 2019
b00b319
Re-arranged some list items to flexbox instead of grid
ssddanbrown Feb 16, 2019
352cbbd
Updated design of page navigation box
ssddanbrown Feb 16, 2019
e9be2b7
Standardized setting casing
ssddanbrown Feb 16, 2019
f1e571a
Made shelf listing more unique & efficient
ssddanbrown Feb 16, 2019
8445304
Added book sort helper buttons
ssddanbrown Feb 17, 2019
e70423c
Standardized breadcrumbs a little further with icons
ssddanbrown Feb 17, 2019
035a0d8
Added experimental breadcrumb traversal
ssddanbrown Feb 24, 2019
5f2d226
Merge branch 'master' into 2019-design
ssddanbrown Mar 10, 2019
837d2bc
Improved login, Fixed breadcrumbs & improved grid thumbnails
ssddanbrown Mar 16, 2019
8b7bee7
Updated standard entity lists
ssddanbrown Mar 17, 2019
53a26a3
Merge branch 'master' into 2019-design
ssddanbrown Mar 30, 2019
42e908c
Cleaned up some existing tri-column views
ssddanbrown Mar 30, 2019
60d175a
Cleaned up sidebar book tree and moved details
ssddanbrown Mar 30, 2019
bda8aa4
Fixed up edit views to use new layout
ssddanbrown Mar 30, 2019
37bf7f1
Implemented new design in entity selector
ssddanbrown Mar 30, 2019
666ced9
Fixed tri-layout overflow in some scenarios
ssddanbrown Mar 30, 2019
17969c0
Added shelves and search shortcuts to profile page
ssddanbrown Apr 6, 2019
aedff7d
Added book selector to books sort
ssddanbrown Apr 6, 2019
745a0bb
Updated custom homepage views
ssddanbrown Apr 6, 2019
67ed471
Cleaned up old toolbar usage
ssddanbrown Apr 6, 2019
7cda9b0
Updated tests to suit layout changes, Updated 404 page
ssddanbrown Apr 6, 2019
d9cde41
Fixed entity excerpt function signature misalignment
ssddanbrown Apr 6, 2019
0a06e2b
Actioned some todo items, Cleaned old grid css
ssddanbrown Apr 7, 2019
8c21b53
Cleaned up usage of some core scss files
ssddanbrown Apr 7, 2019
4a127c2
Removed important color overrides to a tags
ssddanbrown Apr 7, 2019
221a483
Standardised view referencing to dot-notation
ssddanbrown Apr 7, 2019
b12ae6d
Added bookshelves to breadcrumbs
ssddanbrown Apr 7, 2019
2694bb8
Updated the design of the comments section
ssddanbrown Apr 13, 2019
d66fab8
Updated and aligned entity dashboard elements
ssddanbrown Apr 13, 2019
4d5e47a
Updated empty container item states
ssddanbrown Apr 13, 2019
36481bb
Updated guest page-create intermediate page
ssddanbrown Apr 13, 2019
07adfb2
Added select-all helpers to permission tables
ssddanbrown Apr 13, 2019
cc24d47
Organised entity action buttons a little more
ssddanbrown Apr 13, 2019
d3cc261
Fixed "Add comment" layout when no comments exist
ssddanbrown Apr 13, 2019
f797d2d
Added column select-all to role permission table
ssddanbrown Apr 13, 2019
8d358e4
Updated tri-layout on mobile to be tab based
ssddanbrown Apr 13, 2019
21e1123
Updated editor usability on mobile
ssddanbrown Apr 13, 2019
01be72d
Updated markdown editor for mobile
ssddanbrown Apr 14, 2019
9406b4d
Updated view toggle to store date
ssddanbrown Apr 14, 2019
ee58bea
Updated user references to be app-default-supporting functions
ssddanbrown Apr 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/Actions/ActivityService.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function latest($count = 20, $page = 0)
* @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);
Expand All @@ -114,7 +114,7 @@ public function entityActivity($entity, $count = 20, $page = 0)

$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);
}
Expand Down
23 changes: 13 additions & 10 deletions app/Actions/ViewService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@

use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Entity;
use BookStack\Entities\EntityProvider;
use Illuminate\Support\Collection;

class ViewService
{
protected $view;
protected $permissionService;
protected $entityProvider;

/**
* ViewService constructor.
* @param \BookStack\Actions\View $view
* @param \BookStack\Auth\Permissions\PermissionService $permissionService
* @param EntityProvider $entityProvider
*/
public function __construct(View $view, PermissionService $permissionService)
public function __construct(View $view, PermissionService $permissionService, EntityProvider $entityProvider)
{
$this->view = $view;
$this->permissionService = $permissionService;
$this->entityProvider = $entityProvider;
}

/**
Expand Down Expand Up @@ -50,23 +55,21 @@ public function add(Entity $entity)
* Get the entities with the most views.
* @param int $count
* @param int $page
* @param Entity|false|array $filterModel
* @param string|array $filterModels
* @param string $action - used for permission checking
* @return
* @return Collection
*/
public function getPopular($count = 10, $page = 0, $filterModel = false, $action = 'view')
public function getPopular(int $count = 10, int $page = 0, $filterModels = null, string $action = 'view')
{
// TODO - Standardise input filter
$skipCount = $count * $page;
$query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
$query = $this->permissionService
->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
->select('*', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
->groupBy('viewable_id', 'viewable_type')
->orderBy('view_count', 'desc');

if ($filterModel && is_array($filterModel)) {
$query->whereIn('viewable_type', $filterModel);
} else if ($filterModel) {
$query->where('viewable_type', '=', $filterModel->getMorphClass());
if ($filterModels) {
$query->whereIn('viewable_type', $this->entityProvider->getMorphClasses($filterModels));
}

return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
Expand Down
2 changes: 1 addition & 1 deletion app/Auth/Permissions/PermissionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ public function enforceEntityRestrictions($entityType, $query, $action = 'view')
* @param string $entityIdColumn
* @param string $entityTypeColumn
* @param string $action
* @return mixed
* @return QueryBuilder
*/
public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn, $action = 'view')
{
Expand Down
13 changes: 7 additions & 6 deletions app/Auth/Role.php
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,7 +14,7 @@ class Role extends Model
*/
public function users()
{
return $this->belongsToMany(User::class);
return $this->belongsToMany(User::class)->orderBy('name', 'asc');
}

/**
Expand All @@ -30,7 +31,7 @@ public function jointPermissions()
*/
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');
}

/**
Expand All @@ -51,18 +52,18 @@ public function hasPermission($permissionName)

/**
* 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);
}
Expand Down
25 changes: 13 additions & 12 deletions app/Auth/UserRepo.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use BookStack\Exceptions\UserUpdateException;
use BookStack\Uploads\Image;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Images;

class UserRepo
Expand Down Expand Up @@ -48,7 +49,7 @@ public function getById($id)

/**
* Get all the users with their permissions.
* @return \Illuminate\Database\Eloquent\Builder|static
* @return Builder|static
*/
public function getAllUsers()
{
Expand All @@ -59,7 +60,7 @@ public function getAllUsers()
* Get all the users with their permissions in a paginated format.
* @param int $count
* @param $sortData
* @return \Illuminate\Database\Eloquent\Builder|static
* @return Builder|static
*/
public function getAllUsersPaginatedAndSorted($count, $sortData)
{
Expand Down Expand Up @@ -223,16 +224,15 @@ public function getActivity(User $user, $count = 20, $page = 0)
*/
public function getRecentlyCreated(User $user, $count = 20)
{
$createdByUserQuery = function(Builder $query) use ($user) {
$query->where('created_by', '=', $user->id);
};

return [
'pages' => $this->entityRepo->getRecentlyCreated('page', $count, 0, function ($query) use ($user) {
$query->where('created_by', '=', $user->id);
}),
'chapters' => $this->entityRepo->getRecentlyCreated('chapter', $count, 0, function ($query) use ($user) {
$query->where('created_by', '=', $user->id);
}),
'books' => $this->entityRepo->getRecentlyCreated('book', $count, 0, function ($query) use ($user) {
$query->where('created_by', '=', $user->id);
})
'pages' => $this->entityRepo->getRecentlyCreated('page', $count, 0, $createdByUserQuery),
'chapters' => $this->entityRepo->getRecentlyCreated('chapter', $count, 0, $createdByUserQuery),
'books' => $this->entityRepo->getRecentlyCreated('book', $count, 0, $createdByUserQuery),
'shelves' => $this->entityRepo->getRecentlyCreated('bookshelf', $count, 0, $createdByUserQuery)
];
}

Expand All @@ -247,6 +247,7 @@ public function getAssetCounts(User $user)
'pages' => $this->entityRepo->getUserTotalCreated('page', $user),
'chapters' => $this->entityRepo->getUserTotalCreated('chapter', $user),
'books' => $this->entityRepo->getUserTotalCreated('book', $user),
'shelves' => $this->entityRepo->getUserTotalCreated('bookshelf', $user),
];
}

Expand All @@ -256,7 +257,7 @@ public function getAssetCounts(User $user)
*/
public function getAllRoles()
{
return $this->role->all();
return $this->role->newQuery()->orderBy('name', 'asc')->get();
}

/**
Expand Down
13 changes: 11 additions & 2 deletions app/Entities/Book.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function getUrl($path = false)
*/
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;
}
Expand Down Expand Up @@ -69,6 +69,15 @@ public function pages()
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
Expand All @@ -92,7 +101,7 @@ public function shelves()
* @param int $length
* @return string
*/
public function getExcerpt($length = 100)
public function getExcerpt(int $length = 100)
{
$description = $this->description;
return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
Expand Down
17 changes: 14 additions & 3 deletions app/Entities/Bookshelf.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public function getUrl($path = false)
*/
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;
}
Expand All @@ -64,7 +65,7 @@ public function getBookCover($width = 440, $height = 250)
}

/**
* Get the cover image of the book
* Get the cover image of the shelf
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function cover()
Expand All @@ -77,7 +78,7 @@ public function cover()
* @param int $length
* @return string
*/
public function getExcerpt($length = 100)
public function getExcerpt(int $length = 100)
{
$description = $this->description;
return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
Expand All @@ -91,4 +92,14 @@ public function entityRawQuery()
{
return "'BookStack\\\\BookShelf' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
}

/**
* Check if this shelf contains the given book.
* @param Book $book
* @return bool
*/
public function contains(Book $book)
{
return $this->books()->where('id', '=', $book->id)->count() > 0;
}
}
34 changes: 34 additions & 0 deletions app/Entities/BreadcrumbsViewComposer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php namespace BookStack\Entities;

use Illuminate\View\View;

class BreadcrumbsViewComposer
{

protected $entityContextManager;

/**
* BreadcrumbsViewComposer constructor.
* @param EntityContextManager $entityContextManager
*/
public function __construct(EntityContextManager $entityContextManager)
{
$this->entityContextManager = $entityContextManager;
}

/**
* Modify data when the view is composed.
* @param View $view
*/
public function compose(View $view)
{
$crumbs = $view->getData()['crumbs'];
if (array_first($crumbs) instanceof Book) {
$shelf = $this->entityContextManager->getContextualShelfForBook(array_first($crumbs));
if ($shelf) {
array_unshift($crumbs, $shelf);
$view->with('crumbs', $crumbs);
}
}
}
}
13 changes: 11 additions & 2 deletions app/Entities/Chapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public function getUrl($path = false)
* @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;
}

Expand All @@ -67,4 +67,13 @@ public function entityRawQuery()
{
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;
}
}
19 changes: 19 additions & 0 deletions app/Entities/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ public function views()
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
Expand Down Expand Up @@ -218,6 +223,20 @@ public function getText()
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
Expand Down
Loading