diff --git a/apps/cloud/vite.config.ts b/apps/cloud/vite.config.ts index 247d9a6171..523c5a827b 100644 --- a/apps/cloud/vite.config.ts +++ b/apps/cloud/vite.config.ts @@ -126,7 +126,7 @@ export default defineConfig(({ mode }) => { { name: 'removeAttributesBySelector', params: { - selector: ":not(path[fill='none'])", + selector: ":not(path[fill='none'],rect[fill='none'])", attributes: ['fill'], }, }, diff --git a/apps/daas/src/assets/icons/svg/right.svg b/apps/daas/src/assets/icons/svg/right.svg deleted file mode 100644 index 7de3a76480..0000000000 --- a/apps/daas/src/assets/icons/svg/right.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - jiantou_yemian_xiangyou - - - - - - - - \ No newline at end of file diff --git a/apps/daas/src/auto-imports.d.ts b/apps/daas/src/auto-imports.d.ts index e8c32485ff..38c618866c 100644 --- a/apps/daas/src/auto-imports.d.ts +++ b/apps/daas/src/auto-imports.d.ts @@ -5,18 +5,10 @@ // Generated by unplugin-auto-import export {} declare global { - const ElButton: typeof import('element-plus/es')['ElButton'] - const ElDrawer: typeof import('element-plus/es')['ElDrawer'] - const ElIconArrowRight: typeof import('@element-plus/icons-vue')['ArrowRight'] const ElIconCopyDocument: typeof import('@element-plus/icons-vue')['CopyDocument'] const ElIconRefresh: typeof import('@element-plus/icons-vue')['Refresh'] const ElIconSearch: typeof import('@element-plus/icons-vue')['Search'] const ElInput: typeof import('element-plus/es')['ElInput'] - const ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] const ElMessage: typeof import('element-plus/es')['ElMessage'] const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] - const ElOption: typeof import('element-plus/es')['ElOption'] - const ElSelect: typeof import('element-plus/es')['ElSelect'] - const ElTabs: typeof import('element-plus/es')['ElTabs'] - const ElTag: typeof import('element-plus/es')['ElTag'] } diff --git a/apps/daas/src/components.d.ts b/apps/daas/src/components.d.ts index 3a802bb466..4953fbfdbd 100644 --- a/apps/daas/src/components.d.ts +++ b/apps/daas/src/components.d.ts @@ -76,6 +76,7 @@ declare module 'vue' { ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] + ElText: typeof import('element-plus/es')['ElText'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTree: typeof import('element-plus/es')['ElTree'] ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] diff --git a/apps/daas/src/layouts/Header.vue b/apps/daas/src/layouts/Header.vue index d221d4dd72..acb9d57614 100644 --- a/apps/daas/src/layouts/Header.vue +++ b/apps/daas/src/layouts/Header.vue @@ -227,7 +227,8 @@ onMounted(() => { if ( import.meta.env.VUE_APP_MODE !== 'community' && - window.getSettingByKey?.('SHOW_LICENSE') + window.getSettingByKey?.('SHOW_LICENSE') && + window.getSettingByKey('checkLicense') !== 'false' ) { getLicense() } diff --git a/apps/daas/vite.config.ts b/apps/daas/vite.config.ts index 2ddb571479..acd241d2a4 100644 --- a/apps/daas/vite.config.ts +++ b/apps/daas/vite.config.ts @@ -77,7 +77,7 @@ export default defineConfig(({ mode }) => { { name: 'removeAttributesBySelector', params: { - selector: ":not(path[fill='none'])", + selector: ":not(path[fill='none'],rect[fill='none'])", attributes: ['fill'], }, }, diff --git a/package.json b/package.json index 98c68dacd4..568d445108 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "nb": "node scripts/worktree-checkout.js" }, "dependencies": { - "element-plus": "^2.9.8", + "element-plus": "^2.9.10", "lodash-es": "^4.17.21", "vue-router": "^4.0.8" }, @@ -61,7 +61,7 @@ "@formily/reactive-vue": "^2.3.0", "@formily/shared": "^2.3.0", "@formily/vue": "^2.3.0", - "element-plus": "^2.9.8", + "element-plus": "^2.9.10", "vue": "^3.4.29", "vue-virtual-scroller": "2.0.0-beta.8" }, diff --git a/packages/assets/icons/svg/Lightning.svg b/packages/assets/icons/svg/Lightning.svg new file mode 100644 index 0000000000..892d480678 --- /dev/null +++ b/packages/assets/icons/svg/Lightning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/assets/icons/svg/LucideHash.svg b/packages/assets/icons/svg/LucideHash.svg new file mode 100644 index 0000000000..232c61a257 --- /dev/null +++ b/packages/assets/icons/svg/LucideHash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/assets/icons/svg/LucideLink.svg b/packages/assets/icons/svg/LucideLink.svg new file mode 100644 index 0000000000..73ff49dcd8 --- /dev/null +++ b/packages/assets/icons/svg/LucideLink.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/assets/icons/svg/LucideTable.svg b/packages/assets/icons/svg/LucideTable.svg new file mode 100644 index 0000000000..aa4db5dee5 --- /dev/null +++ b/packages/assets/icons/svg/LucideTable.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/assets/icons/svg/Sparkles.svg b/packages/assets/icons/svg/Sparkles.svg new file mode 100644 index 0000000000..9e1415c0a1 --- /dev/null +++ b/packages/assets/icons/svg/Sparkles.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/assets/styles/element.scss b/packages/assets/styles/element.scss index f4d6011403..5f2c9c9c58 100644 --- a/packages/assets/styles/element.scss +++ b/packages/assets/styles/element.scss @@ -155,6 +155,13 @@ } // Radio +.el-radio-group.has-space { + gap: 1rem; + .el-radio-button__inner { + border-left: var(--el-border); + border-radius: var(--el-border-radius-base); + } +} .el-radio-group.button-style-outline { .el-radio-button { --el-radio-button-checked-bg-color: #fff; @@ -454,6 +461,12 @@ // Alert .el-alert { + &.fit-content { + .el-alert__content { + flex: 1; + min-width: 0; + } + } &--info.is-light { --el-alert-bg-color: var(--info-fill); --el-color-info: var(--el-text-color-title); diff --git a/packages/assets/styles/utilities.scss b/packages/assets/styles/utilities.scss index 9b690ede12..ba50da9849 100644 --- a/packages/assets/styles/utilities.scss +++ b/packages/assets/styles/utilities.scss @@ -12557,4 +12557,18 @@ .-z-10 { z-index: -10; -} \ No newline at end of file +} + +.bg-gray-50 { + background-color: rgb(249 250 251); +} + +.bg-gray-100 { + background-color: rgb(243 244 246); +} + +.bg-gray-200 { + background-color: rgb(229 231 235); +} + + diff --git a/packages/business/package.json b/packages/business/package.json index 79c08d6268..7ac83afbd7 100644 --- a/packages/business/package.json +++ b/packages/business/package.json @@ -21,6 +21,7 @@ "lodash": "^4.17.15", "qs": "^6.11.0", "tiny-emitter": "^2.1.0", + "vue": "^3.0.0", "vue-json-viewer": "^2.2.15", "vue-virtual-scroller": "2.0.0-beta.8", "vuex": "^4.0.2" diff --git a/packages/business/src/components/create-connection/SceneDialog.vue b/packages/business/src/components/create-connection/SceneDialog.vue index dd255ff3ba..330e9bbb39 100644 --- a/packages/business/src/components/create-connection/SceneDialog.vue +++ b/packages/business/src/components/create-connection/SceneDialog.vue @@ -80,7 +80,7 @@ export default { 'Clickhouse', 'Elasticsearch', 'Dummy', - 'Kafka', + 'Kafka-Enhanced', 'Doris', 'BigQuery', ], @@ -178,7 +178,9 @@ export default { 'packages_business_create_connection_elasticsearch_desc', ), Dummy: i18n.t('packages_business_create_connection_dummy_desc'), - Kafka: i18n.t('packages_business_create_connection_kafka_desc'), + 'Kafka-Enhanced': i18n.t( + 'packages_business_create_connection_kafka_desc', + ), Doris: i18n.t('packages_business_create_connection_doris_desc'), 'MongoDB Atlas': i18n.t( 'packages_business_create_connection_mongodbatlas_desc', diff --git a/packages/business/src/components/logs/NodeLog.vue b/packages/business/src/components/logs/NodeLog.vue index 9db9c40586..066eecb9db 100644 --- a/packages/business/src/components/logs/NodeLog.vue +++ b/packages/business/src/components/logs/NodeLog.vue @@ -1049,8 +1049,10 @@ Stack Trace: ${this.codeDialog.data.errorStack ? `\n${this.codeDialog.data.error }} - {{ fullscreen ? 'suoxiao' : 'fangda' }} @@ -1059,7 +1061,7 @@ Stack Trace: ${this.codeDialog.data.errorStack ? `\n${this.codeDialog.data.error ? $t('packages_form_js_editor_exit_fullscreen') : $t('packages_form_js_editor_fullscreen') }} - +
-import { inspectApi, taskApi } from '@tap/api' +import { Check } from '@element-plus/icons-vue' +import { databaseTypesApi, inspectApi, taskApi } from '@tap/api' import { AsyncSelect } from '@tap/form' import i18n from '@tap/i18n' import Time from '@tap/shared/src/time' import { ElMessage, ElMessageBox } from 'element-plus' import { cloneDeep } from 'lodash-es' -import { computed, onMounted, provide, reactive, ref } from 'vue' +import { + computed, + onMounted, + provide, + reactive, + ref, + useTemplateRef, +} from 'vue' import { useRoute, useRouter } from 'vue-router' import PageContainer from '../../components/PageContainer.vue' @@ -79,6 +87,8 @@ const defaultTime = ref([ new Date(2025, 2, 1, 23, 59, 59), ]) +const taskSelect = useTemplateRef('taskSelect') + const form = reactive({ flowId: '', name: '', @@ -202,6 +212,7 @@ const autoAddTableLoading = ref(false) const taskOptionCache = ref(null) const baseForm = ref(null) const conditionBox = ref(null) +const activePanel = ref('condition') const saveDisabled = computed(() => { return ( @@ -279,21 +290,10 @@ const getData = async (id: string) => { applyTask(data.taskDto) } - // 任务一致性/任意表 都走异步获取 capabilities/tags - const capabilitiesMap = await conditionBox.value.getCapabilities([ - ...new Set([ - ...data.tasks.map((t) => t.source.connectionId), - ...data.tasks.map((t) => t.target.connectionId), - ]), - ]) - data.tasks = data.tasks.map((t) => { t.source = Object.assign({}, TABLE_PARAMS, t.source) t.target = Object.assign({}, TABLE_PARAMS, t.target) - t.source.capabilities = - capabilitiesMap[t.source.connectionId]?.capabilities || [] - t.target.capabilities = - capabilitiesMap[t.target.connectionId]?.capabilities || [] + if (t.source.nodeId) { t.source.currentLabel = `${t.source.nodeName} / ${t.source.connectionName}` t.target.currentLabel = `${t.target.nodeName} / ${t.target.connectionName}` @@ -476,12 +476,34 @@ const save = async (saveOnly = false) => { if (webScript && webScript !== '') { script = `function validate(sourceRow){${webScript}}` } + + if ( + source.enableCustomCommand && + source.databaseType.toLowerCase().includes('mongo') + ) { + source.customCommand.params.collection = source.tableName + + if (source.customCommand.command === 'executeQuery') { + source.customCommand.params.op = 'find' + } + } + + if ( + target.enableCustomCommand && + target.databaseType.toLowerCase().includes('mongo') + ) { + target.customCommand.params.collection = target.tableName + + if (target.customCommand.command === 'executeQuery') { + target.customCommand.params.op = 'find' + } + } + const newSource = cloneDeep(source) const newTarget = cloneDeep(target) newSource.fields = [] newTarget.fields = [] - newSource.capabilities = [] - newTarget.capabilities = [] + return { taskId, source: newSource, @@ -543,487 +565,493 @@ const handleSelectTask = (task: any, byClick: boolean) => { } } +const ConnectorMap = ref({}) + +const fetchDatabaseTypes = async () => { + const databaseItems = await databaseTypesApi.get() + + ConnectorMap.value = databaseItems.reduce((map, item) => { + map[item.type] = { + pdkHash: item.pdkHash, + isNullsLast: item.tags?.includes('NullsLast'), + capabilityMap: + item.capabilities?.reduce((map, item) => { + map[item.id] = true + return map + }, {}) || {}, + } + return map + }, {}) +} + +const openTaskSelect = () => { + taskSelect.value.focus() + taskSelect.value.$el.querySelector('input').click() +} + +fetchDatabaseTypes() + provide('formData', form) +provide('ConnectorMap', ConnectorMap) + + + + + + + @@ -1105,4 +1133,45 @@ provide('formData', form) margin-top: 8px; } } + +.has-sticky { + --sticky-top: 0px; + :deep(.el-collapse-item__header) { + position: sticky; + top: var(--sticky-top); + z-index: 10; + } +} + +.el-collapse { + &.last-item-noborder { + border-bottom: none; + :deep(.el-collapse-item:last-child) { + margin-bottom: 0; + .el-collapse-item__header, + .el-collapse-item__wrap { + border-bottom: none; + } + } + } +} + +.condition-panel { + &.is-active { + :deep(.el-collapse-item__wrap) { + overflow: unset; + } + :deep(.condition-footer) { + position: sticky; + bottom: 72px; + backdrop-filter: blur(12px); + background-color: rgba(255, 255, 255, 0.8); + z-index: 10; + } + } +} + +.content-footer { + height: 72px; +} diff --git a/packages/business/src/views/verification/History.vue b/packages/business/src/views/verification/History.vue index 987d83305c..55530e5b7f 100644 --- a/packages/business/src/views/verification/History.vue +++ b/packages/business/src/views/verification/History.vue @@ -278,7 +278,7 @@ export default { {{ statusMap[scope.row.status] }} - + -
- - - {{ - $t('packages_business_components_fieldbox_quanziduan') - }} - {{ - $t('packages_business_connections_databaseform_zidingyi') - }} - - - - {{ - $t('packages_business_components_conditionbox_chakanzidingyi') - }} - ({{ item.source.columns ? item.source.columns.length : 0 }}) - -
-
- {{ $t('packages_business_verification_advanceVerify') }} - -
-
- - {{ $t('packages_business_verification_addJS') }} - - -
-
-
{{ item.webScript }}
+ +
+
+
{{ item.webScript }}
+
- - - - - - -
-
-
- function validate(sourceRow){ + + @@ -274,15 +276,15 @@ export default {
{{ $t('packages_dag_monitor_bottompanel_rizhi') }} {{ $t('public_button_close') }} { const emit = defineEmits([ 'update:modelValue', 'update:loading', - 'change-label', + 'changeLabel', 'optionSelect', ]) @@ -194,7 +194,7 @@ const handleChange = () => { const onChange = (value: any) => { nextTick(() => { - emit('change-label', selectRef.value.states.selected.currentLabel) + emit('changeLabel', selectRef.value.states.selected.currentLabel) // Find the selected object by matching itemValue with the selected value const selectedOption = isStrItem.value @@ -223,6 +223,9 @@ const onUpdateModelValue = (val) => { defineExpose({ loadDataList, + focus: () => { + selectRef.value.focus() + }, }) watch( @@ -254,7 +257,6 @@ onMounted(() => {