Skip to content

Commit be6e111

Browse files
authored
Merge pull request #602 from tapdata/fix/TAP-12135-api
fix: enhance parameter name validation with tooltip feedback and rege…
2 parents a4eab1d + 9f4940f commit be6e111

2 files changed

Lines changed: 77 additions & 16 deletions

File tree

packages/business/src/views/data-server/Drawer.vue

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import FieldsTree from './FieldsTree.vue'
4646
import FieldsTreePreview from './FieldsTreePreview.vue'
4747
import MqlEditor from './MqlEditor.vue'
4848
49-
import { getTableOptions, useDrawer } from './shared'
49+
import { getTableOptions, PARAM_NAME_PATTERN, useDrawer } from './shared'
5050
import type { InputInstance, SelectInstance, TableInstance } from 'element-plus'
5151
5252
// Types
@@ -640,6 +640,45 @@ const tabChanged = (tab: string | number) => {
640640
641641
const handleChangeApiType = () => {
642642
form.value.params = getDefaultParams(form.value.apiType)
643+
focusedParamNameIndex.value = null
644+
hoveredParamNameIndex.value = null
645+
}
646+
647+
const focusedParamNameIndex = ref<number | null>(null)
648+
const hoveredParamNameIndex = ref<number | null>(null)
649+
650+
const getParamNameError = (index: number) => {
651+
const paramName = form.value.params?.[index]?.name || ''
652+
653+
if (!paramName.trim()) {
654+
return t('packages_business_data_server_drawer_qingshurucanshu')
655+
}
656+
657+
if (!PARAM_NAME_PATTERN.test(paramName)) {
658+
return t('packages_business_data_server_drawer_geshicuowu')
659+
}
660+
661+
return ''
662+
}
663+
664+
const isParamNameTipVisible = (index: number) => {
665+
return (
666+
!!getParamNameError(index) &&
667+
(focusedParamNameIndex.value === index ||
668+
hoveredParamNameIndex.value === index)
669+
)
670+
}
671+
672+
const hideFocusedParamNameTip = (index: number) => {
673+
if (focusedParamNameIndex.value === index) {
674+
focusedParamNameIndex.value = null
675+
}
676+
}
677+
678+
const hideHoveredParamNameTip = (index: number) => {
679+
if (hoveredParamNameIndex.value === index) {
680+
hoveredParamNameIndex.value = null
681+
}
643682
}
644683
645684
const handleChangeTable = () => {
@@ -1747,16 +1786,33 @@ provide('form', form)
17471786
min-width="80"
17481787
>
17491788
<template #default="{ row, $index }">
1750-
<div v-if="editable(row, form)">
1751-
<ElFormItem
1752-
:prop="`params.${$index}.name`"
1753-
:error="!form.params[$index].name ? 'true' : ''"
1754-
:show-message="false"
1755-
:rules="rules.param"
1756-
class="mb-0"
1789+
<div
1790+
v-if="editable(row, form)"
1791+
@mouseenter="hoveredParamNameIndex = $index"
1792+
@mouseleave="hideHoveredParamNameTip($index)"
1793+
>
1794+
<ElTooltip
1795+
:disabled="!getParamNameError($index)"
1796+
:content="getParamNameError($index)"
1797+
:hide-after="0"
1798+
transition="none"
1799+
:visible="isParamNameTipVisible($index)"
1800+
placement="top"
17571801
>
1758-
<ElInput v-model="form.params[$index].name" />
1759-
</ElFormItem>
1802+
<ElFormItem
1803+
:prop="`params.${$index}.name`"
1804+
:error="getParamNameError($index)"
1805+
:show-message="false"
1806+
:rules="rules.param"
1807+
class="mb-0"
1808+
>
1809+
<ElInput
1810+
v-model="form.params[$index].name"
1811+
@focus="focusedParamNameIndex = $index"
1812+
@blur="hideFocusedParamNameTip($index)"
1813+
/>
1814+
</ElFormItem>
1815+
</ElTooltip>
17601816
</div>
17611817
<div v-else>{{ row.name }}</div>
17621818
</template>
@@ -1800,7 +1856,7 @@ provide('form', form)
18001856
<ElTableColumn
18011857
:label="$t('packages_business_data_server_drawer_required')"
18021858
prop="required"
1803-
min-width="60"
1859+
min-width="80"
18041860
align="center"
18051861
>
18061862
<template #default="{ row, $index }">

packages/business/src/views/data-server/shared.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { uid } from '@tap/shared'
33
import { merge } from 'lodash-es'
44
import type { Ref } from 'vue'
55

6+
export const PARAM_NAME_PATTERN = /^[a-z$_\u4E00-\u9FA5][\w$\u4E00-\u9FA5]*$/i
7+
68
export const makeTree = (data: any[]) => {
79
const root: any = {
810
children: [],
@@ -91,27 +93,30 @@ export const useDrawer = (t: any, apiApplication?: Ref<any>) => {
9193
'tidb',
9294
]
9395
// Regex validation patterns
94-
const PARAM_PATTERN = /^[a-z$_\u4E00-\u9FA5][\w$\u4E00-\u9FA5]*$/i
9596
const PATH_PATTERN = /^(?!\/)[\w$/-]+$/
9697

9798
// Validation rules
98-
const validateParams = (rule: any, value: string, callback: Function) => {
99-
if (PARAM_PATTERN.test(value)) {
99+
const validateParams = (_rule: any, value: string, callback: Function) => {
100+
const paramName = value || ''
101+
102+
if (!paramName.trim()) {
103+
callback(t('packages_business_data_server_drawer_qingshurucanshu'))
104+
} else if (PARAM_NAME_PATTERN.test(paramName)) {
100105
callback()
101106
} else {
102107
callback(t('packages_business_data_server_drawer_geshicuowu'))
103108
}
104109
}
105110

106-
const validateBasePath = (rule: any, value: string, callback: Function) => {
111+
const validateBasePath = (_rule: any, value: string, callback: Function) => {
107112
if (!value || PATH_PATTERN.test(value)) {
108113
callback()
109114
} else {
110115
callback(t('packages_business_data_server_drawer_validate'))
111116
}
112117
}
113118

114-
const validatePrefix = (rule: any, value: string, callback: Function) => {
119+
const validatePrefix = (_rule: any, value: string, callback: Function) => {
115120
if (PATH_PATTERN.test(value) || value === '') {
116121
callback()
117122
} else {

0 commit comments

Comments
 (0)