Pluralized modal titles and empty state strings

All itemNames used in empty state messages, and delete modal titles
need to be plural and capitalized.  Because of this change we no
longer need the ucFirst() in utils/strings.js.
This commit is contained in:
Alex Corey
2019-09-19 13:41:13 -04:00
parent 8dd4379bf2
commit b3b53a8ce4
16 changed files with 33 additions and 52 deletions
@@ -212,7 +212,6 @@ class AddResourceRole extends React.Component {
selectedLabel={i18n._(t`Selected`)}
selectedResourceRows={selectedResourceRows}
sortedColumnKey="username"
itemName="user"
/>
)}
{selectedResource === 'teams' && (
@@ -222,7 +221,6 @@ class AddResourceRole extends React.Component {
onSearch={readTeams}
selectedLabel={i18n._(t`Selected`)}
selectedResourceRows={selectedResourceRows}
itemName="team"
/>
)}
</Fragment>
@@ -74,7 +74,6 @@ class SelectResourceStep extends React.Component {
onRowClick,
selectedLabel,
selectedResourceRows,
itemName,
i18n,
} = this.props;
@@ -100,7 +99,6 @@ class SelectResourceStep extends React.Component {
<PaginatedDataList
items={resources}
itemCount={count}
itemName={itemName}
qsConfig={this.qsConfig}
toolbarColumns={columns}
renderItem={item => (
@@ -132,7 +130,6 @@ SelectResourceStep.propTypes = {
selectedLabel: PropTypes.string,
selectedResourceRows: PropTypes.arrayOf(PropTypes.object),
sortedColumnKey: PropTypes.string,
itemName: PropTypes.string,
};
SelectResourceStep.defaultProps = {
@@ -141,7 +138,6 @@ SelectResourceStep.defaultProps = {
selectedLabel: null,
selectedResourceRows: [],
sortedColumnKey: 'name',
itemName: 'item',
};
export { SelectResourceStep as _SelectResourceStep };
+2 -2
View File
@@ -212,7 +212,7 @@ class Lookup extends React.Component {
i18n,
} = this.props;
const header = lookupHeader || i18n._(t`items`);
const header = lookupHeader || i18n._(t`Items`);
const canDelete = !required || (multiple && value.length > 1);
const chips = value ? (
@@ -268,7 +268,7 @@ class Lookup extends React.Component {
<PaginatedDataList
items={results}
itemCount={count}
itemName={lookupHeader}
pluralizedItemName={lookupHeader}
qsConfig={this.qsConfig}
toolbarColumns={columns}
renderItem={item => (
@@ -17,7 +17,6 @@ import {
parseQueryString,
addParams,
} from '@util/qs';
import { ucFirst } from '@util/strings';
import { QSConfig } from '@types';
@@ -63,7 +62,7 @@ class PaginatedDataList extends React.Component {
qsConfig,
renderItem,
toolbarColumns,
itemName,
pluralizedItemName,
showPageSizeOptions,
location,
i18n,
@@ -81,11 +80,11 @@ class PaginatedDataList extends React.Component {
];
const queryParams = parseQueryString(qsConfig, location.search);
const dataListLabel = i18n._(t`${itemName} List`);
const dataListLabel = i18n._(t`${pluralizedItemName} List`);
const emptyContentMessage = i18n._(
t`Please add ${itemName} to populate this list `
t`Please add ${pluralizedItemName} to populate this list `
);
const emptyContentTitle = i18n._(t`No ${itemName} Found `);
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
let Content;
if (hasContentLoading && items.length <= 0) {
@@ -157,7 +156,7 @@ const Item = PropTypes.shape({
PaginatedDataList.propTypes = {
items: PropTypes.arrayOf(Item).isRequired,
itemCount: PropTypes.number.isRequired,
itemName: PropTypes.string,
pluralizedItemName: PropTypes.string,
qsConfig: QSConfig.isRequired,
renderItem: PropTypes.func,
toolbarColumns: arrayOf(
@@ -177,7 +176,7 @@ PaginatedDataList.defaultProps = {
hasContentLoading: false,
contentError: null,
toolbarColumns: [],
itemName: 'item',
pluralizedItemName: 'Items',
showPageSizeOptions: true,
renderItem: item => <PaginatedDataListItem key={item.id} item={item} />,
renderToolbar: props => <DataListToolbar {...props} />,
@@ -6,7 +6,6 @@ import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import AlertModal from '../AlertModal';
import { pluralize } from '../../util/strings';
const DeleteButton = styled(Button)`
padding: 5px 8px;
@@ -41,11 +40,11 @@ class ToolbarDeleteButton extends React.Component {
static propTypes = {
onDelete: func.isRequired,
itemsToDelete: arrayOf(ItemToDelete).isRequired,
itemName: string,
pluralizedItemName: string,
};
static defaultProps = {
itemName: 'item',
pluralizedItemName: 'Items',
};
constructor(props) {
@@ -75,7 +74,7 @@ class ToolbarDeleteButton extends React.Component {
}
renderTooltip() {
const { itemsToDelete, itemName, i18n } = this.props;
const { itemsToDelete, pluralizedItemName, i18n } = this.props;
const itemsUnableToDelete = itemsToDelete
.filter(cannotDelete)
@@ -85,7 +84,7 @@ class ToolbarDeleteButton extends React.Component {
return (
<div>
{i18n._(
t`You do not have permission to delete the following ${itemName}: ${itemsUnableToDelete}`
t`You do not have permission to delete the following ${pluralizedItemName}: ${itemsUnableToDelete}`
)}
</div>
);
@@ -97,7 +96,7 @@ class ToolbarDeleteButton extends React.Component {
}
render() {
const { itemsToDelete, itemName, i18n } = this.props;
const { itemsToDelete, pluralizedItemName, i18n } = this.props;
const { isModalOpen } = this.state;
const isDisabled =
@@ -123,7 +122,7 @@ class ToolbarDeleteButton extends React.Component {
{isModalOpen && (
<AlertModal
variant="danger"
title={itemName}
title={pluralizedItemName}
isOpen={isModalOpen}
onClose={this.handleCancelDelete}
actions={[
@@ -3,9 +3,9 @@
exports[`<ToolbarDeleteButton /> should render button 1`] = `
<ToolbarDeleteButton
i18n={"/i18n/"}
itemName="item"
itemsToDelete={Array []}
onDelete={[Function]}
pluralizedItemName="Items"
>
<Tooltip
appendTo={[Function]}
@@ -159,7 +159,7 @@ class JobList extends Component {
hasContentLoading={hasContentLoading}
items={jobs}
itemCount={itemCount}
itemName={itemCount === 1 ? 'Job' : 'Jobs'}
pluralizedItemName="Jobs"
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@@ -188,7 +188,7 @@ class JobList extends Component {
key="delete"
onDelete={this.handleJobDelete}
itemsToDelete={selected}
itemName={selected.length === 1 ? 'Job' : 'Jobs' }
pluralizedItemName="Jobs"
/>,
]}
/>
@@ -165,7 +165,7 @@ class OrganizationAccess extends React.Component {
hasContentLoading={hasContentLoading}
items={accessRecords}
itemCount={itemCount}
itemName={itemCount.length === 1 ? 'Role' : 'Roles'}
pluralizedItemName="Roles"
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@@ -37,8 +37,8 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
error={null}
hasContentLoading={true}
itemCount={0}
itemName="Roles"
items={Array []}
pluralizedItemName="Roles"
qsConfig={
Object {
"dateFields": Array [
@@ -91,8 +91,8 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
hasContentLoading={true}
i18n={"/i18n/"}
itemCount={0}
itemName="Roles"
items={Array []}
pluralizedItemName="Roles"
qsConfig={
Object {
"dateFields": Array [
@@ -144,7 +144,6 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
history={"/history/"}
i18n={"/i18n/"}
itemCount={0}
itemName="Roles"
items={Array []}
location={
Object {
@@ -162,6 +161,7 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
"url": "",
}
}
pluralizedItemName="Roles"
qsConfig={
Object {
"dateFields": Array [
@@ -153,7 +153,7 @@ class OrganizationsList extends Component {
hasContentLoading={hasContentLoading}
items={organizations}
itemCount={itemCount}
itemName={itemCount === 1 ? 'Organization' : 'Organizations'}
pluralizedItemName="Organizations"
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@@ -187,7 +187,7 @@ class OrganizationsList extends Component {
key="delete"
onDelete={this.handleOrgDelete}
itemsToDelete={selected}
itemName="Organization"
pluralizedItemName="Organizations"
/>,
canAdd ? (
<ToolbarAddButton key="add" linkTo={`${match.url}/add`} />
@@ -204,7 +204,7 @@ class OrganizationNotifications extends Component {
hasContentLoading={hasContentLoading}
items={notifications}
itemCount={itemCount}
itemName={itemCount.length === 1 ? 'Notification' : 'Notifications'}
pluralizedItemName="Notifications"
qsConfig={QS_CONFIG}
toolbarColumns={COLUMNS}
renderItem={notification => (
@@ -42,7 +42,6 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
contentError={null}
hasContentLoading={false}
itemCount={2}
itemName="Notifications"
items={
Array [
Object {
@@ -65,6 +64,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
},
]
}
pluralizedItemName="Notifications"
qsConfig={
Object {
"dateFields": Array [
@@ -116,7 +116,6 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
hasContentLoading={false}
i18n={"/i18n/"}
itemCount={2}
itemName="Notifications"
items={
Array [
Object {
@@ -139,6 +138,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
},
]
}
pluralizedItemName="Notifications"
qsConfig={
Object {
"dateFields": Array [
@@ -188,7 +188,6 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
history={"/history/"}
i18n={"/i18n/"}
itemCount={2}
itemName="Notifications"
items={
Array [
Object {
@@ -227,6 +226,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
"url": "",
}
}
pluralizedItemName="Notifications"
qsConfig={
Object {
"dateFields": Array [
@@ -1827,10 +1827,10 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
</Route>
</withRouter(ListHeader)>
<DataList
aria-label="{itemDisplayName} List"
aria-label="{pluralizedItemName} List"
>
<ul
aria-label="{itemDisplayName} List"
aria-label="{pluralizedItemName} List"
className="pf-c-data-list"
>
<WithI18n
@@ -65,7 +65,7 @@ class OrganizationTeams extends React.Component {
hasContentLoading={hasContentLoading}
items={teams}
itemCount={itemCount}
itemName={itemCount.length === 1 ? 'Notification' : 'Notifications'}
pluralizedItemName="Notifications"
qsConfig={QS_CONFIG}
/>
);
@@ -178,7 +178,7 @@ class TemplatesList extends Component {
hasContentLoading={hasContentLoading}
items={templates}
itemCount={itemCount}
itemName={itemCount === 1 ? 'Template' : 'Templates'}
pluralizedItemName="Templates"
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@@ -213,7 +213,7 @@ class TemplatesList extends Component {
key="delete"
onDelete={this.handleTemplateDelete}
itemsToDelete={selected}
itemName={selected.length === 1 ? 'Template' : 'Templates'}
pluralizedItemName="Templates"
/>,
canAdd && (
<Dropdown
-5
View File
@@ -1,4 +1,3 @@
// TODO: switch to using Lingui i18n for articles
export function getArticle(str) {
const first = str[0];
@@ -8,10 +7,6 @@ export function getArticle(str) {
return 'a';
}
export function ucFirst(str) {
return `${str[0].toUpperCase()}${str.substr(1)}`;
}
export const toTitleCase = string => {
if (!string) {
return '';
+1 -7
View File
@@ -1,4 +1,4 @@
import { getArticle, ucFirst, toTitleCase } from './strings';
import { getArticle, toTitleCase } from './strings';
describe('string utils', () => {
describe('getArticle', () => {
@@ -16,12 +16,6 @@ describe('string utils', () => {
});
});
describe('ucFirst', () => {
test('should capitalize first character', () => {
expect(ucFirst('team')).toEqual('Team');
});
});
describe('toTitleCase', () => {
test('should upper case each word', () => {
expect(toTitleCase('a_string_of_words')).toEqual('A String Of Words');