feat: eslint

This commit is contained in:
ulleo
2025-06-12 14:54:30 +08:00
parent dbc205dcfe
commit 1611d8584e
13 changed files with 79 additions and 133 deletions
-10
View File
@@ -1,10 +0,0 @@
/node_modules/
/dist/
/public/
*.md
*.woff
*.ttf
.vscode/
.DS_Store
eslint.config.cjs
.eslintrc.js
+6
View File
@@ -0,0 +1,6 @@
{
"globals": {
"ElMessage": true,
"ElMessageBox": true
}
}
-33
View File
@@ -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',
},
],
},
}
+4 -3
View File
@@ -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,
)
+1
View File
@@ -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>
+3
View File
@@ -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')
+2 -2
View File
@@ -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>
+1 -1
View File
@@ -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>
-11
View File
@@ -341,17 +341,6 @@ const sendMessage = async () => {
}
}
//@ts-ignore
const formatMessage = (content: string) => {
if (!content) return ''
return content
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\n/g, '<br>')
.replace(/ {2}/g, '&nbsp;&nbsp;')
}
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>
+3
View File
@@ -15,6 +15,9 @@ export default defineConfig(({ mode }) => {
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
eslintrc: {
enabled: false,
},
}),
Components({
resolvers: [ElementPlusResolver()],