mirror of
https://github.com/ansible/awx.git
synced 2026-02-21 13:10:11 -03:30
update awx-pf to use withI18n i18n._ and t exclusively
This commit is contained in:
158
src/App.jsx
158
src/App.jsx
@@ -9,7 +9,7 @@ import {
|
||||
Button
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { RootDialog } from './contexts/RootDialog';
|
||||
@@ -66,92 +66,88 @@ class App extends Component {
|
||||
render () {
|
||||
const { isAboutModalOpen, isNavOpen } = this.state;
|
||||
|
||||
const { render, routeGroups = [], navLabel = '' } = this.props;
|
||||
const { render, routeGroups = [], navLabel = '', i18n } = this.props;
|
||||
|
||||
return (
|
||||
<Config>
|
||||
{({ ansible_version, version, me }) => (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<RootDialog>
|
||||
{({
|
||||
title,
|
||||
bodyText,
|
||||
variant = 'info',
|
||||
clearRootDialogMessage
|
||||
}) => (
|
||||
<Fragment>
|
||||
{(title || bodyText) && (
|
||||
<AlertModal
|
||||
variant={variant}
|
||||
isOpen={!!(title || bodyText)}
|
||||
onClose={clearRootDialogMessage}
|
||||
title={title}
|
||||
actions={[
|
||||
<Button
|
||||
key="close"
|
||||
variant="secondary"
|
||||
onClick={clearRootDialogMessage}
|
||||
>
|
||||
{i18n._(t`Close`)}
|
||||
</Button>
|
||||
]}
|
||||
<RootDialog>
|
||||
{({
|
||||
title,
|
||||
bodyText,
|
||||
variant = 'info',
|
||||
clearRootDialogMessage
|
||||
}) => (
|
||||
<Fragment>
|
||||
{(title || bodyText) && (
|
||||
<AlertModal
|
||||
variant={variant}
|
||||
isOpen={!!(title || bodyText)}
|
||||
onClose={clearRootDialogMessage}
|
||||
title={title}
|
||||
actions={[
|
||||
<Button
|
||||
key="close"
|
||||
variant="secondary"
|
||||
onClick={clearRootDialogMessage}
|
||||
>
|
||||
{bodyText}
|
||||
</AlertModal>
|
||||
)}
|
||||
<Page
|
||||
usecondensed="True"
|
||||
header={(
|
||||
<PageHeader
|
||||
showNavToggle
|
||||
onNavToggle={this.onNavToggle}
|
||||
logo={<TowerLogo linkTo="/" />}
|
||||
toolbar={(
|
||||
<PageHeaderToolbar
|
||||
loggedInUser={me}
|
||||
isAboutDisabled={!version}
|
||||
onAboutClick={this.onAboutModalOpen}
|
||||
onLogoutClick={this.onLogout}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
sidebar={(
|
||||
<PageSidebar
|
||||
isNavOpen={isNavOpen}
|
||||
nav={(
|
||||
<Nav aria-label={navLabel}>
|
||||
<NavList>
|
||||
{routeGroups.map(
|
||||
({ groupId, groupTitle, routes }) => (
|
||||
<NavExpandableGroup
|
||||
key={groupId}
|
||||
groupId={groupId}
|
||||
groupTitle={groupTitle}
|
||||
routes={routes}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</NavList>
|
||||
</Nav>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{render && render({ routeGroups })}
|
||||
</Page>
|
||||
<About
|
||||
ansible_version={ansible_version}
|
||||
version={version}
|
||||
isOpen={isAboutModalOpen}
|
||||
onClose={this.onAboutModalClose}
|
||||
/>
|
||||
</Fragment>
|
||||
{i18n._(t`Close`)}
|
||||
</Button>
|
||||
]}
|
||||
>
|
||||
{bodyText}
|
||||
</AlertModal>
|
||||
)}
|
||||
</RootDialog>
|
||||
<Page
|
||||
usecondensed="True"
|
||||
header={(
|
||||
<PageHeader
|
||||
showNavToggle
|
||||
onNavToggle={this.onNavToggle}
|
||||
logo={<TowerLogo linkTo="/" />}
|
||||
toolbar={(
|
||||
<PageHeaderToolbar
|
||||
loggedInUser={me}
|
||||
isAboutDisabled={!version}
|
||||
onAboutClick={this.onAboutModalOpen}
|
||||
onLogoutClick={this.onLogout}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
sidebar={(
|
||||
<PageSidebar
|
||||
isNavOpen={isNavOpen}
|
||||
nav={(
|
||||
<Nav aria-label={navLabel}>
|
||||
<NavList>
|
||||
{routeGroups.map(
|
||||
({ groupId, groupTitle, routes }) => (
|
||||
<NavExpandableGroup
|
||||
key={groupId}
|
||||
groupId={groupId}
|
||||
groupTitle={groupTitle}
|
||||
routes={routes}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</NavList>
|
||||
</Nav>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{render && render({ routeGroups })}
|
||||
</Page>
|
||||
<About
|
||||
ansible_version={ansible_version}
|
||||
version={version}
|
||||
isOpen={isAboutModalOpen}
|
||||
onClose={this.onAboutModalClose}
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
</RootDialog>
|
||||
)}
|
||||
</Config>
|
||||
);
|
||||
@@ -159,4 +155,4 @@ class App extends Component {
|
||||
}
|
||||
|
||||
export { App as _App };
|
||||
export default withNetwork(App);
|
||||
export default withI18n()(withNetwork(App));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
AboutModal,
|
||||
TextContent,
|
||||
@@ -41,46 +41,43 @@ class About extends React.Component {
|
||||
ansible_version,
|
||||
version,
|
||||
isOpen,
|
||||
onClose
|
||||
onClose,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
const speechBubble = this.createSpeechBubble(version);
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<AboutModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
productName="Ansible Tower"
|
||||
trademark={i18n._(t`Copyright 2018 Red Hat, Inc.`)}
|
||||
brandImageSrc={brandImg}
|
||||
brandImageAlt={i18n._(t`Brand Image`)}
|
||||
logoImageSrc={logoImg}
|
||||
logoImageAlt={i18n._(t`AboutModal Logo`)}
|
||||
>
|
||||
<pre>
|
||||
{ speechBubble }
|
||||
{`
|
||||
\\
|
||||
\\ ^__^
|
||||
(oo)\\_______
|
||||
(__) A )\\
|
||||
||----w |
|
||||
|| ||
|
||||
`}
|
||||
</pre>
|
||||
<TextContent>
|
||||
<TextList component="dl">
|
||||
<TextListItem component="dt">
|
||||
<Trans>Ansible Version</Trans>
|
||||
</TextListItem>
|
||||
<TextListItem component="dd">{ ansible_version }</TextListItem>
|
||||
</TextList>
|
||||
</TextContent>
|
||||
</AboutModal>
|
||||
)}
|
||||
</I18n>
|
||||
<AboutModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
productName="Ansible Tower"
|
||||
trademark={i18n._(t`Copyright 2018 Red Hat, Inc.`)}
|
||||
brandImageSrc={brandImg}
|
||||
brandImageAlt={i18n._(t`Brand Image`)}
|
||||
logoImageSrc={logoImg}
|
||||
logoImageAlt={i18n._(t`AboutModal Logo`)}
|
||||
>
|
||||
<pre>
|
||||
{ speechBubble }
|
||||
{`
|
||||
\\
|
||||
\\ ^__^
|
||||
(oo)\\_______
|
||||
(__) A )\\
|
||||
||----w |
|
||||
|| ||
|
||||
`}
|
||||
</pre>
|
||||
<TextContent>
|
||||
<TextList component="dl">
|
||||
<TextListItem component="dt">
|
||||
{i18n._(t`Ansible Version`)}
|
||||
</TextListItem>
|
||||
<TextListItem component="dd">{ ansible_version }</TextListItem>
|
||||
</TextList>
|
||||
</TextContent>
|
||||
</AboutModal>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -98,4 +95,4 @@ About.defaultProps = {
|
||||
version: null,
|
||||
};
|
||||
|
||||
export default About;
|
||||
export default withI18n()(About);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Wizard } from '@patternfly/react-core';
|
||||
import SelectResourceStep from './SelectResourceStep';
|
||||
@@ -127,113 +127,103 @@ class AddResourceRole extends React.Component {
|
||||
} = this.state;
|
||||
const {
|
||||
onClose,
|
||||
roles
|
||||
roles,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
const userColumns = [
|
||||
{ name: i18nMark('Username'), key: 'username', isSortable: true }
|
||||
{ name: i18n._(t`Username`), key: 'username', isSortable: true }
|
||||
];
|
||||
|
||||
const teamColumns = [
|
||||
{ name: i18nMark('Name'), key: 'name', isSortable: true }
|
||||
{ name: i18n._(t`Name`), key: 'name', isSortable: true }
|
||||
];
|
||||
|
||||
let wizardTitle = '';
|
||||
|
||||
switch (selectedResource) {
|
||||
case 'users':
|
||||
wizardTitle = i18nMark('Add User Roles');
|
||||
wizardTitle = i18n._(t`Add User Roles`);
|
||||
break;
|
||||
case 'teams':
|
||||
wizardTitle = i18nMark('Add Team Roles');
|
||||
wizardTitle = i18n._(t`Add Team Roles`);
|
||||
break;
|
||||
default:
|
||||
wizardTitle = i18nMark('Add Roles');
|
||||
wizardTitle = i18n._(t`Add Roles`);
|
||||
}
|
||||
|
||||
const steps = [
|
||||
{
|
||||
id: 1,
|
||||
name: i18nMark('Select Users Or Teams'),
|
||||
name: i18n._(t`Select Users Or Teams`),
|
||||
component: (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<div style={{ display: 'flex' }}>
|
||||
<SelectableCard
|
||||
isSelected={selectedResource === 'users'}
|
||||
label={i18n._(t`Users`)}
|
||||
onClick={() => this.handleResourceSelect('users')}
|
||||
/>
|
||||
<SelectableCard
|
||||
isSelected={selectedResource === 'teams'}
|
||||
label={i18n._(t`Teams`)}
|
||||
onClick={() => this.handleResourceSelect('teams')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</I18n>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<SelectableCard
|
||||
isSelected={selectedResource === 'users'}
|
||||
label={i18n._(t`Users`)}
|
||||
onClick={() => this.handleResourceSelect('users')}
|
||||
/>
|
||||
<SelectableCard
|
||||
isSelected={selectedResource === 'teams'}
|
||||
label={i18n._(t`Teams`)}
|
||||
onClick={() => this.handleResourceSelect('teams')}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
enableNext: selectedResource !== null
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: i18nMark('Select items from list'),
|
||||
name: i18n._(t`Select items from list`),
|
||||
component: (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
{selectedResource === 'users' && (
|
||||
<SelectResourceStep
|
||||
columns={userColumns}
|
||||
displayKey="username"
|
||||
onRowClick={this.handleResourceCheckboxClick}
|
||||
onSearch={this.readUsers}
|
||||
selectedLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
sortedColumnKey="username"
|
||||
itemName="user"
|
||||
/>
|
||||
)}
|
||||
{selectedResource === 'teams' && (
|
||||
<SelectResourceStep
|
||||
columns={teamColumns}
|
||||
onRowClick={this.handleResourceCheckboxClick}
|
||||
onSearch={this.readTeams}
|
||||
selectedLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
itemName="team"
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
{selectedResource === 'users' && (
|
||||
<SelectResourceStep
|
||||
columns={userColumns}
|
||||
displayKey="username"
|
||||
onRowClick={this.handleResourceCheckboxClick}
|
||||
onSearch={this.readUsers}
|
||||
selectedLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
sortedColumnKey="username"
|
||||
itemName="user"
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
{selectedResource === 'teams' && (
|
||||
<SelectResourceStep
|
||||
columns={teamColumns}
|
||||
onRowClick={this.handleResourceCheckboxClick}
|
||||
onSearch={this.readTeams}
|
||||
selectedLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
itemName="team"
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
),
|
||||
enableNext: selectedResourceRows.length > 0
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: i18nMark('Apply roles'),
|
||||
name: i18n._(t`Apply roles`),
|
||||
component: (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<SelectRoleStep
|
||||
onRolesClick={this.handleRoleCheckboxClick}
|
||||
roles={roles}
|
||||
selectedListKey={selectedResource === 'users' ? 'username' : 'name'}
|
||||
selectedListLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
selectedRoleRows={selectedRoleRows}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
<SelectRoleStep
|
||||
onRolesClick={this.handleRoleCheckboxClick}
|
||||
roles={roles}
|
||||
selectedListKey={selectedResource === 'users' ? 'username' : 'name'}
|
||||
selectedListLabel={i18n._(t`Selected`)}
|
||||
selectedResourceRows={selectedResourceRows}
|
||||
selectedRoleRows={selectedRoleRows}
|
||||
/>
|
||||
),
|
||||
nextButtonText: i18nMark('Save'),
|
||||
nextButtonText: i18n._(t`Save`),
|
||||
enableNext: selectedRoleRows.length > 0
|
||||
}
|
||||
];
|
||||
|
||||
const currentStep = steps.find(step => step.id === currentStepId);
|
||||
|
||||
// TODO: somehow internationalize steps and currentStep.nextButtonText
|
||||
return (
|
||||
<Wizard
|
||||
style={{ overflow: 'scroll' }}
|
||||
@@ -259,4 +249,4 @@ AddResourceRole.defaultProps = {
|
||||
roles: {}
|
||||
};
|
||||
|
||||
export default AddResourceRole;
|
||||
export default withI18n()(AddResourceRole);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
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 CheckboxListItem from '../ListItem';
|
||||
import SelectedList from '../SelectedList';
|
||||
@@ -87,11 +88,12 @@ class SelectResourceStep extends React.Component {
|
||||
selectedLabel,
|
||||
selectedResourceRows,
|
||||
itemName,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{isLoading && (<div>Loading...</div>)}
|
||||
{isLoading && (<div>{i18n._(t`Loading...`)}</div>)}
|
||||
{isInitialized && (
|
||||
<Fragment>
|
||||
{selectedResourceRows.length > 0 && (
|
||||
@@ -146,11 +148,11 @@ SelectResourceStep.propTypes = {
|
||||
SelectResourceStep.defaultProps = {
|
||||
displayKey: 'name',
|
||||
onRowClick: () => {},
|
||||
selectedLabel: i18nMark('Selected Items'),
|
||||
selectedLabel: null,
|
||||
selectedResourceRows: [],
|
||||
sortedColumnKey: 'name',
|
||||
itemName: 'item',
|
||||
};
|
||||
|
||||
export { SelectResourceStep as _SelectResourceStep };
|
||||
export default withRouter(SelectResourceStep);
|
||||
export default withI18n()(withRouter(SelectResourceStep));
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { Fragment } from 'react';
|
||||
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 SelectedList from '../SelectedList';
|
||||
@@ -14,7 +15,8 @@ class RolesStep extends React.Component {
|
||||
selectedListKey,
|
||||
selectedListLabel,
|
||||
selectedResourceRows,
|
||||
selectedRoleRows
|
||||
selectedRoleRows,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -24,7 +26,7 @@ class RolesStep extends React.Component {
|
||||
<SelectedList
|
||||
displayKey={selectedListKey}
|
||||
isReadOnly
|
||||
label={selectedListLabel}
|
||||
label={selectedListLabel || i18n._(t`Selected`)}
|
||||
selected={selectedResourceRows}
|
||||
showOverflowAfter={5}
|
||||
/>
|
||||
@@ -61,9 +63,9 @@ RolesStep.propTypes = {
|
||||
RolesStep.defaultProps = {
|
||||
onRolesClick: () => {},
|
||||
selectedListKey: 'name',
|
||||
selectedListLabel: i18nMark('Selected'),
|
||||
selectedListLabel: null,
|
||||
selectedResourceRows: [],
|
||||
selectedRoleRows: []
|
||||
};
|
||||
|
||||
export default RolesStep;
|
||||
export default withI18n()(RolesStep);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
FormSelect,
|
||||
@@ -20,29 +20,25 @@ class AnsibleSelect extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { label, value, data, defaultSelected } = this.props;
|
||||
const { label, value, data, defaultSelected, i18n } = this.props;
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<FormSelect
|
||||
value={value}
|
||||
onChange={this.onSelectChange}
|
||||
aria-label={i18n._(t`Select Input`)}
|
||||
>
|
||||
{data.map((datum) => (
|
||||
datum === defaultSelected ? (
|
||||
<FormSelectOption
|
||||
key=""
|
||||
value=""
|
||||
label={i18n._(t`Use Default ${label}`)}
|
||||
/>
|
||||
) : (
|
||||
<FormSelectOption key={datum} value={datum} label={datum} />
|
||||
)
|
||||
))}
|
||||
</FormSelect>
|
||||
)}
|
||||
</I18n>
|
||||
<FormSelect
|
||||
value={value}
|
||||
onChange={this.onSelectChange}
|
||||
aria-label={i18n._(t`Select Input`)}
|
||||
>
|
||||
{data.map((datum) => (
|
||||
datum === defaultSelected ? (
|
||||
<FormSelectOption
|
||||
key=""
|
||||
value=""
|
||||
label={i18n._(t`Use Default ${label}`)}
|
||||
/>
|
||||
) : (
|
||||
<FormSelectOption key={datum} value={datum} label={datum} />
|
||||
)
|
||||
))}
|
||||
</FormSelect>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -62,4 +58,4 @@ AnsibleSelect.propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default AnsibleSelect;
|
||||
export default withI18n()(AnsibleSelect);
|
||||
|
||||
@@ -3,40 +3,32 @@ import { string } from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button } from '@patternfly/react-core';
|
||||
import { TimesIcon } from '@patternfly/react-icons';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
function CardCloseButton ({ linkTo, ...props }) {
|
||||
function CardCloseButton ({ linkTo, i18n, i18nHash, ...props }) {
|
||||
if (linkTo) {
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Link
|
||||
className="pf-c-button pf-c-card__close"
|
||||
aria-label={i18n._(t`Close`)}
|
||||
title={i18n._(t`Close`)}
|
||||
to={linkTo}
|
||||
{...props}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Link>
|
||||
)}
|
||||
</I18n>
|
||||
<Link
|
||||
className="pf-c-button pf-c-card__close"
|
||||
aria-label={i18n._(t`Close`)}
|
||||
title={i18n._(t`Close`)}
|
||||
to={linkTo}
|
||||
{...props}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Button
|
||||
variant="plain"
|
||||
className="pf-c-card__close"
|
||||
aria-label={i18n._(t`Close`)}
|
||||
{...props}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Button>
|
||||
)}
|
||||
</I18n>
|
||||
<Button
|
||||
variant="plain"
|
||||
className="pf-c-card__close"
|
||||
aria-label={i18n._(t`Close`)}
|
||||
{...props}
|
||||
>
|
||||
<TimesIcon />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
CardCloseButton.propTypes = {
|
||||
@@ -46,4 +38,4 @@ CardCloseButton.defaultProps = {
|
||||
linkTo: null,
|
||||
};
|
||||
|
||||
export default CardCloseButton;
|
||||
export default withI18n()(CardCloseButton);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Checkbox,
|
||||
@@ -85,70 +85,66 @@ class DataListToolbar extends React.Component {
|
||||
sortOrder,
|
||||
sortedColumnKey,
|
||||
additionalControls,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
const showExpandCollapse = (onCompact && onExpand);
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<AWXToolbar>
|
||||
<Toolbar marginleft={noLeftMargin ? 1 : 0}>
|
||||
<ColumnLeft>
|
||||
{ showSelectAll && (
|
||||
<Fragment>
|
||||
<ToolbarItem>
|
||||
<Checkbox
|
||||
checked={isAllSelected}
|
||||
onChange={onSelectAll}
|
||||
aria-label={i18n._(t`Select all`)}
|
||||
id="select-all"
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<VerticalSeparator />
|
||||
</Fragment>
|
||||
)}
|
||||
<ToolbarItem css="flex-grow: 1;">
|
||||
<Search
|
||||
columns={columns}
|
||||
onSearch={onSearch}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
<AWXToolbar>
|
||||
<Toolbar marginleft={noLeftMargin ? 1 : 0}>
|
||||
<ColumnLeft>
|
||||
{ showSelectAll && (
|
||||
<Fragment>
|
||||
<ToolbarItem>
|
||||
<Checkbox
|
||||
checked={isAllSelected}
|
||||
onChange={onSelectAll}
|
||||
aria-label={i18n._(t`Select all`)}
|
||||
id="select-all"
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<VerticalSeparator />
|
||||
</ColumnLeft>
|
||||
<ColumnRight>
|
||||
<ToolbarItem>
|
||||
<Sort
|
||||
columns={columns}
|
||||
onSort={onSort}
|
||||
sortOrder={sortOrder}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
</Fragment>
|
||||
)}
|
||||
<ToolbarItem css="flex-grow: 1;">
|
||||
<Search
|
||||
columns={columns}
|
||||
onSearch={onSearch}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
<VerticalSeparator />
|
||||
</ColumnLeft>
|
||||
<ColumnRight>
|
||||
<ToolbarItem>
|
||||
<Sort
|
||||
columns={columns}
|
||||
onSort={onSort}
|
||||
sortOrder={sortOrder}
|
||||
sortedColumnKey={sortedColumnKey}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
{showExpandCollapse && (
|
||||
<Fragment>
|
||||
<VerticalSeparator />
|
||||
<ToolbarGroup>
|
||||
<ExpandCollapse
|
||||
isCompact={isCompact}
|
||||
onCompact={onCompact}
|
||||
onExpand={onExpand}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
{showExpandCollapse && (
|
||||
<Fragment>
|
||||
<VerticalSeparator />
|
||||
<ToolbarGroup>
|
||||
<ExpandCollapse
|
||||
isCompact={isCompact}
|
||||
onCompact={onCompact}
|
||||
onExpand={onExpand}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
{ additionalControls && (
|
||||
<VerticalSeparator />
|
||||
)}
|
||||
</Fragment>
|
||||
</ToolbarGroup>
|
||||
{ additionalControls && (
|
||||
<VerticalSeparator />
|
||||
)}
|
||||
<AdditionalControlsWrapper>
|
||||
{additionalControls}
|
||||
</AdditionalControlsWrapper>
|
||||
</ColumnRight>
|
||||
</Toolbar>
|
||||
</AWXToolbar>
|
||||
|
||||
)}
|
||||
</I18n>
|
||||
</Fragment>
|
||||
)}
|
||||
<AdditionalControlsWrapper>
|
||||
{additionalControls}
|
||||
</AdditionalControlsWrapper>
|
||||
</ColumnRight>
|
||||
</Toolbar>
|
||||
</AWXToolbar>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -184,4 +180,4 @@ DataListToolbar.defaultProps = {
|
||||
additionalControls: [],
|
||||
};
|
||||
|
||||
export default DataListToolbar;
|
||||
export default withI18n()(DataListToolbar);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
@@ -22,36 +22,33 @@ class ExpandCollapse extends React.Component {
|
||||
const {
|
||||
onCompact,
|
||||
onExpand,
|
||||
isCompact
|
||||
isCompact,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Collapse`)}
|
||||
onClick={onCompact}
|
||||
style={isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<BarsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Expand`)}
|
||||
onClick={onExpand}
|
||||
style={!isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<EqualsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
<Fragment>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Collapse`)}
|
||||
onClick={onCompact}
|
||||
style={isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<BarsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Expand`)}
|
||||
onClick={onExpand}
|
||||
style={!isCompact ? ToolbarActiveStyle : null}
|
||||
>
|
||||
<EqualsIcon />
|
||||
</Button>
|
||||
</ToolbarItem>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -64,4 +61,4 @@ ExpandCollapse.propTypes = {
|
||||
|
||||
ExpandCollapse.defaultProps = {};
|
||||
|
||||
export default ExpandCollapse;
|
||||
export default withI18n()(ExpandCollapse);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
ActionGroup,
|
||||
@@ -20,21 +20,17 @@ const buttonGroupStyle = {
|
||||
marginRight: '20px'
|
||||
};
|
||||
|
||||
const FormActionGroup = ({ onSubmit, submitDisabled, onCancel }) => (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ActionGroup style={formActionGroupStyle}>
|
||||
<Toolbar>
|
||||
<ToolbarGroup style={buttonGroupStyle}>
|
||||
<Button aria-label={i18n._(t`Save`)} variant="primary" type="submit" onClick={onSubmit} isDisabled={submitDisabled}>{i18n._(t`Save`)}</Button>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
<Button aria-label={i18n._(t`Cancel`)} variant="secondary" type="button" onClick={onCancel}>{i18n._(t`Cancel`)}</Button>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</ActionGroup>
|
||||
)}
|
||||
</I18n>
|
||||
const FormActionGroup = ({ onSubmit, submitDisabled, onCancel, i18n }) => (
|
||||
<ActionGroup style={formActionGroupStyle}>
|
||||
<Toolbar>
|
||||
<ToolbarGroup style={buttonGroupStyle}>
|
||||
<Button aria-label={i18n._(t`Save`)} variant="primary" type="submit" onClick={onSubmit} isDisabled={submitDisabled}>{i18n._(t`Save`)}</Button>
|
||||
</ToolbarGroup>
|
||||
<ToolbarGroup>
|
||||
<Button aria-label={i18n._(t`Cancel`)} variant="secondary" type="button" onClick={onCancel}>{i18n._(t`Cancel`)}</Button>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
</ActionGroup>
|
||||
);
|
||||
|
||||
FormActionGroup.propTypes = {
|
||||
@@ -47,4 +43,4 @@ FormActionGroup.defaultProps = {
|
||||
submitDisabled: false,
|
||||
};
|
||||
|
||||
export default FormActionGroup;
|
||||
export default withI18n()(FormActionGroup);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
InputGroup,
|
||||
Modal,
|
||||
} from '@patternfly/react-core';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { withNetwork } from '../../contexts/Network';
|
||||
@@ -130,7 +130,9 @@ class Lookup extends React.Component {
|
||||
results,
|
||||
count,
|
||||
} = 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 ? (
|
||||
<div className="pf-c-chip-group">
|
||||
@@ -143,64 +145,60 @@ class Lookup extends React.Component {
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
<InputGroup className="awx-lookup">
|
||||
<Button
|
||||
aria-label="Search"
|
||||
id={id}
|
||||
onClick={this.handleModalToggle}
|
||||
variant={ButtonVariant.tertiary}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
<div className="pf-c-form-control">
|
||||
{chips}
|
||||
</div>
|
||||
</InputGroup>
|
||||
<Modal
|
||||
className="awx-c-modal"
|
||||
title={`Select ${lookupHeader}`}
|
||||
isOpen={isModalOpen}
|
||||
onClose={this.handleModalToggle}
|
||||
actions={[
|
||||
<Button key="save" variant="primary" onClick={this.saveModal} style={(results.length === 0) ? { display: 'none' } : {}}>{i18n._(t`Save`)}</Button>,
|
||||
<Button key="cancel" variant="secondary" onClick={this.handleModalToggle}>{(results.length === 0) ? i18n._(t`Close`) : i18n._(t`Cancel`)}</Button>
|
||||
]}
|
||||
>
|
||||
<PaginatedDataList
|
||||
items={results}
|
||||
itemCount={count}
|
||||
itemName={lookupHeader}
|
||||
qsConfig={this.qsConfig}
|
||||
toolbarColumns={columns}
|
||||
renderItem={item => (
|
||||
<CheckboxListItem
|
||||
key={item.id}
|
||||
itemId={item.id}
|
||||
name={item.name}
|
||||
isSelected={lookupSelectedItems.some(i => i.id === item.id)}
|
||||
onSelect={() => this.toggleSelected(item)}
|
||||
/>
|
||||
)}
|
||||
alignToolbarLeft
|
||||
showPageSizeOptions={false}
|
||||
paginationStyling={paginationStyling}
|
||||
<Fragment>
|
||||
<InputGroup className="awx-lookup">
|
||||
<Button
|
||||
aria-label="Search"
|
||||
id={id}
|
||||
onClick={this.handleModalToggle}
|
||||
variant={ButtonVariant.tertiary}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
<div className="pf-c-form-control">
|
||||
{chips}
|
||||
</div>
|
||||
</InputGroup>
|
||||
<Modal
|
||||
className="awx-c-modal"
|
||||
title={i18n._(t`Select ${header}`)}
|
||||
isOpen={isModalOpen}
|
||||
onClose={this.handleModalToggle}
|
||||
actions={[
|
||||
<Button key="save" variant="primary" onClick={this.saveModal} style={(results.length === 0) ? { display: 'none' } : {}}>{i18n._(t`Save`)}</Button>,
|
||||
<Button key="cancel" variant="secondary" onClick={this.handleModalToggle}>{(results.length === 0) ? i18n._(t`Close`) : i18n._(t`Cancel`)}</Button>
|
||||
]}
|
||||
>
|
||||
<PaginatedDataList
|
||||
items={results}
|
||||
itemCount={count}
|
||||
itemName={lookupHeader}
|
||||
qsConfig={this.qsConfig}
|
||||
toolbarColumns={columns}
|
||||
renderItem={item => (
|
||||
<CheckboxListItem
|
||||
key={item.id}
|
||||
itemId={item.id}
|
||||
name={item.name}
|
||||
isSelected={lookupSelectedItems.some(i => i.id === item.id)}
|
||||
onSelect={() => this.toggleSelected(item)}
|
||||
/>
|
||||
{lookupSelectedItems.length > 0 && (
|
||||
<SelectedList
|
||||
label={i18n._(t`Selected`)}
|
||||
selected={lookupSelectedItems}
|
||||
showOverflowAfter={5}
|
||||
onRemove={this.toggleSelected}
|
||||
/>
|
||||
)}
|
||||
{ error ? <div>error</div> : '' }
|
||||
</Modal>
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
)}
|
||||
alignToolbarLeft
|
||||
showPageSizeOptions={false}
|
||||
paginationStyling={paginationStyling}
|
||||
/>
|
||||
{lookupSelectedItems.length > 0 && (
|
||||
<SelectedList
|
||||
label={i18n._(t`Selected`)}
|
||||
selected={lookupSelectedItems}
|
||||
showOverflowAfter={5}
|
||||
onRemove={this.toggleSelected}
|
||||
/>
|
||||
)}
|
||||
{ error ? <div>error</div> : '' }
|
||||
</Modal>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -217,9 +215,9 @@ Lookup.propTypes = {
|
||||
|
||||
Lookup.defaultProps = {
|
||||
id: 'lookup-search',
|
||||
lookupHeader: 'items',
|
||||
lookupHeader: null,
|
||||
name: null,
|
||||
};
|
||||
|
||||
export { Lookup as _Lookup };
|
||||
export default withNetwork(withRouter(Lookup));
|
||||
export default withI18n()(withNetwork(withRouter(Lookup)));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
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 { Link } from 'react-router-dom';
|
||||
import {
|
||||
@@ -37,66 +37,75 @@ function NotificationListItem (props) {
|
||||
detailUrl,
|
||||
successTurnedOn,
|
||||
errorTurnedOn,
|
||||
toggleNotification
|
||||
toggleNotification,
|
||||
i18n
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<DataListItem
|
||||
aria-labelledby={`items-list-item-${notification.id}`}
|
||||
key={notification.id}
|
||||
>
|
||||
<DataListItemRow>
|
||||
<DataListItemCells dataListCells={[
|
||||
<DataListCell key="name">
|
||||
<Link
|
||||
to={{
|
||||
pathname: detailUrl
|
||||
}}
|
||||
css="margin-right: 1.5em;"
|
||||
>
|
||||
<b id={`items-list-item-${notification.id}`}>{notification.name}</b>
|
||||
</Link>
|
||||
<Badge
|
||||
css="text-transform: capitalize;"
|
||||
isRead
|
||||
>
|
||||
{notification.notification_type}
|
||||
</Badge>
|
||||
</DataListCell>,
|
||||
<DataListCell righthalf="true" key="toggles">
|
||||
<Switch
|
||||
id={`notification-${notification.id}-success-toggle`}
|
||||
label={i18n._(t`Successful`)}
|
||||
isChecked={successTurnedOn}
|
||||
isDisabled={!canToggleNotifications}
|
||||
onChange={() => toggleNotification(
|
||||
notification.id,
|
||||
successTurnedOn,
|
||||
'success'
|
||||
)}
|
||||
aria-label={i18n._(t`Toggle notification success`)}
|
||||
/>
|
||||
<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`)}
|
||||
/>
|
||||
</DataListCell>
|
||||
]}
|
||||
<DataListItem
|
||||
aria-labelledby={`items-list-item-${notification.id}`}
|
||||
key={notification.id}
|
||||
>
|
||||
<DataListItemRow>
|
||||
<DataListItemCells dataListCells={[
|
||||
<DataListCell key="name">
|
||||
<Link
|
||||
to={{
|
||||
pathname: detailUrl
|
||||
}}
|
||||
css="margin-right: 1.5em;"
|
||||
>
|
||||
<b id={`items-list-item-${notification.id}`}>{notification.name}</b>
|
||||
</Link>
|
||||
<Badge
|
||||
css="text-transform: capitalize;"
|
||||
isRead
|
||||
>
|
||||
{notification.notification_type}
|
||||
</Badge>
|
||||
</DataListCell>,
|
||||
<DataListCell righthalf="true" key="toggles">
|
||||
<Switch
|
||||
id={`notification-${notification.id}-success-toggle`}
|
||||
label={i18n._(t`Successful`)}
|
||||
isChecked={successTurnedOn}
|
||||
isDisabled={!canToggleNotifications}
|
||||
onChange={() => toggleNotification(
|
||||
notification.id,
|
||||
successTurnedOn,
|
||||
'success'
|
||||
)}
|
||||
aria-label={i18n._(t`Toggle notification success`)}
|
||||
/>
|
||||
</DataListItemRow>
|
||||
</DataListItem>
|
||||
)}
|
||||
</I18n>
|
||||
<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`)}
|
||||
/>
|
||||
</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>
|
||||
</DataListItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,4 +127,4 @@ NotificationListItem.defaultProps = {
|
||||
successTurnedOn: false,
|
||||
};
|
||||
|
||||
export default NotificationListItem;
|
||||
export default withI18n()(NotificationListItem);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import { Redirect, withRouter } from 'react-router-dom';
|
||||
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { withRootDialog } from '../contexts/RootDialog';
|
||||
|
||||
@@ -14,16 +14,13 @@ const NotifyAndRedirect = ({
|
||||
strict,
|
||||
sensitive,
|
||||
setRootDialogMessage,
|
||||
location
|
||||
location,
|
||||
i18n
|
||||
}) => {
|
||||
setRootDialogMessage({
|
||||
title: '404',
|
||||
bodyText: (
|
||||
<Trans>
|
||||
Cannot find route
|
||||
<strong>{` ${location.pathname}`}</strong>
|
||||
.
|
||||
</Trans>
|
||||
<Fragment>{i18n._(t`Cannot find route ${(<strong>{location.pathname}</strong>)}.`)}</Fragment>
|
||||
),
|
||||
variant: 'warning'
|
||||
});
|
||||
@@ -41,4 +38,4 @@ const NotifyAndRedirect = ({
|
||||
};
|
||||
|
||||
export { NotifyAndRedirect as _NotifyAndRedirect };
|
||||
export default withRootDialog(withRouter(NotifyAndRedirect));
|
||||
export default withI18n()(withRootDialog(withRouter(NotifyAndRedirect)));
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { I18n } from '@lingui/react';
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
@@ -57,78 +56,75 @@ class PageHeaderToolbar extends Component {
|
||||
isAboutDisabled,
|
||||
onAboutClick,
|
||||
onLogoutClick,
|
||||
loggedInUser
|
||||
loggedInUser,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Toolbar>
|
||||
<ToolbarGroup>
|
||||
<Tooltip position="left" content={<div>{i18n._(t`Info`)}</div>}>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
isPlain
|
||||
isOpen={isHelpOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleHelpSelect}
|
||||
toggle={(
|
||||
<DropdownToggle onToggle={this.handleHelpToggle}>
|
||||
<QuestionCircleIcon />
|
||||
</DropdownToggle>
|
||||
<Toolbar>
|
||||
<ToolbarGroup>
|
||||
<Tooltip position="left" content={<div>{i18n._(t`Info`)}</div>}>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
isPlain
|
||||
isOpen={isHelpOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleHelpSelect}
|
||||
toggle={(
|
||||
<DropdownToggle onToggle={this.handleHelpToggle}>
|
||||
<QuestionCircleIcon />
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="help" target="_blank" href={DOCLINK}>
|
||||
{i18n._(t`Help`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="about"
|
||||
component="button"
|
||||
isDisabled={isAboutDisabled}
|
||||
onClick={onAboutClick}
|
||||
>
|
||||
{i18n._(t`About`)}
|
||||
</DropdownItem>
|
||||
]}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</Tooltip>
|
||||
<Tooltip position="left" content={<div>User</div>}>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
isPlain
|
||||
isOpen={isUserOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleUserSelect}
|
||||
toggle={(
|
||||
<DropdownToggle onToggle={this.handleUserToggle}>
|
||||
<UserIcon />
|
||||
{loggedInUser && (
|
||||
<span style={{ marginLeft: '10px' }}>
|
||||
{loggedInUser.username}
|
||||
</span>
|
||||
)}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="help" target="_blank" href={DOCLINK}>
|
||||
{i18n._(t`Help`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="about"
|
||||
component="button"
|
||||
isDisabled={isAboutDisabled}
|
||||
onClick={onAboutClick}
|
||||
>
|
||||
{i18n._(t`About`)}
|
||||
</DropdownItem>
|
||||
]}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</Tooltip>
|
||||
<Tooltip position="left" content={<div>User</div>}>
|
||||
<ToolbarItem>
|
||||
<Dropdown
|
||||
isPlain
|
||||
isOpen={isUserOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleUserSelect}
|
||||
toggle={(
|
||||
<DropdownToggle onToggle={this.handleUserToggle}>
|
||||
<UserIcon />
|
||||
{loggedInUser && (
|
||||
<span style={{ marginLeft: '10px' }}>
|
||||
{loggedInUser.username}
|
||||
</span>
|
||||
)}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="user" href="#/home">
|
||||
{i18n._(t`User Details`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="logout"
|
||||
component="button"
|
||||
onClick={onLogoutClick}
|
||||
>
|
||||
{i18n._(t`Logout`)}
|
||||
</DropdownItem>
|
||||
]}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</Tooltip>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
)}
|
||||
</I18n>
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="user" href="#/home">
|
||||
{i18n._(t`User Details`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="logout"
|
||||
component="button"
|
||||
onClick={onLogoutClick}
|
||||
>
|
||||
{i18n._(t`Logout`)}
|
||||
</DropdownItem>
|
||||
]}
|
||||
/>
|
||||
</ToolbarItem>
|
||||
</Tooltip>
|
||||
</ToolbarGroup>
|
||||
</Toolbar>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -143,4 +139,4 @@ PageHeaderToolbar.defaultProps = {
|
||||
isAboutDisabled: false
|
||||
};
|
||||
|
||||
export default PageHeaderToolbar;
|
||||
export default withI18n()(PageHeaderToolbar);
|
||||
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
EmptyStateBody,
|
||||
} from '@patternfly/react-core';
|
||||
import { CubesIcon } from '@patternfly/react-icons';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { withRouter, Link } from 'react-router-dom';
|
||||
|
||||
import Pagination from '../Pagination';
|
||||
@@ -108,13 +108,15 @@ class PaginatedDataList extends React.Component {
|
||||
showPageSizeOptions,
|
||||
paginationStyling,
|
||||
location,
|
||||
i18n
|
||||
} = this.props;
|
||||
const { error } = this.state;
|
||||
const [orderBy, sortOrder] = this.getSortOrder();
|
||||
const queryParams = parseNamespacedQueryString(qsConfig, location.search);
|
||||
const columns = toolbarColumns || [{ name: i18n._(t`Name`), key: 'name', isSortable: true }];
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
{error && (
|
||||
<Fragment>
|
||||
{error && (
|
||||
<Fragment>
|
||||
@@ -128,24 +130,10 @@ class PaginatedDataList extends React.Component {
|
||||
<EmptyState>
|
||||
<EmptyStateIcon icon={CubesIcon} />
|
||||
<Title size="lg">
|
||||
<Trans>
|
||||
No
|
||||
{' '}
|
||||
{ucFirst(itemNamePlural || pluralize(itemName))}
|
||||
{' '}
|
||||
Found
|
||||
</Trans>
|
||||
{i18n._(t`No ${ucFirst(itemNamePlural || pluralize(itemName))} Found`)}
|
||||
</Title>
|
||||
<EmptyStateBody>
|
||||
<Trans>
|
||||
Please add
|
||||
{' '}
|
||||
{getArticle(itemName)}
|
||||
{' '}
|
||||
{itemName}
|
||||
{' '}
|
||||
to populate this list
|
||||
</Trans>
|
||||
{i18n._(t`Please add ${getArticle(itemName)} ${itemName} to populate this list`)}
|
||||
</EmptyStateBody>
|
||||
</EmptyState>
|
||||
) : (
|
||||
@@ -199,9 +187,67 @@ class PaginatedDataList extends React.Component {
|
||||
/>
|
||||
</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>
|
||||
)}
|
||||
</I18n>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -235,9 +281,7 @@ PaginatedDataList.propTypes = {
|
||||
|
||||
PaginatedDataList.defaultProps = {
|
||||
renderItem: null,
|
||||
toolbarColumns: [
|
||||
{ name: i18nMark('Name'), key: 'name', isSortable: true },
|
||||
],
|
||||
toolbarColumns: [],
|
||||
additionalControls: [],
|
||||
itemName: 'item',
|
||||
itemNamePlural: '',
|
||||
@@ -250,4 +294,4 @@ PaginatedDataList.defaultProps = {
|
||||
};
|
||||
|
||||
export { PaginatedDataList as _PaginatedDataList };
|
||||
export default withRouter(PaginatedDataList);
|
||||
export default withI18n()(withRouter(PaginatedDataList));
|
||||
|
||||
@@ -3,7 +3,7 @@ import { string, func } from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button as PFButton } from '@patternfly/react-core';
|
||||
import { PlusIcon } from '@patternfly/react-icons';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import styled from 'styled-components';
|
||||
|
||||
@@ -20,39 +20,32 @@ const Button = styled(PFButton)`
|
||||
}
|
||||
`;
|
||||
|
||||
function ToolbarAddButton ({ linkTo, onClick }) {
|
||||
function ToolbarAddButton ({ linkTo, onClick, i18n }) {
|
||||
if (!linkTo && !onClick) {
|
||||
throw new Error('ToolbarAddButton requires either `linkTo` or `onClick` prop');
|
||||
}
|
||||
if (linkTo) {
|
||||
// TODO: This should only be a <Link> (no <Button>) but CSS is off
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Link to={linkTo}>
|
||||
<Button
|
||||
variant="primary"
|
||||
aria-label={i18n._(t`Add`)}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Link to={linkTo}>
|
||||
<Button
|
||||
variant="primary"
|
||||
aria-label={i18n._(t`Add`)}
|
||||
onClick={onClick}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
)}
|
||||
</I18n>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="primary"
|
||||
aria-label={i18n._(t`Add`)}
|
||||
onClick={onClick}
|
||||
>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
ToolbarAddButton.propTypes = {
|
||||
@@ -64,4 +57,4 @@ ToolbarAddButton.defaultProps = {
|
||||
onClick: null
|
||||
};
|
||||
|
||||
export default ToolbarAddButton;
|
||||
export default withI18n()(ToolbarAddButton);
|
||||
|
||||
@@ -2,9 +2,9 @@ import React, { Fragment } from 'react';
|
||||
import { func, bool, number, string, arrayOf, shape } from 'prop-types';
|
||||
import { Button as PFButton, Tooltip } from '@patternfly/react-core';
|
||||
import { TrashAltIcon } from '@patternfly/react-icons';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import styled from 'styled-components';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import AlertModal from '../AlertModal';
|
||||
import { pluralize } from '../../util/strings';
|
||||
|
||||
@@ -89,103 +89,95 @@ class ToolbarDeleteButton extends React.Component {
|
||||
}
|
||||
|
||||
renderTooltip () {
|
||||
const { itemsToDelete, itemName } = this.props;
|
||||
const { itemsToDelete, itemName, i18n } = this.props;
|
||||
|
||||
const itemsUnableToDelete = itemsToDelete
|
||||
.filter(cannotDelete)
|
||||
.map(item => (
|
||||
<div key={item.id}>
|
||||
{item.name}
|
||||
</div>
|
||||
));
|
||||
if (itemsToDelete.some(cannotDelete)) {
|
||||
return (
|
||||
<div>
|
||||
<Trans>
|
||||
You dont have permission to delete the following
|
||||
{' '}
|
||||
{pluralize(itemName)}
|
||||
:
|
||||
</Trans>
|
||||
{itemsToDelete
|
||||
.filter(cannotDelete)
|
||||
.map(item => (
|
||||
<div key={item.id}>
|
||||
{item.name}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
{i18n._(t`You do not have permission to delete the following ${pluralize(itemName)}: ${itemsUnableToDelete}`)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
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 () {
|
||||
const { itemsToDelete, itemName } = this.props;
|
||||
const { itemsToDelete, itemName, i18n } = this.props;
|
||||
const { isModalOpen } = this.state;
|
||||
|
||||
const isDisabled = itemsToDelete.length === 0
|
||||
|| itemsToDelete.some(cannotDelete);
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Fragment>
|
||||
<Tooltip
|
||||
content={this.renderTooltip()}
|
||||
position="left"
|
||||
>
|
||||
<Fragment>
|
||||
<Tooltip
|
||||
content={this.renderTooltip()}
|
||||
position="left"
|
||||
>
|
||||
<Button
|
||||
className="awx-ToolBarBtn"
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Delete`)}
|
||||
onClick={this.handleConfirmDelete}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
<TrashAltIcon className="awx-ToolBarTrashCanIcon" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{ isModalOpen && (
|
||||
<AlertModal
|
||||
variant="danger"
|
||||
title={itemsToDelete === 1
|
||||
? i18n._(t`Delete ${itemName}`)
|
||||
: i18n._(t`Delete ${pluralize(itemName)}`)
|
||||
}
|
||||
isOpen={isModalOpen}
|
||||
onClose={this.handleCancelDelete}
|
||||
actions={[
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Delete`)}
|
||||
onClick={this.handleConfirmDelete}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
<TrashAltIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{ isModalOpen && (
|
||||
<AlertModal
|
||||
key="delete"
|
||||
variant="danger"
|
||||
title={itemsToDelete === 1
|
||||
? i18n._(t`Delete ${itemName}`)
|
||||
: i18n._(t`Delete ${pluralize(itemName)}`)
|
||||
}
|
||||
isOpen={isModalOpen}
|
||||
onClose={this.handleCancelDelete}
|
||||
actions={[
|
||||
<Button
|
||||
key="delete"
|
||||
variant="danger"
|
||||
aria-label={i18n._(t`confirm delete`)}
|
||||
onClick={this.handleDelete}
|
||||
>
|
||||
{i18n._(t`Delete`)}
|
||||
</Button>,
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="secondary"
|
||||
aria-label={i18n._(t`cancel delete`)}
|
||||
onClick={this.handleCancelDelete}
|
||||
>
|
||||
{i18n._(t`Cancel`)}
|
||||
</Button>
|
||||
]}
|
||||
aria-label={i18n._(t`confirm delete`)}
|
||||
onClick={this.handleDelete}
|
||||
>
|
||||
{i18n._(t`Are you sure you want to delete:`)}
|
||||
{i18n._(t`Delete`)}
|
||||
</Button>,
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="secondary"
|
||||
aria-label={i18n._(t`cancel delete`)}
|
||||
onClick={this.handleCancelDelete}
|
||||
>
|
||||
{i18n._(t`Cancel`)}
|
||||
</Button>
|
||||
]}
|
||||
>
|
||||
{i18n._(t`Are you sure you want to delete:`)}
|
||||
<br />
|
||||
{itemsToDelete.map((item) => (
|
||||
<span key={item.id}>
|
||||
<strong>
|
||||
{item.name}
|
||||
</strong>
|
||||
<br />
|
||||
{itemsToDelete.map((item) => (
|
||||
<span key={item.id}>
|
||||
<strong>
|
||||
{item.name}
|
||||
</strong>
|
||||
<br />
|
||||
</span>
|
||||
))}
|
||||
<br />
|
||||
</AlertModal>
|
||||
)}
|
||||
</Fragment>
|
||||
</span>
|
||||
))}
|
||||
<br />
|
||||
</AlertModal>
|
||||
)}
|
||||
</I18n>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ToolbarDeleteButton;
|
||||
export default withI18n()(ToolbarDeleteButton);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
@@ -106,7 +106,8 @@ class Pagination extends Component {
|
||||
page_size,
|
||||
pageSizeOptions,
|
||||
showPageSizeOptions,
|
||||
style
|
||||
style,
|
||||
i18n
|
||||
} = this.props;
|
||||
const { value, isOpen } = this.state;
|
||||
let opts = [];
|
||||
@@ -135,98 +136,89 @@ class Pagination extends Component {
|
||||
));
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<div className="awx-pagination" style={style}>
|
||||
{showPageSizeOptions && (
|
||||
<div className="awx-pagination__page-size-selection">
|
||||
<Trans>Items Per Page</Trans>
|
||||
<Dropdown
|
||||
<div className="awx-pagination" style={style}>
|
||||
{showPageSizeOptions && (
|
||||
<div className="awx-pagination__page-size-selection">
|
||||
{i18n._(t`Items Per Page`)}
|
||||
<Dropdown
|
||||
onToggle={this.onTogglePageSize}
|
||||
onSelect={this.onSelectPageSize}
|
||||
direction={up}
|
||||
isOpen={isOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
className="togglePageSize"
|
||||
onToggle={this.onTogglePageSize}
|
||||
onSelect={this.onSelectPageSize}
|
||||
direction={up}
|
||||
isOpen={isOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
className="togglePageSize"
|
||||
onToggle={this.onTogglePageSize}
|
||||
>
|
||||
{page_size}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={dropdownItems}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="awx-pagination__counts">
|
||||
<div className="awx-pagination__item-count">
|
||||
<Trans>{`Items ${itemMin} – ${itemMax} of ${count}`}</Trans>
|
||||
</div>
|
||||
{pageCount !== 1 && (
|
||||
<div className="awx-pagination__page-count">
|
||||
<div className="pf-c-input-group pf-m-previous">
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`First`)}
|
||||
isDisabled={isOnFirst}
|
||||
onClick={this.onFirst}
|
||||
>
|
||||
<i className="fas fa-angle-double-left" />
|
||||
</Button>
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Previous`)}
|
||||
isDisabled={isOnFirst}
|
||||
onClick={this.onPrevious}
|
||||
>
|
||||
<i className="fas fa-angle-left" />
|
||||
</Button>
|
||||
</div>
|
||||
<form
|
||||
className="awx-pagination__page-input-form"
|
||||
onSubmit={this.onSubmit}
|
||||
>
|
||||
<Trans>
|
||||
{'Page '}
|
||||
<TextInput
|
||||
className="awx-pagination__page-input"
|
||||
aria-label={i18n._(t`Page Number`)}
|
||||
value={value}
|
||||
type="text"
|
||||
onChange={this.onPageChange}
|
||||
/>
|
||||
{' of '}
|
||||
{pageCount}
|
||||
</Trans>
|
||||
</form>
|
||||
<div className="pf-c-input-group">
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Next`)}
|
||||
isDisabled={isOnLast}
|
||||
onClick={this.onNext}
|
||||
>
|
||||
<i className="fas fa-angle-right" />
|
||||
</Button>
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Last`)}
|
||||
isDisabled={isOnLast}
|
||||
onClick={this.onLast}
|
||||
>
|
||||
<i className="fas fa-angle-double-right" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
>
|
||||
{page_size}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
</div>
|
||||
dropdownItems={dropdownItems}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</I18n>
|
||||
<div className="awx-pagination__counts">
|
||||
<div className="awx-pagination__item-count">
|
||||
{i18n._(t`Items ${itemMin} – ${itemMax} of ${count}`)}
|
||||
</div>
|
||||
{pageCount !== 1 && (
|
||||
<div className="awx-pagination__page-count">
|
||||
<div className="pf-c-input-group pf-m-previous">
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`First`)}
|
||||
isDisabled={isOnFirst}
|
||||
onClick={this.onFirst}
|
||||
>
|
||||
<i className="fas fa-angle-double-left" />
|
||||
</Button>
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Previous`)}
|
||||
isDisabled={isOnFirst}
|
||||
onClick={this.onPrevious}
|
||||
>
|
||||
<i className="fas fa-angle-left" />
|
||||
</Button>
|
||||
</div>
|
||||
<form
|
||||
className="awx-pagination__page-input-form"
|
||||
onSubmit={this.onSubmit}
|
||||
>
|
||||
{i18n._(t`Page ${(<TextInput
|
||||
className="awx-pagination__page-input"
|
||||
aria-label={i18n._(t`Page Number`)}
|
||||
value={value}
|
||||
type="text"
|
||||
onChange={this.onPageChange}
|
||||
/>)} of ${pageCount}`)}
|
||||
</form>
|
||||
<div className="pf-c-input-group">
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Next`)}
|
||||
isDisabled={isOnLast}
|
||||
onClick={this.onNext}
|
||||
>
|
||||
<i className="fas fa-angle-right" />
|
||||
</Button>
|
||||
<Button
|
||||
className="awx-pagination__page-button"
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Last`)}
|
||||
isDisabled={isOnLast}
|
||||
onClick={this.onLast}
|
||||
>
|
||||
<i className="fas fa-angle-double-right" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -248,4 +240,4 @@ Pagination.defaultProps = {
|
||||
showPageSizeOptions: true
|
||||
};
|
||||
|
||||
export default Pagination;
|
||||
export default withI18n()(Pagination);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button as PFButton,
|
||||
@@ -90,7 +90,8 @@ class Search extends React.Component {
|
||||
render () {
|
||||
const { up } = DropdownPosition;
|
||||
const {
|
||||
columns
|
||||
columns,
|
||||
i18n
|
||||
} = this.props;
|
||||
const {
|
||||
isSearchDropdownOpen,
|
||||
@@ -109,41 +110,37 @@ class Search extends React.Component {
|
||||
));
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<div className="pf-c-input-group">
|
||||
<Dropdown
|
||||
<div className="pf-c-input-group">
|
||||
<Dropdown
|
||||
onToggle={this.handleDropdownToggle}
|
||||
onSelect={this.handleDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSearchDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
id="awx-search"
|
||||
onToggle={this.handleDropdownToggle}
|
||||
onSelect={this.handleDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSearchDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
id="awx-search"
|
||||
onToggle={this.handleDropdownToggle}
|
||||
>
|
||||
{searchColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={searchDropdownItems}
|
||||
/>
|
||||
<TextInput
|
||||
type="search"
|
||||
aria-label="Search text input"
|
||||
value={searchValue}
|
||||
onChange={this.handleSearchInputChange}
|
||||
style={{ height: '30px' }}
|
||||
/>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Search`)}
|
||||
onClick={this.handleSearch}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</I18n>
|
||||
{searchColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={searchDropdownItems}
|
||||
/>
|
||||
<TextInput
|
||||
type="search"
|
||||
aria-label={i18n._(t`Search text input`)}
|
||||
value={searchValue}
|
||||
onChange={this.handleSearchInputChange}
|
||||
style={{ height: '30px' }}
|
||||
/>
|
||||
<Button
|
||||
variant="tertiary"
|
||||
aria-label={i18n._(t`Search`)}
|
||||
onClick={this.handleSearch}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -159,4 +156,4 @@ Search.defaultProps = {
|
||||
sortedColumnKey: 'name'
|
||||
};
|
||||
|
||||
export default Search;
|
||||
export default withI18n()(Search);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Button,
|
||||
@@ -85,7 +85,8 @@ class Sort extends React.Component {
|
||||
const {
|
||||
columns,
|
||||
sortedColumnKey,
|
||||
sortOrder
|
||||
sortOrder,
|
||||
i18n
|
||||
} = this.props;
|
||||
const {
|
||||
isSortDropdownOpen
|
||||
@@ -109,40 +110,36 @@ class Sort extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<React.Fragment>
|
||||
{ sortDropdownItems.length > 1 && (
|
||||
<Dropdown
|
||||
style={{ marginRight: '20px' }}
|
||||
<React.Fragment>
|
||||
{ sortDropdownItems.length > 1 && (
|
||||
<Dropdown
|
||||
style={{ marginRight: '20px' }}
|
||||
onToggle={this.handleDropdownToggle}
|
||||
onSelect={this.handleDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSortDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
id="awx-sort"
|
||||
onToggle={this.handleDropdownToggle}
|
||||
onSelect={this.handleDropdownSelect}
|
||||
direction={up}
|
||||
isOpen={isSortDropdownOpen}
|
||||
toggle={(
|
||||
<DropdownToggle
|
||||
id="awx-sort"
|
||||
onToggle={this.handleDropdownToggle}
|
||||
>
|
||||
{sortedColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
dropdownItems={sortDropdownItems}
|
||||
/>
|
||||
>
|
||||
{sortedColumnName}
|
||||
</DropdownToggle>
|
||||
)}
|
||||
<Button
|
||||
onClick={this.handleSort}
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Sort`)}
|
||||
css="padding: 0;"
|
||||
>
|
||||
<IconWrapper>
|
||||
<SortIcon />
|
||||
</IconWrapper>
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
dropdownItems={sortDropdownItems}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
<Button
|
||||
onClick={this.handleSort}
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Sort`)}
|
||||
css="padding: 0;"
|
||||
>
|
||||
<IconWrapper>
|
||||
<SortIcon />
|
||||
</IconWrapper>
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -160,4 +157,4 @@ Sort.defaultProps = {
|
||||
sortedColumnKey: 'name'
|
||||
};
|
||||
|
||||
export default Sort;
|
||||
export default withI18n()(Sort);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Brand } from '@patternfly/react-core';
|
||||
|
||||
@@ -34,6 +34,7 @@ class TowerLogo extends Component {
|
||||
|
||||
render () {
|
||||
const { hover } = this.state;
|
||||
const { i18n } = this.props;
|
||||
|
||||
let src = TowerLogoHeader;
|
||||
|
||||
@@ -42,19 +43,15 @@ class TowerLogo extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Brand
|
||||
src={src}
|
||||
alt={i18n._(t`Tower Brand Image`)}
|
||||
onMouseOut={this.onHover}
|
||||
onMouseOver={this.onHover}
|
||||
onBlur={this.onHover}
|
||||
onFocus={this.onHover}
|
||||
onClick={this.onClick}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
<Brand
|
||||
src={src}
|
||||
alt={i18n._(t`Tower Brand Image`)}
|
||||
onMouseOut={this.onHover}
|
||||
onMouseOver={this.onHover}
|
||||
onBlur={this.onHover}
|
||||
onFocus={this.onHover}
|
||||
onClick={this.onClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -67,4 +64,4 @@ TowerLogo.defaultProps = {
|
||||
linkTo: null,
|
||||
};
|
||||
|
||||
export default withRouter(TowerLogo);
|
||||
export default withI18n()(withRouter(TowerLogo));
|
||||
|
||||
@@ -4,7 +4,8 @@ import React, { Component } from 'react';
|
||||
|
||||
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';
|
||||
|
||||
@@ -33,27 +34,27 @@ class Provider extends Component {
|
||||
}
|
||||
|
||||
handle401 () {
|
||||
const { handle401, history, setRootDialogMessage } = this.props;
|
||||
const { handle401, history, setRootDialogMessage, i18n } = this.props;
|
||||
if (handle401) {
|
||||
handle401();
|
||||
return;
|
||||
}
|
||||
history.replace('/login');
|
||||
setRootDialogMessage({
|
||||
bodyText: i18nMark('You have been logged out.')
|
||||
bodyText: i18n._(t`You have been logged out.`)
|
||||
});
|
||||
}
|
||||
|
||||
handle404 () {
|
||||
const { handle404, history, setRootDialogMessage } = this.props;
|
||||
const { handle404, history, setRootDialogMessage, i18n } = this.props;
|
||||
if (handle404) {
|
||||
handle404();
|
||||
return;
|
||||
}
|
||||
history.replace('/home');
|
||||
setRootDialogMessage({
|
||||
title: i18nMark('404'),
|
||||
bodyText: i18nMark('Cannot find resource.'),
|
||||
title: i18n._(t`404`),
|
||||
bodyText: i18n._(t`Cannot find resource.`),
|
||||
variant: 'warning'
|
||||
});
|
||||
}
|
||||
@@ -72,7 +73,7 @@ class Provider extends Component {
|
||||
}
|
||||
|
||||
export { Provider as _NetworkProvider };
|
||||
export const NetworkProvider = withRootDialog(withRouter(Provider));
|
||||
export const NetworkProvider = withI18n()(withRootDialog(withRouter(Provider)));
|
||||
|
||||
export function withNetwork (Child) {
|
||||
return (props) => (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Applications extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Applications</Trans>
|
||||
{i18n._(t`Applications`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Applications extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Applications;
|
||||
export default withI18n()(Applications);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class AuthSettings extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Authentication Settings</Trans>
|
||||
{i18n._(t`Authentication Settings`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class AuthSettings extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthSettings;
|
||||
export default withI18n()(AuthSettings);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class CredentialTypes extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Credential Types</Trans>
|
||||
{i18n._(t`Credential Types`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class CredentialTypes extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default CredentialTypes;
|
||||
export default withI18n()(CredentialTypes);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Credentials extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Credentials</Trans>
|
||||
{i18n._(t`Credentials`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Credentials extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Credentials;
|
||||
export default withI18n()(Credentials);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Dashboard extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Dashboard</Trans>
|
||||
{i18n._(t`Dashboard`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Dashboard extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Dashboard;
|
||||
export default withI18n()(Dashboard);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class InstanceGroups extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Instance Groups</Trans>
|
||||
{i18n._(t`Instance Groups`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class InstanceGroups extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default InstanceGroups;
|
||||
export default withI18n()(InstanceGroups);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Inventories extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Inventories</Trans>
|
||||
{i18n._(t`Inventories`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Inventories extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Inventories;
|
||||
export default withI18n()(Inventories);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class InventoryScripts extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Inventory Scripts</Trans>
|
||||
{i18n._(t`Inventory Scripts`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class InventoryScripts extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default InventoryScripts;
|
||||
export default withI18n()(InventoryScripts);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Jobs extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Jobs</Trans>
|
||||
{i18n._(t`Jobs`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Jobs extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Jobs;
|
||||
export default withI18n()(Jobs);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class JobsSettings extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Jobs Settings</Trans>
|
||||
{i18n._(t`Jobs Settings`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class JobsSettings extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default JobsSettings;
|
||||
export default withI18n()(JobsSettings);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class License extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>License</Trans>
|
||||
{i18n._(t`License`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class License extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default License;
|
||||
export default withI18n()(License);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect, withRouter } from 'react-router-dom';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
LoginForm,
|
||||
@@ -62,7 +62,7 @@ class AWXLogin extends Component {
|
||||
|
||||
render () {
|
||||
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;
|
||||
|
||||
if (isAuthenticated) {
|
||||
@@ -70,34 +70,30 @@ class AWXLogin extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<LoginPage
|
||||
brandImgSrc={logoSrc}
|
||||
brandImgAlt={alt || 'Ansible Tower'}
|
||||
loginTitle={i18n._(t`Welcome to Ansible Tower! Please Sign In.`)}
|
||||
textContent={loginInfo}
|
||||
>
|
||||
<LoginForm
|
||||
className={errorMessage && 'pf-m-error'}
|
||||
usernameLabel={i18n._(t`Username`)}
|
||||
passwordLabel={i18n._(t`Password`)}
|
||||
showHelperText={!isInputValid || !!errorMessage}
|
||||
helperText={errorMessage || i18n._(t`Invalid username or password. Please try again.`)}
|
||||
usernameValue={username}
|
||||
passwordValue={password}
|
||||
isValidUsername={isInputValid}
|
||||
isValidPassword={isInputValid}
|
||||
onChangeUsername={this.onChangeUsername}
|
||||
onChangePassword={this.onChangePassword}
|
||||
onLoginButtonClick={this.onLoginButtonClick}
|
||||
/>
|
||||
</LoginPage>
|
||||
)}
|
||||
</I18n>
|
||||
<LoginPage
|
||||
brandImgSrc={logoSrc}
|
||||
brandImgAlt={alt || 'Ansible Tower'}
|
||||
loginTitle={i18n._(t`Welcome to Ansible Tower! Please Sign In.`)}
|
||||
textContent={loginInfo}
|
||||
>
|
||||
<LoginForm
|
||||
className={errorMessage && 'pf-m-error'}
|
||||
usernameLabel={i18n._(t`Username`)}
|
||||
passwordLabel={i18n._(t`Password`)}
|
||||
showHelperText={!isInputValid || !!errorMessage}
|
||||
helperText={errorMessage || i18n._(t`Invalid username or password. Please try again.`)}
|
||||
usernameValue={username}
|
||||
passwordValue={password}
|
||||
isValidUsername={isInputValid}
|
||||
isValidPassword={isInputValid}
|
||||
onChangeUsername={this.onChangeUsername}
|
||||
onChangePassword={this.onChangePassword}
|
||||
onLoginButtonClick={this.onLoginButtonClick}
|
||||
/>
|
||||
</LoginPage>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { AWXLogin as _AWXLogin };
|
||||
export default withNetwork(withRootDialog(withRouter(AWXLogin)));
|
||||
export default withI18n()(withNetwork(withRootDialog(withRouter(AWXLogin))));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class ManagementJobs extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Management Jobs</Trans>
|
||||
{i18n._(t`Management Jobs`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class ManagementJobs extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default ManagementJobs;
|
||||
export default withI18n()(ManagementJobs);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class NotificationTemplates extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Notification Templates</Trans>
|
||||
{i18n._(t`Notification Templates`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class NotificationTemplates extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default NotificationTemplates;
|
||||
export default withI18n()(NotificationTemplates);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Route, withRouter, Switch } from 'react-router-dom';
|
||||
import { i18nMark } from '@lingui/react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { Config } from '../../contexts/Config';
|
||||
import { NetworkProvider } from '../../contexts/Network';
|
||||
@@ -14,34 +14,42 @@ import OrganizationAdd from './screens/OrganizationAdd';
|
||||
import Organization from './screens/Organization/Organization';
|
||||
|
||||
class Organizations extends Component {
|
||||
state = {
|
||||
breadcrumbConfig: {
|
||||
'/organizations': i18nMark('Organizations'),
|
||||
'/organizations/add': i18nMark('Create New Organization')
|
||||
}
|
||||
};
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
const { i18n } = props;
|
||||
|
||||
this.state = {
|
||||
breadcrumbConfig: {
|
||||
'/organizations': i18n._(t`Organizations`),
|
||||
'/organizations/add': i18n._(t`Create New Organization`)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
setBreadcrumbConfig = (organization) => {
|
||||
const { i18n } = this.props;
|
||||
|
||||
if (!organization) {
|
||||
return;
|
||||
}
|
||||
|
||||
const breadcrumbConfig = {
|
||||
'/organizations': i18nMark('Organizations'),
|
||||
'/organizations/add': i18nMark('Create New Organization'),
|
||||
'/organizations': i18n._(t`Organizations`),
|
||||
'/organizations/add': i18n._(t`Create New Organization`),
|
||||
[`/organizations/${organization.id}`]: `${organization.name}`,
|
||||
[`/organizations/${organization.id}/edit`]: i18nMark('Edit Details'),
|
||||
[`/organizations/${organization.id}/details`]: i18nMark('Details'),
|
||||
[`/organizations/${organization.id}/access`]: i18nMark('Access'),
|
||||
[`/organizations/${organization.id}/teams`]: i18nMark('Teams'),
|
||||
[`/organizations/${organization.id}/notifications`]: i18nMark('Notifications'),
|
||||
[`/organizations/${organization.id}/edit`]: i18n._(t`Edit Details`),
|
||||
[`/organizations/${organization.id}/details`]: i18n._(t`Details`),
|
||||
[`/organizations/${organization.id}/access`]: i18n._(t`Access`),
|
||||
[`/organizations/${organization.id}/teams`]: i18n._(t`Teams`),
|
||||
[`/organizations/${organization.id}/notifications`]: i18n._(t`Notifications`),
|
||||
};
|
||||
|
||||
this.setState({ breadcrumbConfig });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { match, history, location, setRootDialogMessage } = this.props;
|
||||
const { match, history, location, setRootDialogMessage, i18n } = this.props;
|
||||
const { breadcrumbConfig } = this.state;
|
||||
|
||||
return (
|
||||
@@ -65,11 +73,11 @@ class Organizations extends Component {
|
||||
setRootDialogMessage({
|
||||
title: '404',
|
||||
bodyText: (
|
||||
<Trans>
|
||||
Cannot find organization with ID
|
||||
<Fragment>
|
||||
{i18n._(t`Cannot find organization with ID`)}
|
||||
<strong>{` ${newRouteMatch.params.id}`}</strong>
|
||||
.
|
||||
</Trans>
|
||||
</Fragment>
|
||||
),
|
||||
variant: 'warning'
|
||||
});
|
||||
@@ -101,4 +109,4 @@ class Organizations extends Component {
|
||||
}
|
||||
|
||||
export { Organizations as _Organizations };
|
||||
export default withRootDialog(withRouter(Organizations));
|
||||
export default withI18n()(withRootDialog(withRouter(Organizations)));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import { func, string } from 'prop-types';
|
||||
import { Button } from '@patternfly/react-core';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { t, Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import AlertModal from '../../../components/AlertModal';
|
||||
import { Role } from '../../../types';
|
||||
|
||||
@@ -24,57 +24,43 @@ class DeleteRoleConfirmationModal extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { role, username, onCancel, onConfirm } = this.props;
|
||||
const title = `Remove ${this.isTeamRole() ? 'Team' : 'User'} Access`;
|
||||
const { role, username, onCancel, onConfirm, i18n } = this.props;
|
||||
const title = i18n._(t`Remove ${this.isTeamRole() ? i18n._(t`Team`) : i18n._(t`User`)} Access`);
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<AlertModal
|
||||
<AlertModal
|
||||
variant="danger"
|
||||
title={title}
|
||||
isOpen
|
||||
onClose={onCancel}
|
||||
actions={[
|
||||
<Button
|
||||
key="delete"
|
||||
variant="danger"
|
||||
title={i18nMark(title)}
|
||||
isOpen
|
||||
onClose={onCancel}
|
||||
actions={[
|
||||
<Button
|
||||
key="delete"
|
||||
variant="danger"
|
||||
aria-label="Confirm delete"
|
||||
onClick={onConfirm}
|
||||
>
|
||||
{i18n._(t`Delete`)}
|
||||
</Button>,
|
||||
<Button key="cancel" variant="secondary" onClick={onCancel}>
|
||||
{i18n._(t`Cancel`)}
|
||||
</Button>
|
||||
]}
|
||||
aria-label="Confirm delete"
|
||||
onClick={onConfirm}
|
||||
>
|
||||
{this.isTeamRole() ? (
|
||||
<Trans>
|
||||
Are you sure you want to remove
|
||||
<b>{` ${role.name} `}</b>
|
||||
access from
|
||||
<b>{` ${role.team_name}`}</b>
|
||||
? Doing so affects all members of the team.
|
||||
<br />
|
||||
<br />
|
||||
If you
|
||||
<b><i> only </i></b>
|
||||
want to remove access for this particular user, please remove them from the team.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
Are you sure you want to remove
|
||||
<b>{` ${role.name} `}</b>
|
||||
access from
|
||||
<b>{` ${username}`}</b>
|
||||
?
|
||||
</Trans>
|
||||
)}
|
||||
</AlertModal>
|
||||
{i18n._(t`Delete`)}
|
||||
</Button>,
|
||||
<Button key="cancel" variant="secondary" onClick={onCancel}>
|
||||
{i18n._(t`Cancel`)}
|
||||
</Button>
|
||||
]}
|
||||
>
|
||||
{this.isTeamRole() ? (
|
||||
<Fragment>
|
||||
{i18n._(t`Are you sure you want to remove ${role.name} access from ${role.team_name}? Doing so affects all members of the team.`)}
|
||||
<br />
|
||||
<br />
|
||||
{i18n._(t`If you ${(<b><i>only</i></b>)} want to remove access for this particular user, please remove them from the team.`)}
|
||||
</Fragment>
|
||||
) : (
|
||||
<Fragment>
|
||||
{i18n._(t`Are you sure you want to remove ${role.name} access from ${username}?`)}
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
</AlertModal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DeleteRoleConfirmationModal;
|
||||
export default withI18n()(DeleteRoleConfirmationModal);
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import React, { Fragment } from 'react';
|
||||
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 { QuestionCircleIcon } from '@patternfly/react-icons';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import Lookup from '../../../components/Lookup';
|
||||
|
||||
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 {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
@@ -29,43 +23,43 @@ class InstanceGroupsLookup extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { value, tooltip, onChange } = this.props;
|
||||
const { value, tooltip, onChange, i18n } = this.props;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<FormGroup
|
||||
label={(
|
||||
<Fragment>
|
||||
{i18n._(t`Instance Groups`)}
|
||||
{' '}
|
||||
{
|
||||
tooltip && (
|
||||
<Tooltip
|
||||
position="right"
|
||||
content={tooltip}
|
||||
>
|
||||
<QuestionCircleIcon />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</Fragment>
|
||||
)}
|
||||
fieldId="org-instance-groups"
|
||||
>
|
||||
<Lookup
|
||||
id="org-instance-groups"
|
||||
lookupHeader={i18n._(t`Instance Groups`)}
|
||||
name="instanceGroups"
|
||||
value={value}
|
||||
onLookupSave={onChange}
|
||||
getItems={this.getInstanceGroups}
|
||||
columns={INSTANCE_GROUPS_LOOKUP_COLUMNS}
|
||||
sortedColumnKey="name"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={(
|
||||
<Fragment>
|
||||
{i18n._(t`Instance Groups`)}
|
||||
{' '}
|
||||
{
|
||||
tooltip && (
|
||||
<Tooltip
|
||||
position="right"
|
||||
content={tooltip}
|
||||
>
|
||||
<QuestionCircleIcon />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
fieldId="org-instance-groups"
|
||||
>
|
||||
<Lookup
|
||||
id="org-instance-groups"
|
||||
lookupHeader={i18n._(t`Instance Groups`)}
|
||||
name="instanceGroups"
|
||||
value={value}
|
||||
onLookupSave={onChange}
|
||||
getItems={this.getInstanceGroups}
|
||||
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"
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -80,4 +74,4 @@ InstanceGroupsLookup.defaultProps = {
|
||||
tooltip: '',
|
||||
};
|
||||
|
||||
export default withNetwork(InstanceGroupsLookup);
|
||||
export default withI18n()(withNetwork(InstanceGroupsLookup));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { func } from 'prop-types';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
DataListItem,
|
||||
@@ -81,96 +81,92 @@ class OrganizationAccessItem extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { accessRecord, onRoleDelete } = this.props;
|
||||
const { accessRecord, onRoleDelete, i18n } = this.props;
|
||||
const [teamRoles, userRoles] = this.getRoleLists();
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<DataListItem aria-labelledby="access-list-item" key={accessRecord.id}>
|
||||
<DataListItemRow>
|
||||
<DataListItemCells dataListCells={[
|
||||
<DataListCell key="name">
|
||||
{accessRecord.username && (
|
||||
<TextContent style={detailWrapperStyle}>
|
||||
{accessRecord.url ? (
|
||||
<Link to={{ pathname: accessRecord.url }}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{accessRecord.username}
|
||||
</Text>
|
||||
</Link>
|
||||
) : (
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{accessRecord.username}
|
||||
</Text>
|
||||
)}
|
||||
</TextContent>
|
||||
)}
|
||||
{accessRecord.first_name || accessRecord.last_name ? (
|
||||
<Detail
|
||||
label={i18n._(t`Name`)}
|
||||
value={`${accessRecord.first_name} ${accessRecord.last_name}`}
|
||||
url={null}
|
||||
customStyles={null}
|
||||
/>
|
||||
<DataListItem aria-labelledby="access-list-item" key={accessRecord.id}>
|
||||
<DataListItemRow>
|
||||
<DataListItemCells dataListCells={[
|
||||
<DataListCell key="name">
|
||||
{accessRecord.username && (
|
||||
<TextContent style={detailWrapperStyle}>
|
||||
{accessRecord.url ? (
|
||||
<Link to={{ pathname: accessRecord.url }}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{accessRecord.username}
|
||||
</Text>
|
||||
</Link>
|
||||
) : (
|
||||
null
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{accessRecord.username}
|
||||
</Text>
|
||||
)}
|
||||
</DataListCell>,
|
||||
<DataListCell key="roles">
|
||||
{userRoles.length > 0 && (
|
||||
<ul style={userRolesWrapperStyle}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{i18n._(t`User Roles`)}
|
||||
</Text>
|
||||
{userRoles.map(role => (
|
||||
role.user_capabilities.unattach ? (
|
||||
<Chip
|
||||
key={role.id}
|
||||
className="awx-c-chip"
|
||||
onClick={() => { onRoleDelete(role, accessRecord); }}
|
||||
>
|
||||
{role.name}
|
||||
</Chip>
|
||||
) : (
|
||||
<BasicChip key={role.id}>
|
||||
{role.name}
|
||||
</BasicChip>
|
||||
)
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
{teamRoles.length > 0 && (
|
||||
<ul style={userRolesWrapperStyle}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{i18n._(t`Team Roles`)}
|
||||
</Text>
|
||||
{teamRoles.map(role => (
|
||||
role.user_capabilities.unattach ? (
|
||||
<Chip
|
||||
key={role.id}
|
||||
className="awx-c-chip"
|
||||
onClick={() => { onRoleDelete(role, accessRecord); }}
|
||||
>
|
||||
{role.name}
|
||||
</Chip>
|
||||
) : (
|
||||
<BasicChip key={role.id}>
|
||||
{role.name}
|
||||
</BasicChip>
|
||||
)
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</DataListCell>
|
||||
]}
|
||||
/>
|
||||
</DataListItemRow>
|
||||
</DataListItem>
|
||||
)}
|
||||
</I18n>
|
||||
</TextContent>
|
||||
)}
|
||||
{accessRecord.first_name || accessRecord.last_name ? (
|
||||
<Detail
|
||||
label={i18n._(t`Name`)}
|
||||
value={`${accessRecord.first_name} ${accessRecord.last_name}`}
|
||||
url={null}
|
||||
customStyles={null}
|
||||
/>
|
||||
) : (
|
||||
null
|
||||
)}
|
||||
</DataListCell>,
|
||||
<DataListCell key="roles">
|
||||
{userRoles.length > 0 && (
|
||||
<ul style={userRolesWrapperStyle}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{i18n._(t`User Roles`)}
|
||||
</Text>
|
||||
{userRoles.map(role => (
|
||||
role.user_capabilities.unattach ? (
|
||||
<Chip
|
||||
key={role.id}
|
||||
className="awx-c-chip"
|
||||
onClick={() => { onRoleDelete(role, accessRecord); }}
|
||||
>
|
||||
{role.name}
|
||||
</Chip>
|
||||
) : (
|
||||
<BasicChip key={role.id}>
|
||||
{role.name}
|
||||
</BasicChip>
|
||||
)
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
{teamRoles.length > 0 && (
|
||||
<ul style={userRolesWrapperStyle}>
|
||||
<Text component={TextVariants.h6} style={detailLabelStyle}>
|
||||
{i18n._(t`Team Roles`)}
|
||||
</Text>
|
||||
{teamRoles.map(role => (
|
||||
role.user_capabilities.unattach ? (
|
||||
<Chip
|
||||
key={role.id}
|
||||
className="awx-c-chip"
|
||||
onClick={() => { onRoleDelete(role, accessRecord); }}
|
||||
>
|
||||
{role.name}
|
||||
</Chip>
|
||||
) : (
|
||||
<BasicChip key={role.id}>
|
||||
{role.name}
|
||||
</BasicChip>
|
||||
)
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</DataListCell>
|
||||
]}
|
||||
/>
|
||||
</DataListItemRow>
|
||||
</DataListItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrganizationAccessItem;
|
||||
export default withI18n()(OrganizationAccessItem);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { Formik, Field } from 'formik';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Form,
|
||||
@@ -83,76 +83,72 @@ class OrganizationForm extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { organization, handleCancel } = this.props;
|
||||
const { organization, handleCancel, i18n } = this.props;
|
||||
const { instanceGroups, formIsValid, error } = this.state;
|
||||
const defaultVenv = '/venv/ansible/';
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Formik
|
||||
initialValues={{
|
||||
name: organization.name,
|
||||
description: organization.description,
|
||||
custom_virtualenv: organization.custom_virtualenv || '',
|
||||
}}
|
||||
onSubmit={this.handleSubmit}
|
||||
render={formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
id="org-name"
|
||||
name="name"
|
||||
type="text"
|
||||
label={i18n._(t`Name`)}
|
||||
validate={required()}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="org-description"
|
||||
name="description"
|
||||
type="text"
|
||||
label={i18n._(t`Description`)}
|
||||
/>
|
||||
<Config>
|
||||
{({ custom_virtualenvs }) => (
|
||||
custom_virtualenvs && custom_virtualenvs.length > 1 && (
|
||||
<Field
|
||||
name="custom_virtualenv"
|
||||
render={({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="org-custom-virtualenv"
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
>
|
||||
<AnsibleSelect
|
||||
data={custom_virtualenvs}
|
||||
defaultSelected={defaultVenv}
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Config>
|
||||
</FormRow>
|
||||
<InstanceGroupsLookup
|
||||
value={instanceGroups}
|
||||
onChange={this.handleInstanceGroupsChange}
|
||||
tooltip={i18n._(t`Select the Instance Groups for this Organization to run on.`)}
|
||||
/>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
submitDisabled={!formIsValid}
|
||||
/>
|
||||
{error ? <div>error</div> : null}
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
<Formik
|
||||
initialValues={{
|
||||
name: organization.name,
|
||||
description: organization.description,
|
||||
custom_virtualenv: organization.custom_virtualenv || '',
|
||||
}}
|
||||
onSubmit={this.handleSubmit}
|
||||
render={formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
id="org-name"
|
||||
name="name"
|
||||
type="text"
|
||||
label={i18n._(t`Name`)}
|
||||
validate={required(null, i18n)}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="org-description"
|
||||
name="description"
|
||||
type="text"
|
||||
label={i18n._(t`Description`)}
|
||||
/>
|
||||
<Config>
|
||||
{({ custom_virtualenvs }) => (
|
||||
custom_virtualenvs && custom_virtualenvs.length > 1 && (
|
||||
<Field
|
||||
name="custom_virtualenv"
|
||||
render={({ field }) => (
|
||||
<FormGroup
|
||||
fieldId="org-custom-virtualenv"
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
>
|
||||
<AnsibleSelect
|
||||
data={custom_virtualenvs}
|
||||
defaultSelected={defaultVenv}
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Config>
|
||||
</FormRow>
|
||||
<InstanceGroupsLookup
|
||||
value={instanceGroups}
|
||||
onChange={this.handleInstanceGroupsChange}
|
||||
tooltip={i18n._(t`Select the Instance Groups for this Organization to run on.`)}
|
||||
/>
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
submitDisabled={!formIsValid}
|
||||
/>
|
||||
{error ? <div>error</div> : null}
|
||||
</Form>
|
||||
)}
|
||||
</I18n>
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -176,4 +172,4 @@ OrganizationForm.contextTypes = {
|
||||
};
|
||||
|
||||
export { OrganizationForm as _OrganizationForm };
|
||||
export default withNetwork(withRouter(OrganizationForm));
|
||||
export default withI18n()(withNetwork(withRouter(OrganizationForm)));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { string, bool, func } from 'prop-types';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Badge as PFBadge,
|
||||
DataListItem,
|
||||
@@ -62,6 +63,7 @@ class OrganizationListItem extends React.Component {
|
||||
isSelected,
|
||||
onSelect,
|
||||
detailUrl,
|
||||
i18n
|
||||
} = this.props;
|
||||
const labelId = `check-action-${organization.id}`;
|
||||
return (
|
||||
@@ -86,13 +88,15 @@ class OrganizationListItem extends React.Component {
|
||||
</DataListCell>,
|
||||
<DataListCell key="org-members" righthalf="true" width={2}>
|
||||
<ListGroup>
|
||||
<Trans>Members</Trans>
|
||||
{i18n._(t`Members`)}
|
||||
<Badge isRead>
|
||||
{organization.summary_fields.related_field_counts.users}
|
||||
</Badge>
|
||||
</ListGroup>
|
||||
</DataListCell>,
|
||||
<DataListCell>
|
||||
<ListGroup>
|
||||
<Trans>Teams</Trans>
|
||||
{i18n._(t`Teams`)}
|
||||
<Badge isRead>
|
||||
{organization.summary_fields.related_field_counts.teams}
|
||||
</Badge>
|
||||
@@ -105,4 +109,4 @@ class OrganizationListItem extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
export default OrganizationListItem;
|
||||
export default withI18n()(OrganizationListItem);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { I18n, i18nMark } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Switch, Route, withRouter, Redirect } from 'react-router-dom';
|
||||
import { Card, CardHeader, PageSection } from '@patternfly/react-core';
|
||||
@@ -100,7 +100,8 @@ class Organization extends Component {
|
||||
location,
|
||||
match,
|
||||
me,
|
||||
history
|
||||
history,
|
||||
i18n
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@@ -126,14 +127,14 @@ class Organization extends Component {
|
||||
);
|
||||
|
||||
const tabsArray = [
|
||||
{ name: i18nMark('Details'), link: `${match.url}/details`, id: 0 },
|
||||
{ name: i18nMark('Access'), link: `${match.url}/access`, id: 1 },
|
||||
{ name: i18nMark('Teams'), link: `${match.url}/teams`, id: 2 }
|
||||
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
|
||||
{ name: i18n._(t`Access`), link: `${match.url}/access`, id: 1 },
|
||||
{ name: i18n._(t`Teams`), link: `${match.url}/teams`, id: 2 }
|
||||
];
|
||||
|
||||
if (canSeeNotificationsTab) {
|
||||
tabsArray.push({
|
||||
name: i18nMark('Notifications'),
|
||||
name: i18n._(t`Notifications`),
|
||||
link: `${match.url}/notifications`,
|
||||
id: 3
|
||||
});
|
||||
@@ -145,24 +146,18 @@ class Organization extends Component {
|
||||
<CardHeader
|
||||
style={tabsStyle}
|
||||
>
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<React.Fragment>
|
||||
<div className="awx-orgTabs-container">
|
||||
<RoutedTabs
|
||||
match={match}
|
||||
history={history}
|
||||
labeltext={i18n._(t`Organization detail tabs`)}
|
||||
tabsArray={tabsArray}
|
||||
/>
|
||||
<CardCloseButton linkTo="/organizations" />
|
||||
<div
|
||||
className="awx-orgTabs__bottom-border"
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</I18n>
|
||||
<div className="awx-orgTabs-container">
|
||||
<RoutedTabs
|
||||
match={match}
|
||||
history={history}
|
||||
labeltext={i18n._(t`Organization detail tabs`)}
|
||||
tabsArray={tabsArray}
|
||||
/>
|
||||
<CardCloseButton linkTo="/organizations" />
|
||||
<div
|
||||
className="awx-orgTabs__bottom-border"
|
||||
/>
|
||||
</div>
|
||||
</CardHeader>
|
||||
));
|
||||
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 };
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Fragment } from 'react';
|
||||
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 OrganizationAccessItem from '../../components/OrganizationAccessItem';
|
||||
import DeleteRoleConfirmationModal from '../../components/DeleteRoleConfirmationModal';
|
||||
@@ -130,7 +131,7 @@ class OrganizationAccess extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { api, organization } = this.props;
|
||||
const { api, organization, i18n } = this.props;
|
||||
const {
|
||||
isLoading,
|
||||
isInitialized,
|
||||
@@ -167,9 +168,9 @@ class OrganizationAccess extends React.Component {
|
||||
itemName="role"
|
||||
qsConfig={QS_CONFIG}
|
||||
toolbarColumns={[
|
||||
{ name: i18nMark('Name'), key: 'first_name', isSortable: true },
|
||||
{ name: i18nMark('Username'), key: 'username', isSortable: true },
|
||||
{ name: i18nMark('Last Name'), key: 'last_name', isSortable: true },
|
||||
{ name: i18n._(t`Name`), key: 'first_name', isSortable: true },
|
||||
{ name: i18n._(t`Username`), key: 'username', isSortable: true },
|
||||
{ name: i18n._(t`Last Name`), key: 'last_name', isSortable: true },
|
||||
]}
|
||||
additionalControls={canEdit ? [
|
||||
<ToolbarAddButton key="add" onClick={this.toggleAddModal} />
|
||||
@@ -197,4 +198,4 @@ class OrganizationAccess extends React.Component {
|
||||
}
|
||||
|
||||
export { OrganizationAccess as _OrganizationAccess };
|
||||
export default withNetwork(withRouter(OrganizationAccess));
|
||||
export default withI18n()(withNetwork(withRouter(OrganizationAccess)));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link, withRouter } from 'react-router-dom';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import {
|
||||
CardBody,
|
||||
@@ -103,7 +103,8 @@ class OrganizationDetail extends Component {
|
||||
modified,
|
||||
summary_fields
|
||||
},
|
||||
match
|
||||
match,
|
||||
i18n
|
||||
} = this.props;
|
||||
const showOverflowChipAfter = 5;
|
||||
|
||||
@@ -127,58 +128,54 @@ class OrganizationDetail extends Component {
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<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">
|
||||
<Detail
|
||||
label={i18n._(t`Name`)}
|
||||
value={name}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Description`)}
|
||||
value={description}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
value={custom_virtualenv}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Created`)}
|
||||
value={created}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Last Modified`)}
|
||||
value={modified}
|
||||
/>
|
||||
{(instanceGroups && instanceGroups.length > 0) && (
|
||||
<TextContent style={{ display: 'flex', gridColumn: '1 / -1' }}>
|
||||
<Text
|
||||
component={TextVariants.h6}
|
||||
style={detailLabelStyle}
|
||||
>
|
||||
<Trans>Instance Groups</Trans>
|
||||
</Text>
|
||||
<div style={detailValueStyle}>
|
||||
{instanceGroupChips}
|
||||
{overflowChip}
|
||||
</div>
|
||||
</TextContent>
|
||||
)}
|
||||
</div>
|
||||
{summary_fields.user_capabilities.edit && (
|
||||
<div style={{ display: 'flex', flexDirection: 'row-reverse', marginTop: '20px' }}>
|
||||
<Link to={`/organizations/${match.params.id}/edit`}>
|
||||
<Button><Trans>Edit</Trans></Button>
|
||||
</Link>
|
||||
<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">
|
||||
<Detail
|
||||
label={i18n._(t`Name`)}
|
||||
value={name}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Description`)}
|
||||
value={description}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
value={custom_virtualenv}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Created`)}
|
||||
value={created}
|
||||
/>
|
||||
<Detail
|
||||
label={i18n._(t`Last Modified`)}
|
||||
value={modified}
|
||||
/>
|
||||
{(instanceGroups && instanceGroups.length > 0) && (
|
||||
<TextContent style={{ display: 'flex', gridColumn: '1 / -1' }}>
|
||||
<Text
|
||||
component={TextVariants.h6}
|
||||
style={detailLabelStyle}
|
||||
>
|
||||
{i18n._(t`Instance Groups`)}
|
||||
</Text>
|
||||
<div style={detailValueStyle}>
|
||||
{instanceGroupChips}
|
||||
{overflowChip}
|
||||
</div>
|
||||
)}
|
||||
{error ? 'error!' : ''}
|
||||
</CardBody>
|
||||
</TextContent>
|
||||
)}
|
||||
</div>
|
||||
{summary_fields.user_capabilities.edit && (
|
||||
<div style={{ display: 'flex', flexDirection: 'row-reverse', marginTop: '20px' }}>
|
||||
<Link to={`/organizations/${match.params.id}/edit`}>
|
||||
<Button>{i18n._(t`Edit`)}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</I18n>
|
||||
{error ? 'error!' : ''}
|
||||
</CardBody>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(withNetwork(OrganizationDetail));
|
||||
export default withI18n()(withRouter(withNetwork(OrganizationDetail)));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
@@ -57,30 +57,27 @@ class OrganizationAdd extends React.Component {
|
||||
|
||||
render () {
|
||||
const { error } = this.state;
|
||||
const { i18n } = this.props;
|
||||
|
||||
return (
|
||||
<PageSection>
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Card>
|
||||
<CardHeader className="at-u-textRight">
|
||||
<Tooltip
|
||||
content={i18n._(t`Close`)}
|
||||
position="top"
|
||||
>
|
||||
<CardCloseButton onClick={this.handleCancel} />
|
||||
</Tooltip>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<OrganizationForm
|
||||
handleSubmit={this.handleSubmit}
|
||||
handleCancel={this.handleCancel}
|
||||
/>
|
||||
{error ? <div>error</div> : ''}
|
||||
</CardBody>
|
||||
</Card>
|
||||
)}
|
||||
</I18n>
|
||||
<Card>
|
||||
<CardHeader className="at-u-textRight">
|
||||
<Tooltip
|
||||
content={i18n._(t`Close`)}
|
||||
position="top"
|
||||
>
|
||||
<CardCloseButton onClick={this.handleCancel} />
|
||||
</Tooltip>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<OrganizationForm
|
||||
handleSubmit={this.handleSubmit}
|
||||
handleCancel={this.handleCancel}
|
||||
/>
|
||||
{error ? <div>error</div> : ''}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</PageSection>
|
||||
);
|
||||
}
|
||||
@@ -95,4 +92,4 @@ OrganizationAdd.contextTypes = {
|
||||
};
|
||||
|
||||
export { OrganizationAdd as _OrganizationAdd };
|
||||
export default withNetwork(withRouter(OrganizationAdd));
|
||||
export default withI18n()(withNetwork(withRouter(OrganizationAdd)));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { i18nMark } from '@lingui/react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
Card,
|
||||
PageSection,
|
||||
@@ -15,12 +16,6 @@ import PaginatedDataList, {
|
||||
import OrganizationListItem from '../components/OrganizationListItem';
|
||||
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', {
|
||||
page: 1,
|
||||
page_size: 5,
|
||||
@@ -36,7 +31,7 @@ class OrganizationsList extends Component {
|
||||
isLoading: true,
|
||||
isInitialized: false,
|
||||
organizations: [],
|
||||
selected: [],
|
||||
selected: []
|
||||
};
|
||||
|
||||
this.handleSelectAll = this.handleSelectAll.bind(this);
|
||||
@@ -148,9 +143,9 @@ class OrganizationsList extends Component {
|
||||
isLoading,
|
||||
isInitialized,
|
||||
selected,
|
||||
organizations,
|
||||
organizations
|
||||
} = this.state;
|
||||
const { match } = this.props;
|
||||
const { match, i18n } = this.props;
|
||||
|
||||
const isAllSelected = selected.length === organizations.length;
|
||||
|
||||
@@ -163,7 +158,11 @@ class OrganizationsList extends Component {
|
||||
itemCount={itemCount}
|
||||
itemName="organization"
|
||||
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
|
||||
isAllSelected={isAllSelected}
|
||||
onSelectAll={this.handleSelectAll}
|
||||
@@ -198,4 +197,4 @@ class OrganizationsList extends Component {
|
||||
}
|
||||
|
||||
export { OrganizationsList as _OrganizationsList };
|
||||
export default withNetwork(withRouter(OrganizationsList));
|
||||
export default withI18n()(withNetwork(withRouter(OrganizationsList)));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Portal extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>My View</Trans>
|
||||
{i18n._(t`My View`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Portal extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Portal;
|
||||
export default withI18n()(Portal);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Projects extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Projects</Trans>
|
||||
{i18n._(t`Projects`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Projects extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Projects;
|
||||
export default withI18n()(Projects);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Schedules extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Schedules</Trans>
|
||||
{i18n._(t`Schedules`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Schedules extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Schedules;
|
||||
export default withI18n()(Schedules);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class SystemSettings extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>System Settings</Trans>
|
||||
{i18n._(t`System Settings`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class SystemSettings extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default SystemSettings;
|
||||
export default withI18n()(SystemSettings);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Teams extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Teams</Trans>
|
||||
{i18n._(t`Teams`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Teams extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Teams;
|
||||
export default withI18n()(Teams);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Templates extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Templates</Trans>
|
||||
{i18n._(t`Templates`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Templates extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Templates;
|
||||
export default withI18n()(Templates);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class UISettings extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>User Interface Settings</Trans>
|
||||
{i18n._(t`User Interface Settings`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class UISettings extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default UISettings;
|
||||
export default withI18n()(UISettings);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
@@ -8,13 +9,14 @@ import {
|
||||
|
||||
class Users extends Component {
|
||||
render () {
|
||||
const { i18n } = this.props;
|
||||
const { light, medium } = PageSectionVariants;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageSection variant={light} className="pf-m-condensed">
|
||||
<Title size="2xl">
|
||||
<Trans>Users</Trans>
|
||||
{i18n._(t`Users`)}
|
||||
</Title>
|
||||
</PageSection>
|
||||
<PageSection variant={medium} />
|
||||
@@ -23,4 +25,4 @@ class Users extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Users;
|
||||
export default withI18n()(Users);
|
||||
|
||||
@@ -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
20
src/util/validators.jsx
Normal 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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user