Skip to content

Commit e17c33e

Browse files
committed
Merge branch '6.2' into 6.2-cronjob-to-grid-view
# Conflicts: # wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php
2 parents b14ed2e + 01a2c45 commit e17c33e

File tree

44 files changed

+1754
-957
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1754
-957
lines changed

com.woltlab.wcf/clipboardAction.xml

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,43 @@
137137
</pages>
138138
</action>
139139
<!-- /com.woltlab.wcf.media -->
140+
<action name="assignUserByClipboard">
141+
<actionclassname>wcf\system\clipboard\action\ModerationQueueClipboardAction</actionclassname>
142+
<showorder>1</showorder>
143+
<pages>
144+
<page>wcf\page\ModerationListPage</page>
145+
</pages>
146+
</action>
147+
<action name="enableContent">
148+
<actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
149+
<showorder>2</showorder>
150+
<pages>
151+
<page>wcf\page\ModerationListPage</page>
152+
</pages>
153+
</action>
154+
<action name="removeActivationContent">
155+
<actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
156+
<showorder>3</showorder>
157+
<pages>
158+
<page>wcf\page\ModerationListPage</page>
159+
</pages>
160+
</action>
161+
<action name="removeReport">
162+
<actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
163+
<showorder>4</showorder>
164+
<pages>
165+
<page>wcf\page\ModerationListPage</page>
166+
</pages>
167+
</action>
168+
<action name="removeReportContent">
169+
<actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
170+
<showorder>5</showorder>
171+
<pages>
172+
<page>wcf\page\ModerationListPage</page>
173+
</pages>
174+
</action>
175+
</import>
176+
<delete>
140177
<!-- com.woltlab.wcf.article -->
141178
<action name="trash">
142179
<actionclassname>wcf\system\clipboard\action\ArticleClipboardAction</actionclassname>
@@ -180,40 +217,5 @@
180217
<page>wcf\acp\page\ArticleListPage</page>
181218
</pages>
182219
</action>
183-
<action name="assignUserByClipboard">
184-
<actionclassname>wcf\system\clipboard\action\ModerationQueueClipboardAction</actionclassname>
185-
<showorder>1</showorder>
186-
<pages>
187-
<page>wcf\page\ModerationListPage</page>
188-
</pages>
189-
</action>
190-
<action name="enableContent">
191-
<actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
192-
<showorder>2</showorder>
193-
<pages>
194-
<page>wcf\page\ModerationListPage</page>
195-
</pages>
196-
</action>
197-
<action name="removeActivationContent">
198-
<actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
199-
<showorder>3</showorder>
200-
<pages>
201-
<page>wcf\page\ModerationListPage</page>
202-
</pages>
203-
</action>
204-
<action name="removeReport">
205-
<actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
206-
<showorder>4</showorder>
207-
<pages>
208-
<page>wcf\page\ModerationListPage</page>
209-
</pages>
210-
</action>
211-
<action name="removeReportContent">
212-
<actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
213-
<showorder>5</showorder>
214-
<pages>
215-
<page>wcf\page\ModerationListPage</page>
216-
</pages>
217-
</action>
218-
</import>
220+
</delete>
219221
</data>

com.woltlab.wcf/fileDelete.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,7 @@
27202720
<file>lib/system/cli/command/PackageCommand.class.php</file>
27212721
<file>lib/system/cli/command/WorkerCommand.class.php</file>
27222722
<file>lib/system/clipboard/action/UserExtendedClipboardAction.class.php</file>
2723+
<file>lib/system/clipboard/action/ArticleClipboardAction.class.php</file>
27232724
<file>lib/system/condition/INoticeCondition.class.php</file>
27242725
<file>lib/system/condition/UserReputationCondition.class.php</file>
27252726
<file>lib/system/cronjob/CleanUpCronjobLogCronjob.class.php</file>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Handles bulk interactions that open a form builder dialog.
3+
*
4+
* @author Olaf Braun
5+
* @copyright 2001-2025 WoltLab GmbH
6+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7+
* @since 6.2
8+
*/
9+
10+
import { show as showNotification } from "WoltLabSuite/Core/Ui/Notification";
11+
import { dialogFactory } from "WoltLabSuite/Core/Component/Dialog";
12+
13+
async function handleFormBuilderDialogAction(
14+
container: HTMLElement,
15+
objectIds: number[],
16+
endpoint: string,
17+
): Promise<void> {
18+
const { ok } = await dialogFactory().usingFormBuilder().fromEndpoint(endpoint);
19+
20+
if (!ok) {
21+
return;
22+
}
23+
24+
for (let i = 0; i < objectIds.length; i++) {
25+
const element = container.querySelector(`[data-object-id="${objectIds[i]}"]`);
26+
if (!element) {
27+
continue;
28+
}
29+
30+
element.dispatchEvent(
31+
new CustomEvent("refresh", {
32+
bubbles: true,
33+
}),
34+
);
35+
}
36+
37+
// TODO: This shows a generic success message and should be replaced with a more specific message.
38+
showNotification();
39+
40+
container.dispatchEvent(new CustomEvent("reset-selection"));
41+
}
42+
43+
export function setup(identifier: string, container: HTMLElement): void {
44+
container.addEventListener("bulk-interaction", (event: CustomEvent) => {
45+
if (event.detail.bulkInteraction === identifier) {
46+
void handleFormBuilderDialogAction(container, JSON.parse(event.detail.objectIds), event.detail.endpoint);
47+
}
48+
});
49+
}
Lines changed: 5 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,8 @@
11
{include file='header' pageTitle='wcf.acp.article.list'}
22

