diff --git a/paimon-web-ui-new/src/locales/en/modules/playground.ts b/paimon-web-ui-new/src/locales/en/modules/playground.ts
index 7cb35ed0d..9babf1786 100644
--- a/paimon-web-ui-new/src/locales/en/modules/playground.ts
+++ b/paimon-web-ui-new/src/locales/en/modules/playground.ts
@@ -16,12 +16,12 @@ specific language governing permissions and limitations
under the License. */
export default {
- database_query: 'Database Query',
+ query: 'Query',
workbench: 'Workbench',
task_operation_and_maintenance: 'Task Operation and Maintenance',
settings: 'Settings',
terminal: 'Terminal',
- branch: 'Branch',
+ git_branch: 'Git Branch',
data: 'Data',
saved_query: 'Saved Query',
query_record: 'Query Record',
@@ -31,7 +31,7 @@ export default {
save: 'Save',
clear: 'Clear',
unfold: 'Unfold',
- pack_up: 'Pack Up',
+ collapse: 'Collapse',
logs: 'Logs',
result: 'Result',
}
diff --git a/paimon-web-ui-new/src/locales/zh/modules/playground.ts b/paimon-web-ui-new/src/locales/zh/modules/playground.ts
index 2b413b345..2787b5b2e 100644
--- a/paimon-web-ui-new/src/locales/zh/modules/playground.ts
+++ b/paimon-web-ui-new/src/locales/zh/modules/playground.ts
@@ -16,12 +16,12 @@ specific language governing permissions and limitations
under the License. */
export default {
- database_query: '数据库查询',
+ query: '查询',
workbench: '工作台',
task_operation_and_maintenance: '任务运维',
settings: '设置',
terminal: '终端',
- branch: '分支',
+ git_branch: 'Git 分支',
data: '数据',
saved_query: '已保存查询',
query_record: '查询记录',
@@ -31,7 +31,7 @@ export default {
save: '保存',
clear: '清空',
unfold: '展开',
- pack_up: '收起',
+ collapse: '折叠',
logs: '日志',
result: '结果',
}
diff --git a/paimon-web-ui-new/src/router/modules/playground.ts b/paimon-web-ui-new/src/router/modules/playground.ts
index 42967263c..ab92430bd 100644
--- a/paimon-web-ui-new/src/router/modules/playground.ts
+++ b/paimon-web-ui-new/src/router/modules/playground.ts
@@ -33,9 +33,15 @@ export default [
{
path: '/playground/database',
name: 'playground-database',
- meta: { title: '数据库查询' },
+ meta: { title: '查询' },
component: () => import('@/views/playground/components/database')
},
+ {
+ path: '/playground/workbench',
+ name: 'playground-workbench',
+ meta: { title: '工作台' },
+ component: () => import('@/views/playground/components/workbench')
+ },
]
},
]
diff --git a/paimon-web-ui-new/src/views/playground/components/database/components/console/index.tsx b/paimon-web-ui-new/src/views/playground/components/database/components/console/index.tsx
index a97cebbb2..4ecf92a78 100644
--- a/paimon-web-ui-new/src/views/playground/components/database/components/console/index.tsx
+++ b/paimon-web-ui-new/src/views/playground/components/database/components/console/index.tsx
@@ -99,7 +99,7 @@ export default defineComponent({
)
}}>
- {this.t('playground.pack_up')}
+ {this.t('playground.collapse')}
diff --git a/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.module.scss b/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.module.scss
index 328552d57..536333ae0 100644
--- a/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.module.scss
+++ b/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.module.scss
@@ -25,5 +25,9 @@ under the License. */
.search {
display: flex;
}
+
+ .icon {
+ display: flex;
+ }
}
}
diff --git a/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.tsx b/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.tsx
index b29ef6660..552a78baa 100644
--- a/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.tsx
+++ b/paimon-web-ui-new/src/views/playground/components/database/components/menu-tree/index.tsx
@@ -15,7 +15,7 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
-import { FileTrayFullOutline, Search, ServerOutline } from '@vicons/ionicons5';
+import { CodeSlash, FileTrayFullOutline, Search, ServerOutline } from '@vicons/ionicons5';
import styles from './index.module.scss'
import { NIcon, type TreeOption } from 'naive-ui';
@@ -119,6 +119,48 @@ export default defineComponent({
tabData.value = data
})
+ const savedQueryList = ref([
+ {
+ key: 1,
+ label: 'test1',
+ prefix: () =>
+ h(NIcon, {color: '#0066FF'}, {
+ default: () => h(CodeSlash)
+ }),
+ content: ''
+ },
+ {
+ key: 2,
+ label: 'test2',
+ prefix: () =>
+ h(NIcon, {color: '#0066FF'}, {
+ default: () => h(CodeSlash)
+ }),
+ content: ''
+ }
+ ]) as any
+
+ const recordList = ref([
+ {
+ key: 3,
+ label: 'test3',
+ prefix: () =>
+ h(NIcon, {color: '#0066FF'}, {
+ default: () => h(CodeSlash)
+ }),
+ content: ''
+ },
+ {
+ key: 4,
+ label: 'test4',
+ prefix: () =>
+ h(NIcon, {color: '#0066FF'}, {
+ default: () => h(CodeSlash)
+ }),
+ content: ''
+ }
+ ]) as any
+
onMounted(() => {
mittBus.emit('initTreeData', treeVariables)
})
@@ -127,7 +169,9 @@ export default defineComponent({
t,
...toRefs(treeVariables),
nodeProps,
- handleTreeSelect
+ handleTreeSelect,
+ savedQueryList,
+ recordList
}
},
render() {
@@ -156,10 +200,44 @@ export default defineComponent({
- Look forward to
+
+
+ }}
+ >
+
+
+
- Look forward to
+
+
+ }}
+ >
+
+
+
diff --git a/paimon-web-ui-new/src/views/playground/components/database/index.tsx b/paimon-web-ui-new/src/views/playground/components/database/index.tsx
index 436a0a61e..66a56a919 100644
--- a/paimon-web-ui-new/src/views/playground/components/database/index.tsx
+++ b/paimon-web-ui-new/src/views/playground/components/database/index.tsx
@@ -123,9 +123,12 @@ export default defineComponent({
}
-
-
-
+ {
+ this.tabData.panelsList?.length > 0 &&
+
+
+
+ }
diff --git a/paimon-web-ui-new/src/views/playground/components/slider/index.tsx b/paimon-web-ui-new/src/views/playground/components/slider/index.tsx
index 6f755abd0..92cb4b3b7 100644
--- a/paimon-web-ui-new/src/views/playground/components/slider/index.tsx
+++ b/paimon-web-ui-new/src/views/playground/components/slider/index.tsx
@@ -25,6 +25,7 @@ export default defineComponent({
setup() {
const configStore = useConfigStore()
const { t } = useLocaleHooks()
+ const router = useRouter()
const renderIcon = (icon: any) => {
return () => h(NIcon, { size: 24 }, { default: () => h(icon) })
@@ -35,14 +36,16 @@ export default defineComponent({
{
icon: renderIcon(Layers),
title: 'Layers',
- description: computed(() => (t('playground.database_query'))),
- isClick: true
+ description: computed(() => (t('playground.query'))),
+ isClick: true,
+ path: '/playground/database'
},
{
icon: renderIcon(CodeSlashSharp),
title: 'Code',
description: computed(() => (t('playground.workbench'))),
- isClick: false
+ isClick: false,
+ path: '/playground/workbench'
},
],
domainList: [
@@ -59,7 +62,7 @@ export default defineComponent({
{
icon: renderIcon(GitBranch),
title: 'GitBranch',
- description: computed(() => (t('playground.branch'))),
+ description: computed(() => (t('playground.git_branch'))),
}
],
})
@@ -70,6 +73,7 @@ export default defineComponent({
sliderVariables.workspaceList[i].isClick = false
}
sliderVariables.workspaceList[index].isClick = true
+ router.push(sliderVariables.workspaceList[index].path)
}
}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.module.scss b/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.module.scss
new file mode 100644
index 000000000..626d6f8b2
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.module.scss
@@ -0,0 +1,29 @@
+/* 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. */
+
+
+.editor-console {
+ width: 100%;
+ height: 100%;
+ position: relative;
+
+ .operations {
+ position: absolute;
+ top: 17px;
+ right: 20px;
+ }
+}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.tsx b/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.tsx
new file mode 100644
index 000000000..4ecf92a78
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/console/index.tsx
@@ -0,0 +1,109 @@
+/* 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 { ChevronDown, ChevronUp, TrashOutline } from '@vicons/ionicons5'
+import styles from './index.module.scss'
+
+export default defineComponent({
+ name: 'EditorConsole',
+ emits: ['ConsoleUp', 'ConsoleDown'],
+ setup(props, { emit }) {
+ const { t } = useLocaleHooks()
+
+ const handleUp = () => {
+ emit('ConsoleUp', 'up')
+ }
+
+ const handleDown = () => {
+ emit('ConsoleDown', 'down')
+ }
+
+ return {
+ t,
+ handleUp,
+ handleDown
+ }
+ },
+ render() {
+ return (
+
+
+
+ {this.t('playground.logs')}
+
+
+ {this.t('playground.result')}
+
+
+
+
+ (
+
+ }}
+ >
+
+ )
+ }}>
+ {this.t('playground.clear')}
+
+ (
+
+ }}
+ >
+
+ )
+ }}>
+ {this.t('playground.unfold')}
+
+ (
+
+ }}
+ >
+
+ )
+ }}>
+ {this.t('playground.collapse')}
+
+
+
+
+ )
+ }
+})
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.module.scss b/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.module.scss
new file mode 100644
index 000000000..0ab88421f
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.module.scss
@@ -0,0 +1,34 @@
+/* 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. */
+
+
+.container {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+
+ .run {
+ display: flex;
+ }
+
+ .operations {
+ display: flex;
+ flex: 1;
+ justify-content: flex-end;
+ }
+}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.tsx b/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.tsx
new file mode 100644
index 000000000..044317272
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/debugger/index.tsx
@@ -0,0 +1,139 @@
+/* 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 { Play, ChevronDown, ReaderOutline, Save } from '@vicons/ionicons5';
+import styles from './index.module.scss'
+
+export default defineComponent({
+ name: 'EditorDebugger',
+ emits: ['handleFormat', 'handleSave'],
+ setup(props, { emit }) {
+ const { t } = useLocaleHooks()
+
+ const debuggerVariables = reactive({
+ operatingConditionOptions: [
+ {
+ label: 'Limit 100 items',
+ key: "100"
+ },
+ {
+ label: 'Limit 1000 items',
+ key: "1000"
+ },
+ ],
+ conditionValue: 'Flink',
+ bigDataOptions: [
+ {
+ label: 'Flink',
+ value: "Flink"
+ },
+ {
+ label: 'Spark',
+ value: "Spark"
+ },
+ ],
+ conditionValue2: 'test1',
+ clusterOptions: [
+ {
+ label: 'test1',
+ value: "test1"
+ },
+ {
+ label: 'test2',
+ value: "test2"
+ },
+ ]
+ })
+
+ const handleSelect = (key: string) => {
+ console.log(key)
+ }
+
+ const handleFormat = () => {
+ emit('handleFormat')
+ }
+
+ const handleSave = () => {
+ emit('handleSave')
+ }
+
+ return {
+ t,
+ ...toRefs(debuggerVariables),
+ handleSelect,
+ handleFormat,
+ handleSave
+ }
+ },
+ render() {
+ return (
+
+
+ ,
+ default: () => {
+ return
+ {this.t('playground.run')}
+
+
+
+
+
+ }
+ }}
+ >
+
+
+
+
+
+ (
+
+ }}
+ >
+
+ )
+ }}>
+ {this.t('playground.format')}
+
+ (
+
+ }}
+ >
+
+ )
+ }}>
+ {this.t('playground.save')}
+
+
+
+
+ );
+ }
+});
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.module.scss b/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.module.scss
new file mode 100644
index 000000000..536333ae0
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.module.scss
@@ -0,0 +1,33 @@
+/* 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. */
+
+.container {
+ width: 100%;
+ height: 100%;
+
+ .card {
+ height: 100%;
+
+ .search {
+ display: flex;
+ }
+
+ .icon {
+ display: flex;
+ }
+ }
+}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.tsx b/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.tsx
new file mode 100644
index 000000000..0cbc3688a
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/menu-tree/index.tsx
@@ -0,0 +1,159 @@
+/* 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 { CodeSlash, FileTrayFullOutline, Search, ServerOutline } from '@vicons/ionicons5';
+import styles from './index.module.scss'
+import { NIcon, type TreeOption } from 'naive-ui';
+
+export default defineComponent({
+ name: 'MenuTree',
+ setup() {
+ const { t } = useLocaleHooks()
+
+ const treeVariables = reactive({
+ treeData: [
+ {
+ key: 'paimon2',
+ label: 'paimon2',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(ServerOutline)
+ }),
+ children: [
+ {
+ key: 'user',
+ label: 'user',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(ServerOutline)
+ }),
+ children: [
+ {
+ label: 'user_table',
+ key: '1',
+ content: 'select * from abc where abc.a="abc";select * from cba where cba.a="cba";',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(FileTrayFullOutline)
+ })
+ },
+ {
+ label: 'people_table',
+ key: '2',
+ content: 'select * from abc where abc.a="abc";',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(FileTrayFullOutline)
+ })
+ }
+ ]
+ },
+ {
+ key: 'role',
+ label: 'role',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(ServerOutline)
+ }),
+ children: [
+ {
+ label: 'user_table',
+ key: '3',
+ content: 'select * from kkk;',
+ prefix: () =>
+ h(NIcon, null, {
+ default: () => h(FileTrayFullOutline)
+ })
+ },
+ ]
+ }
+ ]
+ }
+ ],
+ filterValue: '',
+ selectedKeys: []
+ })
+
+ const nodeProps = ({ option }: { option: TreeOption }) => {
+ return {
+ onClick () {
+ if (option.children) return
+ if (tabData.value.panelsList?.some((item: any) => item.key === option.key)) {
+ tabData.value.chooseTab = option.key
+ return
+ }
+ tabData.value.panelsList.push({
+ tableName: option.label,
+ key: option.key,
+ isSaved: false,
+ content: option.content
+ })
+ tabData.value.chooseTab = option.key
+ },
+ }
+ }
+
+ const handleTreeSelect = (value: never[], option: { children: any; }[]) => {
+ if (option[0]?.children) return
+ treeVariables.selectedKeys = value
+ }
+
+ // mitt - handle tab choose
+ const tabData = ref({}) as any
+ const { mittBus } = getCurrentInstance()!.appContext.config.globalProperties
+ mittBus.on('initTabData', (data: any) => {
+ tabData.value = data
+ })
+
+ onMounted(() => {
+ mittBus.emit('initTreeData', treeVariables)
+ })
+
+ return {
+ t,
+ ...toRefs(treeVariables),
+ nodeProps,
+ handleTreeSelect
+ }
+ },
+ render() {
+ return (
+
+
+
+
+ }}
+ >
+
+
+
+
+
+ );
+ }
+});
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.module.scss b/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.module.scss
new file mode 100644
index 000000000..9b67bd79a
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.module.scss
@@ -0,0 +1,35 @@
+/* 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. */
+
+
+.tabs {
+ display: flex;
+ align-items: center;
+
+ .dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: #33994A;
+ margin-right: 8px;
+ }
+
+ .asterisk {
+ color: #C82E2E;
+ padding-left: 10px;
+ }
+}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.tsx b/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.tsx
new file mode 100644
index 000000000..706953cf7
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/components/tabs/index.tsx
@@ -0,0 +1,109 @@
+/* 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: 'EditorTabs',
+ setup() {
+ const { mittBus } = getCurrentInstance()!.appContext.config.globalProperties
+
+ const tabVariables = reactive({
+ chooseTab: '',
+ panelsList: [] as any,
+ })
+
+ const handleAdd = () => {
+ tabVariables.panelsList.push({
+ tableName: 'test' + (tabVariables.panelsList.length + 1),
+ key: 'test' + (tabVariables.panelsList.length + 1),
+ isSaved: false,
+ content: ''
+ })
+ tabVariables.chooseTab = 'test' + tabVariables.panelsList.length
+ }
+
+ const handleClose = (key: any) => {
+ const index = tabVariables.panelsList.findIndex((item: any) => item.key === key)
+ tabVariables.panelsList.splice(index, 1)
+ if (key === tabVariables.chooseTab) {
+ if (tabVariables.panelsList[index - 1]) {
+ tabVariables.chooseTab = tabVariables.panelsList[index - 1].key
+ } else {
+ tabVariables.chooseTab = tabVariables.panelsList[index]?.key || ''
+ }
+ }
+ }
+
+ // mitt - handle tree choose
+ const treeData = ref({}) as any
+ const changeTreeChoose = (value: string) => {
+ treeData.value.selectedKeys = [value]
+ tabVariables.chooseTab = value
+ }
+ mittBus.on('initTreeData', (data: any) => {
+ treeData.value = data
+ })
+
+ onMounted(() => {
+ mittBus.emit('initTabData', tabVariables)
+ })
+
+ return {
+ ...toRefs(tabVariables),
+ handleAdd,
+ handleClose,
+ changeTreeChoose
+ }
+ },
+ render() {
+ return (
+
+
'',
+ suffix: () => ''
+ }}
+ >
+ {
+ this.panelsList.map((item: any) => (
+ (
+
+
+
{item.tableName}
+ {!item.isSaved &&
*
}
+
+ )
+ }}
+ >
+ ))
+ }
+
+
+ );
+ }
+});
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/index.module.scss b/paimon-web-ui-new/src/views/playground/components/workbench/index.module.scss
new file mode 100644
index 000000000..d77f10b4a
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/index.module.scss
@@ -0,0 +1,59 @@
+/* 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. */
+
+.workbench {
+ display: flex;
+ width: 100%;
+ height: 100%;
+
+ .menu-tree {
+ width: 20%;
+ height: 100%;
+ }
+
+ .editor-area {
+ width: 80%;
+ height: 100%;
+
+ :global {
+ .n-card {
+ height: 100%;
+ }
+ }
+
+ .tabs {
+ display: flex;
+ height: 41px;
+ width: 100%;
+ }
+
+ .debugger {
+ display: flex;
+ height: 64px;
+ }
+
+ .editor {
+ height: 60%;
+ overflow-y: scroll;
+ }
+
+ .console {
+ height: 40%;
+ overflow-y: scroll;
+ }
+ }
+}
diff --git a/paimon-web-ui-new/src/views/playground/components/workbench/index.tsx b/paimon-web-ui-new/src/views/playground/components/workbench/index.tsx
new file mode 100644
index 000000000..602436970
--- /dev/null
+++ b/paimon-web-ui-new/src/views/playground/components/workbench/index.tsx
@@ -0,0 +1,138 @@
+/* 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 MenuTree from './components/menu-tree';
+import EditorTabs from './components/tabs';
+import EditorDebugger from './components/debugger';
+import * as monaco from 'monaco-editor'
+import MonacoEditor from '@/components/monaco-editor';
+import EditorConsole from './components/console';
+import { format } from 'sql-formatter';
+import { useMessage } from 'naive-ui'
+
+export default defineComponent({
+ name: 'WorkbenchPage',
+ setup() {
+ const message = useMessage()
+
+ const editorVariables = reactive({
+ editor: {} as any,
+ language: 'sql'
+ })
+
+ const editorMounted = (editor: monaco.editor.IStandaloneCodeEditor) => {
+ editorVariables.editor = editor
+ }
+
+ const handleFormat = () => {
+ toRaw(editorVariables.editor).setValue(format(toRaw(editorVariables.editor).getValue()))
+ }
+
+ const editorSave = () => {
+ message.success('Save success')
+ tabData.value.panelsList.find((item: any) => item.key === tabData.value.chooseTab).content = toRaw(editorVariables.editor).getValue()
+ handleFormat()
+ tabData.value.panelsList.find((item: any) => item.key === tabData.value.chooseTab).isSaved = true
+ }
+
+ const handleContentChange = (value: string) => {
+ tabData.value.panelsList.find((item: any) => item.key === tabData.value.chooseTab).content = value
+ tabData.value.panelsList.find((item: any) => item.key === tabData.value.chooseTab).isSaved = false
+ }
+
+ const consoleHeightType = ref('down')
+
+ const handleConsoleUp = (type: string) => {
+ consoleHeightType.value = type
+ }
+
+ const handleConsoleDown = (type: string) => {
+ consoleHeightType.value = type
+ }
+
+
+ watch(
+ () => consoleHeightType.value,
+ () => {
+ if (tabData.value.panelsList?.length > 0) {
+ editorVariables.editor?.layout()
+ }
+ }
+ )
+
+ // mitt - handle tab choose
+ const tabData = ref({}) as any
+ const { mittBus } = getCurrentInstance()!.appContext.config.globalProperties
+ mittBus.on('initTabData', (data: any) => {
+ tabData.value = data
+ })
+
+ return {
+ ...toRefs(editorVariables),
+ editorMounted,
+ editorSave,
+ handleContentChange,
+ handleFormat,
+ tabData,
+ handleConsoleUp,
+ handleConsoleDown,
+ consoleHeightType
+ }
+ },
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {
+ this.tabData.panelsList?.length > 0 &&
+
+ item.key === this.tabData.chooseTab).content}
+ language={this.language}
+ onEditorMounted={this.editorMounted}
+ onEditorSave={this.editorSave}
+ onChange={this.handleContentChange}
+ />
+
+ }
+
+
+ {
+ this.tabData.panelsList?.length > 0 &&
+
+
+
+ }
+
+
+
+
+ );
+ }
+});