Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically render form field in Create Dataset Form + Fields Validations #369

Merged
merged 67 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
3367103
feat(DynamicFormFieldsRender): Initial setup with mocked data
g-saracca Mar 20, 2024
e15c6e4
feat(DesignSystem): using Accordion own props and extending Accordion…
g-saracca Mar 21, 2024
969823b
feat(DynamicFormFieldsRender): filter blocks and fields
g-saracca Mar 21, 2024
2f4af31
feat(DynamicFormFieldsRender): remove custom styles from accordion an…
g-saracca Mar 22, 2024
faa52da
feat(DynamicFormFieldsRender): detecting different fields
g-saracca Mar 22, 2024
349b444
feat(DynamicFormFieldsRender): Different fields and wrapper
g-saracca Mar 25, 2024
8d1a15f
feat(DynamicFormFieldsRender): Update models and mock
g-saracca Mar 25, 2024
3fee0b6
feat(DynamicFormFieldsRender): Refactor to avoid for now multiple act…
g-saracca Mar 25, 2024
5566900
feat: change styles for checbox group
g-saracca Mar 26, 2024
57632ec
feat: add names to form fields
g-saracca Mar 26, 2024
01acf84
Merge branch 'feature/316-create-functional-create-dataset-form' into…
g-saracca Mar 26, 2024
f1a6d37
feat(DynamicFormFieldsRender): Add metadta block form fields skeleton
g-saracca Mar 26, 2024
d18f576
feat(design system): Clone through fragments recursively
g-saracca Mar 27, 2024
c788028
feat: Allow form fields to inherit props like required and withinMult…
g-saracca Mar 27, 2024
fc731a1
test(Dynamic Fields): Add component test for dynamic fields
g-saracca Mar 27, 2024
d5bea19
test(Dynamic Fields): Refactor Fields
g-saracca Mar 28, 2024
501434f
test(Dynamic Fields): Multiple refactor to use mocked data response
g-saracca Mar 28, 2024
8378a4c
feat(Dynamic Fields): Add stories and its mocks repositories
g-saracca Mar 28, 2024
3a4291e
feat(Dynamic Fields): Add more tests
g-saracca Mar 28, 2024
4215794
feat(Dynamic Fields): Skip test of submiting valid form
g-saracca Mar 28, 2024
9857e9b
feat(Dynamic Fields): Add test for rendering childrens trough react f…
g-saracca Mar 28, 2024
7fde401
Merge pull request #357 from IQSS/feature/336-dynamically-render-form…
g-saracca Apr 1, 2024
69d7aca
feat: Install react-hook-form library
g-saracca Apr 1, 2024
5403001
feat: Add placeholder prop
g-saracca Apr 1, 2024
aeccafa
fix(design system): Remove span from feedback col causing overflow-x
g-saracca Apr 2, 2024
65ac28e
chore: avoid checking voids return on attributes
g-saracca Apr 2, 2024
a7e05fa
feat: forward ref to Fields
g-saracca Apr 2, 2024
4843632
feat(design system): forward refs to form-elements
g-saracca Apr 2, 2024
ae9244e
feat: replicate borders for checkbox group, more forward refs and rem…
g-saracca Apr 2, 2024
7f25f14
chore: comment unused imports temporarily
g-saracca Apr 2, 2024
db641b2
feat: validations in progress
g-saracca Apr 4, 2024
4abfaa7
feat: validations done
g-saracca Apr 4, 2024
fc1f36e
feat: use real endpoint refactor
g-saracca Apr 5, 2024
3b3154b
fix: use items as router Links and add collectionId to route link
g-saracca Apr 5, 2024
62ff552
refactor: collectionId could either be a number or a string
g-saracca Apr 5, 2024
37af53a
feat: change vocabulary multiple to work with checkboxes
g-saracca Apr 6, 2024
c79ad59
feat(design system): forward ref to checkbox input
g-saracca Apr 6, 2024
1ed3a0e
feat: Remove unnecesary props from fields
g-saracca Apr 6, 2024
6fc322a
feat: Use locales for fields validations
g-saracca Apr 6, 2024
5b874e5
feat: Add feedback validation to checkbox group
g-saracca Apr 6, 2024
42378c1
feat: map metadatablock info fields names with dots to slashes to avo…
g-saracca Apr 6, 2024
c386f84
feat: map metadatablock info fields names and viceversa on form submit
g-saracca Apr 8, 2024
d00d4e9
feat: finish formatting form values to DTO
g-saracca Apr 8, 2024
9dde1ec
feat: Add test cases to cover validation rules
g-saracca Apr 10, 2024
acdee29
feat: rename metadaBlockInfo types
g-saracca Apr 10, 2024
26b8c2c
feat: More testings
g-saracca Apr 10, 2024
08dd236
feat: finish with component testing and remove submitting state becau…
g-saracca Apr 10, 2024
599ab9b
chore: use different version of client-js
g-saracca Apr 10, 2024
d6fa9fa
feat: small changes reading submitting state
g-saracca Apr 10, 2024
d3276a5
test: refactor e2e test
g-saracca Apr 11, 2024
2e6e97c
feat: back to original submitting state
g-saracca Apr 11, 2024
cf4ead7
chore: remove comments
g-saracca Apr 11, 2024
60eeb53
Merge pull request #368 from IQSS/feature/338-form-validation-library
g-saracca Apr 11, 2024
3a31ef4
Merge branch 'develop' into feature/sub-branch/dynamic-fields-and-val…
g-saracca Apr 11, 2024
3338768
feat: Bring back error validation alert and add tests
g-saracca Apr 11, 2024
06ecc4b
refactor: simplify fields rendering
g-saracca Apr 15, 2024
cb8be83
refactor: remove comments and add return types
g-saracca Apr 15, 2024
3f56ec4
refactor: simplify tests by asserting with non-unique data attribute
g-saracca Apr 15, 2024
5e6ab11
refactor: add specific use case for only display on create
g-saracca Apr 15, 2024
f9c572e
chore: update client-js lib
g-saracca Apr 15, 2024
3e3d1c7
refactor: change utils folder to helper class
g-saracca Apr 15, 2024
3c2be40
refactor: change test file name
g-saracca Apr 15, 2024
d48f063
refactor: use own specific props
g-saracca Apr 15, 2024
f27a468
docs: add non published changes to CHANGELOG
g-saracca Apr 15, 2024
5dccfe8
merge branch develop into feature/sub-branc/dynamic-fields-validation
g-saracca Apr 15, 2024
686245a
Merge branch 'develop' into feature/sub-branch/dynamic-fields-and-val…
g-saracca Apr 16, 2024
321a41c
refactor: Remove story because of files no longer in existence
g-saracca Apr 16, 2024
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
8 changes: 8 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
"trailingComma": "none",
"bracketSameLine": true
}
],
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": {
"attributes": false
}
}
]
},
"overrides": [
Expand Down
2 changes: 1 addition & 1 deletion .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["export"]
"ignorePseudoClasses": ["export", "global"]
}
],
"property-no-unknown": [
Expand Down
95 changes: 20 additions & 75 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@faker-js/faker": "7.6.0",
"@iqss/dataverse-client-javascript": "2.0.0-pr132.dd49caf",
"@iqss/dataverse-client-javascript": "2.0.0-pr141.2d54907",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand All @@ -33,6 +33,7 @@
"moment-timezone": "0.5.43",
"react-bootstrap": "2.7.2",
"react-bootstrap-icons": "1.10.3",
"react-hook-form": "7.51.2",
"react-i18next": "12.1.5",
"react-infinite-scroll-hook": "4.1.1",
"react-loader-spinner": "5.3.4",
Expand Down
14 changes: 3 additions & 11 deletions packages/design-system/src/lib/components/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { ReactNode } from 'react'
import { Accordion as AccordionBS } from 'react-bootstrap'
import { Accordion as AccordionBS, AccordionProps as AccordionPropsBS } from 'react-bootstrap'
import { AccordionItem } from './AccordionItem'
import { AccordionBody } from './AccordionBody'
import { AccordionHeader } from './AccordionHeader'

interface AccordionProps {
defaultActiveKey?: string[] | string
alwaysOpen?: boolean
children: ReactNode
}

function Accordion({ defaultActiveKey, children, alwaysOpen = false }: AccordionProps) {
function Accordion({ alwaysOpen = false, children, ...rest }: AccordionPropsBS) {
return (
g-saracca marked this conversation as resolved.
Show resolved Hide resolved
<AccordionBS defaultActiveKey={defaultActiveKey} alwaysOpen={alwaysOpen}>
<AccordionBS alwaysOpen={alwaysOpen} {...rest}>
{children}
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
</AccordionBS>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ReactNode } from 'react'
import { ElementType, ReactNode } from 'react'
import { Accordion as AccordionBS } from 'react-bootstrap'

interface AccordionBodyProps {
interface AccordionBodyProps extends React.HTMLAttributes<HTMLElement> {
children: ReactNode
bsPrefix?: string
as?: ElementType
}

export function AccordionBody({ children }: AccordionBodyProps) {
return <AccordionBS.Body>{children}</AccordionBS.Body>
export function AccordionBody({ children, ...rest }: AccordionBodyProps) {
return <AccordionBS.Body {...rest}>{children}</AccordionBS.Body>
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ReactNode } from 'react'
import { ElementType, ReactNode } from 'react'
import { Accordion as AccordionBS } from 'react-bootstrap'

interface AccordionHeaderProps {
interface AccordionHeaderProps extends React.HTMLAttributes<HTMLElement> {
children: ReactNode
onClick?: () => void
bsPrefix?: string
as?: ElementType
}

export function AccordionHeader({ children }: AccordionHeaderProps) {
return <AccordionBS.Header>{children}</AccordionBS.Header>
export function AccordionHeader({ children, ...rest }: AccordionHeaderProps) {
return <AccordionBS.Header {...rest}>{children}</AccordionBS.Header>
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ReactNode } from 'react'
import { ElementType, ReactNode } from 'react'
import { Accordion as AccordionBS } from 'react-bootstrap'

interface AccordionItemProps {
export interface AccordionItemProps extends React.HTMLAttributes<HTMLElement> {
eventKey: string
children: ReactNode
bsPrefix?: string
as?: ElementType
}

export function AccordionItem({ eventKey, children }: AccordionItemProps) {
return <AccordionBS.Item eventKey={eventKey}>{children}</AccordionBS.Item>
export function AccordionItem({ children, ...rest }: AccordionItemProps) {
return <AccordionBS.Item {...rest}>{children}</AccordionBS.Item>
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "src/lib/assets/styles/design-tokens/typography.module";
@import 'src/lib/assets/styles/design-tokens/typography.module';

.title {
padding-top: calc(0.375rem + 1px);
padding-bottom: calc(0.375rem + 1px);
display: inline-block;
margin-bottom: 0.5rem;
font-weight: $dv-font-weight-bold;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function FormCheckboxGroup({
}: PropsWithChildren<FormCheckboxGroupProps>) {
const validationClass = isInvalid ? 'is-invalid' : isValid ? 'is-valid' : ''
return (
<Row>
<Row className="mb-3">
<Col sm={3}>
<span className={styles.title}>
{title} {required && <RequiredInputSymbol />}{' '}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,21 @@ export function FormGroupWithMultipleFields({
const isFirstField = index == 0

return (
<Row key={index}>
<Row key={index} className="mb-3">
<Col sm={3}>
{isFirstField && <Title title={title} required={required} message={message} />}
</Col>
<Col sm={6}>{field}</Col>
<Col sm={3}>
{withDynamicFields && (
<Col sm={withDynamicFields ? 6 : 9}>{field}</Col>

{withDynamicFields && (
<Col sm={3}>
<DynamicFieldsButtons
originalField={isFirstField}
onAddButtonClick={() => addField(field)}
onRemoveButtonClick={() => removeField(index)}
/>
)}
</Col>
</Col>
)}
</Row>
)
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,7 @@ function FormGroup({
children,
...props
}: PropsWithChildren<FormGroupProps>) {
const childrenWithRequiredProp = React.Children.map(children as JSX.Element, (child) => {
return React.cloneElement(child, {
required: required,
withinMultipleFieldsGroup: as === Col
})
})
const childrenWithRequiredProp = cloneThroughFragments(children, required, as)

return (
<FormBS.Group
Expand All @@ -42,6 +37,29 @@ function FormGroup({
</FormBS.Group>
)
}
function cloneThroughFragments(
children: React.ReactNode,
required?: boolean,
as?: typeof Col | typeof Row
): React.ReactNode {
return React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
if (child.type === React.Fragment) {
const hasChildren = (props: unknown): props is { children: React.ReactNode } =>
typeof props === 'object' && Object.hasOwnProperty.call(props, 'children')

if (hasChildren(child.props)) {
return cloneThroughFragments(child.props.children, required, as)
}
}
return React.cloneElement(child as React.ReactElement, {
required: required,
withinMultipleFieldsGroup: as === Col
})
}
return child
})
}

FormGroup.Label = FormLabel
FormGroup.Input = FormInput
Expand Down
Loading
Loading