perf: 优化全局组织 (#621)

* feat: 默认组织改为实体组织

* perf: 优化在root组织下,应不能创建

* perf: 优化全局组织

* perf: 优化组织选择

Co-authored-by: ibuler <ibuler@qq.com>
This commit is contained in:
fit2bot
2021-03-03 14:47:44 +08:00
committed by GitHub
parent 4ee32dd51b
commit 6fde735cbd
28 changed files with 170 additions and 90 deletions

15
src/api/orgs.js Normal file
View File

@@ -0,0 +1,15 @@
import request from '@/utils/request'
export function getOrgDetail(oid) {
return request({
url: `/api/v1/orgs/orgs/current/?oid=${oid}`,
method: 'get'
})
}
export function getCurrentOrg() {
return request({
url: `/api/v1/orgs/orgs/current/`,
method: 'get'
})
}

View File

@@ -16,6 +16,7 @@ export default {
},
props: {
hasCreate: defaultTrue,
canCreate: defaultTrue,
hasBulkDelete: defaultTrue,
hasBulkUpdate: defaultFalse,
hasLeftActions: defaultTrue,
@@ -66,7 +67,7 @@ export default {
title: this.$t('common.Create'),
type: 'primary',
has: this.hasCreate,
can: true,
can: this.canCreate,
callback: this.handleCreate
}
],

View File

@@ -28,6 +28,9 @@ export default {
},
hasTips: false,
tipStatus(val, vm) {
if (!val) {
return vm.$t('assets.Unknown')
}
if (val.status === 0) {
return vm.$t('assets.Unreachable')
} else if (val.status === 1) {
@@ -55,6 +58,9 @@ export default {
return this.formatterArgs.tipStatus(this.cellValue, vm)
},
tipTime() {
if (!this.cellValue) {
return ''
}
return toSafeLocalDateStr(this.cellValue.datetime)
}
}

View File

@@ -42,21 +42,20 @@ export default {
}
},
computed: {
dataTable() {
return this.$refs.dataTable.$refs.dataTable
},
hasCreateAction() {
const hasLeftAction = this.headerActions.hasLeftActions
if (hasLeftAction === false) {
return false
}
const hasCreate = this.headerActions.hasCreate
if (hasCreate === false) {
return false
}
return true
},
// hasCreateAction() {
// const hasLeftAction = this.headerActions.hasLeftActions
// if (hasLeftAction === false) {
// return false
// }
// const hasCreate = this.headerActions.hasCreate
// if (hasCreate === false) {
// return false
// }
// return true
// },
iTableConfig() {
const config = deepmerge(this.tableConfig, { extraQuery: this.extraQuery })
this.$log.debug('Header actions', this.headerActions)

View File

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

View File

@@ -0,0 +1,32 @@
<template>
<ListTable v-bind="iAttrs" v-on="$listeners" />
</template>
<script>
import ListTable from '@/components/ListTable/index'
import { mapGetters } from 'vuex'
export default {
name: 'GenericListTable',
components: {
ListTable
},
computed: {
...mapGetters(['currentOrgIsRoot']),
iAttrs() {
const attrs = _.cloneDeep(this.$attrs)
const canCreate = _.get(attrs, 'header-actions.canCreate', null)
this.$log.debug('Can create: ', canCreate)
if (canCreate === null && this.currentOrgIsRoot) {
_.set(attrs, 'header-actions.canCreate', false)
}
// attrs.headerActions.can
// console.log()
return attrs
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,7 +1,7 @@
<template>
<Page>
<el-alert v-if="helpMessage" type="success"> {{ helpMessage }} </el-alert>
<TreeTable ref="TreeTable" :table-config="tableConfig" :header-actions="headerActions" :tree-setting="treeSetting">
<TreeTable ref="TreeTable" :table-config="tableConfig" :header-actions="iHeaderActions" :tree-setting="treeSetting">
<template #table>
<slot name="table" />
</template>
@@ -15,6 +15,7 @@
<script>
import Page from '@/layout/components/Page'
import TreeTable from '@/components/TreeTable'
import { mapGetters } from 'vuex'
export default {
name: 'GenericTreeListPage',
components: {
@@ -27,6 +28,17 @@ export default {
default: null
}
},
computed: {
...mapGetters(['currentOrgIsRoot']),
iHeaderActions() {
const attrs = _.cloneDeep(this.headerActions)
const canCreate = _.get(attrs, 'canCreate', null)
if (canCreate === null && this.currentOrgIsRoot) {
_.set(attrs, 'canCreate', false)
}
return attrs
}
},
methods: {
hideRMenu() {
this.$refs.TreeTable.hideRMenu()

View File

@@ -3,6 +3,8 @@ const getters = {
device: state => state.app.device,
token: state => state.users.token,
currentOrg: state => state.users.currentOrg,
currentOrgIsDefault: state => state.users.currentOrg.is_default,
currentOrgIsRoot: state => state.users.currentOrg.is_root,
currentRole: state => state.users.currentRole,
userAdminOrgList: state => state.users.orgs,
currentUser: state => state.users.profile,

View File

@@ -1,13 +1,13 @@
import { hasUUID, BASE_URL } from '@/utils/common'
import { getOrgDetail } from '@/api/orgs'
import store from '@/store'
const DEFAULT_ORG_ID = '00000000-0000-0000-0000-000000000001'
// const ROOT_ORG_ID = '00000000-0000-0000-0000-000000000000'
function getPropOrg() {
const userAdminOrgList = store.getters.userAdminOrgList
let defaultOrg = userAdminOrgList.find((item) => item.id === '')
if (defaultOrg) {
return defaultOrg
}
defaultOrg = userAdminOrgList.find((item) => item.id === 'DEFAULT')
const defaultOrg = userAdminOrgList.find((item) => item.id === DEFAULT_ORG_ID)
if (defaultOrg) {
return defaultOrg
}
@@ -19,14 +19,14 @@ function change2PropOrg() {
setTimeout(() => changeOrg(org.id), 100)
}
function getOrgIdMapper() {
const mapper = {}
const userAdminOrgList = store.getters.userAdminOrgList
userAdminOrgList.forEach((v) => {
mapper[v.id] = v
})
return mapper
}
// function getOrgIdMapper() {
// const mapper = {}
// const userAdminOrgList = store.getters.userAdminOrgList
// userAdminOrgList.forEach((v) => {
// mapper[v.id] = v
// })
// return mapper
// }
function hasCurrentOrgPermission() {
const currentOrg = store.getters.currentOrg
@@ -37,7 +37,7 @@ function hasCurrentOrgPermission() {
}
async function changeOrg(orgId) {
const org = getOrgIdMapper()[orgId]
const org = await getOrgDetail(orgId)
if (!org) {
console.debug('Error: org not found')
} else {

View File

@@ -6,6 +6,7 @@ import 'nprogress/nprogress.css' // progress bar style
import { getTokenFromCookie } from '@/utils/auth'
import rolec from '@/utils/role'
import orgUtil from '@/utils/org'
import { getCurrentOrg } from '@/api/orgs'
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
let initial = false
@@ -52,22 +53,29 @@ async function getPublicSetting({ to, from, next }) {
}
}
async function refreshCurrentOrg() {
getCurrentOrg().then(org => {
store.dispatch('users/setCurrentOrg', org)
})
}
async function changeCurrentOrgIfNeed({ to, from, next }) {
await store.dispatch('users/getInOrgs')
const adminOrgs = store.getters.userAdminOrgList
if (!adminOrgs || adminOrgs.length === 0) {
return
}
await refreshCurrentOrg()
const currentOrg = store.getters.currentOrg
if (!currentOrg || typeof currentOrg !== 'object') {
// console.log('Not has current org')
orgUtil.change2PropOrg()
return reject('change prop org')
return reject('Change prop org')
}
if (!orgUtil.hasCurrentOrgPermission()) {
console.debug('Not has current org permission')
orgUtil.change2PropOrg()
return reject('change prop org')
return reject('Change prop org')
}
}

View File

@@ -125,6 +125,9 @@ export default {
2: 'fa-circle text-warning'
},
typeChange: function(val) {
if (!val) {
return 2
}
return val.status
},
hasTips: true
@@ -160,6 +163,7 @@ export default {
}
},
headerActions: {
// canCreate: false,
createRoute: {
name: 'AssetCreate',
query: this.$route.query

View File

@@ -1,14 +1,14 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
export default {
name: 'Rules',
components: {
ListTable
GenericListTable
},
props: {
object: {

View File

@@ -1,6 +1,6 @@
<template>
<div>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
<Dialog
v-if="dialogVisible"
:title="this.$t('assets.TestGatewayTestConnection')"
@@ -29,12 +29,12 @@
</template>
<script>
import ListTable from '@/components/ListTable/index'
import GenericListTable from '@/layout/components/GenericListTable/index'
import DisplayFormatter from '@/components/ListTable/formatters/DisplayFormatter'
import Dialog from '@/components/Dialog'
export default {
components: {
ListTable,
GenericListTable,
Dialog
},
props: {

View File

@@ -26,7 +26,7 @@ export default {
ips_or_not: true,
apply_date_expired: date_expired,
apply_date_start: date_start,
org_id: 'DEFAULT',
org_id: '00000000-0000-0000-0000-000000000001',
type: 'apply_application',
apply_actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file']
},

View File

@@ -29,7 +29,10 @@ export default {
},
fields: [
[this.$t('users.Account'), ['name', 'username', 'email', 'groups']],
[this.$t('users.Authentication'), ['password_strategy', 'update_password', 'password', 'set_public_key', 'public_key', 'mfa_level', 'source']],
[this.$t('users.Authentication'), [
'password_strategy', 'update_password', 'password', 'set_public_key',
'public_key', 'mfa_level', 'source'
]],
[this.$t('users.Secure'), ['role', 'org_roles', 'date_expired']],
[this.$t('common.Other'), ['phone', 'wechat', 'comment']]
],
@@ -80,7 +83,7 @@ export default {
role: {
label: this.$t('users.SuperRole'),
hidden: () => {
return !this.currentOrgIsDefault && this.publicSettings.role === 'Admin'
return !this.currentOrgIsRoot && this.publicSettings.role === 'Admin'
}
},
org_roles: {
@@ -88,7 +91,7 @@ export default {
label: this.$t('users.OrgRole'),
component: RoleCheckbox,
hidden: () => {
return (!this.publicSettings.XPACK_LICENSE_IS_VALID)
return !this.publicSettings.XPACK_LICENSE_IS_VALID
},
el: {
disabled: false,
@@ -109,13 +112,10 @@ export default {
}
},
computed: {
...mapGetters(['publicSettings', 'currentOrg']),
currentOrgIsDefault() {
return this.currentOrg.id === 'DEFAULT' || this.currentOrg.id === ''
}
...mapGetters(['publicSettings', 'currentOrgIsRoot'])
},
mounted() {
if (this.currentOrgIsDefault) {
if (this.currentOrgIsRoot) {
this.fieldsMeta.org_roles.el.disabled = true
}
},

View File

@@ -64,7 +64,7 @@ export default {
},
actions: {
formatterArgs: {
hasDelete: () => this.currentOrgIsDefault,
hasDelete: () => this.currentOrgIsRoot,
canUpdate: function(row, cellValue) {
return row.can_update
},
@@ -76,7 +76,7 @@ export default {
title: this.$t('users.Remove'),
name: 'remove',
type: 'warning',
has: () => !this.currentOrgIsDefault,
has: () => !this.currentOrgIsRoot,
can: function(row, cellValue) {
return row.can_delete
},
@@ -89,6 +89,7 @@ export default {
},
headerActions: {
hasBulkDelete: false,
canCreate: true,
extraActions: [
{
name: this.$t('users.InviteUser'),
@@ -197,13 +198,10 @@ export default {
}
},
computed: {
...mapGetters(['currentOrg', 'currentUser', 'device']),
currentOrgIsDefault() {
return this.currentOrg.id === 'DEFAULT' || this.currentOrg.id === ''
}
...mapGetters(['currentOrgIsRoot', 'currentUser', 'device'])
},
mounted() {
if (!this.currentOrgIsDefault) {
if (!this.currentOrgIsRoot) {
this.headerActions.extraMoreActions[0].title = this.$t(
'common.removeSelected'
)
@@ -240,7 +238,7 @@ export default {
},
bulkDeleteCallback({ selectedRows, reloadTable }) {
let msgPrefix = this.$t('common.deleteWarningMsg')
if (!this.currentOrgIsDefault) {
if (!this.currentOrgIsRoot) {
msgPrefix = this.$t('common.removeWarningMsg')
}
const msg =
@@ -264,13 +262,13 @@ export default {
done()
reloadTable()
let successMsg = this.$t('common.bulkDeleteSuccessMsg')
if (!this.currentOrgIsDefault) {
if (!this.currentOrgIsRoot) {
successMsg = this.$t('common.bulkRemoveSuccessMsg')
}
this.$message.success(successMsg)
} catch (error) {
// let errorMsg = this.$t('common.bulkDeleteErrorMsg')
// if (!this.currentOrgIsDefault) {
// if (!this.currentOrgIsRoot) {
// errorMsg = this.$t('common.bulkRemoveErrorMsg')
// }
// this.$message.error(errorMsg + error)

View File

@@ -1,7 +1,7 @@
<template>
<el-row :gutter="20">
<el-col :md="14" :sm="24">
<ListTable ref="listTable" :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable ref="listTable" :table-config="tableConfig" :header-actions="headerActions" />
</el-col>
<el-col :md="10" :sm="24">
<AssetRelationCard type="primary" v-bind="assetRelationConfig" />
@@ -11,7 +11,7 @@
</template>
<script>
import ListTable from '@/components/ListTable/index'
import GenericListTable from '@/layout/components/GenericListTable'
import RelationCard from '@/components/RelationCard/index'
import AssetRelationCard from '@/components/AssetRelationCard'
import { DeleteActionFormatter } from '@/components/ListTable/formatters'
@@ -19,7 +19,7 @@ import { DeleteActionFormatter } from '@/components/ListTable/formatters'
export default {
name: 'ChangeAuthPlanAsset',
components: {
ListTable, RelationCard, AssetRelationCard
GenericListTable, RelationCard, AssetRelationCard
},
props: {
object: {

View File

@@ -1,14 +1,14 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
export default {
name: 'ChangeAuthPlanExecutionTaskList',
components: {
ListTable
GenericListTable
},
props: {
object: {

View File

@@ -1,14 +1,14 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
export default {
name: 'ChangeAuthPlanExecution',
components: {
ListTable
GenericListTable
},
props: {
object: {

View File

@@ -1,15 +1,15 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script type="text/jsx">
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, huaweicloud, qcloud, azure, vmware } from '../const'
import { BooleanFormatter, DetailFormatter } from '@/components/ListTable/formatters'
export default {
components: {
ListTable
GenericListTable
},
data() {
const vm = this

View File

@@ -1,14 +1,14 @@
<template>
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable ref="GenericListTable" :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable/index'
import GenericListTable from '@/layout/components/GenericListTable/index'
import { DateFormatter } from '@/components/ListTable/formatters'
export default {
name: 'AssetList',
components: { ListTable },
components: { GenericListTable },
props: {
object: {
type: Object,
@@ -63,7 +63,7 @@ export default {
this.$axios.delete(`/api/v1/xpack/cloud/sync-instance-tasks/${this.object.id}/released-assets/`).then(
res => {
this.$message.success(this.$t('common.deleteSuccessMsg'))
this.$refs.ListTable.reloadTable()
this.$refs.GenericListTable.reloadTable()
}
).catch(() => {
this.$message.error(this.$t('common.deleteErrorMsg'))

View File

@@ -1,14 +1,14 @@
<template>
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable ref="GenericListTable" :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable/index'
import GenericListTable from '@/layout/components/GenericListTable/index'
import { ActionsFormatter, DateFormatter } from '@/components/ListTable/formatters'
export default {
name: 'HistoryList',
components: { ListTable },
components: { GenericListTable },
props: {
object: {
type: Object,

View File

@@ -1,14 +1,14 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
import { DetailFormatter } from '@/components/ListTable/formatters'
export default {
components: {
ListTable
GenericListTable
},
data() {
const vm = this

View File

@@ -1,13 +1,13 @@
<template>
<ListTable :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
export default {
components: {
ListTable
GenericListTable
},
data() {
const vm = this

View File

@@ -1,7 +1,7 @@
<template>
<el-row :gutter="20">
<el-col :md="14" :sm="24">
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
<GenericListTable ref="GenericListTable" :table-config="tableConfig" :header-actions="headerActions" />
</el-col>
<el-col :md="10" :sm="24">
<RelationCard type="primary" v-bind="memberRelationConfig">
@@ -14,14 +14,14 @@
</template>
<script>
import ListTable from '@/components/ListTable'
import GenericListTable from '@/layout/components/GenericListTable'
import RelationCard from '@/components/RelationCard'
import { DeleteActionFormatter } from '@/components/ListTable/formatters'
export default {
name: 'OrganizationMembershipList',
components: {
ListTable,
GenericListTable,
RelationCard
},
props: {
@@ -108,7 +108,7 @@ export default {
that.iHasObjects = [...that.iHasObjects, ...objects]
that.$refs.select2.clearSelected()
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$refs.ListTable.reloadTable()
this.$refs.GenericListTable.reloadTable()
window.location.reload()
}
}

View File

@@ -53,8 +53,11 @@ export default {
label: this.$t('xpack.Organization.app_perms_amount')
},
actions: {
prop: '',
prop: 'id',
formatterArgs: {
canDelete: function(row, cellValue) {
return !row.is_default
},
onDelete: function({ row, col, cellValue, reload }) {
const msg = this.$t('xpack.Organization.DeleteOrgMsg')
const title = this.$t('xpack.Organization.DeleteOrgTitle')

View File

@@ -7,7 +7,7 @@ import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage
import Uploadkey from '@/components/UploadKey'
import Select2 from '@/components/Select2'
export default {
name: 'AdminUserCreateUpdate',
name: 'VaultCreate',
components: {
GenericCreateUpdatePage
},

View File

@@ -82,7 +82,7 @@ import * as queryUtil from '@/components/DataTable/compenents/el-data-table/util
import { mapGetters } from 'vuex'
export default {
name: 'Vault',
name: 'VaultList',
components: {
GenericTreeListPage,
AssetUserTable,