Skip to content

Commit

Permalink
[apache#793] feat(UI): Replace mock data to real data in Metalakes pa…
Browse files Browse the repository at this point in the history
…ge (apache#803)

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

This PR replaces the original mock data with the data obtained from real
API requests, and shows gravitino version in page header.

When preparing to perform a delete action, a secondary confirmation
popup is added.
<img width="480" alt="image"
src="https://github.com/datastrato/gravitino/assets/17310559/0e224bf9-fd4f-4c72-a3ff-327fe288f97e">


All APIs are include `headers: { Accept:
"application/vnd.gravitino.v1+json" }`.

Associated API addresses:

```
GET http://localhost:8090/api/metalakes
```

```
GET http://localhost:8090/api/metalakes/{metalake_name}
```

```
GET http://localhost:8090/api/version
```

```
POST http://localhost:8090/api/metalakes

Example body: 
{
  "name": "metalake_name",
  "comment": "test comment",
  "properties": {
    "test_key": "test_value"
  }
}
```

```
PUT http://localhost:8090/api/metalakes/{metalake_name}

Example body: 
{
  "updates": [
    {
      "@type": "rename",
      "newName": "newName"
    },
    {
      "@type": "updateComment",
      "newComment": "newComment"
    },
    {
      "@type": "removeProperty",
      "property": "key"
    },
    {
      "@type": "setProperty",
      "property": "key",
      "value": "value"
    }
  ]
}
```

```
DELETE http://localhost:8090/api/metalakes/{metalake_name}
```


### Why are the changes needed?

Fix: apache#793 

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

No

### How was this patch tested?

No

Co-authored-by: Jerry Shao <jerryshao@datastrato.com>
  • Loading branch information
ch3yne and jerryshao authored Nov 24, 2023
1 parent 3fd2e2d commit a03d24f
Show file tree
Hide file tree
Showing 23 changed files with 978 additions and 102 deletions.
3 changes: 2 additions & 1 deletion web/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
"nprogress",
"reduxjs",
"Roboto",
"Segoe"
"Segoe",
"tabler"
],
"search-node-modules.path": "node_modules",
"markdown.extension.toc.updateOnSave": false
Expand Down
18 changes: 18 additions & 0 deletions web/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,25 @@ const path = require('path')

/** @type {import('next').NextConfig} */

const isProdEnv = process.env.NODE_ENV === 'production'

const devConfig = isProdEnv
? {}
: {
async rewrites() {
return {
fallback: [
{
source: '/api/:path*',
destination: 'http://localhost:8090/api/:path*'
}
]
}
}
}

module.exports = {
...devConfig,
distDir: 'dist',
output: process.env.OUTPUT_MODE || 'standalone',
trailingSlash: true,
Expand Down
3 changes: 2 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"react-perfect-scrollbar": "1.5.8",
"react-popper": "2.3.0",
"react-redux": "8.1.3",
"react-use": "^17.4.0",
"yup": "1.3.2"
},
"devDependencies": {
Expand All @@ -65,4 +66,4 @@
"@emotion/react/@emotion/babel-plugin/@babel/core": "7.0.0",
"@emotion/react/@emotion/babel-plugin/@babel/plugin-syntax-jsx/@babel/core": "7.0.0"
}
}
}
22 changes: 22 additions & 0 deletions web/src/@core/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

import axios from 'axios'

import { VersionApiEnum } from 'src/@core/enums/apiEnum'

const ApiEnum = {
...VersionApiEnum
}

export const getVersionApi = () => {
return axios({
url: `${ApiEnum.GET}`,
method: 'get',
headers: {
Accept: 'application/vnd.gravitino.v1+json'
}
})
}
54 changes: 54 additions & 0 deletions web/src/@core/api/metalakes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

import axios from 'axios'

import { MetalakesApiEnum } from 'src/@core/enums/apiEnum'

const ApiEnum = {
...MetalakesApiEnum
}

export const getMetalakesApi = () => {
return axios({
url: `${ApiEnum.GET}`,
method: 'get',
headers: {
Accept: 'application/vnd.gravitino.v1+json'
}
})
}

export const createMetalakeApi = data => {
return axios({
url: `${ApiEnum.CREATE}`,
method: 'post',
data,
headers: {
Accept: 'application/vnd.gravitino.v1+json'
}
})
}

export const deleteMetalakeApi = name => {
return axios({
url: `${ApiEnum.DELETE}/${name}`,
method: 'delete',
headers: {
Accept: 'application/vnd.gravitino.v1+json'
}
})
}

export const updateMetalakeApi = ({ name, data }) => {
return axios({
url: `${ApiEnum.UPDATE}/${name}`,
method: 'put',
headers: {
Accept: 'application/vnd.gravitino.v1+json'
},
data
})
}
63 changes: 63 additions & 0 deletions web/src/@core/components/custom-dialog/ConfirmDeleteDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import Typography from '@mui/material/Typography'
import DialogContent from '@mui/material/DialogContent'
import DialogActions from '@mui/material/DialogActions'

