-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace redux-form with react-final-form and clean up some of the routing and redux data fetching
- Loading branch information
Showing
4 changed files
with
119 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Button } from '@webkom/lego-bricks'; | ||
import { spySubmittable } from 'app/utils/formSpyUtils'; | ||
import type { ReactNode } from 'react'; | ||
|
||
type Props = { | ||
children: ReactNode; | ||
}; | ||
|
||
export const SubmitButton = ({ children }: Props) => | ||
spySubmittable((submittable) => ( | ||
<Button submit disabled={!submittable}> | ||
{children} | ||
</Button> | ||
)); |
This file was deleted.
Oops, something went wrong.
226 changes: 103 additions & 123 deletions
226
app/routes/events/components/EventAdministrate/AdminRegister.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,111 @@ | ||
import { Button } from '@webkom/lego-bricks'; | ||
import { Field } from 'redux-form'; | ||
import { waitinglistPoolId } from 'app/actions/EventActions'; | ||
import { legoForm, TextEditor, SelectInput } from 'app/components/Form'; | ||
import { RenderErrorMessage } from 'app/components/Form/Field'; | ||
import type { ID, EventPool, User } from 'app/models'; | ||
import type { FormProps } from 'react-redux'; | ||
import { LoadingIndicator } from '@webkom/lego-bricks'; | ||
import { Field } from 'react-final-form'; | ||
import { adminRegister, waitinglistPoolId } from 'app/actions/EventActions'; | ||
import { TextEditor, SelectInput } from 'app/components/Form'; | ||
import LegoFinalForm from 'app/components/Form/LegoFinalForm'; | ||
import SubmissionError from 'app/components/Form/SubmissionError'; | ||
import { SubmitButton } from 'app/components/Form/SubmitButton'; | ||
import { selectPoolsForEvent } from 'app/reducers/events'; | ||
import { useAppDispatch, useAppSelector } from 'app/store/hooks'; | ||
import type { DetailedEvent } from 'app/store/models/Event'; | ||
import type { AutocompleteUser } from 'app/store/models/User'; | ||
import { createValidator, required } from 'app/utils/validation'; | ||
import type { FormApi } from 'final-form'; | ||
|
||
type Props = { | ||
eventId: ID; | ||
adminRegister: ( | ||
arg0: ID, | ||
arg1: ID, | ||
arg2: ID, | ||
arg3: string, | ||
arg4: string | ||
) => Promise<any>; | ||
pools: Array<EventPool>; | ||
} & FormProps; | ||
|
||
const AdminRegister = ({ | ||
handleSubmit, | ||
pools, | ||
invalid, | ||
pristine, | ||
submitting, | ||
error, | ||
}: Props) => { | ||
return ( | ||
<div | ||
style={{ | ||
width: '400px', | ||
}} | ||
> | ||
<form onSubmit={handleSubmit}> | ||
<Field | ||
placeholder="Begrunnelse" | ||
label="Begrunnelse" | ||
name="adminRegistrationReason" | ||
component={TextEditor.Field} | ||
/> | ||
<Field | ||
placeholder="Tilbakemelding" | ||
label="Tilbakemelding" | ||
name="feedback" | ||
component={TextEditor.Field} | ||
/> | ||
<Field | ||
name="pool" | ||
component={SelectInput.Field} | ||
placeholder="Pool" | ||
label="Pool" | ||
options={pools | ||
.map((pool) => ({ | ||
value: pool.id, | ||
label: pool.name, | ||
})) | ||
.concat([ | ||
{ | ||
value: waitinglistPoolId, | ||
label: 'Venteliste', | ||
}, | ||
])} | ||
/> | ||
<Field | ||
name="user" | ||
component={SelectInput.AutocompleteField} | ||
filter={['users.user']} | ||
placeholder="Bruker" | ||
label="Bruker" | ||
/> | ||
<RenderErrorMessage error={error} /> | ||
<Button type="submit" disabled={invalid || pristine || submitting}> | ||
Registrer | ||
</Button> | ||
</form> | ||
</div> | ||
); | ||
type FormValues = { | ||
user: AutocompleteUser; | ||
pool: { | ||
value: number; | ||
label: string; | ||
}; | ||
feedback: string; | ||
adminRegistrationReason: string; | ||
}; | ||
|
||
function validateForm(data) { | ||
const errors = {}; | ||
|
||
if (!data.reason) { | ||
errors.reason = 'Forklaring er påkrevet'; | ||
} | ||
type Props = { | ||
event: DetailedEvent; | ||
}; | ||
|
||
if (!data.pool) { | ||
errors.pool = 'Pool er påkrevet'; | ||
} | ||
const AdminRegister = (props: Props) => { | ||
const { event } = props; | ||
const fetching = useAppSelector((state) => state.events.fetching); | ||
const pools = useAppSelector((state) => | ||
selectPoolsForEvent(state, { | ||
eventId: event.id, | ||
}) | ||
); | ||
|
||
if (!data.user) { | ||
errors.user = 'Bruker er påkrevet'; | ||
} | ||
const dispatch = useAppDispatch(); | ||
const onSubmit = async (values: FormValues, form: FormApi<FormValues>) => { | ||
await dispatch( | ||
adminRegister( | ||
event.id, | ||
values.user.id, | ||
values.pool?.value, | ||
values.feedback, | ||
values.adminRegistrationReason | ||
) | ||
); | ||
form.restart(); | ||
}; | ||
|
||
return errors; | ||
} | ||
return ( | ||
<LoadingIndicator loading={fetching}> | ||
<LegoFinalForm onSubmit={onSubmit} validate={validate} subscription={{}}> | ||
{({ handleSubmit }) => ( | ||
<form onSubmit={handleSubmit}> | ||
<Field | ||
required | ||
name="user" | ||
component={SelectInput.AutocompleteField} | ||
filter={['users.user']} | ||
placeholder="Bruker" | ||
label="Bruker" | ||
/> | ||
<Field | ||
required | ||
name="pool" | ||
component={SelectInput.Field} | ||
placeholder="Pool" | ||
label="Pool" | ||
options={pools | ||
.map((pool) => ({ | ||
value: pool.id, | ||
label: pool.name, | ||
})) | ||
.concat([ | ||
{ | ||
value: waitinglistPoolId, | ||
label: 'Venteliste', | ||
}, | ||
])} | ||
/> | ||
<Field | ||
required | ||
placeholder="Begrunnelse" | ||
label="Begrunnelse" | ||
name="adminRegistrationReason" | ||
component={TextEditor.Field} | ||
/> | ||
<Field | ||
placeholder="Tilbakemelding" | ||
label="Melding til arrangør" | ||
name="feedback" | ||
component={TextEditor.Field} | ||
/> | ||
<SubmissionError /> | ||
<SubmitButton>Adminregistrer</SubmitButton> | ||
</form> | ||
)} | ||
</LegoFinalForm> | ||
</LoadingIndicator> | ||
); | ||
}; | ||
|
||
const onSubmit = ( | ||
{ | ||
user, | ||
pool, | ||
feedback, | ||
adminRegistrationReason, | ||
}: { | ||
user: User; | ||
pool: { | ||
value: number; | ||
label: string; | ||
}; | ||
feedback: string; | ||
adminRegistrationReason: string; | ||
}, | ||
_, | ||
{ reset, eventId, adminRegister }: Props | ||
) => | ||
adminRegister( | ||
eventId, | ||
user.id, | ||
pool?.value, | ||
feedback, | ||
adminRegistrationReason | ||
).then(() => { | ||
reset(); | ||
}); | ||
const validate = createValidator({ | ||
adminRegistrationReason: [required()], | ||
pool: [required()], | ||
user: [required()], | ||
}); | ||
|
||
export default legoForm({ | ||
form: 'adminRegister', | ||
validate: validateForm, | ||
onSubmit, | ||
})(AdminRegister); | ||
export default AdminRegister; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters