[Playlist]feat: rename new config prop to title and use pluralize to manage nouns
Signed-off-by: antonio.bergas <anthonyprincedom@hotmail.com>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
+3
-9
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 = () => {
|
||||
<IconButton
|
||||
disabled={!allowed}
|
||||
color="primary"
|
||||
title={`Create ${groupSingularNounLowerCase}`}
|
||||
title={`Create ${singularTitle}`}
|
||||
size="small"
|
||||
onClick={() => setOpenDialog(true)}
|
||||
>
|
||||
@@ -77,7 +77,7 @@ export const CreatePlaylistButton = () => {
|
||||
color="primary"
|
||||
onClick={() => setOpenDialog(true)}
|
||||
>
|
||||
Create {groupSingularNounLowerCase}
|
||||
Create {singularTitle}
|
||||
</Button>
|
||||
)}
|
||||
<PlaylistEditDialog
|
||||
|
||||
@@ -51,7 +51,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
|
||||
import { playlistApiRef } from '../../api';
|
||||
import { useGroupNoun } from '../../hooks/useConfig';
|
||||
import { useTitle } from '../../hooks';
|
||||
import { playlistRouteRef } from '../../routes';
|
||||
import { PlaylistEditDialog } from '../PlaylistEditDialog';
|
||||
|
||||
@@ -105,9 +105,9 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => {
|
||||
[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) && <LinearProgress />}
|
||||
<DialogTitle className={classes.dialogTitle}>
|
||||
Add to {groupSingularNoun}
|
||||
Add to {singularTitle}
|
||||
<TextField
|
||||
fullWidth
|
||||
data-testid="entity-playlist-dialog-search"
|
||||
@@ -204,7 +204,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => {
|
||||
<DialogContent className={classes.dialogContent}>
|
||||
{error && (
|
||||
<ResponseErrorPanel
|
||||
title={`Error loading ${groupPluralNounLowerCase}`}
|
||||
title={`Error loading ${plurlaTitleLowerCase}`}
|
||||
error={error}
|
||||
/>
|
||||
)}
|
||||
@@ -221,7 +221,7 @@ export const EntityPlaylistDialog = (props: EntityPlaylistDialogProps) => {
|
||||
<PlaylistAddIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={`Create new ${groupSingularNounLowerCase}`}
|
||||
primary={`Create new ${singularTitleLowerCase}`}
|
||||
/>
|
||||
</ListItem>
|
||||
)}
|
||||
|
||||
@@ -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 (
|
||||
<Dialog fullWidth maxWidth="xs" onClose={closeDialog} open={open}>
|
||||
@@ -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"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -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 (
|
||||
<PageWithHeader themeId="home" title={groupPluralNoun}>
|
||||
<PageWithHeader themeId="home" title={pluralTitle}>
|
||||
<PlaylistListProvider>
|
||||
<Content>
|
||||
<ContentHeader title="">
|
||||
|
||||
@@ -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 && (
|
||||
<WarningPanel
|
||||
title={`Oops! Something went wrong loading ${groupPluralNounLowercase}`}
|
||||
title={`Oops! Something went wrong loading ${pluralTitleLowerCase}`}
|
||||
>
|
||||
{error.message}
|
||||
</WarningPanel>
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
|
||||
@@ -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 (
|
||||
<Header
|
||||
@@ -146,7 +146,7 @@ export const PlaylistHeader = ({ playlist, onUpdate }: PlaylistHeaderProps) => {
|
||||
onClick: () => setOpenEditDialog(true),
|
||||
},
|
||||
{
|
||||
label: `Delete ${groupSingularNoun}`,
|
||||
label: `Delete ${singularTitle}`,
|
||||
icon: <DeleteIcon />,
|
||||
disabled: !deleteAllowed,
|
||||
onClick: () => setOpenDeleteDialog(true),
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
*/
|
||||
|
||||
export * from './usePlaylistList';
|
||||
export * from './useConfig';
|
||||
export * from './useTitle';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user