diff --git a/frontend/components/software/edit/editSoftwareConfig.tsx b/frontend/components/software/edit/editSoftwareConfig.tsx index ef5a0304d..76706c65a 100644 --- a/frontend/components/software/edit/editSoftwareConfig.tsx +++ b/frontend/components/software/edit/editSoftwareConfig.tsx @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: 2022 - 2023 Dusan Mijatovic (dv4all) +// SPDX-FileCopyrightText: 2022 - 2023 Ewan Cahen (Netherlands eScience Center) // SPDX-FileCopyrightText: 2022 - 2023 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences +// SPDX-FileCopyrightText: 2022 - 2023 Netherlands eScience Center // SPDX-FileCopyrightText: 2022 - 2023 dv4all // SPDX-FileCopyrightText: 2022 Christian Meeßen (GFZ) -// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) // SPDX-FileCopyrightText: 2022 Matthias Rüster (GFZ) -// SPDX-FileCopyrightText: 2022 Netherlands eScience Center // SPDX-FileCopyrightText: 2023 Felix Mühlbauer (GFZ) // // SPDX-License-Identifier: Apache-2.0 @@ -55,12 +55,12 @@ export const softwareInformation = { }, repository_url: { label: 'Repository URL', - help: 'Link to source code repository', + help: (repoUrl: string | null) => repoUrl ? verifyGithubUrl(repoUrl) : 'Link to source code repository', validation: { maxLength: {value: 200, message: 'Maximum length is 200'}, pattern: { value: /^https?:\/\/.+\..+/, - message: 'URL should start with htps://, have at least one dot (.) and at least one slash (/).' + message: 'URL should start with http(s)://, have at least one dot (.) and at least one slash (/).' } } }, @@ -91,7 +91,13 @@ export const softwareInformation = { // field for markdown URL description_url: { label: 'URL location of markdown file', - help: <>Point to the location of markdown file including the filename. Make sure to provide the raw file and not the rendered output., + help: <>Point to the location of markdown file including the filename. Make sure to provide the raw file and not the rendered + output., validation: { required: 'Valid markdown URL must be provided', maxLength: {value: 200, message: 'Maximum length is 200'}, @@ -105,7 +111,10 @@ export const softwareInformation = { title: 'Citation', subtitle: 'We generate citation files using concept DOI', label: 'Concept DOI', - help: <>Concept DOI of your software, i.e. a DOI representing all of the versions of this software, + help: <>Concept DOI of your software, i.e. a DOI representing all of the + versions of this software, validation: { minLength: {value: 7, message: 'Minimum length is 7'}, maxLength: {value: 100, message: 'Maximum length is 100'}, @@ -116,7 +125,7 @@ export const softwareInformation = { } }, validateConceptDoi: { - label:'Validate DOI' + label: 'Validate DOI' }, pageStatus: { title: 'Status', @@ -180,7 +189,7 @@ export const contributorInformation = { }, is_contact_person: { label: 'Contact person', - help:'Is this contributor main contact person' + help: 'Is this contributor the main contact person?' }, given_names: { label: 'First name / Given name(s)', @@ -255,7 +264,7 @@ export const organisationInformation = { minLength: 2, } }, - name:{ + name: { label: 'Name', help: 'Participating organisation', validation: { @@ -306,7 +315,7 @@ export const testimonialInformation = { label: 'Source', help: 'Who provided the credits?', validation: { - required: 'The source of testimonal is required', + required: 'The source of the testimonial is required', minLength: {value: 2, message: 'Minimum length is 2'}, maxLength: {value: 200, message: 'Maximum length is 200'}, } @@ -342,7 +351,7 @@ export const mentionInformation = { label: 'Author', help: 'List all authors', validation: { - required:false + required: false } }, url: { @@ -363,7 +372,7 @@ export const mentionInformation = { }, image_url: { label: 'Image', - help:'Provide URL to image', + help: 'Provide URL to image', validation: { pattern: { value: /^https?:\/\/.+\..+/, @@ -388,6 +397,16 @@ export const mentionInformation = { export const relatedSoftwareInformation = { title: 'Related software', - subtitle:(brand_name:string)=>`Mention software often used together with ${brand_name}`, + subtitle: (brand_name: string) => `Mention software often used together with ${brand_name}`, help: 'Select related RSD software' } + +function verifyGithubUrl(repoUrl: string) { + if ((repoUrl.startsWith('https://github.com/') || repoUrl.startsWith('http://github.com/')) + && !repoUrl.match('^https?://github\\.com/([^\\s/]+)/([^\\s/]+)/?$')) { + return
This does not seem to be the root of a single GitHub repository, are you + sure?
+ } + + return 'Link to source code repository' +} diff --git a/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx b/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx index 9a058167b..140052776 100644 --- a/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx +++ b/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx @@ -36,7 +36,7 @@ async function suggestPlatform(repositoryUrl: string | null) { } try { - const repositoryUrlDomain =new URL(repositoryUrl) + const repositoryUrlDomain = new URL(repositoryUrl) const baseUrl = getBaseUrl() const resp = await fetch( `${baseUrl}/rpc/suggest_platform`, @@ -47,7 +47,7 @@ async function suggestPlatform(repositoryUrl: string | null) { }) if (resp.status === 200) { const platform_type = await resp.json() - if ( platform_type !== null){ + if (platform_type !== null) { return platform_type } } @@ -61,18 +61,18 @@ export default function AutosaveRepositoryUrl() { const {token} = useSession() const {showErrorMessage} = useSnackbar() const {control, watch, resetField} = useFormContext() - const {fieldState:{error:urlError},field:{value:repository_url}} = useController({ + const {fieldState: {error: urlError}, field: {value: repository_url}} = useController({ control, - name:'repository_url' + name: 'repository_url' }) - const [id,repository_platform] = watch(['id','repository_platform']) + const [id, repository_platform] = watch(['id', 'repository_platform']) const [platform, setPlatform] = useState<{ id: CodePlatform | null disabled: boolean helperText: string }>({ id: repository_platform, - disabled: repository_platform===null, + disabled: repository_platform === null, helperText: 'Suggestion' }) const [suggestedPlatform, setSuggestedPlatform] = useState() @@ -82,7 +82,7 @@ export default function AutosaveRepositoryUrl() { label: config.repository_url.label, useNull: true, defaultValue: repository_url, - helperTextMessage: config.repository_url.help, + helperTextMessage: config.repository_url.help(repository_url), helperTextCnt: `${repository_url?.length || 0}/${config.repository_url.validation.maxLength.value}`, } @@ -90,7 +90,7 @@ export default function AutosaveRepositoryUrl() { useEffect(() => { if (typeof urlError == 'undefined' && repository_url) { // Do nothing if the host name is not complete - if (! /^https?:\/\/\S+\//.test(repository_url)) { + if (!/^https?:\/\/\S+\//.test(repository_url)) { return } // debugger @@ -114,11 +114,11 @@ export default function AutosaveRepositoryUrl() { helperText: '' }) } - },[urlError,repository_url,platform.id]) + }, [urlError, repository_url, platform.id]) async function saveRepositoryInfo({name, value}: OnSaveProps) { // complete record for upsert - const data:RepositoryUrl = { + const data: RepositoryUrl = { software: id, url: repository_url ?? '', code_platform: platform.id ?? 'other', @@ -151,7 +151,7 @@ export default function AutosaveRepositoryUrl() { } // update value data.code_platform = value as CodePlatform - // manualy overwriting advice + // manually overwriting advice setPlatform({ id: value as CodePlatform, disabled: false, @@ -183,7 +183,7 @@ export default function AutosaveRepositoryUrl() { } else { // reset both fields resetField('repository_url', {defaultValue: data.url}) - resetField('repository_platform',{defaultValue: data.code_platform}) + resetField('repository_platform', {defaultValue: data.code_platform}) } } @@ -206,7 +206,7 @@ export default function AutosaveRepositoryUrl() { value={platform.id} disabled={platform.disabled} helperText={platform.helperText} - onChange={(platform)=>saveRepositoryInfo({name:'repository_platform',value:platform})} + onChange={(platform) => saveRepositoryInfo({name: 'repository_platform', value: platform})} /> )