Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 3 additions & 73 deletions com.woltlab.wcf/templates/articleAdd.tpl
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
{capture assign='__contentHeader'}
<header class="contentHeader">
<div class="contentHeaderTitle">
<h1 class="contentTitle">
{if $articleIsFrontend|empty}
{if $action == 'add'}{lang}wcf.acp.article.add{/lang}{else}{lang}wcf.acp.article.edit{/lang}{/if}
{else}
{$__wcf->getActivePage()->getTitle()}
{/if}
</h1>
<h1 class="contentTitle">{$__wcf->getActivePage()->getTitle()}</h1>
</div>

{hascontent}
Expand All @@ -25,48 +19,7 @@
</header>
{/capture}

{capture assign='contentInteractionButtons'}
{if $action == 'edit'}
{if $article->canDelete()}
<button
type="button"
class="contentInteractionButton button small jsButtonRestore"
{if !$article->isDeleted} style="display: none"{/if}
>
{icon name='rotate-left'}
<span>{lang}wcf.global.button.restore{/lang}</span>
</button>
<button
type="button"
class="contentInteractionButton button small jsButtonDelete"
{if !$article->isDeleted} style="display: none"{/if}
>
{icon name='xmark'}
<span>{lang}wcf.global.button.delete{/lang}</span>
</button>
<button
type="button"
class="contentInteractionButton button small jsButtonTrash"
{if $article->isDeleted} style="display: none"{/if}
>
{icon name='trash-can'}
<span>{lang}wcf.global.button.trash{/lang}</span>
</button>
{/if}
{if $languages|count > 1 || $article->isMultilingual}
<button type="button" class="contentInteractionButton button small jsButtonToggleI18n">
{icon name='language'}
<span>{lang}wcf.acp.article.button.toggleI18n{/lang}</span>
</button>
{/if}
{/if}
{/capture}

{if $articleIsFrontend|empty}
{include file='header' pageTitle='wcf.acp.article.'|concat:$action}
{else}
{include file='header' contentHeader=$__contentHeader}
{/if}
{include file='header' contentHeader=$__contentHeader}

{if $__wcf->session->getPermission('admin.content.article.canManageArticle')}
<script data-relocate="true">
Expand Down Expand Up @@ -94,27 +47,8 @@
{/if}

