feat(embedded): Support page embedding

This commit is contained in:
dataeaseShu
2025-08-21 17:13:30 +08:00
parent a5ab618c17
commit 64d82205b2
11 changed files with 2092 additions and 1234 deletions
+11
View File
@@ -6,3 +6,14 @@ export const saveAssistant = (data: any) => request.post('/system/assistant', da
export const getOne = (id: any) => request.get(`/system/assistant/${id}`)
export const delOne = (id: any) => request.delete(`/system/assistant/${id}`)
export const dsApi = (id: any) => request.get(`/datasource/ws/${id}`)
export const embeddedApi = {
getList: (pageNum: any, pageSize: any, params: any) =>
request.get(`/system/embedded/${pageNum}/${pageSize}`, {
params,
}),
updateEmbedded: (data: any) => request.put('/system/embedded', data),
addEmbedded: (data: any) => request.post('/system/embedded', data),
deleteEmbedded: (data: any) => request.delete('/system/embedded', data),
getOne: (id: any) => request.get(`/system/embedded/${id}`),
}
@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00022 10.0002C7.56203 10.0002 7.13323 9.96572 6.71734 9.8997L6.38535 11.1387C6.33771 11.3165 6.15493 11.4221 5.97711 11.3744L5.33315 11.2019C5.15533 11.1542 5.0498 10.9714 5.09745 10.7936L5.42255 9.58034C4.88013 9.3961 4.37096 9.15543 3.90491 8.86678L2.8454 9.92629C2.71522 10.0565 2.50417 10.0565 2.37399 9.92629L1.90259 9.45489C1.77242 9.32471 1.77242 9.11366 1.90259 8.98348L2.83565 8.05043C2.35424 7.59967 1.95209 7.08569 1.64812 6.5247C1.64492 6.51881 1.64162 6.51264 1.63823 6.50624C1.5136 6.27086 1.56023 5.97623 1.75709 5.79684C1.92051 5.64792 2.03596 5.54659 2.13639 5.44616C2.14538 5.43717 2.15521 5.42715 2.16569 5.41632C2.31108 5.26609 2.55902 5.32201 2.64417 5.51294C3.47427 7.37447 5.46211 8.6669 8.00022 8.6669C10.4321 8.6669 12.4664 7.40921 13.2829 5.68288C13.3042 5.63796 13.328 5.58139 13.3519 5.52133C13.4276 5.33113 13.6741 5.27374 13.8188 5.41849C13.9259 5.52556 14.0687 5.66833 14.2471 5.84678C14.4235 6.02319 14.4713 6.29259 14.356 6.51383C14.3279 6.56764 14.3006 6.61834 14.2774 6.65865C13.9638 7.20157 13.5572 7.69799 13.0754 8.13259L13.9263 8.98348C14.0565 9.11366 14.0565 9.32471 13.9263 9.45489L13.4549 9.92629C13.3247 10.0565 13.1136 10.0565 12.9835 9.92629L11.9888 8.93161C11.5521 9.1916 11.0792 9.41007 10.5779 9.58034L10.903 10.7936C10.9506 10.9714 10.8451 11.1542 10.6673 11.2019L10.0233 11.3744C9.84552 11.4221 9.66274 11.3165 9.61509 11.1387L9.2831 9.8997C8.86721 9.96572 8.43842 10.0002 8.00022 10.0002Z" fill="#646A73"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.8302 5.33333C10.9869 4.12434 9.58583 3.33333 8 3.33333C5.42267 3.33333 3.33333 5.42267 3.33333 8C3.33333 10.5773 5.42267 12.6667 8 12.6667C10.114 12.6667 11.8997 11.261 12.4734 9.33333L13.8513 9.33333C13.245 12.0053 10.8554 14 8 14C4.68629 14 2 11.3137 2 8C2 4.68629 4.68629 2 8 2C9.88484 2 11.5667 2.86911 12.6667 4.22844V2.33333C12.6667 2.14924 12.8159 2 13 2H13.6667C13.8508 2 14 2.14924 14 2.33333V6C14 6.36819 13.7015 6.66667 13.3333 6.66667L9.66667 6.66667C9.48257 6.66667 9.33333 6.51743 9.33333 6.33333V5.66667C9.33333 5.48257 9.48257 5.33333 9.66667 5.33333L11.8302 5.33333Z" fill="#646A73"/>
</svg>

After

Width:  |  Height:  |  Size: 718 B

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.98994 12.3335C10.1486 12.3335 12.1472 10.9604 14.0001 7.9915C12.1949 5.03321 10.2008 3.66683 7.98994 3.66683C5.77984 3.66683 3.7929 5.03259 2.00009 7.99148C3.84053 10.961 5.83206 12.3335 7.98994 12.3335ZM1.00172 8.59353C0.787049 8.22812 0.785596 7.77385 0.995302 7.40557C1.00277 7.39245 1.00993 7.37994 1.01672 7.36817C2.9521 4.01172 5.27627 2.3335 7.98923 2.3335C10.7133 2.3335 13.0518 4.02544 15.0049 7.40933C15.0107 7.41947 15.0168 7.43018 15.0232 7.44138C15.2208 7.78738 15.2193 8.2145 15.0172 8.55787C13.0127 11.9638 10.67 13.6668 7.98923 13.6668C5.31784 13.6668 2.98867 11.9757 1.00172 8.59353ZM8.00009 10.6668C6.52733 10.6668 5.33342 9.47292 5.33342 8.00016C5.33342 6.5274 6.52733 5.3335 8.00009 5.3335C9.47285 5.3335 10.6668 6.5274 10.6668 8.00016C10.6668 9.47292 9.47285 10.6668 8.00009 10.6668ZM8.00009 9.3335C8.73647 9.3335 9.33342 8.73654 9.33342 8.00016C9.33342 7.26378 8.73647 6.66683 8.00009 6.66683C7.26371 6.66683 6.66675 7.26378 6.66675 8.00016C6.66675 8.73654 7.26371 9.3335 8.00009 9.3335Z" fill="#646A73"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,12 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3082_188703)">
<path d="M7.99999 15.3337C12.0501 15.3337 15.3333 12.0504 15.3333 8.00033C15.3333 3.95024 12.0501 0.666992 7.99999 0.666992C3.9499 0.666992 0.666656 3.95024 0.666656 8.00033C0.666656 12.0504 3.9499 15.3337 7.99999 15.3337Z" fill="#FF8800"/>
<path d="M7.66668 4.66699C7.48258 4.66699 7.33334 4.81623 7.33334 5.00033V9.00033C7.33334 9.18442 7.48258 9.33366 7.66668 9.33366H8.33334C8.51744 9.33366 8.66668 9.18442 8.66668 9.00033V5.00033C8.66668 4.81623 8.51744 4.66699 8.33334 4.66699H7.66668Z" fill="white"/>
<path d="M7.66668 10.0003C7.48258 10.0003 7.33334 10.1496 7.33334 10.3337V11.0003C7.33334 11.1844 7.48258 11.3337 7.66668 11.3337H8.33334C8.51744 11.3337 8.66668 11.1844 8.66668 11.0003V10.3337C8.66668 10.1496 8.51744 10.0003 8.33334 10.0003H7.66668Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_3082_188703">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+8 -1
View File
@@ -462,6 +462,13 @@
"intelligent_data_query": "Hurry up and start intelligent data query~"
},
"embedded": {
"delete_10_apps": "Do you want to delete {msg} apps?",
"click_to_show": "Click to show",
"click_to_hide": "Click to hide",
"your_app_secret": "Are you sure you want to update your App Secret?",
"proceed_with_caution": "Resetting your existing App Secret will invalidate it. Please proceed with caution.",
"password_length": "Password length",
"edit_app": "Edit app",
"embedded_management": "Embedded management",
"embedded_assistant": "Embedded assistant",
"embedded_page": "Embedded page",
@@ -619,4 +626,4 @@
"setting_successfully": "Setting Successfully",
"customize_theme_color": "Customize theme color"
}
}
}
+8 -1
View File
@@ -462,6 +462,13 @@
"intelligent_data_query": "赶快开启智能问数吧~"
},
"embedded": {
"delete_10_apps": "是否删除 {msg} 个应用?",
"click_to_show": "点击显示",
"click_to_hide": "点击隐藏",
"your_app_secret": "确定更新 APP Secret 吗?",
"proceed_with_caution": "重置后现有的 App Secret 将会失效,请谨慎操作。",
"password_length": "密码长度",
"edit_app": "编辑应用",
"embedded_management": "嵌入式管理",
"embedded_assistant": "小助手嵌入",
"embedded_page": "页面嵌入",
@@ -619,4 +626,4 @@
"setting_successfully": "设置成功",
"customize_theme_color": "自定义主题色"
}
}
}
+2
View File
@@ -29,6 +29,8 @@
--ed-border-color: #d9dcdf !important;
--ed-border-radius-base: 6px !important;
--ed-disabled-border-color: #d9dcdf !important;
--ed-border-color-light: #dee0e3 !important;
--ed-border-color-lighter: #dee0e3 !important;
}
a {
+770
View File
@@ -0,0 +1,770 @@
<script lang="ts" setup>
import { ref, onMounted, reactive, unref, nextTick } from 'vue'
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
import { embeddedApi } from '@/api/embedded'
import info_yellow from '@/assets/embedded/info-yellow.svg'
import icon_invisible_outlined from '@/assets/embedded/icon_invisible_outlined.svg'
import icon_visible_outlined from '@/assets/embedded/icon_visible_outlined.svg'
import icon_refresh_outlined from '@/assets/embedded/icon_refresh_outlined.svg'
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
import IconOpeEdit from '@/assets/svg/icon_edit_outlined.svg'
import IconOpeDelete from '@/assets/svg/icon_delete.svg'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue'
import { useClipboard } from '@vueuse/core'
import { useI18n } from 'vue-i18n'
import { cloneDeep } from 'lodash-es'
defineProps({
btnSelect: {
type: String,
default: '',
},
})
const emits = defineEmits(['btnSelectChange'])
const { t } = useI18n()
const multipleSelectionAll = ref<any[]>([])
const keywords = ref('')
const searchLoading = ref(false)
const selectable = () => {
return true
}
onMounted(() => {
search()
})
const dialogFormVisible = ref<boolean>(false)
const multipleTableRef = ref()
const isIndeterminate = ref(true)
const checkAll = ref(false)
const fieldList = ref<any>([])
const pageInfo = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
})
const cancelDelete = () => {
handleToggleRowSelection(false)
multipleSelectionAll.value = []
checkAll.value = false
isIndeterminate.value = false
}
const deleteBatchUser = () => {
ElMessageBox.confirm(t('embedded.delete_10_apps', { msg: multipleSelectionAll.value.length }), {
confirmButtonType: 'danger',
confirmButtonText: t('dashboard.delete_success'),
cancelButtonText: t('common.cancel'),
customClass: 'confirm-no_icon',
autofocus: false,
}).then(() => {
embeddedApi.deleteEmbedded(multipleSelectionAll.value.map((ele) => ele.id)).then(() => {
ElMessage({
type: 'success',
message: t('dashboard.delete_success'),
})
multipleSelectionAll.value = []
search()
})
})
}
const deleteHandler = (row: any) => {
ElMessageBox.confirm(t('embedded.delete', { msg: row.name }), {
confirmButtonType: 'danger',
confirmButtonText: t('dashboard.delete_success'),
cancelButtonText: t('common.cancel'),
customClass: 'confirm-no_icon',
autofocus: false,
}).then(() => {
embeddedApi.deleteEmbedded([row.id]).then(() => {
multipleSelectionAll.value = multipleSelectionAll.value.filter((ele) => row.id !== ele.id)
ElMessage({
type: 'success',
message: t('dashboard.delete_success'),
})
search()
})
})
}
const handleSelectionChange = (val: any[]) => {
if (toggleRowLoading.value) return
const arr = fieldList.value.filter(selectable)
const ids = arr.map((ele: any) => ele.id)
multipleSelectionAll.value = [
...multipleSelectionAll.value.filter((ele) => !ids.includes(ele.id)),
...val,
]
isIndeterminate.value = !(val.length === 0 || val.length === arr.length)
checkAll.value = val.length === arr.length
}
const handleCheckAllChange = (val: any) => {
isIndeterminate.value = false
handleSelectionChange(val ? fieldList.value.filter(selectable) : [])
if (val) {
handleToggleRowSelection()
} else {
multipleTableRef.value.clearSelection()
}
}
const toggleRowLoading = ref(false)
const handleToggleRowSelection = (check: boolean = true) => {
toggleRowLoading.value = true
const arr = fieldList.value.filter(selectable)
let i = 0
const ids = multipleSelectionAll.value.map((ele: any) => ele.id)
for (const key in arr) {
if (ids.includes((arr[key] as any).id)) {
i += 1
multipleTableRef.value.toggleRowSelection(arr[key], check)
}
}
toggleRowLoading.value = false
checkAll.value = i === arr.length
isIndeterminate.value = !(i === 0 || i === arr.length)
}
const setButtonRef = (el: any, row: any) => {
row.buttonRef = el
}
const onClickOutside = (row: any) => {
if (row.popoverRef) {
unref(row.popoverRef).popperRef?.delayHide?.()
}
}
const setPopoverRef = (el: any, row: any) => {
row.popoverRef = el
}
const cancelRefresh = (row: any) => {
if (row.popoverRef) {
unref(row.popoverRef).hide?.()
}
}
const refresh = (row: any) => {
cancelRefresh(row)
}
const search = () => {
searchLoading.value = true
embeddedApi
.getList(pageInfo.currentPage, pageInfo.pageSize, { keyword: keywords.value })
.then((res) => {
toggleRowLoading.value = true
fieldList.value = res.items
pageInfo.total = res.total
nextTick(() => {
handleToggleRowSelection()
})
})
.finally(() => {
searchLoading.value = false
})
}
const termFormRef = ref()
const rules = {
name: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('embedded.application_name'),
},
],
domain: [
{
required: true,
message:
t('datasource.please_enter') + t('common.empty') + t('embedded.cross_domain_settings'),
},
],
}
const saveHandler = () => {
termFormRef.value.validate((res: any) => {
if (res) {
embeddedApi.addEmbedded(unref(pageForm)).then(() => {
ElMessage({
type: 'success',
message: t('common.save_success'),
})
search()
dialogFormVisible.value = false
})
}
})
}
const pwd = '**********'
const dialogTitle = ref('')
const defaultForm = {
id: null,
name: null,
domain: null,
type: 0,
configuration: null,
description: null,
}
const pageForm = ref(cloneDeep(defaultForm))
const editHandler = (row: any) => {
pageForm.value.id = null
if (row) {
pageForm.value = cloneDeep(row)
}
dialogTitle.value = row?.id ? t('embedded.edit_app') : t('embedded.create_application')
dialogFormVisible.value = true
}
const onFormClose = () => {
pageForm.value = cloneDeep(defaultForm)
dialogFormVisible.value = false
}
const handleSizeChange = (val: number) => {
pageInfo.currentPage = 1
pageInfo.pageSize = val
search()
}
const handleCurrentChange = (val: number) => {
pageInfo.currentPage = val
search()
}
const { copy } = useClipboard({ legacy: true })
const copyCode = (row: any, key: any = 'app_secret') => {
copy(row[key])
.then(function () {
ElMessage.success(t('embedded.copy_successful'))
})
.catch(function () {
ElMessage.error(t('embedded.copy_successful'))
})
}
</script>
<template>
<div v-loading="searchLoading" class="embedded-page">
<div class="tool-left">
<div class="btn-select">
<el-button
:class="[btnSelect === 'd' && 'is-active']"
text
@click="emits('btnSelectChange', 'd')"
>
{{ t('embedded.embedded_assistant') }}
</el-button>
<el-button
:class="[btnSelect === 'q' && 'is-active']"
text
@click="emits('btnSelectChange', 'q')"
>
{{ t('embedded.embedded_page') }}
</el-button>
</div>
<div>
<el-input
v-model="keywords"
style="width: 240px; margin-right: 12px"
:placeholder="$t('dashboard.search')"
clearable
@keyup.enter="search"
@blur="search"
>
<template #prefix>
<el-icon>
<icon_searchOutline_outlined />
</el-icon>
</template>
</el-input>
<el-button type="primary" @click="editHandler(null)">
<template #icon>
<icon_add_outlined></icon_add_outlined>
</template>
{{ $t('embedded.create_application') }}
</el-button>
</div>
</div>
<div
v-if="!searchLoading"
class="table-content"
:class="multipleSelectionAll.length && 'show-pagination_height'"
>
<template v-if="!keywords && !fieldList.length">
<EmptyBackground
class="datasource-yet"
:description="$t('embedded.no_application')"
img-type="noneWhite"
/>
<div style="text-align: center; margin-top: -10px">
<el-button type="primary" @click="editHandler(null)">
<template #icon>
<icon_add_outlined></icon_add_outlined>
</template>
{{ $t('embedded.create_application') }}
</el-button>
</div>
</template>
<div v-else class="preview-or-schema">
<el-table
ref="multipleTableRef"
:data="fieldList"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column :selectable="selectable" type="selection" width="55" />
<el-table-column prop="name" :label="$t('embedded.application_name')" width="280" />
<el-table-column prop="app_id" label="APP ID" width="240">
<template #default="scope">
<div class="user-status-container">
<div :title="scope.row.app_id" class="ellipsis" style="max-width: 192px">
{{ scope.row.app_id }}
</div>
<el-tooltip
:offset="12"
effect="dark"
:content="t('datasource.copy')"
placement="top"
>
<el-icon
size="16"
class="hover-icon_with_bg"
@click="copyCode(scope.row, 'app_id')"
>
<icon_copy_outlined></icon_copy_outlined>
</el-icon>
</el-tooltip>
</div>
</template>
</el-table-column>
<el-table-column prop="app_secret" label="APP Secret" width="240">
<template #default="scope">
<div class="user-status-container">
<div
:title="scope.row.showPwd ? scope.row.app_id : pwd"
class="ellipsis"
style="max-width: 133px"
>
{{ scope.row.showPwd ? scope.row.app_id : pwd }}
</div>
<el-tooltip
:offset="12"
effect="dark"
:content="t('datasource.copy')"
placement="top"
>
<el-icon class="hover-icon_with_bg" size="16" @click="copyCode(scope.row)">
<icon_copy_outlined></icon_copy_outlined>
</el-icon>
</el-tooltip>
<el-tooltip
v-if="scope.row.showPwd"
:offset="12"
effect="dark"
:content="t('embedded.click_to_hide')"
placement="top"
>
<el-icon class="hover-icon_with_bg" size="16" @click="scope.row.showPwd = false">
<icon_visible_outlined></icon_visible_outlined>
</el-icon>
</el-tooltip>
<el-tooltip
v-if="!scope.row.showPwd"
:offset="12"
effect="dark"
:content="t('embedded.click_to_show')"
placement="top"
>
<el-icon class="hover-icon_with_bg" size="16" @click="scope.row.showPwd = true">
<icon_invisible_outlined></icon_invisible_outlined>
</el-icon>
</el-tooltip>
<el-icon
:ref="
(el: any) => {
setButtonRef(el, scope.row)
}
"
v-click-outside="() => onClickOutside(scope.row)"
class="hover-icon_with_bg"
:offset="12"
size="16"
>
<icon_refresh_outlined></icon_refresh_outlined>
</el-icon>
<el-popover
:ref="
(el: any) => {
setPopoverRef(el, scope.row)
}
"
:width="280"
:offset="12"
virtual-triggering
:virtual-ref="scope.row.buttonRef"
show-arrow
popper-class="box-item_refresh"
placement="bottom"
>
<template #reference> </template>
<div class="title">
<el-icon class="hover-icon_with_bg" size="16">
<info_yellow></info_yellow>
</el-icon>
<span class="sure">{{ $t('embedded.your_app_secret') }}</span>
</div>
<div class="tips">{{ $t('embedded.proceed_with_caution') }}</div>
<div class="btns">
<el-button secondary @click="cancelRefresh(scope.row)">
{{ t('common.cancel') }}
</el-button>
<el-button type="primary" @click="refresh(scope.row)">
{{ t('common.confirm2') }}
</el-button>
</div>
</el-popover>
</div>
</template>
</el-table-column>
<el-table-column
prop="domain"
:label="$t('embedded.cross_domain_settings')"
width="204"
/>
<el-table-column fixed="right" width="80" :label="t('ds.actions')">
<template #default="scope">
<div class="field-comment">
<el-tooltip
:offset="14"
effect="dark"
:content="$t('datasource.edit')"
placement="top"
>
<el-icon class="action-btn" size="16" @click="editHandler(scope.row)">
<IconOpeEdit></IconOpeEdit>
</el-icon>
</el-tooltip>
<el-tooltip
:offset="14"
effect="dark"
:content="$t('dashboard.delete')"
placement="top"
>
<el-icon class="action-btn" size="16" @click="deleteHandler(scope.row)">
<IconOpeDelete></IconOpeDelete>
</el-icon>
</el-tooltip>
</div>
</template>
</el-table-column>
<template #empty>
<EmptyBackground
v-if="!keywords && !fieldList.length"
:description="$t('embedded.no_application')"
img-type="noneWhite"
/>
<EmptyBackground
v-if="!!keywords && !fieldList.length"
:description="$t('datasource.relevant_content_found')"
img-type="tree"
/>
</template>
</el-table>
</div>
</div>
<div v-if="fieldList.length" class="pagination-container">
<el-pagination
v-model:current-page="pageInfo.currentPage"
v-model:page-size="pageInfo.pageSize"
:page-sizes="[10, 20, 30]"
:background="true"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<div v-if="multipleSelectionAll.length" class="bottom-select">
<el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="handleCheckAllChange"
>
{{ $t('datasource.select_all') }}
</el-checkbox>
<button class="danger-button" @click="deleteBatchUser">{{ $t('workspace.remove') }}</button>
<span class="selected">{{
$t('user.selected_2_items', { msg: multipleSelectionAll.length })
}}</span>
<el-button text @click="cancelDelete">
{{ $t('common.cancel') }}
</el-button>
</div>
</div>
<el-drawer
v-model="dialogFormVisible"
:title="dialogTitle"
destroy-on-close
size="600px"
:before-close="onFormClose"
>
<el-form
ref="termFormRef"
:model="pageForm"
label-width="180px"
label-position="top"
:rules="rules"
class="form-content_error"
@submit.prevent
>
<el-form-item prop="name" :label="t('embedded.application_name')">
<el-input
v-model="pageForm.name"
:placeholder="
$t('datasource.please_enter') + $t('common.empty') + $t('embedded.application_name')
"
autocomplete="off"
maxlength="50"
clearable
/>
</el-form-item>
<el-form-item prop="domain" :label="t('embedded.cross_domain_settings')">
<el-input
v-model="pageForm.domain"
:placeholder="
$t('datasource.please_enter') +
$t('common.empty') +
$t('embedded.cross_domain_settings')
"
autocomplete="off"
maxlength="50"
clearable
/>
</el-form-item>
<el-form-item prop="email" :label="$t('embedded.password_length')">
<el-input
v-model="pageForm.email"
:placeholder="
$t('datasource.please_enter') + $t('common.empty') + $t('embedded.password_length')
"
autocomplete="off"
clearable
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button secondary @click="onFormClose">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="saveHandler">
{{ $t('common.save') }}
</el-button>
</div>
</template>
</el-drawer>
</template>
<style lang="less" scoped>
.embedded-page {
height: 100%;
position: relative;
.datasource-yet {
padding-bottom: 0;
height: auto;
padding-top: 200px;
}
.tool-left {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
.btn-select {
height: 32px;
padding-left: 4px;
padding-right: 4px;
display: inline-flex;
background: #ffffff;
align-items: center;
border: 1px solid #d9dcdf;
border-radius: 6px;
.is-active {
background: var(--ed-color-primary-1a, #1cba901a);
}
.ed-button:not(.is-active) {
color: #1f2329;
}
.ed-button.is-text {
height: 24px;
width: auto;
padding: 0 8px;
line-height: 24px;
}
.ed-button + .ed-button {
margin-left: 4px;
}
}
}
.pagination-container {
display: flex;
justify-content: end;
align-items: center;
margin-top: 16px;
}
.table-content {
max-height: calc(100% - 104px);
overflow-y: auto;
&.show-pagination_height {
max-height: calc(100% - 165px);
}
.preview-or-schema {
.ed-icon {
color: #646a73;
}
.user-status-container {
display: flex;
align-items: center;
font-weight: 400;
font-size: 14px;
line-height: 22px;
height: 24px;
.ed-icon {
margin-left: 8px;
}
}
.field-comment {
height: 24px;
.ed-icon {
position: relative;
cursor: pointer;
margin-top: 4px;
margin-right: 10px;
&::after {
content: '';
background-color: #1f23291a;
position: absolute;
border-radius: 6px;
width: 24px;
height: 24px;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
display: none;
}
&:not(.not-allow):hover {
&::after {
display: block;
}
}
&.not-allow {
cursor: not-allowed;
}
}
}
.preview-num {
margin: 12px 0;
font-weight: 400;
font-size: 14px;
line-height: 22px;
color: #646a73;
}
}
}
.bottom-select {
position: absolute;
height: 64px;
width: calc(100% + 48px);
left: -24px;
bottom: -16px;
border-top: 1px solid #1f232926;
display: flex;
background-color: #fff;
align-items: center;
padding-left: 24px;
background-color: #fff;
z-index: 10;
.danger-button {
border: 1px solid var(--ed-color-danger);
color: var(--ed-color-danger);
border-radius: var(--ed-border-radius-base);
min-width: 80px;
height: 32px;
line-height: 32px;
text-align: center;
cursor: pointer;
margin: 0 16px;
background-color: transparent;
}
.selected {
font-weight: 400;
font-size: 14px;
line-height: 22px;
color: #646a73;
margin-right: 12px;
}
}
}
</style>
<style lang="less">
.box-item_refresh {
--ed-popover-padding: 20px 24px;
.ed-popper__arrow {
background: transparent !important;
&::before {
background: #fff;
}
}
.title {
display: flex;
align-items: center;
.sure {
margin-left: 8px;
font-weight: 500;
font-size: 14px;
}
}
.tips {
font-weight: 400;
font-size: 14px;
line-height: 22px;
margin: 4px 0 16px 0;
padding-left: 24px;
}
.btns {
text-align: right;
.ed-button {
min-width: 48px;
}
}
}
</style>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff