diff --git a/web/src/components/browse/namespace-long-row.tsx b/web/src/components/browse/namespace-long-row.tsx index 8c4021a1..fa1850b0 100644 --- a/web/src/components/browse/namespace-long-row.tsx +++ b/web/src/components/browse/namespace-long-row.tsx @@ -1,29 +1,43 @@ import React, { useRef, useEffect, useCallback } from 'react'; -export const NamespaceLongRow = ({ namespaces, selectedNamespace, handleSelectNamespace }) => { - const containerRef = useRef(null); - const itemRefs = useRef({}); +import { BiggestNamespaceResults } from '../../../types'; - const isInViewport = (element) => { +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(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 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) + 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) => { - if (itemRefs.current[namespace]) { - const element = itemRefs.current[namespace]; - if (!isInViewport(element)) { - element.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - inline: 'start' - }); - } + const scrollToItem = useCallback((namespace: string) => { + const element = itemRefs.current[namespace]; + if (element && !isInViewport(element)) { + element.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + inline: 'start' + }); } }, []); @@ -39,11 +53,11 @@ export const NamespaceLongRow = ({ namespaces, selectedNamespace, handleSelectNa className="row flex-nowrap overflow-auto py-1" style={{ scrollSnapType: 'x mandatory' }} > - {namespaces?.data?.results ? ( - Object.values(namespaces.data.results).map((item, index) => ( + {namespaces ? ( + Object.values(namespaces).map((item, index) => (
itemRefs.current[item.namespace] = el} + ref={(el) => { itemRefs.current[item.namespace] = el; }} className="col-2 flex-shrink-0" style={{ scrollSnapAlign: 'start' }} > diff --git a/web/src/components/browse/project-accordion.tsx b/web/src/components/browse/project-accordion.tsx index 4f2d2e4b..a68d398a 100644 --- a/web/src/components/browse/project-accordion.tsx +++ b/web/src/components/browse/project-accordion.tsx @@ -1,17 +1,23 @@ import { useState } from 'react'; import { Markdown } from '../markdown/render'; +import { ProjectAnnotation } from '../../../types'; import 'bootstrap/dist/css/bootstrap.min.css' import "bootstrap/dist/js/bootstrap.bundle.min.js" -export const ProjectAccordion = ({ projects }) => { +type Props = { + projects: ProjectAnnotation[]; +}; + +export const ProjectAccordion = (props: Props) => { + const { projects } = props; const [openIndex, setOpenIndex] = useState(null); // Filter out the 'length' property const projectItems = Object.entries(projects).filter(([key]) => key !== 'length'); - const formatDate = (dateString) => { + const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleString('en-US', { year: 'numeric', diff --git a/web/src/pages/Browse.tsx b/web/src/pages/Browse.tsx index d6f14429..3abbf0b7 100644 --- a/web/src/pages/Browse.tsx +++ b/web/src/pages/Browse.tsx @@ -45,7 +45,7 @@ export function Browse() { const [orderBy, setOrderBy] = useState('update_date'); const [order, setOrder] = useState<'asc' | 'desc'>('desc'); const [showCreateSchemaModal, setShowCreateSchemaModal] = useState(false); - const [selectedNamespace, setSelectedNamespace] = useState(null) + const [selectedNamespace, setSelectedNamespace] = useState(undefined); const searchDebounced = useDebounce(search, 500); @@ -57,12 +57,12 @@ export function Browse() { // @ts-ignore - just for now, I know this will work fine order: 'asc', search: '', - type: view === 'pep', + type: 'pep', }); - const handleSelectNamespace = (selectedNamespace) => { - setSelectedNamespace(prevSelectedNamespace => - prevSelectedNamespace === selectedNamespace ? null : selectedNamespace + const handleSelectNamespace = (selectedNamespace: string) => { + setSelectedNamespace((prevSelectedNamespace: string | undefined) => + prevSelectedNamespace === selectedNamespace ? undefined : selectedNamespace ); } @@ -114,13 +114,13 @@ export function Browse() { ); } - const renderRow = (startIndex, endIndex) => ( + const renderRow = (startIndex: number, endIndex: number) => (
{namespaces?.data?.results ? ( Object.values(namespaces.data.results) .slice(startIndex, endIndex) - .map((item, index) => ( + .map((item, index: number) => (
@@ -207,7 +207,7 @@ export function Browse() { <>
- {selectedNamespace === null ? + {selectedNamespace === undefined ?
{renderRow(0, 5)} {renderRow(5, 10)} @@ -218,7 +218,7 @@ export function Browse() { :