feat(功能测试): 调整功能用例气泡确认框
This commit is contained in:
parent
e36278861f
commit
8aa3b9cce7
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popover
|
<a-popover
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
|
v-model:popup-visible="currentVisible"
|
||||||
:type="props.type"
|
:type="props.type"
|
||||||
:popup-visible="currentVisible"
|
|
||||||
:class="props.isDelete ? 'w-[352px]' : ''"
|
:class="props.isDelete ? 'w-[352px]' : ''"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
:popup-container="props.popupContainer || 'body'"
|
:popup-container="props.popupContainer || 'body'"
|
||||||
:position="props.isDelete ? 'bottom' : 'rb'"
|
:position="props.isDelete ? 'rb' : 'bottom'"
|
||||||
@popup-visible-change="reset"
|
@popup-visible-change="reset"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
<template>
|
|
||||||
<a-popconfirm
|
|
||||||
v-model:popup-visible="isVisible"
|
|
||||||
class="ms-pop-confirm--hidden-icon"
|
|
||||||
position="bottom"
|
|
||||||
:ok-loading="loading"
|
|
||||||
:on-before-ok="beforeConfirm"
|
|
||||||
:popup-container="props.popupContainer || 'body'"
|
|
||||||
@popup-visible-change="visibleChange"
|
|
||||||
>
|
|
||||||
<template #content>
|
|
||||||
<div class="mb-[8px] font-medium">
|
|
||||||
{{ props.title || '' }}
|
|
||||||
</div>
|
|
||||||
<a-form ref="formRef" :model="form" layout="vertical">
|
|
||||||
<a-form-item
|
|
||||||
class="hidden-item"
|
|
||||||
field="name"
|
|
||||||
:rules="[{ required: true, message: t('featureTest.featureCase.nameNotNullTip') }]"
|
|
||||||
>
|
|
||||||
<a-input
|
|
||||||
v-model:model-value="form.name"
|
|
||||||
:max-length="50"
|
|
||||||
:placeholder="props.placeholder || ''"
|
|
||||||
class="w-[245px]"
|
|
||||||
@press-enter="beforeConfirm(undefined)"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</template>
|
|
||||||
<slot></slot>
|
|
||||||
</a-popconfirm>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, watch } from 'vue';
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
|
||||||
import type { FormInstance } from '@arco-design/web-vue';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
export type OperationType = 'add' | 'rename';
|
|
||||||
|
|
||||||
const isVisible = ref<boolean>(false);
|
|
||||||
|
|
||||||
const loading = ref<boolean>(false);
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
operationType: OperationType;
|
|
||||||
title: string;
|
|
||||||
nodeName?: string;
|
|
||||||
visible?: boolean;
|
|
||||||
popupContainer?: string;
|
|
||||||
placeholder?: string;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emits = defineEmits<{
|
|
||||||
(e: 'update:visible', visible: boolean): void;
|
|
||||||
(e: 'close'): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const form = ref({
|
|
||||||
name: props.title || '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
const visibleChange = () => {
|
|
||||||
form.value.name = '';
|
|
||||||
formRef.value?.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
const beforeConfirm = (done?: (closed: boolean) => void) => {
|
|
||||||
formRef.value?.validate(async (errors) => {
|
|
||||||
if (!errors) {
|
|
||||||
try {
|
|
||||||
loading.value = true;
|
|
||||||
Message.success(
|
|
||||||
props.operationType === 'add'
|
|
||||||
? t('featureTest.featureCase.addSubModuleSuccess')
|
|
||||||
: t('featureTest.featureCase.renameSuccess')
|
|
||||||
);
|
|
||||||
if (done) {
|
|
||||||
done(true);
|
|
||||||
} else {
|
|
||||||
isVisible.value = false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
} else if (done) {
|
|
||||||
done(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.nodeName,
|
|
||||||
(val) => {
|
|
||||||
form.value.name = val || '';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.visible,
|
|
||||||
(val) => {
|
|
||||||
isVisible.value = val;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => isVisible.value,
|
|
||||||
(val) => {
|
|
||||||
if (!val) {
|
|
||||||
emits('close');
|
|
||||||
}
|
|
||||||
emits('update:visible', val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -18,7 +18,7 @@
|
||||||
:type="isExpandFilter ? 'primary' : 'default'"
|
:type="isExpandFilter ? 'primary' : 'default'"
|
||||||
:theme="isExpandFilter ? 'lightOutLine' : 'outline'"
|
:theme="isExpandFilter ? 'lightOutLine' : 'outline'"
|
||||||
size="large"
|
size="large"
|
||||||
class="-mt-[3px] cursor-pointer"
|
class="-mt-[3px] min-w-[64px] cursor-pointer"
|
||||||
>
|
>
|
||||||
<span :class="!isExpandFilter ? 'text-[var(--color-text-4)]' : ''" @click="isExpandFilterHandler"
|
<span :class="!isExpandFilter ? 'text-[var(--color-text-4)]' : ''" @click="isExpandFilterHandler"
|
||||||
><icon-filter class="mr-[4px]" :style="{ 'font-size': '16px' }" />{{
|
><icon-filter class="mr-[4px]" :style="{ 'font-size': '16px' }" />{{
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
:expand-all="props.isExpandAll"
|
:expand-all="props.isExpandAll"
|
||||||
:empty-text="t('featureTest.featureCase.caseEmptyContent')"
|
:empty-text="t('featureTest.featureCase.caseEmptyContent')"
|
||||||
draggable
|
draggable
|
||||||
|
:virtual-list-props="virtualListProps"
|
||||||
block-node
|
block-node
|
||||||
@select="caseNodeSelect"
|
@select="caseNodeSelect"
|
||||||
@more-action-select="handleCaseMoreSelect"
|
@more-action-select="handleCaseMoreSelect"
|
||||||
|
@ -18,25 +19,25 @@
|
||||||
<span class="ml-[4px] text-[var(--color-text-4)]">({{ nodeData.count }})</span>
|
<span class="ml-[4px] text-[var(--color-text-4)]">({{ nodeData.count }})</span>
|
||||||
</template>
|
</template>
|
||||||
<template #extra="nodeData">
|
<template #extra="nodeData">
|
||||||
<ActionPopConfirm
|
<MsPopConfirm
|
||||||
operation-type="add"
|
:is-delete="false"
|
||||||
:all-names="[]"
|
:all-names="[]"
|
||||||
:title="t('featureTest.featureCase.addSubModule')"
|
:title="t('featureTest.featureCase.addSubModule')"
|
||||||
@close="resetFocusNodeKey"
|
@cancel="resetFocusNodeKey"
|
||||||
>
|
>
|
||||||
<MsButton type="icon" size="mini" class="ms-tree-node-extra__btn !mr-0" @click="setFocusKey(nodeData)">
|
<MsButton type="icon" size="mini" class="ms-tree-node-extra__btn !mr-0" @click="setFocusKey(nodeData)">
|
||||||
<MsIcon type="icon-icon_add_outlined" size="14" class="text-[var(--color-text-4)]" />
|
<MsIcon type="icon-icon_add_outlined" size="14" class="text-[var(--color-text-4)]" />
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</ActionPopConfirm>
|
</MsPopConfirm>
|
||||||
<ActionPopConfirm
|
<MsPopConfirm
|
||||||
operation-type="rename"
|
|
||||||
:title="t('featureTest.featureCase.rename')"
|
:title="t('featureTest.featureCase.rename')"
|
||||||
:node-name="renameCaseName"
|
|
||||||
:all-names="[]"
|
:all-names="[]"
|
||||||
@close="resetFocusNodeKey"
|
:is-delete="false"
|
||||||
|
:field-config="{ field: renameCaseName }"
|
||||||
|
@cancel="resetFocusNodeKey"
|
||||||
>
|
>
|
||||||
<span :id="`renameSpan${nodeData.key}`" class="relative"></span>
|
<span :id="`renameSpan${nodeData.key}`" class="relative"></span>
|
||||||
</ActionPopConfirm>
|
</MsPopConfirm>
|
||||||
</template>
|
</template>
|
||||||
</MsTree>
|
</MsTree>
|
||||||
<div class="recycle w-[88%]">
|
<div class="recycle w-[88%]">
|
||||||
|
@ -50,15 +51,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import MsTree from '@/components/business/ms-tree/index.vue';
|
import MsTree from '@/components/business/ms-tree/index.vue';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import useModal from '@/hooks/useModal';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
|
||||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
|
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
|
||||||
import ActionPopConfirm from './actionPopConfirm.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { openModal } = useModal();
|
||||||
|
|
||||||
const focusNodeKey = ref<string | number>('');
|
const focusNodeKey = ref<string | number>('');
|
||||||
|
|
||||||
|
@ -82,6 +86,36 @@
|
||||||
key: 'node2',
|
key: 'node2',
|
||||||
count: 28,
|
count: 28,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -99,6 +133,36 @@
|
||||||
key: 'node5',
|
key: 'node5',
|
||||||
count: 108,
|
count: 108,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node4',
|
||||||
|
count: 138,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Leaf',
|
||||||
|
key: 'node5',
|
||||||
|
count: 108,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -132,13 +196,34 @@
|
||||||
emits('caseNodeSelect', selectedKeys);
|
emits('caseNodeSelect', selectedKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteHandler = (node: MsTreeNodeData) => {};
|
// 删除节点
|
||||||
|
const deleteHandler = (node: MsTreeNodeData) => {
|
||||||
|
openModal({
|
||||||
|
type: 'error',
|
||||||
|
title: t('featureTest.featureCase.deleteTipTitle', { name: node.title }),
|
||||||
|
content: t('featureTest.featureCase.deleteCaseTipContent'),
|
||||||
|
okText: t('featureTest.featureCase.deleteConfirm'),
|
||||||
|
okButtonProps: {
|
||||||
|
status: 'danger',
|
||||||
|
},
|
||||||
|
maskClosable: false,
|
||||||
|
onBeforeOk: async () => {
|
||||||
|
try {
|
||||||
|
Message.success(t('featureTest.featureCase.deleteSuccess'));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideCancel: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function resetFocusNodeKey() {
|
function resetFocusNodeKey() {
|
||||||
focusNodeKey.value = '';
|
focusNodeKey.value = '';
|
||||||
renamePopVisible.value = false;
|
renamePopVisible.value = false;
|
||||||
renameCaseName.value = '';
|
renameCaseName.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用例树节点更多事件
|
// 用例树节点更多事件
|
||||||
const handleCaseMoreSelect = (item: ActionsItem, node: MsTreeNodeData) => {
|
const handleCaseMoreSelect = (item: ActionsItem, node: MsTreeNodeData) => {
|
||||||
switch (item.eventTag) {
|
switch (item.eventTag) {
|
||||||
|
@ -168,6 +253,12 @@
|
||||||
|
|
||||||
const recycleCount = ref<number>(100);
|
const recycleCount = ref<number>(100);
|
||||||
|
|
||||||
|
const virtualListProps = computed(() => {
|
||||||
|
return {
|
||||||
|
height: 'calc(100vh - 376px)',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.selectedKeys,
|
() => props.selectedKeys,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -34,10 +34,12 @@
|
||||||
<MsIcon :type="isExpandAll ? 'icon-icon_folder_collapse1' : 'icon-icon_folder_expansion1'" />
|
<MsIcon :type="isExpandAll ? 'icon-icon_folder_collapse1' : 'icon-icon_folder_expansion1'" />
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<ActionPopConfirm
|
<MsPopConfirm
|
||||||
operation-type="add"
|
:is-delete="false"
|
||||||
:title="t('featureTest.featureCase.addSubModule')"
|
:title="t('featureTest.featureCase.addSubModule')"
|
||||||
:all-names="[]"
|
:all-names="[]"
|
||||||
|
:loading="confirmLoading"
|
||||||
|
@confirm="confirmHandler"
|
||||||
>
|
>
|
||||||
<MsButton type="icon" class="!mr-0 p-[2px]">
|
<MsButton type="icon" class="!mr-0 p-[2px]">
|
||||||
<MsIcon
|
<MsIcon
|
||||||
|
@ -46,7 +48,7 @@
|
||||||
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
||||||
/>
|
/>
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</ActionPopConfirm>
|
</MsPopConfirm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-divider class="my-[8px]" />
|
<a-divider class="my-[8px]" />
|
||||||
|
@ -76,7 +78,7 @@
|
||||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import FeatureCaseTree from './components/featureCaseTree.vue';
|
import FeatureCaseTree from './components/featureCaseTree.vue';
|
||||||
import ActionPopConfirm from './components/actionPopConfirm.vue';
|
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
|
||||||
import CaseTable from './components/caseTable.vue';
|
import CaseTable from './components/caseTable.vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
@ -112,6 +114,18 @@
|
||||||
function caseNodeSelect(keys: (string | number)[]) {
|
function caseNodeSelect(keys: (string | number)[]) {
|
||||||
[activeCase.value] = keys;
|
[activeCase.value] = keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const confirmLoading = ref(false);
|
||||||
|
|
||||||
|
const confirmHandler = () => {
|
||||||
|
try {
|
||||||
|
confirmLoading.value = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|
|
@ -18,4 +18,9 @@ export default {
|
||||||
'featureTest.featureCase.addSubModuleSuccess': 'Add submodule successfully',
|
'featureTest.featureCase.addSubModuleSuccess': 'Add submodule successfully',
|
||||||
'featureTest.featureCase.renameSuccess': 'Rename successful',
|
'featureTest.featureCase.renameSuccess': 'Rename successful',
|
||||||
'featureTest.featureCase.nameNotNullTip': 'The name can not be null',
|
'featureTest.featureCase.nameNotNullTip': 'The name can not be null',
|
||||||
|
'featureTest.featureCase.deleteTipTitle': 'Do you want to delete: {name} use case?',
|
||||||
|
'featureTest.featureCase.deleteCaseTipContent':
|
||||||
|
'After the node is deleted, all resources under the node will be deleted. Exercise caution when performing this operation.',
|
||||||
|
'featureTest.featureCase.deleteConfirm': 'Confirm',
|
||||||
|
'featureTest.featureCase.deleteSuccess': 'Delete Successfully',
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,4 +18,8 @@ export default {
|
||||||
'featureTest.featureCase.addSubModuleSuccess': '添加子模块成功',
|
'featureTest.featureCase.addSubModuleSuccess': '添加子模块成功',
|
||||||
'featureTest.featureCase.renameSuccess': '重命名成功',
|
'featureTest.featureCase.renameSuccess': '重命名成功',
|
||||||
'featureTest.featureCase.nameNotNullTip': '名称不能为空',
|
'featureTest.featureCase.nameNotNullTip': '名称不能为空',
|
||||||
|
'featureTest.featureCase.deleteTipTitle': '是否删除:{name} 用例?',
|
||||||
|
'featureTest.featureCase.deleteCaseTipContent': '删除后,此节点下的所有资源都会被删除,请谨慎操作。',
|
||||||
|
'featureTest.featureCase.deleteConfirm': '确认删除',
|
||||||
|
'featureTest.featureCase.deleteSuccess': '删除成功',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue