update awx-pf to use withI18n i18n._ and t exclusively

This commit is contained in:
John Mitchell
2019-05-15 11:20:00 -04:00
parent 4407aeac20
commit 07664a05fd
57 changed files with 1343 additions and 1355 deletions

View File

@@ -9,7 +9,7 @@ import {
Button Button
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { RootDialog } from './contexts/RootDialog'; import { RootDialog } from './contexts/RootDialog';
@@ -66,13 +66,11 @@ class App extends Component {
render () { render () {
const { isAboutModalOpen, isNavOpen } = this.state; const { isAboutModalOpen, isNavOpen } = this.state;
const { render, routeGroups = [], navLabel = '' } = this.props; const { render, routeGroups = [], navLabel = '', i18n } = this.props;
return ( return (
<Config> <Config>
{({ ansible_version, version, me }) => ( {({ ansible_version, version, me }) => (
<I18n>
{({ i18n }) => (
<RootDialog> <RootDialog>
{({ {({
title, title,
@@ -151,12 +149,10 @@ class App extends Component {
)} )}
</RootDialog> </RootDialog>
)} )}
</I18n>
)}
</Config> </Config>
); );
} }
} }
export { App as _App }; export { App as _App };
export default withNetwork(App); export default withI18n()(withNetwork(App));

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
AboutModal, AboutModal,
TextContent, TextContent,
@@ -41,14 +41,13 @@ class About extends React.Component {
ansible_version, ansible_version,
version, version,
isOpen, isOpen,
onClose onClose,
i18n
} = this.props; } = this.props;
const speechBubble = this.createSpeechBubble(version); const speechBubble = this.createSpeechBubble(version);
return ( return (
<I18n>
{({ i18n }) => (
<AboutModal <AboutModal
isOpen={isOpen} isOpen={isOpen}
onClose={onClose} onClose={onClose}
@@ -73,14 +72,12 @@ class About extends React.Component {
<TextContent> <TextContent>
<TextList component="dl"> <TextList component="dl">
<TextListItem component="dt"> <TextListItem component="dt">
<Trans>Ansible Version</Trans> {i18n._(t`Ansible Version`)}
</TextListItem> </TextListItem>
<TextListItem component="dd">{ ansible_version }</TextListItem> <TextListItem component="dd">{ ansible_version }</TextListItem>
</TextList> </TextList>
</TextContent> </TextContent>
</AboutModal> </AboutModal>
)}
</I18n>
); );
} }
} }
@@ -98,4 +95,4 @@ About.defaultProps = {
version: null, version: null,
}; };
export default About; export default withI18n()(About);

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n, i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Wizard } from '@patternfly/react-core'; import { Wizard } from '@patternfly/react-core';
import SelectResourceStep from './SelectResourceStep'; import SelectResourceStep from './SelectResourceStep';
@@ -127,37 +127,36 @@ class AddResourceRole extends React.Component {
} = this.state; } = this.state;
const { const {
onClose, onClose,
roles roles,
i18n
} = this.props; } = this.props;
const userColumns = [ const userColumns = [
{ name: i18nMark('Username'), key: 'username', isSortable: true } { name: i18n._(t`Username`), key: 'username', isSortable: true }
]; ];
const teamColumns = [ const teamColumns = [
{ name: i18nMark('Name'), key: 'name', isSortable: true } { name: i18n._(t`Name`), key: 'name', isSortable: true }
]; ];
let wizardTitle = ''; let wizardTitle = '';
switch (selectedResource) { switch (selectedResource) {
case 'users': case 'users':
wizardTitle = i18nMark('Add User Roles'); wizardTitle = i18n._(t`Add User Roles`);
break; break;
case 'teams': case 'teams':
wizardTitle = i18nMark('Add Team Roles'); wizardTitle = i18n._(t`Add Team Roles`);
break; break;
default: default:
wizardTitle = i18nMark('Add Roles'); wizardTitle = i18n._(t`Add Roles`);
} }
const steps = [ const steps = [
{ {
id: 1, id: 1,
name: i18nMark('Select Users Or Teams'), name: i18n._(t`Select Users Or Teams`),
component: ( component: (
<I18n>
{({ i18n }) => (
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<SelectableCard <SelectableCard
isSelected={selectedResource === 'users'} isSelected={selectedResource === 'users'}
@@ -170,17 +169,13 @@ class AddResourceRole extends React.Component {
onClick={() => this.handleResourceSelect('teams')} onClick={() => this.handleResourceSelect('teams')}
/> />
</div> </div>
)}
</I18n>
), ),
enableNext: selectedResource !== null enableNext: selectedResource !== null
}, },
{ {
id: 2, id: 2,
name: i18nMark('Select items from list'), name: i18n._(t`Select items from list`),
component: ( component: (
<I18n>
{({ i18n }) => (
<Fragment> <Fragment>
{selectedResource === 'users' && ( {selectedResource === 'users' && (
<SelectResourceStep <SelectResourceStep
@@ -205,17 +200,13 @@ class AddResourceRole extends React.Component {
/> />
)} )}
</Fragment> </Fragment>
)}
</I18n>
), ),
enableNext: selectedResourceRows.length > 0 enableNext: selectedResourceRows.length > 0
}, },
{ {
id: 3, id: 3,
name: i18nMark('Apply roles'), name: i18n._(t`Apply roles`),
component: ( component: (
<I18n>
{({ i18n }) => (
<SelectRoleStep <SelectRoleStep
onRolesClick={this.handleRoleCheckboxClick} onRolesClick={this.handleRoleCheckboxClick}
roles={roles} roles={roles}
@@ -224,16 +215,15 @@ class AddResourceRole extends React.Component {
selectedResourceRows={selectedResourceRows} selectedResourceRows={selectedResourceRows}
selectedRoleRows={selectedRoleRows} selectedRoleRows={selectedRoleRows}
/> />
)}
</I18n>
), ),
nextButtonText: i18nMark('Save'), nextButtonText: i18n._(t`Save`),
enableNext: selectedRoleRows.length > 0 enableNext: selectedRoleRows.length > 0
} }
]; ];
const currentStep = steps.find(step => step.id === currentStepId); const currentStep = steps.find(step => step.id === currentStepId);
// TODO: somehow internationalize steps and currentStep.nextButtonText
return ( return (
<Wizard <Wizard
style={{ overflow: 'scroll' }} style={{ overflow: 'scroll' }}
@@ -259,4 +249,4 @@ AddResourceRole.defaultProps = {
roles: {} roles: {}
}; };
export default AddResourceRole; export default withI18n()(AddResourceRole);

View File

@@ -1,7 +1,8 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import PaginatedDataList from '../PaginatedDataList'; import PaginatedDataList from '../PaginatedDataList';
import CheckboxListItem from '../ListItem'; import CheckboxListItem from '../ListItem';
import SelectedList from '../SelectedList'; import SelectedList from '../SelectedList';
@@ -87,11 +88,12 @@ class SelectResourceStep extends React.Component {
selectedLabel, selectedLabel,
selectedResourceRows, selectedResourceRows,
itemName, itemName,
i18n
} = this.props; } = this.props;
return ( return (
<Fragment> <Fragment>
{isLoading && (<div>Loading...</div>)} {isLoading && (<div>{i18n._(t`Loading...`)}</div>)}
{isInitialized && ( {isInitialized && (
<Fragment> <Fragment>
{selectedResourceRows.length > 0 && ( {selectedResourceRows.length > 0 && (
@@ -146,11 +148,11 @@ SelectResourceStep.propTypes = {
SelectResourceStep.defaultProps = { SelectResourceStep.defaultProps = {
displayKey: 'name', displayKey: 'name',
onRowClick: () => {}, onRowClick: () => {},
selectedLabel: i18nMark('Selected Items'), selectedLabel: null,
selectedResourceRows: [], selectedResourceRows: [],
sortedColumnKey: 'name', sortedColumnKey: 'name',
itemName: 'item', itemName: 'item',
}; };
export { SelectResourceStep as _SelectResourceStep }; export { SelectResourceStep as _SelectResourceStep };
export default withRouter(SelectResourceStep); export default withI18n()(withRouter(SelectResourceStep));

View File

@@ -1,7 +1,8 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import CheckboxCard from './CheckboxCard'; import CheckboxCard from './CheckboxCard';
import SelectedList from '../SelectedList'; import SelectedList from '../SelectedList';
@@ -14,7 +15,8 @@ class RolesStep extends React.Component {
selectedListKey, selectedListKey,
selectedListLabel, selectedListLabel,
selectedResourceRows, selectedResourceRows,
selectedRoleRows selectedRoleRows,
i18n
} = this.props; } = this.props;
return ( return (
@@ -24,7 +26,7 @@ class RolesStep extends React.Component {
<SelectedList <SelectedList
displayKey={selectedListKey} displayKey={selectedListKey}
isReadOnly isReadOnly
label={selectedListLabel} label={selectedListLabel || i18n._(t`Selected`)}
selected={selectedResourceRows} selected={selectedResourceRows}
showOverflowAfter={5} showOverflowAfter={5}
/> />
@@ -61,9 +63,9 @@ RolesStep.propTypes = {
RolesStep.defaultProps = { RolesStep.defaultProps = {
onRolesClick: () => {}, onRolesClick: () => {},
selectedListKey: 'name', selectedListKey: 'name',
selectedListLabel: i18nMark('Selected'), selectedListLabel: null,
selectedResourceRows: [], selectedResourceRows: [],
selectedRoleRows: [] selectedRoleRows: []
}; };
export default RolesStep; export default withI18n()(RolesStep);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
FormSelect, FormSelect,
@@ -20,10 +20,8 @@ class AnsibleSelect extends React.Component {
} }
render () { render () {
const { label, value, data, defaultSelected } = this.props; const { label, value, data, defaultSelected, i18n } = this.props;
return ( return (
<I18n>
{({ i18n }) => (
<FormSelect <FormSelect
value={value} value={value}
onChange={this.onSelectChange} onChange={this.onSelectChange}
@@ -41,8 +39,6 @@ class AnsibleSelect extends React.Component {
) )
))} ))}
</FormSelect> </FormSelect>
)}
</I18n>
); );
} }
} }
@@ -62,4 +58,4 @@ AnsibleSelect.propTypes = {
value: PropTypes.string.isRequired, value: PropTypes.string.isRequired,
}; };
export default AnsibleSelect; export default withI18n()(AnsibleSelect);

View File

@@ -3,14 +3,12 @@ import { string } from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Button } from '@patternfly/react-core'; import { Button } from '@patternfly/react-core';
import { TimesIcon } from '@patternfly/react-icons'; import { TimesIcon } from '@patternfly/react-icons';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
function CardCloseButton ({ linkTo, ...props }) { function CardCloseButton ({ linkTo, i18n, i18nHash, ...props }) {
if (linkTo) { if (linkTo) {
return ( return (
<I18n>
{({ i18n }) => (
<Link <Link
className="pf-c-button pf-c-card__close" className="pf-c-button pf-c-card__close"
aria-label={i18n._(t`Close`)} aria-label={i18n._(t`Close`)}
@@ -20,13 +18,9 @@ function CardCloseButton ({ linkTo, ...props }) {
> >
<TimesIcon /> <TimesIcon />
</Link> </Link>
)}
</I18n>
); );
} }
return ( return (
<I18n>
{({ i18n }) => (
<Button <Button
variant="plain" variant="plain"
className="pf-c-card__close" className="pf-c-card__close"
@@ -35,8 +29,6 @@ function CardCloseButton ({ linkTo, ...props }) {
> >
<TimesIcon /> <TimesIcon />
</Button> </Button>
)}
</I18n>
); );
} }
CardCloseButton.propTypes = { CardCloseButton.propTypes = {
@@ -46,4 +38,4 @@ CardCloseButton.defaultProps = {
linkTo: null, linkTo: null,
}; };
export default CardCloseButton; export default withI18n()(CardCloseButton);

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Checkbox, Checkbox,
@@ -85,12 +85,11 @@ class DataListToolbar extends React.Component {
sortOrder, sortOrder,
sortedColumnKey, sortedColumnKey,
additionalControls, additionalControls,
i18n
} = this.props; } = this.props;
const showExpandCollapse = (onCompact && onExpand); const showExpandCollapse = (onCompact && onExpand);
return ( return (
<I18n>
{({ i18n }) => (
<AWXToolbar> <AWXToolbar>
<Toolbar marginleft={noLeftMargin ? 1 : 0}> <Toolbar marginleft={noLeftMargin ? 1 : 0}>
<ColumnLeft> <ColumnLeft>
@@ -146,9 +145,6 @@ class DataListToolbar extends React.Component {
</ColumnRight> </ColumnRight>
</Toolbar> </Toolbar>
</AWXToolbar> </AWXToolbar>
)}
</I18n>
); );
} }
} }
@@ -184,4 +180,4 @@ DataListToolbar.defaultProps = {
additionalControls: [], additionalControls: [],
}; };
export default DataListToolbar; export default withI18n()(DataListToolbar);

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button, Button,
@@ -22,12 +22,11 @@ class ExpandCollapse extends React.Component {
const { const {
onCompact, onCompact,
onExpand, onExpand,
isCompact isCompact,
i18n
} = this.props; } = this.props;
return ( return (
<I18n>
{({ i18n }) => (
<Fragment> <Fragment>
<ToolbarItem> <ToolbarItem>
<Button <Button
@@ -50,8 +49,6 @@ class ExpandCollapse extends React.Component {
</Button> </Button>
</ToolbarItem> </ToolbarItem>
</Fragment> </Fragment>
)}
</I18n>
); );
} }
} }
@@ -64,4 +61,4 @@ ExpandCollapse.propTypes = {
ExpandCollapse.defaultProps = {}; ExpandCollapse.defaultProps = {};
export default ExpandCollapse; export default withI18n()(ExpandCollapse);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
ActionGroup, ActionGroup,
@@ -20,9 +20,7 @@ const buttonGroupStyle = {
marginRight: '20px' marginRight: '20px'
}; };
const FormActionGroup = ({ onSubmit, submitDisabled, onCancel }) => ( const FormActionGroup = ({ onSubmit, submitDisabled, onCancel, i18n }) => (
<I18n>
{({ i18n }) => (
<ActionGroup style={formActionGroupStyle}> <ActionGroup style={formActionGroupStyle}>
<Toolbar> <Toolbar>
<ToolbarGroup style={buttonGroupStyle}> <ToolbarGroup style={buttonGroupStyle}>
@@ -33,8 +31,6 @@ const FormActionGroup = ({ onSubmit, submitDisabled, onCancel }) => (
</ToolbarGroup> </ToolbarGroup>
</Toolbar> </Toolbar>
</ActionGroup> </ActionGroup>
)}
</I18n>
); );
FormActionGroup.propTypes = { FormActionGroup.propTypes = {
@@ -47,4 +43,4 @@ FormActionGroup.defaultProps = {
submitDisabled: false, submitDisabled: false,
}; };
export default FormActionGroup; export default withI18n()(FormActionGroup);

View File

@@ -9,7 +9,7 @@ import {
InputGroup, InputGroup,
Modal, Modal,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withNetwork } from '../../contexts/Network'; import { withNetwork } from '../../contexts/Network';
@@ -130,7 +130,9 @@ class Lookup extends React.Component {
results, results,
count, count,
} = this.state; } = this.state;
const { id, lookupHeader = 'items', value, columns } = this.props; const { id, lookupHeader, value, columns, i18n } = this.props;
const header = lookupHeader || i18n._(t`items`);
const chips = value ? ( const chips = value ? (
<div className="pf-c-chip-group"> <div className="pf-c-chip-group">
@@ -143,8 +145,6 @@ class Lookup extends React.Component {
) : null; ) : null;
return ( return (
<I18n>
{({ i18n }) => (
<Fragment> <Fragment>
<InputGroup className="awx-lookup"> <InputGroup className="awx-lookup">
<Button <Button
@@ -161,7 +161,7 @@ class Lookup extends React.Component {
</InputGroup> </InputGroup>
<Modal <Modal
className="awx-c-modal" className="awx-c-modal"
title={`Select ${lookupHeader}`} title={i18n._(t`Select ${header}`)}
isOpen={isModalOpen} isOpen={isModalOpen}
onClose={this.handleModalToggle} onClose={this.handleModalToggle}
actions={[ actions={[
@@ -199,8 +199,6 @@ class Lookup extends React.Component {
{ error ? <div>error</div> : '' } { error ? <div>error</div> : '' }
</Modal> </Modal>
</Fragment> </Fragment>
)}
</I18n>
); );
} }
} }
@@ -217,9 +215,9 @@ Lookup.propTypes = {
Lookup.defaultProps = { Lookup.defaultProps = {
id: 'lookup-search', id: 'lookup-search',
lookupHeader: 'items', lookupHeader: null,
name: null, name: null,
}; };
export { Lookup as _Lookup }; export { Lookup as _Lookup };
export default withNetwork(withRouter(Lookup)); export default withI18n()(withNetwork(withRouter(Lookup)));

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { shape, number, string, bool, func } from 'prop-types'; import { shape, number, string, bool, func } from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { import {
@@ -37,12 +37,11 @@ function NotificationListItem (props) {
detailUrl, detailUrl,
successTurnedOn, successTurnedOn,
errorTurnedOn, errorTurnedOn,
toggleNotification toggleNotification,
i18n
} = props; } = props;
return ( return (
<I18n>
{({ i18n }) => (
<DataListItem <DataListItem
aria-labelledby={`items-list-item-${notification.id}`} aria-labelledby={`items-list-item-${notification.id}`}
key={notification.id} key={notification.id}
@@ -93,10 +92,20 @@ function NotificationListItem (props) {
</DataListCell> </DataListCell>
]} ]}
/> />
<Switch
id={`notification-${notification.id}-error-toggle`}
label={i18n._(t`Failure`)}
isChecked={errorTurnedOn}
isDisabled={!canToggleNotifications}
onChange={() => toggleNotification(
notification.id,
errorTurnedOn,
'error'
)}
aria-label={i18n._(t`Toggle notification failure`)}
/>
</DataListItemRow> </DataListItemRow>
</DataListItem> </DataListItem>
)}
</I18n>
); );
} }
@@ -118,4 +127,4 @@ NotificationListItem.defaultProps = {
successTurnedOn: false, successTurnedOn: false,
}; };
export default NotificationListItem; export default withI18n()(NotificationListItem);

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React, { Fragment } from 'react';
import { Redirect, withRouter } from 'react-router-dom'; import { Redirect, withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withRootDialog } from '../contexts/RootDialog'; import { withRootDialog } from '../contexts/RootDialog';
@@ -14,16 +14,13 @@ const NotifyAndRedirect = ({
strict, strict,
sensitive, sensitive,
setRootDialogMessage, setRootDialogMessage,
location location,
i18n
}) => { }) => {
setRootDialogMessage({ setRootDialogMessage({
title: '404', title: '404',
bodyText: ( bodyText: (
<Trans> <Fragment>{i18n._(t`Cannot find route ${(<strong>{location.pathname}</strong>)}.`)}</Fragment>
Cannot find route
<strong>{` ${location.pathname}`}</strong>
.
</Trans>
), ),
variant: 'warning' variant: 'warning'
}); });
@@ -41,4 +38,4 @@ const NotifyAndRedirect = ({
}; };
export { NotifyAndRedirect as _NotifyAndRedirect }; export { NotifyAndRedirect as _NotifyAndRedirect };
export default withRootDialog(withRouter(NotifyAndRedirect)); export default withI18n()(withRootDialog(withRouter(NotifyAndRedirect)));

View File

@@ -1,8 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { I18n } from '@lingui/react';
import { import {
Dropdown, Dropdown,
DropdownItem, DropdownItem,
@@ -57,12 +56,11 @@ class PageHeaderToolbar extends Component {
isAboutDisabled, isAboutDisabled,
onAboutClick, onAboutClick,
onLogoutClick, onLogoutClick,
loggedInUser loggedInUser,
i18n
} = this.props; } = this.props;
return ( return (
<I18n>
{({ i18n }) => (
<Toolbar> <Toolbar>
<ToolbarGroup> <ToolbarGroup>
<Tooltip position="left" content={<div>{i18n._(t`Info`)}</div>}> <Tooltip position="left" content={<div>{i18n._(t`Info`)}</div>}>
@@ -127,8 +125,6 @@ class PageHeaderToolbar extends Component {
</Tooltip> </Tooltip>
</ToolbarGroup> </ToolbarGroup>
</Toolbar> </Toolbar>
)}
</I18n>
); );
} }
} }
@@ -143,4 +139,4 @@ PageHeaderToolbar.defaultProps = {
isAboutDisabled: false isAboutDisabled: false
}; };
export default PageHeaderToolbar; export default withI18n()(PageHeaderToolbar);

