mirror of https://github.com/veops/cmdb.git
Merge pull request #591 from veops/dev_ui_240813
refactor(ui): ci table
This commit is contained in:
commit
e2872f041e
|
@ -0,0 +1,393 @@
|
|||
<template>
|
||||
<div class="ci-table-wrap">
|
||||
<ops-table
|
||||
:id="id"
|
||||
border
|
||||
keep-source
|
||||
show-overflow
|
||||
resizable
|
||||
ref="xTable"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
:row-config="{ useKey: true, keyField: '_id' }"
|
||||
show-header-overflow
|
||||
highlight-hover-row
|
||||
:checkbox-config="{ reserve: true, highlight: true, range: true }"
|
||||
:edit-config="{ trigger: 'dblclick', mode: 'row', showIcon: false }"
|
||||
:sort-config="{ remote: true, trigger: 'cell' }"
|
||||
:row-key="true"
|
||||
:column-key="true"
|
||||
:cell-style="getCellStyle"
|
||||
:scroll-y="{ enabled: true, gt: 20 }"
|
||||
:scroll-x="{ enabled: true, gt: 20 }"
|
||||
class="ops-unstripe-table checkbox-hover-table"
|
||||
:custom-config="{ storage: true }"
|
||||
@checkbox-change="onSelectChange"
|
||||
@checkbox-all="onSelectChange"
|
||||
@checkbox-range-end="onSelectRangeEnd"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<vxe-column
|
||||
align="center"
|
||||
type="checkbox"
|
||||
width="60"
|
||||
:fixed="isCheckboxFixed ? 'left' : ''"
|
||||
v-if="showCheckbox"
|
||||
>
|
||||
<template #default="{row}">
|
||||
{{ getRowSeq(row) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-table-column
|
||||
v-for="(col, index) in columns"
|
||||
:key="`${col.field}_${index}`"
|
||||
:title="col.title"
|
||||
:field="col.field"
|
||||
:width="col.width"
|
||||
:sortable="col.sortable"
|
||||
:edit-render="getColumnsEditRender(col)"
|
||||
:cell-type="col.value_type === '2' ? 'string' : 'auto'"
|
||||
:fixed="col.is_fixed ? 'left' : ''"
|
||||
>
|
||||
<template #header>
|
||||
<span class="vxe-handle">
|
||||
<OpsMoveIcon class="header-move-icon" />
|
||||
<span>{{ col.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="col.is_choice || col.is_password" #edit="{ row }">
|
||||
<vxe-input v-if="col.is_password" v-model="passwordValue[col.field]" />
|
||||
<a-select
|
||||
v-if="col.is_choice"
|
||||
v-model="row[col.field]"
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
:style="{ width: '100%', height: '32px' }"
|
||||
:placeholder="$t('placeholder2')"
|
||||
:showArrow="false"
|
||||
:mode="col.is_list ? 'multiple' : 'default'"
|
||||
class="ci-table-edit-select"
|
||||
allowClear
|
||||
showSearch
|
||||
>
|
||||
<a-select-option
|
||||
v-for="(choice, idx) in col.filters"
|
||||
:value="choice[0]"
|
||||
:key="'edit_' + col.field + idx"
|
||||
>
|
||||
<span
|
||||
:style="{
|
||||
...(choice[1] ? choice[1].style : {}),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center'
|
||||
}"
|
||||
>
|
||||
<template v-if="choice[1] && choice[1].icon && choice[1].icon.name">
|
||||
<img
|
||||
v-if="choice[1].icon.id && choice[1].icon.url"
|
||||
:src="`/api/common-setting/v1/file/${choice[1].icon.url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: choice[1].icon.color, marginRight: '5px' }"
|
||||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
<span>{{ choice[0] }}</span>
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template
|
||||
v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice"
|
||||
#default="{ row }"
|
||||
>
|
||||
<span v-if="col.value_type === '6' && row[col.field]">{{ row[col.field] }}</span>
|
||||
<template v-else-if="col.is_link && row[col.field]">
|
||||
<a
|
||||
v-for="(item, linkIndex) in (col.is_list ? row[col.field] : [row[col.field]])"
|
||||
:key="linkIndex"
|
||||
:href="
|
||||
item.startsWith('http') || item.startsWith('https')
|
||||
? `${item}`
|
||||
: `http://${item}`
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
{{ item }}
|
||||
</a>
|
||||
</template>
|
||||
<PasswordField
|
||||
v-else-if="col.is_password && row[col.field]"
|
||||
:ci_id="row._id"
|
||||
:attr_id="col.attr_id"
|
||||
></PasswordField>
|
||||
<template v-else-if="col.is_choice">
|
||||
<span
|
||||
v-for="value in (col.is_list ? row[col.field] : [row[col.field]])"
|
||||
:key="value"
|
||||
:style="getChoiceValueStyle(col, value)"
|
||||
class="column-default-choice"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, value).id && getChoiceValueIcon(col, value).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, value).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else-if="getChoiceValueIcon(col, value).name"
|
||||
:style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>
|
||||
{{ value }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-column align="left" field="operate" fixed="right" width="80">
|
||||
<template #header>
|
||||
<span>{{ $t('operation') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<a-space>
|
||||
<a @click="openDetail(row.ci_id || row._id)">
|
||||
<a-icon type="unordered-list" />
|
||||
</a>
|
||||
<a-tooltip :title="$t('cmdb.ci.addRelation')">
|
||||
<a @click="openDetail(row.ci_id || row._id, 'tab_2', '2')">
|
||||
<a-icon type="retweet" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<a v-if="showDelete" @click="deleteCI(row)" :style="{ color: 'red' }">
|
||||
<a-icon type="delete" />
|
||||
</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div
|
||||
v-if="loading"
|
||||
class="ci-table-loading"
|
||||
>
|
||||
{{ loadingTip || $t('loading') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '200px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #loading>
|
||||
<div class="ci-table-loading">{{ loadingTip || $t('loading') }}</div>
|
||||
</template>
|
||||
</ops-table>
|
||||
|
||||
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JsonEditor from '../JsonEditor/jsonEditor.vue'
|
||||
import PasswordField from '../passwordField/index.vue'
|
||||
import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
|
||||
|
||||
export default {
|
||||
name: 'CITable',
|
||||
components: {
|
||||
JsonEditor,
|
||||
PasswordField,
|
||||
OpsMoveIcon
|
||||
},
|
||||
props: {
|
||||
// table ID
|
||||
id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// table Loading
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// ci 属性列表
|
||||
attrList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// table column
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
passwordValue: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
// 加载提示
|
||||
loadingTip: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否展示复选框
|
||||
showCheckbox: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否展示删除按钮
|
||||
showDelete: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isCheckboxFixed() {
|
||||
const idx = this.columns.findIndex((item) => item.is_fixed)
|
||||
return idx > -1
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
getVxetableRef() {
|
||||
return this?.$refs?.['xTable']?.getVxetableRef?.() || null
|
||||
},
|
||||
|
||||
onSelectChange() {
|
||||
const xTable = this.getVxetableRef()
|
||||
const records = [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()]
|
||||
this.$emit('onSelectChange', records)
|
||||
},
|
||||
|
||||
onSelectRangeEnd({ records }) {
|
||||
this.$emit('onSelectChange', records)
|
||||
},
|
||||
|
||||
getCellStyle({ row, rowIndex, $rowIndex, column, columnIndex, $columnIndex }) {
|
||||
const { property } = column
|
||||
const _find = this.attrList.find((attr) => attr.name === property)
|
||||
if (
|
||||
_find &&
|
||||
_find.option &&
|
||||
_find.option.fontOptions &&
|
||||
row[`${property}`] !== undefined &&
|
||||
row[`${property}`] !== null
|
||||
) {
|
||||
return { ..._find.option.fontOptions }
|
||||
}
|
||||
},
|
||||
|
||||
getColumnsEditRender(col) {
|
||||
const _editRender = {
|
||||
...col.editRender,
|
||||
}
|
||||
|
||||
if (col.value_type === '6') {
|
||||
_editRender.events = { focus: this.handleFocusJson }
|
||||
}
|
||||
|
||||
return _editRender
|
||||
},
|
||||
|
||||
handleFocusJson({ column, row }) {
|
||||
this.$refs.jsonEditor.open(column, row)
|
||||
},
|
||||
|
||||
jsonEditorOk(row, column, jsonData) {
|
||||
this.$attrs.data.forEach((item) => {
|
||||
if (item._id === row._id) {
|
||||
item[column.property] = JSON.stringify(jsonData)
|
||||
}
|
||||
})
|
||||
this.getVxetableRef().refreshColumn()
|
||||
},
|
||||
|
||||
getChoiceValueStyle(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.style || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
getChoiceValueIcon(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.icon || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
/**
|
||||
* 开启当前 ci 详情弹窗
|
||||
*/
|
||||
openDetail(id, activeTabKey, ciDetailRelationKey) {
|
||||
this.$emit('openDetail', id, activeTabKey, ciDetailRelationKey)
|
||||
},
|
||||
|
||||
deleteCI(row) {
|
||||
this.$emit('deleteCI', row)
|
||||
},
|
||||
|
||||
getRowSeq(row) {
|
||||
return this.getVxetableRef().getRowSeq(row)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-table-wrap {
|
||||
.ci-table-loading {
|
||||
width: 100%;
|
||||
line-height: 200px;
|
||||
}
|
||||
|
||||
.header-move-icon {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.column-default-choice {
|
||||
border-radius: 4px;
|
||||
padding: 1px 5px;
|
||||
margin: 2px;
|
||||
vertical-align: bottom;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-hover-table {
|
||||
/deep/ .vxe-table--body-wrapper {
|
||||
.vxe-checkbox--label {
|
||||
display: inline;
|
||||
padding-left: 0px !important;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-checked ~ .vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-cell--checkbox {
|
||||
&:hover {
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -74,205 +74,24 @@
|
|||
</div>
|
||||
</SearchForm>
|
||||
<CiDetailDrawer ref="detail" :typeId="typeId" />
|
||||
<ops-table
|
||||
:id="`cmdb-ci-${typeId}`"
|
||||
border
|
||||
keep-source
|
||||
show-overflow
|
||||
resizable
|
||||
|
||||
<CITable
|
||||
ref="xTable"
|
||||
size="small"
|
||||
:row-config="{ useKey: true, keyField: '_id' }"
|
||||
:height="tableHeight"
|
||||
show-header-overflow
|
||||
highlight-hover-row
|
||||
:id="`cmdb-ci-${typeId}`"
|
||||
:loading="loading"
|
||||
:attrList="preferenceAttrList"
|
||||
:columns="columns"
|
||||
:passwordValue="passwordValue"
|
||||
:data="instanceList"
|
||||
@checkbox-change="onSelectChange"
|
||||
@checkbox-all="onSelectChange"
|
||||
@checkbox-range-end="onSelectRangeEnd"
|
||||
:checkbox-config="{ reserve: true, highlight: true, range: true }"
|
||||
:height="tableHeight"
|
||||
@onSelectChange="onSelectChange"
|
||||
@edit-closed="handleEditClose"
|
||||
@edit-actived="handleEditActived"
|
||||
:edit-config="{ trigger: 'dblclick', mode: 'row', showIcon: false }"
|
||||
:sort-config="{ remote: true, trigger: 'cell' }"
|
||||
@sort-change="handleSortCol"
|
||||
:row-key="true"
|
||||
:column-key="true"
|
||||
:cell-style="getCellStyle"
|
||||
:scroll-y="{ enabled: true, gt: 20 }"
|
||||
:scroll-x="{ enabled: true, gt: 0 }"
|
||||
class="ops-unstripe-table checkbox-hover-table"
|
||||
:custom-config="{ storage: true }"
|
||||
>
|
||||
<vxe-column align="center" type="checkbox" width="60" :fixed="isCheckboxFixed ? 'left' : ''">
|
||||
<template #default="{row}">
|
||||
{{ getRowSeq(row) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-table-column
|
||||
v-for="(col, index) in columns"
|
||||
:key="`${col.field}_${index}`"
|
||||
:title="col.title"
|
||||
:field="col.field"
|
||||
:width="col.width"
|
||||
:sortable="col.sortable"
|
||||
:edit-render="getColumnsEditRender(col)"
|
||||
:cell-type="col.value_type === '2' ? 'string' : 'auto'"
|
||||
:fixed="col.is_fixed ? 'left' : ''"
|
||||
>
|
||||
<template #header>
|
||||
<span class="vxe-handle">
|
||||
<OpsMoveIcon
|
||||
style="width: 17px; height: 17px; display: none; position: absolute; left: -3px; top: 12px"
|
||||
/>
|
||||
<span>{{ col.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="col.is_choice || col.is_password" #edit="{ row }">
|
||||
<vxe-input v-if="col.is_password" v-model="passwordValue[col.field]" />
|
||||
<a-select
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
:style="{ width: '100%', height: '32px' }"
|
||||
v-model="row[col.field]"
|
||||
:v-bind="$t('placeholder2')"
|
||||
v-if="col.is_choice"
|
||||
:showArrow="false"
|
||||
:mode="col.is_list ? 'multiple' : 'default'"
|
||||
class="ci-table-edit-select"
|
||||
allowClear
|
||||
showSearch
|
||||
>
|
||||
<a-select-option
|
||||
:value="choice[0]"
|
||||
:key="'edit_' + col.field + idx"
|
||||
v-for="(choice, idx) in col.filters"
|
||||
>
|
||||
<span
|
||||
:style="{ ...(choice[1] ? choice[1].style : {}), display: 'inline-flex', alignItems: 'center' }"
|
||||
>
|
||||
<template v-if="choice[1] && choice[1].icon && choice[1].icon.name">
|
||||
<img
|
||||
v-if="choice[1].icon.id && choice[1].icon.url"
|
||||
:src="`/api/common-setting/v1/file/${choice[1].icon.url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: choice[1].icon.color, marginRight: '5px' }"
|
||||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
<span>{{ choice[0] }}</span>
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template
|
||||
v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice"
|
||||
#default="{ row }"
|
||||
>
|
||||
<span v-if="col.value_type === '6' && row[col.field]">{{ row[col.field] }}</span>
|
||||
<template v-else-if="col.is_link && row[col.field]">
|
||||
<a
|
||||
v-for="(item, linkIndex) in (col.is_list ? row[col.field] : [row[col.field]])"
|
||||
:key="linkIndex"
|
||||
:href="
|
||||
item.startsWith('http') || item.startsWith('https')
|
||||
? `${item}`
|
||||
: `http://${item}`
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
{{ item }}
|
||||
</a>
|
||||
</template>
|
||||
<PasswordField
|
||||
v-else-if="col.is_password && row[col.field]"
|
||||
:ci_id="row._id"
|
||||
:attr_id="col.attr_id"
|
||||
></PasswordField>
|
||||
<template v-else-if="col.is_choice">
|
||||
<template v-if="col.is_list">
|
||||
<span
|
||||
v-for="value in row[col.field]"
|
||||
:key="value"
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px',
|
||||
verticalAlign: 'bottom',
|
||||
...getChoiceValueStyle(col, value),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, value).id && getChoiceValueIcon(col, value).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, value).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else-if="getChoiceValueIcon(col, value).name"
|
||||
:style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>{{ value }}
|
||||
</span>
|
||||
</template>
|
||||
<span
|
||||
v-else
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px 0',
|
||||
verticalAlign: 'bottom',
|
||||
...getChoiceValueStyle(col, row[col.field]),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, row[col.field]).id && getChoiceValueIcon(col, row[col.field]).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, row[col.field]).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else-if="getChoiceValueIcon(col, row[col.field]).name"
|
||||
:style="{ color: getChoiceValueIcon(col, row[col.field]).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, row[col.field]).name"
|
||||
/>
|
||||
{{ row[col.field] }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-column align="left" field="operate" fixed="right" width="80">
|
||||
<template #header>
|
||||
<span>{{ $t('operation') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<a-space>
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id)">
|
||||
<a-icon type="unordered-list" />
|
||||
</a>
|
||||
<a-tooltip :title="$t('cmdb.ci.addRelation')">
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id, 'tab_2', '2')">
|
||||
<a-icon type="retweet" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<a @click="deleteCI(row)" :style="{ color: 'red' }">
|
||||
<a-icon type="delete" />
|
||||
</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div v-if="loading" style="height: 200px; line-height: 200px">{{ $t('loading') }}</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '200px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</ops-table>
|
||||
@openDetail="openDetail"
|
||||
@deleteCI="deleteCI"
|
||||
/>
|
||||
|
||||
<div :style="{ textAlign: 'right', marginTop: '4px' }">
|
||||
<a-pagination
|
||||
:showSizeChanger="true"
|
||||
|
@ -304,7 +123,6 @@
|
|||
</a-pagination>
|
||||
</div>
|
||||
<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" />
|
||||
|
@ -324,7 +142,6 @@ import SearchForm from '../../components/searchForm/SearchForm.vue'
|
|||
import CreateInstanceForm from './modules/CreateInstanceForm'
|
||||
import CiDetailDrawer from './modules/ciDetailDrawer.vue'
|
||||
import EditAttrsPopover from './modules/editAttrsPopover'
|
||||
import JsonEditor from '../../components/JsonEditor/jsonEditor.vue'
|
||||
import { searchCI, updateCI, deleteCI } from '@/modules/cmdb/api/ci'
|
||||
import { getSubscribeAttributes, subscribeCIType, subscribeTreeView } from '@/modules/cmdb/api/preference'
|
||||
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
|
||||
|
@ -332,15 +149,14 @@ import { roleHasPermissionToGrant } from '@/modules/acl/api/permission'
|
|||
import { searchResourceType } from '@/modules/acl/api/resource'
|
||||
import { getCITableColumns } from '../../utils/helper'
|
||||
import { intersection } from '@/utils/functions/set'
|
||||
import PasswordField from '../../components/passwordField/index.vue'
|
||||
import BatchDownload from '../../components/batchDownload/batchDownload.vue'
|
||||
import PreferenceSearch from '../../components/preferenceSearch/preferenceSearch.vue'
|
||||
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'
|
||||
import CITable from '@/modules/cmdb/components/ciTable/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'InstanceList',
|
||||
|
@ -348,24 +164,18 @@ export default {
|
|||
SearchForm,
|
||||
CreateInstanceForm,
|
||||
CiDetailDrawer,
|
||||
JsonEditor,
|
||||
PasswordField,
|
||||
EditAttrsPopover,
|
||||
BatchDownload,
|
||||
PreferenceSearch,
|
||||
MetadataDrawer,
|
||||
CMDBGrant,
|
||||
OpsMoveIcon,
|
||||
CiRollbackForm,
|
||||
CITable
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
isCheckboxFixed() {
|
||||
const idx = this.columns.findIndex((item) => item.is_fixed)
|
||||
return idx > -1
|
||||
},
|
||||
tableHeight() {
|
||||
// if (this.selectedRowKeys && this.selectedRowKeys.length) {
|
||||
// return this.windowHeight - 246
|
||||
|
@ -551,12 +361,7 @@ export default {
|
|||
const subscribed = await getSubscribeAttributes(this.typeId)
|
||||
this.preferenceAttrList = subscribed.attributes // All columns that have been subscribed
|
||||
},
|
||||
onSelectChange() {
|
||||
const xTable = this.$refs.xTable.getVxetableRef()
|
||||
const records = [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()]
|
||||
this.selectedRowKeys = records.map((i) => i.ci_id || i._id)
|
||||
},
|
||||
onSelectRangeEnd({ records }) {
|
||||
onSelectChange(records) {
|
||||
this.selectedRowKeys = records.map((i) => i.ci_id || i._id)
|
||||
},
|
||||
reloadData() {
|
||||
|
@ -820,28 +625,6 @@ export default {
|
|||
await this.loadPreferenceAttrList()
|
||||
await this.loadTableData()
|
||||
},
|
||||
getColumnsEditRender(col) {
|
||||
const _editRender = {
|
||||
...col.editRender,
|
||||
}
|
||||
if (col.value_type === '6') {
|
||||
_editRender.events = { focus: this.handleFocusJson }
|
||||
}
|
||||
return _editRender
|
||||
},
|
||||
handleFocusJson({ column, row }) {
|
||||
this.$refs.jsonEditor.open(column, row)
|
||||
},
|
||||
jsonEditorOk(row, column, jsonData) {
|
||||
// The backend writes data at different speeds. You can modify the table data directly without pulling the interface.
|
||||
// this.reloadData()
|
||||
this.instanceList.forEach((item) => {
|
||||
if (item._id === row._id) {
|
||||
item[column.property] = JSON.stringify(jsonData)
|
||||
}
|
||||
})
|
||||
this.$refs.xTable.getVxetableRef().refreshColumn()
|
||||
},
|
||||
onShowSizeChange(current, pageSize) {
|
||||
this.pageSize = pageSize
|
||||
if (this.currentPage === 1) {
|
||||
|
@ -903,23 +686,6 @@ export default {
|
|||
)
|
||||
})
|
||||
},
|
||||
// tableFilterChangeEvent({ column, property, values, datas, filterList, $event }) {
|
||||
// console.log(111)
|
||||
// },
|
||||
getChoiceValueStyle(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.style || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getChoiceValueIcon(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.icon || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
handleEditActived() {
|
||||
this.isEditActive = true
|
||||
const passwordCol = this.columns.filter((col) => col.is_password)
|
||||
|
@ -945,19 +711,6 @@ export default {
|
|||
this.lastEditCiId = row._id
|
||||
})
|
||||
},
|
||||
getCellStyle({ row, rowIndex, $rowIndex, column, columnIndex, $columnIndex }) {
|
||||
const { property } = column
|
||||
const _find = this.preferenceAttrList.find((attr) => attr.name === property)
|
||||
if (
|
||||
_find &&
|
||||
_find.option &&
|
||||
_find.option.fontOptions &&
|
||||
row[`${property}`] !== undefined &&
|
||||
row[`${property}`] !== null
|
||||
) {
|
||||
return { ..._find.option.fontOptions }
|
||||
}
|
||||
},
|
||||
getQAndSort() {
|
||||
const fuzzySearch = this.$refs['search'].fuzzySearch || ''
|
||||
const expression = this.$refs['search'].expression || ''
|
||||
|
@ -1055,8 +808,8 @@ export default {
|
|||
this.visible = false
|
||||
}
|
||||
},
|
||||
getRowSeq(row) {
|
||||
return this.$refs.xTable.getVxetableRef().getRowSeq(row)
|
||||
openDetail(id, activeTabKey, ciDetailRelationKey) {
|
||||
this.$refs.detail.create(id, activeTabKey, ciDetailRelationKey)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1075,33 +828,4 @@ export default {
|
|||
overflow: auto;
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
.checkbox-hover-table {
|
||||
/deep/ .vxe-table--body-wrapper {
|
||||
.vxe-checkbox--label {
|
||||
display: inline;
|
||||
padding-left: 0px !important;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-checked ~ .vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-cell--checkbox {
|
||||
&:hover {
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -73,6 +73,7 @@ export const category_1_bar_options = (data, options) => {
|
|||
type: 'bar',
|
||||
stack: options?.barStack ?? 'total',
|
||||
barGap: 0,
|
||||
barMaxWidth: '16px',
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
|
@ -242,6 +243,7 @@ export const category_2_bar_options = (data, options, chartType) => {
|
|||
label: {
|
||||
show: false,
|
||||
},
|
||||
barMaxWidth: '16px',
|
||||
areaStyle: chartType === 'line' && options?.isShadow ? {
|
||||
opacity: 0.5,
|
||||
color: {
|
||||
|
|
|
@ -163,204 +163,26 @@
|
|||
</div>
|
||||
</a-space>
|
||||
</SearchForm>
|
||||
<vxe-table
|
||||
:id="`cmdb-relation-${viewId}-${currentTypeId}`"
|
||||
border
|
||||
keep-source
|
||||
show-overflow
|
||||
resizable
|
||||
|
||||
<CITable
|
||||
ref="xTable"
|
||||
size="small"
|
||||
row-id="_id"
|
||||
:height="tableHeight"
|
||||
:id="`cmdb-relation-${viewId}-${currentTypeId}`"
|
||||
:loading="loading"
|
||||
show-header-overflow
|
||||
highlight-hover-row
|
||||
:attrList="preferenceAttrList"
|
||||
:columns="columns"
|
||||
:passwordValue="passwordValue"
|
||||
:data="instanceList"
|
||||
@checkbox-change="onSelectChange"
|
||||
@checkbox-all="onSelectChange"
|
||||
@checkbox-range-start="checkboxRangeStart"
|
||||
@checkbox-range-change="checkboxRangeChange"
|
||||
@checkbox-range-end="checkboxRangeEnd"
|
||||
:checkbox-config="{ reserve: true, range: true }"
|
||||
:height="tableHeight"
|
||||
:showCheckbox="isLeaf"
|
||||
:showDelete="isLeaf"
|
||||
@onSelectChange="onSelectChange"
|
||||
@edit-closed="handleEditClose"
|
||||
@edit-actived="handleEditActived"
|
||||
:edit-config="{ trigger: 'dblclick', mode: 'row', showIcon: false }"
|
||||
:sort-config="{ remote: true, trigger: 'cell' }"
|
||||
@sort-change="handleSortCol"
|
||||
:row-key="true"
|
||||
:column-key="true"
|
||||
:cell-style="getCellStyle"
|
||||
:scroll-y="{ enabled: true, gt: 20 }"
|
||||
:scroll-x="{ enabled: true, gt: 0 }"
|
||||
class="ops-unstripe-table checkbox-hover-table"
|
||||
:custom-config="{ storage: true }"
|
||||
>
|
||||
<vxe-column v-if="isLeaf" align="center" type="checkbox" width="50" fixed="left">
|
||||
<template #default="{row}">
|
||||
{{ getRowSeq(row) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-table-column
|
||||
v-for="(col, index) in columns"
|
||||
:key="`${col.field}_${index}`"
|
||||
:title="col.title"
|
||||
:field="col.field"
|
||||
:width="col.width"
|
||||
:sortable="col.sortable"
|
||||
:edit-render="getColumnsEditRender(col)"
|
||||
:cell-type="col.value_type === '2' ? 'string' : 'auto'"
|
||||
:fixed="col.is_fixed ? 'left' : ''"
|
||||
>
|
||||
<template #header>
|
||||
<span class="vxe-handle">
|
||||
<OpsMoveIcon
|
||||
style="width: 17px; height: 17px; display: none; position: absolute; left: -3px; top: 12px"
|
||||
/>
|
||||
{{ col.title }}</span
|
||||
>
|
||||
</template>
|
||||
<template v-if="col.is_choice || col.is_password" #edit="{ row }">
|
||||
<vxe-input v-if="col.is_password" v-model="passwordValue[col.field]" />
|
||||
<a-select
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
:style="{ width: '100%', height: '32px' }"
|
||||
v-model="row[col.field]"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-if="col.is_choice"
|
||||
:showArrow="false"
|
||||
:mode="col.is_list ? 'multiple' : 'default'"
|
||||
class="ci-table-edit-select"
|
||||
allowClear
|
||||
>
|
||||
<a-select-option
|
||||
:value="choice[0]"
|
||||
:key="'edit_' + col.field + idx"
|
||||
v-for="(choice, idx) in col.filters"
|
||||
>
|
||||
<span
|
||||
:style="{ ...(choice[1] ? choice[1].style : {}), display: 'inline-flex', alignItems: 'center' }"
|
||||
>
|
||||
<template v-if="choice[1] && choice[1].icon && choice[1].icon.name">
|
||||
<img
|
||||
v-if="choice[1].icon.id && choice[1].icon.url"
|
||||
:src="`/api/common-setting/v1/file/${choice[1].icon.url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: choice[1].icon.color, marginRight: '5px' }"
|
||||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
{{ choice[0] }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template
|
||||
v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice"
|
||||
#default="{row}"
|
||||
>
|
||||
<span v-if="col.value_type === '6' && row[col.field]">{{ row[col.field] }}</span>
|
||||
<a
|
||||
v-else-if="col.is_link && row[col.field]"
|
||||
:href="
|
||||
row[col.field].startsWith('http') || row[col.field].startsWith('https')
|
||||
? `${row[col.field]}`
|
||||
: `http://${row[col.field]}`
|
||||
"
|
||||
target="_blank"
|
||||
>{{ row[col.field] }}</a
|
||||
>
|
||||
<PasswordField
|
||||
v-else-if="col.is_password && row[col.field]"
|
||||
:ci_id="row._id"
|
||||
:attr_id="col.attr_id"
|
||||
></PasswordField>
|
||||
<template v-else-if="col.is_choice">
|
||||
<template v-if="col.is_list">
|
||||
<span
|
||||
v-for="value in row[col.field]"
|
||||
:key="value"
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px',
|
||||
...getChoiceValueStyle(col, value),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, value).id && getChoiceValueIcon(col, value).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, value).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>{{ value }}</span
|
||||
>
|
||||
</template>
|
||||
<span
|
||||
v-else-if="row[col.field]"
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px 0',
|
||||
...getChoiceValueStyle(col, row[col.field]),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, row[col.field]).id && getChoiceValueIcon(col, row[col.field]).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, row[col.field]).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: getChoiceValueIcon(col, row[col.field]).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, row[col.field]).name"
|
||||
/>{{ row[col.field] }}</span
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-column align="left" field="operate" fixed="right" width="80">
|
||||
<template #header>
|
||||
<span>{{ $t('operation') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<a-space>
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id)">
|
||||
<a-icon type="unordered-list" />
|
||||
</a>
|
||||
<a-tooltip :title="$t('cmdb.ci.addRelation')">
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id, 'tab_2', '2')">
|
||||
<a-icon type="retweet" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<template v-if="isLeaf">
|
||||
<a-tooltip :title="$t('cmdb.ciType.deleteInstance')">
|
||||
<a @click="deleteCI(row)" :style="{ color: 'red' }">
|
||||
<a-icon type="delete" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div v-if="loading" style="height: 200px; line-height: 200px">{{ $t('loading') }}</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '200px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-table>
|
||||
@openDetail="openDetail"
|
||||
@deleteCI="deleteCI"
|
||||
/>
|
||||
|
||||
<div :style="{ textAlign: 'right', marginTop: '4px' }">
|
||||
<a-pagination
|
||||
:showSizeChanger="true"
|
||||
|
@ -405,7 +227,6 @@
|
|||
@reload="sumbitFromCreateInstance"
|
||||
@submit="batchUpdateFromCreateInstance"
|
||||
/>
|
||||
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
|
||||
<BatchDownload ref="batchDownload" @batchDownload="batchDownload" />
|
||||
<ReadPermissionsModal ref="readPermissionsModal" />
|
||||
<RevokeModal ref="revokeModal" @handleRevoke="handleRevoke" />
|
||||
|
@ -440,16 +261,14 @@ import SplitPane from '@/components/SplitPane'
|
|||
import EditAttrsPopover from '../ci/modules/editAttrsPopover.vue'
|
||||
import CiDetailDrawer from '../ci/modules/ciDetailDrawer.vue'
|
||||
import CreateInstanceForm from '../ci/modules/CreateInstanceForm'
|
||||
import JsonEditor from '../../components/JsonEditor/jsonEditor.vue'
|
||||
import BatchDownload from '../../components/batchDownload/batchDownload.vue'
|
||||
import PasswordField from '../../components/passwordField/index.vue'
|
||||
import PreferenceSearch from '../../components/preferenceSearch/preferenceSearch.vue'
|
||||
import CMDBGrant from '../../components/cmdbGrant'
|
||||
import GrantModal from '../../components/cmdbGrant/grantModal.vue'
|
||||
import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
|
||||
import { getAttrPassword } from '../../api/CITypeAttr'
|
||||
import ReadPermissionsModal from './modules/ReadPermissionsModal.vue'
|
||||
import RevokeModal from '../../components/cmdbGrant/revokeModal.vue'
|
||||
import CITable from '@/modules/cmdb/components/ciTable/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'RelationViews',
|
||||
|
@ -464,13 +283,11 @@ export default {
|
|||
EditAttrsPopover,
|
||||
CiDetailDrawer,
|
||||
CreateInstanceForm,
|
||||
JsonEditor,
|
||||
BatchDownload,
|
||||
PasswordField,
|
||||
PreferenceSearch,
|
||||
OpsMoveIcon,
|
||||
ReadPermissionsModal,
|
||||
RevokeModal,
|
||||
CITable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -635,7 +452,7 @@ export default {
|
|||
refreshTable() {
|
||||
this.selectedRowKeys = []
|
||||
this.sortByTable = undefined
|
||||
const xTable = this.$refs.xTable
|
||||
const xTable = this.$refs.xTable.getVxetableRef()
|
||||
if (xTable) {
|
||||
xTable.clearCheckboxRow()
|
||||
xTable.clearCheckboxReserve()
|
||||
|
@ -815,8 +632,8 @@ export default {
|
|||
},
|
||||
|
||||
changeCIType(typeId) {
|
||||
this.$refs.xTable.clearCheckboxRow()
|
||||
this.$refs.xTable.clearCheckboxReserve()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
this.$refs.search.reset()
|
||||
this.selectedRowKeys = []
|
||||
this.currentTypeId = [typeId]
|
||||
|
@ -983,8 +800,8 @@ export default {
|
|||
if (keys) {
|
||||
const _tempKeys = keys.split('@^@').filter((item) => item !== '')
|
||||
if (_tempKeys.length === this.levels.length) {
|
||||
this.$refs.xTable.clearCheckboxRow()
|
||||
this.$refs.xTable.clearCheckboxReserve()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
this.selectedRowKeys = []
|
||||
}
|
||||
this.treeKeys = _tempKeys
|
||||
|
@ -1073,7 +890,10 @@ export default {
|
|||
this.currentView = `${this.viewId}`
|
||||
this.typeId = this.levels[0][0]
|
||||
this.viewOption = this.relationViews.views[this.viewName].option ?? {}
|
||||
this.refreshTable()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.refreshTable()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -1097,7 +917,7 @@ export default {
|
|||
}
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.$refs.xTable.refreshColumn()
|
||||
this.$refs.xTable.getVxetableRef().refreshColumn()
|
||||
})
|
||||
},
|
||||
calculateParamsFromTreeKey(treeKey, menuKey) {
|
||||
|
@ -1167,23 +987,8 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
onSelectChange({ records, reserves }) {
|
||||
this.selectedRowKeys = [...records, ...reserves]
|
||||
},
|
||||
checkboxRangeStart(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
const lastSelected = xTable.getCheckboxRecords()
|
||||
const selectedReserve = xTable.getCheckboxReserveRecords()
|
||||
this.lastSelected = [...lastSelected, ...selectedReserve]
|
||||
},
|
||||
checkboxRangeChange(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
xTable.setCheckboxRow(this.lastSelected, true)
|
||||
},
|
||||
checkboxRangeEnd(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
this.lastSelected = []
|
||||
this.selectedRowKeys = [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()]
|
||||
onSelectChange(records) {
|
||||
this.selectedRowKeys = records
|
||||
},
|
||||
batchDeleteCIRelation() {
|
||||
const currentShowType = this.showTypes.find((item) => item.id === Number(this.currentTypeId[0]))
|
||||
|
@ -1214,8 +1019,8 @@ export default {
|
|||
[first_ci_id],
|
||||
ancestor_ids
|
||||
).then((res) => {
|
||||
that.$refs.xTable.clearCheckboxRow()
|
||||
that.$refs.xTable.clearCheckboxReserve()
|
||||
that.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
that.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
that.selectedRowKeys = []
|
||||
that.loadData({ parameter: {}, refreshType: 'refreshNumber' })
|
||||
})
|
||||
|
@ -1273,7 +1078,7 @@ export default {
|
|||
},
|
||||
columnDrop() {
|
||||
this.$nextTick(() => {
|
||||
const xTable = this.$refs.xTable
|
||||
const xTable = this.$refs.xTable.getVxetableRef()
|
||||
this.sortable = Sortable.create(
|
||||
xTable.$el.querySelector('.body--wrapper>.vxe-table--header .vxe-header--row'),
|
||||
{
|
||||
|
@ -1305,49 +1110,13 @@ export default {
|
|||
)
|
||||
})
|
||||
},
|
||||
getChoiceValueStyle(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.style || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getChoiceValueIcon(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.icon || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getCellStyle({ row, rowIndex, $rowIndex, column, columnIndex, $columnIndex }) {
|
||||
const { property } = column
|
||||
const _find = this.preferenceAttrList.find((attr) => attr.name === property)
|
||||
if (
|
||||
_find &&
|
||||
_find.option &&
|
||||
_find.option.fontOptions &&
|
||||
row[`${property}`] !== undefined &&
|
||||
row[`${property}`] !== null
|
||||
) {
|
||||
return { ..._find.option.fontOptions }
|
||||
}
|
||||
},
|
||||
refreshAfterEditAttrs() {
|
||||
this.loadColumns()
|
||||
},
|
||||
getColumnsEditRender(col) {
|
||||
const _editRender = {
|
||||
...col.editRender,
|
||||
}
|
||||
if (col.value_type === '6') {
|
||||
_editRender.events = { focus: this.handleFocusJson }
|
||||
}
|
||||
return _editRender
|
||||
},
|
||||
handleEditActived() {
|
||||
const passwordCol = this.columns.filter((col) => col.is_password)
|
||||
this.$nextTick(() => {
|
||||
const editRecord = this.$refs.xTable.getEditRecord()
|
||||
const editRecord = this.$refs.xTable.getVxetableRef().getEditRecord()
|
||||
const { row, column } = editRecord
|
||||
if (passwordCol.length && this.lastEditCiId !== row._id) {
|
||||
this.$nextTick(async () => {
|
||||
|
@ -1358,10 +1127,10 @@ export default {
|
|||
})
|
||||
}
|
||||
this.isContinueCloseEdit = false
|
||||
await this.$refs.xTable.clearEdit()
|
||||
await this.$refs.xTable.getVxetableRef().clearEdit()
|
||||
this.isContinueCloseEdit = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.xTable.setEditCell(row, column.field)
|
||||
this.$refs.xTable.getVxetableRef().setEditCell(row, column.field)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1372,7 +1141,7 @@ export default {
|
|||
if (!this.isContinueCloseEdit) {
|
||||
return
|
||||
}
|
||||
const $table = this.$refs['xTable']
|
||||
const $table = this.$refs['xTable'].getVxetableRef()
|
||||
const data = {}
|
||||
this.columns.forEach((item) => {
|
||||
if (
|
||||
|
@ -1501,10 +1270,10 @@ export default {
|
|||
if (_find && _find.value_type === '6') jsonAttrList.push(key)
|
||||
})
|
||||
const data = _.cloneDeep([
|
||||
...this.$refs.xTable.getCheckboxReserveRecords(),
|
||||
...this.$refs.xTable.getCheckboxRecords(true),
|
||||
...this.$refs.xTable.getVxetableRef().getCheckboxReserveRecords(),
|
||||
...this.$refs.xTable.getVxetableRef().getCheckboxRecords(true),
|
||||
])
|
||||
this.$refs.xTable.exportData({
|
||||
this.$refs.xTable.getVxetableRef().exportData({
|
||||
filename,
|
||||
type,
|
||||
columnFilterMethod({ column }) {
|
||||
|
@ -1518,8 +1287,8 @@ export default {
|
|||
],
|
||||
})
|
||||
this.selectedRowKeys = []
|
||||
this.$refs.xTable.clearCheckboxRow()
|
||||
this.$refs.xTable.clearCheckboxReserve()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
this.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
},
|
||||
batchDelete() {
|
||||
const that = this
|
||||
|
@ -1543,25 +1312,13 @@ export default {
|
|||
.finally(() => {
|
||||
that.loading = false
|
||||
that.selectedRowKeys = []
|
||||
that.$refs.xTable.clearCheckboxRow()
|
||||
that.$refs.xTable.clearCheckboxReserve()
|
||||
that.$refs.xTable.getVxetableRef().clearCheckboxRow()
|
||||
that.$refs.xTable.getVxetableRef().clearCheckboxReserve()
|
||||
that.loadData({ parameter: {}, refreshType: 'refreshNumber' })
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
handleFocusJson({ column, row }) {
|
||||
this.$refs.jsonEditor.open(column, row)
|
||||
},
|
||||
jsonEditorOk(row, column, jsonData) {
|
||||
// 后端写数据有快慢,不拉接口直接修改table的数据
|
||||
this.instanceList.forEach((item) => {
|
||||
if (item._id === row._id) {
|
||||
item[column.property] = JSON.stringify(jsonData)
|
||||
}
|
||||
})
|
||||
this.$refs.xTable.refreshColumn()
|
||||
},
|
||||
relationViewRefreshNumber() {
|
||||
this.loadData({ parameter: {}, refreshType: 'refreshNumber' })
|
||||
},
|
||||
|
@ -1585,7 +1342,9 @@ export default {
|
|||
})
|
||||
},
|
||||
setPreferenceSearchCurrent(id = null) {
|
||||
this.$refs.preferenceSearch.currentPreferenceSearch = id
|
||||
this.$nextTick(() => {
|
||||
this.$refs.preferenceSearch.currentPreferenceSearch = id
|
||||
})
|
||||
},
|
||||
copyExpression() {
|
||||
const expression = this.$refs['search'].expression || ''
|
||||
|
@ -1846,8 +1605,8 @@ export default {
|
|||
return array
|
||||
},
|
||||
|
||||
getRowSeq(row) {
|
||||
return this.$refs.xTable.getRowSeq(row)
|
||||
openDetail(id, activeTabKey, ciDetailRelationKey) {
|
||||
this.$refs.detail.create(id, activeTabKey, ciDetailRelationKey)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1916,36 +1675,6 @@ export default {
|
|||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: @border-radius-box;
|
||||
|
||||
.checkbox-hover-table {
|
||||
.vxe-table--body-wrapper {
|
||||
.vxe-checkbox--label {
|
||||
display: inline;
|
||||
padding-left: 0px !important;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-checked ~ .vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-cell--checkbox {
|
||||
&:hover {
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -144,209 +144,25 @@
|
|||
</template>
|
||||
</div>
|
||||
</SearchForm>
|
||||
<ops-table
|
||||
:id="`cmdb-tree-${typeId}`"
|
||||
border
|
||||
|
||||
<CITable
|
||||
ref="xTable"
|
||||
size="small"
|
||||
keep-source
|
||||
:id="`cmdb-tree-${typeId}`"
|
||||
:loading="loading"
|
||||
:attrList="currentAttrList"
|
||||
:columns="columns"
|
||||
:passwordValue="passwordValue"
|
||||
:data="instanceList"
|
||||
highlight-hover-row
|
||||
show-overflow
|
||||
show-header-overflow
|
||||
row-id="_id"
|
||||
resizable
|
||||
:row-key="true"
|
||||
:column-key="true"
|
||||
:sort-config="{ remote: true, trigger: 'cell' }"
|
||||
@sort-change="handleSortCol"
|
||||
:cell-style="getCellStyle"
|
||||
:scroll-y="{ enabled: true, gt: 20 }"
|
||||
:scroll-x="{ enabled: true, gt: 0 }"
|
||||
:height="`${windowHeight - 240}px`"
|
||||
@checkbox-change="onSelectChange"
|
||||
@checkbox-all="onSelectChange"
|
||||
@checkbox-range-end="onSelectRangeEnd"
|
||||
:checkbox-config="{ reserve: true, highlight: true, range: true }"
|
||||
:loadingTip="loadTip"
|
||||
@onSelectChange="onSelectChange"
|
||||
@edit-closed="handleEditClose"
|
||||
@edit-actived="handleEditActived"
|
||||
:edit-config="{ trigger: 'dblclick', mode: 'row', showIcon: false }"
|
||||
class="ops-unstripe-table checkbox-hover-table"
|
||||
:custom-config="{ storage: true }"
|
||||
>
|
||||
<vxe-column align="center" type="checkbox" width="60" :fixed="isCheckboxFixed ? 'left' : ''">
|
||||
<template #default="{row}">
|
||||
{{ getRowSeq(row) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-table-column
|
||||
v-for="(col, index) in columns"
|
||||
:key="`${col.field}_${index}`"
|
||||
:title="col.title"
|
||||
:field="col.field"
|
||||
:width="col.width"
|
||||
:sortable="col.sortable"
|
||||
:edit-render="getColumnsEditRender(col)"
|
||||
:cell-type="col.value_type === '2' ? 'string' : 'auto'"
|
||||
:fixed="col.is_fixed ? 'left' : ''"
|
||||
>
|
||||
<template #header>
|
||||
<span class="vxe-handle">
|
||||
<OpsMoveIcon
|
||||
style="width: 17px; height: 17px; display: none; position: absolute; left: -3px; top: 12px"
|
||||
/>
|
||||
{{ col.title }}</span
|
||||
>
|
||||
</template>
|
||||
<template v-if="col.is_choice || col.is_password" #edit="{ row }">
|
||||
<vxe-input v-if="col.is_password" v-model="passwordValue[col.field]" />
|
||||
<a-select
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
:style="{ width: '100%', height: '32px' }"
|
||||
v-model="row[col.field]"
|
||||
:placeholder="$t('placeholder2')"
|
||||
v-if="col.is_choice"
|
||||
:showArrow="false"
|
||||
:mode="col.is_list ? 'multiple' : 'default'"
|
||||
class="ci-table-edit-select"
|
||||
allowClear
|
||||
>
|
||||
<a-select-option
|
||||
:value="choice[0]"
|
||||
:key="'edit_' + col.field + idx"
|
||||
v-for="(choice, idx) in col.filters"
|
||||
>
|
||||
<span
|
||||
:style="{ ...(choice[1] ? choice[1].style : {}), display: 'inline-flex', alignItems: 'center' }"
|
||||
>
|
||||
<template v-if="choice[1] && choice[1].icon && choice[1].icon.name">
|
||||
<img
|
||||
v-if="choice[1].icon.id && choice[1].icon.url"
|
||||
:src="`/api/common-setting/v1/file/${choice[1].icon.url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: choice[1].icon.color, marginRight: '5px' }"
|
||||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
{{ choice[0] }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template
|
||||
v-if="col.value_type === '6' || col.is_link || col.is_password || col.is_choice"
|
||||
#default="{row}"
|
||||
>
|
||||
<span v-if="col.value_type === '6' && row[col.field]">{{ row[col.field] }}</span>
|
||||
<template v-else-if="col.is_link && row[col.field]">
|
||||
<a
|
||||
v-for="(item, linkIndex) in (col.is_list ? row[col.field] : [row[col.field]])"
|
||||
:key="linkIndex"
|
||||
:href="
|
||||
item.startsWith('http') || item.startsWith('https')
|
||||
? `${item}`
|
||||
: `http://${item}`
|
||||
"
|
||||
target="_blank"
|
||||
>
|
||||
{{ item }}
|
||||
</a>
|
||||
</template>
|
||||
<PasswordField
|
||||
v-else-if="col.is_password && row[col.field]"
|
||||
:ci_id="row._id"
|
||||
:attr_id="col.attr_id"
|
||||
></PasswordField>
|
||||
<template v-else-if="col.is_choice">
|
||||
<template v-if="col.is_list">
|
||||
<span
|
||||
v-for="value in row[col.field]"
|
||||
:key="value"
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px',
|
||||
...getChoiceValueStyle(col, value),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, value).id && getChoiceValueIcon(col, value).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, value).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>{{ value }}</span
|
||||
>
|
||||
</template>
|
||||
<span
|
||||
v-else-if="row[col.field]"
|
||||
:style="{
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
margin: '2px 0',
|
||||
...getChoiceValueStyle(col, row[col.field]),
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="getChoiceValueIcon(col, row[col.field]).id && getChoiceValueIcon(col, row[col.field]).url"
|
||||
:src="`/api/common-setting/v1/file/${getChoiceValueIcon(col, row[col.field]).url}`"
|
||||
:style="{ maxHeight: '13px', maxWidth: '13px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else
|
||||
:style="{ color: getChoiceValueIcon(col, row[col.field]).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, row[col.field]).name"
|
||||
/>{{ row[col.field] }}</span
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column align="left" field="operate" fixed="right" width="120">
|
||||
<template #header>
|
||||
<span>{{ $t('operation') }}</span>
|
||||
</template>
|
||||
<template #default="{ row }">
|
||||
<a-space>
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id)">
|
||||
<a-icon type="unordered-list" />
|
||||
</a>
|
||||
<a-tooltip :title="$t('cmdb.ci.addRelation')">
|
||||
<a @click="$refs.detail.create(row.ci_id || row._id, 'tab_2', '2')">
|
||||
<a-icon type="retweet" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<template>
|
||||
<a-tooltip :title="$t('cmdb.ciType.deleteInstance')">
|
||||
<a @click="deleteCI(row)" :style="{ color: 'red' }">
|
||||
<a-icon type="delete" />
|
||||
</a>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-space>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<template #empty>
|
||||
<div v-if="loading" style="height: 200px; line-height: 200px">{{ $t('loading') }}</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '200px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #loading>
|
||||
<div style="height: 200px; line-height: 200px">{{ loadTip || $t('loading') }}</div>
|
||||
</template>
|
||||
</ops-table>
|
||||
@sort-change="handleSortCol"
|
||||
@openDetail="openDetail"
|
||||
@deleteCI="deleteCI"
|
||||
/>
|
||||
|
||||
<div :style="{ textAlign: 'right', marginTop: '4px' }">
|
||||
<a-pagination
|
||||
:showSizeChanger="true"
|
||||
|
@ -398,7 +214,6 @@
|
|||
@reload="sumbitFromCreateInstance"
|
||||
@submit="batchUpdateFromCreateInstance"
|
||||
/>
|
||||
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
|
||||
<BatchDownload ref="batchDownload" @batchDownload="batchDownload" />
|
||||
<MetadataDrawer ref="metadataDrawer" />
|
||||
</div>
|
||||
|
@ -420,38 +235,36 @@ import { getCITypes } from '@/modules/cmdb/api/CIType'
|
|||
import { getCITableColumns } from '../../utils/helper'
|
||||
import SearchForm from '../../components/searchForm/SearchForm.vue'
|
||||
import SubscribeSetting from '../../components/subscribeSetting/subscribeSetting'
|
||||
import PasswordField from '../../components/passwordField/index.vue'
|
||||
import SplitPane from '@/components/SplitPane'
|
||||
import TreeViewsNode from './modules/treeViewsNode.vue'
|
||||
import EditAttrsPopover from '../ci/modules/editAttrsPopover.vue'
|
||||
import CiDetailDrawer from '../ci/modules/ciDetailDrawer.vue'
|
||||
import CreateInstanceForm from '../ci/modules/CreateInstanceForm'
|
||||
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
|
||||
import JsonEditor from '../../components/JsonEditor/jsonEditor.vue'
|
||||
import BatchDownload from '../../components/batchDownload/batchDownload.vue'
|
||||
import PreferenceSearch from '../../components/preferenceSearch/preferenceSearch.vue'
|
||||
import MetadataDrawer from '../ci/modules/MetadataDrawer.vue'
|
||||
import { intersection } from '@/utils/functions/set'
|
||||
import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
|
||||
import { getAttrPassword } from '../../api/CITypeAttr'
|
||||
import CITable from '@/modules/cmdb/components/ciTable/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'TreeViews',
|
||||
components: {
|
||||
SearchForm,
|
||||
SubscribeSetting,
|
||||
PasswordField,
|
||||
SplitPane,
|
||||
TreeViewsNode,
|
||||
EditAttrsPopover,
|
||||
CiDetailDrawer,
|
||||
CreateInstanceForm,
|
||||
JsonEditor,
|
||||
BatchDownload,
|
||||
PreferenceSearch,
|
||||
MetadataDrawer,
|
||||
OpsMoveIcon,
|
||||
draggable,
|
||||
CITable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -516,10 +329,6 @@ export default {
|
|||
const _find = this.subscribeTreeViewCiTypes.find((item) => item.type_id === Number(this.typeId))
|
||||
return _find?.id
|
||||
},
|
||||
isCheckboxFixed() {
|
||||
const idx = this.columns.findIndex((item) => item.is_fixed)
|
||||
return idx > -1
|
||||
},
|
||||
currentCiTypeName() {
|
||||
const _find = this.citypes.find((item) => Number(item.id) === Number(this.typeId))
|
||||
return _find?.alias || _find?.name || ''
|
||||
|
@ -858,33 +667,6 @@ export default {
|
|||
this.currentPage = 1
|
||||
this.handleLoadInstance({ sortByTable })
|
||||
},
|
||||
getChoiceValueStyle(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.style || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getChoiceValueIcon(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.icon || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
getCellStyle({ row, rowIndex, $rowIndex, column, columnIndex, $columnIndex }) {
|
||||
const { property } = column
|
||||
const _find = this.currentAttrList.find((attr) => attr.name === property)
|
||||
if (
|
||||
_find &&
|
||||
_find.option &&
|
||||
_find.option.fontOptions &&
|
||||
row[`${property}`] !== undefined &&
|
||||
row[`${property}`] !== null
|
||||
) {
|
||||
return { ..._find.option.fontOptions }
|
||||
}
|
||||
},
|
||||
onNodeClick(keys, type) {
|
||||
console.log(keys)
|
||||
if (keys) {
|
||||
|
@ -921,9 +703,7 @@ export default {
|
|||
},
|
||||
})
|
||||
},
|
||||
onSelectChange(e) {
|
||||
const xTable = this.$refs.xTable.getVxetableRef()
|
||||
const records = [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()]
|
||||
onSelectChange(records) {
|
||||
this.selectedRowKeys = records.map((i) => i.ci_id || i._id)
|
||||
},
|
||||
setSelectRows() {
|
||||
|
@ -942,9 +722,6 @@ export default {
|
|||
this.$refs['xTable'].getVxetableRef().setCheckboxRow(rows, true)
|
||||
}
|
||||
},
|
||||
onSelectRangeEnd({ records }) {
|
||||
this.selectedRowKeys = records.map((i) => i.ci_id || i._id)
|
||||
},
|
||||
handleEditActived() {
|
||||
const passwordCol = this.columns.filter((col) => col.is_password)
|
||||
this.$nextTick(() => {
|
||||
|
@ -1023,28 +800,6 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
jsonEditorOk(row, column, jsonData) {
|
||||
// 后端写数据有快慢,不拉接口直接修改table的数据
|
||||
// this.reloadData()
|
||||
this.instanceList.forEach((item) => {
|
||||
if (item._id === row._id) {
|
||||
item[column.property] = JSON.stringify(jsonData)
|
||||
}
|
||||
})
|
||||
this.$refs.xTable.getVxetableRef().refreshColumn()
|
||||
},
|
||||
getColumnsEditRender(col) {
|
||||
const _editRender = {
|
||||
...col.editRender,
|
||||
}
|
||||
if (col.value_type === '6') {
|
||||
_editRender.events = { focus: this.handleFocusJson }
|
||||
}
|
||||
return _editRender
|
||||
},
|
||||
handleFocusJson({ column, row }) {
|
||||
this.$refs.jsonEditor.open(column, row)
|
||||
},
|
||||
async openBatchDownload() {
|
||||
this.$refs.batchDownload.open({ preferenceAttrList: this.currentAttrList, ciTypeName: this.currentCiTypeName })
|
||||
},
|
||||
|
@ -1237,8 +992,8 @@ export default {
|
|||
}
|
||||
)
|
||||
},
|
||||
getRowSeq(row) {
|
||||
return this.$refs.xTable.getVxetableRef().getRowSeq(row)
|
||||
openDetail(id, activeTabKey, ciDetailRelationKey) {
|
||||
this.$refs.detail.create(id, activeTabKey, ciDetailRelationKey)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1348,36 +1103,6 @@ export default {
|
|||
overflow: auto;
|
||||
width: 100%;
|
||||
border-radius: @border-radius-box;
|
||||
|
||||
.checkbox-hover-table {
|
||||
.vxe-table--body-wrapper {
|
||||
.vxe-checkbox--label {
|
||||
display: inline;
|
||||
padding-left: 0px !important;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-icon-checkbox-checked ~ .vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vxe-cell--checkbox {
|
||||
&:hover {
|
||||
.vxe-icon-checkbox-unchecked {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.vxe-checkbox--label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue