Skip to content

Commit

Permalink
Theo's suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-parker committed Jul 29, 2024
1 parent 2a6032e commit 7f531e4
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 92 deletions.
3 changes: 1 addition & 2 deletions website/src/components/DataUseTerms/DataUseTermsSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ const DataUseTermsSelector: FC<DataUseTermsSelectorProps> = ({ dataUseTermsType,
Open
</label>
<div className='text-xs pl-8 text-gray-500 pb-4'>
I confirm that the data submitted is not sensitive, restricted-access or human-identifiable and
anyone can use and share the data (though we believe researchers should exercise scientific
Anyone can use and share the data (though we believe researchers should exercise scientific
etiquette, including the importance of citation).{' '}
<a href={routes.datauseTermsPage()} className='text-primary-600'>
Find out more
Expand Down
25 changes: 25 additions & 0 deletions website/src/components/Submission/DataUploadForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ const InnerDataUploadForm = ({

const [agreedToINSDCUploadTerms, setAgreedToINSDCUploadTerms] = useState(false);

const [confirmedNoPII, setConfirmedNoPII] = useState(false);

const isClient = useClientFlag();

const handleLoadExampleData = async () => {
Expand All @@ -305,6 +307,13 @@ const InnerDataUploadForm = ({
return;
}

if (!confirmedNoPII) {
onError(
'Please confirm the data you submitted does not include restricted or personally identifiable information.',
);
return;
}

if (!metadataFile) {
onError('Please select metadata file');
return;
Expand Down Expand Up @@ -461,6 +470,22 @@ const InnerDataUploadForm = ({
</div>
</label>
</div>
<div className='mb-4 mt-3 py-5'>
<label className='flex items-center'>
<input
type='checkbox'
name='confirmation-no-pii'
className='mr-3 ml-1 h-5 w-5 rounded border-gray-300 text-blue focus:ring-blue'
checked={confirmedNoPII}
onChange={() => setConfirmedNoPII(!confirmedNoPII)}
/>
<div>
<p className='text-xs pl-4 text-gray-500'>
I confirm that the data submitted is not sensitive or human-identifiable.
</p>
</div>
</label>
</div>
</div>
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions website/src/components/Submission/SubmissionForm.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ describe('SubmitForm', () => {
await userEvent.click(
getByLabelText(/I confirm I have not and will not submit this data independently to INSDC/i),
);
await userEvent.click(
getByLabelText(/I confirm that the data submitted is not sensitive or human-identifiable/i),
);

const submitButton = getByText('Submit sequences');
await userEvent.click(submitButton);
Expand Down Expand Up @@ -141,6 +144,9 @@ describe('SubmitForm', () => {
await userEvent.click(
getByLabelText(/I confirm I have not and will not submit this data independently to INSDC/i),
);
await userEvent.click(
getByLabelText(/I confirm that the data submitted is not sensitive or human-identifiable/i),
);

const submitButton = getByText('Submit sequences');
await userEvent.click(submitButton);
Expand Down
101 changes: 11 additions & 90 deletions website/src/components/User/GroupCreationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Dialog, Transition, TransitionChild, DialogPanel } from '@headlessui/react';
import React, { type ComponentProps, type FC, type FormEvent, type PropsWithChildren, useState, Fragment } from 'react';
import { type ComponentProps, type FC, type FormEvent, type PropsWithChildren, useState } from 'react';

import { listOfCountries } from './listOfCountries.ts';
import useClientFlag from '../../hooks/isClient.ts';
Expand All @@ -8,8 +7,6 @@ import { routes } from '../../routes/routes.ts';
import { type ClientConfig } from '../../types/runtimeConfig.ts';
import { ErrorFeedback } from '../ErrorFeedback.tsx';
import { withQueryProvider } from '../common/withQueryProvider.tsx';
import X from '~icons/material-symbols/close';
import MaterialSymbolsInfoOutline from '~icons/material-symbols/info-outline';

interface GroupManagerProps {
clientConfig: ClientConfig;
Expand Down Expand Up @@ -147,112 +144,37 @@ const fieldMapping = {
const groupCreationCssClass =
'block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6';

const InstitutionInfoButton: FC = () => {
const [isOpen, setIsOpen] = React.useState(false);

const openDialog = () => setIsOpen(true);
const closeDialog = () => setIsOpen(false);
return (
<>
<button type='button' onClick={openDialog} className='text-gray-400 hover:text-primary-600 '>
<MaterialSymbolsInfoOutline className='inline-block h-6 w-5' />
</button>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as='div' className='relative z-10' onClose={closeDialog}>
<TransitionChild
as={Fragment}
enter='ease-out duration-300'
enterFrom='opacity-0'
enterTo='opacity-100'
leave='ease-in duration-200'
leaveFrom='opacity-100'
leaveTo='opacity-0'
>
<div className='fixed inset-0 bg-black bg-opacity-25' />
</TransitionChild>

<div className='fixed inset-0 overflow-y-auto'>
<div className='flex min-h-full items-center justify-center p-4 text-center'>
<TransitionChild
as={Fragment}
enter='ease-out duration-300'
enterFrom='opacity-0 scale-95'
enterTo='opacity-100 scale-100'
leave='ease-in duration-200'
leaveFrom='opacity-100 scale-100'
leaveTo='opacity-0 scale-95'
>
<DialogPanel className='w-full max-w-2xl transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all'>
<p className='block text-sm'>
If you consent to Loculus submitting your OPEN sequences to{' '}
<a href='https://www.insdc.org/' className='text-primary-600 hover:underline'>
INSDC,
</a>{' '}
your institution will be designated as your "center name" or INSDC group
identifier. This identifier will facilitate the recognition and attribution of
your sequences within the INSDC.
</p>
<button className='absolute right-2 top-2 p-1' onClick={closeDialog}>
<X className='h-6 w-6' />
</button>
</DialogPanel>
</TransitionChild>
</div>
</div>
</Dialog>
</Transition>
</>
);
};

type LabelledInputContainerProps = PropsWithChildren<{
label: string;
htmlFor: string;
className: string;
required?: boolean;
showInstitutionInfo?: boolean;
}>;

const LabelledInputContainer: FC<LabelledInputContainerProps> = ({
children,
label,
htmlFor,
className,
required,
showInstitutionInfo,
}) => {
return (
<div className={className}>
<div>
<label htmlFor={htmlFor} className='block text-sm font-medium leading-6 text-gray-900'>
{label}
{required === true && <span className='ml-1 text-red-600'>*</span>}
{showInstitutionInfo !== undefined && showInstitutionInfo && (
<InstitutionInfoButton></InstitutionInfoButton>
)}
</label>
<div className='mt-1'>{children}</div>
</div>
</div>
);
};
const LabelledInputContainer: FC<LabelledInputContainerProps> = ({ children, label, htmlFor, className, required }) => (
<div className={className}>
<label htmlFor={htmlFor} className='block text-sm font-medium leading-6 text-gray-900'>
{label}
{required === true && <span className='ml-1 text-red-600'>*</span>}
</label>
<div className='mt-1'>{children}</div>
</div>
);

type TextInputProps = {
className: string;
label: string;
name: string;
fieldMappingKey: keyof typeof fieldMapping;
type: ComponentProps<'input'>['type'];
showInstitutionInfo?: boolean;
};

const TextInput: FC<TextInputProps> = ({ className, label, name, fieldMappingKey, type, showInstitutionInfo }) => (
const TextInput: FC<TextInputProps> = ({ className, label, name, fieldMappingKey, type }) => (
<LabelledInputContainer
className={className}
label={label}
htmlFor={name}
required={fieldMapping[fieldMappingKey].required}
showInstitutionInfo={showInstitutionInfo}
>
<input
type={type}
Expand All @@ -276,7 +198,6 @@ const InstitutionNameInput = () => (
label='Institution'
name='institution-name'
fieldMappingKey='institution'
showInstitutionInfo
/>
);

Expand Down
1 change: 1 addition & 0 deletions website/tests/pages/revise/revise.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class RevisePage {
await this.setSequenceFile();
await this.setRevisedMetadataFile(accessions);
await this.page.getByText('I confirm I have not and will not submit this data independently to INSDC').click();
await this.page.getByText('I confirm that the data submitted is not sensitive or human-identifiable').click();
await this.page.getByRole('button', { name: 'Submit' }).click();
}

Expand Down
3 changes: 3 additions & 0 deletions website/tests/pages/submission/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ test.describe('The submit page', () => {
await Promise.all([submitPage.uploadSequenceData(), submitPage.uploadMetadata()]);

await submitPage.confirmationINSDCTerms.click();
await submitPage.confirmationNoPII.click();
await submitPage.submitButton.click();

await submitPage.page.waitForURL(`${baseUrl}${routes.userSequenceReviewPage(dummyOrganism.key, groupId)}`);
Expand All @@ -31,6 +32,7 @@ test.describe('The submit page', () => {
await Promise.all([submitPage.uploadCompressedSequenceData(), submitPage.uploadCompressedMetadata()]);

await submitPage.confirmationINSDCTerms.click();
await submitPage.confirmationNoPII.click();
await submitPage.submitButton.click();

await submitPage.page.waitForURL(`${baseUrl}${routes.userSequenceReviewPage(dummyOrganism.key, groupId)}`);
Expand All @@ -44,6 +46,7 @@ test.describe('The submit page', () => {
await Promise.all([submitPage.uploadSequenceData(), submitPage.uploadMetadata()]);
await submitPage.selectRestrictedDataUseTerms();
await submitPage.confirmationINSDCTerms.click();
await submitPage.confirmationNoPII.click();
await submitPage.submitButton.click();
await expect(submitPage.page.getByText('Response Sequence Headers')).toBeVisible();

Expand Down
4 changes: 4 additions & 0 deletions website/tests/pages/submission/submit.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
export class SubmitPage {
public readonly submitButton: Locator;
public readonly confirmationINSDCTerms: Locator;
public readonly confirmationNoPII: Locator;
public readonly dataUseTermsDropdown: Locator;
public readonly loginButton: Locator;

Expand All @@ -21,6 +22,9 @@ export class SubmitPage {
this.confirmationINSDCTerms = page.getByText(
'I confirm I have not and will not submit this data independently to INSDC',
);
this.confirmationNoPII = page.getByText(
'I confirm that the data submitted is not sensitive or human-identifiable',
);
this.dataUseTermsDropdown = page.locator('#dataUseTermsDropdown');
this.loginButton = page.locator('a', { hasText: 'Login or register' });
}
Expand Down

0 comments on commit 7f531e4

Please sign in to comment.