From 261c79e01f0b7959fa2303d549f67d0bc0ae584e Mon Sep 17 00:00:00 2001 From: Garrett Michael Flynn Date: Thu, 26 Oct 2023 13:09:40 -0700 Subject: [PATCH] Manage dashboard with css grid. Splitter cannot be adjusted, though this should be the only inconsistency --- .gitignore | 2 + src/App.css | 35 +++++++++ src/ApplicationBar.tsx | 2 +- src/MainWindow.tsx | 64 +++++++--------- src/TabWidget/TabWidget.tsx | 15 ++-- src/components/HBoxLayout.tsx | 4 +- src/components/Splitter.tsx | 65 ++++++---------- .../ComputeResourceAppsTable.tsx | 10 +-- .../ComputeResourceAppsTableMenuBar.tsx | 3 +- .../ComputeResourcePage.tsx | 8 +- .../ComputeResourcesPage.tsx | 2 +- src/pages/DandiBrowser/DandiBrowser.tsx | 64 +++++++--------- src/pages/DandiBrowser/DandisetView.tsx | 10 +-- src/pages/DandiBrowser/SearchResults.tsx | 20 ++--- src/pages/HomePage/HomePage.tsx | 5 +- .../ProjectPage/FileBrowser/FileBrowser2.tsx | 12 +-- .../FileBrowser/FileBrowserMenuBar.tsx | 4 +- .../FileEditor/FigurlFileEditor.tsx | 4 +- .../ProjectPage/FileEditor/FileEditor.tsx | 6 +- .../ProjectPage/FileEditor/NwbFileEditor.tsx | 10 +-- src/pages/ProjectPage/JobView/JobView.tsx | 6 +- .../ProjectPage/JobsWindow/JobsTable.tsx | 14 ++-- .../JobsWindow/JobsTableMenuBar.tsx | 4 +- .../ProjectPage/JobsWindow/JobsWindow.tsx | 6 +- src/pages/ProjectPage/ProcessorsView.tsx | 13 ++-- src/pages/ProjectPage/ProjectFiles.tsx | 10 +-- src/pages/ProjectPage/ProjectHome.tsx | 7 +- src/pages/ProjectPage/ProjectJobs.tsx | 9 +-- src/pages/ProjectPage/ProjectPage.tsx | 76 +++++-------------- src/pages/ProjectsPage/ProjectsPage.tsx | 7 +- 30 files changed, 198 insertions(+), 299 deletions(-) diff --git a/.gitignore b/.gitignore index ad2e686..48f927e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ tmp __pycache__ +.env + # Logs logs *.log diff --git a/src/App.css b/src/App.css index 3fb3548..cbd038e 100644 --- a/src/App.css +++ b/src/App.css @@ -40,3 +40,38 @@ .read-the-docs { color: #888; } */ +* { + box-sizing: border-box; +} + +#main-window { + display: grid; + grid-template-areas: "a a a" + "b c c" + "b c c"; + + grid-template-rows: auto 1fr; + grid-template-columns: auto 1fr; + width: 100vw; + height: 100vh; +} + +.main { + grid-area: c; + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.splitterChild { + width: min-content; + border-right: gray 1px solid; +} + +.splitterChild:last-child { + flex-grow: 1; + min-width: 50%; + border-right: none; +} \ No newline at end of file diff --git a/src/ApplicationBar.tsx b/src/ApplicationBar.tsx index ad0b101..b59db8c 100644 --- a/src/ApplicationBar.tsx +++ b/src/ApplicationBar.tsx @@ -33,7 +33,7 @@ const ApplicationBar: FunctionComponent = () => { }, []) return ( - + logo diff --git a/src/MainWindow.tsx b/src/MainWindow.tsx index dc0d843..2b9ebd8 100644 --- a/src/MainWindow.tsx +++ b/src/MainWindow.tsx @@ -1,9 +1,8 @@ import { FunctionComponent } from "react"; -import ApplicationBar, { applicationBarHeight } from "./ApplicationBar"; +import ApplicationBar from "./ApplicationBar"; import AboutPage from "./pages/AboutPage/AboutPage"; import HomePage from "./pages/HomePage/HomePage"; import useRoute from "./useRoute"; -import useWindowDimensions from "./useWindowDimensions"; import DandiBrowser from "./pages/DandiBrowser/DandiBrowser"; import ProjectPage from "./pages/ProjectPage/ProjectPage"; import RegisterComputeResourcePage from "./pages/RegisterComputeResourcePage/RegisterComputeResourcePage"; @@ -18,41 +17,34 @@ type Props = { const MainWindow: FunctionComponent = () => { const {route} = useRoute() - const {width, height} = useWindowDimensions() return ( -
-
- -
-
- { - route.page === 'home' ? ( - - ) : (route.page === 'dandisets' || route.page === 'dandiset') ? ( - - ) : route.page === 'project' ? ( - - ) : route.page === 'about' ? ( - - ) : route.page === 'compute-resource' ? ( - - ) : route.page === 'compute-resources' ? ( - - ) : route.page === 'projects' ? ( - - ) : route.page === 'register-compute-resource' ? ( - - ) : route.page === 'github-auth' ? ( - - ) : ( -
404
- ) - } -
+
+ + { + route.page === 'home' ? ( + + ) : (route.page === 'dandisets' || route.page === 'dandiset') ? ( + + ) : route.page === 'project' ? ( + + ) : route.page === 'about' ? ( + + ) : route.page === 'compute-resource' ? ( + + ) : route.page === 'compute-resources' ? ( + + ) : route.page === 'projects' ? ( + + ) : route.page === 'register-compute-resource' ? ( + + ) : route.page === 'github-auth' ? ( + + ) : ( +
404
+ ) + }
) } diff --git a/src/TabWidget/TabWidget.tsx b/src/TabWidget/TabWidget.tsx index 47007ba..3cab568 100644 --- a/src/TabWidget/TabWidget.tsx +++ b/src/TabWidget/TabWidget.tsx @@ -11,13 +11,11 @@ type Props = { currentTabId: string | undefined setCurrentTabId: (id: string) => void onCloseTab: (id: string) => void - width: number - height: number } const tabBarHeight = 30 -const TabWidget: FunctionComponent> = ({children, tabs, currentTabId, setCurrentTabId, onCloseTab, width, height}) => { +const TabWidget: FunctionComponent> = ({children, tabs, currentTabId, setCurrentTabId, onCloseTab}) => { const currentTabIndex = useMemo(() => { if (!currentTabId) return undefined const index = tabs.findIndex(t => t.id === currentTabId) @@ -28,10 +26,7 @@ const TabWidget: FunctionComponent> = ({children, tabs, if ((children2 || []).length !== tabs.length) { throw Error(`TabWidget: incorrect number of tabs ${(children2 || []).length} <> ${tabs.length}`) } - const hMargin = 8 - const vMargin = 8 - const W = (width || 300) - hMargin * 2 - const H = height - vMargin * 2 + const [hasBeenVisible, setHasBeenVisible] = useState([]) useEffect(() => { if (currentTabIndex === undefined) return @@ -45,10 +40,10 @@ const TabWidget: FunctionComponent> = ({children, tabs, }, [setCurrentTabId, tabs]) return (
-
+
> = ({children, tabs, return (
{(visible || hasBeenVisible.includes(i)) && ( - + )}
) diff --git a/src/components/HBoxLayout.tsx b/src/components/HBoxLayout.tsx index 112c17f..274b917 100644 --- a/src/components/HBoxLayout.tsx +++ b/src/components/HBoxLayout.tsx @@ -10,11 +10,11 @@ const HBoxLayout: React.FunctionComponent> = const totalWidth = widths.reduce((a, b) => (a + b), 0) const children2 = React.Children.toArray(children).map(ch => (ch as any as ReactElement)) return ( -
+
{ children2.map((child: ReactElement, i) => { return child ? ( -
(a + b), 0), top: 0, width: widths[i], height}}> +
) : diff --git a/src/components/Splitter.tsx b/src/components/Splitter.tsx index 9b74185..bd43b4d 100644 --- a/src/components/Splitter.tsx +++ b/src/components/Splitter.tsx @@ -2,9 +2,9 @@ import React, { FunctionComponent, PropsWithChildren, ReactElement, useEffect, u import Draggable, { DraggableData, DraggableEvent } from 'react-draggable'; interface Props { - width: number - height: number - initialPosition: number + // width: number + // height: number + initialPosition: number // Ratio? positionFromRight?: boolean onChange?: (newPosition: number) => void gripThickness?: number @@ -23,13 +23,14 @@ const defaultGripMargin = 2 const Draggable1: any = Draggable const Splitter: FunctionComponent> = (props) => { - const {width, height, initialPosition, onChange, adjustable=true, positionFromRight=false, direction='horizontal', hideSecondChild} = props + const { width, height, initialPosition, onChange, adjustable=true, positionFromRight=false, direction='horizontal', hideSecondChild} = props const size1 = direction === 'horizontal' ? width : height // const size2 = direction === 'horizontal' ? height : width const [gripPosition, setGripPosition] = useState(initialPosition) useEffect(() => { + if (gripPosition > size1 - 4) { setGripPosition(size1 - 4) } @@ -65,7 +66,7 @@ const Splitter: FunctionComponent> = (props) => { } if (!child2) { - return + return } let gripPositionFromLeft = positionFromRight ? size1 - gripPosition : gripPosition @@ -79,36 +80,9 @@ const Splitter: FunctionComponent> = (props) => { const size1A = gripPositionFromLeft - gripThickness / 2 - gripMargin const size1B = size1 - size1A - gripThickness - 2 * gripMargin - const style0: React.CSSProperties = { - top: 0, - left: 0, - width: width, - height: height, - overflow: 'hidden' - }; - const style1: React.CSSProperties = { - left: 0, - top: 0, - width: direction === 'horizontal' ? size1A : width, - height: direction === 'horizontal' ? height : size1A, - zIndex: 0, - overflowY: direction === 'horizontal' ? 'auto' : 'hidden', - overflowX: direction === 'horizontal' ? 'hidden' : 'auto' - }; - const style2: React.CSSProperties = { - left: direction === 'horizontal' ? size1A + gripThickness + 2 * gripMargin : 0, - top: direction === 'horizontal' ? 0 : size1A + gripThickness + 2 * gripMargin, - width: direction === 'horizontal' ? size1B : width, - height: direction === 'horizontal' ? height : size1B, - zIndex: 0, - overflowY: direction === 'horizontal' ? 'auto' : 'hidden', - overflowX: direction === 'horizontal' ? 'hidden' : 'auto' - }; const styleGripOuter: React.CSSProperties = { left: 0, top: 0, - width: direction === 'horizontal' ? gripThickness + 2 * gripMargin : width, - height: direction === 'horizontal' ? height : gripThickness + 2 * gripMargin, backgroundColor: 'transparent', cursor: direction === 'horizontal' ? 'col-resize' : 'row-resize', zIndex: 9998 @@ -116,16 +90,12 @@ const Splitter: FunctionComponent> = (props) => { const styleGrip: React.CSSProperties = { left: direction === 'horizontal' ? gripMargin : 0, top: direction === 'horizontal' ? 0 : gripMargin, - width: direction === 'horizontal' ? gripThickness : width, - height: direction === 'horizontal' ? height : gripThickness, background: 'rgb(230, 230, 230)', cursor: direction === 'horizontal' ? 'col-resize' : 'row-resize' }; const styleGripInner: React.CSSProperties = { top: direction === 'horizontal' ? 0 : (gripThickness - gripInnerThickness) / 2, left: direction === 'horizontal' ? (gripThickness - gripInnerThickness) / 2 : 0, - width: direction === 'horizontal' ? gripInnerThickness : width, - height: direction === 'horizontal' ? height : gripInnerThickness, background: 'gray', cursor: direction === 'horizontal' ? 'col-resize' : 'row-resize' }; @@ -140,10 +110,17 @@ const Splitter: FunctionComponent> = (props) => { setGripPosition(newGripPosition) onChange && onChange(newGripPosition) } + + console.log('HIEE!', hideSecondChild) return ( -
-
- +
+
+
{ adjustable && !hideSecondChild && ( @@ -164,10 +141,12 @@ const Splitter: FunctionComponent> = (props) => { ) } -
- {/* */} - -
+ { + !hideSecondChild &&
+ {/* */} + +
+ }
) } diff --git a/src/pages/ComputeResourcePage/ComputeResourceAppsTable.tsx b/src/pages/ComputeResourcePage/ComputeResourceAppsTable.tsx index b76fe95..ab0bb12 100644 --- a/src/pages/ComputeResourcePage/ComputeResourceAppsTable.tsx +++ b/src/pages/ComputeResourcePage/ComputeResourceAppsTable.tsx @@ -8,7 +8,6 @@ import ComputeResourceAppsTableMenuBar from "./ComputeResourceAppsTableMenuBar" import NewAppWindow from "./NewAppWindow" type Props = { - width: number height: number computeResource: ProtocaasComputeResource onNewApp: (name: string, specUri: string, absBatch?: ComputeResourceAwsBatchOpts, slurm?: ComputeResourceSlurmOpts) => void @@ -20,7 +19,7 @@ const menuBarHeight = 30 const hPadding = 20 const vPadding = 5 -const ComputeResourceAppsTable: FunctionComponent = ({width, height, computeResource, onNewApp, onEditApp, onDeleteApps}) => { +const ComputeResourceAppsTable: FunctionComponent = ({ height, computeResource, onNewApp, onEditApp, onDeleteApps}) => { const [selectedAppNames, selectedAppNamesDispatch] = useReducer(selectedStringsReducer, new Set()) const {visible: newAppWindowVisible, handleOpen: openNewAppWindow, handleClose: closeNewAppWindow} = useModalDialog() @@ -39,10 +38,9 @@ const ComputeResourceAppsTable: FunctionComponent = ({width, height, comp }, [selectedAppNames, computeResource]) return ( -
-
+
+
= ({width, height, comp onEditApp={openEditAppWindow} />
-
+
diff --git a/src/pages/ComputeResourcePage/ComputeResourceAppsTableMenuBar.tsx b/src/pages/ComputeResourcePage/ComputeResourceAppsTableMenuBar.tsx index 2646f8e..a959e6c 100644 --- a/src/pages/ComputeResourcePage/ComputeResourceAppsTableMenuBar.tsx +++ b/src/pages/ComputeResourcePage/ComputeResourceAppsTableMenuBar.tsx @@ -4,7 +4,6 @@ import SmallIconButton from "../../components/SmallIconButton" import { confirm } from "../../confirm_prompt_alert" type ComputeResourceAppsTableMenuBarProps = { - width: number height: number selectedAppNames: string[] onDeleteApps: (appNames: string[]) => void @@ -12,7 +11,7 @@ type ComputeResourceAppsTableMenuBarProps = { onEditApp: () => void } -const ComputeResourceAppsTableMenuBar: FunctionComponent = ({width, height, selectedAppNames, onAddApp, onDeleteApps, onEditApp}) => { +const ComputeResourceAppsTableMenuBar: FunctionComponent = ({ selectedAppNames, onAddApp, onDeleteApps, onEditApp}) => { const handleDelete = useCallback(async () => { const okay = await confirm(`Are you sure you want to delete these ${selectedAppNames.length} apps?`) if (!okay) return diff --git a/src/pages/ComputeResourcePage/ComputeResourcePage.tsx b/src/pages/ComputeResourcePage/ComputeResourcePage.tsx index 50cec9f..88f454e 100644 --- a/src/pages/ComputeResourcePage/ComputeResourcePage.tsx +++ b/src/pages/ComputeResourcePage/ComputeResourcePage.tsx @@ -9,12 +9,10 @@ import JobsTable from "../ProjectPage/JobsWindow/JobsTable"; import ComputeResourceAppsTable from "./ComputeResourceAppsTable"; type Props = { - width: number - height: number computeResourceId: string } -const ComputeResourcesPage: FunctionComponent = ({width, height, computeResourceId}) => { +const ComputeResourcesPage: FunctionComponent = ({ computeResourceId }) => { const [computeResource, setComputeResources] = useState() const auth = useGithubAuth() @@ -73,7 +71,7 @@ const ComputeResourcesPage: FunctionComponent = ({width, height, computeR const jobsTableHeight = 500 return ( -
+

Compute resource: {computeResource?.name}

@@ -103,7 +101,6 @@ const ComputeResourcesPage: FunctionComponent = ({width, height, computeR

Apps

{computeResource && = ({width, height, computeR

Jobs

= ({width, height}) => { return ( -
+

Your compute resources


diff --git a/src/pages/DandiBrowser/DandiBrowser.tsx b/src/pages/DandiBrowser/DandiBrowser.tsx index c800a4e..9407838 100644 --- a/src/pages/DandiBrowser/DandiBrowser.tsx +++ b/src/pages/DandiBrowser/DandiBrowser.tsx @@ -7,8 +7,7 @@ import useRoute from "../../useRoute" import Hyperlink from "../../components/Hyperlink" type Props = { - width: number - height: number + } export const getDandiApiHeaders = (useStaging: boolean): {[key: string]: string} => { @@ -27,7 +26,7 @@ export const getDandiApiHeaders = (useStaging: boolean): {[key: string]: string} const topBarHeight = 12 const searchBarHeight = 50 -const DandiBrowser: FunctionComponent = ({width, height}) => { +const DandiBrowser: FunctionComponent = ({ }) => { const {staging, toggleStaging} = useRoute() const [searchText, setSearchText] = useState('') const [searchResult, setSearchResults] = useState([]) @@ -54,62 +53,51 @@ const DandiBrowser: FunctionComponent = ({width, height}) => { }, [searchText, stagingStr, staging]) return ( -
-
+
+
{/* */} use {staging ? 'main site' : 'staging site'}
-
+
-
- -
+
) } type SearchBarProps = { - width: number height: number onSearch: (searchText: string) => void } -const SearchBar: FunctionComponent = ({width, height, onSearch}) => { +const SearchBar: FunctionComponent = ({ height, onSearch }) => { const [searchText, setSearchText] = useState('') const searchButtonWidth = height return ( -
-
- onSearch(searchText)} /> -
- -
- setSearchText(e.target.value)} - // when enter is pressed - onKeyDown={e => { - if (e.key === 'Enter') { - onSearch(searchText) - } - }} - // do not spell check - spellCheck={false} - /> -
+
+ onSearch(searchText)} /> + setSearchText(e.target.value)} + // when enter is pressed + onKeyDown={e => { + if (e.key === 'Enter') { + onSearch(searchText) + } + }} + // do not spell check + spellCheck={false} + />
) } @@ -131,7 +119,7 @@ type SearchButtonProps = { height: number } -const SearchButton: FunctionComponent = ({onClick, width, height}) => { +const SearchButton: FunctionComponent = ({onClick, height}) => { return ( } diff --git a/src/pages/DandiBrowser/DandisetView.tsx b/src/pages/DandiBrowser/DandisetView.tsx index e13c5f3..195a5bc 100644 --- a/src/pages/DandiBrowser/DandisetView.tsx +++ b/src/pages/DandiBrowser/DandisetView.tsx @@ -12,13 +12,11 @@ import useProjectsForTag from "./useProjectsForTag" type DandisetViewProps = { dandisetId: string - width: number - height: number useStaging?: boolean onImportItems?: (items: {dandisetId: string, dandisetVersion: string, assetItem: AssetsResponseItem}[]) => Promise } -const DandisetView: FunctionComponent = ({dandisetId, width, height, useStaging, onImportItems}) => { +const DandisetView: FunctionComponent = ({dandisetId, useStaging, onImportItems}) => { const [dandisetResponse, setDandisetResponse] = useState(null) const [dandisetVersionInfo, setDandisetVersionInfo] = useState(null) const [assetsResponses, setAssetsResponses] = useState([]) @@ -172,8 +170,8 @@ const DandisetView: FunctionComponent = ({dandisetId, width, const topBarHeight = canImport ? 30 : 0 const buttonColor = selectedAssets.assetPaths.length > 0 ? 'darkgreen' : 'gray' return ( -
-
+
+
{ onImportItems && ( canImport ? ( @@ -188,7 +186,7 @@ const DandisetView: FunctionComponent = ({dandisetId, width, ) }
-
+
diff --git a/src/pages/DandiBrowser/SearchResults.tsx b/src/pages/DandiBrowser/SearchResults.tsx index 3d8fa1f..cc59ea8 100644 --- a/src/pages/DandiBrowser/SearchResults.tsx +++ b/src/pages/DandiBrowser/SearchResults.tsx @@ -8,8 +8,6 @@ import formatByteCount from "./formatByteCount" import { DandisetSearchResultItem } from "./types" type SearchResultsProps = { - width: number - height: number searchResults: DandisetSearchResultItem[] useStaging?: boolean } @@ -17,7 +15,7 @@ type SearchResultsProps = { const defaultMinLeft = 200 const defaultMaxLeft = 500 -const SearchResults: FunctionComponent = ({width, height, searchResults, useStaging}) => { +const SearchResults: FunctionComponent = ({searchResults, useStaging}) => { // const [selectedDandisetItem, setSelectedDandisetItem] = useState(null) const {route, setRoute} = useRoute() const dandisetId = route.page === 'dandiset' ? route.dandisetId : undefined @@ -41,15 +39,10 @@ const SearchResults: FunctionComponent = ({width, height, se return ( = ({width, height, se /> {onClickAsset(selectedItem?.identifier || '', selectedItem?.most_recent_published_version?.version || 'draft', assetItem)}} useStaging={useStaging} onImportItems={undefined} @@ -69,7 +60,11 @@ const SearchResults: FunctionComponent = ({width, height, se const SearchResultsLeft: FunctionComponent void}> = ({width, height, searchResults, setSelectedItem}) => { return ( -
+
{ searchResults.map((result, i) => ( void } -const SearchResultItem: FunctionComponent = ({result, width, onClick}) => { +const SearchResultItem: FunctionComponent = ({result, onClick}) => { const {identifier, created, modified, contact_person, most_recent_published_version, draft_version} = result const X = most_recent_published_version || draft_version if (!X) return
Unexpected error: no version
diff --git a/src/pages/HomePage/HomePage.tsx b/src/pages/HomePage/HomePage.tsx index 5684e0a..31d3dae 100644 --- a/src/pages/HomePage/HomePage.tsx +++ b/src/pages/HomePage/HomePage.tsx @@ -2,11 +2,10 @@ import { FunctionComponent, useEffect } from "react"; import useRoute from "../../useRoute"; type Props = { - width: number - height: number + } -const HomePage: FunctionComponent = ({width, height}) => { +const HomePage: FunctionComponent = ({ }) => { const {setRoute} = useRoute() useEffect(() => { setRoute({page: 'dandisets'}) diff --git a/src/pages/ProjectPage/FileBrowser/FileBrowser2.tsx b/src/pages/ProjectPage/FileBrowser/FileBrowser2.tsx index c4b4b69..33dc2f6 100644 --- a/src/pages/ProjectPage/FileBrowser/FileBrowser2.tsx +++ b/src/pages/ProjectPage/FileBrowser/FileBrowser2.tsx @@ -12,8 +12,6 @@ import formatByteCount from './formatByteCount'; import { DandiUploadTask } from '../DandiUpload/prepareDandiUploadTask'; type Props = { - width: number - height: number files: ProtocaasFile[] | undefined onOpenFile: (path: string) => void onDeleteFile: (path: string) => void @@ -117,7 +115,7 @@ type TreeNode = { file?: ProtocaasFile } -const FileBrowser2: FunctionComponent = ({width, height, onOpenFile, files, hideSizeColumn, onRunBatchSpikeSorting, onDandiUpload}) => { +const FileBrowser2: FunctionComponent = ({ onOpenFile, files, hideSizeColumn, onRunBatchSpikeSorting, onDandiUpload}) => { const {currentTabName} = useProject() const rootNode = useMemo(() => { @@ -269,18 +267,16 @@ const FileBrowser2: FunctionComponent = ({width, height, onOpenFile, file }, [files, selectedFileNames]) return ( -
-
+
+
selectedFileNamesDispatch({type: 'set', values: new Set()})} onRunBatchSpikeSorting={onRunBatchSpikeSorting} onDandiUpload={onDandiUpload} />
-
+
diff --git a/src/pages/ProjectPage/FileBrowser/FileBrowserMenuBar.tsx b/src/pages/ProjectPage/FileBrowser/FileBrowserMenuBar.tsx index f5f502f..430d0db 100644 --- a/src/pages/ProjectPage/FileBrowser/FileBrowserMenuBar.tsx +++ b/src/pages/ProjectPage/FileBrowser/FileBrowserMenuBar.tsx @@ -6,15 +6,13 @@ import { useProject } from "../ProjectPageContext" import prepareDandiUploadTask, { DandiUploadTask } from "../DandiUpload/prepareDandiUploadTask" type FileBrowserMenuBarProps = { - width: number - height: number selectedFileNames: string[] onResetSelection: () => void onRunBatchSpikeSorting?: (filePaths: string[]) => void onDandiUpload?: (dandiUploadTask: DandiUploadTask) => void } -const FileBrowserMenuBar: FunctionComponent = ({ width, height, selectedFileNames, onResetSelection, onRunBatchSpikeSorting, onDandiUpload }) => { +const FileBrowserMenuBar: FunctionComponent = ({ selectedFileNames, onResetSelection, onRunBatchSpikeSorting, onDandiUpload }) => { const {deleteFile, refreshFiles, projectRole} = useProject() const [operating, setOperating] = useState(false) const handleDelete = useCallback(async () => { diff --git a/src/pages/ProjectPage/FileEditor/FigurlFileEditor.tsx b/src/pages/ProjectPage/FileEditor/FigurlFileEditor.tsx index 30fa7de..5afca98 100644 --- a/src/pages/ProjectPage/FileEditor/FigurlFileEditor.tsx +++ b/src/pages/ProjectPage/FileEditor/FigurlFileEditor.tsx @@ -3,11 +3,9 @@ import { useProject } from "../ProjectPageContext" type FigurlFileEditorProps = { fileName: string - width: number - height: number } -const FigurlFileEditor: FunctionComponent = ({fileName, width, height}) => { +const FigurlFileEditor: FunctionComponent = ({ fileName }) => { if (!fileName.endsWith('.figurl')) { throw Error('Unexpected file extension: ' + fileName) } diff --git a/src/pages/ProjectPage/FileEditor/FileEditor.tsx b/src/pages/ProjectPage/FileEditor/FileEditor.tsx index 48a5738..402d97b 100644 --- a/src/pages/ProjectPage/FileEditor/FileEditor.tsx +++ b/src/pages/ProjectPage/FileEditor/FileEditor.tsx @@ -4,17 +4,13 @@ import NwbFileEditor from "./NwbFileEditor"; type Props = { fileName: string - width: number - height: number } -const FileEditor: FunctionComponent = ({fileName, width, height}) => { +const FileEditor: FunctionComponent = ({fileName }) => { if (fileName.endsWith('.nwb')) { return ( ) } diff --git a/src/pages/ProjectPage/FileEditor/NwbFileEditor.tsx b/src/pages/ProjectPage/FileEditor/NwbFileEditor.tsx index 6c2d607..4fe18a6 100644 --- a/src/pages/ProjectPage/FileEditor/NwbFileEditor.tsx +++ b/src/pages/ProjectPage/FileEditor/NwbFileEditor.tsx @@ -15,16 +15,12 @@ import { getDandiApiHeaders } from "../../DandiBrowser/DandiBrowser"; type Props = { fileName: string - width: number - height: number } -const NwbFileEditor: FunctionComponent = ({fileName, width, height}) => { +const NwbFileEditor: FunctionComponent = ({ fileName }) => { return ( = ({fileName, width, height}) }, [jobs, nbFile]) return ( -
+

diff --git a/src/pages/ProjectPage/JobView/JobView.tsx b/src/pages/ProjectPage/JobView/JobView.tsx index 2fc372c..769af58 100644 --- a/src/pages/ProjectPage/JobView/JobView.tsx +++ b/src/pages/ProjectPage/JobView/JobView.tsx @@ -8,8 +8,6 @@ import EditJobDefinitionWindow from "../EditJobDefinitionWindow/EditJobDefinitio import { ElapsedTimeComponent } from "../FileEditor/NwbFileEditor"; type Props = { - width: number, - height: number, jobId: string } @@ -51,7 +49,7 @@ const useJob = (jobId: string) => { return {job, refreshJob, jobConsoleOutput} } -const JobView: FunctionComponent = ({ width, height, jobId }) => { +const JobView: FunctionComponent = ({ jobId }) => { const {job, refreshJob, jobConsoleOutput} = useJob(jobId) const secretParameterNames = useMemo(() => { if (!job) return [] @@ -82,7 +80,7 @@ const JobView: FunctionComponent = ({ width, height, jobId }) => { ) } return ( -
+


diff --git a/src/pages/ProjectPage/JobsWindow/JobsTable.tsx b/src/pages/ProjectPage/JobsWindow/JobsTable.tsx index 6666010..cc229e2 100644 --- a/src/pages/ProjectPage/JobsWindow/JobsTable.tsx +++ b/src/pages/ProjectPage/JobsWindow/JobsTable.tsx @@ -10,8 +10,8 @@ import { Checkbox, selectedStringsReducer } from "../FileBrowser/FileBrowser2"; import JobsTableMenuBar from "./JobsTableMenuBar"; type Props = { - width: number - height: number + width?: number + height?: number fileName: string jobs: ProtocaasJob[] | undefined onJobClicked: (jobId: string) => void @@ -35,7 +35,7 @@ type RowItem = { role: string } -const JobsTable: FunctionComponent = ({ width, height, fileName, jobs, onJobClicked, createJobEnabled, createJobTitle }) => { +const JobsTable: FunctionComponent = ({ height = 100, fileName, jobs, onJobClicked, createJobEnabled, createJobTitle }) => { const sortedJobs = useMemo(() => { if (!jobs) return [] return [...jobs].sort((a, b) => (b.timestampCreated - a.timestampCreated)) @@ -212,18 +212,16 @@ const JobsTable: FunctionComponent = ({ width, height, fileName, jobs, on }, [sortedJobs, selectedJobIds]) return ( -
-
+
+
selectedJobIdsDispatch({type: 'set', values: new Set()})} createJobEnabled={createJobEnabled} createJobTitle={createJobTitle} />
-
+
diff --git a/src/pages/ProjectPage/JobsWindow/JobsTableMenuBar.tsx b/src/pages/ProjectPage/JobsWindow/JobsTableMenuBar.tsx index f31191a..8e0ecf8 100644 --- a/src/pages/ProjectPage/JobsWindow/JobsTableMenuBar.tsx +++ b/src/pages/ProjectPage/JobsWindow/JobsTableMenuBar.tsx @@ -5,15 +5,13 @@ import { confirm } from "../../../confirm_prompt_alert" import { useProject } from "../ProjectPageContext" type JobsTableMenuBarProps = { - width: number - height: number selectedJobIds: string[] onResetSelection: () => void createJobEnabled?: boolean createJobTitle?: string } -const JobsTableMenuBar: FunctionComponent = ({width, height, selectedJobIds, onResetSelection, createJobEnabled, createJobTitle}) => { +const JobsTableMenuBar: FunctionComponent = ({selectedJobIds, onResetSelection, createJobEnabled, createJobTitle}) => { const {deleteJob, refreshJobs, projectRole} = useProject() const [operating, setOperating] = useState(false) const handleDelete = useCallback(async () => { diff --git a/src/pages/ProjectPage/JobsWindow/JobsWindow.tsx b/src/pages/ProjectPage/JobsWindow/JobsWindow.tsx index 41bb9b0..0cff9c7 100644 --- a/src/pages/ProjectPage/JobsWindow/JobsWindow.tsx +++ b/src/pages/ProjectPage/JobsWindow/JobsWindow.tsx @@ -3,14 +3,12 @@ import { useProject } from "../ProjectPageContext"; import JobsTable from "./JobsTable"; type Props = { - width: number, - height: number, fileName: string createJobEnabled?: boolean createJobTitle?: string } -const JobsWindow: FunctionComponent = ({ width, height, fileName, createJobEnabled, createJobTitle }) => { +const JobsWindow: FunctionComponent = ({ fileName, createJobEnabled, createJobTitle }) => { const {jobs, openTab} = useProject() const filteredJobs = useMemo(() => { @@ -28,8 +26,6 @@ const JobsWindow: FunctionComponent = ({ width, height, fileName, createJ return ( openTab(`job:${jobId}`)} diff --git a/src/pages/ProjectPage/ProcessorsView.tsx b/src/pages/ProjectPage/ProcessorsView.tsx index 8a7fee8..b4b1037 100644 --- a/src/pages/ProjectPage/ProcessorsView.tsx +++ b/src/pages/ProjectPage/ProcessorsView.tsx @@ -5,11 +5,10 @@ import './Processor.css' import { useProject } from "./ProjectPageContext" type ProcessorsViewProps = { - width: number - height: number + } -const ProcessorsView: FunctionComponent = ({width, height}) => { +const ProcessorsView: FunctionComponent = ({ }) => { const {computeResource} = useProject() const allProcessors = useMemo(() => { if (!computeResource) return [] @@ -18,14 +17,13 @@ const ProcessorsView: FunctionComponent = ({width, height}) }, [computeResource]) if (!computeResource) return
Loading compute resource spec...
return ( -
+

{ allProcessors.map((processor, i) => (
@@ -37,17 +35,16 @@ const ProcessorsView: FunctionComponent = ({width, height}) type ProcessorViewProps = { processor: ComputeResourceSpecProcessor - width: number } -const ProcessorView: FunctionComponent = ({processor, width}) => { +const ProcessorView: FunctionComponent = ({ processor }) => { const attrs: {[key: string]: any} = {} processor.attributes.forEach((attr) => { attrs[attr.name] = attr.value }) const wipElmt = attrs.wip ? (WIP) : null return ( -
+
{ diff --git a/src/pages/ProjectPage/ProjectFiles.tsx b/src/pages/ProjectPage/ProjectFiles.tsx index 9269d85..7593e0a 100644 --- a/src/pages/ProjectPage/ProjectFiles.tsx +++ b/src/pages/ProjectPage/ProjectFiles.tsx @@ -9,13 +9,11 @@ import { confirm } from "../../confirm_prompt_alert"; import { DandiUploadTask } from "./DandiUpload/prepareDandiUploadTask"; type ProjectFilesProps = { - width: number - height: number onRunBatchSpikeSorting?: (filePaths: string[]) => void onDandiUpload?: (dandiUploadTask: DandiUploadTask) => void } -const ProjectFiles: FunctionComponent = ({width, height, onRunBatchSpikeSorting, onDandiUpload}) => { +const ProjectFiles: FunctionComponent = ({onRunBatchSpikeSorting, onDandiUpload}) => { const {filesIncludingPending, openTab, deleteFile, closeTab, openTabs, refreshFiles} = useProject() const handleOpenFile = useCallback((fileName: string) => { @@ -33,15 +31,11 @@ const ProjectFiles: FunctionComponent = ({width, height, onRu return ( = ({width, height}) => { +const ProjectHome: FunctionComponent = ({ }) => { const {setRoute} = useRoute() const {project, files, jobs, projectId} = useProject() const {visible: settingsWindowVisible, handleOpen: openSettingsWindow, handleClose: closeSettingsWindow} = useModalDialog() return ( -
+
Project: {project?.name}
 
diff --git a/src/pages/ProjectPage/ProjectJobs.tsx b/src/pages/ProjectPage/ProjectJobs.tsx index 4b6872d..b5ab3c5 100644 --- a/src/pages/ProjectPage/ProjectJobs.tsx +++ b/src/pages/ProjectPage/ProjectJobs.tsx @@ -4,28 +4,23 @@ import JobsTable from "./JobsWindow/JobsTable"; import JobView from "./JobView/JobView"; import { useProject } from "./ProjectPageContext"; -const ProjectJobs: FunctionComponent<{width: number, height: number}> = ({width, height}) => { +const ProjectJobs: FunctionComponent<{}> = ({ }) => { const {jobs} = useProject() const [selectedJobId, setSelectedJobId] = useState(undefined) return ( j.jobId).includes(selectedJobId))} > setSelectedJobId(jobId)} /> diff --git a/src/pages/ProjectPage/ProjectPage.tsx b/src/pages/ProjectPage/ProjectPage.tsx index 958bc9c..26c34a1 100644 --- a/src/pages/ProjectPage/ProjectPage.tsx +++ b/src/pages/ProjectPage/ProjectPage.tsx @@ -21,11 +21,10 @@ import DandisetView from "../DandiBrowser/DandisetView"; import { AssetResponse, AssetsResponseItem } from "../DandiBrowser/types"; type Props = { - width: number - height: number + } -const ProjectPage: FunctionComponent = ({width, height}) => { +const ProjectPage: FunctionComponent = ({ }) => { const {route} = useRoute() if (route.page !== 'project') throw Error('route.page != project') const projectId = route.projectId @@ -33,10 +32,7 @@ const ProjectPage: FunctionComponent = ({width, height}) => { - + ) } @@ -79,41 +75,27 @@ const projectPageViews: ProjectPageView[] = [ } ] -const ProjectPageChild: FunctionComponent = ({width, height}) => { +const ProjectPageChild: FunctionComponent = ({ }) => { const leftMenuPanelWidth = 150 return ( -
- - - - -
+ +
) } type LeftMenuPanelProps = { - width: number - height: number + } -const LeftMenuPanel: FunctionComponent = ({width, height}) => { +const LeftMenuPanel: FunctionComponent = ({ }) => { const {route, setRoute} = useRoute() const {projectId} = useProject() if (route.page !== 'project') throw Error(`Unexpected route ${JSON.stringify(route)}`) const currentView = route.tab || 'project-home' return ( -
+
{ projectPageViews.map(view => (
= ({width, height}) = } type MainPanelProps = { - width: number - height: number + } -const MainPanel: FunctionComponent = ({width, height}) => { +const MainPanel: FunctionComponent = ({ }) => { const {openTab, project, refreshFiles, computeResourceId} = useProject() const auth = useGithubAuth() const {route, setRoute, staging} = useRoute() @@ -247,32 +228,22 @@ const MainPanel: FunctionComponent = ({width, height}) => { }, [handleImportDandiNwbFiles, stagingStr, staging]) return ( -
-
- +
+
+
-
+
-
- +
+
{dandisetId && ( -
+
= ({width, height}) => { onNwbFileSelected={handleImportManualNwbFile} />
*/} -
- +
+
-
+
{ computeResourceId && ( ) diff --git a/src/pages/ProjectsPage/ProjectsPage.tsx b/src/pages/ProjectsPage/ProjectsPage.tsx index 215860c..853edeb 100644 --- a/src/pages/ProjectsPage/ProjectsPage.tsx +++ b/src/pages/ProjectsPage/ProjectsPage.tsx @@ -5,14 +5,13 @@ import Hyperlink from "../../components/Hyperlink"; import './ProjectsPage.css' type Props = { - width: number - height: number + } -const ProjectsPage: FunctionComponent = ({width, height}) => { +const ProjectsPage: FunctionComponent = ({ }) => { const {setRoute} = useRoute() return ( -
+

Your projects