Skip to content

Commit

Permalink
refactor(utils): refactor to return error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
seaerchin committed Sep 6, 2023
1 parent a3d2d47 commit 84a83e6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 29 deletions.
15 changes: 13 additions & 2 deletions src/layouts/EditHomepage/EditHomepage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import {
RESOURCES_SECTION,
} from "./constants"
import { HomepagePreview } from "./HomepagePreview"
import { getDefaultValues, getHasErrorFromHomepageState } from "./utils"
import { getDefaultValues, getErrorsFromHomepageState } from "./utils"

/* eslint-disable react/no-array-index-key */

Expand Down Expand Up @@ -160,6 +160,7 @@ const EditHomepage = ({ match }) => {
setDisplayHighlights(displayHighlights)
}
const heroSection = frontMatter.sections.filter((section) => !!section.hero)
const errorMessages = getErrorsFromHomepageState(homepageState)

const errorToast = useErrorToast()

Expand Down Expand Up @@ -1092,8 +1093,18 @@ const EditHomepage = ({ match }) => {
/>
</HStack>
<Footer>
{errorMessages.some((message) => message.includes("longer")) && (
<Text
mr="0.25rem"
textStyle="body-2"
textColor="base.content.medium"
>
You have blocks without content. Please add content to your
empty blocks before saving.
</Text>
)}
<LoadingButton
isDisabled={getHasErrorFromHomepageState(homepageState)}
isDisabled={errorMessages.length > 0}
onClick={savePage}
>
Save
Expand Down
62 changes: 35 additions & 27 deletions src/layouts/EditHomepage/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,65 @@ export const getDefaultValues = (
return _.mapValues(obj, () => "")
}

const validate = <T>(
obj: Record<string, T>,
predicate: (key: string, val: T) => string
): string[] => {
return _(obj)
.entries()
.map(([key, value]) => predicate(key, value))
.filter()
.value()
}

// NOTE: We might wish to extend this so that we map the values to
// error msg etc then extract an overall boolean based on that
// but for now will return a bool
export const getHasErrorFromHomepageState = ({
export const getErrorsFromHomepageState = ({
frontMatter,
}: EditorHomepageState) => {
}: EditorHomepageState): string[] => {
// we validate the frontmatter to check that all the fields are valid
const { sections } = frontMatter
const [initialSection, ...rest] = sections
const heroSection = (initialSection as HeroFrontmatterSection).hero

let hasError = false
let errorMessages: string[] = []
if (isHighlightSection(heroSection)) {
hasError = heroSection.key_highlights.reduce((acc, cur) => {
const curErr = _(cur)
.entries()
.map(([key, value]) => validateHighlight(key, value))
.some()
return acc || curErr
}, hasError)
const highlightErrors = heroSection.key_highlights.reduce((acc, cur) => {
const curError = validate(cur, validateHighlight)
return [...acc, ...curError]
}, errorMessages)
errorMessages = [...errorMessages, ...highlightErrors]
}

// NOTE: This is mutually exclusive with the above check
// as our hero section only has these 2 options.
if (isDropdownSection(heroSection)) {
hasError = heroSection.dropdown.options.reduce((acc, cur) => {
const curError = _(cur)
.entries()
.map(([key, value]) => validateDropdownElem(key, value))
.some()
return acc || curError
}, hasError)
const dropdownErrors = heroSection.dropdown.options.reduce((acc, cur) => {
const curError = validate(cur, validateDropdownElem)
return [...acc, ...curError]
}, errorMessages)
errorMessages = [...errorMessages, ...dropdownErrors]
}

// NOTE: Section is an object keyed by the section type
// this is, for example, `{ infobar: someValue }`
const hasSectionErrors = _(rest)
const sectionErrors = _(rest)
.map((section) =>
// NOTE: Section obj contains the actual values to validate
// this is, for example, `title`/`subtitle`/`button` etc
_.entries(section).map(([sectionType, sectionObj]) =>
// NOTE: Check if there is some value for which validation failed
// we know validation fail as it returns a non-empty string
_.some(
sectionObj,
(val, key) => !!validateSection(sectionType, key, val)
_(section)
.entries()
.map(([sectionType, sectionObj]) =>
validate(sectionObj, (key, val) =>
validateSection(sectionType, key, val)
)
)
)
.flatten()
.value()
)
.flatten()
.some()
.value()

return hasError || hasSectionErrors
return [...errorMessages, ...sectionErrors]
}

0 comments on commit 84a83e6

Please sign in to comment.