refactor: 高级筛选-名称校验样式&优化自定义字段代码

This commit is contained in:
teukkk 2024-09-10 14:11:29 +08:00 committed by Craftsman
parent c0e7d517db
commit 72bc243cea
6 changed files with 117 additions and 74 deletions

View File

@ -1,5 +1,5 @@
<template>
<MsDrawer v-model:visible="visible" :mask="false" :width="600">
<MsDrawer v-model:visible="visible" class="filter-drawer" :mask="false" :width="600">
<template #title>
<ViewNameInput
v-if="isShowNameInput"
@ -87,6 +87,7 @@
:disabled="isValueDisabled(item)"
:max-length="255"
:placeholder="t('common.pleaseInput')"
v-bind="item.numberProps"
/>
<MsTagsInput
v-else-if="item.type === FilterType.TAGS_INPUT&& ![OperatorEnum.COUNT_LT, OperatorEnum.COUNT_GT].includes(item.operator as OperatorEnum)"
@ -182,12 +183,7 @@
:placeholder="t('advanceFilter.inputPlaceholder')"
/>
</a-form-item>
<a-button
v-if="formModel.list.length > 1"
type="outline"
class="arco-btn-outline--secondary"
@click="handleDeleteItem(listIndex)"
>
<a-button type="outline" class="arco-btn-outline--secondary" @click="handleDeleteItem(listIndex)">
<template #icon> <MsIcon type="icon-icon_block_outlined" class="text-[var(--color-text-4)]" /> </template>
</a-button>
</div>
@ -197,7 +193,7 @@
{{ t('advanceFilter.addCondition') }}
</MsButton>
<template #footer>
<div v-if="!isSaveAsView" class="flex items-center gap-[8px]">
<div v-if="!isSaveAsView" class="mb-[22px] flex items-center gap-[8px]">
<a-button v-if="!formModel?.id" type="primary" @click="handleSaveAndFilter">{{
t('advanceFilter.saveAndFilter')
}}</a-button>
@ -207,7 +203,7 @@
v-if="!isInternalViews(formModel?.id) && formModel?.id"
type="text"
:loading="saveLoading"
class="!text-[var(--color-text-1)]"
class="h-[32px] !text-[var(--color-text-1)]"
@click="handleSaveView()"
>
{{ t('common.save') }}
@ -215,7 +211,7 @@
<MsButton
v-if="(formModel?.id && !isInternalViews(formModel?.id)) || formModel?.id === 'all_data'"
type="text"
class="!text-[var(--color-text-1)]"
class="h-[32px] !text-[var(--color-text-1)]"
@click="handleToSaveAs"
>
{{ t('advanceFilter.saveAsView') }}
@ -228,7 +224,9 @@
class="w-[240px]"
:all-names="allViewNames"
/>
<a-button type="primary" :loading="addLoading" @click="handleAddView">{{ t('common.save') }}</a-button>
<a-button type="primary" class="mb-[22px]" :loading="addLoading" @click="handleAddView">{{
t('common.save')
}}</a-button>
<a-button @click="handleCancelSaveAsView">{{ t('common.cancel') }}</a-button>
</div>
</template>
@ -317,15 +315,6 @@
console.log(error);
}
}
watch(
() => visible.value,
async (val) => {
//
if (!val && formModel.value?.id !== props.currentView) {
await getUserViewDetail(props.currentView);
}
}
);
const isShowNameInput = ref(false);
const viewNameInputRef = ref<InstanceType<typeof ViewNameInput>>();
@ -395,7 +384,6 @@
}
function handleDeleteItem(index: number) {
if (formModel.value.list.length === 1) return;
formModel.value.list.splice(index, 1);
}
function handleAddItem() {
@ -563,9 +551,23 @@
handleSaveView(true);
}
watch(
() => visible.value,
async (val) => {
//
if (!val) {
handleCancelSaveAsView();
if (formModel.value?.id !== props.currentView) {
await getUserViewDetail(props.currentView);
}
}
}
);
defineExpose({
resetToNewViewForm,
handleReset,
getUserViewDetail,
});
</script>
@ -575,7 +577,37 @@
display: none;
}
.arco-form-item-message {
margin-bottom: 2px;
margin-bottom: 0;
}
.arco-select-view {
height: 32px;
.arco-select-view-inner {
@apply overflow-y-auto overflow-x-hidden;
.ms-scroll-bar();
}
}
}
</style>
<style lang="less">
// input
.filter-drawer {
.arco-drawer-header {
align-items: baseline;
padding-top: 16px;
height: 60px;
.arco-form-item-content,
.arco-input-wrapper,
.arco-form-item-wrapper-col {
height: 26px;
min-height: 26px;
}
}
.arco-drawer-footer {
padding-bottom: 0;
& > div {
align-items: start;
}
}
}
</style>

View File

