mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-03 20:49:56 +08:00
feat(测试用例): 测试用例支持高级搜索&修改高级搜索交互
This commit is contained in:
parent
73a011985c
commit
543909c358
@ -245,7 +245,7 @@ export function getDefaultLocale() {
|
||||
|
||||
// 视图列表
|
||||
export function getViewList(viewType: string, scopeId: string) {
|
||||
return MSR.get<ViewList>({ url: `/user-view/${viewType}/grouped/list`, params: scopeId });
|
||||
return MSR.get<ViewList>({ url: `/user-view/${viewType}/grouped/list`, params: { scopeId } });
|
||||
}
|
||||
// 视图详情
|
||||
export function getViewDetail(viewType: string, id: string) {
|
||||
@ -261,5 +261,5 @@ export function addView(viewType: string, data: ViewParams) {
|
||||
}
|
||||
// 删除视图
|
||||
export function deleteView(viewType: string, id: string) {
|
||||
return MSR.post({ url: `/user-view/${viewType}/delete/${id}` });
|
||||
return MSR.get({ url: `/user-view/${viewType}/delete/${id}` });
|
||||
}
|
||||
|
@ -302,7 +302,8 @@
|
||||
.arco-input-tag-disabled,
|
||||
.arco-input-disabled,
|
||||
.arco-textarea-disabled,
|
||||
.arco-select-view-disabled
|
||||
.arco-select-view-disabled,
|
||||
.arco-picker-disabled
|
||||
):hover {
|
||||
border-color: rgb(var(--primary-5)) !important;
|
||||
background-color: white;
|
||||
@ -314,7 +315,8 @@
|
||||
.arco-input-tag-disabled,
|
||||
.arco-select-view-disabled,
|
||||
.arco-textarea-disabled,
|
||||
.arco-input-disabled {
|
||||
.arco-input-disabled,
|
||||
.arco-picker-disabled {
|
||||
border-color: var(--color-text-n9) !important;
|
||||
background-color: var(--color-text-n9) !important;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
class="hidden-item"
|
||||
hide-asterisk
|
||||
field="name"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[{ required: true, message: t('advanceFilter.viewNameRequired') }, { validator: validateName }]"
|
||||
>
|
||||
<a-input
|
||||
@ -60,7 +60,16 @@
|
||||
});
|
||||
}
|
||||
|
||||
function validateForm(cb: () => void) {
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
inputFocus,
|
||||
validateForm,
|
||||
});
|
||||
</script>
|
||||
|
@ -2,17 +2,18 @@
|
||||
<MsDrawer v-model:visible="visible" :mask="false" :width="600">
|
||||
<template #title>
|
||||
<ViewNameInput
|
||||
v-show="isShowNameInput"
|
||||
v-if="isShowNameInput"
|
||||
ref="viewNameInputRef"
|
||||
v-model:form="formModel"
|
||||
:all-names="allViewNames"
|
||||
:all-names="allViewNames.filter((name) => name !== savedFormModel.name)"
|
||||
@handle-submit="isShowNameInput = false"
|
||||
/>
|
||||
<div v-show="!isShowNameInput" class="flex flex-1 items-center gap-[8px] overflow-hidden">
|
||||
<div v-else class="flex flex-1 items-center gap-[8px] overflow-hidden">
|
||||
<a-tooltip :content="formModel.name">
|
||||
<div class="one-line-text"> {{ formModel.name }}</div>
|
||||
</a-tooltip>
|
||||
<MsIcon
|
||||
v-if="formModel?.internalViewKey !== 'ALL_DATA'"
|
||||
type="icon-icon_edit_outlined"
|
||||
class="min-w-[16px] cursor-pointer hover:text-[rgb(var(--primary-5))]"
|
||||
@click="showNameInput"
|
||||
@ -92,6 +93,18 @@
|
||||
:max-length="255"
|
||||
:placeholder="t('common.pleaseInput')"
|
||||
/>
|
||||
<MsSelect
|
||||
v-else-if="item.type === FilterType.MEMBER"
|
||||
v-model:model-value="item.value"
|
||||
allow-clear
|
||||
allow-search
|
||||
:placeholder="t('common.pleaseSelect')"
|
||||
:disabled="isValueDisabled(item)"
|
||||
:options="props.memberOptions"
|
||||
multiple
|
||||
:search-keys="['label']"
|
||||
:max-tag-count="1"
|
||||
/>
|
||||
<MsSelect
|
||||
v-else-if="item.type === FilterType.SELECT"
|
||||
v-model:model-value="item.value"
|
||||
@ -180,12 +193,13 @@
|
||||
{{ t('advanceFilter.addCondition') }}
|
||||
</MsButton>
|
||||
<template #footer>
|
||||
<div v-show="!isSaveAsView" class="flex items-center gap-[8px]">
|
||||
<div v-if="!isSaveAsView" class="flex items-center gap-[8px]">
|
||||
<a-button type="primary" @click="handleFilter">{{ t('common.filter') }}</a-button>
|
||||
<a-button class="mr-[16px]" @click="handleReset">{{ t('common.reset') }}</a-button>
|
||||
<MsButton
|
||||
v-if="formModel?.internalViewKey !== 'ALL_DATA'"
|
||||
type="text"
|
||||
:loading="saveLoading"
|
||||
class="!text-[var(--color-text-1)]"
|
||||
@click="handleSaveView"
|
||||
>
|
||||
@ -195,14 +209,14 @@
|
||||
{{ t('advanceFilter.saveAsView') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
<div v-show="isSaveAsView" class="flex items-center gap-[8px]">
|
||||
<div v-else class="flex items-center gap-[8px]">
|
||||
<ViewNameInput
|
||||
ref="saveAsViewNameInputRef"
|
||||
v-model:form="saveAsViewForm"
|
||||
class="w-[240px]"
|
||||
:all-names="allViewNames"
|
||||
/>
|
||||
<a-button type="primary" @click="handleAddView">{{ t('common.save') }}</a-button>
|
||||
<a-button type="primary" :loading="addLoading" @click="handleAddView">{{ t('common.save') }}</a-button>
|
||||
<a-button @click="handleCancelSaveAsView">{{ t('common.cancel') }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
@ -221,6 +235,7 @@
|
||||
|
||||
import { addView, getViewDetail, updateView } from '@/api/modules/user/index';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { SelectValue } from '@/models/projectManagement/menuManagement';
|
||||
import { FilterType, OperatorEnum, ViewTypeEnum } from '@/enums/advancedFilterEnum';
|
||||
@ -234,6 +249,8 @@
|
||||
viewType: ViewTypeEnum;
|
||||
currentView: string; // 当前视图
|
||||
allViewNames: string[];
|
||||
canNotAddView: boolean;
|
||||
memberOptions: { label: string; value: string }[];
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'handleFilter', value: FilterResult): void;
|
||||
@ -242,6 +259,7 @@
|
||||
const visible = defineModel<boolean>('visible', { required: true });
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const defaultFormModel: FilterForm = {
|
||||
name: '',
|
||||
@ -361,6 +379,7 @@
|
||||
// 重置
|
||||
function handleReset() {
|
||||
formModel.value = cloneDeep(savedFormModel.value);
|
||||
isShowNameInput.value = false;
|
||||
}
|
||||
// 过滤
|
||||
function handleFilter() {
|
||||
@ -378,29 +397,49 @@
|
||||
handleFilter();
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => visible.value,
|
||||
async (val) => {
|
||||
// 新建视图关闭后重新获取数据
|
||||
if (!val && formModel.value?.id !== props.currentView) {
|
||||
await getUserViewDetail(props.currentView);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const isSaveAsView = ref(false);
|
||||
const saveAsViewForm = ref({ name: '' });
|
||||
const saveAsViewNameInputRef = ref<InstanceType<typeof ViewNameInput>>();
|
||||
// 数据改为新建视图的空数据
|
||||
function resetToNewViewForm() {
|
||||
// TODO lmy 命名递增数字
|
||||
// 命名递增数字
|
||||
let name = '';
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const defaultName = `${t('advanceFilter.unnamedView')}${String(i).padStart(3, '0')}`;
|
||||
if (!props.allViewNames.includes(defaultName)) {
|
||||
name = defaultName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
formModel.value = {
|
||||
...cloneDeep(defaultFormModel),
|
||||
name: '未命名视图001',
|
||||
name,
|
||||
};
|
||||
savedFormModel.value = cloneDeep(formModel.value);
|
||||
}
|
||||
// 保存视图
|
||||
function handleSaveView() {
|
||||
// TODO lmy 校验名称
|
||||
const saveLoading = ref(false);
|
||||
function realSaveView() {
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
try {
|
||||
saveLoading.value = true;
|
||||
if (formModel.value.id) {
|
||||
await updateView(props.viewType, { ...getParams(), name: formModel.value.name, id: formModel.value.id });
|
||||
} else {
|
||||
await addView(props.viewType, { ...getParams(), name: formModel.value.name, id: formModel.value.id });
|
||||
await addView(props.viewType, {
|
||||
...getParams(),
|
||||
scopeId: appStore.currentProjectId,
|
||||
name: formModel.value.name,
|
||||
id: formModel.value.id,
|
||||
});
|
||||
}
|
||||
Message.success(t('common.saveSuccess'));
|
||||
savedFormModel.value = cloneDeep(formModel.value);
|
||||
@ -408,15 +447,34 @@
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
saveLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function handleSaveView() {
|
||||
if (viewNameInputRef.value) {
|
||||
viewNameInputRef.value?.validateForm(realSaveView);
|
||||
} else {
|
||||
realSaveView();
|
||||
}
|
||||
}
|
||||
// 开启另存为视图模式
|
||||
const isSaveAsView = ref(false);
|
||||
const saveAsViewForm = ref({ name: '' });
|
||||
const saveAsViewNameInputRef = ref<InstanceType<typeof ViewNameInput>>();
|
||||
function handleToSaveAs() {
|
||||
if (props.canNotAddView) {
|
||||
Message.warning(t('advanceFilter.maxViewTip'));
|
||||
return;
|
||||
}
|
||||
formRef.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
isSaveAsView.value = true;
|
||||
nextTick(() => {
|
||||
saveAsViewNameInputRef.value?.inputFocus();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -426,17 +484,29 @@
|
||||
saveAsViewForm.value.name = '';
|
||||
}
|
||||
// 新增视图
|
||||
async function handleAddView() {
|
||||
// TODO lmy 校验名称 saveAsViewNameInputRef
|
||||
const addLoading = ref(false);
|
||||
async function realAddView() {
|
||||
try {
|
||||
await addView(props.viewType, { ...getParams(), name: formModel.value.name, id: formModel.value.id });
|
||||
addLoading.value = true;
|
||||
await addView(props.viewType, {
|
||||
...getParams(),
|
||||
scopeId: appStore.currentProjectId,
|
||||
name: saveAsViewForm.value.name,
|
||||
id: formModel.value.id,
|
||||
});
|
||||
Message.success(t('common.saveSuccess'));
|
||||
emit('refreshViewList');
|
||||
handleCancelSaveAsView();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
addLoading.value = false;
|
||||
}
|
||||
}
|
||||
async function handleAddView() {
|
||||
saveAsViewNameInputRef.value?.validateForm(realAddView);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
resetToNewViewForm,
|
||||
|
@ -38,6 +38,7 @@ export const operatorOptionsMap: Record<string, { value: string; label: string }
|
||||
[FilterType.RADIO]: COMMON_SELECTION_OPERATORS,
|
||||
[FilterType.CHECKBOX]: COMMON_SELECTION_OPERATORS,
|
||||
[FilterType.SELECT]: COMMON_SELECTION_OPERATORS,
|
||||
[FilterType.MEMBER]: COMMON_SELECTION_OPERATORS,
|
||||
[FilterType.TAGS_INPUT]: [EMPTY, CONTAINS, NO_CONTAINS, COUNT_LT, COUNT_GT],
|
||||
[FilterType.TREE_SELECT]: [BELONG_TO, NOT_BELONG_TO],
|
||||
[FilterType.DATE_PICKER]: [BETWEEN, EQUAL, EMPTY, NOT_EMPTY],
|
||||
|
@ -34,8 +34,9 @@
|
||||
<a-select
|
||||
v-if="props.viewType"
|
||||
v-model:model-value="currentView"
|
||||
:loading="viewListLoading"
|
||||
:trigger-props="{ contentClass: 'view-select-trigger' }"
|
||||
class="w-[160px]"
|
||||
class="w-[180px]"
|
||||
show-footer-on-empty
|
||||
>
|
||||
<template #prefix> {{ t('advanceFilter.view') }} </template>
|
||||
@ -45,25 +46,34 @@
|
||||
</a-option>
|
||||
</a-optgroup>
|
||||
<a-optgroup :label="t('advanceFilter.myView')">
|
||||
<a-option v-for="item in customViews" :key="item.id" :value="item.id">
|
||||
{{ item.name }}
|
||||
<div class="flex">
|
||||
<a-tooltip :content="t('common.rename')">
|
||||
<MsButton type="text" status="secondary" class="!mr-[4px]" @click.stop="handleRenameView(item)">
|
||||
<MsIcon type="icon-icon_edit_outlined" class="hover:text-[rgb(var(--primary-4))]" size="12" />
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
<a-tooltip :content="t('advanceFilter.deleteView')">
|
||||
<MsButton type="text" status="secondary" @click.stop="handleDeleteView(item)">
|
||||
<MsIcon
|
||||
type="icon-icon_delete-trash_outlined1"
|
||||
class="hover:text-[rgb(var(--primary-4))]"
|
||||
size="12"
|
||||
/>
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</a-option>
|
||||
<template v-for="item in customViews" :key="item.id">
|
||||
<a-option v-show="!item.isShowNameInput" :value="item.id">
|
||||
<div>{{ item.name }}</div>
|
||||
<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" />
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
<a-tooltip :content="t('advanceFilter.deleteView')">
|
||||
<MsButton type="text" :disabled="deleteLoading" status="secondary" @click="handleDeleteView(item)">
|
||||
<MsIcon
|
||||
type="icon-icon_delete-trash_outlined1"
|
||||
class="hover:text-[rgb(var(--primary-4))]"
|
||||
size="12"
|
||||
/>
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</a-option>
|
||||
<ViewNameInput
|
||||
v-if="item.isShowNameInput"
|
||||
:ref="(el:refItem) => setNameInputRefMap(el, item)"
|
||||
v-model:form="formModel"
|
||||
:all-names="allViewNames.filter((name) => name !== item.name)"
|
||||
@handle-submit="handleRenameView"
|
||||
/>
|
||||
</template>
|
||||
</a-optgroup>
|
||||
<template #footer>
|
||||
<div class="flex cursor-pointer items-center gap-[8px]" @click="toNewView">
|
||||
@ -111,6 +121,8 @@
|
||||
:all-view-names="allViewNames"
|
||||
:config-list="props.filterConfigList"
|
||||
:custom-list="props.customFieldsConfigList"
|
||||
:can-not-add-view="canNotAddView"
|
||||
:member-options="memberOptions"
|
||||
@handle-filter="handleFilter"
|
||||
@refresh-view-list="getUserViewList"
|
||||
/>
|
||||
@ -122,9 +134,11 @@
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsTag from '../ms-tag/ms-tag.vue';
|
||||
import ViewNameInput from './components/viewNameInput.vue';
|
||||
import FilterDrawer from './filterDrawer.vue';
|
||||
|
||||
import { deleteView, getViewList } from '@/api/modules/user/index';
|
||||
import { getProjectOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { deleteView, getViewList, updateView } from '@/api/modules/user/index';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
@ -159,42 +173,94 @@
|
||||
const currentView = ref(''); // 当前视图
|
||||
const internalViews = ref<ViewItem[]>([]);
|
||||
const customViews = ref<ViewItem[]>([]);
|
||||
const viewListLoading = ref(false);
|
||||
const allViewNames = computed(() => [...internalViews.value, ...customViews.value].map((item) => item.name));
|
||||
const canNotAddView = computed(() => customViews.value.length >= 10);
|
||||
async function getUserViewList() {
|
||||
try {
|
||||
viewListLoading.value = true;
|
||||
const res = await getViewList(props.viewType as ViewTypeEnum, appStore.currentProjectId);
|
||||
internalViews.value = res.internalViews;
|
||||
customViews.value = res.customViews;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
viewListLoading.value = false;
|
||||
}
|
||||
}
|
||||
const memberOptions = ref<{ label: string; value: string }[]>([]);
|
||||
async function getMemberOptions() {
|
||||
const res = await getProjectOptions(appStore.currentProjectId);
|
||||
memberOptions.value = [{ name: t('common.currentUser'), id: 'CURRENT_USER' }, ...res].map((e: any) => ({
|
||||
label: e.name,
|
||||
value: e.id,
|
||||
}));
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getUserViewList();
|
||||
currentView.value = internalViews.value[0].id;
|
||||
if (props.viewType) {
|
||||
getMemberOptions();
|
||||
await getUserViewList();
|
||||
currentView.value = internalViews.value[0]?.id;
|
||||
}
|
||||
});
|
||||
|
||||
const filterDrawerRef = ref<InstanceType<typeof FilterDrawer>>();
|
||||
function toNewView() {
|
||||
if (canNotAddView.value) {
|
||||
Message.warning(t('advanceFilter.maxViewTip'));
|
||||
return;
|
||||
}
|
||||
visible.value = true;
|
||||
filterDrawerRef.value?.resetToNewViewForm();
|
||||
}
|
||||
function handleRenameView(item: ViewItem) {
|
||||
// TODO lmy 重命名
|
||||
|
||||
type refItem = Element | ComponentPublicInstance | null;
|
||||
const viewNameInputRefMap: Record<string, any> = {};
|
||||
function setNameInputRefMap(el: refItem, item: ViewItem) {
|
||||
if (el) {
|
||||
viewNameInputRefMap[`${item.id}`] = el;
|
||||
}
|
||||
}
|
||||
async function handleDeleteView(item: ViewItem) {
|
||||
const formModel = ref({ name: '', id: '' });
|
||||
function handleToRenameView(item: ViewItem) {
|
||||
formModel.value.id = item.id;
|
||||
formModel.value.name = item.name;
|
||||
item.isShowNameInput = true;
|
||||
nextTick(() => {
|
||||
viewNameInputRefMap[item.id]?.inputFocus();
|
||||
});
|
||||
}
|
||||
async function handleRenameView() {
|
||||
try {
|
||||
await deleteView(item.viewType, item.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
await updateView(props.viewType as string, { name: formModel.value.name, id: formModel.value.id });
|
||||
Message.success(t('common.saveSuccess'));
|
||||
getUserViewList();
|
||||
currentView.value = internalViews.value[0].id;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除试图
|
||||
const deleteLoading = ref(false);
|
||||
async function handleDeleteView(item: ViewItem) {
|
||||
try {
|
||||
deleteLoading.value = true;
|
||||
await deleteView(props.viewType as string, item.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
await getUserViewList();
|
||||
if (item.id === currentView.value) {
|
||||
currentView.value = internalViews.value[0].id;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
deleteLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const isAdvancedSearchMode = ref(false);
|
||||
const handleFilter = (filter: FilterResult) => {
|
||||
keyword.value = '';
|
||||
@ -242,6 +308,14 @@
|
||||
.arco-select-option-content {
|
||||
@apply flex w-full items-center justify-between;
|
||||
}
|
||||
.select-extra {
|
||||
visibility: hidden;
|
||||
}
|
||||
.arco-select-option:hover {
|
||||
.select-extra {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
.arco-select-dropdown-list-wrapper {
|
||||
max-height: 255px;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ export default {
|
||||
'advanceFilter.operator.length.le': 'Length less than or equal to',
|
||||
|
||||
'advanceFilter.view': 'View',
|
||||
'advanceFilter.unnamedView': 'Unnamed View',
|
||||
'advanceFilter.systemView': 'System view',
|
||||
'advanceFilter.myView': 'My view',
|
||||
'advanceFilter.newView': 'New view',
|
||||
@ -40,4 +41,5 @@ export default {
|
||||
'advanceFilter.conditionRequired': 'Query condition cannot be empty',
|
||||
'advanceFilter.filterContentRequired': 'Filter content cannot be empty',
|
||||
'advanceFilter.filterTip': 'Filter mode, module filtering can only be operated in the current filter',
|
||||
'advanceFilter.maxViewTip': 'Up to 10 views can be added',
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ export default {
|
||||
'advanceFilter.operator.length.le': '长度小于等于',
|
||||
|
||||
'advanceFilter.view': '视图',
|
||||
'advanceFilter.unnamedView': '未命名视图',
|
||||
'advanceFilter.systemView': '系统视图',
|
||||
'advanceFilter.myView': '我的视图',
|
||||
'advanceFilter.newView': '新建视图',
|
||||
@ -40,4 +41,5 @@ export default {
|
||||
'advanceFilter.conditionRequired': '查询条件不能为空',
|
||||
'advanceFilter.filterContentRequired': '筛选内容不能为空',
|
||||
'advanceFilter.filterTip': '筛选模式,模块过滤仅可在当前过滤器中操作',
|
||||
'advanceFilter.maxViewTip': '最多可添加 10 个视图',
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ export interface ConditionsItem extends CombineItem {
|
||||
|
||||
export interface FilterResult {
|
||||
// 匹配模式 所有/任一
|
||||
searchMode: AccordBelowType;
|
||||
searchMode?: AccordBelowType;
|
||||
// 高级搜索
|
||||
conditions?: ConditionsItem[];
|
||||
combine?: any; // TODO lmy 此为防报错占位 所有高级筛选都完成后 删除这一行
|
||||
@ -69,6 +69,7 @@ export interface ViewItem {
|
||||
pos?: number; // 自定义排序
|
||||
createTime?: number;
|
||||
updateTime?: number;
|
||||
isShowNameInput?: boolean;
|
||||
}
|
||||
export interface ViewList {
|
||||
internalViews: ViewItem[];
|
||||
|
@ -75,6 +75,11 @@
|
||||
background-color: var(--color-text-n8);
|
||||
}
|
||||
}
|
||||
.ms-button-text {
|
||||
@apply p-0;
|
||||
|
||||
color: rgb(var(--primary-5));
|
||||
}
|
||||
.ms-button--secondary {
|
||||
color: var(--color-text-2);
|
||||
&:not(.ms-button-text, .ms-button--disabled):hover {
|
||||
@ -106,9 +111,4 @@
|
||||
padding: 0 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.ms-button-text {
|
||||
@apply p-0;
|
||||
|
||||
color: rgb(var(--primary-5));
|
||||
}
|
||||
</style>
|
||||
|
@ -18,6 +18,7 @@ export enum FilterType {
|
||||
INPUT = 'Input',
|
||||
NUMBER = 'Number',
|
||||
SELECT = 'Select',
|
||||
MEMBER = 'Member',
|
||||
DATE_PICKER = 'DatePicker',
|
||||
TAGS_INPUT = 'TagsInput',
|
||||
TREE_SELECT = 'TreeSelect',
|
||||
|
@ -208,4 +208,5 @@ export default {
|
||||
'common.cutSuccess': 'Cut successfully',
|
||||
'common.copySuccessToClipboard': 'Copied to clipboard',
|
||||
'common.casePriority': 'Case Priority',
|
||||
'common.currentUser': 'Current user',
|
||||
};
|
||||
|
@ -208,4 +208,5 @@ export default {
|
||||
'common.cutSuccess': '剪切成功',
|
||||
'common.copySuccessToClipboard': '已复制到剪切板',
|
||||
'common.casePriority': '用例等级',
|
||||
'common.currentUser': '当前用户',
|
||||
};
|
||||
|
@ -412,7 +412,6 @@
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
import { getSocket } from '@/api/modules/project-management/commonScript';
|
||||
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
|
||||
import { getProjectOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
@ -774,7 +773,6 @@
|
||||
],
|
||||
};
|
||||
|
||||
const memberOptions = ref<{ label: string; value: string }[]>([]);
|
||||
const filterConfigList = computed<FilterFormItem[]>(() => [
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnID',
|
||||
@ -787,7 +785,7 @@
|
||||
type: FilterType.INPUT,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnModule',
|
||||
title: 'common.belongModule',
|
||||
dataIndex: 'moduleId',
|
||||
type: FilterType.TREE_SELECT,
|
||||
treeSelectData: caseTreeData.value,
|
||||
@ -800,44 +798,59 @@
|
||||
multiple: true,
|
||||
treeCheckable: true,
|
||||
treeCheckStrictly: true,
|
||||
maxTagCount: 2,
|
||||
maxTagCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnVersion',
|
||||
dataIndex: 'versionId',
|
||||
title: 'caseManagement.featureCase.tableColumnReviewResult',
|
||||
dataIndex: 'reviewStatus',
|
||||
type: FilterType.SELECT,
|
||||
selectProps: {
|
||||
multiple: true,
|
||||
options: reviewResultOptions.value,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnExecutionResult',
|
||||
dataIndex: 'lastExecuteResult',
|
||||
type: FilterType.SELECT,
|
||||
selectProps: {
|
||||
multiple: true,
|
||||
options: executeResultOptions.value,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.associatedDemand',
|
||||
dataIndex: 'demand',
|
||||
type: FilterType.INPUT,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnCreateUser',
|
||||
dataIndex: 'createUserName',
|
||||
type: FilterType.SELECT,
|
||||
selectProps: {
|
||||
mode: 'static',
|
||||
options: memberOptions.value,
|
||||
},
|
||||
title: 'caseManagement.featureCase.relatedAttachments',
|
||||
dataIndex: 'attachment',
|
||||
type: FilterType.INPUT,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnCreateTime',
|
||||
title: 'common.creator',
|
||||
dataIndex: 'createUser',
|
||||
type: FilterType.MEMBER,
|
||||
},
|
||||
{
|
||||
title: 'common.createTime',
|
||||
dataIndex: 'createTime',
|
||||
type: FilterType.DATE_PICKER,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnUpdateUser',
|
||||
dataIndex: 'updateUserName',
|
||||
type: FilterType.SELECT,
|
||||
selectProps: {
|
||||
mode: 'static',
|
||||
options: memberOptions.value,
|
||||
},
|
||||
title: 'common.updateUserName',
|
||||
dataIndex: 'updateUser',
|
||||
type: FilterType.MEMBER,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnUpdateTime',
|
||||
title: 'common.updateTime',
|
||||
dataIndex: 'updateTime',
|
||||
type: FilterType.DATE_PICKER,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnTag',
|
||||
title: 'common.tag',
|
||||
dataIndex: 'tags',
|
||||
type: FilterType.TAGS_INPUT,
|
||||
},
|
||||
@ -846,8 +859,6 @@
|
||||
|
||||
async function initFilter() {
|
||||
const result = await getCustomFieldsTable(currentProjectId.value);
|
||||
memberOptions.value = await getProjectOptions(appStore.currentProjectId, keyword.value);
|
||||
memberOptions.value = memberOptions.value.map((e: any) => ({ label: e.name, value: e.id }));
|
||||
// 处理系统自定义字段
|
||||
searchCustomFields.value = result.map((item: any) => {
|
||||
const FilterTypeKey: keyof typeof FilterType = CustomTypeMaps[item.type].type;
|
||||
|
@ -67,6 +67,7 @@ export default {
|
||||
'caseManagement.featureCase.moveTo': 'Move to',
|
||||
'caseManagement.featureCase.copyTo': 'Copy to',
|
||||
'caseManagement.featureCase.associatedDemand': 'Associated demand',
|
||||
'caseManagement.featureCase.relatedAttachments': 'Related attachments',
|
||||
'caseManagement.featureCase.generatingDependencies': 'Generative dependency',
|
||||
'caseManagement.featureCase.addToPublic': 'Add to public case',
|
||||
'caseManagement.featureCase.updateCase': 'Update Case',
|
||||
|
@ -67,6 +67,7 @@ export default {
|
||||
'caseManagement.featureCase.moveTo': '移动到',
|
||||
'caseManagement.featureCase.copyTo': '复制到',
|
||||
'caseManagement.featureCase.associatedDemand': '关联需求',
|
||||
'caseManagement.featureCase.relatedAttachments': '关联附件',
|
||||
'caseManagement.featureCase.generatingDependencies': '生成依赖关系',
|
||||
'caseManagement.featureCase.addToPublic': '添加到公共用例库',
|
||||
'caseManagement.featureCase.updateCase': '更新用例',
|
||||
|
Loading…
Reference in New Issue
Block a user