feat(项目管理): 菜单管理前端修改

This commit is contained in:
RubyLiu 2023-10-12 19:37:01 +08:00 committed by 刘瑞斌
parent 26e0691216
commit 074effb40c
12 changed files with 171 additions and 35 deletions

View File

@ -4,4 +4,5 @@
/node_modules/** /node_modules/**
**/*.svg **/*.svg
**/*.sh **/*.sh
src/auto-imports.js

View File

@ -30,7 +30,7 @@ export function postUpdateMenu(data: MenuTableListParams) {
suffix = 'test-plan'; suffix = 'test-plan';
break; break;
case MenuEnum.bugManagement: case MenuEnum.bugManagement:
suffix = 'issue'; suffix = 'bug';
break; break;
case MenuEnum.caseManagement: case MenuEnum.caseManagement:
suffix = 'case'; suffix = 'case';
@ -58,7 +58,7 @@ export function getConfigByMenuItem(data: MenuTableListParams) {
suffix = 'test-plan'; suffix = 'test-plan';
break; break;
case MenuEnum.bugManagement: case MenuEnum.bugManagement:
suffix = 'issue'; suffix = 'bug';
break; break;
case MenuEnum.caseManagement: case MenuEnum.caseManagement:
suffix = 'case'; suffix = 'case';

View File

@ -210,7 +210,7 @@
.arco-select-view-single, .arco-select-view-single,
.arco-select { .arco-select {
border: 1px solid var(--color-text-input-border); border: 1px solid var(--color-text-input-border);
background-color: var(--color-text-fff) !important; background-color: var(--color-text-fff);
&:not(:disabled):hover { &:not(:disabled):hover {
border-color: rgb(var(--primary-5)); border-color: rgb(var(--primary-5));
} }

View File

@ -115,6 +115,7 @@
], ],
onUpdate: () => { onUpdate: () => {
content.value = `${editor.value?.getHTML()}`; content.value = `${editor.value?.getHTML()}`;
console.log(content.value);
}, },
}); });

View File

@ -408,6 +408,9 @@
initColumn(); initColumn();
batchLeft.value = getBatchLeft(); batchLeft.value = getBatchLeft();
}); });
defineExpose({
initColumn,
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -1,5 +1,121 @@
<template> <template>
<a-input> <div class="ms-time-selector">
<template #append> </template> <a-input-number
</a-input> v-model="current.value"
class="w-[120px]"
:min="0"
:max="current.max"
hide-button
size="small"
@blur="handleBlur"
>
<template #suffix>
<a-select v-model="current.type" size="small" class="max-w-[64px]" :options="option"> </a-select>
</template>
</a-input-number>
</div>
</template> </template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/useI18n';
const { t } = useI18n();
const props = defineProps<{ modelValue: string }>();
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
(e: 'change', value: string): void;
}>();
function parseValue(v: string) {
// 使
const match = v.match(/^(\d+)([MYHD])$/);
if (match) {
const value = parseInt(match[1], 10); //
const type = match[2]; //
let max = 0;
//
switch (type) {
case 'H':
max = 24;
break;
case 'M':
max = 12;
break;
default:
max = Number.MAX_VALUE;
}
return { type, value, max };
}
//
return { type: 'H', value: undefined, max: Number.MAX_VALUE };
}
const current = reactive(parseValue(props.modelValue));
const handleBlur = () => {
const result = current.value ? `${current.value}${current.type}` : '';
emit('update:modelValue', current.value ? `${current.value}${current.type}` : '');
emit('change', result);
};
const option = computed(() => [
{
label: t('msTimeSelector.hour'),
value: 'H',
},
{
label: t('msTimeSelector.day'),
value: 'D',
},
{
label: t('msTimeSelector.month'),
value: 'M',
},
{
label: t('msTimeSelector.year'),
value: 'Y',
},
]);
</script>
<style lang="less" scoped>
.ms-time-selector {
display: inline;
:deep(.arco-input-wrapper) {
padding-right: 0;
:focus-within {
border-color: rgb(var(--primary-7));
border-top: none;
border-bottom: none;
border-left: none;
}
.arco-input.arco-input-size-small {
padding: 0;
}
}
:deep(.arco-input-wrapper:not(:disabled):hover) {
border-color: rgb(var(--primary-7));
background-color: var(--color-text-n10);
}
:deep(.arco-select) {
border-top: 1px solid var(--color-text-n7);
border-right: 1px solid var(--color-text-n7);
border-bottom: 1px solid var(--color-text-n7);
border-radius: 0 4px 4px 0;
background: var(--color-text-n8);
}
:deep(.arco-select-focused) {
border-color: rgb(var(--primary-7));
}
:deep(.arco-select-view-single) {
padding: 5px 8px;
.arco-select-view-value {
padding-top: 0;
padding-bottom: 0;
height: 22px;
min-height: 22px;
line-height: 22px;
}
}
}
</style>

View File

@ -1 +1,6 @@
export default {}; export default {
'msTimeSelector.hour': 'Hour',
'msTimeSelector.day': 'Day',
'msTimeSelector.month': 'Month',
'msTimeSelector.year': 'Year',
};

View File

@ -1 +1,6 @@
export default {}; export default {
'msTimeSelector.hour': '小时',
'msTimeSelector.day': '天',
'msTimeSelector.month': '月',
'msTimeSelector.year': '年',
};

View File

@ -41,7 +41,7 @@ const ProjectManagement: AppRouteRecordRaw = {
{ {
path: 'menuManagement', path: 'menuManagement',
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
component: () => import('@/views/project-management/projectAndPermission/menuManagement/index.vue'), component: () => import('@/views/project-management/projectAndPermission/menuManagement/menuManagement.vue'),
meta: { meta: {
locale: 'project.permission.menuManagement', locale: 'project.permission.menuManagement',
roles: ['*'], roles: ['*'],

View File

@ -12,7 +12,9 @@
@select="onSelect" @select="onSelect"
@ok="onOk" @ok="onOk"
/> />
<MsRichText v-model="content" /> <!-- <MsRichText v-model="content" /> -->
<MsTimeSelector v-model="timeValue" />
<div>value: {{ timeValue }}</div>
</MsCard> </MsCard>
</template> </template>
@ -20,6 +22,8 @@
import MsPagination from '@/components/pure/ms-pagination/index'; import MsPagination from '@/components/pure/ms-pagination/index';
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue'; import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
import MsTimeSelector from '@/components/pure/ms-time-selector/MsTimeSelector.vue';
const content = ref(''); const content = ref('');
const timeValue = ref('3M');
</script> </script>

View File

@ -23,9 +23,8 @@ export default {
'project.menu.API_SYNC_CASE': '变更同步CASE', 'project.menu.API_SYNC_CASE': '变更同步CASE',
'project.menu.CASE_PUBLIC': '公共用例库', 'project.menu.CASE_PUBLIC': '公共用例库',
'project.menu.CASE_RE_REVIEW': '关联需求', 'project.menu.CASE_RE_REVIEW': '重新提审',
'project.menu.CASE_RELATED': '重新提审', 'project.menu.CASE_ENABLE': '关联需求',
'project.menu.CASE_ENABLE': '接口测试待更新同步规则',
'project.menu.ISSUE_SYNC': '同步缺陷', 'project.menu.ISSUE_SYNC': '同步缺陷',
'project.menu.CRON_EXPRESSION': '同步频率', 'project.menu.CRON_EXPRESSION': '同步频率',
'project.menu.SYNC_ENABLE': '状态', 'project.menu.SYNC_ENABLE': '状态',

View File

@ -32,11 +32,11 @@
</div> </div>
<div v-if="record.type === 'TEST_PLAN_CLEAN_REPORT'"> <div v-if="record.type === 'TEST_PLAN_CLEAN_REPORT'">
<!-- 测试计划 报告保留时间范围 --> <!-- 测试计划 报告保留时间范围 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'TEST_PLAN_SHARE_REPORT'"> <div v-if="record.type === 'TEST_PLAN_SHARE_REPORT'">
<!-- 测试计划 报告链接有效期 --> <!-- 测试计划 报告链接有效期 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'ISSUE_SYNC'"> <div v-if="record.type === 'ISSUE_SYNC'">
<!-- 缺陷同步 --> <!-- 缺陷同步 -->
@ -47,28 +47,28 @@
<!-- 用例 公共用例库 --> <!-- 用例 公共用例库 -->
{{ t('project.menu.row3') }} {{ t('project.menu.row3') }}
</div> </div>
<div v-if="record.type === 'CASE_RE_REVIEW'" class="flex flex-row"> <div v-if="record.type === 'CASE_ENABLE'" class="flex flex-row">
<!-- 用例 关联需求 --> <!-- 用例 关联需求 -->
<div>{{ t('project.menu.row4') }}</div> <div>{{ t('project.menu.row4') }}</div>
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.rr') }}</div> <div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.rr') }}</div>
</div> </div>
<div v-if="record.type === 'CASE_RELATED'"> <div v-if="record.type === 'CASE_RE_REVIEW'">
<!-- 用例 重新提审 --> <!-- 用例 重新提审 -->
{{ t('project.menu.row5') }} {{ t('project.menu.row5') }}
</div> </div>
<div v-if="record.type === 'API_URL_REPEATABLE'"> <div v-if="record.type === 'API_URL_REPEATABLE'">
<!-- 接口 --> <!-- 接口测试 接口定义URL可重复 -->
{{ t('project.menu.row6') }} {{ t('project.menu.row6') }}
</div> </div>
<div v-if="record.type === 'API_CLEAN_REPORT'"> <div v-if="record.type === 'API_CLEAN_REPORT'">
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'API_SHARE_REPORT'"> <div v-if="record.type === 'API_SHARE_REPORT'">
<!-- 报告链接有效期 --> <!--接口测试 报告链接有效期 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'API_RESOURCE_POOL'" class="flex flex-row items-center"> <div v-if="record.type === 'API_RESOURCE_POOL'" class="flex flex-row items-center">
<!-- 执行资源池 --> <!--接口测试 执行资源池 -->
<a-select v-model="record.typeValue" /> <a-select v-model="record.typeValue" />
<a-tooltip :content="t('project.menu.manageTip')" position="bl"> <a-tooltip :content="t('project.menu.manageTip')" position="bl">
<div> <div>
@ -77,7 +77,7 @@
</a-tooltip> </a-tooltip>
</div> </div>
<div v-if="record.type === 'API_SCRIPT_REVIEWER'" class="flex flex-row items-center"> <div v-if="record.type === 'API_SCRIPT_REVIEWER'" class="flex flex-row items-center">
<!-- 脚本审核 --> <!--接口测试 脚本审核 -->
<a-select v-model="record.typeValue" /> <a-select v-model="record.typeValue" />
<a-tooltip :content="t('project.menu.manageTip')" position="bl"> <a-tooltip :content="t('project.menu.manageTip')" position="bl">
<div> <div>
@ -86,8 +86,8 @@
</a-tooltip> </a-tooltip>
</div> </div>
<div v-if="record.type === 'API_ERROR_REPORT_RULE'" class="flex w-[100%] flex-row items-center"> <div v-if="record.type === 'API_ERROR_REPORT_RULE'" class="flex w-[100%] flex-row items-center">
<!-- 误报规则 --> <!--接口测试 误报规则 -->
<a-select v-model="record.typeValue" class="w-[290px]" /> <a-select v-model="record.typeValue" class="w-[120px]" />
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.far') }}</div> <div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.far') }}</div>
<a-tooltip :content="t('project.menu.manageTip')" position="bl"> <a-tooltip :content="t('project.menu.manageTip')" position="bl">
<div> <div>
@ -98,15 +98,15 @@
<div v-if="record.type === 'API_SYNC_CASE'">{{ t('project.menu.row7') }} </div> <div v-if="record.type === 'API_SYNC_CASE'">{{ t('project.menu.row7') }} </div>
<div v-if="record.type === 'UI_CLEAN_REPORT'"> <div v-if="record.type === 'UI_CLEAN_REPORT'">
<!--UI 报告保留时间范围 --> <!--UI 报告保留时间范围 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'UI_SHARE_REPORT'"> <div v-if="record.type === 'UI_SHARE_REPORT'">
<!--UI 报告链接有效期 --> <!--UI 报告链接有效期 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'UI_RESOURCE_POOL'" class="flex flex-row items-center"> <div v-if="record.type === 'UI_RESOURCE_POOL'" class="flex flex-row items-center">
<!--UI 执行资源池 --> <!--UI 执行资源池 -->
<a-select v-model="record.typeValue" /> <a-select v-model="record.typeValue" class="w-[120px]" />
<a-tooltip :content="t('project.menu.manageTip')" position="bl"> <a-tooltip :content="t('project.menu.manageTip')" position="bl">
<div> <div>
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" /> <MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
@ -115,15 +115,15 @@
</div> </div>
<div v-if="record.type === 'PERFORMANCE_TEST_CLEAN_REPORT'"> <div v-if="record.type === 'PERFORMANCE_TEST_CLEAN_REPORT'">
<!--性能测试 报告保留时间范围 --> <!--性能测试 报告保留时间范围 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'PERFORMANCE_TEST_SHARE_REPORT'"> <div v-if="record.type === 'PERFORMANCE_TEST_SHARE_REPORT'">
<!--UI 报告链接有效期 --> <!--UI 报告链接有效期 -->
<a-input v-model="record.typeValue" /> <MsTimeSelectorVue v-model="record.typeValue" />
</div> </div>
<div v-if="record.type === 'PERFORMANCE_TEST_SCRIPT_REVIEWER'" class="flex flex-row items-center"> <div v-if="record.type === 'PERFORMANCE_TEST_SCRIPT_REVIEWER'" class="flex flex-row items-center">
<!--UI 脚本审核 --> <!--UI 脚本审核 -->
<a-select v-model="record.typeValue" /> <a-select v-model="record.typeValue" class="w-[120px]" />
<a-tooltip :content="t('project.menu.manageTip')" position="bl"> <a-tooltip :content="t('project.menu.manageTip')" position="bl">
<div> <div>
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" /> <MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
@ -134,14 +134,13 @@
</MsBaseTable> </MsBaseTable>
<MsDrawer <MsDrawer
v-model:visible="defectDrawerVisible" v-model:visible="defectDrawerVisible"
title="缺陷同步" :title="t('project.menu.ISSUE_SYNC')"
:width="600"
:destroy-on-close="true" :destroy-on-close="true"
:closable="true" :closable="true"
:mask-closable="false" :mask-closable="false"
:footer="null"
:get-container="false" :get-container="false"
:body-style="{ padding: '0px' }" :body-style="{ padding: '0px' }"
:width="400"
> >
<DefectSync /> <DefectSync />
</MsDrawer> </MsDrawer>
@ -161,6 +160,9 @@
import { MenuTableListItem } from '@/models/projectManagement/menuManagement'; import { MenuTableListItem } from '@/models/projectManagement/menuManagement';
import { MenuEnum } from '@/enums/commonEnum'; import { MenuEnum } from '@/enums/commonEnum';
import { Message, TableData } from '@arco-design/web-vue'; import { Message, TableData } from '@arco-design/web-vue';
import MsTimeSelectorVue from '@/components/pure/ms-time-selector/MsTimeSelector.vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import DefectSync from './components/defectSync.vue';
const appStore = useAppStore(); const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId); const currentProjectId = computed(() => appStore.currentProjectId);