Skip to content

Commit

Permalink
Resolved bug, added file view and file delete.
Browse files Browse the repository at this point in the history
  • Loading branch information
harley-codes committed Jun 18, 2024
1 parent 490ff51 commit 1456b3e
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 23 deletions.
18 changes: 15 additions & 3 deletions src/app/dashboard/_actions/fileActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,22 @@ export async function createDataFileServerAction(file: NewDataFile): Promise<Dat
return newFile
}


export async function getDataFilesPaginatedServerAction(skip: number, take: number): Promise<DataFilesPaginatedResponse>
export async function getDataFilesPaginatedServerAction(skip: number, take?: number): Promise<DataFilesPaginatedResponse>
{
const client = await getDatabaseClientAsync()
const files = await client.getDataFilesPaginatedAsync(skip, take)
const files = await client.getDataFilesPaginatedAsync(skip, take ?? Number(process.env.PAGINATION_PAGE_SIZE))
return files
}

export async function getDataFileDetailsServerAction(fileId: string): Promise<DataFileDetails>
{
const client = await getDatabaseClientAsync()
const file = await client.getDataFileDetailsAsync(fileId)
return file
}

export async function deleteDataFileServerAction(fileId: string): Promise<void>
{
const client = await getDatabaseClientAsync()
await client.deleteDataFileAsync(fileId)
}
68 changes: 49 additions & 19 deletions src/app/dashboard/files/_components/FilesView.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
'use client'

import { createDataFileServerAction, getDataFilesPaginatedServerAction } from '@/app/dashboard/_actions/fileActions'
import
{
createDataFileServerAction,
deleteDataFileServerAction,
getDataFileDetailsServerAction,
getDataFilesPaginatedServerAction
} from '@/app/dashboard/_actions/fileActions'

import { FileListItem } from '@/app/dashboard/files/_components/FileListItem'
import { NewFileDialog } from '@/app/dashboard/files/_components/NewFileDialog'
import { ViewFileDialog, invokeViewFileRequest } from '@/app/dashboard/files/_components/ViewFileDialog'
import { invokeLoadingModal } from '@/components/LoadingModal'
import { NewDataFile } from '@/modules/database/requestTypes'
import { DataFileSearchItem, DataFilesPaginatedResponse } from '@/modules/database/responseTypes'
Expand All @@ -18,7 +26,7 @@ export function FilesView(props: DataFilesPaginatedResponse)

async function fileUploadHandler(fileData: NewDataFile)
{
const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Uploading Image' })
const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Uploading File' })

invokeLoading(true)

Expand All @@ -28,34 +36,55 @@ export function FilesView(props: DataFilesPaginatedResponse)
invokeLoading(false)
}

async function fileViewHandler(fileId: string)
{
const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Loading File' })

invokeLoading(true)
{
const file = await getDataFileDetailsServerAction(fileId)
invokeViewFileRequest(file)
}
invokeLoading(false)
}

async function fileDeleteHandler(fileId: string)
{
const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Deleting File' })

invokeLoading(true)

await deleteDataFileServerAction(fileId)
await resetPagination()

invokeLoading(false)
}

async function resetPagination()
{
const files = await getDataFilesPaginatedServerAction(0, process.env.PAGINATION_PAGE_SIZE)
const files = await getDataFilesPaginatedServerAction(0)
setDataFilesSearches({ 1: files.fileDetails })
setTotalFiles(files.totalFiles)
setPagination(files.request)
setPage(1)
}

async function paginationHandler(_event: React.ChangeEvent<unknown>, value: number)
{
if (dataFilesSearches[value])
if (!dataFilesSearches[value])
{
setPage(value)
return
}

const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Loading' })
const invokeLoading = (display: boolean) => invokeLoadingModal({ display, textOverride: 'Loading' })

invokeLoading(true)
{
// BUG: Review pagination issue - need to remove images before I can test
throw new Error('NEEDS WORK')
const result = await getDataFilesPaginatedServerAction((value - 1) * pagination.take, pagination.take)
const newDataFilesSearches = { ...dataFilesSearches }
newDataFilesSearches[value] = result.fileDetails
setDataFilesSearches(newDataFilesSearches)
invokeLoading(true)
{
const result = await getDataFilesPaginatedServerAction((value - 1) * pagination.take, pagination.take)
const newDataFilesSearches = { ...dataFilesSearches }
newDataFilesSearches[value] = result.fileDetails
setDataFilesSearches(newDataFilesSearches)
}
invokeLoading(false)
}
invokeLoading(false)

setPage(value)
}

