<template>
<plugin-setting v-if="isOpen" title="设置数据源" class="data-source-form">
<template #header>
<button-group>
<tiny-button class="field-save" type="primary" @click="save">保存</tiny-button>
<div class="field-handler" @click="deleteDataSource" v-if="editable" tips="删除">
<svg-button name="delete"></svg-button>
</div>
</button-group>
<svg-button class="close-plugin-setting-icon" name="close" @click="closeAllPanel"></svg-button>
</template>
<template #content>
<tiny-form label-width="0">
<data-source-type v-model="state.dataSource.data.type" :editable="editable"></data-source-type>
<data-source-name v-model="state.dataSource.name"></data-source-name>
<data-source-field
v-model="state.dataSource.data.columns"
:editable="editable"
@openRemotePanel="openRemotePanel"
></data-source-field>
</tiny-form>
</template>
</plugin-setting>
</template>
<script lang="jsx">
import { reactive, ref, watch } from 'vue'
import { Form, Button } from '@opentiny/vue'
import { ButtonGroup, PluginSetting, SvgButton } from '@opentiny/tiny-engine-common'
import DataSourceType from './DataSourceType.vue'
import DataSourceName, { getDataSourceName } from './DataSourceName.vue'
import DataSourceField from './DataSourceField.vue'
import { close as closeRemotePanel, open as openRemotePanel } from './DataSourceRemotePanel.vue'
import {
requestUpdateDataSource,
requestAddDataSource,
fetchTemplateDetail,
requestDeleteDataSource,
requestGenerateDataSource
} from './js/http'
import { useModal, useDataSource, useNotify, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
import { extend } from '@opentiny/vue-renderless/common/object'
let isOpen = ref(false)
export const open = () => {
isOpen.value = true
}
export const close = () => {
isOpen.value = false
}
export default {
components: {
ButtonGroup,
SvgButton,
TinyForm: Form,
TinyButton: Button,
PluginSetting,
DataSourceType,
DataSourceName,
DataSourceField
},
props: {
modelValue: {
type: Object,
default: () => ({})
},
editable: {
type: Boolean,
default: true
}
},
emits: ['update:modelValue', 'save'],
setup(props, { emit }) {
const { message } = useModal()
const { dataSourceState } = useDataSource()
const state = reactive({
dataSource: {}
})
watch(
() => state.dataSource.name,
(value) => {
dataSourceState.dataSourceColumn.name = value
}
)
watch(
() => state.dataSource.data?.columns,
(value) => {
if (!value || !state.dataSource.id) {
return
}
dataSourceState.dataSourceColumn.columns = value?.map(({ name, title, type, format }) => ({
name,
title,
type,
format
}))
},
{ deep: true }
)
watch(
() => props.modelValue,
(value) => {
state.dataSource = value || {}
const {
id,
name,
data: { columns, type }
} = value
if (!id) {
return
}
const filterColumns = (columns || []).map(({ name, title, type, format }) => ({
name,
title,
type,
format
}))
dataSourceState.dataSourceColumn = { name, type: type || 'array', columns: filterColumns }
dataSourceState.dataSourceColumnCopies = extend(true, {}, dataSourceState.dataSourceColumn)
}
)
const closeAllPanel = () => {
close()
closeRemotePanel()
}
const getAppId = () => getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id
const deleteDataSource = () => {
const execDelete = () =>
requestDeleteDataSource(state.dataSource.id)
.then((data) => {
if (data) {
requestGenerateDataSource(getAppId())
useNotify({
title: '数据源删除成功',
type: 'success'
})
close()
emit('save')
}
})
.catch((error) => {
message({ message: `数据源删除失败,${error?.message || ''}`, status: 'error' })
})
useModal().confirm({
message: '确认删除此条数据源配置吗?',
exec: execDelete
})
}
const save = () => {
getDataSourceName().validate((valid) => {
if (valid) {
close()
closeRemotePanel()
const columns = state.dataSource.data.columns.map(({ name, title, type, format, field }) => {
return {
name,
title,
field,
type,
format
}
})
if (props.editable) {
requestUpdateDataSource(state.dataSource.id, {
name: state.dataSource.name,
data: Object.assign(state.dataSource.data, { columns, ...dataSourceState.remoteConfig })
}).then(() => {
requestGenerateDataSource(getAppId())
useNotify({
title: '数据源修改成功',
type: 'success'
})
emit('save')
dataSourceState.dataSourceColumn = {}
dataSourceState.dataSourceColumnCopies = {}
})
} else {
requestAddDataSource({
name: state.dataSource.name,
app: getAppId(),
data: {
columns,
data: [],
type: state.dataSource.data.type ? state.dataSource.data.type : 'array',
...dataSourceState.remoteConfig
}
})
.then(() => {
requestGenerateDataSource(getAppId())
useNotify({
title: '数据源新增成功',
type: 'success'
})
emit('save')
dataSourceState.dataSourceColumn = {}
dataSourceState.dataSourceColumnCopies = {}
})
.catch((error) => {
message({ message: `数据源保存失败:${error?.message || ''}`, status: 'error' })
})
}
}
})
}
const selectDataSourceTemplate = (templateId) => {
fetchTemplateDetail(templateId).then((res) => {
if (res && res.length > 0) {
state.dataSource.data.columns = (res[0].data.columns || []).map(({ title, field, name, type }) => ({
title,
name,
field,
type,
format: {}
}))
}
})
}
return {
state,
isOpen,
save,
closeAllPanel,
openRemotePanel,
selectDataSourceTemplate,
deleteDataSource
}
}
}
</script>
<style lang="less" scoped>
.data-source-form {
.button-group {
column-gap: 6px;
.tiny-button {
width: 40px;
padding: 0;
min-width: 40px;
}
}
.close-plugin-setting-icon {
margin-left: 4px;
}
}
.datasource-form-footer {
padding: 12px;
.tiny-svg {
margin-right: 6px;
}
.del:hover {
background-color: var(--ti-lowcode-datasource-delete-button-hover-bg);
}
}
</style>