Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe
2026-04-04 17:09:05 +01:00
11 changed files with 150 additions and 17 deletions
@@ -406,7 +406,11 @@ class AccessoriesController extends Controller
{
$this->authorize('history', $accessory);
$history = $accessory->getHistory($request);
$total = $accessory->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -344,7 +344,11 @@ class AssetModelsController extends Controller
{
$this->authorize('history', $model);
$history = $model->getHistory($request);
$total = $model->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -1445,7 +1445,11 @@ class AssetsController extends Controller
{
$this->authorize('history', $asset);
$history = $asset->getHistory($request);
$total = $asset->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -392,7 +392,11 @@ class ComponentsController extends Controller
{
$this->authorize('history', $component);
$history = $component->getHistory($request);
$total = $component->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -362,7 +362,11 @@ class ConsumablesController extends Controller
{
$this->authorize('history', $consumable);
$history = $consumable->getHistory($request);
$total = $consumable->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -283,7 +283,11 @@ class LicensesController extends Controller
{
$this->authorize('history', $license);
$history = $license->getHistory($request);
$total = $license->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -463,7 +463,11 @@ class LocationsController extends Controller
{
$this->authorize('history', $location);
$history = $location->getHistory($request);
$total = $location->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
@@ -261,7 +261,11 @@ class MaintenancesController extends Controller
$asset = $maintenance->asset;
$this->authorize('history', $asset);
$history = $maintenance->getHistory($request);
$total = $maintenance->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
+5 -1
View File
@@ -971,7 +971,11 @@ class UsersController extends Controller
{
$this->authorize('history', $user);
$history = $user->getHistory($request);
$total = $user->getHistory($request)->count();
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$history = $history->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $history->count()), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
return response()->json((new ActionlogsTransformer)->transformActionlogs($history, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
}
}
+3 -8
View File
@@ -67,8 +67,8 @@ trait Loggable
'action_date',
];
// Start with the polymorphic history relation so all subsequent filters,
// search terms, and sorting are applied to the same query instance.
// Start with the polymorphic history relation so all filters and
// ordering are applied to the same query instance.
$history = $this->history();
if ($request->filled('search')) {
@@ -95,11 +95,6 @@ trait Loggable
$history = $history->whereNotNull('filename');
}
$total = $history->count();
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');
$order = ($request->input('order') == 'asc') ? 'asc' : 'desc';
switch ($request->input('sort')) {
@@ -112,7 +107,7 @@ trait Loggable
break;
}
return $history->skip($offset)->take($limit)->get();
return $history;
}
+102
View File
@@ -338,4 +338,106 @@ class IndexHistoryTest extends TestCase
->assertJsonPath('rows.0.created_by.id', $alphaCreator->id)
->assertJsonPath('rows.1.created_by.id', $omegaCreator->id);
}
public function test_viewing_user_history_respects_limit_and_keeps_full_total()
{
$subject = User::factory()->create();
$actor = User::factory()->viewUserHistory()->create();
$uniqueNote = 'history-pagination-limit-'.uniqid();
$first = Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-01-01 00:00:00',
'action_date' => '2026-01-01 00:00:00',
]);
Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-01-02 00:00:00',
'action_date' => '2026-01-02 00:00:00',
]);
Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-01-03 00:00:00',
'action_date' => '2026-01-03 00:00:00',
]);
$this->actingAsForApi($actor)
->getJson(route('api.users.history', [
'user' => $subject,
'search' => $uniqueNote,
'sort' => 'created_at',
'order' => 'asc',
'offset' => 0,
'limit' => 1,
]))
->assertOk()
->assertJsonPath('total', 3)
->assertJsonCount(1, 'rows')
->assertJsonPath('rows.0.id', $first->id);
}
public function test_viewing_user_history_respects_offset_and_limit_and_keeps_full_total()
{
$subject = User::factory()->create();
$actor = User::factory()->viewUserHistory()->create();
$uniqueNote = 'history-pagination-offset-'.uniqid();
Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-02-01 00:00:00',
'action_date' => '2026-02-01 00:00:00',
]);
$second = Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-02-02 00:00:00',
'action_date' => '2026-02-02 00:00:00',
]);
Actionlog::factory()->create([
'item_id' => $subject->id,
'item_type' => User::class,
'created_by' => $actor->id,
'action_type' => 'update',
'note' => $uniqueNote,
'created_at' => '2026-02-03 00:00:00',
'action_date' => '2026-02-03 00:00:00',
]);
$this->actingAsForApi($actor)
->getJson(route('api.users.history', [
'user' => $subject,
'search' => $uniqueNote,
'sort' => 'created_at',
'order' => 'asc',
'offset' => 1,
'limit' => 1,
]))
->assertOk()
->assertJsonPath('total', 3)
->assertJsonCount(1, 'rows')
->assertJsonPath('rows.0.id', $second->id);
}
}