Skip to content

Commit

Permalink
Rewrite PollEditor to final-form
Browse files Browse the repository at this point in the history
  • Loading branch information
ollfkaih committed Feb 18, 2023
1 parent 960d408 commit 6b160fc
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 113 deletions.
228 changes: 115 additions & 113 deletions app/routes/polls/components/PollEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Component } from 'react';
import { Helmet } from 'react-helmet-async';
import { Form, Field, FieldArray } from 'redux-form';
import { Field } from 'react-final-form';
import { Form } from 'app/components/Form';
import { FieldArray } from 'react-final-form-arrays';
import arrayMutators from 'final-form-arrays';
import Button from 'app/components/Button';
import { Content } from 'app/components/Content';
import {
TextInput,
SelectInput,
TextArea,
legoForm,
CheckBox,
} from 'app/components/Form';
import Icon from 'app/components/Icon';
Expand All @@ -23,32 +25,29 @@ import type {
fieldArrayMetaPropTypes,
fieldArrayFieldsPropTypes,
} from 'redux-form';
import LegoFinalForm from 'app/components/Form/LegoFinalForm';

const keyCodes = {
enter: 13,
space: 32,
};
type Props = {
pristine: boolean;
submitting: boolean;
editOrCreatePoll: (arg0: PollEntity) => Promise<any>;
handleSubmit: (arg0: Record<string, any>) => Promise<any>;
//TODO add reduxForm typing
editing: boolean;
initialValues: PollEntity;
pollId: ID;
deletePoll: () => Promise<any>;
toggleEdit: () => void;
};
type FieldArrayPropTypes = {
/*type FieldArrayPropTypes = {
fields: fieldArrayFieldsPropTypes;
meta: fieldArrayMetaPropTypes;
};
};*/

const renderOptions = ({
fields,
meta: { touched, error },
}: FieldArrayPropTypes): ReactNode => (
const renderOptions = (
{ fields, meta: { touched, error } }: any /*FieldArrayPropTypes*/
): ReactNode => (
<div>
<ul className={styles.options}>
{fields.map((option, i) => (
Expand Down Expand Up @@ -82,92 +81,14 @@ const renderOptions = ({
</div>
);

class EditPollForm extends Component<Props, any> {
render() {
const { pristine, submitting, handleSubmit, editing, deletePoll } =
this.props;
return (
<Content>
<Helmet title={editing ? `Redigerer avstemning` : 'Ny avstemning'} />
{!editing && (
<NavigationTab
title="Ny avstemning"
back={{
label: 'Tilbake',
path: '/polls',
}}
/>
)}
<Form onSubmit={handleSubmit}>
<Field
name="title"
label="Spørsmål"
placeholder="Hva er din favorittrett?"
component={TextInput.Field}
required
/>
<span />
<Field
name="description"
label="Beskrivelse"
placeholder="Mer info..."
component={TextArea.Field}
/>
<Field
name="pinned"
label="Vis på forsiden"
component={CheckBox.Field}
/>
<Field
name="resultsHidden"
label="Skjul resultatet"
component={CheckBox.Field}
/>
<Field
name="tags"
label="Tags"
filter={['tags.tag']}
placeholder="Skriv inn tags"
component={SelectInput.AutocompleteField}
isMulti
tags
shouldKeyDownEventCreateNewOption={({
keyCode,
}: {
keyCode: number;
}) => keyCode === keyCodes.enter || keyCode === keyCodes.space}
/>
<FieldArray
name="options"
component={renderOptions}
rerenderOnEveryChange={true}
/>
<Flex className={styles.actionButtons}>
<Button disabled={pristine || submitting} success={editing} submit>
{editing ? 'Lagre endringer' : 'Lag ny avstemning'}
</Button>
{editing && (
<ConfirmModalWithParent
title="Slett avstemning"
message="Er du sikker på at du vil slette avstemningen?"
onConfirm={deletePoll}
closeOnConfirm
>
<Button danger>
<Icon name="trash" size={19} />
Slett avstemning
</Button>
</ConfirmModalWithParent>
)}
</Flex>
</Form>
</Content>
);
}
}

const onSubmit = (
{
const EditPollForm = ({
deletePoll,
editOrCreatePoll,
editing,
initialValues,
toggleEdit,
}: Props) => {
const onSubmit = ({
title,
description,
tags,
Expand All @@ -187,27 +108,108 @@ const onSubmit = (
}>;
resultsHidden: boolean;
pinned: boolean;
},
dispatch,
props
) =>
props
.editOrCreatePoll({
}) =>
editOrCreatePoll({
title,
description,
resultsHidden,
tags: tags ? tags.map((val) => val.value) : [],
options,
pinned: pinned ? pinned : false,
...(rest as Record<string, any>),
})
.then(() => props.toggleEdit());
}).then(() => toggleEdit());

return (
<Content>
<Helmet title={editing ? `Redigerer avstemning` : 'Ny avstemning'} />
{!editing && (
<NavigationTab
title="Ny avstemning"
back={{
label: 'Tilbake',
path: '/polls',
}}
/>
)}
<LegoFinalForm
onSubmit={onSubmit}
initialValues={initialValues ?? { options: [{}, {}], pinned: false }}
mutators={{
...arrayMutators,
}}
>
{({ handleSubmit, pristine, submitting }) => (
<Form onSubmit={handleSubmit}>
<Field
name="title"
label="Spørsmål"
placeholder="Hva er din favorittrett?"
component={TextInput.Field}
required
/>
<span />
<Field
name="description"
label="Beskrivelse"
placeholder="Mer info..."
component={TextArea.Field}
/>
<Field
name="pinned"
label="Vis på forsiden"
component={CheckBox.Field}
/>
<Field
name="resultsHidden"
label="Skjul resultatet"
component={CheckBox.Field}
/>
<Field
name="tags"
label="Tags"
filter={['tags.tag']}
placeholder="Skriv inn tags"
component={SelectInput.AutocompleteField}
isMulti
tags
shouldKeyDownEventCreateNewOption={({
keyCode,
}: {
keyCode: number;
}) => keyCode === keyCodes.enter || keyCode === keyCodes.space}
/>
<FieldArray
name="options"
component={renderOptions}
rerenderOnEveryChange={true}
/>
<Flex className={styles.actionButtons}>
<Button
disabled={pristine || submitting}
success={editing}
submit
>
{editing ? 'Lagre endringer' : 'Lag ny avstemning'}
</Button>
{editing && (
<ConfirmModalWithParent
title="Slett avstemning"
message="Er du sikker på at du vil slette avstemningen?"
onConfirm={deletePoll}
closeOnConfirm
>
<Button danger>
<Icon name="trash" size={19} />
Slett avstemning
</Button>
</ConfirmModalWithParent>
)}
</Flex>
</Form>
)}
</LegoFinalForm>
</Content>
);
};

export default legoForm({
form: 'createPollForm',
onSubmit,
initialValues: {
options: [{}, {}],
pinned: false,
},
})(EditPollForm);
export default EditPollForm;
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"es6-promise-pool": "^2.5.0",
"file-saver": "^2.0.5",
"final-form": "^4.20.9",
"final-form-arrays": "^3.1.0",
"final-form-focus": "^1.1.2",
"fuzzy": "^0.1.3",
"immer": "^9.0.19",
Expand All @@ -78,6 +79,7 @@
"react-dom": "npm:@hot-loader/react-dom@^16.8.6",
"react-dropzone": "^14.2.2",
"react-final-form": "^6.5.9",
"react-final-form-arrays": "^3.1.4",
"react-helmet-async": "^1.3.0",
"react-infinite-scroller": "^1.2.6",
"react-notification": "^6.8.5",
Expand Down
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,13 @@
dependencies:
regenerator-runtime "^0.13.11"

"@babel/runtime@^7.19.4":
version "7.20.13"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b"
integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==
dependencies:
regenerator-runtime "^0.13.11"

"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
Expand Down Expand Up @@ -5414,6 +5421,11 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"

final-form-arrays@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/final-form-arrays/-/final-form-arrays-3.1.0.tgz#8bdace2fccedd61f3cbd032ae429813ae5ea37af"
integrity sha512-TWBvun+AopgBLw9zfTFHBllnKMVNEwCEyDawphPuBGGqNsuhGzhT7yewHys64KFFwzIs6KEteGLpKOwvTQEscQ==

final-form-focus@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/final-form-focus/-/final-form-focus-1.1.2.tgz#8ea5c4bd802e220cebaa47a587bb0be164eb6806"
Expand Down Expand Up @@ -8982,6 +8994,13 @@ react-fast-compare@^3.2.0:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==

react-final-form-arrays@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/react-final-form-arrays/-/react-final-form-arrays-3.1.4.tgz#2744941d8fd200fc648481022e515588f60bbac3"
integrity sha512-siVFAolUAe29rMR6u8VwepoysUcUdh6MLV2OWnCtKpsPRUdT9VUgECjAPaVMAH2GROZNiVB9On1H9MMrm9gdpg==
dependencies:
"@babel/runtime" "^7.19.4"

react-final-form@^6.5.9:
version "6.5.9"
resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.9.tgz#644797d4c122801b37b58a76c87761547411190b"
Expand Down

0 comments on commit 6b160fc

Please sign in to comment.