Skip to content

Commit 16f99b6

Browse files
committed
make discord bot list to grid view
1 parent d5bb466 commit 16f99b6

7 files changed

Lines changed: 187 additions & 105 deletions

File tree

acptemplates/discordBotList.tpl

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,80 +13,8 @@
1313
</nav>
1414
</header>
1515

16-
{hascontent}
17-
<div class="paginationTop">
18-
{content}
19-
{pages print=true assign=pagesLinks controller='DiscordBotList' link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
20-
{/content}
21-
</div>
22-
{/hascontent}
23-
24-
{if $objects|count}
25-
<div class="section tabularBox">
26-
<table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\discord\bot\DiscordBotAction">
27-
<thead>
28-
<tr>
29-
<th class="columnIcon"></th>
30-
<th class="columnID columnBotID{if $sortField == 'botID'} active {$sortOrder}{/if}"><a href="{link controller='DiscordBotList'}pageNo={$pageNo}&sortField=botID&sortOrder={if $sortField == 'botID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
31-
<th class="columnTitle columnBotName{if $sortField == 'botName'} active {$sortOrder}{/if}"><a href="{link controller='DiscordBotList'}pageNo={$pageNo}&sortField=botName&sortOrder={if $sortField == 'botName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordBotList.botName{/lang}</a></th>
32-
<th class="columnText columnGuildName{if $sortField == 'guildName'} active {$sortOrder}{/if}"><a href="{link controller='DiscordBotList'}pageNo={$pageNo}&sortField=guildName&sortOrder={if $sortField == 'guildName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordBotList.server{/lang}</a></th>
33-
<th class="columnDate columnBotTime{if $sortField == 'botTime'} active {$sortOrder}{/if}"><a href="{link controller='DiscordBotList'}pageNo={$pageNo}&sortField=botTime&sortOrder={if $sortField == 'botTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.date{/lang}</a></th>
34-
35-
{event name='columns'}
36-
</tr>
37-
</thead>
38-
39-
<tbody>
40-
{foreach from=$objects item=discordBot}
41-
<tr class="jsObjectActionObject" data-object-id="{$discordBot->botID}">
42-
<td class="columnIcon">
43-
<a href="{link controller='DiscordBotEdit' id=$discordBot->botID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon size=16 name='pencil'}</a>
44-
{objectAction action="delete" objectTitle=$discordBot->botName}
45-
46-
{event name='icons'}
47-
</td>
48-
<td class="columnID">
49-
{#$discordBot->botID}
50-
</td>
51-
<td class="columnTitle">
52-
{$discordBot->botName}
53-
</td>
54-
<td class="columnText">
55-
{if !$discordBot->guildIcon|empty}
56-
<img src="https://cdn.discordapp.com/icons/{$discordBot->guildID}/{$discordBot->guildIcon}.png" style="max-width: 32px; border-radius: 50%; margin-right: 10px;">
57-
{/if}
58-
{$discordBot->guildName}
59-
</td>
60-
<td class="columnDate">
61-
{time time=$discordBot->botTime}
62-
</td>
63-
64-
{event name='columnsItem'}
65-
</tr>
66-
{/foreach}
67-
</tbody>
68-
</table>
69-
</div>
70-
71-
<footer class="contentFooter">
72-
{hascontent}
73-
<div class="paginationBottom">
74-
{content}{unsafe:$pagesLinks}{/content}
75-
</div>
76-
{/hascontent}
77-
78-
{hascontent}
79-
<nav class="contentFooterNavigation">
80-
<ul>
81-
{content}
82-
{event name='contentFooterNavigation'}
83-
{/content}
84-
</ul>
85-
</nav>
86-
{/hascontent}
87-
</footer>
88-
{else}
89-
<p class="info">{lang}wcf.global.noItems{/lang}</p>
90-
{/if}
16+
<div class="section">
17+
{unsafe:$gridView->render()}
18+
</div>
9119

9220
{include file='footer'}

files/lib/acp/page/DiscordBotListPage.class.php

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace wcf\acp\page;
44

5-
use wcf\data\discord\bot\DiscordBotList;
6-
use wcf\page\SortablePage;
5+
use Override;
6+
use wcf\page\AbstractGridViewPage;
7+
use wcf\system\gridView\AbstractGridView;
8+
use wcf\system\gridView\admin\DiscordBotGridView;
79

810
/**
911
* Übersicht aller Discord-Bots
@@ -13,35 +15,13 @@
1315
* @license Freie Lizenz (https://hanashi.dev/freie-lizenz/)
1416
* @package WoltLabSuite\Core\Acp\Page
1517
*/
16-
class DiscordBotListPage extends SortablePage
18+
final class DiscordBotListPage extends AbstractGridViewPage
1719
{
18-
/**
19-
* @inheritDoc
20-
*/
21-
public $neededPermissions = ['admin.discord.canManageConnection'];
22-
23-
/**
24-
* @inheritDoc
25-
*/
2620
public $activeMenuItem = 'wcf.acp.menu.link.configuration.discord.discordBotList';
2721

28-
/**
29-
* @inheritDoc
30-
*/
31-
public $objectListClassName = DiscordBotList::class;
32-
33-
/**
34-
* @inheritDoc
35-
*/
36-
public $defaultSortField = 'botID';
37-
38-
/**
39-
* @inheritDoc
40-
*/
41-
public $defaultSortOrder = 'ASC';
42-
43-
/**
44-
* @inheritDoc
45-
*/
46-
public $validSortFields = ['botID', 'botName', 'guildID', 'guildName', 'botTime'];
22+
#[Override]
23+
protected function createGridView(): AbstractGridView
24+
{
25+
return new DiscordBotGridView();
26+
}
4727
}

files/lib/bootstrap/dev.hanashi.wsc.discord-api.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use wcf\acp\page\DiscordWebhookListPage;
66
use wcf\event\acp\dashboard\box\PHPExtensionCollecting;
77
use wcf\event\acp\menu\item\ItemCollecting;
8+
use wcf\event\endpoint\ControllerCollecting;
89
use wcf\event\worker\RebuildWorkerCollecting;
10+
use wcf\system\endpoint\controller\hanashi\discord\bot\DeleteBot;
911
use wcf\system\event\EventHandler;
1012
use wcf\system\menu\acp\AcpMenuItem;
1113
use wcf\system\request\LinkHandler;
@@ -77,4 +79,11 @@ static function (RebuildWorkerCollecting $event) {
7779
$event->register(DiscordWebhookAvatarRebuildDataWorker::class, 0);
7880
}
7981
);
82+
83+
EventHandler::getInstance()->register(
84+
ControllerCollecting::class,
85+
static function (ControllerCollecting $event) {
86+
$event->register(new DeleteBot());
87+
}
88+
);
8089
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace wcf\event\interaction\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\interaction\admin\DiscordBotInteractions;
7+
8+
final class DiscordBotInteractionCollecting implements IPsr14Event
9+
{
10+
public function __construct(public readonly DiscordBotInteractions $provider)
11+
{
12+
}
13+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\hanashi\discord\bot;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Override;
7+
use Psr\Http\Message\ResponseInterface;
8+
use Psr\Http\Message\ServerRequestInterface;
9+
use wcf\data\discord\bot\DiscordBot;
10+
use wcf\data\discord\bot\DiscordBotAction;
11+
use wcf\http\Helper;
12+
use wcf\system\endpoint\DeleteRequest;
13+
use wcf\system\endpoint\IController;
14+
use wcf\system\WCF;
15+
16+
#[DeleteRequest('/hanashi/discord/bot/{id:\d+}')]
17+
final class DeleteBot implements IController
18+
{
19+
#[Override]
20+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
21+
{
22+
$bot = Helper::fetchObjectFromRequestParameter($variables['id'], DiscordBot::class);
23+
24+
WCF::getSession()->checkPermissions(['admin.discord.canManageConnection']);
25+
26+
$action = new DiscordBotAction([$bot], 'delete');
27+
$action->executeAction();
28+
29+
return new JsonResponse([]);
30+
}
31+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace wcf\system\gridView\admin;
4+
5+
use Override;
6+
use wcf\acp\form\DiscordBotEditForm;
7+
use wcf\data\DatabaseObjectList;
8+
use wcf\data\discord\bot\DiscordBot;
9+
use wcf\data\discord\bot\DiscordBotList;
10+
use wcf\system\gridView\AbstractGridView;
11+
use wcf\system\gridView\filter\TextFilter;
12+
use wcf\system\gridView\filter\TimeFilter;
13+
use wcf\system\gridView\GridViewColumn;
14+
use wcf\system\gridView\renderer\DefaultColumnRenderer;
15+
use wcf\system\gridView\renderer\ObjectIdColumnRenderer;
16+
use wcf\system\gridView\renderer\TimeColumnRenderer;
17+
use wcf\system\interaction\admin\DiscordBotInteractions;
18+
use wcf\system\interaction\Divider;
19+
use wcf\system\interaction\EditInteraction;
20+
use wcf\system\WCF;
21+
22+
final class DiscordBotGridView extends AbstractGridView
23+
{
24+
public function __construct()
25+
{
26+
$this->addColumns([
27+
GridViewColumn::for('botID')
28+
->label('wcf.global.objectID')
29+
->renderer(new ObjectIdColumnRenderer())
30+
->sortable(),
31+
GridViewColumn::for('botName')
32+
->label('wcf.acp.discordBotList.botName')
33+
->sortable()
34+
->titleColumn()
35+
->filter(new TextFilter()),
36+
GridViewColumn::for('guildName')
37+
->label('wcf.acp.discordBotList.server')
38+
->renderer([
39+
new class extends DefaultColumnRenderer {
40+
public function render(mixed $value, mixed $context = null): string
41+
{
42+
\assert($context instanceof DiscordBot);
43+
44+
$content = '';
45+
if (!empty($context->guildIcon)) {
46+
$content = \sprintf(
47+
'<img
48+
src="https://cdn.discordapp.com/icons/%s/%s.png"
49+
style="max-width: 32px; border-radius: 50%%; margin-right: 10px;"
50+
>',
51+
$context->guildID,
52+
$context->guildIcon
53+
);
54+
}
55+
56+
return $content . $context->guildName;
57+
}
58+
},
59+
])
60+
->sortable()
61+
->filter(new TextFilter()),
62+
GridViewColumn::for('botTime')
63+
->label('wcf.global.date')
64+
->renderer(new TimeColumnRenderer())
65+
->sortable()
66+
->filter(new TimeFilter()),
67+
]);
68+
69+
$provider = new DiscordBotInteractions();
70+
$provider->addInteractions([
71+
new Divider(),
72+
new EditInteraction(DiscordBotEditForm::class),
73+
]);
74+
$this->setInteractionProvider($provider);
75+
76+
$this->setSortField('botID');
77+
$this->setSortOrder('ASC');
78+
}
79+
80+
#[Override]
81+
public function isAccessible(): bool
82+
{
83+
return WCF::getSession()->getPermission('admin.discord.canManageConnection');
84+
}
85+
86+
#[Override]
87+
protected function createObjectList(): DatabaseObjectList
88+
{
89+
return new DiscordBotList();
90+
}
91+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace wcf\system\interaction\admin;
4+
5+
use Override;
6+
use wcf\data\discord\bot\DiscordBot;
7+
use wcf\event\interaction\admin\DiscordBotInteractionCollecting;
8+
use wcf\system\event\EventHandler;
9+
use wcf\system\interaction\AbstractInteractionProvider;
10+
use wcf\system\interaction\DeleteInteraction;
11+
12+
final class DiscordBotInteractions extends AbstractInteractionProvider
13+
{
14+
public function __construct()
15+
{
16+
$this->addInteractions([
17+
new DeleteInteraction('hanashi/discord/bot/%s'),
18+
]);
19+
20+
EventHandler::getInstance()->fire(
21+
new DiscordBotInteractionCollecting($this)
22+
);
23+
}
24+
25+
#[Override]
26+
public function getObjectClassName(): string
27+
{
28+
return DiscordBot::class;
29+
}
30+
}

0 commit comments

Comments
 (0)