fix(测试跟踪): 优化测试计划内批量编辑接口和场景用例的环境,增加已选环境的反显
--bug=1024643 --user=宋天阳 【测试跟踪】测试计划-接口用例tab-批量编辑接口case页面显示运行环境信息优化 https://www.tapd.cn/55049933/s/1354319
This commit is contained in:
parent
1dda504ebb
commit
091c41cccd
|
@ -9,43 +9,115 @@
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
append-to-body
|
append-to-body
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
v-loading="loading">
|
v-loading="loading"
|
||||||
<span class="select-row">{{$t('test_track.batch_operate_select_row_count', [size])}}</span>
|
>
|
||||||
|
<span class="select-row">{{
|
||||||
|
$t("test_track.batch_operate_select_row_count", [size])
|
||||||
|
}}</span>
|
||||||
|
|
||||||
<el-form :model="form" label-position="top" label-width="180px" size="small" ref="form" :rules="rules" style="margin-top: 24px" class="batchEditForm">
|
<el-form
|
||||||
|
:model="form"
|
||||||
|
label-position="top"
|
||||||
|
label-width="180px"
|
||||||
|
size="small"
|
||||||
|
ref="form"
|
||||||
|
:rules="rules"
|
||||||
|
style="margin-top: 24px"
|
||||||
|
class="batchEditForm"
|
||||||
|
>
|
||||||
<el-form-item :label="$t('test_track.case.select_attr')" prop="type">
|
<el-form-item :label="$t('test_track.case.select_attr')" prop="type">
|
||||||
<el-select v-model="form.type" style="width: 100%" @change="changeType">
|
<el-select
|
||||||
<el-option v-for="(type, index) in typeArr" :key="index" :value="type.custom ? type.custom : type.id"
|
v-model="form.type"
|
||||||
:label="type.name"/>
|
style="width: 100%"
|
||||||
|
@change="changeType"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(type, index) in typeArr"
|
||||||
|
:key="index"
|
||||||
|
:value="type.custom ? type.custom : type.id"
|
||||||
|
:label="type.name"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="form.type === 'projectEnv'" :label="$t('test_track.case.batch_update_to')">
|
<el-form-item
|
||||||
<env-popover :env-map="projectEnvMap"
|
v-if="form.type === 'projectEnv'"
|
||||||
:project-ids="projectIds"
|
:label="$t('test_track.case.batch_update_to')"
|
||||||
@setProjectEnvMap="setProjectEnvMap"
|
>
|
||||||
:show-config-button-with-out-permission="showConfigButtonWithOutPermission"
|
<env-popover
|
||||||
:project-list="projectList"
|
:env-map="projectEnvMap"
|
||||||
:environment-type.sync="environmentType"
|
:project-ids="projectIds"
|
||||||
:group-id="envGroupId"
|
@setProjectEnvMap="setProjectEnvMap"
|
||||||
:is-scenario="false"
|
:show-config-button-with-out-permission="
|
||||||
@setEnvGroup="setEnvGroup"
|
showConfigButtonWithOutPermission
|
||||||
ref="envPopover"/>
|
"
|
||||||
|
:project-list="projectList"
|
||||||
|
:environment-type.sync="environmentType"
|
||||||
|
:group-id="envGroupId"
|
||||||
|
:is-scenario="false"
|
||||||
|
@setEnvGroup="setEnvGroup"
|
||||||
|
ref="envPopover"
|
||||||
|
/>
|
||||||
|
<div v-if="showProjectEnv" type="flex" style="margin-top: 5px">
|
||||||
|
<div
|
||||||
|
v-for="(values, key) in projectEnvDescMap"
|
||||||
|
:key="key"
|
||||||
|
style="margin-right: 10px"
|
||||||
|
>
|
||||||
|
<el-row>
|
||||||
|
{{ key + ":" }}
|
||||||
|
<ms-tag
|
||||||
|
:key="values"
|
||||||
|
type="success"
|
||||||
|
:content="values"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-else-if="form.type === 'tags'" :label="$t('test_track.case.batch_update_to')">
|
<el-form-item
|
||||||
<ms-input-tag :currentScenario="form" v-if="showInputTag" ref="tag" class="ms-case-input"></ms-input-tag>
|
v-else-if="form.type === 'tags'"
|
||||||
|
:label="$t('test_track.case.batch_update_to')"
|
||||||
|
>
|
||||||
|
<ms-input-tag
|
||||||
|
:currentScenario="form"
|
||||||
|
v-if="showInputTag"
|
||||||
|
ref="tag"
|
||||||
|
class="ms-case-input"
|
||||||
|
></ms-input-tag>
|
||||||
<el-checkbox v-model="form.appendTag">
|
<el-checkbox v-model="form.appendTag">
|
||||||
{{ $t('commons.append_tag') }}
|
{{ $t("commons.append_tag") }}
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('commons.append_tag_tip')" placement="top">
|
<el-tooltip
|
||||||
|
class="item"
|
||||||
|
effect="dark"
|
||||||
|
:content="$t('commons.append_tag_tip')"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
<i class="el-icon-question"></i>
|
<i class="el-icon-question"></i>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-else-if="form.type === 'reviewers'" :label="$t('test_track.case.batch_update_to')" prop="value">
|
<el-form-item
|
||||||
<el-select multiple v-model="form.value" style="width: 100%" :filterable="filterable" :disabled="!form.type">
|
v-else-if="form.type === 'reviewers'"
|
||||||
<el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.name">
|
:label="$t('test_track.case.batch_update_to')"
|
||||||
|
prop="value"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
multiple
|
||||||
|
v-model="form.value"
|
||||||
|
style="width: 100%"
|
||||||
|
:filterable="filterable"
|
||||||
|
:disabled="!form.type"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(option, index) in options"
|
||||||
|
:key="index"
|
||||||
|
:value="option.id"
|
||||||
|
:label="option.name"
|
||||||
|
>
|
||||||
<div v-if="option.email">
|
<div v-if="option.email">
|
||||||
<span>{{ option.id }}({{ option.name }})</span>
|
<span>{{ option.id }}({{ option.name }})</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,17 +125,40 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<el-checkbox v-model="form.appendTag">
|
<el-checkbox v-model="form.appendTag">
|
||||||
{{ $t('commons.append_reviewer') }}
|
{{ $t("commons.append_reviewer") }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-else-if="fieldType === 'custom'" prop="customFieldValue" :label="$t('test_track.case.batch_update_to')">
|
<el-form-item
|
||||||
<custom-filed-component v-if="customField" :data="customField" prop="defaultValue"/>
|
v-else-if="fieldType === 'custom'"
|
||||||
|
prop="customFieldValue"
|
||||||
|
:label="$t('test_track.case.batch_update_to')"
|
||||||
|
>
|
||||||
|
<custom-filed-component
|
||||||
|
v-if="customField"
|
||||||
|
:data="customField"
|
||||||
|
prop="defaultValue"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-else prop="value" :label="$t('test_track.case.batch_update_to')">
|
<el-form-item
|
||||||
<el-select v-model="form.value" style="width: 100%" :filterable="filterable" :disabled="!form.type" @change="changeValue">
|
v-else
|
||||||
<el-option v-for="(option, index) in options" :key="index" :value="option.id" :label="option.name">
|
prop="value"
|
||||||
|
:label="$t('test_track.case.batch_update_to')"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
v-model="form.value"
|
||||||
|
style="width: 100%"
|
||||||
|
:filterable="filterable"
|
||||||
|
:disabled="!form.type"
|
||||||
|
@change="changeValue"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(option, index) in options"
|
||||||
|
:key="index"
|
||||||
|
:value="option.id"
|
||||||
|
:label="option.name"
|
||||||
|
>
|
||||||
<div v-if="option.email">
|
<div v-if="option.email">
|
||||||
<span>{{ option.id }}({{ option.name }})</span>
|
<span>{{ option.id }}({{ option.name }})</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,25 +166,48 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="form.type === 'status' && this.showDescription"
|
<el-form-item
|
||||||
:label="$t('commons.description')" :label-width="formLabelWidth" prop="description">
|
v-if="form.type === 'status' && this.showDescription"
|
||||||
<el-input v-model="form.description"
|
:label="$t('commons.description')"
|
||||||
type="textarea"
|
:label-width="formLabelWidth"
|
||||||
:autosize="{ minRows: 2, maxRows: 4}"
|
prop="description"
|
||||||
:rows="2"
|
>
|
||||||
:placeholder="$t('commons.input_un_pass_reason')"/>
|
<el-input
|
||||||
|
v-model="form.description"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||||
|
:rows="2"
|
||||||
|
:placeholder="$t('commons.input_un_pass_reason')"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="form.type === 'reviewStatus'"
|
<el-form-item
|
||||||
:label="$t('原因')" :label-width="formLabelWidth" prop="description">
|
v-if="form.type === 'reviewStatus'"
|
||||||
<comment-edit-input :placeholder="'请输入原因'" :data="form" ref="commentEditInput"/>
|
:label="$t('原因')"
|
||||||
|
:label-width="formLabelWidth"
|
||||||
|
prop="description"
|
||||||
|
>
|
||||||
|
<comment-edit-input
|
||||||
|
:placeholder="'请输入原因'"
|
||||||
|
:data="form"
|
||||||
|
ref="commentEditInput"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<el-button @click="dialogVisible = false" size="small">{{ $t('commons.cancel') }}</el-button>
|
<el-button @click="dialogVisible = false" size="small">{{
|
||||||
<el-button v-prevent-re-click :type="!form.type ? 'info' : 'primary'" @click="submit('form')"
|
$t("commons.cancel")
|
||||||
@keydown.enter.native.prevent size="small" :disabled="!form.type" style="margin-left: 12px">{{ $t('commons.confirm') }}</el-button>
|
}}</el-button>
|
||||||
|
<el-button
|
||||||
|
v-prevent-re-click
|
||||||
|
:type="!form.type ? 'info' : 'primary'"
|
||||||
|
@click="submit('form')"
|
||||||
|
@keydown.enter.native.prevent
|
||||||
|
size="small"
|
||||||
|
:disabled="!form.type"
|
||||||
|
style="margin-left: 12px"
|
||||||
|
>{{ $t("commons.confirm") }}</el-button
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,14 +215,18 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
||||||
import {listenGoBack, removeGoBackListener} from "metersphere-frontend/src/utils";
|
import {
|
||||||
|
listenGoBack,
|
||||||
|
removeGoBackListener,
|
||||||
|
} from "metersphere-frontend/src/utils";
|
||||||
import EnvPopover from "@/business/plan/env/EnvPopover";
|
import EnvPopover from "@/business/plan/env/EnvPopover";
|
||||||
import {ENV_TYPE} from "metersphere-frontend/src/utils/constants";
|
import MsTag from "metersphere-frontend/src/components/MsTag";
|
||||||
|
import { ENV_TYPE } from "metersphere-frontend/src/utils/constants";
|
||||||
import CustomFiledComponent from "metersphere-frontend/src/components/template/CustomFiledComponent";
|
import CustomFiledComponent from "metersphere-frontend/src/components/template/CustomFiledComponent";
|
||||||
import MsInputTag from "metersphere-frontend/src/components/MsInputTag";
|
import MsInputTag from "metersphere-frontend/src/components/MsInputTag";
|
||||||
import {getOwnerProjects} from "@/business/utils/sdk-utils";
|
import { getOwnerProjects } from "@/business/utils/sdk-utils";
|
||||||
import {getApiScenarioEnvByProjectId} from "@/api/remote/api/api-automation";
|
import { getApiScenarioEnvByProjectId } from "@/api/remote/api/api-automation";
|
||||||
import {getCustomField} from "@/api/custom-field";
|
import { getCustomField } from "@/api/custom-field";
|
||||||
import CommentEditInput from "@/business/review/view/components/commnet/CommentEditInput";
|
import CommentEditInput from "@/business/review/view/components/commnet/CommentEditInput";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -114,7 +236,8 @@ export default {
|
||||||
CustomFiledComponent,
|
CustomFiledComponent,
|
||||||
EnvPopover,
|
EnvPopover,
|
||||||
MsDialogFooter,
|
MsDialogFooter,
|
||||||
MsInputTag
|
MsInputTag,
|
||||||
|
MsTag,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
typeArr: Array,
|
typeArr: Array,
|
||||||
|
@ -122,8 +245,8 @@ export default {
|
||||||
dialogTitle: {
|
dialogTitle: {
|
||||||
type: String,
|
type: String,
|
||||||
default() {
|
default() {
|
||||||
return this.$t('test_track.case.batch_operate')
|
return this.$t("test_track.case.batch_operate");
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -134,32 +257,36 @@ export default {
|
||||||
appendTag: true,
|
appendTag: true,
|
||||||
customFieldValue: null,
|
customFieldValue: null,
|
||||||
tags: null,
|
tags: null,
|
||||||
value: null
|
value: null,
|
||||||
},
|
},
|
||||||
formLabelWidth: "100px",
|
formLabelWidth: "100px",
|
||||||
size: 0,
|
size: 0,
|
||||||
rules: {
|
rules: {
|
||||||
type: {required: true, message: this.$t('test_track.case.please_select_attr'), trigger: ['blur', 'change']},
|
type: {
|
||||||
|
required: true,
|
||||||
|
message: this.$t("test_track.case.please_select_attr"),
|
||||||
|
trigger: ["blur", "change"],
|
||||||
|
},
|
||||||
value: {
|
value: {
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('test_track.case.please_select_required_value'),
|
message: this.$t("test_track.case.please_select_required_value"),
|
||||||
trigger: ['blur', 'change']
|
trigger: ["blur", "change"],
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('test_track.case.please_select_required_value'),
|
message: this.$t("test_track.case.please_select_required_value"),
|
||||||
trigger: ['blur', 'change']
|
trigger: ["blur", "change"],
|
||||||
},
|
},
|
||||||
customFieldValue: {
|
customFieldValue: {
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('test_track.case.please_select_required_value'),
|
message: this.$t("test_track.case.please_select_required_value"),
|
||||||
trigger: ['blur', 'change']
|
trigger: ["blur", "change"],
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t('test_track.case.please_select_required_value'),
|
message: this.$t("test_track.case.please_select_required_value"),
|
||||||
trigger: ['blur']
|
trigger: ["blur"],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
options: [],
|
options: [],
|
||||||
filterable: false,
|
filterable: false,
|
||||||
|
@ -168,26 +295,33 @@ export default {
|
||||||
selectRows: new Set(),
|
selectRows: new Set(),
|
||||||
allDataRows: new Set(),
|
allDataRows: new Set(),
|
||||||
projectEnvMap: new Map(),
|
projectEnvMap: new Map(),
|
||||||
|
projectEnvDescMap: {},
|
||||||
map: new Map(),
|
map: new Map(),
|
||||||
isScenario: '',
|
isScenario: "",
|
||||||
showDescription: false,
|
showDescription: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
environmentType: ENV_TYPE.JSON,
|
environmentType: ENV_TYPE.JSON,
|
||||||
envGroupId: "",
|
envGroupId: "",
|
||||||
customField: null,
|
customField: null,
|
||||||
fieldType: "",
|
fieldType: "",
|
||||||
showInputTag: true
|
showInputTag: true,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
ENV_TYPE() {
|
ENV_TYPE() {
|
||||||
return ENV_TYPE;
|
return ENV_TYPE;
|
||||||
}
|
},
|
||||||
|
showProjectEnv() {
|
||||||
|
return (
|
||||||
|
this.projectEnvDescMap &&
|
||||||
|
JSON.stringify(this.projectEnvDescMap) !== "{}"
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'customField.defaultValue'() {
|
"customField.defaultValue"() {
|
||||||
this.$set(this.form, 'customFieldValue', this.customField.defaultValue);
|
this.$set(this.form, "customFieldValue", this.customField.defaultValue);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit(form) {
|
submit(form) {
|
||||||
|
@ -198,8 +332,8 @@ export default {
|
||||||
this.$refs[form].validate(async (valid) => {
|
this.$refs[form].validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.form.projectEnvMap = this.projectEnvMap;
|
this.form.projectEnvMap = this.projectEnvMap;
|
||||||
if (this.form.type === 'projectEnv') {
|
if (this.form.type === "projectEnv") {
|
||||||
if (!await this.$refs.envPopover.checkEnv()) {
|
if (!(await this.$refs.envPopover.checkEnv())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.form.map = this.map;
|
this.form.map = this.map;
|
||||||
|
@ -218,14 +352,19 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
validateReviewStatus() {
|
validateReviewStatus() {
|
||||||
if (this.form.type === 'reviewStatus' && this.form.value === 'UnPass' && !this.form.description) {
|
if (
|
||||||
|
this.form.type === "reviewStatus" &&
|
||||||
|
this.form.value === "UnPass" &&
|
||||||
|
!this.form.description
|
||||||
|
) {
|
||||||
this.$refs.commentEditInput.inputLight();
|
this.$refs.commentEditInput.inputLight();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
setProjectEnvMap(projectEnvMap) {
|
setProjectEnvMap(projectEnvMap, projectEnvDescMap) {
|
||||||
this.projectEnvMap = projectEnvMap;
|
this.projectEnvMap = projectEnvMap;
|
||||||
|
this.projectEnvDescMap = projectEnvDescMap;
|
||||||
},
|
},
|
||||||
setEnvGroup(id) {
|
setEnvGroup(id) {
|
||||||
this.envGroupId = id;
|
this.envGroupId = id;
|
||||||
|
@ -234,8 +373,8 @@ export default {
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
this.projectEnvMap.clear();
|
this.projectEnvMap.clear();
|
||||||
this.form = {
|
this.form = {
|
||||||
appendTag: true
|
appendTag: true,
|
||||||
}
|
};
|
||||||
if (size) {
|
if (size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,9 +386,9 @@ export default {
|
||||||
setSelectRows(rows) {
|
setSelectRows(rows) {
|
||||||
this.selectRows = rows;
|
this.selectRows = rows;
|
||||||
this.projectIds.clear();
|
this.projectIds.clear();
|
||||||
this.selectRows.forEach(row => {
|
this.selectRows.forEach((row) => {
|
||||||
this.projectIds.add(row.projectId)
|
this.projectIds.add(row.projectId);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
setScenarioSelectRows(rows, sign) {
|
setScenarioSelectRows(rows, sign) {
|
||||||
this.selectRows = rows;
|
this.selectRows = rows;
|
||||||
|
@ -269,27 +408,29 @@ export default {
|
||||||
let id = val.slice(6);
|
let id = val.slice(6);
|
||||||
this.fieldType = "custom";
|
this.fieldType = "custom";
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getCustomField(id)
|
getCustomField(id).then((res) => {
|
||||||
.then(res => {
|
this.loading = false;
|
||||||
this.loading = false;
|
if (res) {
|
||||||
if (res) {
|
res.data.defaultValue = null;
|
||||||
res.data.defaultValue = null;
|
this.customField = res.data;
|
||||||
this.customField = res.data;
|
} else {
|
||||||
} else {
|
this.customField = { defaultValue: null };
|
||||||
this.customField = {defaultValue: null};
|
}
|
||||||
}
|
this.customField.options = JSON.parse(this.customField.options);
|
||||||
this.customField.options = JSON.parse(this.customField.options);
|
if (
|
||||||
if (this.customField.type === 'checkbox' || this.customField.type === 'multipleMember') {
|
this.customField.type === "checkbox" ||
|
||||||
this.customField.defaultValue = [];
|
this.customField.type === "multipleMember"
|
||||||
}
|
) {
|
||||||
});
|
this.customField.defaultValue = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
changeType(val) {
|
changeType(val) {
|
||||||
this.showDescription = false;
|
this.showDescription = false;
|
||||||
if (val && val.startsWith("custom")) {
|
if (val && val.startsWith("custom")) {
|
||||||
this._handleCustomField(val);
|
this._handleCustomField(val);
|
||||||
}
|
}
|
||||||
if (val === 'tags') {
|
if (val === "tags") {
|
||||||
// 跳过form rules的检查
|
// 跳过form rules的检查
|
||||||
this.$set(this.form, "value", "tags");
|
this.$set(this.form, "value", "tags");
|
||||||
} else {
|
} else {
|
||||||
|
@ -298,7 +439,7 @@ export default {
|
||||||
|
|
||||||
this.filterable = val === "maintainer" || val === "executor";
|
this.filterable = val === "maintainer" || val === "executor";
|
||||||
this.options = this.valueArr[val];
|
this.options = this.valueArr[val];
|
||||||
this.typeArr.forEach(item => {
|
this.typeArr.forEach((item) => {
|
||||||
if (item.id === val) {
|
if (item.id === val) {
|
||||||
if (item.optionMethod) {
|
if (item.optionMethod) {
|
||||||
this.options = [];
|
this.options = [];
|
||||||
|
@ -307,35 +448,35 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.typeArr.forEach(item => {
|
this.typeArr.forEach((item) => {
|
||||||
if (item.id === val && item.uuid) {
|
if (item.id === val && item.uuid) {
|
||||||
this.$set(this.form, "id", item.uuid);
|
this.$set(this.form, "id", item.uuid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (val === 'projectEnv' && this.isScenario !== '') {
|
if (val === "projectEnv" && this.isScenario !== "") {
|
||||||
this.projectIds.clear();
|
this.projectIds.clear();
|
||||||
this.map.clear();
|
this.map.clear();
|
||||||
if (this.allDataRows != null && this.allDataRows.length > 0) {
|
if (this.allDataRows != null && this.allDataRows.length > 0) {
|
||||||
this.allDataRows.forEach(row => {
|
this.allDataRows.forEach((row) => {
|
||||||
this.getApiScenarioProjectId(row);
|
this.getApiScenarioProjectId(row);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.selectRows.forEach(row => {
|
this.selectRows.forEach((row) => {
|
||||||
this.getApiScenarioProjectId(row);
|
this.getApiScenarioProjectId(row);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeValue(val) {
|
changeValue(val) {
|
||||||
if (val === 'UnPass') {
|
if (val === "UnPass") {
|
||||||
this.showDescription = true;
|
this.showDescription = true;
|
||||||
} else {
|
} else {
|
||||||
this.showDescription = false;
|
this.showDescription = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.form.type === 'reviewStatus') {
|
if (this.form.type === "reviewStatus") {
|
||||||
if (val === 'UnPass') {
|
if (val === "UnPass") {
|
||||||
this.rules.description.required = true;
|
this.rules.description.required = true;
|
||||||
} else {
|
} else {
|
||||||
this.rules.description.required = false;
|
this.rules.description.required = false;
|
||||||
|
@ -343,34 +484,32 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getApiScenarioProjectId(row) {
|
getApiScenarioProjectId(row) {
|
||||||
let id = this.isScenario === 'scenario' ? row.id : row.caseId;
|
let id = this.isScenario === "scenario" ? row.id : row.caseId;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getApiScenarioEnvByProjectId(id)
|
getApiScenarioEnvByProjectId(id).then((res) => {
|
||||||
.then(res => {
|
this.loading = false;
|
||||||
this.loading = false;
|
let data = res.data;
|
||||||
let data = res.data;
|
data.projectIds.forEach((d) => this.projectIds.add(d));
|
||||||
data.projectIds.forEach(d => this.projectIds.add(d));
|
this.map.set(row.id, data.projectIds);
|
||||||
this.map.set(row.id, data.projectIds);
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
getWsProjects() {
|
getWsProjects() {
|
||||||
getOwnerProjects()
|
getOwnerProjects().then((res) => {
|
||||||
.then(res => {
|
this.projectList = res.data;
|
||||||
this.projectList = res.data;
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.select-row {
|
.select-row {
|
||||||
font-family: 'PingFang SC';
|
font-family: "PingFang SC";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
color: #646A73;
|
color: #646a73;
|
||||||
flex: none;
|
flex: none;
|
||||||
order: 1;
|
order: 1;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
@ -378,12 +517,12 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-form-item__label) {
|
:deep(.el-form-item__label) {
|
||||||
font-family: 'PingFang SC';
|
font-family: "PingFang SC";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
color: #1F2329;
|
color: #1f2329;
|
||||||
flex: none;
|
flex: none;
|
||||||
order: 0;
|
order: 0;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
@ -391,7 +530,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-button--small span) {
|
:deep(.el-button--small span) {
|
||||||
font-family: 'PingFang SC';
|
font-family: "PingFang SC";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -416,19 +555,19 @@ export default {
|
||||||
|
|
||||||
.batchEditForm :deep(.el-form-item.is-required > .el-form-item__label:after) {
|
.batchEditForm :deep(.el-form-item.is-required > .el-form-item__label:after) {
|
||||||
content: "*";
|
content: "*";
|
||||||
color: #F56C6C;
|
color: #f56c6c;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ms-case-input :deep(.el-tag.el-tag--info) {
|
.ms-case-input :deep(.el-tag.el-tag--info) {
|
||||||
background-color: rgba(31, 35, 41, 0.1);
|
background-color: rgba(31, 35, 41, 0.1);
|
||||||
font-family: 'PingFang SC';
|
font-family: "PingFang SC";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #1F2329;
|
color: #1f2329;
|
||||||
flex: none;
|
flex: none;
|
||||||
order: 1;
|
order: 1;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
@ -442,7 +581,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.ms-case-input :deep(.el-tag.el-tag--info .el-icon-close:hover) {
|
.ms-case-input :deep(.el-tag.el-tag--info .el-icon-close:hover) {
|
||||||
color: #783887;;
|
color: #783887;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,60 +5,70 @@
|
||||||
width="400"
|
width="400"
|
||||||
:disabled="isReadOnly"
|
:disabled="isReadOnly"
|
||||||
@show="showPopover"
|
@show="showPopover"
|
||||||
trigger="click">
|
trigger="click"
|
||||||
<env-select :project-ids="projectIds" :env-map="envMap" @close="visible = false"
|
>
|
||||||
:show-config-button-with-out-permission="showConfigButtonWithOutPermission"
|
<env-select
|
||||||
ref="envSelect" @setProjectEnvMap="setProjectEnvMap" :project-list="projectList"/>
|
:project-ids="projectIds"
|
||||||
<el-button type="primary" slot="reference" size="mini" style="margin-top: 2px;">
|
:env-map="envMap"
|
||||||
{{ $t('api_test.definition.request.run_env') }}
|
@close="visible = false"
|
||||||
|
:show-config-button-with-out-permission="
|
||||||
|
showConfigButtonWithOutPermission
|
||||||
|
"
|
||||||
|
ref="envSelect"
|
||||||
|
@setProjectEnvMap="setProjectEnvMap"
|
||||||
|
:project-list="projectList"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
slot="reference"
|
||||||
|
size="mini"
|
||||||
|
style="margin-top: 2px"
|
||||||
|
>
|
||||||
|
{{ $t("api_test.definition.request.run_env") }}
|
||||||
<i class="el-icon-caret-bottom el-icon--right"></i>
|
<i class="el-icon-caret-bottom el-icon--right"></i>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import EnvSelect from "@/business/plan/env/EnvSelect";
|
import EnvSelect from "@/business/plan/env/EnvSelect";
|
||||||
export default {
|
export default {
|
||||||
name: "EnvPopover",
|
name: "EnvPopover",
|
||||||
components: {EnvSelect},
|
components: { EnvSelect },
|
||||||
props: {
|
props: {
|
||||||
envMap: Map,
|
envMap: Map,
|
||||||
projectIds: Set,
|
projectIds: Set,
|
||||||
projectList: Array,
|
projectList: Array,
|
||||||
showConfigButtonWithOutPermission:{
|
showConfigButtonWithOutPermission: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
isReadOnly: {
|
isReadOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
visible: false
|
visible: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showPopover() {
|
showPopover() {
|
||||||
this.$refs.envSelect.open();
|
this.$refs.envSelect.open();
|
||||||
},
|
},
|
||||||
setProjectEnvMap(map) {
|
setProjectEnvMap(map, groupDescMap) {
|
||||||
this.$emit("setProjectEnvMap", map);
|
this.$emit("setProjectEnvMap", map, groupDescMap);
|
||||||
},
|
},
|
||||||
checkEnv() {
|
checkEnv() {
|
||||||
return this.$refs.envSelect.checkEnv();
|
return this.$refs.envSelect.checkEnv();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,20 +1,41 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="result.loading">
|
<div v-loading="result.loading">
|
||||||
<div v-for="pe in data" :key="pe.id" style="margin-left: 20px;">
|
<div v-for="pe in data" :key="pe.id" style="margin-left: 20px">
|
||||||
<el-select v-model="pe['selectEnv']" filterable :placeholder="$t('api_test.environment.select_environment')"
|
<el-select
|
||||||
style="margin-top: 8px;width: 200px;" size="small">
|
v-model="pe['selectEnv']"
|
||||||
<el-option v-for="(environment, index) in pe.envs" :key="index"
|
filterable
|
||||||
:label="environment.name"
|
:placeholder="$t('api_test.environment.select_environment')"
|
||||||
:value="environment.id"/>
|
style="margin-top: 8px; width: 200px"
|
||||||
<el-button class="ms-scenario-button" v-if="isShowConfirmButton(pe.id)" size="mini" type="primary"
|
size="small"
|
||||||
@click="openEnvironmentConfig(pe.id)">
|
>
|
||||||
{{ $t('api_test.environment.environment_config') }}
|
<el-option
|
||||||
|
v-for="(environment, index) in pe.envs"
|
||||||
|
:key="index"
|
||||||
|
:label="environment.name"
|
||||||
|
:value="environment.id"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
class="ms-scenario-button"
|
||||||
|
v-if="isShowConfirmButton(pe.id)"
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
@click="openEnvironmentConfig(pe.id)"
|
||||||
|
>
|
||||||
|
{{ $t("api_test.environment.environment_config") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<template v-slot:empty>
|
<template v-slot:empty>
|
||||||
<!--这里只做没有可搜索内容时使用,否则如果没有符合搜索条件的,也会显示该项,与上面的btn重复显示 -->
|
<!--这里只做没有可搜索内容时使用,否则如果没有符合搜索条件的,也会显示该项,与上面的btn重复显示 -->
|
||||||
<div v-if="isShowConfirmButton(pe.id) && pe.envs.length===0" class="empty-environment">
|
<div
|
||||||
<el-button class="ms-scenario-button" size="mini" type="primary" @click="openEnvironmentConfig(pe.id)">
|
v-if="isShowConfirmButton(pe.id) && pe.envs.length === 0"
|
||||||
{{ $t('api_test.environment.environment_config') }}
|
class="empty-environment"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
class="ms-scenario-button"
|
||||||
|
size="mini"
|
||||||
|
type="primary"
|
||||||
|
@click="openEnvironmentConfig(pe.id)"
|
||||||
|
>
|
||||||
|
{{ $t("api_test.environment.environment_config") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -24,24 +45,32 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button type="primary" @click="handleConfirm" size="small" class="env-confirm">{{ $t('commons.confirm') }}
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleConfirm"
|
||||||
|
size="small"
|
||||||
|
class="env-confirm"
|
||||||
|
>{{ $t("commons.confirm") }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<!-- 环境配置 -->
|
<!-- 环境配置 -->
|
||||||
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
<api-environment-config
|
||||||
|
ref="environmentConfig"
|
||||||
|
@close="environmentConfigClose"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {parseEnvironment} from "metersphere-frontend/src/model/EnvironmentModel";
|
import { parseEnvironment } from "metersphere-frontend/src/model/EnvironmentModel";
|
||||||
import ApiEnvironmentConfig from "metersphere-frontend/src/components/environment/ApiEnvironmentConfig";
|
import ApiEnvironmentConfig from "metersphere-frontend/src/components/environment/ApiEnvironmentConfig";
|
||||||
import {getOwnerProjectIds} from "@/api/project";
|
import { getOwnerProjectIds } from "@/api/project";
|
||||||
import {getEnvironmentByProjectId} from "@/api/remote/api/api-environment";
|
import { getEnvironmentByProjectId } from "@/api/remote/api/api-environment";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "EnvSelect",
|
name: "EnvSelect",
|
||||||
components: {
|
components: {
|
||||||
ApiEnvironmentConfig
|
ApiEnvironmentConfig,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
envMap: Map,
|
envMap: Map,
|
||||||
|
@ -50,14 +79,14 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
projectList: Array
|
projectList: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: [],
|
data: [],
|
||||||
result: {loading: false},
|
result: { loading: false },
|
||||||
projects: [],
|
projects: [],
|
||||||
environments: [],
|
environments: [],
|
||||||
permissionProjectIds: [],
|
permissionProjectIds: [],
|
||||||
|
@ -87,28 +116,28 @@ export default {
|
||||||
this.getUserPermissionProjectIds();
|
this.getUserPermissionProjectIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.projectIds.forEach(id => {
|
this.projectIds.forEach((id) => {
|
||||||
const project = this.projectList.find(p => p.id === id);
|
const project = this.projectList.find((p) => p.id === id);
|
||||||
if (project) {
|
if (project) {
|
||||||
let item = {id: id, envs: [], selectEnv: ""};
|
let item = { id: id, envs: [], selectEnv: "" };
|
||||||
this.data.push(item);
|
this.data.push(item);
|
||||||
this.result.loading = true;
|
this.result.loading = true;
|
||||||
getEnvironmentByProjectId(id)
|
getEnvironmentByProjectId(id).then((res) => {
|
||||||
.then(res => {
|
this.result.loading = false;
|
||||||
this.result.loading = false;
|
let envs = res.data;
|
||||||
let envs = res.data;
|
envs.forEach((environment) => {
|
||||||
envs.forEach(environment => {
|
parseEnvironment(environment);
|
||||||
parseEnvironment(environment);
|
|
||||||
});
|
|
||||||
// 固定环境列表渲染顺序
|
|
||||||
let temp = this.data.find(dt => dt.id === id);
|
|
||||||
temp.envs = envs;
|
|
||||||
if (this.envMap && this.envMap.size > 0) {
|
|
||||||
let envId = this.envMap.get(id);
|
|
||||||
// 选中环境是否存在
|
|
||||||
temp.selectEnv = envs.filter(e => e.id === envId).length === 0 ? null : envId;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
// 固定环境列表渲染顺序
|
||||||
|
let temp = this.data.find((dt) => dt.id === id);
|
||||||
|
temp.envs = envs;
|
||||||
|
if (this.envMap && this.envMap.size > 0) {
|
||||||
|
let envId = this.envMap.get(id);
|
||||||
|
// 选中环境是否存在
|
||||||
|
temp.selectEnv =
|
||||||
|
envs.filter((e) => e.id === envId).length === 0 ? null : envId;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -119,12 +148,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getProjectName(id) {
|
getProjectName(id) {
|
||||||
const project = this.projectList.find(p => p.id === id);
|
const project = this.projectList.find((p) => p.id === id);
|
||||||
return project ? project.name : "";
|
return project ? project.name : "";
|
||||||
},
|
},
|
||||||
openEnvironmentConfig(projectId) {
|
openEnvironmentConfig(projectId) {
|
||||||
if (!projectId) {
|
if (!projectId) {
|
||||||
this.$error(this.$t('api_test.select_project'));
|
this.$error(this.$t("api_test.select_project"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$refs.environmentConfig.open(projectId);
|
this.$refs.environmentConfig.open(projectId);
|
||||||
|
@ -132,25 +161,30 @@ export default {
|
||||||
handleConfirm() {
|
handleConfirm() {
|
||||||
let map = new Map();
|
let map = new Map();
|
||||||
let sign = true;
|
let sign = true;
|
||||||
this.data.forEach(dt => {
|
let projectEnvDesc = {};
|
||||||
|
this.data.forEach((dt) => {
|
||||||
if (!dt.selectEnv) {
|
if (!dt.selectEnv) {
|
||||||
sign = false;
|
sign = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
map.set(dt.id, dt.selectEnv);
|
map.set(dt.id, dt.selectEnv);
|
||||||
|
let filteredEnv = dt.envs.filter((e) => e.id === dt.selectEnv);
|
||||||
|
if (filteredEnv.length > 0) {
|
||||||
|
projectEnvDesc[this.getProjectName(dt.id)] = filteredEnv[0].name;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (!sign) {
|
if (!sign) {
|
||||||
this.$warning("请为当前场景选择一个运行环境!");
|
this.$warning("请为当前场景选择一个运行环境!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$emit('setProjectEnvMap', map);
|
this.$emit("setProjectEnvMap", map, projectEnvDesc);
|
||||||
this.$emit('close');
|
this.$emit("close");
|
||||||
},
|
},
|
||||||
checkEnv() {
|
checkEnv() {
|
||||||
let sign = true;
|
let sign = true;
|
||||||
this.isFullUrl = true;
|
this.isFullUrl = true;
|
||||||
if (this.data.length > 0) {
|
if (this.data.length > 0) {
|
||||||
this.data.forEach(dt => {
|
this.data.forEach((dt) => {
|
||||||
if (!dt.selectEnv) {
|
if (!dt.selectEnv) {
|
||||||
sign = false;
|
sign = false;
|
||||||
return false;
|
return false;
|
||||||
|
@ -159,7 +193,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
// 如果有环境,检查环境
|
// 如果有环境,检查环境
|
||||||
if (this.envMap && this.envMap.size > 0) {
|
if (this.envMap && this.envMap.size > 0) {
|
||||||
this.projectIds.forEach(id => {
|
this.projectIds.forEach((id) => {
|
||||||
if (!this.envMap.get(id)) {
|
if (!this.envMap.get(id)) {
|
||||||
sign = false;
|
sign = false;
|
||||||
return false;
|
return false;
|
||||||
|
@ -180,12 +214,11 @@ export default {
|
||||||
// todo 关闭处理
|
// todo 关闭处理
|
||||||
},
|
},
|
||||||
getUserPermissionProjectIds() {
|
getUserPermissionProjectIds() {
|
||||||
getOwnerProjectIds()
|
getOwnerProjectIds().then((res) => {
|
||||||
.then(res => {
|
this.permissionProjectIds = res.data;
|
||||||
this.permissionProjectIds = res.data;
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue