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/paimon-webui.git
The following commit(s) were added to refs/heads/main by this push:
new 332ed2fd [Improvement] Optimize query page style (#315)
332ed2fd is described below
commit 332ed2fd2cd9121033463f59e1b41ab843742be2
Author: s7monk <[email protected]>
AuthorDate: Fri Jun 7 11:17:45 2024 +0800
[Improvement] Optimize query page style (#315)
---
.../console/components/table/index.module.scss | 2 +-
.../components/console/components/table/index.tsx | 86 ++++++++++++++++--
.../components/query/components/console/index.tsx | 29 +++++-
.../playground/components/query/index.module.scss | 53 +++++++++--
.../views/playground/components/query/index.tsx | 101 +++++++++++++--------
5 files changed, 212 insertions(+), 59 deletions(-)
diff --git
a/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
index 87820735..c7c41421 100644
---
a/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
+++
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
@@ -24,4 +24,4 @@ under the License. */
.table {
padding-left: 20px;
}
-}
\ No newline at end of file
+}
diff --git
a/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.tsx
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.tsx
index d400f58e..592a71ff 100644
---
a/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.tsx
+++
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.tsx
@@ -22,18 +22,27 @@ import { useJobStore } from '@/store/job'
export default defineComponent({
name: 'TableResult',
- setup() {
+ props: {
+ maxHeight: {
+ type: Number as PropType<number>,
+ default: 150,
+ },
+ },
+ setup(props) {
const { t } = useLocaleHooks()
const message = useMessage()
const jobStore = useJobStore()
-
+ const scrollX = ref('100%')
+ const tableContainer = ref<HTMLElement | null>(null)
const tableRef = ref<DataTableInst | null>(null)
+ const maxTableHeight = ref(0)
interface TableColumn {
title: string
key: string
fixed?: string
width?: number
+ originalWidth?: number
render?: (row: any, index: number) => string | number | JSX.Element
}
@@ -59,12 +68,19 @@ export default defineComponent({
render: (_, index) => `${index + 1}`,
}
- const dynamicColumns = Object.keys(sampleObject).map(key => ({
- title: key,
- key,
- resizable: true,
- sortable: true,
- }))
+ const dynamicColumns = Object.keys(sampleObject).map((key) => {
+ const maxContentWidth = Math.max(...data.value.map(item =>
item[key]?.toString().length || 0))
+ const maxTitleWidth = key.length * 10
+ const originalWidth = Math.max(100, maxContentWidth * 10,
maxTitleWidth)
+ return {
+ title: key,
+ key,
+ width: originalWidth,
+ originalWidth,
+ resizable: true,
+ sortable: true,
+ }
+ })
return [indexColumn, ...dynamicColumns]
}
@@ -83,26 +99,76 @@ export default defineComponent({
}
})
+ const updateTableWidth = () => {
+ if (tableContainer.value) {
+ const totalColumnWidth = columns.value.reduce((acc, col) => acc +
(col.originalWidth || 100), 0)
+ if (totalColumnWidth > tableContainer.value.clientWidth) {
+ scrollX.value = `${totalColumnWidth}px`
+ columns.value.forEach((col) => {
+ if (col.originalWidth !== undefined)
+ col.width = col.originalWidth
+ })
+ }
+ else {
+ scrollX.value = ''
+ columns.value.forEach((col) => {
+ col.width = undefined
+ })
+ }
+ }
+ }
+
+ watchEffect(updateTableWidth)
+
+ watch(data, async (newData) => {
+ if (newData && newData.length > 0) {
+ await nextTick()
+ if (tableContainer.value) {
+ const headerElement =
tableContainer.value.querySelector('.n-data-table-base-table-header')
+ if (headerElement) {
+ const headerHeight = headerElement.clientHeight
+ maxTableHeight.value = Math.max(0, props.maxHeight - headerHeight)
+ }
+ }
+ }
+ }, { immediate: true })
+
+ onMounted(() => {
+ nextTick(() => {
+ updateTableWidth()
+ window.addEventListener('resize', updateTableWidth)
+ })
+ })
+
onUnmounted(() => {
mittBus.off('triggerDownloadCsv')
mittBus.off('triggerCopyData')
+ window.removeEventListener('resize', updateTableWidth)
})
return {
columns,
data,
tableRef,
+ tableContainer,
+ scrollX,
+ maxHeight: props.maxHeight,
+ maxTableHeight,
}
},
render() {
return (
- <div>
+ <div
+ ref="tableContainer"
+ style={{ height: `${this.maxHeight}px` }}
+ >
<n-data-table
ref={(el: any) => { this.tableRef = el }}
class={styles.table}
columns={this.columns}
data={this.data}
- max-height={90}
+ max-height={`${this.maxTableHeight}px`}
+ scroll-x={this.scrollX || undefined}
v-slots={{
empty: () => '',
}}
diff --git
a/paimon-web-ui/src/views/playground/components/query/components/console/index.tsx
b/paimon-web-ui/src/views/playground/components/query/components/console/index.tsx
index 23c23ab5..b9436070 100644
---
a/paimon-web-ui/src/views/playground/components/query/components/console/index.tsx
+++
b/paimon-web-ui/src/views/playground/components/query/components/console/index.tsx
@@ -16,6 +16,7 @@ specific language governing permissions and limitations
under the License. */
import { CloseSharp, KeyboardDoubleArrowDownSharp, KeyboardDoubleArrowUpSharp
} from '@vicons/material'
+import { throttle } from 'lodash'
import TableActionBar from './components/controls'
import TableResult from './components/table'
import styles from './index.module.scss'
@@ -25,6 +26,8 @@ export default defineComponent({
emits: ['ConsoleUp', 'ConsoleDown', 'ConsoleClose'],
setup(props, { emit }) {
const { t } = useLocaleHooks()
+ const editorConsoleRef = ref<HTMLElement | null>(null)
+ const adjustedHeight = ref(0)
const handleUp = () => {
emit('ConsoleUp', 'up')
@@ -38,16 +41,38 @@ export default defineComponent({
emit('ConsoleClose', 'close')
}
+ const handleResize = throttle((entries) => {
+ for (const entry of entries) {
+ const { height } = entry.contentRect
+ adjustedHeight.value = height - 106
+ }
+ }, 100)
+
+ let resizeObserver: ResizeObserver
+ onMounted(() => {
+ if (editorConsoleRef.value) {
+ resizeObserver = new ResizeObserver(handleResize)
+ resizeObserver.observe(editorConsoleRef.value)
+ }
+ })
+
+ onUnmounted(() => {
+ if (editorConsoleRef.value)
+ resizeObserver.unobserve(editorConsoleRef.value)
+ })
+
return {
t,
handleUp,
handleDown,
handleClose,
+ editorConsoleRef,
+ adjustedHeight,
}
},
render() {
return (
- <div class={styles['editor-console']}>
+ <div class={styles['editor-console']} ref="editorConsoleRef">
<n-tabs
type="line"
size="large"
@@ -60,7 +85,7 @@ export default defineComponent({
</n-tab-pane>
<n-tab-pane name="result" tab={this.t('playground.result')}>
<TableActionBar />
- <TableResult />
+ <TableResult maxHeight={this.adjustedHeight} />
</n-tab-pane>
</n-tabs>
<div class={styles.operations}>
diff --git
a/paimon-web-ui/src/views/playground/components/query/index.module.scss
b/paimon-web-ui/src/views/playground/components/query/index.module.scss
index 0a807a10..cbda480c 100644
--- a/paimon-web-ui/src/views/playground/components/query/index.module.scss
+++ b/paimon-web-ui/src/views/playground/components/query/index.module.scss
@@ -21,17 +21,40 @@ under the License. */
height: 100%;
.menu-tree {
- width: 20%;
+ width: 100%;
height: 100%;
}
+ .split {
+ position: relative;
+ width: 0;
+ height: 100%;
+ flex: none;
+ cursor: col-resize;
+
+ &::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: -5px;
+ bottom: 0;
+ left: -5px;
+ background: transparent;
+ z-index: 1;
+ }
+ }
+
.editor-area {
- width: 80%;
+ display: flex;
+ flex: 1;
height: 100%;
+ flex-direction: column;
:global {
.n-card {
height: 100%;
+ display: flex;
+ flex-direction: column;
}
}
@@ -46,13 +69,31 @@ under the License. */
}
.editor {
- height: 60%;
- overflow-y: scroll;
+ height: 100%;
+ flex: 1;
}
.console {
- height: 40%;
- overflow-y: scroll;
+ height: 100%;
+ flex: 1;
+ }
+
+ .console-splitter {
+ position: relative;
+ height: 0;
+ background: transparent;
+ cursor: ns-resize;
+
+ &::after {
+ content: '';
+ position: absolute;
+ top: -5px;
+ right: 0;
+ bottom: -5px;
+ left: 0;
+ background: transparent;
+ z-index: 1;
+ }
}
}
}
diff --git a/paimon-web-ui/src/views/playground/components/query/index.tsx
b/paimon-web-ui/src/views/playground/components/query/index.tsx
index 34a20196..0b0c0172 100644
--- a/paimon-web-ui/src/views/playground/components/query/index.tsx
+++ b/paimon-web-ui/src/views/playground/components/query/index.tsx
@@ -168,47 +168,68 @@ export default defineComponent({
render() {
return (
<div class={styles.query}>
- <div class={styles['menu-tree']}>
- <MenuTree ref="menuTreeRef" />
- </div>
- <div class={styles['editor-area']}>
- <n-card class={styles.card} content-style="padding: 5px
18px;display: flex;flex-direction: column;">
- <div class={styles.tabs}>
- <EditorTabs />
- </div>
- <div class={styles.debugger}>
- <EditorDebugger tabData={this.tabData}
onHandleFormat={this.handleFormat} onHandleSave={this.editorSave} />
- </div>
- <div class={styles.editor} style={`height:
${this.consoleHeightType === 'up' ? '20%' : '60%'}`}>
- {
- this.tabData.panelsList?.length > 0
- && (
- <n-card content-style="padding: 0;">
- <MonacoEditor
- v-model={this.tabData.panelsList.find((item: any) =>
item.key === this.tabData.chooseTab).content}
- language={this.language}
- onEditorMounted={this.editorMounted}
- onEditorSave={this.editorSave}
- onChange={this.handleContentChange}
- />
- </n-card>
- )
- }
- </div>
- { this.showConsole && (
- <div class={styles.console} style={`height:
${this.consoleHeightType === 'up' ? '80%' : '40%'}`}>
- {
- this.tabData.panelsList?.length > 0
- && (
- <n-card content-style="padding: 0;">
- <EditorConsole onConsoleDown={this.handleConsoleDown}
onConsoleUp={this.handleConsoleUp} onConsoleClose={this.handleConsoleClose} />
- </n-card>
- )
- }
+ <n-split direction="horizontal" max={0.35} min={0.16}
resize-trigger-size={0} default-size={0.20}>
+ {{
+ '1': () => (
+ <div class={styles['menu-tree']}>
+ <MenuTree ref="menuTreeRef" />
</div>
- )}
- </n-card>
- </div>
+ ),
+ '2': () => (
+ <div class={styles['editor-area']}>
+ <n-card class={styles.card} content-style="padding: 5px
18px;display: flex;flex-direction: column;">
+ <div class={styles.tabs}>
+ <EditorTabs />
+ </div>
+ <div class={styles.debugger}>
+ <EditorDebugger tabData={this.tabData}
onHandleFormat={this.handleFormat} onHandleSave={this.editorSave} />
+ </div>
+ <n-split direction="vertical" max={0.60} min={0.00}
resize-trigger-size={0} default-size={0.6}>
+ {{
+ '1': () => (
+ <div class={styles.editor}>
+ {
+ this.tabData.panelsList?.length > 0
+ && (
+ <n-card content-style="padding: 0;">
+ <MonacoEditor
+ v-model={this.tabData.panelsList.find((item:
any) => item.key === this.tabData.chooseTab).content}
+ language={this.language}
+ onEditorMounted={this.editorMounted}
+ onEditorSave={this.editorSave}
+ onChange={this.handleContentChange}
+ />
+ </n-card>
+ )
+ }
+ </div>
+ ),
+ '2': () => (this.showConsole && (
+ <div class={styles.console}>
+ {
+ this.tabData.panelsList?.length > 0
+ && (
+ <n-card content-style="padding: 0;">
+ <EditorConsole
onConsoleDown={this.handleConsoleDown} onConsoleUp={this.handleConsoleUp}
onConsoleClose={this.handleConsoleClose} />
+ </n-card>
+ )
+ }
+ </div>
+ )
+ ),
+ 'resize-trigger': () => (
+ <div class={styles['console-splitter']} />
+ ),
+ }}
+ </n-split>
+ </n-card>
+ </div>
+ ),
+ 'resize-trigger': () => (
+ <div class={styles.split} />
+ ),
+ }}
+ </n-split>
</div>
)
},