fix(系统设置): 修复用户组页面bug'

This commit is contained in:
RubyLiu 2023-08-31 17:30:42 +08:00 committed by fit2-zhao
parent fdbe2d1796
commit 357d8df26e
13 changed files with 188 additions and 154 deletions

View File

@ -78,6 +78,8 @@ body {
font-size: 12px; font-size: 12px;
color: rgb(var(--color-text-4)); color: rgb(var(--color-text-4));
} }
/* 单航文本缩略 */
.one-line-text { .one-line-text {
@apply overflow-hidden overflow-ellipsis whitespace-nowrap; @apply overflow-hidden overflow-ellipsis whitespace-nowrap;
} }

View File

@ -1,14 +1,14 @@
<template> <template>
<MsPopconfirm <MsPopconfirm
:ok-text="t('common.remove')"
:cancel-text="t('common.cancel')"
type="error" type="error"
:title="props.title" :title="props.title"
:sub-title-tip="props.subTitleTip" :sub-title-tip="props.subTitleTip"
:loading="props.loading" :loading="props.loading"
:visible="currentVisible"
@confirm="handleOk" @confirm="handleOk"
@cancel="handleCancel"
> >
<MsButton>{{ t('common.remove') }}</MsButton> <MsButton @click="showPopover">{{ t('common.remove') }}</MsButton>
</MsPopconfirm> </MsPopconfirm>
</template> </template>
@ -16,6 +16,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
import MsPopconfirm from '@/components/pure/ms-popconfirm/index.vue'; import MsPopconfirm from '@/components/pure/ms-popconfirm/index.vue';
import { ref } from 'vue';
const props = defineProps<{ const props = defineProps<{
title: string; title: string;
@ -27,9 +28,17 @@
(e: 'ok'): void; (e: 'ok'): void;
}>(); }>();
const { t } = useI18n();
const currentVisible = ref(false);
const handleOk = () => { const handleOk = () => {
emit('ok'); emit('ok');
}; };
const handleCancel = () => {
currentVisible.value = false;
};
const { t } = useI18n(); const showPopover = () => {
currentVisible.value = true;
};
</script> </script>

View File

@ -1,38 +1,48 @@
<template> <template>
<a-popconfirm <a-popover v-bind="attrs" :type="props.type" :popup-visible="currentVisible" class="w-[352px]" trigger="click">
v-bind="attrs"
:type="props.type"
class="w-[352px]"
:ok-loading="props.loading"
@before-ok="handleConfirm"
>
<template v-if="props.type === 'error'" #icon>
<MsIcon type="icon-icon_warning_filled" class="mr-[2px] text-xl text-[rgb(var(--danger-6))]" />
</template>
<slot v-if="props.type !== 'error'" name="icon"></slot>
<template #content> <template #content>
<span class="font-semibold"> <div class="flex flex-row flex-nowrap items-center">
{{ props.title }} <slot name="icon">
</span> <MsIcon type="icon-icon_warning_filled" class="mr-[2px] text-xl text-[rgb(var(--danger-6))]" />
<div class="py-2 text-sm leading-6 text-[var(--color-text-2)]"> </slot>
<span class="ml-2 font-semibold">
{{ props.title }}
</span>
</div>
<div class="ml-8 mt-2 text-sm text-[var(--color-text-2)]">
{{ props.subTitleTip }} {{ props.subTitleTip }}
</div> </div>
<div class="mt-4 flex flex-row flex-nowrap justify-end gap-2">
<a-button type="secondary" size="mini" :disabled="props.loading" @click="handleCancel">
{{ props.cancelText || t('common.cancel') }}
</a-button>
<a-button type="primary" size="mini" :loading="props.loading" @click="handleConfirm">
{{ props.okText || t('common.remove') }}
</a-button>
</div>
</template> </template>
<slot></slot> <slot></slot>
</a-popconfirm> </a-popover>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useAttrs } from 'vue'; import { useI18n } from '@/hooks/useI18n';
import { ref, useAttrs, watchEffect } from 'vue';
export type types = 'error' | 'info' | 'success' | 'warning'; export type types = 'error' | 'info' | 'success' | 'warning';
const { t } = useI18n();
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
title: string; title: string;
subTitleTip: string; subTitleTip: string;
type: types; type: types;
loading?: boolean; loading?: boolean;
okText?: string;
cancelText?: string;
visible?: boolean;
}>(), }>(),
{ {
type: 'warning', type: 'warning',
@ -40,11 +50,23 @@
); );
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'confirm'): void; (e: 'confirm'): void;
(e: 'cancel'): void;
}>(); }>();
const currentVisible = ref(props.visible || false);
const attrs = useAttrs(); const attrs = useAttrs();
const handleConfirm = () => { const handleConfirm = () => {
emits('confirm'); emits('confirm');
}; };
const handleCancel = () => {
emits('cancel');
};
watchEffect(() => {
currentVisible.value = props.visible;
});
</script> </script>
<style scoped lang="less"></style> <style scoped lang="less"></style>

