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

improve records view #110

Merged
merged 4 commits into from
Oct 19, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Typography from '@mui/material/Typography'
import { ExperimentUidContext } from './ExperimentTable'
import {
selectExperimentFunctionHasNWB,
selectExperimentFunctionMessage,
selectExperimentFunctionName,
selectExperimentFunctionNodeIdList,
selectExperimentFunctionStatus,
Expand Down Expand Up @@ -77,6 +78,7 @@ const TableRowOfFunction = React.memo<{
const name = useSelector(selectExperimentFunctionName(uid, nodeId))
const status = useSelector(selectExperimentFunctionStatus(uid, nodeId))
const hasNWB = useSelector(selectExperimentFunctionHasNWB(uid, nodeId))
const message = useSelector(selectExperimentFunctionMessage(uid, nodeId))

return (
<TableRow key={nodeId}>
Expand All @@ -85,7 +87,7 @@ const TableRowOfFunction = React.memo<{
</TableCell>
<TableCell>{nodeId}</TableCell>
<TableCell>
<ExperimentStatusIcon status={status} />
<ExperimentStatusIcon status={status} message={message} />
</TableCell>
<TableCell>
<NWBDownloadButton name={name} nodeId={nodeId} hasNWB={hasNWB} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,68 @@ import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'
import HorizontalRuleIcon from '@mui/icons-material/HorizontalRule'

import { EXPERIMENTS_STATUS } from 'store/slice/Experiments/ExperimentsType'
import { IconButton, Popover, Typography } from '@mui/material'

export const ExperimentStatusIcon = React.memo<{ status: EXPERIMENTS_STATUS }>(
({ status }) => {
switch (status) {
case 'error':
return <ErrorOutlineIcon color="error" />
case 'success':
return <DoneIcon color="success" />
case 'running':
return <HorizontalRuleIcon color="inherit" />
}
},
)
export const ExperimentStatusIcon = React.memo<{
status: EXPERIMENTS_STATUS
message?: string
}>(({ status, message }) => {
switch (status) {
case 'error':
return <ErrorIcon message={message} />
case 'success':
return <DoneIcon color="success" />
case 'running':
return <HorizontalRuleIcon color="inherit" />
}
})

const ErrorIcon = React.memo<{ message?: string }>(({ message }) => {
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}

const open = Boolean(anchorEl)
const id = open ? 'error-message-popover' : undefined

return message == null ? (
<ErrorOutlineIcon color="error" />
) : (
<>
<IconButton
aria-describedby={id}
onClick={handleClick}
size="small"
color="error"
style={{ padding: 0 }}
>
<ErrorOutlineIcon color="error" />
</IconButton>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
slotProps={{ paper: { sx: { width: '60%' } } }}
>
<Typography
variant="body2"
paragraph
color="error"
padding={2}
marginBottom={0}
>
{message}
</Typography>
</Popover>
</>
)
})
41 changes: 31 additions & 10 deletions frontend/src/components/Workspace/Experiment/ExperimentTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import { CollapsibleTable } from './CollapsibleTable'
import {
selectExperimentsStatusIsUninitialized,
selectExperimentsStatusIsFulfilled,
selectExperimentTimeStamp,
selectExperimentStartedAt,
selectExperimentFinishedAt,
selectExperimentName,
selectExperimentStatus,
selectExperimentsStatusIsError,
Expand All @@ -41,7 +42,7 @@ import {
getExperiments,
} from 'store/slice/Experiments/ExperimentsActions'
import { ExperimentStatusIcon } from './ExperimentStatusIcon'
import { Experiment } from 'store/slice/Experiments/ExperimentsType'
import { ExperimentSortKeys } from 'store/slice/Experiments/ExperimentsType'
import { DeleteButton } from './Button/DeleteButton'
import {
NWBDownloadButton,
Expand All @@ -58,7 +59,7 @@ import {
selectCurrentWorkspaceId,
selectIsWorkspaceOwner,
} from 'store/slice/Workspace/WorkspaceSelector'
import { AppDispatch } from "../../../store/store";
import { AppDispatch } from '../../../store/store'

export const ExperimentUidContext = React.createContext<string>('')

Expand Down Expand Up @@ -104,11 +105,12 @@ const TableImple = React.memo(() => {
const onClickReload = () => {
dispatch(getExperiments())
}
const [order, setOrder] = React.useState<Order>('asc')
const [order, setOrder] = React.useState<Order>('desc')
const [sortTarget, setSortTarget] =
React.useState<keyof Experiment>('timestamp')
React.useState<keyof ExperimentSortKeys>('startedAt')
const sortHandler =
(property: keyof Experiment) => (event: React.MouseEvent<unknown>) => {
(property: keyof ExperimentSortKeys) =>
(event: React.MouseEvent<unknown>) => {
const isAsc = sortTarget === property && order === 'asc'
setOrder(isAsc ? 'desc' : 'asc')
setSortTarget(property)
Expand Down Expand Up @@ -346,7 +348,7 @@ const HeadItem = React.memo<{
<TableSortLabel
active
direction={order}
onClick={sortHandler('timestamp')}
onClick={sortHandler('startedAt')}
>
Timestamp
</TableSortLabel>
Expand Down Expand Up @@ -388,7 +390,8 @@ const RowItem = React.memo<{
}>(({ onCheckBoxClick, checked, isOwner }) => {
const workspaceId = useSelector(selectCurrentWorkspaceId)
const uid = React.useContext(ExperimentUidContext)
const timestamp = useSelector(selectExperimentTimeStamp(uid))
const startedAt = useSelector(selectExperimentStartedAt(uid))
const finishedAt = useSelector(selectExperimentFinishedAt(uid))
const status = useSelector(selectExperimentStatus(uid))
const name = useSelector(selectExperimentName(uid))
const hasNWB = useSelector(selectExperimentHasNWB(uid))
Expand Down Expand Up @@ -452,8 +455,26 @@ const RowItem = React.memo<{
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
itutu-tienday marked this conversation as resolved.
Show resolved Hide resolved
<TableCell component="th" scope="row">
{timestamp}
<TableCell
sx={{ minWidth: 210, width: 210 }}
component="th"
scope="row"
>
{finishedAt == null ? (
startedAt
) : (
<>
{/* date string format is YYYY-MM-DD HH:mm:ss */}
<Typography variant="body2">{`${startedAt} - ${finishedAt.split(" ")[1]}`}</Typography>
<Typography variant="body2">
(elapsed{" "}
{(new Date(finishedAt).getTime() -
new Date(startedAt).getTime()) /
1000}{" "}
sec)
</Typography>
</>
)}
</TableCell>
<TableCell>{uid}</TableCell>
<TableCell sx={{ width: 160, position: 'relative' }} onClick={onEdit}>
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/store/slice/Experiments/Experiments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ describe('Experiments', () => {
experimentList: {
[uid1]: {
uid: uid1,
timestamp: '2022-05-07 05:26:54',
startedAt: '2022-05-07 05:26:54',
finishedAt: '2022-05-07 05:26:55',
frameRate: 30,
name: 'record test',
hasNWB: true,
Expand Down Expand Up @@ -133,7 +134,8 @@ describe('Experiments', () => {
},
[uid2]: {
uid: uid2,
timestamp: '2022-05-07 05:54:53',
startedAt: '2022-05-07 05:54:53',
finishedAt: '2022-05-07 05:54:54',
frameRate: 30,
name: 'New flow',
hasNWB: true,
Expand Down
20 changes: 14 additions & 6 deletions frontend/src/store/slice/Experiments/ExperimentsSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ export const selectExperimentUidList = (state: RootState) =>
export const selectExperiment = (uid: string) => (state: RootState) =>
selectExperimentList(state)[uid]

export const selectExperimentTimeStamp = (uid: string) => (state: RootState) =>
selectExperiment(uid)(state).timestamp
export const selectExperimentStartedAt = (uid: string) => (state: RootState) =>
selectExperiment(uid)(state).startedAt

export const selectExperimentFinishedAt = (uid: string) => (state: RootState) =>
selectExperiment(uid)(state).finishedAt

export const selectExperimentName = (uid: string) => (state: RootState) =>
selectExperiment(uid)(state).name
Expand Down Expand Up @@ -87,11 +90,16 @@ export const selectExperimentFunctionStatus =
(uid: string, nodeId: string) => (state: RootState) =>
selectExperimentFunction(uid, nodeId)(state).status

export const selectExperimentFunctionMessage =
(uid: string, nodeId: string) => (state: RootState) =>
selectExperimentFunction(uid, nodeId)(state).message

export const selectExperimentFunctionHasNWB =
(uid: string, nodeId: string) => (state: RootState) =>
selectExperimentFunction(uid, nodeId)(state).hasNWB

export const selectFrameRate = (currentPipelineUid?: string) => (state: RootState) => {
if(!currentPipelineUid) return 50
return selectExperiment(currentPipelineUid)(state).frameRate || 50
}
export const selectFrameRate =
(currentPipelineUid?: string) => (state: RootState) => {
if (!currentPipelineUid) return 50
return selectExperiment(currentPipelineUid)(state).frameRate || 50
}
7 changes: 4 additions & 3 deletions frontend/src/store/slice/Experiments/ExperimentsType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export type ExperimentType = {
}
status?: EXPERIMENTS_STATUS
name: string
timestamp: string
startedAt: string
finishedAt?: string
hasNWB: boolean
frameRate?: number
}
Expand All @@ -42,8 +43,8 @@ export type ExperimentFunction = {

export type EXPERIMENTS_STATUS = 'success' | 'error' | 'running'

export interface Experiment {
export interface ExperimentSortKeys {
uid: string
name: string
timestamp: string
startedAt: string
}
5 changes: 3 additions & 2 deletions frontend/src/store/slice/Experiments/ExperimentsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ export function convertToExperimentType(dto: ExperimentDTO): ExperimentType {
})
return {
uid: dto.unique_id,
timestamp: dto.started_at,
startedAt: dto.started_at,
finishedAt: dto.finished_at,
status: dto.success,
name: dto.name,
hasNWB: dto.hasNWB,
functions,
frameRate: dto.nwb?.imaging_plane.imaging_rate
frameRate: dto.nwb?.imaging_plane.imaging_rate,
}
}

Expand Down