Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browse page #387

Merged
merged 7 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions web/src/components/browse/namespace-long-row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useRef, useEffect, useCallback } from 'react';

import { BiggestNamespaceResults } from '../../../types';

type Props = {
namespaces: BiggestNamespaceResults[] | undefined;
selectedNamespace: string | undefined;
handleSelectNamespace: (selectedNamespace: string) => void;
};

export const NamespaceLongRow = (props: Props) => {
const {
namespaces,
selectedNamespace,
handleSelectNamespace
} = props;

const containerRef = useRef<HTMLDivElement>(null);
const itemRefs = useRef<{ [key: string]: HTMLDivElement | null }>({});

const isInViewport = (element: HTMLElement): boolean => {
const rect = element.getBoundingClientRect();
const padding = 12; // Adjust this value to increase or decrease the padding

return (
rect.top >= 0 - padding &&
rect.left >= 0 - padding &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + padding &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth) + padding
);
};

const scrollToItem = useCallback((namespace: string) => {
const element = itemRefs.current[namespace];
if (element && !isInViewport(element)) {
element.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start'
});
}
}, []);

useEffect(() => {
if (selectedNamespace) {
scrollToItem(selectedNamespace);
}
}, [selectedNamespace, scrollToItem]);

return (
<div className="position-relative">
<div
ref={containerRef}
className="row flex-nowrap overflow-auto pb-2 scroll-track-none"
style={{ scrollSnapType: 'x mandatory' }}
>
{namespaces && (
Object.values(namespaces).map((item, index) => (
<div
key={index}
ref={(el) => { itemRefs.current[item.namespace] = el; }}
className="col-2 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'}`}>
<div className="card-body text-center px-0">
<p className={`card-title mt-2 text-primary-emphasis ${item?.namespace === selectedNamespace ? 'fw-bold' : 'fw-semibold'}`}>
<a className='text-decoration-none text-reset stretched-link' onClick={() => handleSelectNamespace(item?.namespace)}>
{index + 1}. {item?.namespace}
</a>
</p>
<p className={`card-text mb-2 text-sm ${item?.namespace === selectedNamespace ? 'fw-medium' : 'fw-normal'}`}>
{item?.number_of_projects} Projects
</p>
</div>
</div>
</div>
))
)}
</div>
</div>
);
};
66 changes: 66 additions & 0 deletions web/src/components/browse/project-accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useState } from 'react';

import { Markdown } from '../markdown/render';
import { ProjectAnnotation } from '../../../types';
import { dateStringToDateTime } from '../../utils/dates'

type Props = {
projects: ProjectAnnotation[];
};