View File

@ -13,7 +13,7 @@
</div> </div>
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> <MsBaseTable v-bind="propsRes" v-on="propsEvent">
<template #name="{ record }"> <template #name="{ record }">
<span class="overflow-hidden text-ellipsis whitespace-nowrap">{{ record.name }}</span> <span class="one-text-line">{{ record.name }}</span>
<a-tooltip background-color="#FFFFFF"> <a-tooltip background-color="#FFFFFF">
<template #content> <template #content>
<span class="text-[var(--color-text-1)]">{{ t('system.project.revokeDeleteToolTip') }}</span> <span class="text-[var(--color-text-1)]">{{ t('system.project.revokeDeleteToolTip') }}</span>

View File

@ -1,80 +1,78 @@
<template> <template>
<div class="user-group-left"> <a-input-search
<a-input-search class="w-[252px]"
class="w-[252px]" :placeholder="t('system.userGroup.searchHolder')"
:placeholder="t('system.userGroup.searchHolder')" allow-clear
allow-clear @press-enter="enterData"
@press-enter="enterData" @search="searchData"
@search="searchData" />
/> <div class="mt-2 flex flex-col">
<div class="mt-2 flex flex-col"> <div class="flex h-[38px] items-center px-[8px] leading-[24px]">
<div class="flex h-[38px] items-center px-[8px] leading-[24px]"> <div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div>
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div> </div>
</div> <div>
<div> <div
<div v-for="element in globalUserGroupList"
v-for="element in globalUserGroupList" :key="element.id"
:key="element.id" class="flex h-[38px] cursor-pointer items-center px-[8px]"
class="flex h-[38px] cursor-pointer items-center px-[8px]" :class="{
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId,
'bg-[rgb(var(--primary-1))]': element.id === currentId, }"
}" @click="handleListItemClick(element)"
@click="handleListItemClick(element)" >
> <div class="flex flex-row flex-nowrap">
<div class="flex grow flex-row"> <div class="one-line-text max-w-[156px] text-[var(--color-text-1)]">{{ element.name }}</div>
<div class="leading-[24px] text-[var(--color-text-1)]"> <div v-if="element.type" class="text-[var(--color-text-4)]"
<span class="text-[var(--color-text-1)]">{{ element.name }}</span> >{{ t(`system.userGroup.${element.type}`) }}</div
<span v-if="element.type" class="text-[var(--color-text-4)]" >
>{{ t(`system.userGroup.${element.type}`) }}</span
>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<a-divider class="mt-2" /> </div>
<div class="mt-2 flex flex-col"> <a-divider class="mt-2" />
<AddOrUpdateUserGroupPopup <div class="mt-2 flex flex-col">
:visible="addUserGroupVisible" <AddOrUpdateUserGroupPopup
:list="customUserGroupList" :visible="addUserGroupVisible"
@cancel="handleAddUserGroupCancel" :list="customUserGroupList"
@search="initData" @cancel="handleAddUserGroupCancel"
@search="initData"
>
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]">
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.custom') }}</div>
<div class="cursor-pointer text-[rgb(var(--primary-5))]"
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup"
/></div>
</div>
</AddOrUpdateUserGroupPopup>
<div>
<div
v-for="element in customUserGroupList"
:key="element.id"
class="flex h-[38px] cursor-pointer items-center"
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
@click="handleListItemClick(element)"
> >
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]"> <AddOrUpdateUserGroupPopup
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.custom') }}</div> :id="element.id"
<div class="cursor-pointer text-[rgb(var(--primary-5))]" :visible="popVisible[element.id]"
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup" :default-name="popDefaultName"
/></div> :list="customUserGroupList"
</div> @cancel="() => handlePopConfirmCancel(element.id)"
</AddOrUpdateUserGroupPopup>
<div>
<div
v-for="element in customUserGroupList"
:key="element.id"
class="flex h-[38px] cursor-pointer items-center px-[8px]"
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
@click="handleListItemClick(element)"
> >
<AddOrUpdateUserGroupPopup <div class="flex grow flex-row justify-between px-[8px]">
:id="element.id" <a-tooltip :content="element.name">
:visible="popVisible[element.id]" <div class="flex flex-row flex-nowrap">
:default-name="popDefaultName" <div class="one-line-text max-w-[156px] text-[var(--color-text-1)]">{{ element.name }}</div>
:list="customUserGroupList" <div v-if="element.type" class="text-[var(--color-text-4)]"
@cancel="() => handlePopConfirmCancel(element.id)" >{{ t(`system.userGroup.${element.type}`) }}</div
>
<div class="flex grow flex-row justify-between">
<div class="leading-[24px] text-[var(--color-text-1)]">
<span class="text-[var(--color-text-1)]">{{ element.name }}</span>
<span v-if="element.type" class="text-[var(--color-text-4)]"
>{{ t(`system.userGroup.${element.type}`) }}</span
> >
</div> </div>
<div v-if="element.id === currentId && !element.internal"> </a-tooltip>
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" /> <div v-if="element.id === currentId && !element.internal">
</div> <MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
</div> </div>
</AddOrUpdateUserGroupPopup> </div>
</div> </AddOrUpdateUserGroupPopup>
</div> </div>
</div> </div>
</div> </div>

