fix(项目管理): 修复环境管理切换环境未提示保存&统一样式

This commit is contained in:
xinxin.wu 2024-04-11 12:43:51 +08:00 committed by Craftsman
parent e11d4b631a
commit e98109923b
7 changed files with 80 additions and 33 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<a-tooltip :content="allTagText" :disabled="innerModelValue.length === 0" :mouse-enter-delay="300"> <a-tooltip :content="allTagText" :disabled="(innerModelValue || []).length === 0" :mouse-enter-delay="300">
<div :class="`flex w-full items-center ${props.class}`"> <div :class="`flex w-full items-center ${props.class}`">
<a-input-tag <a-input-tag
v-model:model-value="innerModelValue" v-model:model-value="innerModelValue"

View File

@ -72,7 +72,7 @@ const useProjectEnvStore = defineStore(
projectId: '', projectId: '',
name: '', name: '',
description: '', description: '',
config: envParamsDefaultConfig, config: cloneDeep(envParamsDefaultConfig),
}); });
const allParamDetailInfo = ref<GlobalParams>(); // 全局参数详情 const allParamDetailInfo = ref<GlobalParams>(); // 全局参数详情
const httpNoWarning = ref(true); const httpNoWarning = ref(true);
@ -115,7 +115,9 @@ const useProjectEnvStore = defineStore(
} else if (id !== ALL_PARAM && id) { } else if (id !== ALL_PARAM && id) {
const tmpObj = await getDetailEnv(id); const tmpObj = await getDetailEnv(id);
currentEnvDetailInfo.value = { ...tmpObj }; currentEnvDetailInfo.value = { ...tmpObj };
backupEnvDetailInfo.value = cloneDeep(tmpObj); nextTick(() => {
backupEnvDetailInfo.value = cloneDeep(currentEnvDetailInfo.value);
});
} }
} catch (e) { } catch (e) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@ -67,7 +67,7 @@
const defaultParamItem = { const defaultParamItem = {
key: '', key: '',
paramType: '', paramType: 'CONSTANT',
value: '', value: '',
description: '', description: '',
tags: [], tags: [],

View File

@ -1,8 +1,11 @@
<template> <template>
<div class="flex items-center justify-between"> <div class="grid grid-cols-4">
<div class="col-start-1">
<a-button v-permission="['PROJECT_ENVIRONMENT:READ+UPDATE']" type="outline" @click="handleAdd">{{ <a-button v-permission="['PROJECT_ENVIRONMENT:READ+UPDATE']" type="outline" @click="handleAdd">{{
t('project.environmental.database.addDatabase') t('project.environmental.database.addDatabase')
}}</a-button> }}</a-button>
</div>
<div class="col-end-5 text-right">
<a-input-search <a-input-search
v-model="keyword" v-model="keyword"
class="w-[240px]" class="w-[240px]"
@ -12,6 +15,7 @@
@search="fetchData" @search="fetchData"
></a-input-search> ></a-input-search>
</div> </div>
</div>
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent"> <MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
<template #driverId="{ record }"> <template #driverId="{ record }">
{{ getDriver(record.driverId) }} {{ getDriver(record.driverId) }}

View File

@ -5,7 +5,8 @@
t('project.environmental.httpNoWarning') t('project.environmental.httpNoWarning')
}}</span> }}</span>
</div> </div>
<div class="flex items-center justify-between"> <div class="grid grid-cols-4">
<div class="col-start-1">
<a-button <a-button
v-if="!store.currentEnvDetailInfo.mock" v-if="!store.currentEnvDetailInfo.mock"
v-permission="['PROJECT_ENVIRONMENT:READ+UPDATE']" v-permission="['PROJECT_ENVIRONMENT:READ+UPDATE']"
@ -13,7 +14,9 @@
@click="handleAddHttp" @click="handleAddHttp"
>{{ t('project.environmental.addHttp') }}</a-button >{{ t('project.environmental.addHttp') }}</a-button
> >
<div class="flex flex-row gap-[8px]"> </div>
<div class="col-end-5 flex flex-row gap-[8px]">
<a-input-number <a-input-number
v-model:model-value="form.requestTimeout" v-model:model-value="form.requestTimeout"
:min="0" :min="0"
@ -141,6 +144,7 @@
title: 'project.environmental.http.desc', title: 'project.environmental.http.desc',
dataIndex: 'description', dataIndex: 'description',
showDrag: true, showDrag: true,
showTooltip: true,
}, },
{ {
title: 'project.environmental.http.enableScope', title: 'project.environmental.http.enableScope',

View File

@ -248,6 +248,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { isEqual } from 'lodash-es';
import { VueDraggable } from 'vue-draggable-plus'; import { VueDraggable } from 'vue-draggable-plus';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
@ -274,6 +275,7 @@
listEnv, listEnv,
} from '@/api/modules/project-management/envManagement'; } from '@/api/modules/project-management/envManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useLeaveUnSaveTip from '@/hooks/useLeaveUnSaveTip';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import useProjectEnvStore, { import useProjectEnvStore, {
@ -282,12 +284,18 @@
NEW_ENV_PARAM, NEW_ENV_PARAM,
} from '@/store/modules/setting/useProjectEnvStore'; } from '@/store/modules/setting/useProjectEnvStore';
import { downloadByteFile } from '@/utils'; import { downloadByteFile } from '@/utils';
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
import { EnvListItem, PopVisible } from '@/models/projectManagement/environmental'; import { EnvListItem, PopVisible } from '@/models/projectManagement/environmental';
import { EnvAuthScopeEnum, EnvAuthTypeEnum } from '@/enums/envEnum'; import { EnvAuthScopeEnum, EnvAuthTypeEnum } from '@/enums/envEnum';
import { SortableEvent } from 'sortablejs'; import { SortableEvent } from 'sortablejs';
const { openModal } = useModal();
const { setState } = useLeaveUnSaveTip();
setState(false);
const { t } = useI18n(); const { t } = useI18n();
const store = useProjectEnvStore(); const store = useProjectEnvStore();
@ -530,7 +538,7 @@
function searchData() { function searchData() {
initData(keyword.value); initData(keyword.value);
} }
const { openModal } = useModal();
// //
const handleDeleteEnv = async (id: string) => { const handleDeleteEnv = async (id: string) => {
if (store.currentId === NEW_ENV_PARAM) { if (store.currentId === NEW_ENV_PARAM) {
@ -632,7 +640,29 @@
const handleListItemClick = (element: EnvListItem) => { const handleListItemClick = (element: EnvListItem) => {
const { id } = element; const { id } = element;
//
if (store.currentId !== id) {
if (!hasAnyPermission(['PROJECT_ENVIRONMENT:READ+ADD', 'PROJECT_ENVIRONMENT:READ+UPDATE'])) {
store.setCurrentId(id); store.setCurrentId(id);
return;
}
if (isEqual(store.currentEnvDetailInfo, store.backupEnvDetailInfo)) {
store.setCurrentId(id);
} else {
// tab
openModal({
type: 'warning',
title: t('common.tip'),
content: t('apiTestDebug.unsavedLeave'),
hideCancel: false,
cancelText: t('common.stay'),
okText: t('common.leave'),
onBeforeOk: async () => {
store.setCurrentId(id);
},
});
}
}
}; };
const handleListItemClickGroup = (element: EnvListItem) => { const handleListItemClickGroup = (element: EnvListItem) => {
@ -686,16 +716,21 @@
}; };
function resetHandler() { function resetHandler() {
const unSaveEnv = envList.value.filter((item) => item.id === NEW_ENV_PARAM).length < 2; const unSaveEnv = envList.value.filter((item) => item.id === NEW_ENV_PARAM).length;
// NEW_ENV_PARAMid // @desc: NEW_ENV_PARAM
if (unSaveEnv) { if (unSaveEnv) {
envList.value = envList.value.filter((item: any) => item.id !== NEW_ENV_PARAM); envList.value = envList.value.filter((item: any) => item.id !== NEW_ENV_PARAM);
const excludeMock = envList.value.filter((item) => !item.mock); const excludeMock = envList.value.filter((item) => !item.mock);
// @desc: MOCK
if (showType.value === 'PROJECT' && !excludeMock.length) { if (showType.value === 'PROJECT' && !excludeMock.length) {
store.setCurrentId(ALL_PARAM); store.setCurrentId(ALL_PARAM);
// @desc: MOCKMOCK
} else if (excludeMock.length) { } else if (excludeMock.length) {
store.setCurrentId(excludeMock[0].id); store.setCurrentId(excludeMock[0].id);
} }
// @desc:
} else {
store.initEnvDetail();
} }
} }

View File

@ -19,10 +19,12 @@
<span class="one-line-text mr-1 max-w-[300px] font-medium text-[var(--color-text-000)]">{{ <span class="one-line-text mr-1 max-w-[300px] font-medium text-[var(--color-text-000)]">{{
projectDetail?.name projectDetail?.name
}}</span> }}</span>
<span v-if="!projectDetail?.deleted && projectDetail?.enable" class="button enable-button mr-1">{{ <span
t('project.basicInfo.enable') v-if="!projectDetail?.deleted && projectDetail?.enable"
}}</span> class="button mr-1"
<span v-else class="button delete-button">{{ t('project.basicInfo.deleted') }}</span> :class="[projectDetail?.enable ? 'enable-button' : 'delete-button']"
>{{ projectDetail?.enable ? t('project.basicInfo.enable') : t('project.basicInfo.enable') }}</span
>
</div> </div>
<div class="one-line-text text-xs text-[--color-text-4]">{{ projectDetail?.description }}</div> <div class="one-line-text text-xs text-[--color-text-4]">{{ projectDetail?.description }}</div>
</div> </div>