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

nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-paimon-webui.git


The following commit(s) were added to refs/heads/main by this push:
     new 670eb7d  [Feature] Enhance metadata menu tree lazy load mock and 
suffix button style (#92)
670eb7d is described below

commit 670eb7daa3bafcd2ae8169d4bbaae37edf49a85f
Author: xiaomo <[email protected]>
AuthorDate: Mon Nov 6 11:15:42 2023 +0800

    [Feature] Enhance metadata menu tree lazy load mock and suffix button style 
(#92)
---
 paimon-web-ui-new/src/api/models/catalog/index.ts  |  7 +++
 paimon-web-ui-new/src/store/catalog/index.ts       | 66 +++++++++++++++++----
 .../views/metadata/components/menu-tree/index.tsx  | 68 +++++++++++++++++++---
 3 files changed, 121 insertions(+), 20 deletions(-)

diff --git a/paimon-web-ui-new/src/api/models/catalog/index.ts 
b/paimon-web-ui-new/src/api/models/catalog/index.ts
index edacc5d..2045279 100644
--- a/paimon-web-ui-new/src/api/models/catalog/index.ts
+++ b/paimon-web-ui-new/src/api/models/catalog/index.ts
@@ -29,4 +29,11 @@ export const getAllCatalogs = () => {
   return httpRequest.get<any, Catalog[]>('/catalog/getAllCatalogs')
 }
 
+/**
+ * # Get database by catalog id
+ */
+export const getDatabasesByCatalogId = (id: number) => {
+  return httpRequest.get<any, 
Catalog[]>(`/database/getDatabasesByCatalogId/${id}`)
+}
+
 // #endregion
diff --git a/paimon-web-ui-new/src/store/catalog/index.ts 
b/paimon-web-ui-new/src/store/catalog/index.ts
index 0e5bb55..30da5fb 100644
--- a/paimon-web-ui-new/src/store/catalog/index.ts
+++ b/paimon-web-ui-new/src/store/catalog/index.ts
@@ -16,26 +16,23 @@ specific language governing permissions and limitations
 under the License. */
 
 import { NIcon, type TreeOption } from 'naive-ui'
-import { FolderOpenOutline } from '@vicons/ionicons5'
+import { FileTrayOutline, FolderOutline } from '@vicons/ionicons5'
 
 
-import { getAllCatalogs, type Catalog } from "@/api/models/catalog"
+import { getAllCatalogs, type Catalog } from '@/api/models/catalog'
 
 export interface CatalogState {
-  _catalogs: Catalog[];
+  catalogs: TreeOption[];
   _catalogLoading: boolean;
 }
 
 export const useCatalogStore = defineStore('catalog', {
   state: (): CatalogState => ({
-    _catalogs: [],
+    catalogs: [],
     _catalogLoading: false
   }),
   persist: true,
   getters: {
-    catalogs: (state): TreeOption[] => {
-      return transformCatalog(state._catalogs)
-    },
     catalogLoading: (state): boolean => {
       return state._catalogLoading
     }
@@ -46,22 +43,67 @@ export const useCatalogStore = defineStore('catalog', {
 
       this._catalogLoading = true
       const res = await useAllCatalog()
-      this._catalogs = res.data
+      this.catalogs = transformCatalog(res.data)
       this._catalogLoading = false
+    },
+    getDatabasesByCatalogId(id: number): Promise<any> {
+      // TODO: fetch database list by catalog id
+      // Waiting for the deployment of the back end interface
+
+      // const [, useDatabaseByCatalogId] = getDatabasesByCatalogId(id)
+      // return useDatabaseByCatalogId()
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          resolve([
+            {
+              label: 'database',
+              type: 'database',
+              key: ++id,
+              isLeaf: false,
+              prefix: () =>
+                h(NIcon, null, {
+                  default: () => h(FolderOutline)
+                }),
+            }
+          ])
+        }, 1000)
+      })
+    },
+    getTablesByDataBaseId(id: number): Promise<any> {
+      // TODO: fetch table list by catalog id and database name
+      // Waiting for the deployment of the back end interface
+
+      // const [, useDatabaseByCatalogId] = getDatabasesByCatalogId(id)
+      // return useDatabaseByCatalogId()
+      return new Promise((resolve) => {
+        setTimeout(() => {
+          resolve([
+            {
+              label: 'table',
+              type: 'table',
+              key: ++id,
+              isLeaf: true,
+              prefix: () =>
+                h(NIcon, null, {
+                  default: () => h(FileTrayOutline)
+                }),
+            }
+          ])
+        }, 1000)
+      })
     }
   }
 })
 
 const transformCatalog = (catalogs: Catalog[]): TreeOption[] => {
   return catalogs.map(catalog => ({
-    label: catalog.name,
-    type: catalog.type,
+    label: catalog.name || 'paimon',
+    type: catalog.type || 'catalog',
     key: catalog.id,
     isLeaf: false,
-    children: [],
     prefix: () =>
       h(NIcon, null, {
-        default: () => h(FolderOpenOutline)
+        default: () => h(FolderOutline)
       }),
   }))
 }
