Skip to content

Commit 9bef970

Browse files
committed
Merge branch 'master' into refactor/edit-profile-modal
2 parents 05ea82c + 3a92e78 commit 9bef970

5 files changed

Lines changed: 28 additions & 108 deletions

File tree

frontend/src/ts/elements/account-settings/ape-key-table.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import {
1010
ApeKeyNameSchema,
1111
} from "@monkeytype/schemas/ape-keys";
1212
import { format } from "date-fns/format";
13-
import { SimpleModal, TextArea } from "../simple-modal";
13+
import { SimpleModal } from "../simple-modal";
1414
import { isAuthenticated } from "../../states/core";
1515
import { qs, qsr } from "../../utils/dom";
16+
import { TextArea } from "../../states/simple-modal";
1617

1718
const editApeKey = new SimpleModal({
1819
id: "editApeKey",

frontend/src/ts/elements/simple-modal.ts

Lines changed: 10 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9,113 +9,31 @@ import { showLoaderBar, hideLoaderBar } from "../states/loader-bar";
99
import {
1010
showNoticeNotification,
1111
addNotificationWithLevel,
12-
AddNotificationOptions,
1312
} from "../states/notifications";
1413
import {
1514
ValidatedHtmlInputElement,
1615
ValidationOptions,
1716
} from "./input-validation";
1817
import { ElementWithUtils, qsr } from "../utils/dom";
18+
import { ValidationResult } from "../types/validation";
1919
import {
20-
IsValidResponse,
21-
Validation,
22-
ValidationResult,
23-
} from "../types/validation";
20+
SimpleModalConfig,
21+
SimpleModalInput,
22+
ExecReturn as BaseExecReturn,
23+
} from "../states/simple-modal";
2424

2525
const simpleModalEl = qsr<HTMLDialogElement>("#simpleModal");
2626

27-
type CommonInput<TType, TValue> = {
28-
type: TType;
29-
initVal?: TValue;
30-
placeholder?: string;
31-
hidden?: boolean;
32-
disabled?: boolean;
33-
optional?: boolean;
34-
label?: string;
35-
oninput?: (event: Event) => void;
36-
/**
37-
* Validate the input value and indicate the validation result next to the input.
38-
* If the schema is defined it is always checked first.
39-
* Only if the schema validaton is passed or missing the `isValid` method is called.
40-
*/
41-
validation?: Omit<Validation<string>, "isValid"> & {
42-
/**
43-
* Custom async validation method.
44-
* This is intended to be used for validations that cannot be handled with a Zod schema like server-side validations.
45-
* @param value current input value
46-
* @param thisPopup the current modal
47-
* @returns true if the `value` is valid, an errorMessage as string if it is invalid.
48-
*/
49-
isValid?: (
50-
value: string,
51-
thisPopup: SimpleModal,
52-
) => Promise<IsValidResponse>;
53-
};
54-
};
55-
56-
export type TextInput = CommonInput<"text", string>;
57-
export type TextArea = CommonInput<"textarea", string>;
58-
export type PasswordInput = CommonInput<"password", string>;
59-
type EmailInput = CommonInput<"email", string>;
60-
61-
type RangeInput = {
62-
min: number;
63-
max: number;
64-
step?: number;
65-
} & CommonInput<"range", number>;
66-
67-
type DateTimeInput = {
68-
min?: Date;
69-
max?: Date;
70-
} & CommonInput<"datetime-local", Date>;
71-
type DateInput = {
72-
min?: Date;
73-
max?: Date;
74-
} & CommonInput<"date", Date>;
75-
76-
type CheckboxInput = {
77-
label: string;
78-
placeholder?: never;
79-
description?: string;
80-
} & CommonInput<"checkbox", boolean>;
81-
82-
type NumberInput = {
83-
min?: number;
84-
max?: number;
85-
} & CommonInput<"number", number>;
86-
87-
type CommonInputType =
88-
| TextInput
89-
| TextArea
90-
| PasswordInput
91-
| EmailInput
92-
| RangeInput
93-
| DateTimeInput
94-
| DateInput
95-
| CheckboxInput
96-
| NumberInput;
97-
98-
export type ExecReturn = {
99-
status: "success" | "notice" | "error";
100-
message: string;
101-
showNotification?: false;
102-
notificationOptions?: AddNotificationOptions;
27+
export type ExecReturn = BaseExecReturn & {
10328
hideOptions?: HideOptions;
104-
afterHide?: () => void;
105-
alwaysHide?: boolean;
10629
};
10730

108-
type FormInput = CommonInputType & {
31+
type FormInput = SimpleModalInput & {
10932
hasError?: boolean;
11033
currentValue: () => string;
11134
};
112-
type SimpleModalOptions = {
35+
type SimpleModalOptions = Omit<SimpleModalConfig, "execFn"> & {
11336
id: string;
114-
title: string;
115-
inputs?: CommonInputType[];
116-
text?: string;
117-
textAllowHtml?: boolean;
118-
buttonText: string;
11937
execFn: (thisPopup: SimpleModal, ...params: string[]) => Promise<ExecReturn>;
12038
beforeInitFn?: (thisPopup: SimpleModal) => void;
12139
beforeShowFn?: (thisPopup: SimpleModal) => void;
@@ -135,7 +53,7 @@ export class SimpleModal {
13553
inputs: FormInput[];
13654
text?: string;
13755
textAllowHtml: boolean;
138-
buttonText: string;
56+
buttonText?: string;
13957
execFn: (thisPopup: SimpleModal, ...params: string[]) => Promise<ExecReturn>;
14058
beforeInitFn: ((thisPopup: SimpleModal) => void) | undefined;
14159
beforeShowFn: ((thisPopup: SimpleModal) => void) | undefined;
@@ -183,7 +101,7 @@ export class SimpleModal {
183101

184102
this.initInputs();
185103

186-
if (this.buttonText === "") {
104+
if (this.buttonText === "" || this.buttonText === undefined) {
187105
this.element.qs(".submitButton")?.remove();
188106
} else {
189107
this.element.qs(".submitButton")?.setText(this.buttonText);

frontend/src/ts/modals/simple-modals.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ import { createErrorMessage } from "../utils/error";
2121
import * as ThemeController from "../controllers/theme-controller";
2222
import * as CustomThemes from "../collections/custom-themes";
2323
import * as AccountSettings from "../pages/account-settings";
24-
import {
25-
ExecReturn,
26-
PasswordInput,
27-
SimpleModal,
28-
TextInput,
29-
} from "../elements/simple-modal";
3024

3125
import { GenerateDataRequest } from "@monkeytype/contracts/dev";
3226
import {
@@ -42,6 +36,8 @@ import { list, PopupKey, showPopup } from "./simple-modals-base";
4236
import { getTheme } from "../states/theme";
4337
import { normalizeName } from "../utils/strings";
4438
import { IsValidResponse } from "../types/validation";
39+
import { ExecReturn, SimpleModal } from "../elements/simple-modal";
40+
import { PasswordInput, TextInput } from "../states/simple-modal";
4541

4642
export { list, showPopup };
4743
export type { PopupKey };
@@ -196,10 +192,6 @@ list.updateEmail = new SimpleModal({
196192
initVal: "",
197193
validation: {
198194
schema: UserEmailSchema,
199-
isValid: async (currentValue, thisPopup) =>
200-
currentValue === thisPopup.inputs?.[1]?.currentValue() ||
201-
"Emails don't match",
202-
debounceDelay: 0,
203195
},
204196
},
205197
],

frontend/src/ts/states/simple-modal.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { showLoaderBar, hideLoaderBar } from "./loader-bar";
1010
import { Validation } from "../types/validation";
1111

12-
type CommonInput<TType, TValue> = {
12+
export type CommonInput<TType, TValue> = {
1313
type: TType;
1414
name?: string;
1515
initVal?: TValue;
@@ -20,6 +20,11 @@ type CommonInput<TType, TValue> = {
2020
label?: string;
2121
class?: string;
2222
oninput?: (event: Event) => void;
23+
/**
24+
* Validate the input value and indicate the validation result next to the input.
25+
* If the schema is defined it is always checked first.
26+
* Only if the schema validaton is passed or missing the `isValid` method is called.
27+
*/
2328
validation?: Validation<string>;
2429
};
2530

frontend/storybook/stories/InputField.stories.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function createFieldMock(options: {
1717
name?: string;
1818
value?: string;
1919
meta?: MetaState;
20+
validators?: object;
2021
}) {
2122
const stateMeta = {
2223
isTouched: true,
@@ -27,6 +28,9 @@ function createFieldMock(options: {
2728
};
2829
return {
2930
name: options.name ?? "test",
31+
options: {
32+
validators: options.validators,
33+
},
3034
get state() {
3135
return {
3236
value: options.value ?? "",
@@ -47,7 +51,6 @@ const meta = preview.meta({
4751
component: InputField as Component<{
4852
field: Accessor<AnyFieldApi>;
4953
placeholder?: string;
50-
showIndicator?: true;
5154
autocomplete?: string;
5255
type?: string;
5356
disabled?: boolean;
@@ -59,7 +62,6 @@ const meta = preview.meta({
5962
tags: ["autodocs"],
6063
argTypes: {
6164
placeholder: { control: "text" },
62-
showIndicator: { control: "boolean" },
6365
autocomplete: { control: "text" },
6466
type: { control: "text" },
6567
disabled: { control: "boolean" },
@@ -74,8 +76,10 @@ export const Default = meta.story({
7476

7577
export const withIndicator = meta.story({
7678
args: {
77-
showIndicator: true,
78-
field: () => createFieldMock({}),
79+
field: () =>
80+
createFieldMock({
81+
validators: { onChange: () => undefined },
82+
}),
7983
},
8084
});
8185

0 commit comments

Comments
 (0)