Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of incomplete mail configuration #1921

Merged
merged 6 commits into from
Feb 7, 2020
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
54 changes: 36 additions & 18 deletions js/src/admin/components/MailPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ export default class MailPage extends Page {
init() {
super.init();

this.loading = true;
this.saving = false;
this.refresh();
}

refresh() {
this.loading = true;

this.driverFields = {};
this.fields = ['mail_driver', 'mail_from'];
this.values = {};
this.status = {sending: false, errors: {}};

const settings = app.data.settings;
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));

app.request({
method: 'GET',
url: app.forum.attribute('apiUrl') + '/mail-drivers'
url: app.forum.attribute('apiUrl') + '/mail-settings'
}).then(response => {
this.driverFields = response['data'].reduce(
(hash, driver) => ({...hash, [driver['id']]: driver['attributes']['fields']}),
{}
);
this.driverFields = response['data']['attributes']['fields'];
this.status.sending = response['data']['attributes']['sending'];
this.status.errors = response['data']['attributes']['errors'];

for (const driver in this.driverFields) {
for (const field in this.driverFields[driver]) {
Expand All @@ -42,7 +46,7 @@ export default class MailPage extends Page {
}

view() {
if (this.loading) {
if (this.loading || this.saving) {
return (
<div className="MailPage">
<div className="container">
Expand All @@ -52,6 +56,9 @@ export default class MailPage extends Page {
);
}

const fields = this.driverFields[this.values.mail_driver()];
const fieldKeys = Object.keys(fields);

return (
<div className="MailPage">
<div className="container">
Expand All @@ -66,8 +73,10 @@ export default class MailPage extends Page {
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
<label>{app.translator.trans('core.admin.email.from_label')}</label>
<input className="FormControl" value={this.values.mail_from() || ''} oninput={m.withAttr('value', this.values.mail_from)} />
<label>
{app.translator.trans('core.admin.email.from_label')}
<input className="FormControl" value={this.values.mail_from() || ''} oninput={m.withAttr('value', this.values.mail_from)} />
</label>
</div>
]
})}
Expand All @@ -77,20 +86,30 @@ export default class MailPage extends Page {
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
<label>{app.translator.trans('core.admin.email.driver_label')}</label>
<Select value={this.values.mail_driver()} options={Object.keys(this.driverFields).reduce((memo, val) => ({...memo, [val]: val}), {})} onchange={this.values.mail_driver} />
<label>
{app.translator.trans('core.admin.email.driver_label')}
<Select value={this.values.mail_driver()} options={Object.keys(this.driverFields).reduce((memo, val) => ({...memo, [val]: val}), {})} onchange={this.values.mail_driver} />
</label>
</div>
]
})}

{Object.keys(this.driverFields[this.values.mail_driver()]).length > 0 && FieldSet.component({
{this.status.sending || Alert.component({
children: app.translator.trans('core.admin.email.not_sending_message'),
dismissible: false,
})}

{fieldKeys.length > 0 && FieldSet.component({
label: app.translator.trans(`core.admin.email.${this.values.mail_driver()}_heading`),
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
{Object.keys(this.driverFields[this.values.mail_driver()]).map(field => [
<label>{app.translator.trans(`core.admin.email.${field}_label`)}</label>,
this.renderField(field),
{fieldKeys.map(field => [
<label>
{app.translator.trans(`core.admin.email.${field}_label`)}
{this.renderField(field)}
</label>,
this.status.errors[field] && <p className='ValidationError'>{this.status.errors[field]}</p>,
])}
</div>
]
Expand All @@ -100,7 +119,6 @@ export default class MailPage extends Page {
type: 'submit',
className: 'Button Button--primary',
children: app.translator.trans('core.admin.email.submit_button'),
loading: this.saving,
disabled: !this.changed()
})}
</form>
Expand All @@ -115,7 +133,7 @@ export default class MailPage extends Page {
const prop = this.values[name];

if (typeof field === 'string') {
return <input className="FormControl" value={prop() || ''} oninput={m.withAttr('value', prop)}/>;
return <input className="FormControl" value={prop() || ''} oninput={m.withAttr('value', prop)} />;
} else {
return <Select value={prop()} options={field} onchange={prop} />;
}
Expand Down Expand Up @@ -144,7 +162,7 @@ export default class MailPage extends Page {
.catch(() => {})
.then(() => {
this.saving = false;
m.redraw();
this.refresh();
});
}
}
23 changes: 8 additions & 15 deletions less/admin/MailPage.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,25 @@
}
}

fieldset {
margin-bottom: 30px;
fieldset, .Alert {
margin-bottom: 20px;
}

> ul {
list-style: none;
margin: 0;
padding: 0;
}
fieldset > ul {
list-style: none;
margin: 0;
padding: 0;
}
}

.MailPage-MailSettings-input {

label {
margin-bottom: 5px;
}

.FormControl {
display: block;
margin-bottom: 7px;
}

.Select {
display: block;
}

:last-child {
margin-bottom: 0;
}
}
5 changes: 5 additions & 0 deletions less/common/ValidationError.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ValidationError {
font-size: 0.9em;
font-weight: bold;
color: @validation-error-color;
}
1 change: 1 addition & 0 deletions less/common/common.less
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
@import "Search";
@import "Select";
@import "Tooltip";
@import "ValidationError";
6 changes: 5 additions & 1 deletion less/common/variables.less
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,19 @@
@hero-color: @control-color;
@hero-muted-color: @control-color;

@error-color: #d83e3e;

@alert-bg: #fff2ae;
@alert-color: #ad6c00;

@alert-error-bg: #d83e3e;
@alert-error-bg: @error-color;
@alert-error-color: #fff;

@alert-success-bg: #B4F1AF;
@alert-success-color: #33722D;

@validation-error-color: @error-color;

.define-header(@config-colored-header);
.define-header(false) {
@header-bg: @body-bg;
Expand Down
43 changes: 0 additions & 43 deletions src/Api/Controller/ListMailDriversController.php

This file was deleted.

56 changes: 56 additions & 0 deletions src/Api/Controller/ShowMailSettingsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Api\Controller;

use Flarum\Api\Serializer\MailSettingsSerializer;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\AssertPermissionTrait;
use Illuminate\Contracts\Validation\Factory;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;

class ShowMailSettingsController extends AbstractShowController
{
use AssertPermissionTrait;

/**
* {@inheritdoc}
*/
public $serializer = MailSettingsSerializer::class;

/**
* {@inheritdoc}
*/
protected function data(ServerRequestInterface $request, Document $document)
{
$this->assertAdmin($request->getAttribute('actor'));

$drivers = array_map(function ($driver) {
return self::$container->make($driver);
}, self::$container->make('mail.supported_drivers'));

$settings = self::$container->make(SettingsRepositoryInterface::class);
$configured = self::$container->make('flarum.mail.configured_driver');
$actual = self::$container->make('mail.driver');
$validator = self::$container->make(Factory::class);

if (method_exists($configured, 'validate')) {
$errors = $configured->validate($settings, $validator);
} else {
$errors = new \Illuminate\Support\MessageBag;
}

return [
'drivers' => $drivers,
'sending' => method_exists($actual, 'canSend') ? $actual->canSend() : true,
'errors' => $errors,
];
}
}
57 changes: 0 additions & 57 deletions src/Api/Serializer/MailDriverSerializer.php

This file was deleted.

Loading