Skip to content

Commit

Permalink
split combined error message component and cleaned up browse page sli…
Browse files Browse the repository at this point in the history
…ghtly
  • Loading branch information
sanghoonio committed Sep 17, 2024
1 parent 012b801 commit 3131ecb
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 258 deletions.
4 changes: 2 additions & 2 deletions web/src/components/browse/namespace-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const NamespaceGrid = (props: Props) => {
return (
<div className="row mt-1">
<div className="col-12 col-lg-10 offset-lg-1">
<div className="row row-cols-1 row-cols-sm-3 row-cols-xl-5 g-lg-4 g-3">
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-xxl-5 g-lg-4 g-3">
{namespaces && (
Object.values(namespaces).map((item, index: number) => (
<div key={index} className="col">
Expand All @@ -30,7 +30,7 @@ export const NamespaceGrid = (props: Props) => {
</a>
</p>
<p className={`card-text mb-2 text-sm ${item?.namespace === selectedNamespace ? 'fw-medium' : 'fw-normal'}`}>
{item?.number_of_projects} Projects
{item?.number_of_projects} {item?.number_of_projects === 1 ? 'Project' : 'Projects'}
</p>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/browse/namespace-long-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const NamespaceLongRow = (props: Props) => {
<div
key={index}
ref={(el) => { itemRefs.current[item.namespace] = el; }}
className="col-xl-2 col-md-4 flex-shrink-0"
className="col-xxl-2 col-lg-3 col-md-4 col-sm-6 flex-shrink-0"
style={{ scrollSnapAlign: 'start' }}
>
<div className={`card shadow-sm position-relative cursor-pointer ${item?.namespace === selectedNamespace ? 'bg-primary-subtle' : 'bg-body-tertiary namespace-card'}`}>
Expand All @@ -70,7 +70,7 @@ export const NamespaceLongRow = (props: Props) => {
</a>
</p>
<p className={`card-text mb-2 text-sm ${item?.namespace === selectedNamespace ? 'fw-medium' : 'fw-normal'}`}>
{item?.number_of_projects} Projects
{item?.number_of_projects} {item?.number_of_projects === 1 ? 'Project' : 'Projects'}
</p>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions web/src/components/browse/project-accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ export const ProjectAccordion = (props: Props) => {
aria-controls={`collapse${key}`}
>
<span style={{minWidth: '2.5em'}}>{index + 1}.</span>
<span className='w-75'>{project.namespace}/<span className='fw-semibold'>{project.name}</span>:{project.tag}</span>
<div className='col-lg-9 col-md-7'>{project.namespace}/<span className='fw-semibold'>{project.name}</span>:{project.tag}</div>

<span className='text-xs text-start d-flex justify-content-between' style={{width: '15%'}}>
<div className='d-none d-md-flex text-xs text-start justify-content-between' style={{width: '15%'}}>

<span className='ps-1' style={{minWidth: '60%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}><span className='fw-medium'>Sample Count: </span>{project.number_of_samples}</span>
<span> | </span>
<span className='ps-1' style={{minWidth: '20%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}><span className='fw-medium'>Stars: </span>{project.stars_number}</span>

</span>
</div>
</button>
</h2>
<div
Expand Down
32 changes: 2 additions & 30 deletions web/src/components/forms/blank-project-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { arraysToSampleList, sampleListToArrays } from '../../utils/sample-table
import { ProjectConfigEditor } from '../project/project-config';
import { SampleTable } from '../tables/sample-table';
import { SchemaDropdown } from './components/schemas-databio-dropdown';
import { CombinedErrorMessage } from './components/combined-error-message'

interface BlankProjectInputs {
is_private: boolean;
Expand All @@ -27,35 +28,6 @@ interface Props {
defaultNamespace?: string;
}

type CombinedErrorMessageProps = {
errors: FieldErrors<BlankProjectInputs>;
};

const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors } = props;
const nameError = errors.project_name?.message;
const tagError = errors.tag?.message;
let msg = null;

if (nameError == 'empty' && !tagError) {
msg = 'Project Name must not be empty.';
} else if (nameError == 'invalid' && !tagError) {
msg = "Project Name must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'empty' && tagError == 'invalid') {
msg = "Project Name must not be empty and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'invalid' && tagError == 'invalid') {
msg = "Project Name and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (!nameError && tagError == 'invalid') {
msg = "Project Tag must contain only alphanumeric characters, '-', or '_'.";
}

if (nameError || tagError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
};

export const BlankProjectForm = (props: Props) => {
const { onHide, defaultNamespace } = props;
// get user innfo
Expand Down Expand Up @@ -175,7 +147,7 @@ sample_table: samples.csv
placeholder="default"
/>
</div>
<CombinedErrorMessage errors={errors}/>
<CombinedErrorMessage errors={errors} formType={'project'}/>
<label className="fw-semibold text-sm mt-2">Description</label>
<textarea
id="blank_description"
Expand Down
49 changes: 49 additions & 0 deletions web/src/components/forms/components/combined-error-message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { FC } from 'react';

type CombinedErrorMessageProps = {
errors: FieldErrors<any>;
formType: string;
};

export const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors, formType } = props;

if (formType === 'schema') {
const nameError = errors.name?.message;
let msg = null;

if (nameError == 'empty') {
msg = 'Schema Name must not be empty.';
} else if (nameError == 'invalid') {
msg = "Schema Name must contain only alphanumeric characters, '.', '-', or '_'.";
}

if (nameError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}
return null;
} else if (formType === 'project') {
const nameError = errors.project_name?.message;
const tagError = errors.tag?.message;
let msg = null;

if (nameError == 'empty' && !tagError) {
msg = 'Project Name must not be empty.';
} else if (nameError == 'invalid' && !tagError) {
msg = "Project Name must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'empty' && tagError == 'invalid') {
msg = "Project Name must not be empty and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'invalid' && tagError == 'invalid') {
msg = "Project Name and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (!nameError && tagError == 'invalid') {
msg = "Project Tag must contain only alphanumeric characters, '-', or '_'.";
}

if (nameError || tagError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
}

};
25 changes: 2 additions & 23 deletions web/src/components/forms/create-schema-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Controller, FieldErrors, useForm } from 'react-hook-form';

import { useSession } from '../../contexts/session-context';
import { useCreateSchemaMutation } from '../../hooks/mutations/useCreateSchemaMutation';
import { CombinedErrorMessage } from './components/combined-error-message'

const defaultSchemaYaml = `properties:
samples:
Expand Down Expand Up @@ -43,28 +44,6 @@ type FormFields = {
schemaYaml: string;
};

type CombinedErrorMessageProps = {
errors: FieldErrors<BlankSchemaInputs>;
};

const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors } = props;
const nameError = errors.name?.message;
let msg = null;

if (nameError == 'empty') {
msg = 'Schema Name must not be empty.';
} else if (nameError == 'invalid') {
msg = "Schema Name must contain only alphanumeric characters, '.', '-', or '_'.";
}

if (nameError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
};

export const CreateSchemaForm = (props: Props) => {
const { onCancel, onSubmit, editorHeight, defaultNamespace } = props;
const { user } = useSession();
Expand Down Expand Up @@ -145,7 +124,7 @@ export const CreateSchemaForm = (props: Props) => {
/>
</div>
</div>
<CombinedErrorMessage errors={errors} />
<CombinedErrorMessage errors={errors} formType={'schema'} />
<label className="fw-semibold text-sm mt-2">Description</label>
<textarea
{...register('description')}
Expand Down
32 changes: 2 additions & 30 deletions web/src/components/forms/pop-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ProjectAnnotation } from '../../../types';
import { useSession } from '../../contexts/session-context';
import { usePopCreateMutation } from '../../hooks/mutations/usePopCreateMutation';
import { PepSelector } from './components/pep-selector';
import { CombinedErrorMessage } from './components/combined-error-message'

interface POPInputs {
is_private: boolean;
Expand All @@ -21,35 +22,6 @@ interface Props {
defaultNamespace?: string;
}

type CombinedErrorMessageProps = {
errors: FieldErrors<POPInputs>;
};

const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors } = props;
const nameError = errors.project_name?.message;
const tagError = errors.tag?.message;
let msg = null;

if (nameError == 'empty' && !tagError) {
msg = 'Project Name must not be empty.';
} else if (nameError == 'invalid' && !tagError) {
msg = "Project Name must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'empty' && tagError == 'invalid') {
msg = "Project Name must not be empty and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'invalid' && tagError == 'invalid') {
msg = "Project Name and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (!nameError && tagError == 'invalid') {
msg = "Project Tag must contain only alphanumeric characters, '-', or '_'.";
}

if (nameError || tagError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
};

export const PopForm: FC<Props> = ({ onHide, defaultNamespace }) => {
// get user innfo
const { user } = useSession();
Expand Down Expand Up @@ -154,7 +126,7 @@ export const PopForm: FC<Props> = ({ onHide, defaultNamespace }) => {
/>
</div>
</div>
<CombinedErrorMessage errors={errors} />
<CombinedErrorMessage errors={errors} formType={'project'} />
<label className="fw-semibold text-sm mt-2">Description</label>
<textarea
id="blank_description"
Expand Down
36 changes: 4 additions & 32 deletions web/src/components/forms/project-upload-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { popFileFromFileList } from '../../utils/dragndrop';
import { GitHubAvatar } from '../badges/github-avatar';
import { FileDropZone } from './components/file-dropzone';
import { SchemaDropdown } from './components/schemas-databio-dropdown';
import { CombinedErrorMessage } from './components/combined-error-message'

interface FromFileInputs {
is_private: boolean;
Expand All @@ -25,35 +26,6 @@ interface Props {
defaultNamespace?: string;
}

type CombinedErrorMessageProps = {
errors: FieldErrors<FromFileInputs>;
};

const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors } = props;
const nameError = errors.name?.message;
const tagError = errors.tag?.message;
let msg = null;

if (nameError == 'empty' && !tagError) {
msg = 'Project Name must not be empty.';
} else if (nameError == 'invalid' && !tagError) {
msg = "Project Name must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'empty' && tagError == 'invalid') {
msg = "Project Name must not be empty and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (nameError == 'invalid' && tagError == 'invalid') {
msg = "Project Name and Tag must contain only alphanumeric characters, '-', or '_'.";
} else if (!nameError && tagError == 'invalid') {
msg = "Project Tag must contain only alphanumeric characters, '-', or '_'.";
}

if (nameError || tagError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
};

export const ProjectUploadForm = ({ onHide, defaultNamespace }: Props) => {
// get user info
const { user } = useSession();
Expand All @@ -77,7 +49,7 @@ export const ProjectUploadForm = ({ onHide, defaultNamespace }: Props) => {

const uploadFiles = watch('files');
const namespace = watch('namespace');
const projectName = watch('name');
const projectName = watch('project_name');
const tag = watch('tag');
const description = watch('description');
const isPrivate = watch('is_private');
Expand Down Expand Up @@ -131,7 +103,7 @@ export const ProjectUploadForm = ({ onHide, defaultNamespace }: Props) => {
className="form-control"
placeholder="name"
// dont allow any whitespace
{...register('name', {
{...register('project_name', {
required: {
value: true,
message: "empty",
Expand Down Expand Up @@ -160,7 +132,7 @@ export const ProjectUploadForm = ({ onHide, defaultNamespace }: Props) => {
/>
</div>
</div>
<CombinedErrorMessage errors={errors} />
<CombinedErrorMessage errors={errors} formType={'project'} />
<label className="fw-semibold text-sm mt-2">Description</label>
<textarea
id="description"
Expand Down
25 changes: 2 additions & 23 deletions web/src/components/forms/upload-schema-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useSession } from '../../contexts/session-context';
import { useUploadSchemaFile } from '../../hooks/mutations/useUploadSchemaFile';
import { GitHubAvatar } from '../badges/github-avatar';
import { FileDropZone } from './components/file-dropzone';
import { CombinedErrorMessage } from './components/combined-error-message'

type FromFileInputs = {
isPrivate: boolean;
Expand All @@ -22,28 +23,6 @@ type Props = {
defaultNamespace?: string;
};

type CombinedErrorMessageProps = {
errors: FieldErrors<FromFileInputs>;
};

const CombinedErrorMessage = (props: CombinedErrorMessageProps) => {
const { errors } = props;
const nameError = errors.name?.message;
let msg = null;

if (nameError == 'empty') {
msg = 'Schema Name must not be empty.';
} else if (nameError == 'invalid') {
msg = "Schema Name must contain only alphanumeric characters, '.', '-', or '_'.";
}

if (nameError) {
return <p className="text-danger text-xs pt-1 mb-0">{msg}</p>;
}

return null;
};

export const SchemaUploadForm = (props: Props) => {
const { defaultNamespace, onCancel, onSubmit } = props;

Expand Down Expand Up @@ -132,7 +111,7 @@ export const SchemaUploadForm = (props: Props) => {
/>
</div>
</div>
<CombinedErrorMessage errors={errors} />
<CombinedErrorMessage errors={errors} formType={'schema'} />
<label className="fw-semibold text-sm mt-2">Description</label>
<textarea
id="description"
Expand Down
6 changes: 3 additions & 3 deletions web/src/pages/Browse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export function Browse() {

<div className="row mt-0">
<div className="col-12">
{topNamespace?.data?.results ? (
{topNamespace?.data?.results || isLoading ? (
<>
<div className="d-flex flex-wrap align-items-center justify-content-between">
<div className="fs-6 fw-medium pt-3">Top 10 Starred PEPs</div>
Expand All @@ -181,11 +181,11 @@ export function Browse() {
Want to see more? Visit the namespace to view remaining projects.
</p>
</>
) : selectedNamespace ? (
) : (
<div className="col-12 mt-4 text-center">
<LoadingSpinner />
</div>
) : null}
)}
</div>
</div>
</>
Expand Down
Loading

0 comments on commit 3131ecb

Please sign in to comment.