1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
2// See the LICENCE file in the repository root for full licence text.
3
4import FormErrorJson from 'interfaces/form-error-json';
5import { action, makeObservable, observable } from 'mobx';
6import { flattenFormErrorJson } from 'utils/json';
7
8export class FormErrors {
9 @observable private errors = new Map<string, string[]>();
10
11 constructor() {
12 makeObservable(this);
13 }
14
15 @action
16 clear() {
17 this.errors.clear();
18 }
19
20 /**
21 * Returns a list of errors with errors for specific input fields filtered out.
22 * This works fine for its current use-case and the way validation error keys
23 * are currently returned.
24 *
25 * @param names field names to filter out.
26 * @returns List of error messages.
27 */
28 except(names: readonly string[]): string[] {
29 const keys = [...this.errors.keys()].filter((key) => names.every((name) => key !== name));
30
31 const messages: string[] = [];
32 for (const key of keys) {
33 const strings = this.errors.get(key);
34 if (strings != null) {
35 strings.forEach((value) => messages.push(value));
36 }
37 }
38
39 return messages;
40 }
41
42 get(name: string) {
43 return this.errors.get(name);
44 }
45
46 @action
47 handleResponse = (xhr: JQuery.jqXHR<unknown>) => {
48 // TODO: extra checks
49 const errors = xhr.responseJSON?.form_error as FormErrorJson | undefined;
50
51 // only handle responses with form_error
52 if (errors == null) return;
53
54 this.errors = flattenFormErrorJson(errors);
55 };
56}