Skip to content

Commit

Permalink
SWC-7063 with mock stories
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-hodgson committed Oct 21, 2024
1 parent 6003ee3 commit a7e6392
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react'
import { Box, SxProps, Tooltip, Typography } from '@mui/material'
import { useTheme } from '@mui/material'
import { useSynapseContext } from '../../utils'
import { useProjectStorageUsage } from '../../synapse-queries'
import { SYNAPSE_STORAGE_LOCATION_ID } from 'src/synapse-client'
import HelpPopover from '../HelpPopover'
import { calculateFriendlyFileSize } from 'src/utils/functions/calculateFriendlyFileSize'

export type ProjectDataAvailabilityProps = {
projectId?: string
sx?: SxProps
}
const usageBarWidth = 142 //px

export const ProjectDataAvailability: React.FunctionComponent<
ProjectDataAvailabilityProps
> = ({ projectId, sx }) => {
const { accessToken } = useSynapseContext()
const isLoggedIn = !!accessToken
const { data } = useProjectStorageUsage(projectId!, {
enabled: !!projectId && isLoggedIn,
})

const projectDataUsageArray = data?.locations.filter(
v => parseInt(v.storageLocationId) == SYNAPSE_STORAGE_LOCATION_ID,
)
const synapseStorageUsage =
projectDataUsageArray?.length == 1 ? projectDataUsageArray[0] : undefined
if (!synapseStorageUsage) {
return <></>
}
const { sumFileBytes = 0, maxAllowedFileBytes = 1 } = synapseStorageUsage
const usageBarFilledPx = Math.min(
Math.round((sumFileBytes / maxAllowedFileBytes) * usageBarWidth),
usageBarWidth,
)
const friendlySumFileBytes = calculateFriendlyFileSize(sumFileBytes, 1)
const friendlyMaxAllowedFileBytes = calculateFriendlyFileSize(
maxAllowedFileBytes,
0,
)
return (
<Box
display="flex"
flexDirection="column"
width="210px"
fontFamily="DM Sans"
color="white"
px="10px"
sx={sx}
>
<Box display="flex" flexDirection="row" gap="5px">
<Typography
sx={{
// match current styles in Project metadata
fontWeight: 700,
fontSize: '16px',
}}
>
Data Availability{' '}
</Typography>{' '}
<HelpPopover
markdownText="Hosting Plan Options:
- Basic Plan: Free, for sharing small datasets (<100GB) with self-service setup. No direct support.
- Self-Managed Plan: Ideal for data longevity, FAIR principles, and NIH compliance. Includes consultation services and data access management tools.
- Data Coordination Plan: For large, multi-institutional projects, with personalized consulting, data curation, and a custom data portal."
helpUrl="https://help.synapse.org/docs/Sage-Offerings.2965078125.html"
/>
</Box>
{synapseStorageUsage.maxAllowedFileBytes && (
<Tooltip
title={`Using ${friendlySumFileBytes} out of ${friendlyMaxAllowedFileBytes}`}
>
<Box display="flex" flexDirection="row" gap="5px" alignItems="center">
<Typography variant="body1" fontSize="12px">
0
</Typography>
{/* Progress Bar */}
<Box
width={`${usageBarWidth}px`}
height="4px"
sx={{ backgroundColor: 'white', borderRadius: '50px' }}
>
<Box
width={`${usageBarFilledPx}px`}
height="4px"
sx={{ backgroundColor: '#EDC766', borderRadius: '50px' }}
></Box>
</Box>
<Typography variant="body1" fontSize="12px">
{friendlyMaxAllowedFileBytes}
</Typography>
</Box>
</Tooltip>
)}
</Box>
)
}

export default ProjectDataAvailability
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Meta, StoryObj } from '@storybook/react'
import ProjectDataAvailability from './ProjectDataAvailability'
import { MOCK_REPO_ORIGIN } from 'src/utils/functions/getEndpoint'
import { getUserProfileHandlers } from 'src/mocks/msw/handlers/userProfileHandlers'
import { getEntityHandlers } from 'src/mocks/msw/handlers/entityHandlers'
import { getProjectStorageHandlers } from 'src/mocks/msw/handlers/projectStorageHandlers'
import {
OVER_LIMIT_PROJECT_ID,
UNDER_LIMIT_PROJECT_ID,
} from 'src/mocks/projectStorage/mockProjectStorageLimits'

