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>