mirror of
https://github.com/flarum/framework.git
synced 2025-02-06 01:34:37 +08:00
Extract AlertManagerState from AlertManager (#2163)
This commit is contained in:
parent
417e878c0c
commit
95f367c837
|
@ -2,7 +2,6 @@ import Page from '../../common/components/Page';
|
|||
import FieldSet from '../../common/components/FieldSet';
|
||||
import Select from '../../common/components/Select';
|
||||
import Button from '../../common/components/Button';
|
||||
import Alert from '../../common/components/Alert';
|
||||
import saveSettings from '../utils/saveSettings';
|
||||
import ItemList from '../../common/utils/ItemList';
|
||||
import Switch from '../../common/components/Switch';
|
||||
|
@ -186,7 +185,10 @@ export default class BasicsPage extends Page {
|
|||
|
||||
saveSettings(settings)
|
||||
.then(() => {
|
||||
app.alerts.show((this.successAlert = new Alert({ type: 'success', children: app.translator.trans('core.admin.basics.saved_message') })));
|
||||
this.successAlert = app.alerts.show({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.admin.basics.saved_message'),
|
||||
});
|
||||
})
|
||||
.catch(() => {})
|
||||
.then(() => {
|
||||
|
|
|
@ -179,9 +179,10 @@ export default class MailPage extends Page {
|
|||
})
|
||||
.then((response) => {
|
||||
this.sendingTest = false;
|
||||
app.alerts.show(
|
||||
(this.testEmailSuccessAlert = new Alert({ type: 'success', children: app.translator.trans('core.admin.email.send_test_mail_success') }))
|
||||
);
|
||||
this.testEmailSuccessAlert = app.alerts.show({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.admin.email.send_test_mail_success'),
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.sendingTest = false;
|
||||
|
@ -204,7 +205,10 @@ export default class MailPage extends Page {
|
|||
|
||||
saveSettings(settings)
|
||||
.then(() => {
|
||||
app.alerts.show((this.successAlert = new Alert({ type: 'success', children: app.translator.trans('core.admin.basics.saved_message') })));
|
||||
this.successAlert = app.alerts.show({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.admin.basics.saved_message'),
|
||||
});
|
||||
})
|
||||
.catch(() => {})
|
||||
.then(() => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import ItemList from './utils/ItemList';
|
||||
import Alert from './components/Alert';
|
||||
import Button from './components/Button';
|
||||
import ModalManager from './components/ModalManager';
|
||||
import AlertManager from './components/AlertManager';
|
||||
|
@ -23,6 +22,7 @@ import Group from './models/Group';
|
|||
import Notification from './models/Notification';
|
||||
import { flattenDeep } from 'lodash-es';
|
||||
import PageState from './states/PageState';
|
||||
import AlertManagerState from './states/AlertManagerState';
|
||||
|
||||
/**
|
||||
* The `App` class provides a container for an application, as well as various
|
||||
|
@ -109,13 +109,13 @@ export default class Application {
|
|||
booted = false;
|
||||
|
||||
/**
|
||||
* An Alert that was shown as a result of an AJAX request error. If present,
|
||||
* it will be dismissed on the next successful request.
|
||||
* The key for an Alert that was shown as a result of an AJAX request error.
|
||||
* If present, it will be dismissed on the next successful request.
|
||||
*
|
||||
* @type {null|Alert}
|
||||
* @type {int}
|
||||
* @private
|
||||
*/
|
||||
requestError = null;
|
||||
requestErrorAlert = null;
|
||||
|
||||
/**
|
||||
* The page the app is currently on.
|
||||
|
@ -139,6 +139,11 @@ export default class Application {
|
|||
*/
|
||||
previous = new PageState(null);
|
||||
|
||||
/*
|
||||
* An object that manages the state of active alerts.
|
||||
*/
|
||||
alerts = new AlertManagerState();
|
||||
|
||||
data;
|
||||
|
||||
title = '';
|
||||
|
@ -175,7 +180,7 @@ export default class Application {
|
|||
|
||||
mount(basePath = '') {
|
||||
this.modal = m.mount(document.getElementById('modal'), <ModalManager />);
|
||||
this.alerts = m.mount(document.getElementById('alerts'), <AlertManager />);
|
||||
m.mount(document.getElementById('alerts'), <AlertManager state={this.alerts} />);
|
||||
|
||||
this.drawer = new Drawer();
|
||||
|
||||
|
@ -313,7 +318,7 @@ export default class Application {
|
|||
}
|
||||
};
|
||||
|
||||
if (this.requestError) this.alerts.dismiss(this.requestError.alert);
|
||||
if (this.requestErrorAlert) this.alerts.dismiss(this.requestErrorAlert);
|
||||
|
||||
// Now make the request. If it's a failure, inspect the error that was
|
||||
// returned and show an alert containing its contents.
|
||||
|
@ -322,8 +327,6 @@ export default class Application {
|
|||
m.request(options).then(
|
||||
(response) => deferred.resolve(response),
|
||||
(error) => {
|
||||
this.requestError = error;
|
||||
|
||||
let children;
|
||||
|
||||
switch (error.status) {
|
||||
|
@ -357,7 +360,7 @@ export default class Application {
|
|||
// the details property is decoded to transform escaped characters such as '\n'
|
||||
const formattedError = error.response && Array.isArray(error.response.errors) && error.response.errors.map((e) => decodeURI(e.detail));
|
||||
|
||||
error.alert = new Alert({
|
||||
error.alert = {
|
||||
type: 'error',
|
||||
children,
|
||||
controls: isDebug && [
|
||||
|
@ -365,7 +368,7 @@ export default class Application {
|
|||
Debug
|
||||
</Button>,
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
options.errorHandler(error);
|
||||
|
@ -381,7 +384,7 @@ export default class Application {
|
|||
console.groupEnd();
|
||||
}
|
||||
|
||||
this.alerts.show(error.alert);
|
||||
this.requestErrorAlert = this.alerts.show(error.alert);
|
||||
}
|
||||
|
||||
deferred.reject(error);
|
||||
|
@ -397,7 +400,7 @@ export default class Application {
|
|||
* @private
|
||||
*/
|
||||
showDebug(error, formattedError) {
|
||||
this.alerts.dismiss(this.requestError.alert);
|
||||
this.alerts.dismiss(this.requestErrorAlert);
|
||||
|
||||
this.modal.show(new RequestErrorModal({ error, formattedError }));
|
||||
}
|
||||
|
|
|
@ -7,20 +7,16 @@ import Alert from './Alert';
|
|||
*/
|
||||
export default class AlertManager extends Component {
|
||||
init() {
|
||||
/**
|
||||
* An array of Alert components which are currently showing.
|
||||
*
|
||||
* @type {Alert[]}
|
||||
* @protected
|
||||
*/
|
||||
this.components = [];
|
||||
this.state = this.props.state;
|
||||
}
|
||||
|
||||
view() {
|
||||
return (
|
||||
<div className="AlertManager">
|
||||
{this.components.map((component) => (
|
||||
<div className="AlertManager-alert">{component}</div>
|
||||
{Object.entries(this.state.getActiveAlerts()).map(([key, alert]) => (
|
||||
<div className="AlertManager-alert">
|
||||
{(alert.componentClass || Alert).component({ ...alert.attrs, ondismiss: this.state.dismiss.bind(this.state, key) })}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
@ -32,46 +28,4 @@ export default class AlertManager extends Component {
|
|||
// to be retained across route changes.
|
||||
context.retain = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an Alert in the alerts area.
|
||||
*
|
||||
* @param {Alert} component
|
||||
* @public
|
||||
*/
|
||||
show(component) {
|
||||
if (!(component instanceof Alert)) {
|
||||
throw new Error('The AlertManager component can only show Alert components');
|
||||
}
|
||||
|
||||
component.props.ondismiss = this.dismiss.bind(this, component);
|
||||
|
||||
this.components.push(component);
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss an alert.
|
||||
*
|
||||
* @param {Alert} component
|
||||
* @public
|
||||
*/
|
||||
dismiss(component) {
|
||||
const index = this.components.indexOf(component);
|
||||
|
||||
if (index !== -1) {
|
||||
this.components.splice(index, 1);
|
||||
m.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all alerts.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
clear() {
|
||||
this.components = [];
|
||||
m.redraw();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,16 @@ import Button from './Button';
|
|||
export default class Modal extends Component {
|
||||
init() {
|
||||
/**
|
||||
* An alert component to show below the header.
|
||||
* Attributes for an alert component to show below the header.
|
||||
*
|
||||
* @type {Alert}
|
||||
* @type {object}
|
||||
*/
|
||||
this.alert = null;
|
||||
this.alertAttrs = null;
|
||||
}
|
||||
|
||||
view() {
|
||||
if (this.alert) {
|
||||
this.alert.props.dismissible = false;
|
||||
if (this.alertAttrs) {
|
||||
this.alertAttrs.dismissible = false;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -43,7 +43,7 @@ export default class Modal extends Component {
|
|||
<h3 className="App-titleControl App-titleControl--text">{this.title()}</h3>
|
||||
</div>
|
||||
|
||||
{alert ? <div className="Modal-alert">{this.alert}</div> : ''}
|
||||
{this.alertAttrs ? <div className="Modal-alert">{Alert.component(this.alertAttrs)}</div> : ''}
|
||||
|
||||
{this.content()}
|
||||
</form>
|
||||
|
@ -123,7 +123,7 @@ export default class Modal extends Component {
|
|||
* @param {RequestError} error
|
||||
*/
|
||||
onerror(error) {
|
||||
this.alert = error.alert;
|
||||
this.alertAttrs = error.alert;
|
||||
|
||||
m.redraw();
|
||||
|
||||
|
|
50
framework/core/js/src/common/states/AlertManagerState.js
Normal file
50
framework/core/js/src/common/states/AlertManagerState.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import Alert from '../components/Alert';
|
||||
|
||||
export default class AlertManagerState {
|
||||
constructor() {
|
||||
this.activeAlerts = {};
|
||||
this.alertId = 0;
|
||||
}
|
||||
|
||||
getActiveAlerts() {
|
||||
return this.activeAlerts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an Alert in the alerts area.
|
||||
*/
|
||||
show(attrs, componentClass = Alert) {
|
||||
// Breaking Change Compliance Warning, Remove in Beta 15.
|
||||
// This is applied to the first argument (attrs) because previously, the alert was passed as the first argument.
|
||||
if (attrs === Alert || attrs instanceof Alert) {
|
||||
// This is duplicated so that if the error is caught, an error message still shows up in the debug console.
|
||||
console.error('The AlertManager can only show Alerts. Whichever extension triggered this alert should be updated to comply with beta 14.');
|
||||
throw new Error('The AlertManager can only show Alerts. Whichever extension triggered this alert should be updated to comply with beta 14.');
|
||||
}
|
||||
// End Change Compliance Warning, Remove in Beta 15
|
||||
this.activeAlerts[++this.alertId] = { attrs, componentClass };
|
||||
m.redraw();
|
||||
|
||||
return this.alertId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss an alert.
|
||||
*/
|
||||
dismiss(key) {
|
||||
if (!key || !(key in this.activeAlerts)) return;
|
||||
|
||||
delete this.activeAlerts[key];
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all alerts.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
clear() {
|
||||
this.activeAlerts = {};
|
||||
m.redraw();
|
||||
}
|
||||
}
|
|
@ -122,7 +122,7 @@ export default class ChangeEmailModal extends Modal {
|
|||
|
||||
onerror(error) {
|
||||
if (error.status === 401) {
|
||||
error.alert.props.children = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
||||
error.alert.children = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
||||
}
|
||||
|
||||
super.onerror(error);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import ComposerBody from './ComposerBody';
|
||||
import Alert from '../../common/components/Alert';
|
||||
import Button from '../../common/components/Button';
|
||||
import icon from '../../common/helpers/icon';
|
||||
|
||||
|
@ -101,13 +100,11 @@ export default class EditPostComposer extends ComposerBody {
|
|||
app.alerts.dismiss(alert);
|
||||
},
|
||||
});
|
||||
app.alerts.show(
|
||||
(alert = new Alert({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.forum.composer_edit.edited_message'),
|
||||
controls: [viewButton],
|
||||
}))
|
||||
);
|
||||
alert = app.alerts.show({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.forum.composer_edit.edited_message'),
|
||||
controls: [viewButton],
|
||||
});
|
||||
}
|
||||
|
||||
app.composer.hide();
|
||||
|
|
|
@ -104,7 +104,7 @@ export default class ForgotPasswordModal extends Modal {
|
|||
|
||||
onerror(error) {
|
||||
if (error.status === 404) {
|
||||
error.alert.props.children = app.translator.trans('core.forum.forgot_password.not_found_message');
|
||||
error.alert.children = app.translator.trans('core.forum.forgot_password.not_found_message');
|
||||
}
|
||||
|
||||
super.onerror(error);
|
||||
|
|
|
@ -179,7 +179,7 @@ export default class LogInModal extends Modal {
|
|||
|
||||
onerror(error) {
|
||||
if (error.status === 401) {
|
||||
error.alert.props.children = app.translator.trans('core.forum.log_in.invalid_login_message');
|
||||
error.alert.children = app.translator.trans('core.forum.log_in.invalid_login_message');
|
||||
}
|
||||
|
||||
super.onerror(error);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import ComposerBody from './ComposerBody';
|
||||
import Alert from '../../common/components/Alert';
|
||||
import Button from '../../common/components/Button';
|
||||
import icon from '../../common/helpers/icon';
|
||||
import extractText from '../../common/utils/extractText';
|
||||
|
@ -104,13 +103,11 @@ export default class ReplyComposer extends ComposerBody {
|
|||
app.alerts.dismiss(alert);
|
||||
},
|
||||
});
|
||||
app.alerts.show(
|
||||
(alert = new Alert({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.forum.composer_reply.posted_message'),
|
||||
controls: [viewButton],
|
||||
}))
|
||||
);
|
||||
alert = app.alerts.show({
|
||||
type: 'success',
|
||||
children: app.translator.trans('core.forum.composer_reply.posted_message'),
|
||||
controls: [viewButton],
|
||||
});
|
||||
}
|
||||
|
||||
app.composer.hide();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import Alert from '../../common/components/Alert';
|
||||
import Button from '../../common/components/Button';
|
||||
import Separator from '../../common/components/Separator';
|
||||
import EditUserModal from '../components/EditUserModal';
|
||||
|
@ -134,12 +133,10 @@ export default {
|
|||
error: 'core.forum.user_controls.delete_error_message',
|
||||
}[type];
|
||||
|
||||
app.alerts.show(
|
||||
new Alert({
|
||||
type,
|
||||
children: app.translator.trans(message, { username, email }),
|
||||
})
|
||||
);
|
||||
app.alerts.show({
|
||||
type,
|
||||
children: app.translator.trans(message, { username, email }),
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user