This is an automated email from the ASF dual-hosted git repository.

jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 79c69b7251 [#7106] subtask(web): support update model/model version 
for UI (#7107)
79c69b7251 is described below

commit 79c69b72514f9fa1d802285ba8e4c4163b3808a9
Author: Qian Xia <[email protected]>
AuthorDate: Wed Apr 30 12:01:25 2025 +0800

    [#7106] subtask(web): support update model/model version for UI (#7107)
    
    ### What changes were proposed in this pull request?
    update model for UI
    update model version for UI
    <img width="883" alt="image"
    
src="https://github.com/user-attachments/assets/1c41a1fe-e991-4d1a-b0b3-ac35ca973304";
    />
    <img width="835" alt="image"
    
src="https://github.com/user-attachments/assets/ea089f22-c39a-4abe-9b28-4db898303946";
    />
    
    
    ### Why are the changes needed?
    
    Fix: #7106
    
    ### Does this PR introduce _any_ user-facing change?
    N/A
    
    ### How was this patch tested?
    manually
---
 .../metalake/rightContent/LinkVersionDialog.js     | 47 +++++++++++++++++++---
 .../metalake/rightContent/RegisterModelDialog.js   | 24 +++++++++--
 .../tabsContent/tableView/TableView.js             | 43 +++++++++++++++++++-
 web/web/src/lib/api/models/index.js                | 12 ++++++
 web/web/src/lib/store/metalakes/index.js           | 26 +++++++++++-
 web/web/src/lib/utils/index.js                     |  4 ++
 6 files changed, 146 insertions(+), 10 deletions(-)

diff --git 
a/web/web/src/app/metalakes/metalake/rightContent/LinkVersionDialog.js 
b/web/web/src/app/metalakes/metalake/rightContent/LinkVersionDialog.js
index dadb464c4b..83c3127947 100644
--- a/web/web/src/app/metalakes/metalake/rightContent/LinkVersionDialog.js
+++ b/web/web/src/app/metalakes/metalake/rightContent/LinkVersionDialog.js
@@ -40,12 +40,12 @@ import {
 import Icon from '@/components/Icon'
 
 import { useAppDispatch } from '@/lib/hooks/useStore'
-import { linkVersion } from '@/lib/store/metalakes'
+import { linkVersion, updateVersion } from '@/lib/store/metalakes'
 
 import * as yup from 'yup'
 import { useForm, Controller, useFieldArray } from 'react-hook-form'
 import { yupResolver } from '@hookform/resolvers/yup'
-
+import { genUpdates } from '@/lib/utils'
 import { groupBy } from 'lodash-es'
 import { keyRegex } from '@/lib/utils/regex'
 import { useSearchParams } from 'next/navigation'
@@ -224,6 +224,27 @@ const LinkVersionDialog = props => {
               handleClose()
             }
           })
+        } else {
+          const reqData = { updates: genUpdates(cacheData, schemaData) }
+          console.log('reqData', reqData)
+
+          if (reqData.updates.length !== 0) {
+            dispatch(
+              updateVersion({
+                metalake,
+                catalog,
+                type: catalogType,
+                schema: schemaName,
+                model,
+                version: cacheData.version,
+                data: reqData
+              })
+            ).then(res => {
+              if (!res.payload?.err) {
+                handleClose()
+              }
+            })
+          }
         }
       })
       .catch(err => {
@@ -243,6 +264,10 @@ const LinkVersionDialog = props => {
       setValue('uri', data.uri)
       setValue('comment', data.comment)
 
+      data.aliases.forEach((alias, index) => {
+        setValue(`aliases.${index}.name`, alias)
+      })
+
       const propsItems = Object.entries(properties).map(([key, value]) => {
         return {
           key,
@@ -292,7 +317,6 @@ const LinkVersionDialog = props => {
                       label='URI'
                       onChange={onChange}
                       placeholder=''
-                      disabled={type === 'update'}
                       error={Boolean(errors.uri)}
                       data-refer='link-uri-field'
                     />
@@ -323,6 +347,7 @@ const LinkVersionDialog = props => {
                                   field.onChange(event)
                                   trigger('aliases')
                                 }}
+                                disabled={type === 'update'}
                                 label={`Alias ${index + 1}`}
                                 error={!!errors.aliases?.[index]?.name || 
!!errors.aliases?.message}
                                 
helperText={errors.aliases?.[index]?.name?.message || errors.aliases?.message}
@@ -334,13 +359,25 @@ const LinkVersionDialog = props => {
                         <Box>
                           {index === 0 ? (
                             <Box sx={{ minWidth: 40 }}>
-                              <IconButton onClick={() => append({ name: '' })}>
+                              <IconButton
+                                sx={{ cursor: type === 'update' ? 
'not-allowed' : 'pointer' }}
+                                onClick={() => {
+                                  if (type === 'update') return
+                                  append({ name: '' })
+                                }}
+                              >
                                 <Icon icon='mdi:plus-circle-outline' />
                               </IconButton>
                             </Box>
                           ) : (
                             <Box sx={{ minWidth: 40 }}>
-                              <IconButton onClick={() => remove(index)}>
+                              <IconButton
+                                sx={{ cursor: type === 'update' ? 
'not-allowed' : 'pointer' }}
+                                onClick={() => {
+                                  if (type === 'update') return
+                                  remove(index)
+                                }}
+                              >
                                 <Icon icon='mdi:minus-circle-outline' />
                               </IconButton>
                             </Box>
diff --git 
a/web/web/src/app/metalakes/metalake/rightContent/RegisterModelDialog.js 
b/web/web/src/app/metalakes/metalake/rightContent/RegisterModelDialog.js
index 68661fa9ba..b9b2800dc7 100644
--- a/web/web/src/app/metalakes/metalake/rightContent/RegisterModelDialog.js
+++ b/web/web/src/app/metalakes/metalake/rightContent/RegisterModelDialog.js
@@ -40,12 +40,12 @@ import {
 import Icon from '@/components/Icon'
 
 import { useAppDispatch } from '@/lib/hooks/useStore'
-import { registerModel } from '@/lib/store/metalakes'
+import { registerModel, updateModel } from '@/lib/store/metalakes'
 
 import * as yup from 'yup'
 import { useForm, Controller } from 'react-hook-form'
 import { yupResolver } from '@hookform/resolvers/yup'
-
+import { genUpdates } from '@/lib/utils'
 import { groupBy } from 'lodash-es'
 import { nameRegex, nameRegexDesc, keyRegex } from '@/lib/utils/regex'
 import { useSearchParams } from 'next/navigation'
@@ -190,6 +190,25 @@ const RegisterModelDialog = props => {
               }
             }
           )
+        } else {
+          const reqData = { updates: genUpdates(cacheData, schemaData) }
+
+          if (reqData.updates.length !== 0) {
+            dispatch(
+              updateModel({
+                metalake,
+                catalog,
+                type: catalogType,
+                schema: schemaName,
+                model: cacheData.name,
+                data: reqData
+              })
+            ).then(res => {
+              if (!res.payload?.err) {
+                handleClose()
+              }
+            })
+          }
         }
       })
       .catch(err => {
@@ -258,7 +277,6 @@ const RegisterModelDialog = props => {
                       label='Name'
                       onChange={onChange}
                       placeholder=''
-                      disabled={type === 'update'}
                       error={Boolean(errors.name)}
                       data-refer='model-name-field'
                     />
diff --git 
a/web/web/src/app/metalakes/metalake/rightContent/tabsContent/tableView/TableView.js
 
b/web/web/src/app/metalakes/metalake/rightContent/tabsContent/tableView/TableView.js
index aca7960b23..bdf8318f3b 100644
--- 
a/web/web/src/app/metalakes/metalake/rightContent/tabsContent/tableView/TableView.js
+++ 
b/web/web/src/app/metalakes/metalake/rightContent/tabsContent/tableView/TableView.js
@@ -44,6 +44,8 @@ import CreateSchemaDialog from '../../CreateSchemaDialog'
 import CreateFilesetDialog from '../../CreateFilesetDialog'
 import CreateTopicDialog from '../../CreateTopicDialog'
 import CreateTableDialog from '../../CreateTableDialog'
+import RegisterModelDialog from '../../RegisterModelDialog'
+import LinkVersionDialog from '../../LinkVersionDialog'
 
 import { useAppSelector, useAppDispatch } from '@/lib/hooks/useStore'
 import {
@@ -120,6 +122,8 @@ const TableView = () => {
   const [openFilesetDialog, setOpenFilesetDialog] = useState(false)
   const [openTopicDialog, setOpenTopicDialog] = useState(false)
   const [openTableDialog, setOpenTableDialog] = useState(false)
+  const [openModelDialog, setOpenModelDialog] = useState(false)
+  const [openModelVersionDialog, setOpenModelVersionDialog] = useState(false)
   const [dialogData, setDialogData] = useState({})
   const [dialogType, setDialogType] = useState('create')
   const [isHideEdit, setIsHideEdit] = useState(true)
@@ -132,7 +136,7 @@ const TableView = () => {
       const isHideAction =
         (['lakehouse-hudi', 'kafka'].includes(currentCatalog?.provider) && 
paramsSize == 3) ||
         (currentCatalog?.provider === 'lakehouse-hudi' && paramsSize == 4)
-      setIsHideEdit(isHideAction || type === 'model')
+      setIsHideEdit(isHideAction)
       setIsHideDrop(isHideAction)
     }
   }, [store.catalogs, store.catalogs.length, paramsSize, catalog, type])
@@ -637,6 +641,34 @@ const TableView = () => {
         }
         break
       }
+      case 'model': {
+        if (metalake && catalog && schema) {
+          const [err, res] = await to(getModelDetailsApi({ metalake, catalog, 
schema, model: data.row?.name }))
+          if (err || !res) {
+            throw new Error(err)
+          }
+
+          setDialogType('update')
+          setDialogData(res.model)
+          setOpenModelDialog(true)
+        }
+        break
+      }
+      case 'version': {
+        if (metalake && catalog && schema && model) {
+          const [err, res] = await to(
+            getVersionDetailsApi({ metalake, catalog, schema, model, version: 
data.row?.name })
+          )
+          if (err || !res) {
+            throw new Error(err)
+          }
+
+          setDialogType('update')
+          setDialogData(res.modelVersion)
+          setOpenModelVersionDialog(true)
+        }
+        break
+      }
       default:
         return
     }
@@ -779,6 +811,15 @@ const TableView = () => {
       <CreateTopicDialog open={openTopicDialog} setOpen={setOpenTopicDialog} 
data={dialogData} type={dialogType} />
 
       <CreateTableDialog open={openTableDialog} setOpen={setOpenTableDialog} 
data={dialogData} type={dialogType} />
+
+      <RegisterModelDialog open={openModelDialog} setOpen={setOpenModelDialog} 
data={dialogData} type={dialogType} />
+
+      <LinkVersionDialog
+        open={openModelVersionDialog}
+        setOpen={setOpenModelVersionDialog}
+        data={dialogData}
+        type={dialogType}
+      />
     </Box>
   )
 }
diff --git a/web/web/src/lib/api/models/index.js 
b/web/web/src/lib/api/models/index.js
index 74d2e0d368..435e4806d4 100644
--- a/web/web/src/lib/api/models/index.js
+++ b/web/web/src/lib/api/models/index.js
@@ -46,6 +46,11 @@ const Apis = {
     
`/api/metalakes/${encodeURIComponent(metalake)}/catalogs/${encodeURIComponent(
       catalog
     
)}/schemas/${encodeURIComponent(schema)}/models/${encodeURIComponent(model)}/versions`,
+  UPDATE_VERSION: ({ metalake, catalog, schema, model, version }) => {
+    return 
`/api/metalakes/${encodeURIComponent(metalake)}/catalogs/${encodeURIComponent(
+      catalog
+    
)}/schemas/${encodeURIComponent(schema)}/models/${encodeURIComponent(model)}/versions/${version}`
+  },
   DELETE_VERSION: ({ metalake, catalog, schema, model, version }) => {
     return 
`/api/metalakes/${encodeURIComponent(metalake)}/catalogs/${encodeURIComponent(
       catalog
@@ -87,6 +92,13 @@ export const linkVersionApi = ({ metalake, catalog, schema, 
model, data }) => {
   return defHttp.post({ url: `${Apis.LINK_VERSION({ metalake, catalog, schema, 
model })}`, data })
 }
 
+export const updateVersionApi = ({ metalake, catalog, schema, model, version, 
data }) => {
+  return defHttp.put({
+    url: `${Apis.UPDATE_VERSION({ metalake, catalog, schema, model, version 
})}`,
+    data
+  })
+}
+
 export const getVersionDetailsApi = ({ metalake, catalog, schema, model, 
version }) => {
   return defHttp.get({
     url: `${Apis.GET_VERSION_DETAIL({ metalake, catalog, schema, model, 
version })}`
diff --git a/web/web/src/lib/store/metalakes/index.js 
b/web/web/src/lib/store/metalakes/index.js
index 9d4eebc3c9..2862ca96d5 100644
--- a/web/web/src/lib/store/metalakes/index.js
+++ b/web/web/src/lib/store/metalakes/index.js
@@ -64,6 +64,7 @@ import {
   getModelVersionsApi,
   getVersionDetailsApi,
   linkVersionApi,
+  updateVersionApi,
   deleteVersionApi
 } from '@/lib/api/models'
 
@@ -1304,7 +1305,7 @@ export const registerModel = createAsyncThunk(
 export const updateModel = createAsyncThunk(
   'appMetalakes/updateModel',
   async ({ metalake, catalog, type, schema, model, data }, { dispatch }) => {
-    const [err, res] = await to(updateTopicApi({ metalake, catalog, schema, 
model, data }))
+    const [err, res] = await to(updateModelApi({ metalake, catalog, schema, 
model, data }))
     if (err || !res) {
       return { err: true }
     }
@@ -1422,6 +1423,19 @@ export const linkVersion = createAsyncThunk(
   }
 )
 
+export const updateVersion = createAsyncThunk(
+  'appMetalakes/updateVersion',
+  async ({ metalake, catalog, type, schema, model, version, data }, { dispatch 
}) => {
+    const [err, res] = await to(updateVersionApi({ metalake, catalog, schema, 
model, version, data }))
+    if (err || !res) {
+      return { err: true }
+    }
+    dispatch(fetchModelVersions({ metalake, catalog, type, schema, model, 
init: true }))
+
+    return res.modelVersion
+  }
+)
+
 export const deleteVersion = createAsyncThunk(
   'appMetalakes/deleteVersion',
   async ({ metalake, catalog, type, schema, model, version }, { dispatch }) => 
{
@@ -1828,6 +1842,16 @@ export const appMetalakesSlice = createSlice({
         toast.error(action.error.message)
       }
     })
+    builder.addCase(updateVersion.rejected, (state, action) => {
+      if (!action.error.message.includes('CanceledError')) {
+        toast.error(action.error.message)
+      }
+    })
+    builder.addCase(deleteVersion.rejected, (state, action) => {
+      if (!action.error.message.includes('CanceledError')) {
+        toast.error(action.error.message)
+      }
+    })
   }
 })
 
diff --git a/web/web/src/lib/utils/index.js b/web/web/src/lib/utils/index.js
index 8b41db98a6..2755a8346c 100644
--- a/web/web/src/lib/utils/index.js
+++ b/web/web/src/lib/utils/index.js
@@ -59,6 +59,10 @@ export const genUpdates = (originalData, newData) => {
     updates.push({ '@type': 'rename', newName: newData.name })
   }
 
+  if (originalData.uri !== newData.uri) {
+    updates.push({ '@type': 'updateUri', newUri: newData.uri })
+  }
+
   if (originalData.comment !== newData.comment) {
     updates.push({ '@type': 'updateComment', newComment: newData.comment })
   }

Reply via email to