Add File
This commit is contained in:
597
frontend/src/views/system/model/ModelForm.vue
Normal file
597
frontend/src/views/system/model/ModelForm.vue
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, onMounted, nextTick, computed } from 'vue'
|
||||||
|
import arrow_down from '@/assets/svg/arrow-down.svg'
|
||||||
|
import dashboard_info from '@/assets/svg/dashboard-info.svg'
|
||||||
|
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
|
||||||
|
import icon_delete from '@/assets/svg/icon_delete.svg'
|
||||||
|
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
||||||
|
import ParamsForm from './ParamsForm.vue'
|
||||||
|
import { modelTypeOptions } from '@/entity/CommonEntity.ts'
|
||||||
|
import { base_model_options, get_supplier } from '@/entity/supplier'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
activeName: string
|
||||||
|
editModel: boolean
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
activeName: '',
|
||||||
|
editModel: false,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
interface ParamsFormData {
|
||||||
|
key?: string
|
||||||
|
val?: string
|
||||||
|
name?: string
|
||||||
|
id?: string
|
||||||
|
}
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const modelForm = reactive({
|
||||||
|
id: '',
|
||||||
|
supplier: 0,
|
||||||
|
name: '',
|
||||||
|
model_type: 0,
|
||||||
|
base_model: '',
|
||||||
|
api_key: '',
|
||||||
|
api_domain: '',
|
||||||
|
config_list: [],
|
||||||
|
protocol: 1,
|
||||||
|
})
|
||||||
|
const isCreate = ref(false)
|
||||||
|
const modelRef = ref()
|
||||||
|
const paramsFormRef = ref()
|
||||||
|
const advancedSetting = ref([] as ParamsFormData[])
|
||||||
|
const paramsFormDrawer = ref(false)
|
||||||
|
const configExpand = ref(true)
|
||||||
|
let tempConfigMap = new Map<string, Array<any>>()
|
||||||
|
|
||||||
|
const modelSelected = computed(() => {
|
||||||
|
return !!modelForm.base_model
|
||||||
|
})
|
||||||
|
const currentSupplier = computed(() => {
|
||||||
|
if (!modelForm.supplier) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return get_supplier(modelForm.supplier)
|
||||||
|
})
|
||||||
|
const modelList = computed(() => {
|
||||||
|
if (!modelForm.supplier) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return base_model_options(modelForm.supplier, modelForm.model_type)
|
||||||
|
})
|
||||||
|
const handleParamsEdite = (ele?: any) => {
|
||||||
|
isCreate.value = false
|
||||||
|
paramsFormDrawer.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
paramsFormRef.value.initForm(ele)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleParamsCreate = () => {
|
||||||
|
isCreate.value = true
|
||||||
|
paramsFormDrawer.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
paramsFormRef.value.initForm()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleParamsDel = (item: any) => {
|
||||||
|
advancedSetting.value = advancedSetting.value.filter((ele) => ele.id !== item.id)
|
||||||
|
}
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const advancedSettingPagination = computed(() => {
|
||||||
|
return advancedSetting.value.slice(currentPage.value * 5 - 5, currentPage.value * 5)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleCurrentChange = (val: any) => {
|
||||||
|
currentPage.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = computed(() => ({
|
||||||
|
model_type: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: 'type',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
api_domain: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('datasource.please_enter') + t('common.empty') + t('model.api_domain_name'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
base_model: [{ required: true, message: t('model.the_basic_model_de'), trigger: 'blur' }],
|
||||||
|
name: [
|
||||||
|
{ required: true, message: t('model.the_basic_model'), trigger: 'blur' },
|
||||||
|
{
|
||||||
|
max: 100,
|
||||||
|
message: t('model.length_max_error', { msg: t('model.model_name'), max: 100 }),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
api_key: [
|
||||||
|
{
|
||||||
|
required: !currentSupplier.value?.is_private,
|
||||||
|
message: t('datasource.please_enter') + t('common.empty') + 'API Key',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
modelRef.value.clearValidate()
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
|
||||||
|
const addParams = () => {
|
||||||
|
paramsFormRef.value.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
const duplicateName = async (item: any) => {
|
||||||
|
const arr = advancedSetting.value.filter((ele: any) => ele.id !== item.id)
|
||||||
|
const names = arr.map((ele: any) => ele.name)
|
||||||
|
const keys = arr.map((ele: any) => ele.key)
|
||||||
|
if (names.includes(item.name)) {
|
||||||
|
ElMessage.error(t('embedded.duplicate_name'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys.includes(item.key)) {
|
||||||
|
ElMessage.error(t('embedded.repeating_parameters'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCreate.value) {
|
||||||
|
advancedSetting.value.push({ ...item, id: +new Date() })
|
||||||
|
beforeClose()
|
||||||
|
tempConfigMap.set(`${modelForm.supplier}-${modelForm.base_model}`, [...advancedSetting.value])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (const key in advancedSetting.value) {
|
||||||
|
const element = advancedSetting.value[key]
|
||||||
|
if (element.id === item.id) {
|
||||||
|
Object.assign(element, { ...item })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempConfigMap.set(`${modelForm.supplier}-${modelForm.base_model}`, [...advancedSetting.value])
|
||||||
|
beforeClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = (item: any) => {
|
||||||
|
duplicateName(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
const beforeClose = () => {
|
||||||
|
paramsFormRef.value.close()
|
||||||
|
paramsFormDrawer.value = false
|
||||||
|
}
|
||||||
|
const supplierChang = (supplier: any) => {
|
||||||
|
modelForm.supplier = supplier.id
|
||||||
|
const config = supplier.model_config[modelForm.model_type || 0]
|
||||||
|
modelForm.api_domain = config.api_domain
|
||||||
|
modelForm.base_model = ''
|
||||||
|
modelForm.protocol = supplier.type === 'vllm' ? 2 : 1
|
||||||
|
advancedSetting.value = []
|
||||||
|
}
|
||||||
|
let curId = +new Date()
|
||||||
|
const initForm = (item?: any) => {
|
||||||
|
modelForm.id = ''
|
||||||
|
modelRef.value.clearValidate()
|
||||||
|
tempConfigMap = new Map<string, Array<any>>()
|
||||||
|
if (item) {
|
||||||
|
Object.assign(modelForm, { ...item })
|
||||||
|
if (item?.config_list?.length) {
|
||||||
|
advancedSetting.value = item.config_list
|
||||||
|
advancedSetting.value.forEach((ele: any) => {
|
||||||
|
if (!ele.id) {
|
||||||
|
ele.id = curId
|
||||||
|
curId += 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
advancedSetting.value = []
|
||||||
|
}
|
||||||
|
tempConfigMap.set(`${modelForm.supplier}-${modelForm.base_model}`, [...advancedSetting.value])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const formatAdvancedSetting = (list: Array<any>) => {
|
||||||
|
const setting_list = [
|
||||||
|
...list.map((item) => {
|
||||||
|
return { id: ++curId, name: item.name, key: item.key, val: item.val } as any
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
advancedSetting.value = setting_list
|
||||||
|
}
|
||||||
|
const baseModelChange = (val: string) => {
|
||||||
|
if (!val || !modelForm.supplier) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const current_model = modelList.value?.find((model: any) => model.name == val)
|
||||||
|
if (current_model) {
|
||||||
|
modelForm.api_domain = current_model.api_domain || getSupplierDomain() || ''
|
||||||
|
}
|
||||||
|
const current_config_list = tempConfigMap.get(`${modelForm.supplier}-${modelForm.base_model}`)
|
||||||
|
if (current_config_list) {
|
||||||
|
formatAdvancedSetting(current_config_list)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const defaultArgs = getModelDefaultArgs()
|
||||||
|
if (defaultArgs?.size) {
|
||||||
|
const defaultArgsList = [...defaultArgs.values()]
|
||||||
|
formatAdvancedSetting(defaultArgsList)
|
||||||
|
tempConfigMap.set(`${modelForm.supplier}-${modelForm.base_model}`, [...advancedSetting.value])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getSupplierDomain = () => {
|
||||||
|
return currentSupplier.value?.model_config[modelForm.model_type || 0].api_domain
|
||||||
|
}
|
||||||
|
const getModelDefaultArgs = () => {
|
||||||
|
if (!modelForm.supplier || !modelForm.base_model) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const model_config = currentSupplier.value?.model_config[modelForm.model_type || 0]
|
||||||
|
const common_args = model_config?.common_args || []
|
||||||
|
const current_model = modelList.value?.find((model: any) => model.name == modelForm.base_model)
|
||||||
|
|
||||||
|
if (current_model?.args?.length) {
|
||||||
|
const modelArgs = current_model.args
|
||||||
|
common_args.push(...modelArgs)
|
||||||
|
}
|
||||||
|
const argMap = common_args.reduce((acc: any, item: any) => {
|
||||||
|
acc.set(item.key, { ...item, name: item.key })
|
||||||
|
return acc
|
||||||
|
}, new Map())
|
||||||
|
return argMap
|
||||||
|
}
|
||||||
|
const emits = defineEmits(['submit'])
|
||||||
|
|
||||||
|
const submitModel = () => {
|
||||||
|
modelRef.value.validate((res: any) => {
|
||||||
|
if (res) {
|
||||||
|
emits('submit', {
|
||||||
|
...modelForm,
|
||||||
|
config_list: [
|
||||||
|
...advancedSetting.value.map((item) => {
|
||||||
|
return { key: item.key, name: item.name, val: item.val }
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
initForm,
|
||||||
|
submitModel,
|
||||||
|
supplierChang,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="model-form" :class="editModel && 'is-edit_model'">
|
||||||
|
<div v-if="!editModel" class="model-name">{{ activeName }}</div>
|
||||||
|
<div class="form-content">
|
||||||
|
<el-form
|
||||||
|
ref="modelRef"
|
||||||
|
:rules="rules"
|
||||||
|
label-position="top"
|
||||||
|
:model="modelForm"
|
||||||
|
style="width: 100%"
|
||||||
|
@submit.prevent
|
||||||
|
>
|
||||||
|
<el-form-item class="custom-require flex-inline" prop="name">
|
||||||
|
<template #label
|
||||||
|
><span class="custom-require_danger">{{ t('model.model_name') }}</span>
|
||||||
|
<el-tooltip effect="dark" :content="t('model.custom_model_name')" placement="right">
|
||||||
|
<el-icon style="margin-left: 4px" size="16">
|
||||||
|
<dashboard_info></dashboard_info>
|
||||||
|
</el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<el-input
|
||||||
|
v-model="modelForm.name"
|
||||||
|
clearable
|
||||||
|
:placeholder="
|
||||||
|
$t('datasource.please_enter') + $t('common.empty') + $t('model.model_name')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="type" :label="t('model.model_type')">
|
||||||
|
<el-select v-model="modelForm.model_type" style="width: 100%" disabled>
|
||||||
|
<el-option
|
||||||
|
v-for="item in modelTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item class="custom-require" prop="base_model">
|
||||||
|
<template #label
|
||||||
|
><span class="custom-require_danger">{{ t('model.basic_model') }}</span>
|
||||||
|
<span class="enter">{{ t('model.enter_to_add') }}</span>
|
||||||
|
</template>
|
||||||
|
<el-select
|
||||||
|
v-model="modelForm['base_model']"
|
||||||
|
style="width: 100%"
|
||||||
|
filterable
|
||||||
|
allow-create
|
||||||
|
default-first-option
|
||||||
|
:reserve-keyword="false"
|
||||||
|
@change="baseModelChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in modelList"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="modelSelected" prop="api_domain" :label="t('model.api_domain_name')">
|
||||||
|
<el-input
|
||||||
|
v-model="modelForm.api_domain"
|
||||||
|
clearable
|
||||||
|
:placeholder="
|
||||||
|
$t('datasource.please_enter') + $t('common.empty') + $t('model.api_domain_name')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="modelSelected" prop="api_key" label="API Key">
|
||||||
|
<el-input
|
||||||
|
v-model="modelForm.api_key"
|
||||||
|
clearable
|
||||||
|
:placeholder="$t('datasource.please_enter') + $t('common.empty') + 'API Key'"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div
|
||||||
|
v-if="modelSelected"
|
||||||
|
class="advance-setting"
|
||||||
|
:class="configExpand && 'expand'"
|
||||||
|
@click="configExpand = !configExpand"
|
||||||
|
>
|
||||||
|
{{ t('model.advanced_settings') }}
|
||||||
|
<el-icon size="16">
|
||||||
|
<arrow_down></arrow_down>
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div v-if="modelSelected && configExpand" class="model-params">
|
||||||
|
{{ t('model.model_parameters') }}
|
||||||
|
<span class="btn" @click="handleParamsCreate">
|
||||||
|
<el-icon size="16">
|
||||||
|
<icon_add_outlined></icon_add_outlined>
|
||||||
|
</el-icon>
|
||||||
|
{{ t('model.add') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="modelSelected && configExpand"
|
||||||
|
class="params-table"
|
||||||
|
:class="!advancedSettingPagination.length && 'bottom-border'"
|
||||||
|
>
|
||||||
|
<el-table :data="advancedSettingPagination" style="width: 100%">
|
||||||
|
<el-table-column prop="key" :label="t('model.parameters')" width="280" />
|
||||||
|
<el-table-column prop="name" :label="t('model.display_name')" width="280" />
|
||||||
|
<el-table-column prop="val" show-overflow-tooltip :label="t('model.parameter_value')" />
|
||||||
|
<el-table-column
|
||||||
|
fixed="right"
|
||||||
|
width="80"
|
||||||
|
class-name="operation-column_text"
|
||||||
|
:label="$t('ds.actions')"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button text type="primary" @click="handleParamsEdite(scope.row)">
|
||||||
|
<el-icon size="16">
|
||||||
|
<icon_edit_outlined></icon_edit_outlined>
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<el-button text type="primary" @click="handleParamsDel(scope.row)">
|
||||||
|
<el-icon size="16">
|
||||||
|
<icon_delete></icon_delete>
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="modelSelected && advancedSetting.length > 5 && configExpand"
|
||||||
|
class="params-table_pagination"
|
||||||
|
>
|
||||||
|
<el-pagination
|
||||||
|
:default-page-size="5"
|
||||||
|
layout="prev, pager, next"
|
||||||
|
:total="advancedSetting.length"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-drawer
|
||||||
|
v-model="paramsFormDrawer"
|
||||||
|
:size="600"
|
||||||
|
:before-close="beforeClose"
|
||||||
|
:title="
|
||||||
|
isCreate
|
||||||
|
? $t('model.add') + $t('common.empty') + $t('model.parameters')
|
||||||
|
: $t('datasource.edit') + $t('common.empty') + $t('model.parameters')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ParamsForm ref="paramsFormRef" @submit="submit"></ParamsForm>
|
||||||
|
<template #footer>
|
||||||
|
<el-button secondary @click="beforeClose"> {{ $t('common.cancel') }} </el-button>
|
||||||
|
<el-button type="primary" @click="addParams">
|
||||||
|
{{ isCreate ? t('model.add') : t('common.save') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.model-form {
|
||||||
|
width: calc(100% - 280px);
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 56px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&.is-edit_model {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.model-name {
|
||||||
|
height: 56px;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 24px;
|
||||||
|
border-bottom: 1px solid #1f232926;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.form-content {
|
||||||
|
width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-top: 24px;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: calc(100% - 176px);
|
||||||
|
padding-bottom: 24px;
|
||||||
|
|
||||||
|
.ed-form-item--default {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&.is-error {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(
|
||||||
|
.custom-require.ed-form-item.is-required:not(.is-no-asterisk).asterisk-right
|
||||||
|
> .ed-form-item__label:after
|
||||||
|
) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.flex-inline .ed-form-item__label) {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #ff8800;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-require_danger::after {
|
||||||
|
color: var(--ed-color-danger);
|
||||||
|
content: '*';
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advance-setting {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.ed-icon {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.expand {
|
||||||
|
.ed-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-params {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 16px 0 8px 0;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
height: 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 4px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #1f23291a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ed-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.params-table {
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #dee0e3;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&.bottom-border {
|
||||||
|
border-bottom: 1px solid #dee0e3;
|
||||||
|
}
|
||||||
|
:deep(.ed-table .ed-table__cell) {
|
||||||
|
padding: 7px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ed-table .cell) {
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.params-table_pagination {
|
||||||
|
margin-top: 8px;
|
||||||
|
|
||||||
|
.ed-pagination {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ed-pager li.number:hover) {
|
||||||
|
background-color: var(--ed-color-primary-1a, #1cba901a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.operation-column_text {
|
||||||
|
.ed-button {
|
||||||
|
color: #646a73;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
.ed-button:not(.is-disabled):hover {
|
||||||
|
background: #1f23291a;
|
||||||
|
}
|
||||||
|
.ed-button + .ed-button {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user