@ -113,7 +113,7 @@ export const CustomTypeMaps: Record<string, any> = {
},
},
MEMBER: {
type: 'SELECT',
type: 'MEMBER',
propsKey: 'selectProps',
props: {
mode: 'remote',
@ -128,7 +128,7 @@ export const CustomTypeMaps: Record<string, any> = {
},
},
MULTIPLE_MEMBER: {
type: 'SELECT',
type: 'MEMBER',
propsKey: 'selectProps',
props: {
mode: 'remote',
@ -165,9 +165,38 @@ export const CustomTypeMaps: Record<string, any> = {
},
MULTIPLE_INPUT: {
type: 'TAGS_INPUT',
propsKey: 'numberProps',
props: {
precision: 0,
},
},
};
// 处理自定义字段
export function getFilterCustomFields(result: any[]) {
return result.map((item: any) => {
const FilterTypeKey: keyof typeof FilterType = CustomTypeMaps[item.type].type;
const formObject = CustomTypeMaps[item.type];
const { props: formProps } = formObject;
const currentItem: any = {
title: item.name,
dataIndex: item.id,
type: FilterType[FilterTypeKey],
customField: true,
customFieldType: item.type,
};
if (formObject.propsKey) {
if (item.options) {
formProps.options = item.options;
}
currentItem[formObject.propsKey] = {
...formProps,
};
}
return currentItem;
});
}
// 全部数据默认显示搜索条件ID、名称、模块
// TODO lmy 计划详情功能用例增加:测试点;接口定义、计划详情接口用例增加:协议;
export function getAllDataDefaultConditions(viewType: ViewTypeEnum) {

View File

@ -77,7 +77,7 @@
<div class="select-extra flex">
<a-tooltip :content="t('common.rename')">
<MsButton type="text" status="secondary" class="!mr-[4px]" @click="handleToRenameView(item)">
<MsIcon type="icon-icon_edit_outlined" class="hover:text-[rgb(var(--primary-4))]" size="12" />
<MsIcon type="icon-icon_edit_outlined" class="hover:text-[rgb(var(--primary-4))]" size="14" />
</MsButton>
</a-tooltip>
<a-tooltip :content="t('advanceFilter.deleteView')">
@ -85,7 +85,7 @@
<MsIcon
type="icon-icon_delete-trash_outlined1"
class="hover:text-[rgb(var(--primary-4))]"
size="12"
size="14"
/>
</MsButton>
</a-tooltip>
@ -272,7 +272,10 @@
try {
await updateView(props.viewType as string, { name: formModel.value.name, id: formModel.value.id });
Message.success(t('common.saveSuccess'));
getUserViewList();
await getUserViewList();
if (formModel.value.id === currentView.value) {
filterDrawerRef.value?.getUserViewDetail(currentView.value);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);

View File

@ -27,6 +27,12 @@ export interface MsCascaderProps {
labelKey?: string; // 传入自定义的 labelKey
}
export interface NumberProps {
mode: 'embed' | 'button';
precision: number;
step: number;
}
export interface FilterFormItem {
dataIndex?: string; // 第一列下拉的value
title?: string; // 第一列下拉显示的label
@ -36,6 +42,7 @@ export interface FilterFormItem {
customField?: boolean; // 是否是自定义字段
customFieldType?: string; // 自定义字段的类型
cascaderOptions?: CascaderOption[]; // 级联选择的选项
numberProps?: Partial<NumberProps>;
selectProps?: Partial<MsSearchSelectProps>; // select的props, 参考 MsSelect
cascaderProps?: Partial<MsCascaderProps>; // cascader的props, 参考 MsCascader
treeSelectData?: TreeNodeData[];

View File

@ -368,7 +368,7 @@
import { Message, TableChangeExtra, TableData } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es';
import { CustomTypeMaps, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { getFilterCustomFields, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { FilterFormItem, FilterResult } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
@ -861,33 +861,21 @@
title: 'common.tag',
dataIndex: 'tags',
type: FilterType.TAGS_INPUT,
numberProps: {
precision: 0,
},
},
]);
const searchCustomFields = ref<FilterFormItem[]>([]);
async function initFilter() {
const result = await getCustomFieldsTable(currentProjectId.value);
//
searchCustomFields.value = result.map((item: any) => {
const FilterTypeKey: keyof typeof FilterType = CustomTypeMaps[item.type].type;
const formType = FilterType[FilterTypeKey];
const formObject = CustomTypeMaps[item.type];
const { props: formProps } = formObject;
const currentItem: any = {
title: item.name,
dataIndex: item.id,
type: formType,
customField: true,
};
if (formObject.propsKey && formProps.options) {
formProps.options = item.options;
currentItem[formObject.propsKey] = {
...formProps,
};
}
return currentItem;
});
try {
const result = await getCustomFieldsTable(currentProjectId.value);
searchCustomFields.value = getFilterCustomFields(result); //
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
function getCustomMaps(detailResult: CaseManagementTable) {

View File

@ -335,7 +335,7 @@
import { FormInstance, Message, SelectOptionData } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es';
import { CustomTypeMaps, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { getFilterCustomFields, MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
import { FilterFormItem, FilterResult } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
@ -1097,29 +1097,13 @@
]);
const searchCustomFields = ref<FilterFormItem[]>([]);
async function initFilter() {
const result = await getCustomFieldsTable(appStore.currentProjectId);
searchCustomFields.value = result.map((item: any) => {
const FilterTypeKey: keyof typeof FilterType = CustomTypeMaps[item.type].type;
const formType = FilterType[FilterTypeKey];
const formObject = CustomTypeMaps[item.type];
const { props: formProps } = formObject;
const currentItem: any = {
title: item.name,
dataIndex: item.id,
type: formType,
customField: true,
customFieldType: item.type,
};
if (formObject.propsKey && formProps.options) {
formProps.options = item.options;
currentItem[formObject.propsKey] = {
...formProps,
customFieldType: item.type,
};
}
return currentItem;
});
try {
const result = await getCustomFieldsTable(appStore.currentProjectId);
searchCustomFields.value = getFilterCustomFields(result); //
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
//
const handleAdvSearch = async (filter: FilterResult, id: string, isStartAdvance: boolean) => {