mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-14 11:55:34 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
607eec6c44 | ||
|
|
28daf41fb5 | ||
|
|
e45720af1b | ||
|
|
2c69b36291 | ||
|
|
d267cd1f5e | ||
|
|
807e3a407a | ||
|
|
1ba790e680 | ||
|
|
44b701edbc | ||
|
|
8619ab8bca | ||
|
|
79e92fa46b | ||
|
|
f19c863440 | ||
|
|
fff8b79a45 | ||
|
|
cf810b3d3e | ||
|
|
f58e37a76a | ||
|
|
5889e20aae | ||
|
|
7caa2c8264 | ||
|
|
865388dedc | ||
|
|
35c1077eed | ||
|
|
487e199995 | ||
|
|
f584e96675 | ||
|
|
1f4f1d3712 | ||
|
|
08facb1eda | ||
|
|
34cb9424d4 | ||
|
|
36767cd265 | ||
|
|
86b9fc8f5a | ||
|
|
49054e5dc0 | ||
|
|
bac7cef23c | ||
|
|
4013ea6212 | ||
|
|
37153ebe1d | ||
|
|
da35d9be25 | ||
|
|
c3c24b0ad1 | ||
|
|
98da517724 | ||
|
|
f002c7f917 | ||
|
|
0d4e4324ce | ||
|
|
fdeab46970 | ||
|
|
5acbdd5679 | ||
|
|
3a64120241 | ||
|
|
81d1cbf3a1 | ||
|
|
cec17bbef8 | ||
|
|
fbc3373e1b | ||
|
|
b4a935ab15 | ||
|
|
7fbff42067 | ||
|
|
5077fec5a8 | ||
|
|
c4619af96f | ||
|
|
025d0abeae | ||
|
|
5735a591ba | ||
|
|
3b664ee1dc | ||
|
|
a3f6de330e | ||
|
|
cbc67a5a4c | ||
|
|
dec0593907 | ||
|
|
1ed432b1e2 | ||
|
|
06d6c54db8 |
@@ -46,7 +46,7 @@ server {
|
||||
|
||||
|
||||
## License & Copyright
|
||||
Copyright (c) 2014-2020 飞致云 FIT2CLOUD, All rights reserved.
|
||||
Copyright (c) 2014-2021 飞致云 FIT2CLOUD, All rights reserved.
|
||||
|
||||
Licensed under The GNU General Public License version 2 (GPLv2) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import request from '@/utils/request'
|
||||
|
||||
export function getTicketOpenCount(assign) {
|
||||
return request({
|
||||
url: `/api/v1/tickets/tickets/?assign=${assign}&status=open&offset=0&limit=15&display=1&draw=1/`,
|
||||
url: `/api/v1/tickets/tickets/?assignees__id=${assign}&status=open&offset=0&limit=15&display=1&draw=1/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="grouped ? 'el-button-group' : ''">
|
||||
<el-button v-for="item in iActions" :key="item.name" :size="size" v-bind="item" @click="handleClick(item.name)">
|
||||
<el-tooltip v-if="['actionExport', 'actionImport', 'actionRefresh'].indexOf(item.name) !== -1" effect="dark" :content="item.tip" placement="top">
|
||||
<el-tooltip v-if="item.tip" effect="dark" :content="item.tip" placement="top">
|
||||
<i v-if="item.fa" :class="'fa ' + item.fa" />{{ item.title }}
|
||||
</el-tooltip>
|
||||
<span v-else>
|
||||
|
||||
@@ -157,6 +157,11 @@ export default {
|
||||
y -= (offset.top + scrollTop) / 3 - 10
|
||||
x += document.body.scrollLeft
|
||||
y += document.body.scrollTop + document.documentElement.scrollTop
|
||||
|
||||
if (y + $(`#${rMenuID} ul`).height() >= window.innerHeight) {
|
||||
y -= $(`#${rMenuID} ul`).height()
|
||||
}
|
||||
|
||||
this.rMenu.css({ 'top': y + 'px', 'left': x + 'px', 'visibility': 'visible' })
|
||||
$(`#${rMenuID} ul`).show()
|
||||
$('body').bind('mousedown', this.onBodyMouseDown)
|
||||
@@ -235,10 +240,7 @@ export default {
|
||||
})
|
||||
},
|
||||
refresh: function() {
|
||||
this.$axios.post(
|
||||
'/api/v1/assets/nodes/00000000-0000-0000-0000-000000000000/tasks/',
|
||||
{ action: 'refresh_cache' }
|
||||
)
|
||||
|
||||
},
|
||||
getSelectedNodes: function() {
|
||||
return this.zTree.getSelectedNodes()
|
||||
|
||||
@@ -1010,7 +1010,7 @@ export default {
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
if (this.size === val) return
|
||||
|
||||
this.$emit('sizeChange', val)
|
||||
this.page = defaultFirstPage
|
||||
this.size = val
|
||||
this.getList()
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
<template>
|
||||
<ElDatableTable ref="table" class="el-table" v-bind="tableConfig" @update="onUpdate" v-on="iListeners" />
|
||||
<ElDatableTable
|
||||
ref="table"
|
||||
class="el-table"
|
||||
v-bind="tableConfig"
|
||||
@update="onUpdate"
|
||||
v-on="iListeners"
|
||||
@sizeChange="handleSizeChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { default as ElDatableTable } from './compenents/el-data-table'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DataTable',
|
||||
@@ -58,7 +66,6 @@ export default {
|
||||
pageCount: 5,
|
||||
paginationLayout: 'total, sizes, prev, pager, next',
|
||||
paginationSizes: [15, 30, 50, 100],
|
||||
paginationSize: 15,
|
||||
paginationBackground: true,
|
||||
transformQuery: query => {
|
||||
if (query.page && query.size) {
|
||||
@@ -85,12 +92,17 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
tableConfig() {
|
||||
const config = Object.assign(this.defaultConfig, this.config)
|
||||
const tableDefaultConfig = this.defaultConfig
|
||||
tableDefaultConfig.paginationSize = _.get(this.globalTableConfig, 'paginationSize', 15)
|
||||
const config = Object.assign(tableDefaultConfig, this.config)
|
||||
return config
|
||||
},
|
||||
iListeners() {
|
||||
return Object.assign({}, this.$listeners, this.tableConfig.listeners)
|
||||
}
|
||||
},
|
||||
...mapGetters({
|
||||
'globalTableConfig': 'tableConfig'
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
config: {
|
||||
@@ -131,6 +143,14 @@ export default {
|
||||
this.toggleRowSelection(row, true)
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.$store.commit('table/SET_TABLE_CONFIG',
|
||||
{
|
||||
key: 'paginationSize',
|
||||
value: val
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import IBox from '../IBox'
|
||||
import TableAction from './TableAction'
|
||||
import Emitter from '@/mixins/emitter'
|
||||
import deepmerge from 'deepmerge'
|
||||
|
||||
export default {
|
||||
name: 'ListTable',
|
||||
components: {
|
||||
@@ -41,6 +42,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
dataTable() {
|
||||
return this.$refs.dataTable.$refs.dataTable
|
||||
},
|
||||
@@ -55,20 +57,9 @@ export default {
|
||||
}
|
||||
return true
|
||||
},
|
||||
hasCloneAction() {
|
||||
const hasClone = _.get(this.tableConfig, 'columnsMeta.actions.formatterArgs.hasClone', null)
|
||||
if (hasClone) {
|
||||
return true
|
||||
}
|
||||
if (this.hasCreateAction && hasClone == null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
iTableConfig() {
|
||||
const config = deepmerge(this.tableConfig, { extraQuery: this.extraQuery })
|
||||
this.$log.debug('Header actions', this.headerActions)
|
||||
_.set(config, 'columnsMeta.actions.formatterArgs.hasClone', this.hasCloneAction)
|
||||
this.$log.debug('ListTable: iTableConfig change', config)
|
||||
return config
|
||||
}
|
||||
@@ -79,6 +70,12 @@ export default {
|
||||
this.$log.debug('ListTable: found extraQuery change')
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
tableColConfig: {
|
||||
handler() {
|
||||
this.$log.debug('ListTable: found colConfig change')
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"appPath": "应用路径",
|
||||
"appType": "应用类型",
|
||||
"appName": "应用名称",
|
||||
"asset": "资产",
|
||||
"database": "数据库",
|
||||
"host": "主机",
|
||||
@@ -58,8 +59,10 @@
|
||||
"AdminUserDetail": "管理用户详情",
|
||||
"AdminUserListHelpMessage": "管理用户是资产(被控服务器)上的 root,或拥有 NOPASSWD: ALL sudo 权限的用户, JumpServer 使用该用户来 `推送系统用户`、`获取资产硬件信息` 等。\n",
|
||||
"Asset": "资产",
|
||||
"HardwareInfo": "硬件信息",
|
||||
"AssetDetail": "资产详情",
|
||||
"AssetList": "资产列表",
|
||||
"ReplaceNodeAssetsAdminUser":"替换节点资产的管理员",
|
||||
"AssetListHelpMessage": "左侧是资产树,右击可以新建、删除、更改树节点,授权资产也是以节点方式组织的,右侧是属于该节点下的资产\n",
|
||||
"TestGatewayTestConnection":"测试连接网关",
|
||||
"TestGatewayHelpMessage": "如果使用了nat端口映射,请设置为ssh真实监听的端口",
|
||||
@@ -184,11 +187,13 @@
|
||||
"Action": "动作",
|
||||
"RequestTickets": "申请工单",
|
||||
"Actions": "操作",
|
||||
"CustomCol":"自定义列表字段",
|
||||
"Activate": "激活",
|
||||
"NeedSpecifiedFile": "需上传指定格式文件",
|
||||
"TestPortErrorMsg":"端口错误,请重新输入",
|
||||
"Active": "激活中",
|
||||
"actionsTips":"剪切板权限控制目前仅支持 RDP/VNC 协议的连接",
|
||||
"TableColSettingInfo": "请选择您想显示的列表详细信息。",
|
||||
"Add": "添加",
|
||||
"UpdateAssetDetail": "配置更多信息",
|
||||
"AddSuccessMsg": "添加成功",
|
||||
@@ -200,6 +205,7 @@
|
||||
"Basic": "基本",
|
||||
"PleaseAgreeToTheTerms": "请同意条款",
|
||||
"BasicInfo": "基本信息",
|
||||
"ApplyInfo": "申请信息",
|
||||
"Cancel": "取消",
|
||||
"Close": "关闭",
|
||||
"Command filter": "命令过滤器",
|
||||
@@ -331,7 +337,8 @@
|
||||
"NUMBER_REQUIRED": "须包含数字",
|
||||
"SPECIAL_CHAR_REQUIRED": "须包含特殊字符",
|
||||
"MIN_LENGTH_ERROR": "密码最小长度 {0} 位"
|
||||
}
|
||||
},
|
||||
"lastCannotBeDeleteMsg": "最后一项,不能被删除"
|
||||
},
|
||||
"dashboard": {
|
||||
"ActiveAsset": "近期被登录过",
|
||||
@@ -422,6 +429,7 @@
|
||||
"SystemUser": "系统用户",
|
||||
"User": "用户",
|
||||
"UserGroups": "用户组",
|
||||
"PermName":"授权名称",
|
||||
"DatabaseAppPermission": "数据库授权",
|
||||
"RemoteAppPermission": "远程应用授权",
|
||||
"addApplicationToThisPermission": "添加应用",
|
||||
@@ -792,6 +800,8 @@
|
||||
"Assignee": "处理人",
|
||||
"Assignees": "待处理人",
|
||||
"Close": "关闭",
|
||||
"OpenStatus":"开启",
|
||||
"CloseStatus":"关闭",
|
||||
"Comment": "备注",
|
||||
"MyTickets": "我发起的",
|
||||
"RequestPerm":"授权申请",
|
||||
@@ -800,10 +810,14 @@
|
||||
"reply": "回复",
|
||||
"status": "状态",
|
||||
"title": "标题",
|
||||
"action": "动作",
|
||||
"IPGroup": "IP 组",
|
||||
"type": "类型",
|
||||
"user": "用户",
|
||||
"Status": "状态",
|
||||
"Open": "待处理",
|
||||
"OrgName":"组织名称",
|
||||
"AssignedInfo":"审批信息",
|
||||
"OpenTicket": "创建工单",
|
||||
"HandleTicket": "处理工单",
|
||||
"FinishedTicket": "完成工单",
|
||||
@@ -812,6 +826,7 @@
|
||||
"Asset": "资产",
|
||||
"SystemUser": "系统用户",
|
||||
"RequestAssetPerm": "申请资产授权",
|
||||
"RequestApplicationPerm": "申请应用授权",
|
||||
"Applicant": "申请人",
|
||||
"Pending": "待处理",
|
||||
"Approved": "已同意",
|
||||
@@ -819,7 +834,8 @@
|
||||
"Closed": "已完成",
|
||||
"helpText": {
|
||||
"ips": "请输入逗号分割的IP地址组",
|
||||
"fuzzySearch": "支持模糊搜索"
|
||||
"fuzzySearch": "支持模糊搜索",
|
||||
"application": "请输入逗号分割的应用名称组"
|
||||
}
|
||||
},
|
||||
"tree": {
|
||||
@@ -1060,6 +1076,14 @@
|
||||
"DeleteOrgTitle": "请确保组织内的以下信息已删除",
|
||||
"DeleteOrgMsg": "用户列表、用户组、资产列表、网域列表、管理用户、系统用户、标签管理、资产授权规则",
|
||||
"OrgRole": "组织角色",
|
||||
"users_amount": "用户数量",
|
||||
"groups_amount": "用户组数量",
|
||||
"assets_amount": "资产数量",
|
||||
"admin_users_amount": "管理用户数量",
|
||||
"system_users_amount": "系统用户数量",
|
||||
"applications_amount": "应用数量",
|
||||
"asset_perms_amount": "资产授权数量",
|
||||
"app_perms_amount": "应用授权数量",
|
||||
"CreateOrgMsg": "请去组织详情内添加用户",
|
||||
"AddOrgMembers": "添加组织成员"
|
||||
},
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"appPath": "App path",
|
||||
"appType": "App type",
|
||||
"appName": "App name",
|
||||
"asset": "Asset",
|
||||
"database": "Database",
|
||||
"host": "Host",
|
||||
@@ -55,9 +56,11 @@
|
||||
"Action": "Action",
|
||||
"ActiveSelected": "Active selected",
|
||||
"AdminUser": "Admin user",
|
||||
"ReplaceNodeAssetsAdminUser":"Replace node assets admin user with this",
|
||||
"AdminUserDetail": "Admin user detail",
|
||||
"AdminUserListHelpMessage": "Admin users are asset (charged server) on the root, or have NOPASSWD: ALL sudo permissions users, JumpServer users of the system using the user to `push system user`, `get assets hardware information`, etc.\n",
|
||||
"Asset": "Asset",
|
||||
"HardwareInfo": "Hardware info",
|
||||
"Hardware": "Hardware",
|
||||
"AccountList": "Account list",
|
||||
"AssetDetail": "Asset detail",
|
||||
@@ -182,6 +185,7 @@
|
||||
"common": {
|
||||
"Nothing": "Nothing",
|
||||
"Action": "Action",
|
||||
"CustomCol":"Custom table col",
|
||||
"RequestTickets": "Request tickets",
|
||||
"Actions": "Actions",
|
||||
"NeedSpecifiedFile": "Required to upload the specified format file",
|
||||
@@ -189,6 +193,7 @@
|
||||
"Activate": "Activate",
|
||||
"actionsTips":"Clipboard's copy and paste control only support RDP/VNC protocol.",
|
||||
"Active": "Active",
|
||||
"TableColSettingInfo": "Please select the list details you want to display",
|
||||
"Add": "Add",
|
||||
"PleaseAgreeToTheTerms": "Please agree to the terms",
|
||||
"PushSelected":"Push selected",
|
||||
@@ -200,6 +205,7 @@
|
||||
"BadConflictErrorMsg": "Refreshing, please try again later",
|
||||
"Basic": "Basic",
|
||||
"BasicInfo": "Basic info",
|
||||
"ApplyInfo": "Apply info",
|
||||
"Cancel": "Cancel",
|
||||
"Close": "Close",
|
||||
"Command filter": "Command filter",
|
||||
@@ -329,7 +335,8 @@
|
||||
"NUMBER_REQUIRED": "Number required",
|
||||
"SPECIAL_CHAR_REQUIRED": "Special char required",
|
||||
"MIN_LENGTH_ERROR": "Password minimum length {}"
|
||||
}
|
||||
},
|
||||
"lastCannotBeDeleteMsg": "The last one can't be delete"
|
||||
},
|
||||
"dashboard": {
|
||||
"ActiveAsset": "Asset active",
|
||||
@@ -433,6 +440,7 @@
|
||||
"addUserGroupToThisPermission": "Add user group to this permission",
|
||||
"addUserToThisPermission": "Add user to this permission",
|
||||
"all": "All",
|
||||
"PermName":"Perm name",
|
||||
"assetAndNode": "Assets and node",
|
||||
"assetCount": "Asset count",
|
||||
"connect": "Connect",
|
||||
@@ -779,13 +787,18 @@
|
||||
"AssignedMe": "Assigned me",
|
||||
"Assignee": "Assignee",
|
||||
"RequestPerm":"Request Perm",
|
||||
"AssignedInfo":"Assigned Info",
|
||||
"OpenTicket": "Open Ticket",
|
||||
"HandleTicket": "Handle Ticket",
|
||||
"FinishedTicket": "Finished Ticket",
|
||||
"Assignees": "Assignees",
|
||||
"Close": "Close",
|
||||
"OpenStatus":"Open",
|
||||
"CloseStatus":"Close",
|
||||
"Comment": "Comment",
|
||||
"MyTickets": "My tickets",
|
||||
"action": "Action",
|
||||
"IPGroup": "IP 组",
|
||||
"Reject": "Reject",
|
||||
"date": "Date",
|
||||
"reply": "Reply",
|
||||
@@ -795,19 +808,22 @@
|
||||
"user": "User",
|
||||
"Status": "Status",
|
||||
"Open": "Open",
|
||||
"OrgName":"Org name",
|
||||
"IP": "IP",
|
||||
"Hostname": "Hostname",
|
||||
"Asset": "Asset",
|
||||
"SystemUser": "System user",
|
||||
"Applicant": "Applicant",
|
||||
"RequestAssetPerm": "Request asset perm",
|
||||
"RequestApplicationPerm": "Request application perm",
|
||||
"Pending": "Open",
|
||||
"Approved": "Approved",
|
||||
"Rejected": "Rejected",
|
||||
"Closed": "Closed",
|
||||
"helpText": {
|
||||
"ips": "Enter the IP address group, separated by commas",
|
||||
"fuzzySearch": "Support for fuzzy search"
|
||||
"fuzzySearch": "Support for fuzzy search",
|
||||
"application": "Enter the application group, separated by commas"
|
||||
}
|
||||
},
|
||||
"tree": {
|
||||
@@ -1049,7 +1065,15 @@
|
||||
"DeleteOrgMsg":"User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission",
|
||||
"OrgRole": "Org role",
|
||||
"CreateOrgMsg": "Please go to Organization Details to add users",
|
||||
"AddOrgMembers": "Add organization members"
|
||||
"AddOrgMembers": "Add organization members",
|
||||
"users_amount": "Users amount",
|
||||
"groups_amount": "Groups amount",
|
||||
"assets_amount": "Assets amount",
|
||||
"admin_users_amount": "Admin users amount",
|
||||
"system_users_amount": "System users amount",
|
||||
"applications_amount": "Applications amount",
|
||||
"asset_perms_amount": "Asset perms amount",
|
||||
"app_perms_amount": "App perms amount"
|
||||
},
|
||||
"RestoreButton": "Restore Default",
|
||||
"SubscriptionID": "Subscription ID",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Version <strong> dev </strong> <span v-if="!publicSettings.XPACK_LICENSE_IS_VALID"> GPLv2. </span>
|
||||
</div>
|
||||
<div v-if="!publicSettings.XPACK_LICENSE_IS_VALID" style="padding-left:20px;">
|
||||
<strong>Copyright</strong> FIT2CLOUD 飞致云 © 2014-2020
|
||||
<strong>Copyright</strong> FIT2CLOUD 飞致云 © 2014-2021
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<script>
|
||||
import { getTicketOpenCount } from '@/api/ticket'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'WebTerminal',
|
||||
@@ -17,13 +18,17 @@ export default {
|
||||
assignedTicketCount: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'currentUser'
|
||||
])
|
||||
},
|
||||
created() {
|
||||
this.ticketsOpenedCount()
|
||||
},
|
||||
methods: {
|
||||
|
||||
ticketsOpenedCount() {
|
||||
getTicketOpenCount(1).then(data => {
|
||||
getTicketOpenCount(this.currentUser.id).then(data => {
|
||||
this.assignedTicketCount = data.count
|
||||
})
|
||||
},
|
||||
|
||||
@@ -45,5 +45,12 @@ export default [
|
||||
name: 'CeleryTaskLog',
|
||||
hidden: true,
|
||||
meta: { title: i18n.t('route.CeleryTaskLog'), roles: ['SuperAdmin', 'Admin', 'Auditor', 'User'] }
|
||||
},
|
||||
{
|
||||
path: '/ops/task/task/:id/log/',
|
||||
component: () => import('@/views/ops/CeleryTaskLog'),
|
||||
name: 'TaskLog',
|
||||
hidden: true,
|
||||
meta: { title: i18n.t('route.CeleryTaskLog'), roles: ['SuperAdmin', 'Admin', 'Auditor', 'User'] }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -56,7 +56,7 @@ const ApplicationPermissionRoutes = [
|
||||
component: () => import('@/views/perms/ApplicationPermission/ApplicationPermissionDetail/index'),
|
||||
name: 'ApplicationPermissionDetail',
|
||||
hidden: true,
|
||||
meta: { title: i18n.t('route.ApplicationPermissionDetail'), activeMenu: '/perms/remote-app-permissions' }
|
||||
meta: { title: i18n.t('route.ApplicationPermissionDetail'), activeMenu: '/perms/app-permissions' }
|
||||
},
|
||||
{
|
||||
path: ':id/update',
|
||||
|
||||
@@ -27,5 +27,19 @@ export default [
|
||||
component: () => import('@/views/tickets/RequestAssetPerm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
component: () => import('@/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate'),
|
||||
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/:id',
|
||||
name: 'AppsTicketDetail',
|
||||
component: () => import('@/views/tickets/RequestApplicationPerm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -103,6 +103,20 @@ export default [
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/create',
|
||||
name: 'RequestApplicationPermTicketCreateUpdate',
|
||||
component: () => import('@/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate'),
|
||||
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/request-application-perm/:id',
|
||||
name: 'AppsTicketDetail',
|
||||
component: () => import('@/views/tickets/RequestApplicationPerm/Detail/index'),
|
||||
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_USE] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'tickets/:id',
|
||||
name: 'TicketDetail',
|
||||
|
||||
@@ -13,6 +13,7 @@ const getters = {
|
||||
currentOrgRoles: state => state.users.roles,
|
||||
currentOrgPerms: state => state.users.perms,
|
||||
MFAVerifyAt: state => state.users.MFAVerifyAt,
|
||||
MFA_TTl: state => state.settings.publicSettings.SECURITY_MFA_VERIFY_TTL
|
||||
MFA_TTl: state => state.settings.publicSettings.SECURITY_MFA_VERIFY_TTL,
|
||||
tableConfig: state => state.table.tableConfig
|
||||
}
|
||||
export default getters
|
||||
|
||||
28
src/store/modules/table.js
Normal file
28
src/store/modules/table.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import VueCookie from 'vue-cookie'
|
||||
import Vue from 'vue'
|
||||
|
||||
function getTableConfigfromCookie() {
|
||||
return VueCookie.get('tableConfig') ? JSON.parse(VueCookie.get('tableConfig')) : {}
|
||||
}
|
||||
|
||||
const state = {
|
||||
tableConfig: getTableConfigfromCookie()
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
SET_TABLE_CONFIG: (state, tableConfig) => {
|
||||
Vue.set(state.tableConfig, tableConfig.key, tableConfig.value)
|
||||
VueCookie.set('tableConfig', JSON.stringify(state.tableConfig), 14)
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@@ -38,7 +38,6 @@ const mutations = {
|
||||
state.orgs = orgs
|
||||
},
|
||||
MODIFY_ORG: (state, org) => {
|
||||
// console.log(state.orgs)
|
||||
state.orgs = state.orgs.map(oldOrg => {
|
||||
if (oldOrg.id === org.id) {
|
||||
oldOrg.name = org.name
|
||||
|
||||
@@ -90,6 +90,11 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'platform',
|
||||
label: this.$t('assets.Platform'),
|
||||
width: '120px'
|
||||
},
|
||||
{
|
||||
prop: 'comment',
|
||||
label: this.$t('assets.Comment'),
|
||||
@@ -155,10 +160,10 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
refreshAllFavorites() {
|
||||
this.tableConfig.columns[4].formatterArgs.loading = true
|
||||
this.tableConfig.columns[this.tableConfig.columns.length - 1].formatterArgs.loading = true
|
||||
this.$axios.get('/api/v1/assets/favorite-assets/').then(resp => {
|
||||
this.allFavorites = resp
|
||||
this.tableConfig.columns[4].formatterArgs.loading = false
|
||||
this.tableConfig.columns[this.tableConfig.columns.length - 1].formatterArgs.loading = false
|
||||
})
|
||||
},
|
||||
addOrDeleteFavorite(assetId) {
|
||||
|
||||
@@ -77,8 +77,11 @@ export function toSafeLocalDateStr(d) {
|
||||
return ''
|
||||
}
|
||||
const date = safeDate(d)
|
||||
// let date_s = date.toLocaleString(getUserLang(), {hour12: false});
|
||||
const date_s = date.toLocaleString(getUserLang(), { hourCycle: 'h23' })
|
||||
// const date_s = date.toLocaleString(getUserLang(), { hourCycle: 'h23' })
|
||||
const date_s =
|
||||
date.toLocaleDateString(getUserLang(), { hourCycle: 'h23' }) +
|
||||
' ' +
|
||||
date.toLocaleTimeString(getUserLang(), { hourCycle: 'h23' })
|
||||
return date_s
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ function refreshSessionAgeDelay(response) {
|
||||
}
|
||||
timer = setTimeout(function() {
|
||||
refreshSessionIdAge()
|
||||
}, 60 * 10 * 1000)
|
||||
}, 30 * 1000)
|
||||
}
|
||||
|
||||
// response interceptor
|
||||
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
actions: {
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
hasClone: true,
|
||||
hasClone: false,
|
||||
performDelete: function({ row, col, cellValue, reload }) {
|
||||
this.$axios.delete(
|
||||
`/api/v1/applications/applications/${row.id}/`
|
||||
|
||||
@@ -29,6 +29,7 @@ export default {
|
||||
actions: {
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
hasClone: false,
|
||||
performDelete: function({ row, col, cellValue, reload }) {
|
||||
this.$axios.delete(
|
||||
`/api/v1/applications/applications/${row.id}/`
|
||||
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasClone: true,
|
||||
hasClone: false,
|
||||
onUpdate: ({ row }) => {
|
||||
vm.$router.push({ name: 'RemoteAppUpdate', params: { id: row.id }, query: { type: row.type }})
|
||||
},
|
||||
|
||||
@@ -4,21 +4,16 @@
|
||||
<el-col :span="16">
|
||||
<AssetUserTable :url="assetUserUrl" :has-import="false" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QuickActions from '@/components/QuickActions/index'
|
||||
import { AssetUserTable } from '@/components'
|
||||
|
||||
export default {
|
||||
name: 'Detail',
|
||||
components: {
|
||||
QuickActions,
|
||||
AssetUserTable
|
||||
},
|
||||
props: {
|
||||
126
src/views/assets/AdminUser/AdminUserDetail/AssetList.vue
Normal file
126
src/views/assets/AdminUser/AdminUserDetail/AssetList.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<RelationCard ref="RelationCard" type="info" style="margin-top: 15px" v-bind="nodeRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QuickActions from '@/components/QuickActions/index'
|
||||
import ListTable from '@/components/ListTable'
|
||||
import RelationCard from '@/components/RelationCard'
|
||||
import { BooleanFormatter } from '@/components/ListTable/formatters'
|
||||
|
||||
export default {
|
||||
name: 'AssetList',
|
||||
components: {
|
||||
QuickActions,
|
||||
ListTable,
|
||||
RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/assets/assets/?admin_user__id=${this.object.id}`,
|
||||
columns: [
|
||||
'hostname', 'ip', 'admin_user_display', 'connectivity'
|
||||
],
|
||||
columnsMeta: {
|
||||
admin_user_display: {
|
||||
label: this.$t('assets.AdminUser')
|
||||
},
|
||||
connectivity: {
|
||||
label: this.$t('assets.Reachable'),
|
||||
formatter: BooleanFormatter,
|
||||
formatterArgs: {
|
||||
iconChoices: {
|
||||
0: 'fa-times text-danger',
|
||||
1: 'fa-check text-primary',
|
||||
2: 'fa-circle text-warning'
|
||||
},
|
||||
typeChange: function(val) {
|
||||
return val.status
|
||||
},
|
||||
hasTips: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasLeftActions: false,
|
||||
hasBulkDelete: false,
|
||||
hasImport: false,
|
||||
hasExport: true,
|
||||
hasCreate: false,
|
||||
hasSearch: true,
|
||||
hasMoreActions: false
|
||||
},
|
||||
quickActions: [
|
||||
{
|
||||
title: this.$t('assets.TestAssetsConnective'),
|
||||
attrs: {
|
||||
type: 'primary',
|
||||
label: this.$t('assets.Test')
|
||||
},
|
||||
callbacks: {
|
||||
click: function() {
|
||||
this.$axios.get(
|
||||
`/api/v1/assets/admin-users/${this.object.id}/connective/`
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '', 'width=900,height=600')
|
||||
}
|
||||
)
|
||||
}.bind(this)
|
||||
}
|
||||
}
|
||||
],
|
||||
nodeRelationConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('assets.ReplaceNodeAssetsAdminUser'),
|
||||
objectsAjax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
},
|
||||
performAdd: (items) => {
|
||||
const data = []
|
||||
const relationUrl = `/api/v1/assets/admin-users/${this.object.id}/nodes/`
|
||||
items.map(v => {
|
||||
data.push(v.value)
|
||||
})
|
||||
return this.$axios.patch(relationUrl, { nodes: data }).then(res => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
|
||||
})
|
||||
},
|
||||
onAddSuccess: () => {
|
||||
this.$refs.RelationCard.$refs.select2.clearSelected()
|
||||
this.$refs.ListTable.reloadTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -9,13 +9,15 @@
|
||||
<script>
|
||||
import { GenericDetailPage, TabPage } from '@/layout/components'
|
||||
import Detail from './Detail.vue'
|
||||
import AssetUserList from './AssetUserList.vue'
|
||||
import AccountList from './AccountList.vue'
|
||||
import AssetList from './AssetList.vue'
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
TabPage,
|
||||
Detail,
|
||||
AssetUserList
|
||||
AssetList,
|
||||
AccountList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -28,8 +30,12 @@ export default {
|
||||
name: 'Detail'
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AssetUserList'),
|
||||
name: 'AssetUserList'
|
||||
title: this.$t('assets.AssetList'),
|
||||
name: 'AssetList'
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AccountList'),
|
||||
name: 'AccountList'
|
||||
}
|
||||
],
|
||||
hasRightSide: true
|
||||
|
||||
@@ -135,6 +135,7 @@ export default {
|
||||
actions: {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
hasClone: true,
|
||||
performDelete: ({ row, col }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/assets/assets/${id}/`
|
||||
|
||||
@@ -36,6 +36,7 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasClone: false,
|
||||
updateRoute: {
|
||||
name: 'CommandFilterRulesUpdate',
|
||||
query: {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMeta"
|
||||
:url="url"
|
||||
:has-detail-in-msg="false"
|
||||
:get-next-route="getNextRoute"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
:fields="fields"
|
||||
:has-detail-in-msg="false"
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMeta"
|
||||
:url="url"
|
||||
|
||||
@@ -96,6 +96,9 @@ export default {
|
||||
hidden: (form) => {
|
||||
this.fieldsMeta.username.el.disabled = form.username_same_with_user
|
||||
return form.protocol === 'k8s'
|
||||
},
|
||||
el: {
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
auto_generate_key: {
|
||||
@@ -233,9 +236,10 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
const params = this.$route.params
|
||||
const method = params.id ? 'post' : 'put'
|
||||
if (method === 'post') {
|
||||
const method = params.id ? 'update' : 'create'
|
||||
if (method === 'update') {
|
||||
this.fieldsMeta.token.rules[0].required = false
|
||||
this.fieldsMeta.username_same_with_user.el.disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,14 @@ export default {
|
||||
return selectedRows.length > 0 && vm.object.auto_push
|
||||
},
|
||||
callback: this.bulkPushCallback.bind(this)
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.TestAssetsConnective'),
|
||||
name: 'TestSelected',
|
||||
can({ selectedRows }) {
|
||||
return selectedRows.length > 0
|
||||
},
|
||||
callback: this.bulkTestCallback.bind(this)
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -214,7 +222,17 @@ export default {
|
||||
})
|
||||
const data = { action: 'push', assets: assets }
|
||||
this.$axios.post(theUrl, data).then(resp => {
|
||||
window.open(`/#/ops/celery/task/${resp.task}/log/`, '', 'width=900,height=600')
|
||||
window.open(`/#/ops/task/task/${resp.task}/log/`, '', 'width=900,height=600')
|
||||
})
|
||||
},
|
||||
bulkTestCallback({ selectedRows }) {
|
||||
const theUrl = `/api/v1/assets/system-users/${this.object.id}/tasks/`
|
||||
const assets = selectedRows.map((v) => {
|
||||
return v.asset
|
||||
})
|
||||
const data = { action: 'test', assets: assets }
|
||||
this.$axios.post(theUrl, data).then(resp => {
|
||||
window.open(`/#/ops/task/task/${resp.task}/log/`, '', 'width=900,height=600')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ export default {
|
||||
},
|
||||
assets_amount: {
|
||||
width: '80px'
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasClone: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,11 +8,14 @@ import { Terminal } from 'xterm'
|
||||
import { FitAddon } from 'xterm-addon-fit'
|
||||
export default {
|
||||
name: 'CeleryTaskLog',
|
||||
props: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
xterm: null,
|
||||
ws: null,
|
||||
taskId: this.$route.params.id,
|
||||
type: this.$route.params.type || this.$route.query.type || 'celery',
|
||||
url: '/ws/ops/tasks/log/',
|
||||
failOverPort: process.env.VUE_APP_WS_PORT
|
||||
}
|
||||
@@ -71,7 +74,7 @@ export default {
|
||||
this.xterm.write(data.message)
|
||||
}
|
||||
this.ws.onopen = (e) => {
|
||||
const msg = { 'task': this.taskId }
|
||||
const msg = { 'task': this.taskId, 'type': this.type }
|
||||
this.ws.send(JSON.stringify(msg))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -77,7 +77,7 @@ export default {
|
||||
value: this.object.id,
|
||||
formatter: function(row, value) {
|
||||
const onClick = function() {
|
||||
window.open(`/#/ops/celery/task/${value}/log/`, '', 'width=900,height=600')
|
||||
window.open(`/#/ops/task/task/${value}/log/?type=ansible`, '', 'width=900,height=600')
|
||||
}
|
||||
const title = this.$t('common.View')
|
||||
return <a onClick={onClick} >{ title }</a>
|
||||
|
||||
@@ -101,7 +101,7 @@ export default {
|
||||
value: this.object.latest_execution.id,
|
||||
formatter: function(row, value) {
|
||||
const onClick = function() {
|
||||
window.open(`/#/ops/celery/task/${value}/log/`, '', 'width=900,height=600')
|
||||
window.open(`/#/ops/task/task/${value}/log/?type=ansible`, '', 'width=900,height=600')
|
||||
}
|
||||
const title = this.$t('common.View')
|
||||
return <a onClick={onClick} >{ title }</a>
|
||||
|
||||
@@ -54,15 +54,9 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRefresh: true,
|
||||
hasLeftActions: true,
|
||||
hasRightActions: true,
|
||||
hasLeftActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
hasBulkUpdate: false
|
||||
hasImport: false
|
||||
},
|
||||
userRelationConfig: {
|
||||
icon: 'fa-user',
|
||||
|
||||
@@ -56,15 +56,9 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRefresh: true,
|
||||
hasLeftActions: true,
|
||||
hasRightActions: true,
|
||||
hasLeftActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
hasBulkUpdate: false
|
||||
hasImport: false
|
||||
},
|
||||
remoteAppRelationConfig: {
|
||||
icon: 'fa-edit',
|
||||
@@ -117,7 +111,7 @@ export default {
|
||||
this.$log.debug('Select value', that.select2.value)
|
||||
that.iHasObjects = [...that.iHasObjects, ...objects]
|
||||
that.$refs.select2.clearSelected()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
this.$refs.ListTable.reloadTable()
|
||||
},
|
||||
performDelete: (item) => {
|
||||
@@ -125,6 +119,10 @@ export default {
|
||||
const relationUrl = `/api/v1/perms/application-permissions/${objectId}/`
|
||||
const objectOldRelationSystemUsers = this.object.system_users
|
||||
const objectNewRelationSystemUsers = objectOldRelationSystemUsers.filter(v => v !== item.value)
|
||||
if (objectNewRelationSystemUsers.length === 0) {
|
||||
this.$message.error(this.$tc('common.lastCannotBeDeleteMsg'))
|
||||
return
|
||||
}
|
||||
const data = { system_users: objectNewRelationSystemUsers }
|
||||
return this.$axios.patch(relationUrl, data)
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ export default {
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/system-users/',
|
||||
url: '/api/v1/assets/system-users/?protocol__in=rdp,ssh,vnc,telnet',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
:create-success-next-route="successUrl"
|
||||
:clean-form-value="cleanFormValue"
|
||||
:object="formData"
|
||||
:has-detail-in-msg="false"
|
||||
:fields-meta="fieldsMeta"
|
||||
/>
|
||||
</div>
|
||||
@@ -68,7 +69,7 @@ export default {
|
||||
fieldsMap: {
|
||||
es: [[this.$t('common.Basic'), ['name', 'type', 'hosts', 'index', 'doc_type', 'comment']]]
|
||||
},
|
||||
url: '/api/v1/terminal/command-storages/'
|
||||
url: this.$route.params.id ? '/api/v1/terminal/command-storages/' : `/api/v1/terminal/command-storages/?type=es`
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -137,9 +138,9 @@ export default {
|
||||
type: 'es',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
es_hosts: host_array,
|
||||
es_index: value.index,
|
||||
es_doc_type: value.doc_type
|
||||
HOSTS: host_array,
|
||||
INDEX: value.index,
|
||||
DOC_TYPE: value.doc_type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
:create-success-next-route="successUrl"
|
||||
:clean-form-value="cleanFormValue"
|
||||
:object="formData"
|
||||
:has-detail-in-msg="false"
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMetas"
|
||||
/>
|
||||
@@ -36,7 +37,7 @@ export default {
|
||||
name: '',
|
||||
comment: ''
|
||||
},
|
||||
url: '/api/v1/terminal/replay-storages/',
|
||||
url: this.$route.params.id ? `/api/v1/terminal/replay-storages/` : `/api/v1/terminal/replay-storages/?type=${storageType}`,
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'type']],
|
||||
[storageTypeMeta.title, storageTypeMeta.meta],
|
||||
@@ -55,7 +56,8 @@ export default {
|
||||
rules: [Required]
|
||||
},
|
||||
bucket: {
|
||||
label: this.$t('sessions.bucket')
|
||||
label: this.$t('sessions.bucket'),
|
||||
rules: [Required]
|
||||
},
|
||||
access_key: {
|
||||
label: 'Access key',
|
||||
@@ -67,10 +69,12 @@ export default {
|
||||
},
|
||||
endpoint: {
|
||||
label: this.$t('sessions.endPoint'),
|
||||
helpText: storageTypeMeta.endpointHelpText
|
||||
helpText: storageTypeMeta.endpointHelpText,
|
||||
rules: [Required]
|
||||
},
|
||||
region: {
|
||||
label: this.$t('sessions.region')
|
||||
label: this.$t('sessions.region'),
|
||||
rules: [Required]
|
||||
},
|
||||
protocol: {
|
||||
label: this.$t('sessions.protocol'),
|
||||
@@ -82,13 +86,16 @@ export default {
|
||||
rules: [Required]
|
||||
},
|
||||
container_name: {
|
||||
label: this.$t('sessions.containerName')
|
||||
label: this.$t('sessions.containerName'),
|
||||
rules: [Required]
|
||||
},
|
||||
account_name: {
|
||||
label: this.$t('sessions.accountName')
|
||||
label: this.$t('sessions.accountName'),
|
||||
rules: [Required]
|
||||
},
|
||||
account_key: {
|
||||
label: this.$t('sessions.accountKey')
|
||||
label: this.$t('sessions.accountKey'),
|
||||
rules: [Required]
|
||||
},
|
||||
endpoint_suffix: {
|
||||
label: this.$t('sessions.endpointSuffix'),
|
||||
@@ -221,10 +228,10 @@ export default {
|
||||
type: 's3',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
s3_bucket: value.bucket,
|
||||
s3_access_key: value.access_key,
|
||||
s3_secret_key: value.secret_key,
|
||||
s3_endpoint: value.endpoint
|
||||
BUCKET: value.bucket,
|
||||
ACCESS_KEY: value.access_key,
|
||||
SECRET_KEY: value.secret_key,
|
||||
ENDPOINT: value.endpoint
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -234,10 +241,10 @@ export default {
|
||||
type: 'ceph',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
ceph_bucket: value.bucket,
|
||||
ceph_access_key: value.access_key,
|
||||
ceph_secret_key: value.secret_key,
|
||||
ceph_endpoint: value.endpoint
|
||||
BUCKET: value.bucket,
|
||||
ACCESS_KEY: value.access_key,
|
||||
SECRET_KEY: value.secret_key,
|
||||
ENDPOINT: value.endpoint
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -247,12 +254,12 @@ export default {
|
||||
type: 'swift',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
swift_bucket: value.bucket,
|
||||
swift_access_key: value.access_key,
|
||||
swift_secret_key: value.secret_key,
|
||||
swift_region: value.region,
|
||||
swift_endpoint: value.endpoint,
|
||||
swift_protocol: value.protocol
|
||||
BUCKET: value.bucket,
|
||||
ACCESS_KEY: value.access_key,
|
||||
SECRET_KEY: value.secret_key,
|
||||
REGION: value.region,
|
||||
ENDPOINT: value.endpoint,
|
||||
PROTOCOL: value.protocol
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -262,10 +269,10 @@ export default {
|
||||
type: 'oss',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
oss_bucket: value.bucket,
|
||||
oss_access_key: value.access_key,
|
||||
oss_secret_key: value.secret_key,
|
||||
oss_endpoint: value.endpoint
|
||||
BUCKET: value.bucket,
|
||||
ACCESS_KEY: value.access_key,
|
||||
SECRET_KEY: value.secret_key,
|
||||
ENDPOINT: value.endpoint
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -275,10 +282,10 @@ export default {
|
||||
type: 'azure',
|
||||
comment: value.comment,
|
||||
meta: {
|
||||
azure_container_name: value.container_name,
|
||||
azure_account_name: value.account_name,
|
||||
azure_account_key: value.account_key,
|
||||
azure_endpoint_suffix: value.endpoint_suffix
|
||||
CONTAINER_NAME: value.container_name,
|
||||
ACCOUNT_NAME: value.account_name,
|
||||
ACCOUNT_KEY: value.account_key,
|
||||
ENDPOINT_SUFFIX: value.endpoint_suffix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,15 +73,11 @@ export default {
|
||||
type: 'primary',
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
TestCommandStorage(cellValue).then(data => {
|
||||
let success = 'success'
|
||||
if (!data.is_valid) {
|
||||
success = 'error'
|
||||
this.$message.error(data.msg)
|
||||
} else {
|
||||
this.$message.success(data.msg)
|
||||
}
|
||||
this.$notify({
|
||||
message: data.msg,
|
||||
type: success,
|
||||
duration: 4500
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,15 +94,11 @@ export default {
|
||||
type: 'primary',
|
||||
callback: function({ row, col, cellValue, reload }) {
|
||||
TestReplayStorage(cellValue).then(data => {
|
||||
let success = 'success'
|
||||
if (!data.is_valid) {
|
||||
success = 'error'
|
||||
this.$message.error(data.msg)
|
||||
} else {
|
||||
this.$message.success(data.msg)
|
||||
}
|
||||
this.$notify({
|
||||
message: data.msg,
|
||||
type: success,
|
||||
duration: 4500
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,19 @@
|
||||
|
||||
<script>
|
||||
import TicketListTable from './TicketListTable'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'AssignedTicketList',
|
||||
components: {
|
||||
TicketListTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: '/api/v1/tickets/tickets/?assign=1'
|
||||
}
|
||||
computed: {
|
||||
url() {
|
||||
return `/api/v1/tickets/tickets/?assignees__id=${this.currentUser.id}`
|
||||
},
|
||||
...mapGetters([
|
||||
'currentUser'
|
||||
])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
<script>
|
||||
import TicketListTable from './TicketListTable'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'MyTicketList',
|
||||
components: {
|
||||
@@ -11,8 +12,16 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: '/api/v1/tickets/tickets/?assign=0'
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
url() {
|
||||
return `/api/v1/tickets/tickets/?applicant=${this.currentUser.id}`
|
||||
},
|
||||
...mapGetters([
|
||||
'currentUser'
|
||||
])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<el-select v-model="value" v-bind="$attrs" class="select2" v-on="$listeners">
|
||||
<el-option-group
|
||||
v-for="group in options"
|
||||
:key="group.org_name"
|
||||
:label="group.org_name"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in group.org_admins"
|
||||
:key="item.id"
|
||||
:label="item.name + '(' + item.username + ')'"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GroupSelectFormatter',
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
options: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$axios.get(this.url).then(
|
||||
res => {
|
||||
this.options = res
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.select2 {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
255
src/views/tickets/RequestApplicationPerm/Detail/TicketDetail.vue
Normal file
255
src/views/tickets/RequestApplicationPerm/Detail/TicketDetail.vue
Normal file
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<GenericTicketDetail
|
||||
:object="object"
|
||||
:detail-card-items="detailCardItems"
|
||||
:special-card-items="specialCardItems"
|
||||
:assigned-card-items="assignedCardItems"
|
||||
:approve="handleApprove"
|
||||
:close="handleClose"
|
||||
:reject="handleReject"
|
||||
>
|
||||
<IBox v-if="hasActionPerm&&object.status !== 'closed'" class="box">
|
||||
<div slot="header" class="clearfix ibox-title">
|
||||
<i class="fa fa-edit" /> {{ $t('common.Actions') }}
|
||||
</div>
|
||||
<template>
|
||||
<el-form ref="requestForm" :model="requestForm" label-width="140px" label-position="left" class="assets">
|
||||
<el-form-item :label="$t('perms.PermName')" required>
|
||||
<el-input v-model="requestForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('assets.Applications')" required>
|
||||
<Select2 v-model="requestForm.application" v-bind="apps_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.SystemUser')" required>
|
||||
<Select2 v-model="requestForm.systemuser" v-bind="systemuser_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateStart')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_start"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateExpired')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_expired"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</IBox>
|
||||
</GenericTicketDetail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatTime, getDateTimeStamp } from '@/utils/index'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import { STATUS_MAP } from '../../const'
|
||||
import Select2 from '@/components/Select2'
|
||||
import IBox from '@/components/IBox'
|
||||
import GenericTicketDetail from '@/views/tickets/components/GenericTicketDetail'
|
||||
export default {
|
||||
name: '',
|
||||
components: { GenericTicketDetail, IBox, Select2 },
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
requestForm: {
|
||||
name: this.object.meta.approve_permission_name,
|
||||
application: this.object.meta.recommend_applications,
|
||||
systemuser: this.object.meta.recommend_system_users,
|
||||
apply_date_expired: this.object.meta.apply_date_expired,
|
||||
apply_date_start: this.object.meta.apply_date_start
|
||||
},
|
||||
comments: '',
|
||||
assets: [],
|
||||
apps_select2: {
|
||||
multiple: true,
|
||||
value: this.object.meta.recommend_applications,
|
||||
ajax: {
|
||||
url: `/api/v1/applications/applications/?oid=${(this.object.org_id === '')
|
||||
? 'DEFAULT'
|
||||
: this.object.org_id}&category=${this.object.meta.apply_category}&type=${this.object.meta.apply_type}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
systemuser_select2: {
|
||||
multiple: true,
|
||||
value: this.object.meta.recommend_system_users,
|
||||
ajax: {
|
||||
url: `/api/v1/assets/system-users/?oid=${(this.object.org_id === '')
|
||||
? 'DEFAULT'
|
||||
: this.object.org_id
|
||||
}&protocol=${(this.object.meta.apply_category === 'remote_app')
|
||||
? 'rdp'
|
||||
: this.object.meta.apply_type
|
||||
}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.status'),
|
||||
value: this.object.status,
|
||||
formatter: (item, val) => {
|
||||
return <el-tag type={this.statusMap.type} size='mini'> { this.statusMap.title }</el-tag>
|
||||
}
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.type'),
|
||||
value: this.object.type_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.user'),
|
||||
value: this.object.applicant_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
value: this.object.assignees_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: (this.object.processor_display === 'No') ? '' : this.object.processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.OrgName'),
|
||||
value: this.object.org_name
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.Comment'),
|
||||
value: this.object.comment
|
||||
}
|
||||
]
|
||||
},
|
||||
specialCardItems() {
|
||||
return [
|
||||
// {
|
||||
// key: this.$t('tickets.Assignee'),
|
||||
// value: this.object.assignee_display
|
||||
// },
|
||||
{
|
||||
key: this.$t('applications.appType'),
|
||||
value: `${this.object.meta.apply_category_display} / ${this.object.meta.apply_type_display} `
|
||||
},
|
||||
{
|
||||
key: this.$t('applications.appName'),
|
||||
value: this.object.meta.apply_application_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta.apply_system_user_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
assignedCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('applications.appName'),
|
||||
value: this.object.meta.approve_applications_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta.approve_system_users_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
hasActionPerm() {
|
||||
return this.object.assignees.indexOf(this.$store.state.users.profile.id) !== -1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTime(dateStr) {
|
||||
return formatTime(getDateTimeStamp(dateStr))
|
||||
},
|
||||
toSafeLocalDateStr(dataStr) {
|
||||
return toSafeLocalDateStr(dataStr)
|
||||
},
|
||||
reloadPage() {
|
||||
window.location.reload()
|
||||
},
|
||||
handleApprove() {
|
||||
if (this.requestForm.application.length === 0 || this.requestForm.systemuser.length === 0) {
|
||||
return this.$message.error(this.$t('common.NeedAssetsAndSystemUserErrMsg'))
|
||||
} else {
|
||||
this.$axios.put(`/api/v1/tickets/tickets/${this.object.id}/approve/`, {
|
||||
meta: {
|
||||
approve_permission_name: this.requestForm.name,
|
||||
approve_system_users: this.requestForm.systemuser,
|
||||
approve_applications: this.requestForm.application,
|
||||
approve_date_start: this.requestForm.apply_date_start,
|
||||
approve_date_expired: this.requestForm.apply_date_expired
|
||||
}
|
||||
}).then(
|
||||
() => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.reloadPage()
|
||||
}
|
||||
).catch(
|
||||
() => this.$message.success(this.$t('common.updateErrorMsg'))
|
||||
)
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/close/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
},
|
||||
handleReject() {
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/reject/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.assets{
|
||||
margin-top: 14px;
|
||||
}
|
||||
.feed-activity-list .feed-element {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
}
|
||||
.feed-element > .pull-left {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.feed-element .header-avatar {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
.box {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
50
src/views/tickets/RequestApplicationPerm/Detail/index.vue
Normal file
50
src/views/tickets/RequestApplicationPerm/Detail/index.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="ticket" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<component :is="config.activeMenu" :object="ticket" />
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage, TabPage } from '@/layout/components'
|
||||
import TicketDetail from './TicketDetail'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
TicketDetail,
|
||||
TabPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' },
|
||||
config: {
|
||||
activeMenu: 'TicketDetail',
|
||||
url: '',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('route.TicketDetail'),
|
||||
name: 'TicketDetail'
|
||||
}
|
||||
],
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/tickets/tickets/${this.$route.params.id}/`
|
||||
},
|
||||
getObjectName: this.getObjectName,
|
||||
hasRightSide: false
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
getObjectName() {
|
||||
return this.ticket.title
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
v-bind="$data"
|
||||
:perform-submit="performSubmit"
|
||||
:create-success-next-route="createSuccessNextRoute"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import Select2 from '@/components/Select2'
|
||||
import { getDaysFuture } from '@/utils/common'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
export default {
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
|
||||
data() {
|
||||
const now = new Date()
|
||||
const date_expired = getDaysFuture(7, now).toISOString()
|
||||
const date_start = now.toISOString()
|
||||
return {
|
||||
hasDetailInMsg: false,
|
||||
initial: {
|
||||
ips_or_not: true,
|
||||
apply_date_expired: date_expired,
|
||||
apply_date_start: date_start,
|
||||
org_id: 'DEFAULT',
|
||||
type: 'apply_application',
|
||||
apply_actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file']
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'assignees', 'comment']],
|
||||
[this.$t('tickets.RequestPerm'), ['apply_category_type', 'apply_application_group', 'apply_system_user_group', 'apply_date_start', 'apply_date_expired']]
|
||||
|
||||
],
|
||||
fieldsMeta: {
|
||||
type: {
|
||||
hidden: () => true,
|
||||
el: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
apply_category_type: {
|
||||
type: 'cascader',
|
||||
label: this.$t('applications.appType'),
|
||||
rules: [Required],
|
||||
el: {
|
||||
multiple: false,
|
||||
options: [
|
||||
{
|
||||
label: this.$t(`applications.applicationsCategory.db`),
|
||||
value: 'db',
|
||||
children: [
|
||||
{
|
||||
label: 'MySQL',
|
||||
value: 'mysql'
|
||||
},
|
||||
{
|
||||
label: 'Oracle',
|
||||
value: 'oracle'
|
||||
},
|
||||
{
|
||||
label: 'PostgreSQL',
|
||||
value: 'postgresql'
|
||||
},
|
||||
{
|
||||
label: 'MariaDB',
|
||||
value: 'mariadb'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: this.$t(`applications.applicationsCategory.cloud`),
|
||||
value: 'cloud',
|
||||
children: [
|
||||
{
|
||||
label: 'Kubernetes',
|
||||
value: 'k8s'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: this.$t(`applications.applicationsCategory.remote_app`),
|
||||
value: 'remote_app',
|
||||
children: [
|
||||
{
|
||||
label: 'MySQL Workbench',
|
||||
value: 'mysql_workbench'
|
||||
},
|
||||
{
|
||||
label: 'vSphere Client',
|
||||
value: 'vmware_client'
|
||||
},
|
||||
{
|
||||
label: 'Custom',
|
||||
value: 'custom'
|
||||
}, {
|
||||
label: 'Chrome',
|
||||
value: 'chrome'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
apply_application_group: {
|
||||
label: this.$t('applications.appName'),
|
||||
helpText: this.$t('tickets.helpText.application')
|
||||
},
|
||||
apply_system_user_group: {
|
||||
label: this.$t('assets.SystemUser'),
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
},
|
||||
apply_date_start: {
|
||||
label: this.$t('common.DateStart'),
|
||||
type: 'date-picker',
|
||||
el: {
|
||||
type: 'datetime'
|
||||
}
|
||||
},
|
||||
apply_date_expired: {
|
||||
label: this.$t('common.DateEnd'),
|
||||
type: 'date-picker',
|
||||
el: {
|
||||
type: 'datetime'
|
||||
}
|
||||
},
|
||||
org_id: {
|
||||
component: Select2,
|
||||
el: {
|
||||
multiple: false,
|
||||
options: this.$store.state.users.profile.user_all_orgs
|
||||
},
|
||||
on: {
|
||||
changeOptions: ([event], updateForm) => {
|
||||
this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/assignees/?org_id=${event[0].value}`
|
||||
}
|
||||
}
|
||||
},
|
||||
assignees: {
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: `/api/v1/tickets/assignees/?org_id=DEFAULT`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/tickets/tickets/?type=apply_application&action=open',
|
||||
createSuccessNextRoute: {
|
||||
name: 'TicketList'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
performSubmit(validValues) {
|
||||
const meta = {}
|
||||
const applications = validValues.apply_application_group
|
||||
const systemUser = validValues.apply_system_user_group
|
||||
if (applications) {
|
||||
meta.apply_application_group = applications.split(',')
|
||||
}
|
||||
delete validValues['apply_application_group']
|
||||
|
||||
if (systemUser) {
|
||||
meta.apply_system_user_group = systemUser.split(',')
|
||||
}
|
||||
|
||||
delete validValues['apply_system_user_group']
|
||||
|
||||
meta.apply_category = validValues.apply_category_type[0]
|
||||
meta.apply_type = validValues.apply_category_type[1]
|
||||
|
||||
delete validValues['apply_category_type']
|
||||
|
||||
meta.apply_date_start = validValues.apply_date_start
|
||||
delete validValues['apply_date_start']
|
||||
|
||||
meta.apply_date_expired = validValues.apply_date_expired
|
||||
delete validValues['apply_date_expired']
|
||||
|
||||
validValues['meta'] = meta
|
||||
|
||||
return this.$axios['post'](`/api/v1/tickets/tickets/open/?type=apply_application`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-form ::v-deep .el-cascader {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,7 @@
|
||||
:object="object"
|
||||
:detail-card-items="detailCardItems"
|
||||
:special-card-items="specialCardItems"
|
||||
:assigned-card-items="assignedCardItems"
|
||||
:approve="handleApprove"
|
||||
:close="handleClose"
|
||||
:reject="handleReject"
|
||||
@@ -13,12 +14,27 @@
|
||||
</div>
|
||||
<template>
|
||||
<el-form ref="requestForm" :model="requestForm" label-width="140px" label-position="left" class="assets">
|
||||
<el-form-item :label="$t('perms.PermName')" required>
|
||||
<el-input v-model="requestForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.Asset')" required>
|
||||
<Select2 v-model="requestForm.asset" v-bind="asset_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.SystemUser')" required>
|
||||
<Select2 v-model="requestForm.systemuser" v-bind="systemuser_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateStart')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_start"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateExpired')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_expired"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('assets.Action')" required>
|
||||
<AssetPermissionFormActionField v-model="requestForm.actions" style="width: 30% !important" />
|
||||
</el-form-item>
|
||||
@@ -49,17 +65,20 @@ export default {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
requestForm: {
|
||||
asset: this.object.confirmed_assets,
|
||||
systemuser: this.object.confirmed_system_users,
|
||||
actions: this.object.actions
|
||||
name: this.object.meta.approve_permission_name,
|
||||
asset: this.object.meta.recommend_assets,
|
||||
systemuser: this.object.meta.recommend_system_users,
|
||||
actions: this.object.meta.apply_actions,
|
||||
apply_date_expired: this.object.meta.apply_date_expired,
|
||||
apply_date_start: this.object.meta.apply_date_start
|
||||
},
|
||||
comments: '',
|
||||
assets: [],
|
||||
asset_select2: {
|
||||
multiple: true,
|
||||
value: this.object.confirmed_assets,
|
||||
value: this.object.meta.recommend_assets,
|
||||
ajax: {
|
||||
url: this.object.assets_waitlist_url,
|
||||
url: `/api/v1/assets/assets/?oid=${(this.object.org_id === '') ? 'DEFAULT' : this.object.org_id}&protocol__in=rdp,vnc,ssh,telnet`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.hostname, value: item.id }
|
||||
}
|
||||
@@ -67,9 +86,9 @@ export default {
|
||||
},
|
||||
systemuser_select2: {
|
||||
multiple: true,
|
||||
value: this.object.confirmed_system_users,
|
||||
value: this.object.meta.recommend_system_users,
|
||||
ajax: {
|
||||
url: this.object.system_users_waitlist_url,
|
||||
url: `/api/v1/assets/system-users/?oid=${(this.object.org_id === '') ? 'DEFAULT' : this.object.org_id}&protocol__in=rdp,vnc,ssh,telnet`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
@@ -93,7 +112,7 @@ export default {
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.user'),
|
||||
value: this.object.user_display
|
||||
value: this.object.applicant_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
@@ -101,7 +120,11 @@ export default {
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: this.object.assignee_display
|
||||
value: (this.object.processor_display === 'No') ? '' : this.object.processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.OrgName'),
|
||||
value: this.object.org_name
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
@@ -121,23 +144,43 @@ export default {
|
||||
// },
|
||||
{
|
||||
key: this.$t('tickets.IP'),
|
||||
value: this.object.ips
|
||||
value: this.object.meta.apply_ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Hostname'),
|
||||
value: this.object.hostname
|
||||
value: this.object.meta.apply_hostname_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.system_user
|
||||
value: this.object.meta.apply_system_user_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.date_start)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.date_expired)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
assignedCardItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('assets.Asset'),
|
||||
value: this.object.meta.approve_assets_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta.approve_system_users_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -159,31 +202,32 @@ export default {
|
||||
if (this.requestForm.asset.length === 0 || this.requestForm.systemuser.length === 0) {
|
||||
return this.$message.error(this.$t('common.NeedAssetsAndSystemUserErrMsg'))
|
||||
} else {
|
||||
this.$axios.patch(`/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/`, {
|
||||
confirmed_system_users: this.requestForm.systemuser,
|
||||
confirmed_assets: this.requestForm.asset,
|
||||
actions: this.requestForm.actions
|
||||
}).then(res => {
|
||||
this.$axios.post(`/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/approve/`).then(
|
||||
() => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.reloadPage()
|
||||
}
|
||||
)
|
||||
}).catch(
|
||||
this.$axios.put(`/api/v1/tickets/tickets/${this.object.id}/approve/`, {
|
||||
meta: {
|
||||
approve_permission_name: this.requestForm.name,
|
||||
approve_system_users: this.requestForm.systemuser,
|
||||
approve_assets: this.requestForm.asset,
|
||||
approve_actions: this.requestForm.actions,
|
||||
approve_date_start: this.requestForm.apply_date_start,
|
||||
approve_date_expired: this.requestForm.apply_date_expired
|
||||
}
|
||||
}).then(
|
||||
() => {
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.reloadPage()
|
||||
}
|
||||
).catch(
|
||||
() => this.$message.success(this.$t('common.updateErrorMsg'))
|
||||
)
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
const url = `/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/close/`
|
||||
const data = { status: 'closed' }
|
||||
this.$axios.post(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/close/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
},
|
||||
handleReject() {
|
||||
const url = `/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/reject/`
|
||||
const data = { action: 'reject' }
|
||||
this.$axios.post(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/reject/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,16 @@ export default {
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' },
|
||||
config: {
|
||||
activeMenu: 'TicketDetail',
|
||||
url: '',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('route.TicketDetail'),
|
||||
name: 'TicketDetail'
|
||||
}
|
||||
],
|
||||
actions: {
|
||||
detailApiUrl: `/api/v1/tickets/tickets/${this.$route.params.id}/`
|
||||
},
|
||||
getObjectName: this.getObjectName,
|
||||
hasRightSide: false
|
||||
}
|
||||
|
||||
@@ -17,33 +17,59 @@ export default {
|
||||
const date_expired = getDaysFuture(7, now).toISOString()
|
||||
const date_start = now.toISOString()
|
||||
return {
|
||||
// 工单创建 隐藏提示信息中的跳转连接
|
||||
hasDetailInMsg: false,
|
||||
initial: {
|
||||
ips_or_not: true,
|
||||
date_expired: date_expired,
|
||||
date_start: date_start,
|
||||
apply_date_expired: date_expired,
|
||||
apply_date_start: date_start,
|
||||
org_id: 'DEFAULT',
|
||||
actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file']
|
||||
type: 'apply_asset',
|
||||
apply_actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file']
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['title', 'org_id', 'assignees', 'comment']],
|
||||
[this.$t('tickets.RequestPerm'), ['ips', 'hostname', 'system_user', 'actions', 'date_start', 'date_expired']]
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'assignees', 'comment']],
|
||||
[this.$t('tickets.RequestPerm'), ['apply_ip_group', 'apply_hostname_group', 'apply_system_user_group', 'apply_actions', 'apply_date_start', 'apply_date_expired']]
|
||||
|
||||
],
|
||||
fieldsMeta: {
|
||||
ips: {
|
||||
type: {
|
||||
hidden: () => true,
|
||||
el: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
apply_ip_group: {
|
||||
label: this.$t('tickets.IPGroup'),
|
||||
helpText: this.$t('tickets.helpText.ips')
|
||||
},
|
||||
hostname: {
|
||||
apply_hostname_group: {
|
||||
label: this.$t('assets.Hostname'),
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
},
|
||||
system_user: {
|
||||
apply_system_user_group: {
|
||||
label: this.$t('assets.SystemUser'),
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
},
|
||||
actions: {
|
||||
apply_actions: {
|
||||
label: this.$t('perms.Actions'),
|
||||
component: AssetPermissionFormActionField,
|
||||
helpText: this.$t('common.actionsTips')
|
||||
},
|
||||
apply_date_start: {
|
||||
label: this.$t('common.DateStart'),
|
||||
type: 'date-picker',
|
||||
el: {
|
||||
type: 'datetime'
|
||||
}
|
||||
},
|
||||
apply_date_expired: {
|
||||
label: this.$t('common.DateEnd'),
|
||||
type: 'date-picker',
|
||||
el: {
|
||||
type: 'datetime'
|
||||
}
|
||||
},
|
||||
org_id: {
|
||||
component: Select2,
|
||||
el: {
|
||||
@@ -52,8 +78,7 @@ export default {
|
||||
},
|
||||
on: {
|
||||
changeOptions: ([event], updateForm) => {
|
||||
// console.log(event[0].value) // output: input value
|
||||
this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/tickets/request-asset-perm/assignees/?org_id=${event[0].value}`
|
||||
this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/assignees/?org_id=${event[0].value}`
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -62,7 +87,7 @@ export default {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/tickets/tickets/request-asset-perm/assignees/',
|
||||
url: `/api/v1/tickets/assignees/?org_id=DEFAULT`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
@@ -70,7 +95,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/tickets/tickets/request-asset-perm/',
|
||||
url: '/api/v1/tickets/tickets/?type=apply_asset&action=open',
|
||||
createSuccessNextRoute: {
|
||||
name: 'TicketList'
|
||||
}
|
||||
@@ -78,14 +103,37 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
performSubmit(validValues) {
|
||||
const ips = validValues.ips
|
||||
const meta = {}
|
||||
const ips = validValues.apply_ip_group
|
||||
if (ips) {
|
||||
validValues.ips = ips.split(',')
|
||||
meta.apply_ip_group = ips.split(',')
|
||||
}
|
||||
if (ips === '') {
|
||||
delete validValues['ips']
|
||||
delete validValues['apply_ip_group']
|
||||
}
|
||||
return this.$axios['post'](this.url, validValues)
|
||||
if (validValues.apply_hostname_group) {
|
||||
meta.apply_hostname_group = validValues.apply_hostname_group.split(',')
|
||||
delete validValues['apply_hostname_group']
|
||||
}
|
||||
|
||||
if (validValues.apply_system_user_group) {
|
||||
meta.apply_system_user_group = validValues.apply_system_user_group.split(',')
|
||||
delete validValues['apply_system_user_group']
|
||||
}
|
||||
|
||||
if (validValues.apply_actions) {
|
||||
meta.apply_actions = validValues.apply_actions
|
||||
delete validValues['apply_actions']
|
||||
}
|
||||
meta.apply_date_start = validValues.apply_date_start
|
||||
delete validValues['apply_date_start']
|
||||
|
||||
meta.apply_date_expired = validValues.apply_date_expired
|
||||
delete validValues['apply_date_expired']
|
||||
|
||||
validValues['meta'] = meta
|
||||
|
||||
return this.$axios['post'](`/api/v1/tickets/tickets/open/?type=apply_asset`, validValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export default {
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.Applicant'),
|
||||
value: this.object.user_display
|
||||
value: this.object.applicant_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.type'),
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: this.object.assignee_display
|
||||
value: this.object.processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
|
||||
@@ -16,7 +16,14 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' },
|
||||
ticket: {
|
||||
title: '',
|
||||
user_display: '',
|
||||
type_display: '',
|
||||
status: '',
|
||||
assignees_display: '',
|
||||
date_created: ''
|
||||
},
|
||||
config: {
|
||||
activeMenu: 'TicketDetail',
|
||||
submenu: [
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import { mapGetters } from 'vuex'
|
||||
import AssignedTicketList from './AssignedTicketList'
|
||||
import MyTicketList from './MyTicketList'
|
||||
import { getTicketOpenCount } from '@/api/ticket'
|
||||
@@ -38,12 +39,17 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'currentUser'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
this.getTicketOpenCount()
|
||||
},
|
||||
methods: {
|
||||
getTicketOpenCount() {
|
||||
getTicketOpenCount(1).then(data => {
|
||||
getTicketOpenCount(this.currentUser.id).then(data => {
|
||||
this.assignedTicketCount = data.count
|
||||
})
|
||||
},
|
||||
|
||||
@@ -32,8 +32,10 @@ export default {
|
||||
sortable: 'custom',
|
||||
formatterArgs: {
|
||||
getRoute: function({ row }) {
|
||||
if (row.type === 'request_asset') {
|
||||
if (row.type === 'apply_asset') {
|
||||
return 'AssetsTicketDetail'
|
||||
} else if (row.type === 'apply_application') {
|
||||
return 'AppsTicketDetail'
|
||||
} else {
|
||||
return 'TicketDetail'
|
||||
}
|
||||
@@ -41,14 +43,14 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'user_display',
|
||||
prop: 'applicant_display',
|
||||
label: this.$t('tickets.user'),
|
||||
sortable: 'custom'
|
||||
},
|
||||
{
|
||||
prop: 'type_display',
|
||||
label: this.$t('tickets.type'),
|
||||
width: '110px'
|
||||
width: '160px'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
@@ -56,6 +58,20 @@ export default {
|
||||
align: 'center',
|
||||
width: '90px',
|
||||
sortable: 'custom',
|
||||
formatter: row => {
|
||||
if (row.status === 'open') {
|
||||
return <el-tag type='primary' size='mini'style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.OpenStatus') }</el-tag>
|
||||
} else {
|
||||
return <el-tag type='danger' size='mini'style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.CloseStatus') }</el-tag>
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'action',
|
||||
label: this.$t('tickets.action'),
|
||||
align: 'center',
|
||||
width: '90px',
|
||||
sortable: 'custom',
|
||||
formatter: row => {
|
||||
if (row.status === 'open') {
|
||||
return <el-tag type='success' size='mini'style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Pending') }</el-tag>
|
||||
@@ -69,7 +85,6 @@ export default {
|
||||
return <el-tag type='info' size='mini' style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Closed') }</el-tag>
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
prop: 'date_created',
|
||||
@@ -89,9 +104,9 @@ export default {
|
||||
default: {
|
||||
status: {
|
||||
key: 'status',
|
||||
label: this.$t('tickets.Status'),
|
||||
label: this.$t('tickets.action'),
|
||||
value: 'open',
|
||||
valueLabel: this.$t('tickets.Open')
|
||||
valueLabel: this.$t('tickets.Pending')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -105,16 +120,20 @@ export default {
|
||||
genExtraMoreActions() {
|
||||
return [
|
||||
{
|
||||
name: '',
|
||||
name: 'RequestAssetPerm',
|
||||
title: this.$t('tickets.RequestAssetPerm'),
|
||||
type: 'primary',
|
||||
can: true,
|
||||
callback: this.onCallback
|
||||
callback: () => this.$router.push({ name: 'RequestAssetPermTicketCreateUpdate' })
|
||||
},
|
||||
{
|
||||
name: 'RequestApplicationPerm',
|
||||
title: this.$t('tickets.RequestApplicationPerm'),
|
||||
type: 'primary',
|
||||
can: true,
|
||||
callback: () => this.$router.push({ name: 'RequestApplicationPermTicketCreateUpdate' })
|
||||
}
|
||||
]
|
||||
},
|
||||
onCallback() {
|
||||
this.$router.push({ name: 'RequestAssetPermTicketCreateUpdate' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<i class="fa fa-comments" /> {{ $t('common.Message') }}
|
||||
</div>
|
||||
<template v-if="comments">
|
||||
<div v-for="item in comments" :key="item.user_display + item.body" class="feed-activity-list">
|
||||
<div v-for="item in comments" :key="item.id" class="feed-activity-list">
|
||||
<div class="feed-element">
|
||||
<a href="#" class="pull-left">
|
||||
<el-avatar :src="imageUrl" class="header-avatar" />
|
||||
@@ -117,7 +117,7 @@ export default {
|
||||
},
|
||||
getComment() {
|
||||
this.loading = true
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/comments/`
|
||||
const url = `/api/v1/tickets/comments/?ticket_id=${this.object.id}`
|
||||
this.$axios.get(url).then(res => {
|
||||
this.comments = res
|
||||
}).catch(err => {
|
||||
@@ -130,25 +130,22 @@ export default {
|
||||
defaultApprove() {
|
||||
this.createComment(function() {
|
||||
})
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/`
|
||||
const data = { action: 'approve' }
|
||||
this.$axios.patch(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/approve/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
},
|
||||
defaultReject() {
|
||||
this.createComment(function() {})
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/`
|
||||
const data = { action: 'reject' }
|
||||
this.$axios.patch(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/reject/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
},
|
||||
defaultClose() {
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/`
|
||||
const data = { status: 'closed' }
|
||||
this.$axios.patch(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
const url = `/api/v1/tickets/tickets/${this.object.id}/close/`
|
||||
this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err))
|
||||
},
|
||||
createComment(successCallback) {
|
||||
const commentText = this.form.comments
|
||||
const ticketId = this.object.id
|
||||
const commentUrl = `/api/v1/tickets/tickets/${ticketId}/comments/`
|
||||
const commentUrl = `/api/v1/tickets/comments/?ticket_id=${this.object.id}`
|
||||
if (!commentText) { return }
|
||||
const body = {
|
||||
body: commentText,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<IBox class="box">
|
||||
<div slot="header" class="clearfix ibox-title">
|
||||
<i class="fa fa-info-circle" /> {{ $t('common.BasicInfo') }}
|
||||
<i class="fa fa-info-circle" /> {{ title }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row :gutter="10">
|
||||
@@ -54,6 +54,10 @@ export default {
|
||||
detailCardItems: {
|
||||
type: Array,
|
||||
default: () => ([])
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="17">
|
||||
<Details :detail-card-items="detailCardItems" :special-card-items="specialCardItems" />
|
||||
<Details :detail-card-items="detailCardItems" :title="$t('common.BasicInfo')" />
|
||||
<Details v-if="specialCardItems.length > 0" :detail-card-items="specialCardItems" :title="$t('common.ApplyInfo')" />
|
||||
<Details v-if="object.action === 'approve' && assignedCardItems.length > 0" :detail-card-items="assignedCardItems" :title="$t('tickets.AssignedInfo')" />
|
||||
<slot id="MoreDetails" />
|
||||
<Comments :object="object" v-bind="$attrs" />
|
||||
</el-col>
|
||||
@@ -30,7 +32,12 @@ export default {
|
||||
detailCardItems: {
|
||||
type: Array,
|
||||
default: () => ([])
|
||||
},
|
||||
assignedCardItems: {
|
||||
type: Array,
|
||||
default: () => ([])
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:description="`${this.$t('tickets.Applicant')}:${object.user_display}`"
|
||||
>
|
||||
<div slot="description">
|
||||
<div>{{ `${this.$t('tickets.Applicant')}:${object.user_display}` }}</div>
|
||||
<div>{{ `${this.$t('tickets.Applicant')}:${object.applicant_display}` }}</div>
|
||||
<div>{{ `${this.$t('common.dateCreated')}: ${toSafeLocalDateStr(object.date_created)}` }}</div>
|
||||
</div>
|
||||
</el-step>
|
||||
@@ -20,7 +20,7 @@
|
||||
:description="ticketSteps===STATUS.close ? `${this.$t('tickets.Assignee')}:${object.assignee_display}`:'' "
|
||||
>
|
||||
<div v-if="ticketSteps===STATUS.close" slot="description">
|
||||
<div>{{ `${this.$t('tickets.Assignee')}:${object.assignee_display}` }}</div>
|
||||
<div>{{ `${this.$t('tickets.Assignee')}:${object.processor_display}` }}</div>
|
||||
<div>{{ `${this.$t('common.dateFinished')}: ${toSafeLocalDateStr(object.date_updated)}` }}</div>
|
||||
</div>
|
||||
</el-step>
|
||||
|
||||
@@ -50,9 +50,6 @@ export default {
|
||||
return this.$route.meta.action !== 'update' || formValue.source !== 'local'
|
||||
}
|
||||
},
|
||||
source: {
|
||||
hidden: () => { return true }
|
||||
},
|
||||
password: {
|
||||
component: UserPassword,
|
||||
hidden: (formValue) => {
|
||||
|
||||
@@ -265,11 +265,11 @@ export default {
|
||||
}
|
||||
this.$message.success(successMsg)
|
||||
} catch (error) {
|
||||
let errorMsg = this.$t('common.bulkDeleteErrorMsg')
|
||||
if (!this.currentOrgIsDefault) {
|
||||
errorMsg = this.$t('common.bulkRemoveErrorMsg')
|
||||
}
|
||||
this.$message.error(errorMsg + error)
|
||||
// let errorMsg = this.$t('common.bulkDeleteErrorMsg')
|
||||
// if (!this.currentOrgIsDefault) {
|
||||
// errorMsg = this.$t('common.bulkRemoveErrorMsg')
|
||||
// }
|
||||
// this.$message.error(errorMsg + error)
|
||||
} finally {
|
||||
instance.confirmButtonLoading = false
|
||||
}
|
||||
|
||||
@@ -36,6 +36,38 @@ export default {
|
||||
key: this.$t('common.createBy'),
|
||||
value: this.object.created_by
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.users_amount'),
|
||||
value: this.object.resource_statistics.users_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.groups_amount'),
|
||||
value: this.object.resource_statistics.groups_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.assets_amount'),
|
||||
value: this.object.resource_statistics.assets_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.admin_users_amount'),
|
||||
value: this.object.resource_statistics.admin_users_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.system_users_amount'),
|
||||
value: this.object.resource_statistics.system_users_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.applications_amount'),
|
||||
value: this.object.resource_statistics.applications_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.asset_perms_amount'),
|
||||
value: this.object.resource_statistics.asset_perms_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.Organization.app_perms_amount'),
|
||||
value: this.object.resource_statistics.app_perms_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
|
||||
@@ -17,8 +17,41 @@ export default {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/orgs/orgs/',
|
||||
columns: ['name', 'comment', 'actions'],
|
||||
columns: ['name',
|
||||
'resource_statistics.users_amount',
|
||||
'resource_statistics.groups_amount',
|
||||
'resource_statistics.assets_amount',
|
||||
'resource_statistics.admin_users_amount',
|
||||
'resource_statistics.system_users_amount',
|
||||
'resource_statistics.applications_amount',
|
||||
'resource_statistics.asset_perms_amount',
|
||||
'resource_statistics.app_perms_amount',
|
||||
'comment', 'actions'],
|
||||
columnsMeta: {
|
||||
'resource_statistics.users_amount': {
|
||||
label: this.$t('xpack.Organization.users_amount')
|
||||
},
|
||||
'resource_statistics.groups_amount': {
|
||||
label: this.$t('xpack.Organization.groups_amount')
|
||||
},
|
||||
'resource_statistics.assets_amount': {
|
||||
label: this.$t('xpack.Organization.assets_amount')
|
||||
},
|
||||
'resource_statistics.admin_users_amount': {
|
||||
label: this.$t('xpack.Organization.admin_users_amount')
|
||||
},
|
||||
'resource_statistics.system_users_amount': {
|
||||
label: this.$t('xpack.Organization.system_users_amount')
|
||||
},
|
||||
'resource_statistics.applications_amount': {
|
||||
label: this.$t('xpack.Organization.applications_amount')
|
||||
},
|
||||
'resource_statistics.asset_perms_amount': {
|
||||
label: this.$t('xpack.Organization.asset_perms_amount')
|
||||
},
|
||||
'resource_statistics.app_perms_amount': {
|
||||
label: this.$t('xpack.Organization.app_perms_amount')
|
||||
},
|
||||
actions: {
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
import Uploadkey from '@/components/UploadKey'
|
||||
|
||||
import Select2 from '@/components/Select2'
|
||||
export default {
|
||||
name: 'AdminUserCreateUpdate',
|
||||
components: {
|
||||
@@ -23,6 +23,7 @@ export default {
|
||||
fieldsMeta: {
|
||||
asset: {
|
||||
label: this.$t('perms.Asset'),
|
||||
component: Select2,
|
||||
el: {
|
||||
multiple: false,
|
||||
ajax: {
|
||||
|
||||
Reference in New Issue
Block a user