From f4f50d8eef222bd07cff48d27816ec0b1ec979f8 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:01:03 +0100 Subject: [PATCH 01/12] [Playlist] feat: added dynamic group noun through the config Signed-off-by: antonio.bergas --- app-config.yaml | 4 ++ plugins/playlist/config.d.ts | 31 +++++++++++ plugins/playlist/package.json | 23 +++++++- .../CreatePlaylistButton.tsx | 14 +++-- .../EntityPlaylistDialog.tsx | 38 +++++++++++--- .../PlaylistEditDialog/PlaylistEditDialog.tsx | 13 +++-- .../PlaylistIndexPage/PlaylistIndexPage.tsx | 52 ++++++++++--------- .../components/PlaylistList/PlaylistList.tsx | 7 ++- .../PlaylistPage/PlaylistEntitiesTable.tsx | 10 ++-- .../PlaylistPage/PlaylistHeader.tsx | 5 +- plugins/playlist/src/hooks/index.ts | 1 + plugins/playlist/src/hooks/useConfig.ts | 27 ++++++++++ .../playlist/src/hooks/usePlaylistList.tsx | 2 +- 13 files changed, 181 insertions(+), 46 deletions(-) create mode 100644 plugins/playlist/config.d.ts create mode 100644 plugins/playlist/src/hooks/useConfig.ts diff --git a/app-config.yaml b/app-config.yaml index 385c9c2e0e..7b94e2fb2e 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -125,6 +125,10 @@ proxy: organization: name: My Company + +playlist: + groupPluralNoun: Collections + groupSingularNoun: Collection # Reference documentation http://backstage.io/docs/features/techdocs/configuration # Note: After experimenting with basic setup, use CI/CD to generate docs diff --git a/plugins/playlist/config.d.ts b/plugins/playlist/config.d.ts new file mode 100644 index 0000000000..5f59ffc236 --- /dev/null +++ b/plugins/playlist/config.d.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2020 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 interface Config { + playlist: { + /** + * (Optional) The plural noun for the entities grouping that will shown in the UI; leave empty for `PLaylists`. + * @visibility frontend + */ + groupPluralNoun: string; + + /** + * (Optional) The singular noun for the entities grouping that will shown in the UI; leave empty for `PLaylists`. + * @visibility frontend + */ + groupSingularNoun: string; + }; +} diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 59cde3f246..bed1d654c5 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -66,5 +66,26 @@ }, "files": [ "dist" - ] + ], + "configSchema": { + "$schema": "https://backstage.io/schema/config-v1", + "type": "object", + "properties": { + "playlist": { + "type": "object", + "properties": { + "groupPluralNoun": { + "type": "string", + "description": "Frontend plural entities grouping name", + "visibility": "frontend" + }, + "groupSingularNoun": { + "type": "string", + "description": "Frontend singular entities grouping name", + "visibility": "frontend" + } + } + } + } + } } diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx index c064f28591..a615e2cb36 100644 --- a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx @@ -14,7 +14,12 @@ * limitations under the License. */ -import { errorApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { + configApiRef, + errorApiRef, + useApi, + useRouteRef, +} from '@backstage/core-plugin-api'; import { BackstageTheme } from '@backstage/theme'; import { usePermission } from '@backstage/plugin-permission-react'; import { @@ -29,6 +34,7 @@ import { useNavigate } from 'react-router-dom'; import { playlistApiRef } from '../../api'; import { playlistRouteRef } from '../../routes'; import { PlaylistEditDialog } from '../PlaylistEditDialog'; +import { useGroupNoun } from '../../hooks/useConfig'; export const CreatePlaylistButton = () => { const navigate = useNavigate(); @@ -55,13 +61,15 @@ export const CreatePlaylistButton = () => { [errorApi, navigate, playlistApi, playlistRoute], ); + const groupSingularNounLowerCase = useGroupNoun(false, false); + return ( <> {isXSScreen ? ( setOpenDialog(true)} > @@ -74,7 +82,7 @@ export const CreatePlaylistButton = () => { color="primary" onClick={() => setOpenDialog(true)} > - Create Playlist + Create {groupSingularNounLowerCase} )} { [playlistApi], ); + const groupSingularNoun = useGroupNoun(true, false); + const groupSingularNounLowerCase = useGroupNoun(false, true); + const groupPluralNounLowerCase = useGroupNoun(true, true); + useEffect(() => { if (open) { loadPlaylists(); @@ -120,12 +130,19 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { navigate(playlistRoute({ playlistId })); } catch (e) { alertApi.post({ - message: `Failed to add entity to playlist: ${e}`, + message: `Failed to add entity to ${groupSingularNounLowerCase}: ${e}`, severity: 'error', }); } }, - [alertApi, entity, navigate, playlistApi, playlistRoute], + [ + alertApi, + entity, + navigate, + playlistApi, + playlistRoute, + groupSingularNounLowerCase, + ], ); const [{ loading: addEntityLoading }, addToPlaylist] = useAsyncFn( @@ -141,12 +158,12 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { }); } catch (e) { alertApi.post({ - message: `Failed to add entity to playlist: ${e}`, + message: `Failed to add entity to ${groupSingularNounLowerCase}: ${e}`, severity: 'error', }); } }, - [alertApi, closeDialog, entity, playlistApi], + [alertApi, closeDialog, entity, playlistApi, groupSingularNounLowerCase], ); return ( @@ -160,7 +177,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { > {(loading || addEntityLoading) && } - Add to Playlist + Add to {groupSingularNoun} { {error && ( - + )} {playlists && entity && ( @@ -205,7 +225,9 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { - + )} {playlists diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx index 27cc13fede..ebdf4a1798 100644 --- a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx @@ -15,7 +15,11 @@ */ import { parseEntityRef } from '@backstage/catalog-model'; -import { identityApiRef, useApi } from '@backstage/core-plugin-api'; +import { + configApiRef, + identityApiRef, + useApi, +} from '@backstage/core-plugin-api'; import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; import { @@ -39,6 +43,7 @@ import React from 'react'; import { useForm, Controller } from 'react-hook-form'; import useAsync from 'react-use/lib/useAsync'; import useAsyncFn from 'react-use/lib/useAsyncFn'; +import { useGroupNoun } from '../../hooks/useConfig'; const useStyles = makeStyles({ buttonWrapper: { @@ -105,6 +110,8 @@ export const PlaylistEditDialog = ({ } }; + const groupSingularNounLowercase = useGroupNoun(false, false); + return ( @@ -121,7 +128,7 @@ export const PlaylistEditDialog = ({ fullWidth label="Name" margin="dense" - placeholder="Give your playlist name" + placeholder={`Give your ${groupSingularNounLowercase} name`} required type="text" /> @@ -139,7 +146,7 @@ export const PlaylistEditDialog = ({ label="Description" margin="dense" multiline - placeholder="Describe your playlist" + placeholder={`Describe your ${groupSingularNounLowercase}`} type="text" /> )} diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx index 0ee829018a..6a92718df2 100644 --- a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx +++ b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx @@ -23,7 +23,7 @@ import { } from '@backstage/core-components'; import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; -import { PlaylistListProvider } from '../../hooks'; +import { PlaylistListProvider, useGroupNoun } from '../../hooks'; import { CreatePlaylistButton } from '../CreatePlaylistButton'; import { PersonalListPicker } from '../PersonalListPicker'; import { PlaylistList } from '../PlaylistList'; @@ -31,26 +31,30 @@ import { PlaylistOwnerPicker } from '../PlaylistOwnerPicker'; import { PlaylistSearchBar } from '../PlaylistSearchBar'; import { PlaylistSortPicker } from '../PlaylistSortPicker'; -export const PlaylistIndexPage = () => ( - - - - - - - - - - - - - - - - - - - - - -); +export const PlaylistIndexPage = () => { + const groupPluralNoun = useGroupNoun(true, false); + + return ( + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx index fcc3971542..fd8569e758 100644 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx @@ -23,18 +23,21 @@ import { } from '@backstage/core-components'; import { Typography } from '@material-ui/core'; -import { usePlaylistList } from '../../hooks'; +import { useGroupNoun, usePlaylistList } from '../../hooks'; import { PlaylistCard } from '../PlaylistCard'; export const PlaylistList = () => { const { loading, error, playlists } = usePlaylistList(); + const groupPluralNounLowercase = useGroupNoun(true, true); return ( <> {loading && } {error && ( - + {error.message} )} diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx index f499f59a61..384d51612b 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx @@ -21,7 +21,7 @@ import { Table, TableFilter, } from '@backstage/core-components'; -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; +import { configApiRef, errorApiRef, useApi } from '@backstage/core-plugin-api'; import { EntityRefLink } from '@backstage/plugin-catalog-react'; import { usePermission } from '@backstage/plugin-permission-react'; import { permissions } from '@backstage/plugin-playlist-common'; @@ -32,6 +32,7 @@ import React, { forwardRef, useCallback, useEffect, useState } from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; import { playlistApiRef } from '../../api'; +import { useGroupNoun } from '../../hooks/useConfig'; import { AddEntitiesDrawer } from './AddEntitiesDrawer'; export const PlaylistEntitiesTable = ({ @@ -41,6 +42,7 @@ export const PlaylistEntitiesTable = ({ }) => { const errorApi = useApi(errorApiRef); const playlistApi = useApi(playlistApiRef); + const configApi = useApi(configApiRef); const [openAddEntitiesDrawer, setOpenAddEntitiesDrawer] = useState(false); const { allowed: editAllowed } = usePermission({ @@ -84,16 +86,18 @@ export const PlaylistEntitiesTable = ({ [errorApi, loadEntities, playlistApi, playlistId], ); + const groupSingularNounLowerCase = useGroupNoun(false, true); + const actions = editAllowed ? [ { icon: DeleteIcon, - tooltip: 'Remove from playlist', + tooltip: `Remove from ${groupSingularNounLowerCase}`, onClick: removeEntity, }, { icon: AddBoxIcon, - tooltip: 'Add entities to playlist', + tooltip: `Add entities to ${groupSingularNounLowerCase}`, isFreeAction: true, onClick: () => setOpenAddEntitiesDrawer(true), }, diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx index 7f4457062d..ecf443b565 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx @@ -45,6 +45,7 @@ import useAsyncFn from 'react-use/lib/useAsyncFn'; import { playlistApiRef } from '../../api'; import { rootRouteRef } from '../../routes'; import { PlaylistEditDialog } from '../PlaylistEditDialog'; +import { useGroupNoun } from '../../hooks/useConfig'; const useStyles = makeStyles({ buttonWrapper: { @@ -109,6 +110,8 @@ export const PlaylistHeader = ({ playlist, onUpdate }: PlaylistHeaderProps) => { } }, [playlistApi]); + const groupSingularNoun = useGroupNoun(false, false); + return (
{ onClick: () => setOpenEditDialog(true), }, { - label: 'Delete Playlist', + label: `Delete ${groupSingularNoun}`, icon: , disabled: !deleteAllowed, onClick: () => setOpenDeleteDialog(true), diff --git a/plugins/playlist/src/hooks/index.ts b/plugins/playlist/src/hooks/index.ts index 316121b515..da045fbf65 100644 --- a/plugins/playlist/src/hooks/index.ts +++ b/plugins/playlist/src/hooks/index.ts @@ -15,3 +15,4 @@ */ export * from './usePlaylistList'; +export * from './useConfig'; diff --git a/plugins/playlist/src/hooks/useConfig.ts b/plugins/playlist/src/hooks/useConfig.ts new file mode 100644 index 0000000000..15d44570a8 --- /dev/null +++ b/plugins/playlist/src/hooks/useConfig.ts @@ -0,0 +1,27 @@ +/* + * 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 { configApiRef, useApi } from '@backstage/core-plugin-api'; + +export function useGroupNoun(inPlural: boolean, inLowerCase: boolean) { + const configApi = useApi(configApiRef); + const defaultNoun = inPlural ? 'Playlists' : 'Playlist'; + const configProp = inPlural ? 'groupPluralNoun' : 'groupSingularNoun'; + const groupNoun = + configApi.getOptionalString(`playlist.${configProp}`) ?? `${defaultNoun}`; + + return inLowerCase ? groupNoun.toLocaleLowerCase('en-US') : groupNoun; +} diff --git a/plugins/playlist/src/hooks/usePlaylistList.tsx b/plugins/playlist/src/hooks/usePlaylistList.tsx index 69f712413b..4d2b857520 100644 --- a/plugins/playlist/src/hooks/usePlaylistList.tsx +++ b/plugins/playlist/src/hooks/usePlaylistList.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { useApi } from '@backstage/core-plugin-api'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { Playlist } from '@backstage/plugin-playlist-common'; import { compact, isEqual } from 'lodash'; import qs from 'qs'; From 1207646d38af969cd8052d73f4d982c8dcda14c5 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:13:00 +0100 Subject: [PATCH 02/12] [Playlist] feat: added dynamic group noun through the config Signed-off-by: antonio.bergas --- plugins/playlist/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/playlist/README.md b/plugins/playlist/README.md index 6ae3fb84ac..c85eee8f94 100644 --- a/plugins/playlist/README.md +++ b/plugins/playlist/README.md @@ -131,6 +131,18 @@ const defaultEntityPage = ( Note: the above only shows an example for the `defaultEntityPage` for a full example of this you can look at [this EntityPage](../../packages/app/src/components/catalog/EntityPage.tsx) +## Custom Group Noun + +You can define your custom group noun to shown in all the components of the Playlist plugin in the UI. To do this you just need to add some config in your **app-config.yaml**, here's an example: + +```yaml +playlist: + groupPluralNoun: Collections + groupSingularNoun: Collection +``` + +_You will always need the plural and the singular matching to have a consistency in the UI_ + ## Features ### View All Playlists From 03cfdd388cfdac2e27f5d5e0f3b46c417e0840a0 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:14:14 +0100 Subject: [PATCH 03/12] [Playlist] feat: added dynamic group noun through the config Signed-off-by: antonio.bergas --- app-config.yaml | 4 ---- .../EntityPlaylistDialog/EntityPlaylistDialog.tsx | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index 7b94e2fb2e..385c9c2e0e 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -125,10 +125,6 @@ proxy: organization: name: My Company - -playlist: - groupPluralNoun: Collections - groupSingularNoun: Collection # Reference documentation http://backstage.io/docs/features/techdocs/configuration # Note: After experimenting with basic setup, use CI/CD to generate docs diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx index 1bf26fadd7..cc69a24d78 100644 --- a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx +++ b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx @@ -16,12 +16,7 @@ import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { ResponseErrorPanel } from '@backstage/core-components'; -import { - alertApiRef, - configApiRef, - useApi, - useRouteRef, -} from '@backstage/core-plugin-api'; +import { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { humanizeEntityRef, useAsyncEntity, From a3967b9a55c82ec7980ade5ade17f113a6389ff4 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:16:05 +0100 Subject: [PATCH 04/12] [Playlist] feat: added dynamic group noun through the config Signed-off-by: antonio.bergas --- plugins/playlist/src/hooks/usePlaylistList.test.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/playlist/src/hooks/usePlaylistList.test.tsx b/plugins/playlist/src/hooks/usePlaylistList.test.tsx index 9b4b0ca0fc..f528375db6 100644 --- a/plugins/playlist/src/hooks/usePlaylistList.test.tsx +++ b/plugins/playlist/src/hooks/usePlaylistList.test.tsx @@ -16,7 +16,6 @@ import { ConfigApi, - configApiRef, IdentityApi, identityApiRef, } from '@backstage/core-plugin-api'; From 81933db1259a3a0f4ec84110b59fb8fe57d2edbc Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:24:08 +0100 Subject: [PATCH 05/12] Fixed wrong import delete Signed-off-by: antonio.bergas --- plugins/playlist/src/hooks/usePlaylistList.test.tsx | 1 + plugins/playlist/src/hooks/usePlaylistList.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/playlist/src/hooks/usePlaylistList.test.tsx b/plugins/playlist/src/hooks/usePlaylistList.test.tsx index f528375db6..9b4b0ca0fc 100644 --- a/plugins/playlist/src/hooks/usePlaylistList.test.tsx +++ b/plugins/playlist/src/hooks/usePlaylistList.test.tsx @@ -16,6 +16,7 @@ import { ConfigApi, + configApiRef, IdentityApi, identityApiRef, } from '@backstage/core-plugin-api'; diff --git a/plugins/playlist/src/hooks/usePlaylistList.tsx b/plugins/playlist/src/hooks/usePlaylistList.tsx index 4d2b857520..69f712413b 100644 --- a/plugins/playlist/src/hooks/usePlaylistList.tsx +++ b/plugins/playlist/src/hooks/usePlaylistList.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { useApi } from '@backstage/core-plugin-api'; import { Playlist } from '@backstage/plugin-playlist-common'; import { compact, isEqual } from 'lodash'; import qs from 'qs'; From ed30a8b213b7958cd9fe120daf7f988be8611c92 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:33:16 +0100 Subject: [PATCH 06/12] Update changelog and version Signed-off-by: antonio.bergas --- plugins/playlist/CHANGELOG.md | 4 ++++ plugins/playlist/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index 43a7ff4e4d..648ff6319d 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,9 @@ # @backstage/plugin-playlist +## 0.1.8 + +- Added config properties to change dynamically the group noun for all the components in the UI + ## 0.1.7 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index bed1d654c5..289236428b 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.7", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", From 1b3c05460479ec0ebbe1a9e16d859fcc6c4bab86 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Sat, 18 Mar 2023 23:42:21 +0100 Subject: [PATCH 07/12] Added missing changeset Removed imports not used Signed-off-by: antonio.bergas --- .changeset/perfect-deers-add.md | 5 +++++ .../CreatePlaylistButton/CreatePlaylistButton.tsx | 7 +------ .../components/PlaylistEditDialog/PlaylistEditDialog.tsx | 6 +----- .../src/components/PlaylistPage/PlaylistEntitiesTable.tsx | 3 +-- 4 files changed, 8 insertions(+), 13 deletions(-) create mode 100644 .changeset/perfect-deers-add.md diff --git a/.changeset/perfect-deers-add.md b/.changeset/perfect-deers-add.md new file mode 100644 index 0000000000..c932351a19 --- /dev/null +++ b/.changeset/perfect-deers-add.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-playlist': patch +--- + +Added config properties to change dynamically the group noun for all the components in the UI diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx index a615e2cb36..cc7427c96c 100644 --- a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx @@ -14,12 +14,7 @@ * limitations under the License. */ -import { - configApiRef, - errorApiRef, - useApi, - useRouteRef, -} from '@backstage/core-plugin-api'; +import { errorApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { BackstageTheme } from '@backstage/theme'; import { usePermission } from '@backstage/plugin-permission-react'; import { diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx index ebdf4a1798..d8f48cbecf 100644 --- a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx @@ -15,11 +15,7 @@ */ import { parseEntityRef } from '@backstage/catalog-model'; -import { - configApiRef, - identityApiRef, - useApi, -} from '@backstage/core-plugin-api'; +import { identityApiRef, useApi } from '@backstage/core-plugin-api'; import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; import { PlaylistMetadata } from '@backstage/plugin-playlist-common'; import { diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx index 384d51612b..3f9e10c4c8 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx @@ -21,7 +21,7 @@ import { Table, TableFilter, } from '@backstage/core-components'; -import { configApiRef, errorApiRef, useApi } from '@backstage/core-plugin-api'; +import { errorApiRef, useApi } from '@backstage/core-plugin-api'; import { EntityRefLink } from '@backstage/plugin-catalog-react'; import { usePermission } from '@backstage/plugin-permission-react'; import { permissions } from '@backstage/plugin-playlist-common'; @@ -42,7 +42,6 @@ export const PlaylistEntitiesTable = ({ }) => { const errorApi = useApi(errorApiRef); const playlistApi = useApi(playlistApiRef); - const configApi = useApi(configApiRef); const [openAddEntitiesDrawer, setOpenAddEntitiesDrawer] = useState(false); const { allowed: editAllowed } = usePermission({ From 5f50c92dc3f06b4099be7f5bc7aa48e1469f7a9c Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Mon, 20 Mar 2023 18:06:36 +0100 Subject: [PATCH 08/12] [Playlist]feat: rename new config prop to title and use pluralize to manage nouns Signed-off-by: antonio.bergas --- app-config.yaml | 3 ++ plugins/playlist/CHANGELOG.md | 4 --- plugins/playlist/README.md | 9 ++---- plugins/playlist/config.d.ts | 12 ++------ plugins/playlist/package.json | 28 ++++--------------- .../CreatePlaylistButton.tsx | 8 +++--- .../EntityPlaylistDialog.tsx | 22 +++++++-------- .../PlaylistEditDialog/PlaylistEditDialog.tsx | 8 +++--- .../PlaylistIndexPage/PlaylistIndexPage.tsx | 6 ++-- .../components/PlaylistList/PlaylistList.tsx | 6 ++-- .../PlaylistPage/PlaylistEntitiesTable.tsx | 8 +++--- .../PlaylistPage/PlaylistHeader.tsx | 6 ++-- plugins/playlist/src/hooks/index.ts | 2 +- .../src/hooks/{useConfig.ts => useTitle.ts} | 14 ++++++---- yarn.lock | 1 + 15 files changed, 56 insertions(+), 81 deletions(-) rename plugins/playlist/src/hooks/{useConfig.ts => useTitle.ts} (65%) diff --git a/app-config.yaml b/app-config.yaml index 385c9c2e0e..ba9df18085 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -126,6 +126,9 @@ proxy: organization: name: My Company +playlist: + title: Module + # Reference documentation http://backstage.io/docs/features/techdocs/configuration # Note: After experimenting with basic setup, use CI/CD to generate docs # and an external cloud storage when deploying TechDocs for production use-case. diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index 648ff6319d..43a7ff4e4d 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,9 +1,5 @@ # @backstage/plugin-playlist -## 0.1.8 - -- Added config properties to change dynamically the group noun for all the components in the UI - ## 0.1.7 ### Patch Changes diff --git a/plugins/playlist/README.md b/plugins/playlist/README.md index c85eee8f94..e35f94b9e5 100644 --- a/plugins/playlist/README.md +++ b/plugins/playlist/README.md @@ -131,18 +131,15 @@ const defaultEntityPage = ( Note: the above only shows an example for the `defaultEntityPage` for a full example of this you can look at [this EntityPage](../../packages/app/src/components/catalog/EntityPage.tsx) -## Custom Group Noun +## Custom Title -You can define your custom group noun to shown in all the components of the Playlist plugin in the UI. To do this you just need to add some config in your **app-config.yaml**, here's an example: +You can define a custom title to be shown in all the components of this plugin to replace the default term "playlist" in the UI. To do this you just need to add some config in your **app-config.yaml**, here's an example: ```yaml playlist: - groupPluralNoun: Collections - groupSingularNoun: Collection + title: Collection ``` -_You will always need the plural and the singular matching to have a consistency in the UI_ - ## Features ### View All Playlists diff --git a/plugins/playlist/config.d.ts b/plugins/playlist/config.d.ts index 5f59ffc236..e6245e22a6 100644 --- a/plugins/playlist/config.d.ts +++ b/plugins/playlist/config.d.ts @@ -15,17 +15,11 @@ */ export interface Config { - playlist: { + playlist?: { /** - * (Optional) The plural noun for the entities grouping that will shown in the UI; leave empty for `PLaylists`. + * (Optional) The title that will shown in the UI; leave empty for `PLaylist`. * @visibility frontend */ - groupPluralNoun: string; - - /** - * (Optional) The singular noun for the entities grouping that will shown in the UI; leave empty for `PLaylists`. - * @visibility frontend - */ - groupSingularNoun: string; + title?: string | undefined; }; } diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 289236428b..285673a99c 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.8", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -42,6 +42,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.57", "lodash": "^4.17.21", + "pluralize": "^8.0.0", "qs": "^6.9.4", "react-hook-form": "^7.13.0", "react-use": "^17.2.4" @@ -65,27 +66,8 @@ "swr": "^2.0.0" }, "files": [ - "dist" + "dist", + "config.d.ts" ], - "configSchema": { - "$schema": "https://backstage.io/schema/config-v1", - "type": "object", - "properties": { - "playlist": { - "type": "object", - "properties": { - "groupPluralNoun": { - "type": "string", - "description": "Frontend plural entities grouping name", - "visibility": "frontend" - }, - "groupSingularNoun": { - "type": "string", - "description": "Frontend singular entities grouping name", - "visibility": "frontend" - } - } - } - } - } + "configSchema": "config.d.ts" } diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx index cc7427c96c..3859b2aa1e 100644 --- a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx @@ -29,7 +29,7 @@ import { useNavigate } from 'react-router-dom'; import { playlistApiRef } from '../../api'; import { playlistRouteRef } from '../../routes'; import { PlaylistEditDialog } from '../PlaylistEditDialog'; -import { useGroupNoun } from '../../hooks/useConfig'; +import { useTitle } from '../../hooks'; export const CreatePlaylistButton = () => { const navigate = useNavigate(); @@ -56,7 +56,7 @@ export const CreatePlaylistButton = () => { [errorApi, navigate, playlistApi, playlistRoute], ); - const groupSingularNounLowerCase = useGroupNoun(false, false); + const singularTitle = useTitle(false, false); return ( <> @@ -64,7 +64,7 @@ export const CreatePlaylistButton = () => { setOpenDialog(true)} > @@ -77,7 +77,7 @@ export const CreatePlaylistButton = () => { color="primary" onClick={() => setOpenDialog(true)} > - Create {groupSingularNounLowerCase} + Create {singularTitle} )} { [playlistApi], ); - const groupSingularNoun = useGroupNoun(true, false); - const groupSingularNounLowerCase = useGroupNoun(false, true); - const groupPluralNounLowerCase = useGroupNoun(true, true); + const singularTitle = useTitle(true, false); + const singularTitleLowerCase = useTitle(false, true); + const plurlaTitleLowerCase = useTitle(true, true); useEffect(() => { if (open) { @@ -125,7 +125,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { navigate(playlistRoute({ playlistId })); } catch (e) { alertApi.post({ - message: `Failed to add entity to ${groupSingularNounLowerCase}: ${e}`, + message: `Failed to add entity to ${singularTitleLowerCase}: ${e}`, severity: 'error', }); } @@ -136,7 +136,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { navigate, playlistApi, playlistRoute, - groupSingularNounLowerCase, + singularTitleLowerCase, ], ); @@ -153,12 +153,12 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { }); } catch (e) { alertApi.post({ - message: `Failed to add entity to ${groupSingularNounLowerCase}: ${e}`, + message: `Failed to add entity to ${singularTitleLowerCase}: ${e}`, severity: 'error', }); } }, - [alertApi, closeDialog, entity, playlistApi, groupSingularNounLowerCase], + [alertApi, closeDialog, entity, playlistApi, singularTitleLowerCase], ); return ( @@ -172,7 +172,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { > {(loading || addEntityLoading) && } - Add to {groupSingularNoun} + Add to {singularTitle} { {error && ( )} @@ -221,7 +221,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { )} diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx index d8f48cbecf..1989f25ae7 100644 --- a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx @@ -39,7 +39,7 @@ import React from 'react'; import { useForm, Controller } from 'react-hook-form'; import useAsync from 'react-use/lib/useAsync'; import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { useGroupNoun } from '../../hooks/useConfig'; +import { useTitle } from '../../hooks'; const useStyles = makeStyles({ buttonWrapper: { @@ -106,7 +106,7 @@ export const PlaylistEditDialog = ({ } }; - const groupSingularNounLowercase = useGroupNoun(false, false); + const titleSingularLowerCase = useTitle(false, false); return ( @@ -124,7 +124,7 @@ export const PlaylistEditDialog = ({ fullWidth label="Name" margin="dense" - placeholder={`Give your ${groupSingularNounLowercase} name`} + placeholder={`Give your ${titleSingularLowerCase} name`} required type="text" /> @@ -142,7 +142,7 @@ export const PlaylistEditDialog = ({ label="Description" margin="dense" multiline - placeholder={`Describe your ${groupSingularNounLowercase}`} + placeholder={`Describe your ${titleSingularLowerCase}`} type="text" /> )} diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx index 6a92718df2..eabce5d0c6 100644 --- a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx +++ b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx @@ -23,7 +23,7 @@ import { } from '@backstage/core-components'; import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; -import { PlaylistListProvider, useGroupNoun } from '../../hooks'; +import { PlaylistListProvider, useTitle } from '../../hooks'; import { CreatePlaylistButton } from '../CreatePlaylistButton'; import { PersonalListPicker } from '../PersonalListPicker'; import { PlaylistList } from '../PlaylistList'; @@ -32,10 +32,10 @@ import { PlaylistSearchBar } from '../PlaylistSearchBar'; import { PlaylistSortPicker } from '../PlaylistSortPicker'; export const PlaylistIndexPage = () => { - const groupPluralNoun = useGroupNoun(true, false); + const pluralTitle = useTitle(true, false); return ( - + diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx index fd8569e758..6c90914c49 100644 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx @@ -23,12 +23,12 @@ import { } from '@backstage/core-components'; import { Typography } from '@material-ui/core'; -import { useGroupNoun, usePlaylistList } from '../../hooks'; +import { useTitle, usePlaylistList } from '../../hooks'; import { PlaylistCard } from '../PlaylistCard'; export const PlaylistList = () => { const { loading, error, playlists } = usePlaylistList(); - const groupPluralNounLowercase = useGroupNoun(true, true); + const pluralTitleLowerCase = useTitle(true, true); return ( <> @@ -36,7 +36,7 @@ export const PlaylistList = () => { {error && ( {error.message} diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx index 3f9e10c4c8..69a6beadb2 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx @@ -32,7 +32,7 @@ import React, { forwardRef, useCallback, useEffect, useState } from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; import { playlistApiRef } from '../../api'; -import { useGroupNoun } from '../../hooks/useConfig'; +import { useTitle } from '../../hooks'; import { AddEntitiesDrawer } from './AddEntitiesDrawer'; export const PlaylistEntitiesTable = ({ @@ -85,18 +85,18 @@ export const PlaylistEntitiesTable = ({ [errorApi, loadEntities, playlistApi, playlistId], ); - const groupSingularNounLowerCase = useGroupNoun(false, true); + const singularTitleLowerCase = useTitle(false, true); const actions = editAllowed ? [ { icon: DeleteIcon, - tooltip: `Remove from ${groupSingularNounLowerCase}`, + tooltip: `Remove from ${singularTitleLowerCase}`, onClick: removeEntity, }, { icon: AddBoxIcon, - tooltip: `Add entities to ${groupSingularNounLowerCase}`, + tooltip: `Add entities to ${singularTitleLowerCase}`, isFreeAction: true, onClick: () => setOpenAddEntitiesDrawer(true), }, diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx index ecf443b565..8ead799db2 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx @@ -45,7 +45,7 @@ import useAsyncFn from 'react-use/lib/useAsyncFn'; import { playlistApiRef } from '../../api'; import { rootRouteRef } from '../../routes'; import { PlaylistEditDialog } from '../PlaylistEditDialog'; -import { useGroupNoun } from '../../hooks/useConfig'; +import { useTitle } from '../../hooks'; const useStyles = makeStyles({ buttonWrapper: { @@ -110,7 +110,7 @@ export const PlaylistHeader = ({ playlist, onUpdate }: PlaylistHeaderProps) => { } }, [playlistApi]); - const groupSingularNoun = useGroupNoun(false, false); + const singularTitle = useTitle(false, false); return (
{ onClick: () => setOpenEditDialog(true), }, { - label: `Delete ${groupSingularNoun}`, + label: `Delete ${singularTitle}`, icon: , disabled: !deleteAllowed, onClick: () => setOpenDeleteDialog(true), diff --git a/plugins/playlist/src/hooks/index.ts b/plugins/playlist/src/hooks/index.ts index da045fbf65..bb164d961c 100644 --- a/plugins/playlist/src/hooks/index.ts +++ b/plugins/playlist/src/hooks/index.ts @@ -15,4 +15,4 @@ */ export * from './usePlaylistList'; -export * from './useConfig'; +export * from './useTitle'; diff --git a/plugins/playlist/src/hooks/useConfig.ts b/plugins/playlist/src/hooks/useTitle.ts similarity index 65% rename from plugins/playlist/src/hooks/useConfig.ts rename to plugins/playlist/src/hooks/useTitle.ts index 15d44570a8..ade68d03e8 100644 --- a/plugins/playlist/src/hooks/useConfig.ts +++ b/plugins/playlist/src/hooks/useTitle.ts @@ -15,13 +15,15 @@ */ import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import pluralize from 'pluralize'; -export function useGroupNoun(inPlural: boolean, inLowerCase: boolean) { +export function useTitle(inPlural: boolean, inLowerCase: boolean) { const configApi = useApi(configApiRef); - const defaultNoun = inPlural ? 'Playlists' : 'Playlist'; - const configProp = inPlural ? 'groupPluralNoun' : 'groupSingularNoun'; - const groupNoun = - configApi.getOptionalString(`playlist.${configProp}`) ?? `${defaultNoun}`; + let title = configApi.getOptionalString('playlist.title') ?? 'Playlist'; - return inLowerCase ? groupNoun.toLocaleLowerCase('en-US') : groupNoun; + if (inPlural) { + title = pluralize(title); + } + + return inLowerCase ? title.toLocaleLowerCase('en-US') : title; } diff --git a/yarn.lock b/yarn.lock index 3cf7b49696..2687870b8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7380,6 +7380,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^1.0.0 + pluralize: ^8.0.0 qs: ^6.9.4 react-hook-form: ^7.13.0 react-use: ^17.2.4 From 39973bcd50476f0ce31904de34c3155ca25cd863 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Mon, 20 Mar 2023 18:22:30 +0100 Subject: [PATCH 09/12] [Playlist]feat: removed unneccessary playlist config Signed-off-by: antonio.bergas --- app-config.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index ba9df18085..385c9c2e0e 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -126,9 +126,6 @@ proxy: organization: name: My Company -playlist: - title: Module - # Reference documentation http://backstage.io/docs/features/techdocs/configuration # Note: After experimenting with basic setup, use CI/CD to generate docs # and an external cloud storage when deploying TechDocs for production use-case. From d48fdc7396d2f8c1e61d32d7060dbb76dccbcbc8 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Mon, 20 Mar 2023 19:35:36 +0100 Subject: [PATCH 10/12] [Playlist]feat: fixed wrong copyright Signed-off-by: antonio.bergas --- plugins/playlist/config.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/playlist/config.d.ts b/plugins/playlist/config.d.ts index e6245e22a6..5b9ff8aad8 100644 --- a/plugins/playlist/config.d.ts +++ b/plugins/playlist/config.d.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2023 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. From 904b7ffd5e044d2f5a9aabb70576c028bc594f9e Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Mon, 20 Mar 2023 20:19:22 +0100 Subject: [PATCH 11/12] Update plugins/playlist/config.d.ts Improve description in config interface Co-authored-by: Phil Kuang Signed-off-by: Antonio Bergas --- plugins/playlist/config.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/playlist/config.d.ts b/plugins/playlist/config.d.ts index 5b9ff8aad8..d949cfe73a 100644 --- a/plugins/playlist/config.d.ts +++ b/plugins/playlist/config.d.ts @@ -17,7 +17,7 @@ export interface Config { playlist?: { /** - * (Optional) The title that will shown in the UI; leave empty for `PLaylist`. + * (Optional) The title that will shown in the UI; Defaults to`Playlist` if undefined. * @visibility frontend */ title?: string | undefined; From d08f00fd777d4227c83f97db64d6e10ba96c0a7b Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Mon, 20 Mar 2023 20:45:11 +0100 Subject: [PATCH 12/12] [Playlist]feat: improve useTitle hook and fixing tests Signed-off-by: antonio.bergas --- .../CreatePlaylistButton.tsx | 5 +- .../EntityPlaylistDialog.tsx | 17 ++++- .../PlaylistEditDialog/PlaylistEditDialog.tsx | 7 +- .../PlaylistIndexPage/PlaylistIndexPage.tsx | 5 +- .../PlaylistList/PlaylistList.test.tsx | 76 +++++++++++-------- .../components/PlaylistList/PlaylistList.tsx | 5 +- .../PlaylistPage/PlaylistEntitiesTable.tsx | 5 +- .../PlaylistPage/PlaylistHeader.tsx | 5 +- plugins/playlist/src/hooks/useTitle.ts | 13 +++- 9 files changed, 91 insertions(+), 47 deletions(-) diff --git a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx index 3859b2aa1e..7669a48c26 100644 --- a/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx +++ b/plugins/playlist/src/components/CreatePlaylistButton/CreatePlaylistButton.tsx @@ -56,7 +56,10 @@ export const CreatePlaylistButton = () => { [errorApi, navigate, playlistApi, playlistRoute], ); - const singularTitle = useTitle(false, false); + const singularTitle = useTitle({ + pluralize: false, + lowerCase: false, + }); return ( <> diff --git a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx index 711858577a..150ca6bc56 100644 --- a/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx +++ b/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx @@ -105,9 +105,18 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { [playlistApi], ); - const singularTitle = useTitle(true, false); - const singularTitleLowerCase = useTitle(false, true); - const plurlaTitleLowerCase = useTitle(true, true); + const singularTitle = useTitle({ + pluralize: true, + lowerCase: false, + }); + const singularTitleLowerCase = useTitle({ + pluralize: false, + lowerCase: true, + }); + const pluralTitleLowerCase = useTitle({ + pluralize: true, + lowerCase: true, + }); useEffect(() => { if (open) { @@ -204,7 +213,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => { {error && ( )} diff --git a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx index 1989f25ae7..a213c7c51c 100644 --- a/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx +++ b/plugins/playlist/src/components/PlaylistEditDialog/PlaylistEditDialog.tsx @@ -106,7 +106,10 @@ export const PlaylistEditDialog = ({ } }; - const titleSingularLowerCase = useTitle(false, false); + const titleSingularLowerCase = useTitle({ + pluralize: false, + lowerCase: false, + }); return ( @@ -124,7 +127,7 @@ export const PlaylistEditDialog = ({ fullWidth label="Name" margin="dense" - placeholder={`Give your ${titleSingularLowerCase} name`} + placeholder={`Give your ${titleSingularLowerCase} a name`} required type="text" /> diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx index eabce5d0c6..f25df19ee7 100644 --- a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx +++ b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx @@ -32,7 +32,10 @@ import { PlaylistSearchBar } from '../PlaylistSearchBar'; import { PlaylistSortPicker } from '../PlaylistSortPicker'; export const PlaylistIndexPage = () => { - const pluralTitle = useTitle(true, false); + const pluralTitle = useTitle({ + pluralize: true, + lowerCase: false, + }); return ( diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx index 27030ec1c7..976db99983 100644 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx @@ -14,13 +14,19 @@ * limitations under the License. */ +import { ConfigApi, configApiRef } from '@backstage/core-plugin-api'; import { Playlist } from '@backstage/plugin-playlist-common'; +import { TestApiProvider } from '@backstage/test-utils'; import { render } from '@testing-library/react'; import React from 'react'; import { MockPlaylistListProvider } from '../../testUtils'; import { PlaylistList } from './PlaylistList'; +const mockConfigApi = { + getOptionalString: () => undefined, +} as Partial; + jest.mock('../PlaylistCard', () => ({ PlaylistCard: ({ playlist }: { playlist: Playlist }) => (
{playlist.name}
@@ -30,9 +36,11 @@ jest.mock('../PlaylistCard', () => ({ describe('', () => { it('renders error on error', () => { const rendered = render( - - - , + + + + + , ); expect(rendered.getByText('Test Error')).toBeInTheDocument(); @@ -40,9 +48,11 @@ describe('', () => { it('handles no playlists', () => { const rendered = render( - - - , + + + + + , ); expect( @@ -52,32 +62,34 @@ describe('', () => { it('renders playlists', () => { const rendered = render( - - - , + + + + + , ); expect(rendered.getByText('playlist-1')).toBeInTheDocument(); diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx index 6c90914c49..2f815f07c6 100644 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx +++ b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx @@ -28,7 +28,10 @@ import { PlaylistCard } from '../PlaylistCard'; export const PlaylistList = () => { const { loading, error, playlists } = usePlaylistList(); - const pluralTitleLowerCase = useTitle(true, true); + const pluralTitleLowerCase = useTitle({ + pluralize: true, + lowerCase: true, + }); return ( <> diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx index 69a6beadb2..3d8efe3bc5 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.tsx @@ -85,7 +85,10 @@ export const PlaylistEntitiesTable = ({ [errorApi, loadEntities, playlistApi, playlistId], ); - const singularTitleLowerCase = useTitle(false, true); + const singularTitleLowerCase = useTitle({ + pluralize: false, + lowerCase: true, + }); const actions = editAllowed ? [ diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx index 8ead799db2..621f94f75c 100644 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx +++ b/plugins/playlist/src/components/PlaylistPage/PlaylistHeader.tsx @@ -110,7 +110,10 @@ export const PlaylistHeader = ({ playlist, onUpdate }: PlaylistHeaderProps) => { } }, [playlistApi]); - const singularTitle = useTitle(false, false); + const singularTitle = useTitle({ + pluralize: false, + lowerCase: false, + }); return (