diff --git 
a/paimon-web-ui-new/src/views/metadata/components/menu-tree/index.tsx 
b/paimon-web-ui-new/src/views/metadata/components/menu-tree/index.tsx
index 7e17e4c..461f4a9 100644
--- a/paimon-web-ui-new/src/views/metadata/components/menu-tree/index.tsx
+++ b/paimon-web-ui-new/src/views/metadata/components/menu-tree/index.tsx
@@ -15,7 +15,8 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License. */
 
-import { Search } from '@vicons/ionicons5'
+import { Add, FolderOutline, FolderOpenOutline, Search } from 
'@vicons/ionicons5'
+import { NButton, NIcon, type TreeOption } from 'naive-ui';
 
 import { useCatalogStore } from '@/store/catalog'
 
@@ -42,22 +43,64 @@ export default defineComponent({
       },
     ]
 
-    const nodeProps = () => {
-      return {
-        onClick () {
-        },
+    const updatePrefixWithExpanded = (
+      _keys: Array<string | number>,
+      _option: Array<TreeOption | null>,
+      meta: {
+        node: TreeOption | null
+        action: 'expand' | 'collapse' | 'filter'
       }
+    ) => {
+      if (!meta.node) return
+      switch (meta.action) {
+        case 'expand':
+          meta.node.prefix = () =>
+            h(NIcon, null, {
+              default: () => h(FolderOpenOutline)
+            })
+          break
+        case 'collapse':
+          meta.node.prefix = () =>
+            h(NIcon, null, {
+              default: () => h(FolderOutline)
+            })
+          break
+      }
+    }
+
+    const renderSuffix = ({ option }: { option: TreeOption }) => {
+      return option.type !== 'table' ? h(NButton, {
+        quaternary: true,
+        circle: true,
+        size: 'tiny',
+        onClick: (e) => {
+          e.stopPropagation()
+        }
+      }, {
+        default: () => h(NIcon, null, {
+          default: () => h(Add)
+        })
+      }) : undefined
     }
 
     onMounted(catalogStore.getAllCatalogs)
 
+    const onLoadMenu = async (node: TreeOption) => {
+      const loadFn = node.type === 'catalog' ? 
catalogStore.getDatabasesByCatalogId : catalogStore.getTablesByDataBaseId
+      node.children = await loadFn(node.key as number)
+
+      return Promise.resolve()
+    }
+
     return {
       menuLoading: catalogStoreRef.catalogLoading,
       menuList: catalogStoreRef.catalogs,
       dropdownMenu,
       filterValue,
       t,
-      nodeProps,
+      onLoadMenu,
+      updatePrefixWithExpanded,
+      renderSuffix
     }
   },
   render() {
@@ -65,6 +108,14 @@ export default defineComponent({
       <div class={styles.container}>
         <n-card class={styles.card} content-style={'padding:20px 18px;'}>
           <n-space vertical>
+            <n-space justify='space-between' align='enter'>
+              <article>Catalog</article>
+              <n-button size='small' quaternary circle>
+                <n-icon>
+                  <Add />
+                </n-icon>
+              </n-button>
+            </n-space>
             <n-input placeholder={this.t('playground.search')} style="width: 
100%;"
               v-model:value={this.filterValue}
               v-slots={{
@@ -76,10 +127,11 @@ export default defineComponent({
               <n-tree
                 block-line
                 expand-on-click
-                on-load={() => {}}
+                renderSuffix={this.renderSuffix}
+                onUpdate:expandedKeys={this.updatePrefixWithExpanded}
+                onLoad={this.onLoadMenu}
                 data={this.menuList}
                 pattern={this.filterValue}
-                node-props={this.nodeProps}
               />
             </n-spin>
           </n-space>

Reply via email to