diff --git a/.changeset/short-pots-report.md b/.changeset/short-pots-report.md new file mode 100644 index 0000000000..4323a957f3 --- /dev/null +++ b/.changeset/short-pots-report.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-org': patch +--- + +- Fixes padding in `MembersListCard` +- Fixes email icon size in `GroupProfileCard` +- Uniform sizing across `GroupProfileCard` and `UserProfileCard` diff --git a/plugins/org/package.json b/plugins/org/package.json index 4e12ad8837..4a278a22f5 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -22,6 +22,7 @@ "dependencies": { "@backstage/catalog-model": "^0.7.1", "@backstage/core": "^0.6.1", + "@backstage/core-api": "^0.2.9", "@backstage/plugin-catalog-react": "^0.0.3", "@backstage/theme": "^0.2.3", "@material-ui/core": "^4.11.0", @@ -29,6 +30,7 @@ "@material-ui/lab": "4.0.0-alpha.45", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-use": "^15.3.3" }, diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx new file mode 100644 index 0000000000..39d30d8165 --- /dev/null +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2021 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 { Grid } from '@material-ui/core'; +import React from 'react'; +import { MemoryRouter } from 'react-router'; +import { GroupEntity } from '@backstage/catalog-model'; +import { EntityContext } from '@backstage/plugin-catalog-react'; +import { GroupProfileCard } from '.'; + +export default { + title: 'Plugins/Org/Group Profile Card', + component: GroupProfileCard, +}; + +const dummyDepartment = { + type: 'childOf', + target: { + namespace: 'default', + kind: 'group', + name: 'department-a', + }, +}; + +const defaultEntity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'team-a', + description: 'Team A', + }, + spec: { + profile: { + displayName: 'Team A', + email: 'team-a@example.com', + picture: + 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + }, + type: 'group', + children: [], + }, + relations: [dummyDepartment], +}; + +export const Default = () => ( + + + + + + + + + +); diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index 9a72606c16..1682192880 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -117,7 +117,7 @@ export const GroupProfileCard = ({ - + {profile.email} diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx new file mode 100644 index 0000000000..20fb3a10ec --- /dev/null +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx @@ -0,0 +1,131 @@ +/* + * Copyright 2021 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 { Grid } from '@material-ui/core'; +import React from 'react'; +import { MemoryRouter } from 'react-router'; +import { Entity, GroupEntity } from '@backstage/catalog-model'; +import { EntityContext, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { ApiProvider, ApiRegistry } from '@backstage/core-api'; + +import { MembersListCard } from '.'; + +export default { + title: 'Plugins/Org/Group Members List Card', + component: MembersListCard, +}; + +const makeUser = ({ + name, + uid, + displayName, + email, +}: { + name: string; + uid: string; + displayName: string; + email: string; +}) => ({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name, + uid, + }, + spec: { + profile: { + displayName, + email, + picture: `https://avatars.dicebear.com/api/avataaars/${email}.svg?background=%23fff`, + }, + }, + relations: [ + { + type: 'memberOf', + target: { + namespace: 'default', + kind: 'group', + name: 'team-a', + }, + }, + ], +}); + +const defaultEntity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'team-a', + description: 'Team A', + }, + spec: { + profile: { + displayName: 'Team A', + email: 'team-a@example.com', + picture: + 'https://avatars.dicebear.com/api/identicon/team-a@example.com.svg?background=%23fff&margin=25', + }, + type: 'group', + children: [], + }, +}; + +const alice = makeUser({ + name: 'alice', + uid: '123', + displayName: 'Alice Doe', + email: 'alice@example.com', +}); +const bob = makeUser({ + name: 'bob', + uid: '456', + displayName: 'Bob Jones', + email: 'bob@example.com', +}); + +const catalogApi = (items: Entity[]) => ({ + getEntities: () => Promise.resolve({ items }), +}); + +const apiRegistry = (items: Entity[]) => + ApiRegistry.from([[catalogApiRef, catalogApi(items)]]); + +export const Default = () => ( + + + + + + + + + + + +); + +export const Empty = () => ( + + + + + + + + + + + +); diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx index 7f8ede2eb7..e60e22a8f2 100644 --- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx @@ -47,7 +47,7 @@ const useStyles = makeStyles((theme: Theme) => borderRadius: '4px', overflow: 'visible', position: 'relative', - margin: theme.spacing(3, 0, 1), + margin: theme.spacing(4, 1, 1), flex: '1', minWidth: '0px', }, @@ -69,7 +69,7 @@ const MemberComponent = ({ const displayName = profile?.displayName ?? metaName; return ( - + ({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name, + }, + spec: { + type, + }, + relations: [ + { + type: 'ownedBy', + target: { + namespace: 'default', + kind: 'Group', + name: 'team-a', + }, + }, + ], +}); + +const serviceA = makeComponent({ type: 'service', name: 'service-a' }); +const serviceB = makeComponent({ type: 'service', name: 'service-a' }); +const websiteA = makeComponent({ type: 'website', name: 'website-a' }); + +const catalogApi: Partial = { + getEntities: () => Promise.resolve({ items: [serviceA, serviceB, websiteA] }), +}; + +const apiRegistry = ApiRegistry.from([[catalogApiRef, catalogApi]]); + +export const Default = () => ( + + + + + + + + + + + +); diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx new file mode 100644 index 0000000000..b30427e923 --- /dev/null +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -0,0 +1,93 @@ +/* + * Copyright 2021 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 { Grid } from '@material-ui/core'; +import React from 'react'; +import { MemoryRouter } from 'react-router'; +import { UserEntity } from '@backstage/catalog-model'; +import { EntityContext } from '@backstage/plugin-catalog-react'; +import { UserProfileCard } from '.'; + +export default { + title: 'Plugins/Org/User Profile Card', + component: UserProfileCard, +}; + +const dummyGroup = { + type: 'memberOf', + target: { + namespace: 'default', + kind: 'group', + name: 'team-a', + }, +}; + +const defaultEntity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: 'guest', + }, + spec: { + profile: { + displayName: 'Guest User', + email: 'guest@example.com', + picture: + 'https://avatars.dicebear.com/api/avataaars/guest@example.com.svg?background=%23fff', + }, + memberOf: ['team-a'], + }, + relations: [dummyGroup], +}; + +export const Default = () => ( + + + + + + + + + +); + +const noImageEntity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: 'guest', + }, + spec: { + profile: { + displayName: 'Guest User', + email: 'guest@example.com', + }, + memberOf: ['team-a'], + }, + relations: [dummyGroup], +}; + +export const NoImage = () => ( + + + + + + + + + +); diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx index a4969f615b..4dfa543d95 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx @@ -95,11 +95,11 @@ export const UserProfileCard = ({ return ( } variant={variant}> - + - + {profile?.email && (