export const ProjectAccordion = (props: Props) => {
const { projects } = props;

// Filter out the 'length' property
const projectItems = Object.entries(projects).filter(([key]) => key !== 'length');

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' : ''}`}
type="button"
data-bs-toggle="collapse"
data-bs-target={`#collapse${key}`}
aria-expanded={index === 0 ? 'true' : 'false'}
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>
<span style={{marginLeft: '10em', minWidth: '4.5em'}} className='text-center text-sm border border-dark rounded-2 px-2 py-1'>{project.stars_number} Stars</span>
</button>
</h2>
<div
id={`collapse${key}`}
className={`accordion-collapse collapse ${index === 0 ? '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>}
<p className='m-0 text-sm'><span className='fw-semibold'>Sample Count:</span> {project.number_of_samples}</p>
<p className='m-0 text-sm'><span className='fw-semibold'>Created:</span> {dateStringToDateTime(project.submission_date)}</p>
<p className='m-0 text-sm'><span className='fw-semibold'>Updated:</span> {dateStringToDateTime(project.last_update_date)}</p>
</div>
<div className='col-1 d-flex align-items-center justify-content-end'>
<a
className='btn btn-dark fw-medium'
href={`${project.namespace}/${project.name}?tag=${project.tag}`}
target="_blank"
rel="noopener noreferrer"
>
Go <i className='bi bi-caret-right-fill'/>
</a>
</div>
</div>
</div>
</div>
</div>
))}
</div>
);
};
2 changes: 1 addition & 1 deletion web/src/components/layout/nav/nav-desktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export const NavDesktop = () => {
</div>
</li>
<li className="text-body mx-2 my-0 nav-item h5 pt-1">
<a className="nav-link" href="/schemas">
<a className="nav-link" href="/browse">
<i className="bi bi-globe2 me-1 text-base align-top"></i>Browse
</a>
</li>
Expand Down
15 changes: 2 additions & 13 deletions web/src/components/namespace/archive/namespace-archive-table.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import { FC, useState, useMemo } from 'react';

import { ArchiveItem, ArchiveResponse } from '../../../api/namespace'
import { dateStringToDateTime } from '../../../utils/dates'

interface Props {
data: ArchiveResponse;
}

const ITEMS_PER_PAGE = 10;

const formatDate = (dateString: string): string => {
const date = new Date(dateString);
return date.toLocaleString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: true
});
};

export const NamespaceArchiveTable: React.FC<Props> = ({ data }) => {
const [currentPage, setCurrentPage] = useState(1);
const [sortConfig, setSortConfig] = useState<{ key: keyof ArchiveItem; direction: 'ascending' | 'descending' }>({
Expand Down Expand Up @@ -94,7 +83,7 @@ export const NamespaceArchiveTable: React.FC<Props> = ({ data }) => {
<tr key={result.identifier}>
<td>{result.namespace}</td>
<td>{result.number_of_projects}</td>
<td>{formatDate(result.creation_date)}</td>
<td>{dateStringToDateTime(result.creation_date)}</td>
<td>{(result.file_size / 1024 / 1024 / 1024).toFixed(2)} gb</td>
<td>
<a href={result.file_path} className="btn btn-sm btn-secondary" target="_blank" rel="noopener noreferrer">
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/project/view-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const ViewSelector = (props: ViewSelectorProps) => {
}}
className="top-z w-100"
options={[
{ value: null, label: "Default view" },
{ value: null, label: "Default View" },
...(projectViews?.views.map((view) => ({
view: view.name,
description: view.description || 'No description',
Expand Down Expand Up @@ -115,7 +115,7 @@ export const ViewSelector = (props: ViewSelectorProps) => {
}
value={
view === undefined
? { value: null, label: "Default view" }
? { value: null, label: "Default View" }
: { view: view, description: view, value: view, label: view }
}
/>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/schemas/schema-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const SchemaHeader = (props: Props) => {
<div className="p-2 w-100">
<div className="d-flex align-items-center justify-content-between w-100">
<Breadcrumb className="fw-bold pt-2">
<Breadcrumb.Item href="/schemas">schemas</Breadcrumb.Item>
<Breadcrumb.Item href="/browse?view=schemas">schemas</Breadcrumb.Item>
<Breadcrumb.Item href={`/schemas/${namespace}`}>{namespace}</Breadcrumb.Item>
<Breadcrumb.Item active>{schema}</Breadcrumb.Item>
</Breadcrumb>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/schemas/schemas-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const SchemasNav = (props: Props) => {
<div className="d-flex flex-column align-items-center gap-2">
<div className="d-flex align-items-center justify-content-between w-100">
<div className="d-flex align-items-center">
<h1 className="m-0 fw-bold">PEPhub schemas</h1>
<h3 className="m-0 fw-semibold">PEPhub schemas</h3>
</div>
{user && (
<div className="d-flex align-items-center gap-1">
Expand Down
28 changes: 25 additions & 3 deletions web/src/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ body {
transition: all 180ms;
}

.namespace-nav .nav-link:hover {
.namespace-nav .nav-link:hover,
.namespace-card:hover {
background-color: #052c6512;
color: #052c65;
}
Expand Down Expand Up @@ -778,7 +779,7 @@ body {
background-color: white !important;
color: black !important;
box-shadow: .5px 1px 7px 1px #00000010 !important;
font-weight: 600 !important;
font-weight: 500 !important;
}

.modal-pill .nav-pills .nav-item {
Expand Down Expand Up @@ -809,7 +810,7 @@ body {

.modal-pill .nav-tabs .nav-link.active {
color: black !important;
font-weight: 600 !important;
font-weight: 500 !important;
}

.modal-pill .nav-tabs .nav-link {
Expand Down Expand Up @@ -870,6 +871,27 @@ body {
color: #052c65cf;
}

.scroll-track-none::-webkit-scrollbar {
width: 3px;
height: 6px;
}

.scroll-track-none::-webkit-scrollbar-button {
width: 0;
height: 0;
display: none;
}

.scroll-track-none::-webkit-scrollbar-corner {
background-color: transparent;
}

.scroll-track-none::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.2);
-webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.10), inset 0 -1px 0 rgba(0, 0, 0, 0.07);
border-radius: .375em;
}

@keyframes pulse-fast {
0%, 88%, 100% { opacity: 1; }
10% { opacity: 0.5; }
Expand Down
7 changes: 4 additions & 3 deletions web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'bootstrap-icons/font/bootstrap-icons.css';
// css
import 'bootstrap/dist/css/bootstrap.min.css';
import 'handsontable/dist/handsontable.full.min.css';
import "bootstrap/dist/js/bootstrap.bundle.min.js"
// Language
// handsontable stuff
import { registerAllModules } from 'handsontable/registry';
Expand All @@ -26,7 +27,7 @@ import { LoginSuccessPage } from './pages/LoginSuccess';
import { NamespacePage } from './pages/Namespace';
import { ProjectPage } from './pages/Project';
import { Schema } from './pages/Schema';
import { Schemas } from './pages/Schemas';
import { Browse } from './pages/Browse';
import { SearchPage } from './pages/Search';
import { EidoValidator } from './pages/Validator';

Expand Down Expand Up @@ -72,8 +73,8 @@ const router = createBrowserRouter([
),
},
{
path: '/schemas',
element: <Schemas />,
path: '/browse',
element: <Browse />,
},
{
path: '/schemas/:namespace',
Expand Down
Loading
Loading