feat(ui): baseline rollback (#502)

This commit is contained in:
pycook 2024-04-29 10:10:07 +08:00 committed by GitHub
parent 74b587e46c
commit 994a28dd25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 342 additions and 28 deletions

View File

@ -71,3 +71,19 @@ export function judgeItsmInstalled() {
isShowMessage: false 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
})
}

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="cmdb-grant" :style="{ maxHeight: `${windowHeight - 130}px` }"> <div class="cmdb-grant" :style="{ }">
<template v-if="cmdbGrantType.includes('ci_type')"> <template v-if="cmdbGrantType.includes('ci_type')">
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div> <div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div>
<CiTypeGrant <CiTypeGrant

View File

@ -520,7 +520,21 @@ if __name__ == "__main__":
newUpdateField: 'Add a Attribute', newUpdateField: 'Add a Attribute',
attributeSettings: 'Attribute Settings', attributeSettings: 'Attribute Settings',
share: 'Share', 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: { serviceTree: {
remove: 'Remove', remove: 'Remove',

View File

@ -520,7 +520,21 @@ if __name__ == "__main__":
newUpdateField: '新增修改字段', newUpdateField: '新增修改字段',
attributeSettings: '字段设置', attributeSettings: '字段设置',
share: '分享', share: '分享',
noPermission: '暂无权限' noPermission: '暂无权限',
rollback: '回滚',
rollbackHeader: '实例回滚',
rollbackTo: '回滚至: ',
rollbackToTips: '请选择回滚时间点',
baselineDiff: '基线对比结果',
instance: '实例',
rollbackBefore: '当前值',
rollbackAfter: '回滚后',
noDiff: '在【{baseline}】后数据没有发生变化',
rollbackConfirm: '确认要回滚吗 ',
rollbackSuccess: '回滚成功',
rollbackingTips: '正在批量回滚中',
batchRollbacking: '正在回滚,共{total}个,成功{successNum}个,失败{errorNum}个',
baselineTips: '该时间点的变更也会被回滚, 唯一标识、密码属性不支持回滚',
}, },
serviceTree: { serviceTree: {
remove: '移除', remove: '移除',

View File

@ -2,7 +2,7 @@
<div> <div>
<div class="ci-detail-header">{{ this.type.alias }}</div> <div class="ci-detail-header">{{ this.type.alias }}</div>
<div class="ci-detail-page"> <div class="ci-detail-page">
<CiDetailTab ref="ciDetailTab" :typeId="typeId" /> <ci-detail-tab ref="ciDetailTab" :typeId="typeId" :attributeHistoryTableHeight="windowHeight - 250" />
</div> </div>
</div> </div>
</template> </template>
@ -23,6 +23,11 @@ export default {
attributes: {}, attributes: {},
} }
}, },
computed: {
windowHeight() {
return this.$store.state.windowHeight
},
},
provide() { provide() {
return { return {
attrList: () => { attrList: () => {
@ -55,7 +60,6 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.ci-detail-header { .ci-detail-header {
border-left: 3px solid @primary-color; border-left: 3px solid @primary-color;
padding-left: 10px; padding-left: 10px;

View File

@ -68,6 +68,8 @@
<span @click="openBatchDownload">{{ $t('download') }}</span> <span @click="openBatchDownload">{{ $t('download') }}</span>
<a-divider type="vertical" /> <a-divider type="vertical" />
<span @click="batchDelete">{{ $t('delete') }}</span> <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> <span>{{ $t('cmdb.ci.selectRows', { rows: selectedRowKeys.length }) }}</span>
</div> </div>
</SearchForm> </SearchForm>
@ -293,6 +295,7 @@
<create-instance-form ref="create" @reload="reloadData" @submit="batchUpdate" /> <create-instance-form ref="create" @reload="reloadData" @submit="batchUpdate" />
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" /> <JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
<BatchDownload ref="batchDownload" @batchDownload="batchDownload" /> <BatchDownload ref="batchDownload" @batchDownload="batchDownload" />
<ci-rollback-form ref="ciRollbackForm" @batchRollbackAsync="batchRollbackAsync($event)" :ciIds="selectedRowKeys" />
<MetadataDrawer ref="metadataDrawer" /> <MetadataDrawer ref="metadataDrawer" />
<CMDBGrant ref="cmdbGrant" resourceTypeName="CIType" app_id="cmdb" /> <CMDBGrant ref="cmdbGrant" resourceTypeName="CIType" app_id="cmdb" />
</a-spin> </a-spin>
@ -325,6 +328,8 @@ import MetadataDrawer from './modules/MetadataDrawer.vue'
import CMDBGrant from '../../components/cmdbGrant' import CMDBGrant from '../../components/cmdbGrant'
import { ops_move_icon as OpsMoveIcon } from '@/core/icons' import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
import { getAttrPassword } from '../../api/CITypeAttr' import { getAttrPassword } from '../../api/CITypeAttr'
import CiRollbackForm from './modules/ciRollbackForm.vue'
import { CIBaselineRollback } from '../../api/history'
export default { export default {
name: 'InstanceList', name: 'InstanceList',
@ -340,6 +345,7 @@ export default {
MetadataDrawer, MetadataDrawer,
CMDBGrant, CMDBGrant,
OpsMoveIcon, OpsMoveIcon,
CiRollbackForm,
}, },
computed: { computed: {
windowHeight() { windowHeight() {
@ -429,6 +435,12 @@ export default {
// window.onkeypress = (e) => { // window.onkeypress = (e) => {
// this.handleKeyPress(e) // this.handleKeyPress(e)
// } // }
this.$nextTick(() => {
const loadingNode = document.getElementsByClassName('ant-drawer-mask')
if (loadingNode?.style) {
loadingNode.style.zIndex = 8
}
})
setTimeout(() => { setTimeout(() => {
this.columnDrop() this.columnDrop()
}, 1000) }, 1000)
@ -661,7 +673,7 @@ export default {
message: this.$t('warning'), message: this.$t('warning'),
description: errorMsg, description: errorMsg,
duration: 0, duration: 0,
style: { whiteSpace: 'break-spaces' }, style: { whiteSpace: 'break-spaces', overflow: 'auto', height: this.windowHeight - 80 + 'px' },
}) })
errorNum += 1 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() { async refreshAfterEditAttrs() {
await this.loadPreferenceAttrList() await this.loadPreferenceAttrList()
await this.loadTableData() await this.loadTableData()

View File

@ -1,12 +1,13 @@
<template> <template>
<CustomDrawer <CustomDrawer
width="80%" width="90%"
placement="left" placement="left"
@close=" @close="
() => { () => {
visible = false visible = false
} }
" "
style="transform: translateX(0px)!important"
:visible="visible" :visible="visible"
:hasTitle="false" :hasTitle="false"
:hasFooter="false" :hasFooter="false"

View File

@ -7,7 +7,7 @@
resizable resizable
border border
size="small" size="small"
class="ops-stripe-table" class="ops-unstripe-table"
:span-method="mergeRowMethod" :span-method="mergeRowMethod"
:data="tableData" :data="tableData"
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }" v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
@ -35,7 +35,7 @@
:filters="[ :filters="[
{ value: 0, label: $t('new') }, { value: 0, label: $t('new') },
{ value: 1, label: $t('delete') }, { value: 1, label: $t('delete') },
{ value: 3, label: $t('update') }, { value: 2, label: $t('update') },
]" ]"
:filter-method="filterOperateMethod" :filter-method="filterOperateMethod"
:title="$t('operation')" :title="$t('operation')"
@ -104,6 +104,10 @@ export default {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
attrList: {
type: Array,
default: () => [],
}
}, },
data() { data() {
return { return {
@ -170,8 +174,8 @@ export default {
if (attrColumn) { if (attrColumn) {
$table.setFilter( $table.setFilter(
attrColumn, attrColumn,
this.tableData.map((item) => { this.attrList().map((attr) => {
return { value: item.attr_alias, label: item.attr_alias } return { value: attr.alias || attr.name, label: attr.alias || attr.name }
}) })
) )
} }

View File

@ -20,7 +20,7 @@
:key="attr.name" :key="attr.name"
v-for="attr in group.attributes" 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-item>
</el-descriptions> </el-descriptions>
</div> </div>
@ -28,22 +28,32 @@
<a-tab-pane key="tab_2"> <a-tab-pane key="tab_2">
<span slot="tab"><a-icon type="branches" />{{ $t('cmdb.relation') }}</span> <span slot="tab"><a-icon type="branches" />{{ $t('cmdb.relation') }}</span>
<div :style="{ height: '100%', padding: '24px', overflow: 'auto' }"> <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> </div>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="tab_3"> <a-tab-pane key="tab_3">
<span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span> <span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span>
<div :style="{ padding: '24px', height: '100%' }"> <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 <vxe-table
ref="xTable" ref="xTable"
show-overflow
show-header-overflow
:data="ciHistory" :data="ciHistory"
size="small" size="small"
height="auto" :height="tableHeight"
highlight-hover-row
:span-method="mergeRowMethod" :span-method="mergeRowMethod"
:scroll-y="{ enabled: false, gt: 20 }"
:scroll-x="{ enabled: false, gt: 0 }"
border border
resizable resizable
:scroll-y="{ enabled: false }" class="ops-unstripe-table"
class="ops-stripe-table"
> >
<template #empty> <template #empty>
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }"> <a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
@ -63,7 +73,7 @@
:filters="[ :filters="[
{ value: 0, label: $t('new') }, { value: 0, label: $t('new') },
{ value: 1, label: $t('delete') }, { value: 1, label: $t('delete') },
{ value: 3, label: $t('update') }, { value: 2, label: $t('update') },
]" ]"
:filter-method="filterOperateMethod" :filter-method="filterOperateMethod"
:title="$t('operation')" :title="$t('operation')"
@ -78,8 +88,18 @@
:filters="[]" :filters="[]"
:filter-method="filterAttrMethod" :filter-method="filterAttrMethod"
></vxe-table-column> ></vxe-table-column>
<vxe-table-column field="old" :title="$t('cmdb.history.old')"></vxe-table-column> <vxe-table-column field="old" :title="$t('cmdb.history.old')">
<vxe-table-column field="new" :title="$t('cmdb.history.new')"></vxe-table-column> <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> </vxe-table>
</div> </div>
</a-tab-pane> </a-tab-pane>
@ -92,7 +112,7 @@
<a-tab-pane key="tab_5"> <a-tab-pane key="tab_5">
<span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span> <span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span>
<div :style="{ padding: '24px', height: '100%' }"> <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> </div>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
@ -119,6 +139,9 @@ import CiDetailAttrContent from './ciDetailAttrContent.vue'
import CiDetailRelation from './ciDetailRelation.vue' import CiDetailRelation from './ciDetailRelation.vue'
import TriggerTable from '../../operation_history/modules/triggerTable.vue' import TriggerTable from '../../operation_history/modules/triggerTable.vue'
import RelatedItsmTable from './ciDetailRelatedItsmTable.vue' import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
import CiRollbackForm from './ciRollbackForm.vue'
import { sleep } from '@/utils/util'
export default { export default {
name: 'CiDetailTab', name: 'CiDetailTab',
components: { components: {
@ -128,6 +151,7 @@ export default {
CiDetailRelation, CiDetailRelation,
TriggerTable, TriggerTable,
RelatedItsmTable, RelatedItsmTable,
CiRollbackForm,
}, },
props: { props: {
typeId: { typeId: {
@ -138,10 +162,15 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
attributeHistoryTableHeight: {
type: Number,
default: null
}
}, },
data() { data() {
return { return {
ci: {}, ci: {},
item: [],
attributeGroups: [], attributeGroups: [],
activeTabKey: 'tab_1', activeTabKey: 'tab_1',
rowSpanMap: {}, rowSpanMap: {},
@ -150,6 +179,7 @@ export default {
ci_types: [], ci_types: [],
hasPermission: true, hasPermission: true,
itsmInstalled: true, itsmInstalled: true,
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120),
} }
}, },
computed: { computed: {
@ -227,8 +257,9 @@ export default {
}) })
}, },
async judgeItsmInstalled() { async judgeItsmInstalled() {
await judgeItsmInstalled() await judgeItsmInstalled().catch((e) => {
.catch((e) => { this.itsmInstalled = false }) this.itsmInstalled = false
})
}, },
getCIHistory() { getCIHistory() {
@ -368,6 +399,11 @@ export default {
this.$message.error(this.$t('cmdb.ci.copyFailed')) this.$message.error(this.$t('cmdb.ci.copyFailed'))
}) })
}, },
handleRollbackCI() {
this.$nextTick(() => {
this.$refs.ciRollbackForm.onOpen()
})
},
}, },
} }
</script> </script>

View File

@ -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>

View File

@ -223,10 +223,10 @@
<a-form-item :label="$t('cmdb.ciType.isInherit')"> <a-form-item :label="$t('cmdb.ciType.isInherit')">
<a-radio-group v-model="isInherit"> <a-radio-group v-model="isInherit">
<a-radio :value="true"> <a-radio :value="true">
{{ $t('yes') }}
</a-radio> </a-radio>
<a-radio :value="false"> <a-radio :value="false">
{{ $t('no') }}
</a-radio> </a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>

View File

@ -17,7 +17,6 @@
show-header-overflow show-header-overflow
highlight-hover-row highlight-hover-row
keep-source keep-source
:height="windowHeight - 190"
class="ops-stripe-table" class="ops-stripe-table"
:row-class-name="rowClass" :row-class-name="rowClass"
:edit-config="{ trigger: 'dblclick', mode: 'cell', showIcon: false }" :edit-config="{ trigger: 'dblclick', mode: 'cell', showIcon: false }"

View File

@ -5,7 +5,7 @@
show-header-overflow show-header-overflow
stripe stripe
size="small" size="small"
class="ops-stripe-table" class="ops-unstripe-table"
:data="tableData" :data="tableData"
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }" v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
> >