Skip to content

Commit

Permalink
Add support for toggle actions
Browse files Browse the repository at this point in the history
  • Loading branch information
BurntimeX committed Nov 12, 2024
1 parent 6290e6d commit f4d3e02
Show file tree
Hide file tree
Showing 15 changed files with 291 additions and 17 deletions.
38 changes: 29 additions & 9 deletions com.woltlab.wcf/templates/shared_gridViewRows.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,36 @@
{/foreach}
{if $view->hasActions()}
<td class="gridView__column gridView__actionColumn">
<div class="dropdown">
<button type="button" class="gridViewActions button small dropdownToggle" aria-label="{lang}wcf.global.button.more{/lang}">{icon name='ellipsis-vertical'}</button>
<div class="gridView__actionColumn__buttons">
{foreach from=$view->getQuickActions() item='action'}
{unsafe:$view->renderAction($action, $row)}
{/foreach}

<ul class="dropdownMenu">
{foreach from=$view->getActions() item='action'}
<li>
{unsafe:$view->renderAction($action, $row)}
</li>
{/foreach}
</ul>
{if $view->hasDropdownActions()}
{hascontent}
<div class="dropdown">
<button type="button" class="gridViewActions button small dropdownToggle" aria-label="{lang}wcf.global.button.more{/lang}">
{icon name='ellipsis-vertical'}
</button>

<ul class="dropdownMenu">
{content}
{foreach from=$view->getDropdownActions() item='action'}
{if $action->isAvailable($row)}
<li>
{unsafe:$view->renderAction($action, $row)}
</li>
{/if}
{/foreach}
{/content}
</ul>
</div>
{hascontentelse}
<button type="button" disabled class="button small" aria-label="{lang}wcf.global.button.more{/lang}">
{icon name='ellipsis-vertical'}
</button>
{/hascontent}
{/if}
</div>
</td>
{/if}
Expand Down
22 changes: 22 additions & 0 deletions ts/WoltLabSuite/Core/Api/PostObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Sends a post request to the given endpoint.
*
* @author Marcel Werk
* @copyright 2001-2024 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.2
* @woltlabExcludeBundle tiny
*/

import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
import { ApiResult, apiResultFromError, apiResultFromValue } from "./Result";

export async function postObject(endpoint: string): Promise<ApiResult<[]>> {
try {
await prepareRequest(endpoint).post().fetchAsJson();
} catch (e) {
return apiResultFromError(e);
}

return apiResultFromValue([]);
}
9 changes: 8 additions & 1 deletion ts/WoltLabSuite/Core/Component/GridView.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getRows } from "../Api/GridViews/GetRows";
import DomChangeListener from "../Dom/Change/Listener";
import DomUtil from "../Dom/Util";
import { promiseMutex } from "../Helper/PromiseMutex";
import UiDropdownSimple from "../Ui/Dropdown/Simple";
Expand Down Expand Up @@ -122,6 +123,8 @@ export class GridView {
this.#updateQueryString();
}

DomChangeListener.trigger();

