QualificationsPage: FormDialog refactor
This commit is contained in:
parent
d09704f5e8
commit
19d43b96ba
|
@ -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'))
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Reference in New Issue