From eaabeab8c922fe468209bd68a46ee5e72edd4b54 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Fri, 10 Nov 2023 22:59:34 +0100 Subject: [PATCH] chore: extract `FormModal` from `Modal` (#3922) --- .../js/src/forum/components/FlagPostModal.js | 4 +- .../js/src/forum/components/NicknameModal.js | 4 +- .../StatisticsWidgetDateSelectionModal.tsx | 6 +- .../src/forum/components/SuspendUserModal.js | 4 +- .../js/src/admin/components/EditTagModal.tsx | 6 +- .../common/components/TagSelectionModal.tsx | 10 +-- .../tags/js/src/common/states/TagListState.ts | 2 +- .../src/admin/components/CreateUserModal.tsx | 6 +- .../src/admin/components/EditGroupModal.tsx | 6 +- .../js/src/admin/components/LoadingModal.tsx | 4 -- .../js/src/admin/components/SettingsModal.tsx | 6 +- framework/core/js/src/common/common.ts | 1 + .../src/common/components/EditUserModal.tsx | 6 +- .../js/src/common/components/FormModal.tsx | 51 +++++++++++++++ .../core/js/src/common/components/Modal.tsx | 63 +++++++------------ .../src/forum/components/ChangeEmailModal.tsx | 4 +- .../forum/components/ChangePasswordModal.tsx | 4 +- .../forum/components/ForgotPasswordModal.tsx | 6 +- .../js/src/forum/components/LogInModal.tsx | 6 +- .../forum/components/NewAccessTokenModal.tsx | 6 +- .../components/RenameDiscussionModal.tsx | 8 ++- .../js/src/forum/components/SignUpModal.tsx | 6 +- 22 files changed, 126 insertions(+), 93 deletions(-) create mode 100644 framework/core/js/src/common/components/FormModal.tsx diff --git a/extensions/flags/js/src/forum/components/FlagPostModal.js b/extensions/flags/js/src/forum/components/FlagPostModal.js index 204dad1dcd..560b99ec28 100644 --- a/extensions/flags/js/src/forum/components/FlagPostModal.js +++ b/extensions/flags/js/src/forum/components/FlagPostModal.js @@ -1,5 +1,5 @@ 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 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 ItemList from 'flarum/common/utils/ItemList'; -export default class FlagPostModal extends Modal { +export default class FlagPostModal extends FormModal { oninit(vnode) { super.oninit(vnode); diff --git a/extensions/nicknames/js/src/forum/components/NicknameModal.js b/extensions/nicknames/js/src/forum/components/NicknameModal.js index cf6484e05b..2304a78bfe 100644 --- a/extensions/nicknames/js/src/forum/components/NicknameModal.js +++ b/extensions/nicknames/js/src/forum/components/NicknameModal.js @@ -1,10 +1,10 @@ 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 Stream from 'flarum/common/utils/Stream'; import Form from '@flarum/core/src/common/components/Form'; -export default class NicknameModal extends Modal { +export default class NicknameModal extends FormModal { oninit(vnode) { super.oninit(vnode); this.nickname = Stream(app.session.user.displayName()); diff --git a/extensions/statistics/js/src/admin/components/StatisticsWidgetDateSelectionModal.tsx b/extensions/statistics/js/src/admin/components/StatisticsWidgetDateSelectionModal.tsx index 060d10c63f..da4deaa900 100644 --- a/extensions/statistics/js/src/admin/components/StatisticsWidgetDateSelectionModal.tsx +++ b/extensions/statistics/js/src/admin/components/StatisticsWidgetDateSelectionModal.tsx @@ -1,7 +1,7 @@ import app from 'flarum/admin/app'; import ItemList from 'flarum/common/utils/ItemList'; 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 Button from 'flarum/common/components/Button'; @@ -22,7 +22,7 @@ export interface IDateSelection { end: number; } -export interface IStatisticsWidgetDateSelectionModalAttrs extends IInternalModalAttrs { +export interface IStatisticsWidgetDateSelectionModalAttrs extends IFormModalAttrs { onModalSubmit: (dates: IDateSelection) => void; value?: IDateSelection; } @@ -38,7 +38,7 @@ interface IStatisticsWidgetDateSelectionModalState { }; } -export default class StatisticsWidgetDateSelectionModal extends Modal { +export default class StatisticsWidgetDateSelectionModal extends FormModal { /* @ts-expect-error core typings don't allow us to set the type of the state attr :( */ state: IStatisticsWidgetDateSelectionModalState = { inputs: { diff --git a/extensions/suspend/js/src/forum/components/SuspendUserModal.js b/extensions/suspend/js/src/forum/components/SuspendUserModal.js index c581c803ef..eaeb90622e 100644 --- a/extensions/suspend/js/src/forum/components/SuspendUserModal.js +++ b/extensions/suspend/js/src/forum/components/SuspendUserModal.js @@ -1,5 +1,5 @@ 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 Stream from 'flarum/common/utils/Stream'; 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 FieldSet from '@flarum/core/src/common/components/FieldSet'; -export default class SuspendUserModal extends Modal { +export default class SuspendUserModal extends FormModal { oninit(vnode) { super.oninit(vnode); diff --git a/extensions/tags/js/src/admin/components/EditTagModal.tsx b/extensions/tags/js/src/admin/components/EditTagModal.tsx index 62c412ebe8..ffc76c2880 100644 --- a/extensions/tags/js/src/admin/components/EditTagModal.tsx +++ b/extensions/tags/js/src/admin/components/EditTagModal.tsx @@ -1,5 +1,5 @@ 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 ColorPreviewInput from 'flarum/common/components/ColorPreviewInput'; import ItemList from 'flarum/common/utils/ItemList'; @@ -12,7 +12,7 @@ import type Mithril from 'mithril'; import tagLabel from '../../common/helpers/tagLabel'; import type Tag from '../../common/models/Tag'; -export interface EditTagModalAttrs extends IInternalModalAttrs { +export interface EditTagModalAttrs extends IFormModalAttrs { primary?: boolean; model?: Tag; } @@ -21,7 +21,7 @@ export interface EditTagModalAttrs extends IInternalModalAttrs { * The `EditTagModal` component shows a modal dialog which allows the user * to create or edit a tag. */ -export default class EditTagModal extends Modal { +export default class EditTagModal extends FormModal { tag!: Tag; name!: Stream; diff --git a/extensions/tags/js/src/common/components/TagSelectionModal.tsx b/extensions/tags/js/src/common/components/TagSelectionModal.tsx index 496a958c81..68e8affb42 100644 --- a/extensions/tags/js/src/common/components/TagSelectionModal.tsx +++ b/extensions/tags/js/src/common/components/TagSelectionModal.tsx @@ -5,7 +5,7 @@ import extractText from 'flarum/common/utils/extractText'; import highlight from 'flarum/common/helpers/highlight'; import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable'; 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 sortTags from '../utils/sortTags'; @@ -14,7 +14,7 @@ import tagIcon from '../helpers/tagIcon'; import ToggleButton from '../../forum/components/ToggleButton'; 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'; 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. */ className?: string; /** Modal title, defaults to 'Choose Tags'. */ @@ -64,7 +64,7 @@ export type ITagSelectionModalState = undefined; export default class TagSelectionModal< CustomAttrs extends ITagSelectionModalAttrs = ITagSelectionModalAttrs, CustomState extends ITagSelectionModalState = ITagSelectionModalState -> extends Modal { +> extends FormModal { protected loading = true; protected tags!: Tag[]; protected selected: Tag[] = []; @@ -108,7 +108,7 @@ export default class TagSelectionModal< .onSelect(this.select.bind(this)) .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; if (this.attrs.selectableTags) { diff --git a/extensions/tags/js/src/common/states/TagListState.ts b/extensions/tags/js/src/common/states/TagListState.ts index e0db4a215e..06661a4c1e 100644 --- a/extensions/tags/js/src/common/states/TagListState.ts +++ b/extensions/tags/js/src/common/states/TagListState.ts @@ -21,7 +21,7 @@ export default class TagListState { async query(includes: string[] = []): Promise { this.loadedIncludes ??= new Set(); - return app.store.find('tags', { include: includes.join(',') }).then((val) => { + return app.store.find('tags', { include: includes.join(',') }).then((val: Tag) => { includes.forEach((include) => this.loadedIncludes!.add(include)); return val; }); diff --git a/framework/core/js/src/admin/components/CreateUserModal.tsx b/framework/core/js/src/admin/components/CreateUserModal.tsx index 7b8dfa9601..a351364c48 100644 --- a/framework/core/js/src/admin/components/CreateUserModal.tsx +++ b/framework/core/js/src/admin/components/CreateUserModal.tsx @@ -1,5 +1,5 @@ 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 extractText from '../../common/utils/extractText'; import ItemList from '../../common/utils/ItemList'; @@ -9,7 +9,7 @@ import Switch from '../../common/components/Switch'; import { generateRandomString } from '../../common/utils/string'; import Form from '../../common/components/Form'; -export interface ICreateUserModalAttrs extends IInternalModalAttrs { +export interface ICreateUserModalAttrs extends IFormModalAttrs { username?: string; email?: string; password?: string; @@ -24,7 +24,7 @@ export type SignupBody = { password: string; }; -export default class CreateUserModal extends Modal { +export default class CreateUserModal extends FormModal { /** * The value of the username input. */ diff --git a/framework/core/js/src/admin/components/EditGroupModal.tsx b/framework/core/js/src/admin/components/EditGroupModal.tsx index a77e684df8..123d40e11c 100644 --- a/framework/core/js/src/admin/components/EditGroupModal.tsx +++ b/framework/core/js/src/admin/components/EditGroupModal.tsx @@ -1,5 +1,5 @@ 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 Badge from '../../common/components/Badge'; import Group from '../../common/models/Group'; @@ -11,7 +11,7 @@ import extractText from '../../common/utils/extractText'; import ColorPreviewInput from '../../common/components/ColorPreviewInput'; import Form from '../../common/components/Form'; -export interface IEditGroupModalAttrs extends IInternalModalAttrs { +export interface IEditGroupModalAttrs extends IFormModalAttrs { group?: Group; } @@ -19,7 +19,7 @@ export interface IEditGroupModalAttrs extends IInternalModalAttrs { * The `EditGroupModal` component shows a modal dialog which allows the user * to create or edit a group. */ -export default class EditGroupModal extends Modal { +export default class EditGroupModal extends FormModal { group!: Group; nameSingular!: Stream; namePlural!: Stream; diff --git a/framework/core/js/src/admin/components/LoadingModal.tsx b/framework/core/js/src/admin/components/LoadingModal.tsx index f0bd33508c..485c00c0dc 100644 --- a/framework/core/js/src/admin/components/LoadingModal.tsx +++ b/framework/core/js/src/admin/components/LoadingModal.tsx @@ -19,8 +19,4 @@ export default class LoadingModal extends Modal { +export default abstract class SettingsModal extends FormModal { settings: MutableSettings = {}; loading: boolean = false; diff --git a/framework/core/js/src/common/common.ts b/framework/core/js/src/common/common.ts index 4e1d8c4e2f..13c450dc53 100644 --- a/framework/core/js/src/common/common.ts +++ b/framework/core/js/src/common/common.ts @@ -65,6 +65,7 @@ import './components/SelectDropdown'; import './components/ModalManager'; import './components/Button'; import './components/Modal'; +import './components/FormModal'; import './components/GroupBadge'; import './components/TextEditor'; import './components/TextEditorButton'; diff --git a/framework/core/js/src/common/components/EditUserModal.tsx b/framework/core/js/src/common/components/EditUserModal.tsx index d23e07c92f..a8dc5b6e25 100644 --- a/framework/core/js/src/common/components/EditUserModal.tsx +++ b/framework/core/js/src/common/components/EditUserModal.tsx @@ -1,5 +1,5 @@ import app from '../../common/app'; -import Modal, { IInternalModalAttrs } from './Modal'; +import FormModal, { IFormModalAttrs } from '../../common/components/FormModal'; import Button from './Button'; import GroupBadge from './GroupBadge'; import Group from '../models/Group'; @@ -11,11 +11,11 @@ import type User from '../models/User'; import type { SaveAttributes, SaveRelationships } from '../Model'; import Form from './Form'; -export interface IEditUserModalAttrs extends IInternalModalAttrs { +export interface IEditUserModalAttrs extends IFormModalAttrs { user: User; } -export default class EditUserModal extends Modal { +export default class EditUserModal extends FormModal { protected username!: Stream; protected email!: Stream; protected isEmailConfirmed!: Stream; diff --git a/framework/core/js/src/common/components/FormModal.tsx b/framework/core/js/src/common/components/FormModal.tsx new file mode 100644 index 0000000000..40d3e8e550 --- /dev/null +++ b/framework/core/js/src/common/components/FormModal.tsx @@ -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 extends Modal< + ModalAttrs, + CustomState +> { + wrapper(children: Mithril.Children): Mithril.Children { + return
{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. + * + * @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(); + } + } +} diff --git a/framework/core/js/src/common/components/Modal.tsx b/framework/core/js/src/common/components/Modal.tsx index 3e6e0275cf..7b1787798f 100644 --- a/framework/core/js/src/common/components/Modal.tsx +++ b/framework/core/js/src/common/components/Modal.tsx @@ -5,7 +5,6 @@ import Button from './Button'; import type Mithril from 'mithril'; import type ModalManagerState from '../states/ModalManagerState'; -import type RequestError from '../utils/RequestError'; import type ModalManager from './ModalManager'; import fireDebugWarning from '../helpers/fireDebugWarning'; import classList from '../utils/classList'; @@ -101,22 +100,31 @@ export default abstract class Modal )} + {this.wrapper(this.inner())} + + + ); + } -
-
-

