Merge pull request #419 from jumpserver/dev

chore: merge dev to master
This commit is contained in:
Orange 2020-10-13 18:53:29 +08:00 committed by GitHub
commit b78b95e67a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 193 additions and 136 deletions

View File

@ -3,7 +3,7 @@
<table style="width: 100%">
<tr>
<td colspan="2">
<AssetSelect ref="assetSelect" />
<AssetSelect ref="assetSelect" :can-select="canSelect" />
</td>
</tr>
<tr>
@ -49,6 +49,12 @@ export default {
onAddSuccess: {
type: Function,
default: (objects, that) => {}
},
canSelect: {
type: Function,
default(row, index) {
return true
}
}
},
data() {

View File

@ -34,6 +34,12 @@ export default {
value: {
type: Array,
default: () => []
},
canSelect: {
type: Function,
default(row, index) {
return true
}
}
},
data() {
@ -68,6 +74,7 @@ export default {
tableConfig: {
url: '/api/v1/assets/assets/',
hasTree: true,
canSelect: this.canSelect,
columns: [
{
prop: 'hostname',

View File

@ -13,7 +13,7 @@
:row-class-name="rowClassName"
@selection-change="selectStrategy.onSelectionChange"
@select="selectStrategy.onSelect"
@select-all="selectStrategy.onSelectAll($event, selectable)"
@select-all="selectStrategy.onSelectAll($event, canSelect)"
@sort-change="onSortChange"
>
<!--TODO 不用jsx写, 感觉template逻辑有点不清晰了-->
@ -90,7 +90,7 @@
<!--非树-->
<template v-else>
<el-data-table-column v-if="hasSelection" type="selection" :align="selectionAlign" />
<el-data-table-column v-if="hasSelection" type="selection" :align="selectionAlign" :selectable="canSelect" />
<el-data-table-column
v-for="col in columns"
:key="col.prop"
@ -713,6 +713,12 @@ export default {
hasDetail: {
type: Boolean,
default: true
},
canSelect: {
type: Function,
default(row, index) {
return true
}
}
},
data() {

View File

@ -39,7 +39,8 @@ export default {
iZTreeID: `zTree_${this._uid}`,
iRMenuID: `rMenu_${this._uid}`,
zTree: '',
rMenu: ''
rMenu: '',
init: false
}
},
computed: {
@ -56,7 +57,14 @@ export default {
},
methods: {
initTree: function() {
this.$axios.get(this.treeSetting.treeUrl).then(res => {
let treeUrl
if (this.init && this.treeSetting.treeUrl.indexOf('/perms/') !== -1 && this.treeSetting.treeUrl.indexOf('rebuild_tree') === -1) {
treeUrl = (this.treeSetting.treeUrl.indexOf('?') === -1) ? `${this.treeSetting.treeUrl}?rebuild_tree=1` : `${this.treeSetting.treeUrl}&rebuild_tree=1`
} else {
treeUrl = this.treeSetting.treeUrl
this.init = true
}
this.$axios.get(treeUrl).then(res => {
if (!res) {
res = []
}
@ -65,6 +73,7 @@ export default {
name: this.$t('common.tree.Empty')
})
}
this.treeSetting.treeUrl = treeUrl
this.zTree = $.fn.zTree.init($(`#${this.iZTreeID}`), this.treeSetting, res)
if (this.treeSetting.showRefresh) {
this.rootNodeAddDom(

View File

@ -93,7 +93,7 @@ export default {
<style lang='less' scoped>
.datepicker{
width: 240px;
width: 233px;
}
.el-input__inner{
border: 1px solid #dcdee2;

View File

@ -1,7 +1,9 @@
<template>
<div>
<!-- <el-link class="el-link" target="_blank" @click="goToTickets">{{ $t('route.Ticket') }}</el-link>-->
<el-badge v-if="getBadgeValue() !== 0" :value="getBadgeValue()" size="mini" type="primary">
<el-link class="el-link" target="_blank" @click="goToTickets">{{ $t('route.Ticket') }}</el-link>
<el-badge v-if="getBadgeValue() !== 0" :value="getBadgeValue()" size="mini" type="primary" />
</el-badge>
</div>
</template>
@ -40,4 +42,7 @@ export default {
font-size: 13px;
font-weight: 400
}
.el-badge ::v-deep .el-badge__content.is-fixed{
top:10px;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div v-if="!loading">
<el-alert v-if="isExpire" type="error">
{{ isExpire }}
</el-alert>
</div>
</template>
<script>
import { toSafeLocalDateStr } from '@/utils/common'
import { mapGetters } from 'vuex'
export default {
name: 'LicenseExpireTip',
data() {
return {
loading: true,
licenseData: {}
}
},
computed: {
...mapGetters([
'publicSettings'
]),
isExpire() {
const intervalDays = this.getIntervalDays(this.licenseData.date_expired)
if (intervalDays < 0) {
return this.$t('setting.LicenseExpired')
}
if (intervalDays < 7) {
return this.$t('setting.LicenseWillBe') + this.licenseData.date_expired + this.$t('setting.Expire')
}
return false
}
},
mounted() {
if (this.publicSettings.XPACK_ENABLED) {
this.$axios.get('/api/v1/xpack/license/detail').then(res => {
this.licenseData = res
}).finally(() => {
this.loading = false
})
} else {
this.loading = false
}
},
methods: {
getIntervalDays(date) {
const dateExpired = new Date(toSafeLocalDateStr(date))
const dateNow = new Date()
const intervalTime = dateExpired.getTime() - dateNow.getTime()
return Math.floor(intervalTime / (24 * 3600 * 1000))
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,4 +1,8 @@
<template>
<div>
<slot name="globalNotification">
<LicenseExpireTip />
</slot>
<div class="page-heading">
<el-row :gutter="0">
<el-col :span="16" class="page-heading-left">
@ -11,12 +15,17 @@
</el-col>
</el-row>
</div>
</div>
<!-- <Breadcrumb />-->
</template>
<script>
import LicenseExpireTip from '@/layout/components/Page/LicenseExpireTip'
export default {
name: 'PageHeading',
components: {
LicenseExpireTip
},
props: {
title: {
type: String,

View File

@ -145,6 +145,13 @@ export function getDaysFuture(days, now) {
return new Date(now.getTime() + 3600 * 1000 * 24 * days)
}
export function getDayEnd(now) {
if (!now) {
now = new Date()
}
return new Date(new Date(now.toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)
}
export function setUrlParam(url, name, value) {
const urlArray = url.split('?')
if (urlArray.length === 1) {

View File

@ -282,7 +282,8 @@ export default {
formSetting: {
url: '/api/v1/assets/assets/',
initial: {
platform: 'Linux'
platform: 'Linux',
protocols: ['ssh/22']
},
fields: [
'platform', 'protocols', 'domain', 'admin_user', 'labels', 'comment'

View File

@ -9,7 +9,7 @@
<script type="text/jsx">
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo } from '@/utils/common'
import { getDayEnd, getDaysAgo } from '@/utils/common'
import { Dialog, ListTable } from '@/components'
import { DisplayFormatter } from '@/components/ListTable/formatters'
import { setUrlParam } from '@/utils/common'
@ -21,7 +21,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
const vm = this
return {
tableConfig: {

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo } from '@/utils/common'
import { getDayEnd, getDaysAgo } from '@/utils/common'
export default {
components: {
@ -13,7 +13,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: '/api/v1/audits/ftp-logs/',

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo } from '@/utils/common'
import { getDayEnd, getDaysAgo } from '@/utils/common'
export default {
components: {
@ -13,7 +13,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: '/api/v1/audits/login-logs/',

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo } from '@/utils/common'
import { getDayEnd, getDaysAgo } from '@/utils/common'
export default {
components: {
@ -13,7 +13,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: '/api/v1/audits/operate-logs/',

View File

@ -4,7 +4,7 @@
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo } from '@/utils/common'
import { getDayEnd, getDaysAgo } from '@/utils/common'
export default {
components: {
@ -13,7 +13,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: '/api/v1/audits/password-change-logs/',

View File

@ -70,6 +70,10 @@ export default {
assetRelationConfig: {
icon: 'fa-edit',
title: this.$t('perms.addAssetToThisPermission'),
hasObjectsId: this.object.assets,
canSelect: (row, index) => {
return this.object.assets.indexOf(row.id) === -1
},
performAdd: (items, that) => {
const relationUrl = `/api/v1/perms/asset-permissions-assets-relations/`
const objectId = this.object.id
@ -86,6 +90,7 @@ export default {
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$refs.ListTable.reloadTable()
that.$refs.assetSelect.$refs.select2.clearSelected()
window.location.reload()
}
},
nodeRelationConfig: {

View File

@ -4,7 +4,7 @@
<script>
import { GenericListPage } from '@/layout/components'
import { getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { getDayEnd, getDaysAgo, toSafeLocalDateStr } from '@/utils/common'
import { OutputExpandFormatter } from './formatters'
import { DetailFormatter } from '@/components/ListTable/formatters'
@ -16,7 +16,7 @@ export default {
const vm = this
const now = new Date()
const dateFrom = getDaysAgo(2, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: '/api/v1/terminal/commands/',

View File

@ -4,7 +4,7 @@
<script type="text/jsx">
import ListTable from '@/components/ListTable'
import { timeOffset, getDaysAgo } from '@/utils/common'
import { timeOffset, getDaysAgo, getDayEnd } from '@/utils/common'
import { ActionsFormatter } from '@/components/ListTable/formatters'
export default {
name: 'BaseList',
@ -24,7 +24,7 @@ export default {
data() {
const now = new Date()
const dateFrom = getDaysAgo(2, now).toISOString()
const dateTo = now.toISOString()
const dateTo = getDayEnd(now).toISOString()
return {
tableConfig: {
url: this.url,

View File

@ -1,8 +1,5 @@
<template>
<div v-if="!loading">
<el-alert v-if="isExpire" type="error">
{{ isExpire }}
</el-alert>
<el-alert v-if="!isValidateLicense" type="success">
{{ this.$t('setting.ImportLicenseTip') }}
</el-alert>
@ -33,7 +30,6 @@ import { QuickActions, Dialog } from '@/components'
import DetailCard from '@/components/DetailCard/index'
import { importLicense } from '@/api/settings'
import { mapGetters } from 'vuex'
import { toSafeLocalDateStr } from '@/utils/common'
export default {
name: 'License',
@ -89,16 +85,6 @@ export default {
}
return true
},
isExpire() {
const intervalDays = this.getIntervalDays(this.licenseData.date_expired)
if (intervalDays < 0) {
return this.$t('setting.LicenseExpired')
}
if (intervalDays < 7) {
return this.$t('setting.LicenseWillBe') + this.licenseData.date_expired + this.$t('setting.Expire')
}
return false
},
cardTitle() {
return ''
},
@ -172,12 +158,6 @@ export default {
},
fileChange(e) {
this.licenseFile['file'] = e.target.files[0]
},
getIntervalDays(date) {
const dateExpired = new Date(toSafeLocalDateStr(date))
const dateNow = new Date()
const intervalTime = dateExpired.getTime() - dateNow.getTime()
return Math.floor(intervalTime / (24 * 3600 * 1000))
}
}
}

View File

@ -97,7 +97,7 @@ export default {
this.InviteOptions = []
this.selectLoading = true
this.$axios
.get(` /api/v1/users/users/?search=${query}&all=1`)
.get(` /api/v1/users/users/suggestion/?search=${query}`)
.then(result => {
console.log(result)
for (let i = 0; i < result.length; i++) {

View File

@ -102,6 +102,9 @@ export default {
} else {
delete data['password']
}
if (data['interval'] === '') {
delete data['interval']
}
return data
},
generatePasswordRulesItemsFields() {

View File

@ -4,9 +4,11 @@
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
</el-col>
<el-col :md="10" :sm="24">
<RelationCard type="primary" v-bind="adminRelationConfig" />
<RelationCard type="info" style="margin-top: 15px" v-bind="auditorRelationConfig" />
<RelationCard type="warning" style="margin-top: 15px" v-bind="userRelationConfig" />
<RelationCard type="primary" v-bind="memberRelationConfig">
<el-radio-group v-model="defaultOrgRole" style="padding: 8px">
<el-radio v-for="item in group" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</RelationCard>
</el-col>
</el-row>
</template>
@ -30,6 +32,19 @@ export default {
},
data() {
return {
defaultOrgRole: 'User',
group: [
{
label: this.$t('users.OrgAdmin'),
value: 'Admin'
}, {
label: this.$t('users.OrgAuditor'),
value: 'Auditor'
}, {
label: this.$t('users.OrgUser'),
value: 'User'
}
],
tableConfig: {
url: `/api/v1/orgs/org-memeber-relation/?org_id=${this.object.id}`,
columns: [
@ -68,79 +83,9 @@ export default {
hasBulkDelete: false,
hasBulkUpdate: false
},
adminRelationConfig: {
memberRelationConfig: {
icon: 'fa-user',
title: this.$t('xpack.Admin'),
objectsAjax: {
url: '/api/v1/users/users/?fields_size=mini&order=name&all=1',
transformOption: (item) => {
return { label: item.name + '(' + item.username + ')', value: item.id }
}
},
hasObjectsId: this.object.admins,
showHasObjects: false,
performAdd: (items) => {
const objectId = this.object.id
const relationUrl = `/api/v1/orgs/orgs/${objectId}/`
const objectRelationAdmin = this.object.admins
items.map(v => objectRelationAdmin.push(v.value))
const data = { admins: objectRelationAdmin }
return this.$axios.patch(relationUrl, data)
},
performDelete: (item) => {
const objectId = this.object.id
const relationUrl = `/api/v1/orgs/orgs/${objectId}/`
const objectOldRelationAdmin = this.object.admins
const objectNewRelationAdmin = objectOldRelationAdmin.filter(v => v !== item.value)
const data = { admins: objectNewRelationAdmin }
return this.$axios.patch(relationUrl, data)
},
onAddSuccess: (objects, that) => {
this.$log.debug('Select value', that.select2.value)
that.iHasObjects = [...that.iHasObjects, ...objects]
that.$refs.select2.clearSelected()
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$refs.ListTable.reloadTable()
}
},
auditorRelationConfig: {
icon: 'fa-user',
title: this.$t('xpack.Auditor'),
objectsAjax: {
url: '/api/v1/users/users/?fields_size=mini&order=name&all=1',
transformOption: (item) => {
return { label: item.name + '(' + item.username + ')', value: item.id }
}
},
hasObjectsId: this.object.auditors,
showHasObjects: false,
performAdd: (items) => {
const objectId = this.object.id
const relationUrl = `/api/v1/orgs/orgs/${objectId}/`
const objectRelationAuditors = this.object.auditors
items.map(v => objectRelationAuditors.push(v.value))
const data = { auditors: objectRelationAuditors }
return this.$axios.patch(relationUrl, data)
},
performDelete: (item) => {
const objectId = this.object.id
const relationUrl = `/api/v1/orgs/orgs/${objectId}/`
const objectOldRelationAuditors = this.object.auditors
const objectNewRelationAuditors = objectOldRelationAuditors.filter(v => v !== item.value)
const data = { auditors: objectNewRelationAuditors }
return this.$axios.patch(relationUrl, data)
},
onAddSuccess: (objects, that) => {
this.$log.debug('Select value', that.select2.value)
that.iHasObjects = [...that.iHasObjects, ...objects]
that.$refs.select2.clearSelected()
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$refs.ListTable.reloadTable()
}
},
userRelationConfig: {
icon: 'fa-user',
title: this.$t('xpack.User'),
title: this.$t('xpack.Organization.AddOrgMembers'),
objectsAjax: {
url: '/api/v1/users/users/?fields_size=mini&order=name&all=1',
transformOption: (item) => {
@ -150,12 +95,12 @@ export default {
hasObjectsId: this.object.users,
showHasObjects: false,
performAdd: (items) => {
const objectId = this.object.id
const relationUrl = `/api/v1/orgs/orgs/${objectId}/`
const objectRelationUsers = this.object.users
items.map(v => objectRelationUsers.push(v.value))
const data = { users: objectRelationUsers }
return this.$axios.patch(relationUrl, data)
const relationUrl = `/api/v1/orgs/org-memeber-relation/`
const data = []
for (const user of items) {
data.push({ org: this.object.id, user: user.value, role: this.defaultOrgRole })
}
return this.$axios.post(relationUrl, data)
},
onAddSuccess: (objects, that) => {
this.$log.debug('Select value', that.select2.value)
@ -163,9 +108,23 @@ export default {
that.$refs.select2.clearSelected()
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$refs.ListTable.reloadTable()
window.location.reload()
}
}
}
},
watch: {
defaultOrgRole(value) {
if (value === 'Admin') {
this.$set(this.memberRelationConfig, 'hasObjectsId', this.object.admins)
}
if (value === 'Auditor') {
this.$set(this.memberRelationConfig, 'hasObjectsId', this.object.auditors)
}
if (value === 'User') {
this.$set(this.memberRelationConfig, 'hasObjectsId', this.object.users)
}
}
}
}
</script>