mirror of
https://github.com/ansible/awx.git
synced 2026-01-21 14:38:00 -03:30
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:
parent
8dd4379bf2
commit
b3b53a8ce4
@ -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 };
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,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');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user