Skip to content

Commit

Permalink
Merge pull request #395 from pepkit/dev
Browse files Browse the repository at this point in the history
Hotfix bug fixes and add warning to metadata standardizer for projects with 9+ columns
  • Loading branch information
sanghoonio authored Sep 25, 2024
2 parents 44aff8a + c1e98ab commit d59bd90
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 132 deletions.
7 changes: 7 additions & 0 deletions web/src/components/forms/components/pep-search-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ export const PepSearchDropdown = (props: Props) => {
value: `${n.namespace}/${n.name}:${n.tag}`,
})) || []
}
styles={{
control: (provided) => ({
...provided,
borderRadius: '.375em',
borderColor: '#dee2e6'
})
}}
placeholder="Search for PEPs"
menuPlacement="bottom"
controlShouldRenderValue={true}
Expand Down
27 changes: 23 additions & 4 deletions web/src/components/modals/remove-pep-from-pop.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { FC, useState } from 'react';
import { Modal } from 'react-bootstrap';
import { useParams, useSearchParams } from 'react-router-dom';

import { Sample } from '../../../types';
import { useSampleTableMutation } from '../../hooks/mutations/useSampleTableMutation';
import { useTotalProjectChangeMutation } from '../../hooks/mutations/useTotalProjectChangeMutation';
import { useProjectConfig } from '../../hooks/queries/useProjectConfig';
import { useSampleTable } from '../../hooks/queries/useSampleTable';
import { useSubsampleTable } from '../../hooks/queries/useSubsampleTable';

