mirror of
https://github.com/flarum/framework.git
synced 2025-04-28 07:34:03 +08:00
refactor: convert core modals to TypeScript (#3515)
* refactor: convert core modals to TypeScript * chore: excplicitly specify return type instead * chore: `yarn format` Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
This commit is contained in:
parent
d86440506d
commit
1af506d4b8
@ -134,8 +134,11 @@ export type SettingsComponentOptions =
|
|||||||
*/
|
*/
|
||||||
export type AdminHeaderAttrs = AdminHeaderOptions & Partial<Omit<Mithril.Attributes, 'class'>>;
|
export type AdminHeaderAttrs = AdminHeaderOptions & Partial<Omit<Mithril.Attributes, 'class'>>;
|
||||||
|
|
||||||
|
export type SettingValue = string;
|
||||||
|
export type MutableSettings = Record<string, Stream<SettingValue>>;
|
||||||
|
|
||||||
export default abstract class AdminPage<CustomAttrs extends IPageAttrs = IPageAttrs> extends Page<CustomAttrs> {
|
export default abstract class AdminPage<CustomAttrs extends IPageAttrs = IPageAttrs> extends Page<CustomAttrs> {
|
||||||
settings: Record<string, Stream<string>> = {};
|
settings: MutableSettings = {};
|
||||||
loading: boolean = false;
|
loading: boolean = false;
|
||||||
|
|
||||||
view(vnode: Mithril.Vnode<CustomAttrs, this>): Mithril.Children {
|
view(vnode: Mithril.Vnode<CustomAttrs, this>): Mithril.Children {
|
||||||
|
@ -1,18 +1,31 @@
|
|||||||
import app from '../../admin/app';
|
import app from '../../admin/app';
|
||||||
import Modal from '../../common/components/Modal';
|
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
import Badge from '../../common/components/Badge';
|
import Badge from '../../common/components/Badge';
|
||||||
import Group from '../../common/models/Group';
|
import Group from '../../common/models/Group';
|
||||||
import ItemList from '../../common/utils/ItemList';
|
import ItemList from '../../common/utils/ItemList';
|
||||||
import Switch from '../../common/components/Switch';
|
import Switch from '../../common/components/Switch';
|
||||||
import Stream from '../../common/utils/Stream';
|
import Stream from '../../common/utils/Stream';
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
import extractText from '../../common/utils/extractText';
|
||||||
|
|
||||||
|
export interface IEditGroupModalAttrs extends IInternalModalAttrs {
|
||||||
|
group?: Group;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `EditGroupModal` component shows a modal dialog which allows the user
|
* The `EditGroupModal` component shows a modal dialog which allows the user
|
||||||
* to create or edit a group.
|
* to create or edit a group.
|
||||||
*/
|
*/
|
||||||
export default class EditGroupModal extends Modal {
|
export default class EditGroupModal<CustomAttrs extends IEditGroupModalAttrs = IEditGroupModalAttrs> extends Modal<CustomAttrs> {
|
||||||
oninit(vnode) {
|
group!: Group;
|
||||||
|
nameSingular!: Stream<string>;
|
||||||
|
namePlural!: Stream<string>;
|
||||||
|
icon!: Stream<string>;
|
||||||
|
color!: Stream<string>;
|
||||||
|
isHidden!: Stream<boolean>;
|
||||||
|
|
||||||
|
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||||
super.oninit(vnode);
|
super.oninit(vnode);
|
||||||
|
|
||||||
this.group = this.attrs.group || app.store.createRecord('groups');
|
this.group = this.attrs.group || app.store.createRecord('groups');
|
||||||
@ -134,7 +147,7 @@ export default class EditGroupModal extends Modal {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e: SubmitEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
@ -149,7 +162,7 @@ export default class EditGroupModal extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteGroup() {
|
deleteGroup() {
|
||||||
if (confirm(app.translator.trans('core.admin.edit_group.delete_confirmation'))) {
|
if (confirm(extractText(app.translator.trans('core.admin.edit_group.delete_confirmation')))) {
|
||||||
this.group.delete().then(() => m.redraw());
|
this.group.delete().then(() => m.redraw());
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
@ -1,18 +1,18 @@
|
|||||||
import app from '../../admin/app';
|
import app from '../../admin/app';
|
||||||
import Modal from '../../common/components/Modal';
|
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
import Stream from '../../common/utils/Stream';
|
import Stream from '../../common/utils/Stream';
|
||||||
import saveSettings from '../utils/saveSettings';
|
import saveSettings from '../utils/saveSettings';
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
import { MutableSettings, SettingValue } from './AdminPage';
|
||||||
|
|
||||||
export default class SettingsModal extends Modal {
|
export interface ISettingsModalAttrs extends IInternalModalAttrs {}
|
||||||
oninit(vnode) {
|
|
||||||
super.oninit(vnode);
|
|
||||||
|
|
||||||
this.settings = {};
|
export default abstract class SettingsModal<CustomAttrs extends ISettingsModalAttrs = ISettingsModalAttrs> extends Modal<CustomAttrs> {
|
||||||
this.loading = false;
|
settings: MutableSettings = {};
|
||||||
}
|
loading: boolean = false;
|
||||||
|
|
||||||
form() {
|
form(): Mithril.Children {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ export default class SettingsModal extends Modal {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
submitButton() {
|
submitButton(): Mithril.Children {
|
||||||
return (
|
return (
|
||||||
<Button type="submit" className="Button Button--primary" loading={this.loading} disabled={!this.changed()}>
|
<Button type="submit" className="Button Button--primary" loading={this.loading} disabled={!this.changed()}>
|
||||||
{app.translator.trans('core.admin.settings.submit_button')}
|
{app.translator.trans('core.admin.settings.submit_button')}
|
||||||
@ -36,14 +36,14 @@ export default class SettingsModal extends Modal {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setting(key, fallback = '') {
|
setting(key: string, fallback: string = ''): Stream<SettingValue> {
|
||||||
this.settings[key] = this.settings[key] || Stream(app.data.settings[key] || fallback);
|
this.settings[key] = this.settings[key] || Stream(app.data.settings[key] || fallback);
|
||||||
|
|
||||||
return this.settings[key];
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty() {
|
dirty() {
|
||||||
const dirty = {};
|
const dirty: Record<string, SettingValue> = {};
|
||||||
|
|
||||||
Object.keys(this.settings).forEach((key) => {
|
Object.keys(this.settings).forEach((key) => {
|
||||||
const value = this.settings[key]();
|
const value = this.settings[key]();
|
||||||
@ -60,7 +60,7 @@ export default class SettingsModal extends Modal {
|
|||||||
return Object.keys(this.dirty()).length;
|
return Object.keys(this.dirty()).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e: SubmitEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
@ -1,35 +1,34 @@
|
|||||||
import app from '../../forum/app';
|
import app from '../../forum/app';
|
||||||
import Modal from '../../common/components/Modal';
|
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
import Stream from '../../common/utils/Stream';
|
import Stream from '../../common/utils/Stream';
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
import RequestError from '../../common/utils/RequestError';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `ChangeEmailModal` component shows a modal dialog which allows the user
|
* The `ChangeEmailModal` component shows a modal dialog which allows the user
|
||||||
* to change their email address.
|
* to change their email address.
|
||||||
*/
|
*/
|
||||||
export default class ChangeEmailModal extends Modal {
|
export default class ChangeEmailModal<CustomAttrs extends IInternalModalAttrs = IInternalModalAttrs> extends Modal<CustomAttrs> {
|
||||||
oninit(vnode) {
|
/**
|
||||||
|
* The value of the email input.
|
||||||
|
*/
|
||||||
|
email!: Stream<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the password input.
|
||||||
|
*/
|
||||||
|
password!: Stream<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the email has been changed successfully.
|
||||||
|
*/
|
||||||
|
success: boolean = false;
|
||||||
|
|
||||||
|
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||||
super.oninit(vnode);
|
super.oninit(vnode);
|
||||||
|
|
||||||
/**
|
this.email = Stream(app.session.user!.email() || '');
|
||||||
* Whether or not the email has been changed successfully.
|
|
||||||
*
|
|
||||||
* @type {Boolean}
|
|
||||||
*/
|
|
||||||
this.success = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the email input.
|
|
||||||
*
|
|
||||||
* @type {function}
|
|
||||||
*/
|
|
||||||
this.email = Stream(app.session.user.email());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the password input.
|
|
||||||
*
|
|
||||||
* @type {function}
|
|
||||||
*/
|
|
||||||
this.password = Stream('');
|
this.password = Stream('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +66,7 @@ export default class ChangeEmailModal extends Modal {
|
|||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
className="FormControl"
|
className="FormControl"
|
||||||
placeholder={app.session.user.email()}
|
placeholder={app.session.user!.email()}
|
||||||
bidi={this.email}
|
bidi={this.email}
|
||||||
disabled={this.loading}
|
disabled={this.loading}
|
||||||
/>
|
/>
|
||||||
@ -98,12 +97,12 @@ export default class ChangeEmailModal extends Modal {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e: SubmitEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// If the user hasn't actually entered a different email address, we don't
|
// If the user hasn't actually entered a different email address, we don't
|
||||||
// need to do anything. Woot!
|
// need to do anything. Woot!
|
||||||
if (this.email() === app.session.user.email()) {
|
if (this.email() === app.session.user!.email()) {
|
||||||
this.hide();
|
this.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -111,8 +110,8 @@ export default class ChangeEmailModal extends Modal {
|
|||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.alertAttrs = null;
|
this.alertAttrs = null;
|
||||||
|
|
||||||
app.session.user
|
app.session
|
||||||
.save(
|
.user!.save(
|
||||||
{ email: this.email() },
|
{ email: this.email() },
|
||||||
{
|
{
|
||||||
errorHandler: this.onerror.bind(this),
|
errorHandler: this.onerror.bind(this),
|
||||||
@ -126,8 +125,8 @@ export default class ChangeEmailModal extends Modal {
|
|||||||
.then(this.loaded.bind(this));
|
.then(this.loaded.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
onerror(error) {
|
onerror(error: RequestError) {
|
||||||
if (error.status === 401) {
|
if (error.status === 401 && error.alert) {
|
||||||
error.alert.content = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
error.alert.content = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
|||||||
import app from '../../forum/app';
|
import app from '../../forum/app';
|
||||||
import Modal from '../../common/components/Modal';
|
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `ChangePasswordModal` component shows a modal dialog which allows the
|
* The `ChangePasswordModal` component shows a modal dialog which allows the
|
||||||
* user to send themself a password reset email.
|
* user to send themself a password reset email.
|
||||||
*/
|
*/
|
||||||
export default class ChangePasswordModal extends Modal {
|
export default class ChangePasswordModal<CustomAttrs extends IInternalModalAttrs = IInternalModalAttrs> extends Modal<CustomAttrs> {
|
||||||
className() {
|
className() {
|
||||||
return 'ChangePasswordModal Modal--small';
|
return 'ChangePasswordModal Modal--small';
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ export default class ChangePasswordModal extends Modal {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e: SubmitEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
@ -44,7 +44,7 @@ export default class ChangePasswordModal extends Modal {
|
|||||||
.request({
|
.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + '/forgot',
|
url: app.forum.attribute('apiUrl') + '/forgot',
|
||||||
body: { email: app.session.user.email() },
|
body: { email: app.session.user!.email() },
|
||||||
})
|
})
|
||||||
.then(this.hide.bind(this), this.loaded.bind(this));
|
.then(this.hide.bind(this), this.loaded.bind(this));
|
||||||
}
|
}
|
@ -1,13 +1,24 @@
|
|||||||
import app from '../../forum/app';
|
import app from '../../forum/app';
|
||||||
import Modal from '../../common/components/Modal';
|
import Modal, { IInternalModalAttrs } from '../../common/components/Modal';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
import Stream from '../../common/utils/Stream';
|
import Stream from '../../common/utils/Stream';
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
import Discussion from '../../common/models/Discussion';
|
||||||
|
|
||||||
|
export interface IRenameDiscussionModalAttrs extends IInternalModalAttrs {
|
||||||
|
discussion: Discussion;
|
||||||
|
currentTitle: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 'RenameDiscussionModal' displays a modal dialog with an input to rename a discussion
|
* The 'RenameDiscussionModal' displays a modal dialog with an input to rename a discussion
|
||||||
*/
|
*/
|
||||||
export default class RenameDiscussionModal extends Modal {
|
export default class RenameDiscussionModal<CustomAttrs extends IRenameDiscussionModalAttrs = IRenameDiscussionModalAttrs> extends Modal<CustomAttrs> {
|
||||||
oninit(vnode) {
|
discussion!: Discussion;
|
||||||
|
currentTitle!: string;
|
||||||
|
newTitle!: Stream<string>;
|
||||||
|
|
||||||
|
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||||
super.oninit(vnode);
|
super.oninit(vnode);
|
||||||
|
|
||||||
this.discussion = this.attrs.discussion;
|
this.discussion = this.attrs.discussion;
|
||||||
@ -45,7 +56,7 @@ export default class RenameDiscussionModal extends Modal {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onsubmit(e) {
|
onsubmit(e: SubmitEvent): Promise<void> | void {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
Loading…
x
Reference in New Issue
Block a user