-
Notifications
You must be signed in to change notification settings - Fork 885
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
Add extension point in saved object management to register namespaces and show filter #2656
Changes from all commits
15878e3
e61d803
ef6bd97
bc6158c
e3dc3b3
445ffc7
f31e0ef
f4d13eb
ee15b77
2141b33
51b1325
c2ceffe
5f01763
2d97645
0cd8012
b805531
9a153ea
8211f5e
8bd743f
d2098e8
3331bf2
deb909f
ad80403
05a3943
24f9d38
2630566
9cd0900
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,7 @@ import { | |
ISavedObjectsManagementServiceRegistry, | ||
SavedObjectsManagementActionServiceStart, | ||
SavedObjectsManagementColumnServiceStart, | ||
SavedObjectsManagementNamespaceServiceStart, | ||
} from '../../services'; | ||
import { Header, Table, Flyout, Relationships } from './components'; | ||
import { DataPublicPluginStart } from '../../../../../plugins/data/public'; | ||
|
@@ -99,6 +100,7 @@ export interface SavedObjectsTableProps { | |
serviceRegistry: ISavedObjectsManagementServiceRegistry; | ||
actionRegistry: SavedObjectsManagementActionServiceStart; | ||
columnRegistry: SavedObjectsManagementColumnServiceStart; | ||
namespaceRegistry: SavedObjectsManagementNamespaceServiceStart; | ||
savedObjectsClient: SavedObjectsClientContract; | ||
indexPatterns: IndexPatternsContract; | ||
http: HttpStart; | ||
|
@@ -177,7 +179,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
|
||
fetchCounts = async () => { | ||
const { allowedTypes } = this.props; | ||
const { queryText, visibleTypes } = parseQuery(this.state.activeQuery); | ||
const { queryText, visibleTypes, visibleNamespaces } = parseQuery(this.state.activeQuery); | ||
|
||
const filteredTypes = allowedTypes.filter( | ||
(type) => !visibleTypes || visibleTypes.includes(type) | ||
|
@@ -187,6 +189,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
const filteredSavedObjectCounts = await getSavedObjectCounts( | ||
this.props.http, | ||
filteredTypes, | ||
visibleNamespaces, | ||
queryText | ||
); | ||
|
||
|
@@ -206,7 +209,12 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
|
||
// Fetch all the saved objects that exist so we can accurately populate the counts within | ||
// the table filter dropdown. | ||
const savedObjectCounts = await getSavedObjectCounts(this.props.http, allowedTypes, queryText); | ||
const savedObjectCounts = await getSavedObjectCounts( | ||
this.props.http, | ||
allowedTypes, | ||
[], | ||
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. Why passing empty array here, base on the context seems here should pass in the allowedNameSpaces? 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. Hey Kristen, thank you for pointing this out. For this implementation I was thinking that since namespaces are registered by plugins and not a static amount like with FYI I am working on a follow-up to this PR with a fix for a regression introduced on exporting button because of the
instead of:
I have some changes ready, but want to add better test coverage. You can see changes being prepared here: main...cwperks:OpenSearch-Dashboards:namespace-registry-fixes |
||
queryText | ||
); | ||
|
||
this.setState((state) => ({ | ||
...state, | ||
|
@@ -227,15 +235,19 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
debouncedFetchObjects = debounce(async () => { | ||
const { activeQuery: query, page, perPage } = this.state; | ||
const { notifications, http, allowedTypes } = this.props; | ||
const { queryText, visibleTypes } = parseQuery(query); | ||
const { queryText, visibleTypes, visibleNamespaces } = parseQuery(query); | ||
const filteredTypes = allowedTypes.filter( | ||
(type) => !visibleTypes || visibleTypes.includes(type) | ||
); | ||
// "searchFields" is missing from the "findOptions" but gets injected via the API. | ||
// The API extracts the fields from each uiExports.savedObjectsManagement "defaultSearchField" attribute | ||
const findOptions: SavedObjectsFindOptions = { | ||
search: queryText ? `${queryText}*` : undefined, | ||
perPage, | ||
page: page + 1, | ||
fields: ['id'], | ||
type: allowedTypes.filter((type) => !visibleTypes || visibleTypes.includes(type)), | ||
type: filteredTypes, | ||
namespaces: visibleNamespaces, | ||
}; | ||
if (findOptions.type.length > 1) { | ||
findOptions.sortField = 'type'; | ||
|
@@ -390,6 +402,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
onExportAll = async () => { | ||
const { exportAllSelectedOptions, isIncludeReferencesDeepChecked, activeQuery } = this.state; | ||
const { notifications, http } = this.props; | ||
|
||
const { queryText } = parseQuery(activeQuery); | ||
const exportTypes = Object.entries(exportAllSelectedOptions).reduce((accum, [id, selected]) => { | ||
if (selected) { | ||
|
@@ -764,18 +777,55 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
isSearching, | ||
savedObjectCounts, | ||
} = this.state; | ||
const { http, allowedTypes, applications } = this.props; | ||
const { http, allowedTypes, applications, namespaceRegistry } = this.props; | ||
|
||
const selectionConfig = { | ||
onSelectionChange: this.onSelectionChanged, | ||
}; | ||
const typeCounts = savedObjectCounts.type || {}; | ||
|
||
const filterOptions = allowedTypes.map((type) => ({ | ||
value: type, | ||
name: type, | ||
view: `${type} (${savedObjectCounts[type] || 0})`, | ||
view: `${type} (${typeCounts[type] || 0})`, | ||
cwperks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
})); | ||
|
||
const filters = [ | ||
{ | ||
type: 'field_value_selection', | ||
field: 'type', | ||
name: i18n.translate('savedObjectsManagement.objectsTable.table.typeFilterName', { | ||
defaultMessage: 'Type', | ||
}), | ||
multiSelect: 'or', | ||
options: filterOptions, | ||
}, | ||
]; | ||
|
||
const availableNamespaces = namespaceRegistry.getAll() || []; | ||
if (availableNamespaces && availableNamespaces.length > 0) { | ||
const nsCounts = savedObjectCounts.namespaces || {}; | ||
const nsFilterOptions = availableNamespaces.map((ns) => { | ||
return { | ||
name: ns.name, | ||
value: ns.id, | ||
view: `${ns.name} (${nsCounts[ns.id] || 0})`, | ||
}; | ||
}); | ||
|
||
filters.push({ | ||
type: 'field_value_selection', | ||
field: 'namespaces', | ||
name: | ||
namespaceRegistry.getAlias() || | ||
i18n.translate('savedObjectsManagement.objectsTable.table.namespaceFilterName', { | ||
defaultMessage: 'Namespaces', | ||
}), | ||
multiSelect: 'or', | ||
options: nsFilterOptions, | ||
}); | ||
} | ||
|
||
return ( | ||
<EuiPageContent horizontalPosition="center"> | ||
{this.renderFlyout()} | ||
|
@@ -799,7 +849,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb | |
selectedSavedObjects={selectedSavedObjects} | ||
onQueryChange={this.onQueryChange} | ||
onTableChange={this.onTableChange} | ||
filterOptions={filterOptions} | ||
filters={filters} | ||
onExport={this.onExport} | ||
canDelete={applications.capabilities.savedObjectsManagement.delete as boolean} | ||
onDelete={this.onDelete} | ||
|
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.
can this be made optional?
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.
The
filterFields
param? It can, but in practical use it will always at least containtype
.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.
FYI reverted this back to the original parseQuery, but modified the function to also extract namespaces.