const meta = {
title: 'Synapse/ProjectStorage',
component: ProjectDataAvailability,
parameters: {
chromatic: { viewports: [600, 1200] },
},
argTypes: {
isAuthenticated: {
type: 'boolean',
},
},
args: {
isAuthenticated: true,
},
} satisfies Meta
export default meta
type Story = StoryObj<typeof meta>

export const ProjectDataUnderLimit: Story = {
args: {
projectId: UNDER_LIMIT_PROJECT_ID,
sx: { backgroundColor: '#375574' },
},
parameters: {
stack: 'mock',
msw: {
handlers: [
...getUserProfileHandlers(MOCK_REPO_ORIGIN),
...getEntityHandlers(MOCK_REPO_ORIGIN),
...getProjectStorageHandlers(MOCK_REPO_ORIGIN),
],
},
},
}

export const ProjectDataOverLimit: Story = {
args: {
projectId: OVER_LIMIT_PROJECT_ID,
sx: { backgroundColor: '#375574' },
},

parameters: {
stack: 'mock',
msw: {
handlers: [
...getUserProfileHandlers(MOCK_REPO_ORIGIN),
...getEntityHandlers(MOCK_REPO_ORIGIN),
...getProjectStorageHandlers(MOCK_REPO_ORIGIN),
],
},
},
}

