Added EntityOrderFilter to sort entities by different fields
Signed-off-by: Mahendra Patel <mahendramp197@gmail.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': minor
|
||||
---
|
||||
|
||||
Added EntityOrderFilter to sort entities by different fields/columns. This new filter allows users to specify the order in which entities are displayed in the catalog.
|
||||
|
||||
Example usage:
|
||||
|
||||
```ts
|
||||
import { EntityOrderFilter } from '@backstage/plugin-catalog-react';
|
||||
|
||||
updateFilters({
|
||||
order: new EntityOrderFilter([
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'desc',
|
||||
},
|
||||
]),
|
||||
});
|
||||
```
|
||||
@@ -60,6 +60,12 @@ const mockUser: UserEntity = {
|
||||
};
|
||||
|
||||
const ownershipEntityRefs = ['user:default/testuser'];
|
||||
const orderFields = [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
];
|
||||
|
||||
const mockConfigApi = mockApis.config({
|
||||
data: { organization: { name: 'Test Company' } },
|
||||
@@ -190,6 +196,7 @@ describe('<UserListPicker />', () => {
|
||||
'metadata.namespace': ['default'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: {
|
||||
@@ -197,6 +204,7 @@ describe('<UserListPicker />', () => {
|
||||
'relations.ownedBy': ['user:default/testuser'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: {
|
||||
@@ -204,6 +212,7 @@ describe('<UserListPicker />', () => {
|
||||
'metadata.name': ['e-1', 'e-2'],
|
||||
},
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -229,10 +238,12 @@ describe('<UserListPicker />', () => {
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { 'metadata.tags': ['tag1'] },
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { 'metadata.name': ['e-1', 'e-2'], 'metadata.tags': ['tag1'] },
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: {
|
||||
@@ -240,6 +251,7 @@ describe('<UserListPicker />', () => {
|
||||
'metadata.tags': ['tag1'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -272,10 +284,12 @@ describe('<UserListPicker />', () => {
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { kind: 'component' },
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { kind: 'component', 'metadata.name': ['e-1', 'e-2'] },
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: {
|
||||
@@ -283,6 +297,7 @@ describe('<UserListPicker />', () => {
|
||||
'relations.ownedBy': ['user:default/testuser'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -308,10 +323,12 @@ describe('<UserListPicker />', () => {
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { kind: 'component', 'metadata.name': ['e-1', 'e-2'] },
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { kind: 'component' },
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: {
|
||||
@@ -319,6 +336,7 @@ describe('<UserListPicker />', () => {
|
||||
'relations.ownedBy': ['user:default/testuser'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -451,6 +469,7 @@ describe('<UserListPicker />', () => {
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { 'metadata.name': ['e-1', 'e-2'] },
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
expect(updateFilters).not.toHaveBeenCalledWith({
|
||||
@@ -624,6 +643,7 @@ describe('<UserListPicker />', () => {
|
||||
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith({
|
||||
filter: { 'metadata.name': ['e-1', 'e-2'] },
|
||||
limit: 1000,
|
||||
orderFields,
|
||||
});
|
||||
});
|
||||
expect(updateFilters).not.toHaveBeenCalledWith({
|
||||
|
||||
@@ -74,6 +74,12 @@ describe('useAllEntitiesCount', () => {
|
||||
'relations.ownedBy': ['user:default/owner'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields: [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(result.current).toEqual({ count: 10, loading: false });
|
||||
|
||||
@@ -115,6 +115,12 @@ describe('useOwnedEntitiesCount', () => {
|
||||
'relations.ownedBy': ['user:default/spiderman', 'user:group/a-group'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields: [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -190,6 +196,12 @@ describe('useOwnedEntitiesCount', () => {
|
||||
'relations.ownedBy': ['user:group/a-group'],
|
||||
},
|
||||
limit: 0,
|
||||
orderFields: [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -87,6 +87,12 @@ describe('useStarredEntitiesCount', () => {
|
||||
'metadata.name': ['favourite1', 'favourite2'],
|
||||
},
|
||||
limit: 1000,
|
||||
orderFields: [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(result.current).toEqual({
|
||||
count: 2,
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
import { AlphaEntity } from '@backstage/catalog-model/alpha';
|
||||
import { EntityFilter, UserListFilterKind } from './types';
|
||||
import { getEntityRelations } from './utils/getEntityRelations';
|
||||
import { EntityOrderQuery } from '@backstage/catalog-client';
|
||||
|
||||
/**
|
||||
* Filter entities based on Kind.
|
||||
@@ -331,3 +332,19 @@ export class EntityErrorFilter implements EntityFilter {
|
||||
return error !== undefined && this.value === error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort entities by a given field/column.
|
||||
* @public
|
||||
*/
|
||||
export class EntityOrderFilter implements EntityFilter {
|
||||
constructor(readonly value: EntityOrderQuery) {}
|
||||
|
||||
getOrderFilters(): EntityOrderQuery {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
filterEntity(_: Entity): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
EntityKindFilter,
|
||||
EntityLifecycleFilter,
|
||||
EntityNamespaceFilter,
|
||||
EntityOrderFilter,
|
||||
EntityOrphanFilter,
|
||||
EntityOwnerFilter,
|
||||
EntityTagFilter,
|
||||
@@ -64,6 +65,7 @@ export type DefaultEntityFilters = {
|
||||
orphan?: EntityOrphanFilter;
|
||||
error?: EntityErrorFilter;
|
||||
namespace?: EntityNamespaceFilter;
|
||||
order?: EntityOrderFilter;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
@@ -287,7 +289,6 @@ export const EntityListProvider = <EntityFilters extends DefaultEntityFilters>(
|
||||
...backendFilter,
|
||||
limit,
|
||||
offset,
|
||||
orderFields: [{ field: 'metadata.name', order: 'asc' }],
|
||||
});
|
||||
setOutputState({
|
||||
appliedFilters: requestedFilters,
|
||||
|
||||
@@ -19,6 +19,7 @@ import { EntityFilter } from '../types';
|
||||
import {
|
||||
EntityLifecycleFilter,
|
||||
EntityNamespaceFilter,
|
||||
EntityOrderFilter,
|
||||
EntityOrphanFilter,
|
||||
EntityOwnerFilter,
|
||||
EntityTagFilter,
|
||||
@@ -26,18 +27,24 @@ import {
|
||||
EntityUserFilter,
|
||||
UserListFilter,
|
||||
} from '../filters';
|
||||
import { EntityOrderQuery } from '@backstage/catalog-client';
|
||||
|
||||
export interface CatalogFilters {
|
||||
filter: Record<string, string | symbol | (string | symbol)[]>;
|
||||
fullTextFilter?: {
|
||||
term: string;
|
||||
};
|
||||
orderFields?: EntityOrderQuery;
|
||||
}
|
||||
|
||||
function isEntityTextFilter(t: EntityFilter): t is EntityTextFilter {
|
||||
return !!(t as EntityTextFilter).getFullTextFilters;
|
||||
}
|
||||
|
||||
function isEntityOrderFilter(t: EntityFilter): t is EntityOrderFilter {
|
||||
return !!(t as EntityOrderFilter).getOrderFilters;
|
||||
}
|
||||
|
||||
export function reduceCatalogFilters(filters: EntityFilter[]): CatalogFilters {
|
||||
const condensedFilters = filters.reduce<CatalogFilters['filter']>(
|
||||
(compoundFilter, filter) => {
|
||||
@@ -50,7 +57,14 @@ export function reduceCatalogFilters(filters: EntityFilter[]): CatalogFilters {
|
||||
);
|
||||
|
||||
const fullTextFilter = filters.find(isEntityTextFilter)?.getFullTextFilters();
|
||||
return { filter: condensedFilters, fullTextFilter };
|
||||
|
||||
const orderFields = filters.find(isEntityOrderFilter)?.getOrderFilters() || [
|
||||
{
|
||||
field: 'metadata.name',
|
||||
order: 'asc',
|
||||
},
|
||||
];
|
||||
return { filter: condensedFilters, fullTextFilter, orderFields };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user