feat(测试跟踪): 缺陷自定义字段下拉框选项支持远程搜索

This commit is contained in:
chenjianxing 2023-02-19 17:23:39 +08:00 committed by jianxing
parent 36fe2a65f4
commit 085c4c70b3
8 changed files with 111 additions and 6 deletions

View File

@ -11,7 +11,10 @@
:data="item" :data="item"
:form="form" :form="form"
:default-open="defaultOpen" :default-open="defaultOpen"
:disabled="isPublic"/> :disabled="isPublic"
@inputSearch="handleInputSearch"
ref="customFiled"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<div v-else> <div v-else>
@ -21,7 +24,12 @@
:prop="item.name" :prop="item.name"
:default-open="defaultOpen" :default-open="defaultOpen"
:label-width="formLabelWidth"> :label-width="formLabelWidth">
<custom-filed-component :data="item" :form="form" prop="defaultValue"/> <custom-filed-component
:data="item"
:form="form"
prop="defaultValue"
@inputSearch="handleInputSearch"
ref="customFiled"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</div> </div>
@ -81,6 +89,16 @@ export default {
} }
} }
return customFields; return customFields;
}
},
methods: {
handleInputSearch(data, query) {
this.$emit('inputSearch', data, query);
},
stopLoading() {
this.$refs.customFiled.forEach(item => {
item.stopLoading();
});
}, },
} }
} }

View File

