Skip to content

Commit

Permalink
Feature/input validation (#512)
Browse files Browse the repository at this point in the history
* feature: Added input validation when creating and editing a community (#172)

* feature: Added input validation when creating and editing a community

* feature: Added input validation when creating and editing a community

* feature: Added input validation when creating and editing a community
  • Loading branch information
espensimensen authored Dec 1, 2023
1 parent 9066af2 commit caf1a2a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 14 deletions.
36 changes: 32 additions & 4 deletions src/devhub/components/molecule/Input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@ const TextInput = ({
? type
: "text";

const isValid = () => {
if (!value || value.length === 0) {
return !inputProps.required;
} else if (inputProps.min && inputProps.min > value?.length) {
return false;
} else if (inputProps.max && inputProps.max < value?.length) {
return false;
} else if (
inputProps.allowCommaAndSpace === false &&
/^[^,\s]*$/.test(value) === false
) {
return false;
} else if (
inputProps.validUrl === true &&
/^(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/.test(
value
) === false
) {
return false;
}
return true;
};

const renderedLabels = [
(label?.length ?? 0) > 0 ? (
<span className="d-inline-flex gap-1 text-wrap">
Expand All @@ -36,17 +59,20 @@ const TextInput = ({

format === "comma-separated" ? (
<span
className="d-inline-flex align-items-center text-muted"
className={`d-inline-flex align-items-center ${
isValid() ? "text-muted" : "text-danger"
}`}
style={{ fontSize: 12 }}
>
{format}
</span>
) : null,

(inputProps.max ?? null) !== null ? (
<span className="d-inline-flex text-muted" style={{ fontSize: 12 }}>{`${
value?.length ?? 0
} / ${inputProps.max}`}</span>
<span
className={`d-inline-flex ${isValid() ? "text-muted" : "text-danger"}`}
style={{ fontSize: 12 }}
>{`${value?.length ?? 0} / ${inputProps.max}`}</span>
) : null,
].filter((label) => label !== null);

Expand Down Expand Up @@ -81,6 +107,7 @@ const TextInput = ({
" "
)}
type={typeAttribute}
maxLength={inputProps.max}
{...{ onChange, placeholder, value, ...inputProps }}
/>
</div>
Expand All @@ -94,6 +121,7 @@ const TextInput = ({
}
style={{ resize: inputProps.resize ?? "vertical" }}
type={typeAttribute}
maxLength={inputProps.max}
{...{ onChange, placeholder, value, ...inputProps }}
/>
)}
Expand Down
40 changes: 37 additions & 3 deletions src/devhub/components/organism/Configurator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,49 @@ const Configurator = ({
? toFormatted(form.values)
: form.values;

const isFormValid = isValid ? isValid(formFormattedValues) : true;
const internalValidation = () =>
Object.keys(schema).every((key) => {
const fieldDefinition = schema[key];
const value = form.values[key];
if (!value || value.length === 0) {
return !fieldDefinition.inputProps.required;
} else if (
fieldDefinition.inputProps.min &&
fieldDefinition.inputProps.min > value?.length
) {
return false;
} else if (
fieldDefinition.inputProps.max &&
fieldDefinition.inputProps.max < value?.length
) {
return false;
} else if (
fieldDefinition.inputProps.allowCommaAndSpace === false &&
/^[^,\s]*$/.test(value) === false
) {
return false;
} else if (
fieldDefinition.inputProps.validUrl === true &&
/^(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/.test(
value
) === false
) {
return false;
}
return true;
});

const isFormValid = () => {
return internalValidation() && (!isValid || isValid(formFormattedValues));
};

const onCancelClick = () => {
form.reset();
if (onCancel) onCancel();
};

const onSubmitClick = () => {
if (onSubmit && isFormValid) {
if (onSubmit && isFormValid()) {
onSubmit(formFormattedValues);
}
};
Expand Down Expand Up @@ -298,7 +332,7 @@ const Configurator = ({
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Button"}
props={{
classNames: { root: classNames.submit || "btn-success" },
disabled: !form.hasUnsubmittedChanges || !isFormValid,
disabled: !form.hasUnsubmittedChanges || !isFormValid(),
icon: submitIcon || {
type: "bootstrap_icon",
variant: "bi-check-circle-fill",
Expand Down
5 changes: 2 additions & 3 deletions src/devhub/entity/community/Spawner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ const CommunityInputsPartialSchema = {
inputProps: {
min: 2,
max: 40,

allowCommaAndSpace: false,
placeholder:
"Choose unique URL handle for your community. Example: zero-knowledge.",

required: true,
},

Expand All @@ -38,7 +37,7 @@ const CommunityInputsPartialSchema = {
inputProps: {
min: 2,
max: 30,

allowCommaAndSpace: false,
placeholder:
"Any posts with this tag will show up in your community feed.",

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const CommunityAboutSchema = {

placeholder:
"Tell people about your community. This will appear on your community’s homepage.",

required: true,
resize: "none",
},

Expand Down Expand Up @@ -37,7 +37,7 @@ const CommunityAboutSchema = {
},

website_url: {
inputProps: { prefix: "https://", min: 2, max: 60 },
inputProps: { prefix: "https://", min: 2, max: 60, validUrl: true },
label: "Website",
order: 5,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const CommunityInformationSchema = {
inputProps: {
min: 2,
max: 40,

allowCommaAndSpace: false,
placeholder:
"Choose unique URL handle for your community. Example: zero-knowledge.",

Expand All @@ -45,7 +45,7 @@ const CommunityInformationSchema = {
inputProps: {
min: 2,
max: 30,

allowCommaAndSpace: false,
placeholder:
"Any posts with this tag will show up in your community feed.",

Expand Down

0 comments on commit caf1a2a

Please sign in to comment.