mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-26 13:14:47 +00:00
Revised webhooks list to new format
Also aligned query naming to start with model in use. Also added created/updated sort options to roles.
This commit is contained in:
parent
98b59a1024
commit
f75091a1c5
12 changed files with 123 additions and 40 deletions
app
Actions/Queries
Auth/Queries
Http/Controllers
resources
lang/en
sass
views
common
settings
34
app/Actions/Queries/WebhooksAllPaginatedAndSorted.php
Normal file
34
app/Actions/Queries/WebhooksAllPaginatedAndSorted.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace BookStack\Actions\Queries;
|
||||
|
||||
use BookStack\Actions\Webhook;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Get all the webhooks in the system in a paginated format.
|
||||
*/
|
||||
class WebhooksAllPaginatedAndSorted
|
||||
{
|
||||
/**
|
||||
* @param array{sort: string, order: string, search: string} $sortData
|
||||
*/
|
||||
public function run(int $count, array $sortData): LengthAwarePaginator
|
||||
{
|
||||
$sort = $sortData['sort'];
|
||||
|
||||
$query = Webhook::query()->select(['*'])
|
||||
->withCount(['trackedEvents'])
|
||||
->orderBy($sort, $sortData['order']);
|
||||
|
||||
if ($sortData['search']) {
|
||||
$term = '%' . $sortData['search'] . '%';
|
||||
$query->where(function ($query) use ($term) {
|
||||
$query->where('name', 'like', $term)
|
||||
->orWhere('endpoint', 'like', $term);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->paginate($count);
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
|||
/**
|
||||
* Get all the roles in the system in a paginated format.
|
||||
*/
|
||||
class AllRolesPaginatedAndSorted
|
||||
class RolesAllPaginatedAndSorted
|
||||
{
|
||||
/**
|
||||
* @param array{sort: string, order: string, search: string} $sortData
|
|
@ -11,7 +11,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
|||
* user is assumed to be trusted. (Admin users).
|
||||
* Email search can be abused to extract email addresses.
|
||||
*/
|
||||
class AllUsersPaginatedAndSorted
|
||||
class UsersAllPaginatedAndSorted
|
||||
{
|
||||
/**
|
||||
* @param array{sort: string, order: string, search: string} $sortData
|
|
@ -3,7 +3,7 @@
|
|||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Auth\Permissions\PermissionsRepo;
|
||||
use BookStack\Auth\Queries\AllRolesPaginatedAndSorted;
|
||||
use BookStack\Auth\Queries\RolesAllPaginatedAndSorted;
|
||||
use BookStack\Auth\Role;
|
||||
use BookStack\Exceptions\PermissionsException;
|
||||
use Exception;
|
||||
|
@ -32,7 +32,7 @@ class RoleController extends Controller
|
|||
'order' => setting()->getForCurrentUser('roles_sort_order', 'asc'),
|
||||
];
|
||||
|
||||
$roles = (new AllRolesPaginatedAndSorted())->run(20, $listDetails);
|
||||
$roles = (new RolesAllPaginatedAndSorted())->run(20, $listDetails);
|
||||
$roles->appends(['search' => $listDetails['search']]);
|
||||
|
||||
$this->setPageTitle(trans('settings.roles'));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Auth\Access\SocialAuthService;
|
||||
use BookStack\Auth\Queries\AllUsersPaginatedAndSorted;
|
||||
use BookStack\Auth\Queries\UsersAllPaginatedAndSorted;
|
||||
use BookStack\Auth\Role;
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Auth\UserRepo;
|
||||
|
@ -42,7 +42,7 @@ class UserController extends Controller
|
|||
'order' => setting()->getForCurrentUser('users_sort_order', 'asc'),
|
||||
];
|
||||
|
||||
$users = (new AllUsersPaginatedAndSorted())->run(20, $listDetails);
|
||||
$users = (new UsersAllPaginatedAndSorted())->run(20, $listDetails);
|
||||
|
||||
$this->setPageTitle(trans('settings.users'));
|
||||
$users->appends(['search' => $listDetails['search']]);
|
||||
|
@ -251,7 +251,7 @@ class UserController extends Controller
|
|||
*/
|
||||
public function changeSort(Request $request, string $id, string $type)
|
||||
{
|
||||
$validSortTypes = ['books', 'bookshelves', 'shelf_books', 'users', 'roles'];
|
||||
$validSortTypes = ['books', 'bookshelves', 'shelf_books', 'users', 'roles', 'webhooks'];
|
||||
if (!in_array($type, $validSortTypes)) {
|
||||
return redirect()->back(500);
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ class UserController extends Controller
|
|||
// Probably better to do a simple validation here then validate at usage.
|
||||
$validSorts = [
|
||||
'name', 'created_at', 'updated_at', 'default', 'email', 'last_activity_at', 'display_name',
|
||||
'users_count', 'permissions_count',
|
||||
'users_count', 'permissions_count', 'endpoint', 'active',
|
||||
];
|
||||
if (!in_array($sort, $validSorts)) {
|
||||
$sort = 'name';
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Actions\Queries\WebhooksAllPaginatedAndSorted;
|
||||
use BookStack\Actions\Webhook;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
@ -18,16 +19,23 @@ class WebhookController extends Controller
|
|||
/**
|
||||
* Show all webhooks configured in the system.
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$webhooks = Webhook::query()
|
||||
->orderBy('name', 'desc')
|
||||
->with('trackedEvents')
|
||||
->get();
|
||||
$listDetails = [
|
||||
'search' => $request->get('search', ''),
|
||||
'sort' => setting()->getForCurrentUser('webhooks_sort', 'name'),
|
||||
'order' => setting()->getForCurrentUser('webhooks_sort_order', 'asc'),
|
||||
];
|
||||
|
||||
$webhooks = (new WebhooksAllPaginatedAndSorted())->run(20, $listDetails);
|
||||
$webhooks->appends(['search' => $listDetails['search']]);
|
||||
|
||||
$this->setPageTitle(trans('settings.webhooks'));
|
||||
|
||||
return view('settings.webhooks.index', ['webhooks' => $webhooks]);
|
||||
return view('settings.webhooks.index', [
|
||||
'webhooks' => $webhooks,
|
||||
'listDetails' => $listDetails,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -247,6 +247,8 @@ return [
|
|||
|
||||
// Webhooks
|
||||
'webhooks' => 'Webhooks',
|
||||
'webhooks_index_desc' => 'Webhooks are a way to send data to external URLs when certain actions and events occur within the system which allows event-based integration with external platforms such as messaging or notification systems.',
|
||||
'webhooks_x_trigger_events' => '1 trigger event|:count trigger events',
|
||||
'webhooks_create' => 'Create New Webhook',
|
||||
'webhooks_none_created' => 'No webhooks have yet been created.',
|
||||
'webhooks_edit' => 'Edit Webhook',
|
||||
|
|
|
@ -969,4 +969,17 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
|
|||
}
|
||||
.item-list-row:hover .item-list-row-toggle-all {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.status-indicator-active, .status-indicator-inactive {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
.status-indicator-active {
|
||||
background-color: $positive;
|
||||
}
|
||||
.status-indicator-inactive {
|
||||
background-color: $negative;
|
||||
}
|
3
resources/views/common/status-indicator.blade.php
Normal file
3
resources/views/common/status-indicator.blade.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<span title="{{ trans('common.status_' . ($status ? 'active' : 'inactive')) }}"
|
||||
class="status-indicator-{{ $status ? 'active' : 'inactive' }}"
|
||||
></span>
|
|
@ -31,6 +31,8 @@
|
|||
'display_name' => trans('common.sort_name'),
|
||||
'users_count' => trans('settings.roles_assigned_users'),
|
||||
'permissions_count' => trans('settings.roles_permissions_provided'),
|
||||
'created_at' => trans('common.sort_created_at'),
|
||||
'updated_at' => trans('common.sort_updated_at'),
|
||||
], 'order' => $listDetails['order'], 'sort' => $listDetails['sort'], 'type' => 'roles'])
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,48 +8,51 @@
|
|||
|
||||
<div class="card content-wrap auto-height">
|
||||
|
||||
<div class="grid half v-center">
|
||||
<div class="flex-container-row items-center justify-space-between wrap">
|
||||
<h1 class="list-heading">{{ trans('settings.webhooks') }}</h1>
|
||||
|
||||
<div class="text-right">
|
||||
<div>
|
||||
<a href="{{ url("/settings/webhooks/create") }}"
|
||||
class="button outline">{{ trans('settings.webhooks_create') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(count($webhooks) > 0)
|
||||
<p class="text-muted">{{ trans('settings.webhooks_index_desc') }}</p>
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ trans('common.name') }}</th>
|
||||
<th width="100">{{ trans('settings.webhook_events_table_header') }}</th>
|
||||
<th width="100">{{ trans('common.status') }}</th>
|
||||
</tr>
|
||||
<div class="flex-container-row items-center justify-space-between gap-m mt-m mb-l wrap">
|
||||
<div>
|
||||
<div class="block inline mr-xs">
|
||||
<form method="get" action="{{ url("/settings/webhooks") }}">
|
||||
<input type="text" name="search" placeholder="{{ trans('common.search') }}" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-flex-end">
|
||||
@include('common.sort', ['options' => [
|
||||
'name' => trans('common.sort_name'),
|
||||
'endpoint' => trans('settings.webhooks_endpoint'),
|
||||
'created_at' => trans('common.sort_created_at'),
|
||||
'updated_at' => trans('common.sort_updated_at'),
|
||||
'active' => trans('common.status'),
|
||||
], 'order' => $listDetails['order'], 'sort' => $listDetails['sort'], 'type' => 'webhooks'])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(count($webhooks) > 0)
|
||||
<div class="item-list">
|
||||
@foreach($webhooks as $webhook)
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ $webhook->getUrl() }}">{{ $webhook->name }}</a> <br>
|
||||
<span class="small text-muted italic">{{ $webhook->endpoint }}</span>
|
||||
</td>
|
||||
<td>
|
||||
@if($webhook->tracksEvent('all'))
|
||||
{{ trans('settings.webhooks_events_all') }}
|
||||
@else
|
||||
{{ $webhook->trackedEvents->count() }}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
{{ trans('common.status_' . ($webhook->active ? 'active' : 'inactive')) }}
|
||||
</td>
|
||||
</tr>
|
||||
@include('settings.webhooks.parts.webhooks-list-item', ['webhook' => $webhook])
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<p class="text-muted empty-text px-none">
|
||||
{{ trans('settings.webhooks_none_created') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<div class="my-m">
|
||||
{{ $webhooks->links() }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<div class="item-list-row py-s">
|
||||
<div class="flex-container-row">
|
||||
<div class="flex-2 py-xxs px-m flex-container-row items-center gap-s">
|
||||
@include('common.status-indicator', ['status' => $webhook->active])
|
||||
<a href="{{ $webhook->getUrl() }}">{{ $webhook->name }}</a>
|
||||
</div>
|
||||
<div class="flex py-xxs px-m text-right text-muted">
|
||||
@if($webhook->tracksEvent('all'))
|
||||
{{ trans('settings.webhooks_events_all') }}
|
||||
@else
|
||||
{{ trans_choice('settings.webhooks_x_trigger_events', $webhook->tracked_events_count, ['count' => $webhook->tracked_events_count]) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-m py-xxs text-muted italic text-limit-lines-1">
|
||||
<small>{{ $webhook->endpoint }}</small>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue