Skip to content

Commit

Permalink
feat(ui): CI change logs related itsm
Browse files Browse the repository at this point in the history
  • Loading branch information
pycook committed Apr 24, 2024
1 parent bf1076f commit 51332c7
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 4 deletions.
17 changes: 17 additions & 0 deletions cmdb-ui/src/modules/cmdb/api/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,20 @@ export function getCiTriggersByCiId(ci_id, params) {
params
})
}

export function getCiRelatedTickets(params) {
return axios({
url: `/itsm/v1/process_ticket/get_tickets_by`,
method: 'POST',
data: params,
isShowMessage: false
})
}

export function judgeItsmInstalled() {
return axios({
url: `/itsm/v1/process_ticket/itsm_existed`,
method: 'GET',
isShowMessage: false
})
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion cmdb-ui/src/modules/cmdb/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,15 @@ const cmdb_en = {
noModifications: 'No Modifications',
attr: 'attribute',
attrId: 'attribute id',
changeDescription: 'attribute id: {attr_id}, {before_days} day(s) in advance, Subject: {subject}\nContent: {body}\nNotify At: {notify_at}'
changeDescription: 'attribute id: {attr_id}, {before_days} day(s) in advance, Subject: {subject}\nContent: {body}\nNotify At: {notify_at}',
ticketStartTime: 'Start Time',
ticketCreator: 'Creator',
ticketTitle: 'Title',
ticketFinishTime: 'Finish Time',
ticketNodeName: 'Node Name',
itsmUninstalled: 'Please use it in combination with VE ITSM',
applyItsm: 'Free Apply ITSM',
ticketId: 'Ticket ID',
},
relation_type: {
addRelationType: 'New',
Expand Down
10 changes: 9 additions & 1 deletion cmdb-ui/src/modules/cmdb/lang/zh.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,15 @@ const cmdb_zh = {
noModifications: '没有修改',
attr: '属性名',
attrId: '属性ID',
changeDescription: '属性ID:{attr_id},提前:{before_days}天,主题:{subject}\n内容:{body}\n通知时间:{notify_at}'
changeDescription: '属性ID:{attr_id},提前:{before_days}天,主题:{subject}\n内容:{body}\n通知时间:{notify_at}',
ticketStartTime: '工单发起时间',
ticketCreator: '发起人',
ticketTitle: '工单名称',
ticketFinishTime: '节点完成时间',
ticketNodeName: '节点名称',
itsmUninstalled: '请结合维易ITSM使用',
applyItsm: '免费申请',
ticketId: '工单ID',
},
relation_type: {
addRelationType: '新增关系类型',
Expand Down
221 changes: 221 additions & 0 deletions cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelatedItsmTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<template>
<div :style="{ height: '100%' }" v-if="itsmInstalled">
<vxe-table
ref="xTable"
show-overflow
show-header-overflow
resizable
border
size="small"
class="ops-stripe-table"
:span-method="mergeRowMethod"
:data="tableData"
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
>
<template #empty>
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
<img slot="image" :src="require('@/assets/data_empty.png')" />
<span slot="description"> {{ $t('noData') }} </span>
</a-empty>
</template>
<vxe-column field="ticket.ticket_id" min-width="80" :title="$t('cmdb.history.ticketId')"> </vxe-column>
<vxe-column field="ticket.created_at" width="160" :title="$t('cmdb.history.ticketStartTime')"> </vxe-column>
<vxe-column field="ticket.creator_name" min-width="80" :title="$t('cmdb.history.ticketCreator')"> </vxe-column>
<vxe-column field="ticket.title" min-width="150" :title="$t('cmdb.history.ticketTitle')">
<template slot-scope="{ row }">
<a target="_blank" :href="row.ticket.url">{{ row.ticket.title }}</a>
</template>
</vxe-column>
<vxe-column field="ticket.node_finish_time" width="160" :title="$t('cmdb.history.ticketFinishTime')">
</vxe-column>
<vxe-column field="ticket.node_name" min-width="100" :title="$t('cmdb.history.ticketNodeName')"> </vxe-column>
<vxe-table-column
field="operate_type"
min-width="100"
:filters="[
{ value: 0, label: $t('new') },
{ value: 1, label: $t('delete') },
{ value: 3, label: $t('update') },
]"
:filter-method="filterOperateMethod"
:title="$t('operation')"
>
<template #default="{ row }">
{{ operateTypeMap[row.operate_type] }}
</template>
</vxe-table-column>
<vxe-table-column
field="attr_alias"
min-width="100"
:title="$t('cmdb.attribute')"
:filters="[]"
:filter-method="filterAttrMethod"
>
</vxe-table-column>
<vxe-table-column field="old" min-width="100" :title="$t('cmdb.history.old')"></vxe-table-column>
<vxe-table-column field="new" min-width="100" :title="$t('cmdb.history.new')"></vxe-table-column>
</vxe-table>
<div :style="{ textAlign: 'right' }" v-if="!ci_id">
<a-pagination
size="small"
show-size-changer
show-quick-jumper
:page-size-options="pageSizeOptions"
:current="tablePage.currentPage"
:total="tablePage.totalResult"
:show-total="(total, range) => $t('cmdb.history.totalItems', { total: total })"
:page-size="tablePage.pageSize"
:default-current="1"
@change="pageOrSizeChange"
@showSizeChange="pageOrSizeChange"
>
</a-pagination>
</div>
</div>
<a-empty
v-else
:image-style="{
height: '200px',
}"
:style="{ paddingTop: '10%' }"
>
<img slot="image" :src="require('@/modules/cmdb/assets/itsm_uninstalled.png')" />
<span slot="description"> {{ $t('cmdb.history.itsmUninstalled') }} </span>
<a-button href="https://veops.cn/apply" target="_blank" type="primary">
{{ $t('cmdb.history.applyItsm') }}
</a-button>
</a-empty>
</template>

<script>
import { getCiRelatedTickets } from '../../../api/history'
export default {
name: 'RelatedItsmTable',
props: {
ci_id: {
type: Number,
default: null,
},
ciHistory: {
type: Array,
default: () => [],
},
itsmInstalled: {
type: Boolean,
default: true,
},
},
data() {
return {
tableData: [],
tablePage: {
currentPage: 1,
pageSize: 50,
totalResult: 0,
},
pageSizeOptions: ['50', '100', '200'],
}
},
computed: {
windowHeight() {
return this.$store.state.windowHeight
},
operateTypeMap() {
return {
0: this.$t('new'),
1: this.$t('delete'),
2: this.$t('update'),
}
},
},
mounted() {
this.updateTableData()
},
methods: {
updateTableData(currentPage = 1, pageSize = this.tablePage.pageSize) {
const params = { page: currentPage, page_size: pageSize, next_todo_ids: [] }
if (this.ci_id) {
const tableData = []
this.ciHistory.forEach((item) => {
if (item.ticket_id) {
params.next_todo_ids.push(item.ticket_id)
tableData.push(item)
}
})
if (params.next_todo_ids.length) {
getCiRelatedTickets(params)
.then((res) => {
const ticketId2Detail = {}
res.forEach((item) => {
ticketId2Detail[item.next_todo_id] = item
})
this.tableData = tableData.map((item) => {
return {
...item,
ticket: ticketId2Detail[item.ticket_id],
}
})
this.updateAttrFilter()
})
.catch((e) => {})
}
} else {
}
},
updateAttrFilter() {
this.$nextTick(() => {
const $table = this.$refs.xTable
if ($table) {
const attrColumn = $table.getColumnByField('attr_alias')
if (attrColumn) {
$table.setFilter(
attrColumn,
this.tableData.map((item) => {
return { value: item.attr_alias, label: item.attr_alias }
})
)
}
}
})
},
mergeRowMethod({ row, _rowIndex, column, visibleData }) {
const fields = [
'ticket.ticket_id',
'ticket.created_at',
'ticket.creator_name',
'ticket.title',
'ticket.node_finish_time',
'ticket.node_name',
]
const cellValue1 = row.ticket.ticket_id
const cellValue2 = row.ticket.node_name
if (cellValue1 && cellValue2 && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1]
let nextRow = visibleData[_rowIndex + 1]
if (prevRow && prevRow.ticket.ticket_id === cellValue1 && prevRow.ticket.node_name === cellValue2) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow.ticket.ticket_id === cellValue1 && nextRow.ticket.node_name === cellValue2) {
nextRow = visibleData[++countRowspan + _rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
},
pageOrSizeChange(currentPage, pageSize) {
this.updateTableData(currentPage, pageSize)
},
filterOperateMethod({ value, row, column }) {
return Number(row.operate_type) === Number(value)
},
filterAttrMethod({ value, row, column }) {
return row.attr_alias === value
},
},
}
</script>

<style></style>
29 changes: 27 additions & 2 deletions cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@
height="auto"
:span-method="mergeRowMethod"
border
resizable
:scroll-y="{ enabled: false }"
class="ops-stripe-table"
>
<template #empty>
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
<img slot="image" :src="require('@/assets/data_empty.png')" />
<span slot="description"> {{ $t('noData') }} </span>
</a-empty>
</template>
<vxe-table-column sortable field="created_at" :title="$t('created_at')"></vxe-table-column>
<vxe-table-column
field="username"
Expand Down Expand Up @@ -82,6 +89,12 @@
<TriggerTable :ci_id="ci._id" />
</div>
</a-tab-pane>
<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" />
</div>
</a-tab-pane>
</a-tabs>
<a-empty
v-else
Expand All @@ -100,11 +113,12 @@
import _ from 'lodash'
import { Descriptions, DescriptionsItem } from 'element-ui'
import { getCITypeGroupById, getCITypes } from '@/modules/cmdb/api/CIType'
import { getCIHistory } from '@/modules/cmdb/api/history'
import { getCIHistory, judgeItsmInstalled } from '@/modules/cmdb/api/history'
import { getCIById } from '@/modules/cmdb/api/ci'
import CiDetailAttrContent from './ciDetailAttrContent.vue'
import CiDetailRelation from './ciDetailRelation.vue'
import TriggerTable from '../../operation_history/modules/triggerTable.vue'
import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
export default {
name: 'CiDetailTab',
components: {
Expand All @@ -113,6 +127,7 @@ export default {
CiDetailAttrContent,
CiDetailRelation,
TriggerTable,
RelatedItsmTable,
},
props: {
typeId: {
Expand All @@ -134,6 +149,7 @@ export default {
ciId: null,
ci_types: [],
hasPermission: true,
itsmInstalled: true,
}
},
computed: {
Expand Down Expand Up @@ -179,6 +195,7 @@ export default {
}
this.ciId = ciId
await this.getCI()
await this.judgeItsmInstalled()
if (this.hasPermission) {
this.getAttributes()
this.getCIHistory()
Expand All @@ -203,7 +220,15 @@ export default {
this.hasPermission = false
}
})
.catch((e) => {})
.catch((e) => {
if (e.response.status === 404) {
this.itsmInstalled = false
}
})
},
async judgeItsmInstalled() {
await judgeItsmInstalled()
.catch((e) => { this.itsmInstalled = false })
},

getCIHistory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
:data="tableData"
v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
>
<template #empty>
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
<img slot="image" :src="require('@/assets/data_empty.png')" />
<span slot="description"> {{ $t('noData') }} </span>
</a-empty>
</template>
<vxe-column field="trigger_name" :title="$t('cmdb.history.triggerName')"> </vxe-column>
<vxe-column field="type" :title="$t('type')">
<template #default="{ row }">
Expand Down

0 comments on commit 51332c7

Please sign in to comment.