diff --git a/frontend/components/person/AvatarOptions.tsx b/frontend/components/person/AvatarOptions.tsx index e3e59b554..c0e7ab2d3 100644 --- a/frontend/components/person/AvatarOptions.tsx +++ b/frontend/components/person/AvatarOptions.tsx @@ -63,7 +63,7 @@ export default function AvatarOptions(props: AvatarOptionsProps) { />
-

Image options

+

Avatar options

- - {getDisplayInitials({given_names, family_names})} - {avatar_options.map(img => { return ( ) })} + + {getDisplayInitials({given_names, family_names})} +
diff --git a/frontend/components/software/edit/contributors/AvatarOptionsContributor.tsx b/frontend/components/person/AvatarOptionsPerson.tsx similarity index 73% rename from frontend/components/software/edit/contributors/AvatarOptionsContributor.tsx rename to frontend/components/person/AvatarOptionsPerson.tsx index 5fa43a8f2..db98f1f84 100644 --- a/frontend/components/software/edit/contributors/AvatarOptionsContributor.tsx +++ b/frontend/components/person/AvatarOptionsPerson.tsx @@ -5,18 +5,26 @@ // // SPDX-License-Identifier: Apache-2.0 -import {ChangeEvent} from 'react' +import {ChangeEvent, useEffect} from 'react' import {UseFormSetValue, UseFormWatch} from 'react-hook-form' import useSnackbar from '~/components/snackbar/useSnackbar' import {handleFileUpload} from '~/utils/handleFileUpload' import AvatarOptions from '~/components/person/AvatarOptions' -import {NewRsdContributor} from './AggregatedContributorModal' -type AvatarOptionsProps = { +export type RequiredAvatarProps={ + avatar_id: string | null + avatar_b64: string | null + avatar_mime_type: string | null avatar_options: string[] - watch: UseFormWatch - setValue: UseFormSetValue + given_names: string + family_names: string +} + +export type AvatarOptionsProps = { + avatar_options: string[] + watch: UseFormWatch + setValue: UseFormSetValue } export default function AvatarOptionsContributor(props: AvatarOptionsProps) { @@ -25,6 +33,18 @@ export default function AvatarOptionsContributor(props: AvatarOptionsProps) { const [avatar_id, avatar_b64] = watch(['avatar_id', 'avatar_b64']) const [given_names, family_names] = watch(['given_names', 'family_names']) + useEffect(()=>{ + if (avatar_options.length===0){ + // initial loading - reset avatar_id and change dirty flag + // this is needed to enable Save when no avatar to choose + // debugger + setValue('avatar_id', null, {shouldDirty: true,shouldValidate:true}) + }else if (avatar_options.length>0){ + // if there is avatar we select firstone by default + setValue('avatar_id', avatar_options[0], {shouldDirty: true,shouldValidate:true}) + } + },[avatar_options,setValue]) + async function onFileUpload(e:ChangeEvent|undefined) { if (typeof e !== 'undefined') { const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) diff --git a/frontend/components/projects/edit/team/AggregatedMemberModal.tsx b/frontend/components/projects/edit/team/AggregatedMemberModal.tsx index cbe98a144..e6465ea6e 100644 --- a/frontend/components/projects/edit/team/AggregatedMemberModal.tsx +++ b/frontend/components/projects/edit/team/AggregatedMemberModal.tsx @@ -15,7 +15,7 @@ import DialogContent from '@mui/material/DialogContent' import DialogTitle from '@mui/material/DialogTitle' import useMediaQuery from '@mui/material/useMediaQuery' -import {useForm} from 'react-hook-form' +import {UseFormSetValue, UseFormWatch, useForm} from 'react-hook-form' import {useSession} from '~/auth' import {SaveTeamMember} from '~/types/Project' @@ -28,7 +28,7 @@ import ControlledSwitch from '~/components/form/ControlledSwitch' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' import ControlledAutocomplete from '~/components/form/ControlledAutocomplete' import {AggregatedPerson} from '~/components/person/groupByOrcid' -import AvatarOptionsTeamMember from './AvatarOptionsTeamMember' +import AvatarOptionsPerson, {RequiredAvatarProps} from '~/components/person/AvatarOptionsPerson' import {postTeamMember} from './editTeamMembers' import {cfgTeamMembers as config} from './config' @@ -156,9 +156,9 @@ export default function AggregatedMemberModal({open, onCancel, onSubmit, member} - } + setValue={setValue as unknown as UseFormSetValue} avatar_options={member.avatar_options} />
diff --git a/frontend/components/projects/edit/team/AvatarOptionsTeamMember.tsx b/frontend/components/projects/edit/team/AvatarOptionsTeamMember.tsx deleted file mode 100644 index 2decff90c..000000000 --- a/frontend/components/projects/edit/team/AvatarOptionsTeamMember.tsx +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Dusan Mijatovic (Netherlands eScience Center) -// SPDX-FileCopyrightText: 2023 Dusan Mijatovic (dv4all) -// SPDX-FileCopyrightText: 2023 Netherlands eScience Center -// SPDX-FileCopyrightText: 2023 dv4all -// -// SPDX-License-Identifier: Apache-2.0 - -import {ChangeEvent} from 'react' -import {UseFormSetValue, UseFormWatch} from 'react-hook-form' - -import useSnackbar from '~/components/snackbar/useSnackbar' -import {handleFileUpload} from '~/utils/handleFileUpload' -import AvatarOptions from '~/components/person/AvatarOptions' -import {NewRsdMember} from './AggregatedMemberModal' - -type AvatarOptionsProps = { - avatar_options: string[] - watch: UseFormWatch - setValue: UseFormSetValue -} - -export default function AvatarOptionsTeamMember(props: AvatarOptionsProps) { - const {showWarningMessage, showErrorMessage} = useSnackbar() - const {setValue, avatar_options, watch} = props - const [avatar_id, avatar_b64] = watch(['avatar_id', 'avatar_b64']) - const [given_names, family_names] = watch(['given_names', 'family_names']) - - async function onFileUpload(e:ChangeEvent|undefined) { - if (typeof e !== 'undefined') { - const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) - if (status === 200 && image_b64 && image_mime_type) { - saveImage(image_b64, image_mime_type) - } else if (status===413) { - showWarningMessage(message) - } else { - showErrorMessage(message) - } - } - } - - function saveImage(avatar_b64: string, avatar_mime_type: string) { - // console.log('saveImage...',avatar_mime_type) - if (avatar_id) { - // remove id in the form - setValue('avatar_id', null) - } - // write new logo to logo_b64 - // we upload the image after submit - setValue('avatar_b64', avatar_b64) - setValue('avatar_mime_type', avatar_mime_type, {shouldDirty: true}) - } - - function deleteAvatar() { - // console.log('deleteAvatar...') - if (avatar_id) { - // update form - setValue('avatar_id', null, {shouldDirty: true,shouldValidate:true}) - } - // just remove uploaded image from form - // because it is not saved yet to DB - setValue('avatar_b64', null) - setValue('avatar_mime_type', null, {shouldDirty: true}) - } - - return ( - setValue('avatar_id', img)} - onNoAvatar={deleteAvatar} - onFileUpload={onFileUpload} - /> - ) -} diff --git a/frontend/components/software/edit/contributors/AggregatedContributorModal.tsx b/frontend/components/software/edit/contributors/AggregatedContributorModal.tsx index dee45a1b7..f873f780d 100644 --- a/frontend/components/software/edit/contributors/AggregatedContributorModal.tsx +++ b/frontend/components/software/edit/contributors/AggregatedContributorModal.tsx @@ -2,7 +2,9 @@ // SPDX-FileCopyrightText: 2022 - 2023 dv4all // SPDX-FileCopyrightText: 2022 Christian Meeßen (GFZ) // SPDX-FileCopyrightText: 2022 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences +// SPDX-FileCopyrightText: 2023 Dusan Mijatovic (Netherlands eScience Center) // SPDX-FileCopyrightText: 2023 Dusan Mijatovic (dv4all) (dv4all) +// SPDX-FileCopyrightText: 2023 Netherlands eScience Center // // SPDX-License-Identifier: Apache-2.0 @@ -13,21 +15,21 @@ import DialogContent from '@mui/material/DialogContent' import DialogTitle from '@mui/material/DialogTitle' import useMediaQuery from '@mui/material/useMediaQuery' -import {useForm} from 'react-hook-form' +import {UseFormSetValue, UseFormWatch, useForm} from 'react-hook-form' import {useSession} from '~/auth' +import {upsertImage} from '~/utils/editImage' +import {postContributor} from '~/utils/editContributors' +import {getPropsFromObject} from '~/utils/getPropsFromObject' +import {ContributorProps, SaveContributor} from '~/types/Contributor' import useSnackbar from '~/components/snackbar/useSnackbar' import ControlledTextField from '~/components/form/ControlledTextField' import ControlledSwitch from '~/components/form/ControlledSwitch' -import {contributorInformation as config} from '../editSoftwareConfig' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' -import {upsertImage} from '~/utils/editImage' -import {getPropsFromObject} from '~/utils/getPropsFromObject' -import {ContributorProps, SaveContributor} from '~/types/Contributor' import ControlledAutocomplete from '~/components/form/ControlledAutocomplete' -import {postContributor} from '~/utils/editContributors' import {AggregatedPerson} from '~/components/person/groupByOrcid' -import AvatarOptionsContributor from './AvatarOptionsContributor' +import AvatarOptionsPerson, {RequiredAvatarProps} from '~/components/person/AvatarOptionsPerson' +import {contributorInformation as config} from '../editSoftwareConfig' type AggregatedContributorModalProps = { open: boolean, @@ -153,12 +155,12 @@ export default function AggregatedContributorModal({open, onCancel, onSubmit, co - } + setValue={setValue as unknown as UseFormSetValue} avatar_options={contributor.avatar_options} /> -
+