diff --git a/frontend/src/ts/elements/account-settings/ape-key-table.ts b/frontend/src/ts/elements/account-settings/ape-key-table.ts index 2bc129194f24..206cd7700942 100644 --- a/frontend/src/ts/elements/account-settings/ape-key-table.ts +++ b/frontend/src/ts/elements/account-settings/ape-key-table.ts @@ -10,9 +10,10 @@ import { ApeKeyNameSchema, } from "@monkeytype/schemas/ape-keys"; import { format } from "date-fns/format"; -import { SimpleModal, TextArea } from "../simple-modal"; +import { SimpleModal } from "../simple-modal"; import { isAuthenticated } from "../../states/core"; import { qs, qsr } from "../../utils/dom"; +import { TextArea } from "../../states/simple-modal"; const editApeKey = new SimpleModal({ id: "editApeKey", diff --git a/frontend/src/ts/elements/simple-modal.ts b/frontend/src/ts/elements/simple-modal.ts index b77e603f5f50..aedee33584de 100644 --- a/frontend/src/ts/elements/simple-modal.ts +++ b/frontend/src/ts/elements/simple-modal.ts @@ -9,113 +9,31 @@ import { showLoaderBar, hideLoaderBar } from "../states/loader-bar"; import { showNoticeNotification, addNotificationWithLevel, - AddNotificationOptions, } from "../states/notifications"; import { ValidatedHtmlInputElement, ValidationOptions, } from "./input-validation"; import { ElementWithUtils, qsr } from "../utils/dom"; +import { ValidationResult } from "../types/validation"; import { - IsValidResponse, - Validation, - ValidationResult, -} from "../types/validation"; + SimpleModalConfig, + SimpleModalInput, + ExecReturn as BaseExecReturn, +} from "../states/simple-modal"; const simpleModalEl = qsr("#simpleModal"); -type CommonInput = { - type: TType; - initVal?: TValue; - placeholder?: string; - hidden?: boolean; - disabled?: boolean; - optional?: boolean; - label?: string; - oninput?: (event: Event) => void; - /** - * Validate the input value and indicate the validation result next to the input. - * If the schema is defined it is always checked first. - * Only if the schema validaton is passed or missing the `isValid` method is called. - */ - validation?: Omit, "isValid"> & { - /** - * Custom async validation method. - * This is intended to be used for validations that cannot be handled with a Zod schema like server-side validations. - * @param value current input value - * @param thisPopup the current modal - * @returns true if the `value` is valid, an errorMessage as string if it is invalid. - */ - isValid?: ( - value: string, - thisPopup: SimpleModal, - ) => Promise; - }; -}; - -export type TextInput = CommonInput<"text", string>; -export type TextArea = CommonInput<"textarea", string>; -export type PasswordInput = CommonInput<"password", string>; -type EmailInput = CommonInput<"email", string>; - -type RangeInput = { - min: number; - max: number; - step?: number; -} & CommonInput<"range", number>; - -type DateTimeInput = { - min?: Date; - max?: Date; -} & CommonInput<"datetime-local", Date>; -type DateInput = { - min?: Date; - max?: Date; -} & CommonInput<"date", Date>; - -type CheckboxInput = { - label: string; - placeholder?: never; - description?: string; -} & CommonInput<"checkbox", boolean>; - -type NumberInput = { - min?: number; - max?: number; -} & CommonInput<"number", number>; - -type CommonInputType = - | TextInput - | TextArea - | PasswordInput - | EmailInput - | RangeInput - | DateTimeInput - | DateInput - | CheckboxInput - | NumberInput; - -export type ExecReturn = { - status: "success" | "notice" | "error"; - message: string; - showNotification?: false; - notificationOptions?: AddNotificationOptions; +export type ExecReturn = BaseExecReturn & { hideOptions?: HideOptions; - afterHide?: () => void; - alwaysHide?: boolean; }; -type FormInput = CommonInputType & { +type FormInput = SimpleModalInput & { hasError?: boolean; currentValue: () => string; }; -type SimpleModalOptions = { +type SimpleModalOptions = Omit & { id: string; - title: string; - inputs?: CommonInputType[]; - text?: string; - textAllowHtml?: boolean; - buttonText: string; execFn: (thisPopup: SimpleModal, ...params: string[]) => Promise; beforeInitFn?: (thisPopup: SimpleModal) => void; beforeShowFn?: (thisPopup: SimpleModal) => void; @@ -135,7 +53,7 @@ export class SimpleModal { inputs: FormInput[]; text?: string; textAllowHtml: boolean; - buttonText: string; + buttonText?: string; execFn: (thisPopup: SimpleModal, ...params: string[]) => Promise; beforeInitFn: ((thisPopup: SimpleModal) => void) | undefined; beforeShowFn: ((thisPopup: SimpleModal) => void) | undefined; @@ -183,7 +101,7 @@ export class SimpleModal { this.initInputs(); - if (this.buttonText === "") { + if (this.buttonText === "" || this.buttonText === undefined) { this.element.qs(".submitButton")?.remove(); } else { this.element.qs(".submitButton")?.setText(this.buttonText); diff --git a/frontend/src/ts/modals/simple-modals.ts b/frontend/src/ts/modals/simple-modals.ts index b0e3957c789f..591d3bb07f94 100644 --- a/frontend/src/ts/modals/simple-modals.ts +++ b/frontend/src/ts/modals/simple-modals.ts @@ -21,12 +21,6 @@ import { createErrorMessage } from "../utils/error"; import * as ThemeController from "../controllers/theme-controller"; import * as CustomThemes from "../collections/custom-themes"; import * as AccountSettings from "../pages/account-settings"; -import { - ExecReturn, - PasswordInput, - SimpleModal, - TextInput, -} from "../elements/simple-modal"; import { GenerateDataRequest } from "@monkeytype/contracts/dev"; import { @@ -42,6 +36,8 @@ import { list, PopupKey, showPopup } from "./simple-modals-base"; import { getTheme } from "../states/theme"; import { normalizeName } from "../utils/strings"; import { IsValidResponse } from "../types/validation"; +import { ExecReturn, SimpleModal } from "../elements/simple-modal"; +import { PasswordInput, TextInput } from "../states/simple-modal"; export { list, showPopup }; export type { PopupKey }; @@ -196,10 +192,6 @@ list.updateEmail = new SimpleModal({ initVal: "", validation: { schema: UserEmailSchema, - isValid: async (currentValue, thisPopup) => - currentValue === thisPopup.inputs?.[1]?.currentValue() || - "Emails don't match", - debounceDelay: 0, }, }, ], diff --git a/frontend/src/ts/states/simple-modal.ts b/frontend/src/ts/states/simple-modal.ts index a9a6e3544fba..3c1c686c067b 100644 --- a/frontend/src/ts/states/simple-modal.ts +++ b/frontend/src/ts/states/simple-modal.ts @@ -9,7 +9,7 @@ import { import { showLoaderBar, hideLoaderBar } from "./loader-bar"; import { Validation } from "../types/validation"; -type CommonInput = { +export type CommonInput = { type: TType; name?: string; initVal?: TValue; @@ -20,6 +20,11 @@ type CommonInput = { label?: string; class?: string; oninput?: (event: Event) => void; + /** + * Validate the input value and indicate the validation result next to the input. + * If the schema is defined it is always checked first. + * Only if the schema validaton is passed or missing the `isValid` method is called. + */ validation?: Validation; };