mirror of https://github.com/veops/cmdb.git
feat(ui): baseline rollback (#502)
This commit is contained in:
parent
74b587e46c
commit
994a28dd25
|
@ -71,3 +71,19 @@ export function judgeItsmInstalled() {
|
|||
isShowMessage: false
|
||||
})
|
||||
}
|
||||
|
||||
export function getCIsBaseline(params) {
|
||||
return axios({
|
||||
url: `/v0.1/ci/baseline`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function CIBaselineRollback(ciId, params) {
|
||||
return axios({
|
||||
url: `/v0.1/ci/${ciId}/baseline/rollback`,
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="cmdb-grant" :style="{ maxHeight: `${windowHeight - 130}px` }">
|
||||
<div class="cmdb-grant" :style="{ }">
|
||||
<template v-if="cmdbGrantType.includes('ci_type')">
|
||||
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div>
|
||||
<CiTypeGrant
|
||||
|
|
|
@ -520,7 +520,21 @@ if __name__ == "__main__":
|
|||
newUpdateField: 'Add a Attribute',
|
||||
attributeSettings: 'Attribute Settings',
|
||||
share: 'Share',
|
||||
noPermission: 'No Permission'
|
||||
noPermission: 'No Permission',
|
||||
rollback: 'Rollback',
|
||||
rollbackHeader: 'Instance Rollback',
|
||||
rollbackTo: 'Rollback to',
|
||||
rollbackToTips: 'Please select rollback time',
|
||||
baselineDiff: 'Difference from baseline',
|
||||
instance: 'Instance',
|
||||
rollbackBefore: 'Current value',
|
||||
rollbackAfter: 'After rollback',
|
||||
noDiff: 'CI data has not changed after {baseline}',
|
||||
rollbackConfirm: 'Are you sure you want to rollback?',
|
||||
rollbackSuccess: 'Rollback successfully',
|
||||
rollbackingTips: 'Rollbacking',
|
||||
batchRollbacking: 'Deleting {total} items in total, {successNum} items successful, {errorNum} items failed',
|
||||
baselineTips: 'Changes at this point in time will also be rollbacked, Unique ID and password attributes do not support',
|
||||
},
|
||||
serviceTree: {
|
||||
remove: 'Remove',
|
||||
|
|
|
@ -520,7 +520,21 @@ if __name__ == "__main__":
|
|||
newUpdateField: '新增修改字段',
|
||||
attributeSettings: '字段设置',
|
||||
share: '分享',
|
||||
noPermission: '暂无权限'
|
||||
noPermission: '暂无权限',
|
||||
rollback: '回滚',
|
||||
rollbackHeader: '实例回滚',
|
||||
rollbackTo: '回滚至: ',
|
||||
rollbackToTips: '请选择回滚时间点',
|
||||
baselineDiff: '基线对比结果',
|
||||
instance: '实例',
|
||||
rollbackBefore: '当前值',
|
||||
rollbackAfter: '回滚后',
|
||||
noDiff: '在【{baseline}】后数据没有发生变化',
|
||||
rollbackConfirm: '确认要回滚吗 ?',
|
||||
rollbackSuccess: '回滚成功',
|
||||
rollbackingTips: '正在批量回滚中',
|
||||
batchRollbacking: '正在回滚,共{total}个,成功{successNum}个,失败{errorNum}个',
|
||||
baselineTips: '该时间点的变更也会被回滚, 唯一标识、密码属性不支持回滚',
|
||||
},
|
||||
serviceTree: {
|
||||
remove: '移除',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<div class="ci-detail-header">{{ this.type.alias }}</div>
|
||||
<div class="ci-detail-page">
|
||||
<CiDetailTab ref="ciDetailTab" :typeId="typeId" />
|
||||
<ci-detail-tab ref="ciDetailTab" :typeId="typeId" :attributeHistoryTableHeight="windowHeight - 250" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -23,6 +23,11 @@ export default {
|
|||
attributes: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
attrList: () => {
|
||||
|
@ -55,7 +60,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.ci-detail-header {
|
||||
border-left: 3px solid @primary-color;
|
||||
padding-left: 10px;
|
||||
|
|
|
@ -68,6 +68,8 @@
|
|||
<span @click="openBatchDownload">{{ $t('download') }}</span>
|
||||
<a-divider type="vertical" />
|
||||
<span @click="batchDelete">{{ $t('delete') }}</span>
|
||||
<a-divider type="vertical" />
|
||||
<span @click="batchRollback">{{ $t('cmdb.ci.rollback') }}</span>
|
||||
<span>{{ $t('cmdb.ci.selectRows', { rows: selectedRowKeys.length }) }}</span>
|
||||
</div>
|
||||
</SearchForm>
|
||||
|
@ -293,6 +295,7 @@
|
|||
<create-instance-form ref="create" @reload="reloadData" @submit="batchUpdate" />
|
||||
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
|
||||
<BatchDownload ref="batchDownload" @batchDownload="batchDownload" />
|
||||
<ci-rollback-form ref="ciRollbackForm" @batchRollbackAsync="batchRollbackAsync($event)" :ciIds="selectedRowKeys" />
|
||||
<MetadataDrawer ref="metadataDrawer" />
|
||||
<CMDBGrant ref="cmdbGrant" resourceTypeName="CIType" app_id="cmdb" />
|
||||
</a-spin>
|
||||
|
@ -325,6 +328,8 @@ import MetadataDrawer from './modules/MetadataDrawer.vue'
|
|||
import CMDBGrant from '../../components/cmdbGrant'
|
||||
import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
|
||||
import { getAttrPassword } from '../../api/CITypeAttr'
|
||||
import CiRollbackForm from './modules/ciRollbackForm.vue'
|
||||
import { CIBaselineRollback } from '../../api/history'
|
||||
|
||||
export default {
|
||||
name: 'InstanceList',
|
||||
|
@ -340,6 +345,7 @@ export default {
|
|||
MetadataDrawer,
|
||||
CMDBGrant,
|
||||
OpsMoveIcon,
|
||||
CiRollbackForm,
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
|
@ -429,6 +435,12 @@ export default {
|
|||
// window.onkeypress = (e) => {
|
||||
// this.handleKeyPress(e)
|
||||
// }
|
||||
this.$nextTick(() => {
|
||||
const loadingNode = document.getElementsByClassName('ant-drawer-mask')
|
||||
if (loadingNode?.style) {
|
||||
loadingNode.style.zIndex = 8
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.columnDrop()
|
||||
}, 1000)
|
||||
|
@ -661,7 +673,7 @@ export default {
|
|||
message: this.$t('warning'),
|
||||
description: errorMsg,
|
||||
duration: 0,
|
||||
style: { whiteSpace: 'break-spaces' },
|
||||
style: { whiteSpace: 'break-spaces', overflow: 'auto', height: this.windowHeight - 80 + 'px' },
|
||||
})
|
||||
errorNum += 1
|
||||
})
|
||||
|
@ -744,6 +756,55 @@ export default {
|
|||
},
|
||||
})
|
||||
},
|
||||
batchRollback() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.ciRollbackForm.onOpen(true)
|
||||
})
|
||||
},
|
||||
async batchRollbackAsync(params) {
|
||||
const mask = document.querySelector('.ant-drawer-mask')
|
||||
const oldValue = mask.style.zIndex
|
||||
mask.style.zIndex = 2
|
||||
let successNum = 0
|
||||
let errorNum = 0
|
||||
this.loading = true
|
||||
this.loadTip = this.$t('cmdb.ci.rollbackingTips')
|
||||
const floor = Math.ceil(this.selectedRowKeys.length / 6)
|
||||
for (let i = 0; i < floor; i++) {
|
||||
const itemList = this.selectedRowKeys.slice(6 * i, 6 * i + 6)
|
||||
const promises = itemList.map((x) => CIBaselineRollback(x, params))
|
||||
await Promise.allSettled(promises)
|
||||
.then((res) => {
|
||||
res.forEach((r) => {
|
||||
if (r.status === 'fulfilled') {
|
||||
successNum += 1
|
||||
} else {
|
||||
errorNum += 1
|
||||
}
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadTip = this.$t('cmdb.ci.batchRollbacking', {
|
||||
total: this.selectedRowKeys.length,
|
||||
successNum: successNum,
|
||||
errorNum: errorNum,
|
||||
})
|
||||
})
|
||||
}
|
||||
this.loading = false
|
||||
this.loadTip = ''
|
||||
mask.style.zIndex = oldValue
|
||||
this.selectedRowKeys = []
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
this.$nextTick(() => {
|
||||
if (this.currentPage === 1) {
|
||||
this.loadTableData()
|
||||
} else {
|
||||
this.currentPage = 1
|
||||
}
|
||||
})
|
||||
},
|
||||
async refreshAfterEditAttrs() {
|
||||
await this.loadPreferenceAttrList()
|
||||
await this.loadTableData()
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<template>
|
||||
<CustomDrawer
|
||||
width="80%"
|
||||
width="90%"
|
||||
placement="left"
|
||||
@close="
|
||||
() => {
|
||||
visible = false
|
||||
}
|
||||
"
|
||||
style="transform: translateX(0px)!important"
|
||||
:visible="visible"
|
||||
:hasTitle="false"
|
||||
:hasFooter="false"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
resizable
|
||||
border
|
||||
size="small"
|
||||
class="ops-stripe-table"
|
||||
class="ops-unstripe-table"
|
||||
:span-method="mergeRowMethod"
|
||||
:data="tableData"
|
||||
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
|
||||
|
@ -35,7 +35,7 @@
|
|||
:filters="[
|
||||
{ value: 0, label: $t('new') },
|
||||
{ value: 1, label: $t('delete') },
|
||||
{ value: 3, label: $t('update') },
|
||||
{ value: 2, label: $t('update') },
|
||||
]"
|
||||
:filter-method="filterOperateMethod"
|
||||
:title="$t('operation')"
|
||||
|
@ -104,6 +104,10 @@ export default {
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
attrList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -170,8 +174,8 @@ export default {
|
|||
if (attrColumn) {
|
||||
$table.setFilter(
|
||||
attrColumn,
|
||||
this.tableData.map((item) => {
|
||||
return { value: item.attr_alias, label: item.attr_alias }
|
||||
this.attrList().map((attr) => {
|
||||
return { value: attr.alias || attr.name, label: attr.alias || attr.name }
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
:key="attr.name"
|
||||
v-for="attr in group.attributes"
|
||||
>
|
||||
<CiDetailAttrContent :ci="ci" :attr="attr" @refresh="refresh" @updateCIByself="updateCIByself" />
|
||||
<ci-detail-attr-content :ci="ci" :attr="attr" @refresh="refresh" @updateCIByself="updateCIByself" />
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
@ -28,22 +28,32 @@
|
|||
<a-tab-pane key="tab_2">
|
||||
<span slot="tab"><a-icon type="branches" />{{ $t('cmdb.relation') }}</span>
|
||||
<div :style="{ height: '100%', padding: '24px', overflow: 'auto' }">
|
||||
<CiDetailRelation ref="ciDetailRelation" :ciId="ciId" :typeId="typeId" :ci="ci" />
|
||||
<ci-detail-relation ref="ciDetailRelation" :ciId="ciId" :typeId="typeId" :ci="ci" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="tab_3">
|
||||
<span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span>
|
||||
<div :style="{ padding: '24px', height: '100%' }">
|
||||
<a-space :style="{ 'margin-bottom': '10px', display: 'flex' }">
|
||||
<a-button type="primary" class="ops-button-ghost" ghost @click="handleRollbackCI()">
|
||||
<ops-icon type="shishizhuangtai" />{{ $t('cmdb.ci.rollback') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
<ci-rollback-form ref="ciRollbackForm" :ciIds="[ciId]" @getCIHistory="getCIHistory" />
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
show-overflow
|
||||
show-header-overflow
|
||||
:data="ciHistory"
|
||||
size="small"
|
||||
height="auto"
|
||||
:height="tableHeight"
|
||||
highlight-hover-row
|
||||
:span-method="mergeRowMethod"
|
||||
:scroll-y="{ enabled: false, gt: 20 }"
|
||||
:scroll-x="{ enabled: false, gt: 0 }"
|
||||
border
|
||||
resizable
|
||||
:scroll-y="{ enabled: false }"
|
||||
class="ops-stripe-table"
|
||||
class="ops-unstripe-table"
|
||||
>
|
||||
<template #empty>
|
||||
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
|
||||
|
@ -63,7 +73,7 @@
|
|||
:filters="[
|
||||
{ value: 0, label: $t('new') },
|
||||
{ value: 1, label: $t('delete') },
|
||||
{ value: 3, label: $t('update') },
|
||||
{ value: 2, label: $t('update') },
|
||||
]"
|
||||
:filter-method="filterOperateMethod"
|
||||
:title="$t('operation')"
|
||||
|
@ -78,8 +88,18 @@
|
|||
:filters="[]"
|
||||
:filter-method="filterAttrMethod"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="old" :title="$t('cmdb.history.old')"></vxe-table-column>
|
||||
<vxe-table-column field="new" :title="$t('cmdb.history.new')"></vxe-table-column>
|
||||
<vxe-table-column field="old" :title="$t('cmdb.history.old')">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.value_type === '6'">{{ JSON.parse(row.old) }}</span>
|
||||
<span v-else>{{ row.old }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="new" :title="$t('cmdb.history.new')">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.value_type === '6'">{{ JSON.parse(row.new) }}</span>
|
||||
<span v-else>{{ row.new }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
@ -92,7 +112,7 @@
|
|||
<a-tab-pane key="tab_5">
|
||||
<span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span>
|
||||
<div :style="{ padding: '24px', height: '100%' }">
|
||||
<RelatedItsmTable :ci_id="ci._id" :ciHistory="ciHistory" :itsmInstalled="itsmInstalled" />
|
||||
<related-itsm-table :ci_id="ci._id" :ciHistory="ciHistory" :itsmInstalled="itsmInstalled" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
@ -119,6 +139,9 @@ import CiDetailAttrContent from './ciDetailAttrContent.vue'
|
|||
import CiDetailRelation from './ciDetailRelation.vue'
|
||||
import TriggerTable from '../../operation_history/modules/triggerTable.vue'
|
||||
import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
|
||||
import CiRollbackForm from './ciRollbackForm.vue'
|
||||
import { sleep } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
name: 'CiDetailTab',
|
||||
components: {
|
||||
|
@ -128,6 +151,7 @@ export default {
|
|||
CiDetailRelation,
|
||||
TriggerTable,
|
||||
RelatedItsmTable,
|
||||
CiRollbackForm,
|
||||
},
|
||||
props: {
|
||||
typeId: {
|
||||
|
@ -138,10 +162,15 @@ export default {
|
|||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
attributeHistoryTableHeight: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ci: {},
|
||||
item: [],
|
||||
attributeGroups: [],
|
||||
activeTabKey: 'tab_1',
|
||||
rowSpanMap: {},
|
||||
|
@ -150,6 +179,7 @@ export default {
|
|||
ci_types: [],
|
||||
hasPermission: true,
|
||||
itsmInstalled: true,
|
||||
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -227,8 +257,9 @@ export default {
|
|||
})
|
||||
},
|
||||
async judgeItsmInstalled() {
|
||||
await judgeItsmInstalled()
|
||||
.catch((e) => { this.itsmInstalled = false })
|
||||
await judgeItsmInstalled().catch((e) => {
|
||||
this.itsmInstalled = false
|
||||
})
|
||||
},
|
||||
|
||||
getCIHistory() {
|
||||
|
@ -368,6 +399,11 @@ export default {
|
|||
this.$message.error(this.$t('cmdb.ci.copyFailed'))
|
||||
})
|
||||
},
|
||||
handleRollbackCI() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.ciRollbackForm.onOpen()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
<template>
|
||||
<CustomDrawer
|
||||
:closable="true"
|
||||
:title="drawerTitle"
|
||||
:visible="drawerVisible"
|
||||
@close="onClose"
|
||||
placement="right"
|
||||
width="800"
|
||||
:bodyStyle="{ paddingTop: 0 }"
|
||||
>
|
||||
<div class="custom-drawer-bottom-action">
|
||||
<a-button @click="onClose">{{ $t('cancel') }}</a-button>
|
||||
<a-button type="primary" @click="handleSubmit" :loading="loading" :disabled="!hasDiff">{{
|
||||
$t('submit')
|
||||
}}</a-button>
|
||||
</div>
|
||||
<a-form :form="form" :style="{ paddingTop: '20px' }">
|
||||
<a-form-item :label="$t('cmdb.ci.rollbackTo')" required :help="$t('cmdb.ci.baselineTips')">
|
||||
<a-date-picker
|
||||
:style="{ width: '278px' }"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
valueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
@ok="getBaselineDiff"
|
||||
:show-time="{ format: 'HH:mm:ss' }"
|
||||
:placeholder="$t('cmdb.ci.rollbackToTips')"
|
||||
v-decorator="['before_date', { rules: [{ required: true, message: $t('cmdb.ci.rollbackToTips') }] }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<span :style="{ fontWeight: 'bold' }">{{ $t('cmdb.ci.baselineDiff') }}</span>
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
show-overflow
|
||||
show-header-overflow
|
||||
resizable
|
||||
border
|
||||
size="small"
|
||||
:span-method="mergeRowMethod"
|
||||
:data="tableData"
|
||||
:scroll-y="{ enabled: false, gt: 20 }"
|
||||
:scroll-x="{ enabled: false, gt: 0 }"
|
||||
class="ops-unstripe-table"
|
||||
>
|
||||
<template #empty>
|
||||
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
|
||||
<img slot="image" :src="require('@/assets/data_empty.png')" />
|
||||
<span slot="description"> {{ dataLoad }} </span>
|
||||
</a-empty>
|
||||
</template>
|
||||
<vxe-column field="instance" min-width="80" :title="$t('cmdb.ci.instance')"> </vxe-column>
|
||||
<vxe-column field="attr_name" min-width="80" :title="$t('cmdb.attribute')"> </vxe-column>
|
||||
<vxe-column field="cur" min-width="80" :title="$t('cmdb.ci.rollbackBefore')">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.value_type === '6'">{{ JSON.stringify(row.cur) }}</span>
|
||||
<span v-else>{{ row.cur }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="to" min-width="80" :title="$t('cmdb.ci.rollbackAfter')">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.value_type === '6'">{{ JSON.stringify(row.to) }}</span>
|
||||
<span v-else>{{ row.to }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</a-form>
|
||||
</CustomDrawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCIsBaseline, CIBaselineRollback } from '../../../api/history'
|
||||
export default {
|
||||
name: 'CiRollbackForm',
|
||||
props: {
|
||||
ciIds: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
drawerTitle: this.$t('cmdb.ci.rollbackHeader'),
|
||||
drawerVisible: false,
|
||||
|
||||
formLayout: 'horizontal',
|
||||
|
||||
tableData: [],
|
||||
dataLoad: this.$t('noData'),
|
||||
loading: false,
|
||||
hasDiff: false,
|
||||
batched: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClose() {
|
||||
this.drawerVisible = false
|
||||
this.form.resetFields()
|
||||
this.tableData = []
|
||||
this.dataLoad = this.$t('noData')
|
||||
},
|
||||
onOpen(batched = false) {
|
||||
this.drawerTitle = this.$t('cmdb.ci.rollbackHeader')
|
||||
this.drawerVisible = true
|
||||
this.batched = batched
|
||||
},
|
||||
handleSubmit() {
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: that.$t('warning'),
|
||||
content: that.$t('cmdb.ci.rollbackConfirm'),
|
||||
onOk() {
|
||||
if (that.batched) {
|
||||
that.$emit('batchRollbackAsync', values)
|
||||
} else {
|
||||
that.rollbackCI(values)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
rollbackCI(params) {
|
||||
CIBaselineRollback(this.ciIds[0], params).then((res) => {
|
||||
this.$message.success(this.$t('cmdb.ci.rollbackSuccess'))
|
||||
this.form.resetFields()
|
||||
this.$emit('getCIHistory')
|
||||
})
|
||||
},
|
||||
getBaselineDiff(value) {
|
||||
this.dataLoad = 'loading...'
|
||||
this.loading = true
|
||||
this.hasDiff = false
|
||||
getCIsBaseline({ ci_ids: this.ciIds.join(','), before_date: value }).then((res) => {
|
||||
this.tableData = res
|
||||
this.loading = false
|
||||
if (!res.length) {
|
||||
this.dataLoad = this.$t('cmdb.ci.noDiff', { baseline: value })
|
||||
} else {
|
||||
this.hasDiff = true
|
||||
}
|
||||
})
|
||||
},
|
||||
mergeRowMethod({ row, _rowIndex, column, visibleData }) {
|
||||
const fields = ['instance']
|
||||
const cellValue1 = row.instance
|
||||
if (cellValue1 && fields.includes(column.property)) {
|
||||
const prevRow = visibleData[_rowIndex - 1]
|
||||
let nextRow = visibleData[_rowIndex + 1]
|
||||
if (prevRow && prevRow.instance === cellValue1) {
|
||||
return { rowspan: 0, colspan: 0 }
|
||||
} else {
|
||||
let countRowspan = 1
|
||||
while (nextRow && nextRow.instance === cellValue1) {
|
||||
nextRow = visibleData[++countRowspan + _rowIndex]
|
||||
}
|
||||
if (countRowspan > 1) {
|
||||
return { rowspan: countRowspan, colspan: 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -223,10 +223,10 @@
|
|||
<a-form-item :label="$t('cmdb.ciType.isInherit')">
|
||||
<a-radio-group v-model="isInherit">
|
||||
<a-radio :value="true">
|
||||
是
|
||||
{{ $t('yes') }}
|
||||
</a-radio>
|
||||
<a-radio :value="false">
|
||||
否
|
||||
{{ $t('no') }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
show-header-overflow
|
||||
highlight-hover-row
|
||||
keep-source
|
||||
:height="windowHeight - 190"
|
||||
class="ops-stripe-table"
|
||||
:row-class-name="rowClass"
|
||||
:edit-config="{ trigger: 'dblclick', mode: 'cell', showIcon: false }"
|
||||
|
@ -37,9 +36,9 @@
|
|||
<template #default="{row}">
|
||||
<span v-if="row.isParent && constraintMap[row.constraint]">{{
|
||||
constraintMap[row.constraint]
|
||||
.split('')
|
||||
.split(' ')
|
||||
.reverse()
|
||||
.join('')
|
||||
.join(' ')
|
||||
}}</span>
|
||||
<span v-else>{{ constraintMap[row.constraint] }}</span>
|
||||
</template>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
show-header-overflow
|
||||
stripe
|
||||
size="small"
|
||||
class="ops-stripe-table"
|
||||
class="ops-unstripe-table"
|
||||
:data="tableData"
|
||||
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue