feat(项目设置): 应用管理关联需求对接form-create

This commit is contained in:
RubyLiu 2023-11-02 18:46:16 +08:00 committed by Craftsman
parent c24aff44e1
commit c7b775d004
9 changed files with 64 additions and 82 deletions

View File

@ -132,6 +132,16 @@ export function postSaveDefectSync(data: MenuTableConfigItem, projectId: string)
return MSR.post<MenuTableListItem>({ url: `${Url.postSyncBugConfigUrl}${projectId}`, data });
}
/**
*
* @param data
* @param projectId ID
* @returns
*/
export function postSaveRelatedCase(data: MenuTableConfigItem, projectId: string) {
return MSR.post<MenuTableListItem>({ url: `${Url.postRelatedCaseConfigUrl}${projectId}`, data });
}
// 误报规则列表查询
export function postFakeTableList(data: TableQueryParams) {
return MSR.post<FakeTableListItem[]>({ url: `${Url.postFakeTableUrl}`, data });

View File

@ -13,6 +13,8 @@ export const getPluginInfoByBug = '/project/application/bug/platform/info/';
// 缺陷管理-同步缺陷配置
export const postSyncBugConfigUrl = '/project/application/update/bug/sync/';
// 用例管理-关联需求配置
export const postRelatedCaseConfigUrl = '/project/application/update/case/related/';
// 误报规则列表查询
export const postFakeTableUrl = '/fake/error/list';
// 误报规则列表删除

View File

@ -2,7 +2,7 @@
<div class="usergroup-auth-table">
<a-table
:span-method="dataSpanMethod"
:scroll="{ y: '500px', x: '800px' }"
:scroll="props.scroll"
:data="tableData"
:loading="loading"
:bordered="{ wrapper: true, cell: true }"
@ -99,9 +99,21 @@
current: CurrentUserGroupItem;
width?: string;
showBottom?: boolean;
scroll?: {
x?: number | string;
y?: number | string;
minWidth?: number | string;
maxHeight?: number | string;
};
}>(),
{
showBottom: true,
scroll() {
return {
x: '800px',
y: 'calc(100vh - 230px)',
};
},
}
);

View File

@ -12,13 +12,7 @@
{{ null }}
</template>
<template #content>
<img
class="h-[247px] w-[398px]"
:style="{
border: '1px solid red',
}"
:src="previewIcon"
/>
<img class="h-[247px] w-[398px]" :src="previewIcon" />
</template>
<span class="cursor-pointer text-[rgb(var(--primary-5))]">{{ t('project.menu.preview') }}</span>
</a-popover>

View File