{this.title()}

-
- - {!!this.alertAttrs && ( -
- -
- )} + protected wrapper(children: Mithril.Children): Mithril.Children { + return <>{children}; + } - {this.content()} -
+ protected inner(): Mithril.Children { + return ( + <> +
+

{this.title()}

- + + {!!this.alertAttrs && ( +
+ +
+ )} + + {this.content()} + ); } @@ -135,20 +143,11 @@ export default abstract class Modal extends Modal { +export default class ChangeEmailModal extends FormModal { /** * The value of the email input. */ diff --git a/framework/core/js/src/forum/components/ChangePasswordModal.tsx b/framework/core/js/src/forum/components/ChangePasswordModal.tsx index 9e92102f11..f84c9a2037 100644 --- a/framework/core/js/src/forum/components/ChangePasswordModal.tsx +++ b/framework/core/js/src/forum/components/ChangePasswordModal.tsx @@ -1,5 +1,5 @@ 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 Mithril from 'mithril'; 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 * user to send themself a password reset email. */ -export default class ChangePasswordModal extends Modal { +export default class ChangePasswordModal extends FormModal { className() { return 'ChangePasswordModal Modal--small'; } diff --git a/framework/core/js/src/forum/components/ForgotPasswordModal.tsx b/framework/core/js/src/forum/components/ForgotPasswordModal.tsx index 9475273538..c9c32b7d69 100644 --- a/framework/core/js/src/forum/components/ForgotPasswordModal.tsx +++ b/framework/core/js/src/forum/components/ForgotPasswordModal.tsx @@ -1,5 +1,5 @@ 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 extractText from '../../common/utils/extractText'; import Stream from '../../common/utils/Stream'; @@ -8,7 +8,7 @@ import RequestError from '../../common/utils/RequestError'; import ItemList from '../../common/utils/ItemList'; import Form from '../../common/components/Form'; -export interface IForgotPasswordModalAttrs extends IInternalModalAttrs { +export interface IForgotPasswordModalAttrs extends IFormModalAttrs { email?: string; } @@ -16,7 +16,7 @@ export interface IForgotPasswordModalAttrs extends IInternalModalAttrs { * The `ForgotPasswordModal` component displays a modal which allows the user to * enter their email address and request a link to reset their password. */ -export default class ForgotPasswordModal extends Modal { +export default class ForgotPasswordModal extends FormModal { /** * The value of the email input. */ diff --git a/framework/core/js/src/forum/components/LogInModal.tsx b/framework/core/js/src/forum/components/LogInModal.tsx index c087e64310..dfe8d8c23f 100644 --- a/framework/core/js/src/forum/components/LogInModal.tsx +++ b/framework/core/js/src/forum/components/LogInModal.tsx @@ -1,5 +1,5 @@ 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 LogInButtons from './LogInButtons'; import extractText from '../../common/utils/extractText'; @@ -9,13 +9,13 @@ import type Mithril from 'mithril'; import RequestError from '../../common/utils/RequestError'; import type { LoginParams } from '../../common/Session'; -export interface ILoginModalAttrs extends IInternalModalAttrs { +export interface ILoginModalAttrs extends IFormModalAttrs { identification?: string; password?: string; remember?: boolean; } -export default class LogInModal extends Modal { +export default class LogInModal extends FormModal { /** * The value of the identification input. */ diff --git a/framework/core/js/src/forum/components/NewAccessTokenModal.tsx b/framework/core/js/src/forum/components/NewAccessTokenModal.tsx index 3f54cd98de..fd242d9e28 100644 --- a/framework/core/js/src/forum/components/NewAccessTokenModal.tsx +++ b/framework/core/js/src/forum/components/NewAccessTokenModal.tsx @@ -1,5 +1,5 @@ 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 Stream from '../../common/utils/Stream'; import type AccessToken from '../../common/models/AccessToken'; @@ -7,11 +7,11 @@ import type { SaveAttributes } from '../../common/Model'; import type Mithril from 'mithril'; import Form from '../../common/components/Form'; -export interface INewAccessTokenModalAttrs extends IInternalModalAttrs { +export interface INewAccessTokenModalAttrs extends IFormModalAttrs { onsuccess: (token: AccessToken) => void; } -export default class NewAccessTokenModal extends Modal { +export default class NewAccessTokenModal extends FormModal { protected titleInput = Stream(''); className(): string { diff --git a/framework/core/js/src/forum/components/RenameDiscussionModal.tsx b/framework/core/js/src/forum/components/RenameDiscussionModal.tsx index 12a0e865ac..7857fe41cd 100644 --- a/framework/core/js/src/forum/components/RenameDiscussionModal.tsx +++ b/framework/core/js/src/forum/components/RenameDiscussionModal.tsx @@ -1,12 +1,12 @@ 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 Stream from '../../common/utils/Stream'; import Mithril from 'mithril'; import Discussion from '../../common/models/Discussion'; import Form from '../../common/components/Form'; -export interface IRenameDiscussionModalAttrs extends IInternalModalAttrs { +export interface IRenameDiscussionModalAttrs extends IFormModalAttrs { discussion: Discussion; currentTitle: string; } @@ -14,7 +14,9 @@ export interface IRenameDiscussionModalAttrs extends IInternalModalAttrs { /** * 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 FormModal { discussion!: Discussion; currentTitle!: string; newTitle!: Stream; diff --git a/framework/core/js/src/forum/components/SignUpModal.tsx b/framework/core/js/src/forum/components/SignUpModal.tsx index c456cbb7f4..f989e1e155 100644 --- a/framework/core/js/src/forum/components/SignUpModal.tsx +++ b/framework/core/js/src/forum/components/SignUpModal.tsx @@ -1,5 +1,5 @@ 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 LogInButtons from './LogInButtons'; import extractText from '../../common/utils/extractText'; @@ -7,7 +7,7 @@ import ItemList from '../../common/utils/ItemList'; import Stream from '../../common/utils/Stream'; import type Mithril from 'mithril'; -export interface ISignupModalAttrs extends IInternalModalAttrs { +export interface ISignupModalAttrs extends IFormModalAttrs { username?: string; email?: string; password?: string; @@ -20,7 +20,7 @@ export type SignupBody = { email: string; } & ({ token: string } | { password: string }); -export default class SignUpModal extends Modal { +export default class SignUpModal extends FormModal { /** * The value of the username input. */