feat(功能测试): 调整功能用例气泡确认框

This commit is contained in:
xinxin.wu 2023-10-07 15:21:03 +08:00 committed by 刘瑞斌
parent e36278861f
commit 8aa3b9cce7
7 changed files with 133 additions and 144 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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' }" />{{

View File

@ -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) => {

View File

@ -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">

View File

@ -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',
}; };

View File

@ -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': '删除成功',
}; };