QualificationsPage: FormDialog refactor

This commit is contained in:
Dawid Wysokiński 2021-03-13 13:23:11 +01:00
parent d09704f5e8
commit 19d43b96ba
2 changed files with 44 additions and 37 deletions

View File

@ -1,10 +1,10 @@
import { useEffect, useMemo } from 'react';
import { Controller, useFieldArray, useForm } from 'react-hook-form';
import { useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { omit, pick } from 'lodash';
import useProfessionAutocomplete from './FormDialog.useProfessionAutocomplete.js';
import { FORMULAS, MAX_NAME_LENGTH } from './constants';
import { Maybe, Qualification, QualificationInput } from 'libs/graphql/types';
import { ExtendedProfession, Input } from './types';
import { Input } from './types';
import { makeStyles } from '@material-ui/core/styles';
import {
@ -42,43 +42,18 @@ const FormDialog = ({
setValue,
formState: { isSubmitting },
} = useForm<Input>({});
const { fields: selectedProfessions } = useFieldArray<
ExtendedProfession,
'key'
>({
control,
name: 'professions',
keyName: 'key',
});
const {
professions,
loading,
isLoadingSuggestions,
suggestions,
setSearch,
autocompleteOptions,
selectedProfessions,
} = useProfessionAutocomplete({
qualificationID: qualification?.id,
omit: selectedProfessions.map(profession => profession?.id ?? 0),
control: control,
});
const classes = useStyles();
const autocompleteOptions:
| typeof selectedProfessions
| typeof suggestions = useMemo(() => {
return [
...suggestions
.filter(
profession =>
!selectedProfessions.some(
otherProfession => otherProfession.id === profession.id
)
)
.map(p => ({ ...p, disabled: false })),
...selectedProfessions.map(p => ({
...p,
disabled: true,
})),
];
}, [suggestions, selectedProfessions]);
useEffect(() => {
reset({
@ -86,7 +61,7 @@ const FormDialog = ({
});
}, [professions, reset]);
const prepateDataBeforeSave = (data: Input): QualificationInput => {
const prepareDataBeforeSave = (data: Input): QualificationInput => {
return {
...pick(data, ['name', 'description', 'formula', 'code']),
associateProfession: data.professions
@ -109,7 +84,7 @@ const FormDialog = ({
};
const _onSubmit = async (data: Input) => {
const success = await onSubmit(prepateDataBeforeSave(data));
const success = await onSubmit(prepareDataBeforeSave(data));
if (success) {
onClose();
}
@ -183,7 +158,7 @@ const FormDialog = ({
loading={isLoadingSuggestions}
value={selectedProfessions}
getOptionDisabled={option => !!option.disabled}
onChange={(_, opts, reason) => {
onChange={(_, opts) => {
setValue(
'professions',
opts.map(profession => omit(profession, 'key'))

View File

@ -1,5 +1,6 @@
import { useMemo, useState } from 'react';
import { useApolloClient, useQuery } from '@apollo/client';
import { Control, useFieldArray } from 'react-hook-form';
import { useDebounce } from 'react-use';
import { QUERY_PROFESSIONS } from './queries';
import {
@ -12,15 +13,23 @@ import { ExtendedProfession } from './types';
export interface Options {
qualificationID?: Maybe<Scalars['ID']>;
omit?: Scalars['ID'][];
control: Control;
}
const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
const useProfessionAutocomplete = ({ qualificationID, control }: Options) => {
const [suggestions, setSuggestions] = useState<ExtendedProfession[]>([]);
const [isLoadingSuggestions, setIsLoadingSuggestions] = useState<boolean>(
false
);
const [search, setSearch] = useState<string>('');
const { fields: selectedProfessions } = useFieldArray<
ExtendedProfession,
'key'
>({
control,
name: 'professions',
keyName: 'key',
});
const client = useApolloClient();
const { data, loading } = useQuery<
Pick<Query, 'professions'>,
@ -35,6 +44,24 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
},
});
const professions = useMemo(() => data?.professions.items ?? [], [data]);
const autocompleteOptions:
| typeof selectedProfessions
| typeof suggestions = useMemo(() => {
return [
...suggestions
.filter(
profession =>
!selectedProfessions.some(
otherProfession => otherProfession.id === profession.id
)
)
.map(p => ({ ...p, disabled: false })),
...selectedProfessions.map(p => ({
...p,
disabled: true,
})),
];
}, [suggestions, selectedProfessions]);
const loadSuggestions = async (search: string) => {
setIsLoadingSuggestions(true);
@ -46,7 +73,10 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
query: QUERY_PROFESSIONS,
fetchPolicy: 'no-cache',
variables: {
filter: { nameIEQ: '%' + search + '%', idNEQ: omit },
filter: {
nameIEQ: '%' + search + '%',
idNEQ: selectedProfessions.map(profession => profession.id ?? 0),
},
limit: 10,
},
});
@ -74,6 +104,8 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
suggestions,
setSearch,
search,
autocompleteOptions,
selectedProfessions,
};
};