@ -16,7 +16,7 @@
<a-form ref="formRef" class="rounded-[4px]" :model="form" layout="vertical">
<a-form-item field="platformKey" :label="t('project.menu.platformLabel')">
<a-select
v-model="form.platformKey"
v-model="form.PLATFORM_KEY"
allow-clear
:disabled="platformDisabled"
:options="platformOption"
@ -29,56 +29,17 @@
<!-- form-create -->
<MsFormCreate
v-if="platformRules && platformRules.length"
v-model:api="fApi"
:form-rule="platformRules"
:form-create-key="FormCreateKeyEnum.PROJECT_DEFECT_SYNC_TEMPLATE"
/>
<!-- 同步机制 -->
<a-form-item field="MECHANISM" :label="t('project.menu.syncMechanism')">
<a-space>
<a-radio-group v-model="form.MECHANISM">
<a-radio value="increment">
<div class="flex flex-row items-center gap-[4px]">
<span class="text-[var(--color-text-1)]">{{ t('project.menu.incrementalSync') }}</span>
<a-tooltip :content="t('project.menu.incrementalSyncTip')" position="top">
<div>
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
</div>
</a-tooltip>
</div>
</a-radio>
<a-radio value="full">
<div class="flex flex-row items-center gap-[4px]">
<span class="text-[var(--color-text-1)]">{{ t('project.menu.fullSync') }}</span>
<a-tooltip :content="t('project.menu.fullSyncTip')" position="bl">
<div>
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
</div>
</a-tooltip>
</div>
</a-radio>
</a-radio-group>
</a-space>
</a-form-item>
<!-- 同步频率 -->
<a-form-item field="CRON_EXPRESSION" :label="t('project.menu.CRON_EXPRESSION')">
<a-select v-model="form.CRON_EXPRESSION">
<a-option v-for="data in frequencyOption" :key="data.value" :value="data.value">
<span class="text-[var(--color-text-1)]">
{{ data.label }}
</span>
<span v-if="data.extra" class="text-[var(--color-text-4)]"> {{ data.extra }} </span>
</a-option>
<a-option value="custom">
<div class="border-t-1 cursor-pointer text-[rgb(var(--primary-5))]">{{
t('project.menu.defect.customLabel')
}}</div>
</a-option>
</a-select>
</a-form-item>
</a-form>
<template #footerLeft>
<template v-if="platformOption.length" #footerLeft>
<div class="flex flex-row items-center gap-[4px]">
<a-switch size="small" />
<a-tooltip v-if="okDisabled" :content="t('project.menu.defect.enableAfterConfig')">
<a-switch size="small" disabled />
</a-tooltip>
<a-switch v-else v-model="form.SYNC_ENABLE" size="small" />
<span class="text-[var(--color-text-1)]">
{{ t('project.menu.status') }}
</span>
@ -99,7 +60,7 @@
</template>
<script lang="ts" setup>
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
import { FormInstance, Message } from '@arco-design/web-vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import MsFormCreate from '@/components/pure/ms-form-create/form-create.vue';
@ -108,7 +69,7 @@
import {
getPlatformInfo,
getPlatformOptions,
postSaveDefectSync,
postSaveRelatedCase,
} from '@/api/modules/project-management/menuManagement';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
@ -123,12 +84,7 @@
}>();
const currentVisible = ref<boolean>(props.visible);
const platformOption = ref<PoolOption[]>([]);
const frequencyOption = ref([
{ label: '0 0 0/1 * * ?', extra: '每隔1小时', value: '1H' },
{ label: '0 0 0/6 * * ?', extra: '每隔6小时', value: '6H' },
{ label: '0 0 0/12 * * ?', extra: '每隔12小时', value: '12H' },
{ label: '0 0 0 * * ?', extra: '(每隔一天)', value: '1D' },
]);
const fApi = ref<any>({});
const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
@ -140,18 +96,11 @@
const platformRules = ref<FormItem[]>([]);
const form = reactive({
platformKey: '',
MECHANISM: '', //
PLATFORM_KEY: '',
SYNC_ENABLE: 'false', //
CRON_EXPRESSION: '', //
organizationId: '',
projectKey: '',
projectId: '',
azureId: '',
bugType: '',
});
const okDisabled = computed(() => !form.platformKey);
const okDisabled = computed(() => !form.PLATFORM_KEY);
const emit = defineEmits<{
(e: 'cancel', shouldSearch: boolean): void;
@ -159,11 +108,13 @@
const handleCancel = (shouldSearch: boolean) => {
emit('cancel', shouldSearch);
sessionStorage.removeItem('platformKey');
fApi.value.clearValidateState();
};
const handlePlatformChange = async (value: SelectValue) => {
try {
if (value) {
const res = await getPlatformInfo(value as string, MenuEnum.bugManagement);
const res = await getPlatformInfo(value as string, MenuEnum.caseManagement);
platformRules.value = res.formItems;
} else {
platformRules.value = [];
@ -175,13 +126,10 @@
};
const handleConfirm = async () => {
await formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
if (errors) {
return;
}
await fApi.value?.submit(async (formData: FormData) => {
try {
okLoading.value = true;
await postSaveDefectSync(form, currentProjectId.value);
await postSaveRelatedCase({ ...form, DEMAND_PLATFORM_CONFIG: formData }, currentProjectId.value);
Message.success(t('common.createSuccess'));
handleCancel(true);
} catch (error) {
@ -195,7 +143,7 @@
const initPlatformOption = async () => {
try {
const res = await getPlatformOptions(currentOrgId.value, MenuEnum.bugManagement);
const res = await getPlatformOptions(currentOrgId.value, MenuEnum.caseManagement);
if (res) {
platformOption.value = res;
}

View File

@ -39,7 +39,6 @@
:disabled="!isXpack"
allow-search
:options="affiliatedOrgOption"
:default-value="isXpack ? '' : '100001'"
:placeholder="t('system.project.affiliatedOrgPlaceholder')"
:field-names="{ label: 'name', value: 'id' }"
>
@ -189,6 +188,9 @@
try {
const res = await getSystemOrgOption();
affiliatedOrgOption.value = res;
if (!isXpack.value) {
form.organizationId = affiliatedOrgOption.value[0].id;
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);

View File

@ -172,7 +172,6 @@
);
const fetchData = async () => {
setKeyword(props.keyword);
await loadList();
};
@ -309,6 +308,10 @@
fetchData,
});
watchEffect(() => {
setKeyword(props.keyword);
});
onMounted(() => {
fetchData();
});

View File

@ -172,7 +172,6 @@
);
const fetchData = async () => {
setKeyword(props.keyword);
await loadList();
};
@ -303,6 +302,14 @@
fetchData,
});
watchEffect(() => {
setKeyword(props.keyword);
});
onMounted(() => {
fetchData();
});
await tableStore.initColumn(TableKeyEnum.SYSTEM_PROJECT, organizationColumns, 'drawer');
</script>

View File

@ -10,6 +10,7 @@
</div>
<div class="flex items-center">
<a-input-search
v-model="keyword"
:placeholder="t('system.user.searchUser')"
class="w-[240px]"
allow-clear
@ -54,6 +55,7 @@
const organizationCount = ref(0);
const projectCount = ref(0);
const currentKeyword = ref('');
const keyword = ref('');
const orgTableRef = ref();
const projectTableRef = ref();
const projectVisible = ref(false);
@ -122,9 +124,11 @@
watch(
() => currentTable.value,
() => {
tableSearch();
currentKeyword.value = '';
keyword.value = '';
}
);
onBeforeMount(() => {
tableSearch();
});