Force entity references to be full in the owner picker.
Signed-off-by: Aramis Sennyey <sennyeya@amazon.com>
This commit is contained in:
committed by
Fredrik Adelöw
parent
b39b897a7b
commit
0b42e304f8
@@ -198,7 +198,7 @@ describe('<EntityOwnerPicker/>', () => {
|
||||
);
|
||||
|
||||
expect(updateFilters).toHaveBeenLastCalledWith({
|
||||
owners: new EntityOwnerFilter(['another-owner']),
|
||||
owners: new EntityOwnerFilter(['group:default/another-owner']),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -224,7 +224,7 @@ describe('<EntityOwnerPicker/>', () => {
|
||||
fireEvent.click(screen.getByTestId('owner-picker-expand'));
|
||||
fireEvent.click(screen.getByText('some-owner'));
|
||||
expect(updateFilters).toHaveBeenLastCalledWith({
|
||||
owners: new EntityOwnerFilter(['some-owner']),
|
||||
owners: new EntityOwnerFilter(['group:default/some-owner']),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -245,9 +245,10 @@ describe('<EntityOwnerPicker/>', () => {
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(updateFilters).toHaveBeenLastCalledWith({
|
||||
owners: new EntityOwnerFilter(['some-owner']),
|
||||
owners: new EntityOwnerFilter(['group:default/some-owner']),
|
||||
});
|
||||
fireEvent.click(screen.getByTestId('owner-picker-expand'));
|
||||
|
||||
expect(screen.getByLabelText('some-owner')).toBeChecked();
|
||||
|
||||
fireEvent.click(screen.getByLabelText('some-owner'));
|
||||
@@ -272,7 +273,7 @@ describe('<EntityOwnerPicker/>', () => {
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(updateFilters).toHaveBeenLastCalledWith({
|
||||
owners: new EntityOwnerFilter(['team-a']),
|
||||
owners: new EntityOwnerFilter(['group:default/team-a']),
|
||||
});
|
||||
rendered.rerender(
|
||||
<ApiProvider apis={mockApis}>
|
||||
@@ -288,7 +289,7 @@ describe('<EntityOwnerPicker/>', () => {
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(updateFilters).toHaveBeenLastCalledWith({
|
||||
owners: new EntityOwnerFilter(['team-b']),
|
||||
owners: new EntityOwnerFilter(['group:default/team-b']),
|
||||
});
|
||||
});
|
||||
it('removes owners from filters if there are none available', async () => {
|
||||
|
||||
@@ -107,14 +107,13 @@ export const EntityOwnerPicker = () => {
|
||||
if (entity) {
|
||||
return {
|
||||
label: humanizeEntity(entity, { defaultKind: 'Group' }),
|
||||
entityRef: humanizeEntityRef(entity, { defaultKind: 'Group' }),
|
||||
entityRef: stringifyEntityRef(entity),
|
||||
};
|
||||
}
|
||||
return {
|
||||
label: humanizeEntityRef(
|
||||
parseEntityRef(ownerEntityRefs[index], { defaultKind: 'Group' }),
|
||||
{ defaultKind: 'group' },
|
||||
),
|
||||
label: humanizeEntityRef(parseEntityRef(ownerEntityRefs[index]), {
|
||||
defaultKind: 'group',
|
||||
}),
|
||||
entityRef: ownerEntityRefs[index],
|
||||
};
|
||||
});
|
||||
@@ -143,7 +142,8 @@ export const EntityOwnerPicker = () => {
|
||||
// external updates to the page location.
|
||||
useEffect(() => {
|
||||
if (queryParamOwners.length) {
|
||||
setSelectedOwners(queryParamOwners);
|
||||
const filter = new EntityOwnerFilter(queryParamOwners);
|
||||
setSelectedOwners(filter.values);
|
||||
}
|
||||
}, [queryParamOwners]);
|
||||
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
|
||||
import { AlphaEntity } from '@backstage/catalog-model/alpha';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import {
|
||||
EntityErrorFilter,
|
||||
EntityOrphanFilter,
|
||||
EntityOwnerFilter,
|
||||
EntityTextFilter,
|
||||
} from './filters';
|
||||
|
||||
@@ -143,3 +144,50 @@ describe('EntityErrorFilter', () => {
|
||||
expect(filter.filterEntity(entities[1])).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('EntityOwnerFilter', () => {
|
||||
it('should handle humanizedEntityRefs', () => {
|
||||
const filter = new EntityOwnerFilter(['my-user']);
|
||||
expect(
|
||||
filter.filterEntity({
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
targetRef: 'group:default/my-user',
|
||||
},
|
||||
],
|
||||
} as Entity),
|
||||
).toBeTruthy();
|
||||
expect(filter.values).toStrictEqual(['group:default/my-user']);
|
||||
});
|
||||
|
||||
it('should also handle full entityRefs', () => {
|
||||
const filter = new EntityOwnerFilter(['group:default/my-user']);
|
||||
expect(
|
||||
filter.filterEntity({
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
targetRef: 'group:default/my-user',
|
||||
},
|
||||
],
|
||||
} as Entity),
|
||||
).toBeTruthy();
|
||||
expect(filter.values).toStrictEqual(['group:default/my-user']);
|
||||
});
|
||||
|
||||
it('should also gracefully reject non-entity refs', () => {
|
||||
const filter = new EntityOwnerFilter(['group:default/my-user', '']);
|
||||
expect(
|
||||
filter.filterEntity({
|
||||
relations: [
|
||||
{
|
||||
type: RELATION_OWNED_BY,
|
||||
targetRef: 'group:default/my-user',
|
||||
},
|
||||
],
|
||||
} as Entity),
|
||||
).toBeTruthy();
|
||||
expect(filter.values).toStrictEqual(['group:default/my-user']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,9 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
parseEntityRef,
|
||||
RELATION_OWNED_BY,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import { AlphaEntity } from '@backstage/catalog-model/alpha';
|
||||
import { humanizeEntityRef } from './components/EntityRefLink';
|
||||
import { EntityFilter, UserListFilterKind } from './types';
|
||||
import { getEntityRelations } from './utils';
|
||||
|
||||
@@ -113,18 +117,37 @@ export class EntityTextFilter implements EntityFilter {
|
||||
/**
|
||||
* Filter matching entities that are owned by group.
|
||||
* @public
|
||||
*
|
||||
* CAUTION: This class may contain both full and partial entity refs.
|
||||
*/
|
||||
export class EntityOwnerFilter implements EntityFilter {
|
||||
constructor(readonly values: string[]) {}
|
||||
readonly values: string[];
|
||||
constructor(values: string[]) {
|
||||
this.values = values.reduce((fullRefs, ref) => {
|
||||
// Attempt to remove bad entity references here.
|
||||
try {
|
||||
fullRefs.push(
|
||||
stringifyEntityRef(parseEntityRef(ref, { defaultKind: 'Group' })),
|
||||
);
|
||||
return fullRefs;
|
||||
} catch (err) {
|
||||
return fullRefs;
|
||||
}
|
||||
}, [] as string[]);
|
||||
}
|
||||
|
||||
filterEntity(entity: Entity): boolean {
|
||||
return this.values.some(v =>
|
||||
getEntityRelations(entity, RELATION_OWNED_BY).some(
|
||||
o => humanizeEntityRef(o, { defaultKind: 'group' }) === v,
|
||||
o => stringifyEntityRef(o) === v,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL query parameter value. May be a mix of full and humanized entity refs.
|
||||
* @returns list of entity refs.
|
||||
*/
|
||||
toQueryValue(): string[] {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user