Skip to content

Commit

Permalink
[apache#2570][apache#2559] refactor(web): Displaying a fallback while…
Browse files Browse the repository at this point in the history
… content is loading for each small module (apache#2574)

### What changes were proposed in this pull request?

1. Displaying a fallback while content is loading for the main content
Displaying a fallback while content is loading for metalakes list table
body module
Displaying a fallback while content is loading for catalog tree list
modul

![UILoading](https://github.com/datastrato/gravitino/assets/9210625/0911c818-ee1b-400d-9b58-3af764a59363)

2. Define metadata icon src path based on the operating environment

3. Fix some issue of inconsistent behaviour
- Smooth display of loaded data
- Preserve search parameters when strongly refreshing a page

![fixbugs](https://github.com/datastrato/gravitino/assets/9210625/dd94fce7-4ee0-4c76-a40e-94e4a87f5ecc)


### Why are the changes needed?

An instant loading state is fallback UI that is shown immediately upon
navigation.
You can pre-render loading indicators such as skeletons and spinners.
This helps users understand the app is responding and provides a better
user experience.

Fix issue because of the need for consistent behaviour after refactoring

Fix: apache#2570, apache#2559

### Does this PR introduce _any_ user-facing change?

N/A

### How was this patch tested?
Will run e2e test after PR apache#2534 merged

---------

Co-authored-by: CHEYNE <contact@ch3yne.com>
  • Loading branch information
LauraXia123 and ch3yne authored Mar 19, 2024
1 parent 5b17e6f commit 0544f2a
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 305 deletions.
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@mui/x-tree-view": "^6.17.0",
"@reduxjs/toolkit": "^1.9.7",
"antd": "^5.13.3",
"axios": "^1.6.5",
"axios": "^1.6.8",
"chroma-js": "^2.4.2",
"clsx": "^2.0.0",
"dayjs": "^1.11.10",
Expand Down
14 changes: 7 additions & 7 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 3 additions & 10 deletions web/src/app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,16 @@

import '@/lib/styles/globals.css'

import { Suspense } from 'react'

import { NavigationEvents } from './rootLayout/navigation-events'

import Provider from '@/lib/provider'

import Loading from './rootLayout/Loading'
import Layout from './rootLayout/Layout'
import StyledToast from '../components/StyledToast'

export const metadata = {
title: 'Gravitino',
description: 'A high-performance, geo-distributed and federated metadata lake.',
icons: {
icon: '/ui/icons/gravitino.svg'
icon: process.env.NEXT_PUBLIC_BASE_PATH + '/icons/gravitino.svg'
}
}

Expand All @@ -28,10 +23,8 @@ const RootLayout = ({ children }) => {
<html lang='en' suppressHydrationWarning>
<body>
<Provider>
<Suspense fallback={<Loading />}>
<NavigationEvents />
<Layout>{children}</Layout>
</Suspense>
<NavigationEvents />
<Layout>{children}</Layout>
</Provider>
<StyledToast />
</body>
Expand Down
3 changes: 2 additions & 1 deletion web/src/app/metalakes/CreateMetalakeDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { useState, forwardRef, useEffect } from 'react'
import { updateMetalake } from '@/lib/store/metalakes'

import {
Box,
Expand Down Expand Up @@ -53,7 +54,7 @@ const Transition = forwardRef(function Transition(props, ref) {
})

const CreateMetalakeDialog = props => {
const { open, setOpen, data = {}, updateMetalake, type = 'create' } = props
const { open, setOpen, data = {}, type = 'create' } = props

const dispatch = useAppDispatch()

Expand Down
256 changes: 256 additions & 0 deletions web/src/app/metalakes/TableBody.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
/*
* Copyright 2023 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/

import { useState, useEffect, Fragment } from 'react'

import Link from 'next/link'

import { Box, Typography, Portal, Tooltip } from '@mui/material'
import { DataGrid, GridActionsCellItem, GridToolbar } from '@mui/x-data-grid'
import {
VisibilityOutlined as ViewIcon,
EditOutlined as EditIcon,
DeleteOutlined as DeleteIcon
} from '@mui/icons-material'

import { formatToDateTime } from '@/lib/utils/date'
import { useAppDispatch, useAppSelector } from '@/lib/hooks/useStore'
import { fetchMetalakes, setFilteredMetalakes, deleteMetalake, resetTree } from '@/lib/store/metalakes'
import ConfirmDeleteDialog from '@/components/ConfirmDeleteDialog'

const TableBody = props => {
const { value, setOpenDialog, setDialogData, setDialogType, setDrawerData, setOpenDrawer } = props

const dispatch = useAppDispatch()
const store = useAppSelector(state => state.metalakes)
const [paginationModel, setPaginationModel] = useState({ page: 0, pageSize: 10 })

const [openConfirmDelete, setOpenConfirmDelete] = useState(false)
const [confirmCacheData, setConfirmCacheData] = useState(null)

const handleDeleteMetalake = name => () => {
setOpenConfirmDelete(true)
setConfirmCacheData(name)
}

const handleConfirmDeleteSubmit = () => {
if (confirmCacheData) {
dispatch(deleteMetalake(confirmCacheData))
setOpenConfirmDelete(false)
}
}

const handleCloseConfirm = () => {
setOpenConfirmDelete(false)
setConfirmCacheData(null)
}

const handleShowEditDialog = data => () => {
setDialogType('update')
setOpenDialog(true)
setDialogData(data)
}

const handleShowDetails = row => () => {
setDrawerData(row)
setOpenDrawer(true)
}

const handleClickLink = () => {
dispatch(resetTree())
}

useEffect(() => {
dispatch(fetchMetalakes())
}, [dispatch])

useEffect(() => {
const filteredData = store.metalakes
.filter(i => i.name.toLowerCase().includes(value.toLowerCase()))
.sort((a, b) => {
if (a.name.toLowerCase() === value.toLowerCase()) return -1
if (b.name.toLowerCase() === value.toLowerCase()) return 1

return 0
})

dispatch(setFilteredMetalakes(filteredData))
}, [dispatch, store.metalakes, value])

/** @type {import('@mui/x-data-grid').GridColDef[]} */
const columns = [
{
flex: 0.2,
minWidth: 230,
disableColumnMenu: true,
filterable: true,
type: 'string',
field: 'name',
headerName: 'Name',
renderCell: ({ row }) => {
const { name } = row

return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Tooltip title={name} placement='right'>
<Typography
noWrap
component={Link}
href={`/metalakes?metalake=${name}`}
onClick={() => handleClickLink()}
sx={{
fontWeight: 500,
color: 'primary.main',
textDecoration: 'none',
maxWidth: 240,
overflow: 'hidden',
textOverflow: 'ellipsis',
'&:hover': { color: 'primary.main', textDecoration: 'underline' }
}}
>
{name}
</Typography>
</Tooltip>
</Box>
)
}
},
{
flex: 0.15,
minWidth: 150,
disableColumnMenu: true,
type: 'string',
field: 'createdBy',
valueGetter: params => `${params.row.audit?.creator}`,
headerName: 'Created by',
renderCell: ({ row }) => {
return (
<Typography noWrap sx={{ color: 'text.secondary' }}>
{row.audit?.creator}
</Typography>
)
}
},
{
flex: 0.15,
minWidth: 150,
disableColumnMenu: true,
type: 'dateTime',
field: 'createdAt',
valueGetter: params => new Date(params.row.audit?.createTime),
headerName: 'Created at',
renderCell: ({ row }) => {
return (
<Typography title={row.audit?.createTime} noWrap sx={{ color: 'text.secondary' }}>
{formatToDateTime(row.audit?.createTime)}
</Typography>
)
}
},
{
flex: 0.1,
minWidth: 90,
type: 'actions',
headerName: 'Actions',
field: 'actions',
getActions: ({ id, row }) => [
<GridActionsCellItem
key='details'
label='Details'
title='Details'
data-refer={`view-metalake-${row.name}`}
icon={<ViewIcon viewBox='0 0 24 22' />}
onClick={handleShowDetails(row)}
sx={{
'& svg': {
fontSize: '24px'
}
}}
/>,
<GridActionsCellItem
key='edit'
label='Edit'
title='Edit'
data-refer={`edit-metalake-${row.name}`}
icon={<EditIcon />}
onClick={handleShowEditDialog(row)}
sx={{
'& svg': {
fontSize: '24px'
}
}}
/>,
<GridActionsCellItem
key='delete'
icon={<DeleteIcon />}
label='Delete'
title='Delete'
data-refer={`delete-metalake-${row.name}`}
onClick={handleDeleteMetalake(row.name)}
sx={{
'& svg': {
fontSize: '24px',
color: theme => theme.palette.error.light
}
}}
/>
]
}
]

function TableToolbar(props) {
return (
<>
<Fragment>
<Portal container={() => document.getElementById('filter-panel')}>
<Box className={`twc-flex twc-w-full twc-justify-between`}>
<GridToolbar {...props} />
</Box>
</Portal>
</Fragment>
</>
)
}

return (
<>
<DataGrid
disableColumnSelector
disableDensitySelector
slots={{ toolbar: TableToolbar }}
slotProps={{
toolbar: {
printOptions: { disableToolbarButton: true },
csvOptions: { disableToolbarButton: true }
}
}}
sx={{
'& .MuiDataGrid-virtualScroller': {
minHeight: 36
},
maxHeight: 'calc(100vh - 23.2rem)'
}}
getRowId={row => row?.name}
rows={store.filteredMetalakes}
columns={columns}
disableRowSelectionOnClick
onCellClick={(params, event) => event.stopPropagation()}
onRowClick={(params, event) => event.stopPropagation()}
pageSizeOptions={[10, 25, 50]}
paginationModel={paginationModel}
onPaginationModelChange={setPaginationModel}
/>
<ConfirmDeleteDialog
open={openConfirmDelete}
setOpen={setOpenConfirmDelete}
confirmCacheData={confirmCacheData}
handleClose={handleCloseConfirm}
handleConfirmDeleteSubmit={handleConfirmDeleteSubmit}
/>
</>
)
}

export default TableBody
17 changes: 0 additions & 17 deletions web/src/app/metalakes/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,11 @@

import { Grid, Typography } from '@mui/material'
import { useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react'
import Metalake from './metalake/MetalakeView.js'

const MetalakesView = ({ children }) => {
const searchParams = useSearchParams()

const [, setRouteParams] = useState({})

const metalakeName = searchParams.get('metalake')
const catalogName = searchParams.get('catalog')
const schemaName = searchParams.get('schema')
const tableName = searchParams.get('table')

useEffect(() => {
const takeParams = {
metalake: metalakeName,
catalog: catalogName,
schema: schemaName,
table: tableName
}
setRouteParams(takeParams)
}, [metalakeName, catalogName, schemaName, tableName])

return (
<>
Expand Down
Loading

0 comments on commit 0544f2a

Please sign in to comment.