<script data-relocate="true">
require(['Language', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'], function(Language, UiUserSearchInput, AcpUiArticleInlineEditor) {
Language.addObject({
'wcf.article.convertFromI18n.question': '{jslang}wcf.article.convertFromI18n.question{/jslang}',
'wcf.article.convertFromI18n.description': '{jslang}wcf.article.convertFromI18n.description{/jslang}',
'wcf.article.convertToI18n.question': '{jslang}wcf.article.convertToI18n.question{/jslang}',
'wcf.article.convertToI18n.description': '{jslang}wcf.article.convertToI18n.description{/jslang}',
'wcf.acp.article.i18n.source': '{jslang}wcf.acp.article.i18n.source{/jslang}',
'wcf.message.status.deleted': '{jslang}wcf.message.status.deleted{/jslang}',
});

require(['WoltLabSuite/Core/Ui/User/Search/Input'], (UiUserSearchInput) => {
new UiUserSearchInput(document.querySelector('input[name="username"]'));
{if $action == 'edit'}
new AcpUiArticleInlineEditor({$article->articleID}, {
i18n: {
defaultLanguageId: {$defaultLanguageID},
isI18n: {if $article->isMultilingual}true{else}false{/if},
languages: { {implode from=$languages item=language glue=', '}{$language->languageID}: '{$language|encodeJS}'{/implode} }
},
redirectUrl: '{link controller='ArticleList'}{/link}'
});
{/if}
});
</script>

Expand All @@ -131,10 +65,6 @@
</script>
{/if}

{if $articleIsFrontend|empty}
{unsafe:$__contentHeader}
{/if}

{include file='shared_formNotice'}

{if $action == 'edit'}
Expand Down
1 change: 1 addition & 0 deletions ts/WoltLabSuite/Core/Acp/Ui/Article/InlineEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @author Alexander Ebert
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @deprecated 6.2 No longer in use.
*/

import { showDefaultSuccessSnackbar } from "WoltLabSuite/Core/Component/Snackbar";
Expand Down
54 changes: 46 additions & 8 deletions ts/WoltLabSuite/Core/Component/Interaction/FormBuilderDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,65 @@

import { dialogFactory } from "WoltLabSuite/Core/Component/Dialog";
import { showDefaultSuccessSnackbar } from "WoltLabSuite/Core/Component/Snackbar";
import { InteractionEffect } from "./InteractionEffect";

async function handleFormBuilderDialogAction(element: HTMLElement, endpoint: string): Promise<void> {
type Payload = Record<string, string>;

async function handleFormBuilderDialogAction(
container: HTMLElement,
element: HTMLElement,
endpoint: string,
interactionEffect: InteractionEffect = InteractionEffect.ReloadItem,
detail: Payload,
): Promise<void> {
const { ok } = await dialogFactory().usingFormBuilder().fromEndpoint(endpoint);

if (!ok) {
return;
}

element.dispatchEvent(
new CustomEvent("interaction:invalidate", {
bubbles: true,
}),
);
if (interactionEffect === InteractionEffect.ReloadItem || interactionEffect === InteractionEffect.ReloadPage) {
element.dispatchEvent(
new CustomEvent<Payload>("interaction:invalidate", {
bubbles: true,
detail: {
...detail,
_reloadPage: String(interactionEffect === InteractionEffect.ReloadPage),
},
}),
);
} else if (interactionEffect === InteractionEffect.ReloadList) {
container.dispatchEvent(
new CustomEvent<Payload>("interaction:invalidate-all", {
detail: {
...detail,
},
}),
);
} else {
element.dispatchEvent(
new CustomEvent<Payload>("interaction:remove", {
bubbles: true,
detail: {
...detail,
},
}),
);
}

showDefaultSuccessSnackbar();
}

export function setup(identifier: string, container: HTMLElement): void {
container.addEventListener("interaction:execute", (event: CustomEvent) => {
container.addEventListener("interaction:execute", (event: CustomEvent<Payload>) => {
if (event.detail.interaction === identifier) {
void handleFormBuilderDialogAction(event.target as HTMLElement, event.detail.endpoint);
void handleFormBuilderDialogAction(
container,
event.target as HTMLElement,
event.detail.endpoint,
event.detail.interactionEffect as InteractionEffect,
event.detail,
);
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
export enum InteractionEffect {
ReloadItem = "ReloadItem",
ReloadList = "ReloadList",
ReloadPage = "ReloadPage",
RemoveItem = "RemoveItem",
}
27 changes: 20 additions & 7 deletions ts/WoltLabSuite/Core/Component/Interaction/LegacyDboAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { showDefaultSuccessSnackbar, showSuccessSnackbar } from "WoltLabSuite/Co
import { getPhrase } from "WoltLabSuite/Core/Language";
import { InteractionEffect } from "./InteractionEffect";

type Payload = Record<string, string>;

async function handleDboAction(
container: HTMLElement,
element: HTMLElement,
Expand All @@ -23,6 +25,7 @@ async function handleDboAction(
confirmationType: ConfirmationType,
customConfirmationMessage: string = "",
interactionEffect: InteractionEffect = InteractionEffect.ReloadItem,
detail: Payload,
): Promise<void> {
const confirmationResult = await handleConfirmation(objectName, confirmationType, customConfirmationMessage);
if (!confirmationResult.result) {
Expand All @@ -34,18 +37,27 @@ async function handleDboAction(
.payload(confirmationResult.reason ? { reason: confirmationResult.reason } : {})
.dispatch();

if (interactionEffect === InteractionEffect.ReloadItem) {
if (interactionEffect === InteractionEffect.ReloadItem || interactionEffect === InteractionEffect.ReloadPage) {
element.dispatchEvent(
new CustomEvent("interaction:invalidate", {
new CustomEvent<Payload>("interaction:invalidate", {
bubbles: true,
detail: {
...detail,
_reloadPage: String(interactionEffect === InteractionEffect.ReloadPage),
},
}),
);
} else if (interactionEffect === InteractionEffect.ReloadList) {
container.dispatchEvent(new CustomEvent("interaction:invalidate-all"));
container.dispatchEvent(
new CustomEvent<Payload>("interaction:invalidate-all", {
detail,
}),
);
} else {
element.dispatchEvent(
new CustomEvent("interaction:remove", {
new CustomEvent<Payload>("interaction:remove", {
bubbles: true,
detail,
}),
);
}
Expand All @@ -58,17 +70,18 @@ async function handleDboAction(
}

export function setup(identifier: string, container: HTMLElement): void {
container.addEventListener("interaction:execute", (event: CustomEvent) => {
container.addEventListener("interaction:execute", (event: CustomEvent<Payload>) => {
if (event.detail.interaction === identifier) {
void handleDboAction(
container,
event.target as HTMLElement,
event.detail.objectName,
event.detail.className,
event.detail.actionName,
event.detail.confirmationType,
event.detail.confirmationType as ConfirmationType,
event.detail.confirmationMessage,
event.detail.interactionEffect,
event.detail.interactionEffect as InteractionEffect,
event.detail,
);
}
});
Expand Down
23 changes: 16 additions & 7 deletions ts/WoltLabSuite/Core/Component/Interaction/Rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { showDefaultSuccessSnackbar, showSuccessSnackbar } from "WoltLabSuite/Co
import { getPhrase } from "WoltLabSuite/Core/Language";
import { InteractionEffect } from "./InteractionEffect";

type Payload = Record<string, string>;

async function handleRpcInteraction(
container: HTMLElement,
element: HTMLElement,
Expand All @@ -22,6 +24,7 @@ async function handleRpcInteraction(
confirmationType: ConfirmationType,
customConfirmationMessage: string = "",
interactionEffect: InteractionEffect = InteractionEffect.ReloadItem,
detail: Payload,
): Promise<void> {
const confirmationResult = await handleConfirmation(objectName, confirmationType, customConfirmationMessage);
if (!confirmationResult.result) {
Expand All @@ -43,18 +46,23 @@ async function handleRpcInteraction(
}
}

if (interactionEffect === InteractionEffect.ReloadItem) {
if (interactionEffect === InteractionEffect.ReloadItem || interactionEffect === InteractionEffect.ReloadPage) {
element.dispatchEvent(
new CustomEvent("interaction:invalidate", {
new CustomEvent<Payload>("interaction:invalidate", {
bubbles: true,
detail: {
...detail,
_reloadPage: String(interactionEffect === InteractionEffect.ReloadPage),
},
}),
);
} else if (interactionEffect === InteractionEffect.ReloadList) {
container.dispatchEvent(new CustomEvent("interaction:invalidate-all"));
container.dispatchEvent(new CustomEvent<Payload>("interaction:invalidate-all", { detail }));
} else {
element.dispatchEvent(
new CustomEvent("interaction:remove", {
new CustomEvent<Payload>("interaction:remove", {
bubbles: true,
detail,
}),
);
}
Expand All @@ -67,16 +75,17 @@ async function handleRpcInteraction(
}

export function setup(identifier: string, container: HTMLElement): void {
container.addEventListener("interaction:execute", (event: CustomEvent) => {
container.addEventListener("interaction:execute", (event: CustomEvent<Payload>) => {
if (event.detail.interaction === identifier) {
void handleRpcInteraction(
container,
event.target as HTMLElement,
event.detail.objectName,
event.detail.endpoint,
event.detail.confirmationType,
event.detail.confirmationType as ConfirmationType,
event.detail.confirmationMessage,
event.detail.interactionEffect,
event.detail.interactionEffect as InteractionEffect,
event.detail,
);
}
});
Expand Down
18 changes: 14 additions & 4 deletions ts/WoltLabSuite/Core/Component/Interaction/StandaloneButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ interface HeaderContent {
template: string;
}

type Payload = Record<string, string>;

export class StandaloneButton {
#container: HTMLElement;
#providerClassName: string;
Expand Down Expand Up @@ -100,9 +102,15 @@ export class StandaloneButton {
}

#initEventListeners(): void {
this.#container.addEventListener("interaction:invalidate", () => {
void this.#refreshContextMenu();
void this.#refreshHeader();
this.#container.addEventListener("interaction:invalidate", (event: CustomEvent<Payload>) => {
if (event.detail._reloadPage === "true") {
setTimeout(() => {
window.location.reload();
}, 2000);
} else {
void this.#refreshContextMenu();
void this.#refreshHeader();
}
});

this.#container.addEventListener("interaction:invalidate-all", () => {
Expand All @@ -111,7 +119,9 @@ export class StandaloneButton {
});

this.#container.addEventListener("interaction:remove", () => {
window.location.href = this.#redirectUrl;
setTimeout(() => {
window.location.href = this.#redirectUrl;
}, 2000);
});
}
}
7 changes: 5 additions & 2 deletions wcfsetup/install/files/acp/templates/adAdd.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@

<nav class="contentHeaderNavigation">
<ul>
<li><a href="{link controller='AdList'}{/link}" class="button">{icon name='list'} <span>{lang}wcf.acp.menu.link.ad.list{/lang}</span></a></li>

{if $action == 'edit'}
<li>
{unsafe:$interactionContextMenu->render()}
</li>
{/if}
{event name='contentHeaderNavigation'}
</ul>
</nav>
Expand Down
Loading