import Icon from 'src/@core/components/icon'

const ConfirmDeleteDialog = props => {
const { open, setOpen, handleConfirmDeleteSubmit } = props

const handleClose = () => setOpen(false)

return (
<Dialog fullWidth open={open} onClose={handleClose} sx={{ '& .MuiPaper-root': { width: '100%', maxWidth: 512 } }}>
<DialogContent
sx={{
px: theme => [`${theme.spacing(5)} !important`, `${theme.spacing(15)} !important`],
pt: theme => [`${theme.spacing(8)} !important`, `${theme.spacing(12.5)} !important`]
}}
>
<Box
sx={{
display: 'flex',
textAlign: 'center',
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'center',
'& svg': { mb: 8, color: 'warning.main' }
}}
>
<Icon icon='tabler:alert-circle' fontSize='5.5rem' />
<Typography variant='h4' sx={{ mb: 5, color: 'text.secondary' }}>
Confirm Delete ?
</Typography>
<Typography>This action can not reserve!</Typography>
</Box>
</DialogContent>
<DialogActions
sx={{
justifyContent: 'center',
px: theme => [`${theme.spacing(5)} !important`, `${theme.spacing(15)} !important`],
pb: theme => [`${theme.spacing(8)} !important`, `${theme.spacing(12.5)} !important`]
}}
>
<Button variant='contained' sx={{ mr: 2 }} onClick={() => handleConfirmDeleteSubmit()}>
Submit
</Button>
<Button variant='outlined' color='secondary' onClick={() => handleClose()}>
Cancel
</Button>
</DialogActions>
</Dialog>
)
}

export default ConfirmDeleteDialog
15 changes: 15 additions & 0 deletions web/src/@core/enums/apiEnum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

export const MetalakesApiEnum = {
GET: '/api/metalakes',
CREATE: '/api/metalakes',
DELETE: '/api/metalakes',
UPDATE: '/api/metalakes'
}

export const VersionApiEnum = {
GET: '/api/version'
}
38 changes: 38 additions & 0 deletions web/src/@core/enums/httpEnum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

/**
* @description: Request result set
*/
export const ResultEnum = {
SUCCESS: 0,
ERROR: 1,
TIMEOUT: 401,
TYPE: 'success'
}

/**
* @description: request method
*/
export const RequestEnum = {
GET: 'GET',
POST: 'POST',
PUT: 'PUT',
DELETE: 'DELETE'
}

/**
* @description: contentType
*/
export const ContentTypeEnum = {
// ** json
JSON: 'application/json;charset=UTF-8',

// ** form-data qs
FORM_URLENCODED: 'application/x-www-form-urlencoded;charset=UTF-8',

// ** form-data upload
FORM_DATA: 'multipart/form-data;charset=UTF-8'
}
96 changes: 96 additions & 0 deletions web/src/@core/utils/func.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2023 Datastrato.
* This software is licensed under the Apache License version 2.
*/

export const randomColor = () => {
let maxVal = 0xffffff
let randomNumber = Math.random() * maxVal
randomNumber = Math.floor(randomNumber)
randomNumber = randomNumber.toString(16)
let randColor = randomNumber.padStart(6, 0)

return `#${randColor.toUpperCase()}`
}

export function setObjToUrlParams(baseUrl, obj) {
let parameters = ''
for (const key in obj) {
parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
}
parameters = parameters.replace(/&$/, '')

return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters
}

export function deepMerge(src = {}, target = {}) {
let key
for (key in target) {
src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key])
}

return src
}

export const parseNum = (number, m = 0) => {
return Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
}

/**
* Calculate the page number based on the total number of items.
* @param {number} count
* @param {number} pageSize
* @returns
*/
export function pagerCount(count, pageSize) {
if (typeof count == 'number') {
if (count > 0) {
try {
let _pagerCount = count % pageSize == 0 ? count / pageSize : count / pageSize + 1
let c = _pagerCount.toFixed(0)
_pagerCount = c > _pagerCount ? c - 1 : c

return _pagerCount
} catch (error) {
return 0
}
} else {
return 0
}
} else {
return 0
}
}

export const genUpdateMetalakeUpdates = (originalData, newData) => {
const updates = []

if (originalData.name !== newData.name) {
updates.push({ '@type': 'rename', newName: newData.name })
}

if (originalData.comment !== newData.comment) {
updates.push({ '@type': 'updateComment', newComment: newData.comment })
}

const originalProperties = originalData.properties || {}
const newProperties = newData.properties || {}

for (const key in originalProperties) {
if (!(key in newProperties)) {
updates.push({ '@type': 'removeProperty', property: key })
}
}

for (const key in newProperties) {
if (originalProperties[key] !== newProperties[key]) {
if (originalProperties[key] === undefined) {
updates.push({ '@type': 'setProperty', property: key, value: newProperties[key] })
} else {
updates.push({ '@type': 'setProperty', property: key, value: newProperties[key] })
}
}
}

return updates
}
Loading

0 comments on commit a03d24f

Please sign in to comment.