@ -1,12 +1,18 @@
<template> <template>
<span> <span>
<el-select v-if="data.type === 'select' || data.type === 'multipleSelect'" <el-select v-if="data.type === 'select' || data.type === 'multipleSelect'"
:loading="loading"
@click.native="clickPane" @click.native="clickPane"
:disabled="disabled" :disabled="disabled"
:multiple="data.type === 'multipleSelect'" :multiple="data.type === 'multipleSelect'"
@change="handleChange" @change="handleChange"
@clear="handleClear"
clearable clearable
filterable v-model="data[prop]" :placeholder="$t('commons.default')"> filterable
v-model="data[prop]"
:filter-method="data.inputSearch ? handleSelectInput : null"
:remote="data.inputSearch"
:placeholder="$t('commons.default')">
<el-option <el-option
v-for="(item,index) in data.options ? data.options : []" v-for="(item,index) in data.options ? data.options : []"
:key="index" :key="index"
@ -95,7 +101,9 @@
@change="handleChange" @change="handleChange"
clearable clearable
:disabled="disabled" :disabled="disabled"
filterable v-model="data[prop]" :placeholder="$t('commons.default')"> filterable
v-model="data[prop]"
:placeholder="$t('commons.default')">
<el-option <el-option
v-for="(item) in memberOptions" v-for="(item) in memberOptions"
:key="item.id" :key="item.id"
@ -158,6 +166,8 @@ export default {
data() { data() {
return { return {
memberOptions: [], memberOptions: [],
originOptions: null,
loading: false
}; };
}, },
mounted() { mounted() {
@ -213,6 +223,26 @@ export default {
this.$emit('change', this.data.name); this.$emit('change', this.data.name);
this.$forceUpdate(); this.$forceUpdate();
}, },
handleSelectInput(val) {
this.loading = true;
if (!this.originOptions) {
this.originOptions = this.data.options;
}
if (!val) {
//
this.data.options = this.originOptions;
}
this.$emit('inputSearch', this.data, val);
},
handleClear() {
if (this.originOptions && this.data.inputSearch) {
//
this.data.options = this.originOptions;
}
},
stopLoading() {
this.loading = false;
},
setFormData() { setFormData() {
if (this.form && this.data && this.data[this.prop]) { if (this.form && this.data && this.data[this.prop]) {
this.$set(this.form, this.data.name, this.data[this.prop]); this.$set(this.form, this.data.name, this.data[this.prop]);

View File

@ -20,4 +20,8 @@ public class CustomFieldDao extends CustomField {
private String originGlobalId; private String originGlobalId;
private String key; private String key;
private Boolean inputSearch;
private String optionMethod;
} }

View File

@ -17,6 +17,7 @@ import io.metersphere.excel.domain.ExcelResponse;
import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.notice.annotation.SendNotice; import io.metersphere.notice.annotation.SendNotice;
import io.metersphere.platform.domain.SelectOption; import io.metersphere.platform.domain.SelectOption;
import io.metersphere.request.PlatformOptionRequest;
import io.metersphere.request.issues.IssueExportRequest; import io.metersphere.request.issues.IssueExportRequest;
import io.metersphere.request.issues.IssueImportRequest; import io.metersphere.request.issues.IssueImportRequest;
import io.metersphere.request.issues.PlatformIssueTypeRequest; import io.metersphere.request.issues.PlatformIssueTypeRequest;
@ -220,6 +221,11 @@ public class IssuesController {
return platformPluginService.getPlatformOptions(); return platformPluginService.getPlatformOptions();
} }
@PostMapping("/platform/form/option")
public List<SelectOption> getPlatformOptions(@RequestBody PlatformOptionRequest request) {
return platformPluginService.getFormOption(request);
}
@PostMapping("/check/third/project") @PostMapping("/check/third/project")
public void checkThirdProjectExist(@RequestBody Project project) { public void checkThirdProjectExist(@RequestBody Project project) {
issuesService.checkThirdProjectExist(project); issuesService.checkThirdProjectExist(project);

View File

@ -0,0 +1,12 @@
package io.metersphere.request;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PlatformOptionRequest extends IntegrationRequest {
private String optionMethod;
private String projectConfig;
private String query;
}

View File

@ -11,11 +11,14 @@ import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.ServiceIntegration; import io.metersphere.base.domain.ServiceIntegration;
import io.metersphere.commons.constants.PluginScenario; import io.metersphere.commons.constants.PluginScenario;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.platform.domain.GetOptionRequest;
import io.metersphere.platform.domain.PlatformRequest; import io.metersphere.platform.domain.PlatformRequest;
import io.metersphere.platform.domain.SelectOption; import io.metersphere.platform.domain.SelectOption;
import io.metersphere.platform.impl.JiraPlatform;
import io.metersphere.platform.loader.PlatformPluginManager; import io.metersphere.platform.loader.PlatformPluginManager;
import io.metersphere.request.IntegrationRequest; import io.metersphere.request.IntegrationRequest;
import io.metersphere.request.PlatformOptionRequest;
import io.metersphere.utils.PluginManagerUtil; import io.metersphere.utils.PluginManagerUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -148,4 +152,17 @@ public class PlatformPluginService {
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public List<SelectOption> getFormOption(PlatformOptionRequest request) {
Platform platform = getPlatform(request.getPlatform(), request.getWorkspaceId());
GetOptionRequest getOptionRequest = new GetOptionRequest();
getOptionRequest.setOptionMethod(request.getOptionMethod());
getOptionRequest.setProjectConfig(request.getProjectConfig());
getOptionRequest.setQuery(request.getQuery());
try {
return platform.getFormOptions(getOptionRequest);
} catch (Exception e) {
return new ArrayList<>();
}
}
} }

View File

@ -298,3 +298,7 @@ export function getIssuePartTemplateWithProject(callback, reject) {
export function getPlatformOption() { export function getPlatformOption() {
return get(BASE_URL + 'platform/option'); return get(BASE_URL + 'platform/option');
} }
export function getPlatformFormOption(param) {
return post(BASE_URL + 'platform/form/option', param);
}

View File

@ -42,7 +42,10 @@
:form="customFieldForm" :form="customFieldForm"
:default-open="richTextDefaultOpen" :default-open="richTextDefaultOpen"
:form-label-width="formLabelWidth" :form-label-width="formLabelWidth"
:issue-template="issueTemplate"/> :issue-template="issueTemplate"
@inputSearch="handleInputSearch"
ref="customFieldItem"
/>
</el-form> </el-form>
<el-row v-if="platformTransitions"> <el-row v-if="platformTransitions">
@ -204,7 +207,7 @@ import {
saveFollow, saveFollow,
getFollow, getFollow,
getComments, getComments,
getTapdUser, getPlatformTransitions getTapdUser, getPlatformTransitions, getPlatformFormOption
} from "@/api/issue"; } from "@/api/issue";
import { import {
uploadIssueAttachment, uploadIssueAttachment,
@ -728,6 +731,17 @@ export default {
this.getFileMetaData(this.issueId); this.getFileMetaData(this.issueId);
} }
}, },
handleInputSearch(data, query) {
getPlatformFormOption({
optionMethod: data.optionMethod,
workspaceId: getCurrentWorkspaceId(),
platform: this.issueTemplate.platform,
query
}).then((r) => {
data.options = r.data;
this.$refs.customFieldItem.stopLoading();
});
},
handleDelete(file, index) { handleDelete(file, index) {
this.$alert((this.cancelFileToken.length > 0 ? this.$t('load_test.delete_file_when_uploading') + '<br/>' : "") + this.$t('load_test.delete_file_confirm') + file.name + "?", '', { this.$alert((this.cancelFileToken.length > 0 ? this.$t('load_test.delete_file_when_uploading') + '<br/>' : "") + this.$t('load_test.delete_file_confirm') + file.name + "?", '', {
confirmButtonText: this.$t('commons.confirm'), confirmButtonText: this.$t('commons.confirm'),