-
Notifications
You must be signed in to change notification settings - Fork 670
Add extension for list-page filters #1693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import * as React from 'react'; | ||
| import { RouteProps, RouteComponentProps } from 'react-router'; | ||
| import { K8sKind, K8sResourceKindReference } from '@console/internal/module/k8s'; | ||
| import { K8sKind, K8sResourceKindReference, K8sResourceKind } from '@console/internal/module/k8s'; | ||
| import { Extension } from './extension'; | ||
|
|
||
| type LazyLoader<T> = () => Promise<React.ComponentType<T>>; | ||
|
|
@@ -13,6 +13,11 @@ namespace ExtensionProperties { | |
| loader: LazyLoader<T>; | ||
| } | ||
|
|
||
| interface ResourceListFilterGroups { | ||
| selected: any; | ||
| all: string[]; | ||
| } | ||
|
|
||
| export type ResourceListPage = ResourcePage<{ | ||
| /** See https://reacttraining.com/react-router/web/api/match */ | ||
| match?: RouteComponentProps['match']; | ||
|
|
@@ -24,7 +29,10 @@ namespace ExtensionProperties { | |
| mock?: boolean; | ||
| /** The namespace scope. */ | ||
| namespace?: string; | ||
| }>; | ||
| }> & { | ||
| /** Function. If "true" is returned then particular item is included in the list. */ | ||
| filter?: (filterGroups: ResourceListFilterGroups, obj: K8sResourceKind) => boolean; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the filter be named and allow more than one? |
||
| }; | ||
|
|
||
| export type ResourceDetailsPage = ResourcePage<{ | ||
| /** See https://reacttraining.com/react-router/web/api/match */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,6 +50,7 @@ import { | |
| getTemplateInstanceStatus, | ||
| getNodeRoles, | ||
| } from '../../module/k8s'; | ||
| import * as plugins from '../../plugins'; | ||
|
|
||
| const fuzzyCaseInsensitive = (a, b) => fuzzy(_.toLower(a), _.toLower(b)); | ||
|
|
||
|
|
@@ -194,6 +195,32 @@ const listFilters = { | |
| }, | ||
| }; | ||
|
|
||
| /* Append filters from plugins | ||
|
|
||
| TODO(mlibra): | ||
| Some objects (like VirtualMachines) require to query additional objects | ||
| to fully asses state (like pods and CRs in the case of a VirtualMachine). | ||
| Recent filtering logic can handle just a single "listed" object. | ||
| We will need to find a way how to pass additional resources there. | ||
| */ | ||
| (function () { | ||
| const baseListCount = Object.keys(listFilters).length; | ||
|
|
||
| plugins.registry.getResourceListPages() | ||
| .filter(rlp => !!rlp.properties.filter) | ||
| .forEach(rlp => { | ||
| if (listFilters[rlp.properties.model.kind]) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn(`List filter for ${rlp.properties.model.kind} already defined, skipping.`); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this check to a unit test.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this is exactly the purpose of #1708 - run extension checks as part of |
||
| } else { | ||
| listFilters[rlp.properties.model.kind] = rlp.properties.filter; | ||
| } | ||
| }); | ||
|
|
||
| // eslint-disable-next-line no-console | ||
| console.info(`${Object.keys(listFilters).length - baseListCount} new list filters added by plugins.`); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really necessary?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is in-line with a former convention to inform users about extensions being applied & any potential conflicts. With #1708 we no longer need this because
|
||
| })(); | ||
|
|
||
| const getFilteredRows = (_filters, objects) => { | ||
| if (_.isEmpty(_filters)) { | ||
| return objects; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mareklibra If I understand correctly, this PR is effectively about extending the
listFiltersobject declared inpublic/components/factory/list.tsx, which is used to filterListcomponent's rendered data.The
ResourceListPageextension makes Console aware of additional list pages, mapping model to page component to handle listing for that model. The implementation of the entire list page component is provided by the plugin.Therefore, I think a better approach is to make the
Listcomponent itself extensible in terms of list filters used.ListInnerPropsalready includesfilters, this value is used to lookup the corresponding filter impl. within thelistFiltersobject. So I'd suggest doing the following:Step 1, improve typing of list filters. In the
Listcomponent:ListFilterGroupstype (theResourceprefix is not needed)type ListFilter = (groups: ListFilterGroups, obj: K8sResourceKind) => boolean;listFiltersobject to useListFiltertype consistently, for example:'name': (filter, obj): ListFilter => fuzzyCaseInsensitive(filter, obj.metadata.name),ListFilterGroupstype if necessary (add properties likevaluesetc.)Step 2, allow extension of built-in list filters. In the
Listcomponent:ListInnerProps, addcustomFilterFuncs?: {[name: string]: ListFilter};stateToPropscustomFilterFuncs = {}topropsobject destructuring assignmentgetFilteredRows(allFilters, data);togetFilteredRows(allFilters, data, customFilterFuncs);getFilteredRowsconst filter = listFilters[name] || customFilterFuncs[name];filterPropTypeif (key in listFilters || key in customFilterFuncs || key === 'loadTest') { continue; }Step 3, use the newly introduced
customFilterFuncsprop ofListcomponent inVirtualMachinesPage.This way, we have a
Listcomponent that supports using custom filters in addition to ones that are built-in.cc @christianvogt @spadgett
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the
Listcomponent is deprecated and soon to be removed! We should be making these changes totable.tsx.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I'll look into this.
What we actually need here is adding new prop to
Tablecomponent (successor ofList) that allows us to extend the built-intableFilters.(This is unrelated to resource list page mapping extension point.)