refactor: 评论展开收起
This commit is contained in:
parent
28c7f3abbb
commit
ee591fc936
|
@ -79,8 +79,8 @@ export function groupDeleteEnv(data: EnvListItem) {
|
|||
return MSR.post<EnvListItem>({ url: envURL.groupDeleteEnvUrl, data });
|
||||
}
|
||||
// 获取项目组的项目
|
||||
export function groupProjectEnv() {
|
||||
return MSR.get<ProjectOptionItem[]>({ url: envURL.groupProjectEnvUrl });
|
||||
export function groupProjectEnv(organizationId: string) {
|
||||
return MSR.get<ProjectOptionItem[]>({ url: envURL.groupProjectEnvUrl + organizationId });
|
||||
}
|
||||
|
||||
/** 项目管理-环境-全局参数-更新or新增 */
|
||||
|
|
|
@ -17,7 +17,7 @@ export const groupDetailEnvUrl = '/project/environment/group/get/';
|
|||
export const groupDeleteEnvUrl = '/project/environment/group/delete/';
|
||||
export const getEnvPluginUrl = '/project/environment/scripts/';
|
||||
// 获取项目组的项目
|
||||
export const groupProjectEnvUrl = '/project/environment/group/get-project';
|
||||
export const groupProjectEnvUrl = '/project/environment/group/get-project/';
|
||||
// 全局参数
|
||||
export const updateGlobalParamUrl = '/project/global/params/update';
|
||||
export const addGlobalParamUrl = '/project/global/params/add';
|
||||
|
|
|
@ -95,3 +95,10 @@ body {
|
|||
background: rgb(var(--primary-6));
|
||||
}
|
||||
}
|
||||
|
||||
/* 评论组件的样式 */
|
||||
.ms-comment-child-container {
|
||||
padding: 16px;
|
||||
border: 0.5px solid var(--color-text-input-border); /* 设置近似 0.5px 的边框 */
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
|
@ -51,18 +51,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {defineModel, ref} from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { defineModel, ref } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
|
||||
import MsIconfont from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
|
||||
import MsIconfont from '@/components/pure/ms-icon-font/index.vue';
|
||||
|
||||
import {useI18n} from '@/hooks/useI18n';
|
||||
import useUserStore from '@/store/modules/user/index';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useUserStore from '@/store/modules/user/index';
|
||||
|
||||
import {CommentItem} from './types';
|
||||
import { CommentItem } from './types';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userStore = useUserStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
defineOptions({ name: 'MsCommentItem' });
|
||||
|
@ -86,12 +86,14 @@ const userStore = useUserStore();
|
|||
(event: 'reply'): void;
|
||||
(event: 'edit'): void;
|
||||
(event: 'delete'): void;
|
||||
(event: 'expend', value: boolean): void;
|
||||
}>();
|
||||
|
||||
const expendComment = ref(false);
|
||||
|
||||
const expendChange = () => {
|
||||
expendComment.value = !expendComment.value;
|
||||
emit('expend', expendComment.value);
|
||||
};
|
||||
const replyClick = () => {
|
||||
emit('reply');
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
import Item from './comment-item.vue';
|
||||
import CommentInput from './input.vue';
|
||||
|
||||
import {useI18n} from '@/hooks/useI18n';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import {CommentEvent, CommentItem, CommentParams, CommentType} from './types';
|
||||
import { CommentEvent, CommentItem, CommentParams, CommentType } from './types';
|
||||
import message from '@arco-design/web-vue/es/message';
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -33,6 +33,7 @@ export default defineComponent({
|
|||
// 控制回复编辑删除按钮的状态
|
||||
commentStatus: 'normal',
|
||||
});
|
||||
const expendedIds = ref<string[]>([]); // 展开的评论id
|
||||
// 被@的用户id
|
||||
const noticeUserIds = ref<string[]>([]);
|
||||
const { t } = useI18n();
|
||||
|
@ -85,6 +86,16 @@ export default defineComponent({
|
|||
emit('delete', item.id);
|
||||
};
|
||||
|
||||
const handleExpend = (val: boolean, id: string) => {
|
||||
if (val) {
|
||||
// 展开
|
||||
expendedIds.value = [...expendedIds.value, id];
|
||||
} else {
|
||||
// 收起
|
||||
expendedIds.value = expendedIds.value.filter((item) => item !== id);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReply = (item: CommentItem) => {
|
||||
if (item.childComments && Array.isArray(item.childComments)) {
|
||||
// 点击的是父级评论的回复
|
||||
|
@ -122,8 +133,8 @@ export default defineComponent({
|
|||
if (!list || list.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return list.map((item) => {
|
||||
return (
|
||||
|
||||
return list.map((item) => (
|
||||
<div class="flex flex-col">
|
||||
<Item
|
||||
mode={'child'}
|
||||
|
@ -138,33 +149,30 @@ export default defineComponent({
|
|||
/>
|
||||
{item.id === currentItem.id && renderInput(item)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
));
|
||||
};
|
||||
|
||||
const renderParentList = (list: CommentItem[]) => {
|
||||
return list.map((item) => {
|
||||
return (
|
||||
return list.map((item) => (
|
||||
<>
|
||||
<Item
|
||||
mode={'parent'}
|
||||
onReply={() => handleReply(item)}
|
||||
onEdit={() => handelEdit(item)}
|
||||
onDelete={() => handleDelete(item)}
|
||||
onExpend={(val: boolean) => handleExpend(val, item.id)}
|
||||
status={item.id === currentItem.id ? currentItem.commentStatus : 'normal'}
|
||||
onUpdate:status={(v: string) => {
|
||||
currentItem.commentStatus = v;
|
||||
}}
|
||||
element={item}
|
||||
>
|
||||
<div class="rounded border border-[var(--color-text-7)] p-[16px]">
|
||||
{renderChildrenList(item.childComments)}
|
||||
</div>
|
||||
</Item>
|
||||
/>
|
||||
{expendedIds.value.includes(item.id) && (
|
||||
<div class="ms-comment-child-container">{renderChildrenList(item.childComments)}</div>
|
||||
)}
|
||||
{item.id === currentItem.id && renderInput(item)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
));
|
||||
};
|
||||
|
||||
return () => <div class="ms-comment gap[24px] flex flex-col">{renderParentList(commentList.value)}</div>;
|
||||
|
|
|
@ -372,6 +372,10 @@ export default defineComponent(
|
|||
}
|
||||
emit('update:modelValue', value);
|
||||
emit('change', value);
|
||||
emit(
|
||||
'changeObject',
|
||||
remoteOriginOptions.value.filter((e) => value === e[props.valueKey || 'value'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,6 +548,14 @@ export default defineComponent(
|
|||
'disabled',
|
||||
'size',
|
||||
],
|
||||
emits: ['update:modelValue', 'remoteSearch', 'popupVisibleChange', 'update:loading', 'remove', 'change'],
|
||||
emits: [
|
||||
'update:modelValue',
|
||||
'remoteSearch',
|
||||
'popupVisibleChange',
|
||||
'update:loading',
|
||||
'remove',
|
||||
'change',
|
||||
'changeObject',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
|
|
@ -209,7 +209,11 @@
|
|||
const handleMouseMove = (_event: MouseEvent) => {
|
||||
if (resizing.value) {
|
||||
const newWidth = initialWidth + (startX - _event.clientX); // 新的宽度等于当前抽屉宽度+鼠标移动的距离
|
||||
if (newWidth >= (props.width || 480) && newWidth <= window.innerWidth * 0.9) {
|
||||
if (
|
||||
typeof props.width === 'number' &&
|
||||
newWidth >= (props.width || 480) &&
|
||||
newWidth <= window.innerWidth * 0.9
|
||||
) {
|
||||
// 最大最小宽度限制,最小宽度为传入的width或480,最大宽度为视图窗口宽度的90%
|
||||
drawerWidth.value = newWidth;
|
||||
}
|
||||
|
|
|
@ -291,20 +291,62 @@
|
|||
</a-tooltip>
|
||||
<a-input v-model="record.matchValue" size="mini" class="param-input" />
|
||||
</template>
|
||||
<template #project="{ record, columnConfig, rowIndex }">
|
||||
<template #project="{ record, rowIndex }">
|
||||
<a-select
|
||||
v-model="record.projectId"
|
||||
class="param-input"
|
||||
size="mini"
|
||||
@change="(val) => handelProjectChange(val as string, record.projectId, rowIndex)"
|
||||
v-model:model-value="record.projectId"
|
||||
class="param-input w-max-[200px] focus-within:!bg-[var(--color-text-n8)] hover:!bg-[var(--color-text-n8)]"
|
||||
:bordered="false"
|
||||
allow-search
|
||||
@change="(val) => handleProjectChange(val as string,record.projectId, rowIndex)"
|
||||
>
|
||||
<a-option v-for="item in columnConfig.options" :key="item.id">{{ item.name }}</a-option>
|
||||
<template #arrow-icon>
|
||||
<icon-caret-down />
|
||||
</template>
|
||||
<a-tooltip
|
||||
v-for="project of appStore.projectList"
|
||||
:key="project.id"
|
||||
:mouse-enter-delay="500"
|
||||
:content="project.name"
|
||||
>
|
||||
<a-option
|
||||
:value="project.id"
|
||||
:class="project.id === appStore.currentProjectId ? 'arco-select-option-selected' : ''"
|
||||
>
|
||||
{{ project.name }}
|
||||
</a-option>
|
||||
</a-tooltip>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #environment="{ record, columnConfig }">
|
||||
<a-select v-model="record.environmentId" size="mini" class="param-input">
|
||||
<a-option v-for="item in columnConfig.options" :key="item.id">{{ item.name }}</a-option>
|
||||
</a-select>
|
||||
<template #environment="{ record }">
|
||||
<MsSelect
|
||||
v-if="record.projectId"
|
||||
v-model:model-value="record.environmentId"
|
||||
v-model:input-value="record.environmentInput"
|
||||
:disabled="!record.projectId"
|
||||
:options="[]"
|
||||
mode="remote"
|
||||
value-key="id"
|
||||
label-key="name"
|
||||
:search-keys="['name']"
|
||||
size="mini"
|
||||
allow-search
|
||||
class="param-input"
|
||||
:remote-func="initEnvOptions"
|
||||
:remote-extra-params="{ projectId: record.projectId, keyword: record.environmentInput }"
|
||||
@change-object="(val) => handleEnvironment(val, record)"
|
||||
/>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
<template #host="{ record }">
|
||||
<span v-if="record.host.length === 1" class="text-[var(--color-text-4)]">{{ record.host }}</span>
|
||||
<span
|
||||
v-if="record.host.length > 1"
|
||||
class="cursor-pointer text-[var(--color-text-4)]"
|
||||
@click="showHostModal(record)"
|
||||
>
|
||||
{{ t('common.more') }}
|
||||
</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
<template #operation="{ record, rowIndex, columnConfig }">
|
||||
<div class="flex flex-row items-center" :class="{ 'justify-end': columnConfig.align === 'right' }">
|
||||
|
@ -399,6 +441,9 @@
|
|||
:max-length="1000"
|
||||
></a-textarea>
|
||||
</a-modal>
|
||||
<a-modal v-model:visible="hostVisible" :title="t('apiTestDebug.host')" @close="hostModalClose">
|
||||
<a-table :columns="hostColumn" :data="hostData"> </a-table>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script async setup lang="ts">
|
||||
|
@ -415,12 +460,15 @@
|
|||
import MsTagsGroup from '@/components/pure/ms-tag/ms-tag-group.vue';
|
||||
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import MsSelect from '@/components/business/ms-select/index';
|
||||
import paramDescInput from './paramDescInput.vue';
|
||||
|
||||
import { groupProjectEnv, listEnv } from '@/api/modules/project-management/envManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { ProjectOptionItem } from '@/models/projectManagement/environmental';
|
||||
import { RequestBodyFormat, RequestContentTypeEnum, RequestParamsType } from '@/enums/apiEnum';
|
||||
import { SelectAllEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
|
@ -632,6 +680,70 @@
|
|||
};
|
||||
/** 断言-文档-end */
|
||||
|
||||
/** 环境管理-环境组 start */
|
||||
|
||||
const sourceProjectOptions = ref<ProjectOptionItem[]>([]);
|
||||
|
||||
// 获取项目的options
|
||||
const initProjectOptions = async () => {
|
||||
const res = await groupProjectEnv(appStore.currentOrgId);
|
||||
sourceProjectOptions.value = res;
|
||||
};
|
||||
// 获取环境的options
|
||||
const initEnvOptions = async (params: Record<string, any>) => {
|
||||
const { projectId, keyword } = params;
|
||||
const res = await listEnv({ projectId, keyword });
|
||||
return res;
|
||||
};
|
||||
|
||||
const handleEnvironment = (obj: Record<string, any>, record: Record<string, any>) => {
|
||||
record.host = obj.host;
|
||||
emit('change', propsRes.value.data);
|
||||
};
|
||||
|
||||
const hostVisible = ref(false);
|
||||
const hostData = ref<any[]>([]);
|
||||
const hostColumn = [
|
||||
{
|
||||
title: 'project.environmental.http.host',
|
||||
dataIndex: 'host',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.http.desc',
|
||||
dataIndex: 'desc',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.http.applyScope',
|
||||
dataIndex: 'applyScope',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.http.enableScope',
|
||||
dataIndex: 'enableScope',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.http.value',
|
||||
dataIndex: 'value',
|
||||
},
|
||||
];
|
||||
|
||||
const showHostModal = (record: Record<string, any>) => {
|
||||
hostVisible.value = true;
|
||||
hostData.value = record.hostList || [];
|
||||
};
|
||||
|
||||
const hostModalClose = () => {
|
||||
hostVisible.value = false;
|
||||
hostData.value = [];
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.columns.some((e) => e.dataIndex === 'projectId')) {
|
||||
initProjectOptions();
|
||||
}
|
||||
});
|
||||
|
||||
/** 环境管理-环境组 end */
|
||||
|
||||
/**
|
||||
* 当表格输入框变化时,给参数表格添加一行数据行
|
||||
* @param val 输入值
|
||||
|
@ -813,7 +925,7 @@
|
|||
emit('moreActionSelect', event, record);
|
||||
}
|
||||
|
||||
function handelProjectChange(val: string, projectId: string, rowIndex: number) {
|
||||
function handleProjectChange(val: string, projectId: string, rowIndex: number) {
|
||||
emit('projectChange', projectId);
|
||||
addTableLine(rowIndex);
|
||||
}
|
||||
|
@ -851,6 +963,9 @@
|
|||
.arco-select-view-value {
|
||||
color: var(--color-text-brand);
|
||||
}
|
||||
.arco-select {
|
||||
border-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.param-input-number) {
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MsComment from '@/components/business/ms-comment';
|
||||
import {CommentItem, CommentParams} from '@/components/business/ms-comment/types';
|
||||
import MsComment from '@/components/business/ms-comment';
|
||||
import { CommentItem, CommentParams } from '@/components/business/ms-comment/types';
|
||||
|
||||
import {createOrUpdateComment, deleteComment, getCommentList} from '@/api/modules/bug-management/index';
|
||||
import {useI18n} from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { createOrUpdateComment, deleteComment, getCommentList } from '@/api/modules/bug-management/index';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
|
||||
import message from '@arco-design/web-vue/es/message';
|
||||
import message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const { openModal } = useModal();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const props = defineProps<{
|
||||
bugId: string;
|
||||
|
|
|
@ -52,16 +52,12 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script lang="ts" setup async>
|
||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
import { groupProjectEnv, listEnv } from '@/api/modules/project-management/envManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
|
||||
import { EnvListItem, ProjectOptionItem } from '@/models/projectManagement/environmental';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const envGroupForm = ref();
|
||||
|
@ -70,31 +66,25 @@
|
|||
description: '',
|
||||
});
|
||||
const store = useProjectEnvStore();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const sourceProjectOptions = ref<ProjectOptionItem[]>([]);
|
||||
const projectOptions = computed(() => {
|
||||
return sourceProjectOptions.value;
|
||||
});
|
||||
const environmentOptions = ref<EnvListItem[]>([]);
|
||||
|
||||
const columns = computed<ParamTableColumn[]>(() => [
|
||||
{
|
||||
title: 'project.environmental.project',
|
||||
dataIndex: 'projectId',
|
||||
slotName: 'project',
|
||||
options: projectOptions.value,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.env',
|
||||
dataIndex: 'environmentId',
|
||||
slotName: 'environment',
|
||||
options: environmentOptions.value,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.host',
|
||||
dataIndex: 'host',
|
||||
slotName: 'host',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.desc',
|
||||
|
@ -123,24 +113,9 @@
|
|||
}
|
||||
});
|
||||
};
|
||||
// 获取项目的options
|
||||
const initProjectOptions = async () => {
|
||||
const res = await groupProjectEnv();
|
||||
sourceProjectOptions.value = res;
|
||||
};
|
||||
// 获取环境的options
|
||||
const initEnvOptions = async () => {
|
||||
const res = await listEnv({ projectId: appStore.currentProjectId, keyword: '' });
|
||||
environmentOptions.value = res;
|
||||
};
|
||||
|
||||
function handleParamTableChange(resultArr: any[]) {
|
||||
innerParams.value = [...resultArr];
|
||||
}
|
||||
onMounted(() => {
|
||||
initProjectOptions();
|
||||
initEnvOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
>
|
||||
<template #prefix>
|
||||
<div class="input-prefix">
|
||||
<a-select>
|
||||
<a-select default-value="like">
|
||||
<a-option v-for="item in OPERATOR_MAP.string" :key="item.value" :value="item.value">{{
|
||||
t(item.label)
|
||||
}}</a-option>
|
||||
|
@ -192,9 +192,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: 1px solid var(--color-text-n7);
|
||||
border-radius: 0 4px 4px 0;
|
||||
background: var(--color-text-n8);
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
const envList = ref<EnvListItem[]>([]); // 环境列表
|
||||
const evnGroupList = ref<EnvListItem[]>([]); // 环境组列表
|
||||
|
||||
const showType = ref<EnvAuthScopeEnum>(EnvAuthScopeEnum.PROJECT); // 展示类型
|
||||
const showType = ref<EnvAuthScopeEnum>(EnvAuthScopeEnum.PROJECT_GROUP); // 展示类型
|
||||
|
||||
const activeKey = computed(() => store.currentId); // 当前选中的id
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export default {
|
|||
'project.environmental.http.apiModuleSelect': 'Select API Test Module',
|
||||
'project.environmental.http.uiModuleSelect': 'Select UI Test Module',
|
||||
'project.environmental.http.pathRequired': 'Path is required',
|
||||
'project.environmental.http.pathPlaceholder': 'Please enter the path',
|
||||
'project.environmental.database.addDatabase': 'Add Database',
|
||||
'project.environmental.database.updateDatabase': 'Update Database {name}',
|
||||
'project.environmental.database.name': 'Database Name',
|
||||
|
|
|
@ -61,6 +61,7 @@ export default {
|
|||
'project.environmental.http.apiModuleSelect': '接口模块选择',
|
||||
'project.environmental.http.uiModuleSelect': '选择UI测试模块',
|
||||
'project.environmental.http.pathRequired': '路径必填',
|
||||
'project.environmental.http.pathPlaceholder': '请输入路径',
|
||||
'project.environmental.database.addDatabase': '添加数据源',
|
||||
'project.environmental.database.updateDatabase': '更新数据源{name}',
|
||||
'project.environmental.database.name': '数据源名称',
|
||||
|
|
Loading…
Reference in New Issue