this.#renderFilters(response.filterLabels);
this.#initActions();
}
Expand Down Expand Up @@ -158,7 +161,11 @@ export class GridView {
#initActions(): void {
this.#table.querySelectorAll<HTMLTableRowElement>("tbody tr").forEach((row) => {
row.querySelectorAll<HTMLElement>(".gridViewActions").forEach((element) => {
const dropdown = UiDropdownSimple.getDropdownMenu(element.dataset.target!)!;
let dropdown = UiDropdownSimple.getDropdownMenu(element.dataset.target!);
if (!dropdown) {
dropdown = element.closest(".dropdown")!.querySelector<HTMLElement>(".dropdownMenu")!;
}

dropdown?.querySelectorAll<HTMLButtonElement>("[data-action]").forEach((element) => {
element.addEventListener("click", () => {
row.dispatchEvent(
Expand Down
18 changes: 18 additions & 0 deletions ts/WoltLabSuite/Core/Component/GridView/Action/Toggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { wheneverFirstSeen } from "WoltLabSuite/Core/Helper/Selector";
import { postObject } from "WoltLabSuite/Core/Api/PostObject";

async function handleToggle(checked: boolean, enableEndpoint: string, disableEndpoint: string): Promise<void> {
await postObject(checked ? enableEndpoint : disableEndpoint);
}

export function setup(tableId: string): void {
wheneverFirstSeen(`#${tableId} .gridView__row woltlab-core-toggle-button`, (toggleButton) => {
toggleButton.addEventListener("change", (event: CustomEvent) => {
void handleToggle(
event.detail.checked as boolean,
toggleButton.dataset.enableEndpoint!,
toggleButton.dataset.disableEndpoint!,
);
});
});
}
23 changes: 23 additions & 0 deletions wcfsetup/install/files/js/WoltLabSuite/Core/Api/PostObject.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions wcfsetup/install/files/js/WoltLabSuite/Core/Api/ToggleObject.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,27 @@ public function hasActions(): bool
return $this->actions !== [];
}

public function hasDropdownActions(): bool
{
return $this->getDropdownActions() !== [];
}

/**
* @return IGridViewAction[]
*/
public function getDropdownActions(): array
{
return \array_filter($this->getActions(), fn($action) => !$action->isQuickAction());
}

/**
* @return IGridViewAction[]
*/
public function getQuickActions(): array
{
return \array_filter($this->getActions(), fn($action) => $action->isQuickAction());
}

public function render(): string
{
return WCF::getTPL()->fetch('shared_gridView', 'wcf', ['view' => $this], true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace wcf\system\view\grid\action;

use Closure;

abstract class AbstractAction implements IGridViewAction
{
public function __construct(
private readonly ?Closure $isAvailableCallback = null
) {}

#[\Override]
public function isAvailable(mixed $row): bool
{
if ($this->isAvailableCallback === null) {
return true;
}

return ($this->isAvailableCallback)($row);
}

#[\Override]
public function isQuickAction(): bool
{
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace wcf\system\view\grid\action;

use Closure;
use wcf\action\ApiAction;
use wcf\data\DatabaseObject;
use wcf\data\ITitledObject;
Expand All @@ -10,22 +11,34 @@
use wcf\system\WCF;
use wcf\util\StringUtil;

class DeleteAction implements IGridViewAction
class DeleteAction extends AbstractAction
{
public function __construct(
private readonly string $endpoint,
) {}
?Closure $isAvailableCallback = null
) {
parent::__construct($isAvailableCallback);
}

#[\Override]
public function render(mixed $row): string
{
\assert($row instanceof DatabaseObject);

$label = WCF::getLanguage()->get('wcf.global.button.delete');

if (!$this->isAvailable($row)) {
return <<<HTML
<span>
{$label}
</span>
HTML;
}

$endpoint = StringUtil::encodeHTML(
LinkHandler::getInstance()->getControllerLink(ApiAction::class, ['id' => 'rpc']) .
\sprintf($this->endpoint, $row->getObjectID())
);
$label = WCF::getLanguage()->get('wcf.global.button.delete');
if ($row instanceof ITitledObject) {
$objectName = StringUtil::encodeHTML($row->getTitle());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

namespace wcf\system\view\grid\action;

use Closure;
use wcf\data\DatabaseObject;
use wcf\system\request\LinkHandler;
use wcf\system\view\grid\AbstractGridView;
use wcf\system\WCF;

class EditAction implements IGridViewAction
class EditAction extends AbstractAction
{
public function __construct(
private readonly string $controllerClass,
) {}
?Closure $isAvailableCallback = null
) {
parent::__construct($isAvailableCallback);
}

#[\Override]
public function render(mixed $row): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ interface IGridViewAction
public function render(mixed $row): string;

public function renderInitialization(AbstractGridView $gridView): ?string;

public function isQuickAction(): bool;

public function isAvailable(mixed $row): bool;
}
Loading

0 comments on commit f4d3e02

Please sign in to comment.