Skip to content

Commit

Permalink
fix(ojoi): Updated controllers and bugfixes (#17146)
Browse files Browse the repository at this point in the history
* Updated data schema to make less api calls, fixed bug when user selected a previous advert the inputs fields were not updating. Switched out controller components since we have our own.

* Returning false instead of undefined.

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
jonbjarnio and kodiakhq[bot] authored Dec 5, 2024
1 parent 4704971 commit 2804be7
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 277 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SkeletonLoader } from '@island.is/island-ui/core'
import { Input, SkeletonLoader } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
import { InputController } from '@island.is/shared/form-fields'
import { MessageDescriptor } from 'react-intl'
import { OJOI_INPUT_HEIGHT } from '../../lib/constants'
import { useApplication } from '../../hooks/useUpdateApplication'
Expand Down Expand Up @@ -60,7 +59,7 @@ export const OJOIInputController = ({
}

return (
<InputController
<Input
id={name}
name={name}
label={labelText}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
import { SkeletonLoader } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
import { SelectController } from '@island.is/shared/form-fields'
import { MessageDescriptor } from 'react-intl'
import { OJOI_INPUT_HEIGHT } from '../../lib/constants'
import { useApplication } from '../../hooks/useUpdateApplication'
import { OJOIApplication } from '../../lib/types'
import { useFormContext } from 'react-hook-form'
import set from 'lodash/set'
import { InputFields } from '../../lib/types'
import { Select, SkeletonLoader } from '@island.is/island-ui/core'
import { OJOI_INPUT_HEIGHT } from '../../lib/constants'
import { isBaseEntity } from '../../lib/utils'
import { getValueViaPath } from '@island.is/application/core'

type OJOISelectControllerOption = {
type SelectOption<T> = {
label: string
value: string
value: T
}

type Props = {
type Props<T> = {
name: string
label: string | MessageDescriptor
placeholder: string | MessageDescriptor
options?: OJOISelectControllerOption[]
defaultValue?: string
options?: SelectOption<T>[]
defaultValue?: T
loading?: boolean
applicationId: string
disabled?: boolean
onChange?: (label: string, value: string) => void
onBeforeChange?: (answers: OJOIApplication['answers'], value: T) => void
onChange?: (value: T) => void
}

export const OJOISelectController = ({
export const OJOISelectController = <T,>({
name,
label,
placeholder,
Expand All @@ -33,30 +36,41 @@ export const OJOISelectController = ({
loading,
applicationId,
disabled,
onBeforeChange,
onChange,
}: Props) => {
}: Props<T>) => {
const { formatMessage: f } = useLocale()
const { updateApplication, application } = useApplication({ applicationId })
const { updateApplication, application } = useApplication({
applicationId,
})

const { setValue } = useFormContext()

const placeholderText =
typeof placeholder === 'string' ? placeholder : f(placeholder)

const labelText = typeof label === 'string' ? label : f(label)

const handleChange = (label: string, value: string) => {
const handleChange = (value: T) => {
const currentAnswers = structuredClone(application.answers)
const newAnswers = set(currentAnswers, name, value)
onBeforeChange && onBeforeChange(newAnswers, value)

// we must reset the selected typeId if the department changes
if (name === InputFields.advert.departmentId) {
set(newAnswers, InputFields.advert.typeId, '')
}

setValue(name, value)
updateApplication(newAnswers)

onChange && onChange(label, value)
onChange && onChange(value)
}

const defaultVal = getValueViaPath(application.answers, name, defaultValue)
const defaultOpt = options?.find((opt) => {
if (isBaseEntity(opt.value) && isBaseEntity(defaultVal)) {
return opt.value.id === defaultVal.id
}

return false
})

if (loading) {
return (
<SkeletonLoader
Expand All @@ -68,17 +82,19 @@ export const OJOISelectController = ({
}

return (
<SelectController
id={name}
<Select
size="sm"
name={name}
label={labelText}
isDisabled={disabled}
placeholder={placeholderText}
size="sm"
backgroundColor="blue"
options={options}
defaultValue={defaultValue}
disabled={disabled}
onSelect={(opt) => handleChange(opt.label, opt.value)}
defaultValue={defaultOpt}
onChange={(opt) => {
if (!opt?.value) return
return handleChange(opt.value)
}}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useCallback } from 'react'
import { InputFields, OJOIFieldBaseProps } from '../lib/types'
import { Box } from '@island.is/island-ui/core'
import { FormGroup } from '../components/form/FormGroup'
Expand All @@ -15,86 +14,80 @@ import set from 'lodash/set'
import { HTMLEditor } from '../components/htmlEditor/HTMLEditor'
import { getAdvertMarkup } from '../lib/utils'

type Props = OJOIFieldBaseProps & {
timeStamp: string
}

export const Advert = ({ application, timeStamp }: Props) => {
export const Advert = ({ application }: OJOIFieldBaseProps) => {
const { setValue } = useFormContext()
const { application: currentApplication, updateApplication } = useApplication(
{
applicationId: application.id,
},
)
const { application: currentApplication } = useApplication({
applicationId: application.id,
})
const { departments, loading: loadingDepartments } = useDepartments()
const {
useLazyTypes,
getLazyTypes,
types,
loading: loadingTypes,
} = useTypes({
initalDepartmentId: application.answers?.advert?.departmentId,
initalDepartmentId: application.answers?.advert?.department?.id,
})

const handleDepartmentChange = useCallback(
(value: string) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useLazyTypes({
params: {
department: value,
pageSize: 100,
},
})
},
[useLazyTypes],
)

const updateTypeHandler = (name: string, id: string) => {
let currentAnswers = structuredClone(currentApplication.answers)
currentAnswers = set(currentAnswers, InputFields.advert.typeName, name)

currentAnswers = set(currentAnswers, InputFields.advert.typeId, id)

updateApplication(currentAnswers)
}

const titlePreview = getAdvertMarkup({
type: currentApplication.answers.advert?.typeName,
type: currentApplication.answers.advert?.type?.title,
title: currentApplication.answers.advert?.title,
})

const departmentOptions = departments?.map((d) => ({
label: d.title,
value: {
id: d.id,
title: d.title,
slug: d.slug,
},
}))

const typeOptions = types?.map((d) => ({
label: d.title,
value: {
id: d.id,
title: d.title,
slug: d.slug,
},
}))

return (
<>
<FormGroup>
<Box className={styles.inputWrapper}>
<OJOISelectController
applicationId={application.id}
name={InputFields.advert.departmentId}
name={InputFields.advert.department}
label={advert.inputs.department.label}
placeholder={advert.inputs.department.placeholder}
loading={loadingDepartments}
options={departments?.map((d) => ({
label: d.title,
value: d.id,
}))}
onChange={(_, value) => handleDepartmentChange(value)}
options={departmentOptions}
defaultValue={application.answers?.advert?.department}
onBeforeChange={(answers) => {
setValue(InputFields.advert.type, null)
set(answers, InputFields.advert.type, null)
}}
onChange={(value) =>
getLazyTypes({
variables: {
params: {
department: value.id,
pageSize: 100,
},
},
})
}
/>
</Box>
<Box className={styles.inputWrapper}>
<OJOISelectController
applicationId={application.id}
name={InputFields.advert.typeId}
name={InputFields.advert.type}
label={advert.inputs.type.label}
placeholder={advert.inputs.type.placeholder}
loading={loadingTypes}
disabled={!types}
defaultValue={application.answers?.advert?.typeId}
options={types?.map((d) => ({
label: d.title,
value: d.id,
}))}
onChange={(label, value) => {
updateTypeHandler(label, value)
}}
options={typeOptions}
/>
</Box>
<Box>
Expand Down Expand Up @@ -132,7 +125,6 @@ export const Advert = ({ application, timeStamp }: Props) => {
applicationId={application.id}
name={InputFields.advert.html}
defaultValue={currentApplication.answers?.advert?.html}
editorKey={timeStamp}
// we have use setValue from useFormContext to update the value
// because this is not a controlled component
onChange={(value) => setValue(InputFields.advert.html, value)}
Expand Down
Loading

0 comments on commit 2804be7

Please sign in to comment.