perf: move to roles manage to form

This commit is contained in:
ibuler
2025-02-06 19:18:16 +08:00
parent 5f35e0bb94
commit 8019ee550e
8 changed files with 126 additions and 38 deletions

View File

@@ -75,7 +75,7 @@
v-bind="{...cleanButtonAction(action), icon: ''}"
@click="handleClick(action)"
>
<el-tooltip :content="action.tip" :disabled="!action.tip" :open-delay="500" placement="top">
<el-tooltip :content="action.tip" :disabled="!action.tip" placement="top">
<span>
<span v-if="action.icon" style="vertical-align: initial">
<Icon :icon="action.icon" />

View File

@@ -8,18 +8,20 @@
v-bind="data.attrs"
>
<template v-if="data.label" #label>
<span :title="data.label">{{ data.label }}</span>
<el-tooltip
v-if="data.helpTip"
:open-delay="500"
:tabindex="-1"
effect="dark"
placement="right"
popper-class="help-tips"
>
<div slot="content" v-sanitize="data.helpTip" /> <!-- Noncompliant -->
<i class="fa fa-question-circle-o help-tip-icon" />
</el-tooltip>
<span :title="data.label">
{{ data.label }}
<el-tooltip
v-if="data.helpTip"
:open-delay="500"
:tabindex="-1"
effect="dark"
placement="right"
popper-class="help-tips"
>
<div slot="content" v-sanitize="data.helpTip" /> <!-- Noncompliant -->
<i class="fa fa-question-circle-o help-tip-icon" />
</el-tooltip>
</span>
</template>
<template v-if="readonly && hasReadonlyContent">
<div
@@ -100,6 +102,9 @@
</el-alert>
<span v-else v-sanitize="data.helpText" />
</div>
<div v-if="data.helpTextFormatter" class="help-block">
<RenderHelpTextSafe :render-content="data.helpTextFormatter" />
</div>
</el-form-item>
</template>
<script>
@@ -122,6 +127,18 @@ function validator(data) {
export default {
components: {
RenderHelpTextSafe: {
functional: true,
props: {
renderContent: {
type: Function,
required: true
}
},
render(h, { props }) {
return props.renderContent()
}
},
/**
* 🐂🍺只需要有组件选项对象,就可以立刻包装成函数式组件在 template 中使用
* FYI: https://cn.vuejs.org/v2/guide/render-function.html#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BB%84%E4%BB%B6

View File

@@ -50,6 +50,10 @@ export default {
},
computed: {
drawerSize() {
const drawerWidth = localStorage.getItem('drawerWidth')
if (drawerWidth && drawerWidth > 100 && drawerWidth < 2000) {
return drawerWidth + 'px'
}
const width = window.innerWidth
if (width >= 800) return '767px'
return '90%'

View File

@@ -20,6 +20,7 @@ Vue.directive('el-drawer-drag-width', {
// 宽度不能大于浏览器宽度 80%,不能小于宽度的 20%
realWidth = realWidth > width80 ? width80 : realWidth < width30 ? width30 : realWidth
drawerEle.style.width = realWidth + 'px'
localStorage.setItem('drawerWidth', realWidth)
}
document.onmouseup = function(e) {
// 拖拽时结束时,取消禁用文本选中

View File

@@ -8,6 +8,18 @@
size="600px"
top="1vh"
>
<template #title>
<div class="drawer-title">
<span>{{ $tc('SelectPlatform') }}</span>
<el-link
type="text"
size="small"
@click="handleManagePlatform"
>
<i class="fa fa-cog" /> {{ $tc('PlatformManage') }}
</el-link>
</div>
</template>
<div v-loading="loading" class="platform-content">
<el-row :gutter="20">
<el-collapse v-model="activeType" accordion>
@@ -47,7 +59,6 @@ import { loadPlatformIcon } from '@/utils/jms'
export default {
name: 'PlatformDrawer',
components: {},
props: {
visible: {
type: Boolean,
@@ -138,6 +149,10 @@ export default {
handleSelect(platform) {
this.$store.dispatch('assets/addToRecentPlatforms', platform)
this.$emit('select-platform', platform)
},
handleManagePlatform() {
this.$router.push({ name: 'PlatformList' })
this.iVisible = false
}
}
}
@@ -212,4 +227,16 @@ export default {
text-overflow: ellipsis;
white-space: nowrap;
}
.drawer-title {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding-right: 40px;
.el-link {
margin-left: 15px;
}
}
</style>

View File

@@ -21,6 +21,7 @@ export default {
GenericCreateUpdatePage
},
data() {
const roleManage = this.$t('RoleManage')
return {
loading: true,
initial: {
@@ -134,6 +135,16 @@ export default {
component: Select2,
label: this.$t('OrgRoles'),
rules: this.$store.getters.currentOrgIsRoot ? [] : [rules.RequiredChange],
helpTextFormatter: () => {
const handleClick = () => {
window.open('/settings/roles', '_blank')
}
return (
<el-link onClick={handleClick}>
<i class='fa fa-external-link'></i> {roleManage}
</el-link>
)
},
el: {
multiple: true,
ajax: {
@@ -198,15 +209,40 @@ export default {
computed: {
...mapGetters(['currentOrgIsRoot', 'currentUser'])
},
async mounted() {
mounted() {
if (this.currentOrgIsRoot) {
this.fieldsMeta.groups.el.disabled = true
}
await this.setDefaultRoles()
this.setDefaultRoles()
this.disableMFAFieldIfNeed(null)
this.loading = false
this.initRoleManagementLink()
},
methods: {
initRoleManagementLink() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
const gotoRoleElement = document.querySelector('.goto-role')
if (gotoRoleElement) {
const handleClick = () => {
this.$router.push({ path: '/settings/roles' })
}
gotoRoleElement.addEventListener('click', handleClick)
this.$once('hook:beforeDestroy', () => {
gotoRoleElement.removeEventListener('click', handleClick)
observer.disconnect()
})
observer.disconnect()
}
}
})
})
observer.observe(document.body, {
childList: true,
subtree: true
})
},
afterGetUser(user) {
this.user = user
if (this.user.id === this.currentUser.id) {

View File

@@ -238,18 +238,18 @@ export default {
callback: () => {
this.InviteDialogSetting.InviteDialogVisible = true
}
},
{
name: this.$t('Roles'),
title: this.$t('Roles'),
has: () => {
return this.publicSettings.XPACK_LICENSE_IS_VALID &&
this.$hasPerm(['rbac.view_orgrole | rbac.view_systemrole'],)
},
callback: () => {
this.$router.push({ name: 'RoleList' })
}
}
// {
// name: this.$t('Roles'),
// title: this.$t('Roles'),
// has: () => {
// return this.publicSettings.XPACK_LICENSE_IS_VALID &&
// this.$hasPerm(['rbac.view_orgrole | rbac.view_systemrole'],)
// },
// callback: () => {
// this.$router.push({ name: 'RoleList' })
// }
// }
],
hasBulkUpdate: true,
canBulkUpdate: ({ selectedRows }) => {

View File

@@ -43,6 +43,9 @@ module.exports = {
warnings: false,
errors: true
},
watchOptions: {
aggregateTimeout: 2000
},
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
@@ -94,7 +97,7 @@ module.exports = {
elementLocale: resolve('node_modules/element-ui/lib/locale/lang/en.js')
},
extensions: ['.vue', '.js', '.json']
},
}
},
chainWebpack(config) {
// it can improve the speed of the first screen, it is recommended to turn on preload
@@ -148,16 +151,16 @@ module.exports = {
config
.when(process.env.NODE_ENV === 'production', config => {
config
.plugin('CompressionWebpackPlugin')
.use(CompressionWebpackPlugin, [
{
algorithm: 'gzip',
test: productionGzipExtensions, // 处理所有匹配此 {RegExp} 的资源
threshold: 10240, // 只处理比这个值大的资源。按字节计算(楼主设置10K以上进行压缩)
minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
cache: false
}
])
.plugin('CompressionWebpackPlugin')
.use(CompressionWebpackPlugin, [
{
algorithm: 'gzip',
test: productionGzipExtensions, // 处理所有匹配此 {RegExp} 的资源
threshold: 10240, // 只处理比这个值大的资源。按字节计算(楼主设置10K以上进行压缩)
minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
cache: false
}
])
})
config