View File

@@ -14,8 +14,8 @@ import {
EmptyStateBody, EmptyStateBody,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { CubesIcon } from '@patternfly/react-icons'; import { CubesIcon } from '@patternfly/react-icons';
import { I18n, i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withRouter, Link } from 'react-router-dom'; import { withRouter, Link } from 'react-router-dom';
import Pagination from '../Pagination'; import Pagination from '../Pagination';
@@ -108,13 +108,15 @@ class PaginatedDataList extends React.Component {
showPageSizeOptions, showPageSizeOptions,
paginationStyling, paginationStyling,
location, location,
i18n
} = this.props; } = this.props;
const { error } = this.state; const { error } = this.state;
const [orderBy, sortOrder] = this.getSortOrder(); const [orderBy, sortOrder] = this.getSortOrder();
const queryParams = parseNamespacedQueryString(qsConfig, location.search); const queryParams = parseNamespacedQueryString(qsConfig, location.search);
const columns = toolbarColumns || [{ name: i18n._(t`Name`), key: 'name', isSortable: true }];
return ( return (
<I18n> <Fragment>
{({ i18n }) => ( {error && (
<Fragment> <Fragment>
{error && ( {error && (
<Fragment> <Fragment>
@@ -128,24 +130,10 @@ class PaginatedDataList extends React.Component {
<EmptyState> <EmptyState>
<EmptyStateIcon icon={CubesIcon} /> <EmptyStateIcon icon={CubesIcon} />
<Title size="lg"> <Title size="lg">
<Trans> {i18n._(t`No ${ucFirst(itemNamePlural || pluralize(itemName))} Found`)}
No
{' '}
{ucFirst(itemNamePlural || pluralize(itemName))}
{' '}
Found
</Trans>
</Title> </Title>
<EmptyStateBody> <EmptyStateBody>
<Trans> {i18n._(t`Please add ${getArticle(itemName)} ${itemName} to populate this list`)}
Please add
{' '}
{getArticle(itemName)}
{' '}
{itemName}
{' '}
to populate this list
</Trans>
</EmptyStateBody> </EmptyStateBody>
</EmptyState> </EmptyState>
) : ( ) : (
@@ -199,9 +187,67 @@ class PaginatedDataList extends React.Component {
/> />
</Fragment> </Fragment>
)} )}
</Fragment> // TODO: replace with proper error handling
)}
{items.length === 0 ? (
<EmptyState>
<EmptyStateIcon icon={CubesIcon} />
<Title size="lg">
{i18n._(t`No ${ucFirst(itemNamePlural || pluralize(itemName))} Found`)}
</Title>
<EmptyStateBody>
{i18n._(t`Please add ${getArticle(itemName)} ${itemName} to populate this list`)}
</EmptyStateBody>
</EmptyState>
) : (
<Fragment>
<DataListToolbar
sortedColumnKey={orderBy}
sortOrder={sortOrder}
columns={columns}
onSearch={() => { }}
onSort={this.handleSort}
showSelectAll={showSelectAll}
isAllSelected={isAllSelected}
onSelectAll={onSelectAll}
additionalControls={additionalControls}
/>
<DataList aria-label={i18n._(t`${ucFirst(pluralize(itemName))} List`)}>
{items.map(item => (renderItem ? renderItem(item) : (
<DataListItem
aria-labelledby={`items-list-item-${item.id}`}
key={item.id}
>
<DataListItemRow>
<DataListItemCells dataListCells={[
<DataListCell key="team-name">
<TextContent style={detailWrapperStyle}>
<Link to={{ pathname: item.url }}>
<Text
id={`items-list-item-${item.id}`}
style={detailLabelStyle}
>
{item.name}
</Text>
</Link>
</TextContent>
</DataListCell>
]}
/>
</DataListItemRow>
</DataListItem>
)))}
</DataList>
<Pagination
count={itemCount}
page={queryParams.page}
pageCount={this.getPageCount()}
page_size={queryParams.page_size}
onSetPage={this.handleSetPage}
/>
</Fragment> </Fragment>
)} )}
</I18n> </Fragment>
); );
} }
} }
@@ -235,9 +281,7 @@ PaginatedDataList.propTypes = {
PaginatedDataList.defaultProps = { PaginatedDataList.defaultProps = {
renderItem: null, renderItem: null,
toolbarColumns: [ toolbarColumns: [],
{ name: i18nMark('Name'), key: 'name', isSortable: true },
],
additionalControls: [], additionalControls: [],
itemName: 'item', itemName: 'item',
itemNamePlural: '', itemNamePlural: '',
@@ -250,4 +294,4 @@ PaginatedDataList.defaultProps = {
}; };
export { PaginatedDataList as _PaginatedDataList }; export { PaginatedDataList as _PaginatedDataList };
export default withRouter(PaginatedDataList); export default withI18n()(withRouter(PaginatedDataList));

View File

@@ -3,7 +3,7 @@ import { string, func } from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Button as PFButton } from '@patternfly/react-core'; import { Button as PFButton } from '@patternfly/react-core';
import { PlusIcon } from '@patternfly/react-icons'; import { PlusIcon } from '@patternfly/react-icons';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -20,15 +20,13 @@ const Button = styled(PFButton)`
} }
`; `;
function ToolbarAddButton ({ linkTo, onClick }) { function ToolbarAddButton ({ linkTo, onClick, i18n }) {
if (!linkTo && !onClick) { if (!linkTo && !onClick) {
throw new Error('ToolbarAddButton requires either `linkTo` or `onClick` prop'); throw new Error('ToolbarAddButton requires either `linkTo` or `onClick` prop');
} }
if (linkTo) { if (linkTo) {
// TODO: This should only be a <Link> (no <Button>) but CSS is off // TODO: This should only be a <Link> (no <Button>) but CSS is off
return ( return (
<I18n>
{({ i18n }) => (
<Link to={linkTo}> <Link to={linkTo}>
<Button <Button
variant="primary" variant="primary"
@@ -37,13 +35,10 @@ function ToolbarAddButton ({ linkTo, onClick }) {
<PlusIcon /> <PlusIcon />
</Button> </Button>
</Link> </Link>
)}
</I18n>
); );
} }
return ( return (
<I18n>
{({ i18n }) => (
<Button <Button
variant="primary" variant="primary"
aria-label={i18n._(t`Add`)} aria-label={i18n._(t`Add`)}
@@ -51,8 +46,6 @@ function ToolbarAddButton ({ linkTo, onClick }) {
> >
<PlusIcon /> <PlusIcon />
</Button> </Button>
)}
</I18n>
); );
} }
ToolbarAddButton.propTypes = { ToolbarAddButton.propTypes = {
@@ -64,4 +57,4 @@ ToolbarAddButton.defaultProps = {
onClick: null onClick: null
}; };
export default ToolbarAddButton; export default withI18n()(ToolbarAddButton);

View File

@@ -2,9 +2,9 @@ import React, { Fragment } from 'react';
import { func, bool, number, string, arrayOf, shape } from 'prop-types'; import { func, bool, number, string, arrayOf, shape } from 'prop-types';
import { Button as PFButton, Tooltip } from '@patternfly/react-core'; import { Button as PFButton, Tooltip } from '@patternfly/react-core';
import { TrashAltIcon } from '@patternfly/react-icons'; import { TrashAltIcon } from '@patternfly/react-icons';
import { I18n, i18nMark } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
import { pluralize } from '../../util/strings'; import { pluralize } from '../../util/strings';
@@ -89,55 +89,49 @@ class ToolbarDeleteButton extends React.Component {
} }
renderTooltip () { renderTooltip () {
const { itemsToDelete, itemName } = this.props; const { itemsToDelete, itemName, i18n } = this.props;
if (itemsToDelete.some(cannotDelete)) {
return ( const itemsUnableToDelete = itemsToDelete
<div>
<Trans>
You dont have permission to delete the following
{' '}
{pluralize(itemName)}
:
</Trans>
{itemsToDelete
.filter(cannotDelete) .filter(cannotDelete)
.map(item => ( .map(item => (
<div key={item.id}> <div key={item.id}>
{item.name} {item.name}
</div> </div>
)) ));
} if (itemsToDelete.some(cannotDelete)) {
return (
<div>
{i18n._(t`You do not have permission to delete the following ${pluralize(itemName)}: ${itemsUnableToDelete}`)}
</div> </div>
); );
} }
if (itemsToDelete.length) { if (itemsToDelete.length) {
return i18nMark('Delete'); return i18n._(t`Delete`);
} }
return i18nMark('Select a row to delete'); return i18n._(t`Select a row to delete`);
} }
render () { render () {
const { itemsToDelete, itemName } = this.props; const { itemsToDelete, itemName, i18n } = this.props;
const { isModalOpen } = this.state; const { isModalOpen } = this.state;
const isDisabled = itemsToDelete.length === 0 const isDisabled = itemsToDelete.length === 0
|| itemsToDelete.some(cannotDelete); || itemsToDelete.some(cannotDelete);
return ( return (
<I18n>
{({ i18n }) => (
<Fragment> <Fragment>
<Tooltip <Tooltip
content={this.renderTooltip()} content={this.renderTooltip()}
position="left" position="left"
> >
<Button <Button
className="awx-ToolBarBtn"
variant="plain" variant="plain"
aria-label={i18n._(t`Delete`)} aria-label={i18n._(t`Delete`)}
onClick={this.handleConfirmDelete} onClick={this.handleConfirmDelete}
isDisabled={isDisabled} isDisabled={isDisabled}
> >
<TrashAltIcon /> <TrashAltIcon className="awx-ToolBarTrashCanIcon" />
</Button> </Button>
</Tooltip> </Tooltip>
{ isModalOpen && ( { isModalOpen && (
@@ -182,10 +176,8 @@ class ToolbarDeleteButton extends React.Component {
</AlertModal> </AlertModal>
)} )}
</Fragment> </Fragment>
)}
</I18n>
); );
} }
} }
export default ToolbarDeleteButton; export default withI18n()(ToolbarDeleteButton);

View File

@@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button, Button,
Dropdown, Dropdown,
@@ -106,7 +106,8 @@ class Pagination extends Component {
page_size, page_size,
pageSizeOptions, pageSizeOptions,
showPageSizeOptions, showPageSizeOptions,
style style,
i18n
} = this.props; } = this.props;
const { value, isOpen } = this.state; const { value, isOpen } = this.state;
let opts = []; let opts = [];
@@ -135,12 +136,10 @@ class Pagination extends Component {
)); ));
return ( return (
<I18n>
{({ i18n }) => (
<div className="awx-pagination" style={style}> <div className="awx-pagination" style={style}>
{showPageSizeOptions && ( {showPageSizeOptions && (
<div className="awx-pagination__page-size-selection"> <div className="awx-pagination__page-size-selection">
<Trans>Items Per Page</Trans> {i18n._(t`Items Per Page`)}
<Dropdown <Dropdown
onToggle={this.onTogglePageSize} onToggle={this.onTogglePageSize}
onSelect={this.onSelectPageSize} onSelect={this.onSelectPageSize}
@@ -160,7 +159,7 @@ class Pagination extends Component {
)} )}
<div className="awx-pagination__counts"> <div className="awx-pagination__counts">
<div className="awx-pagination__item-count"> <div className="awx-pagination__item-count">
<Trans>{`Items ${itemMin} ${itemMax} of ${count}`}</Trans> {i18n._(t`Items ${itemMin} ${itemMax} of ${count}`)}
</div> </div>
{pageCount !== 1 && ( {pageCount !== 1 && (
<div className="awx-pagination__page-count"> <div className="awx-pagination__page-count">
@@ -188,18 +187,13 @@ class Pagination extends Component {
className="awx-pagination__page-input-form" className="awx-pagination__page-input-form"
onSubmit={this.onSubmit} onSubmit={this.onSubmit}
> >
<Trans> {i18n._(t`Page ${(<TextInput
{'Page '}
<TextInput
className="awx-pagination__page-input" className="awx-pagination__page-input"
aria-label={i18n._(t`Page Number`)} aria-label={i18n._(t`Page Number`)}
value={value} value={value}
type="text" type="text"
onChange={this.onPageChange} onChange={this.onPageChange}
/> />)} of ${pageCount}`)}
{' of '}
{pageCount}
</Trans>
</form> </form>
<div className="pf-c-input-group"> <div className="pf-c-input-group">
<Button <Button
@@ -225,8 +219,6 @@ class Pagination extends Component {
)} )}
</div> </div>
</div> </div>
)}
</I18n>
); );
} }
} }
@@ -248,4 +240,4 @@ Pagination.defaultProps = {
showPageSizeOptions: true showPageSizeOptions: true
}; };
export default Pagination; export default withI18n()(Pagination);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button as PFButton, Button as PFButton,
@@ -90,7 +90,8 @@ class Search extends React.Component {
render () { render () {
const { up } = DropdownPosition; const { up } = DropdownPosition;
const { const {
columns columns,
i18n
} = this.props; } = this.props;
const { const {
isSearchDropdownOpen, isSearchDropdownOpen,
@@ -109,8 +110,6 @@ class Search extends React.Component {
)); ));
return ( return (
<I18n>
{({ i18n }) => (
<div className="pf-c-input-group"> <div className="pf-c-input-group">
<Dropdown <Dropdown
onToggle={this.handleDropdownToggle} onToggle={this.handleDropdownToggle}
@@ -129,7 +128,7 @@ class Search extends React.Component {
/> />
<TextInput <TextInput
type="search" type="search"
aria-label="Search text input" aria-label={i18n._(t`Search text input`)}
value={searchValue} value={searchValue}
onChange={this.handleSearchInputChange} onChange={this.handleSearchInputChange}
style={{ height: '30px' }} style={{ height: '30px' }}
@@ -142,8 +141,6 @@ class Search extends React.Component {
<SearchIcon /> <SearchIcon />
</Button> </Button>
</div> </div>
)}
</I18n>
); );
} }
} }
@@ -159,4 +156,4 @@ Search.defaultProps = {
sortedColumnKey: 'name' sortedColumnKey: 'name'
}; };
export default Search; export default withI18n()(Search);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button, Button,
@@ -85,7 +85,8 @@ class Sort extends React.Component {
const { const {
columns, columns,
sortedColumnKey, sortedColumnKey,
sortOrder sortOrder,
i18n
} = this.props; } = this.props;
const { const {
isSortDropdownOpen isSortDropdownOpen
@@ -109,8 +110,6 @@ class Sort extends React.Component {
} }
return ( return (
<I18n>
{({ i18n }) => (
<React.Fragment> <React.Fragment>
{ sortDropdownItems.length > 1 && ( { sortDropdownItems.length > 1 && (
<Dropdown <Dropdown
@@ -141,8 +140,6 @@ class Sort extends React.Component {
</IconWrapper> </IconWrapper>
</Button> </Button>
</React.Fragment> </React.Fragment>
)}
</I18n>
); );
} }
} }
@@ -160,4 +157,4 @@ Sort.defaultProps = {
sortedColumnKey: 'name' sortedColumnKey: 'name'
}; };
export default Sort; export default withI18n()(Sort);

View File

@@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Brand } from '@patternfly/react-core'; import { Brand } from '@patternfly/react-core';
@@ -34,6 +34,7 @@ class TowerLogo extends Component {
render () { render () {
const { hover } = this.state; const { hover } = this.state;
const { i18n } = this.props;
let src = TowerLogoHeader; let src = TowerLogoHeader;
@@ -42,8 +43,6 @@ class TowerLogo extends Component {
} }
return ( return (
<I18n>
{({ i18n }) => (
<Brand <Brand
src={src} src={src}
alt={i18n._(t`Tower Brand Image`)} alt={i18n._(t`Tower Brand Image`)}
@@ -53,8 +52,6 @@ class TowerLogo extends Component {
onFocus={this.onHover} onFocus={this.onHover}
onClick={this.onClick} onClick={this.onClick}
/> />
)}
</I18n>
); );
} }
} }
@@ -67,4 +64,4 @@ TowerLogo.defaultProps = {
linkTo: null, linkTo: null,
}; };
export default withRouter(TowerLogo); export default withI18n()(withRouter(TowerLogo));

View File

@@ -4,7 +4,8 @@ import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { withRootDialog } from './RootDialog'; import { withRootDialog } from './RootDialog';
@@ -33,27 +34,27 @@ class Provider extends Component {
} }
handle401 () { handle401 () {
const { handle401, history, setRootDialogMessage } = this.props; const { handle401, history, setRootDialogMessage, i18n } = this.props;
if (handle401) { if (handle401) {
handle401(); handle401();
return; return;
} }
history.replace('/login'); history.replace('/login');
setRootDialogMessage({ setRootDialogMessage({
bodyText: i18nMark('You have been logged out.') bodyText: i18n._(t`You have been logged out.`)
}); });
} }
handle404 () { handle404 () {
const { handle404, history, setRootDialogMessage } = this.props; const { handle404, history, setRootDialogMessage, i18n } = this.props;
if (handle404) { if (handle404) {
handle404(); handle404();
return; return;
} }
history.replace('/home'); history.replace('/home');
setRootDialogMessage({ setRootDialogMessage({
title: i18nMark('404'), title: i18n._(t`404`),
bodyText: i18nMark('Cannot find resource.'), bodyText: i18n._(t`Cannot find resource.`),
variant: 'warning' variant: 'warning'
}); });
} }
@@ -72,7 +73,7 @@ class Provider extends Component {
} }
export { Provider as _NetworkProvider }; export { Provider as _NetworkProvider };
export const NetworkProvider = withRootDialog(withRouter(Provider)); export const NetworkProvider = withI18n()(withRootDialog(withRouter(Provider)));
export function withNetwork (Child) { export function withNetwork (Child) {
return (props) => ( return (props) => (

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Applications extends Component { class Applications extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Applications</Trans> {i18n._(t`Applications`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Applications extends Component {
} }
} }
export default Applications; export default withI18n()(Applications);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class AuthSettings extends Component { class AuthSettings extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Authentication Settings</Trans> {i18n._(t`Authentication Settings`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class AuthSettings extends Component {
} }
} }
export default AuthSettings; export default withI18n()(AuthSettings);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class CredentialTypes extends Component { class CredentialTypes extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Credential Types</Trans> {i18n._(t`Credential Types`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class CredentialTypes extends Component {
} }
} }
export default CredentialTypes; export default withI18n()(CredentialTypes);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Credentials extends Component { class Credentials extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Credentials</Trans> {i18n._(t`Credentials`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Credentials extends Component {
} }
} }
export default Credentials; export default withI18n()(Credentials);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Dashboard extends Component { class Dashboard extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Dashboard</Trans> {i18n._(t`Dashboard`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Dashboard extends Component {
} }
} }
export default Dashboard; export default withI18n()(Dashboard);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class InstanceGroups extends Component { class InstanceGroups extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Instance Groups</Trans> {i18n._(t`Instance Groups`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class InstanceGroups extends Component {
} }
} }
export default InstanceGroups; export default withI18n()(InstanceGroups);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Inventories extends Component { class Inventories extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Inventories</Trans> {i18n._(t`Inventories`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Inventories extends Component {
} }
} }
export default Inventories; export default withI18n()(Inventories);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class InventoryScripts extends Component { class InventoryScripts extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Inventory Scripts</Trans> {i18n._(t`Inventory Scripts`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class InventoryScripts extends Component {
} }
} }
export default InventoryScripts; export default withI18n()(InventoryScripts);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Jobs extends Component { class Jobs extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Jobs</Trans> {i18n._(t`Jobs`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Jobs extends Component {
} }
} }
export default Jobs; export default withI18n()(Jobs);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class JobsSettings extends Component { class JobsSettings extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Jobs Settings</Trans> {i18n._(t`Jobs Settings`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class JobsSettings extends Component {
} }
} }
export default JobsSettings; export default withI18n()(JobsSettings);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class License extends Component { class License extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>License</Trans> {i18n._(t`License`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class License extends Component {
} }
} }
export default License; export default withI18n()(License);

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Redirect, withRouter } from 'react-router-dom'; import { Redirect, withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
LoginForm, LoginForm,
@@ -62,7 +62,7 @@ class AWXLogin extends Component {
render () { render () {
const { username, password, isInputValid, isAuthenticated } = this.state; const { username, password, isInputValid, isAuthenticated } = this.state;
const { alt, loginInfo, logo, bodyText: errorMessage } = this.props; const { alt, loginInfo, logo, bodyText: errorMessage, i18n } = this.props;
const logoSrc = logo ? `data:image/jpeg;${logo}` : towerLogo; const logoSrc = logo ? `data:image/jpeg;${logo}` : towerLogo;
if (isAuthenticated) { if (isAuthenticated) {
@@ -70,8 +70,6 @@ class AWXLogin extends Component {
} }
return ( return (
<I18n>
{({ i18n }) => (
<LoginPage <LoginPage
brandImgSrc={logoSrc} brandImgSrc={logoSrc}
brandImgAlt={alt || 'Ansible Tower'} brandImgAlt={alt || 'Ansible Tower'}
@@ -93,11 +91,9 @@ class AWXLogin extends Component {
onLoginButtonClick={this.onLoginButtonClick} onLoginButtonClick={this.onLoginButtonClick}
/> />
</LoginPage> </LoginPage>
)}
</I18n>
); );
} }
} }
export { AWXLogin as _AWXLogin }; export { AWXLogin as _AWXLogin };
export default withNetwork(withRootDialog(withRouter(AWXLogin))); export default withI18n()(withNetwork(withRootDialog(withRouter(AWXLogin))));

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class ManagementJobs extends Component { class ManagementJobs extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Management Jobs</Trans> {i18n._(t`Management Jobs`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class ManagementJobs extends Component {
} }
} }
export default ManagementJobs; export default withI18n()(ManagementJobs);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class NotificationTemplates extends Component { class NotificationTemplates extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Notification Templates</Trans> {i18n._(t`Notification Templates`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class NotificationTemplates extends Component {
} }
} }
export default NotificationTemplates; export default withI18n()(NotificationTemplates);

View File

@@ -1,7 +1,7 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Route, withRouter, Switch } from 'react-router-dom'; import { Route, withRouter, Switch } from 'react-router-dom';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Config } from '../../contexts/Config'; import { Config } from '../../contexts/Config';
import { NetworkProvider } from '../../contexts/Network'; import { NetworkProvider } from '../../contexts/Network';
@@ -14,34 +14,42 @@ import OrganizationAdd from './screens/OrganizationAdd';
import Organization from './screens/Organization/Organization'; import Organization from './screens/Organization/Organization';
class Organizations extends Component { class Organizations extends Component {
state = { constructor (props) {
super(props);
const { i18n } = props;
this.state = {
breadcrumbConfig: { breadcrumbConfig: {
'/organizations': i18nMark('Organizations'), '/organizations': i18n._(t`Organizations`),
'/organizations/add': i18nMark('Create New Organization') '/organizations/add': i18n._(t`Create New Organization`)
} }
}; };
}
setBreadcrumbConfig = (organization) => { setBreadcrumbConfig = (organization) => {
const { i18n } = this.props;
if (!organization) { if (!organization) {
return; return;
} }
const breadcrumbConfig = { const breadcrumbConfig = {
'/organizations': i18nMark('Organizations'), '/organizations': i18n._(t`Organizations`),
'/organizations/add': i18nMark('Create New Organization'), '/organizations/add': i18n._(t`Create New Organization`),
[`/organizations/${organization.id}`]: `${organization.name}`, [`/organizations/${organization.id}`]: `${organization.name}`,
[`/organizations/${organization.id}/edit`]: i18nMark('Edit Details'), [`/organizations/${organization.id}/edit`]: i18n._(t`Edit Details`),
[`/organizations/${organization.id}/details`]: i18nMark('Details'), [`/organizations/${organization.id}/details`]: i18n._(t`Details`),
[`/organizations/${organization.id}/access`]: i18nMark('Access'), [`/organizations/${organization.id}/access`]: i18n._(t`Access`),
[`/organizations/${organization.id}/teams`]: i18nMark('Teams'), [`/organizations/${organization.id}/teams`]: i18n._(t`Teams`),
[`/organizations/${organization.id}/notifications`]: i18nMark('Notifications'), [`/organizations/${organization.id}/notifications`]: i18n._(t`Notifications`),
}; };
this.setState({ breadcrumbConfig }); this.setState({ breadcrumbConfig });
} }
render () { render () {
const { match, history, location, setRootDialogMessage } = this.props; const { match, history, location, setRootDialogMessage, i18n } = this.props;
const { breadcrumbConfig } = this.state; const { breadcrumbConfig } = this.state;
return ( return (
@@ -65,11 +73,11 @@ class Organizations extends Component {
setRootDialogMessage({ setRootDialogMessage({
title: '404', title: '404',
bodyText: ( bodyText: (
<Trans> <Fragment>
Cannot find organization with ID {i18n._(t`Cannot find organization with ID`)}
<strong>{` ${newRouteMatch.params.id}`}</strong> <strong>{` ${newRouteMatch.params.id}`}</strong>
. .
</Trans> </Fragment>
), ),
variant: 'warning' variant: 'warning'
}); });
@@ -101,4 +109,4 @@ class Organizations extends Component {
} }
export { Organizations as _Organizations }; export { Organizations as _Organizations };
export default withRootDialog(withRouter(Organizations)); export default withI18n()(withRootDialog(withRouter(Organizations)));

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React, { Fragment } from 'react';
import { func, string } from 'prop-types'; import { func, string } from 'prop-types';
import { Button } from '@patternfly/react-core'; import { Button } from '@patternfly/react-core';
import { I18n, i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import AlertModal from '../../../components/AlertModal'; import AlertModal from '../../../components/AlertModal';
import { Role } from '../../../types'; import { Role } from '../../../types';
@@ -24,14 +24,12 @@ class DeleteRoleConfirmationModal extends React.Component {
} }
render () { render () {
const { role, username, onCancel, onConfirm } = this.props; const { role, username, onCancel, onConfirm, i18n } = this.props;
const title = `Remove ${this.isTeamRole() ? 'Team' : 'User'} Access`; const title = i18n._(t`Remove ${this.isTeamRole() ? i18n._(t`Team`) : i18n._(t`User`)} Access`);
return ( return (
<I18n>
{({ i18n }) => (
<AlertModal <AlertModal
variant="danger" variant="danger"
title={i18nMark(title)} title={title}
isOpen isOpen
onClose={onCancel} onClose={onCancel}
actions={[ actions={[
@@ -49,32 +47,20 @@ class DeleteRoleConfirmationModal extends React.Component {
]} ]}
> >
{this.isTeamRole() ? ( {this.isTeamRole() ? (
<Trans> <Fragment>
Are you sure you want to remove {i18n._(t`Are you sure you want to remove ${role.name} access from ${role.team_name}? Doing so affects all members of the team.`)}
<b>{` ${role.name} `}</b>
access from
<b>{` ${role.team_name}`}</b>
? Doing so affects all members of the team.
<br /> <br />
<br /> <br />
If you {i18n._(t`If you ${(<b><i>only</i></b>)} want to remove access for this particular user, please remove them from the team.`)}
<b><i> only </i></b> </Fragment>
want to remove access for this particular user, please remove them from the team.
</Trans>
) : ( ) : (
<Trans> <Fragment>
Are you sure you want to remove {i18n._(t`Are you sure you want to remove ${role.name} access from ${username}?`)}
<b>{` ${role.name} `}</b> </Fragment>
access from
<b>{` ${username}`}</b>
?
</Trans>
)} )}
</AlertModal> </AlertModal>
)}
</I18n>
); );
} }
} }
export default DeleteRoleConfirmationModal; export default withI18n()(DeleteRoleConfirmationModal);

View File

@@ -1,20 +1,14 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18n, i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { FormGroup, Tooltip } from '@patternfly/react-core'; import { FormGroup, Tooltip } from '@patternfly/react-core';
import { QuestionCircleIcon } from '@patternfly/react-icons'; import { QuestionCircleIcon } from '@patternfly/react-icons';
import { t } from '@lingui/macro';
import Lookup from '../../../components/Lookup'; import Lookup from '../../../components/Lookup';
import { withNetwork } from '../../../contexts/Network'; import { withNetwork } from '../../../contexts/Network';
const INSTANCE_GROUPS_LOOKUP_COLUMNS = [
{ name: i18nMark('Name'), key: 'name', isSortable: true },
{ name: i18nMark('Modified'), key: 'modified', isSortable: false, isNumeric: true },
{ name: i18nMark('Created'), key: 'created', isSortable: false, isNumeric: true }
];
class InstanceGroupsLookup extends React.Component { class InstanceGroupsLookup extends React.Component {
constructor (props) { constructor (props) {
super(props); super(props);
@@ -29,11 +23,9 @@ class InstanceGroupsLookup extends React.Component {
} }
render () { render () {
const { value, tooltip, onChange } = this.props; const { value, tooltip, onChange, i18n } = this.props;
return ( return (
<I18n>
{({ i18n }) => (
<FormGroup <FormGroup
label={( label={(
<Fragment> <Fragment>
@@ -60,12 +52,14 @@ class InstanceGroupsLookup extends React.Component {
value={value} value={value}
onLookupSave={onChange} onLookupSave={onChange}
getItems={this.getInstanceGroups} getItems={this.getInstanceGroups}
columns={INSTANCE_GROUPS_LOOKUP_COLUMNS} columns={[
{ name: i18n._(t`Name`), key: 'name', isSortable: true },
{ name: i18n._(t`Modified`), key: 'modified', isSortable: false, isNumeric: true },
{ name: i18n._(t`Created`), key: 'created', isSortable: false, isNumeric: true }
]}
sortedColumnKey="name" sortedColumnKey="name"
/> />
</FormGroup> </FormGroup>
)}
</I18n>
); );
} }
} }
@@ -80,4 +74,4 @@ InstanceGroupsLookup.defaultProps = {
tooltip: '', tooltip: '',
}; };
export default withNetwork(InstanceGroupsLookup); export default withI18n()(withNetwork(InstanceGroupsLookup));

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { func } from 'prop-types'; import { func } from 'prop-types';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
DataListItem, DataListItem,
@@ -81,12 +81,10 @@ class OrganizationAccessItem extends React.Component {
} }
render () { render () {
const { accessRecord, onRoleDelete } = this.props; const { accessRecord, onRoleDelete, i18n } = this.props;
const [teamRoles, userRoles] = this.getRoleLists(); const [teamRoles, userRoles] = this.getRoleLists();
return ( return (
<I18n>
{({ i18n }) => (
<DataListItem aria-labelledby="access-list-item" key={accessRecord.id}> <DataListItem aria-labelledby="access-list-item" key={accessRecord.id}>
<DataListItemRow> <DataListItemRow>
<DataListItemCells dataListCells={[ <DataListItemCells dataListCells={[
@@ -167,10 +165,8 @@ class OrganizationAccessItem extends React.Component {
/> />
</DataListItemRow> </DataListItemRow>
</DataListItem> </DataListItem>
)}
</I18n>
); );
} }
} }
export default OrganizationAccessItem; export default withI18n()(OrganizationAccessItem);

View File

@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { Formik, Field } from 'formik'; import { Formik, Field } from 'formik';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Form, Form,
@@ -83,13 +83,11 @@ class OrganizationForm extends Component {
} }
render () { render () {
const { organization, handleCancel } = this.props; const { organization, handleCancel, i18n } = this.props;
const { instanceGroups, formIsValid, error } = this.state; const { instanceGroups, formIsValid, error } = this.state;
const defaultVenv = '/venv/ansible/'; const defaultVenv = '/venv/ansible/';
return ( return (
<I18n>
{({ i18n }) => (
<Formik <Formik
initialValues={{ initialValues={{
name: organization.name, name: organization.name,
@@ -105,7 +103,7 @@ class OrganizationForm extends Component {
name="name" name="name"
type="text" type="text"
label={i18n._(t`Name`)} label={i18n._(t`Name`)}
validate={required()} validate={required(null, i18n)}
isRequired isRequired
/> />
<FormField <FormField
@@ -151,8 +149,6 @@ class OrganizationForm extends Component {
</Form> </Form>
)} )}
/> />
)}
</I18n>
); );
} }
} }
@@ -176,4 +172,4 @@ OrganizationForm.contextTypes = {
}; };
export { OrganizationForm as _OrganizationForm }; export { OrganizationForm as _OrganizationForm };
export default withNetwork(withRouter(OrganizationForm)); export default withI18n()(withNetwork(withRouter(OrganizationForm)));

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { string, bool, func } from 'prop-types'; import { string, bool, func } from 'prop-types';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
Badge as PFBadge, Badge as PFBadge,
DataListItem, DataListItem,
@@ -62,6 +63,7 @@ class OrganizationListItem extends React.Component {
isSelected, isSelected,
onSelect, onSelect,
detailUrl, detailUrl,
i18n
} = this.props; } = this.props;
const labelId = `check-action-${organization.id}`; const labelId = `check-action-${organization.id}`;
return ( return (
@@ -86,13 +88,15 @@ class OrganizationListItem extends React.Component {
</DataListCell>, </DataListCell>,
<DataListCell key="org-members" righthalf="true" width={2}> <DataListCell key="org-members" righthalf="true" width={2}>
<ListGroup> <ListGroup>
<Trans>Members</Trans> {i18n._(t`Members`)}
<Badge isRead> <Badge isRead>
{organization.summary_fields.related_field_counts.users} {organization.summary_fields.related_field_counts.users}
</Badge> </Badge>
</ListGroup> </ListGroup>
</DataListCell>,
<DataListCell>
<ListGroup> <ListGroup>
<Trans>Teams</Trans> {i18n._(t`Teams`)}
<Badge isRead> <Badge isRead>
{organization.summary_fields.related_field_counts.teams} {organization.summary_fields.related_field_counts.teams}
</Badge> </Badge>
@@ -105,4 +109,4 @@ class OrganizationListItem extends React.Component {
); );
} }
} }
export default OrganizationListItem; export default withI18n()(OrganizationListItem);

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { I18n, i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Switch, Route, withRouter, Redirect } from 'react-router-dom'; import { Switch, Route, withRouter, Redirect } from 'react-router-dom';
import { Card, CardHeader, PageSection } from '@patternfly/react-core'; import { Card, CardHeader, PageSection } from '@patternfly/react-core';
@@ -100,7 +100,8 @@ class Organization extends Component {
location, location,
match, match,
me, me,
history history,
i18n
} = this.props; } = this.props;
const { const {
@@ -126,14 +127,14 @@ class Organization extends Component {
); );
const tabsArray = [ const tabsArray = [
{ name: i18nMark('Details'), link: `${match.url}/details`, id: 0 }, { name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{ name: i18nMark('Access'), link: `${match.url}/access`, id: 1 }, { name: i18n._(t`Access`), link: `${match.url}/access`, id: 1 },
{ name: i18nMark('Teams'), link: `${match.url}/teams`, id: 2 } { name: i18n._(t`Teams`), link: `${match.url}/teams`, id: 2 }
]; ];
if (canSeeNotificationsTab) { if (canSeeNotificationsTab) {
tabsArray.push({ tabsArray.push({
name: i18nMark('Notifications'), name: i18n._(t`Notifications`),
link: `${match.url}/notifications`, link: `${match.url}/notifications`,
id: 3 id: 3
}); });
@@ -145,9 +146,6 @@ class Organization extends Component {
<CardHeader <CardHeader
style={tabsStyle} style={tabsStyle}
> >
<I18n>
{({ i18n }) => (
<React.Fragment>
<div className="awx-orgTabs-container"> <div className="awx-orgTabs-container">
<RoutedTabs <RoutedTabs
match={match} match={match}
@@ -160,9 +158,6 @@ class Organization extends Component {
className="awx-orgTabs__bottom-border" className="awx-orgTabs__bottom-border"
/> />
</div> </div>
</React.Fragment>
)}
</I18n>
</CardHeader> </CardHeader>
)); ));
if (!match) { if (!match) {
@@ -245,5 +240,5 @@ class Organization extends Component {
); );
} }
} }
export default withNetwork(withRouter(Organization)); export default withI18n()(withNetwork(withRouter(Organization)));
export { Organization as _Organization }; export { Organization as _Organization };

View File

@@ -1,6 +1,7 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import PaginatedDataList, { ToolbarAddButton } from '../../../../components/PaginatedDataList'; import PaginatedDataList, { ToolbarAddButton } from '../../../../components/PaginatedDataList';
import OrganizationAccessItem from '../../components/OrganizationAccessItem'; import OrganizationAccessItem from '../../components/OrganizationAccessItem';
import DeleteRoleConfirmationModal from '../../components/DeleteRoleConfirmationModal'; import DeleteRoleConfirmationModal from '../../components/DeleteRoleConfirmationModal';
@@ -130,7 +131,7 @@ class OrganizationAccess extends React.Component {
} }
render () { render () {
const { api, organization } = this.props; const { api, organization, i18n } = this.props;
const { const {
isLoading, isLoading,
isInitialized, isInitialized,
@@ -167,9 +168,9 @@ class OrganizationAccess extends React.Component {
itemName="role" itemName="role"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
toolbarColumns={[ toolbarColumns={[
{ name: i18nMark('Name'), key: 'first_name', isSortable: true }, { name: i18n._(t`Name`), key: 'first_name', isSortable: true },
{ name: i18nMark('Username'), key: 'username', isSortable: true }, { name: i18n._(t`Username`), key: 'username', isSortable: true },
{ name: i18nMark('Last Name'), key: 'last_name', isSortable: true }, { name: i18n._(t`Last Name`), key: 'last_name', isSortable: true },
]} ]}
additionalControls={canEdit ? [ additionalControls={canEdit ? [
<ToolbarAddButton key="add" onClick={this.toggleAddModal} /> <ToolbarAddButton key="add" onClick={this.toggleAddModal} />
@@ -197,4 +198,4 @@ class OrganizationAccess extends React.Component {
} }
export { OrganizationAccess as _OrganizationAccess }; export { OrganizationAccess as _OrganizationAccess };
export default withNetwork(withRouter(OrganizationAccess)); export default withI18n()(withNetwork(withRouter(OrganizationAccess)));

View File

@@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom'; import { Link, withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
CardBody, CardBody,
@@ -103,7 +103,8 @@ class OrganizationDetail extends Component {
modified, modified,
summary_fields summary_fields
}, },
match match,
i18n
} = this.props; } = this.props;
const showOverflowChipAfter = 5; const showOverflowChipAfter = 5;
@@ -127,8 +128,6 @@ class OrganizationDetail extends Component {
) : null; ) : null;
return ( return (
<I18n>
{({ i18n }) => (
<CardBody> <CardBody>
<div className="pf-l-grid pf-m-gutter pf-m-all-12-col-on-md pf-m-all-6-col-on-lg pf-m-all-4-col-on-xl"> <div className="pf-l-grid pf-m-gutter pf-m-all-12-col-on-md pf-m-all-6-col-on-lg pf-m-all-4-col-on-xl">
<Detail <Detail
@@ -157,7 +156,7 @@ class OrganizationDetail extends Component {
component={TextVariants.h6} component={TextVariants.h6}
style={detailLabelStyle} style={detailLabelStyle}
> >
<Trans>Instance Groups</Trans> {i18n._(t`Instance Groups`)}
</Text> </Text>
<div style={detailValueStyle}> <div style={detailValueStyle}>
{instanceGroupChips} {instanceGroupChips}
@@ -169,16 +168,14 @@ class OrganizationDetail extends Component {
{summary_fields.user_capabilities.edit && ( {summary_fields.user_capabilities.edit && (
<div style={{ display: 'flex', flexDirection: 'row-reverse', marginTop: '20px' }}> <div style={{ display: 'flex', flexDirection: 'row-reverse', marginTop: '20px' }}>
<Link to={`/organizations/${match.params.id}/edit`}> <Link to={`/organizations/${match.params.id}/edit`}>
<Button><Trans>Edit</Trans></Button> <Button>{i18n._(t`Edit`)}</Button>
</Link> </Link>
</div> </div>
)} )}
{error ? 'error!' : ''} {error ? 'error!' : ''}
</CardBody> </CardBody>
)}
</I18n>
); );
} }
} }
export default withRouter(withNetwork(OrganizationDetail)); export default withI18n()(withRouter(withNetwork(OrganizationDetail)));

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
@@ -57,11 +57,10 @@ class OrganizationAdd extends React.Component {
render () { render () {
const { error } = this.state; const { error } = this.state;
const { i18n } = this.props;
return ( return (
<PageSection> <PageSection>
<I18n>
{({ i18n }) => (
<Card> <Card>
<CardHeader className="at-u-textRight"> <CardHeader className="at-u-textRight">
<Tooltip <Tooltip
@@ -79,8 +78,6 @@ class OrganizationAdd extends React.Component {
{error ? <div>error</div> : ''} {error ? <div>error</div> : ''}
</CardBody> </CardBody>
</Card> </Card>
)}
</I18n>
</PageSection> </PageSection>
); );
} }
@@ -95,4 +92,4 @@ OrganizationAdd.contextTypes = {
}; };
export { OrganizationAdd as _OrganizationAdd }; export { OrganizationAdd as _OrganizationAdd };
export default withNetwork(withRouter(OrganizationAdd)); export default withI18n()(withNetwork(withRouter(OrganizationAdd)));

View File

@@ -1,6 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { i18nMark } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
Card, Card,
PageSection, PageSection,
@@ -15,12 +16,6 @@ import PaginatedDataList, {
import OrganizationListItem from '../components/OrganizationListItem'; import OrganizationListItem from '../components/OrganizationListItem';
import { getQSConfig, parseNamespacedQueryString } from '../../../util/qs'; import { getQSConfig, parseNamespacedQueryString } from '../../../util/qs';
const COLUMNS = [
{ name: i18nMark('Name'), key: 'name', isSortable: true },
{ name: i18nMark('Modified'), key: 'modified', isSortable: true, isNumeric: true },
{ name: i18nMark('Created'), key: 'created', isSortable: true, isNumeric: true },
];
const QS_CONFIG = getQSConfig('organization', { const QS_CONFIG = getQSConfig('organization', {
page: 1, page: 1,
page_size: 5, page_size: 5,
@@ -36,7 +31,7 @@ class OrganizationsList extends Component {
isLoading: true, isLoading: true,
isInitialized: false, isInitialized: false,
organizations: [], organizations: [],
selected: [], selected: []
}; };
this.handleSelectAll = this.handleSelectAll.bind(this); this.handleSelectAll = this.handleSelectAll.bind(this);
@@ -148,9 +143,9 @@ class OrganizationsList extends Component {
isLoading, isLoading,
isInitialized, isInitialized,
selected, selected,
organizations, organizations
} = this.state; } = this.state;
const { match } = this.props; const { match, i18n } = this.props;
const isAllSelected = selected.length === organizations.length; const isAllSelected = selected.length === organizations.length;
@@ -163,7 +158,11 @@ class OrganizationsList extends Component {
itemCount={itemCount} itemCount={itemCount}
itemName="organization" itemName="organization"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
toolbarColumns={COLUMNS} toolbarColumns={[
{ name: i18n._(t`Name`), key: 'name', isSortable: true },
{ name: i18n._(t`Modified`), key: 'modified', isSortable: true, isNumeric: true },
{ name: i18n._(t`Created`), key: 'created', isSortable: true, isNumeric: true },
]}
showSelectAll showSelectAll
isAllSelected={isAllSelected} isAllSelected={isAllSelected}
onSelectAll={this.handleSelectAll} onSelectAll={this.handleSelectAll}
@@ -198,4 +197,4 @@ class OrganizationsList extends Component {
} }
export { OrganizationsList as _OrganizationsList }; export { OrganizationsList as _OrganizationsList };
export default withNetwork(withRouter(OrganizationsList)); export default withI18n()(withNetwork(withRouter(OrganizationsList)));

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Portal extends Component { class Portal extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>My View</Trans> {i18n._(t`My View`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Portal extends Component {
} }
} }
export default Portal; export default withI18n()(Portal);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Projects extends Component { class Projects extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Projects</Trans> {i18n._(t`Projects`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Projects extends Component {
} }
} }
export default Projects; export default withI18n()(Projects);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Schedules extends Component { class Schedules extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Schedules</Trans> {i18n._(t`Schedules`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Schedules extends Component {
} }
} }
export default Schedules; export default withI18n()(Schedules);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class SystemSettings extends Component { class SystemSettings extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>System Settings</Trans> {i18n._(t`System Settings`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class SystemSettings extends Component {
} }
} }
export default SystemSettings; export default withI18n()(SystemSettings);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Teams extends Component { class Teams extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Teams</Trans> {i18n._(t`Teams`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Teams extends Component {
} }
} }
export default Teams; export default withI18n()(Teams);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Templates extends Component { class Templates extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Templates</Trans> {i18n._(t`Templates`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Templates extends Component {
} }
} }
export default Templates; export default withI18n()(Templates);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class UISettings extends Component { class UISettings extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>User Interface Settings</Trans> {i18n._(t`User Interface Settings`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class UISettings extends Component {
} }
} }
export default UISettings; export default withI18n()(UISettings);

View File

@@ -1,5 +1,6 @@
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { import {
PageSection, PageSection,
PageSectionVariants, PageSectionVariants,
@@ -8,13 +9,14 @@ import {
class Users extends Component { class Users extends Component {
render () { render () {
const { i18n } = this.props;
const { light, medium } = PageSectionVariants; const { light, medium } = PageSectionVariants;
return ( return (
<Fragment> <Fragment>
<PageSection variant={light} className="pf-m-condensed"> <PageSection variant={light} className="pf-m-condensed">
<Title size="2xl"> <Title size="2xl">
<Trans>Users</Trans> {i18n._(t`Users`)}
</Title> </Title>
</PageSection> </PageSection>
<PageSection variant={medium} /> <PageSection variant={medium} />
@@ -23,4 +25,4 @@ class Users extends Component {
} }
} }
export default Users; export default withI18n()(Users);

View File

@@ -1,20 +0,0 @@
import { i18nMark } from '@lingui/react';
export function required (message) {
return value => {
if (!value.trim()) {
return message || i18nMark('This field must not be blank');
}
return undefined;
};
}
export function maxLength (max) {
return value => {
if (value.trim().length
> max) {
return i18nMark(`This field must not exceed ${max} characters`);
}
return undefined;
};
}

20
src/util/validators.jsx Normal file
View File

@@ -0,0 +1,20 @@
import { t } from '@lingui/macro';
export function required (message, i18n) {
return value => {
if (!value.trim()) {
return message || i18n._(t`This field must not be blank`);
}
return undefined;
};
}
export function maxLength (max, i18n) {
return value => {
if (value.trim().length
> max) {
return i18n._(t`This field must not exceed ${max} characters`);
}
return undefined;
};
}