Skip to content

Commit 58eafde

Browse files
authored
Merge pull request #6261 from WoltLab/6.2-GridView-Dialog
Implement `usingGridView()` to create an dialog with a grid view
2 parents 761e6b5 + d430fe2 commit 58eafde

6 files changed

Lines changed: 211 additions & 1 deletion

File tree

ts/WoltLabSuite/Core/Component/Dialog/Setup.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import DialogControls from "./Controls";
1212
import * as DomUtil from "../../Dom/Util";
1313
import FormBuilderSetup from "../FormBuilder/Setup";
14+
import GridViewSetup from "WoltLabSuite/Core/Component/GridView/Setup";
1415

1516
export class DialogSetup {
1617
fromElement(element: HTMLElement | DocumentFragment): DialogControls {
@@ -51,6 +52,10 @@ export class DialogSetup {
5152
return new FormBuilderSetup();
5253
}
5354

55+
usingGridView(): GridViewSetup {
56+
return new GridViewSetup();
57+
}
58+
5459
withoutContent(): DialogControls {
5560
const dialog = document.createElement("woltlab-core-dialog");
5661

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @author Olaf Braun
3+
* @copyright 2001-2025 WoltLab GmbH
4+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
5+
* @since 6.2
6+
*/
7+
8+
import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
9+
import WoltlabCoreDialog from "WoltLabSuite/Core/Element/woltlab-core-dialog";
10+
11+
interface ResponseGridView {
12+
gridView: string;
13+
}
14+
15+
export class GridViewSetup {
16+
async fromPreset(
17+
title: string,
18+
gridViewClass: string,
19+
pageNo: number = 1,
20+
sortField: string = "",
21+
sortOrder: string = "ASC",
22+
filters?: Map<string, string>,
23+
gridViewParameters?: Map<string, string>,
24+
): Promise<WoltlabCoreDialog> {
25+
const url = new URL(`${window.WSC_RPC_API_URL}core/grid-views/render`);
26+
url.searchParams.set("gridView", gridViewClass);
27+
url.searchParams.set("pageNo", pageNo.toString());
28+
url.searchParams.set("sortField", sortField);
29+
url.searchParams.set("sortOrder", sortOrder);
30+
if (filters) {
31+
filters.forEach((value, key) => {
32+
url.searchParams.set(`filters[${key}]`, value);
33+
});
34+
}
35+
if (gridViewParameters) {
36+
gridViewParameters.forEach((value, key) => {
37+
url.searchParams.set(`gridViewParameters[${key}]`, value);
38+
});
39+
}
40+
const json = (await prepareRequest(url).get().fetchAsJson()) as ResponseGridView;
41+
42+
// Prevents a circular dependency.
43+
const { dialogFactory } = await import("../Dialog");
44+
45+
const dialog = dialogFactory().fromHtml(json.gridView).withoutControls();
46+
dialog.show(title);
47+
48+
return dialog;
49+
}
50+
}
51+
52+
export default GridViewSetup;

wcfsetup/install/files/js/WoltLabSuite/Core/Component/Dialog/Setup.js

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wcfsetup/install/files/js/WoltLabSuite/Core/Component/GridView/Setup.js

Lines changed: 71 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
138138
$event->register(new \wcf\system\endpoint\controller\core\comments\responses\UpdateResponse());
139139
$event->register(new \wcf\system\endpoint\controller\core\exceptions\RenderException());
140140
$event->register(new \wcf\system\endpoint\controller\core\gridViews\GetRows());
141+
$event->register(new \wcf\system\endpoint\controller\core\gridViews\GetGridView());
141142
$event->register(new \wcf\system\endpoint\controller\core\gridViews\GetRow());
142143
$event->register(new \wcf\system\endpoint\controller\core\cronjobs\logs\ClearLogs());
143144
$event->register(new \wcf\system\endpoint\controller\core\messages\GetMentionSuggestions());
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\gridViews;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\http\Helper;
9+
use wcf\system\endpoint\GetRequest;
10+
use wcf\system\endpoint\IController;
11+
use wcf\system\exception\PermissionDeniedException;
12+
use wcf\system\exception\UserInputException;
13+
use wcf\system\gridView\AbstractGridView;
14+
15+
/**
16+
* API endpoint for the rendering of a grid view in a dialog.
17+
*
18+
* @author Olaf Braun
19+
* @copyright 2001-2025 WoltLab GmbH
20+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
21+
* @since 6.2
22+
*/
23+
#[GetRequest('/core/grid-views/render')]
24+
final class GetGridView implements IController
25+
{
26+
#[\Override]
27+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
28+
{
29+
$parameters = Helper::mapApiParameters($request, GetGridViewParameters::class);
30+
31+
if (!\is_subclass_of($parameters->gridView, AbstractGridView::class)) {
32+
throw new UserInputException('gridView', 'invalid');
33+
}
34+
35+
$view = new $parameters->gridView(...$parameters->gridViewParameters);
36+
// @phpstan-ignore function.alreadyNarrowedType, instanceof.alwaysTrue
37+
\assert($view instanceof AbstractGridView);
38+
39+
if (!$view->isAccessible()) {
40+
throw new PermissionDeniedException();
41+
}
42+
43+
$view->setPageNo($parameters->pageNo);
44+
if ($parameters->sortField) {
45+
$view->setSortField($parameters->sortField);
46+
}
47+
if ($parameters->sortOrder) {
48+
$view->setSortOrder($parameters->sortOrder);
49+
}
50+
51+
if ($parameters->filters !== []) {
52+
$view->setActiveFilters($parameters->filters);
53+
}
54+
55+
return new JsonResponse([
56+
'gridView' => $view->render(),
57+
]);
58+
}
59+
}
60+
61+
/** @internal */
62+
final class GetGridViewParameters
63+
{
64+
public function __construct(
65+
/** @var non-empty-string */
66+
public readonly string $gridView,
67+
/** @var positive-int */
68+
public readonly int $pageNo,
69+
public readonly string $sortField,
70+
public readonly string $sortOrder,
71+
/** @var array<string, string|int> */
72+
public readonly array $filters,
73+
/** @var array<string, string> */
74+
public readonly array $gridViewParameters,
75+
) {
76+
}
77+
}

0 commit comments

Comments
 (0)