refactor: 系统和组织的用户组用splitbox重构
This commit is contained in:
parent
61e7c4d197
commit
6aef0347ae
|
@ -47,12 +47,23 @@
|
|||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<div
|
||||
class="fixed bottom-[16px] right-[16px] z-[999] flex justify-between bg-white p-[24px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
|
||||
:style="{ width: props.width }"
|
||||
>
|
||||
<ms-button class="btn" :disabled="!canSave" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
||||
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleSave">{{
|
||||
t('system.userGroup.save')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject, ref, RenderFunction, VNodeChild, watchEffect } from 'vue';
|
||||
import { Message, type TableColumnData, type TableData } from '@arco-design/web-vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
||||
import { getAuthByUserGroup, saveProjectUGSetting } from '@/api/modules/project-management/usergroup';
|
||||
import {
|
||||
getGlobalUSetting,
|
||||
|
@ -84,6 +95,7 @@
|
|||
|
||||
const props = defineProps<{
|
||||
current: CurrentUserGroupItem;
|
||||
width?: string;
|
||||
}>();
|
||||
|
||||
const systemType = inject<AuthScopeEnum>('systemType');
|
||||
|
@ -334,11 +346,6 @@
|
|||
initData(props.current.id, props.current.internal);
|
||||
}
|
||||
});
|
||||
defineExpose({
|
||||
handleReset,
|
||||
handleSave,
|
||||
canSave,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="fade" mode="out-in" appear>
|
||||
<!-- transition内必须有且只有一个根元素,不然会导致二级路由的组件无法渲染 -->
|
||||
<!-- eslint-disable-next-line vue/require-toggle-inside-transition -->
|
||||
<div class="page-content">
|
||||
<component :is="Component" v-if="!route.meta.isCache" :key="route.fullPath" />
|
||||
<keep-alive v-else>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export function addPixelValues(...values: string[]) {
|
||||
const pixelValues = values.filter((v) => v.endsWith('px')).map((v) => parseInt(v, 10));
|
||||
const totalValue = pixelValues.reduce((acc, val) => acc + val, 0);
|
||||
return `${totalValue}px`;
|
||||
}
|
||||
export default {};
|
|
@ -1,14 +1,11 @@
|
|||
<template>
|
||||
<div class="card">
|
||||
<div class="flex h-full flex-row">
|
||||
<div v-if="leftCollapse" class="user-group-left ms-scroll-bar">
|
||||
<MsSplitBox v-model:width="leftWidth" @expand-change="handleCollapse">
|
||||
<template #left>
|
||||
<UserGroupLeft ref="ugLeftRef" @handle-select="handleSelect" @add-user-success="handleAddMember" />
|
||||
</div>
|
||||
<div class="usergroup-collapse" :style="{ left: leftCollapse ? '300px' : '0' }" @click="handleCollapse">
|
||||
<icon-double-left v-if="leftCollapse" class="text-[12px] text-[var(--color-text-brand)]" />
|
||||
<icon-double-right v-else class="text-[12px] text-[var(--color-text-brand)]" />
|
||||
</div>
|
||||
<div class="p-[24px]" :style="{ width: leftCollapse ? 'calc(100% - 300px)' : '100%' }">
|
||||
</template>
|
||||
<template #right>
|
||||
<div class="p-[24px]">
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<a-tooltip :content="currentUserGroupItem.name">
|
||||
<div class="one-line-text max-w-[300px]">{{ currentUserGroupItem.name }}</div>
|
||||
|
@ -22,7 +19,12 @@
|
|||
@press-enter="handleEnter"
|
||||
@search="handleSearch"
|
||||
></a-input-search>
|
||||
<a-radio-group v-if="couldShowUser && couldShowAuth" v-model="currentTable" class="ml-[14px]" type="button">
|
||||
<a-radio-group
|
||||
v-if="couldShowUser && couldShowAuth"
|
||||
v-model="currentTable"
|
||||
class="ml-[14px]"
|
||||
type="button"
|
||||
>
|
||||
<a-radio v-if="couldShowAuth" value="auth">{{ t('system.userGroup.auth') }}</a-radio>
|
||||
<a-radio v-if="couldShowUser" value="user">{{ t('system.userGroup.user') }}</a-radio>
|
||||
</a-radio-group>
|
||||
|
@ -35,20 +37,15 @@
|
|||
:keyword="currentKeyword"
|
||||
:current="currentUserGroupItem"
|
||||
/>
|
||||
<AuthTable v-if="currentTable === 'auth' && couldShowAuth" ref="authRef" :current="currentUserGroupItem" />
|
||||
<AuthTable
|
||||
v-if="currentTable === 'auth' && couldShowAuth"
|
||||
:current="currentUserGroupItem"
|
||||
:width="bottomWidth"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="currentTable === 'auth'"
|
||||
class="fixed bottom-[16px] right-[16px] z-[999] flex justify-between bg-white p-[24px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
|
||||
:style="{ width: `calc(100% - ${menuWidth + 16}px)` }"
|
||||
>
|
||||
<ms-button class="btn" :disabled="!canSave" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
||||
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleSave">{{
|
||||
t('system.userGroup.save')
|
||||
}}</a-button>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -58,13 +55,14 @@
|
|||
*/
|
||||
import { computed, nextTick, onMounted, provide, ref, watchEffect } from 'vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||
import AuthTable from '@/components/business/ms-user-group-comp/authTable.vue';
|
||||
import UserGroupLeft from '@/components/business/ms-user-group-comp/msUserGroupLeft.vue';
|
||||
import UserTable from '@/components/business/ms-user-group-comp/userTable.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import { addPixelValues } from '@/utils/css';
|
||||
|
||||
import { CurrentUserGroupItem } from '@/models/setting/usergroup';
|
||||
import { AuthScopeEnum } from '@/enums/commonEnum';
|
||||
|
@ -72,7 +70,6 @@
|
|||
// 注入系统层级
|
||||
provide('systemType', AuthScopeEnum.ORGANIZATION);
|
||||
const currentTable = ref('user');
|
||||
const leftCollapse = ref(true);
|
||||
|
||||
const { t } = useI18n();
|
||||
const currentKeyword = ref('');
|
||||
|
@ -83,13 +80,17 @@
|
|||
type: AuthScopeEnum.ORGANIZATION,
|
||||
internal: true,
|
||||
});
|
||||
const authRef = ref<{
|
||||
handleReset: () => void;
|
||||
handleSave: () => void;
|
||||
canSave: boolean;
|
||||
}>();
|
||||
const userRef = ref();
|
||||
const appStore = useAppStore();
|
||||
const leftCollapse = ref(true);
|
||||
const leftWidth = ref('300px');
|
||||
const bottomWidth = computed(() => {
|
||||
const width = appStore.menuCollapse ? '86px' : `${appStore.menuWidth}px`;
|
||||
if (leftCollapse.value) {
|
||||
return `calc(100% - ${addPixelValues(width, leftWidth.value, '20px')})`;
|
||||
}
|
||||
return `calc(100% - ${addPixelValues(width, '16px')})`;
|
||||
});
|
||||
|
||||
const tableSearch = () => {
|
||||
if (currentTable.value === 'user' && userRef.value) {
|
||||
|
@ -112,44 +113,24 @@
|
|||
|
||||
const couldShowUser = computed(() => currentUserGroupItem.value.type === AuthScopeEnum.ORGANIZATION);
|
||||
const couldShowAuth = computed(() => currentUserGroupItem.value.id !== 'admin');
|
||||
|
||||
const handleSelect = (item: CurrentUserGroupItem) => {
|
||||
currentUserGroupItem.value = item;
|
||||
};
|
||||
|
||||
const handleCollapse = () => {
|
||||
leftCollapse.value = !leftCollapse.value;
|
||||
if (leftCollapse.value) {
|
||||
const handleCollapse = (collapse: boolean) => {
|
||||
leftCollapse.value = collapse;
|
||||
if (collapse) {
|
||||
leftWidth.value = '300px';
|
||||
nextTick(() => {
|
||||
ugLeftRef.value?.initData(currentUserGroupItem.value.id);
|
||||
});
|
||||
}
|
||||
};
|
||||
const menuWidth = computed(() => {
|
||||
const width = appStore.menuCollapse ? 86 : appStore.menuWidth;
|
||||
if (leftCollapse.value) {
|
||||
return width + 300;
|
||||
}
|
||||
return width;
|
||||
});
|
||||
const handleSelect = (item: CurrentUserGroupItem) => {
|
||||
currentUserGroupItem.value = item;
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
authRef.value?.handleReset();
|
||||
};
|
||||
const handleSave = () => {
|
||||
authRef.value?.handleSave();
|
||||
};
|
||||
const handleAddMember = (id: string) => {
|
||||
if (id === currentUserGroupItem.value.id) {
|
||||
tableSearch();
|
||||
}
|
||||
};
|
||||
const canSave = computed(() => {
|
||||
if (currentTable.value === 'auth') {
|
||||
return authRef.value?.canSave;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (!couldShowAuth.value) {
|
||||
currentTable.value = 'user';
|
||||
|
@ -173,27 +154,4 @@
|
|||
border-radius: var(--border-radius-large);
|
||||
box-shadow: 0 0 10px rgb(120 56 135 / 5%);
|
||||
}
|
||||
.user-group-left {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-right: 6px;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--color-border-1);
|
||||
}
|
||||
.usergroup-collapse {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
z-index: 101;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 36px;
|
||||
background-color: var(--color-text-n8);
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="card">
|
||||
<MsSplitBox @expand-change="handleCollapse">
|
||||
<MsSplitBox v-model:width="leftWidth" @expand-change="handleCollapse">
|
||||
<template #left>
|
||||
<UserGroupLeft ref="ugLeftRef" @handle-select="handleSelect" @add-user-success="handleAddMember" />
|
||||
</template>
|
||||
|
@ -37,22 +37,16 @@
|
|||
:keyword="currentKeyword"
|
||||
:current="currentUserGroupItem"
|
||||
/>
|
||||
<AuthTable v-if="currentTable === 'auth' && couldShowAuth" ref="authRef" :current="currentUserGroupItem" />
|
||||
<AuthTable
|
||||
v-if="currentTable === 'auth' && couldShowAuth"
|
||||
:current="currentUserGroupItem"
|
||||
:width="bottomWidth"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
</div>
|
||||
<div
|
||||
v-if="currentTable === 'auth'"
|
||||
class="fixed bottom-[16px] right-[16px] z-[999] flex justify-between bg-white p-[24px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
|
||||
:style="{ width: `calc(100% - ${menuWidth + 16}px)` }"
|
||||
>
|
||||
<ms-button class="btn" :disabled="!canSave" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
||||
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleSave">{{
|
||||
t('system.userGroup.save')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -61,7 +55,6 @@
|
|||
*/
|
||||
import { computed, nextTick, onMounted, provide, ref, watchEffect } from 'vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||
import AuthTable from '@/components/business/ms-user-group-comp/authTable.vue';
|
||||
import UserGroupLeft from '@/components/business/ms-user-group-comp/msUserGroupLeft.vue';
|
||||
|
@ -69,6 +62,7 @@
|
|||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import { addPixelValues } from '@/utils/css';
|
||||
|
||||
import { CurrentUserGroupItem } from '@/models/setting/usergroup';
|
||||
import { AuthScopeEnum } from '@/enums/commonEnum';
|
||||
|
@ -79,6 +73,7 @@
|
|||
const { t } = useI18n();
|
||||
const currentKeyword = ref('');
|
||||
const ugLeftRef = ref();
|
||||
|
||||
const currentUserGroupItem = ref<CurrentUserGroupItem>({
|
||||
id: '',
|
||||
name: '',
|
||||
|
@ -86,15 +81,17 @@
|
|||
internal: true,
|
||||
});
|
||||
|
||||
const leftCollapse = ref(true);
|
||||
|
||||
const authRef = ref<{
|
||||
handleReset: () => void;
|
||||
handleSave: () => void;
|
||||
canSave: boolean;
|
||||
}>();
|
||||
const userRef = ref();
|
||||
const appStore = useAppStore();
|
||||
const leftCollapse = ref(true);
|
||||
const leftWidth = ref('300px');
|
||||
const bottomWidth = computed(() => {
|
||||
const width = appStore.menuCollapse ? '86px' : `${appStore.menuWidth}px`;
|
||||
if (leftCollapse.value) {
|
||||
return `calc(100% - ${addPixelValues(width, leftWidth.value, '20px')})`;
|
||||
}
|
||||
return `calc(100% - ${addPixelValues(width, '16px')})`;
|
||||
});
|
||||
|
||||
const tableSearch = () => {
|
||||
if (currentTable.value === 'user' && userRef.value) {
|
||||
|
@ -128,32 +125,14 @@
|
|||
const couldShowUser = computed(() => currentUserGroupItem.value.type === AuthScopeEnum.SYSTEM);
|
||||
const couldShowAuth = computed(() => currentUserGroupItem.value.id !== 'admin');
|
||||
const handleCollapse = (collapse: boolean) => {
|
||||
leftCollapse.value = collapse;
|
||||
if (collapse) {
|
||||
leftWidth.value = '300px';
|
||||
nextTick(() => {
|
||||
ugLeftRef.value?.initData(currentUserGroupItem.value.id);
|
||||
});
|
||||
}
|
||||
};
|
||||
const menuWidth = computed(() => {
|
||||
const width = appStore.menuCollapse ? 86 : appStore.menuWidth;
|
||||
if (leftCollapse.value) {
|
||||
return width + 300;
|
||||
}
|
||||
return width;
|
||||
});
|
||||
|
||||
const handleReset = () => {
|
||||
authRef.value?.handleReset();
|
||||
};
|
||||
const handleSave = () => {
|
||||
authRef.value?.handleSave();
|
||||
};
|
||||
const canSave = computed(() => {
|
||||
if (currentTable.value === 'auth') {
|
||||
return authRef.value?.canSave;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (!couldShowAuth.value) {
|
||||
currentTable.value = 'user';
|
||||
|
@ -177,28 +156,4 @@
|
|||
border-radius: var(--border-radius-large);
|
||||
box-shadow: 0 0 10px rgb(120 56 135 / 5%);
|
||||
}
|
||||
.user-group-left {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 24px;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--color-border-1);
|
||||
}
|
||||
.usergroup-collapse {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
z-index: 101;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 36px;
|
||||
background-color: var(--color-text-n8);
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue