mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-25 06:19:51 +00:00
@@ -19,7 +19,7 @@ VUE_APP_CORE_HOST = 'JUMPSERVER_APIHOST'
|
||||
$ yarn serve
|
||||
|
||||
4. 构建
|
||||
$ yarn build
|
||||
$ yarn build:prod
|
||||
```
|
||||
|
||||
## 生产中部署
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
const tokens = {
|
||||
admin: {
|
||||
token: 'admin-token'
|
||||
@@ -46,7 +45,6 @@ export default [
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// get user info
|
||||
{
|
||||
url: '/vue-admin-template/user/info\.*',
|
||||
|
@@ -7,7 +7,7 @@
|
||||
:title="title"
|
||||
@close="onClose"
|
||||
>
|
||||
<span class="announcement-main"> {{ announcement.content }}</span>
|
||||
<span class="announcement-main">{{ announcement.content }}</span>
|
||||
<span v-if="announcement.link">
|
||||
<el-link :href="announcement.link" target="_blank" class="link-more">
|
||||
{{ $t('common.ViewMore') }}
|
||||
@@ -60,6 +60,7 @@ export default {
|
||||
}
|
||||
.announcement-main {
|
||||
word-wrap:break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.link-more {
|
||||
font-size: 10px;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="grouped ? 'el-button-group' : 'el-button-ungroup'">
|
||||
<div :class="grouped ? 'el-button-group' : 'el-button-ungroup'" class="layout">
|
||||
<template v-for="action in iActions">
|
||||
<el-dropdown
|
||||
v-if="action.dropdown"
|
||||
@@ -13,9 +13,14 @@
|
||||
<el-button :size="size" v-bind="cleanButtonAction(action)">
|
||||
{{ action.title }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-menu slot="dropdown" style="overflow: auto;max-height: 60vh">
|
||||
<template v-for="option in action.dropdown">
|
||||
<div v-if="option.group" :key="'group:'+option.name" class="dropdown-menu-title" style="width:130px">
|
||||
<div
|
||||
v-if="option.group"
|
||||
:key="'group:'+option.name"
|
||||
class="dropdown-menu-title"
|
||||
style="width:130px"
|
||||
>
|
||||
{{ option.group }}
|
||||
</div>
|
||||
<el-dropdown-item
|
||||
@@ -149,6 +154,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dropdown-menu-title {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
@@ -165,7 +175,7 @@ export default {
|
||||
}
|
||||
|
||||
.el-button-ungroup .action-item {
|
||||
margin-left: 4px
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.el-button-ungroup .action-item:first-child {
|
||||
|
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<ElFormRender
|
||||
ref="form"
|
||||
:class="mobile? 'mobile' : 'desktop'"
|
||||
:content="fields"
|
||||
:form="basicForm"
|
||||
label-position="right"
|
||||
:label-position="labelPosition"
|
||||
label-width="20%"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
@@ -68,6 +69,14 @@ export default {
|
||||
basicForm: this.form
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
mobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelPosition() {
|
||||
return this.mobile ? 'top' : 'right'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取表单数据
|
||||
submitForm(formName, addContinue) {
|
||||
@@ -99,27 +108,35 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-form ::v-deep .el-form-item {
|
||||
.el-form ::v-deep .el-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .el-form-item__content {
|
||||
.el-form ::v-deep .el-form-item__content {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .el-form-item__label {
|
||||
.mobile.el-form ::v-deep .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .el-form-item__label {
|
||||
padding: 0 30px 0 0;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .el-form-item__error {
|
||||
.el-form ::v-deep .el-form-item__error {
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .form-group-header {
|
||||
.el-form ::v-deep .form-group-header {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .help-block {
|
||||
.el-form.mobile ::v-deep .form-group-header {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.el-form ::v-deep .help-block {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
@@ -127,7 +144,7 @@ export default {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.el-form ::v-deep .help-block a {
|
||||
.el-form ::v-deep .help-block a {
|
||||
color: #1c84c6;
|
||||
}
|
||||
.form-buttons {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<el-dialog
|
||||
:title="title"
|
||||
:top="top"
|
||||
:width="iWidth"
|
||||
class="dialog"
|
||||
v-bind="$attrs"
|
||||
append-to-body
|
||||
@@ -39,6 +40,10 @@ export default {
|
||||
type: String,
|
||||
default: '3vh'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '60%'
|
||||
},
|
||||
showConfirm: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -58,6 +63,11 @@ export default {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iWidth() {
|
||||
return this.$store.getters.isMobile ? '80%' : this.width
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onCancel() {
|
||||
this.$emit('cancel')
|
||||
|
@@ -91,18 +91,22 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
<style lang='scss' scoped>
|
||||
.datepicker{
|
||||
width: 233px;
|
||||
&>>> .el-range__icon {
|
||||
margin-top: 2px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
&>>> .el-range-input {
|
||||
width: 49%;
|
||||
}
|
||||
}
|
||||
.el-input__inner{
|
||||
border: 1px solid #dcdee2;
|
||||
border-radius: 3px;
|
||||
height: 36px;
|
||||
}
|
||||
/*.el-date-editor ::v-deep .el-input__icon{*/
|
||||
/* line-height: 28px;*/
|
||||
/*}*/
|
||||
.el-date-editor ::v-deep .el-range-separator{
|
||||
line-height: 28px;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<div class="tableFilter">
|
||||
<el-radio-group v-model="importStatusFilter" size="small">
|
||||
<el-radio-button label="all">{{ $t('common.Total') }}</el-radio-button>
|
||||
@@ -11,7 +11,7 @@
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" style="text-align: center">
|
||||
<el-col :md="8" :sm="24" style="text-align: center">
|
||||
<span class="summary-item summary-total"> {{ $t('common.Total') }}: {{ totalCount }}</span>
|
||||
<span class="summary-item summary-success"> {{ $t('common.Success') }}: {{ successCount }}</span>
|
||||
<span class="summary-item summary-failed"> {{ $t('common.Failed') }}: {{ failedCount }}</span>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="table-header clearfix">
|
||||
<div class="table-header clearfix" :class="device">
|
||||
<slot name="header">
|
||||
<LeftSide v-if="hasLeftActions" style="float: left" :class="'left-side ' + device" :selected-rows="selectedRows" :table-url="tableUrl" v-bind="$attrs" v-on="$listeners" />
|
||||
<RightSide v-if="hasRightActions" style="float: right" :selected-rows="selectedRows" :table-url="tableUrl" v-bind="$attrs" v-on="$listeners" />
|
||||
<div style="display: flex;flex-direction: row" class="search" :class="hasLeftActions ? 'right' : 'left'">
|
||||
<LeftSide v-if="hasLeftActions" class="left-side" :selected-rows="selectedRows" :table-url="tableUrl" v-bind="$attrs" v-on="$listeners" />
|
||||
<RightSide v-if="hasRightActions" class="right-side" :selected-rows="selectedRows" :table-url="tableUrl" v-bind="$attrs" v-on="$listeners" />
|
||||
<div class="search" :class="searchClass">
|
||||
<AutoDataSearch v-if="hasSearch" class="right-side-item action-search" v-bind="iSearchTableConfig" @tagSearch="handleTagSearch" />
|
||||
<DatetimeRangePicker v-if="hasDatePicker" v-bind="datePicker" class="datepicker" @dateChange="handleDateChange" />
|
||||
</div>
|
||||
@@ -77,6 +77,9 @@ export default {
|
||||
return 'mobile'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
searchClass() {
|
||||
return this.hasLeftActions ? 'right' : 'left'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -143,11 +146,33 @@ export default {
|
||||
.datepicker{
|
||||
margin-left: 10px;
|
||||
}
|
||||
.left-side {
|
||||
float: left;
|
||||
}
|
||||
.right-side {
|
||||
float: right;
|
||||
}
|
||||
.search {
|
||||
display: flex;
|
||||
flex-direction: row
|
||||
}
|
||||
.mobile .search {
|
||||
display: inherit;
|
||||
}
|
||||
.mobile .search .datepicker {
|
||||
margin-left: 0;
|
||||
}
|
||||
.search.left {
|
||||
float: left;
|
||||
}
|
||||
.search.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mobile .search.right {
|
||||
float: left;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.mobile .right-side {
|
||||
padding-top: 6px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -192,6 +192,15 @@ export default {
|
||||
& >>> .el-table__header thead > tr > th {
|
||||
background-color: white;
|
||||
}
|
||||
&>>> .el-table__row .cell {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&>>> .el-table__expanded-cell pre {
|
||||
max-height: 500px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
//修改颜色
|
||||
|
@@ -10,14 +10,14 @@
|
||||
v-on="$listeners"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-col :md="4" :sm="24">
|
||||
<div style="line-height: 34px;text-align: center">MFA</div>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<el-input v-model="MFAToken" />
|
||||
<span class="help-tips help-block">{{ $t('common.MFARequireForSecurity') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :md="4" :sm="24">
|
||||
<el-button size="mini" type="primary" style="line-height:20px " @click="verifyMFA">
|
||||
{{ this.$t('common.Confirm') }}
|
||||
</el-button>
|
||||
|
@@ -26,5 +26,19 @@ export default {
|
||||
year: 'numeric', month: 'short', day: 'numeric',
|
||||
hour: 'numeric', minute: 'numeric', hour12: true
|
||||
}
|
||||
},
|
||||
'ja': {
|
||||
short: {
|
||||
year: 'numeric', month: 'short', day: 'numeric'
|
||||
},
|
||||
medium: {
|
||||
year: 'numeric', month: '2-digit', day: '2-digit',
|
||||
hour: '2-digit', minute: '2-digit', second: '2-digit',
|
||||
hourCycle: 'h23', hour12: false
|
||||
},
|
||||
long: {
|
||||
year: 'numeric', month: 'short', day: 'numeric',
|
||||
hour: 'numeric', minute: 'numeric', hour12: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,8 +7,12 @@ import date from './date'
|
||||
import VueCookie from 'vue-cookie'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
const cookieLang = VueCookie.get('django_language')
|
||||
const browserLang = navigator.systemLanguage || navigator.language
|
||||
let lang = cookieLang || browserLang || 'zh'
|
||||
lang = lang.slice(0, 2)
|
||||
const i18n = new VueI18n({
|
||||
locale: (VueCookie.get('django_language') || 'zh-hans') === 'zh-hans' ? 'cn' : 'en',
|
||||
locale: lang,
|
||||
fallbackLocale: 'en',
|
||||
silentFallbackWarn: true,
|
||||
silentTranslationWarn: true,
|
||||
|
@@ -314,12 +314,14 @@
|
||||
"Delete": "Delete",
|
||||
"Disable": "Disable",
|
||||
"Download": "Download",
|
||||
"Copy": "Copy",
|
||||
"Enable": "Enable",
|
||||
"On/Off": "On/Off",
|
||||
"EnterForSearch": "Press enter to search",
|
||||
"Export": "Export",
|
||||
"Import": "Import",
|
||||
"ContinueImport": "ContinueImport",
|
||||
"ImportAll": "Import All",
|
||||
"Continue": "Continue",
|
||||
"Stop": "Stop",
|
||||
"Finished": "Finished",
|
||||
@@ -416,8 +418,9 @@
|
||||
},
|
||||
"isValid": "Is valid",
|
||||
"nav": {
|
||||
"TempPassword": "Temporary password",
|
||||
"APIKey": "API Key",
|
||||
"Workspace": "Workbench",
|
||||
"Workbench": "Workbench",
|
||||
"Navigation": "Navigation",
|
||||
"Console": "Console",
|
||||
"Audits": "Audit",
|
||||
@@ -651,6 +654,10 @@
|
||||
},
|
||||
"route": {
|
||||
"": "",
|
||||
"CreateEndpoint": "Create endpoint",
|
||||
"UpdateEndpoint": "Update endpoint",
|
||||
"CreateEndpointRule": "Create endpoint rule",
|
||||
"UpdateEndpointRule": "Update endpoint rule",
|
||||
"SystemSetting": "System setting",
|
||||
"Index": "Index",
|
||||
"Role": "Role",
|
||||
@@ -767,6 +774,7 @@
|
||||
"Activity": "Activity",
|
||||
"SessionOffline": "Sessions offline",
|
||||
"SessionOnline": "Sessions online",
|
||||
"RecentSession": "Recent session",
|
||||
"Sessions": "Sessions",
|
||||
"Settings": "Settings",
|
||||
"SystemUserCreate": "System user create",
|
||||
@@ -982,6 +990,7 @@
|
||||
"LDAPUser": "LDAP User",
|
||||
"InsecureCommandAlert": "Insecure command alert",
|
||||
"helpText": {
|
||||
"TempPassword": "For a while, there is a period of 300 seconds, and there is a period of reuse.",
|
||||
"ApiKeyList": "The API key is used to sign the request header. The header of each request is different. Please refer to the usage documentation",
|
||||
"authLdapSearchFilter": "Choice may be (cn|uid|sAMAccountName)=%(user)s)",
|
||||
"authLdapSearchOu": "Use | split User OUs",
|
||||
@@ -1057,7 +1066,7 @@
|
||||
"refreshLdapCache":"Refreshing Ldap cache ",
|
||||
"LicenseExpired": "License expired",
|
||||
"LicenseWillBe": "License will expire at ",
|
||||
"Expire": "",
|
||||
"Expire": "Expire",
|
||||
"WeCom": "WeCom",
|
||||
"DingTalk": "DingTalk",
|
||||
"dingTalkTest": "Test",
|
||||
@@ -1366,6 +1375,8 @@
|
||||
"AWS_China": "AWS(China)",
|
||||
"AWS_Int": "AWS(International)",
|
||||
"HuaweiCloud": "Huawei Cloud",
|
||||
"BaiduCloud": "Baidu Cloud",
|
||||
"JDCloud": "JD Cloud",
|
||||
"Azure":"Azure(China)",
|
||||
"Azure_Int": "Azure(International)",
|
||||
"HostnameStrategy": "Used to produce the asset hostname. For example, 1. Instance name (instanceDemo);2. Instance name and Partial IP (instanceDemo-250.1)",
|
||||
@@ -1432,6 +1443,8 @@
|
||||
"License": "License",
|
||||
"LicenseDetail": "License detail",
|
||||
"ComponentMonitor": "System Monitor",
|
||||
"Endpoint": "Endpoint",
|
||||
"EndpointRule": "Endpoint rule",
|
||||
"ServiceRatio": "Service ratio",
|
||||
"LoadStatus":"Status",
|
||||
"NormalLoad":"Normal",
|
||||
|
@@ -1,15 +1,21 @@
|
||||
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
|
||||
import enLocale from 'element-ui/lib/locale/lang/en'
|
||||
import zh from './cn.json'
|
||||
import jaLocale from 'element-ui/lib/locale/lang/ja'
|
||||
import zh from './zh.json'
|
||||
import en from './en.json'
|
||||
import ja from './ja.json'
|
||||
|
||||
export default {
|
||||
cn: {
|
||||
zh: {
|
||||
...zhLocale,
|
||||
...zh
|
||||
},
|
||||
en: {
|
||||
...enLocale,
|
||||
...en
|
||||
},
|
||||
ja: {
|
||||
...jaLocale,
|
||||
...ja
|
||||
}
|
||||
}
|
||||
|
1555
src/i18n/langs/ja.json
Normal file
1555
src/i18n/langs/ja.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,8 @@ import json
|
||||
i18n_report_path = '/tmp/abc.json'
|
||||
lang_paths = {
|
||||
'cn': 'cn.json',
|
||||
'en': 'en.json'
|
||||
'en': 'en.json',
|
||||
'ja': 'ja.json'
|
||||
}
|
||||
|
||||
|
||||
@@ -51,5 +52,5 @@ def remove_keys(lang):
|
||||
f.write(data)
|
||||
|
||||
|
||||
for i in ['cn', 'en']:
|
||||
for i in ['cn', 'en', 'ja']:
|
||||
remove_keys(i)
|
||||
|
@@ -254,6 +254,7 @@
|
||||
"ReLogin": "重新登录"
|
||||
},
|
||||
"common": {
|
||||
"Component": "组件",
|
||||
"PrivateCloud": "私有云",
|
||||
"PublicCloud": "公有云",
|
||||
"Correlation": "关联",
|
||||
@@ -326,12 +327,14 @@
|
||||
"Delete": "删除",
|
||||
"Disable": "禁用",
|
||||
"Download": "下载",
|
||||
"Copy": "复制",
|
||||
"Enable": "启用",
|
||||
"On/Off": "启/停",
|
||||
"EnterForSearch": "按回车进行搜索",
|
||||
"Export": "导出",
|
||||
"Import": "导入",
|
||||
"ContinueImport": "继续导入",
|
||||
"ImportAll": "导入全部",
|
||||
"Continue": "继续",
|
||||
"Stop": "停止",
|
||||
"Finished": "完成",
|
||||
@@ -428,8 +431,9 @@
|
||||
"fileType": "文件类型",
|
||||
"isValid": "有效",
|
||||
"nav": {
|
||||
"TempPassword": "临时密码",
|
||||
"APIKey": "API Key",
|
||||
"Workspace": "工作台",
|
||||
"Workbench": "工作台",
|
||||
"Navigation": "导航",
|
||||
"Console": "控制台",
|
||||
"Audits": "审计台",
|
||||
@@ -661,6 +665,10 @@
|
||||
},
|
||||
"route": {
|
||||
"": "",
|
||||
"CreateEndpoint": "创建端点",
|
||||
"UpdateEndpoint": "更新端点",
|
||||
"CreateEndpointRule": "创建端点规则",
|
||||
"UpdateEndpointRule": "更新端点规则",
|
||||
"Index": "首页",
|
||||
"SystemSetting": "系统设置",
|
||||
"WorkBench": "工作台",
|
||||
@@ -783,6 +791,7 @@
|
||||
"Detail": "详情",
|
||||
"SessionOffline": "历史会话",
|
||||
"SessionOnline": "在线会话",
|
||||
"RecentSession": "最近会话",
|
||||
"Sessions": "会话管理",
|
||||
"Settings": "系统设置",
|
||||
"SystemUserCreate": "创建系统用户",
|
||||
@@ -1008,6 +1017,7 @@
|
||||
"LDAPServerInfo": "LDAP 服务器",
|
||||
"LDAPUser": "LDAP 用户",
|
||||
"helpText": {
|
||||
"TempPassword": "临时密码有效期为 300 秒,有效期内可重复使用",
|
||||
"ApiKeyList": "使用api key签名请求头,每个请求的头部是不一样的, 请查阅使用文档",
|
||||
"authLdapSearchFilter": "可能的选项是(cn或uid或sAMAccountName=%(user)s)",
|
||||
"authLdapSearchOu": "使用|分隔各OU",
|
||||
@@ -1409,6 +1419,8 @@
|
||||
"AWS_China": "AWS(中国)",
|
||||
"AWS_Int": "AWS(国际)",
|
||||
"HuaweiCloud": "华为云",
|
||||
"BaiduCloud": "百度云",
|
||||
"JDCloud": "京东云",
|
||||
"Azure":"Azure(中国)",
|
||||
"Azure_Int": "Azure(国际)",
|
||||
"HostnameStrategy": "用于生成资产主机名。例如:1. 实例名称 (instanceDemo);2. 实例名称和部分IP(后两位) (instanceDemo-250.1)",
|
||||
@@ -1477,6 +1489,8 @@
|
||||
"InterfaceSettings": "界面设置",
|
||||
"License": "许可证",
|
||||
"ComponentMonitor": "组件监控",
|
||||
"Endpoint": "终端节点",
|
||||
"EndpointRule": "终端节点规则",
|
||||
"ServiceRatio": "组件负载统计",
|
||||
"LoadStatus":"组件状态",
|
||||
"NormalLoad":"正常",
|
@@ -7,15 +7,22 @@
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="4" :sm="24">
|
||||
<div class="select-prop-label">
|
||||
<label>{{ selectPropertiesLabel }}</label>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-col :md="18" :sm="24">
|
||||
<el-checkbox-group v-model="checkedFields" @change="handleCheckedFieldsChange">
|
||||
<el-checkbox v-for="(value, name) in iFormSetting.fieldsMeta" :key="name" :checked="true" :label="name">{{ value.label }}</el-checkbox>
|
||||
<el-checkbox
|
||||
v-for="(value, name) in iFormSetting.fieldsMeta"
|
||||
:key="name"
|
||||
:checked="true"
|
||||
:label="name"
|
||||
>
|
||||
{{ value.label }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -9,6 +9,7 @@
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-user" command="profile">{{ $t('common.nav.Profile') }}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="$hasPerm('authentication.view_accesskey')" icon="el-icon-key" command="apiKey">{{ $t('common.nav.APIKey') }}</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-magic-stick" command="tempPassword">{{ $t('common.nav.TempPassword') }}</el-dropdown-item>
|
||||
<el-dropdown-item divided command="logout"><svg-icon icon-class="logout" style="margin-right: 4px" />{{ $t('common.nav.Logout') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
@@ -50,6 +51,8 @@ export default {
|
||||
case 'apiKey':
|
||||
this.$router.push('/profile/key')
|
||||
break
|
||||
case 'tempPassword':
|
||||
this.$router.push('/profile/tempPassword')
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
@@ -65,4 +68,7 @@ export default {
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mobile .header-avatar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
@@ -25,6 +25,11 @@ export default {
|
||||
title: '中文(简体)',
|
||||
code: 'cn',
|
||||
cookieCode: 'zh-hans' // cookie code是为了让后端知道当前语言
|
||||
},
|
||||
{
|
||||
title: '日本語',
|
||||
code: 'ja',
|
||||
cookieCode: 'ja' // cookie code是为了让后端知道当前语言
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -58,6 +63,8 @@ export default {
|
||||
changeMomentLang() {
|
||||
if (this.currentLang.code.indexOf('en') > -1) {
|
||||
this.$moment.locale('en')
|
||||
} else if (this.currentLang.code.indexOf('ja') > -1) {
|
||||
this.$moment.locale('ja')
|
||||
} else {
|
||||
this.$moment.locale('zh-cn')
|
||||
}
|
||||
|
@@ -146,25 +146,25 @@ export default {
|
||||
background-color: rgba(144, 147, 152, .5);
|
||||
}
|
||||
|
||||
& > > > .el-input__prefix {
|
||||
&>>> .el-input__prefix {
|
||||
left: 8px
|
||||
}
|
||||
|
||||
& > > > .el-input--prefix .el-input__inner {
|
||||
&>>> .el-input--prefix .el-input__inner {
|
||||
line-height: 35px !important;
|
||||
height: 35px !important;
|
||||
}
|
||||
|
||||
& > > > .fa-sitemap {
|
||||
&>>> .fa-sitemap {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
& > > > .el-input__icon {
|
||||
&>>> .el-input__icon {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.option-group > > > .el-select-group__title {
|
||||
.option-group >>> .el-select-group__title {
|
||||
color: #909399 !important;
|
||||
padding-left: 15px;
|
||||
font-size: 12px;
|
||||
|
@@ -2,7 +2,8 @@
|
||||
<el-menu
|
||||
default-active="activeIndex"
|
||||
class="menu-main"
|
||||
mode="horizontal"
|
||||
:class="mode"
|
||||
:mode="mode"
|
||||
@select="handleSelectView"
|
||||
>
|
||||
<el-submenu
|
||||
@@ -21,7 +22,7 @@
|
||||
v-perms="view.perms"
|
||||
:index="view.name"
|
||||
>
|
||||
<i class="icons" :class="view.meta.icon" />
|
||||
<i v-if="mode === 'horizontal'" class="icons" :class="view.meta.icon" />
|
||||
<span slot="title" class="icons-title">{{ view.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
@@ -37,6 +38,10 @@ export default {
|
||||
showTitle: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'horizontal'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -131,4 +136,8 @@ export default {
|
||||
.el-menu-item.is-active {
|
||||
font-weight: bold;
|
||||
}
|
||||
.menu-main.mobile-view-switch >>> .el-submenu__icon-arrow {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@@ -4,13 +4,13 @@
|
||||
<div class="nav-logo">
|
||||
<Logo v-if="showLogo" :collapse="isCollapse" />
|
||||
</div>
|
||||
<div class="active-mobile">
|
||||
<ViewSwitcher mode="vertical" class="mobile-view-switch" />
|
||||
<Organization class="organization" />
|
||||
</div>
|
||||
<div class="nav-title" :class="{'collapsed': isCollapse}">
|
||||
{{ isTitle }}
|
||||
</div>
|
||||
<div class="active-mobile">
|
||||
<ViewSwitcher />
|
||||
<Organization class="organization" />
|
||||
</div>
|
||||
</div>
|
||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
||||
<el-menu
|
||||
@@ -174,6 +174,9 @@ export default {
|
||||
&>>> .menu-main {
|
||||
margin-left: -10px;
|
||||
}
|
||||
&>>> .title-label {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 992px) {
|
||||
.active-mobile {
|
||||
|
@@ -7,7 +7,9 @@
|
||||
</template>
|
||||
</PageHeading>
|
||||
<PageContent>
|
||||
<el-alert v-if="helpMessage" type="success"> <span v-html="helpMessage" /> </el-alert>
|
||||
<el-alert v-if="helpMessage" type="success">
|
||||
<span class="announcement-main">{{ helpMessage }}</span>
|
||||
</el-alert>
|
||||
<slot />
|
||||
</PageContent>
|
||||
</div>
|
||||
@@ -34,7 +36,6 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
iTitle() {
|
||||
// return ''
|
||||
return this.title || this.$route.meta.title
|
||||
}
|
||||
}
|
||||
@@ -52,5 +53,9 @@ export default {
|
||||
.print-margin{
|
||||
margin-top: 10px;
|
||||
}
|
||||
.announcement-main {
|
||||
word-wrap:break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -30,8 +30,12 @@
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
</el-tabs>
|
||||
<transition name="fade-transform" mode="out-in">
|
||||
<slot />
|
||||
<transition name="fade-transform" mode="out-in" appear>
|
||||
<slot>
|
||||
<keep-alive>
|
||||
<component :is="computeActiveComponent" />
|
||||
</keep-alive>
|
||||
</slot>
|
||||
</transition>
|
||||
</div>
|
||||
</Page>
|
||||
@@ -76,9 +80,19 @@ export default {
|
||||
}
|
||||
})
|
||||
return map
|
||||
},
|
||||
computeActiveComponent() {
|
||||
let needActiveComponent = ''
|
||||
for (const i of this.submenu) {
|
||||
if (i.component && (i.name === this.iActiveMenu)) {
|
||||
needActiveComponent = i.component
|
||||
break
|
||||
}
|
||||
}
|
||||
return needActiveComponent
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
created() {
|
||||
this.iActiveMenu = this.getPropActiveTab()
|
||||
},
|
||||
methods: {
|
||||
@@ -106,7 +120,7 @@ export default {
|
||||
const currentTab = typeof preTab === 'object' ? preTab.name : preTab
|
||||
for (const tabName of this.tabIndices) {
|
||||
const currentTabName = tabName?.name || ''
|
||||
if (currentTab && currentTabName && currentTab.toLowerCase() === currentTabName.toLowerCase()) {
|
||||
if (currentTab?.toLowerCase() === currentTabName?.toLowerCase()) {
|
||||
return currentTabName
|
||||
}
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ export const constantRoutes = [
|
||||
// 权限路由
|
||||
import consoleViewRoutes from './console'
|
||||
import auditViewRoutes from './audit'
|
||||
import workspaceViewRoutes from './workspace'
|
||||
import workbenchViewRoutes from './workbench'
|
||||
import ticketsRoutes from './tickets'
|
||||
import settingsRoutes from './settings'
|
||||
import profileRoutes from './profile'
|
||||
@@ -92,7 +92,7 @@ import { getPermedPreferView } from '@/utils/jms'
|
||||
export const viewRoutes = [
|
||||
consoleViewRoutes,
|
||||
auditViewRoutes,
|
||||
workspaceViewRoutes,
|
||||
workbenchViewRoutes,
|
||||
ticketsRoutes,
|
||||
settingsRoutes,
|
||||
profileRoutes
|
||||
|
@@ -53,6 +53,16 @@ export default {
|
||||
resource: 'accesskey',
|
||||
app: 'authentication'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/profile/tempPassword',
|
||||
component: () => import('@/views/profile/TempPassword'),
|
||||
name: 'TempPassword',
|
||||
meta: {
|
||||
title: i18n.t('common.nav.TempPassword'),
|
||||
icon: 'magic',
|
||||
permissions: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ export default {
|
||||
component: () => import('@/views/settings/Terminal'),
|
||||
meta: {
|
||||
title: i18n.t('setting.Terminal'),
|
||||
icon: 'terminal',
|
||||
icon: 'tasks',
|
||||
permissions: ['settings.change_terminal']
|
||||
}
|
||||
},
|
||||
@@ -152,6 +152,50 @@ export default {
|
||||
permissions: ['terminal.change_commandstorage']
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'endpoint/create',
|
||||
name: 'EndpointCreate',
|
||||
component: () => import('@/views/settings/Terminal/Endpoint/EndpointCreateUpdate'),
|
||||
meta: {
|
||||
title: i18n.t('route.CreateEndpoint'),
|
||||
activeMenu: '/settings/terminal',
|
||||
permissions: ['terminal.add_endpoint']
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'endpoint/:id/update',
|
||||
name: 'EndpointUpdate',
|
||||
component: () => import('@/views/settings/Terminal/Endpoint/EndpointCreateUpdate'),
|
||||
meta: {
|
||||
title: i18n.t('route.UpdateEndpoint'),
|
||||
activeMenu: '/settings/terminal',
|
||||
permissions: ['terminal.change_endpoint']
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'endpoint-rule/create',
|
||||
name: 'EndpointRuleCreate',
|
||||
component: () => import('@/views/settings/Terminal/EndpointRule/EndpointRuleCreateUpdate'),
|
||||
meta: {
|
||||
title: i18n.t('route.CreateEndpointRule'),
|
||||
activeMenu: '/settings/terminal',
|
||||
permissions: ['terminal.add_endpointrule']
|
||||
},
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'endpoint-rule/:id/update',
|
||||
name: 'EndpointRuleUpdate',
|
||||
component: () => import('@/views/settings/Terminal/EndpointRule/EndpointRuleCreateUpdate'),
|
||||
meta: {
|
||||
title: i18n.t('route.UpdateEndpointRule'),
|
||||
activeMenu: '/settings/terminal',
|
||||
permissions: ['terminal.change_endpointrule']
|
||||
},
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -4,23 +4,23 @@ import { BASE_URL } from '@/utils/common'
|
||||
import empty from '@/layout/empty'
|
||||
|
||||
export default {
|
||||
path: '/workspace/',
|
||||
path: '/workbench/',
|
||||
component: Layout,
|
||||
name: 'workspace',
|
||||
redirect: '/workspace/home',
|
||||
name: 'workbench',
|
||||
redirect: '/workbench/home',
|
||||
meta: {
|
||||
title: i18n.t('common.nav.Workspace'),
|
||||
title: i18n.t('common.nav.Workbench'),
|
||||
type: 'view',
|
||||
view: 'workspace',
|
||||
view: 'workbench',
|
||||
icon: 'el-icon-user-solid',
|
||||
showNavSwitcher: true,
|
||||
showOrganization: true,
|
||||
permissions: ['rbac.view_workspace']
|
||||
permissions: ['rbac.view_workbench']
|
||||
},
|
||||
children: [
|
||||
// 404 page must be placed at the end !!!
|
||||
{
|
||||
path: '/workspace/home',
|
||||
path: '/workbench/home',
|
||||
name: 'MyHome',
|
||||
component: () => import('@/views/myhome'),
|
||||
meta: {
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/workspace/assets',
|
||||
path: '/workbench/assets',
|
||||
name: 'MyAssets',
|
||||
component: () => import('@/views/myassets'),
|
||||
meta: {
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/workspace/apps',
|
||||
path: '/workbench/apps',
|
||||
name: 'Apps',
|
||||
component: empty,
|
||||
redirect: 'remoteapp',
|
||||
@@ -82,7 +82,7 @@ export default {
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workspace/ops',
|
||||
path: '/workbench/ops',
|
||||
component: empty,
|
||||
meta: {
|
||||
permissions: ['ops.add_commandexecution'],
|
@@ -1,6 +1,7 @@
|
||||
const getters = {
|
||||
sidebar: state => state.app.sidebar,
|
||||
device: state => state.app.device,
|
||||
isMobile: state => state.app.device === 'mobile',
|
||||
token: state => state.users.token,
|
||||
currentOrg: state => state.users.currentOrg,
|
||||
currentOrgIsDefault: state => state.users.currentOrg['is_default'],
|
||||
|
@@ -170,3 +170,11 @@ input[type=file] {
|
||||
min-width: 70px!important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-col.el-col-sm-24 .ibox {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.el-pagination {
|
||||
overflow: auto;
|
||||
}
|
@@ -109,7 +109,7 @@ export function getApiPath(that) {
|
||||
// ticket ...
|
||||
pagePath = pagePathArray.slice(1, pagePathArray.length).join('/')
|
||||
} else {
|
||||
// console,audit,workspace
|
||||
// console,audit,workbench
|
||||
pagePath = pagePathArray.slice(2, pagePathArray.length).join('/')
|
||||
}
|
||||
return `/api/v1/${pagePath}/`
|
||||
@@ -276,5 +276,19 @@ const scheme = document.location.protocol
|
||||
const port = document.location.port ? ':' + document.location.port : ''
|
||||
const BASE_URL = scheme + '//' + document.location.hostname + port
|
||||
|
||||
export function groupedDropdownToCascader(group) {
|
||||
const firstType = group[0]
|
||||
return {
|
||||
value: firstType.category,
|
||||
label: firstType.group,
|
||||
children: group.map(item => {
|
||||
return {
|
||||
value: item.name,
|
||||
label: item.title
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export { BASE_URL }
|
||||
|
||||
|
@@ -43,7 +43,6 @@ export function getResourceNameByPath(path) {
|
||||
|
||||
export function getResourceFromApiUrl(apiUrl) {
|
||||
const re = new RegExp('/api/v1/([A-Za-z0-9_-]+)/([A-Za-z0-9_-]+)/.*')
|
||||
console.log('Api url: ', apiUrl)
|
||||
const matched = apiUrl.match(re)
|
||||
if (!matched) {
|
||||
return { path: '', app: '', resource: '' }
|
||||
@@ -84,7 +83,7 @@ export function hasActionPerm(route, action) {
|
||||
const viewRequirePermsMapper = {
|
||||
console: 'rbac.view_console',
|
||||
audit: 'rbac.view_audit',
|
||||
workspace: 'rbac.view_workspace'
|
||||
workbench: 'rbac.view_workbench'
|
||||
}
|
||||
|
||||
export function getViewRequirePerms(view) {
|
||||
|
@@ -1,21 +1,14 @@
|
||||
<template>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" />
|
||||
</keep-alive>
|
||||
</TabPage>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import AssetChangeAuthPlanList from './AssetChangeAuthPlan/ChangeAuthPlanList'
|
||||
import AppChangeAuthPlanList from './AppChangeAuthPlan/AppChangeAuthPlanList'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
TabPage,
|
||||
AssetChangeAuthPlanList,
|
||||
AppChangeAuthPlanList
|
||||
TabPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -25,13 +18,14 @@ export default {
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.AssetChangeAuthPlan'),
|
||||
name: 'AssetChangeAuthPlanList',
|
||||
hidden: () => !this.$hasPerm('xpack.view_changeauthplan')
|
||||
|
||||
hidden: () => !this.$hasPerm('xpack.view_changeauthplan'),
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.AppChangeAuthPlan'),
|
||||
name: 'AppChangeAuthPlanList',
|
||||
hidden: () => !this.$hasPerm('xpack.view_applicationchangeauthplan')
|
||||
hidden: () => !this.$hasPerm('xpack.view_applicationchangeauthplan'),
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/AppChangeAuthPlanList.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,21 +1,14 @@
|
||||
<template>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" />
|
||||
</keep-alive>
|
||||
</TabPage>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import GatheredUserList from './GatheredUserList'
|
||||
import TaskList from './TaskList'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
TabPage,
|
||||
GatheredUserList,
|
||||
TaskList
|
||||
TabPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -25,12 +18,14 @@ export default {
|
||||
{
|
||||
title: this.$t('xpack.GatherUser.GatherUserList'),
|
||||
name: 'GatheredUserList',
|
||||
hidden: !this.$hasPerm('assets.view_gathereduser')
|
||||
hidden: !this.$hasPerm('assets.view_gathereduser'),
|
||||
component: () => import('@/views/accounts/GatheredUser/GatheredUserList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.GatherUser.GatherUserTaskList'),
|
||||
name: 'TaskList',
|
||||
hidden: !this.$hasPerm('xpack.view_gatherusertask')
|
||||
hidden: !this.$hasPerm('xpack.view_gatherusertask'),
|
||||
component: () => import('@/views/accounts/GatheredUser/TaskList.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -17,11 +17,6 @@ export default {
|
||||
],
|
||||
fieldsMeta: {
|
||||
type: {
|
||||
type: 'select',
|
||||
options: [{
|
||||
label: 'MySQL',
|
||||
value: 'mysql'
|
||||
}],
|
||||
disabled: true
|
||||
},
|
||||
domain: {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
import { DATABASE } from '@/views/applications/const'
|
||||
import { DATABASE, KV_DATABASE } from '@/views/applications/const'
|
||||
|
||||
function getAppType(arr) {
|
||||
const searchAppType = []
|
||||
@@ -25,7 +25,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
const appType = DATABASE
|
||||
const appType = [...DATABASE, ...KV_DATABASE]
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/applications/applications/?category=db',
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import store from '@/store'
|
||||
import { groupedDropdownToCascader } from '@/utils/common'
|
||||
|
||||
export const CHROME = 'chrome'
|
||||
export const MYSQL_WORKBENCH = 'mysql_workbench'
|
||||
export const VMWARE_CLIENT = 'vmware_client'
|
||||
@@ -87,7 +89,10 @@ export const DATABASE = [
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY,
|
||||
has: hasLicence
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
export const KV_DATABASE = [
|
||||
{
|
||||
name: REDIS,
|
||||
title: i18n.t(`applications.applicationsType.${REDIS}`),
|
||||
@@ -95,53 +100,17 @@ export const DATABASE = [
|
||||
category: DATABASE_CATEGORY,
|
||||
has: true,
|
||||
group: i18n.t('applications.NoSQLProtocol')
|
||||
}
|
||||
// {
|
||||
// name: MONGODB,
|
||||
// title: i18n.t(`applications.applicationsType.${MONGODB}`),
|
||||
// type: 'primary',
|
||||
// category: DATABASE_CATEGORY
|
||||
// }
|
||||
]
|
||||
|
||||
export const AppPlanDatabase = [
|
||||
{
|
||||
name: MYSQL,
|
||||
title: i18n.t(`applications.applicationsType.${MYSQL}`),
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY,
|
||||
has: true,
|
||||
group: i18n.t('applications.RDBProtocol')
|
||||
},
|
||||
{
|
||||
name: ORACLE,
|
||||
title: i18n.t(`applications.applicationsType.${ORACLE}`),
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY,
|
||||
has: hasLicence
|
||||
},
|
||||
{
|
||||
name: POSTGRESQL,
|
||||
title: i18n.t(`applications.applicationsType.${POSTGRESQL}`),
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY,
|
||||
has: hasLicence
|
||||
},
|
||||
{
|
||||
name: MARIADB,
|
||||
title: i18n.t(`applications.applicationsType.${MARIADB}`),
|
||||
name: MONGODB,
|
||||
title: i18n.t(`applications.applicationsType.${MONGODB}`),
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY
|
||||
},
|
||||
{
|
||||
name: SQLSERVER,
|
||||
title: i18n.t(`applications.applicationsType.${SQLSERVER}`),
|
||||
type: 'primary',
|
||||
category: DATABASE_CATEGORY,
|
||||
has: hasLicence
|
||||
}
|
||||
]
|
||||
|
||||
export const AppPlanDatabase = DATABASE
|
||||
|
||||
export const KUBERNETES = 'k8s'
|
||||
export const CLOUD_CATEGORY = 'cloud'
|
||||
|
||||
@@ -157,5 +126,16 @@ export const CLOUD = [
|
||||
]
|
||||
|
||||
export const ApplicationTypes = [
|
||||
...REMOTE_APP, ...DATABASE, ...CLOUD
|
||||
...DATABASE, ...KV_DATABASE, ...REMOTE_APP, ...CLOUD
|
||||
]
|
||||
|
||||
export const ApplicationSystemUserTypes = [
|
||||
...DATABASE, ...KV_DATABASE, ...CLOUD
|
||||
]
|
||||
|
||||
export const ApplicationCascader = [
|
||||
groupedDropdownToCascader(DATABASE),
|
||||
groupedDropdownToCascader(KV_DATABASE),
|
||||
groupedDropdownToCascader(REMOTE_APP),
|
||||
groupedDropdownToCascader(CLOUD)
|
||||
]
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<AccountListTable ref="ListTable" :url="assetUserUrl" :has-import="false" :has-clone="false" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<RelationCard ref="NodeRelation" v-perms="'assets.change_asset'" type="info" style="margin-top: 15px" v-bind="nodeRelationConfig" />
|
||||
<LabelCard v-if="$hasPerm('assets.view_label')" type="warning" style="margin-top: 15px" v-bind="labelConfig" />
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<PermUserGroupCard v-bind="UserGroupCardConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -54,6 +54,7 @@ export default {
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: vm.$hasPerm('users.view_user') ? DetailFormatter : '',
|
||||
formatterArgs: {
|
||||
route: 'UserDetail'
|
||||
},
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<RelationCard ref="systemUserRelation" style="margin-top: 15px" v-bind="systemUserRelationConfig" />
|
||||
</el-col>
|
||||
|
@@ -36,7 +36,7 @@ export default {
|
||||
{
|
||||
title: this.$t('assets.SystemUser'),
|
||||
name: 'SystemUserList',
|
||||
hidden: () => !this.$hasPerm('assets.view_systemuser')
|
||||
hidden: () => !this.$hasPerm('assets.view_authbook')
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AccountList'),
|
||||
|
@@ -34,8 +34,8 @@
|
||||
</GenericTreeListPage>
|
||||
<Dialog width="30%" :title="this.$t('assets.NodeInformation')" :visible.sync="nodeInfoDialogSetting.dialogVisible" :show-cancel="false" :show-confirm="false">
|
||||
<el-row v-for="item in nodeInfoDialogSetting.items" :key="'card-' + item.key" :gutter="10" class="item">
|
||||
<el-col :span="6"><div class="item-label"><label>{{ item.label }}: </label></div></el-col>
|
||||
<el-col :span="18"><div class="item-text">{{ item.value }}</div></el-col>
|
||||
<el-col :md="6" :sm="24"><div class="item-label"><label>{{ item.label }}: </label></div></el-col>
|
||||
<el-col :md="18" :sm="24"><div class="item-text">{{ item.value }}</div></el-col>
|
||||
</el-row>
|
||||
</Dialog>
|
||||
<AssetBulkUpdateDialog
|
||||
@@ -51,7 +51,11 @@
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage/index'
|
||||
import { DetailFormatter, ActionsFormatter, TagsFormatter } from '@/components/TableFormatters'
|
||||
import {
|
||||
DetailFormatter,
|
||||
ActionsFormatter,
|
||||
TagsFormatter
|
||||
} from '@/components/TableFormatters'
|
||||
import $ from '@/utils/jquery-vendor'
|
||||
import Dialog from '@/components/Dialog'
|
||||
import { mapGetters } from 'vuex'
|
||||
@@ -88,17 +92,14 @@ export default {
|
||||
hasTree: true,
|
||||
columns: [
|
||||
'hostname', 'ip', 'public_ip', 'admin_user_display',
|
||||
'protocols', 'platform', 'hardware_info', 'model',
|
||||
'cpu_model', 'cpu_cores', 'cpu_count', 'cpu_vcpus',
|
||||
'disk_info', 'disk_total', 'memory', 'os', 'os_arch',
|
||||
'os_version', 'number', 'vendor', 'sn', 'is_active',
|
||||
'protocols', 'category', 'type', 'platform', 'sn', 'is_active',
|
||||
'connectivity', 'labels_display',
|
||||
'created_by', 'date_created', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['hostname', 'ip', 'actions'],
|
||||
default: [
|
||||
'hostname', 'ip', 'platform', 'protocols', 'hardware_info',
|
||||
'hostname', 'ip', 'platform', 'category', 'type',
|
||||
'connectivity', 'actions'
|
||||
]
|
||||
},
|
||||
@@ -237,12 +238,12 @@ export default {
|
||||
name: 'RemoveFromCurrentNode',
|
||||
title: this.$t('assets.RemoveFromCurrentNode'),
|
||||
can: ({ selectedRows }) => {
|
||||
if (!this.$route.query.node) {
|
||||
if (!vm.$route.query.node) {
|
||||
return false
|
||||
}
|
||||
return selectedRows.length > 0 &&
|
||||
!vm.currentOrgIsRoot &&
|
||||
vm.$hasPerm('assets.change_asset')
|
||||
vm.$hasPerm('assets.change_node')
|
||||
},
|
||||
callback: function({ selectedRows, reloadTable }) {
|
||||
const assetsId = []
|
||||
|
@@ -4,9 +4,10 @@
|
||||
|
||||
<script type="text/jsx">
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, huaweicloud, qcloud, azure, azure_international, vmware, nutanix, qingcloud_private, huaweicloud_private, openstack, gcp } from '../const'
|
||||
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, huaweicloud, qcloud, azure, azure_international, vmware, nutanix, qingcloud_private, huaweicloud_private, openstack, gcp, baiducloud, jdcloud } from '../const'
|
||||
|
||||
export default {
|
||||
name: 'AccountList',
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
@@ -85,6 +86,14 @@ export default {
|
||||
name: huaweicloud,
|
||||
title: ACCOUNT_PROVIDER_ATTRS_MAP[huaweicloud].title
|
||||
},
|
||||
{
|
||||
name: baiducloud,
|
||||
title: ACCOUNT_PROVIDER_ATTRS_MAP[baiducloud].title
|
||||
},
|
||||
{
|
||||
name: jdcloud,
|
||||
title: ACCOUNT_PROVIDER_ATTRS_MAP[jdcloud].title
|
||||
},
|
||||
{
|
||||
name: aws_china,
|
||||
title: ACCOUNT_PROVIDER_ATTRS_MAP[aws_china].title
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -8,6 +8,7 @@ import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
|
||||
export default {
|
||||
name: 'SyncInstanceTaskList',
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
|
@@ -13,6 +13,8 @@ export const qingcloud_private = 'qingcloud_private'
|
||||
export const huaweicloud_private = 'huaweicloud_private'
|
||||
export const openstack = 'openstack'
|
||||
export const gcp = 'gcp'
|
||||
export const baiducloud = 'baiducloud'
|
||||
export const jdcloud = 'jdcloud'
|
||||
|
||||
export const ACCOUNT_PROVIDER_ATTRS_MAP = {
|
||||
[aliyun]: {
|
||||
@@ -35,6 +37,16 @@ export const ACCOUNT_PROVIDER_ATTRS_MAP = {
|
||||
title: i18n.t('xpack.Cloud.HuaweiCloud'),
|
||||
attrs: ['access_key_id', 'access_key_secret']
|
||||
},
|
||||
[baiducloud]: {
|
||||
name: baiducloud,
|
||||
title: i18n.t('xpack.Cloud.BaiduCloud'),
|
||||
attrs: ['access_key_id', 'access_key_secret']
|
||||
},
|
||||
[jdcloud]: {
|
||||
name: jdcloud,
|
||||
title: i18n.t('xpack.Cloud.JDCloud'),
|
||||
attrs: ['access_key_id', 'access_key_secret']
|
||||
},
|
||||
[qcloud]: {
|
||||
name: qcloud,
|
||||
title: i18n.t('xpack.Cloud.Qcloud'),
|
||||
|
@@ -1,21 +1,14 @@
|
||||
<template>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" />
|
||||
</keep-alive>
|
||||
</TabPage>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import AccountList from './Account/AccountList'
|
||||
import SyncInstanceTaskList from './SyncInstanceTask/SyncInstanceTaskList'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
name: 'CloudIndex',
|
||||
components: {
|
||||
TabPage,
|
||||
AccountList,
|
||||
SyncInstanceTaskList
|
||||
TabPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -25,13 +18,14 @@ export default {
|
||||
{
|
||||
title: this.$t('xpack.Cloud.SyncInstanceTaskList'),
|
||||
name: 'SyncInstanceTaskList',
|
||||
hidden: () => !this.$hasPerm('xpack.view_syncinstancetask')
|
||||
hidden: () => !this.$hasPerm('xpack.view_syncinstancetask'),
|
||||
component: () => import('@/views/assets/Cloud/SyncInstanceTask/SyncInstanceTaskList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.Cloud.AccountList'),
|
||||
name: 'AccountList',
|
||||
hidden: () => !this.$hasPerm('xpack.view_account')
|
||||
|
||||
hidden: () => !this.$hasPerm('xpack.view_account'),
|
||||
component: () => import('@/views/assets/Cloud/Account/AccountList.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<RelationCard ref="systemUserRelation" v-bind="systemUserRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10" />
|
||||
<el-col :md="10" :sm="24" />
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
@@ -12,14 +12,14 @@
|
||||
:destroy-on-close="true"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<div style="line-height: 34px;text-align: center">{{ $t('assets.SshPort') }}</div>
|
||||
<el-col :md="4" :sm="24">
|
||||
<div style="line-height: 34px">{{ $t('assets.SshPort') }}</div>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<el-input v-model="portInput" />
|
||||
<span class="help-tips help-block">{{ $t('assets.TestGatewayHelpMessage') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :md="4" :sm="24">
|
||||
<el-button size="mini" type="primary" style="line-height:20px " :loading="buttonLoading" @click="dialogConfirm">{{ this.$t('common.Confirm') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10" />
|
||||
<el-col :md="10" :sm="24" />
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
@@ -29,6 +29,7 @@ export default {
|
||||
[this.$t('common.Basic'), ['name', 'protocol', 'username', 'type']],
|
||||
[this.$t('common.Auth'), ['password', 'private_key', 'passphrase']],
|
||||
[this.$t('common.Command filter'), ['cmd_filters']],
|
||||
[this.$t('assets.UserSwitch'), ['su_enabled', 'su_from']],
|
||||
[this.$t('common.Other'), ['priority', 'sftp_root', 'comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
@@ -73,7 +74,9 @@ export default {
|
||||
rules: [Required],
|
||||
helpText: this.$t('assets.SFTPHelpMessage')
|
||||
},
|
||||
cmd_filters: fields.cmd_filters
|
||||
cmd_filters: fields.cmd_filters,
|
||||
su_enabled: fields.su_enabled,
|
||||
su_from: fields.su_from
|
||||
},
|
||||
cleanFormValue: (values) => {
|
||||
values['type'] = 'admin'
|
||||
|
@@ -184,6 +184,26 @@ function getFields() {
|
||||
const type = {
|
||||
}
|
||||
|
||||
const su_enabled = {
|
||||
type: 'switch',
|
||||
hidden: (item) => item.protocol !== 'ssh'
|
||||
}
|
||||
|
||||
const su_from = {
|
||||
hidden: (item) => !item.su_enabled,
|
||||
rules: [Required],
|
||||
el: {
|
||||
multiple: false,
|
||||
clearable: true,
|
||||
ajax: {
|
||||
url: '/api/v1/assets/system-users/su-from/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
login_mode: login_mode,
|
||||
username: username,
|
||||
@@ -197,7 +217,9 @@ function getFields() {
|
||||
password: password,
|
||||
passphrase: passphrase,
|
||||
system_groups: system_groups,
|
||||
type: type
|
||||
type: type,
|
||||
su_enabled: su_enabled,
|
||||
su_from: su_from
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="20">
|
||||
<el-col :md="20" :sm="24">
|
||||
<AccountListTable ref="ListTable" :url="accountUrl" :has-import="false" :has-clone="false" />
|
||||
</el-col>
|
||||
<el-col :span="4" />
|
||||
<el-col :md="4" :sm="24" />
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="20">
|
||||
<el-col :md="20" :sm="24">
|
||||
<AppAccountListTable ref="ListTable" :url="accountUrl" :has-import="false" :has-clone="false" />
|
||||
</el-col>
|
||||
<el-col :span="4" />
|
||||
<el-col :md="4" :sm="24" />
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<RelationCard ref="assetSelect" type="primary" style="margin-top: 15px" v-bind="appRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :md="8" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<AssetRelationCard ref="assetSelect" type="primary" style="margin-top: 15px" v-bind="assetRelationConfig" />
|
||||
<RelationCard ref="nodeRelation" type="info" style="margin-top: 15px" v-bind="nodeRelationConfig" />
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
name: 'Push',
|
||||
title: this.$t('common.Push'),
|
||||
type: 'primary',
|
||||
can: this.object.auto_push,
|
||||
can: this.object.auto_push && vm.$hasPerm('assets.push_assetsystemuser'),
|
||||
callback: ({ row }) => {
|
||||
const theUrl = `/api/v1/assets/system-users/${vm.object.id}/tasks/`
|
||||
const data = { action: 'push', assets: [row.asset] }
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
name: 'Delete',
|
||||
title: this.$t('common.Delete'),
|
||||
type: 'danger',
|
||||
can: !this.$store.getters.currentOrgIsRoot,
|
||||
can: !this.$store.getters.currentOrgIsRoot && vm.$hasPerm('assets.delete_authbook'),
|
||||
callback: (val) => {
|
||||
this.$axios.delete(`/api/v1/assets/system-users-assets-relations/${val.row.id}/`).then(() => {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
title: this.$t('common.PushSelected'),
|
||||
name: 'PushSelected',
|
||||
can({ selectedRows }) {
|
||||
return selectedRows.length > 0 && vm.object.auto_push
|
||||
return selectedRows.length > 0 && vm.object.auto_push && vm.$hasPerm('assets.push_assetsystemuser')
|
||||
},
|
||||
callback: this.bulkPushCallback.bind(this)
|
||||
},
|
||||
@@ -111,7 +111,7 @@ export default {
|
||||
title: this.$t('assets.TestAssetsConnective'),
|
||||
name: 'TestSelected',
|
||||
can({ selectedRows }) {
|
||||
return selectedRows.length > 0
|
||||
return selectedRows.length > 0 && vm.$hasPerm('assets.test_assetconnectivity')
|
||||
},
|
||||
callback: this.bulkTestCallback.bind(this)
|
||||
}
|
||||
@@ -122,7 +122,8 @@ export default {
|
||||
title: this.$t('assets.TestAssetsConnective'),
|
||||
attrs: {
|
||||
type: 'primary',
|
||||
label: this.$t('common.Test')
|
||||
label: this.$t('common.Test'),
|
||||
disabled: !vm.$hasPerm('assets.test_assetconnectivity')
|
||||
},
|
||||
callbacks: {
|
||||
click: function() {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
<RelationCard
|
||||
v-if="!(object.protocol === 'rdp' || object.protocol === 'vnc')"
|
||||
|
@@ -4,10 +4,10 @@
|
||||
<b>{{ Tips.title }}</b>: <span>{{ Tips.body }}</span>
|
||||
</el-alert>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="20">
|
||||
<el-col :md="20" :sm="24">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="4" />
|
||||
<el-col :md="4" :sm="24" />
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
<script>
|
||||
import { GenericListTable } from '@/layout/components'
|
||||
import { ApplicationTypes } from '@/views/applications/const'
|
||||
import { ApplicationSystemUserTypes } from '@/views/applications/const'
|
||||
import { AssetProtocols } from '@/views/assets/const'
|
||||
|
||||
export default {
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
},
|
||||
dropdown: [
|
||||
...AssetProtocols,
|
||||
...ApplicationTypes
|
||||
...ApplicationSystemUserTypes
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import { groupedDropdownToCascader } from '@/utils/common'
|
||||
|
||||
export const AssetProtocols = [
|
||||
{
|
||||
@@ -28,3 +29,5 @@ export const AssetProtocols = [
|
||||
}
|
||||
]
|
||||
|
||||
export const AssetCascader = groupedDropdownToCascader(AssetProtocols)
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="white-bg dashboard-header print-margin">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-col :md="12" :sm="24">
|
||||
<h2>{{ $t('dashboard.LoginOverview') }}</h2>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-button-group style="float: right; padding: 0">
|
||||
<el-col :md="12" :sm="24" class="clearfix">
|
||||
<el-button-group style="float: right; padding: 0" class="clearfix">
|
||||
<el-button type="default" size="mini" :class="{ 'active': active === 'weekly'}" @click="changeDates('weekly')">{{ $t('dashboard.Weekly') }}</el-button>
|
||||
<el-button type="default" size="mini" :class="{ 'active': active === 'monthly'}" @click="changeDates('monthly')">{{ $t('dashboard.Monthly') }}</el-button>
|
||||
</el-button-group>
|
||||
@@ -13,7 +13,7 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="18" :sm="24">
|
||||
<LoginMetric :range="active" class="card-item" style="margin-top: -30px" heigth="300px" />
|
||||
<LoginMetric :range="active" class="card-item" heigth="300px" />
|
||||
</el-col>
|
||||
<el-col :lg="6" :sm="24">
|
||||
<LoginActivePin :range="active" class="card-item" />
|
||||
|
@@ -28,19 +28,19 @@ export default {
|
||||
{
|
||||
title: this.$t('dashboard.UsersTotal'),
|
||||
body: {
|
||||
route: `/users/users`,
|
||||
route: { name: 'UserList' },
|
||||
count: this.counter.total_count_users,
|
||||
comment: 'All users',
|
||||
disabled: !this.$store.state.users.hasAdmin
|
||||
comment: this.$t('dashboard.UsersTotal'),
|
||||
disabled: !this.$hasPerm('users.view_user')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('dashboard.AssetsTotal'),
|
||||
body: {
|
||||
route: `/assets/assets`,
|
||||
route: { name: 'AssetList' },
|
||||
count: this.counter.total_count_assets,
|
||||
comment: 'All assets',
|
||||
disabled: !this.$store.state.users.hasAdmin
|
||||
comment: this.$t('dashboard.AssetsTotal'),
|
||||
disabled: !this.$hasPerm('assets.view_asset')
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -48,7 +48,8 @@ export default {
|
||||
body: {
|
||||
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
|
||||
count: this.counter.total_count_online_users,
|
||||
comment: 'Online users'
|
||||
comment: this.$t('dashboard.OnlineUsers'),
|
||||
disabled: !this.$hasPerm('terminal.view_session')
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -56,7 +57,8 @@ export default {
|
||||
body: {
|
||||
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
|
||||
count: this.counter.total_count_online_sessions,
|
||||
comment: 'Online sessions'
|
||||
comment: this.$t('dashboard.OnlineSessions'),
|
||||
disabled: !this.$hasPerm('terminal.view_session')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<el-row :gutter="10" style="margin-bottom: 20px;margin-top: 20px">
|
||||
<el-col :md="8" :sm="12">
|
||||
<el-col :md="8" :sm="24">
|
||||
<TopUser />
|
||||
</el-col>
|
||||
<el-col :md="8" :sm="12" class="print-margin-top">
|
||||
<el-col :md="8" :sm="24" class="print-margin-top">
|
||||
<TopAssets />
|
||||
</el-col>
|
||||
<el-col :md="8" :sm="12">
|
||||
<el-col :md="8" :sm="24">
|
||||
<Latest10Sessions class="card-item print-margin-top" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<Page>
|
||||
<div v-if="this.$hasPerm('rbac.view_console|rbac.view_workspace')">
|
||||
<div v-if="this.$hasPerm('rbac.view_console|rbac.view_audit')">
|
||||
<Announcement />
|
||||
<ResourceSummary />
|
||||
<DatesLoginSummary />
|
||||
|
@@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<Announcement />
|
||||
<GenericTreeListPage :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
|
||||
<GenericTreeListPage
|
||||
:table-config="tableConfig"
|
||||
:header-actions="headerActions"
|
||||
:tree-setting="treeSetting"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
||||
import { Announcement } from '@/components'
|
||||
import { SystemUserFormatter, DialogDetailFormatter } from '@/components/TableFormatters'
|
||||
export default {
|
||||
components: {
|
||||
GenericTreeListPage,
|
||||
Announcement
|
||||
GenericTreeListPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -39,6 +41,10 @@ export default {
|
||||
url: '/api/v1/perms/users/assets/',
|
||||
hasTree: true,
|
||||
columns: ['hostname', 'ip', 'system_users', 'platform', 'comment', 'actions'],
|
||||
columnsShow: {
|
||||
default: ['hostname', 'ip', 'system_users', 'platform', 'actions'],
|
||||
min: ['hostname', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
hostname: {
|
||||
prop: 'hostname',
|
||||
@@ -86,7 +92,7 @@ export default {
|
||||
showOverflowTooltip: true,
|
||||
align: 'center',
|
||||
label: this.$t('assets.SystemUsers'),
|
||||
width: '150px',
|
||||
width: '120px',
|
||||
formatter: SystemUserFormatter,
|
||||
formatterArgs: {
|
||||
getUrl: ({ row }) => {
|
||||
@@ -102,6 +108,8 @@ export default {
|
||||
width: '100px'
|
||||
},
|
||||
actions: {
|
||||
width: '150px',
|
||||
align: 'center',
|
||||
formatterArgs: {
|
||||
hasDelete: false,
|
||||
loading: true,
|
||||
|
@@ -5,8 +5,8 @@
|
||||
</div>
|
||||
<ul class="content">
|
||||
<li v-if="announcement.content" class="item">
|
||||
<span class="item-title">【{{ announcement.subject }}】</span>
|
||||
<span>{{ announcement.content }}</span>
|
||||
<p class="item-title">【{{ announcement.subject }}】</p>
|
||||
<p class="item-content">{{ announcement.content }}</p>
|
||||
<span v-if="announcement.link">
|
||||
<el-link :href="announcement.link" target="_blank" class="item-url">
|
||||
{{ $t('common.ViewMore') }}
|
||||
@@ -70,6 +70,11 @@ ul,li {
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
vertical-align: middle;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.item-content {
|
||||
white-space: pre-wrap;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.item-url {
|
||||
|
@@ -11,9 +11,10 @@ export default {
|
||||
HomeCard
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
cardConfig: {
|
||||
title: this.$t('route.SessionOffline')
|
||||
title: this.$t('route.RecentSession')
|
||||
},
|
||||
tableConfig: {
|
||||
url: '/api/v1/terminal/my-sessions/?limit=5',
|
||||
@@ -29,7 +30,11 @@ export default {
|
||||
formatter: function(row, column, cellValue, index) {
|
||||
const label = index + 1
|
||||
const route = { to: { name: 'SessionDetail', params: { id: row.id }}}
|
||||
return <router-link {...{ attrs: route }}>{ label }</router-link>
|
||||
if (vm.$hasPerm('terminal.view_session')) {
|
||||
return <router-link {...{ attrs: route }} >{ label }</router-link>
|
||||
} else {
|
||||
return label
|
||||
}
|
||||
}
|
||||
},
|
||||
user: {
|
||||
@@ -59,7 +64,7 @@ export default {
|
||||
}
|
||||
},
|
||||
hasSelection: false,
|
||||
paginationSize: 5
|
||||
paginationSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -39,8 +39,8 @@ export default {
|
||||
return 'AssetsTicketDetail'
|
||||
} else if (row.type === 'apply_application') {
|
||||
return 'AppsTicketDetail'
|
||||
} else if (row.type === 'login_asset_confirm') {
|
||||
return 'loginAssetTicketDetail'
|
||||
} else if (row.type === 'login_asset_confirm' || row.type === 'login_confirm') {
|
||||
return 'LoginAssetTicketDetail'
|
||||
} else if (row.type === 'command_confirm') {
|
||||
return 'CommandConfirmDetail'
|
||||
} else {
|
||||
@@ -64,7 +64,7 @@ export default {
|
||||
}
|
||||
],
|
||||
hasSelection: false,
|
||||
paginationSize: 5
|
||||
paginationSize: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -12,7 +12,10 @@
|
||||
<ul>
|
||||
<li><span class="title">{{ $t('audits.Username') }}</span>:<span>{{ users.name }}</span></li>
|
||||
<li><span class="title">{{ $t('users.Email') }}</span>:<span>{{ users.email }}</span></li>
|
||||
<li><span class="title">{{ $t('audits.LoginDate') }}</span>:<span>{{ this.$moment(users.last_login).format('YYYY-MM-DD HH:mm:ss') }}</span></li>
|
||||
<li>
|
||||
<span class="title">{{ $t('audits.LoginDate') }}</span>:
|
||||
<span>{{ $moment(users.last_login, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<Page>
|
||||
<Announcement />
|
||||
<div class="home">
|
||||
<el-container class="container">
|
||||
<el-main class="main">
|
||||
@@ -8,12 +9,11 @@
|
||||
<el-row>
|
||||
<el-col :md="16" :xs="24" class="content-left">
|
||||
<Session />
|
||||
<Log />
|
||||
<Ticket v-if="hasValidLicense" />
|
||||
<Ticket v-if="$hasLicense() && $hasPerm('tickets.view_ticket')" />
|
||||
</el-col>
|
||||
<el-col :md="8" :xs="24">
|
||||
<User />
|
||||
<Announcement />
|
||||
<Log />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
<script>
|
||||
import { Page } from '@/layout/components'
|
||||
import { Announcement } from '@/components'
|
||||
import User from './components/User'
|
||||
import Announcement from './components/Announcement'
|
||||
import Ticket from './components/Ticket'
|
||||
import Log from './components/LoginLog'
|
||||
import Session from './components/Session'
|
||||
@@ -35,23 +35,12 @@ import Session from './components/Session'
|
||||
export default {
|
||||
name: 'Name',
|
||||
components: {
|
||||
Announcement,
|
||||
Page,
|
||||
User,
|
||||
Announcement,
|
||||
Ticket,
|
||||
Log,
|
||||
Session
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasValidLicense() {
|
||||
return this.$store.getters.hasValidLicense
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :title="cardTitle" :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<RunInfoCard type="danger" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
<RunInfoCard type="info" v-bind="RunSuccessConfig" style="margin-top: 15px" />
|
||||
</el-col>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :title="cardTitle" :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<RunInfoCard type="danger" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
<RunInfoCard type="info" v-bind="RunSuccessConfig" style="margin-top: 15px" />
|
||||
</el-col>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :title="cardTitle" :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<RunInfoCard type="danger" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
<RunInfoCard type="info" v-bind="RunSuccessConfig" style="margin-top: 15px" />
|
||||
</el-col>
|
||||
|
@@ -34,6 +34,7 @@ export default {
|
||||
[this.$t('common.Other'), ['is_active', 'date_start', 'date_expired', 'comment']]
|
||||
],
|
||||
url: `/api/v1/perms/application-permissions/?category=${this.$route.query.category}&type=${this.$route.query.type}`,
|
||||
createSuccessNextRoute: { name: 'ApplicationPermissionDetail' },
|
||||
fieldsMeta: {
|
||||
users: {
|
||||
el: {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,10 +1,17 @@
|
||||
<template>
|
||||
<GenericTreeListPage
|
||||
ref="TreeTablePage"
|
||||
:tree-setting="treeSetting"
|
||||
:header-actions="headerActions"
|
||||
:table-config="tableConfig"
|
||||
/>
|
||||
<div>
|
||||
<GenericTreeListPage
|
||||
ref="TreeTablePage"
|
||||
:tree-setting="treeSetting"
|
||||
:header-actions="headerActions"
|
||||
:table-config="tableConfig"
|
||||
/>
|
||||
<PermBulkUpdateDialog
|
||||
:visible.sync="updateSelectedDialogSetting.visible"
|
||||
v-bind="updateSelectedDialogSetting"
|
||||
:perm-type="permType"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -12,15 +19,19 @@ import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
||||
import { setUrlParam } from '@/utils/common'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import { ApplicationTypes } from '@/views/applications/const'
|
||||
import PermBulkUpdateDialog from '@/views/perms/components/PermBulkUpdateDialog'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AssetAccountList',
|
||||
components: {
|
||||
GenericTreeListPage
|
||||
GenericTreeListPage,
|
||||
PermBulkUpdateDialog
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
permType: 'applications',
|
||||
isInit: true,
|
||||
clickedRow: null,
|
||||
iShowTree: true,
|
||||
@@ -164,9 +175,31 @@ export default {
|
||||
}})
|
||||
},
|
||||
dropdown: ApplicationTypes
|
||||
}
|
||||
},
|
||||
extraMoreActions: [
|
||||
{
|
||||
name: 'actionUpdateSelected',
|
||||
title: this.$t('common.updateSelected'),
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0 &&
|
||||
!vm.currentOrgIsRoot &&
|
||||
vm.$hasPerm('perms.change_applicationpermission')
|
||||
},
|
||||
callback: ({ selectedRows }) => {
|
||||
vm.updateSelectedDialogSetting.selectedRows = selectedRows
|
||||
vm.updateSelectedDialogSetting.visible = true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
updateSelectedDialogSetting: {
|
||||
visible: false,
|
||||
selectedRows: []
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
|
||||
<GenericCreateUpdatePage
|
||||
:fields="fields"
|
||||
:initial="initial"
|
||||
:fields-meta="fieldsMeta"
|
||||
:url="url"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -37,6 +42,7 @@ export default {
|
||||
[this.$t('common.Other'), ['is_active', 'date_start', 'date_expired', 'comment']]
|
||||
],
|
||||
url: '/api/v1/perms/asset-permissions/',
|
||||
createSuccessNextRoute: { name: 'AssetPermissionDetail' },
|
||||
fieldsMeta: {
|
||||
users: {
|
||||
el: {
|
||||
|
@@ -1,16 +1,26 @@
|
||||
<template>
|
||||
<GenericTreeListPage :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
|
||||
<div>
|
||||
<GenericTreeListPage :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting" />
|
||||
<PermBulkUpdateDialog
|
||||
:visible.sync="updateSelectedDialogSetting.visible"
|
||||
v-bind="updateSelectedDialogSetting"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import PermBulkUpdateDialog from '@/views/perms/components/PermBulkUpdateDialog'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericTreeListPage
|
||||
GenericTreeListPage,
|
||||
PermBulkUpdateDialog
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
treeSetting: {
|
||||
showMenu: false,
|
||||
@@ -186,10 +196,32 @@ export default {
|
||||
}
|
||||
]
|
||||
},
|
||||
hasBulkUpdate: false
|
||||
hasBulkUpdate: false,
|
||||
extraMoreActions: [
|
||||
{
|
||||
name: 'actionUpdateSelected',
|
||||
title: this.$t('common.updateSelected'),
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0 &&
|
||||
!vm.currentOrgIsRoot &&
|
||||
vm.$hasPerm('perms.change_assetpermission')
|
||||
},
|
||||
callback: ({ selectedRows }) => {
|
||||
vm.updateSelectedDialogSetting.selectedRows = selectedRows
|
||||
vm.updateSelectedDialogSetting.visible = true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
updateSelectedDialogSetting: {
|
||||
visible: false,
|
||||
selectedRows: []
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['currentOrgIsRoot'])
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
|
87
src/views/perms/components/PermBulkUpdateDialog.vue
Normal file
87
src/views/perms/components/PermBulkUpdateDialog.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<GenericUpdateFormDialog
|
||||
v-if="visible"
|
||||
:selected-rows="selectedRows"
|
||||
:form-setting="formSetting"
|
||||
:visible="visible"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericUpdateFormDialog } from '@/layout/components'
|
||||
import getFields from '@/views/perms/fields'
|
||||
|
||||
export default {
|
||||
name: 'PermBulkUpdateDialog',
|
||||
components: {
|
||||
GenericUpdateFormDialog
|
||||
},
|
||||
props: {
|
||||
permType: {
|
||||
type: String,
|
||||
default: 'asset'
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
selectedRows: {
|
||||
type: Array,
|
||||
default: () => ([])
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formSetting: {
|
||||
url: '',
|
||||
hasSaveContinue: false,
|
||||
initial: {},
|
||||
fields: [],
|
||||
fieldsMeta: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
let url
|
||||
const fieldsManager = getFields.bind(this)()
|
||||
const fields = [
|
||||
'users', 'user_groups', 'system_users',
|
||||
'actions', 'is_active', 'date_start', 'date_expired'
|
||||
]
|
||||
const fieldsMeta = {
|
||||
users: fieldsManager.users,
|
||||
user_groups: fieldsManager.user_groups,
|
||||
system_users: fieldsManager.system_users,
|
||||
actions: fieldsManager.actions,
|
||||
date_start: fieldsManager.date_start,
|
||||
date_expired: fieldsManager.date_expired,
|
||||
is_active: fieldsManager.is_active
|
||||
}
|
||||
if (this.permType !== 'asset') {
|
||||
url = '/api/v1/perms/application-permissions/'
|
||||
fields.splice(2, 0, 'applications')
|
||||
Object.assign(fieldsMeta, { applications: fieldsManager.applications })
|
||||
} else {
|
||||
url = '/api/v1/perms/asset-permissions/'
|
||||
fields.splice(2, 0, ...['assets', 'nodes'])
|
||||
Object.assign(fieldsMeta, {
|
||||
assets: fieldsManager.assets,
|
||||
nodes: fieldsManager.nodes
|
||||
})
|
||||
}
|
||||
this.$data.formSetting.url = url
|
||||
this.$data.formSetting.fields = fields
|
||||
this.$data.formSetting.fieldsMeta = fieldsMeta
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
120
src/views/perms/fields.js
Normal file
120
src/views/perms/fields.js
Normal file
@@ -0,0 +1,120 @@
|
||||
import AssetSelect from '@/components/AssetSelect'
|
||||
import PermissionFormActionField from '@/views/perms/components/PermissionFormActionField'
|
||||
|
||||
function getFields() {
|
||||
const users = {
|
||||
label: this.$t('users.Users'),
|
||||
hidden: () => false,
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/users/users/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const user_groups = {
|
||||
label: this.$t('users.UserGroups'),
|
||||
hidden: () => false,
|
||||
el: {
|
||||
value: [],
|
||||
url: '/api/v1/users/groups/'
|
||||
}
|
||||
}
|
||||
|
||||
const assets = {
|
||||
type: 'assetSelect',
|
||||
hidden: () => false,
|
||||
component: AssetSelect,
|
||||
label: this.$t('perms.Asset'),
|
||||
rules: [{
|
||||
required: false
|
||||
}],
|
||||
el: {
|
||||
value: []
|
||||
}
|
||||
}
|
||||
|
||||
const nodes = {
|
||||
label: this.$t('perms.Node'),
|
||||
hidden: () => false,
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const system_users = {
|
||||
label: this.$t('perms.SystemUser'),
|
||||
hidden: () => false,
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/system-users/?protocol__in=rdp,ssh,vnc,telnet',
|
||||
transformOption: (item) => {
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
label: this.$t('perms.Actions'),
|
||||
hidden: () => false,
|
||||
component: PermissionFormActionField,
|
||||
helpText: this.$t('common.actionsTips')
|
||||
}
|
||||
|
||||
const date_start = {
|
||||
label: this.$t('common.dateStart'),
|
||||
hidden: () => false
|
||||
}
|
||||
|
||||
const date_expired = {
|
||||
label: this.$t('common.dateExpired'),
|
||||
hidden: () => false
|
||||
}
|
||||
|
||||
const is_active = {
|
||||
label: this.$t('assets.IsActive'),
|
||||
type: 'checkbox'
|
||||
}
|
||||
|
||||
const applications = {
|
||||
label: this.$t('assets.Applications'),
|
||||
hidden: () => false,
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: `/api/v1/applications/applications/`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + ' (' + item.type_display + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
users: users,
|
||||
user_groups: user_groups,
|
||||
assets: assets,
|
||||
applications: applications,
|
||||
nodes: nodes,
|
||||
system_users: system_users,
|
||||
actions: actions,
|
||||
is_active: is_active,
|
||||
date_start: date_start,
|
||||
date_expired: date_expired
|
||||
}
|
||||
}
|
||||
|
||||
export default getFields
|
@@ -33,8 +33,6 @@ export default {
|
||||
label: 'AccessKeySecret',
|
||||
formatter: ShowKeyFormatter
|
||||
},
|
||||
is_active: {
|
||||
},
|
||||
date_created: {
|
||||
label: this.$t('common.dateCreated'),
|
||||
showOverflowTooltip: true,
|
||||
@@ -44,6 +42,7 @@ export default {
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
onDelete: function({ row }) {
|
||||
this.$axios.delete(`${ajaxUrl}${row.id}/`).then(res => {
|
||||
this.getRefsListTable.reloadTable()
|
||||
|
@@ -2,10 +2,10 @@
|
||||
<Page v-bind="$attrs">
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailCardItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions
|
||||
type="primary"
|
||||
:title="this.$t('users.AuthSettings')"
|
||||
@@ -30,14 +30,14 @@
|
||||
:destroy-on-close="true"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<div style="line-height: 34px;text-align: center">{{ $t('assets.Password') }}</div>
|
||||
<el-col :md="4" :sm="24">
|
||||
<div style="line-height: 34px">{{ $t('assets.Password') }}</div>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<el-input v-model="passwordInput" type="password" />
|
||||
<span class="help-tips help-block">{{ $t('common.PasswordRequireForSecurity') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :md="4" :sm="24">
|
||||
<el-button size="mini" type="primary" style="line-height:20px " @click="passConfirm">{{ this.$t('common.Confirm') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
98
src/views/profile/TempPassword.vue
Normal file
98
src/views/profile/TempPassword.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<GenericListPage
|
||||
ref="GenericListTable"
|
||||
:table-config="tableConfig"
|
||||
:header-actions="headerActions"
|
||||
:help-message="helpMessage"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
const ajaxUrl = '/api/v1/authentication/temp-tokens/'
|
||||
return {
|
||||
helpMessage: this.$t('setting.helpText.TempPassword'),
|
||||
tableConfig: {
|
||||
hasSelection: true,
|
||||
url: ajaxUrl,
|
||||
columns: [
|
||||
'username', 'secret', 'date_expired', 'date_verified', 'is_valid', 'actions'
|
||||
],
|
||||
columnsMeta: {
|
||||
secret: {
|
||||
label: this.$t('common.nav.TempPassword')
|
||||
},
|
||||
expire: {
|
||||
label: this.$t('setting.Expired') + '( s )'
|
||||
},
|
||||
actions: {
|
||||
prop: '',
|
||||
formatterArgs: {
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
hasDelete: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'Expired',
|
||||
title: this.$t('setting.Expire'),
|
||||
type: 'info',
|
||||
callback: function({ row }) {
|
||||
this.$axios.patch(`${ajaxUrl}${row.id}/expire/`,
|
||||
).then(res => {
|
||||
this.getRefsListTable.reloadTable()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: false,
|
||||
hasRightActions: true,
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasBulkDelete: false,
|
||||
hasCreate: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: this.$t('setting.Create'),
|
||||
title: this.$t('setting.Create'),
|
||||
type: 'primary',
|
||||
can: true,
|
||||
callback: function() {
|
||||
this.$axios.post(
|
||||
`/api/v1/authentication/temp-tokens/`
|
||||
).then(res => {
|
||||
this.getRefsListTable.reloadTable()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + error))
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getRefsListTable() {
|
||||
return this.$refs.GenericListTable.$refs.ListTable.$refs.ListTable || {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-col :md="16" :sm="24">
|
||||
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -66,5 +66,4 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard v-if="object" :items="detailItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions v-if="object" type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<pre style="border: none; background: none; white-space: pre-wrap;padding: 10px 20px">
|
||||
<pre style="border: none; background: none; white-space: pre-wrap; word-wrap: break-word; padding: 10px 20px">
|
||||
{{ '$ '+ row.input }}
|
||||
<br>
|
||||
{{ row.output }}
|
||||
|
@@ -18,6 +18,7 @@
|
||||
<div slot="footer">
|
||||
<el-button @click="hiddenDialog">{{ $t('common.Cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="dialogLdapUserImportLoginStatus" @click="importUserClick">{{ $t('common.Import') }}</el-button>
|
||||
<el-button type="primary" :loading="dialogLdapUserImportAllLoginStatus" @click="importAllUserClick">{{ $t('common.ImportAll') }}</el-button>
|
||||
</div>
|
||||
</Dialog>
|
||||
<Dialog
|
||||
@@ -41,8 +42,10 @@
|
||||
import ListTable from '@/components/ListTable'
|
||||
import { GenericCreateUpdateForm } from '@/layout/components'
|
||||
import Dialog from '@/components/Dialog'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import { importLdapUser, refreshLdapUserCache, startLdapUserCache } from '@/api/settings'
|
||||
import { CronTab } from '@/components'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
export default {
|
||||
name: 'ImportDialog',
|
||||
@@ -54,6 +57,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
dialogLdapUserImportLoginStatus: false,
|
||||
dialogLdapUserImportAllLoginStatus: false,
|
||||
refreshed: false,
|
||||
headerActions: {
|
||||
hasCreate: false,
|
||||
@@ -105,8 +109,24 @@ export default {
|
||||
settings: {
|
||||
visible: false,
|
||||
url: '/api/v1/settings/setting/?category=ldap',
|
||||
fields: ['AUTH_LDAP_SYNC_IS_PERIODIC', 'AUTH_LDAP_SYNC_CRONTAB', 'AUTH_LDAP_SYNC_INTERVAL'],
|
||||
fields: ['AUTH_LDAP_SYNC_ORG_ID', 'AUTH_LDAP_SYNC_IS_PERIODIC', 'AUTH_LDAP_SYNC_CRONTAB', 'AUTH_LDAP_SYNC_INTERVAL'],
|
||||
fieldsMeta: {
|
||||
AUTH_LDAP_SYNC_ORG_ID: {
|
||||
component: Select2,
|
||||
rules: [Required],
|
||||
el: {
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/orgs/orgs/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => {
|
||||
return !this.$hasLicense()
|
||||
}
|
||||
},
|
||||
AUTH_LDAP_SYNC_IS_PERIODIC: {
|
||||
type: 'switch'
|
||||
},
|
||||
@@ -142,6 +162,16 @@ export default {
|
||||
}).finally(() => this.dialogLdapUserImportLoginStatus = false)
|
||||
}
|
||||
},
|
||||
importAllUserClick() {
|
||||
this.dialogLdapUserImportAllLoginStatus = true
|
||||
const data = {
|
||||
username_list: ['*']
|
||||
}
|
||||
importLdapUser(data).then(res => {
|
||||
this.$message.success(res.msg)
|
||||
// eslint-disable-next-line no-return-assign
|
||||
}).finally(() => this.dialogLdapUserImportAllLoginStatus = false)
|
||||
},
|
||||
handlerListTableXHRError(errMsg) {
|
||||
if (this.dialogLdapUserImport) {
|
||||
setTimeout(this.$refs.listTable.reloadTable, 30000)
|
||||
|
@@ -5,10 +5,10 @@
|
||||
{{ this.$t('setting.ImportLicenseTip') }}
|
||||
</el-alert>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="14">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :title="cardTitle" :items="detailItems" />
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions type="primary" :actions="quickActions" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<span>{{ scope.row.value }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-for="header in receiveBackends" :key="header.id" :label="header.name_display" width="120">
|
||||
<el-table-column v-for="header in receiveBackends" :key="header.id" :label="getNameDisplay(header)" width="80">
|
||||
<template v-slot="scope">
|
||||
<span v-if="!scope.row.children">
|
||||
<el-checkbox
|
||||
@@ -86,7 +86,7 @@ export default {
|
||||
|
||||
this.$axios.patch(
|
||||
`/api/v1/notifications/system-msg-subscription/${sub.id}/`,
|
||||
{ receiveBackends: backends }
|
||||
{ receive_backends: backends }
|
||||
).catch(err => {
|
||||
this.$log.error(err)
|
||||
})
|
||||
@@ -105,6 +105,13 @@ export default {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
getNameDisplay(header) {
|
||||
const displayName = header['name_display']
|
||||
if (displayName === 'Site message') {
|
||||
return 'Inbox'
|
||||
}
|
||||
return displayName
|
||||
},
|
||||
onOpenDialog(sub) {
|
||||
this.currentEditSub = sub
|
||||
this.dialogSelectedUsers = sub.receivers
|
||||
|
@@ -14,20 +14,27 @@ export default {
|
||||
GenericCreateUpdateForm
|
||||
},
|
||||
data() {
|
||||
const comp = this.$t('common.Component')
|
||||
return {
|
||||
fields: [
|
||||
[
|
||||
'KoKo',
|
||||
`SSH ${comp}(KoKo)`,
|
||||
[
|
||||
'TERMINAL_PASSWORD_AUTH', 'TERMINAL_PUBLIC_KEY_AUTH',
|
||||
'TERMINAL_ASSET_LIST_SORT_BY', 'TERMINAL_ASSET_LIST_PAGE_SIZE',
|
||||
'TERMINAL_TELNET_REGEX'
|
||||
'TERMINAL_ASSET_LIST_SORT_BY',
|
||||
'TERMINAL_ASSET_LIST_PAGE_SIZE', 'TERMINAL_TELNET_REGEX'
|
||||
]
|
||||
],
|
||||
[
|
||||
'XRDP',
|
||||
`RDP ${comp}(XRDP)`,
|
||||
[
|
||||
'XRDP_ENABLED', 'TERMINAL_RDP_ADDR'
|
||||
'XRDP_ENABLED'
|
||||
]
|
||||
],
|
||||
[
|
||||
`DB ${comp}(Magnus)`,
|
||||
[
|
||||
'TERMINAL_MAGNUS_ENABLED'
|
||||
]
|
||||
]
|
||||
],
|
||||
@@ -35,11 +42,6 @@ export default {
|
||||
TERMINAL_TELNET_REGEX: {
|
||||
type: 'input'
|
||||
},
|
||||
TERMINAL_RDP_ADDR: {
|
||||
hidden: () => {
|
||||
return !this.$store.getters.hasValidLicense
|
||||
}
|
||||
},
|
||||
XRDP_ENABLED: {
|
||||
hidden: () => {
|
||||
return !this.$store.getters.hasValidLicense
|
||||
|
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
v-bind="$data"
|
||||
:create-success-next-route="successUrl"
|
||||
:update-success-next-route="successUrl"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
|
||||
export default {
|
||||
name: 'EndpointCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: '/api/v1/terminal/endpoints/',
|
||||
successUrl: { name: 'TerminalSetting', params: { activeMenu: 'EndpointList' }},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'host']],
|
||||
[
|
||||
this.$t('applications.port'),
|
||||
['http_port', 'https_port', 'ssh_port', 'rdp_port', 'mysql_port', 'mariadb_port', 'postgresql_port']
|
||||
],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
},
|
||||
hasDetailInMsg: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
55
src/views/settings/Terminal/Endpoint/EndpointList.vue
Normal file
55
src/views/settings/Terminal/Endpoint/EndpointList.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/ListTable'
|
||||
|
||||
export default {
|
||||
name: 'EndpointList',
|
||||
components: {
|
||||
ListTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/terminal/endpoints/',
|
||||
columns: [
|
||||
'name', 'host',
|
||||
'http_port', 'https_port', 'ssh_port',
|
||||
'rdp_port', 'mysql_port', 'mariadb_port',
|
||||
'postgresql_port',
|
||||
'date_created', 'comment', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: [
|
||||
'name', 'host', 'actions',
|
||||
'http_port', 'https_port', 'ssh_port', 'rdp_port'
|
||||
]
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: null
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
updateRoute: 'EndpointUpdate',
|
||||
cloneRoute: 'EndpointCreate',
|
||||
canDelete: ({ row }) => row.id !== '00000000-0000-0000-0000-000000000001'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasMoreActions: false,
|
||||
createRoute: 'EndpointCreate'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage
|
||||
v-bind="$data"
|
||||
:create-success-next-route="successUrl"
|
||||
:update-success-next-route="successUrl"
|
||||
:after-get-form-value="afterGetFormValue"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
export default {
|
||||
name: 'EndpointRuleCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: '/api/v1/terminal/endpoint-rules/',
|
||||
successUrl: { name: 'TerminalSetting', params: { activeMenu: 'EndpointRuleList' }},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'ip_group', 'endpoint', 'priority']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
endpoint: {
|
||||
el: {
|
||||
multiple: false,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/terminal/endpoints/?fields_size=mini',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hasDetailInMsg: false,
|
||||
cleanFormValue(value) {
|
||||
if (!Array.isArray(value.ip_group)) {
|
||||
value.ip_group = value.ip_group ? value.ip_group.split(',') : []
|
||||
}
|
||||
return value
|
||||
},
|
||||
afterGetFormValue(formValue) {
|
||||
formValue.ip_group = formValue.ip_group.toString()
|
||||
return formValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user