diff --git a/packages/libs/coreui/src/components/buttons/FloatingButton/index.tsx b/packages/libs/coreui/src/components/buttons/FloatingButton/index.tsx
index 94b4c5f6f3..64438d2522 100644
--- a/packages/libs/coreui/src/components/buttons/FloatingButton/index.tsx
+++ b/packages/libs/coreui/src/components/buttons/FloatingButton/index.tsx
@@ -2,7 +2,7 @@ import { merge } from 'lodash';
import { useMemo } from 'react';
import useUITheme from '../../theming/useUITheme';
-import { blue, gray } from '../../../definitions/colors';
+import { blue, gray, mutedBlue } from '../../../definitions/colors';
import SwissArmyButton from '../SwissArmyButton';
import {
ButtonStyleSpec,
@@ -100,3 +100,26 @@ export default function FloatingButton({
/>
);
}
+
+export const FloatingButtonWDKStyle: ButtonStyleSpec = {
+ default: {
+ color: 'transparent',
+ textColor: '#069',
+ fontWeight: 600,
+ },
+ hover: {
+ color: mutedBlue[100],
+ textColor: '#069',
+ fontWeight: 600,
+ },
+ pressed: {
+ color: mutedBlue[200],
+ textColor: '#069',
+ fontWeight: 600,
+ },
+ disabled: {
+ color: 'transparent',
+ textColor: gray[500],
+ fontWeight: 600,
+ },
+};
diff --git a/packages/libs/coreui/src/components/buttons/OutlinedButton/index.tsx b/packages/libs/coreui/src/components/buttons/OutlinedButton/index.tsx
index d28f483a0f..1519e39359 100644
--- a/packages/libs/coreui/src/components/buttons/OutlinedButton/index.tsx
+++ b/packages/libs/coreui/src/components/buttons/OutlinedButton/index.tsx
@@ -2,7 +2,7 @@ import { merge } from 'lodash';
import { useMemo } from 'react';
import useUITheme from '../../theming/useUITheme';
-import { blue, gray } from '../../../definitions/colors';
+import { blue, gray, mutedBlue } from '../../../definitions/colors';
import SwissArmyButton from '../SwissArmyButton';
import {
ButtonStyleSpec,
@@ -133,3 +133,51 @@ export default function OutlinedButton({
/>
);
}
+
+// Styled for use in the wdk
+export const OutlinedButtonWDKStyle = {
+ default: {
+ textColor: '#0F86C1',
+ fontWeight: 600,
+ color: 'transparent',
+ border: {
+ radius: 5,
+ color: '#0F86C1',
+ style: 'solid',
+ width: 2,
+ },
+ },
+ hover: {
+ textColor: mutedBlue[600],
+ fontWeight: 600,
+ color: 'transparent',
+ border: {
+ radius: 5,
+ color: mutedBlue[600],
+ style: 'solid',
+ width: 2,
+ },
+ },
+ pressed: {
+ textColor: mutedBlue[700],
+ fontWeight: 600,
+ color: 'transparent',
+ border: {
+ radius: 5,
+ color: mutedBlue[700],
+ style: 'solid',
+ width: 2,
+ },
+ },
+ disabled: {
+ textColor: gray[500],
+ fontWeight: 600,
+ color: 'transparent',
+ border: {
+ radius: 5,
+ color: gray[500],
+ style: 'solid',
+ width: 2,
+ },
+ },
+};
diff --git a/packages/libs/user-datasets/src/lib/Components/UploadForm.scss b/packages/libs/user-datasets/src/lib/Components/UploadForm.scss
index 7a2a5f0465..b5b6125c47 100644
--- a/packages/libs/user-datasets/src/lib/Components/UploadForm.scss
+++ b/packages/libs/user-datasets/src/lib/Components/UploadForm.scss
@@ -38,7 +38,6 @@
display: flex;
flex-direction: column;
gap: 0.5em;
- padding-left: 1em;
padding-right: 1em;
> label {
diff --git a/packages/libs/user-datasets/src/lib/Components/UploadForm.tsx b/packages/libs/user-datasets/src/lib/Components/UploadForm.tsx
index 9bdc3ac67e..b4f88684db 100644
--- a/packages/libs/user-datasets/src/lib/Components/UploadForm.tsx
+++ b/packages/libs/user-datasets/src/lib/Components/UploadForm.tsx
@@ -36,12 +36,14 @@ import {
UserDatasetPublication,
} from '../Utils/types';
-import { FloatingButton, Modal } from '@veupathdb/coreui';
+import { FloatingButton, Modal, OutlinedButton } from '@veupathdb/coreui';
+import { OutlinedButtonWDKStyle } from '@veupathdb/coreui/lib/components/buttons/OutlinedButton';
import Banner from '@veupathdb/coreui/lib/components/banners/Banner';
import AddIcon from '@material-ui/icons/Add';
import Trash from '@veupathdb/coreui/lib/components/icons/Trash';
import './UploadForm.scss';
+import { FloatingButtonWDKStyle } from '@veupathdb/coreui/lib/components/buttons/FloatingButton';
const cx = makeClassNameHelper('UploadForm');
@@ -490,143 +492,144 @@ function UploadForm({
/>
-
- Additional Details
-
-
- Publications (Optional)
-
- {publications.map((publication, index) => {
- const updatePublicationsObject = createNestedInputUpdater({
- nestedInputObject: publications,
- index,
- });
- return (
-
{
- const updatedPublications = updatePublicationsObject(
- value,
- 'pubMedId'
- );
- setPublications(updatedPublications);
- }}
- onRemovePublication={(
- event: React.MouseEvent
- ) => {
- event.preventDefault();
- const updatedPublications = [...publications];
- updatedPublications.splice(index, 1);
- setPublications(updatedPublications);
- }}
- citation={publication.citation}
- onAddCitation={(value: string) => {
- const updatedPublications = updatePublicationsObject(
- value,
- 'citation'
- );
- setPublications(updatedPublications);
- }}
- />
- );
- })}
- ) => {
- event.preventDefault();
- setPublications((oldPublications) => [
- ...oldPublications,
- {} as UserDatasetPublication,
- ]);
- }}
- icon={AddIcon}
- />
-
-
-
- Hyperlinks (Optional)
-
- {hyperlinks.map((hyperlink, index) => {
- const updateHyperlinksObject = createNestedInputUpdater({
- nestedInputObject: hyperlinks,
- index,
- });
- return (
- {
- const updatedHyperlinks = updateHyperlinksObject(
- value,
- 'url'
- );
- setHyperlinks(updatedHyperlinks);
- }}
- onRemoveHyperlink={(
- event: React.MouseEvent
- ) => {
- event.preventDefault();
- const updatedHyperlinks = [...hyperlinks];
- updatedHyperlinks.splice(index, 1);
- setHyperlinks(updatedHyperlinks);
- }}
- text={hyperlink.text}
- onAddText={(value: string) => {
- const updatedHyperlinks = updateHyperlinksObject(
- value,
- 'text'
- );
- setHyperlinks(updatedHyperlinks);
- }}
- description={hyperlinks[index]?.description}
- onAddDescription={(value: string) => {
- const updatedHyperlinks = updateHyperlinksObject(
- value,
- 'description'
- );
- setHyperlinks(updatedHyperlinks);
- }}
- isPublication={hyperlinks[index]?.isPublication}
- onAddIsPublication={(value: boolean) => {
- const updatedHyperlinks = updateHyperlinksObject(
- value,
- 'publication'
- );
- setHyperlinks(updatedHyperlinks);
- return;
- }}
- />
- );
- })}
- ) => {
- event.preventDefault();
- setHyperlinks((oldHyperlinks) => [
- ...oldHyperlinks,
- {} as UserDatasetHyperlink,
- ]);
- }}
- icon={AddIcon}
- />
-
+
+
+ Publications
+
+ {publications.map((publication, index) => {
+ const updatePublicationsObject = createNestedInputUpdater({
+ nestedInputObject: publications,
+ index,
+ });
+ return (
+
{
+ const updatedPublications = updatePublicationsObject(
+ value,
+ 'pubMedId'
+ );
+ setPublications(updatedPublications);
+ }}
+ onRemovePublication={(
+ event: React.MouseEvent
+ ) => {
+ event.preventDefault();
+ const updatedPublications = [...publications];
+ updatedPublications.splice(index, 1);
+ setPublications(updatedPublications);
+ }}
+ citation={publication.citation}
+ onAddCitation={(value: string) => {
+ const updatedPublications = updatePublicationsObject(
+ value,
+ 'citation'
+ );
+ setPublications(updatedPublications);
+ }}
+ />
+ );
+ })}
+ ) => {
+ event.preventDefault();
+ setPublications((oldPublications) => [
+ ...oldPublications,
+ {} as UserDatasetPublication,
+ ]);
+ }}
+ icon={AddIcon}
+ styleOverrides={OutlinedButtonWDKStyle}
+ />
+
+
+
+ Hyperlinks
+
+ {hyperlinks.map((hyperlink, index) => {
+ const updateHyperlinksObject = createNestedInputUpdater({
+ nestedInputObject: hyperlinks,
+ index,
+ });
+ return (
+ {
+ const updatedHyperlinks = updateHyperlinksObject(
+ value,
+ 'url'
+ );
+ setHyperlinks(updatedHyperlinks);
+ }}
+ onRemoveHyperlink={(
+ event: React.MouseEvent
+ ) => {
+ event.preventDefault();
+ const updatedHyperlinks = [...hyperlinks];
+ updatedHyperlinks.splice(index, 1);
+ setHyperlinks(updatedHyperlinks);
+ }}
+ text={hyperlink.text}
+ onAddText={(value: string) => {
+ const updatedHyperlinks = updateHyperlinksObject(
+ value,
+ 'text'
+ );
+ setHyperlinks(updatedHyperlinks);
+ }}
+ description={hyperlinks[index]?.description}
+ onAddDescription={(value: string) => {
+ const updatedHyperlinks = updateHyperlinksObject(
+ value,
+ 'description'
+ );
+ setHyperlinks(updatedHyperlinks);
+ }}
+ isPublication={hyperlinks[index]?.isPublication}
+ onAddIsPublication={(value: boolean) => {
+ const updatedHyperlinks = updateHyperlinksObject(
+ value,
+ 'publication'
+ );
+ setHyperlinks(updatedHyperlinks);
+ return;
+ }}
+ />
+ );
+ })}
+ ) => {
+ event.preventDefault();
+ setHyperlinks((oldHyperlinks) => [
+ ...oldHyperlinks,
+ {} as UserDatasetHyperlink,
+ ]);
+ }}
+ icon={AddIcon}
+ styleOverrides={OutlinedButtonWDKStyle}
+ />
+
+ {!datasetUploadType.formConfig.hideRelatedOrganisms && (
- Organisms (Optional)
+ Related Organisms
{organisms.map((organism, index) => {
return (
- Organism {index + 1}
+ Related Organism {index + 1}
);
})}
-
) => {
event.preventDefault();
setOrganisms((oldOrganisms) => [...oldOrganisms, '']);
}}
icon={AddIcon}
+ styleOverrides={OutlinedButtonWDKStyle}
/>
-
-
- Contacts (Optional)
-
- {contacts.map((contact, index) => {
- const updateContactsObject = createNestedInputUpdater({
- nestedInputObject: contacts,
- index,
- });
- return (
- {
- const updatedContacts = updateContactsObject(
- value,
- 'name'
- );
- setContacts(updatedContacts);
- }}
- email={contact.email}
- onAddEmail={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'email'
- );
- setContacts(updatedContacts);
- }}
- affiliation={contact.affiliation}
- onAddAffiliation={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'affiliation'
- );
- setContacts(updatedContacts);
- }}
- city={contact.city}
- onAddCity={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'city'
- );
- setContacts(updatedContacts);
- }}
- state={contact.state}
- onAddState={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'state'
- );
- setContacts(updatedContacts);
- }}
- country={contact.country}
- onAddCountry={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'country'
- );
- setContacts(updatedContacts);
- }}
- address={contact.address}
- onAddAddress={(value: string) => {
- const updatedContacts = updateContactsObject(
- value,
- 'address'
- );
- setContacts(updatedContacts);
- }}
- isPrimary={contact.isPrimary}
- onAddIsPrimary={(value: boolean) => {
- const updatedContacts = updateContactsObject(
- value,
- 'isPrimary'
- );
- setContacts(updatedContacts);
- return;
- }}
- onRemoveContact={(
- event: React.MouseEvent
- ) => {
- event.preventDefault();
- const updatedContacts = [...contacts];
- updatedContacts.splice(index, 1);
- setContacts(updatedContacts);
- }}
- />
- );
- })}
- ) => {
- event.preventDefault();
- setContacts((contacts) => [
- ...contacts,
- {} as UserDatasetContact,
- ]);
- }}
- icon={AddIcon}
- />
-
-
+ )}
+
+
+ Contacts
+
+ {contacts.map((contact, index) => {
+ const updateContactsObject = createNestedInputUpdater({
+ nestedInputObject: contacts,
+ index,
+ });
+ return (
+ {
+ const updatedContacts = updateContactsObject(value, 'name');
+ setContacts(updatedContacts);
+ }}
+ email={contact.email}
+ onAddEmail={(value: string) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'email'
+ );
+ setContacts(updatedContacts);
+ }}
+ affiliation={contact.affiliation}
+ onAddAffiliation={(value: string) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'affiliation'
+ );
+ setContacts(updatedContacts);
+ }}
+ city={contact.city}
+ onAddCity={(value: string) => {
+ const updatedContacts = updateContactsObject(value, 'city');
+ setContacts(updatedContacts);
+ }}
+ state={contact.state}
+ onAddState={(value: string) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'state'
+ );
+ setContacts(updatedContacts);
+ }}
+ country={contact.country}
+ onAddCountry={(value: string) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'country'
+ );
+ setContacts(updatedContacts);
+ }}
+ address={contact.address}
+ onAddAddress={(value: string) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'address'
+ );
+ setContacts(updatedContacts);
+ }}
+ isPrimary={contact.isPrimary}
+ onAddIsPrimary={(value: boolean) => {
+ const updatedContacts = updateContactsObject(
+ value,
+ 'isPrimary'
+ );
+ setContacts(updatedContacts);
+ return;
+ }}
+ onRemoveContact={(
+ event: React.MouseEvent
+ ) => {
+ event.preventDefault();
+ const updatedContacts = [...contacts];
+ updatedContacts.splice(index, 1);
+ setContacts(updatedContacts);
+ }}
+ />
+ );
+ })}
+ ) => {
+ event.preventDefault();
+ setContacts((contacts) => [
+ ...contacts,
+ {} as UserDatasetContact,
+ ]);
+ }}
+ icon={AddIcon}
+ styleOverrides={OutlinedButtonWDKStyle}
+ />
+
{datasetUploadType.formConfig.dependencies && (
@@ -1000,6 +1000,7 @@ export function PublicationInput(props: PublicationInputProps): JSX.Element {
text="Remove"
onPress={onRemovePublication}
icon={Trash}
+ styleOverrides={FloatingButtonWDKStyle}
/>
@@ -1064,6 +1065,7 @@ function HyperlinkInput(props: HyperlinkInputProps): JSX.Element {
text="Remove"
onPress={onRemoveHyperlink}
icon={Trash}
+ styleOverrides={FloatingButtonWDKStyle}
/>
@@ -1161,7 +1163,12 @@ function ContactInput(props: ContactInputProps): JSX.Element {
Contact {n + 1}
-
+
Name
diff --git a/packages/libs/user-datasets/src/lib/Components/UploadFormMenu.tsx b/packages/libs/user-datasets/src/lib/Components/UploadFormMenu.tsx
index 6687a8ea28..4e923a7d91 100644
--- a/packages/libs/user-datasets/src/lib/Components/UploadFormMenu.tsx
+++ b/packages/libs/user-datasets/src/lib/Components/UploadFormMenu.tsx
@@ -20,7 +20,7 @@ export function UploadFormMenu(props: Props) {
const datasetUploadType = datasetUploadTypes[type];
return (
datasetUploadType && (
-
+
{' '}
diff --git a/packages/libs/user-datasets/src/lib/Components/UserDatasetsWorkspace.tsx b/packages/libs/user-datasets/src/lib/Components/UserDatasetsWorkspace.tsx
index ec6f8a1ab8..4484523ff9 100644
--- a/packages/libs/user-datasets/src/lib/Components/UserDatasetsWorkspace.tsx
+++ b/packages/libs/user-datasets/src/lib/Components/UserDatasetsWorkspace.tsx
@@ -1,6 +1,11 @@
-import { ReactNode } from 'react';
+import { ReactNode, useEffect, useState } from 'react';
-import { Switch, Redirect, RouteComponentProps } from 'react-router-dom';
+import {
+ Switch,
+ Redirect,
+ RouteComponentProps,
+ useRouteMatch,
+} from 'react-router-dom';
import WorkspaceNavigation from '@veupathdb/wdk-client/lib/Components/Workspace/WorkspaceNavigation';
import WdkRoute from '@veupathdb/wdk-client/lib/Core/WdkRoute';
@@ -19,6 +24,8 @@ interface Props {
helpTabContents?: ReactNode;
dataNoun: DataNoun;
enablePublicUserDatasets: boolean;
+ activeUploadType?: string;
+ setActiveUploadType?: (newType?: string) => void;
}
function UserDatasetsWorkspace(props: Props) {
@@ -30,8 +37,21 @@ function UserDatasetsWorkspace(props: Props) {
helpTabContents,
dataNoun,
enablePublicUserDatasets,
+ activeUploadType,
+ setActiveUploadType,
} = props;
+ const {
+ path,
+ params: { type: currentUploadType },
+ } = useRouteMatch<{ type?: string }>();
+
+ useEffect(() => {
+ if (setActiveUploadType && path.match('/new/')) {
+ setActiveUploadType(currentUploadType);
+ }
+ }, [currentUploadType, path, setActiveUploadType]);
+
return (
;
}
+
return (
-
+ <>
+
+ Back to choose an upload type
+
+
+ >
);
}
@@ -157,6 +165,7 @@ function InnerUserDatasetUploadController({
) : (
({
[availableUploadTypes, uploadTypeConfig]
);
+ const [activeUploadType, setActiveUploadType] = useState();
+
return (
({
helpTabContents={helpTabContents}
dataNoun={dataNoun}
enablePublicUserDatasets={enablePublicUserDatasets}
+ activeUploadType={activeUploadType}
+ setActiveUploadType={setActiveUploadType}
/>
);
}}
@@ -102,6 +105,8 @@ export function UserDatasetRouter({
helpTabContents={helpTabContents}
dataNoun={dataNoun}
enablePublicUserDatasets={enablePublicUserDatasets}
+ activeUploadType={activeUploadType}
+ setActiveUploadType={setActiveUploadType}
/>
);
}}
@@ -159,6 +164,8 @@ export function UserDatasetRouter({
helpTabContents={helpTabContents}
dataNoun={dataNoun}
enablePublicUserDatasets={enablePublicUserDatasets}
+ activeUploadType={activeUploadType}
+ setActiveUploadType={setActiveUploadType}
/>
);
}}
diff --git a/packages/libs/user-datasets/src/lib/Utils/types.ts b/packages/libs/user-datasets/src/lib/Utils/types.ts
index bafd219f1e..8a7256a7cd 100644
--- a/packages/libs/user-datasets/src/lib/Utils/types.ts
+++ b/packages/libs/user-datasets/src/lib/Utils/types.ts
@@ -109,6 +109,7 @@ export interface DatasetUploadTypeConfigEntry {
render: (props: DependencyProps) => ReactNode;
required?: boolean;
};
+ hideRelatedOrganisms?: boolean;
uploadMethodConfig: {
file?: FileUploadConfig;
url?: UrlUploadConfig;
diff --git a/packages/libs/web-common/src/user-dataset-upload-config.tsx b/packages/libs/web-common/src/user-dataset-upload-config.tsx
index eb5ae751fe..40d1352de9 100644
--- a/packages/libs/web-common/src/user-dataset-upload-config.tsx
+++ b/packages/libs/web-common/src/user-dataset-upload-config.tsx
@@ -175,6 +175,7 @@ export const uploadTypeConfig: DatasetUploadTypeConfig =
'optional longer description of the summary including background, study objectives, methodology, etc.',
},
},
+ hideRelatedOrganisms: true,
renderInfo: () => (
We accept any file in the{' '}
@@ -301,6 +302,7 @@ export const uploadTypeConfig: DatasetUploadTypeConfig =
'optional longer description of the study including background, study objectives, methodology, etc.',
},
},
+ hideRelatedOrganisms: true,
uploadMethodConfig: {
file: {
render: ({ fieldNode }) => (