3-
<script data-relocate="true">
4-
require(['Language', 'WoltLabSuite/Core/Controller/Clipboard', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'],
5-
function(Language, ControllerClipboard, UiUserSearchInput, AcpUiArticleInlineEditor) {
6-
Language.addObject({
7-
'wcf.acp.article.publicationStatus.unpublished': '{jslang}wcf.acp.article.publicationStatus.unpublished{/jslang}',
8-
'wcf.acp.article.setCategory': '{jslang}wcf.acp.article.setCategory{/jslang}',
9-
'wcf.message.status.deleted': '{jslang}wcf.message.status.deleted{/jslang}'
10-
});
11-
12-
new UiUserSearchInput(elBySel('input[name="username"]'));
13-
new AcpUiArticleInlineEditor(0);
14-
15-
ControllerClipboard.setup({
16-
hasMarkedItems: {if $hasMarkedItems}true{else}false{/if},
17-
pageClassName: 'wcf\\acp\\page\\ArticleListPage'
18-
});
19-
});
20-
</script>
21-
223
<header class="contentHeader">
234
<div class="contentHeaderTitle">
24-
<h1 class="contentTitle">{lang}wcf.acp.article.list{/lang}{if $items} <span class="badge badgeInverse">{#$items}</span>{/if}</h1>
5+
<h1 class="contentTitle">{lang}wcf.acp.article.list{/lang} <span class="badge badgeInverse">{#$gridView->countRows()}</span></h1>
256
</div>
267

278
<nav class="contentHeaderNavigation">
@@ -37,208 +18,10 @@
3718
</nav>
3819
</header>
3920

40-
<form method="post" action="{link controller='ArticleList'}{/link}">
41-
<section class="section">
42-
<h2 class="sectionTitle">{lang}wcf.global.filter{/lang}</h2>
43-
44-
<div class="row rowColGap formGrid">
45-
<dl class="col-xs-12 col-md-4">
46-
<dt></dt>
47-
<dd>
48-
<select name="categoryID" id="categoryID">
49-
<option value="0">{lang}wcf.global.category{/lang}</option>
50-
51-
{foreach from=$categoryNodeList item=category}
52-
<option value="{$category->categoryID}"{if $category->categoryID == $categoryID} selected{/if}>{if $category->getDepth() > 1}{@"&nbsp;&nbsp;&nbsp;&nbsp;"|str_repeat:($category->getDepth() - 1)}{/if}{$category->getTitle()}</option>
53-
{/foreach}
54-
</select>
55-
</dd>
56-
</dl>
57-
58-
<dl class="col-xs-12 col-md-4">
59-
<dt></dt>
60-
<dd>
61-
<input type="text" id="pageTitle" name="title" value="{$title}" placeholder="{lang}wcf.global.title{/lang}" class="long">
62-
</dd>
63-
</dl>
64-
65-
<dl class="col-xs-12 col-md-4">
66-
<dt></dt>
67-
<dd>
68-
<input type="text" id="pageContent" name="content" value="{$content}" placeholder="{lang}wcf.acp.article.content{/lang}" class="long">
69-
</dd>
70-
</dl>
71-
72-
<dl class="col-xs-12 col-md-4">
73-
<dt></dt>
74-
<dd>
75-
<input type="text" id="username" name="username" value="{$username}" placeholder="{lang}wcf.acp.article.author{/lang}" class="long">
76-
</dd>
77-
</dl>
78-
79-
<dl class="col-xs-12 col-md-4">
80-
<dt></dt>
81-
<dd>
82-
<select name="publicationStatus" id="publicationStatus">
83-
<option value="-1">{lang}wcf.acp.article.publicationStatus{/lang}</option>
84-
85-
<option value="0"{if $publicationStatus == 0} selected{/if}>{lang}wcf.acp.article.publicationStatus.unpublished{/lang}</option>
86-
<option value="1"{if $publicationStatus == 1} selected{/if}>{lang}wcf.acp.article.publicationStatus.published{/lang}</option>
87-
<option value="2"{if $publicationStatus == 2} selected{/if}>{lang}wcf.acp.article.publicationStatus.delayed{/lang}</option>
88-
</select>
89-
</dd>
90-
</dl>
91-
<dl class="col-xs-12 col-md-4">
92-
<dt></dt>
93-
<dd>
94-
<label><input type="checkbox" name="isDeleted" id="isDeleted" value="1"{if $isDeleted === 1} checked{/if}> {lang}wcf.acp.article.isDeleted{/lang}</label>
95-
</dd>
96-
</dl>
97-
98-
{event name='filterFields'}
99-
</div>
100-
101-
<div class="formSubmit">
102-
<input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
103-
{csrfToken}
104-
</div>
105-
</section>
106-
</form>
107-
108-
{hascontent}
109-
<div class="paginationTop">
110-
{content}
111-
{assign var='linkParameters' value=''}
112-
{if $categoryID}{capture append=linkParameters}&categoryID={@$categoryID}{/capture}{/if}
113-
{if $title}{capture append=linkParameters}&title={@$title|rawurlencode}{/capture}{/if}
114-
{if $content}{capture append=linkParameters}&content={@$content|rawurlencode}{/capture}{/if}
115-
{if $username}{capture append=linkParameters}&username={@$username|rawurlencode}{/capture}{/if}
116-
{if $publicationStatus != -1}{capture append=linkParameters}&publicationStatus={@$publicationStatus}{/capture}{/if}
117-
{if $isDeleted != -1}{capture append=linkParameters}&isDeleted=1{/capture}{/if}
118-
119-
{pages print=true assign=pagesLinks controller="ArticleList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder$linkParameters"}
120-
{/content}
121-
</div>
122-
{/hascontent}
123-
124-
{if $objects|count}
125-
<div class="section tabularBox">
126-
<table data-type="com.woltlab.wcf.article" class="table jsClipboardContainer">
127-
<thead>
128-
<tr>
129-
<th class="columnMark"><label><input type="checkbox" class="jsClipboardMarkAll"></label></th>
130-
<th class="columnID columnArticleID{if $sortField == 'articleID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=articleID&sortOrder={if $sortField == 'articleID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
131-
<th class="columnText columnArticleTitle{if $sortField == 'title'} active {@$sortOrder}{/if}"><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=title&sortOrder={if $sortField == 'title' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.title{/lang}</a></th>
132-
<th class="columnDigits columnViews{if $sortField == 'views'} active {@$sortOrder}{/if}"><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=views&sortOrder={if $sortField == 'views' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.article.views{/lang}</a></th>
133-
<th class="columnDate columnTime{if $sortField == 'time'} active {@$sortOrder}{/if}"><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=time&sortOrder={if $sortField == 'time' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.date{/lang}</a></th>
134-
135-
{event name='columnHeads'}
136-
</tr>
137-
</thead>
138-
139-
<tbody>
140-
{foreach from=$objects item=article}
141-
<tr class="jsArticleRow jsClipboardObject" data-object-id="{@$article->articleID}" data-title="{$article->title}">
142-
<td class="columnMark"><input type="checkbox" class="jsClipboardItem" data-object-id="{@$article->articleID}"></td>
143-
<td class="columnIcon">
144-
{if $article->canEdit()}
145-
<a href="{link controller='ArticleEdit' id=$article->articleID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
146-
{else}
147-
<span class="disabled" title="{lang}wcf.global.button.edit{/lang}">
148-
{icon name='pencil'}
149-
</span>
150-
{/if}
151-
{if $article->canDelete()}
152-
<a href="#" class="jsButtonRestore jsTooltip" title="{lang}wcf.global.button.restore{/lang}"{if !$article->isDeleted} style="display: none"{/if}>{icon name='arrows-rotate'}</a>
153-
<a href="#" class="jsButtonDelete jsTooltip" title="{lang}wcf.global.button.delete{/lang}"{if !$article->isDeleted} style="display: none"{/if}>{icon name='xmark'}</a>
154-
<a href="#" class="jsButtonTrash jsTooltip" title="{lang}wcf.global.button.trash{/lang}"{if $article->isDeleted} style="display: none"{/if}>{icon name='xmark'}</a>
155-
{else}
156-
<span class="disabled" title="{lang}wcf.global.button.delete{/lang}">
157-
{icon name='xmark'}
158-
</span>
159-
{/if}
160-
161-
<a href="{$article->getLink()}" title="{lang}wcf.acp.article.button.viewArticle{/lang}" class="jsTooltip">{icon name='magnifying-glass'}</a>
162-
163-
{event name='rowButtons'}
164-
</td>
165-
<td class="columnID columnArticleID">{@$article->articleID}</td>
166-
<td class="columnText columnArticleTitle">
167-
<div class="box48">
168-
<span>
169-
{if $article->getTeaserImage()}
170-
{@$article->getTeaserImage()->getElementTag(48)}
171-
{else}
172-
<img src="{@$__wcf->getPath()}images/placeholderTiny.png" style="width: 48px; height: 48px" alt="">
173-
{/if}
174-
</span>
175-
176-
<div class="containerHeadline">
177-
{if $article->hasLabels()}
178-
<ul class="labelList" style="float: right; padding-left: 7px;">
179-
{foreach from=$article->getLabels() item=label}
180-
<li>{@$label->render()}</li>
181-
{/foreach}
182-
</ul>
183-
{/if}
184-
185-
<h3>
186-
{if $article->isDeleted}<span class="badge label red jsIconDeleted">{lang}wcf.message.status.deleted{/lang}</span>{/if}
187-
{if $article->publicationStatus == 0}<span class="badge jsUnpublishedArticle">{lang}wcf.acp.article.publicationStatus.unpublished{/lang}</span>{/if}
188-
{if $article->publicationStatus == 2}<span class="badge" title="{$article->publicationDate|plainTime}">{lang}wcf.acp.article.publicationStatus.delayed{/lang}</span>{/if}
189-
<a href="{link controller='ArticleEdit' id=$article->articleID}{/link}" title="{lang}wcf.acp.article.edit{/lang}" class="jsTooltip">{$article->title}</a>
190-
</h3>
191-
<ul class="inlineList dotSeparated">
192-
{if $article->categoryID}
193-
<li class="jsArticleCategory">{$article->getCategory()->getTitle()}</li>
194-
{/if}
195-
196-
{if $article->username}
197-
<li>
198-
{if $article->userID}
199-
<a href="{link controller='UserEdit' id=$article->userID}{/link}">{$article->username}</a>
200-
{else}
201-
{$article->username}
202-
{/if}
203-
</li>
204-
{/if}
205-
</ul>
206-
</div>
207-
</div>
208-
</td>
209-
<td class="columnDigits columnViews">{#$article->views}</td>
210-
<td class="columnDate columnTime">{@$article->time|time}</td>
211-
212-
{event name='columns'}
213-
</tr>
214-
{/foreach}
215-
</tbody>
216-
</table>
217-
</div>
218-
219-
<footer class="contentFooter">
220-
{hascontent}
221-
<div class="paginationBottom">
222-
{content}{@$pagesLinks}{/content}
223-
</div>
224-
{/hascontent}
225-
226-
<nav class="contentFooterNavigation">
227-
<ul>
228-
{if $availableLanguages|count > 1}
229-
<li><a href="#" class="button jsButtonArticleAdd">{icon name='plus'} <span>{lang}wcf.acp.article.add{/lang}</span></a></li>
230-
{else}
231-
<li><a href="{link controller='ArticleAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.article.add{/lang}</span></a></li>
232-
{/if}
233-
234-
{event name='contentFooterNavigation'}
235-
</ul>
236-
</nav>
237-
</footer>
238-
{else}
239-
<woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
240-
{/if}
21+
<div class="section">
22+
{unsafe:$gridView->render()}
23+
</div>
24124

242-
{include file='shared_articleAddDialog'}
25+
{include file='shared_articleAddDialog' categoryID=0}
24326

24427
{include file='footer'}

0 commit comments

Comments
 (0)