Merge pull request #3623 from SDA-SE/feat/org-ownership
Consider group memberships in the OwnershipCard
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Support transitive ownerships of users and groups.
|
||||
@@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { InfoCard, useApi, Progress } from '@backstage/core';
|
||||
import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog';
|
||||
import { useAsync } from 'react-use';
|
||||
import Alert from '@material-ui/lab/Alert';
|
||||
@@ -28,6 +29,7 @@ import {
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import { pageTheme } from '@backstage/theme';
|
||||
import { isOwnerOf } from '../../isOwnerOf';
|
||||
|
||||
type EntitiesKinds = 'Component' | 'API';
|
||||
type EntitiesTypes =
|
||||
@@ -118,9 +120,6 @@ export const OwnershipCard = ({
|
||||
entity: Entity;
|
||||
variant: string;
|
||||
}) => {
|
||||
const {
|
||||
metadata: { name: groupName },
|
||||
} = entity;
|
||||
const catalogApi = useApi(catalogApiRef);
|
||||
const {
|
||||
loading,
|
||||
@@ -129,10 +128,8 @@ export const OwnershipCard = ({
|
||||
} = useAsync(async () => {
|
||||
const entitiesList = await catalogApi.getEntities();
|
||||
const ownedEntitiesList = entitiesList.items.filter(component =>
|
||||
component?.relations?.some(
|
||||
r => r.type === RELATION_OWNED_BY && r.target.name === groupName,
|
||||
),
|
||||
) as Array<Entity>;
|
||||
isOwnerOf(entity, component),
|
||||
);
|
||||
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Entity, EntityName } from '@backstage/catalog-model';
|
||||
|
||||
// TODO: this file is copied from /packages/app/catalog/src/components/getEntityRelations.ts and
|
||||
// should be replaced once common relation-functions are introduced.
|
||||
|
||||
/**
|
||||
* Get the related entity references.
|
||||
*/
|
||||
export function getEntityRelations(
|
||||
entity: Entity | undefined,
|
||||
relationType: string,
|
||||
filter?: { kind: string },
|
||||
): EntityName[] {
|
||||
let entityNames =
|
||||
entity?.relations
|
||||
?.filter(r => r.type === relationType)
|
||||
?.map(r => r.target) || [];
|
||||
|
||||
if (filter?.kind) {
|
||||
entityNames = entityNames?.filter(
|
||||
e => e.kind.toLowerCase() === filter.kind.toLowerCase(),
|
||||
);
|
||||
}
|
||||
|
||||
return entityNames;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
EntityName,
|
||||
getEntityName,
|
||||
RELATION_MEMBER_OF,
|
||||
RELATION_OWNED_BY,
|
||||
} from '@backstage/catalog-model';
|
||||
import { getEntityRelations } from './getEntityRelations';
|
||||
|
||||
// TODO: this file is copied from /packages/app/catalog/src/components/isOwnerOf.ts and
|
||||
// should be replaced once common relation-functions are introduced.
|
||||
|
||||
/**
|
||||
* Check if one entity is owned by another. Returns true, if the entity is owned by the
|
||||
* owner directly, or if the entity is owned by a group that the owner is a member of.
|
||||
*/
|
||||
export function isOwnerOf(owner: Entity, owned: Entity) {
|
||||
const possibleOwners: EntityName[] = [
|
||||
...getEntityRelations(owner, RELATION_MEMBER_OF, { kind: 'group' }),
|
||||
...(owner ? [getEntityName(owner)] : []),
|
||||
];
|
||||
|
||||
const owners = getEntityRelations(owned, RELATION_OWNED_BY);
|
||||
|
||||
for (const owner of owners) {
|
||||
if (
|
||||
possibleOwners.find(
|
||||
o =>
|
||||
owner.kind.toLowerCase() === o.kind.toLowerCase() &&
|
||||
owner.namespace.toLowerCase() === o.namespace.toLowerCase() &&
|
||||
owner.name.toLowerCase() === o.name.toLowerCase(),
|
||||
) !== undefined
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user