Compare commits

...

6 Commits

Author SHA1 Message Date
ibuler
1e777ea67d perf: remove check 2024-12-10 17:28:58 +08:00
ibuler
a290e15b90 perf: 修改抽屉,传递动作 2023-11-08 19:18:49 +08:00
“huailei000”
b47f396cd4 perf: 详情暂时不显示更新按钮 2023-11-08 18:22:35 +08:00
“huailei000”
085554ef7f perf: 优化资产授权报错 2023-11-08 17:15:05 +08:00
feng
a62884564c perf: 在线用户根据websocket添加用户是否活跃状态 2023-11-08 17:03:01 +08:00
fit2bot
a9c0d0677c feat: 右侧抽屉创建 (#3436)
* stash

* perf: 验证用户和网域

* perf: 优化 drawer

* perf: 优化创建后 list reload

* perf: 优化创建

* perf: 替换账号管理相关页面创建、更新组件

* perf: 替换权限管理相关页面组件

* perf: 优化资产这里

* perf: 修改 reload

* perf: 替换权限管理-用户登录页面组件

* perf: 修改资产这里

* perf: 优化一点

* perf: 优化平台列表创建、更新抽屉组件不能正常显示问题

* perf: 优化平台列表创建时表单初始化数据不准确问题

* perf: 优化创建、更新平台表单报错问题

* perf: 优化列表克隆问题

* perf: 优化创建资产时抽屉组件偶尔不显示问题

* perf: 优化工作台创建、更新组件

* perf: GenericCreateUpdateDrawer 组件增加参数visible控制显示隐藏

* perf: 优化visible判断

* perf: 优化资产创建、更新

* perf: 增加el-drawer组件补丁,防止在抽屉里复制拖拽至遮罩层会使抽屉关闭问题

* perf: 优化角色列表创建、更新报错问题;优化关闭抽屉控制台报错问题

* perf: 优化作业管理创建、更新

* perf: 优化工单创建

* perf: 优化远程应用创建、更新

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: “huailei000” <2280131253@qq.com>
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: huailei <31801270+huailei000@users.noreply.github.com>
2023-11-08 11:21:39 +08:00
112 changed files with 1106 additions and 695 deletions

View File

@@ -5,11 +5,10 @@
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
"serve": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
"build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"fix": "eslint --ext .js,.vue --fix src",

View File

@@ -1,16 +1,5 @@
<template>
<Dialog
v-if="iVisible"
:close-on-click-modal="false"
:destroy-on-close="true"
:show-cancel="false"
:show-confirm="false"
:title="title"
:visible.sync="iVisible"
v-bind="$attrs"
width="70%"
v-on="$listeners"
>
<GenericCreateUpdateDrawer v-bind="$attrs">
<AccountCreateUpdateForm
v-if="!loading"
ref="form"
@@ -20,18 +9,18 @@
@add="addAccount"
@edit="editAccount"
/>
</Dialog>
</GenericCreateUpdateDrawer>
</template>
<script>
import Dialog from '@/components/Dialog/index.vue'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
import AccountCreateUpdateForm from '@/components/Apps/AccountCreateUpdateForm/index.vue'
export default {
name: 'CreateAccountDialog',
components: {
Dialog,
AccountCreateUpdateForm
AccountCreateUpdateForm,
GenericCreateUpdateDrawer
},
props: {
visible: {

View File

@@ -14,21 +14,11 @@
@updateAuthDone="onUpdateAuthDone"
/>
<AccountCreateUpdate
v-if="showAddDialog"
:account="account"
:url="url"
:asset="iAsset"
:title="accountCreateUpdateTitle"
:visible.sync="showAddDialog"
@add="addAccountSuccess"
@bulk-create-done="showBulkCreateResult($event)"
/>
<AccountCreateUpdate
v-if="showAddTemplateDialog"
:account="account"
:add-template="true"
:asset="iAsset"
:add-template="addTemplate"
:title="accountCreateUpdateTitle"
:visible.sync="showAddTemplateDialog"
@add="addAccountSuccess"
@bulk-create-done="showBulkCreateResult($event)"
/>
@@ -128,6 +118,7 @@ export default {
showAddDialog: false,
showAddTemplateDialog: false,
createAccountResults: [],
addTemplate: false,
accountCreateUpdateTitle: this.$t('assets.AddAccount'),
iAsset: this.asset,
account: {},
@@ -258,7 +249,7 @@ export default {
name: 'Update',
title: this.$t('common.Update'),
can: this.$hasPerm('accounts.change_account') && !this.$store.getters.currentOrgIsRoot,
callback: ({ row }) => {
callback: ({ row, col }) => {
const data = {
...this.asset,
...row.asset
@@ -266,9 +257,10 @@ export default {
vm.account = row
vm.iAsset = data
vm.showAddDialog = false
vm.addTemplate = false
vm.accountCreateUpdateTitle = this.$t('assets.UpdateAccount')
setTimeout(() => {
vm.showAddDialog = true
vm.$eventBus.$emit('showCreateUpdateDrawer', 'update', { url: this.url, row, col })
})
}
}
@@ -313,8 +305,9 @@ export default {
setTimeout(() => {
vm.iAsset = this.asset
vm.account = {}
vm.addTemplate = false
vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
vm.showAddDialog = true
vm.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: vm.url })
})
}
},
@@ -330,8 +323,9 @@ export default {
setTimeout(() => {
vm.iAsset = this.asset
vm.account = {}
vm.addTemplate = true
vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
vm.showAddTemplateDialog = true
vm.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: vm.url })
})
}
},

View File

@@ -86,7 +86,7 @@ export default {
{
prop: 'protocols',
formatter: function(row) {
const data = row.protocols.map(p => {
const data = row.protocols?.map(p => {
return <el-tag size='mini'>{p.name}/{p.port} </el-tag>
})
return <span> {data} </span>

View File

@@ -1,19 +1,22 @@
<template>
<ElFormRender
ref="form"
:class="mobile? 'mobile' : 'desktop'"
:content="fields"
:form="basicForm"
:label-position="labelPosition"
label-width="20%"
v-bind="$attrs"
v-on="$listeners"
>
<!-- slot 透传 -->
<slot v-for="item in fields" :slot="`id:${item.id}`" :name="`id:${item.id}`" />
<slot v-for="item in fields" :slot="`$id:${item.id}`" :name="`$id:${item.id}`" />
<div>
<ElFormRender
ref="form"
:class="mobile? 'mobile' : 'desktop'"
:content="fields"
:form="basicForm"
:label-position="labelPosition"
class="form-fields"
label-width="22%"
v-bind="$attrs"
v-on="$listeners"
>
<!-- slot 透传 -->
<slot v-for="item in fields" :slot="`id:${item.id}`" :name="`id:${item.id}`" />
<slot v-for="item in fields" :slot="`$id:${item.id}`" :name="`$id:${item.id}`" />
<el-form-item v-if="hasButtons" class="form-buttons">
</ElFormRender>
<div v-if="hasButtons" class="form-buttons">
<el-button
v-for="button in moreButtons"
:key="button.title"
@@ -44,8 +47,8 @@
>
{{ submitBtnText }}
</el-button>
</el-form-item>
</ElFormRender>
</div>
</div>
</template>
<script>
@@ -160,7 +163,7 @@ export default {
}
.el-form ::v-deep .el-form-item__content {
width: 75%;
width: 73%;
}
.mobile.el-form ::v-deep .el-form-item__content {
@@ -198,5 +201,7 @@ export default {
.form-buttons {
margin-top: 20px;
margin-left: 22%;
margin-bottom: 20px;
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div :class="bolder ? 'bolder' : ''" class="input-text">
<div class="input-text">
{{ value.toString() || text }}
</div>
</template>
@@ -9,15 +9,11 @@ export default {
props: {
value: {
type: [String, Boolean],
default: ''
default: () => ''
},
text: {
type: String,
default: ''
},
bolder: {
type: Boolean,
default: true
default: () => ''
}
},
data() {

View File

@@ -75,6 +75,9 @@ export default {
}
})
},
beforeDestroy() {
this.$eventBus.$off('showColumnSettingPopover')
},
methods: {
handleColumnConfirm() {
this.showColumnSettingPopover = false

View File

@@ -124,8 +124,8 @@ export default {
watch: {},
methods: {
getList() {
this.$refs.table.clearSelection()
return this.$refs.table.getList()
this.$refs.table?.clearSelection()
return this.$refs.table?.getList()
},
getData() {
return this.$refs.table.data

View File

@@ -174,6 +174,9 @@ export default {
}
})
},
beforeDestroy() {
this.$eventBus.$off('showExportDialog')
},
methods: {
showExportDialog() {
if (!this.mfaVerifyRequired) {

View File

@@ -147,6 +147,9 @@ export default {
}
})
},
beforeDestroy() {
this.$eventBus.$off('showImportDialog')
},
methods: {
closeDialog() {
this.showImportDialog = false

View File

@@ -38,6 +38,10 @@ export default {
type: Boolean,
default: false
},
createInDrawer: {
type: Boolean,
default: true
},
hasBulkDelete: defaultTrue,
canBulkDelete: defaultTrue,
hasBulkUpdate: defaultFalse,
@@ -187,6 +191,10 @@ export default {
},
methods: {
handleCreate() {
if (this.createInDrawer) {
this.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: this.tableUrl })
return
}
let route
if (typeof this.createRoute === 'string') {
route = { name: this.createRoute }

View File

@@ -79,11 +79,11 @@ export default {
computed: {
...mapGetters(['currentOrgIsRoot']),
dataTable() {
return this.$refs.dataTable.$refs.dataTable
return this.$refs.dataTable?.$refs?.dataTable
},
iHeaderActions() {
// 如果路由中锁定了 root 组织,就不在检查 root 组织下是否可以创建等
const checkRoot = !(this.$route.meta?.disableOrgsChange === true)
const checkRoot = this.$route.meta?.disableOrgsChange !== true
const actions = {
canCreate: { action: 'add', checkRoot: checkRoot },
canBulkDelete: { action: 'delete', checkRoot: false },
@@ -108,7 +108,7 @@ export default {
const config = deepmerge(this.tableConfig, {
extraQuery: this.extraQuery
})
const checkRoot = !(this.$route.meta?.disableOrgsChange === true)
const checkRoot = this.$route.meta?.disableOrgsChange !== true
const formatterArgs = {
'columnsMeta.actions.formatterArgs.canUpdate': () => {
return this.hasActionPerm('change') && (!checkRoot || !this.currentOrgIsRoot)
@@ -165,12 +165,29 @@ export default {
deep: true
}
},
mounted() {
this.$eventBus.$on('closeCreateUpdateDrawer', ({ success }) => {
if (!success) {
return
}
this.extraQuery = {
...this.extraQuery,
order: '-date_updated'
}
setTimeout(() => {
this.reloadTable()
})
})
},
beforeDestroy() {
this.$eventBus.$off('closeCreateUpdateDrawer')
},
methods: {
handleSelectionChange(val) {
this.selectedRows = val
},
reloadTable() {
this.dataTable.getList()
this.dataTable?.getList()
},
search(attrs) {
this.$emit('TagSearch', attrs)

View File

@@ -102,6 +102,9 @@ export default {
this.componentKey += 1
})
},
beforeDestroy() {
this.$eventBus.$off('treeComponentKey')
},
methods: {
hideRMenu() {
this.$refs.AutoDataZTree?.hideRMenu()

View File

@@ -21,34 +21,12 @@ const defaultPerformDelete = function({ row, col }) {
}
const defaultUpdateCallback = function({ row, col }) {
const id = row.id
let route = { params: { id: id }}
const updateRoute = this.colActions.updateRoute
console.log('Update route: ', updateRoute)
if (typeof updateRoute === 'object') {
route = Object.assign(route, updateRoute)
} else if (typeof updateRoute === 'function') {
route = updateRoute({ row, col })
} else {
route.name = updateRoute
}
this.$router.push(route)
this.$eventBus.$emit('showCreateUpdateDrawer', 'update', { url: this.url, row, col })
}
const defaultCloneCallback = function({ row, col }) {
const id = row.id
let route = { query: { clone_from: id }}
const cloneRoute = this.colActions.cloneRoute
if (typeof cloneRoute === 'object') {
route = Object.assign(route, cloneRoute)
} else if (typeof cloneRoute === 'function') {
route = cloneRoute({ row, col })
} else {
route.name = cloneRoute
}
this.$router.push(route)
console.log('Url: ', this.url)
this.$eventBus.$emit('showCreateUpdateDrawer', 'clone', { url: this.url, row, col })
}
const defaultDeleteCallback = function({ row, col, cellValue, reload }) {

View File

@@ -1475,6 +1475,7 @@
"terminal": {
"OnlineSessionHelpMsg": "The current session cannot be offline because it is an online session of the current user. Currently, only users who have logged in through web mode are recorded.",
"Offline": "Offline",
"Active": "Active",
"OfflineSuccessMsg": "Offline success",
"BulkOffline": "Bulk offline",
"Marketplace": "Marketplace",

View File

@@ -1467,6 +1467,7 @@
},
"terminal": {
"Offline": "オフライン",
"Active": "アクティブ",
"OnlineSessionHelpMsg": "セッションが現在のユーザーのオンラインセッションであるため、現在のセッションをオフラインできません。現在はWebログイン済みのユーザーのみが記録されています。",
"OfflineSuccessMsg": "オフラインに成功しました",
"BulkOffline": "オフライン",

View File

@@ -1441,6 +1441,7 @@
"terminal": {
"OnlineSessionHelpMsg": "无法下线当前会话,因为该会话是当前用户的在线会话。当前只记录以 Web 方式登录的用户。",
"Offline": "下线",
"Active": "活跃",
"OfflineSuccessMsg": "下线成功",
"BulkOffline": "批量下线",
"Marketplace": "应用市场",
@@ -2102,6 +2103,7 @@
"SaveSetting": "同步设置",
"Name": "名称",
"Account": "云账号",
"CreateAccount": "创建云账号",
"Node": "节点",
"WindowsAdminUser": "Windows 特权用户",
"LinuxAdminUser": "Linux 特权用户",

View File

@@ -0,0 +1,187 @@
<template>
<el-drawer
:direction="direction"
:modal="false"
:size="width"
:title="iTitle"
:visible.sync="iVisible"
append-to-body
class="drawer generic-create-update-drawer"
wrapper-closable
v-on="$listeners"
>
<div class="el-drawer__content">
<slot>
<GenericCreateUpdateForm
v-if="iVisible"
:action="iAction"
:action-id="iActionId"
v-bind="$attrs"
@submitSuccess="onSubmitSuccess"
v-on="$listeners"
/>
</slot>
</div>
</el-drawer>
</template>
<script>
import GenericCreateUpdateForm from '../GenericCreateUpdateForm/index.vue'
export default {
name: 'GenericCreateUpdateDrawer',
components: {
GenericCreateUpdateForm
},
props: {
direction: {
type: String,
default: 'rtl'
},
title: {
type: String,
default: ''
},
resource: {
type: String,
default: ''
},
width: {
type: String,
default: '700px'
},
name: {
type: String,
default: ''
},
action: {
type: String,
default: 'create'
},
actionId: {
type: String,
default: ''
},
visible: {
type: Boolean,
default: false
},
actionMeta: {
type: Object,
default: () => ({})
}
},
data() {
return {
iVisible: this.visible,
iAction: this.action,
iActionId: this.actionId,
success: false
}
},
computed: {
iTitle() {
if (this.title) {
return this.title
}
let resource = this.resource
if (!resource) {
const routeName = this.$route.meta.title || this.$route.name
resource = routeName.replace('List', '')
.replace('列表', '')
}
let title
if (this.iAction === 'update') {
title = this.$t('common.Update') + ' ' + resource
} else {
title = this.$t('common.Create') + ' ' + resource
}
return title
}
},
watch: {
visible(val) {
this.setVisible(val)
},
iVisible(val) {
if (!val) {
this.iVisible = false
this.$eventBus.$emit(
'closeCreateUpdateDrawer',
{ action: this.iAction, actionId: this.iActionId, success: this.success }
)
this.$emit('close', { action: this.iAction, actionId: this.iActionId, success: this.success })
}
}
},
mounted() {
this.$eventBus.$on('showCreateUpdateDrawer', (action, { url, row }) => {
const tableUrl = this.$attrs.url
this.$log.debug('Table url: ', tableUrl, ' action url: ', url, 'action: ', action, 'row: ', row)
if (!tableUrl || !url) {
return
}
const tablePath = tableUrl.split('?')[0]
const actionPath = url.split('?')[0]
if (tablePath !== actionPath) {
return
}
this.iAction = action
this.iActionId = row ? row.id : ''
this.$emit('update:actionMeta', { action: action, actionId: this.iActionId, row: row })
this.setVisible(true)
})
},
beforeDestroy() {
this.$eventBus.$off('showCreateUpdateDrawer')
},
methods: {
setVisible: _.debounce(function(val) {
this.iVisible = val
}, 100),
onSubmitSuccess(res, { addContinue }) {
this.success = true
if (!addContinue) {
this.iVisible = false
}
}
}
}
</script>
<style lang='scss' scoped>
.ibox >>> .el-card__body {
padding-top: 30px;
}
.el-drawer__content {
>>> .form-fields {
overflow: auto;
max-height: calc(100vh - 150px);
}
>>> .form-buttons {
//position: absolute;
//bottom: 15px;
width: 100%;
background: white;
}
}
.el-drawer__footer {
text-align: right;
vertical-align: middle;
padding-right: 52px;
border-top: solid 1px #ebeef5;
}
.drawer >>> .el-drawer__header {
font-weight: 500;
font-size: 16px;
}
.el-drawer__footer_buttons {
margin-top: 10px;
}
</style>

View File

@@ -7,6 +7,7 @@
:has-save-continue="iHasSaveContinue"
:is-submitting="isSubmitting"
:method="method"
:submit-btn-text="submitBtnText"
:url="iUrl"
v-bind="$attrs"
@afterRemoteMeta="handleAfterRemoteMeta"
@@ -18,7 +19,6 @@
import AutoDataForm from '@/components/Form/AutoDataForm'
import { getUpdateObjURL } from '@/utils/common'
import { encryptPassword } from '@/utils/crypto'
import deepmerge from 'deepmerge'
export default {
name: 'GenericCreateUpdateForm',
@@ -31,6 +31,14 @@ export default {
type: String,
default: ''
},
action: {
type: String,
default: ''
},
actionId: {
type: [String, Number],
default: ''
},
// 更新的对象
object: {
type: Object,
@@ -116,19 +124,11 @@ export default {
return { name: routeName }
}
},
// 获取下一个路由
getNextRoute: {
type: Function,
default(res, method) {
return method === 'post' ? this.createSuccessNextRoute : this.updateSuccessNextRoute
}
},
// 获取提交的方法
submitMethod: {
type: [Function, String],
default: function() {
const params = this.$route.params
if (params.id) {
if (this.action === 'update') {
return 'put'
} else {
return 'post'
@@ -139,20 +139,20 @@ export default {
getUrl: {
type: Function,
default: function() {
const params = this.$route.params
let url = this.url
if (params.id) {
url = getUpdateObjURL(url, params.id)
if (this.action === 'update') {
url = getUpdateObjURL(url, this.actionId)
}
const clone_from = this.$route.query['clone_from']
const query = clone_from ? `clone_from=${clone_from}` : ''
if (query) {
if (url.indexOf('?') === -1) {
url = `${url}?${query}`
} else {
url = `${url}&${query}`
}
const cloneFrom = this.action === 'clone' ? this.actionId : ''
const query = cloneFrom ? `clone_from=${cloneFrom}` : ''
if (!query) {
return url
}
if (url.indexOf('?') === -1) {
url = `${url}?${query}`
} else {
url = `${url}&${query}`
}
return url
}
@@ -204,18 +204,8 @@ export default {
onPerformSuccess: {
type: Function,
default(res, method, vm, addContinue) {
const route = this.getNextRoute(res, method)
if (!(route.params && route.params.id)) {
route['params'] = deepmerge(route['params'] || {}, { 'id': res.id, order: this.extraQueryOrder })
} else {
route['params'] = deepmerge(route['params'], { order: this.extraQueryOrder })
}
this.$emit('submitSuccess', res)
this.$emit('submitSuccess', res, { method, vm, addContinue })
this.emitPerformSuccessMsg(method, res, addContinue)
if (!addContinue) {
setTimeout(() => this.$router.push(route), 100)
}
}
},
onPerformError: {
@@ -292,6 +282,13 @@ export default {
return this.hasReset
}
return this.isUpdateMethod()
},
submitBtnText() {
if (this.action === 'update') {
return this.$t('common.Update')
} else {
return this.$t('common.Create')
}
}
},
async created() {
@@ -306,6 +303,8 @@ export default {
this.loading = false
}
},
mounted() {
},
methods: {
isUpdateMethod() {
return ['put', 'patch'].indexOf(this.method.toLowerCase()) > -1
@@ -348,25 +347,26 @@ export default {
})
},
async getFormValue() {
const cloneFrom = this.$route.query['clone_from']
if ((!this.isUpdateMethod() && !cloneFrom) || !this.needGetObjectDetail) {
const cloneFrom = this.actionId
if (this.action === 'create' || !this.needGetObjectDetail) {
return Object.assign(this.form, this.initial)
}
let object = this.object
if (!object || Object.keys(object).length === 0) {
if (cloneFrom) {
const [curUrl, query] = this.url.split('?')
const url = `${curUrl}${cloneFrom}/${query ? ('?' + query) : ''}`
object = await this.getObjectDetail(url)
if (object['name']) {
object.name = this.$t('common.cloneFrom') + object.name
} else if (object['hostname']) {
object.hostname = this.$t('common.cloneFrom') + object.hostname
object.name = this.$t('common.cloneFrom') + '' + object.name
}
} else {
object = await this.getObjectDetail(this.iUrl)
if (object && Object.keys(object).length > 0) {
return object
}
if (this.action === 'clone') {
const [curUrl, query] = this.url.split('?')
const url = `${curUrl}${cloneFrom}/${query ? ('?' + query) : ''}`
object = await this.getObjectDetail(url)
if (object['name']) {
object.name = this.$t('common.cloneFrom') + object.name
} else if (object['hostname']) {
object.hostname = this.$t('common.cloneFrom') + object.hostname
object.name = this.$t('common.cloneFrom') + '' + object.name
}
} else {
object = await this.getObjectDetail(this.iUrl)
}
if (object) {
object = _.cloneDeep(object)

View File

@@ -129,13 +129,14 @@ export default {
...mapGetters(['currentOrgIsRoot']),
pageActions() {
return [
{
name: 'update',
title: this.$t('common.Update'),
can: this.validActions.canUpdate,
has: this.validActions.hasUpdate,
callback: this.validActions.updateCallback.bind(this)
},
// 暂时处理,详情中关闭更新操作
// {
// name: 'update',
// title: this.$t('common.Update'),
// can: this.validActions.canUpdate,
// has: this.validActions.hasUpdate,
// callback: this.validActions.updateCallback.bind(this)
// },
{
name: 'delete',
title: this.$t('common.Delete'),

View File

@@ -1,16 +1,17 @@
<template>
<Page v-bind="$attrs">
<GenericListTable ref="ListTable" v-bind="$attrs" />
<ListTable ref="ListTable" v-bind="$attrs" />
</Page>
</template>
<script>
import Page from '@/layout/components/Page'
import GenericListTable from '@/layout/components/GenericListTable'
import ListTable from '@/components/Table/ListTable/index'
export default {
name: 'GenericListPage',
components: {
Page, GenericListTable
Page, ListTable
}
}
</script>

View File

@@ -43,7 +43,7 @@
import Page from '../Page/'
import merge from 'webpack-merge'
const ACTIVE_TAB_KEY = 'activeTab'
const ACTIVE_TAB_KEY = 'tab'
export default {
name: 'TabPage',
@@ -109,18 +109,21 @@ export default {
},
created() {
this.iActiveMenu = this.getPropActiveTab()
this.setToRoute()
},
methods: {
handleTabClick(tab) {
this.$emit('tab-click', tab)
this.$emit('update:activeMenu', tab.name)
this.$cookie.set(ACTIVE_TAB_KEY, tab.name, 1)
if (this.$router.currentRoute.query[ACTIVE_TAB_KEY]) {
this.setToRoute()
},
setToRoute() {
setTimeout(() => {
this.$router.push({
query: merge(this.$route.query, { [ACTIVE_TAB_KEY]: '' })
query: merge(this.$route.query, { [ACTIVE_TAB_KEY]: this.iActiveMenu })
})
}
})
},
getPropActiveTab() {
let activeTab = ''

View File

@@ -9,6 +9,7 @@ export { default as GenericListPage } from './GenericListPage'
export { default as GenericListTable } from './GenericListTable'
export { default as GenericDetailPage } from './GenericDetailPage'
export { default as GenericCreateUpdatePage } from './GenericCreateUpdatePage'
export { default as GenericCreateUpdateDrawer } from './GenericCreateUpdateDrawer'
export { default as GenericCreateUpdateForm } from './GenericCreateUpdateForm'
export { default as GenericUpdateFormDialog } from './GenericUpdateFormDialog'
export { default as GenericListTableDialog } from './GenericListTableDialog'

View File

@@ -22,6 +22,7 @@ import ECharts from 'vue-echarts'
import service from '@/utils/request'
import { message } from '@/utils/message'
import xss from '@/utils/xss'
import ElDrawerPatch from '@/utils/elDrawerPatch.js'
import ElTableTooltipPatch from '@/utils/elTableTooltipPatch.js'
/**
@@ -42,6 +43,7 @@ Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui按如下方式声明
// Vue.use(ElementUI)
Vue.use(ElDrawerPatch)
Vue.use(ElTableTooltipPatch)
Vue.config.productionTip = false

View File

@@ -130,14 +130,14 @@ export default [
{
path: 'create',
name: 'CloudCreate',
component: () => import('@/views/assets/Asset/AssetCreateUpdate/CloudsPlatformCreateUpdate.vue'),
component: () => import('@/views/assets/Asset/AssetCreateUpdate/CloudCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.CloudCreate'), activeMenu: '/console/assets/assets' }
},
{
path: ':id/update',
name: 'CloudUpdate',
component: () => import('@/views/assets/Asset/AssetCreateUpdate/CloudsPlatformCreateUpdate.vue'),
component: () => import('@/views/assets/Asset/AssetCreateUpdate/CloudCreateUpdate.vue'),
hidden: true,
meta: { title: i18n.t('route.CloudUpdate'), activeMenu: '/console/assets/assets' }
}

View File

@@ -24,13 +24,6 @@ export default [
hidden: true,
meta: { title: i18n.t('route.AssetPermissionCreate'), action: 'create' }
},
{
path: ':id/update',
component: () => import('@/views/perms/AssetPermission/AssetPermissionCreateUpdate.vue'),
name: 'AssetPermissionUpdate',
hidden: true,
meta: { title: i18n.t('route.AssetPermissionUpdate'), action: 'update' }
},
{
path: ':id',
component: () => import('@/views/perms/AssetPermission/AssetPermissionDetail'),

View File

@@ -64,22 +64,6 @@ export default [
name: 'UserGroupList',
meta: { title: i18n.t('route.UserGroupList'), permissions: ['users.view_usergroup'] }
},
{
path: 'create',
component: () => import('@/views/users/Group/UserGroupCreateUpdate.vue'), // Parent router-view
name: 'UserGroupCreate',
hidden: true,
meta: {
title: i18n.t('route.UserGroupCreate')
}
},
{
path: ':id/update',
component: () => import('@/views/users/Group/UserGroupCreateUpdate.vue'), // Parent router-view
name: 'UserGroupUpdate',
hidden: true,
meta: { title: i18n.t('route.UserGroupUpdate') }
},
{
path: ':id',
component: () => import('@/views/users/Group/UserGroupDetail'), // Parent router-view

View File

@@ -297,17 +297,6 @@ export default {
activeMenu: '/settings/applets'
}
},
{
path: 'hosts/create',
name: 'AppletHostCreate',
component: () => import('@/views/settings/Applet/AppletHost/AppletHostCreateUpdate'),
hidden: true,
meta: {
title: i18n.t('route.AppletHostCreate'),
permissions: ['terminal.add_applethost'],
activeMenu: '/settings/applets'
}
},
{
path: 'hosts/:id',
name: 'AppletHostDetail',

View File

@@ -51,17 +51,6 @@ export default {
showOrganization: false
},
children: [
{
path: 'request-host-perm/create',
name: 'RequestAssetPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestAssetPerm/CreateUpdate'),
meta: {
title: i18n.t('tickets.OpenTicket'),
permissions: ['tickets.view_ticket'],
activeMenu: '/tickets/my-tickets'
},
hidden: true
},
{
path: 'request-host-perm/:id',
name: 'AssetsTicketDetail',

View File

@@ -195,17 +195,6 @@ export default {
activeMenu: '/workbench/ops/templates'
}
},
{
path: 'adhoc/create',
name: 'AdhocCreate',
hidden: true,
component: () => import('@/views/ops/Template/Adhoc/AdhocUpdateCreate'),
meta: {
title: i18n.t('ops.createAdhoc'),
permissions: ['ops.add_adhoc'],
activeMenu: '/workbench/ops/templates'
}
},
{
path: 'adhoc/:id',
component: () => import('@/views/ops/Template/Adhoc/AdhocDetail'),
@@ -217,17 +206,6 @@ export default {
activeMenu: '/workbench/ops/templates'
}
},
{
path: 'playbook/create',
name: 'PlaybookCreate',
hidden: true,
component: () => import('@/views/ops/Template/Playbook/PlaybookCreateUpdate'),
meta: {
title: i18n.t('ops.CreatePlaybook'),
permissions: ['ops.add_playbook'],
activeMenu: '/workbench/ops/templates'
}
},
{
path: 'playbook/:id/update',
name: 'PlaybookUpdate',

View File

@@ -30,6 +30,7 @@ const getters = {
currentUserIsAdmin: state => state.users.isAdmin,
hasValidLicense: state => state.settings.hasValidLicense,
isSystemAdmin: state => state.users.profile.system_roles.some(i => (i?.id === '00000000-0000-0000-0000-000000000001')),
sqlQueryCounter: state => state.common.sqlQueryCounter
sqlQueryCounter: state => state.common.sqlQueryCounter,
currentCreateArgs: state => state.common.createArgs
}
export default getters

View File

@@ -6,7 +6,7 @@ const getDefaultState = () => {
metaPromiseMap: {},
isRouterAlive: true,
sqlQueryCounter: [],
confirmDialogVisible: false
createArgs: {}
}
}
@@ -29,8 +29,8 @@ const mutations = {
state.sqlQueryCounter.shift()
}
},
setConfirmDialogVisible: (state, show) => {
state.confirmDialogVisible = show
SET_CREATE_ARGS: (state, args) => {
state.createArgs = args
}
}
@@ -79,8 +79,8 @@ const actions = {
}
commit('addSQLQueryCounter', { url, count: sqlCount })
},
showConfirmDialog({ commit, state }, show) {
commit('setConfirmDialogVisible', show)
setCreateArgs({ commit, state }, args) {
commit('SET_CREATE_ARGS', args)
}
}

View File

@@ -0,0 +1,28 @@
import { Drawer } from 'element-ui'
const ElDrawer = {
extends: Drawer,
data() {
return {
wrapperMouseDowned: false
}
},
mounted() {
this.$el.onmousedown = (e) => {
this.wrapperMouseDowned = e.target.classList.contains('el-drawer__container')
}
},
methods: {
handleWrapperClick() {
if (this.wrapperClosable && this.wrapperMouseDowned) {
this.closeDrawer()
}
}
}
}
export default {
install(Vue) {
Vue.component(Drawer.name, ElDrawer)
}
}

View File

@@ -2,12 +2,10 @@
import store from '@/store'
import router, { resetRouter } from '@/router'
import Vue from 'vue'
import VueCookie from 'vue-cookie'
import { message } from '@/utils/message'
import orgUtil from '@/utils/org'
import orgs from '@/api/orgs'
import { getPropView, isViewHasOrgs } from '@/utils/jms'
import request from '@/utils/request'
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
@@ -20,24 +18,24 @@ async function checkLogin({ to, from, next }) {
next()
}
// Determine whether the user has logged in
const sessionExpire = VueCookie.get('jms_session_expire')
if (!sessionExpire) {
request.get(process.env['VUE_APP_LOGOUT_PATH']).finally(() => {
window.location = process.env.VUE_APP_LOGIN_PATH
})
return reject('No session mark found in cookie')
} else if (sessionExpire === 'close') {
let startTime = new Date().getTime()
setInterval(() => {
const endTime = new Date().getTime()
const delta = (endTime - startTime)
startTime = endTime
Vue.$log.debug('Set session expire: ', delta)
VueCookie.set('jms_session_expire', 'close', { expires: '2m' })
}, 10 * 1000)
} else if (sessionExpire === 'age') {
Vue.$log.debug('Session expire on age')
}
// const sessionExpire = VueCookie.get('jms_session_expire')
// if (!sessionExpire) {
// request.get(process.env['VUE_APP_LOGOUT_PATH']).finally(() => {
// window.location = process.env.VUE_APP_LOGIN_PATH
// })
// return reject('No session mark found in cookie')
// } else if (sessionExpire === 'close') {
// let startTime = new Date().getTime()
// setInterval(() => {
// const endTime = new Date().getTime()
// const delta = (endTime - startTime)
// startTime = endTime
// Vue.$log.debug('Set session expire: ', delta)
// VueCookie.set('jms_session_expire', 'close', { expires: '2m' })
// }, 10 * 1000)
// } else if (sessionExpire === 'age') {
// Vue.$log.debug('Session expire on age')
// }
try {
return await store.dispatch('users/getProfile')
} catch (e) {

View File

@@ -1,16 +1,16 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import getChangeSecretFields from '@/views/accounts/AccountBackup/fields'
import { encryptPassword } from '@/utils/crypto'
export default {
name: 'AccountBackupPlanUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
const vm = this

View File

@@ -1,16 +1,21 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<AccountBackupCreateUpdate />
</div>
</template>
<script>
import { GenericListTable } from '@/layout/components'
import AccountBackupCreateUpdate from './AccountBackupCreateUpdate.vue'
import { ArrayFormatter, DetailFormatter } from '@/components/Table/TableFormatters'
import { openTaskPage } from '@/utils/jms'
export default {
name: 'AccountBackupPlanList',
components: {
GenericListTable
GenericListTable,
AccountBackupCreateUpdate
},
data() {
const vm = this
@@ -64,7 +69,7 @@ export default {
return {
name: 'AccountBackupList',
query: {
activeTab: 'AccountBackupPlanExecutionList',
tab: 'AccountBackupPlanExecutionList',
plan_id: row.id
}
}
@@ -74,12 +79,8 @@ export default {
actions: {
width: '164px',
formatterArgs: {
onClone: ({ row }) => {
vm.$router.push({ name: 'AccountBackupPlanCreate', query: { clone_from: row.id }})
},
onUpdate: ({ row }) => {
vm.$router.push({ name: 'AccountBackupPlanUpdate', params: { id: row.id }})
},
hasClone: true,
hasUpdate: true,
extraActions: [
{
title: vm.$t('xpack.Execute'),

View File

@@ -1,16 +1,16 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import { getChangeSecretFields } from '@/views/accounts/AccountChangeSecret/fields'
import { AssetSelect, AutomationParams } from '@/components'
export default {
name: 'AccountChangeSecretCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,16 +1,21 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<AccountChangeSecretCreateUpdate />
</div>
</template>
<script>
import { GenericListTable } from '@/layout/components'
import AccountChangeSecretCreateUpdate from './AccountChangeSecretCreateUpdate.vue'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import { openTaskPage } from '@/utils/jms'
export default {
name: 'AccountChangeSecretList',
components: {
GenericListTable
GenericListTable,
AccountChangeSecretCreateUpdate
},
data() {
const vm = this
@@ -69,7 +74,7 @@ export default {
return {
name: 'AccountChangeSecretList',
query: {
activeTab: 'AccountChangeSecretExecutionList',
tab: 'AccountChangeSecretExecutionList',
automation_id: row.id
}
}
@@ -82,12 +87,6 @@ export default {
actions: {
width: '164px',
formatterArgs: {
onClone: ({ row }) => {
vm.$router.push({ name: 'AccountChangeSecretCreate', query: { clone_from: row.id }})
},
onUpdate: ({ row }) => {
vm.$router.push({ name: 'AccountChangeSecretUpdate', params: { id: row.id }})
},
extraActions: [
{
title: vm.$t('xpack.Execute'),

View File

@@ -1,16 +1,21 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<TaskCreateUpdate />
</div>
</template>
<script>
import { GenericListTable } from '@/layout/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import TaskCreateUpdate from './TaskCreateUpdate.vue'
import { openTaskPage } from '@/utils/jms'
export default {
name: 'AccountGatherTaskList',
components: {
GenericListTable
GenericListTable,
TaskCreateUpdate
},
data() {
const vm = this
@@ -33,7 +38,7 @@ export default {
formatterArgs: {
route: 'AccountGatherTaskDetail',
routeQuery: {
activeTab: 'Detail'
tab: 'Detail'
}
}
},
@@ -62,7 +67,7 @@ export default {
return {
name: 'AccountGatherList',
query: {
activeTab: 'AccountGatherTaskExecutionList',
tab: 'AccountGatherTaskExecutionList',
automation_id: row.id
}
}

View File

@@ -1,15 +1,15 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import { CronTab } from '@/components'
import i18n from '@/i18n/i18n'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,17 +1,17 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import i18n from '@/i18n/i18n'
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import { getChangeSecretFields } from '@/views/accounts/AccountChangeSecret/fields'
import { AssetSelect, AutomationParams } from '@/components'
export default {
name: 'AccountPushCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,16 +1,21 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<AccountPushCreateUpdate />
</div>
</template>
<script>
import { DetailFormatter } from '@/components/Table/TableFormatters'
import { openTaskPage } from '@/utils/jms'
import { GenericListTable } from '@/layout/components'
import AccountPushCreateUpdate from './AccountPushCreateUpdate.vue'
export default {
name: 'AccountPushList',
components: {
GenericListTable
GenericListTable,
AccountPushCreateUpdate
},
data() {
const vm = this
@@ -80,7 +85,7 @@ export default {
return {
name: 'AccountPushList',
query: {
activeTab: 'AccountPushExecutionList',
tab: 'AccountPushExecutionList',
automation_id: row.id
}
}

View File

@@ -1,16 +1,16 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer'
import { templateFields, templateFieldsMeta } from './const.js'
import { encryptPassword } from '@/utils/crypto'
export default {
name: 'GatewayCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
const vm = this

View File

@@ -8,11 +8,13 @@
:url="secretUrl"
:visible.sync="showViewSecretDialog"
/>
<AccountTemplateCreateUpdate />
</div>
</template>
<script>
import { GenericListPage } from '@/layout/components'
import AccountTemplateCreateUpdate from './AccountTemplateCreateUpdate.vue'
import { ActionsFormatter } from '@/components/Table/TableFormatters'
import ViewSecret from '@/components/Apps/AccountListTable/ViewSecret'
@@ -20,6 +22,7 @@ export default {
name: 'AccountTemplateList',
components: {
GenericListPage,
AccountTemplateCreateUpdate,
ViewSecret
},
data() {
@@ -86,11 +89,7 @@ export default {
hasExport: false,
hasImport: false,
hasMoreActions: false,
createRoute: () => {
return {
name: 'AccountTemplateCreate'
}
}
createRoute: 'AccountTemplateCreate'
}
}
}

View File

@@ -1,14 +1,19 @@
<template>
<ListTable v-bind="config" />
<div>
<ListTable v-bind="config" />
<VirtualUpdate />
</div>
</template>
<script>
import { ListTable } from '@/components'
import VirtualUpdate from './VirtualUpdate.vue'
export default {
name: 'VirtualAccountList',
components: {
ListTable
ListTable,
VirtualUpdate
},
data() {
return {

View File

@@ -1,14 +1,14 @@
<template>
<GenericCreateUpdatePage v-bind="config" @getObjectDone="handleObjectDone" />
<GenericCreateUpdateDrawer v-bind="config" @getObjectDone="handleObjectDone" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage/index.vue'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
import TextReadonly from '@/components/Form/FormFields/TextReadonly.vue'
export default {
name: 'CreateUpdate',
components: { GenericCreateUpdatePage },
components: { GenericCreateUpdateDrawer },
data() {
return {
object: {},

View File

@@ -1,19 +1,19 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import rules from '@/components/Form/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
import { assetJSONSelectMeta } from '@/views/assets/const'
import AccountFormatter from '@/views/perms/AssetPermission/components/AccountFormatter.vue'
import { WeekCronSelect } from '@/components/Form/FormFields'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer'
export default {
name: 'AclCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,13 +1,18 @@
<template>
<GenericListPage :header-actions="headerActions" :help-message="helpMsg" :table-config="tableConfig" />
<div>
<GenericListPage :header-actions="headerActions" :help-message="helpMsg" :table-config="tableConfig" />
<AssetLoginAclCreateUpdate />
</div>
</template>
<script>
import { GenericListPage } from '@/layout/components'
import AssetLoginAclCreateUpdate from './AssetLoginAclCreateUpdate.vue'
export default {
components: {
GenericListPage
GenericListPage,
AssetLoginAclCreateUpdate
},
data() {
return {

View File

@@ -1,5 +1,5 @@
<template>
<GenericCreateUpdatePage
<GenericCreateUpdateDrawer
:fields="fields"
:fields-meta="fieldsMeta"
:initial="initial"
@@ -9,7 +9,7 @@
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
import AccountFormatter from '@/views/perms/AssetPermission/components/AccountFormatter.vue'
import rules from '@/components/Form/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
@@ -18,7 +18,7 @@ import { assetJSONSelectMeta } from '@/views/assets/const'
export default {
name: 'CommandFilterAclCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -2,6 +2,7 @@
<div>
<el-alert type="success">{{ helpMsg }}</el-alert>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
<CommandFilterAclCreateUpdate />
</div>
</template>
@@ -10,10 +11,12 @@
import { ListTable } from '@/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
import CommandFilterAclCreateUpdate from './CommandFilterAclCreateUpdate.vue'
export default {
components: {
ListTable
ListTable,
CommandFilterAclCreateUpdate
},
data() {
return {
@@ -44,15 +47,8 @@ export default {
width: '160px',
formatter: AmountFormatter,
formatterArgs: {
route: 'AccountGatherList',
getRoute({ row }) {
return {
name: 'CommandFilterAclList',
query: {
activeTab: 'CommandGroup',
command_filters: row.id
}
}
routeQuery: {
tab: 'GroupUser'
}
}
}

View File

@@ -1,5 +1,5 @@
<template>
<GenericCreateUpdatePage
<GenericCreateUpdateDrawer
:fields="fields"
:initial="initial"
:fields-meta="fieldsMeta"
@@ -10,11 +10,11 @@
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
name: 'CommandGroupCreateUpdate',
components: { GenericCreateUpdatePage },
components: { GenericCreateUpdateDrawer },
data() {
const regexPlaceholder = 'rm.*|reboot|shutdown'
const commandPlaceholder = 'rm\rreboot'

View File

@@ -1,14 +1,19 @@
<template>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
<CommandGroupCreateUpdate />
</div>
</template>
<script>
import { ListTable } from '@/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import CommandGroupCreateUpdate from './CommandGroupCreateUpdate.vue'
export default {
components: {
ListTable
ListTable,
CommandGroupCreateUpdate
},
data() {
const _id = this.$route.query.command_filters

View File

@@ -42,7 +42,7 @@ export default {
const query = _.cloneDeep(this.$route.query)
const newQuery = {
...query,
activeTab: tab.name
tab: tab.name
}
this.$nextTick(() => {
this.$router.replace({ query: newQuery })

View File

@@ -1,9 +1,9 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer'
import rules from '@/components/Form/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
import { assetJSONSelectMeta } from '@/views/assets/const'
@@ -12,7 +12,7 @@ import { Select2 } from '@/components/Form/FormFields'
export default {
name: 'AclCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,13 +1,19 @@
<template>
<GenericListPage :header-actions="headerActions" :help-message="helpText" :table-config="tableConfig" />
<div>
<GenericListPage :header-actions="headerActions" :help-message="helpText" :table-config="tableConfig" />
<ConnectMethodAclCreateUpdate />
</div>
</template>
<script>
import GenericListPage from '@/layout/components/GenericListPage/index.vue'
import ConnectMethodAclCreateUpdate from './ConnectMethodAclCreateUpdate.vue'
export default {
name: 'ConnectMethodListAcl',
components: { GenericListPage },
components: {
GenericListPage,
ConnectMethodAclCreateUpdate
},
data() {
return {
helpText: this.$t('acl.ConnectMethodACLHelpMsg'),

View File

@@ -1,9 +1,9 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer'
import { WeekCronSelect } from '@/components/Form/FormFields'
import { Required } from '@/components/Form/DataForm/rules'
import { userJSONSelectMeta } from '@/views/users/const'
@@ -11,7 +11,7 @@ import { userJSONSelectMeta } from '@/views/users/const'
export default {
name: 'AclCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {
@@ -70,18 +70,6 @@ export default {
}
}
},
getUrl() {
const query = this.$route.query
const params = this.$route.params
let url = `/api/v1/acls/login-acls/`
if (params.id) {
url = `${url}${params.id}/`
}
if (query.user) {
url = `${url}?user=${query.user}`
}
return url
},
cleanFormValue(value) {
if (!Array.isArray(value.rules.ip_group)) {
value.rules.ip_group = value.rules.ip_group ? value.rules.ip_group.split(',') : []

View File

@@ -1,13 +1,18 @@
<template>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<ListTable :header-actions="headerActions" :table-config="tableConfig" />
<UserLoginACLCreateUpdate />
</div>
</template>
<script>
import ListTable from '@/components/Table/ListTable/index.vue'
import UserLoginACLCreateUpdate from './UserLoginACLCreateUpdate.vue'
export default {
components: {
ListTable
ListTable,
UserLoginACLCreateUpdate
},
props: {
url: {

View File

@@ -1,15 +1,22 @@
<template>
<GenericCreateUpdatePage v-if="!loading" v-bind="iConfig" />
<GenericCreateUpdateDrawer
v-if="!loading"
:visible="visible"
:action="action"
:action-id="actionId"
v-bind="iConfig"
v-on="$listeners"
/>
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import { assetFieldsMeta } from '@/views/assets/const'
import { encryptPassword } from '@/utils/crypto'
import { getUpdateObjURL, setUrlParam } from '@/utils/common'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
components: { GenericCreateUpdatePage },
components: { GenericCreateUpdateDrawer },
props: {
url: {
type: String,
@@ -28,10 +35,6 @@ export default {
type: [Array, Function],
default: () => []
},
createSuccessNextRoute: {
type: Object,
default: () => ({ name: 'AssetList' })
},
updateSuccessNextRoute: {
type: Object,
default: () => ({ name: 'AssetList' })
@@ -41,11 +44,28 @@ export default {
default: (initial) => {
return initial
}
},
platformId: {
type: Number,
default: 0
},
action: {
type: String,
default: 'create'
},
visible: {
type: Boolean,
default: false
},
row: {
type: Object,
default: () => ({})
}
},
data() {
return {
loading: true,
actionId: this.row?.id,
platform: {},
defaultConfig: {
initial: {},
@@ -62,16 +82,16 @@ export default {
[this.$t('common.Other'), ['domain', 'labels', 'is_active', 'comment']]
],
fieldsMeta: assetFieldsMeta(this),
performSubmit(validValues) {
performSubmit: (validValues) => {
console.log('This row: ', this.row, 'This action: ', this.action)
let url = this.url
const { id = '' } = this.$route.params
const values = _.cloneDeep(validValues)
const submitMethod = id ? 'put' : 'post'
const submitMethod = this.action === 'update' ? 'put' : 'post'
if (values.nodes && values.nodes.length === 0) {
delete values['nodes']
}
if (id) {
url = getUpdateObjURL(url, id)
if (this.action === 'update') {
url = getUpdateObjURL(url, this.row.id)
delete values['accounts']
} else {
const accounts = values?.accounts || []
@@ -89,10 +109,7 @@ export default {
iConfig() {
const { addFields, addFieldsMeta, defaultConfig } = this
let url = this.url
const { id = '' } = this.$route.params
if (this.$route.query.platform && !id) {
url = setUrlParam(url, 'platform', this.$route.query.platform)
}
url = setUrlParam(url, 'platform', this.platformId)
// null, undefined
defaultConfig.fields = defaultConfig.fields.filter(Boolean)
const config = _.merge(defaultConfig, { url })
@@ -105,6 +122,12 @@ export default {
}
}
const tp = this.platform.type?.value
const category = this.platform.category?.value
if (tp && category) {
defaultConfig.fieldsMeta.platform.el.ajax.url = `/api/v1/assets/platforms/?category=${category}&type=${tp}`
}
for (const [name, meta] of Object.entries(addFieldsMeta)) {
if (config.fieldsMeta[name]) {
config.fieldsMeta[name] = Object.assign(config.fieldsMeta[name], meta)
@@ -129,16 +152,16 @@ export default {
},
async setInitial() {
const { defaultConfig } = this
const { node, platform } = this.$route?.query || {}
const { node } = this.$route?.query || {}
const nodesInitial = node ? [node] : []
const platformId = platform || 1
const platformId = this.platformId
const url = `/api/v1/assets/platforms/${platformId}/`
this.platform = await this.$axios.get(url)
const initial = {
labels: [],
is_active: true,
nodes: nodesInitial,
platform: parseInt(platformId),
platform: platformId,
protocols: []
}
if (this.updateInitial) {

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'CloudCreateUpdate',

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'WebCreateUpdate',

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
import { UploadKey } from '@/components'
import rules from '@/components/Form/DataForm/rules'
@@ -18,7 +18,7 @@ export default {
}
},
mounted() {
this.url = `${this.url}?platform=${this.$route.query.platform}`
console.log('Attrs: ', this.$attrs)
},
methods: {
getAddFields() {

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'DeviceCreateUpdate',

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'GPTCreateUpdate',

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" v-on="$listeners" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'HostCreateUpdate',

View File

@@ -1,9 +1,9 @@
<template>
<BaseAssetCreateUpdate v-bind="$data" />
<BaseAssetCreateUpdate v-bind="Object.assign($data, $attrs)" />
</template>
<script>
import BaseAssetCreateUpdate from './BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from './BaseAssetCreateDrawer.vue'
export default {
name: 'WebCreateUpdate',

View File

@@ -137,7 +137,7 @@ export default {
name: 'AppletHostDetail',
params: { id: assetId },
query: {
activeTab: 'Accounts'
tab: 'Accounts'
}
})
return
@@ -146,7 +146,7 @@ export default {
name: 'AssetDetail',
params: { id: assetId },
query: {
activeTab: 'Account'
tab: 'Account'
}
})
}

View File

@@ -0,0 +1,73 @@
<template>
<div>
<component
:is="component"
:visible.sync="visible"
:action="action"
:platform-id="platform.id"
:row="row"
@close="onClose"
/>
</div>
</template>
<script>
import HostCreateUpdate from './HostCreateUpdate.vue'
import DatabaseCreateUpdate from './DatabaseCreateUpdate.vue'
import CloudCreateUpdate from './CloudCreateUpdate.vue'
import WebCreateUpdate from './WebCreateUpdate.vue'
import DeviceCreateUpdate from './DeviceCreateUpdate.vue'
import CustomCreateUpdate from './CustomCreateUpdate.vue'
export default {
name: 'WebCreateUpdate',
components: {
HostCreateUpdate,
DatabaseCreateUpdate,
CloudCreateUpdate,
WebCreateUpdate,
DeviceCreateUpdate,
CustomCreateUpdate
},
props: {
},
data() {
return {
visible: false,
category: '',
component: '',
platform: { id: 0 },
row: {},
action: '',
components: {
host: HostCreateUpdate,
database: DatabaseCreateUpdate,
cloud: CloudCreateUpdate,
web: WebCreateUpdate,
device: DeviceCreateUpdate,
custom: CustomCreateUpdate
}
}
},
mounted() {
this.$eventBus.$on('assetCreateUpdate', (platform, action, { url, row }) => {
this.platform = platform
this.category = platform.category.value
this.component = this.components[this.category]
this.row = row
this.action = action
this.visible = true
})
},
beforeDestroy() {
this.$eventBus.$off('assetCreateUpdate')
},
methods: {
onClose() {
console.log('On closed draw')
this.row = {}
this.component = ''
}
}
}
</script>

View File

@@ -149,7 +149,7 @@ export default {
formatterArgs: {
route: 'AssetPermissionDetail',
routeQuery: {
activeTab: 'AssetPermissionUser'
tab: 'AssetPermissionUser'
}
}
},
@@ -160,7 +160,7 @@ export default {
formatterArgs: {
route: 'AssetPermissionDetail',
routeQuery: {
activeTab: 'AssetPermissionUser'
tab: 'AssetPermissionUser'
}
}
},
@@ -171,7 +171,7 @@ export default {
formatterArgs: {
route: 'AssetPermissionDetail',
routeQuery: {
activeTab: 'AssetPermissionAsset'
tab: 'AssetPermissionAsset'
}
}
}

View File

@@ -15,8 +15,7 @@ export default {
category: 'custom',
url: '/api/v1/assets/customs/',
tableConfig: {
columnsExclude: [
],
columnsExclude: [],
columnsMeta: {
autofill: {
width: '100px'

View File

@@ -1,5 +1,5 @@
<template>
<BaseList v-bind="config" />
<BaseList v-bind="Object.assign(config, $attrs)" />
</template>
<script>

View File

@@ -17,11 +17,13 @@
:port="GatewayPort"
:visible.sync="GatewayVisible"
/>
<AssetCreateUpdate />
</div>
</template>
<script>
import { ListTable } from '@/components'
import AssetCreateUpdate from '../../AssetCreateUpdate'
import {
ActionsFormatter, ArrayFormatter, ChoicesFormatter, DetailFormatter, ProtocolsFormatter, TagsFormatter
} from '@/components/Table/TableFormatters'
@@ -37,7 +39,8 @@ export default {
ListTable,
GatewayDialog,
PlatformDialog,
AssetBulkUpdateDialog
AssetBulkUpdateDialog,
AssetCreateUpdate
},
props: {
url: {
@@ -77,28 +80,13 @@ export default {
data() {
const vm = this
const onAction = (row, action) => {
let routeAction = action
if (action === 'Clone') {
routeAction = 'Create'
const platform = {
...row.platform,
type: row.type,
category: row.category
}
const routeName = _.capitalize(row.category.value) + routeAction
const route = {
name: routeName,
params: {},
query: {}
}
if (action === 'Clone') {
route.query.clone_from = row.id
} else if (action === 'Update') {
route.params.id = row.id
}
if (['Create', 'Update'].includes(routeAction)) {
route.query.platform = row.platform.id
route.query.type = row.type.value
route.query.category = row.type.category
}
const { href } = vm.$router.resolve(route)
window.open(href, '_blank')
console.log('ON action: ', action)
vm.$eventBus.$emit('assetCreateUpdate', platform, action.toLowerCase(), { url: this.url, row })
}
const extraQuery = this.$route.params?.extraQuery || {}
return {

View File

@@ -1,12 +1,13 @@
<template>
<Dialog
<el-drawer
v-if="iVisible"
:show-cancel="false"
:show-confirm="false"
:title="$tc('assets.SelectPlatforms')"
:visible.sync="iVisible"
top="1vh"
width="60%"
class="platform-dialog"
direction="rtl"
size="600px"
>
<div style="margin: 0 10px">
<el-row :gutter="20">
@@ -20,7 +21,7 @@
<el-col
v-for="(platform, index) of ps"
:key="platform.id"
:span="6"
:span="12"
>
<el-card
:style="{ borderLeftColor: randomBorderColor(index) }"
@@ -35,16 +36,13 @@
</el-collapse>
</el-row>
</div>
</Dialog>
</el-drawer>
</template>
<script>
import Dialog from '@/components/Dialog'
export default {
name: 'PlatformDialog',
components: {
Dialog
},
props: {
visible: {
@@ -77,6 +75,7 @@ export default {
computed: {
iVisible: {
set(val) {
console.log('Platform visible changed: ', val)
this.$emit('update:visible', val)
},
get() {
@@ -149,19 +148,12 @@ export default {
localStorage.setItem('RecentPlatforms', JSON.stringify(recentPlatformIds))
},
createAsset(platform) {
const route = _.capitalize(platform.category.value) + 'Create' || 'HostCreate'
this.addToRecentPlatforms(platform)
this.iVisible = false
const query = {
node: this.$route.query?.node || this.$route.query?.node_id || '',
platform: platform.id,
type: platform.type.value,
category: platform.category.value
}
const router = { name: route, query }
const { href } = this.$router.resolve(router)
window.open(href, '_blank')
setTimeout(() => {
this.iVisible = false
})
const url = `/api/v1/assets/${platform.category.value}s/`
this.$eventBus.$emit('assetCreateUpdate', platform, 'create', { url })
}
}
}
@@ -186,8 +178,17 @@ export default {
font-weight: 500;
color: #303133;
}
.platform-dialog {
>>> .el-drawer__header {
margin-bottom: 10px;
}
}
>>> .el-collapse {
border: none;
padding: 0 20px;
.el-collapse-item:last-child {
.el-collapse-item__header {
border: none;

View File

@@ -92,7 +92,7 @@ export default {
const query = _.cloneDeep(this.$route.query)
const newQuery = {
...query,
activeTab: tab.name
tab: tab.name
}
this.$nextTick(() => {
this.$router.replace({ query: newQuery })

View File

@@ -1,25 +1,26 @@
<template>
<GenericCreateUpdatePage
<GenericCreateUpdateDrawer
:initial="initial"
:resource="$tc('xpack.Cloud.Account')"
v-bind="$data"
/>
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { RequiredChange, specialEmojiCheck } from '@/components/Form/DataForm/rules'
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun } from '../const'
import { UploadKey } from '@/components'
import { encryptPassword } from '@/utils/crypto'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
const vm = this
const accountProvider = this.$route.query.provider || aliyun
const accountProviderAttrs = ACCOUNT_PROVIDER_ATTRS_MAP[accountProvider]
const accountProviderAttrs = ACCOUNT_PROVIDER_ATTRS_MAP[accountProvider] || {}
function setFieldAttrs() {
const fieldsObject = {}
@@ -127,12 +128,6 @@ export default {
values.attrs.ip_group = attrs.ip_group.filter(Boolean)
}
return values
},
afterGetFormValue(formValue) {
if (!formValue.attrs) {
return formValue
}
return formValue
}
}
},

View File

@@ -1,9 +1,13 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<AccountCreateUpdate />
</div>
</template>
<script type="text/jsx">
import GenericListTable from '@/layout/components/GenericListTable'
import AccountCreateUpdate from './AccountCreateUpdate.vue'
import {
ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, azure, azure_international, baiducloud,
ctyun_private, fc, gcp, huaweicloud, huaweicloud_private, jdcloud, kingsoftcloud, lan, nutanix, openstack, qcloud,
@@ -13,13 +17,15 @@ import {
export default {
name: 'AccountList',
components: {
GenericListTable
GenericListTable,
AccountCreateUpdate
},
data() {
const vm = this
const url = '/api/v1/xpack/cloud/accounts/'
return {
tableConfig: {
url: '/api/v1/xpack/cloud/accounts/',
url: url,
permissions: {
app: 'xpack',
resource: 'account'
@@ -45,7 +51,13 @@ export default {
updateRoute: 'AccountUpdate',
hasClone: false,
onUpdate: ({ row, col }) => {
vm.$router.push({ name: 'AccountUpdate', params: { id: row.id }, query: { provider: row.provider?.value }})
vm.$router.push({
params: { id: row.id },
query: { provider: row.provider?.value }
})
setTimeout(() => {
vm.$eventBus.$emit('showCreateUpdateDrawer', 'update', { row, col })
})
},
extraActions: [
{
@@ -72,7 +84,10 @@ export default {
},
moreCreates: {
callback: (option) => {
vm.$router.push({ name: 'AccountCreate', query: { provider: option.name }})
vm.$router.push({ query: { provider: option.name }})
setTimeout(() => {
vm.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url })
})
},
dropdown: [
{

View File

@@ -1,16 +1,16 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer :resource="$tc('xpack.Cloud.SyncStrategy')" v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { RequiredChange, specialEmojiCheck } from '@/components/Form/DataForm/rules'
import RuleInput from './components/RuleInput'
import ActionInput from './components/ActionInput'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,15 +1,20 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<StrategyCreateUpdate />
</div>
</template>
<script type="text/jsx">
import GenericListTable from '@/layout/components/GenericListTable'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import StrategyCreateUpdate from './StrategyCreateUpdate.vue'
export default {
name: 'StrategyList',
components: {
GenericListTable
GenericListTable,
StrategyCreateUpdate
},
data() {
return {

View File

@@ -1,16 +1,16 @@
<template>
<GenericCreateUpdatePage ref="createUpdatePage" v-bind="$data" />
<GenericCreateUpdateDrawer ref="createUpdatePage" v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { CronTab, Select2 } from '@/components'
import rules from '@/components/Form/DataForm/rules'
import SyncInstanceTaskStrategy from './components/SyncInstanceTaskStrategy/index'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
const vm = this

View File

@@ -1,22 +1,28 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<SyncInstanceTaskCreateUpdate />
</div>
</template>
<script>
import GenericListTable from '@/layout/components/GenericListTable'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import SyncInstanceTaskCreateUpdate from './SyncInstanceTaskCreateUpdate.vue'
import { openTaskPage } from '@/utils/jms'
export default {
name: 'SyncInstanceTaskList',
components: {
GenericListTable
GenericListTable,
SyncInstanceTaskCreateUpdate
},
data() {
const vm = this
const url = '/api/v1/xpack/cloud/sync-instance-tasks/'
return {
tableConfig: {
url: '/api/v1/xpack/cloud/sync-instance-tasks/',
url: url,
permissions: {
app: 'xpack',
resource: 'syncinstancetask'
@@ -81,7 +87,7 @@ export default {
permissions: 'xpack.view_syncinstancetaskexecution',
route: 'SyncInstanceTaskDetail',
routeQuery: {
activeTab: 'HistoryList'
tab: 'HistoryList'
}
}
},
@@ -91,7 +97,7 @@ export default {
permissions: 'xpack.view_syncinstancetask',
route: 'SyncInstanceTaskDetail',
routeQuery: {
activeTab: 'AssetList'
tab: 'AssetList'
}
}
}
@@ -103,8 +109,7 @@ export default {
headerActions: {
hasMoreActions: false,
hasImport: false,
hasExport: false,
createRoute: 'SyncInstanceTaskCreate'
hasExport: false
}
}
}

View File

@@ -1,21 +1,29 @@
<template>
<GenericCreateUpdatePage :fields="fields" :fields-meta="fieldsMeta" :initial="initial" :url="url" />
<GenericCreateUpdateDrawer
:fields="fields"
:fields-meta="fieldsMeta"
:initial="initial"
:url="url"
v-bind="$attrs"
v-on="$listeners"
/>
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer'
import AssetSelect from '@/components/Apps/AssetSelect'
export default {
name: 'GatewayCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {
initial: {},
fields: [
[this.$t('common.Basic'), ['name', 'assets', 'comment']]
[this.$t('common.Basic'), ['name', 'assets']],
[this.$t('common.Other'), ['comment']]
],
fieldsMeta: {
assets: {

View File

@@ -3,22 +3,32 @@
</template>
<script>
import BaseAssetCreateUpdate from '@/views/assets/Asset/AssetCreateUpdate/BaseAssetCreateUpdate'
import BaseAssetCreateUpdate from '@/views/assets/Asset/AssetCreateUpdate/BaseAssetCreateDrawer.vue'
export default {
name: 'GatewayCreateUpdate',
components: {
BaseAssetCreateUpdate
},
props: {
domain: {
type: String,
default: ''
},
platformType: {
type: String,
default: ''
}
},
data() {
const platformType = this.$route.query.platform_type
const platformType = this.platformType
return {
url: '/api/v1/assets/gateways/',
updateInitial: async(initial) => {
const url = `/api/v1/assets/platforms/?name=Gateway`
const platform = await this.$axios.get(url)
initial.platform = parseInt(platform[0].id)
initial.domain = this.$route.query.domain
initial.domain = this.domain
return initial
},
addFieldsMeta: {
@@ -37,24 +47,6 @@ export default {
}
}
}
},
createSuccessNextRoute: {
name: 'DomainDetail',
params: {
id: this.$route.query.domain
},
query: {
activeTab: 'GatewayList'
}
},
updateSuccessNextRoute: {
name: 'DomainDetail',
params: {
id: this.$route.query.domain
},
query: {
activeTab: 'GatewayList'
}
}
}
},

View File

@@ -10,6 +10,7 @@
:port="port"
:visible.sync="visible"
/>
<GatewayCreateUpdate :domain="domain" :platform-type="platformType" />
</el-col>
</div>
</template>
@@ -17,12 +18,14 @@
<script>
import GenericListTable from '@/layout/components/GenericListTable/index'
import GatewayDialog from '@/components/Apps/GatewayDialog'
import GatewayCreateUpdate from './GatewayCreateUpdate.vue'
import { connectivityMeta } from '@/components/Apps/AccountListTable/const'
import { ArrayFormatter, ChoicesFormatter, DetailFormatter, TagsFormatter } from '@/components/Table/TableFormatters'
export default {
components: {
GenericListTable,
GatewayCreateUpdate,
GatewayDialog
},
props: {
@@ -34,6 +37,8 @@ export default {
},
data() {
return {
domain: '',
platformType: '',
tableConfig: {
url: `/api/v1/assets/gateways/?domain=${this.$route.params.id}`,
columnsExclude: [
@@ -89,7 +94,10 @@ export default {
connectivity: connectivityMeta,
actions: {
formatterArgs: {
updateRoute: { name: 'GatewayUpdate', query: { domain: this.object.id, platform_type: 'linux', 'category': 'host' }},
updateRoute: ({ row }) => {
this.domain = this.object.id
this.platformType = 'linux'
},
performDelete: ({ row }) => {
const id = row.id
const url = `/api/v1/assets/gateways/${id}/`
@@ -130,13 +138,11 @@ export default {
headerActions: {
hasBulkUpdate: false,
hasSearch: true,
createRoute: {
name: 'GatewayCreate',
query: {
domain: this.object.id,
platform_type: 'linux',
category: 'host'
}
onCreate: (item) => {
this.domain = this.object.id
this.platformType = 'linux'
this.category = 'host'
this.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: this.tableConfig.url })
}
},
port: 0,

View File

@@ -1,18 +1,24 @@
<template>
<GenericListPage :header-actions="headerActions" :help-message="notice" :table-config="tableConfig" />
<div>
<GenericListPage :header-actions="headerActions" :help-message="notice" :table-config="tableConfig" />
<DomainCreateUpdate />
</div>
</template>
<script>
import { GenericListPage } from '@/layout/components'
import { DetailFormatter } from '@/components/Table/TableFormatters'
import DomainCreateUpdate from './DomainCreateUpdate.vue'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
export default {
components: {
GenericListPage
GenericListPage,
DomainCreateUpdate
},
data() {
return {
showCreateUpdate: false,
tableConfig: {
url: '/api/v1/assets/domains/',
columnsExclude: ['gateway'],
@@ -28,7 +34,7 @@ export default {
formatter: AmountFormatter,
formatterArgs: {
routeQuery: {
activeTab: 'GroupUser'
tab: 'GroupUser'
}
}
},
@@ -38,7 +44,7 @@ export default {
formatterArgs: {
permissions: 'assets.view_gateway',
routeQuery: {
activeTab: 'GatewayList'
tab: 'GatewayList'
},
getTitle: function({ row }) {
return row.gateways.length
@@ -48,7 +54,6 @@ export default {
}
},
headerActions: {
createRoute: 'DomainCreate'
},
notice: this.$t('assets.DomainHelpMessage')
}

View File

@@ -1,15 +1,21 @@
<template>
<GenericCreateUpdatePage :fields="fields" :fields-meta="fieldsMeta" :has-detail-in-msg="false" :initial="initial" :url="url" />
<GenericCreateUpdateDrawer
:fields="fields"
:fields-meta="fieldsMeta"
:has-detail-in-msg="false"
:initial="initial"
:url="url"
/>
</template>
<script>
import AssetSelect from '@/components/Apps/AssetSelect'
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
export default {
name: 'LabelCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,13 +1,18 @@
<template>
<GenericListPage :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListPage :header-actions="headerActions" :table-config="tableConfig" />
<LabelCreateUpdate />
</div>
</template>
<script>
import { GenericListPage } from '@/layout/components'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter.vue'
import LabelCreateUpdate from '@/views/assets/Label/LabelCreateUpdate.vue'
export default {
components: {
LabelCreateUpdate,
GenericListPage
},
data() {

View File

@@ -1,6 +1,6 @@
<template>
<div v-if="!loading" class="platform-form">
<GenericCreateUpdatePage
<div class="platform-form">
<GenericCreateUpdateDrawer
:after-get-form-value="afterGetFormValue"
:after-get-remote-meta="handleAfterGetRemoteMeta"
:clean-form-value="cleanFormValue"
@@ -10,18 +10,44 @@
:has-reset="false"
:initial="initial"
:url="url"
v-bind="$attrs"
@close="$emit('update:visible', false)"
v-on="$listeners"
/>
</div>
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import { platformFieldsMeta, setAutomations, updateAutomationParams } from './const'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
import { setUrlParam } from '@/utils/common'
export default {
name: 'PlatformCreateUpdate',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
props: {
category: {
type: String,
default: 'host'
},
type: {
type: String,
default: 'linux'
},
action: {
type: String,
default: ''
},
row: {
type: Object,
default: () => ({})
},
visible: {
type: Boolean,
default: false
}
},
data() {
return {
@@ -95,16 +121,18 @@ export default {
}
},
watch: {
},
async mounted() {
try {
await this.setCategories()
await this.setConstraints()
} finally {
this.loading = false
visible(val) {
if (val) {
this.showCreateUpdateDrawer()
}
}
},
methods: {
async showCreateUpdateDrawer() {
await this.setCategories()
await this.setConstraints()
this.$eventBus.$emit('showCreateUpdateDrawer', this.action, { url: this.url, row: this.row })
},
updateSuMethodOptions() {
const options = this.suMethods.filter(i => {
return this.suMethodLimits.includes(i.value)
@@ -124,19 +152,20 @@ export default {
this.initial.su_method = this.suMethodLimits[0]
},
async setCategories() {
const category = this.$route.query.category
const type = this.$route.query.type
const category = this.category
const type = this.type
const state = await this.$store.dispatch('assets/getAssetCategories')
this.fieldsMeta.category_type.el.options = state.assetCategoriesCascader
if (category && type) {
this.initial.category_type = [category, type]
}
this.url += `?category=${category}&type=${type}`
this.url = setUrlParam(this.url, 'category', category)
this.url = setUrlParam(this.url, 'type', type)
return new Promise((resolve, reject) => resolve(true))
},
async setConstraints() {
const category = this.$route.query.category
const type = this.$route.query.type
const category = this.category
const type = this.type
const url = `/api/v1/assets/categories/constraints/?category=${category}&type=${type}`
const constraints = await this.$axios.get(url)
this.defaultOptions = constraints

View File

@@ -1,35 +1,46 @@
<template>
<TabPage
v-if="!loading"
:active-menu.sync="tab.activeMenu"
:submenu="tab.submenu"
@tab-click="changeMoreCreates"
>
<keep-alive>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
</keep-alive>
</TabPage>
<div>
<TabPage
v-if="!loading"
:active-menu.sync="tab.activeMenu"
:submenu="tab.submenu"
@tab-click="changeMoreCreates"
>
<keep-alive>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
</keep-alive>
</TabPage>
<PlatformCreateUpdate :action="action" :category="category" :row="row" :type="type" :visible.sync="showDrawer" />
</div>
</template>
<script>
import { GenericListTable, TabPage } from '@/layout/components'
import { ChoicesFormatter, ProtocolsFormatter } from '../../../components/Table/TableFormatters'
import { ChoicesFormatter, ProtocolsFormatter } from '@/components/Table/TableFormatters'
import PlatformCreateUpdate from '@/views/assets/Platform/PlatformCreateUpdate.vue'
export default {
components: {
PlatformCreateUpdate,
TabPage,
GenericListTable
},
data() {
const vm = this
const url = '/api/v1/assets/platforms/'
return {
loading: true,
showDrawer: false,
category: '',
type: '',
action: 'create',
row: {},
tab: {
submenu: [],
activeMenu: 'host'
},
tableConfig: {
url: '/api/v1/assets/platforms/',
url: url,
columnsExclude: ['automation'],
columnsShow: {
min: ['name', 'actions'],
@@ -65,25 +76,19 @@ export default {
canClone: () => vm.$hasPerm('assets.add_platform'),
canUpdate: ({ row }) => !row.internal && vm.$hasPerm('assets.change_platform'),
canDelete: ({ row }) => !row.internal && vm.$hasPerm('assets.delete_platform'),
updateRoute: ({ row }) => {
return {
name: 'PlatformUpdate',
params: { id: row.id },
query: {
category: row.category.value,
type: row.type.value
}
}
onUpdate: ({ row }) => {
this.category = row.category.value
this.type = row.type.value
this.action = 'update'
this.row = row
this.showDrawer = true
},
cloneRoute: ({ row }) => {
return {
name: 'PlatformCreate',
query: {
category: row.category.value,
type: row.type.value,
clone_from: row.id
}
}
onClone: ({ row }) => {
this.category = row.category.value
this.type = row.type.value
this.action = 'clone'
this.row = row
this.showDrawer = true
}
}
}
@@ -102,10 +107,10 @@ export default {
},
moreCreates: {
callback: (item) => {
this.$router.push({
name: 'PlatformCreate',
query: { type: item.name, category: item.category }
})
this.action = 'create'
this.category = item.category
this.type = item.name
this.showDrawer = true
},
dropdown: []
}

View File

@@ -29,7 +29,6 @@ export const filterSelectValues = (values) => {
export const assetFieldsMeta = (vm) => {
const platformProtocols = []
const secretTypes = []
const platformType = vm?.$route.query?.type
const asset = { address: 'https://jumpserver:330' }
return {
address: {
@@ -72,7 +71,7 @@ export const assetFieldsMeta = (vm) => {
el: {
multiple: false,
ajax: {
url: `/api/v1/assets/platforms/?type=${platformType}`,
url: `/api/v1/assets/platforms/`,
transformOption: (item) => {
return { label: item.name, value: item.id }
}

View File

@@ -1,12 +1,12 @@
<template>
<div v-if="ready">
<div>
<VariableHelpDialog :visible.sync="showHelpDialog" />
<GenericCreateUpdatePage ref="form" v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</div>
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import AssetSelect from '@/components/Apps/AssetSelect'
import CodeEditor from '@/components/Form/FormFields/CodeEditor'
import { CronTab } from '@/components'
@@ -16,8 +16,18 @@ import { Required } from '@/components/Form/DataForm/rules'
export default {
components: {
GenericCreateUpdatePage,
VariableHelpDialog
VariableHelpDialog,
GenericCreateUpdateDrawer
},
props: {
item: {
type: Object,
default: () => {}
},
type: {
type: String,
default: ''
}
},
data() {
return {
@@ -162,41 +172,52 @@ export default {
}
}
},
mounted() {
if (this.$route.query && this.$route.query.type) {
this.initial.type = 'adhoc'
switch (this.$route.query.type) {
case 'adhoc':
this.initial.type = 'adhoc'
if (this.$route.query.id) {
this.$axios.get(`/api/v1/ops/adhocs/${this.$route.query.id}`).then((data) => {
this.initial.module = data.module
this.initial.args = data.args
this.initial.instant = true
this.initial.runAfterSave = true
this.instantTask = true
this.createSuccessNextRoute = { name: 'Adhoc' }
this.ready = true
})
} else {
this.ready = true
}
break
case 'playbook':
this.initial.type = 'playbook'
if (this.$route.query.id) {
this.initial.playbook = this.$route.query.id
this.ready = true
} else {
this.ready = true
}
break
}
} else {
this.ready = true
watch: {
type: {
handler(val) {
this.init()
},
immediate: true
}
},
methods: {}
mounted() {
this.init()
},
methods: {
init() {
if (this.type) {
this.initial.type = 'adhoc'
switch (this.type) {
case 'adhoc':
this.initial.type = 'adhoc'
if (this.item.id) {
this.$axios.get(`/api/v1/ops/adhocs/${this.item.id}`).then((data) => {
this.initial.module = data.module
this.initial.args = data.args
this.initial.instant = true
this.initial.runAfterSave = true
this.instantTask = true
this.ready = true
})
} else {
this.ready = true
}
break
case 'playbook':
this.initial.type = 'playbook'
if (this.item.id) {
this.initial.playbook = this.item.id
this.ready = true
} else {
this.ready = true
}
break
}
} else {
this.ready = true
}
}
}
}
</script>

View File

@@ -2,22 +2,27 @@
<div>
<JobRunDialog v-if="showJobRunDialog" :item="item" :visible.sync="showJobRunDialog" @submit="runJob" />
<GenericListPage :header-actions="headerActions" :table-config="tableConfig" />
<JobUpdateCreate :type="type" :item="item" />
</div>
</template>
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { ActionsFormatter, DateFormatter } from '@/components/Table/TableFormatters'
import JobUpdateCreate from './JobUpdateCreate.vue'
import JobRunDialog from '@/views/ops/Job/JobRunDialog'
import { openTaskPage } from '@/utils/jms'
export default {
components: {
JobRunDialog,
JobUpdateCreate,
GenericListPage
},
data() {
return {
type: '',
createUpdateVisible: false,
item: {},
runtime_parameters: {},
showJobRunDialog: false,
@@ -113,10 +118,9 @@ export default {
hasImport: false,
moreCreates: {
callback: (item) => {
this.$router.push({
name: 'JobCreate',
query: { type: item.name }
})
this.type = item.name
this.item = {}
this.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: this.tableConfig.url })
},
dropdown: [
{

View File

@@ -1,14 +1,19 @@
<template>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<div>
<GenericListTable :header-actions="headerActions" :table-config="tableConfig" />
<AdhocUpdateCreate />
</div>
</template>
<script>
import GenericListTable from '@/layout/components/GenericListTable'
import { ActionsFormatter } from '@/components/Table/TableFormatters'
import AdhocUpdateCreate from './Adhoc/AdhocUpdateCreate.vue'
export default {
components: {
GenericListTable
GenericListTable,
AdhocUpdateCreate
},
data() {
return {

View File

@@ -1,14 +1,14 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
import CodeEditor from '@/components/Form/FormFields/CodeEditor'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,19 +1,22 @@
<template>
<div>
<GenericListTable ref="list" :header-actions="headerActions" :table-config="tableConfig" />
<PlaybookCreateUpdate />
<UploadDialog v-if="uploadDialogVisible" :visible.sync="uploadDialogVisible" @completed="refreshTable" />
</div>
</template>
<script>
import GenericListTable from '@/layout/components/GenericListTable'
import PlaybookCreateUpdate from './Playbook/PlaybookCreateUpdate.vue'
import UploadDialog from '@/views/ops/Template/Playbook/UploadDialog'
import { ActionsFormatter } from '@/components/Table/TableFormatters'
export default {
components: {
UploadDialog,
GenericListTable
GenericListTable,
PlaybookCreateUpdate
},
data() {
return {
@@ -55,7 +58,7 @@ export default {
callback: (item) => {
switch (item.name) {
case 'create':
this.$router.push({ name: 'PlaybookCreate' })
this.$eventBus.$emit('showCreateUpdateDrawer', 'create', { url: this.tableConfig.url })
break
case 'upload':
this.uploadDialogVisible = true

View File

@@ -1,13 +1,13 @@
<template>
<GenericCreateUpdatePage v-bind="$data" />
<GenericCreateUpdateDrawer v-bind="$data" />
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import { GenericCreateUpdateDrawer } from '@/layout/components'
export default {
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
return {

View File

@@ -1,5 +1,5 @@
<template>
<GenericCreateUpdatePage
<GenericCreateUpdateDrawer
:fields="fields"
:fields-meta="fieldsMeta"
:initial="initial"
@@ -9,17 +9,17 @@
</template>
<script>
import { GenericCreateUpdatePage } from '@/layout/components'
import AssetSelect from '@/components/Apps/AssetSelect'
import { getDayFuture } from '@/utils/common'
import AccountFormatter from './components/AccountFormatter'
import { AllAccount } from '../const'
import GenericCreateUpdateDrawer from '@/layout/components/GenericCreateUpdateDrawer/index.vue'
import ProtocolsSelect from '@/components/Form/FormFields/AllOrSpec.vue'
export default {
name: 'AccountFormatter',
components: {
GenericCreateUpdatePage
GenericCreateUpdateDrawer
},
data() {
const nodesInitial = []

View File

@@ -11,6 +11,7 @@
v-bind="updateSelectedDialogSetting"
@update="handlePermBulkUpdate"
/>
<AssetPermissionCreateUpdate />
</Page>
</template>
@@ -21,12 +22,14 @@ import PermBulkUpdateDialog from './components/PermBulkUpdateDialog'
import AmountFormatter from '@/components/Table/TableFormatters/AmountFormatter'
import { mapGetters } from 'vuex'
import { AccountLabelMapper, AssetPermissionListPageSearchConfigOptions } from '../const'
import AssetPermissionCreateUpdate from './AssetPermissionCreateUpdate.vue'
export default {
components: {
Page,
AssetTreeTable,
PermBulkUpdateDialog
PermBulkUpdateDialog,
AssetPermissionCreateUpdate
},
data() {
const vm = this
@@ -55,7 +58,7 @@ export default {
name: {
formatterArgs: {
routeQuery: {
activeTab: 'AssetPermissionDetail'
tab: 'AssetPermissionDetail'
}
}
},
@@ -88,7 +91,7 @@ export default {
formatter: AmountFormatter,
formatterArgs: {
routeQuery: {
activeTab: 'AssetPermissionUser'
tab: 'AssetPermissionUser'
}
}
},
@@ -98,7 +101,7 @@ export default {
formatter: AmountFormatter,
formatterArgs: {
routeQuery: {
activeTab: 'AssetPermissionUser'
tab: 'AssetPermissionUser'
}
}
},
@@ -108,7 +111,7 @@ export default {
formatter: AmountFormatter,
formatterArgs: {
routeQuery: {
activeTab: 'AssetPermissionAsset'
tab: 'AssetPermissionAsset'
}
}
},
@@ -118,7 +121,7 @@ export default {
formatter: AmountFormatter,
formatterArgs: {
routeQuery: {
activeTab: 'AssetPermissionAsset'
tab: 'AssetPermissionAsset'
}
}
},
@@ -133,7 +136,7 @@ export default {
}
},
routeQuery: {
activeTab: 'AssetPermissionAccount'
tab: 'AssetPermissionAccount'
}
}
},

View File

@@ -122,7 +122,7 @@ export default {
},
callbacks: {
click: function() {
this.$router.push({ name: 'ProfileSetting', query: { activeTab: 'PasswordUpdate' }})
this.$router.push({ name: 'ProfileSetting', query: { tab: 'PasswordUpdate' }})
}.bind(this)
}
},
@@ -135,7 +135,7 @@ export default {
},
callbacks: {
click: function() {
this.$router.push({ name: 'ProfileSetting', query: { activeTab: 'SSHUpdate' }})
this.$router.push({ name: 'ProfileSetting', query: { tab: 'SSHUpdate' }})
}.bind(this)
}
},

View File

@@ -30,14 +30,21 @@ export default {
min: ['user_display', 'actions'],
default: [
'user_display', 'backend_display', 'ip', 'city',
'user_agent', 'date_created', 'actions'
'user_agent', 'date_created', 'is_active', 'actions'
]
},
columns: [
'user_display', 'backend_display', 'ip', 'city', 'type',
'user_agent', 'date_created', 'date_expired', 'actions'
'user_agent', 'date_created', 'is_active', 'date_expired', 'actions'
],
columnsMeta: {
is_active: {
label: this.$t('terminal.Active'),
formatterArgs: {
showText: false,
showFalse: false
}
},
user_display: {
label: this.$t('audits.User'),
formatter: function(row) {

View File

@@ -3,8 +3,7 @@
</template>
<script>
import BaseAssetCreateUpdate from '@/views/assets/Asset/AssetCreateUpdate/BaseAssetCreateUpdate'
import { MatchExcludeParenthesis, Required } from '@/components/Form/DataForm/rules'
import BaseAssetCreateUpdate from '@/views/assets/Asset/AssetCreateUpdate/BaseAssetCreateDrawer.vue'
export default {
components: {

View File

@@ -4,6 +4,7 @@
<span v-html="$t('terminal.AppletHostSelectHelpMessage')" />
</el-alert>
<ListTable class="applet-host" v-bind="$data" />
<AppletHostCreateUpdate />
</div>
</template>
@@ -11,11 +12,13 @@
import { ListTable } from '@/components'
import { openTaskPage } from '@/utils/jms'
import { ProtocolsFormatter } from '@/components/Table/TableFormatters'
import AppletHostCreateUpdate from './AppletHostCreateUpdate.vue'
export default {
name: 'AppletHost',
components: {
ListTable
ListTable,
AppletHostCreateUpdate
},
data() {
const vm = this

Some files were not shown because too many files have changed in this diff Show More