mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-03 04:27:56 +08:00
[Core] [Refactor] [UI] [Source] Add delete
This commit is contained in:
parent
ea8a5e8b34
commit
6a92f24e51
@ -78,6 +78,7 @@ export default {
|
|||||||
test: 'Test',
|
test: 'Test',
|
||||||
field: 'Field',
|
field: 'Field',
|
||||||
upload: 'Upload',
|
upload: 'Upload',
|
||||||
|
deleteData: 'Delete Data',
|
||||||
tip: {
|
tip: {
|
||||||
pageNotNetwork: 'Oops! Unable to connect to the network, please check if the network is normal!'
|
pageNotNetwork: 'Oops! Unable to connect to the network, please check if the network is normal!'
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,13 @@ export default {
|
|||||||
ssl: 'SSL',
|
ssl: 'SSL',
|
||||||
file: 'File',
|
file: 'File',
|
||||||
create: 'Create Source',
|
create: 'Create Source',
|
||||||
|
delete: 'Delete Source [ $NAME ]'
|
||||||
},
|
},
|
||||||
tip: {
|
tip: {
|
||||||
selectSource: 'Please select a source'
|
selectSource: 'Please select a source',
|
||||||
|
deleteSuccess: 'Delete source [ $NAME ] success',
|
||||||
|
deleteAlert1: 'You are deleting a data source. This action permanently deletes all data and configurations associated with that data source. Please be sure to confirm your actions before proceeding.',
|
||||||
|
deleteAlert2: 'Warning: Doing this will not be undone. All data and configurations associated with that data source will be permanently deleted.',
|
||||||
|
deleteAlert3: 'To confirm, type [ $NAME ] in the box below'
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -78,6 +78,7 @@ export default {
|
|||||||
test: '测试',
|
test: '测试',
|
||||||
field: '属性',
|
field: '属性',
|
||||||
upload: '上传',
|
upload: '上传',
|
||||||
|
deleteData: '删除数据',
|
||||||
tip: {
|
tip: {
|
||||||
pageNotNetwork: '哎呀!无法连接到网络,请检查网络是否正常!'
|
pageNotNetwork: '哎呀!无法连接到网络,请检查网络是否正常!'
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,14 @@ export default {
|
|||||||
database: '数据库',
|
database: '数据库',
|
||||||
ssl: 'SSL',
|
ssl: 'SSL',
|
||||||
file: '文件',
|
file: '文件',
|
||||||
create: '创建数据源'
|
create: '创建数据源',
|
||||||
|
delete: '删除数据源 [ $NAME ]'
|
||||||
},
|
},
|
||||||
tip: {
|
tip: {
|
||||||
selectSource: '请选择数据源'
|
selectSource: '请选择数据源',
|
||||||
|
deleteSuccess: '删除数据源 [ $NAME ] 成功',
|
||||||
|
deleteAlert1: '您正在删除数据源。此操作将永久删除所有与该数据源相关的数据和配置。请务必在继续操作之前确认您的操作。',
|
||||||
|
deleteAlert2: '警告:执行此操作将不可逆。所有与该数据源相关的数据和配置都会被永久删除。',
|
||||||
|
deleteAlert3: '要确认,请在下面的框中键入 [ $NAME ]'
|
||||||
}
|
}
|
||||||
}
|
}
|
108
core/datacap-ui/src/views/pages/admin/source/SourceDelete.vue
Normal file
108
core/datacap-ui/src/views/pages/admin/source/SourceDelete.vue
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :is-visible="visible" :title="title as string" :width="'40%'">
|
||||||
|
<div class="pl-3 pr-3 space-y-2">
|
||||||
|
<Alert type="error">
|
||||||
|
<template #description>{{ $t('source.tip.deleteAlert1') }}</template>
|
||||||
|
</Alert>
|
||||||
|
<Alert type="error">
|
||||||
|
<template #description>{{ $t('source.tip.deleteAlert2') }}</template>
|
||||||
|
</Alert>
|
||||||
|
<Alert type="info">
|
||||||
|
<template #description>{{ $t('source.tip.deleteAlert3').replace('$NAME', info?.name as string) }}</template>
|
||||||
|
</Alert>
|
||||||
|
<Input v-model="inputValue"/>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="space-x-5">
|
||||||
|
<Button variant="outline" size="sm" @click="handlerCancel">
|
||||||
|
{{ $t('common.cancel') }}
|
||||||
|
</Button>
|
||||||
|
<Button size="sm" variant="destructive" :loading="loading" :disabled="loading || inputValue !== info?.name" @click="handlerSubmit()">
|
||||||
|
{{ title }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import Dialog from '@/views/ui/dialog'
|
||||||
|
import { SourceModel } from '@/model/source'
|
||||||
|
import SourceService from '@/services/source'
|
||||||
|
import { ToastUtils } from '@/utils/toast'
|
||||||
|
import Button from '@/views/ui/button'
|
||||||
|
import Alert from '@/views/ui/alert'
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'SourceDelete',
|
||||||
|
components: {
|
||||||
|
Input,
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
Dialog
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get(): boolean
|
||||||
|
{
|
||||||
|
return this.isVisible
|
||||||
|
},
|
||||||
|
set(value: boolean)
|
||||||
|
{
|
||||||
|
this.$emit('close', value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isVisible: {
|
||||||
|
type: Boolean
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
type: Object as () => SourceModel | null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
title: null as string | null,
|
||||||
|
loading: false,
|
||||||
|
inputValue: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created()
|
||||||
|
{
|
||||||
|
this.handlerInitialize()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handlerInitialize()
|
||||||
|
{
|
||||||
|
if (this.info) {
|
||||||
|
this.title = `${ this.$t('source.common.delete').replace('$NAME', this.info.name as string) }`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlerSubmit()
|
||||||
|
{
|
||||||
|
if (this.info) {
|
||||||
|
this.loading = true
|
||||||
|
SourceService.deleteById(this.info.id as number)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status) {
|
||||||
|
ToastUtils.success(this.$t('source.tip.deleteSuccess').replace('$NAME', this.info?.name as string))
|
||||||
|
this.handlerCancel()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ToastUtils.error(response.message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => this.loading = false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlerCancel()
|
||||||
|
{
|
||||||
|
this.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
@ -29,23 +29,39 @@
|
|||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<div class="space-x-2">
|
<div class="space-x-2">
|
||||||
<Tooltip :content="$t('source.common.modify').replace('$NAME', row.name)">
|
<Tooltip :content="$t('source.common.modify').replace('$NAME', row.name)">
|
||||||
<Button :disabled="loginUserId !== row.user.id" size="icon" class="rounded-full w-8 h-8" @click="handlerInfo(true, row)">
|
<Button :disabled="loginUserId !== row.user.id" size="icon" class="rounded-full w-6 h-6" @click="handlerInfo(true, row)">
|
||||||
<Pencil :size="15"/>
|
<Pencil :size="14"/>
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<Button size="icon" class="rounded-full w-6 h-6" variant="outline">
|
||||||
|
<Cog class="w-full justify-center" :size="14"/>
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent>
|
||||||
|
<DropdownMenuGroup>
|
||||||
|
<DropdownMenuItem :disabled="loginUserId !== row.user.id" class="cursor-pointer" @click="handlerDelete(true, row)">
|
||||||
|
<Trash class="mr-2 h-4 w-4"/>
|
||||||
|
<span>{{ $t('common.deleteData') }}</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuGroup>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</TableCommon>
|
</TableCommon>
|
||||||
</Card>
|
</Card>
|
||||||
<SourceInfo v-if="dataInfoVisible" :is-visible="dataInfoVisible" :info="dataInfo" @close="handlerInfo(false, null)"/>
|
<SourceInfo v-if="dataInfoVisible" :is-visible="dataInfoVisible" :info="dataInfo" @close="handlerInfo(false, null)"/>
|
||||||
|
<SourceDelete v-if="dataDeleteVisible" :is-visible="dataDeleteVisible" :info="dataInfo" @close="handlerDelete(false, null)"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import Card from '@/views/ui/card'
|
import Card from '@/views/ui/card'
|
||||||
import { Button } from '@/components/ui/button'
|
import Button from '@/views/ui/button'
|
||||||
import { CirclePlay, CircleX, Pencil, Plus } from 'lucide-vue-next'
|
import { CirclePlay, CircleX, Cog, Pencil, Plus, Trash } from 'lucide-vue-next'
|
||||||
import TableCommon from '@/views/components/table/TableCommon.vue'
|
import TableCommon from '@/views/components/table/TableCommon.vue'
|
||||||
import { FilterModel } from '@/model/filter'
|
import { FilterModel } from '@/model/filter'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
@ -59,20 +75,31 @@ import Tag from '@/views/ui/tag'
|
|||||||
import { Switch } from '@/components/ui/switch'
|
import { Switch } from '@/components/ui/switch'
|
||||||
import Common from '@/utils/common'
|
import Common from '@/utils/common'
|
||||||
import SourceInfo from '@/views/pages/admin/source/SourceInfo.vue'
|
import SourceInfo from '@/views/pages/admin/source/SourceInfo.vue'
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from '@/components/ui/dropdown-menu'
|
||||||
|
import SourceDelete from '@/views/pages/admin/source/SourceDelete.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SourceHome',
|
name: 'SourceHome',
|
||||||
components: {
|
components: {
|
||||||
|
SourceDelete,
|
||||||
|
DropdownMenuItem, DropdownMenuGroup, DropdownMenuSeparator, DropdownMenuLabel, DropdownMenuContent, DropdownMenuTrigger, DropdownMenu,
|
||||||
SourceInfo,
|
SourceInfo,
|
||||||
Tag,
|
Tag,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Switch,
|
Switch,
|
||||||
Avatar,
|
Avatar,
|
||||||
TableCommon,
|
TableCommon,
|
||||||
Pencil, CircleX, CirclePlay,
|
Pencil, CircleX, CirclePlay, Cog, Trash, Plus,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card
|
||||||
Plus
|
|
||||||
},
|
},
|
||||||
setup()
|
setup()
|
||||||
{
|
{
|
||||||
@ -93,7 +120,8 @@ export default defineComponent({
|
|||||||
data: [],
|
data: [],
|
||||||
pagination: {} as PaginationModel,
|
pagination: {} as PaginationModel,
|
||||||
dataInfoVisible: false,
|
dataInfoVisible: false,
|
||||||
dataInfo: null as SourceModel | null
|
dataInfo: null as SourceModel | null,
|
||||||
|
dataDeleteVisible: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created()
|
created()
|
||||||
@ -126,6 +154,14 @@ export default defineComponent({
|
|||||||
if (!opened) {
|
if (!opened) {
|
||||||
this.handlerInitialize()
|
this.handlerInitialize()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handlerDelete(opened: boolean, value: null | SourceModel)
|
||||||
|
{
|
||||||
|
this.dataDeleteVisible = opened
|
||||||
|
this.dataInfo = value
|
||||||
|
if (!opened) {
|
||||||
|
this.handlerInitialize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
50
core/datacap-ui/src/views/ui/alert/alert.vue
Normal file
50
core/datacap-ui/src/views/ui/alert/alert.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<Alert :class="typeClass">
|
||||||
|
<AlertTitle v-if="title">{{ title }}</AlertTitle>
|
||||||
|
<AlertDescription>
|
||||||
|
<span v-if="description">{{ description }}</span>
|
||||||
|
<slot v-else name="description"/>
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||||
|
import '@/views/ui/alert/style.css'
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
success = 'alert-success',
|
||||||
|
error = 'alert-error',
|
||||||
|
info = 'alert-info',
|
||||||
|
warning = 'alert-warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'DcAlert',
|
||||||
|
components: {
|
||||||
|
Alert, AlertDescription, AlertTitle
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'info'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
typeClass()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
[(Type as any)[this.type]]: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
3
core/datacap-ui/src/views/ui/alert/index.ts
Normal file
3
core/datacap-ui/src/views/ui/alert/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Alert from '@/views/ui/alert/alert.vue'
|
||||||
|
|
||||||
|
export default Alert
|
1
core/datacap-ui/src/views/ui/alert/style.css
Normal file
1
core/datacap-ui/src/views/ui/alert/style.css
Normal file
@ -0,0 +1 @@
|
|||||||
|
.alert-error{border:1px solid #ffb08f;background-color:#ffefe6}.alert-success{border:1px solid #a6e1a6;background-color:#e6ffe6}.alert-warning{border:1px solid #ffe599;background-color:#ffffe6}.alert-info{border:1px solid #bde5f8;background-color:#e6f2ff}
|
@ -1,354 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<Modal v-model="visible" :title="title" :footer="null" width="70%" :closable="false" :mask-closable="false">
|
|
||||||
<Row :gutter="16">
|
|
||||||
<Col :span="4"/>
|
|
||||||
<Col :span="5">
|
|
||||||
<Card :bordered="false" dis-hover>
|
|
||||||
<div style="text-align:center">
|
|
||||||
<Avatar :size="40"
|
|
||||||
:src="formState?.type ? '/static/images/plugin/' + formState?.type.split('_')[0].replace(' Community', '') + '.png' : ''" icon="ios-person"/>
|
|
||||||
<p>{{ !formState['type'] ? '_' : formState['type'] }}</p>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
<Col :span="6">
|
|
||||||
<Card :bordered="false" dis-hover>
|
|
||||||
<div style="text-align:center">
|
|
||||||
<Progress :percent="testInfo.percent"
|
|
||||||
:status="(testInfo.connected && testInfo.successful) ? 'success' : 'wrong'">
|
|
||||||
</Progress>
|
|
||||||
{{ formState.version }}
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
<Col :span="5">
|
|
||||||
<Card :bordered="false" dis-hover>
|
|
||||||
<div style="text-align:center">
|
|
||||||
<Avatar :size="40" :style="{'background-color': !testInfo.percent ? '#CCC' : testInfo.connected ? '#52c41a' : '#ff4d4f'}" icon="ios-cube"/>
|
|
||||||
<p>{{ $t('common.source') }}</p>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
<Col :span="3"/>
|
|
||||||
</Row>
|
|
||||||
<Form :model="formState" :label-width="80">
|
|
||||||
<Tabs v-model="activeKey" :animated="false" @update:modelValue="handlerFilterConfigure($event)">
|
|
||||||
<TabPane :label="$t('common.' + type)" v-for="type in pluginTabs" :name="type" v-bind:key="type" :disabled="!formState.type" icon="md-apps">
|
|
||||||
<div v-if="type === 'source'">
|
|
||||||
<RadioGroup v-if="plugins" v-model="formState.type" type="button" @on-change="handlerChangePlugin($event)">
|
|
||||||
<div v-for="key in Object.keys(plugins)" v-bind:key="key">
|
|
||||||
<Divider orientation="left">{{ key }} ({{ plugins[key].length }})</Divider>
|
|
||||||
<Space wrap :size="[8, 16]">
|
|
||||||
<Tooltip v-for="plugin in plugins[key]" :content="plugin.description" transfer v-bind:key="plugin.name">
|
|
||||||
<Radio :label="plugin.name + '_' + plugin.type">
|
|
||||||
<Avatar :src="'/static/images/plugin/' + plugin.name.split('_')[0].replace(' Community', '') + '.png'" size="small"/>
|
|
||||||
<span style="margin-left: 2px;">{{ plugin.name }}</span>
|
|
||||||
</Radio>
|
|
||||||
</Tooltip>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
</RadioGroup>
|
|
||||||
</div>
|
|
||||||
<div v-else style="margin-top: 10px;">
|
|
||||||
<Row>
|
|
||||||
<Col :span="5"/>
|
|
||||||
<Col :span="14">
|
|
||||||
<FormItem v-for="configure in pluginTabConfigure" :required="configure.required" v-bind:key="configure.field" :prop="configure.field">
|
|
||||||
<template #label>
|
|
||||||
<span v-if="configure.field !== 'configures'">{{ $t('common.' + configure.field) }}</span>
|
|
||||||
</template>
|
|
||||||
<Input v-if="configure.type === 'String'" type="text" :disabled="configure.disabled" v-model="configure.value"/>
|
|
||||||
<InputNumber v-else-if="configure.type === 'Number'" :disabled="configure.disabled" :max="configure.max" :min="configure.min" v-model="configure.value"/>
|
|
||||||
<Switch v-else-if="configure.type === 'Boolean'" :disabled="configure.disabled" v-model="configure.value"/>
|
|
||||||
<Upload v-else-if="configure.type === 'File'" multiple
|
|
||||||
:headers="{
|
|
||||||
'Authorization': auth.type + ' ' + auth.token,
|
|
||||||
'PluginType': formState.type.split(' ')[0]
|
|
||||||
}"
|
|
||||||
:format="['xml']"
|
|
||||||
:on-success="handlerUploadSuccess"
|
|
||||||
:on-remove="handlerUploadRemove"
|
|
||||||
action="/api/v1/source/uploadFile">
|
|
||||||
<Button icon="ios-cloud-upload-outline">{{ $t('common.upload') }}</Button>
|
|
||||||
</Upload>
|
|
||||||
<div v-else>
|
|
||||||
<div style="margin-top: 10px;">
|
|
||||||
<FormItem style="margin-bottom: 5px;">
|
|
||||||
<Button size="small" type="primary" shape="circle" icon="md-add" @click="handlerPlusConfigure(configure.value)"/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem v-for="(element, index) in configure.value" :key="index" style="margin-bottom: 5px;">
|
|
||||||
<Row :gutter="12">
|
|
||||||
<Col :span="10">
|
|
||||||
<FormItem>
|
|
||||||
<Input v-model="element.field">
|
|
||||||
<template #prepend>
|
|
||||||
<span>{{ $t('common.field') }}</span>
|
|
||||||
</template>
|
|
||||||
</Input>
|
|
||||||
</FormItem>
|
|
||||||
</Col>
|
|
||||||
<Col :span="10">
|
|
||||||
<FormItem>
|
|
||||||
<Input v-model="element.value">
|
|
||||||
<template #prepend>
|
|
||||||
<span>{{ $t('common.value') }}</span>
|
|
||||||
</template>
|
|
||||||
</Input>
|
|
||||||
</FormItem>
|
|
||||||
</Col>
|
|
||||||
<Col :span="2">
|
|
||||||
<Button size="small" type="error" shape="circle" icon="md-remove" @click="handlerMinusConfigure(element, configure.value)"/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</FormItem>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
</Col>
|
|
||||||
<Col :span="5"/>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
|
||||||
</Form>
|
|
||||||
<template #footer>
|
|
||||||
<Button key="cancel" type="error" size="small" :disabled="loading.test || loading.save" @click="handlerCancel()">
|
|
||||||
{{ $t('common.cancel') }}
|
|
||||||
</Button>
|
|
||||||
<Button type="primary" size="small" :loading="loading.test" :disabled="loading.save" @click="handlerTest()">
|
|
||||||
{{ $t('common.test') }}
|
|
||||||
</Button>
|
|
||||||
<Button type="primary" size="small" :loading="loading.save" :disabled="!testInfo.connected || loading.test" @click="handlerSave()">
|
|
||||||
{{ $t('common.save') }}
|
|
||||||
</Button>
|
|
||||||
</template>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts">
|
|
||||||
import {SourceModel} from "@/model/SourceModel";
|
|
||||||
import {SourceService} from "@/services/SourceService";
|
|
||||||
import {emptySource} from "@/views/admin/source/SourceGenerate";
|
|
||||||
import {defineComponent, reactive, ref} from "vue";
|
|
||||||
import {Configure} from "@/model/Configure";
|
|
||||||
import {clone, join} from 'lodash'
|
|
||||||
import SourceV2Service from "@/services/SourceV2Service";
|
|
||||||
import Common from "@/common/Common";
|
|
||||||
import {ResponseModel} from "@/model/ResponseModel";
|
|
||||||
|
|
||||||
interface TestInfo
|
|
||||||
{
|
|
||||||
connected: boolean,
|
|
||||||
percent: number,
|
|
||||||
successful: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "SourceDetail",
|
|
||||||
props: {
|
|
||||||
isVisible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: () => false
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: Number,
|
|
||||||
default: () => 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup()
|
|
||||||
{
|
|
||||||
const layout = {
|
|
||||||
labelCol: {span: 6},
|
|
||||||
wrapperCol: {span: 12},
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
activeKey: ref('source'),
|
|
||||||
layout
|
|
||||||
};
|
|
||||||
},
|
|
||||||
components: {},
|
|
||||||
data()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
title: '',
|
|
||||||
isUpdate: false,
|
|
||||||
formState: {} as SourceModel,
|
|
||||||
plugins: null,
|
|
||||||
testInfo: {} as TestInfo,
|
|
||||||
pluginTabs: ['source'],
|
|
||||||
pluginConfigure: null,
|
|
||||||
pluginTabConfigure: null,
|
|
||||||
applyPlugin: null,
|
|
||||||
loading: {
|
|
||||||
test: false,
|
|
||||||
save: false
|
|
||||||
},
|
|
||||||
auth: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created()
|
|
||||||
{
|
|
||||||
this.auth = JSON.parse(localStorage.getItem(Common.token) || '{}');
|
|
||||||
if (this.id <= 0) {
|
|
||||||
this.title = 'Create New Source';
|
|
||||||
this.formState = reactive(emptySource);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.title = 'Modify Source';
|
|
||||||
this.isUpdate = true;
|
|
||||||
}
|
|
||||||
this.handlerInitialize();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handlerInitialize()
|
|
||||||
{
|
|
||||||
this.formState.type = null
|
|
||||||
if (this.id > 0) {
|
|
||||||
SourceV2Service.getById(this.id)
|
|
||||||
.then(response => {
|
|
||||||
if (response.status) {
|
|
||||||
this.formState = reactive(response.data);
|
|
||||||
this.formState.type = this.formState.type + '_' + this.formState.protocol;
|
|
||||||
this.applyPlugin = response.data['schema'];
|
|
||||||
this.pluginConfigure = response.data['schema']['configures'];
|
|
||||||
// Clear
|
|
||||||
this.pluginTabs = ['source'];
|
|
||||||
this.pluginTabs = [...this.pluginTabs, ...Array.from(new Set(this.pluginConfigure.map(v => v.group)))];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
new SourceService().getPlugins()
|
|
||||||
.then(response => {
|
|
||||||
if (response.status) {
|
|
||||||
this.plugins = response.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handlerCancel()
|
|
||||||
{
|
|
||||||
this.visible = false;
|
|
||||||
},
|
|
||||||
handlerSave()
|
|
||||||
{
|
|
||||||
this.loading.save = true;
|
|
||||||
const temp = clone(this.formState.type).split('_');
|
|
||||||
let type = temp[1]
|
|
||||||
let name = temp[0]
|
|
||||||
if (temp.length === 3) {
|
|
||||||
type = temp[2]
|
|
||||||
name = join([temp[0], temp[1]], ' ')
|
|
||||||
}
|
|
||||||
const configure = {
|
|
||||||
id: this.id,
|
|
||||||
type: type,
|
|
||||||
name: name,
|
|
||||||
configure: this.applyPlugin,
|
|
||||||
version: this.formState.version
|
|
||||||
};
|
|
||||||
SourceV2Service.saveAndUpdate(configure, this.isUpdate)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status) {
|
|
||||||
this.$Message.success("Create successful");
|
|
||||||
this.visible = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.loading.save = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handlerTest()
|
|
||||||
{
|
|
||||||
this.loading.test = true;
|
|
||||||
const temp = clone(this.formState.type).split('_');
|
|
||||||
let type = temp[1]
|
|
||||||
let name = temp[0]
|
|
||||||
if (temp.length === 3) {
|
|
||||||
type = temp[2]
|
|
||||||
name = join([temp[0], temp[1]], ' ')
|
|
||||||
}
|
|
||||||
const configure = {
|
|
||||||
type: type,
|
|
||||||
name: name,
|
|
||||||
configure: this.applyPlugin
|
|
||||||
};
|
|
||||||
new SourceService()
|
|
||||||
.testConnection(configure)
|
|
||||||
.then((response) => {
|
|
||||||
this.testInfo.percent = 100;
|
|
||||||
if (response.status) {
|
|
||||||
this.$Message.success("Test successful");
|
|
||||||
this.testInfo.connected = true;
|
|
||||||
this.testInfo.successful = true;
|
|
||||||
this.formState.version = response.data?.columns[0]?.version;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.$Message.error(response.message);
|
|
||||||
this.testInfo.connected = false;
|
|
||||||
this.testInfo.successful = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.loading.test = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handlerPlusConfigure(array: Array<Configure>)
|
|
||||||
{
|
|
||||||
if (array === null) {
|
|
||||||
array = new Array<Configure>();
|
|
||||||
}
|
|
||||||
const configure: Configure = {field: '', value: ''};
|
|
||||||
array.push(configure);
|
|
||||||
},
|
|
||||||
handlerMinusConfigure(configure: Configure, array: Array<Configure>)
|
|
||||||
{
|
|
||||||
const index = array.indexOf(configure);
|
|
||||||
if (index !== -1) {
|
|
||||||
array.splice(index, 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handlerChangePlugin(value)
|
|
||||||
{
|
|
||||||
const pluginAndType = value.split('_');
|
|
||||||
const applyPlugins: [] = this.plugins[pluginAndType[1]];
|
|
||||||
const applyPlugin = applyPlugins.filter(plugin => plugin['name'] === pluginAndType[0])[0];
|
|
||||||
this.applyPlugin = applyPlugin['configure'];
|
|
||||||
this.pluginConfigure = applyPlugin['configure']['configures'];
|
|
||||||
// Clear
|
|
||||||
this.pluginTabs = ['source'];
|
|
||||||
this.pluginTabs = [...this.pluginTabs, ...Array.from(new Set(this.pluginConfigure.map(v => v.group)))];
|
|
||||||
},
|
|
||||||
handlerFilterConfigure(group: string)
|
|
||||||
{
|
|
||||||
if (group === 'source') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.pluginTabConfigure = this.pluginConfigure.filter(field => field.group === group);
|
|
||||||
},
|
|
||||||
handlerUploadSuccess(response: ResponseModel)
|
|
||||||
{
|
|
||||||
if (response.status) {
|
|
||||||
const configure = this.applyPlugin.configures.filter(configure => configure.field === 'file')
|
|
||||||
configure[0].value.push(response.data)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handlerUploadRemove(file)
|
|
||||||
{
|
|
||||||
const configure = this.applyPlugin.configures.filter(configure => configure.field === 'file')
|
|
||||||
configure[0].value = configure[0].value.filter(value => !value.endsWith(file.name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
visible: {
|
|
||||||
get(): boolean
|
|
||||||
{
|
|
||||||
return this.isVisible
|
|
||||||
},
|
|
||||||
set(value: boolean)
|
|
||||||
{
|
|
||||||
this.$emit('close', value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,92 +0,0 @@
|
|||||||
import {SourceModel} from "@/model/SourceModel";
|
|
||||||
|
|
||||||
const emptySource: SourceModel = {
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
protocol: "",
|
|
||||||
host: "",
|
|
||||||
port: 0,
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
catalog: "",
|
|
||||||
database: "",
|
|
||||||
type: "",
|
|
||||||
configures: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const createHeaders = (i18n: any) => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title: i18n.t('common.no'),
|
|
||||||
key: 'id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.name'),
|
|
||||||
key: 'name',
|
|
||||||
slot: 'name',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.type'),
|
|
||||||
key: 'type',
|
|
||||||
slot: 'type'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.protocol'),
|
|
||||||
key: 'protocol',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.host'),
|
|
||||||
key: 'host',
|
|
||||||
slot: 'host',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.port'),
|
|
||||||
key: 'port',
|
|
||||||
ellipsis: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.public'),
|
|
||||||
slot: 'public',
|
|
||||||
key: 'public'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.version'),
|
|
||||||
slot: 'version',
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.available'),
|
|
||||||
key: 'available',
|
|
||||||
slot: 'available',
|
|
||||||
ellipsis: true,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.createTime'),
|
|
||||||
key: 'createTime',
|
|
||||||
ellipsis: true,
|
|
||||||
tooltip: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.updateTime'),
|
|
||||||
key: 'updateTime',
|
|
||||||
ellipsis: true,
|
|
||||||
tooltip: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('common.action'),
|
|
||||||
slot: 'action',
|
|
||||||
key: 'action',
|
|
||||||
width: 150,
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
createHeaders,
|
|
||||||
emptySource
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user