mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-02 20:17:45 +08:00
[Core] [Refactor] [UI] [Source] Add history
This commit is contained in:
parent
d8a6a0fb8b
commit
77fc3c8de5
@ -18,6 +18,7 @@ export default {
|
||||
create: 'Create Source',
|
||||
delete: 'Delete Source [ $NAME ]',
|
||||
syncMetadata: 'Sync Metadata',
|
||||
syncHistory: 'Sync History',
|
||||
},
|
||||
tip: {
|
||||
selectSource: 'Please select a source',
|
||||
|
@ -18,6 +18,7 @@ export default {
|
||||
create: '创建数据源',
|
||||
delete: '删除数据源 [ $NAME ]',
|
||||
syncMetadata: '同步元数据',
|
||||
syncHistory: '同步历史',
|
||||
},
|
||||
tip: {
|
||||
selectSource: '请选择数据源',
|
||||
|
@ -3,6 +3,7 @@ import { BaseService } from '@/services/base'
|
||||
import { HttpUtils } from '@/utils/http'
|
||||
import { SourceModel } from '@/model/source.ts'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { FilterModel } from '@/model/filter.ts'
|
||||
|
||||
const DEFAULT_PATH_V1 = '/api/v1/source'
|
||||
const DEFAULT_PATH_V2 = '/api/v2/source'
|
||||
@ -50,6 +51,11 @@ class SourceService
|
||||
{
|
||||
return new HttpUtils().put(`${ DEFAULT_PATH_V2 }/syncMetadata/${ id }`)
|
||||
}
|
||||
|
||||
getHistory(id: number, configure: FilterModel): Promise<ResponseModel>
|
||||
{
|
||||
return new HttpUtils().post(`${ DEFAULT_PATH_V2 }/getHistory/${ id }`, configure)
|
||||
}
|
||||
}
|
||||
|
||||
export default new SourceService()
|
||||
|
157
core/datacap-ui/src/views/pages/admin/source/SourceHistory.vue
Normal file
157
core/datacap-ui/src/views/pages/admin/source/SourceHistory.vue
Normal file
@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<Dialog :is-visible="visible" :title="$t('source.common.syncHistory')" :width="'60%'">
|
||||
<TableCommon :loading="loading" :columns="headers" :data="data" :pagination="pagination" @changePage="handlerChangePage">
|
||||
<template #elapsed="{row}">
|
||||
{{ (getTime(row.updateTime) - getTime(row.createTime)) / 1000 }}
|
||||
</template>
|
||||
<template #state="{row}">
|
||||
<Badge :style="{backgroundColor: Common.getColor(row?.state)}">
|
||||
<HoverCard v-if="row?.state === 'FAILURE'">
|
||||
<HoverCardTrigger as-child>
|
||||
<Button variant="link">
|
||||
{{ getStateText(row?.state) }}
|
||||
</Button>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent class="w-full">
|
||||
{{ row?.message }}
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
<span v-else>{{ getStateText(row?.state) }}</span>
|
||||
</Badge>
|
||||
</template>
|
||||
<template #result="{row}">
|
||||
<HoverCard>
|
||||
<HoverCardTrigger as-child>
|
||||
<Eye class="cursor-pointer"/>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent class="w-full">
|
||||
<MdPreview :modelValue="toMarkdown(row.info)" style="padding: 0"/>
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
</template>
|
||||
</TableCommon>
|
||||
<template #footer>
|
||||
<div class="space-x-5">
|
||||
<Button variant="outline" size="sm" @click="handlerCancel">
|
||||
{{ $t('common.cancel') }}
|
||||
</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 Button from '@/views/ui/button'
|
||||
import { FilterModel } from '@/model/filter'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { createHistoryHeaders } from '@/views/pages/admin/source/SourceUtils'
|
||||
import { PaginationModel, PaginationRequest } from '@/model/pagination'
|
||||
import TableCommon from '@/views/components/table/TableCommon.vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'
|
||||
import Common from '@/utils/common'
|
||||
import { Eye } from 'lucide-vue-next'
|
||||
import { MdPreview } from 'md-editor-v3'
|
||||
import 'md-editor-v3/lib/style.css'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SourceHistory',
|
||||
components: {
|
||||
Badge,
|
||||
Button,
|
||||
Dialog,
|
||||
TableCommon,
|
||||
HoverCard, HoverCardContent, HoverCardTrigger,
|
||||
Eye,
|
||||
MdPreview
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get(): boolean
|
||||
{
|
||||
return this.isVisible
|
||||
},
|
||||
set(value: boolean)
|
||||
{
|
||||
this.$emit('close', value)
|
||||
}
|
||||
},
|
||||
Common()
|
||||
{
|
||||
return Common
|
||||
}
|
||||
},
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean
|
||||
},
|
||||
info: {
|
||||
type: Object as () => SourceModel | null
|
||||
}
|
||||
},
|
||||
setup()
|
||||
{
|
||||
const i18n = useI18n()
|
||||
const filter: FilterModel = new FilterModel()
|
||||
const headers = createHistoryHeaders(i18n)
|
||||
|
||||
return {
|
||||
filter,
|
||||
headers,
|
||||
i18n
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
loading: false,
|
||||
data: [],
|
||||
pagination: {} as PaginationModel
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize()
|
||||
},
|
||||
methods: {
|
||||
handlerInitialize()
|
||||
{
|
||||
this.loading = true
|
||||
SourceService.getHistory(this.info?.id as number, this.filter)
|
||||
.then((response) => {
|
||||
if (response.status) {
|
||||
this.data = response.data.content
|
||||
this.pagination = PaginationRequest.of(response.data)
|
||||
}
|
||||
})
|
||||
.finally(() => this.loading = false)
|
||||
},
|
||||
handlerChangePage(value: PaginationModel)
|
||||
{
|
||||
this.filter.page = value.currentPage
|
||||
this.filter.size = value.pageSize
|
||||
this.handlerInitialize()
|
||||
},
|
||||
handlerCancel()
|
||||
{
|
||||
this.visible = false
|
||||
},
|
||||
getTime(time: any)
|
||||
{
|
||||
return time ? new Date(time).getTime() : 0
|
||||
},
|
||||
getStateText(origin: string): string
|
||||
{
|
||||
return Common.getText(this.i18n, origin)
|
||||
},
|
||||
toMarkdown(content: string)
|
||||
{
|
||||
return '```json\n' + JSON.stringify(content, null, 4) + '\n```'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -45,6 +45,10 @@
|
||||
<Trash class="mr-2 h-4 w-4"/>
|
||||
<span>{{ $t('common.deleteData') }}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem :disabled="(loginUserId !== row.user.id)" class="cursor-pointer" @click="handlerHistory(true, row)">
|
||||
<History class="mr-2 h-4 w-4"/>
|
||||
{{ $t('source.common.syncHistory') }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem :disabled="(loginUserId !== row.user.id) || !row.available" class="cursor-pointer" @click="handlerSyncMetadata(true, row)">
|
||||
<RefreshCcwDot class="mr-2 h-4 w-4"/>
|
||||
{{ $t('source.common.syncMetadata') }}
|
||||
@ -59,6 +63,7 @@
|
||||
<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)"/>
|
||||
<SourceMetadata v-if="dataSyncMetadataVisible" :is-visible="dataSyncMetadataVisible" :info="dataInfo" @close="handlerSyncMetadata(false, null)"/>
|
||||
<SourceHistory v-if="dataHistoryVisible" :is-visible="dataHistoryVisible" :info="dataInfo" @close="handlerHistory(false, null)"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -66,7 +71,7 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import Card from '@/views/ui/card'
|
||||
import Button from '@/views/ui/button'
|
||||
import { CirclePlay, CircleX, Cog, Pencil, Plus, RefreshCcwDot, Trash } from 'lucide-vue-next'
|
||||
import { CirclePlay, CircleX, Cog, History, Pencil, Plus, RefreshCcwDot, Trash } from 'lucide-vue-next'
|
||||
import TableCommon from '@/views/components/table/TableCommon.vue'
|
||||
import { FilterModel } from '@/model/filter'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
@ -91,10 +96,12 @@ import {
|
||||
} from '@/components/ui/dropdown-menu'
|
||||
import SourceDelete from '@/views/pages/admin/source/SourceDelete.vue'
|
||||
import SourceMetadata from '@/views/pages/admin/source/SourceMetadata.vue'
|
||||
import SourceHistory from '@/views/pages/admin/source/SourceHistory.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SourceHome',
|
||||
components: {
|
||||
SourceHistory,
|
||||
SourceMetadata,
|
||||
SourceDelete,
|
||||
DropdownMenuItem, DropdownMenuGroup, DropdownMenuSeparator, DropdownMenuLabel, DropdownMenuContent, DropdownMenuTrigger, DropdownMenu,
|
||||
@ -104,7 +111,7 @@ export default defineComponent({
|
||||
Switch,
|
||||
Avatar,
|
||||
TableCommon,
|
||||
Pencil, CircleX, CirclePlay, Cog, Trash, Plus, RefreshCcwDot,
|
||||
Pencil, CircleX, CirclePlay, Cog, Trash, Plus, RefreshCcwDot, History,
|
||||
Button,
|
||||
Card
|
||||
},
|
||||
@ -129,7 +136,8 @@ export default defineComponent({
|
||||
dataInfoVisible: false,
|
||||
dataInfo: null as SourceModel | null,
|
||||
dataDeleteVisible: false,
|
||||
dataSyncMetadataVisible: false
|
||||
dataSyncMetadataVisible: false,
|
||||
dataHistoryVisible: false
|
||||
}
|
||||
},
|
||||
created()
|
||||
@ -175,6 +183,11 @@ export default defineComponent({
|
||||
{
|
||||
this.dataSyncMetadataVisible = opened
|
||||
this.dataInfo = value
|
||||
},
|
||||
handlerHistory(opened: boolean, value: null | SourceModel)
|
||||
{
|
||||
this.dataHistoryVisible = opened
|
||||
this.dataInfo = value
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -15,6 +15,19 @@ const createHeaders = (i18n: any) => {
|
||||
]
|
||||
}
|
||||
|
||||
export {
|
||||
createHeaders
|
||||
const createHistoryHeaders = (i18n: any) => {
|
||||
return [
|
||||
{ key: 'id', hidden: true, header: i18n.t('common.id'), width: 80 },
|
||||
{ key: 'name', hidden: true, header: i18n.t('common.name') },
|
||||
{ key: 'createTime', hidden: true, header: i18n.t('common.createTime') },
|
||||
{ key: 'updateTime', hidden: true, header: i18n.t('common.updateTime') },
|
||||
{ key: 'elapsed', hidden: true, header: i18n.t('common.elapsed'), slot: 'elapsed', class: 'text-center' },
|
||||
{ key: 'state', hidden: true, header: i18n.t('common.state'), slot: 'state', class: 'text-center' },
|
||||
{ key: 'result', hidden: true, header: i18n.t('common.result'), slot: 'result' }
|
||||
]
|
||||
}
|
||||
|
||||
export {
|
||||
createHeaders,
|
||||
createHistoryHeaders
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<Modal v-model="visible"
|
||||
:title="$t('common.syncMetadata') + ' [ ' + data.name + ' ]'"
|
||||
:mask-closable="false"
|
||||
@cancel="handlerCancel()">
|
||||
<Alert type="warning"
|
||||
show-icon>
|
||||
{{ $t('source.manager.sourceSyncMetadataTip1') }}
|
||||
</Alert>
|
||||
<Alert type="error"
|
||||
show-icon>
|
||||
{{ $t('source.manager.sourceSyncMetadataTip2') }}
|
||||
</Alert>
|
||||
<p>{{ $t('source.manager.sourceSyncMetadataTip3').replace('REPLACE_NAME', data.name) }}</p>
|
||||
<Input v-model="inputValue"/>
|
||||
<template #footer>
|
||||
<Button type="primary"
|
||||
:disabled="inputValue !== data.name"
|
||||
:loading="loading"
|
||||
@click="handlerSubmit()">
|
||||
<FontAwesomeIcon icon="rotate"/>
|
||||
{{ $t('common.syncMetadata') }}
|
||||
</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from "vue";
|
||||
import SourceV2Service from "@/services/SourceV2Service";
|
||||
|
||||
export class DataItem
|
||||
{
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: "SourceMetadata",
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
data: {
|
||||
type: DataItem
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
loading: false,
|
||||
inputValue: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlerSubmit()
|
||||
{
|
||||
this.loading = true;
|
||||
SourceV2Service
|
||||
.syncMetadata(this.data.id)
|
||||
.then((response) => {
|
||||
if (response.status) {
|
||||
this.$Message.success(`${this.$t('source.manager.sourceSyncMetadataTip4').replace('REPLACE_NAME', this.data.name)}`);
|
||||
this.handlerCancel();
|
||||
}
|
||||
})
|
||||
.finally(() => this.loading = false);
|
||||
},
|
||||
handlerCancel()
|
||||
{
|
||||
this.visible = false;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get(): boolean
|
||||
{
|
||||
return this.isVisible;
|
||||
},
|
||||
set(value: boolean)
|
||||
{
|
||||
this.$emit('close', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user