QualificationsPage: FormDialog refactor
This commit is contained in:
parent
d09704f5e8
commit
19d43b96ba
|
@ -1,10 +1,10 @@
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { Controller, useFieldArray, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import { omit, pick } from 'lodash';
|
import { omit, pick } from 'lodash';
|
||||||
import useProfessionAutocomplete from './FormDialog.useProfessionAutocomplete.js';
|
import useProfessionAutocomplete from './FormDialog.useProfessionAutocomplete.js';
|
||||||
import { FORMULAS, MAX_NAME_LENGTH } from './constants';
|
import { FORMULAS, MAX_NAME_LENGTH } from './constants';
|
||||||
import { Maybe, Qualification, QualificationInput } from 'libs/graphql/types';
|
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 { makeStyles } from '@material-ui/core/styles';
|
||||||
import {
|
import {
|
||||||
|
@ -42,43 +42,18 @@ const FormDialog = ({
|
||||||
setValue,
|
setValue,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
} = useForm<Input>({});
|
} = useForm<Input>({});
|
||||||
const { fields: selectedProfessions } = useFieldArray<
|
|
||||||
ExtendedProfession,
|
|
||||||
'key'
|
|
||||||
>({
|
|
||||||
control,
|
|
||||||
name: 'professions',
|
|
||||||
keyName: 'key',
|
|
||||||
});
|
|
||||||
const {
|
const {
|
||||||
professions,
|
professions,
|
||||||
loading,
|
loading,
|
||||||
isLoadingSuggestions,
|
isLoadingSuggestions,
|
||||||
suggestions,
|
|
||||||
setSearch,
|
setSearch,
|
||||||
|
autocompleteOptions,
|
||||||
|
selectedProfessions,
|
||||||
} = useProfessionAutocomplete({
|
} = useProfessionAutocomplete({
|
||||||
qualificationID: qualification?.id,
|
qualificationID: qualification?.id,
|
||||||
omit: selectedProfessions.map(profession => profession?.id ?? 0),
|
control: control,
|
||||||
});
|
});
|
||||||
const classes = useStyles();
|
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(() => {
|
useEffect(() => {
|
||||||
reset({
|
reset({
|
||||||
|
@ -86,7 +61,7 @@ const FormDialog = ({
|
||||||
});
|
});
|
||||||
}, [professions, reset]);
|
}, [professions, reset]);
|
||||||
|
|
||||||
const prepateDataBeforeSave = (data: Input): QualificationInput => {
|
const prepareDataBeforeSave = (data: Input): QualificationInput => {
|
||||||
return {
|
return {
|
||||||
...pick(data, ['name', 'description', 'formula', 'code']),
|
...pick(data, ['name', 'description', 'formula', 'code']),
|
||||||
associateProfession: data.professions
|
associateProfession: data.professions
|
||||||
|
@ -109,7 +84,7 @@ const FormDialog = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onSubmit = async (data: Input) => {
|
const _onSubmit = async (data: Input) => {
|
||||||
const success = await onSubmit(prepateDataBeforeSave(data));
|
const success = await onSubmit(prepareDataBeforeSave(data));
|
||||||
if (success) {
|
if (success) {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
@ -183,7 +158,7 @@ const FormDialog = ({
|
||||||
loading={isLoadingSuggestions}
|
loading={isLoadingSuggestions}
|
||||||
value={selectedProfessions}
|
value={selectedProfessions}
|
||||||
getOptionDisabled={option => !!option.disabled}
|
getOptionDisabled={option => !!option.disabled}
|
||||||
onChange={(_, opts, reason) => {
|
onChange={(_, opts) => {
|
||||||
setValue(
|
setValue(
|
||||||
'professions',
|
'professions',
|
||||||
opts.map(profession => omit(profession, 'key'))
|
opts.map(profession => omit(profession, 'key'))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useApolloClient, useQuery } from '@apollo/client';
|
import { useApolloClient, useQuery } from '@apollo/client';
|
||||||
|
import { Control, useFieldArray } from 'react-hook-form';
|
||||||
import { useDebounce } from 'react-use';
|
import { useDebounce } from 'react-use';
|
||||||
import { QUERY_PROFESSIONS } from './queries';
|
import { QUERY_PROFESSIONS } from './queries';
|
||||||
import {
|
import {
|
||||||
|
@ -12,15 +13,23 @@ import { ExtendedProfession } from './types';
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
qualificationID?: Maybe<Scalars['ID']>;
|
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 [suggestions, setSuggestions] = useState<ExtendedProfession[]>([]);
|
||||||
const [isLoadingSuggestions, setIsLoadingSuggestions] = useState<boolean>(
|
const [isLoadingSuggestions, setIsLoadingSuggestions] = useState<boolean>(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const [search, setSearch] = useState<string>('');
|
const [search, setSearch] = useState<string>('');
|
||||||
|
const { fields: selectedProfessions } = useFieldArray<
|
||||||
|
ExtendedProfession,
|
||||||
|
'key'
|
||||||
|
>({
|
||||||
|
control,
|
||||||
|
name: 'professions',
|
||||||
|
keyName: 'key',
|
||||||
|
});
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
const { data, loading } = useQuery<
|
const { data, loading } = useQuery<
|
||||||
Pick<Query, 'professions'>,
|
Pick<Query, 'professions'>,
|
||||||
|
@ -35,6 +44,24 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const professions = useMemo(() => data?.professions.items ?? [], [data]);
|
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) => {
|
const loadSuggestions = async (search: string) => {
|
||||||
setIsLoadingSuggestions(true);
|
setIsLoadingSuggestions(true);
|
||||||
|
@ -46,7 +73,10 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
|
||||||
query: QUERY_PROFESSIONS,
|
query: QUERY_PROFESSIONS,
|
||||||
fetchPolicy: 'no-cache',
|
fetchPolicy: 'no-cache',
|
||||||
variables: {
|
variables: {
|
||||||
filter: { nameIEQ: '%' + search + '%', idNEQ: omit },
|
filter: {
|
||||||
|
nameIEQ: '%' + search + '%',
|
||||||
|
idNEQ: selectedProfessions.map(profession => profession.id ?? 0),
|
||||||
|
},
|
||||||
limit: 10,
|
limit: 10,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -74,6 +104,8 @@ const useProfessionAutocomplete = ({ qualificationID, omit = [] }: Options) => {
|
||||||
suggestions,
|
suggestions,
|
||||||
setSearch,
|
setSearch,
|
||||||
search,
|
search,
|
||||||
|
autocompleteOptions,
|
||||||
|
selectedProfessions,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user