View File

@ -10,7 +10,9 @@
</div> </div>
<div class="relative w-[100%] overflow-x-scroll p-[24px]"> <div class="relative w-[100%] overflow-x-scroll p-[24px]">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="title">{{ store.userGroupInfo.currentName }}</div> <a-tooltip :content="store.userGroupInfo.currentName">
<div class="one-line-text max-w-[300px]">{{ store.userGroupInfo.currentName }}</div>
</a-tooltip>
<div class="flex items-center"> <div class="flex items-center">
<a-input-search <a-input-search
v-if="currentTable === 'user'" v-if="currentTable === 'user'"

View File

@ -1,7 +1,7 @@
<template> <template>
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> <MsBaseTable v-bind="propsRes" v-on="propsEvent">
<template #name="{ record }"> <template #name="{ record }">
<span class="overflow-hidden text-ellipsis whitespace-nowrap">{{ record.name }}</span> <span class="one-text-line">{{ record.name }}</span>
<a-tooltip background-color="#FFFFFF"> <a-tooltip background-color="#FFFFFF">
<template #content> <template #content>
<span class="text-[var(--color-text-1)]">{{ t('system.organization.revokeDeleteToolTip') }}</span> <span class="text-[var(--color-text-1)]">{{ t('system.organization.revokeDeleteToolTip') }}</span>

View File

@ -1,7 +1,7 @@
<template> <template>
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> <MsBaseTable v-bind="propsRes" v-on="propsEvent">
<template #name="{ record }"> <template #name="{ record }">
<span class="overflow-hidden text-ellipsis whitespace-nowrap">{{ record.name }}</span> <span class="one-text-line">{{ record.name }}</span>
<a-tooltip background-color="#FFFFFF"> <a-tooltip background-color="#FFFFFF">
<template #content> <template #content>
<span class="text-[var(--color-text-1)]">{{ t('system.project.revokeDeleteToolTip') }}</span> <span class="text-[var(--color-text-1)]">{{ t('system.project.revokeDeleteToolTip') }}</span>

View File

