Skip to content

Commit

Permalink
[KYUUBI #5517] [UI] Initial implement the SQL Lab page
Browse files Browse the repository at this point in the history
### _Why are the changes needed?_

1. New SQL Lab Page
2. New core editor functionality
<img width="1674" alt="image" src="https://github.com/apache/kyuubi/assets/15062456/00cc9194-f43b-422f-a3dd-7b4456d9eb5b">

### _How was this patch tested?_
- [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [x] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/contributing/code/testing.html#running-tests) locally before make a pull request

### _Was this patch authored or co-authored using generative AI tooling?_

No.

Closes #5517 from labbomb/dev.

Closes #5517

7b9f6dc [labbomb] fix: adjust keyword case
edd71d2 [labbomb] fix: delete some language configs
45d999b [labbomb] fix: update license-binary
70edf9f [labbomb] fix: fix some errors
becb4e3 [labbomb] fix: fix some errors
d47e7f5 [labbomb] feat: add editor component

Authored-by: labbomb <[email protected]>
Signed-off-by: Cheng Pan <[email protected]>
  • Loading branch information
labbomb authored and pan3793 committed Oct 25, 2023
1 parent ab4dfa3 commit 2b20f7b
Show file tree
Hide file tree
Showing 11 changed files with 474 additions and 6 deletions.
22 changes: 22 additions & 0 deletions LICENSE-binary
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,16 @@ is auto-generated by `pnpm licenses list --prod`.
├────────────────────────────────────┼──────────────┤
│ typescript │ Apache-2.0 │
├────────────────────────────────────┼──────────────┤
│ moo │ BSD-3-Clause │
├────────────────────────────────────┼──────────────┤
│ normalize-wheel-es │ BSD-3-Clause │
├────────────────────────────────────┼──────────────┤
│ source-map │ BSD-3-Clause │
├────────────────────────────────────┼──────────────┤
│ source-map-js │ BSD-3-Clause │
├────────────────────────────────────┼──────────────┤
│ railroad-diagrams │ CC0-1.0 │
├────────────────────────────────────┼──────────────┤
│ picocolors │ ISC │
├────────────────────────────────────┼──────────────┤
│ @babel/helper-string-parser │ MIT │
Expand Down Expand Up @@ -452,6 +456,8 @@ is auto-generated by `pnpm licenses list --prod`.
├────────────────────────────────────┼──────────────┤
│ combined-stream │ MIT │
├────────────────────────────────────┼──────────────┤
│ commander │ MIT │
├────────────────────────────────────┼──────────────┤
│ csstype │ MIT │
├────────────────────────────────────┼──────────────┤
│ date-fns │ MIT │
Expand All @@ -460,6 +466,8 @@ is auto-generated by `pnpm licenses list --prod`.
├────────────────────────────────────┼──────────────┤
│ delayed-stream │ MIT │
├────────────────────────────────────┼──────────────┤
│ discontinuous-range │ MIT │
├────────────────────────────────────┼──────────────┤
│ element-plus │ MIT │
├────────────────────────────────────┼──────────────┤
│ escape-html │ MIT │
Expand All @@ -470,6 +478,8 @@ is auto-generated by `pnpm licenses list --prod`.
├────────────────────────────────────┼──────────────┤
│ form-data │ MIT │
├────────────────────────────────────┼──────────────┤
│ get-stdin │ MIT │
├────────────────────────────────────┼──────────────┤
│ lodash │ MIT │
├────────────────────────────────────┼──────────────┤
│ lodash-es │ MIT │
Expand All @@ -484,16 +494,26 @@ is auto-generated by `pnpm licenses list --prod`.
├────────────────────────────────────┼──────────────┤
│ mime-types │ MIT │
├────────────────────────────────────┼──────────────┤
│ monaco-editor │ MIT │
├────────────────────────────────────┼──────────────┤
│ nanoid │ MIT │
├────────────────────────────────────┼──────────────┤
│ nearley │ MIT │
├────────────────────────────────────┼──────────────┤
│ pinia │ MIT │
├────────────────────────────────────┼──────────────┤
│ pinia-plugin-persistedstate │ MIT │
├────────────────────────────────────┼──────────────┤
│ postcss │ MIT │
├────────────────────────────────────┼──────────────┤
│ randexp │ MIT │
├────────────────────────────────────┼──────────────┤
│ ret │ MIT │
├────────────────────────────────────┼──────────────┤
│ sourcemap-codec │ MIT │
├────────────────────────────────────┼──────────────┤
│ sql-formatter │ MIT │
├────────────────────────────────────┼──────────────┤
│ to-fast-properties │ MIT │
├────────────────────────────────────┼──────────────┤
│ vue │ MIT │
Expand All @@ -503,4 +523,6 @@ is auto-generated by `pnpm licenses list --prod`.
│ vue-i18n │ MIT │
├────────────────────────────────────┼──────────────┤
│ vue-router │ MIT │
├────────────────────────────────────┼──────────────┤
│ argparse │ Python-2.0 │
└────────────────────────────────────┴──────────────┘
2 changes: 2 additions & 0 deletions kyuubi-server/web-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
"axios": "^0.27.2",
"date-fns": "^2.29.3",
"element-plus": "^2.2.12",
"monaco-editor": "^0.44.0",
"pinia": "^2.0.18",
"pinia-plugin-persistedstate": "^2.1.1",
"sql-formatter": "^13.0.1",
"swagger-ui-dist": "^4.9.1",
"vue": "^3.2.37",
"vue-i18n": "^9.2.2",
Expand Down
72 changes: 67 additions & 5 deletions kyuubi-server/web-ui/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 149 additions & 0 deletions kyuubi-server/web-ui/src/components/monaco-editor/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<!--
* 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.
-->

<template>
<div ref="codeEditBox" style="height: 100%" />
</template>

<script lang="ts" setup>
import * as monaco from 'monaco-editor'
import { format } from 'sql-formatter'
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import { editorProps } from './type'
import { useEditorStore } from '@/pinia/editor'
import { ref, toRaw, watch, onBeforeUnmount, onMounted } from 'vue'

// @ts-ignore: worker
self.MonacoEnvironment = {
getWorker() {
return new EditorWorker()
}
}

const props = defineProps(editorProps)
const emit = defineEmits([
'update:modelValue',
'change',
'editorMounted',
'editorSave'
])

const editorStore = useEditorStore()
const monacoEditorThemeRef = ref(
editorStore.getCurrentTheme === 'dark' ? 'vs-dark' : 'vs'
)
let editor: monaco.editor.IStandaloneCodeEditor
const codeEditBox = ref()
const init = () => {
monaco.languages.registerCompletionItemProvider('sql', {
provideCompletionItems: function (model: any, position: any) {
const word = model.getWordUntilPosition(position)
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
}
const suggestions = []
const keywords = [
'SELECT',
'FROM',
'WHERE',
'AND',
'OR',
'LIMIT',
'ORDER BY',
'GROUP BY'
]
for (const i in keywords) {
suggestions.push({
label: keywords[i],
kind: monaco.languages.CompletionItemKind['Function'],
insertText: keywords[i],
detail: '',
range: range
})
}
return {
suggestions: suggestions
}
}
})

editor = monaco.editor.create(codeEditBox.value, {
value: props.modelValue,
language: props.language,
theme: monacoEditorThemeRef.value,
...props.options
})

editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
emit('editorSave')
})

editor.setValue(format(toRaw(editor).getValue()))

editor.onDidChangeModelContent(() => {
const value = editor.getValue()
emit('update:modelValue', value)
emit('change', value)
})
emit('editorMounted', editor)
}
watch(
() => props.modelValue,
(newValue) => {
if (editor) {
const value = editor.getValue()
if (newValue !== value) {
editor.setValue(newValue)
editor.setValue(format(toRaw(editor).getValue()))
}
}
}
)
watch(
() => props.options,
(newValue) => {
editor.updateOptions(newValue)
},
{ deep: true }
)
watch(
() => props.language,
(newValue) => {
monaco.editor.setModelLanguage(editor.getModel()!, newValue)
}
)
watch(
() => editorStore.getCurrentTheme,
() => {
editor?.dispose()
monacoEditorThemeRef.value =
editorStore.getCurrentTheme === 'dark' ? 'vs-dark' : 'vs'
init()
}
)

onBeforeUnmount(() => {
editor.dispose()
})
onMounted(() => {
init()
})
</script>
Loading

0 comments on commit 2b20f7b

Please sign in to comment.