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 cbddfec  [Feature] Enhance job result page (#232)
cbddfec is described below

commit cbddfecd2194be3c1767ad33ef418335f21f71a7
Author: s7monk <[email protected]>
AuthorDate: Wed May 22 21:28:07 2024 +0800

    [Feature] Enhance job result page (#232)
---
 paimon-web-ui/package.json                         |   3 +-
 paimon-web-ui/src/locales/en/modules/playground.ts |   9 +-
 paimon-web-ui/src/locales/zh/modules/playground.ts |   9 +-
 .../console/components/controls/index.module.scss} |  60 ++++----
 .../console/components/controls/index.tsx          | 170 +++++++++++++++++++++
 .../console/components/table/index.module.scss}    |  38 ++---
 .../components/console/components/table/index.tsx  |  84 ++++++++++
 .../components/query/components/console/index.tsx  |  35 +++--
 .../views/playground/components/query/index.tsx    |  24 ++-
 9 files changed, 352 insertions(+), 80 deletions(-)

diff --git a/paimon-web-ui/package.json b/paimon-web-ui/package.json
index ebb6a17..c9dfb05 100644
--- a/paimon-web-ui/package.json
+++ b/paimon-web-ui/package.json
@@ -42,6 +42,7 @@
     "@vicons/antd": "^0.12.0",
     "@vicons/carbon": "^0.12.0",
     "@vicons/ionicons5": "^0.12.0",
+    "@vicons/material": "^0.12.0",
     "@vitejs/plugin-vue": "^4.3.4",
     "@vitejs/plugin-vue-jsx": "^3.0.2",
     "@vue/eslint-config-prettier": "^8.0.0",
@@ -61,4 +62,4 @@
     "vite": "^4.4.9",
     "vue-tsc": "^1.8.11"
   }
