From 0f9af920f400349253fd81e152f81d9c8954e639 Mon Sep 17 00:00:00 2001 From: Brian Fletcher Date: Thu, 15 Dec 2022 09:06:12 +0000 Subject: [PATCH] remove entity ref link popover This also: - adds stories for the entity ref links componet - and moves some of the components into another file Signed-off-by: Brian Fletcher --- .../CardActionComponents/EmailCardAction.tsx | 33 +++++++ .../EntityCardActions.tsx | 48 ++++++++++ .../CardActionComponents/GroupCardActions.tsx | 33 +++++++ .../CardActionComponents/UserCardActions.tsx | 33 +++++++ .../CardActionComponents/index.ts | 18 ++++ .../EntityNotFoundCard.tsx | 41 ++++++++ .../EntityPeekAheadPopover.tsx | 94 ++----------------- .../EntityRefLink/EntityRefLink.stories.tsx | 94 +------------------ .../EntityRefLink/EntityRefLink.tsx | 21 +++-- .../EntityRefLink/EntityRefLinks.stories.tsx | 42 +++++++++ 10 files changed, 275 insertions(+), 182 deletions(-) create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts create mode 100644 plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityNotFoundCard.tsx create mode 100644 plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx new file mode 100644 index 0000000000..ed9ac7b9aa --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { Button, Tooltip } from '@material-ui/core'; +import EmailIcon from '@material-ui/icons/Email'; +import React from 'react'; + +/** + * Email Card action link + * + * @private + */ +export const EmailCardAction = ({ email }: { email: string }) => { + return ( + + + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx new file mode 100644 index 0000000000..d021a9f69d --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx @@ -0,0 +1,48 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { entityRouteRef } from '../../../routes'; +import { Tooltip } from '@material-ui/core'; +import InfoIcon from '@material-ui/icons/Info'; +import React from 'react'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { Link } from '@backstage/core-components'; + +/** + * Card actions that show for all entities + * + * @private + */ +export const EntityCardActions = ({ entity }: { entity: Entity }) => { + const entityRoute = useRouteRef(entityRouteRef); + + return ( + <> + + + + + + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx new file mode 100644 index 0000000000..fca0763703 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { EmailCardAction } from './EmailCardAction'; +import React from 'react'; +import { GroupEntity } from '@backstage/catalog-model'; + +/** + * Card actions that show for a group + * + * @private + */ +export const GroupCardActions = ({ entity }: { entity: GroupEntity }) => { + return ( + <> + {entity.spec.profile?.email && ( + + )} + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx new file mode 100644 index 0000000000..57801497f6 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { EmailCardAction } from './EmailCardAction'; +import React from 'react'; +import { UserEntity } from '@backstage/catalog-model'; + +/** + * Card actions that show for a user + * + * @private + */ +export const UserCardActions = ({ entity }: { entity: UserEntity }) => { + return ( + <> + {entity.spec.profile?.email && ( + + )} + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts new file mode 100644 index 0000000000..75959026f7 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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. + */ +export { EntityCardActions } from './EntityCardActions'; +export { GroupCardActions } from './GroupCardActions'; +export { UserCardActions } from './UserCardActions'; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityNotFoundCard.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityNotFoundCard.tsx new file mode 100644 index 0000000000..08d92cab22 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityNotFoundCard.tsx @@ -0,0 +1,41 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 { Card, CardContent } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; + +/** + * Entity not found card + * + * @private + */ +export const EntityNotFoundCard = ({ + entityRef, + error, +}: { + entityRef: string; + error?: Error; +}) => { + return ( + + + + {entityRef} was not found {error?.message} + + + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx index 6e5b75ed58..c6cba8d421 100644 --- a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { entityRouteRef } from '../../routes'; import useAsyncFn from 'react-use/lib/useAsyncFn'; import { catalogApiRef } from '../../api'; import React, { PropsWithChildren, useEffect } from 'react'; @@ -25,7 +24,6 @@ import { } from 'material-ui-popup-state/hooks'; import { Box, - Button, Card, CardActions, CardContent, @@ -34,19 +32,19 @@ import { Tooltip, Typography, } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; -import EmailIcon from '@material-ui/icons/Email'; -import InfoIcon from '@material-ui/icons/Info'; -import { useApiHolder, useRouteRef } from '@backstage/core-plugin-api'; +import { useApiHolder } from '@backstage/core-plugin-api'; import { - isUserEntity, isGroupEntity, - UserEntity, - GroupEntity, - Entity, + isUserEntity, parseEntityRef, } from '@backstage/catalog-model'; -import { Link, Progress } from '@backstage/core-components'; +import { Progress } from '@backstage/core-components'; +import { + EntityCardActions, + UserCardActions, + GroupCardActions, +} from './CardActionComponents'; +import { EntityNotFoundCard } from './EntityNotFoundCard'; /** * Properties for an entity popover on hover of a component. @@ -77,80 +75,6 @@ const useStyles = makeStyles(() => { const maxTagChips = 4; -const EmailCardAction = ({ email }: { email: string }) => { - return ( - - - - ); -}; - -const UserCardActions = ({ entity }: { entity: UserEntity }) => { - return ( - <> - {entity.spec.profile?.email && ( - - )} - - ); -}; - -const GroupCardActions = ({ entity }: { entity: GroupEntity }) => { - return ( - <> - {entity.spec.profile?.email && ( - - )} - - ); -}; - -/** - * Shows an entity popover on hover of a component. - * - * @public - */ -const EntityCardActions = ({ entity }: { entity: Entity }) => { - const entityRoute = useRouteRef(entityRouteRef); - - return ( - <> - - - - - - - ); -}; - -const EntityNotFoundCard = ({ - entityRef, - error, -}: { - entityRef: string; - error?: Error; -}) => { - return ( - - - - {entityRef} was not found {error?.message} - - - - ); -}; - /** * Shows an entity popover on hover of a component. * diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx index e09bf89382..e82c4ab963 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx @@ -16,64 +16,8 @@ import React, { ComponentType } from 'react'; import { EntityRefLink, EntityRefLinkProps } from './EntityRefLink'; -import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { catalogApiRef } from '../../api'; -import { CompoundEntityRef } from '@backstage/catalog-model'; +import { wrapInTestApp } from '@backstage/test-utils'; import { entityRouteRef } from '../../routes'; -import { CatalogApi } from '@backstage/catalog-client'; - -const mockCatalogApi = { - getEntityByRef: async (entityRef: CompoundEntityRef) => { - if ( - entityRef.namespace === 'default' && - entityRef.name === 'playback' && - entityRef.kind === 'component' - ) { - return { - kind: 'Component', - metadata: { - name: 'playback', - namespace: 'default', - description: 'Details about the playback service', - }, - }; - } - if ( - entityRef.namespace === 'default' && - entityRef.name === 'fname.lname' && - entityRef.kind === 'user' - ) { - return { - kind: 'User', - metadata: { - name: 'fname.lname', - namespace: 'default', - }, - spec: { - profile: { - email: 'fname.lname@example.com', - }, - }, - }; - } - if ( - entityRef.namespace === 'default' && - entityRef.name === 'slow.catalog.item' && - entityRef.kind === 'component' - ) { - await new Promise(resolve => setTimeout(resolve, 3000)); - return { - kind: 'Component', - metadata: { - name: 'slow.catalog.item', - namespace: 'default', - description: 'Details about the slow.catalog.item service', - }, - }; - } - return undefined; - }, -}; const defaultArgs = { entityRef: 'component:default/playback', @@ -83,20 +27,11 @@ export default { title: 'Catalog /EntityRefLink', decorators: [ (Story: ComponentType<{}>) => - wrapInTestApp( - <> - - - - , - { - mountedRoutes: { - '/catalog/:namespace/:kind/:name': entityRouteRef, - }, + wrapInTestApp(, { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, }, - ), + }), ], }; @@ -104,22 +39,3 @@ export const Default = (args: EntityRefLinkProps) => ( ); Default.args = defaultArgs; - -export const User = (args: EntityRefLinkProps) => ; -User.args = { - entityRef: 'user:default/fname.lname', -}; - -export const NotFound = (args: EntityRefLinkProps) => ( - -); -NotFound.args = { - entityRef: 'user:default/doesnt.exist', -}; - -export const SlowCatalogItem = (args: EntityRefLinkProps) => ( - -); -SlowCatalogItem.args = { - entityRef: 'component:default/slow.catalog.item', -}; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx index de94866bb6..06a632232e 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx @@ -25,7 +25,8 @@ import { entityRouteRef } from '../../routes'; import { humanizeEntityRef } from './humanize'; import { Link, LinkProps } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; -import { EntityPeekAheadPopover } from '../EntityPeekAheadPopover'; +import { Tooltip } from '@material-ui/core'; + /** * Props for {@link EntityRefLink}. * @@ -76,13 +77,17 @@ export const EntityRefLink = forwardRef( { defaultKind }, ); - return ( - - - {children} - {!children && (title ?? formattedEntityRefTitle)} - - + const link = ( + + {children} + {!children && (title ?? formattedEntityRefTitle)} + + ); + + return title ? ( + {link} + ) : ( + link ); }, ) as (props: EntityRefLinkProps) => JSX.Element; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx new file mode 100644 index 0000000000..176dd24530 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * 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 React, { ComponentType } from 'react'; +import { EntityRefLinks, EntityRefLinksProps } from './EntityRefLinks'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { CompoundEntityRef } from '@backstage/catalog-model'; +import { entityRouteRef } from '../../routes'; + +const defaultArgs = { + entityRefs: ['component:default/playback', 'user:default/fname.lname'], +}; + +export default { + title: 'Catalog /EntityRefLinks', + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp(, { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }), + ], +}; + +export const Default = ( + args: EntityRefLinksProps, +) => ; +Default.args = defaultArgs;