diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index 63de0bc44..1bb5d46cd 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -299,7 +299,6 @@ class UserController extends Controller
*/
public function changeSort(string $id, string $type, Request $request)
{
- // TODO - Test this endpoint
$validSortTypes = ['books', 'bookshelves'];
if (!in_array($type, $validSortTypes)) {
return redirect()->back(500);
@@ -307,6 +306,28 @@ class UserController extends Controller
return $this->changeListSort($id, $request, $type);
}
+ /**
+ * Update the stored section expansion preference for the given user.
+ * @param string $id
+ * @param string $key
+ * @param Request $request
+ * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
+ */
+ public function updateExpansionPreference(string $id, string $key, Request $request)
+ {
+ $this->checkPermissionOrCurrentUser('users-manage', $id);
+ $keyWhitelist = ['home-details'];
+ if (!in_array($key, $keyWhitelist)) {
+ return response("Invalid key", 500);
+ }
+
+ $newState = $request->get('expand', 'false');
+
+ $user = $this->user->findOrFail($id);
+ setting()->putUser($user, 'section_expansion#' . $key, $newState);
+ return response("", 204);
+ }
+
/**
* Changed the stored preference for a list sort order.
* @param int $userId
diff --git a/app/Settings/SettingService.php b/app/Settings/SettingService.php
index 663a6ae32..48ae7d0f2 100644
--- a/app/Settings/SettingService.php
+++ b/app/Settings/SettingService.php
@@ -67,6 +67,17 @@ class SettingService
return $this->get($this->userKey($user->id, $key), $default);
}
+ /**
+ * Get a value for the current logged-in user.
+ * @param $key
+ * @param bool $default
+ * @return bool|string
+ */
+ public function getForCurrentUser($key, $default = false)
+ {
+ return $this->getUser(auth()->user(), $key, $default);
+ }
+
/**
* Gets a setting value from the cache or database.
* Looks at the system defaults if not cached or in database.
diff --git a/resources/assets/js/components/expand-toggle.js b/resources/assets/js/components/expand-toggle.js
index 6f317db62..a6a389818 100644
--- a/resources/assets/js/components/expand-toggle.js
+++ b/resources/assets/js/components/expand-toggle.js
@@ -3,8 +3,13 @@ class ExpandToggle {
constructor(elem) {
this.elem = elem;
- this.isOpen = false;
+
+ // Component state
+ this.isOpen = elem.getAttribute('expand-toggle-is-open') === 'yes';
+ this.updateEndpoint = elem.getAttribute('expand-toggle-update-endpoint');
this.selector = elem.getAttribute('expand-toggle');
+
+ // Listener setup
elem.addEventListener('click', this.click.bind(this));
}
@@ -53,11 +58,20 @@ class ExpandToggle {
click(event) {
event.preventDefault();
- let matchingElems = document.querySelectorAll(this.selector);
- for (let i = 0, len = matchingElems.length; i < len; i++) {
- this.isOpen ? this.close(matchingElems[i]) : this.open(matchingElems[i]);
+
+ const matchingElems = document.querySelectorAll(this.selector);
+ for (let match of matchingElems) {
+ this.isOpen ? this.close(match) : this.open(match);
}
+
this.isOpen = !this.isOpen;
+ this.updateSystemAjax(this.isOpen);
+ }
+
+ updateSystemAjax(isOpen) {
+ window.$http.patch(this.updateEndpoint, {
+ expand: isOpen ? 'true' : 'false'
+ });
}
}
diff --git a/resources/views/base.blade.php b/resources/views/base.blade.php
index 03d6f680a..367a2cd8b 100644
--- a/resources/views/base.blade.php
+++ b/resources/views/base.blade.php
@@ -20,6 +20,7 @@
@include('partials.custom-styles')
@include('partials.custom-head')
+ @stack('head')
diff --git a/resources/views/common/home-book.blade.php b/resources/views/common/home-book.blade.php
index 139c77c07..0efaa32ec 100644
--- a/resources/views/common/home-book.blade.php
+++ b/resources/views/common/home-book.blade.php
@@ -9,10 +9,7 @@
{{ trans('common.actions') }}
@include('partials.view-toggle', ['view' => $view, 'type' => 'book'])
-
- @icon('expand-text')
- {{ trans('common.toggle_details') }}
-
+ @include('components.expand-toggle', ['target' => '.entity-list.compact .entity-item-snippet', 'key' => 'home-details'])
diff --git a/resources/views/common/home-custom.blade.php b/resources/views/common/home-custom.blade.php
index 0ef3c2e25..f1133a607 100644
--- a/resources/views/common/home-custom.blade.php
+++ b/resources/views/common/home-custom.blade.php
@@ -8,10 +8,7 @@
diff --git a/resources/views/common/home-shelves.blade.php b/resources/views/common/home-shelves.blade.php
index 8cb99b907..f09bfd416 100644
--- a/resources/views/common/home-shelves.blade.php
+++ b/resources/views/common/home-shelves.blade.php
@@ -9,10 +9,7 @@
{{ trans('common.actions') }}
@include('partials.view-toggle', ['view' => $view, 'type' => 'shelf'])
-
- @icon('expand-text')
- {{ trans('common.toggle_details') }}
-
+ @include('components.expand-toggle', ['target' => '.entity-list.compact .entity-item-snippet', 'key' => 'home-details'])
diff --git a/resources/views/common/home.blade.php b/resources/views/common/home.blade.php
index 53da79fd2..35e45c9c8 100644
--- a/resources/views/common/home.blade.php
+++ b/resources/views/common/home.blade.php
@@ -1,10 +1,11 @@
@extends('simple-layout')
-
@section('body')
-
-
@icon('expand-text'){{ trans('common.toggle_details') }}
+
+
+ @include('components.expand-toggle', ['target' => '.entity-list.compact .entity-item-snippet', 'key' => 'home-details'])
+
diff --git a/resources/views/components/expand-toggle.blade.php b/resources/views/components/expand-toggle.blade.php
new file mode 100644
index 000000000..231b13741
--- /dev/null
+++ b/resources/views/components/expand-toggle.blade.php
@@ -0,0 +1,19 @@
+{{--
+$target - CSS selector of items to expand
+$key - Unique key for checking existing stored state.
+--}}
+getForCurrentUser('section_expansion#'. $key); ?>
+
+ @icon('expand-text')
+ {{ trans('common.toggle_details') }}
+
+@if($isOpen)
+ @push('head')
+
+ @endpush
+@endif
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index 41da967d9..7c2c5917e 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -177,6 +177,7 @@ Route::group(['middleware' => 'auth'], function () {
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::patch('/users/{id}/update-expansion-preference/{key}', 'UserController@updateExpansionPreference');
Route::post('/users/create', 'UserController@store');
Route::get('/users/{id}', 'UserController@edit');
Route::put('/users/{id}', 'UserController@update');
diff --git a/tests/UserPreferencesTest.php b/tests/UserPreferencesTest.php
new file mode 100644
index 000000000..b81664275
--- /dev/null
+++ b/tests/UserPreferencesTest.php
@@ -0,0 +1,76 @@
+getEditor();
+ $this->actingAs($editor);
+
+ $updateRequest = $this->patch('/settings/users/' . $editor->id.'/change-sort/books', [
+ 'sort' => 'created_at',
+ 'order' => 'desc'
+ ]);
+ $updateRequest->assertStatus(302);
+
+ $this->assertDatabaseHas('settings', [
+ 'setting_key' => 'user:' . $editor->id . ':books_sort',
+ 'value' => 'created_at'
+ ]);
+ $this->assertDatabaseHas('settings', [
+ 'setting_key' => 'user:' . $editor->id . ':books_sort_order',
+ 'value' => 'desc'
+ ]);
+ $this->assertEquals('created_at', setting()->getForCurrentUser('books_sort'));
+ $this->assertEquals('desc', setting()->getForCurrentUser('books_sort_order'));
+ }
+
+ public function test_update_sort_preference_defaults()
+ {
+ $editor = $this->getEditor();
+ $this->actingAs($editor);
+
+ $updateRequest = $this->patch('/settings/users/' . $editor->id.'/change-sort/bookshelves', [
+ 'sort' => 'cat',
+ 'order' => 'dog'
+ ]);
+ $updateRequest->assertStatus(302);
+
+ $this->assertEquals('name', setting()->getForCurrentUser('bookshelves_sort'));
+ $this->assertEquals('asc', setting()->getForCurrentUser('bookshelves_sort_order'));
+ }
+
+ public function test_update_sort_bad_entity_type_handled()
+ {
+ $editor = $this->getEditor();
+ $this->actingAs($editor);
+
+ $updateRequest = $this->patch('/settings/users/' . $editor->id.'/change-sort/dogs', [
+ 'sort' => 'name',
+ 'order' => 'asc'
+ ]);
+ $updateRequest->assertStatus(500);
+
+ $this->assertNotEmpty('name', setting()->getForCurrentUser('bookshelves_sort'));
+ $this->assertNotEmpty('asc', setting()->getForCurrentUser('bookshelves_sort_order'));
+ }
+
+ public function test_update_expansion_preference()
+ {
+ $editor = $this->getEditor();
+ $this->actingAs($editor);
+
+ $updateRequest = $this->patch('/settings/users/' . $editor->id.'/update-expansion-preference/home-details', ['expand' => 'true']);
+ $updateRequest->assertStatus(204);
+
+ $this->assertDatabaseHas('settings', [
+ 'setting_key' => 'user:' . $editor->id . ':section_expansion#home-details',
+ 'value' => 'true'
+ ]);
+ $this->assertEquals(true, setting()->getForCurrentUser('section_expansion#home-details'));
+
+ $invalidKeyRequest = $this->patch('/settings/users/' . $editor->id.'/update-expansion-preference/my-home-details', ['expand' => 'true']);
+ $invalidKeyRequest->assertStatus(500);
+ }
+}
\ No newline at end of file