1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 23:47:32 +02:00

chore: extract FormModal from Modal (#3922)

This commit is contained in:
Sami Mazouz
2023-11-10 22:59:34 +01:00
committed by GitHub
parent 9ef366493c
commit eaabeab8c9
22 changed files with 127 additions and 94 deletions

View File

@@ -1,5 +1,5 @@
import app from 'flarum/forum/app'; import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal'; import FormModal from 'flarum/common/components/FormModal';
import Form from 'flarum/common/components/Form'; import Form from 'flarum/common/components/Form';
import Button from 'flarum/common/components/Button'; import Button from 'flarum/common/components/Button';
@@ -7,7 +7,7 @@ import Stream from 'flarum/common/utils/Stream';
import withAttr from 'flarum/common/utils/withAttr'; import withAttr from 'flarum/common/utils/withAttr';
import ItemList from 'flarum/common/utils/ItemList'; import ItemList from 'flarum/common/utils/ItemList';
export default class FlagPostModal extends Modal { export default class FlagPostModal extends FormModal {
oninit(vnode) { oninit(vnode) {
super.oninit(vnode); super.oninit(vnode);

View File

@@ -1,10 +1,10 @@
import app from 'flarum/forum/app'; import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal'; import FormModal from 'flarum/common/components/FormModal';
import Button from 'flarum/common/components/Button'; import Button from 'flarum/common/components/Button';
import Stream from 'flarum/common/utils/Stream'; import Stream from 'flarum/common/utils/Stream';
import Form from '@flarum/core/src/common/components/Form'; import Form from '@flarum/core/src/common/components/Form';
export default class NicknameModal extends Modal { export default class NicknameModal extends FormModal {
oninit(vnode) { oninit(vnode) {
super.oninit(vnode); super.oninit(vnode);
this.nickname = Stream(app.session.user.displayName()); this.nickname = Stream(app.session.user.displayName());

View File

@@ -1,7 +1,7 @@
import app from 'flarum/admin/app'; import app from 'flarum/admin/app';
import ItemList from 'flarum/common/utils/ItemList'; import ItemList from 'flarum/common/utils/ItemList';
import generateElementId from 'flarum/admin/utils/generateElementId'; import generateElementId from 'flarum/admin/utils/generateElementId';
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal'; import FormModal, { IFormModalAttrs } from 'flarum/common/components/FormModal';
import Mithril from 'mithril'; import Mithril from 'mithril';
import Button from 'flarum/common/components/Button'; import Button from 'flarum/common/components/Button';
@@ -22,7 +22,7 @@ export interface IDateSelection {
end: number; end: number;
} }
export interface IStatisticsWidgetDateSelectionModalAttrs extends IInternalModalAttrs { export interface IStatisticsWidgetDateSelectionModalAttrs extends IFormModalAttrs {
onModalSubmit: (dates: IDateSelection) => void; onModalSubmit: (dates: IDateSelection) => void;
value?: IDateSelection; value?: IDateSelection;
} }
@@ -38,7 +38,7 @@ interface IStatisticsWidgetDateSelectionModalState {
}; };
} }
export default class StatisticsWidgetDateSelectionModal extends Modal<IStatisticsWidgetDateSelectionModalAttrs> { export default class StatisticsWidgetDateSelectionModal extends FormModal<IStatisticsWidgetDateSelectionModalAttrs> {
/* @ts-expect-error core typings don't allow us to set the type of the state attr :( */ /* @ts-expect-error core typings don't allow us to set the type of the state attr :( */
state: IStatisticsWidgetDateSelectionModalState = { state: IStatisticsWidgetDateSelectionModalState = {
inputs: { inputs: {

View File

@@ -1,5 +1,5 @@
import app from 'flarum/forum/app'; import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal'; import FormModal from 'flarum/common/components/FormModal';
import Button from 'flarum/common/components/Button'; import Button from 'flarum/common/components/Button';
import Stream from 'flarum/common/utils/Stream'; import Stream from 'flarum/common/utils/Stream';
import withAttr from 'flarum/common/utils/withAttr'; import withAttr from 'flarum/common/utils/withAttr';
@@ -9,7 +9,7 @@ import { getPermanentSuspensionDate } from '../helpers/suspensionHelper';
import Form from '@flarum/core/src/common/components/Form'; import Form from '@flarum/core/src/common/components/Form';
import FieldSet from '@flarum/core/src/common/components/FieldSet'; import FieldSet from '@flarum/core/src/common/components/FieldSet';
export default class SuspendUserModal extends Modal { export default class SuspendUserModal extends FormModal {
oninit(vnode) { oninit(vnode) {
super.oninit(vnode); super.oninit(vnode);

View File

@@ -1,5 +1,5 @@
import app from 'flarum/admin/app'; import app from 'flarum/admin/app';
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal'; import FormModal, { IFormModalAttrs } from 'flarum/common/components/FormModal';
import Button from 'flarum/common/components/Button'; import Button from 'flarum/common/components/Button';
import ColorPreviewInput from 'flarum/common/components/ColorPreviewInput'; import ColorPreviewInput from 'flarum/common/components/ColorPreviewInput';
import ItemList from 'flarum/common/utils/ItemList'; import ItemList from 'flarum/common/utils/ItemList';
@@ -12,7 +12,7 @@ import type Mithril from 'mithril';
import tagLabel from '../../common/helpers/tagLabel'; import tagLabel from '../../common/helpers/tagLabel';
import type Tag from '../../common/models/Tag'; import type Tag from '../../common/models/Tag';
export interface EditTagModalAttrs extends IInternalModalAttrs { export interface EditTagModalAttrs extends IFormModalAttrs {
primary?: boolean; primary?: boolean;
model?: Tag; model?: Tag;
} }
@@ -21,7 +21,7 @@ export interface EditTagModalAttrs extends IInternalModalAttrs {
* The `EditTagModal` component shows a modal dialog which allows the user * The `EditTagModal` component shows a modal dialog which allows the user
* to create or edit a tag. * to create or edit a tag.
*/ */
export default class EditTagModal extends Modal<EditTagModalAttrs> { export default class EditTagModal extends FormModal<EditTagModalAttrs> {
tag!: Tag; tag!: Tag;
name!: Stream<string>; name!: Stream<string>;

View File

@@ -5,7 +5,7 @@ import extractText from 'flarum/common/utils/extractText';
import highlight from 'flarum/common/helpers/highlight'; import highlight from 'flarum/common/helpers/highlight';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable'; import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import Modal from 'flarum/common/components/Modal'; import FormModal from 'flarum/common/components/FormModal';
import Stream from 'flarum/common/utils/Stream'; import Stream from 'flarum/common/utils/Stream';
import sortTags from '../utils/sortTags'; import sortTags from '../utils/sortTags';
@@ -14,7 +14,7 @@ import tagIcon from '../helpers/tagIcon';
import ToggleButton from '../../forum/components/ToggleButton'; import ToggleButton from '../../forum/components/ToggleButton';
import type Tag from '../models/Tag'; import type Tag from '../models/Tag';
import type { IInternalModalAttrs } from 'flarum/common/components/Modal'; import type { IFormModalAttrs } from 'flarum/common/components/FormModal';
import type Mithril from 'mithril'; import type Mithril from 'mithril';
export interface ITagSelectionModalLimits { export interface ITagSelectionModalLimits {
@@ -34,7 +34,7 @@ export interface ITagSelectionModalLimits {
}; };
} }
export interface ITagSelectionModalAttrs extends IInternalModalAttrs { export interface ITagSelectionModalAttrs extends IFormModalAttrs {
/** Custom modal className to use. */ /** Custom modal className to use. */
className?: string; className?: string;
/** Modal title, defaults to 'Choose Tags'. */ /** Modal title, defaults to 'Choose Tags'. */
@@ -64,7 +64,7 @@ export type ITagSelectionModalState = undefined;
export default class TagSelectionModal< export default class TagSelectionModal<
CustomAttrs extends ITagSelectionModalAttrs = ITagSelectionModalAttrs, CustomAttrs extends ITagSelectionModalAttrs = ITagSelectionModalAttrs,
CustomState extends ITagSelectionModalState = ITagSelectionModalState CustomState extends ITagSelectionModalState = ITagSelectionModalState
> extends Modal<CustomAttrs, CustomState> { > extends FormModal<CustomAttrs, CustomState> {
protected loading = true; protected loading = true;
protected tags!: Tag[]; protected tags!: Tag[];
protected selected: Tag[] = []; protected selected: Tag[] = [];
@@ -108,7 +108,7 @@ export default class TagSelectionModal<
.onSelect(this.select.bind(this)) .onSelect(this.select.bind(this))
.onRemove(() => this.selected.splice(this.selected.length - 1, 1)); .onRemove(() => this.selected.splice(this.selected.length - 1, 1));
app.tagList.load(['parent']).then((tags) => { app.tagList.load(['parent']).then((tags: Tag[]) => {
this.loading = false; this.loading = false;
if (this.attrs.selectableTags) { if (this.attrs.selectableTags) {

View File

@@ -21,7 +21,7 @@ export default class TagListState {
async query(includes: string[] = []): Promise<Tag[]> { async query(includes: string[] = []): Promise<Tag[]> {
this.loadedIncludes ??= new Set(); this.loadedIncludes ??= new Set();
return app.store.find<Tag[]>('tags', { include: includes.join(',') }).then((val) => { return app.store.find<Tag[]>('tags', { include: includes.join(',') }).then((val: Tag) => {
includes.forEach((include) => this.loadedIncludes!.add(include)); includes.forEach((include) => this.loadedIncludes!.add(include));
return val; return val;
}); });

View File

@@ -1,5 +1,5 @@
import app from '../../admin/app'; import app from '../../admin/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import extractText from '../../common/utils/extractText'; import extractText from '../../common/utils/extractText';
import ItemList from '../../common/utils/ItemList'; import ItemList from '../../common/utils/ItemList';
@@ -9,7 +9,7 @@ import Switch from '../../common/components/Switch';
import { generateRandomString } from '../../common/utils/string'; import { generateRandomString } from '../../common/utils/string';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface ICreateUserModalAttrs extends IInternalModalAttrs { export interface ICreateUserModalAttrs extends IFormModalAttrs {
username?: string; username?: string;
email?: string; email?: string;
password?: string; password?: string;
@@ -24,7 +24,7 @@ export type SignupBody = {
password: string; password: string;
}; };
export default class CreateUserModal<CustomAttrs extends ICreateUserModalAttrs = ICreateUserModalAttrs> extends Modal<CustomAttrs> { export default class CreateUserModal<CustomAttrs extends ICreateUserModalAttrs = ICreateUserModalAttrs> extends FormModal<CustomAttrs> {
/** /**
* The value of the username input. * The value of the username input.
*/ */

View File

@@ -1,5 +1,5 @@
import app from '../../admin/app'; import app from '../../admin/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
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';
@@ -11,7 +11,7 @@ import extractText from '../../common/utils/extractText';
import ColorPreviewInput from '../../common/components/ColorPreviewInput'; import ColorPreviewInput from '../../common/components/ColorPreviewInput';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface IEditGroupModalAttrs extends IInternalModalAttrs { export interface IEditGroupModalAttrs extends IFormModalAttrs {
group?: Group; group?: Group;
} }
@@ -19,7 +19,7 @@ export interface IEditGroupModalAttrs extends IInternalModalAttrs {
* 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<CustomAttrs extends IEditGroupModalAttrs = IEditGroupModalAttrs> extends Modal<CustomAttrs> { export default class EditGroupModal<CustomAttrs extends IEditGroupModalAttrs = IEditGroupModalAttrs> extends FormModal<CustomAttrs> {
group!: Group; group!: Group;
nameSingular!: Stream<string>; nameSingular!: Stream<string>;
namePlural!: Stream<string>; namePlural!: Stream<string>;

View File

@@ -19,8 +19,4 @@ export default class LoadingModal<ModalAttrs extends ILoadingModalAttrs = ILoadi
content() { content() {
return null; return null;
} }
onsubmit(e: Event): void {
throw new Error('LoadingModal should not throw errors.');
}
} }

View File

@@ -1,5 +1,5 @@
import app from '../../admin/app'; import app from '../../admin/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
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';
@@ -7,9 +7,9 @@ import Mithril from 'mithril';
import { MutableSettings, SettingValue } from './AdminPage'; import { MutableSettings, SettingValue } from './AdminPage';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface ISettingsModalAttrs extends IInternalModalAttrs {} export interface ISettingsModalAttrs extends IFormModalAttrs {}
export default abstract class SettingsModal<CustomAttrs extends ISettingsModalAttrs = ISettingsModalAttrs> extends Modal<CustomAttrs> { export default abstract class SettingsModal<CustomAttrs extends ISettingsModalAttrs = ISettingsModalAttrs> extends FormModal<CustomAttrs> {
settings: MutableSettings = {}; settings: MutableSettings = {};
loading: boolean = false; loading: boolean = false;

View File

@@ -65,6 +65,7 @@ import './components/SelectDropdown';
import './components/ModalManager'; import './components/ModalManager';
import './components/Button'; import './components/Button';
import './components/Modal'; import './components/Modal';
import './components/FormModal';
import './components/GroupBadge'; import './components/GroupBadge';
import './components/TextEditor'; import './components/TextEditor';
import './components/TextEditorButton'; import './components/TextEditorButton';

View File

@@ -1,5 +1,5 @@
import app from '../../common/app'; import app from '../../common/app';
import Modal, { IInternalModalAttrs } from './Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from './Button'; import Button from './Button';
import GroupBadge from './GroupBadge'; import GroupBadge from './GroupBadge';
import Group from '../models/Group'; import Group from '../models/Group';
@@ -11,11 +11,11 @@ import type User from '../models/User';
import type { SaveAttributes, SaveRelationships } from '../Model'; import type { SaveAttributes, SaveRelationships } from '../Model';
import Form from './Form'; import Form from './Form';
export interface IEditUserModalAttrs extends IInternalModalAttrs { export interface IEditUserModalAttrs extends IFormModalAttrs {
user: User; user: User;
} }
export default class EditUserModal<CustomAttrs extends IEditUserModalAttrs = IEditUserModalAttrs> extends Modal<CustomAttrs> { export default class EditUserModal<CustomAttrs extends IEditUserModalAttrs = IEditUserModalAttrs> extends FormModal<CustomAttrs> {
protected username!: Stream<string>; protected username!: Stream<string>;
protected email!: Stream<string>; protected email!: Stream<string>;
protected isEmailConfirmed!: Stream<boolean>; protected isEmailConfirmed!: Stream<boolean>;

View File

@@ -0,0 +1,51 @@
import Modal from './Modal';
import type { IInternalModalAttrs } from './Modal';
import RequestError from '../utils/RequestError';
import Mithril from 'mithril';
export interface IFormModalAttrs extends IInternalModalAttrs {}
/**
* The `FormModal` component displays a modal dialog, wrapped in a form.
* Subclasses should implement the `className`, `title`, and `content` methods.
*/
export default abstract class FormModal<ModalAttrs extends IFormModalAttrs = IFormModalAttrs, CustomState = undefined> extends Modal<
ModalAttrs,
CustomState
> {
wrapper(children: Mithril.Children): Mithril.Children {
return <form onsubmit={this.onsubmit.bind(this)}>{children}</form>;
}
/**
* Handle the modal form's submit event.
*/
onsubmit(e: SubmitEvent): void {
// ...
}
/**
* Callback executed when the modal is shown and ready to be interacted with.
*
* @remark Focuses the first input in the modal.
*/
onready(): void {
this.$().find('input, select, textarea').first().trigger('focus').trigger('select');
}
/**
* Shows an alert describing an error returned from the API, and gives focus to
* the first relevant field involved in the error.
*/
onerror(error: RequestError): void {
this.alertAttrs = error.alert;
m.redraw();
if (error.status === 422 && error.response?.errors) {
this.$('form [name=' + (error.response.errors as any[])[0].source.pointer.replace('/data/attributes/', '') + ']').trigger('select');
} else {
this.onready();
}
}
}

View File

@@ -5,7 +5,6 @@ import Button from './Button';
import type Mithril from 'mithril'; import type Mithril from 'mithril';
import type ModalManagerState from '../states/ModalManagerState'; import type ModalManagerState from '../states/ModalManagerState';
import type RequestError from '../utils/RequestError';
import type ModalManager from './ModalManager'; import type ModalManager from './ModalManager';
import fireDebugWarning from '../helpers/fireDebugWarning'; import fireDebugWarning from '../helpers/fireDebugWarning';
import classList from '../utils/classList'; import classList from '../utils/classList';
@@ -101,25 +100,34 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
/> />
</div> </div>
)} )}
{this.wrapper(this.inner())}
<form onsubmit={this.onsubmit.bind(this)}>
<div className="Modal-header">
<h3 className="App-titleControl App-titleControl--text">{this.title()}</h3>
</div>
{!!this.alertAttrs && (
<div className="Modal-alert">
<Alert {...this.alertAttrs} />
</div>
)}
{this.content()}
</form>
</div> </div>
</div> </div>
); );
} }
protected wrapper(children: Mithril.Children): Mithril.Children {
return <>{children}</>;
}
protected inner(): Mithril.Children {
return (
<>
<div className="Modal-header">
<h3 className="App-titleControl App-titleControl--text">{this.title()}</h3>
</div>
{!!this.alertAttrs && (
<div className="Modal-alert">
<Alert {...this.alertAttrs} />
</div>
)}
{this.content()}
</>
);
}
/** /**
* Get the class name to apply to the modal. * Get the class name to apply to the modal.
*/ */
@@ -135,20 +143,11 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
*/ */
abstract content(): Mithril.Children; abstract content(): Mithril.Children;
/**
* Handle the modal form's submit event.
*/
onsubmit(e: SubmitEvent): void {
// ...
}
/** /**
* Callback executed when the modal is shown and ready to be interacted with. * Callback executed when the modal is shown and ready to be interacted with.
*
* @remark Focuses the first input in the modal.
*/ */
onready(): void { onready(): void {
this.$().find('input, select, textarea').first().trigger('focus').trigger('select'); // ...
} }
/** /**
@@ -166,22 +165,6 @@ export default abstract class Modal<ModalAttrs extends IInternalModalAttrs = IIn
m.redraw(); m.redraw();
} }
/**
* Shows an alert describing an error returned from the API, and gives focus to
* the first relevant field involved in the error.
*/
onerror(error: RequestError): void {
this.alertAttrs = error.alert;
m.redraw();
if (error.status === 422 && error.response?.errors) {
this.$('form [name=' + (error.response.errors as any[])[0].source.pointer.replace('/data/attributes/', '') + ']').trigger('select');
} else {
this.onready();
}
}
private get dismissibleOptions(): IDismissibleOptions { private get dismissibleOptions(): IDismissibleOptions {
return (this.constructor as typeof Modal).dismissibleOptions; return (this.constructor as typeof Modal).dismissibleOptions;
} }

View File

@@ -1,5 +1,5 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
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 type Mithril from 'mithril'; import type Mithril from 'mithril';
@@ -11,7 +11,7 @@ import Form from '../../common/components/Form';
* 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<CustomAttrs extends IInternalModalAttrs = IInternalModalAttrs> extends Modal<CustomAttrs> { export default class ChangeEmailModal<CustomAttrs extends IFormModalAttrs = IFormModalAttrs> extends FormModal<CustomAttrs> {
/** /**
* The value of the email input. * The value of the email input.
*/ */

View File

@@ -1,5 +1,5 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import Mithril from 'mithril'; import Mithril from 'mithril';
import ItemList from '../../common/utils/ItemList'; import ItemList from '../../common/utils/ItemList';
@@ -9,7 +9,7 @@ import Form from '../../common/components/Form';
* 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<CustomAttrs extends IInternalModalAttrs = IInternalModalAttrs> extends Modal<CustomAttrs> { export default class ChangePasswordModal<CustomAttrs extends IFormModalAttrs = IFormModalAttrs> extends FormModal<CustomAttrs> {
className() { className() {
return 'ChangePasswordModal Modal--small'; return 'ChangePasswordModal Modal--small';
} }

View File

@@ -1,5 +1,5 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import extractText from '../../common/utils/extractText'; import extractText from '../../common/utils/extractText';
import Stream from '../../common/utils/Stream'; import Stream from '../../common/utils/Stream';
@@ -8,7 +8,7 @@ import RequestError from '../../common/utils/RequestError';
import ItemList from '../../common/utils/ItemList'; import ItemList from '../../common/utils/ItemList';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface IForgotPasswordModalAttrs extends IInternalModalAttrs { export interface IForgotPasswordModalAttrs extends IFormModalAttrs {
email?: string; email?: string;
} }
@@ -16,7 +16,7 @@ export interface IForgotPasswordModalAttrs extends IInternalModalAttrs {
* The `ForgotPasswordModal` component displays a modal which allows the user to * The `ForgotPasswordModal` component displays a modal which allows the user to
* enter their email address and request a link to reset their password. * enter their email address and request a link to reset their password.
*/ */
export default class ForgotPasswordModal<CustomAttrs extends IForgotPasswordModalAttrs = IForgotPasswordModalAttrs> extends Modal<CustomAttrs> { export default class ForgotPasswordModal<CustomAttrs extends IForgotPasswordModalAttrs = IForgotPasswordModalAttrs> extends FormModal<CustomAttrs> {
/** /**
* The value of the email input. * The value of the email input.
*/ */

View File

@@ -1,5 +1,5 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import LogInButtons from './LogInButtons'; import LogInButtons from './LogInButtons';
import extractText from '../../common/utils/extractText'; import extractText from '../../common/utils/extractText';
@@ -9,13 +9,13 @@ import type Mithril from 'mithril';
import RequestError from '../../common/utils/RequestError'; import RequestError from '../../common/utils/RequestError';
import type { LoginParams } from '../../common/Session'; import type { LoginParams } from '../../common/Session';
export interface ILoginModalAttrs extends IInternalModalAttrs { export interface ILoginModalAttrs extends IFormModalAttrs {
identification?: string; identification?: string;
password?: string; password?: string;
remember?: boolean; remember?: boolean;
} }
export default class LogInModal<CustomAttrs extends ILoginModalAttrs = ILoginModalAttrs> extends Modal<CustomAttrs> { export default class LogInModal<CustomAttrs extends ILoginModalAttrs = ILoginModalAttrs> extends FormModal<CustomAttrs> {
/** /**
* The value of the identification input. * The value of the identification input.
*/ */

View File

@@ -1,5 +1,5 @@
import app from '../app'; import app from '../app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
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 type AccessToken from '../../common/models/AccessToken'; import type AccessToken from '../../common/models/AccessToken';
@@ -7,11 +7,11 @@ import type { SaveAttributes } from '../../common/Model';
import type Mithril from 'mithril'; import type Mithril from 'mithril';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface INewAccessTokenModalAttrs extends IInternalModalAttrs { export interface INewAccessTokenModalAttrs extends IFormModalAttrs {
onsuccess: (token: AccessToken) => void; onsuccess: (token: AccessToken) => void;
} }
export default class NewAccessTokenModal<CustomAttrs extends INewAccessTokenModalAttrs = INewAccessTokenModalAttrs> extends Modal<CustomAttrs> { export default class NewAccessTokenModal<CustomAttrs extends INewAccessTokenModalAttrs = INewAccessTokenModalAttrs> extends FormModal<CustomAttrs> {
protected titleInput = Stream(''); protected titleInput = Stream('');
className(): string { className(): string {

View File

@@ -1,12 +1,12 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
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 Mithril from 'mithril';
import Discussion from '../../common/models/Discussion'; import Discussion from '../../common/models/Discussion';
import Form from '../../common/components/Form'; import Form from '../../common/components/Form';
export interface IRenameDiscussionModalAttrs extends IInternalModalAttrs { export interface IRenameDiscussionModalAttrs extends IFormModalAttrs {
discussion: Discussion; discussion: Discussion;
currentTitle: string; currentTitle: string;
} }
@@ -14,7 +14,9 @@ export interface IRenameDiscussionModalAttrs extends IInternalModalAttrs {
/** /**
* 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<CustomAttrs extends IRenameDiscussionModalAttrs = IRenameDiscussionModalAttrs> extends Modal<CustomAttrs> { export default class RenameDiscussionModal<
CustomAttrs extends IRenameDiscussionModalAttrs = IRenameDiscussionModalAttrs
> extends FormModal<CustomAttrs> {
discussion!: Discussion; discussion!: Discussion;
currentTitle!: string; currentTitle!: string;
newTitle!: Stream<string>; newTitle!: Stream<string>;

View File

@@ -1,5 +1,5 @@
import app from '../../forum/app'; import app from '../../forum/app';
import Modal, { IInternalModalAttrs } from '../../common/components/Modal'; import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import LogInButtons from './LogInButtons'; import LogInButtons from './LogInButtons';
import extractText from '../../common/utils/extractText'; import extractText from '../../common/utils/extractText';
@@ -7,7 +7,7 @@ import ItemList from '../../common/utils/ItemList';
import Stream from '../../common/utils/Stream'; import Stream from '../../common/utils/Stream';
import type Mithril from 'mithril'; import type Mithril from 'mithril';
export interface ISignupModalAttrs extends IInternalModalAttrs { export interface ISignupModalAttrs extends IFormModalAttrs {
username?: string; username?: string;
email?: string; email?: string;
password?: string; password?: string;
@@ -20,7 +20,7 @@ export type SignupBody = {
email: string; email: string;
} & ({ token: string } | { password: string }); } & ({ token: string } | { password: string });
export default class SignUpModal<CustomAttrs extends ISignupModalAttrs = ISignupModalAttrs> extends Modal<CustomAttrs> { export default class SignUpModal<CustomAttrs extends ISignupModalAttrs = ISignupModalAttrs> extends FormModal<CustomAttrs> {
/** /**
* The value of the username input. * The value of the username input.
*/ */