Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/cyberstorm-remix/app/settings/teams/Teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ function CreateTeamForm(props: { config: () => RequestConfig }) {
InputErrors
>({
inputs: formInputs,
validators: { name: { required: true } },
submitor,
onSubmitSuccess: (fi) => {
createTeamRevalidate();
Expand Down Expand Up @@ -223,10 +224,11 @@ function CreateTeamForm(props: { config: () => RequestConfig }) {
</Modal.Body>
<Modal.Footer>
<NewButton
disabled={!strongForm.isReady}
csVariant="accent"
onClick={() => {
strongForm.submit().then(() => setOpen(false));
}}
csVariant="accent"
>
Create
</NewButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export function MemberAddForm(props: {
InputErrors
>({
inputs: formInputs,
validators: { username: { required: true } },
submitor,
onSubmitSuccess: () => {
props.updateTrigger();
Expand Down Expand Up @@ -151,7 +152,11 @@ export function MemberAddForm(props: {
</div>
</Modal.Body>
<Modal.Footer>
<NewButton csVariant="accent" onClick={strongForm.submit}>
<NewButton
csVariant="accent"
disabled={!strongForm.isReady}
onClick={strongForm.submit}
>
Add member
</NewButton>
</Modal.Footer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ function AddServiceAccountForm(props: {
nickname: "",
});

const isValid = formInputs.nickname.trim().length > 0;

type SubmitorOutput = Awaited<ReturnType<typeof teamAddServiceAccount>>;

async function submitor(data: typeof formInputs): Promise<SubmitorOutput> {
Expand All @@ -140,6 +138,7 @@ function AddServiceAccountForm(props: {
InputErrors
>({
inputs: formInputs,
validators: { nickname: { required: true } },
submitor,
onSubmitSuccess: (result) => {
onSuccess(result);
Expand Down Expand Up @@ -203,7 +202,7 @@ function AddServiceAccountForm(props: {
className="service-accounts__form"
onSubmit={(e) => {
e.preventDefault();
if (isValid) {
if (strongForm.isReady) {
strongForm.submit();
}
}}
Expand Down Expand Up @@ -234,7 +233,7 @@ function AddServiceAccountForm(props: {
)}
{serviceAccountAdded ? null : (
<Modal.Footer>
<NewButton onClick={strongForm.submit} disabled={!isValid}>
<NewButton onClick={strongForm.submit} disabled={!strongForm.isReady}>
Add Service Account
</NewButton>
</Modal.Footer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import {
ParseError,
RequestBodyParseError,
RequestQueryParamsParseError,
} from "../../../../../packages/thunderstore-api/src";

export type Validator = {
required?: boolean;
};

interface UseStrongFormProps<
Inputs,
SubmissionDataShape,
Expand All @@ -13,6 +17,15 @@ interface UseStrongFormProps<
SubmissionError,
> {
inputs: Inputs;
/**
* Validators for the form inputs.
*
* NOTE: If you add new validator types here, make sure to implement the
* validation logic in the `isReady` memo inside `useStrongForm`.
*/
validators?: {
[K in keyof Inputs]?: Validator;
};
refiner?: (inputs: Inputs) => Promise<SubmissionDataShape>;
onRefineSuccess?: (output: SubmissionDataShape) => void;
onRefineError?: (error: RefinerError) => void;
Expand Down Expand Up @@ -45,6 +58,20 @@ export function useStrongForm<
const [submitError, setSubmitError] = useState<SubmissionError>();
const [inputErrors, setInputErrors] = useState<InputErrors>();

const isReady = useMemo(() => {
if (!props.validators) return true;
for (const key in props.validators) {
const validator = props.validators[key];
const value = props.inputs[key];
// NOTE: Expand the checks as more validators are added
if (validator?.required) {
if (typeof value === "string" && value.trim() === "") return false;
if (value === undefined || value === null) return false;
}
}
return true;
}, [props.inputs]);

useEffect(() => {
if (refining || submitting) {
return;
Expand Down Expand Up @@ -165,5 +192,6 @@ export function useStrongForm<
refining,
refineError,
inputErrors,
isReady,
};
}
Loading