Merge pull request #1124 from jumpserver/dev

v2.15.0-rc3
This commit is contained in:
Jiangjie.Bai
2021-10-27 19:34:31 +08:00
committed by GitHub
25 changed files with 196 additions and 103 deletions

View File

@@ -2,7 +2,6 @@
<div class="c-weektime">
<div class="c-schedue" />
<div :class="{'c-schedue': true, 'c-schedue-notransi': mode}" :style="styleValue" />
<table class="c-weektime-table" :class="{'c-min-table': colspan < 2}">
<thead class="c-weektime-head">
<tr>
@@ -34,6 +33,7 @@
<div class="g-clearfix c-weektime-con">
<span class="g-pull-left">{{ this.$t('common.WeekCronSelect.CanDragSelect') }}</span>
<a class="g-pull-right" @click.prevent="clearWeektime">{{ this.$t('common.WeekCronSelect.ClearSelection') }}</a>
<a class="g-pull-right g-pull-margin" @click.prevent="selectAll">{{ this.$t('common.WeekCronSelect.SelectAll') }}</a>
</div>
</td>
</tr>
@@ -221,6 +221,15 @@ export default {
this.timeRange = []
this.$emit('change', this.timeRange)
},
// 全选
selectAll() {
this.weektimeData.forEach(item => {
item.child.forEach(t => {
this.$set(t, 'check', true)
})
})
this.setTimeRange()
},
setTimeRange() {
this.timeRange = this.weektimeData.map(item => {
return {
@@ -301,7 +310,6 @@ export default {
}
</script>
<style lang="scss" scoped>
.c-weektime {
min-width: 640px;
position: relative;
@@ -392,6 +400,9 @@ export default {
float: right;
color: #409eff!important;
}
.g-pull-margin {
margin-right: 12px;
}
.g-tip-text {
color: #999;
}

View File

@@ -1,6 +1,6 @@
<template>
<IBox v-bind="$attrs">
<div class="ibox-heading">
<div v-if="contentHeading" class="ibox-heading">
<slot name="content-heading">
<h3 v-if="contentHeading.title"><i v-if="contentHeading.fa" :class="'fa ' + contentHeading.fa" /> {{ contentHeading.title }}</h3>
<small v-if="contentHeading.content"><i class="fa fa-tim" /> {{ contentHeading.content }}</small>
@@ -18,7 +18,7 @@ export default {
props: {
contentHeading: {
type: Object,
default: () => ({})
default: null
}
}
}

View File

@@ -441,6 +441,7 @@
"Saturday": "星期六",
"Sunday": "星期天",
"ClearSelection": "清空选择",
"SelectAll": "全选",
"CanDragSelect": "可拖动鼠标选择时间段",
"WeekOrTime": "星期/时间"
},

View File

@@ -464,6 +464,7 @@
"Saturday": "Saturday",
"Sunday": "Sunday",
"ClearSelection": "Clear selection",
"SelectAll": "Select all",
"CanDragSelect": "Can drag the mouse to select a time period",
"WeekOrTime": "Week/Time"
}

View File

@@ -186,6 +186,7 @@ export default {
const url = this.validActions.detailApiUrl
return this.$axios.get(url, { disableFlashErrorMsg: true }).then(data => {
this.$emit('update:object', data)
this.$emit('getObjectDone', data)
}).catch(error => {
if (error.response && error.response.status === 404) {
const msg = this.$t('common.ObjectNotFoundOrDeletedMsg')

View File

@@ -61,8 +61,7 @@ export default {
},
showTickets() {
return this.publicSettings.TICKETS_ENABLED &&
this.publicSettings.XPACK_LICENSE_IS_VALID &&
!this.isOrgAuditor
this.publicSettings['XPACK_LICENSE_IS_VALID']
}
},
methods: {

View File

@@ -167,7 +167,8 @@ export const allRoleRoutes = [
children: TicketsRoutes,
hidden: true,
meta: {
licenseRequired: true
licenseRequired: true,
permissions: [rolec.PERM_AUDIT]
// hidden: ({ settings }) => {
// return !settings.TICKETS_ENABLED
// }

View File

@@ -1,61 +1,71 @@
import i18n from '@/i18n/i18n'
import empty from '@/layout/empty'
import rolec from '@/utils/role'
export default [
{
path: 'tickets',
name: 'TicketList',
component: () => import('@/views/tickets/TicketList'),
meta: { title: i18n.t('route.Tickets'), icon: 'check-square-o', activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/:id',
name: 'TicketDetail',
component: () => import('@/views/tickets/TicketDetail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/request-asset-perm/create',
name: 'RequestAssetPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate'),
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/request-asset-perm/:id',
name: 'AssetsTicketDetail',
component: () => import('@/views/tickets/RequestAssetPerm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/login-asset-confirm/:id',
name: 'loginAssetTicketDetail',
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/request-application-perm/create',
name: 'RequestApplicationPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate'),
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/request-application-perm/:id',
name: 'AppsTicketDetail',
component: () => import('@/views/tickets/RequestApplicationPerm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' },
hidden: true
},
{
path: 'tickets/command-confirm/:id',
name: 'CommandConfirmDetail',
component: () => import('@/views/tickets/CommandConfirm/Detail/index'),
meta: { title: i18n.t('route.CommandConfirm'), activeMenu: '/tickets/tickets' },
hidden: true
component: empty,
meta: { permissions: [rolec.PERM_AUDIT] },
hidden: true,
redirect: '',
children: [
{
path: '',
name: 'TicketList',
component: () => import('@/views/tickets/TicketList'),
meta: { title: i18n.t('route.Tickets'), icon: 'check-square-o', activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'request-asset-perm/create',
name: 'RequestAssetPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestAssetPerm/CreateUpdate'),
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'request-asset-perm/:id',
name: 'AssetsTicketDetail',
component: () => import('@/views/tickets/RequestAssetPerm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'login-asset-confirm/:id',
name: 'LoginAssetTicketDetail',
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'request-application-perm/create',
name: 'RequestApplicationPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestApplicationPerm/CreateUpdate'),
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'request-application-perm/:id',
name: 'AppsTicketDetail',
component: () => import('@/views/tickets/RequestApplicationPerm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: 'command-confirm/:id',
name: 'CommandConfirmDetail',
component: () => import('@/views/tickets/CommandConfirm/Detail/index'),
meta: { title: i18n.t('route.CommandConfirm'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
},
{
path: ':id',
name: 'TicketDetail',
component: () => import('@/views/tickets/TicketDetail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_AUDIT] },
hidden: true
}
]
},
{
path: 'flows',

View File

@@ -92,7 +92,7 @@ export default [
{
path: 'tickets/request-asset-perm/create',
name: 'RequestAssetPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate'),
component: () => import('@/views/tickets/RequestAssetPerm/CreateUpdate'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
hidden: true
},
@@ -105,7 +105,7 @@ export default [
},
{
path: 'tickets/login-asset-confirm/:id',
name: 'loginAssetTicketDetail',
name: 'LoginAssetTicketDetail',
component: () => import('@/views/tickets/LoginAssetConfirm/Detail/index'),
meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets', permissions: [rolec.PERM_USE] },
hidden: true
@@ -113,7 +113,7 @@ export default [
{
path: 'tickets/request-application-perm/create',
name: 'RequestApplicationPermTicketCreateUpdate',
component: () => import('@/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate'),
component: () => import('@/views/tickets/RequestApplicationPerm/CreateUpdate'),
meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets', permissions: [rolec.PERM_USE] },
hidden: true
},

View File

@@ -75,7 +75,7 @@ function cleanDateStr(d) {
}
export function toSafeLocalDateStr(d) {
if (d === '') {
if (d === '' || d === null) {
return ''
}
const date = safeDate(d)

View File

@@ -183,21 +183,13 @@ function getFields() {
type: 'switch'
}
// const crontab = {
// label: i18n.t('xpack.RegularlyPerform'),
// hidden: (formValue) => {
// return formValue.is_periodic === false
// },
// helpText: i18n.t('xpack.HelpText.CrontabOfCreateUpdatePage')
// }
const crontab = {
type: 'cronTab',
component: CronTab,
rules: [
{ required: false }
],
label: i18n.t('xpack.RegularlyPerform'),
hidden: (formValue) => {
return formValue.is_periodic === false
},
helpText: i18n.t('xpack.HelpText.CrontabOfCreateUpdatePage')
}

View File

@@ -4,18 +4,20 @@
<DetailCard :items="detailCardItems" />
</el-col>
<el-col :span="10">
<!-- <RelationCard ref="RelationCard" type="info" v-bind="nodeRelationConfig" />-->
<QuickActions type="primary" :actions="quickActions" />
</el-col>
</el-row>
</template>
<script>
import DetailCard from '@/components/DetailCard'
import QuickActions from '@/components/QuickActions'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'Detail',
components: {
DetailCard
DetailCard,
QuickActions
},
props: {
object: {
@@ -50,6 +52,27 @@ export default {
this.$refs.RelationCard.$refs.select2.clearSelected()
}
},
quickActions: [
{
title: this.$t('common.Active'),
type: 'switcher',
attrs: {
model: this.object.is_active
},
callbacks: {
change: function(val) {
this.$axios.patch(
`/api/v1/acls/login-acls/${this.object.id}/`,
{ is_active: val }
).then(res => {
this.$message.success(this.$t('common.updateSuccessMsg'))
}).catch(err => {
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
})
}.bind(this)
}
}
],
dataVal: []
}
},
@@ -99,49 +122,56 @@ export default {
const arrs = this.object.rules.time_period
for (let i = 0; i < arrs.length; i++) {
const cur = arrs[i]
if (cur.value.length > 0) {
let timeStr = cur.value
if (timeStr.length > 0) {
const startTime = timeStr.substr(0, cur.value.length - 5)
let lastTime = timeStr.substr(-5, 5)
let obj = {}
if (lastTime.indexOf('00:00') !== -1) {
lastTime = '24:00'
}
timeStr = startTime + lastTime
switch (cur.id) {
case 0:
obj = {
key: this.$t('common.WeekCronSelect.Sunday'),
value: cur.value
value: timeStr
}
break
case 1:
obj = {
key: this.$t('common.WeekCronSelect.Monday'),
value: cur.value
value: timeStr
}
break
case 2:
obj = {
key: this.$t('common.WeekCronSelect.Tuesday'),
value: cur.value
value: timeStr
}
break
case 3:
obj = {
key: this.$t('common.WeekCronSelect.Wednesday'),
value: cur.value
value: timeStr
}
break
case 4:
obj = {
key: this.$t('common.WeekCronSelect.Thursday'),
value: cur.value
value: timeStr
}
break
case 5:
obj = {
key: this.$t('common.WeekCronSelect.Friday'),
value: cur.value
value: timeStr
}
break
case 6:
obj = {
key: this.$t('common.WeekCronSelect.Saturday'),
value: cur.value
value: timeStr
}
break
}

View File

@@ -30,7 +30,12 @@ export default {
],
fieldsMeta: {
type: {
readonly: true
type: 'select',
options: [{
label: appType,
value: appType
}],
disabled: true
},
attrs: {
fields: fieldsMap,

View File

@@ -67,6 +67,9 @@ export default {
headerActions: {
hasCreate: false,
createRoute: 'SystemUserCreate',
searchConfig: {
exclude: ['type']
},
moreCreates: {
callback: (option) => {
vm.$router.push({ name: 'SystemUserCreate', query: { protocol: option.title.toLowerCase() }})

View File

@@ -88,8 +88,19 @@ export default {
},
headerActions: {
hasLeftActions: false,
hasColumnSetting: false,
hasImport: false,
hasExport: false
hasExport: false,
searchConfig: {
exclude: ['id', 'asset', 'commandexecution'],
options: [
{
label: this.$t('audits.Hosts'),
value: 'asset_display'
}
]
},
hasSearch: true
}
},
headerActions: {

View File

@@ -1,5 +1,5 @@
<template>
<HeadingIBox :title="title" :content-heading="contentHeading">
<HeadingIBox :title="title">
<div v-if="dates_login_record_top10_sessions.length > 0" class="feed-activity-list">
<div v-for="(item, index ) of dates_login_record_top10_sessions" :key="item.user + index" class="feed-element">
<a href="#" class="pull-left">
@@ -26,10 +26,6 @@ export default {
return {
title: this.$t('dashboard.LatestSessions10'),
avatarUrl: require('@/assets/img/admin.png'),
contentHeading: {
title: this.$t('dashboard.LatestTop10'),
content: this.$t('dashboard.LatestSessions')
},
dates_login_record_top10_sessions: []
}
},

View File

@@ -35,6 +35,7 @@ export default {
return {
title: this.$t('common.Announcement'),
visible: false,
enableField: 'ANNOUNCEMENT_ENABLED',
config: {
fields: [
['', ['ANNOUNCEMENT_ENABLED', 'ANNOUNCEMENT']]

View File

@@ -31,7 +31,7 @@ export default {
visible: false,
fields: [
'EMAIL_CUSTOM_USER_CREATED_SUBJECT', 'EMAIL_CUSTOM_USER_CREATED_HONORIFIC',
'EMAIL_CUSTOM_USER_CREATED_BODY', 'EMAIL_CUSTOM_USER_CREATED_SIGNATURE'
'EMAIL_CUSTOM_USER_CREATED_BODY'
],
successUrl: { name: 'Settings', params: { activeMenu: 'EmailContent' }},
fieldsMeta: {

View File

@@ -58,7 +58,19 @@ export default {
submitMethod() {
return 'patch'
},
onConfirm() {}
onConfirm() {},
cleanFormValue(data) {
if (!data['EMAIL_HOST_PASSWORD']) {
delete data['EMAIL_HOST_PASSWORD']
}
if (data['EMAIL_USE_SSL'] === null) {
delete data['EMAIL_USE_SSL']
}
if (data['EMAIL_USE_TLS'] === null) {
delete data['EMAIL_USE_TLS']
}
return data
}
}
},
methods: {

View File

@@ -66,7 +66,7 @@ export default {
apply_applications: {
type: 'assetSelect',
component: Select2,
label: this.$t('perms.Asset'),
label: this.$t('applications.App'),
el: {
value: [],
ajax: {
@@ -80,7 +80,7 @@ export default {
apply_system_users: {
type: 'systemUserSelect',
component: Select2,
label: '系统用户',
label: this.$t('assets.SystemUser'),
el: {
value: [],
ajax: {

View File

@@ -70,7 +70,7 @@ export default {
apply_system_users: {
type: 'systemUserSelect',
component: Select2,
label: '系统用户',
label: this.$t('assets.SystemUser'),
el: {
value: [],
ajax: {

View File

@@ -34,8 +34,6 @@ export default {
}
}
},
mounted() {
},
methods: {
getObjectName() {
return this.ticket.title

View File

@@ -1,5 +1,11 @@
<template>
<GenericDetailPage :object.sync="ticket" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
<GenericDetailPage
:object.sync="ticket"
:active-menu.sync="config.activeMenu"
v-bind="config"
@getObjectDone="afterGetTicket"
v-on="$listeners"
>
<component :is="config.activeMenu" :object="ticket" />
</GenericDetailPage>
</template>
@@ -40,6 +46,21 @@ export default {
methods: {
getObjectName() {
return this.ticket.title
},
afterGetTicket(ticket) {
const ticketRouteMapper = {
'apply_asset': 'AssetsTicketDetail',
'apply_application': 'AppsTicketDetail',
'login_confirm': 'LoginAssetTicketDetail',
'login_asset_confirm': 'CommandConfirmDetail'
}
const routeName = ticketRouteMapper[ticket.type]
setTimeout(() => {
this.$router.push({
name: routeName,
params: { id: this.$route.params['id'] }
})
})
}
}
}

View File

@@ -37,7 +37,7 @@ export default {
} else if (row.type === 'apply_application') {
return 'AppsTicketDetail'
} else if (row.type === 'login_asset_confirm') {
return 'loginAssetTicketDetail'
return 'LoginAssetTicketDetail'
} else if (row.type === 'command_confirm') {
return 'CommandConfirmDetail'
} else {
@@ -71,7 +71,7 @@ export default {
}
},
{
prop: 'action',
prop: 'state',
label: this.$t('tickets.action'),
align: 'center',
width: '90px',

View File

@@ -31,7 +31,7 @@ export default {
width: '140px'
},
asset: {
label: '资产',
label: this.$t('assets.Asset'),
formatter(row) {
return row.attrs.host || row.attrs.hostname
}