interface Props {
show: boolean;
Expand Down Expand Up @@ -33,7 +37,18 @@ export const RemovePEPFromPOPModal: FC<Props> = ({
setConfirmText('');
};

const { isPending: isSampleTablePending, submit } = useSampleTableMutation(
let { namespace, project, tag } = useParams();

const { data: projectConfig } = useProjectConfig(namespace, project, tag);
const { data: subSampleTable } = useSubsampleTable(namespace, project, tag);

// const { isPending: isSampleTablePending, submit } = useSampleTableMutation(
// namespaceToRemoveFrom!,
// projectToRemoveFrom!,
// tagToRemoveFrom || 'default',
// );

const { isPending: isSampleTablePending, submit } = useTotalProjectChangeMutation(
namespaceToRemoveFrom!,
projectToRemoveFrom!,
tagToRemoveFrom || 'default',
Expand Down Expand Up @@ -74,13 +89,17 @@ export const RemovePEPFromPOPModal: FC<Props> = ({
<button
onClick={() => {
submit(
currentPeps.filter((pep) => pep.sample_name !== `${namespaceToRemove}/${projectToRemove}:${tagToRemove}`),
{
config: projectConfig?.config,
samples: currentPeps.filter((pep) => pep.sample_name !== `${namespaceToRemove}/${projectToRemove}:${tagToRemove}`),
subsamples: subSampleTable?.items,
},
{
onSuccess: () => {
onSuccess();
onHide();
},
},
}
);
}}
disabled={confirmText !== `${namespaceToRemove}/${projectToRemove}:${tagToRemove}` || isSampleTablePending}
Expand Down
16 changes: 13 additions & 3 deletions web/src/components/modals/standardize-metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const StandardizeMetadataModal = (props: Props) => {
setResetStandardizedData,
} = props;

const PH_ID_COL = 'ph_id';
const maxColsExceeded = newSamples[0].length >= 9;

const { data: schemaOptions } = useStandardizerSchemas(namespace);

Expand Down Expand Up @@ -250,6 +250,16 @@ export const StandardizeMetadataModal = (props: Props) => {
</div>
</div>
</form>

{maxColsExceeded && (
<div className='row'>
<p className='text-sm mt-3 mb-1'>
<strong>Note: </strong>
Your project has nine or more columns.
Due to server constraints, standardization of nine or more columns on PEPhub may take some time. Please be patient.
</p>
</div>
)}
</div>
</div>

Expand All @@ -267,7 +277,7 @@ export const StandardizeMetadataModal = (props: Props) => {
</div>

<form>
{Object.keys(standardizedData).filter(key => key !== 'ph_id').map((key, index) => (
{Object.keys(standardizedData).map((key, index) => (
<StandardizerTable
columnKey={key}
columnIndex={index}
Expand All @@ -292,7 +302,7 @@ export const StandardizeMetadataModal = (props: Props) => {
<div>
{whereDuplicates !== null && (
<div className="text-danger me-auto mt-3 pt-2 d-inline-block">
Warning: ensure no duplicate column names have been selected.
<strong>Warning:</strong> ensure no duplicate column names have been selected.
</div>
)}
<button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, Fragment, useState } from 'react';
import { FC, Fragment, useState, useEffect } from 'react';
import { Button, ButtonGroup, Dropdown } from 'react-bootstrap';
import toast from 'react-hot-toast';

Expand Down
18 changes: 10 additions & 8 deletions web/src/components/namespace/project-cards/project-card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, Fragment, useState } from 'react';
import { FC, Fragment, useState, useMemo} from 'react';

import { ProjectAnnotation } from '../../../../types';
import { useSession } from '../../../contexts/session-context';
Expand All @@ -23,8 +23,11 @@ export const ProjectCard: FC<Props> = ({ project }) => {
const [showForkPEPModal, setShowForkPEPModal] = useState(false);
const [copied, setCopied] = useState(false);

const isStarred = stars?.find(
(star) => star.namespace === project.namespace && star.name === project.name && star.tag === project.tag,
const isStarred = useMemo(() =>
!!stars?.find(
(star) => star.namespace === project.namespace && star.name === project.name && star.tag === project.tag
),
[stars, project.namespace, project.name, project.tag]
);

return (
Expand Down Expand Up @@ -55,19 +58,18 @@ export const ProjectCard: FC<Props> = ({ project }) => {
</span>
) : null}
</div>
{ !isLoading ?
{ !isLoading && (
<ProjectCardDropdown
project={project}
isStarred={!!isStarred}
isStarred={isStarred}
copied={copied}
setCopied={setCopied}
setShowDeletePEPModal={setShowDeletePEPModal}
setShowForkPEPModal={setShowForkPEPModal}
starNumber={project?.stars_number}
key={project?.digest}
/>
: null
}

)}
</div>
<div className="mb-0">
{project.description ? (
Expand Down
68 changes: 32 additions & 36 deletions web/src/components/pop/pop-card-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, Fragment } from 'react';
import { FC, Fragment, useState, useEffect } from 'react';
import { Button, ButtonGroup, Dropdown } from 'react-bootstrap';
import toast from 'react-hot-toast';
import { useParams, useSearchParams } from 'react-router-dom';
Expand All @@ -9,6 +9,7 @@ import { useAddStar } from '../../hooks/mutations/useAddStar';
import { useRemoveStar } from '../../hooks/mutations/useRemoveStar';
import { copyToClipboard } from '../../utils/etc';
import { LoadingSpinner } from '../spinners/loading-spinner';
import { numberWithCommas } from '../../utils/etc';

interface Props {
project: ProjectAnnotation;
Expand All @@ -17,23 +18,28 @@ interface Props {
setCopied: (copied: boolean) => void;
setShowForkPEPModal: (show: boolean) => void;
setShowRemovePEPModal: (show: boolean) => void;
starNumber: number;
}

export const PopCardDropdown: FC<Props> = (props) => {
let { namespace, project: name } = useParams();

const { project, isStarred, copied, setCopied, setShowForkPEPModal, setShowRemovePEPModal } = props;
const { project, isStarred, copied, setCopied, setShowForkPEPModal, setShowRemovePEPModal, starNumber } = props;

const { user } = useSession();

const { isPending: isAddingStar, addStar } = useAddStar(user?.login || '');
const starRemoveMutation = useRemoveStar(user?.login || '');

const [localStarred, setLocalStarred] = useState(isStarred);

return (
<Dropdown as={ButtonGroup}>
<Button
disabled={isAddingStar || starRemoveMutation.isPending}
variant="outline-dark"
variant="outline"
className={isStarred ? 'border mt-1 shadow-none rounded-start-2 starred-button' : 'border mt-1 shadow-none rounded-start-2 star-button'}
style={{zIndex: 2}}
size="sm"
onClick={() => {
if (!user) {
Expand All @@ -54,42 +60,32 @@ export const PopCardDropdown: FC<Props> = (props) => {
}}
>
{isStarred ? (
<Fragment>
<div className="d-flex align-items-center">
<i className="text-primary bi bi-star-fill me-1"></i>
<span className="text-primary">
s
{starRemoveMutation.isPending ? (
<Fragment>
{copied ? 'Copied!' : 'Star'}
<LoadingSpinner className="w-4 h-4 spin ms-1 mb-tiny fill-secondary" />
</Fragment>
) : (
<Fragment>{copied ? 'Copied!' : 'Star'}</Fragment>
)}
</span>
</div>
</Fragment>
<div className="d-flex align-items-center text-sm">
<i className="bi bi-star-fill me-1 position-relative" style={{paddingRight: '2px', marginTop: '-0.666666px'}}></i>
<span className='fw-semibold'>
<Fragment>
{copied ? 'Copied!' : (localStarred ? numberWithCommas(starNumber) : numberWithCommas(starNumber + 1))}
</Fragment>
</span>
</div>
) : (
<Fragment>
<div className="d-flex align-items-center">
<i className="bi bi-star me-1"></i>
<span>
{starRemoveMutation.isPending ? (
<Fragment>
{copied ? 'Copied!' : 'Star'}
<LoadingSpinner className="w-4 h-4 spin ms-1 mb-tiny fill-secondary" />
</Fragment>
) : (
<Fragment>{copied ? 'Copied!' : 'Star'}</Fragment>
)}
</span>
</div>
</Fragment>
<div className="d-flex align-items-center text-sm">
<i className="bi bi-star me-1 position-relative" style={{paddingRight: '2px', marginTop: '-0.666666px'}}></i>
<span className='fw-normal'>
<Fragment>
{copied ? 'Copied!' : (localStarred ? numberWithCommas(starNumber - 1) : numberWithCommas(starNumber))}
</Fragment>
</span>
</div>
)}
</Button>
<Dropdown.Toggle split variant="outline-dark" id="dropdown-split-basic" />
<Dropdown.Menu>
<Dropdown.Toggle
split
variant="outline"
className='border mt-1 me-1 shadow-none rounded-end-2 star-dropdown-button'
style={{zIndex: 2}}
id="dropdown-split-basic" />
<Dropdown.Menu className='border border-light-subtle shadow-sm'>
<Dropdown.Item href={`/${project.namespace}/${project.name}`}>
<i className="bi bi-eye me-1"></i>
View
Expand Down
92 changes: 47 additions & 45 deletions web/src/components/pop/pop-card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from 'react';
import { FC, useState, useMemo } from 'react';

import { ProjectAnnotation, Sample } from '../../../types';
import { useSession } from '../../contexts/session-context';
Expand All @@ -25,19 +25,21 @@ export const PopCard: FC<Props> = ({ project, currentPeps, parentName, parentNam
const [showRemovePEPModal, setShowRemovePEPModal] = useState(false);
const [copied, setCopied] = useState(false);

const isStarred = stars?.find(
(star) => star.namespace === project.namespace && star.name === project.name && star.tag === project.tag,
const isStarred = useMemo(() =>
!!stars?.find(
(star) => star.namespace === project.namespace && star.name === project.name && star.tag === project.tag
),
[stars, project.namespace, project.name, project.tag]
);

return (
<div
id={`project-card-${project.namespace}/${project.name}:${project.tag}`}
className="w-100 border border-dark rounded shadow-sm p-2 mt-3"
style={{ backgroundColor: '#f6f8fa' }}
className="w-100 border rounded shadow-sm ps-3 pe-2 pb-3 pt-2 mt-3 bg-body-tertiary card namespace-card"
>
<div className="d-flex flex-row align-items-start justify-content-between">
<div className="d-flex flex-row align-items-center">
<a className="fw-bold fs-4" href={`${project.namespace}/${project.name}?tag=${project.tag}`}>
<a className="fw-semibold fs-4 stretched-link text-decoration-none text-primary-emphasis" href={`${project.namespace}/${project.name}?tag=${project.tag}`}>
{project.namespace}/{project.name}:{project.tag}
</a>
{project.is_private ? (
Expand All @@ -60,52 +62,52 @@ export const PopCard: FC<Props> = ({ project, currentPeps, parentName, parentNam
</div>
<PopCardDropdown
project={project}
isStarred={!!isStarred}
isStarred={isStarred}
copied={copied}
setCopied={setCopied}
setShowForkPEPModal={setShowForkPEPModal}
setShowRemovePEPModal={setShowRemovePEPModal}
starNumber={project?.stars_number}
key={project?.digest}
/>
</div>
<div>
<div className="d-flex flex-row align-items-center">
<div className="me-4">
<i className="bi bi-star-fill"></i>
<span className="mx-1">{project.stars_number || 0}</span>
</div>
<div className="me-4">
<label className="fw-bold">No. of samples:</label>
<span className="mx-1">{project.number_of_samples}</span>
</div>
<div>
<label className="fw-bold">Schema:</label>
<span className="mx-1">{project.pep_schema || 'No schema'}</span>
</div>
</div>
<div className="mb-0">
{project.description ? (
<MarkdownToText>{project.description}</MarkdownToText>
) : (
<em>
<span className="text-muted text-italic">No description</span>
</em>
)}
</div>
<div className="mb-0">
{project.description ? (
<MarkdownToText>{project.description}</MarkdownToText>
) : (
<em>
<span className="text-muted text-italic">No description</span>
</em>
)}
</div>
<div className="mt-3">
<div className="d-flex flex-row align-items-center text-muted">
<small>
<span className="me-3">
<i className="bi bi-calendar3"></i>
<span className="mx-1">Created:</span>
<span id="project-submission-date">{dateStringToDateTime(project.submission_date)}</span>
<i className="ms-4 bi bi-calendar3"></i>
<span className="mx-1">Updated:</span>
<span id="project-update-date">{dateStringToDateTime(project.last_update_date)}</span>
</span>
<span className="me-5">{project.digest}</span>
</small>
</div>
<div className="d-flex flex-row align-items-center mt-3 text-sm">
<span className="me-3">
<span className="fw-semibold">Sample Count:</span>
<span className="mx-1">{project.number_of_samples}</span>
</span>
<span>
<span className="fw-semibold">Schema:</span>
<span className="mx-1">{project.pep_schema || 'No schema'}</span>
</span>
</div>
<div className="d-flex flex-row align-items-center text-mute text-sm">
<span className="me-3">
<span className="fw-semibold">Created:</span>
<span className="mx-1" id="project-submission-date">{dateStringToDateTime(project.submission_date)}</span>
</span>
<span>
<span className="fw-semibold">Updated:</span>
<span className="mx-1" id="project-update-date">{dateStringToDateTime(project.last_update_date)}</span>
</span>
{project?.forked_from && (
<div className="p-1 border rounded fw-bold me-1 bg-white ms-auto position-relative forked-link" style={{zIndex: 2, margin: '-1.25em 0 -1em'}}>
<i className="bi bi-bezier2"></i>
<span className="ms-1">Forked from</span>
<a className="text-decoration-none ms-1 stretched-link" href={`/${project?.forked_from.replace(':', '?tag=')}`}>
{project?.forked_from}
</a>
</div>
)}
</div>
<ForkPEPModal
show={showForkPEPModal}
Expand Down
Loading

0 comments on commit d59bd90

Please sign in to comment.