Skip to content

Commit c5b050a

Browse files
committed
Migrate WCF.Conversation.Label.Manager to typescript
1 parent 3e9030f commit c5b050a

File tree

14 files changed

+548
-132
lines changed

14 files changed

+548
-132
lines changed

files/js/WCF.Conversation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,8 @@ WCF.Conversation.Label.Editor = Class.extend({
863863
* Label manager for conversations.
864864
*
865865
* @param string link
866+
*
867+
* @deprecated 6.2 use `WoltLabSuite/Core/Conversation/Component/Label/Manager` instead
866868
*/
867869
WCF.Conversation.Label.Manager = Class.extend({
868870
/**

files/js/WoltLabSuite/Core/Api/Conversations/GetConversationLabelManager.js

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

files/js/WoltLabSuite/Core/Conversation/Component/Label/Manager.js

Lines changed: 102 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<?php
2+
3+
namespace wcf\action;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use Psr\Http\Server\RequestHandlerInterface;
9+
use wcf\data\conversation\label\ConversationLabel;
10+
use wcf\data\conversation\label\ConversationLabelAction;
11+
use wcf\data\IStorableObject;
12+
use wcf\http\Helper;
13+
use wcf\system\exception\PermissionDeniedException;
14+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
15+
use wcf\system\form\builder\field\BadgeColorFormField;
16+
use wcf\system\form\builder\field\CheckboxFormField;
17+
use wcf\system\form\builder\field\dependency\EmptyFormFieldDependency;
18+
use wcf\system\form\builder\field\TextFormField;
19+
use wcf\system\form\builder\IFormDocument;
20+
use wcf\system\form\builder\Psr15DialogForm;
21+
use wcf\system\WCF;
22+
use wcf\util\StringUtil;
23+
24+
/**
25+
* Action for adding/editing conversation labels.
26+
*
27+
* @author Olaf Braun
28+
* @copyright 2001-2025 WoltLab GmbH
29+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
30+
* @since 6.2
31+
*/
32+
final class ConversationLabelFormAction implements RequestHandlerInterface
33+
{
34+
#[\Override]
35+
public function handle(ServerRequestInterface $request): ResponseInterface
36+
{
37+
$parameters = Helper::mapQueryParameters(
38+
$request->getQueryParams(),
39+
<<<'EOT'
40+
array {
41+
labelID?: positive-int
42+
}
43+
EOT
44+
);
45+
46+
if (!WCF::getUser()->userID) {
47+
throw new PermissionDeniedException();
48+
}
49+
if (!WCF::getSession()->getPermission('user.conversation.canUseConversation')) {
50+
throw new PermissionDeniedException();
51+
}
52+
53+
$label = null;
54+
if (isset($parameters['labelID'])) {
55+
$label = new ConversationLabel($parameters['labelID']);
56+
if ($label->userID !== WCF::getUser()->userID) {
57+
throw new PermissionDeniedException();
58+
}
59+
} elseif (
60+
\count(ConversationLabel::getLabelsByUser())
61+
>= WCF::getSession()->getPermission('user.conversation.maxLabels')
62+
) {
63+
throw new PermissionDeniedException();
64+
}
65+
66+
$form = $this->getForm($label);
67+
68+
if ($request->getMethod() === 'GET') {
69+
return $form->toResponse();
70+
} elseif ($request->getMethod() === 'POST') {
71+
$response = $form->validateRequest($request);
72+
if ($response !== null) {
73+
return $response;
74+
}
75+
76+
$data = $form->getData()['data'];
77+
$deleteLabel = $label && $data['deleteLabel'] ?? false;
78+
unset($data['deleteLabel']);
79+
80+
if ($deleteLabel) {
81+
(new ConversationLabelAction([$label], 'delete'))->executeAction();
82+
83+
$labelID = $label->labelID;
84+
} elseif ($label) {
85+
(new ConversationLabelAction([$label], 'update', [
86+
'data' => $data,
87+
]))->executeAction();
88+
89+
$labelID = $label->labelID;
90+
} else {
91+
$returnValues = (new ConversationLabelAction([], 'create', [
92+
'data' => \array_merge($data, [
93+
'userID' => WCF::getUser()->userID,
94+
]),
95+
]))->executeAction();
96+
97+
$labelID = $returnValues['returnValues']->labelID;
98+
}
99+
100+
return new JsonResponse([
101+
'result' => [
102+
'deleteLabel' => $deleteLabel,
103+
'label' => $deleteLabel ? '' : StringUtil::encodeHTML($data['label']),
104+
'cssClassName' => $deleteLabel ? '' : $data['cssClassName'],
105+
'labelID' => $labelID,
106+
],
107+
]);
108+
} else {
109+
throw new \LogicException('Unreachable');
110+
}
111+
}
112+
113+
private function getForm(?ConversationLabel $label): Psr15DialogForm
114+
{
115+
$form = new Psr15DialogForm(
116+
ConversationLabelFormAction::class,
117+
$label ? WCF::getLanguage()->getDynamicVariable('wcf.conversation.label.management.editLabel', [
118+
'labelName' => $label->label
119+
]) : WCF::getLanguage()->get('wcf.conversation.label.management.addLabel')
120+
);
121+
$deleteLabel = CheckboxFormField::create('deleteLabel')
122+
->label('wcf.conversation.label.management.deleteLabel')
123+
->available($label !== null)
124+
->value(false);
125+
$labelFormField = TextFormField::create('label')
126+
->label('wcf.conversation.label.labelName')
127+
->required();
128+
129+
$cssClassNameFormField = BadgeColorFormField::create('cssClassName')
130+
->supportCustomClassName(false)
131+
->label('wcf.conversation.label.cssClassName')
132+
->textReferenceNodeId($form->getPrefix() . 'label')
133+
->defaultLabelText(WCF::getLanguage()->get('wcf.conversation.label.placeholder'))
134+
->value('none')
135+
->required();
136+
137+
if ($label !== null) {
138+
$cssClassNameFormField
139+
->addDependency(
140+
EmptyFormFieldDependency::create('deleteDependency')
141+
->fieldId('deleteLabel')
142+
);
143+
$labelFormField->addDependency(
144+
EmptyFormFieldDependency::create('deleteDependency')
145+
->fieldId('deleteLabel')
146+
);
147+
}
148+
149+
$form->appendChildren([
150+
$deleteLabel,
151+
$labelFormField,
152+
$cssClassNameFormField
153+
]);
154+
155+
// Map the pseudo value 'none' to an empty string
156+
$form->getDataHandler()->addProcessor(
157+
new CustomFormDataProcessor(
158+
'cssClassNameProcessor',
159+
static function (IFormDocument $document, array $parameters) {
160+
if (isset($parameters['data']['cssClassName']) && $parameters['data']['cssClassName'] === 'none') {
161+
$parameters['data']['cssClassName'] = '';
162+
}
163+
164+
return $parameters;
165+
},
166+
static function (IFormDocument $document, array $data, IStorableObject $object) {
167+
if ($data['cssClassName'] === '') {
168+
$data['cssClassName'] = 'none';
169+
}
170+
171+
return $data;
172+
}
173+
)
174+
);
175+
176+
$form->markRequiredFields(false);
177+
if ($label !== null) {
178+
$form->updatedObject($label);
179+
}
180+
$form->build();
181+
182+
return $form;
183+
}
184+
}

files/lib/bootstrap/com.woltlab.wcf.conversation.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
4242
$event->register(new \wcf\system\endpoint\controller\core\conversations\GetConversationPopover());
4343
$event->register(new \wcf\system\endpoint\controller\core\conversations\GetConversationLabels());
4444
$event->register(new \wcf\system\endpoint\controller\core\conversations\AssignConversationLabels());
45+
$event->register(new \wcf\system\endpoint\controller\core\conversations\GetConversationLabelManager());
4546
}
4647
);
4748
};

files/lib/data/conversation/ConversationAction.class.php

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace wcf\data\conversation;
44

55
use wcf\data\AbstractDatabaseObjectAction;
6-
use wcf\data\conversation\label\ConversationLabel;
76
use wcf\data\conversation\message\ConversationMessageAction;
87
use wcf\data\conversation\message\ConversationMessageList;
98
use wcf\data\IClipboardAction;
@@ -434,38 +433,6 @@ public function validateMarkAllAsRead()
434433
// does nothing
435434
}
436435

437-
/**
438-
* Validates user access for label management.
439-
*
440-
* @throws PermissionDeniedException
441-
*/
442-
public function validateGetLabelManagement()
443-
{
444-
if (!WCF::getSession()->getPermission('user.conversation.canUseConversation')) {
445-
throw new PermissionDeniedException();
446-
}
447-
}
448-
449-
/**
450-
* Returns the conversation label management.
451-
*
452-
* @return array
453-
*/
454-
public function getLabelManagement()
455-
{
456-
WCF::getTPL()->assign([
457-
'cssClassNames' => ConversationLabel::getLabelCssClassNames(),
458-
'labelList' => ConversationLabel::getLabelsByUser(),
459-
]);
460-
461-
return [
462-
'actionName' => 'getLabelManagement',
463-
'template' => WCF::getTPL()->fetch('conversationLabelManagement'),
464-
'maxLabels' => WCF::getSession()->getPermission('user.conversation.maxLabels'),
465-
'labelCount' => \count(ConversationLabel::getLabelsByUser()),
466-
];
467-
}
468-
469436
/**
470437
* Validates parameters to close conversations.
471438
*

0 commit comments

Comments
 (0)