requires individual components to pluralize

This commit is contained in:
Alex Corey 2019-09-17 14:27:07 -04:00
parent fcfd59ebe2
commit b79c686336
13 changed files with 25 additions and 61 deletions

View File

@ -269,7 +269,6 @@ class Lookup extends React.Component {
items={results}
itemCount={count}
itemName={lookupHeader}
itemNamePlural={lookupHeader}
qsConfig={this.qsConfig}
toolbarColumns={columns}
renderItem={item => (

View File

@ -17,7 +17,7 @@ import {
parseQueryString,
addParams,
} from '@util/qs';
import { pluralize, ucFirst } from '@util/strings';
import { ucFirst } from '@util/strings';
import { QSConfig } from '@types';
@ -64,7 +64,6 @@ class PaginatedDataList extends React.Component {
renderItem,
toolbarColumns,
itemName,
itemNamePlural,
showPageSizeOptions,
location,
i18n,
@ -82,10 +81,8 @@ class PaginatedDataList extends React.Component {
];
const queryParams = parseQueryString(qsConfig, location.search);
const itemDisplayName = ucFirst(pluralize(itemName));
const itemDisplayNamePlural = ucFirst(
itemNamePlural || pluralize(itemName)
);
const itemDisplayName = ucFirst(itemName);
const itemDisplayNamePlural = ucFirst(itemName);
const dataListLabel = i18n._(t`${itemDisplayName} List`);
const emptyContentMessage = i18n._(
@ -164,7 +161,6 @@ PaginatedDataList.propTypes = {
items: PropTypes.arrayOf(Item).isRequired,
itemCount: PropTypes.number.isRequired,
itemName: PropTypes.string,
itemNamePlural: PropTypes.string,
qsConfig: QSConfig.isRequired,
renderItem: PropTypes.func,
toolbarColumns: arrayOf(
@ -185,7 +181,6 @@ PaginatedDataList.defaultProps = {
contentError: null,
toolbarColumns: [],
itemName: 'item',
itemNamePlural: '',
showPageSizeOptions: true,
renderItem: item => <PaginatedDataListItem key={item.id} item={item} />,
renderToolbar: props => <DataListToolbar {...props} />,

View File

@ -85,9 +85,7 @@ class ToolbarDeleteButton extends React.Component {
return (
<div>
{i18n._(
t`You do not have permission to delete the following ${pluralize(
itemName
)}: ${itemsUnableToDelete}`
t`You do not have permission to delete the following ${itemName}: ${itemsUnableToDelete}`
)}
</div>
);
@ -125,11 +123,7 @@ class ToolbarDeleteButton extends React.Component {
{isModalOpen && (
<AlertModal
variant="danger"
title={
itemsToDelete === 1
? i18n._(t`Delete ${itemName}`)
: i18n._(t`Delete ${pluralize(itemName)}`)
}
title={itemName}
isOpen={isModalOpen}
onClose={this.handleCancelDelete}
actions={[

View File

@ -151,7 +151,7 @@ class JobList extends Component {
} = this.state;
const { match, i18n } = this.props;
const isAllSelected = selected.length === jobs.length;
const itemName = i18n._(t`Job`);
// const itemName = i18n._(t`Job`);
return (
<PageSection>
<Card>
@ -160,7 +160,7 @@ class JobList extends Component {
hasContentLoading={hasContentLoading}
items={jobs}
itemCount={itemCount}
itemName={itemName}
itemName={itemCount === 1 ? i18n._(t`Job`): i18n._(t`Jobs`)}
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@ -189,7 +189,7 @@ class JobList extends Component {
key="delete"
onDelete={this.handleJobDelete}
itemsToDelete={selected}
itemName={itemName}
itemName={selected.length === 1 ? i18n._(t`Job`): i18n._(t`Jobs`)}
/>,
]}
/>

View File

@ -165,7 +165,7 @@ class OrganizationAccess extends React.Component {
hasContentLoading={hasContentLoading}
items={accessRecords}
itemCount={itemCount}
itemName="role"
itemName={itemCount.length === 1 ? i18n._(t`Role`): i18n._(t`Roles`)}
qsConfig={QS_CONFIG}
toolbarColumns={[
{

View File

@ -37,7 +37,7 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
error={null}
hasContentLoading={true}
itemCount={0}
itemName="role"
itemName="Roles"
items={Array []}
qsConfig={
Object {
@ -91,7 +91,7 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
hasContentLoading={true}
i18n={"/i18n/"}
itemCount={0}
itemName="role"
itemName="Roles"
items={Array []}
qsConfig={
Object {
@ -144,8 +144,7 @@ exports[`<OrganizationAccess /> initially renders succesfully 1`] = `
history={"/history/"}
i18n={"/i18n/"}
itemCount={0}
itemName="role"
itemNamePlural=""
itemName="Roles"
items={Array []}
location={
Object {

View File

@ -153,7 +153,7 @@ class OrganizationsList extends Component {
hasContentLoading={hasContentLoading}
items={organizations}
itemCount={itemCount}
itemName="organization"
itemName={itemCount === 1 ? i18n._(t`Organization`): i18n._(t`Organizations`)}
qsConfig={QS_CONFIG}
toolbarColumns={[
{

View File

@ -204,7 +204,7 @@ class OrganizationNotifications extends Component {
hasContentLoading={hasContentLoading}
items={notifications}
itemCount={itemCount}
itemName="notification"
itemName={itemCount.length === 1 ? i18n._(t`Notification`): i18n._(t`Notifications`)}
qsConfig={QS_CONFIG}
toolbarColumns={COLUMNS}
renderItem={notification => (

View File

@ -42,7 +42,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
contentError={null}
hasContentLoading={false}
itemCount={2}
itemName="notification"
itemName="Notifications"
items={
Array [
Object {
@ -116,7 +116,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
hasContentLoading={false}
i18n={"/i18n/"}
itemCount={2}
itemName="notification"
itemName="Notifications"
items={
Array [
Object {
@ -188,8 +188,7 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
history={"/history/"}
i18n={"/i18n/"}
itemCount={2}
itemName="notification"
itemNamePlural=""
itemName="Notifications"
items={
Array [
Object {

View File

@ -1,6 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { OrganizationsAPI } from '@api';
import PaginatedDataList from '@components/PaginatedDataList';
@ -59,13 +61,14 @@ class OrganizationTeams extends React.Component {
render() {
const { contentError, hasContentLoading, teams, itemCount } = this.state;
const { i18n } = this.props;
return (
<PaginatedDataList
contentError={contentError}
hasContentLoading={hasContentLoading}
items={teams}
itemCount={itemCount}
itemName="team"
itemName={itemCount.length === 1 ? i18n._(t`Notification`): i18n._(t`Notifications`)}
qsConfig={QS_CONFIG}
/>
);
@ -77,4 +80,4 @@ OrganizationTeams.propTypes = {
};
export { OrganizationTeams as _OrganizationTeams };
export default withRouter(OrganizationTeams);
export default withI18n()(withRouter(OrganizationTeams));

View File

@ -178,7 +178,7 @@ class TemplatesList extends Component {
hasContentLoading={hasContentLoading}
items={templates}
itemCount={itemCount}
itemName={i18n._(t`Template`)}
itemName={itemCount === 1 ? i18n._(t`Template`): i18n._(t`Templates`)}
qsConfig={QS_CONFIG}
toolbarColumns={[
{
@ -213,7 +213,7 @@ class TemplatesList extends Component {
key="delete"
onDelete={this.handleTemplateDelete}
itemsToDelete={selected}
itemName={i18n._(t`Template`)}
itemName={selected.length === 1 ? i18n._(t`Template`): i18n._(t`Templates`)}
/>,
canAdd && (
<Dropdown

View File

@ -1,14 +1,3 @@
// TODO: switch to using Lingui i18n for pluralization
export function pluralize(str) {
const lastChar = str[str.length - 1];
if (lastChar === 's') {
return `${str}es`;
}
if (lastChar === 'y') {
return `${str.substr(0, str.length - 1)}ies`;
}
return `${str}s`;
}
// TODO: switch to using Lingui i18n for articles
export function getArticle(str) {

View File

@ -1,20 +1,6 @@
import { pluralize, getArticle, ucFirst, toTitleCase } from './strings';
import { getArticle, ucFirst, toTitleCase } from './strings';
describe('string utils', () => {
describe('pluralize', () => {
test('should add an "s"', () => {
expect(pluralize('team')).toEqual('teams');
});
test('should add an "es"', () => {
expect(pluralize('class')).toEqual('classes');
});
test('should handle word ending in y', () => {
expect(pluralize('inventory')).toEqual('inventories');
});
});
describe('getArticle', () => {
test('should return "a"', () => {
expect(getArticle('team')).toEqual('a');