@ -53,6 +53,18 @@
const projectTabeRef = ref(); const projectTabeRef = ref();
const projectVisible = ref(false); const projectVisible = ref(false);
//
const initOrgAndProjectCount = async () => {
try {
const res = await getOrgAndProjectCount();
organizationCount.value = res.organizationTotal;
projectCount.value = res.projectTotal;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
const tableSearch = () => { const tableSearch = () => {
if (currentTable.value === 'organization') { if (currentTable.value === 'organization') {
if (orgTableRef.value) { if (orgTableRef.value) {
@ -69,6 +81,7 @@
projectTabeRef.value?.fetchData(); projectTabeRef.value?.fetchData();
}); });
} }
initOrgAndProjectCount();
}; };
const handleSearch = (value: string) => { const handleSearch = (value: string) => {
@ -95,18 +108,6 @@
organizationVisible.value = false; organizationVisible.value = false;
}; };
//
const initOrgAndProjectCount = async () => {
try {
const res = await getOrgAndProjectCount();
organizationCount.value = res.organizationTotal;
projectCount.value = res.projectTotal;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
watch( watch(
() => currentTable.value, () => currentTable.value,
() => { () => {

View File

@ -85,6 +85,8 @@
currentVisible.value = props.visible; currentVisible.value = props.visible;
}); });
const handleCancel = (shouldSearch: boolean) => { const handleCancel = (shouldSearch: boolean) => {
form.name = '';
form.type = '';
emit('cancel', shouldSearch); emit('cancel', shouldSearch);
}; };

View File

@ -1,49 +1,49 @@
<template> <template>
<div class="user-group-left"> <a-input-search
<a-input-search allow-clear
allow-clear class="w-[252px]"
class="w-[252px]" :placeholder="t('system.userGroup.searchHolder')"
:placeholder="t('system.userGroup.searchHolder')" @press-enter="enterData"
@press-enter="enterData" @search="searchData"
@search="searchData" />
/> <div class="mt-2 flex flex-col">
<div class="mt-2 flex flex-col"> <div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]">
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]"> <div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div>
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div> <div class="cursor-pointer text-[rgb(var(--primary-5))]"
<div class="cursor-pointer text-[rgb(var(--primary-5))]" ><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup"
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup" /></div>
/></div> </div>
</div> <div>
<div> <div
<div v-for="element in userGroupList"
v-for="element in userGroupList" :key="element.id"
:key="element.id" class="flex h-[38px] cursor-pointer items-center"
class="flex h-[38px] cursor-pointer items-center px-[8px]" :class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }" @click="handleListItemClick(element)"
@click="handleListItemClick(element)" >
<popconfirm
:visible="popVisible[element.id]"
:loading="popLoading[element.id]"
:type="popType"
:default-name="popDefaultName"
:list="userGroupList"
@cancel="() => handlePopConfirmCancel(element.id)"
@submit="(value: CustomMoreActionItem) => handlePopConfirmSubmit(value,element.id)"
> >
<popconfirm <div class="flex grow flex-row justify-between px-[8px]">
:visible="popVisible[element.id]" <a-tooltip :content="element.name">
:loading="popLoading[element.id]" <div class="flex flex-row flex-nowrap">
:type="popType" <div class="one-line-text max-w-[156px] text-[var(--color-text-1)]">{{ element.name }}</div>
:default-name="popDefaultName" <div v-if="element.type" class="text-[var(--color-text-4)]"
:list="userGroupList" >{{ t(`system.userGroup.${element.type}`) }}</div
@cancel="() => handlePopConfirmCancel(element.id)"
@submit="(value: CustomMoreActionItem) => handlePopConfirmSubmit(value,element.id)"
>
<div class="draglist-item flex grow flex-row justify-between">
<div class="leading-[24px] text-[var(--color-text-1)]">
<span class="text-[var(--color-text-1)]">{{ element.name }}</span>
<span v-if="element.type" class="text-[var(--color-text-4)]"
>{{ t(`system.userGroup.${element.type}`) }}</span
> >
</div> </div>
<div v-if="element.id === currentId && !element.internal"> </a-tooltip>
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" /> <div v-if="element.id === currentId && !element.internal">
</div> <MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
</div> </div>
</popconfirm> </div>
</div> </popconfirm>
</div> </div>
</div> </div>
</div> </div>

View File

@ -18,7 +18,7 @@
<div class="title">{{ message.title }}</div> <div class="title">{{ message.title }}</div>
</a-form-item> </a-form-item>
<a-form-item field="name" :rules="[{ validator: validateName }]"> <a-form-item field="name" :rules="[{ validator: validateName }]">
<a-input v-if="props.type === 'rename'" v-model="form.name" class="w-[245px]" /> <a-input v-if="props.type === 'rename'" v-model="form.name" class="w-[234px]" />
<a-select v-else v-model="form.name" class="w-[176px]"> <a-select v-else v-model="form.name" class="w-[176px]">
<a-option value="SYSTEM">{{ t('system.userGroup.SYSTEM') }}</a-option> <a-option value="SYSTEM">{{ t('system.userGroup.SYSTEM') }}</a-option>
<a-option value="ORGANIZATION">{{ t('system.userGroup.ORGANIZATION') }}</a-option> <a-option value="ORGANIZATION">{{ t('system.userGroup.ORGANIZATION') }}</a-option>

View File

@ -10,7 +10,9 @@
</div> </div>
<div class="relative w-[100%] overflow-x-scroll p-[24px]"> <div class="relative w-[100%] overflow-x-scroll p-[24px]">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="title">{{ store.userGroupInfo.currentName }}</div> <a-tooltip :content="store.userGroupInfo.currentName">
<div class="one-line-text max-w-[300px]">{{ store.userGroupInfo.currentName }}</div>
</a-tooltip>
<div class="flex items-center"> <div class="flex items-center">
<a-input-search <a-input-search
v-if="currentTable === 'user'" v-if="currentTable === 'user'"
@ -127,14 +129,10 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.title {
color: var(--color-text-1);
}
.user-group {
height: calc(100vh - 72px);
}
.user-group-left { .user-group-left {
position: relative; position: relative;
width: 300px;
height: calc(100vh - 125px);
border-right: 1px solid var(--color-border); border-right: 1px solid var(--color-border);
.usergroup-collapse { .usergroup-collapse {
position: absolute; position: absolute;