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 7baafec434 [#9696] web-v2(impr): update store data and tree node
refplace list entity after update entity (#10054)
7baafec434 is described below
commit 7baafec434ebd5ddb4d54331a540321fd9cff85a
Author: Qian Xia <[email protected]>
AuthorDate: Mon Mar 2 14:37:23 2026 +0800
[#9696] web-v2(impr): update store data and tree node refplace list entity
after update entity (#10054)
### What changes were proposed in this pull request?
<img width="3110" height="1870" alt="image"
src="https://github.com/user-attachments/assets/5cce7867-098a-49b2-951c-03ecf666f834"
/>
<img width="3452" height="1770" alt="image"
src="https://github.com/user-attachments/assets/8011691b-1e29-4568-aaf8-f2aa790f216a"
/>
1. update table only reload tags and policies of the table
2. improve this situation for catalog/schema/topic/fileset/model
### Why are the changes needed?
N/A
Fix: #9696
### Does this PR introduce _any_ user-facing change?
N/A
### How was this patch tested?
manually
---------
Co-authored-by: Copilot <[email protected]>
---
.../catalogs/rightContent/CreateCatalogDialog.js | 2 +-
.../catalogs/rightContent/CreateFilesetDialog.js | 4 +-
.../app/catalogs/rightContent/CreateTableDialog.js | 2 +-
.../app/catalogs/rightContent/CreateTopicDialog.js | 6 +-
.../catalogs/rightContent/RegisterModelDialog.js | 4 +-
.../entitiesContent/CatalogDetailsPage.js | 2 +
.../rightContent/entitiesContent/CatalogsPage.js | 2 +-
.../entitiesContent/SchemaDetailsPage.js | 1 +
.../entitiesContent/TopicDetailsPage.js | 1 +
web-v2/web/src/lib/store/metalakes/index.js | 641 ++++++++++++++++++++-
10 files changed, 644 insertions(+), 21 deletions(-)
diff --git a/web-v2/web/src/app/catalogs/rightContent/CreateCatalogDialog.js
b/web-v2/web/src/app/catalogs/rightContent/CreateCatalogDialog.js
index c7eeafba5a..b1dab97d56 100644
--- a/web-v2/web/src/app/catalogs/rightContent/CreateCatalogDialog.js
+++ b/web-v2/web/src/app/catalogs/rightContent/CreateCatalogDialog.js
@@ -494,7 +494,7 @@ export default function CreateCatalogDialog({ ...props }) {
messageVariables={{ label: 'catalog name' }}
data-refer='catalog-name-field'
>
- <Input placeholder={mismatchName} disabled={!init} />
+ <Input placeholder={mismatchName} disabled={init} />
</Form.Item>
{providerBase[catalogType === 'model' ? 'model' :
currentProvider]?.defaultProps
?.filter(p => !isHidden(p))
diff --git a/web-v2/web/src/app/catalogs/rightContent/CreateFilesetDialog.js
b/web-v2/web/src/app/catalogs/rightContent/CreateFilesetDialog.js
index da357f5ed3..b11893d83a 100644
--- a/web-v2/web/src/app/catalogs/rightContent/CreateFilesetDialog.js
+++ b/web-v2/web/src/app/catalogs/rightContent/CreateFilesetDialog.js
@@ -176,13 +176,13 @@ export default function CreateFilesetDialog({ ...props })
{
const reqData = { updates: genUpdates(cacheData, submitData) }
if (reqData.updates.length) {
await dispatch(
- updateFileset({ data: reqData, metalake, catalog, catalogType,
schema, fileset: cacheData.name })
+ updateFileset({ init, data: reqData, metalake, catalog,
catalogType, schema, fileset: cacheData.name })
)
}
} else {
await dispatch(createFileset({ data: submitData, metalake, catalog,
catalogType, schema }))
}
- treeRef.current.onLoadData({ key: `${catalog}/${schema}`, nodeType:
'schema' })
+ !editFileset && treeRef.current.onLoadData({ key:
`${catalog}/${schema}`, nodeType: 'schema' })
setConfirmLoading(false)
setOpen(false)
})
diff --git a/web-v2/web/src/app/catalogs/rightContent/CreateTableDialog.js
b/web-v2/web/src/app/catalogs/rightContent/CreateTableDialog.js
index f528acd635..a15bf07b6d 100644
--- a/web-v2/web/src/app/catalogs/rightContent/CreateTableDialog.js
+++ b/web-v2/web/src/app/catalogs/rightContent/CreateTableDialog.js
@@ -724,7 +724,7 @@ export default function CreateTableDialog({ ...props }) {
}
if (submitted) {
- treeRef.current.onLoadData({ key: `${catalog}/${schema}`,
nodeType: 'schema' })
+ !editTable && treeRef.current.onLoadData({ key:
`${catalog}/${schema}`, nodeType: 'schema' })
setOpen(false)
}
} catch (error) {
diff --git a/web-v2/web/src/app/catalogs/rightContent/CreateTopicDialog.js
b/web-v2/web/src/app/catalogs/rightContent/CreateTopicDialog.js
index c9c7fe962f..2c39366087 100644
--- a/web-v2/web/src/app/catalogs/rightContent/CreateTopicDialog.js
+++ b/web-v2/web/src/app/catalogs/rightContent/CreateTopicDialog.js
@@ -132,12 +132,14 @@ export default function CreateTopicDialog({ ...props }) {
// update topic
const reqData = { updates: genUpdates(cacheData, submitData) }
if (reqData.updates.length) {
- await dispatch(updateTopic({ metalake, catalog, catalogType,
schema, topic: editTopic, data: reqData }))
+ await dispatch(
+ updateTopic({ init, metalake, catalog, catalogType, schema,
topic: editTopic, data: reqData })
+ )
}
} else {
await dispatch(createTopic({ data: submitData, metalake, catalog,
schema, catalogType }))
}
- init && treeRef.current.onLoadData({ key: `${catalog}/${schema}`,
nodeType: 'schema' })
+ !editTopic && treeRef.current.onLoadData({ key:
`${catalog}/${schema}`, nodeType: 'schema' })
setConfirmLoading(false)
setOpen(false)
})
diff --git a/web-v2/web/src/app/catalogs/rightContent/RegisterModelDialog.js
b/web-v2/web/src/app/catalogs/rightContent/RegisterModelDialog.js
index 5c6994d22b..a001d36d02 100644
--- a/web-v2/web/src/app/catalogs/rightContent/RegisterModelDialog.js
+++ b/web-v2/web/src/app/catalogs/rightContent/RegisterModelDialog.js
@@ -136,7 +136,9 @@ export default function RegisterModelDialog({ ...props }) {
// update model
const reqData = { updates: genUpdates(cacheData, submitData) }
if (reqData.updates.length) {
- await dispatch(updateModel({ metalake, catalog, catalogType,
schema, model: editModel, data: reqData }))
+ await dispatch(
+ updateModel({ init, metalake, catalog, catalogType, schema,
model: editModel, data: reqData })
+ )
}
} else {
await dispatch(registerModel({ data: submitData, metalake, catalog,
schema, catalogType }))
diff --git
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogDetailsPage.js
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogDetailsPage.js
index f59bf91fa8..ca1dd8d71b 100644
---
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogDetailsPage.js
+++
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogDetailsPage.js
@@ -502,6 +502,7 @@ export default function CatalogDetailsPage() {
locationProviders={store.activatedDetails?.properties?.['filesystem-providers']?.split(',')
|| []}
catalogBackend={store.activatedDetails?.properties?.['catalog-backend']}
editSchema={editSchema}
+ init={false}
/>
)}
</>
@@ -520,6 +521,7 @@ export default function CatalogDetailsPage() {
editCatalog={catalog}
catalogType={catalogType}
systemConfig={systemConfig}
+ init={true}
/>
)}
{openOwner && (
diff --git
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogsPage.js
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogsPage.js
index 7c733648d6..d094ae7544 100644
--- a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogsPage.js
+++ b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/CatalogsPage.js
@@ -385,7 +385,7 @@ export default function CatalogsPage() {
metalake={currentMetalake}
catalogType={catalogType}
editCatalog={editCatalog}
- init={true}
+ init={false}
/>
)}
{openOwner && (
diff --git
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/SchemaDetailsPage.js
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/SchemaDetailsPage.js
index 38555281d6..8d8168e78f 100644
---
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/SchemaDetailsPage.js
+++
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/SchemaDetailsPage.js
@@ -645,6 +645,7 @@ export default function SchemaDetailsPage() {
provider={catalogData?.provider}
locationProviders={catalogData?.properties?.['filesystem-providers']?.split(',')
|| []}
editSchema={schema}
+ init={true}
/>
)}
{openOwner && (
diff --git
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
index eb97f93729..140b2cf048 100644
---
a/web-v2/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
+++
b/web-v2/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
@@ -194,6 +194,7 @@ export default function TopicDetailsPage({ ...props }) {
catalog={catalog}
schema={schema}
editTopic={topic}
+ init={true}
/>
)}
{openOwner && (
diff --git a/web-v2/web/src/lib/store/metalakes/index.js
b/web-v2/web/src/lib/store/metalakes/index.js
index 4eeba36c57..d0f2c318f1 100644
--- a/web-v2/web/src/lib/store/metalakes/index.js
+++ b/web-v2/web/src/lib/store/metalakes/index.js
@@ -79,6 +79,16 @@ import {
} from '@/lib/api/models'
import { getFunctionsApi } from '@/lib/api/functions'
+const remapExpandedAndLoadedNodes = ({ getState, mapNode }) => {
+ const expandedNodes = getState().metalakes.expandedNodes.map(mapNode)
+ const loadedNodes = getState().metalakes.loadedNodes.map(mapNode)
+
+ return {
+ expanded: expandedNodes,
+ loaded: loadedNodes
+ }
+}
+
export const fetchMetalakes = createAsyncThunk('appMetalakes/fetchMetalakes',
async (params, { getState }) => {
const [err, res] = await to(getMetalakesApi())
@@ -652,15 +662,94 @@ export const testCatalogConnection = createAsyncThunk(
export const updateCatalog = createAsyncThunk(
'appMetalakes/updateCatalog',
- async ({ init, metalake, catalog, data }, { dispatch }) => {
+ async ({ init, metalake, catalog, data }, { getState, dispatch }) => {
const [err, res] = await to(updateCatalogApi({ metalake, catalog, data }))
if (err || !res) {
return { err: true }
}
if (init) {
- dispatch(fetchCatalogs({ metalake, update: { catalog, newCatalog:
res.catalog }, init }))
+ dispatch(getCatalogDetails({ init, metalake, catalog }))
} else {
- dispatch(getCatalogDetails({ init: true, metalake, catalog }))
+ dispatch(updateCatalogInStore({ metalake, catalog, newCatalog:
res.catalog }))
+
+ if (catalog !== res.catalog.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name === catalog) {
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schema => {
+ const tables = schema.children
+ ? schema.children.map(table => {
+ return {
+ ...table,
+ id:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}{{${schema.name}}}{{${table.name}}}`,
+ key:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}{{${schema.name}}}{{${table.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog: res.catalog.name,
+ catalogType: res.catalog.type,
+ schema: schema.name,
+ table: table.name
+ }).toString()}`
+ }
+ })
+ : []
+
+ return {
+ ...schema,
+ id:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}{{${schema.name}}}`,
+ key:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}{{${schema.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog: res.catalog.name,
+ catalogType: res.catalog.type,
+ schema: schema.name
+ }).toString()}`,
+ tables: tables,
+ children: tables
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ id:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}`,
+ key:
`{{${metalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog: res.catalog.name,
+ catalogType: res.catalog.type
+ }).toString()}`,
+ catalogType: res.catalog.type,
+ provider: res.catalog.provider,
+ name: res.catalog.name,
+ title: res.catalog.name,
+ schemas: schemas,
+ children: schemas
+ }
+ }
+
+ return { ...catalogItem }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, entity] = extractPlaceholder(node)
+ if (currentCatalog !== catalog) {
+ return node
+ }
+
+ return
`{{${currentMetalake}}}{{${res.catalog.name}}}{{${res.catalog.type}}}${
+ currentSchema ? `{{${currentSchema}}}` : ''
+ }${entity ? `{{${entity}}}` : ''}`
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
}
return res.catalog
@@ -806,7 +895,7 @@ export const createSchema = createAsyncThunk(
export const updateSchema = createAsyncThunk(
'appMetalakes/updateSchema',
- async ({ init, metalake, catalog, catalogType, schema, data }, { dispatch })
=> {
+ async ({ init, metalake, catalog, catalogType, schema, data }, { getState,
dispatch }) => {
const [err, res] = await to(updateSchemaApi({ metalake, catalog, schema,
data }))
if (err || !res) {
return { err: true }
@@ -814,7 +903,73 @@ export const updateSchema = createAsyncThunk(
if (init) {
dispatch(getSchemaDetails({ init, metalake, catalog, schema }))
} else {
- dispatch(fetchSchemas({ metalake, catalog, catalogType, init: true }))
+ dispatch(updateSchemaInStore({ metalake, catalog, catalogType, schema,
newSchema: res.schema }))
+
+ if (schema !== res.schema.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name !== catalog) return { ...catalogItem }
+
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schemaItem => {
+ if (schemaItem.name !== schema) return { ...schemaItem }
+
+ const tables = schemaItem.children
+ ? schemaItem.children.map(table => {
+ return {
+ ...table,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${res.schema.name}}}{{${table.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${res.schema.name}}}{{${table.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema: res.schema.name,
+ table: table.name
+ }).toString()}`
+ }
+ })
+ : []
+
+ return {
+ ...schemaItem,
+ ...res.schema,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${res.schema.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${res.schema.name}}}`,
+ path: `?${new URLSearchParams({ metalake, catalog,
catalogType, schema: res.schema.name }).toString()}`,
+ name: res.schema.name,
+ title: res.schema.name,
+ tables: tables,
+ children: tables
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ schemas: schemas,
+ children: schemas
+ }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, table] = extractPlaceholder(node)
+ if (currentCatalog === catalog && currentType === catalogType &&
currentSchema === schema) {
+ return
`{{${currentMetalake}}}{{${currentCatalog}}}{{${currentType}}}{{${res.schema.name}}}${
+ table ? `{{${table}}}` : ''
+ }`
+ }
+
+ return node
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
}
return res.schema
@@ -1051,7 +1206,7 @@ export const createTable = createAsyncThunk(
export const updateTable = createAsyncThunk(
'appMetalakes/updateTable',
- async ({ init, metalake, catalog, catalogType, schema, table, data }, {
dispatch }) => {
+ async ({ init, metalake, catalog, catalogType, schema, table, data }, {
getState, dispatch }) => {
const [err, res] = await to(updateTableApi({ metalake, catalog, schema,
table, data }))
if (err || !res) {
return { err: true }
@@ -1060,7 +1215,75 @@ export const updateTable = createAsyncThunk(
if (init) {
await dispatch(getTableDetails({ init, metalake, catalog, catalogType,
schema, table }))
} else {
- await dispatch(fetchTables({ metalake, catalog, catalogType, schema,
page: 'schemas', init: true }))
+ dispatch(updateTableInStore({ metalake, catalog, catalogType, schema,
table, newTable: res.table }))
+
+ if (table !== res.table.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name !== catalog) return { ...catalogItem }
+
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schemaItem => {
+ if (schemaItem.name !== schema) return { ...schemaItem }
+
+ const tables = schemaItem.children
+ ? schemaItem.children.map(tableItem => {
+ if (tableItem.name !== table) return { ...tableItem }
+
+ return {
+ ...tableItem,
+ ...res.table,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.table.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.table.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ table: res.table.name
+ }).toString()}`,
+ name: res.table.name,
+ title: res.table.name
+ }
+ })
+ : []
+
+ return {
+ ...schemaItem,
+ tables: tables,
+ children: tables
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ schemas: schemas,
+ children: schemas
+ }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, currentTable] = extractPlaceholder(node)
+ if (
+ currentCatalog === catalog &&
+ currentType === catalogType &&
+ currentSchema === schema &&
+ currentTable === table
+ ) {
+ return
`{{${currentMetalake}}}{{${currentCatalog}}}{{${currentType}}}{{${currentSchema}}}{{${res.table.name}}}`
+ }
+
+ return node
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
}
return res.table
@@ -1206,12 +1429,85 @@ export const createFileset = createAsyncThunk(
export const updateFileset = createAsyncThunk(
'appMetalakes/updateFileset',
- async ({ metalake, catalog, catalogType, schema, fileset, data }, { dispatch
}) => {
+ async ({ init, metalake, catalog, catalogType, schema, fileset, data }, {
getState, dispatch }) => {
const [err, res] = await to(updateFilesetApi({ metalake, catalog, schema,
fileset, data }))
if (err || !res) {
return { err: true }
}
- await dispatch(fetchFilesets({ metalake, catalog, catalogType, schema,
init: true }))
+
+ if (init) {
+ await dispatch(getFilesetDetails({ init, metalake, catalog, schema,
fileset }))
+ } else {
+ dispatch(updateFilesetInStore({ metalake, catalog, catalogType, schema,
fileset, newFileset: res.fileset }))
+
+ if (fileset !== res.fileset.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name !== catalog) return { ...catalogItem }
+
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schemaItem => {
+ if (schemaItem.name !== schema) return { ...schemaItem }
+
+ const filesets = schemaItem.children
+ ? schemaItem.children.map(filesetItem => {
+ if (filesetItem.name !== fileset) return {
...filesetItem }
+
+ return {
+ ...filesetItem,
+ ...res.fileset,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.fileset.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.fileset.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ fileset: res.fileset.name
+ }).toString()}`,
+ name: res.fileset.name,
+ title: res.fileset.name,
+ isLeaf: true
+ }
+ })
+ : []
+
+ return {
+ ...schemaItem,
+ children: filesets
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ children: schemas
+ }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, currentFileset] =
+ extractPlaceholder(node)
+ if (
+ currentCatalog === catalog &&
+ currentType === catalogType &&
+ currentSchema === schema &&
+ currentFileset === fileset
+ ) {
+ return
`{{${currentMetalake}}}{{${currentCatalog}}}{{${currentType}}}{{${currentSchema}}}{{${res.fileset.name}}}`
+ }
+
+ return node
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
+ }
return res.fileset
}
@@ -1372,12 +1668,84 @@ export const createTopic = createAsyncThunk(
export const updateTopic = createAsyncThunk(
'appMetalakes/updateTopic',
- async ({ metalake, catalog, catalogType, schema, topic, data }, { dispatch
}) => {
+ async ({ init, metalake, catalog, catalogType, schema, topic, data }, {
getState, dispatch }) => {
const [err, res] = await to(updateTopicApi({ metalake, catalog, schema,
topic, data }))
if (err || !res) {
return { err: true }
}
- await dispatch(fetchTopics({ metalake, catalog, catalogType, schema, init:
true }))
+
+ if (init) {
+ await dispatch(getTopicDetails({ init, metalake, catalog, schema, topic
}))
+ } else {
+ dispatch(updateTopicInStore({ metalake, catalog, catalogType, schema,
topic, newTopic: res.topic }))
+
+ if (topic !== res.topic.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name !== catalog) return { ...catalogItem }
+
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schemaItem => {
+ if (schemaItem.name !== schema) return { ...schemaItem }
+
+ const topics = schemaItem.children
+ ? schemaItem.children.map(topicItem => {
+ if (topicItem.name !== topic) return { ...topicItem }
+
+ return {
+ ...topicItem,
+ ...res.topic,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.topic.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.topic.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ topic: res.topic.name
+ }).toString()}`,
+ name: res.topic.name,
+ title: res.topic.name,
+ isLeaf: true
+ }
+ })
+ : []
+
+ return {
+ ...schemaItem,
+ children: topics
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ children: schemas
+ }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, currentTopic] = extractPlaceholder(node)
+ if (
+ currentCatalog === catalog &&
+ currentType === catalogType &&
+ currentSchema === schema &&
+ currentTopic === topic
+ ) {
+ return
`{{${currentMetalake}}}{{${currentCatalog}}}{{${currentType}}}{{${currentSchema}}}{{${res.topic.name}}}`
+ }
+
+ return node
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
+ }
return res.topic
}
@@ -1503,12 +1871,84 @@ export const registerModel = createAsyncThunk(
export const updateModel = createAsyncThunk(
'appMetalakes/updateModel',
- async ({ metalake, catalog, catalogType, schema, model, data }, { dispatch
}) => {
+ async ({ init, metalake, catalog, catalogType, schema, model, data }, {
getState, dispatch }) => {
const [err, res] = await to(updateModelApi({ metalake, catalog, schema,
model, data }))
if (err || !res) {
return { err: true }
}
- await dispatch(fetchModels({ metalake, catalog, catalogType, schema, init:
true }))
+
+ if (init) {
+ await dispatch(getModelDetails({ init, metalake, catalog, schema, model
}))
+ } else {
+ dispatch(updateModelInStore({ metalake, catalog, catalogType, schema,
model, newModel: res.model }))
+
+ if (model !== res.model.name) {
+ const tree = getState().metalakes.metalakeTree.map(catalogItem => {
+ if (catalogItem.name !== catalog) return { ...catalogItem }
+
+ const schemas = catalogItem.children
+ ? catalogItem.children.map(schemaItem => {
+ if (schemaItem.name !== schema) return { ...schemaItem }
+
+ const models = schemaItem.children
+ ? schemaItem.children.map(modelItem => {
+ if (modelItem.name !== model) return { ...modelItem }
+
+ return {
+ ...modelItem,
+ ...res.model,
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.model.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${res.model.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ model: res.model.name
+ }).toString()}`,
+ name: res.model.name,
+ title: res.model.name,
+ isLeaf: true
+ }
+ })
+ : []
+
+ return {
+ ...schemaItem,
+ children: models
+ }
+ })
+ : []
+
+ return {
+ ...catalogItem,
+ children: schemas
+ }
+ })
+
+ dispatch(setMetalakeTree(tree))
+
+ const { expanded, loaded } = remapExpandedAndLoadedNodes({
+ getState,
+ mapNode: node => {
+ const [currentMetalake, currentCatalog, currentType,
currentSchema, currentModel] = extractPlaceholder(node)
+ if (
+ currentCatalog === catalog &&
+ currentType === catalogType &&
+ currentSchema === schema &&
+ currentModel === model
+ ) {
+ return
`{{${currentMetalake}}}{{${currentCatalog}}}{{${currentType}}}{{${currentSchema}}}{{${res.model.name}}}`
+ }
+
+ return node
+ }
+ })
+
+ dispatch(setExpanded(expanded))
+ dispatch(setLoadedNodes(loaded))
+ }
+ }
return res.model
}
@@ -1766,6 +2206,175 @@ export const appMetalakesSlice = createSlice({
const { key, data } = action.payload
state.metalakeTree = updateTreeData(state.metalakeTree, key, data)
},
+ updateCatalogInStore(state, action) {
+ const { metalake, catalog, newCatalog } = action.payload
+
+ const updateCatalogItem = item => {
+ if (!item || item.name !== catalog) return item
+ const schemas = item.children || item.schemas || []
+
+ return {
+ ...item,
+ ...newCatalog,
+ node: 'catalog',
+ id: `{{${metalake}}}{{${newCatalog.name}}}{{${newCatalog.type}}}`,
+ key: `{{${metalake}}}{{${newCatalog.name}}}{{${newCatalog.type}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog: newCatalog.name,
+ catalogType: newCatalog.type
+ }).toString()}`,
+ catalogType: newCatalog.type,
+ provider: newCatalog.provider,
+ name: newCatalog.name,
+ title: newCatalog.name,
+ namespace: [metalake],
+ schemas: schemas,
+ children: schemas
+ }
+ }
+
+ state.catalogs = state.catalogs.map(updateCatalogItem)
+ state.tableData = state.tableData.map(updateCatalogItem)
+ },
+ updateSchemaInStore(state, action) {
+ const { metalake, catalog, catalogType, schema, newSchema } =
action.payload
+
+ const updateSchemaItem = item => {
+ if (!item || item.name !== schema) return item
+
+ return {
+ ...item,
+ ...newSchema,
+ node: 'schema',
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${newSchema.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${newSchema.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema: newSchema.name
+ }).toString()}`,
+ name: newSchema.name,
+ title: newSchema.name
+ }
+ }
+
+ state.schemas = state.schemas.map(updateSchemaItem)
+ state.tableData = state.tableData.map(updateSchemaItem)
+ },
+ updateTableInStore(state, action) {
+ const { metalake, catalog, catalogType, schema, table, newTable } =
action.payload
+
+ const updateTableItem = item => {
+ if (!item || item.name !== table) return item
+
+ return {
+ ...item,
+ ...newTable,
+ node: 'table',
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newTable.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newTable.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ table: newTable.name
+ }).toString()}`,
+ name: newTable.name,
+ title: newTable.name,
+ isLeaf: true
+ }
+ }
+
+ state.tables = state.tables.map(updateTableItem)
+ state.tableData = state.tableData.map(updateTableItem)
+ },
+ updateTopicInStore(state, action) {
+ const { metalake, catalog, catalogType, schema, topic, newTopic } =
action.payload
+
+ const updateTopicItem = item => {
+ if (!item || item.name !== topic) return item
+
+ return {
+ ...item,
+ ...newTopic,
+ node: 'topic',
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newTopic.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newTopic.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ topic: newTopic.name
+ }).toString()}`,
+ name: newTopic.name,
+ title: newTopic.name,
+ isLeaf: true
+ }
+ }
+
+ state.topics = state.topics.map(updateTopicItem)
+ state.tableData = state.tableData.map(updateTopicItem)
+ },
+ updateFilesetInStore(state, action) {
+ const { metalake, catalog, catalogType, schema, fileset, newFileset } =
action.payload
+
+ const updateFilesetItem = item => {
+ if (!item || item.name !== fileset) return item
+
+ return {
+ ...item,
+ ...newFileset,
+ node: 'fileset',
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newFileset.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newFileset.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ fileset: newFileset.name
+ }).toString()}`,
+ name: newFileset.name,
+ title: newFileset.name,
+ isLeaf: true
+ }
+ }
+
+ state.filesets = state.filesets.map(updateFilesetItem)
+ state.tableData = state.tableData.map(updateFilesetItem)
+ },
+ updateModelInStore(state, action) {
+ const { metalake, catalog, catalogType, schema, model, newModel } =
action.payload
+
+ const updateModelItem = item => {
+ if (!item || item.name !== model) return item
+
+ return {
+ ...item,
+ ...newModel,
+ node: 'model',
+ id:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newModel.name}}}`,
+ key:
`{{${metalake}}}{{${catalog}}}{{${catalogType}}}{{${schema}}}{{${newModel.name}}}`,
+ path: `?${new URLSearchParams({
+ metalake,
+ catalog,
+ catalogType,
+ schema,
+ model: newModel.name
+ }).toString()}`,
+ name: newModel.name,
+ title: newModel.name,
+ isLeaf: true
+ }
+ }
+
+ state.models = state.models.map(updateModelItem)
+ state.tableData = state.tableData.map(updateModelItem)
+ },
updateCatalogInUse(state, action) {
const { catalog, isInUse } = action.payload
const inUseValue = isInUse ? 'true' : 'false'
@@ -2240,6 +2849,12 @@ export const {
setExpanded,
setExpandedNodes,
addCatalogToTree,
+ updateCatalogInStore,
+ updateSchemaInStore,
+ updateTableInStore,
+ updateTopicInStore,
+ updateFilesetInStore,
+ updateModelInStore,
setCatalogInUse,
updateCatalogInUse,
setMetalakeInUse,