Skip to content

Commit

Permalink
add browse table
Browse files Browse the repository at this point in the history
  • Loading branch information
sanghoonio committed Sep 18, 2024
1 parent 359f2ef commit 01f67db
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 13 deletions.
37 changes: 25 additions & 12 deletions web/src/components/browse/project-accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useState } from 'react';

import React, { useState } from 'react';
import { Markdown } from '../markdown/render';
import { ProjectAnnotation } from '../../../types';
import { dateStringToDateTime, dateStringToDateTimeShort } from '../../utils/dates'
import { BrowseTable } from '../tables/browse-table';

type Props = {
projects: ProjectAnnotation[];
Expand All @@ -14,43 +14,45 @@ export const ProjectAccordion = (props: Props) => {
// Filter out the 'length' property
const projectItems = Object.entries(projects).filter(([key]) => key !== 'length');

// Set the initial open item to the first item's key, or null if there are no items
const initialOpenItem = projectItems.length > 0 ? projectItems[0][0] : null;
const [openItem, setOpenItem] = useState<string | null>(initialOpenItem);

const handleAccordionToggle = (key: string) => {
setOpenItem(prevOpenItem => prevOpenItem === key ? null : key);
};

return (
<div className="accordion mt-2" id="projectAccordion">
{projectItems.map(([key, project], index) => (
<div className="accordion-item shadow-sm" key={key}>
<h2 className="accordion-header" id={`heading${key}`}>
<button
className={`accordion-button py-2 ${index !== 0 ? 'collapsed' : ''}`}
className={`accordion-button py-2 ${openItem !== key ? 'collapsed' : ''}`}
type="button"
data-bs-toggle="collapse"
data-bs-target={`#collapse${key}`}
aria-expanded={index === 0 ? 'true' : 'false'}
onClick={() => handleAccordionToggle(key)}
aria-expanded={openItem === key}
aria-controls={`collapse${key}`}
>
<span style={{minWidth: '2.5em'}}>{index + 1}.</span>
<div className='col-lg-9 col-md-7'>{project.namespace}/<span className='fw-semibold'>{project.name}</span>:{project.tag}</div>

<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>

</div>
</button>
</h2>
<div
id={`collapse${key}`}
className={`accordion-collapse collapse ${index === 0 ? 'show' : ''}`}
className={`accordion-collapse collapse ${openItem === key ? 'show' : ''}`}
aria-labelledby={`heading${key}`}
data-bs-parent="#projectAccordion"
>
<div className="accordion-body">
<div className='row'>
<div className='col'>
{project.description ? <Markdown>{project.description}</Markdown> : <p className='fst-italic'>No description</p>}
<span className='m-0 pe-4 text-sm'><span className='fw-medium'>Created:</span> {dateStringToDateTime(project.submission_date)}</span>
<span className='m-0 text-sm'><span className='fw-medium'>Updated:</span> {dateStringToDateTime(project.last_update_date)}</span>
</div>
<div className='col-2 d-flex align-items-center justify-content-end'>
<a
Expand All @@ -63,6 +65,17 @@ export const ProjectAccordion = (props: Props) => {
</a>
</div>
</div>
{openItem === key && (
<div className='row'>
<BrowseTable namespace={project.namespace} project={project.name} tag={project.tag} />
</div>
)}
<div className='row mt-3'>
<div className='col'>
<span className='m-0 pe-4 text-sm'><span className='fw-medium'>Created:</span> {dateStringToDateTime(project.submission_date)}</span>
<span className='m-0 text-sm'><span className='fw-medium'>Updated:</span> {dateStringToDateTime(project.last_update_date)}</span>
</div>
</div>
</div>
</div>
</div>
Expand Down
69 changes: 69 additions & 0 deletions web/src/components/tables/browse-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { HotTable } from '@handsontable/react';
import Handsontable from 'handsontable';
import { formatToPercentage } from '../../utils/etc';
import { useSampleTable } from '../../hooks/queries/useSampleTable';
import { arraysToSampleList, sampleListToArrays } from '../../utils/sample-table';
import { LoadingSpinner } from '../spinners/loading-spinner';

type BrowseTableProps = {
namespace: string;
project: string;
tag: string;
};

export const BrowseTable = (props: BrowseTableProps) => {
const { namespace, project, tag } = props;
const { data: tabData, isFetching } = useSampleTable({
namespace,
project,
tag,
enabled: true
});
const tabSamples = tabData?.items || [];

return (
<>
{isFetching ? (
<div className="col text-center my-4">
<LoadingSpinner />
</div>
) : tabSamples.length > 0 ? (
<div className="col w-100 h-100">
<p className='fw-medium text-sm mb-1'>Sample Table:</p>
<div className="col overflow-auto border border-secondary-subtle rounded-2 shadow-sm p-0">
<HotTable
data={sampleListToArrays(tabSamples)}
colHeaders={false}
rowHeaders={true}
width="100%"
height={Math.min((tabSamples.length + 1) * 23, 180)}
colWidths="100%"
stretchH="all"
autoColumnSize={false}
readOnly={true}
cells={(row, col) => {
const cellProperties: Handsontable.CellProperties = {
row: row,
col: col,
className: row === 0 ? 'fw-bold' : '',
instance: {} as Handsontable.Core,
visualRow: row,
visualCol: col,
prop: col
};
return cellProperties;
}}
licenseKey="non-commercial-and-evaluation"
className="custom-handsontable"
/>
</div>
</div>
) : (
<div className="col text-center text-sm my-4">
<span className='fw-semibold'>This project has no samples.</span>
</div>
)}
</>
);
};
3 changes: 2 additions & 1 deletion web/src/components/tables/standardizer-table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { HotTable } from '@handsontable/react';
import Handsontable from 'handsontable';

import { formatToPercentage } from '../../utils/etc';

type StandardizerTableProps = {
Expand Down Expand Up @@ -52,7 +53,7 @@ export const StandardizerTable = (props: StandardizerTableProps) => {
) : null}
<div className="col-6 text-center">
<div
className="w-100 h-100 overflow-auto border border-secondary-subtle rounded-2 shadow-sm"
className="w-100 h-100 border border-secondary-subtle rounded-2 shadow-sm"
style={{ bottom: '-1px' }}
>
<HotTable
Expand Down

0 comments on commit 01f67db

Please sign in to comment.