-}
\ No newline at end of file
+}
diff --git a/paimon-web-ui/src/locales/en/modules/playground.ts 
b/paimon-web-ui/src/locales/en/modules/playground.ts
index c505377..b512631 100644
--- a/paimon-web-ui/src/locales/en/modules/playground.ts
+++ b/paimon-web-ui/src/locales/en/modules/playground.ts
@@ -29,7 +29,7 @@ export default {
   run: 'Run',
   format: 'Format',
   save: 'Save',
-  clear: 'Clear',
+  close: 'Close',
   unfold: 'Unfold',
   collapse: 'Collapse',
   logs: 'Logs',
@@ -42,4 +42,11 @@ export default {
   close_others: 'Close Others',
   close_right: 'Close Right',
   close_left: 'Close Left',
+  switch_to_table: 'Switch to Table',
+  switch_to_chart: 'Switch to Chart',
+  refresh_data: 'Refresh Data',
+  stop_job: 'Stop Job',
+  schedule_refresh: 'Schedule Refresh',
+  download: 'Export Data',
+  copy: 'Copy Data',
 }
diff --git a/paimon-web-ui/src/locales/zh/modules/playground.ts 
b/paimon-web-ui/src/locales/zh/modules/playground.ts
index 7a52d1a..73d59e9 100644
--- a/paimon-web-ui/src/locales/zh/modules/playground.ts
+++ b/paimon-web-ui/src/locales/zh/modules/playground.ts
@@ -29,7 +29,7 @@ export default {
   run: '运行',
   format: '格式化',
   save: '保存',
-  clear: '清空',
+  close: '关闭',
   unfold: '展开',
   collapse: '折叠',
   logs: '日志',
@@ -42,4 +42,11 @@ export default {
   close_others: '关闭其他',
   close_right: '关闭右侧',
   close_left: '关闭左侧',
+  switch_to_table: '切换到表格',
+  switch_to_chart: '切换到图表',
+  refresh_data: '刷新数据',
+  stop_job: '停止任务',
+  schedule_refresh: '定时刷新',
+  download: '导出数据',
+  copy: '复制数据',
 }
diff --git a/paimon-web-ui/src/locales/en/modules/playground.ts 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.module.scss
similarity index 53%
copy from paimon-web-ui/src/locales/en/modules/playground.ts
copy to 
paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.module.scss
index c505377..d36d549 100644
--- a/paimon-web-ui/src/locales/en/modules/playground.ts
+++ 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.module.scss
@@ -15,31 +15,35 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License. */
 
-export default {
-  query: 'Query',
-  workbench: 'Workbench',
-  task_operation_and_maintenance: 'Task Operation and Maintenance',
-  settings: 'Settings',
-  terminal: 'Terminal',
-  git_branch: 'Git Branch',
-  data: 'Data',
-  saved_query: 'Saved Query',
-  query_record: 'Query Record',
-  search: 'Search',
-  run: 'Run',
-  format: 'Format',
-  save: 'Save',
-  clear: 'Clear',
-  unfold: 'Unfold',
-  collapse: 'Collapse',
-  logs: 'Logs',
-  result: 'Result',
-  new_folder: 'New Folder',
-  new_file: 'New File',
-  rename: 'Rename',
-  delete: 'Delete',
-  close_all: 'Close All',
-  close_others: 'Close Others',
-  close_right: 'Close Right',
-  close_left: 'Close Left',
-}
+.container {
+  $color-gray: #7D818E;
+
+  display: flex;
+  align-items: center;
+  width: 100%;
+  height: 42px;
+
+  .left {
+    display: flex;
+    padding: 10px 0 10px 20px;
+  }
+
+  .right {
+    display: flex;
+    flex: 1;
+    justify-content: flex-end;
+    padding: 10px 20px 10px 0;
+  }
+
+  .active-button {
+    color: #1a6efb;
+  }
+
+  .table-action-bar-button {
+    color: $color-gray;
+  }
+
+  .table-action-bar-text {
+    color: $color-gray;
+  }
+}
\ No newline at end of file
diff --git 
a/paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.tsx
 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.tsx
new file mode 100644
index 0000000..dfbadef
--- /dev/null
+++ 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/controls/index.tsx
@@ -0,0 +1,170 @@
+/* Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. */
+
+import styles from './index.module.scss'
+import { DataTable, Copy, Renew } from "@vicons/carbon"
+import { StopOutline } from "@vicons/ionicons5"
+import { LineChartOutlined, ClockCircleOutlined, DownloadOutlined } from 
"@vicons/antd"
+import { useConfigStore } from '@/store/config'
+
+export default defineComponent({
+  name: 'TableActionBar',
+  setup() {
+    const { t } = useLocaleHooks()
+
+    const configStore = useConfigStore();
+    const isDarkMode = computed(() => configStore.theme === 'dark');
+
+    const activeButton = ref('table');
+    const setActiveButton = (button: any) => {
+      activeButton.value = button;
+    };
+
+    return {
+      t,
+      activeButton,
+      setActiveButton,
+      isDarkMode
+    }
+  },
+  render() {
+    return (
+      <div class={styles.container}>
+       <n-space class={styles.left} item-style="display: flex; align-items: 
center;">
+         <n-popover trigger="hover" placement="bottom-start" 
show-arrow={false} style="padding: 0"
+            v-slots={{
+              trigger: () => (
+                <n-button
+                  text
+                  class={this.activeButton === 'table' ? 
styles['active-button'] : styles['table-action-bar-button']}
+                  onClick={() => this.setActiveButton('table')}
+                  v-slots={{
+                    icon: () => <n-icon component={DataTable}  
size="20"></n-icon>
+                  }}
+                >
+                </n-button>
+              )
+            }}>
+           <span>{this.t('playground.switch_to_table')}</span>
+         </n-popover>
+         <n-popover trigger="hover" placement="bottom-start" show-arrow={false}
+            v-slots={{
+              trigger: () => (
+                <n-button
+                  text
+                  class={this.activeButton === 'chart' ? 
styles['active-button'] : styles['table-action-bar-button']}
+                  onClick={() => this.setActiveButton('chart')}
+                  v-slots={{
+                    icon: () => <n-icon component={LineChartOutlined}  
size="20"></n-icon>
+                  }}
+                >
+                </n-button>
+              )
+            }}>
+           <span>{this.t('playground.switch_to_chart')}</span>
+         </n-popover>
+         <n-divider vertical style="height: 20px; margin-left: 0px; 
margin-right: 0px; border-left-width: 3px;"/>
+         <n-popover trigger="hover" placement="bottom-start" show-arrow={false}
+            v-slots={{
+              trigger: () => (
+                <n-button
+                  text
+                  class={styles['table-action-bar-button']}
+                  v-slots={{
+                    icon: () => <n-icon component={Renew}  size="20"></n-icon>
+                  }}
+                >
+                </n-button>
+              )
+            }}>
+           <span>{this.t('playground.refresh_data')}</span>
+         </n-popover>
+         <n-popover trigger="hover" placement="bottom-start" show-arrow={false}
+            v-slots={{
+              trigger: () => (
+                <n-button
+                  text
+                  class={styles['table-action-bar-button']}
+                  style="color:  #D94F4F"
+                  v-slots={{
+                    icon: () => <n-icon component={StopOutline} 
size="20"></n-icon>
+                  }}
+                >
+                </n-button>
+              )
+            }}>
+           <span>{this.t('playground.stop_job')}</span>
+         </n-popover>
+         <n-popover trigger="hover" placement="bottom-start" show-arrow={false}
+            v-slots={{
+              trigger: () => (
+                <n-button
+                  text
+                  class={styles['table-action-bar-button']}
+                  v-slots={{
+                    icon: () => <n-icon component={ClockCircleOutlined}  
size="18.5"></n-icon>
+                  }}
+                >
+                </n-button>
+              )
+            }}>
+           <span>{this.t('playground.schedule_refresh')}</span>
+         </n-popover>
+         <n-divider vertical style="height: 20px; margin-left: 0px; 
margin-right: 0px;"/>
+         <span class={styles['table-action-bar-text']}>4 Columns</span>
+       </n-space>
+        <div class={styles.right}>
+          <n-space item-style="display: flex; align-items: center;">
+            <div class={styles['table-action-bar-text']}>Job:<span 
style="color: #33994A"> Running</span></div>
+            <span class={styles['table-action-bar-text']}>Rows: 3</span>
+            <span class={styles['table-action-bar-text']}>1m:06s</span>
+            <n-popover trigger="hover" placement="bottom-start" 
show-arrow={false}
+               v-slots={{
+                 trigger: () => (
+                   <n-button
+                     text
+                     class={styles['table-action-bar-button']}
+                     v-slots={{
+                       icon: () => <n-icon component={DownloadOutlined} 
size="20"></n-icon>
+                     }}
+                   >
+                   </n-button>
+                 )
+               }}>
+              <span>{this.t('playground.download')}</span>
+            </n-popover>
+            <n-popover trigger="hover" placement="bottom-start" 
show-arrow={false}
+               v-slots={{
+                 trigger: () => (
+                   <n-button
+                     text
+                     class={styles['table-action-bar-button']}
+                     v-slots={{
+                       icon: () => <n-icon component={Copy}  
size="20"></n-icon>
+                     }}
+                   >
+                   </n-button>
+                 )
+               }}>
+              <span>{this.t('playground.copy')}</span>
+            </n-popover>
+          </n-space>
+        </div>
+      </div>
+    )
+  }
+})
\ No newline at end of file
diff --git a/paimon-web-ui/src/locales/en/modules/playground.ts 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
similarity index 53%
copy from paimon-web-ui/src/locales/en/modules/playground.ts
copy to 
paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
index c505377..8782073 100644
--- a/paimon-web-ui/src/locales/en/modules/playground.ts
+++ 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.module.scss
@@ -15,31 +15,13 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License. */
 
-export default {
-  query: 'Query',
-  workbench: 'Workbench',
-  task_operation_and_maintenance: 'Task Operation and Maintenance',
-  settings: 'Settings',
-  terminal: 'Terminal',
-  git_branch: 'Git Branch',
-  data: 'Data',
-  saved_query: 'Saved Query',
-  query_record: 'Query Record',
-  search: 'Search',
-  run: 'Run',
-  format: 'Format',
-  save: 'Save',
-  clear: 'Clear',
-  unfold: 'Unfold',
-  collapse: 'Collapse',
-  logs: 'Logs',
-  result: 'Result',
-  new_folder: 'New Folder',
-  new_file: 'New File',
-  rename: 'Rename',
-  delete: 'Delete',
-  close_all: 'Close All',
-  close_others: 'Close Others',
-  close_right: 'Close Right',
-  close_left: 'Close Left',
-}
+.container {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+
+  .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
new file mode 100644
index 0000000..21c4bc3
--- /dev/null
+++ 
b/paimon-web-ui/src/views/playground/components/query/components/console/components/table/index.tsx
@@ -0,0 +1,84 @@
+/* Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. */
+
+import styles from './index.module.scss'
+
+export default defineComponent({
+  name: 'TableResult',
+  setup() {
+    const columns = [
+      {
+        title: '#',
+        key: 'key',
+        render: (_:any, index:number) => {
+          return `${index + 1}`
+        }
+      },
+      {
+        title: 'id',
+        key: 'id',
+        resizable: true
+      },
+      {
+        title: 'name',
+        key: 'name',
+        resizable: true
+      },
+      {
+        title: 'age',
+        key: 'age',
+        resizable: true
+      },
+      {
+        title: 'address',
+        key: 'address',
+        resizable: true
+      },
+    ]
+
+    type User = {
+      id: number
+      name: string
+      age: number
+      address: string
+    }
+
+    const data: User[] = [
+      { id: 1, name: 'jack', age: 36, address: 'beijing' },
+      { id: 2, name: 'li hua', age: 38, address: 'shanghai' },
+      { id: 3, name: 'zhao ming', age: 27, address: 'hangzhou' },
+      { id: 3, name: 'zhao ming', age: 27, address: 'hangzhou' }
+    ]
+
+    return {
+      columns,
+      data,
+    }
+  },
+  render() {
+    return(
+      <div>
+        <n-data-table
+          class={styles.table}
+          columns={this.columns}
+          data={this.data}
+          max-height={138}
+        />
+      </div>
+    )
+  }
+})
\ No newline at end of file
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 47a06b4..b4e0006 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
@@ -15,12 +15,14 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License. */
 
-import { ChevronDown, ChevronUp, TrashOutline } from '@vicons/ionicons5'
+import { KeyboardDoubleArrowUpSharp, KeyboardDoubleArrowDownSharp, CloseSharp 
} from '@vicons/material'
+import TableActionBar from './components/controls'
+import TableResult from './components/table'
 import styles from './index.module.scss'
 
 export default defineComponent({
   name: 'EditorConsole',
-  emits: ['ConsoleUp', 'ConsoleDown'],
+  emits: ['ConsoleUp', 'ConsoleDown', 'ConsoleClose'],
   setup(props, { emit }) {
     const { t } = useLocaleHooks()
 
@@ -32,10 +34,15 @@ export default defineComponent({
       emit('ConsoleDown', 'down')
     }
 
+    const handleClose = () => {
+      emit('ConsoleClose', 'close')
+    }
+
     return {
       t,
       handleUp,
-      handleDown
+      handleDown,
+      handleClose
     }
   },
   render() {
@@ -46,13 +53,14 @@ export default defineComponent({
           size="large"
           default-value="logs"
           tabs-padding={20}
-          pane-style="padding: 20px;box-sizing: border-box;"
+          pane-style="padding: 0px;box-sizing: border-box;"
         >
           <n-tab-pane name="logs" tab={this.t('playground.logs')}>
             {this.t('playground.logs')}
           </n-tab-pane>
           <n-tab-pane name="result" tab={this.t('playground.result')}>
-            {this.t('playground.result')}
+            <TableActionBar/>
+            <TableResult/>
           </n-tab-pane>
         </n-tabs>
         <div class={styles.operations}>
@@ -62,44 +70,45 @@ export default defineComponent({
                 trigger: () => (
                   <n-button
                     text
+                    onClick={this.handleUp}
                     v-slots={{
-                      icon: () => <n-icon component={TrashOutline}></n-icon>
+                      icon: () => <n-icon 
component={KeyboardDoubleArrowUpSharp} size="20"></n-icon>
                     }}
                   >
                   </n-button>
                 )
               }}>
-              <span>{this.t('playground.clear')}</span>
+              <span>{this.t('playground.unfold')}</span>
             </n-popover>
             <n-popover trigger="hover" placement="bottom"
               v-slots={{
                 trigger: () => (
                   <n-button
                     text
-                    onClick={this.handleUp}
+                    onClick={this.handleDown}
                     v-slots={{
-                      icon: () => <n-icon component={ChevronUp}></n-icon>
+                      icon: () => <n-icon 
component={KeyboardDoubleArrowDownSharp} size="20"></n-icon>
                     }}
                   >
                   </n-button>
                 )
               }}>
-              <span>{this.t('playground.unfold')}</span>
+              <span>{this.t('playground.collapse')}</span>
             </n-popover>
             <n-popover trigger="hover" placement="bottom"
               v-slots={{
                 trigger: () => (
                   <n-button
                     text
-                    onClick={this.handleDown}
+                    onClick={this.handleClose}
                     v-slots={{
-                      icon: () => <n-icon component={ChevronDown}></n-icon>
+                      icon: () => <n-icon component={CloseSharp} 
size="19"></n-icon>
                     }}
                   >
                   </n-button>
                 )
               }}>
-              <span>{this.t('playground.collapse')}</span>
+              <span>{this.t('playground.close')}</span>
             </n-popover>
           </n-space>
         </div>
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 2a2ee2d..f657e78 100644
--- a/paimon-web-ui/src/views/playground/components/query/index.tsx
+++ b/paimon-web-ui/src/views/playground/components/query/index.tsx
@@ -65,6 +65,10 @@ export default defineComponent({
       consoleHeightType.value = type
     }
 
+    const showConsole = ref(true)
+    const handleConsoleClose = () => {
+      showConsole.value = false
+    }
 
     watch(
       () => consoleHeightType.value,
@@ -91,6 +95,8 @@ export default defineComponent({
       tabData,
       handleConsoleUp,
       handleConsoleDown,
+      handleConsoleClose,
+      showConsole,
       consoleHeightType
     }
   },
@@ -122,14 +128,16 @@ export default defineComponent({
                 </n-card>
               }
             </div>
-            <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} />
-                </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>
+                }
+              </div>
+            )}
           </n-card>
         </div>
       </div>

Reply via email to