mirror of
https://github.com/flarum/core.git
synced 2025-08-06 16:36:47 +02:00
feat: make it easier to modify AppearancePage, BasicsPage, MailPage (#4037)
This commit is contained in:
@@ -19,52 +19,7 @@ export default class AppearancePage extends AdminPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
content() {
|
content() {
|
||||||
return (
|
return this.contentItems().toArray();
|
||||||
<>
|
|
||||||
<div className="Form">
|
|
||||||
<fieldset className="AppearancePage-colors">
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.colors_heading')}</legend>
|
|
||||||
{this.colorItems().toArray()}
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.logo_heading')}</legend>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.appearance.logo_text')}</div>
|
|
||||||
<UploadImageButton name="logo" />
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.favicon_heading')}</legend>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.appearance.favicon_text')}</div>
|
|
||||||
<UploadImageButton name="favicon" />
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.custom_header_heading')}</legend>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_header_text')}</div>
|
|
||||||
<Button className="Button" onclick={() => app.modal.show(EditCustomHeaderModal)}>
|
|
||||||
{app.translator.trans('core.admin.appearance.edit_header_button')}
|
|
||||||
</Button>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.custom_footer_heading')}</legend>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_footer_text')}</div>
|
|
||||||
<Button className="Button" onclick={() => app.modal.show(EditCustomFooterModal)}>
|
|
||||||
{app.translator.trans('core.admin.appearance.edit_footer_button')}
|
|
||||||
</Button>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>{app.translator.trans('core.admin.appearance.custom_styles_heading')}</legend>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_styles_text')}</div>
|
|
||||||
<Button className="Button" onclick={() => app.modal.show(EditCustomCssModal)}>
|
|
||||||
{app.translator.trans('core.admin.appearance.edit_css_button')}
|
|
||||||
</Button>
|
|
||||||
</fieldset>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
colorItems() {
|
colorItems() {
|
||||||
@@ -119,4 +74,77 @@ export default class AppearancePage extends AdminPage {
|
|||||||
onsaved() {
|
onsaved() {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentItems(): ItemList<Mithril.Children> {
|
||||||
|
const items = new ItemList<Mithril.Children>();
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'colors',
|
||||||
|
<div className="Form">
|
||||||
|
<fieldset className="AppearancePage-colors">
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.colors_heading')}</legend>
|
||||||
|
{this.colorItems().toArray()}
|
||||||
|
</fieldset>
|
||||||
|
</div>,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'logo',
|
||||||
|
<fieldset>
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.logo_heading')}</legend>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.appearance.logo_text')}</div>
|
||||||
|
<UploadImageButton name="logo" />
|
||||||
|
</fieldset>,
|
||||||
|
90
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'favicon',
|
||||||
|
<fieldset>
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.favicon_heading')}</legend>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.appearance.favicon_text')}</div>
|
||||||
|
<UploadImageButton name="favicon" />
|
||||||
|
</fieldset>,
|
||||||
|
80
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'custom-header',
|
||||||
|
<fieldset>
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.custom_header_heading')}</legend>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_header_text')}</div>
|
||||||
|
<Button className="Button" onclick={() => app.modal.show(EditCustomHeaderModal)}>
|
||||||
|
{app.translator.trans('core.admin.appearance.edit_header_button')}
|
||||||
|
</Button>
|
||||||
|
</fieldset>,
|
||||||
|
70
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'custom-footer',
|
||||||
|
<fieldset>
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.custom_footer_heading')}</legend>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_footer_text')}</div>
|
||||||
|
<Button className="Button" onclick={() => app.modal.show(EditCustomFooterModal)}>
|
||||||
|
{app.translator.trans('core.admin.appearance.edit_footer_button')}
|
||||||
|
</Button>
|
||||||
|
</fieldset>,
|
||||||
|
60
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'custom-css',
|
||||||
|
<fieldset>
|
||||||
|
<legend>{app.translator.trans('core.admin.appearance.custom_styles_heading')}</legend>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.appearance.custom_styles_text')}</div>
|
||||||
|
<Button className="Button" onclick={() => app.modal.show(EditCustomCssModal)}>
|
||||||
|
{app.translator.trans('core.admin.appearance.edit_css_button')}
|
||||||
|
</Button>
|
||||||
|
</fieldset>,
|
||||||
|
50
|
||||||
|
);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import FieldSet from '../../common/components/FieldSet';
|
|||||||
import ItemList from '../../common/utils/ItemList';
|
import ItemList from '../../common/utils/ItemList';
|
||||||
import AdminPage from './AdminPage';
|
import AdminPage from './AdminPage';
|
||||||
import type { IPageAttrs } from '../../common/components/Page';
|
import type { IPageAttrs } from '../../common/components/Page';
|
||||||
import type Mithril from 'mithril';
|
import Mithril from 'mithril';
|
||||||
|
|
||||||
export type HomePageItem = { path: string; label: Mithril.Children };
|
export type HomePageItem = { path: string; label: Mithril.Children };
|
||||||
|
|
||||||
@@ -44,78 +44,7 @@ export default class BasicsPage<CustomAttrs extends IPageAttrs = IPageAttrs> ext
|
|||||||
content() {
|
content() {
|
||||||
return [
|
return [
|
||||||
<div className="Form">
|
<div className="Form">
|
||||||
{this.buildSettingComponent({
|
{this.contentItems().toArray()}
|
||||||
type: 'text',
|
|
||||||
setting: 'forum_title',
|
|
||||||
label: app.translator.trans('core.admin.basics.forum_title_heading'),
|
|
||||||
})}
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: 'text',
|
|
||||||
setting: 'forum_description',
|
|
||||||
label: app.translator.trans('core.admin.basics.forum_description_heading'),
|
|
||||||
help: app.translator.trans('core.admin.basics.forum_description_text'),
|
|
||||||
})}
|
|
||||||
|
|
||||||
{Object.keys(this.localeOptions).length > 1 && (
|
|
||||||
<>
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: 'select',
|
|
||||||
setting: 'default_locale',
|
|
||||||
options: this.localeOptions,
|
|
||||||
label: app.translator.trans('core.admin.basics.default_language_heading'),
|
|
||||||
})}
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: 'switch',
|
|
||||||
setting: 'show_language_selector',
|
|
||||||
label: app.translator.trans('core.admin.basics.show_language_selector_label'),
|
|
||||||
})}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<FieldSet className="BasicsPage-homePage Form-group" label={app.translator.trans('core.admin.basics.home_page_heading')}>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.basics.home_page_text')}</div>
|
|
||||||
{this.homePageItems()
|
|
||||||
.toArray()
|
|
||||||
.map(({ path, label }) => (
|
|
||||||
<label className="checkbox">
|
|
||||||
<input type="radio" name="homePage" value={path} bidi={this.setting('default_route')} />
|
|
||||||
{label}
|
|
||||||
</label>
|
|
||||||
))}
|
|
||||||
</FieldSet>
|
|
||||||
|
|
||||||
<div className="Form-group BasicsPage-welcomeBanner-input">
|
|
||||||
<label>{app.translator.trans('core.admin.basics.welcome_banner_heading')}</label>
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.basics.welcome_banner_text')}</div>
|
|
||||||
<input type="text" className="FormControl" bidi={this.setting('welcome_title')} />
|
|
||||||
<textarea className="FormControl" bidi={this.setting('welcome_message')} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{Object.keys(this.displayNameOptions).length > 1 &&
|
|
||||||
this.buildSettingComponent({
|
|
||||||
type: 'select',
|
|
||||||
setting: 'display_name_driver',
|
|
||||||
options: this.displayNameOptions,
|
|
||||||
label: app.translator.trans('core.admin.basics.display_name_heading'),
|
|
||||||
help: app.translator.trans('core.admin.basics.display_name_text'),
|
|
||||||
})}
|
|
||||||
|
|
||||||
{Object.keys(this.slugDriverOptions).map((model) => {
|
|
||||||
const options = this.slugDriverOptions[model];
|
|
||||||
|
|
||||||
if (Object.keys(options).length > 1) {
|
|
||||||
return this.buildSettingComponent({
|
|
||||||
type: 'select',
|
|
||||||
setting: `slug_driver_${model}`,
|
|
||||||
options,
|
|
||||||
label: app.translator.trans('core.admin.basics.slug_driver_heading', { model }),
|
|
||||||
help: app.translator.trans('core.admin.basics.slug_driver_text', { model }),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
})}
|
|
||||||
|
|
||||||
{this.submitButton()}
|
{this.submitButton()}
|
||||||
</div>,
|
</div>,
|
||||||
];
|
];
|
||||||
@@ -135,4 +64,111 @@ export default class BasicsPage<CustomAttrs extends IPageAttrs = IPageAttrs> ext
|
|||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentItems(): ItemList<Mithril.Children> {
|
||||||
|
const items = new ItemList<Mithril.Children>();
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'forum-title',
|
||||||
|
this.buildSettingComponent({
|
||||||
|
type: 'text',
|
||||||
|
setting: 'forum_title',
|
||||||
|
label: app.translator.trans('core.admin.basics.forum_title_heading'),
|
||||||
|
}),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'forum-description',
|
||||||
|
this.buildSettingComponent({
|
||||||
|
type: 'text',
|
||||||
|
setting: 'forum_description',
|
||||||
|
label: app.translator.trans('core.admin.basics.forum_description_heading'),
|
||||||
|
help: app.translator.trans('core.admin.basics.forum_description_text'),
|
||||||
|
}),
|
||||||
|
90
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'default-locale',
|
||||||
|
Object.keys(this.localeOptions).length > 1 && (
|
||||||
|
<>
|
||||||
|
{this.buildSettingComponent({
|
||||||
|
type: 'select',
|
||||||
|
setting: 'default_locale',
|
||||||
|
options: this.localeOptions,
|
||||||
|
label: app.translator.trans('core.admin.basics.default_language_heading'),
|
||||||
|
})}
|
||||||
|
{this.buildSettingComponent({
|
||||||
|
type: 'switch',
|
||||||
|
setting: 'show_language_selector',
|
||||||
|
label: app.translator.trans('core.admin.basics.show_language_selector_label'),
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
80
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'home-page',
|
||||||
|
<FieldSet className="BasicsPage-homePage Form-group" label={app.translator.trans('core.admin.basics.home_page_heading')}>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.basics.home_page_text')}</div>
|
||||||
|
{this.homePageItems()
|
||||||
|
.toArray()
|
||||||
|
.map(({ path, label }) => (
|
||||||
|
<label className="checkbox">
|
||||||
|
<input type="radio" name="homePage" value={path} bidi={this.setting('default_route')} />
|
||||||
|
{label}
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</FieldSet>,
|
||||||
|
70
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'welcome-banner',
|
||||||
|
<div className="Form-group BasicsPage-welcomeBanner-input">
|
||||||
|
<label>{app.translator.trans('core.admin.basics.welcome_banner_heading')}</label>
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.basics.welcome_banner_text')}</div>
|
||||||
|
<input type="text" className="FormControl" bidi={this.setting('welcome_title')} />
|
||||||
|
<textarea className="FormControl" bidi={this.setting('welcome_message')} />
|
||||||
|
</div>,
|
||||||
|
60
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'display-name-driver',
|
||||||
|
Object.keys(this.displayNameOptions).length > 1 &&
|
||||||
|
this.buildSettingComponent({
|
||||||
|
type: 'select',
|
||||||
|
setting: 'display_name_driver',
|
||||||
|
options: this.displayNameOptions,
|
||||||
|
label: app.translator.trans('core.admin.basics.display_name_heading'),
|
||||||
|
help: app.translator.trans('core.admin.basics.display_name_text'),
|
||||||
|
}),
|
||||||
|
50
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'slug-driver',
|
||||||
|
Object.keys(this.slugDriverOptions).map((model) => {
|
||||||
|
const options = this.slugDriverOptions[model];
|
||||||
|
|
||||||
|
if (Object.keys(options).length > 1) {
|
||||||
|
return this.buildSettingComponent({
|
||||||
|
type: 'select',
|
||||||
|
setting: `slug_driver_${model}`,
|
||||||
|
options,
|
||||||
|
label: app.translator.trans('core.admin.basics.slug_driver_heading', { model }),
|
||||||
|
help: app.translator.trans('core.admin.basics.slug_driver_text', { model }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
40
|
||||||
|
);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,9 @@ import LoadingIndicator from '../../common/components/LoadingIndicator';
|
|||||||
import AdminPage from './AdminPage';
|
import AdminPage from './AdminPage';
|
||||||
import type { IPageAttrs } from '../../common/components/Page';
|
import type { IPageAttrs } from '../../common/components/Page';
|
||||||
import type { AlertIdentifier } from '../../common/states/AlertManagerState';
|
import type { AlertIdentifier } from '../../common/states/AlertManagerState';
|
||||||
import type Mithril from 'mithril';
|
import Mithril from 'mithril';
|
||||||
import type { SaveSubmitEvent } from './AdminPage';
|
import type { SaveSubmitEvent } from './AdminPage';
|
||||||
|
import ItemList from '../../common/utils/ItemList';
|
||||||
|
|
||||||
export interface MailSettings {
|
export interface MailSettings {
|
||||||
data: {
|
data: {
|
||||||
@@ -65,55 +66,7 @@ export default class MailPage<CustomAttrs extends IPageAttrs = IPageAttrs> exten
|
|||||||
return <LoadingIndicator />;
|
return <LoadingIndicator />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fields = this.driverFields![this.setting('mail_driver')()];
|
return <div className="Form">{this.contentItems().toArray()}</div>;
|
||||||
const fieldKeys = Object.keys(fields);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="Form">
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: 'text',
|
|
||||||
setting: 'mail_from',
|
|
||||||
label: app.translator.trans('core.admin.email.addresses_heading'),
|
|
||||||
})}
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: 'select',
|
|
||||||
setting: 'mail_driver',
|
|
||||||
options: Object.keys(this.driverFields!).reduce((memo, val) => ({ ...memo, [val]: val }), {}),
|
|
||||||
label: app.translator.trans('core.admin.email.driver_heading'),
|
|
||||||
})}
|
|
||||||
{this.status!.sending || <Alert dismissible={false}>{app.translator.trans('core.admin.email.not_sending_message')}</Alert>}
|
|
||||||
|
|
||||||
{!!fieldKeys.length && (
|
|
||||||
<FieldSet label={app.translator.trans(`core.admin.email.${this.setting('mail_driver')()}_heading`)} className="MailPage-MailSettings">
|
|
||||||
<div className="MailPage-MailSettings-input">
|
|
||||||
{fieldKeys.map((field) => {
|
|
||||||
const fieldInfo = fields[field];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{this.buildSettingComponent({
|
|
||||||
type: typeof fieldInfo === 'string' ? 'text' : 'select',
|
|
||||||
label: app.translator.trans(`core.admin.email.${field}_label`),
|
|
||||||
setting: field,
|
|
||||||
options: fieldInfo,
|
|
||||||
})}
|
|
||||||
{this.status!.errors[field] && <p className="ValidationError">{this.status!.errors[field]}</p>}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</FieldSet>
|
|
||||||
)}
|
|
||||||
{this.submitButton()}
|
|
||||||
|
|
||||||
<FieldSet label={app.translator.trans('core.admin.email.send_test_mail_heading')} className="MailPage-MailSettings">
|
|
||||||
<div className="helpText">{app.translator.trans('core.admin.email.send_test_mail_text', { email: app.session.user!.email() })}</div>
|
|
||||||
<Button className="Button Button--primary" disabled={this.sendingTest || this.isChanged()} onclick={() => this.sendTestEmail()}>
|
|
||||||
{app.translator.trans('core.admin.email.send_test_mail_button')}
|
|
||||||
</Button>
|
|
||||||
</FieldSet>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTestEmail() {
|
sendTestEmail() {
|
||||||
@@ -142,4 +95,74 @@ export default class MailPage<CustomAttrs extends IPageAttrs = IPageAttrs> exten
|
|||||||
saveSettings(e: SaveSubmitEvent) {
|
saveSettings(e: SaveSubmitEvent) {
|
||||||
return super.saveSettings(e).then(() => this.refresh());
|
return super.saveSettings(e).then(() => this.refresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentItems(): ItemList<Mithril.Children> {
|
||||||
|
const items = new ItemList<Mithril.Children>();
|
||||||
|
const fields = this.driverFields![this.setting('mail_driver')()];
|
||||||
|
const fieldKeys = Object.keys(fields);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'mail-from',
|
||||||
|
this.buildSettingComponent({
|
||||||
|
type: 'text',
|
||||||
|
setting: 'mail_from',
|
||||||
|
label: app.translator.trans('core.admin.email.addresses_heading'),
|
||||||
|
}),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'mail-driver',
|
||||||
|
this.buildSettingComponent({
|
||||||
|
type: 'select',
|
||||||
|
setting: 'mail_driver',
|
||||||
|
options: Object.keys(this.driverFields!).reduce((memo, val) => ({ ...memo, [val]: val }), {}),
|
||||||
|
label: app.translator.trans('core.admin.email.driver_heading'),
|
||||||
|
}),
|
||||||
|
90
|
||||||
|
);
|
||||||
|
|
||||||
|
!this.status!.sending &&
|
||||||
|
items.add('not-sending', <Alert dismissible={false}>{app.translator.trans('core.admin.email.not_sending_message')}</Alert>, 80);
|
||||||
|
|
||||||
|
!!fieldKeys.length &&
|
||||||
|
items.add(
|
||||||
|
'driver-settings',
|
||||||
|
<FieldSet label={app.translator.trans(`core.admin.email.${this.setting('mail_driver')()}_heading`)} className="MailPage-MailSettings">
|
||||||
|
<div className="MailPage-MailSettings-input">
|
||||||
|
{fieldKeys.map((field) => {
|
||||||
|
const fieldInfo = fields[field];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{this.buildSettingComponent({
|
||||||
|
type: typeof fieldInfo === 'string' ? 'text' : 'select',
|
||||||
|
label: app.translator.trans(`core.admin.email.${field}_label`),
|
||||||
|
setting: field,
|
||||||
|
options: fieldInfo,
|
||||||
|
})}
|
||||||
|
{this.status!.errors[field] && <p className="ValidationError">{this.status!.errors[field]}</p>}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</FieldSet>,
|
||||||
|
70
|
||||||
|
);
|
||||||
|
|
||||||
|
items.add('submit-button', this.submitButton(), 60);
|
||||||
|
|
||||||
|
items.add(
|
||||||
|
'email-test',
|
||||||
|
<FieldSet label={app.translator.trans('core.admin.email.send_test_mail_heading')} className="MailPage-MailSettings">
|
||||||
|
<div className="helpText">{app.translator.trans('core.admin.email.send_test_mail_text', { email: app.session.user!.email() })}</div>
|
||||||
|
<Button className="Button Button--primary" disabled={this.sendingTest || this.isChanged()} onclick={() => this.sendTestEmail()}>
|
||||||
|
{app.translator.trans('core.admin.email.send_test_mail_button')}
|
||||||
|
</Button>
|
||||||
|
</FieldSet>,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user