feat(测试跟踪): 缺陷自定义字段下拉框选项支持远程搜索
This commit is contained in:
parent
36fe2a65f4
commit
085c4c70b3
|
@ -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();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
Loading…
Reference in New Issue