From df737756f87f76528e2b793136c92b43000226fd Mon Sep 17 00:00:00 2001 From: Marvin Zhang Date: Mon, 31 Oct 2022 19:35:54 +0800 Subject: [PATCH] feat(filter): added components of list filter AB#13 --- package.json | 1 + src/components/filter/FilterInput.vue | 55 +++++++++++ src/components/filter/FilterSelect.vue | 93 +++++++++++++++++++ src/constants/action.ts | 3 + src/i18n/lang/en/common.ts | 1 + src/i18n/lang/en/views/nodes.ts | 5 + src/i18n/lang/en/views/notification.ts | 5 + src/i18n/lang/en/views/plugins.ts | 5 + src/i18n/lang/en/views/projects.ts | 5 + src/i18n/lang/en/views/schedules.ts | 5 + src/i18n/lang/en/views/spiders.ts | 14 +++ src/i18n/lang/en/views/tags.ts | 5 + src/i18n/lang/en/views/tasks.ts | 5 + src/i18n/lang/en/views/tokens.ts | 5 + src/i18n/lang/en/views/users.ts | 5 + src/i18n/lang/zh/common.ts | 1 + src/i18n/lang/zh/views/nodes.ts | 5 + src/i18n/lang/zh/views/notification.ts | 5 + src/i18n/lang/zh/views/plugins.ts | 5 + src/i18n/lang/zh/views/projects.ts | 5 + src/i18n/lang/zh/views/schedules.ts | 5 + src/i18n/lang/zh/views/spiders.ts | 14 +++ src/i18n/lang/zh/views/tags.ts | 5 + src/i18n/lang/zh/views/tasks.ts | 5 + src/i18n/lang/zh/views/tokens.ts | 5 + src/i18n/lang/zh/views/users.ts | 5 + .../components/filter/FilterInput.d.ts | 6 ++ .../components/filter/FilterSelect.d.ts | 14 +++ src/interfaces/i18n/common.d.ts | 6 ++ src/interfaces/i18n/views/spiders.d.ts | 9 ++ .../layout/content/list/ListLayout.d.ts | 28 ++++-- src/layouts/content/list/ListLayout.vue | 78 ++++++++++++---- src/layouts/content/list/list.ts | 4 + src/utils/list.ts | 24 +++++ src/views/data/list/ResultList.vue | 8 +- src/views/env/deps/DependencySettings.vue | 8 +- .../deps/components/lang/DependencyLang.vue | 8 +- src/views/node/list/NodeList.vue | 8 +- src/views/notification/NotificationList.vue | 8 +- src/views/plugin/list/PluginList.vue | 8 +- src/views/project/list/ProjectList.vue | 8 +- src/views/schedule/list/ScheduleList.vue | 8 +- src/views/spider/list/SpiderList.vue | 14 ++- src/views/spider/list/spiderList.ts | 51 ++++++++-- src/views/tag/list/TagList.vue | 8 +- .../task/detail/tabs/TaskDetailTabData.vue | 8 +- src/views/task/list/TaskList.vue | 8 +- src/views/token/list/TokenList.vue | 8 +- src/views/user/list/UserList.vue | 8 +- yarn.lock | 5 + 50 files changed, 523 insertions(+), 92 deletions(-) create mode 100644 src/components/filter/FilterInput.vue create mode 100644 src/components/filter/FilterSelect.vue create mode 100644 src/interfaces/components/filter/FilterInput.d.ts create mode 100644 src/interfaces/components/filter/FilterSelect.d.ts diff --git a/package.json b/package.json index 91d78a93f277d..c55af0deb84e1 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "url-join": "^4.0.1", "vue": "^3.2", "vue-clipboard3": "^1.0.1", + "vue-debounce": "^4.0.0", "vue-i18n": "9.1.9", "vue-router": "4.0.11", "vue3-dropzone": "^0.0.7", diff --git a/src/components/filter/FilterInput.vue b/src/components/filter/FilterInput.vue new file mode 100644 index 0000000000000..9330e3658af9d --- /dev/null +++ b/src/components/filter/FilterInput.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/src/components/filter/FilterSelect.vue b/src/components/filter/FilterSelect.vue new file mode 100644 index 0000000000000..d0cfe4333be8b --- /dev/null +++ b/src/components/filter/FilterSelect.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/constants/action.ts b/src/constants/action.ts index d22a4a4c8f41e..33fe4cb2636d3 100644 --- a/src/constants/action.ts +++ b/src/constants/action.ts @@ -15,3 +15,6 @@ export const ACTION_STOP = 'stop'; export const ACTION_SAVE = 'save'; export const ACTION_BACK = 'back'; export const ACTION_ENABLE = 'enable'; +export const ACTION_FILTER = 'filter'; +export const ACTION_FILTER_SEARCH = 'filter-search'; +export const ACTION_FILTER_SELECT = 'filter-select'; diff --git a/src/i18n/lang/en/common.ts b/src/i18n/lang/en/common.ts index 6fa7d96e59fc0..a68000bc3a226 100644 --- a/src/i18n/lang/en/common.ts +++ b/src/i18n/lang/en/common.ts @@ -94,6 +94,7 @@ const common: LCommon = { mode: { default: 'Default', other: 'Other', + all: 'All', }, placeholder: { empty: 'Empty', diff --git a/src/i18n/lang/en/views/nodes.ts b/src/i18n/lang/en/views/nodes.ts index 5f8343b2b1bb1..2ec511b59452f 100644 --- a/src/i18n/lang/en/views/nodes.ts +++ b/src/i18n/lang/en/views/nodes.ts @@ -17,6 +17,11 @@ const nodes: LViewsNodes = { new: { label: 'New Node', tooltip: 'Create a new node' + }, + filter: { + search: { + placeholder: 'Search nodes' + } } }, notice: { diff --git a/src/i18n/lang/en/views/notification.ts b/src/i18n/lang/en/views/notification.ts index a2c17a17a9cb8..4f4f70e14e64f 100644 --- a/src/i18n/lang/en/views/notification.ts +++ b/src/i18n/lang/en/views/notification.ts @@ -4,6 +4,11 @@ const notification: LViewsNotification = { label: 'New Notification', tooltip: 'Create a new notification', }, + filter: { + search: { + placeholder: 'Search notifications', + } + } }, settings: { form: { diff --git a/src/i18n/lang/en/views/plugins.ts b/src/i18n/lang/en/views/plugins.ts index 87ba52a8fb730..d8c54db7c1e66 100644 --- a/src/i18n/lang/en/views/plugins.ts +++ b/src/i18n/lang/en/views/plugins.ts @@ -12,6 +12,11 @@ const plugins: LViewsPlugins = { label: 'New Plugin', tooltip: 'Create a new plugin', }, + filter: { + search: { + placeholder: 'Search plugins', + } + }, install: { label: 'Install Plugin', tooltip: 'Install a new plugin', diff --git a/src/i18n/lang/en/views/projects.ts b/src/i18n/lang/en/views/projects.ts index e2139faafaa50..8bec6ebcc178a 100644 --- a/src/i18n/lang/en/views/projects.ts +++ b/src/i18n/lang/en/views/projects.ts @@ -11,6 +11,11 @@ const projects: LViewProjects = { new: { label: 'New Project', tooltip: 'Create a new project' + }, + filter: { + search: { + placeholder: 'Search projects' + } } } }; diff --git a/src/i18n/lang/en/views/schedules.ts b/src/i18n/lang/en/views/schedules.ts index a329a033afdfa..07fab17aceec0 100644 --- a/src/i18n/lang/en/views/schedules.ts +++ b/src/i18n/lang/en/views/schedules.ts @@ -14,6 +14,11 @@ const schedules: LViewsSchedules = { new: { label: 'New Schedule', tooltip: 'Create a new schedule', + }, + filter: { + search: { + placeholder: 'Search schedules', + } } } }; diff --git a/src/i18n/lang/en/views/spiders.ts b/src/i18n/lang/en/views/spiders.ts index 991500fbcafec..3b7a8e4cf3c53 100644 --- a/src/i18n/lang/en/views/spiders.ts +++ b/src/i18n/lang/en/views/spiders.ts @@ -15,6 +15,20 @@ const spiders: LViewsSpiders = { new: { label: 'New Spider', tooltip: 'Create a new spider' + }, + filter: { + search: { + placeholder: 'Search spiders' + } + } + }, + navActionsExtra: { + filter: { + select: { + project: { + label: 'Project' + } + } } } }; diff --git a/src/i18n/lang/en/views/tags.ts b/src/i18n/lang/en/views/tags.ts index 5a9bb59156cb7..6a2a8d9c43f43 100644 --- a/src/i18n/lang/en/views/tags.ts +++ b/src/i18n/lang/en/views/tags.ts @@ -11,6 +11,11 @@ const tags: LViewsTags = { new: { label: 'New Tag', tooltip: 'Create a new tag', + }, + filter: { + search: { + placeholder: 'Search tags', + } } }, }; diff --git a/src/i18n/lang/en/views/tasks.ts b/src/i18n/lang/en/views/tasks.ts index 9d086b1accc1d..a4bb48bc4451e 100644 --- a/src/i18n/lang/en/views/tasks.ts +++ b/src/i18n/lang/en/views/tasks.ts @@ -22,6 +22,11 @@ const tasks: LViewsTasks = { new: { label: 'New Task', tooltip: 'Create a new task', + }, + filter: { + search: { + placeholder: 'Search tasks', + } } } }; diff --git a/src/i18n/lang/en/views/tokens.ts b/src/i18n/lang/en/views/tokens.ts index 5ee9236e06e69..55c3f1dddc999 100644 --- a/src/i18n/lang/en/views/tokens.ts +++ b/src/i18n/lang/en/views/tokens.ts @@ -9,6 +9,11 @@ const tokens: LViewsTokens = { new: { label: 'New Token', tooltip: 'Create a new token', + }, + filter: { + search: { + placeholder: 'Search tokens', + } } }, messageBox: { diff --git a/src/i18n/lang/en/views/users.ts b/src/i18n/lang/en/views/users.ts index 74b0dfb1a1004..a25798783b01a 100644 --- a/src/i18n/lang/en/views/users.ts +++ b/src/i18n/lang/en/views/users.ts @@ -10,6 +10,11 @@ const users: LViewsUsers = { new: { label: 'New User', tooltip: 'Create a new user', + }, + filter: { + search: { + placeholder: 'Search users', + } } } }; diff --git a/src/i18n/lang/zh/common.ts b/src/i18n/lang/zh/common.ts index fb012bd45f10c..1a1ea97a6a16e 100644 --- a/src/i18n/lang/zh/common.ts +++ b/src/i18n/lang/zh/common.ts @@ -94,6 +94,7 @@ const common: LCommon = { mode: { default: '默认', other: '其他', + all: '全部', }, placeholder: { empty: '空', diff --git a/src/i18n/lang/zh/views/nodes.ts b/src/i18n/lang/zh/views/nodes.ts index 1541ad5abd70f..e34514125f86b 100644 --- a/src/i18n/lang/zh/views/nodes.ts +++ b/src/i18n/lang/zh/views/nodes.ts @@ -17,6 +17,11 @@ const nodes: LViewsNodes = { new: { label: '新建节点', tooltip: '添加一个新节点' + }, + filter: { + search: { + placeholder: '搜索节点' + } } }, notice: { diff --git a/src/i18n/lang/zh/views/notification.ts b/src/i18n/lang/zh/views/notification.ts index 3baa27dda2043..0b0cae43beea8 100644 --- a/src/i18n/lang/zh/views/notification.ts +++ b/src/i18n/lang/zh/views/notification.ts @@ -4,6 +4,11 @@ const notification: LViewsNotification = { label: '新建通知', tooltip: '创建一个新的通知', }, + filter: { + search: { + placeholder: '搜索通知', + } + } }, settings: { form: { diff --git a/src/i18n/lang/zh/views/plugins.ts b/src/i18n/lang/zh/views/plugins.ts index 795af75a8d063..81754a54c088e 100644 --- a/src/i18n/lang/zh/views/plugins.ts +++ b/src/i18n/lang/zh/views/plugins.ts @@ -12,6 +12,11 @@ const plugins: LViewsPlugins = { label: '新建插件', tooltip: '添加一个新插件', }, + filter: { + search: { + placeholder: '搜索插件', + } + }, install: { label: '安装插件', tooltip: '安装一个新插件', diff --git a/src/i18n/lang/zh/views/projects.ts b/src/i18n/lang/zh/views/projects.ts index 64bc39371698d..a903e06f361ec 100644 --- a/src/i18n/lang/zh/views/projects.ts +++ b/src/i18n/lang/zh/views/projects.ts @@ -11,6 +11,11 @@ const projects: LViewProjects = { new: { label: '新建项目', tooltip: '添加一个新项目' + }, + filter: { + search: { + placeholder: '搜索项目' + } } } }; diff --git a/src/i18n/lang/zh/views/schedules.ts b/src/i18n/lang/zh/views/schedules.ts index ddf28878fd7f2..cdc0712e1443d 100644 --- a/src/i18n/lang/zh/views/schedules.ts +++ b/src/i18n/lang/zh/views/schedules.ts @@ -14,6 +14,11 @@ const schedules: LViewsSchedules = { new: { label: '新建定时任务', tooltip: '添加一个新定时任务', + }, + filter: { + search: { + placeholder: '搜索定时任务', + } } } }; diff --git a/src/i18n/lang/zh/views/spiders.ts b/src/i18n/lang/zh/views/spiders.ts index 44a1575aa6a3d..05dea2378453f 100644 --- a/src/i18n/lang/zh/views/spiders.ts +++ b/src/i18n/lang/zh/views/spiders.ts @@ -15,6 +15,20 @@ const spiders: LViewsSpiders = { new: { label: '新建爬虫', tooltip: '添加一个新爬虫' + }, + filter: { + search: { + placeholder: '搜索爬虫' + } + } + }, + navActionsExtra: { + filter: { + select: { + project: { + label: '项目' + } + } } } }; diff --git a/src/i18n/lang/zh/views/tags.ts b/src/i18n/lang/zh/views/tags.ts index 124db3b9dff5c..e0fd0c8175b95 100644 --- a/src/i18n/lang/zh/views/tags.ts +++ b/src/i18n/lang/zh/views/tags.ts @@ -11,6 +11,11 @@ const tags: LViewsTags = { new: { label: '新建标签', tooltip: '添加一个新标签', + }, + filter: { + search: { + placeholder: '搜索标签', + } } }, }; diff --git a/src/i18n/lang/zh/views/tasks.ts b/src/i18n/lang/zh/views/tasks.ts index 7a97e02819a53..1f69b1c5871ac 100644 --- a/src/i18n/lang/zh/views/tasks.ts +++ b/src/i18n/lang/zh/views/tasks.ts @@ -22,6 +22,11 @@ const tasks: LViewsTasks = { new: { label: '新建任务', tooltip: '创建一个新任务', + }, + filter: { + search: { + placeholder: '搜索任务', + } } } }; diff --git a/src/i18n/lang/zh/views/tokens.ts b/src/i18n/lang/zh/views/tokens.ts index 0397a548bfe2a..f4d24cd821afe 100644 --- a/src/i18n/lang/zh/views/tokens.ts +++ b/src/i18n/lang/zh/views/tokens.ts @@ -9,6 +9,11 @@ const tokens: LViewsTokens = { new: { label: '新建令牌', tooltip: '添加一个新令牌', + }, + filter: { + search: { + placeholder: '搜索令牌', + } } }, messageBox: { diff --git a/src/i18n/lang/zh/views/users.ts b/src/i18n/lang/zh/views/users.ts index 88e287cb08be0..8b221f898fccf 100644 --- a/src/i18n/lang/zh/views/users.ts +++ b/src/i18n/lang/zh/views/users.ts @@ -10,6 +10,11 @@ const users: LViewsUsers = { new: { label: '新建用户', tooltip: '添加一个新用户', + }, + filter: { + search: { + placeholder: '搜索用户', + } } } }; diff --git a/src/interfaces/components/filter/FilterInput.d.ts b/src/interfaces/components/filter/FilterInput.d.ts new file mode 100644 index 0000000000000..583b0e3b5a60d --- /dev/null +++ b/src/interfaces/components/filter/FilterInput.d.ts @@ -0,0 +1,6 @@ +export declare global { + interface FilterInputProps { + label?: string; + placeholder?: string; + } +} diff --git a/src/interfaces/components/filter/FilterSelect.d.ts b/src/interfaces/components/filter/FilterSelect.d.ts new file mode 100644 index 0000000000000..901f8f7d26bf7 --- /dev/null +++ b/src/interfaces/components/filter/FilterSelect.d.ts @@ -0,0 +1,14 @@ +export declare global { + interface FilterSelectOptionsRemote { + colName: string; + value?: string; + label?: string; + } + + interface FilterSelectProps { + label?: string; + placeholder?: string; + options?: SelectOption[]; + optionsRemote?: FilterSelectOptionsRemote; + } +} diff --git a/src/interfaces/i18n/common.d.ts b/src/interfaces/i18n/common.d.ts index d39a035423c1d..ff4afa40f7f20 100644 --- a/src/interfaces/i18n/common.d.ts +++ b/src/interfaces/i18n/common.d.ts @@ -4,6 +4,11 @@ export declare global { label: string; tooltip: string; }; + filter: { + search: { + placeholder: string; + }; + }; } interface LCommon { @@ -102,6 +107,7 @@ export declare global { mode: { default: string; other: string; + all: string; }; placeholder: { empty: string; diff --git a/src/interfaces/i18n/views/spiders.d.ts b/src/interfaces/i18n/views/spiders.d.ts index 62344aa07601f..e8ee35c09bae9 100644 --- a/src/interfaces/i18n/views/spiders.d.ts +++ b/src/interfaces/i18n/views/spiders.d.ts @@ -12,4 +12,13 @@ interface LViewsSpiders { }; }; navActions: LNavActions; + navActionsExtra: { + filter: { + select: { + project: { + label: string; + }; + }; + }; + }; } diff --git a/src/interfaces/layout/content/list/ListLayout.d.ts b/src/interfaces/layout/content/list/ListLayout.d.ts index aa2138d73fa39..df205d2675397 100644 --- a/src/interfaces/layout/content/list/ListLayout.d.ts +++ b/src/interfaces/layout/content/list/ListLayout.d.ts @@ -9,6 +9,8 @@ declare global { tablePagination: TablePagination; tableActionsPrefix: ListActionButton[]; tableActionsSuffix: ListActionButton[]; + tableListFilter: FilterConditionData[]; + tableListSort: SortData[]; actionFunctions: ListLayoutActionFunctions; noActions: boolean; selectableFunction: TableSelectableFunction; @@ -25,6 +27,8 @@ declare global { tableData: Ref>; tableTotal: Ref; tablePagination: Ref; + tableListFilter: Ref; + tableListSort: Ref; actionFunctions: ListLayoutActionFunctions; activeDialogKey: ComputedRef; } @@ -36,21 +40,31 @@ declare global { interface ListActionGroup { name?: string; - children?: ListActionButton[]; + children?: (ListActionButton | ListActionFilter)[]; } - interface ListActionButton { - buttonType: ButtonType; + interface ListAction { + id?: string; label?: string; - tooltip?: string; + action?: GenericAction; + className?: string; size?: BasicSize; + } + + interface ListActionButton extends ListAction { + buttonType?: ButtonType; + tooltip?: string; icon?: Icon; type?: BasicType; disabled?: boolean | ListActionButtonDisabledFunc; onClick?: () => void; - className?: string; - id?: string; - action?: GenericAction; + } + + interface ListActionFilter extends ListAction { + placeholder?: string; + options?: SelectOption[]; + optionsRemote?: FilterSelectOptionsRemote; + onChange?: (value: any) => void; } interface ListLayoutActionFunctions { diff --git a/src/layouts/content/list/ListLayout.vue b/src/layouts/content/list/ListLayout.vue index 1091361854824..c6ca756bf7484 100644 --- a/src/layouts/content/list/ListLayout.vue +++ b/src/layouts/content/list/ListLayout.vue @@ -5,25 +5,43 @@ - + + + @@ -94,14 +112,17 @@ import NavActionItem from '@/components/nav/NavActionItem.vue'; import Table from '@/components/table/Table.vue'; import NavActionButton from '@/components/nav/NavActionButton.vue'; import NavActions from '@/components/nav/NavActions.vue'; -import {emptyObjectFunc} from '@/utils/func'; +import FilterSelect from '@/components/filter/FilterSelect.vue'; +import {emptyArrayFunc, emptyObjectFunc} from '@/utils/func'; import {getMd5} from '@/utils/hash'; -import {ACTION_ADD} from '@/constants/action'; -import {useRoute} from 'vue-router'; +import {ACTION_ADD, ACTION_FILTER_SEARCH, ACTION_FILTER_SELECT} from '@/constants/action'; +import FilterInput from '@/components/filter/FilterInput.vue'; export default defineComponent({ name: 'ListLayout', components: { + FilterInput, + FilterSelect, NavActions, NavActionGroup, NavActionItem, @@ -140,6 +161,14 @@ export default defineComponent({ }; } }, + tableListFilter: { + type: Array as PropType, + default: emptyArrayFunc, + }, + tableListSort: { + type: Array as PropType, + default: emptyArrayFunc, + }, tableActionsPrefix: { type: Array as PropType, default: () => { @@ -152,6 +181,7 @@ export default defineComponent({ return []; } }, + tableFilter: {}, actionFunctions: { type: Object as PropType, default: emptyObjectFunc, @@ -259,6 +289,8 @@ export default defineComponent({ onDelete, getNavActionButtonDisabled, ACTION_ADD, + ACTION_FILTER_SEARCH, + ACTION_FILTER_SELECT, }; }, }); @@ -271,6 +303,14 @@ export default defineComponent({ .nav-actions { background-color: $containerWhiteBg; border-bottom: none; + + .nav-action-group { + .nav-action-item { + &:not(:last-child) { + margin-right: 10px; + } + } + } } .content { diff --git a/src/layouts/content/list/list.ts b/src/layouts/content/list/list.ts index 961163cd6a78c..dc0579be1cfaa 100644 --- a/src/layouts/content/list/list.ts +++ b/src/layouts/content/list/list.ts @@ -53,6 +53,8 @@ const useList = (ns: ListStoreNamespace, store: Store, const tableData = computed>(() => state.tableData as TableData); const tableTotal = computed(() => state.tableTotal); const tablePagination = computed(() => state.tablePagination); + const tableListFilter = computed(() => state.tableListFilter); + const tableListSort = computed(() => state.tableListSort); // action functions const actionFunctions = readonly({ @@ -151,6 +153,8 @@ const useList = (ns: ListStoreNamespace, store: Store, tableData, tableTotal, tablePagination, + tableListFilter, + tableListSort, actionFunctions, activeDialogKey, }; diff --git a/src/utils/list.ts b/src/utils/list.ts index a5f75bdcce0c3..136aeb82c8730 100644 --- a/src/utils/list.ts +++ b/src/utils/list.ts @@ -1,6 +1,11 @@ import {onBeforeMount, Ref} from 'vue'; import {Store} from 'vuex'; import {setupAutoUpdate} from '@/utils/auto'; +import {translate} from '@/utils/i18n'; +import {cloneArray} from '@/utils/object'; +import {FILTER_OP_EQUAL} from '@/constants'; + +const t = translate; export const getDefaultUseListOptions = (navActions: Ref, tableColumns: Ref>): UseListOptions => { return { @@ -26,3 +31,22 @@ export const setupListComponent = (ns: ListStoreNamespace, store: Store { + const _options = cloneArray(options); + return cloneArray([ + {label: t('common.mode.all'), value: undefined}, + ..._options, + ]); +}; + +export const onListFilterChangeByKey = (store: Store, ns: ListStoreNamespace, key: string, op?: string) => { + if (!op) op = FILTER_OP_EQUAL; + return async (value: string) => { + store.commit(`${ns}/setTableListFilterByKey`, { + key, + conditions: value ? [{key, op, value}] : [], + }); + await store.dispatch(`${ns}/getList`); + }; +}; diff --git a/src/views/data/list/ResultList.vue b/src/views/data/list/ResultList.vue index d2a26999707f2..3bed4635b2d10 100644 --- a/src/views/data/list/ResultList.vue +++ b/src/views/data/list/ResultList.vue @@ -1,5 +1,5 @@