export const ProjectDataStorageNotSet: Story = {
args: { projectId: 'syn31415123' },
parameters: {
stack: 'mock',
msw: {
handlers: [
...getUserProfileHandlers(MOCK_REPO_ORIGIN),
...getEntityHandlers(MOCK_REPO_ORIGIN),
...getProjectStorageHandlers(MOCK_REPO_ORIGIN),
],
},
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ProjectDataAvailability from './ProjectDataAvailability'
import type { ProjectDataAvailabilityProps } from './ProjectDataAvailability'
export { ProjectDataAvailability, ProjectDataAvailabilityProps }
export default ProjectDataAvailability
1 change: 1 addition & 0 deletions packages/synapse-react-client/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export * from './ProjectViewCarousel'
export * from './Programs'
export * from './ProgrammaticTableDownload'
export * from './ProvenanceGraph'
export * from './ProjectStorage'
export * from './QueryContext'
export * from './QueryCount'
export * from './QueryWrapper'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { rest } from 'msw'
import { PROJECT_STORAGE_USAGE } from '../../../utils/APIConstants'
import { BackendDestinationEnum, getEndpoint } from '../../../utils/functions'
import {
mockProjectStorageUsageOverLimit,
mockProjectStorageUsageUnderLimit,
OVER_LIMIT_PROJECT_ID,
UNDER_LIMIT_PROJECT_ID,
} from '../../../mocks/projectStorage/mockProjectStorageLimits'

export const getProjectStorageHandlers = (
backendOrigin = getEndpoint(BackendDestinationEnum.REPO_ENDPOINT),
) => [
rest.get(
`${backendOrigin}${PROJECT_STORAGE_USAGE(OVER_LIMIT_PROJECT_ID)}`,
async (req, res, ctx) => {
return res(ctx.status(201), ctx.json(mockProjectStorageUsageOverLimit))
},
),
rest.get(
`${backendOrigin}${PROJECT_STORAGE_USAGE(UNDER_LIMIT_PROJECT_ID)}`,
async (req, res, ctx) => {
return res(ctx.status(201), ctx.json(mockProjectStorageUsageUnderLimit))
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ProjectStorageUsage } from '@sage-bionetworks/synapse-types'
import { SYNAPSE_STORAGE_LOCATION_ID } from '../../synapse-client'

export const OVER_LIMIT_PROJECT_ID = 'syn54321'
export const UNDER_LIMIT_PROJECT_ID = 'syn12345'

export const mockProjectStorageUsageOverLimit: ProjectStorageUsage = {
projectId: OVER_LIMIT_PROJECT_ID,
locations: [
{
storageLocationId: `${SYNAPSE_STORAGE_LOCATION_ID}`,
sumFileBytes: 1200000000, // 1.2 GB
maxAllowedFileBytes: 1073741824, // 1 GB limit
isOverLimit: true, // Over the limit
},
{
storageLocationId: 'location-2',
sumFileBytes: 100000000,
maxAllowedFileBytes: 1073741824,
isOverLimit: false,
},
],
}

export const mockProjectStorageUsageUnderLimit: ProjectStorageUsage = {
projectId: UNDER_LIMIT_PROJECT_ID,
locations: [
{
storageLocationId: `${SYNAPSE_STORAGE_LOCATION_ID}`,
sumFileBytes: 500000000,
maxAllowedFileBytes: 1073741824,
isOverLimit: false, // Under the limit
},
{
storageLocationId: 'location-2',
sumFileBytes: 1000,
maxAllowedFileBytes: 1073741824,
isOverLimit: true,
},
],
}
16 changes: 0 additions & 16 deletions packages/synapse-react-client/src/synapse-client/SynapseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ import {
TERMS_OF_USE_INFO,
TERMS_OF_USE_STATUS,
PROJECT_STORAGE_USAGE,
PROJECT_STORAGE_LIMIT,
} from '../utils/APIConstants'
import { dispatchDownloadListChangeEvent } from '../utils/functions/dispatchDownloadListChangeEvent'
import { BackendDestinationEnum, getEndpoint } from '../utils/functions'
Expand Down Expand Up @@ -336,7 +335,6 @@ import {
TermsOfServiceStatus,
AccessToken,
ProjectStorageUsage,
ProjectStorageLocationLimit,
} from '@sage-bionetworks/synapse-types'
import { calculateFriendlyFileSize } from '../utils/functions/calculateFriendlyFileSize'
import {
Expand Down Expand Up @@ -5610,17 +5608,3 @@ export const getProjectStorageUsage = (
{ signal },
)
}

export const getProjectStorageLocationLimit = (
request: ProjectStorageLocationLimit,
accessToken: string | undefined = undefined,
signal?: AbortSignal,
): Promise<ProjectStorageLocationLimit> => {
return doPost<ProjectStorageLocationLimit>(
PROJECT_STORAGE_LIMIT(request.projectId),
request,
accessToken,
BackendDestinationEnum.REPO_ENDPOINT,
{ signal },
)
}
2 changes: 0 additions & 2 deletions packages/synapse-react-client/src/utils/APIConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ export const TERMS_OF_USE_STATUS = `${TERMS_OF_USE}/status`
const PROJECT = (projectId: string) => `${REPO}/project/${projectId}`
export const PROJECT_STORAGE_USAGE = (projectId: string) =>
`${PROJECT(projectId)}/storage/usage`
export const PROJECT_STORAGE_LIMIT = (projectId: string) =>
`${PROJECT(projectId)}/storage/limit`
export const VERIFICATION_SUBMISSION = `${REPO}/verificationSubmission`
export const VERIFICATION_SUBMISSION_STATE = (id: string) =>
`${VERIFICATION_SUBMISSION}/${id}/state`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ const sufixes: string[] = [
'YB',
]

export function calculateFriendlyFileSize(bytes: number) {
export function calculateFriendlyFileSize(
bytes: number,
fractionDigits?: number,
) {
if (!bytes) {
return ''
}
Expand All @@ -19,6 +22,6 @@ export function calculateFriendlyFileSize(bytes: number) {
// tslint:disable-next-line
return (
(!bytes && '0 Bytes') ||
(bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sufixes[i]
(bytes / Math.pow(1024, i)).toFixed(fractionDigits ?? 2) + ' ' + sufixes[i]
)
}

0 comments on commit a7e6392

Please sign in to comment.