mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: eslint
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
/node_modules/
|
||||
/dist/
|
||||
/public/
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.vscode/
|
||||
.DS_Store
|
||||
eslint.config.cjs
|
||||
.eslintrc.js
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"globals": {
|
||||
"ElMessage": true,
|
||||
"ElMessageBox": true
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'eslint:recommended',
|
||||
'@vue/typescript/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'prettier/prettier': [
|
||||
'warn',
|
||||
{
|
||||
singleQuote: true,
|
||||
semi: false,
|
||||
trailingComma: 'es5',
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
endOfLine: 'auto',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -5,11 +5,13 @@ const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommen
|
||||
const eslintPluginVue = require('eslint-plugin-vue')
|
||||
const globals = require('globals')
|
||||
const typescriptEslint = require('typescript-eslint')
|
||||
const eslintrcImport = require('./.eslintrc-auto-import.json')
|
||||
|
||||
|
||||
module.exports = typescriptEslint.config(
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.browser,
|
||||
globals: { ...globals.browser, ...globals.node, ...eslintrcImport.globals },
|
||||
ecmaVersion: 'latest',
|
||||
parserOptions: {
|
||||
parser: typescriptEslint.parser,
|
||||
@@ -47,7 +49,6 @@ module.exports = typescriptEslint.config(
|
||||
'dist/',
|
||||
'public/',
|
||||
'eslint.config.cjs',
|
||||
'.eslintrc.js',
|
||||
'**/*.md',
|
||||
'**/*.woff',
|
||||
'**/*.ttf',
|
||||
@@ -55,5 +56,5 @@ module.exports = typescriptEslint.config(
|
||||
'**/.DS_Store',
|
||||
]),
|
||||
eslintConfigPrettier,
|
||||
eslintPluginPrettierRecommended
|
||||
eslintPluginPrettierRecommended,
|
||||
)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"snowflake-id": "^1.1.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"vue": "^3.5.13",
|
||||
"vue-dompurify-html": "^5.3.0",
|
||||
"vue-i18n": "^9.14.4",
|
||||
"vue-router": "^4.5.0",
|
||||
"web-storage-cache": "^1.1.1"
|
||||
|
||||
@@ -29,10 +29,10 @@ const svgClass = computed(() => {
|
||||
<template>
|
||||
<div
|
||||
v-if="staticContent"
|
||||
v-dompurify-html="staticContent"
|
||||
class="svg-container"
|
||||
:class="svgClass"
|
||||
aria-hidden="true"
|
||||
v-html="staticContent"
|
||||
></div>
|
||||
<slot v-else />
|
||||
</template>
|
||||
|
||||
@@ -4,6 +4,8 @@ import './style.less'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import { i18n } from './i18n'
|
||||
import VueDOMPurifyHTML from 'vue-dompurify-html'
|
||||
|
||||
// import 'element-plus/dist/index.css'
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
@@ -11,4 +13,5 @@ const pinia = createPinia()
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
app.use(i18n)
|
||||
app.use(VueDOMPurifyHTML)
|
||||
app.mount('#app')
|
||||
|
||||
@@ -215,12 +215,12 @@ function onTypeChange() {
|
||||
<div>
|
||||
<template v-if="message.record.sql_answer">
|
||||
<div>SQL Generation:</div>
|
||||
<div v-if="message.record.sql_answer" v-html="renderSqlThinking"></div>
|
||||
<div v-if="message.record.sql_answer" v-dompurify-html="renderSqlThinking"></div>
|
||||
</template>
|
||||
<template v-if="message.record.chart_answer">
|
||||
<el-divider></el-divider>
|
||||
<div>Chart Generation:</div>
|
||||
<div v-html="renderChartThinking"></div>
|
||||
<div v-dompurify-html="renderChartThinking"></div>
|
||||
</template>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
|
||||
@@ -11,7 +11,7 @@ defineProps<{
|
||||
<div class="chat-block">
|
||||
<slot>
|
||||
<div class="chat-block-content">
|
||||
<div v-html="msg?.content"></div>
|
||||
<div v-dompurify-html="msg?.content"></div>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
@@ -341,17 +341,6 @@ const sendMessage = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const formatMessage = (content: string) => {
|
||||
if (!content) return ''
|
||||
return content
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\n/g, '<br>')
|
||||
.replace(/ {2}/g, ' ')
|
||||
}
|
||||
|
||||
const handleCtrlEnter = (e: KeyboardEvent) => {
|
||||
const textarea = e.target as HTMLTextAreaElement
|
||||
const start = textarea.selectionStart
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
||||
import {treeDraggableChart} from '@/views/dashboard/utils/treeDraggableChart'
|
||||
import { treeDraggableChart } from '@/views/dashboard/utils/treeDraggableChart'
|
||||
import newFolder from '@/assets/svg/new-folder.svg'
|
||||
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
|
||||
import icon_folder from '@/assets/svg/icon_folder.svg'
|
||||
@@ -10,41 +10,41 @@ import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
|
||||
import icon_rename from '@/assets/svg/icon_rename.svg'
|
||||
import icon_delete from '@/assets/svg/icon_delete.svg'
|
||||
import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg'
|
||||
import {onMounted, reactive, ref, watch, nextTick, computed} from 'vue'
|
||||
import {ElIcon, ElScrollbar} from 'element-plus-secondary'
|
||||
import {Icon} from '@/components/icon-custom'
|
||||
import {type SQTreeNode} from '@/views/dashboard/utils/treeNode'
|
||||
import { onMounted, reactive, ref, watch, nextTick, computed } from 'vue'
|
||||
import { ElIcon, ElScrollbar } from 'element-plus-secondary'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { type SQTreeNode } from '@/views/dashboard/utils/treeNode'
|
||||
import _ from 'lodash'
|
||||
import router from '@/router'
|
||||
import {dashboardStoreWithOut} from "@/stores/dashboard/dashboard.ts";
|
||||
import ResourceGroupOpt from "@/views/dashboard/common/ResourceGroupOpt.vue";
|
||||
import {dashboardApi} from "@/api/dashboard.ts";
|
||||
import HandleMore from "@/views/dashboard/common/HandleMore.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import { dashboardStoreWithOut } from '@/stores/dashboard/dashboard.ts'
|
||||
import ResourceGroupOpt from '@/views/dashboard/common/ResourceGroupOpt.vue'
|
||||
import { dashboardApi } from '@/api/dashboard.ts'
|
||||
import HandleMore from '@/views/dashboard/common/HandleMore.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const {t} = useI18n()
|
||||
const { t } = useI18n()
|
||||
const dashboardStore = dashboardStoreWithOut()
|
||||
const resourceGroupOptRef = ref(null)
|
||||
|
||||
defineProps({
|
||||
curCanvasType: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
showPosition: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: 'preview'
|
||||
default: 'preview',
|
||||
},
|
||||
resourceTable: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: 'core'
|
||||
}
|
||||
default: 'core',
|
||||
},
|
||||
})
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
label: 'name',
|
||||
}
|
||||
const mounted = ref(false)
|
||||
const selectedNodeKey: any = ref(null)
|
||||
@@ -62,26 +62,24 @@ const state = reactive({
|
||||
{
|
||||
label: t('dashboard.rename'),
|
||||
command: 'rename',
|
||||
svgName: icon_rename
|
||||
svgName: icon_rename,
|
||||
},
|
||||
{
|
||||
label: t('dashboard.delete'),
|
||||
command: 'delete',
|
||||
svgName: icon_delete,
|
||||
divided: true
|
||||
}
|
||||
divided: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
const {handleDrop, allowDrop, handleDragStart} = treeDraggableChart(
|
||||
const { handleDrop, allowDrop, handleDragStart } = treeDraggableChart(
|
||||
state,
|
||||
'resourceTree',
|
||||
'dashboard'
|
||||
)
|
||||
|
||||
|
||||
const routerDashboardId = router.currentRoute.value.query.dashboardId
|
||||
if (routerDashboardId) {
|
||||
selectedNodeKey.value = routerDashboardId
|
||||
@@ -107,7 +105,7 @@ const filterNode = (value: string, data: SQTreeNode) => {
|
||||
}
|
||||
|
||||
const nodeClick = (data: SQTreeNode, node: any) => {
|
||||
dashboardStore.setCurComponent({component: null, index: null})
|
||||
dashboardStore.setCurComponent({ component: null, index: null })
|
||||
if (node.disabled) {
|
||||
nextTick(() => {
|
||||
const currentNode = resourceListTree.value.$el.querySelector('.is-current')
|
||||
@@ -137,14 +135,14 @@ const getTree = async () => {
|
||||
}
|
||||
// @ts-ignore
|
||||
const flattedTree = computed<SQTreeNode[]>(() => {
|
||||
return _.filter(flatTree(state.resourceTree), node => node.leaf)
|
||||
return _.filter(flatTree(state.resourceTree), (node) => node.leaf)
|
||||
})
|
||||
|
||||
const hasData = computed<boolean>(() => flattedTree.value.length > 0)
|
||||
|
||||
function flatTree(tree: SQTreeNode[]) {
|
||||
let result = _.cloneDeep(tree)
|
||||
_.forEach(tree, node => {
|
||||
_.forEach(tree, (node) => {
|
||||
if (node.children && node.children.length > 0) {
|
||||
result = _.union(result, flatTree(node.children))
|
||||
}
|
||||
@@ -172,12 +170,10 @@ const afterTreeInit = () => {
|
||||
const copyLoading = ref(false)
|
||||
const emit = defineEmits(['nodeClick'])
|
||||
|
||||
|
||||
function createNewObject() {
|
||||
}
|
||||
function createNewObject() {}
|
||||
|
||||
// @ts-ignore
|
||||
const resourceEdit = resourceId => {
|
||||
const resourceEdit = (resourceId) => {
|
||||
window.open(`#/canvas?resourceId=${resourceId}`, '_blank')
|
||||
}
|
||||
|
||||
@@ -208,13 +204,11 @@ const getDefaultExpandedKeys = () => {
|
||||
}
|
||||
}
|
||||
|
||||
watch(filterText, val => {
|
||||
watch(filterText, (val) => {
|
||||
resourceListTree.value.filter(val)
|
||||
})
|
||||
|
||||
|
||||
const loadInit = () => {
|
||||
}
|
||||
const loadInit = () => {}
|
||||
onMounted(() => {
|
||||
loadInit()
|
||||
getTree()
|
||||
@@ -240,9 +234,9 @@ const operation = (opt: string, data: SQTreeNode) => {
|
||||
type: 'warning',
|
||||
tip: msg,
|
||||
autofocus: false,
|
||||
showClose: false
|
||||
showClose: false,
|
||||
}).then(() => {
|
||||
dashboardApi.delete_resource({id: data.id}).then(() => {
|
||||
dashboardApi.delete_resource({ id: data.id }).then(() => {
|
||||
ElMessage.success(t('dashboard.delete_success'))
|
||||
getTree()
|
||||
dashboardStore.setCurComponent(null)
|
||||
@@ -250,7 +244,7 @@ const operation = (opt: string, data: SQTreeNode) => {
|
||||
})
|
||||
} else if (opt === 'rename') {
|
||||
//@ts-ignore
|
||||
resourceGroupOptRef.value?.optInit({opt: 'rename', id: data.id, name: data.name})
|
||||
resourceGroupOptRef.value?.optInit({ opt: 'rename', id: data.id, name: data.name })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,11 +252,10 @@ const baseInfoChangeFinish = () => {
|
||||
getTree()
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
hasData,
|
||||
createNewObject,
|
||||
mounted
|
||||
mounted,
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -270,16 +263,16 @@ defineExpose({
|
||||
<div class="resource-tree">
|
||||
<div class="tree-header">
|
||||
<div class="icon-methods">
|
||||
<span class="title">{{ t('dashboard.dashboard') }} </span>
|
||||
<span class="title">{{ t('dashboard.dashboard') }} </span>
|
||||
<div class="flex-align-center">
|
||||
<el-tooltip :content="t('dashboard.new_folder')" placement="top" effect="dark">
|
||||
<el-icon
|
||||
class="custom-icon btn"
|
||||
style="margin-right: 10px"
|
||||
@click="addOperation({opt:'newFolder',type:'folder',pid:'root'} )"
|
||||
@click="addOperation({ opt: 'newFolder', type: 'folder', pid: 'root' })"
|
||||
>
|
||||
<Icon name="dv-new-folder">
|
||||
<newFolder class="svg-icon"/>
|
||||
<newFolder class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
@@ -287,36 +280,29 @@ defineExpose({
|
||||
<el-icon
|
||||
class="custom-icon btn"
|
||||
style="margin-right: 10px"
|
||||
@click="addOperation({opt:'newLeaf',type:'dashboard'} )"
|
||||
@click="addOperation({ opt: 'newLeaf', type: 'dashboard' })"
|
||||
>
|
||||
<Icon name="dv-new-folder">
|
||||
<icon_fileAdd_outlined class="svg-icon"/>
|
||||
<icon_fileAdd_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<el-input
|
||||
:placeholder="t('common.search')"
|
||||
v-model="filterText"
|
||||
clearable
|
||||
class="search-bar"
|
||||
>
|
||||
<el-input v-model="filterText" :placeholder="t('common.search')" clearable class="search-bar">
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Icon name="icon_search-outline_outlined"
|
||||
>
|
||||
<icon_searchOutline_outlined class="svg-icon"
|
||||
/>
|
||||
<Icon name="icon_search-outline_outlined">
|
||||
<icon_searchOutline_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-scrollbar class="custom-tree" v-loading="copyLoading">
|
||||
<el-scrollbar v-loading="copyLoading" class="custom-tree">
|
||||
<el-tree
|
||||
menu
|
||||
ref="resourceListTree"
|
||||
menu
|
||||
:default-expanded-keys="expandedArray"
|
||||
:data="state.resourceTree"
|
||||
:props="defaultProps"
|
||||
@@ -324,46 +310,46 @@ defineExpose({
|
||||
highlight-current
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
draggable
|
||||
@node-expand="nodeExpand"
|
||||
@node-collapse="nodeCollapse"
|
||||
@node-click="nodeClick"
|
||||
@node-drag-start="handleDragStart"
|
||||
@node-drop="handleDrop"
|
||||
draggable
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<el-icon style="font-size: 18px" v-if="data.node_type !== 'leaf'">
|
||||
<Icon name="icon_folder"><icon_folder class="svg-icon"/></Icon>
|
||||
<el-icon v-if="data.node_type !== 'leaf'" style="font-size: 18px">
|
||||
<Icon name="icon_folder"><icon_folder class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
<el-icon style="font-size: 18px" v-else>
|
||||
<Icon name="icon_dashboard"><icon_dashboard class="svg-icon"/></Icon>
|
||||
<el-icon v-else style="font-size: 18px">
|
||||
<Icon name="icon_dashboard"><icon_dashboard class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
<span :title="node.label" class="label-tooltip">
|
||||
{{ node.label }}
|
||||
</span>
|
||||
<div class="icon-more">
|
||||
<el-icon
|
||||
v-on:click.stop
|
||||
v-if="data.node_type !== 'leaf'"
|
||||
class="hover-icon"
|
||||
@click="addOperation({opt:'newLeaf',type:'dashboard',id:data.id} )"
|
||||
@click.stop
|
||||
@click="addOperation({ opt: 'newLeaf', type: 'dashboard', id: data.id })"
|
||||
>
|
||||
<Icon><icon_add_outlined class="svg-icon"/></Icon>
|
||||
<Icon><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
<el-icon
|
||||
v-on:click.stop
|
||||
v-if="data.node_type === 'leaf'"
|
||||
class="hover-icon"
|
||||
@click.stop
|
||||
@click="resourceEdit(data.id)"
|
||||
>
|
||||
<Icon><icon_edit_outlined class="svg-icon"/></Icon>
|
||||
<Icon><icon_edit_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
<HandleMore
|
||||
@handle-command=" (opt:string) => operation(opt,data)"
|
||||
:menu-list="state.folderMenuList"
|
||||
:icon-name="icon_more_outlined"
|
||||
placement="bottom-start"
|
||||
@handle-command="(opt: string) => operation(opt, data)"
|
||||
></HandleMore>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
@@ -10,9 +10,9 @@ import {
|
||||
onMounted,
|
||||
} from 'vue'
|
||||
import CustomTab from '@/views/dashboard/components/sq-tab/CustomTab.vue'
|
||||
import {guid, type CanvasItem} from '@/utils/canvas.ts'
|
||||
import { guid, type CanvasItem } from '@/utils/canvas.ts'
|
||||
import DragHandle from '@/views/dashboard/canvas/DragHandle.vue'
|
||||
import {ArrowDown} from '@element-plus/icons-vue'
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import DashboardEditor from '@/views/dashboard/editor/DashboardEditor.vue'
|
||||
|
||||
const editableTabsValue = ref(null)
|
||||
@@ -48,7 +48,7 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const {configItem} = toRefs(props)
|
||||
const { configItem } = toRefs(props)
|
||||
|
||||
const state = reactive({
|
||||
activeTabName: '',
|
||||
@@ -132,7 +132,7 @@ const isEditMode = computed(() => true)
|
||||
const addTabItem = (item: CanvasItem) => {
|
||||
// do addTabItem
|
||||
const index = configItem.value.propValue.findIndex(
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
(tabItem) => configItem.value.activeTabName === tabItem.name
|
||||
)
|
||||
// @ts-ignore
|
||||
@@ -178,7 +178,7 @@ defineExpose({
|
||||
<template #label>
|
||||
<div class="custom-tab-title" @mousedown.stop>
|
||||
<span class="title-inner" :style="titleStyle(tabItem.name)"
|
||||
>{{ tabItem.title }}
|
||||
>{{ tabItem.title }}
|
||||
<span v-if="isEditMode">
|
||||
<el-dropdown
|
||||
popper-class="custom-de-tab-dropdown"
|
||||
@@ -186,7 +186,7 @@ defineExpose({
|
||||
@command="handleCommand"
|
||||
>
|
||||
<span class="el-dropdown-link">
|
||||
<el-icon v-if="isEditMode"><ArrowDown/></el-icon>
|
||||
<el-icon v-if="isEditMode"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
|
||||
@@ -15,6 +15,9 @@ export default defineConfig(({ mode }) => {
|
||||
vue(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
eslintrc: {
|
||||
enabled: false,
|
||||
},
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
|
||||
Reference in New Issue
Block a user