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}
/>
-
+