impr: add validation for preset names (@fehmer) (#6969)

This commit is contained in:
Christian Fehmer 2025-09-23 16:41:06 +02:00 committed by GitHub
parent c08572bd89
commit 18c465e82d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 3 deletions

View file

@ -145,6 +145,7 @@ export type ValidationOptions<T> = (T extends string
export type ValidatedHtmlInputElement = HTMLInputElement & {
isValid: () => boolean | undefined;
setValue: (val: string | null) => void;
};
/**
* adds an 'InputIndicator` to the given `inputElement` and updates its status depending on the given validation
@ -197,6 +198,15 @@ export function validateWithIndicator<T>(
const result = inputElement as ValidatedHtmlInputElement;
result.isValid = () => isValid;
result.setValue = (val: string | null) => {
inputElement.value = val ?? "";
if (val === null) {
isValid = undefined;
indicator.hide();
} else {
inputElement.dispatchEvent(new Event("input"));
}
};
return result;
}

View file

@ -6,7 +6,11 @@ import * as Settings from "../pages/settings";
import * as Notifications from "../elements/notifications";
import * as ConnectionState from "../states/connection";
import AnimatedModal from "../utils/animated-modal";
import { PresetType, PresetTypeSchema } from "@monkeytype/schemas/presets";
import {
PresetNameSchema,
PresetType,
PresetTypeSchema,
} from "@monkeytype/schemas/presets";
import { getPreset } from "../controllers/preset-controller";
import {
ConfigGroupName,
@ -17,6 +21,10 @@ import {
} from "@monkeytype/schemas/configs";
import { getDefaultConfig } from "../constants/default-config";
import { SnapshotPreset } from "../constants/default-snapshot";
import {
ValidatedHtmlInputElement,
validateWithIndicator,
} from "../elements/input-validation";
const state = {
presetType: "full" as PresetType,
@ -26,6 +34,8 @@ const state = {
setPresetToCurrent: false,
};
let presetNameEl: ValidatedHtmlInputElement | null = null;
export function show(action: string, id?: string, name?: string): void {
if (!ConnectionState.get()) {
Notifications.add("You are offline", 0, {
@ -39,11 +49,22 @@ export function show(action: string, id?: string, name?: string): void {
beforeAnimation: async () => {
$("#editPresetModal .modal .text").addClass("hidden");
addCheckBoxes();
if (!presetNameEl) {
presetNameEl = validateWithIndicator(
document.querySelector(
"#editPresetModal .modal input"
) as HTMLInputElement,
{
schema: PresetNameSchema,
}
);
}
if (action === "add") {
$("#editPresetModal .modal").attr("data-action", "add");
$("#editPresetModal .modal .popupTitle").html("Add new preset");
$("#editPresetModal .modal .submit").html(`add`);
$("#editPresetModal .modal input").val("");
presetNameEl?.setValue(null);
presetNameEl?.parentElement?.classList.remove("hidden");
$("#editPresetModal .modal input").removeClass("hidden");
$(
"#editPresetModal .modal label.changePresetToCurrentCheckbox"
@ -57,7 +78,9 @@ export function show(action: string, id?: string, name?: string): void {
$("#editPresetModal .modal").attr("data-preset-id", id);
$("#editPresetModal .modal .popupTitle").html("Edit preset");
$("#editPresetModal .modal .submit").html(`save`);
$("#editPresetModal .modal input").val(name);
presetNameEl?.setValue(name);
presetNameEl?.parentElement?.classList.remove("hidden");
$("#editPresetModal .modal input").removeClass("hidden");
$(
"#editPresetModal .modal label.changePresetToCurrentCheckbox"
@ -85,6 +108,7 @@ export function show(action: string, id?: string, name?: string): void {
$("#editPresetModal .modal .inputs").addClass("hidden");
$("#editPresetModal .modal .presetType").addClass("hidden");
$("#editPresetModal .modal .presetNameTitle").addClass("hidden");
presetNameEl?.parentElement?.classList.add("hidden");
}
updateUI();
},
@ -238,6 +262,11 @@ async function apply(): Promise<void> {
return;
}
if (presetNameEl?.isValid() === false) {
Notifications.add("Preset name is not valid", 0);
return;
}
hide();
Loader.show();