Expand All @@ -64,7 +93,7 @@ export function FilesView(props: DataFilesPaginatedResponse)
<Grid container spacing={2} paddingRight={4}>
{dataFilesSearches[page].map((file) => (
<Grid item key={file.id} xs={6} sm={4} md={3}>
<FileListItem data={file} onClick={() => { }} />
<FileListItem data={file} onClick={() => fileViewHandler(file.id)} />
</Grid>
))}
</Grid>
Expand All @@ -90,6 +119,7 @@ export function FilesView(props: DataFilesPaginatedResponse)
/>
</Box>
<NewFileDialog onFileUpload={fileUploadHandler} />
<ViewFileDialog onFileDelete={fileDeleteHandler} />
</>
)
}
2 changes: 1 addition & 1 deletion src/app/dashboard/files/_components/NewFileDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function NewFileDialog(props: Props)
if (!dataFile) return

invokeConfirmationModal({
description: 'Are you sure you want to upload this image?',
description: 'Are you sure you want to upload this file?',
onConfirmed: (confirmed) =>
{
if (confirmed)
Expand Down
127 changes: 127 additions & 0 deletions src/app/dashboard/files/_components/ViewFileDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
'use client'

import { FileTypeIcon } from '@/app/dashboard/files/_components/FileTypeIcon'
import { invokeConfirmationModal } from '@/components/ConfirmationModal'
import { ImageBox } from '@/components/ImageBox'
import { createEvent } from '@/modules/custom-events/createEvent'
import { DataFileDetails } from '@/modules/database/responseTypes'
import { Button, Card, Dialog, DialogActions, DialogContent, DialogTitle, InputAdornment, List, ListItem, ListItemText, ListSubheader, TextField } from '@mui/material'
import { useState } from 'react'

const viewFileRequestEvent = createEvent<DataFileDetails>('viewFileRequest')

export const invokeViewFileRequest = viewFileRequestEvent.callEvent

const defaultState = {
display: false,
delete: false
}

type Props = {
onFileDelete: (fileId: string) => void
}

export function ViewFileDialog(props: Props)
{
const { onFileDelete } = props

const [state, setState] = useState(defaultState)
const [dataFile, setDataFile] = useState<DataFileDetails | null>(null)

viewFileRequestEvent.useEvent((file) =>
{
setState({ ...defaultState, display: true })
setDataFile(file)
})

function cancelHandler()
{
setState(defaultState)
}

function deleteStartHandler()
{
if (!dataFile) return

invokeConfirmationModal({
description: 'Are you sure you want to delete this file?',
onConfirmed: (confirmed) =>
{
if (confirmed)
{
setState({ ...state, display: false, delete: true })
}
}
})
}

function exitHandler()
{
if (dataFile && state.delete) onFileDelete(dataFile.id)
setState(defaultState)
setDataFile(null)
}

return (
<Dialog
open={state.display}
TransitionProps={{
onExited: exitHandler,
}}
fullWidth maxWidth="xs"
>
<DialogTitle>File View</DialogTitle>
<DialogContent>
{dataFile && (<>
<TextField
label="File Name"
fullWidth
margin="dense"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<FileTypeIcon extension={dataFile.extension} />
</InputAdornment>
),
}}
defaultValue={dataFile?.name}
disabled
/>
{dataFile.hasThumbnail && (
<ImageBox
src={`/api/public/files/data/${dataFile.id}`}
alt={dataFile.name}
aspectRatio="16/10"
backgroundImageFill
borderRadius='0.25em'
/>
)}

{Object.entries(dataFile.meta).length > 0 && (
<Card sx={{ padding: 0, marginTop: '2em' }}>
<List
dense
disablePadding
subheader={<ListSubheader>Meta</ListSubheader>}
>
{Object.entries(dataFile.meta).map(([key, value]) => (
<ListItem key={key}>
<ListItemText sx={{ display: 'flex', justifyContent: 'space-between' }}
primary={key}
secondary={value}
/>
</ListItem>
))}
</List>
</Card>

)}
</>)}
</DialogContent>
<DialogActions>
<Button onClick={cancelHandler}>Close</Button>
<Button onClick={deleteStartHandler} color='warning'>Delete</Button>
</DialogActions>
</Dialog >
)
}

0 comments on commit 1456b3e

Please sign in to comment.