Merge remote-tracking branch 'origin/add-org-new' into react-context-api

This commit is contained in:
kialam
2018-12-17 11:59:46 -05:00
60 changed files with 2431 additions and 649 deletions

View File

@@ -1,6 +1,8 @@
import React, { Fragment } from 'react';
import { ConfigContext } from './context';
import { I18nProvider, I18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Redirect,
Switch,
@@ -55,6 +57,18 @@ import Teams from './pages/Teams';
import Templates from './pages/Templates';
import Users from './pages/Users';
import ja from '../build/locales/ja/messages';
import en from '../build/locales/en/messages';
const catalogs = { en, ja };
// This spits out the language and the region. Example: es-US
const language = (navigator.languages && navigator.languages[0])
|| navigator.language
|| navigator.userLanguage;
const languageWithoutRegionCode = language.toLowerCase().split(/[_-]+/)[0];
const SideNavItems = ({ items, history }) => {
const currentPath = history.location.pathname.split('/')[1];
let activeGroup;
@@ -146,197 +160,203 @@ class App extends React.Component {
);
return (
<Fragment>
<BackgroundImage
src={{
[BackgroundImageSrc.lg]: '/assets/images/pfbg_1200.jpg',
[BackgroundImageSrc.md]: '/assets/images/pfbg_992.jpg',
[BackgroundImageSrc.md2x]: '/assets/images/pfbg_992@2x.jpg',
[BackgroundImageSrc.sm]: '/assets/images/pfbg_768.jpg',
[BackgroundImageSrc.sm2x]: '/assets/images/pfbg_768@2x.jpg',
[BackgroundImageSrc.xl]: '/assets/images/pfbg_2000.jpg',
[BackgroundImageSrc.xs]: '/assets/images/pfbg_576.jpg',
[BackgroundImageSrc.xs2x]: '/assets/images/pfbg_576@2x.jpg',
[BackgroundImageSrc.filter]: '/assets/images/background-filter.svg'
}}
/>
<Switch>
<ConditionalRedirect shouldRedirect={() => api.isAuthenticated()} redirectPath="/" path="/login" component={() => <Login logo={logo} loginInfo={loginInfo} />} />
<Fragment>
<Page
header={(
<PageHeader
logo={<TowerLogo onClick={this.onLogoClick} />}
toolbar={PageToolbar}
showNavToggle
onNavToggle={this.onNavToggle}
/>
)}
sidebar={(
<PageSidebar
isNavOpen={isNavOpen}
nav={(
<Nav aria-label="Primary Navigation">
<NavList>
<SideNavItems
history={history}
items={[
{
groupName: 'views',
title: 'Views',
routes: [
{
path: 'home',
title: 'Dashboard'
},
{
path: 'jobs',
title: 'Jobs'
},
{
path: 'schedules',
title: 'Schedules'
},
{
path: 'portal',
title: 'Portal Mode'
},
]
},
{
groupName: 'resources',
title: 'Resources',
routes: [
{
path: 'templates',
title: 'Templates'
},
{
path: 'credentials',
title: 'Credentials'
},
{
path: 'projects',
title: 'Projects'
},
{
path: 'inventories',
title: 'Inventories'
},
{
path: 'inventory_scripts',
title: 'Inventory Scripts'
}
]
},
{
groupName: 'access',
title: 'Access',
routes: [
{
path: 'organizations',
title: 'Organizations'
},
{
path: 'users',
title: 'Users'
},
{
path: 'teams',
title: 'Teams'
}
]
},
{
groupName: 'administration',
title: 'Administration',
routes: [
{
path: 'credential_types',
title: 'Credential Types',
},
{
path: 'notification_templates',
title: 'Notifications'
},
{
path: 'management_jobs',
title: 'Management Jobs'
},
{
path: 'instance_groups',
title: 'Instance Groups'
},
{
path: 'applications',
title: 'Integrations'
}
]
},
{
groupName: 'settings',
title: 'Settings',
routes: [
{
path: 'auth_settings',
title: 'Authentication',
},
{
path: 'jobs_settings',
title: 'Jobs'
},
{
path: 'system_settings',
title: 'System'
},
{
path: 'ui_settings',
title: 'User Interface'
},
{
path: 'license',
title: 'License'
}
]
}
]}
/>
</NavList>
</Nav>
)}
/>
)}
useCondensed
>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" exact path="/" component={() => (<Redirect to="/home" />)} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/home" component={Dashboard} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/jobs" component={Jobs} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/schedules" component={Schedules} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/portal" component={Portal} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/templates" component={Templates} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/credentials" component={Credentials} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/projects" component={Projects} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/inventories" component={Inventories} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/inventory_scripts" component={InventoryScripts} />
<ConfigContext.Provider value={this.getSessionObject('config')}>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/organizations" component={Organizations} />
</ConfigContext.Provider>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/users" component={Users} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/teams" component={Teams} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/credential_types" component={CredentialTypes} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/notification_templates" component={NotificationTemplates} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/management_jobs" component={ManagementJobs} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/instance_groups" component={InstanceGroups} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/applications" component={Applications} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/auth_settings" component={AuthSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/jobs_settings" component={JobsSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/system_settings" component={SystemSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/ui_settings" component={UISettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/license" component={License} />
</Page>
</Fragment>
</Switch>
</Fragment>
<I18nProvider language={languageWithoutRegionCode} catalogs={catalogs}>
<Fragment>
<BackgroundImage
src={{
[BackgroundImageSrc.lg]: '/assets/images/pfbg_1200.jpg',
[BackgroundImageSrc.md]: '/assets/images/pfbg_992.jpg',
[BackgroundImageSrc.md2x]: '/assets/images/pfbg_992@2x.jpg',
[BackgroundImageSrc.sm]: '/assets/images/pfbg_768.jpg',
[BackgroundImageSrc.sm2x]: '/assets/images/pfbg_768@2x.jpg',
[BackgroundImageSrc.xl]: '/assets/images/pfbg_2000.jpg',
[BackgroundImageSrc.xs]: '/assets/images/pfbg_576.jpg',
[BackgroundImageSrc.xs2x]: '/assets/images/pfbg_576@2x.jpg',
[BackgroundImageSrc.filter]: '/assets/images/background-filter.svg'
}}
/>
<Switch>
<ConditionalRedirect shouldRedirect={() => api.isAuthenticated()} redirectPath="/" path="/login" component={() => <Login logo={logo} loginInfo={loginInfo} />} />
<Fragment>
<Page
header={(
<PageHeader
logo={<TowerLogo onClick={this.onLogoClick} />}
toolbar={PageToolbar}
showNavToggle
onNavToggle={this.onNavToggle}
/>
)}
sidebar={(
<PageSidebar
isNavOpen={isNavOpen}
nav={(
<I18n>
{({ i18n }) => (
<Nav aria-label={i18n._(t`Primary Navigation`)}>
<NavList>
<SideNavItems
history={history}
items={[
{
groupName: 'views',
title: i18n._('Views'),
routes: [
{
path: 'home',
title: i18n._('Dashboard')
},
{
path: 'jobs',
title: i18n._('Jobs')
},
{
path: 'schedules',
title: i18n._('Schedules')
},
{
path: 'portal',
title: i18n._('Portal Mode')
},
]
},
{
groupName: 'resources',
title: i18n._('Resources'),
routes: [
{
path: 'templates',
title: i18n._('Templates')
},
{
path: 'credentials',
title: i18n._('Credentials')
},
{
path: 'projects',
title: i18n._('Projects')
},
{
path: 'inventories',
title: i18n._('Inventories')
},
{
path: 'inventory_scripts',
title: i18n._('Inventory Scripts')
}
]
},
{
groupName: 'access',
title: i18n._('Access'),
routes: [
{
path: 'organizations',
title: i18n._('Organizations')
},
{
path: 'users',
title: i18n._('Users')
},
{
path: 'teams',
title: i18n._('Teams')
}
]
},
{
groupName: 'administration',
title: i18n._('Administration'),
routes: [
{
path: 'credential_types',
title: i18n._('Credential Types'),
},
{
path: 'notification_templates',
title: i18n._('Notifications')
},
{
path: 'management_jobs',
title: i18n._('Management Jobs')
},
{
path: 'instance_groups',
title: i18n._('Instance Groups')
},
{
path: 'applications',
title: i18n._('Integrations')
}
]
},
{
groupName: 'settings',
title: i18n._('Settings'),
routes: [
{
path: 'auth_settings',
title: i18n._('Authentication'),
},
{
path: 'jobs_settings',
title: i18n._('Jobs')
},
{
path: 'system_settings',
title: i18n._('System')
},
{
path: 'ui_settings',
title: i18n._('User Interface')
},
{
path: 'license',
title: i18n._('License')
}
]
}
]}
/>
</NavList>
</Nav>
)}
</I18n>
)}
/>
)}
useCondensed
>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" exact path="/" component={() => (<Redirect to="/home" />)} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/home" component={Dashboard} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/jobs" component={Jobs} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/schedules" component={Schedules} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/portal" component={Portal} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/templates" component={Templates} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/credentials" component={Credentials} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/projects" component={Projects} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/inventories" component={Inventories} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/inventory_scripts" component={InventoryScripts} />
<ConfigContext.Provider value={this.getSessionObject('config')}>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/organizations" component={Organizations} />
</ConfigContext.Provider>
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/users" component={Users} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/teams" component={Teams} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/credential_types" component={CredentialTypes} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/notification_templates" component={NotificationTemplates} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/management_jobs" component={ManagementJobs} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/instance_groups" component={InstanceGroups} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/applications" component={Applications} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/auth_settings" component={AuthSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/jobs_settings" component={JobsSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/system_settings" component={SystemSettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/ui_settings" component={UISettings} />
<ConditionalRedirect shouldRedirect={() => !api.isAuthenticated()} redirectPath="/login" path="/license" component={License} />
</Page>
</Fragment>
</Switch>
</Fragment>
</I18nProvider>
);
}
}

View File

@@ -1,4 +1,6 @@
import React from 'react';
import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
AboutModal,
TextContent,
@@ -67,37 +69,43 @@ class About extends React.Component {
const { ansible_version = 'loading', version = 'loading' } = config;
return (
<AboutModal
isOpen={isOpen}
onClose={this.handleModalToggle}
productName="Ansible Tower"
trademark="Copyright 2018 Red Hat, Inc."
brandImageSrc={brandImg}
brandImageAlt="Brand Image"
logoImageSrc={logoImg}
logoImageAlt="AboutModal Logo"
heroImageSrc={heroImg}
>
<pre>
{ this.createSpeechBubble(version) }
{`
\\
\\ ^__^
(oo)\\_______
(__) A )\\
||----w |
|| ||
`}
</pre>
<I18n>
{({ i18n }) => (
<AboutModal
isOpen={isOpen}
onClose={this.handleModalToggle}
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`)}
heroImageSrc={heroImg}
>
<pre>
{ this.createSpeechBubble(version) }
{`
\\
\\ ^__^
(oo)\\_______
(__) A )\\
||----w |
|| ||
`}
</pre>
<TextContent>
<TextList component="dl">
<TextListItem component="dt">Ansible Version</TextListItem>
<TextListItem component="dd">{ ansible_version }</TextListItem>
</TextList>
</TextContent>
{ error ? <div>error</div> : ''}
</AboutModal>
<TextContent>
<TextList component="dl">
<TextListItem component="dt">
<Trans>Ansible Version</Trans>
</TextListItem>
<TextListItem component="dd">{ ansible_version }</TextListItem>
</TextList>
</TextContent>
{ error ? <div>error</div> : ''}
</AboutModal>
)}
</I18n>
);
}
}

View File

@@ -1,4 +1,6 @@
import React from 'react';
import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
Button,
Checkbox,
@@ -112,122 +114,126 @@ class DataListToolbar extends React.Component {
};
return (
<div className="awx-toolbar">
<Level>
<LevelItem>
<Toolbar style={{ marginLeft: '20px' }}>
<ToolbarGroup>
<ToolbarItem>
<Checkbox
checked={isAllSelected}
onChange={onSelectAll}
aria-label="Select all"
id="select-all"
/>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<div className="pf-c-input-group">
<Dropdown
onToggle={this.onSearchDropdownToggle}
onSelect={this.onSearchDropdownSelect}
direction={up}
isOpen={isSearchDropdownOpen}
toggle={(
<DropdownToggle
<I18n>
{({ i18n }) => (
<div className="awx-toolbar">
<Level>
<LevelItem>
<Toolbar style={{ marginLeft: '20px' }}>
<ToolbarGroup>
<ToolbarItem>
<Checkbox
checked={isAllSelected}
onChange={onSelectAll}
aria-label={i18n._(t`Select all`)}
id="select-all"
/>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<div className="pf-c-input-group">
<Dropdown
onToggle={this.onSearchDropdownToggle}
onSelect={this.onSearchDropdownSelect}
direction={up}
isOpen={isSearchDropdownOpen}
toggle={(
<DropdownToggle
onToggle={this.onSearchDropdownToggle}
>
{ searchColumnName }
</DropdownToggle>
)}
>
{ searchColumnName }
</DropdownToggle>
)}
>
{columns.filter(({ key }) => key !== searchKey).map(({ key, name }) => (
<DropdownItem key={key} component="button">
{ name }
</DropdownItem>
))}
</Dropdown>
<TextInput
type="search"
aria-label="search text input"
value={searchValue}
onChange={this.handleSearchInputChange}
/>
<Button
variant="tertiary"
aria-label="Search"
onClick={() => onSearch(searchValue)}
>
<i className="fas fa-search" aria-hidden="true" />
</Button>
</div>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<Dropdown
onToggle={this.onSortDropdownToggle}
onSelect={this.onSortDropdownSelect}
direction={up}
isOpen={isSortDropdownOpen}
toggle={(
<DropdownToggle
{columns.filter(({ key }) => key !== searchKey).map(({ key, name }) => (
<DropdownItem key={key} component="button">
{ name }
</DropdownItem>
))}
</Dropdown>
<TextInput
type="search"
aria-label={i18n._(t`Search text input`)}
value={searchValue}
onChange={this.handleSearchInputChange}
/>
<Button
variant="tertiary"
aria-label={i18n._(t`Search`)}
onClick={() => onSearch(searchValue)}
>
<i className="fas fa-search" aria-hidden="true" />
</Button>
</div>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<Dropdown
onToggle={this.onSortDropdownToggle}
onSelect={this.onSortDropdownSelect}
direction={up}
isOpen={isSortDropdownOpen}
toggle={(
<DropdownToggle
onToggle={this.onSortDropdownToggle}
>
{ sortedColumnName }
</DropdownToggle>
)}
>
{ sortedColumnName }
</DropdownToggle>
)}
>
{columns
.filter(({ key, isSortable }) => isSortable && key !== sortedColumnKey)
.map(({ key, name }) => (
<DropdownItem key={key} component="button">
{ name }
</DropdownItem>
))}
</Dropdown>
</ToolbarItem>
<ToolbarItem>
<Button
onClick={() => onSort(sortedColumnKey, sortOrder === 'ascending' ? 'descending' : 'ascending')}
variant="plain"
aria-label="Sort"
>
{displayedSortIcon()}
{columns
.filter(({ key, isSortable }) => isSortable && key !== sortedColumnKey)
.map(({ key, name }) => (
<DropdownItem key={key} component="button">
{ name }
</DropdownItem>
))}
</Dropdown>
</ToolbarItem>
<ToolbarItem>
<Button
onClick={() => onSort(sortedColumnKey, sortOrder === 'ascending' ? 'descending' : 'ascending')}
variant="plain"
aria-label={i18n._(t`Sort`)}
>
{displayedSortIcon()}
</Button>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<Button variant="plain" aria-label={i18n._(t`Expand`)}>
<BarsIcon />
</Button>
</ToolbarItem>
<ToolbarItem>
<Button variant="plain" aria-label={i18n._(t`Collapse`)}>
<EqualsIcon />
</Button>
</ToolbarItem>
</ToolbarGroup>
</Toolbar>
</LevelItem>
<LevelItem>
<Tooltip message={i18n._(t`Delete`)} position="top">
<Button variant="plain" aria-label={i18n._(t`Delete`)}>
<TrashAltIcon />
</Button>
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarItem>
<Button variant="plain" aria-label="Expand">
<BarsIcon />
</Button>
</ToolbarItem>
<ToolbarItem>
<Button variant="plain" aria-label="Collapse">
<EqualsIcon />
</Button>
</ToolbarItem>
</ToolbarGroup>
</Toolbar>
</LevelItem>
<LevelItem>
<Tooltip message="Delete" position="top">
<Button variant="plain" aria-label="Delete">
<TrashAltIcon />
</Button>
</Tooltip>
{addUrl && (
<Link to={addUrl}>
<Button variant="primary" aria-label="Add">
Add
</Button>
</Link>
)}
</LevelItem>
</Level>
</div>
</Tooltip>
{addUrl && (
<Link to={addUrl}>
<Button variant="primary" aria-label={i18n._(t`Add`)}>
<Trans>Add</Trans>
</Button>
</Link>
)}
</LevelItem>
</Level>
</div>
)}
</I18n>
);
}
}

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
Dropdown,
DropdownItem,
@@ -22,14 +23,14 @@ class HelpDropdown extends Component {
target="_blank"
key="help"
>
Help
<Trans>Help</Trans>
</DropdownItem>,
<DropdownItem
onClick={() => this.setState({ showAboutModal: true })}
key="about"
>
About
</DropdownItem>,
<Trans>About</Trans>
</DropdownItem>
];
return (

View File

@@ -1,4 +1,6 @@
import React from 'react';
import { I18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Button,
@@ -8,19 +10,23 @@ import {
import { UserIcon } from '@patternfly/react-icons';
const LogoutButton = ({ onDevLogout }) => (
<Button
id="button-logout"
aria-label="Logout"
variant={ButtonVariant.plain}
onClick={onDevLogout}
onKeyDown={event => {
if (event.keyCode === 13) {
onDevLogout();
}
}}
>
<UserIcon />
</Button>
<I18n>
{({ i18n }) => (
<Button
id="button-logout"
aria-label={i18n._(t`Logout`)}
variant={ButtonVariant.plain}
onClick={onDevLogout}
onKeyDown={event => {
if (event.keyCode === 13) {
onDevLogout();
}
}}
>
<UserIcon />
</Button>
)}
</I18n>
);
export default LogoutButton;

View File

@@ -1,4 +1,6 @@
import React, { Component } from 'react';
import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
Button,
Dropdown,
@@ -126,93 +128,106 @@ class Pagination extends Component {
};
return (
<div className="awx-pagination">
<Level>
<LevelItem>
<Dropdown
onToggle={this.onTogglePageSize}
onSelect={this.onSelectPageSize}
direction={up}
isOpen={isOpen}
toggle={(
<DropdownToggle
onToggle={this.onTogglePageSize}>
{ page_size }
</DropdownToggle>
)}>
{opts.map(option => (
<DropdownItem key={option} component="button">
{ option }
</DropdownItem>
))}
</Dropdown> Per Page
</LevelItem>
<LevelItem>
<Split gutter="md" className="pf-u-display-flex pf-u-align-items-center">
<SplitItem>{itemMin} - {itemMax } of { count }</SplitItem>
<SplitItem>
<div className="pf-c-input-group">
<Button
variant="tertiary"
aria-label="first"
style={isOnFirst ? disabledStyle : {}}
isDisabled={isOnFirst}
onClick={this.onFirst}>
<i className="fas fa-angle-double-left"></i>
</Button>
<Button
variant="tertiary"
aria-label="previous"
style={isOnFirst ? disabledStyle : {}}
isDisabled={isOnFirst}
onClick={this.onPrevious}>
<i className="fas fa-angle-left"></i>
</Button>
</div>
</SplitItem>
<SplitItem isMain>
<form onSubmit={this.onSubmit}>
Page <TextInput
isDisabled={pageCount === 1}
aria-label="Page Number"
style={{
height: '30px',
width: '30px',
textAlign: 'center',
padding: '0',
margin: '0',
...(pageCount === 1 ? disabledStyle : {})
}}
value={value}
type="text"
onChange={this.onPageChange}
/> of { pageCount }
</form>
</SplitItem>
<SplitItem>
<div className="pf-c-input-group">
<Button
variant="tertiary"
aria-label="next"
style={isOnLast ? disabledStyle : {}}
isDisabled={isOnLast}
onClick={this.onNext}>
<i className="fas fa-angle-right"></i>
</Button>
<Button
variant="tertiary"
aria-label="last"
style={isOnLast ? disabledStyle : {}}
isDisabled={isOnLast}
onClick={this.onLast}>
<i className="fas fa-angle-double-right"></i>
</Button>
</div>
</SplitItem>
</Split>
</LevelItem>
</Level>
</div>
<I18n>
{({ i18n }) => (
<div className="awx-pagination">
<Level>
<LevelItem>
<Dropdown
onToggle={this.onTogglePageSize}
onSelect={this.onSelectPageSize}
direction={up}
isOpen={isOpen}
toggle={(
<DropdownToggle
onToggle={this.onTogglePageSize}>
{ page_size }
</DropdownToggle>
)}>
{opts.map(option => (
<DropdownItem key={option} component="button">
{ option }
</DropdownItem>
))}
</Dropdown>
<Trans>Per Page</Trans>
</LevelItem>
<LevelItem>
<Split gutter="md" className="pf-u-display-flex pf-u-align-items-center">
<SplitItem>
<Trans>{ itemMin } - { itemMax } of { count }</Trans>
</SplitItem>
<SplitItem>
<div className="pf-c-input-group">
<Button
variant="tertiary"
aria-label={i18n._(t`First`)}
style={isOnFirst ? disabledStyle : {}}
isDisabled={isOnFirst}
onClick={this.onFirst}
>
<i className="fas fa-angle-double-left" />
</Button>
<Button
variant="tertiary"
aria-label={i18n._(t`Previous`)}
style={isOnFirst ? disabledStyle : {}}
isDisabled={isOnFirst}
onClick={this.onPrevious}
>
<i className="fas fa-angle-left" />
</Button>
</div>
</SplitItem>
<SplitItem isMain>
<form onSubmit={this.onSubmit}>
<Trans>
Page <TextInput
isDisabled={pageCount === 1}
aria-label={i18n._(t`Page Number`)}
style={{
height: '30px',
width: '30px',
textAlign: 'center',
padding: '0',
margin: '0',
...(pageCount === 1 ? disabledStyle : {})
}}
value={value}
type="text"
onChange={this.onPageChange}
/> of { pageCount }
</Trans>
</form>
</SplitItem>
<SplitItem>
<div className="pf-c-input-group">
<Button
variant="tertiary"
aria-label={i18n._(t`Next`)}
style={isOnLast ? disabledStyle : {}}
isDisabled={isOnLast}
onClick={this.onNext}
>
<i className="fas fa-angle-right" />
</Button>
<Button
variant="tertiary"
aria-label={i18n._(t`Last`)}
style={isOnLast ? disabledStyle : {}}
isDisabled={isOnLast}
onClick={this.onLast}
>
<i className="fas fa-angle-double-right" />
</Button>
</div>
</SplitItem>
</Split>
</LevelItem>
</Level>
</div>
)}
</I18n>
);
}
}

View File

@@ -1,5 +1,7 @@
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Brand } from '@patternfly/react-core';
import TowerLogoHeader from '../../../images/tower-logo-header.svg';
@@ -39,15 +41,19 @@ class TowerLogo extends Component {
}
return (
<Brand
src={src}
alt="Tower Brand Image"
onMouseOut={this.onHover}
onMouseOver={this.onHover}
onBlur={this.onHover}
onFocus={this.onHover}
onClick={this.onClick}
/>
<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>
);
}
}

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Applications extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Applications</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Applications</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class AuthSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Authentication Settings</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Authentication Settings</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class CredentialTypes extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Credential Types</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Credential Types</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Credentials extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Credentials</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Credentials</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Dashboard extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Dashboard</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Dashboard</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class InstanceGroups extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Instance Groups</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Instance Groups</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Inventories extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Inventories</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Inventories</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class InventoryScripts extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Inventory Scripts</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Inventory Scripts</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Jobs extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Jobz</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Jobs</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class JobsSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Jobs Settings</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Jobs Settings</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class License extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">License</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>License</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,5 +1,7 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import { I18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
LoginForm,
LoginPage,
@@ -54,34 +56,33 @@ class AtLogin extends Component {
const { username, password, isValidPassword } = this.state;
const { logo, alt } = this.props;
const logoSrc = logo ? `data:image/jpeg;${logo}` : towerLogo;
const logoAlt = alt || 'Ansible Tower';
const LOGIN_ERROR_MESSAGE = 'Invalid username or password. Please try again.';
const LOGIN_TITLE = 'Welcome to Ansible Tower! Please Sign In.';
const LOGIN_USERNAME = 'Username';
const LOGIN_PASSWORD = 'Password';
if (api.isAuthenticated()) {
return (<Redirect to="/" />);
}
return (
<LoginPage
mainBrandImgSrc={logoSrc}
mainBrandImgAlt={logoAlt}
loginTitle={LOGIN_TITLE}
>
<LoginForm
usernameLabel={LOGIN_USERNAME}
usernameValue={username}
onChangeUsername={this.handleUsernameChange}
passwordLabel={LOGIN_PASSWORD}
passwordValue={password}
onChangePassword={this.handlePasswordChange}
isValidPassword={isValidPassword}
passwordHelperTextInvalid={LOGIN_ERROR_MESSAGE}
onLoginButtonClick={this.handleSubmit}
/>
</LoginPage>
<I18n>
{({ i18n }) => (
<LoginPage
mainBrandImgSrc={logoSrc}
mainBrandImgAlt={alt || 'Ansible Tower'}
loginTitle={i18n._(t`Welcome to Ansible Tower! Please Sign In.`)}
>
<LoginForm
usernameLabel={i18n._(t`Username`)}
usernameValue={username}
onChangeUsername={this.handleUsernameChange}
passwordLabel={i18n._(t`Password`)}
passwordValue={password}
onChangePassword={this.handlePasswordChange}
isValidPassword={isValidPassword}
passwordHelperTextInvalid={i18n._(t`Invalid username or password. Please try again.`)}
onLoginButtonClick={this.handleSubmit}
/>
</LoginPage>
)}
</I18n>
);
}
}

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class ManagementJobs extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Management Jobs</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Management Jobs</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class NotificationTemplates extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Notification Templates</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Notification Templates</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -49,14 +50,14 @@ const OrganizationBreadcrumb = ({ parentObj, organization, currentTab, location
breadcrumb = (
<Fragment>
{generateCrumb()}
{' > edit'}
<Trans>{' > edit'}</Trans>
</Fragment>
);
} else if (location.pathname.indexOf('add') > -1) {
breadcrumb = (
<Fragment>
{generateCrumb()}
{' > add'}
<Trans>{' > add'}</Trans>
</Fragment>
);
} else {

View File

@@ -1,4 +1,6 @@
import React, { Fragment } from 'react';
import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
Card,
CardHeader,
@@ -62,52 +64,56 @@ const OrganizationDetail = ({
const deleteResourceView = () => (
<Fragment>
{`deleting ${currentTab} association with orgs `}
<Trans>{`deleting ${currentTab} association with orgs `}</Trans>
<Link to={{ pathname: `${match.url}`, search: `?${params.toString()}`, state: { breadcrumb: parentBreadcrumbObj, organization } }}>
{`confirm removal of ${currentTab}/cancel and go back to ${currentTab} view.`}
<Trans>{`confirm removal of ${currentTab}/cancel and go back to ${currentTab} view.`}</Trans>
</Link>
</Fragment>
);
const addResourceView = () => (
<Fragment>
{`adding ${currentTab} `}
<Trans>{`adding ${currentTab} `}</Trans>
<Link to={{ pathname: `${match.url}`, search: `?${params.toString()}`, state: { breadcrumb: parentBreadcrumbObj, organization } }}>
{`save/cancel and go back to ${currentTab} view`}
<Trans>{`save/cancel and go back to ${currentTab} view`}</Trans>
</Link>
</Fragment>
);
const resourceView = () => (
<Fragment>
{`${currentTab} detail view `}
<Trans>{`${currentTab} detail view `}</Trans>
<Link to={{ pathname: `${match.url}/add-resource`, search: `?${params.toString()}`, state: { breadcrumb: parentBreadcrumbObj, organization } }}>
{`add ${currentTab}`}
<Trans>{`add ${currentTab}`}</Trans>
</Link>
{' '}
<Link to={{ pathname: `${match.url}/delete-resources`, search: `?${params.toString()}`, state: { breadcrumb: parentBreadcrumbObj, organization } }}>
{`delete ${currentTab}`}
<Trans>{`delete ${currentTab}`}</Trans>
</Link>
</Fragment>
);
const detailTabs = (tabs) => (
<ToolbarSection aria-label="Organization detail tabs">
<ToolbarGroup className="at-c-tabs">
{tabs.map(tab => (
<DetailTab
key={tab}
tab={tab}
location={location}
match={match}
currentTab={currentTab}
breadcrumb={parentBreadcrumbObj}
>
{getTabName(tab)}
</DetailTab>
))}
</ToolbarGroup>
</ToolbarSection>
<I18n>
{({ i18n }) => (
<ToolbarSection aria-label={i18n._(t`Organization detail tabs`)}>
<ToolbarGroup className="at-c-tabs">
{tabs.map(tab => (
<DetailTab
key={tab}
tab={tab}
location={location}
match={match}
currentTab={currentTab}
breadcrumb={parentBreadcrumbObj}
>
{getTabName(tab)}
</DetailTab>
))}
</ToolbarGroup>
</ToolbarSection>
)}
</I18n>
);
return (

View File

@@ -1,4 +1,5 @@
import React from 'react';
import { Trans } from '@lingui/macro';
import {
Card,
CardBody,
@@ -16,9 +17,9 @@ const OrganizationEdit = ({ match, parentBreadcrumbObj, organization }) => {
<PageSection variant={medium}>
<Card className="at-c-orgPane">
<CardBody>
{'edit view '}
<Trans>edit view </Trans>
<Link to={{ pathname: `/organizations/${match.params.id}`, state: { breadcrumb: parentBreadcrumbObj, organization } }}>
{'save/cancel and go back to view'}
<Trans>save/cancel and go back to view</Trans>
</Link>
</CardBody>
</Card>

View File

@@ -1,4 +1,6 @@
import React from 'react';
import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
Badge,
Checkbox,
@@ -20,12 +22,16 @@ export default ({
}) => (
<li key={itemId} className="pf-c-data-list__item" aria-labelledby="check-action-item1">
<div className="pf-c-data-list__check">
<Checkbox
checked={isSelected}
onChange={onSelect}
aria-label={`select organization ${itemId}`}
id={`select-organization-${itemId}`}
/>
<I18n>
{({ i18n }) => (
<Checkbox
checked={isSelected}
onChange={onSelect}
aria-label={i18n._(t`select organization ${itemId}`)}
id={`select-organization-${itemId}`}
/>
)}
</I18n>
</div>
<div className="pf-c-data-list__cell">
<span id="check-action-item1">
@@ -41,7 +47,7 @@ export default ({
</div>
<div className="pf-c-data-list__cell">
<Link to={`${detailUrl}?tab=users`}>
Users
<Trans>Users</Trans>
</Link>
<Badge isRead>
{' '}
@@ -49,7 +55,7 @@ export default ({
{' '}
</Badge>
<Link to={`${detailUrl}?tab=teams`}>
Teams
<Trans>Teams</Trans>
</Link>
<Badge isRead>
{' '}
@@ -57,7 +63,7 @@ export default ({
{' '}
</Badge>
<Link to={`${detailUrl}?tab=admins`}>
Admins
<Trans>Admins</Trans>
</Link>
<Badge isRead>
{' '}

View File

@@ -1,5 +1,6 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -68,7 +69,9 @@ class OrganizationAdd extends React.Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">Organization Add</Title>
<Title size="2xl">
<Trans>Organization Add</Trans>
</Title>
</PageSection>
<PageSection>
<Card>

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { i18nMark } from '@lingui/react';
import {
Switch,
Route
@@ -58,7 +59,7 @@ class OrganizationView extends Component {
}
const { name } = data;
if (parentBreadcrumbObj === 'loading') {
this.setState({ parentBreadcrumbObj: [{ name: 'Organizations', url: '/organizations' }, { name, url: match.url }] });
this.setState({ parentBreadcrumbObj: [{ name: i18nMark('Organizations'), url: '/organizations' }, { name, url: match.url }] });
}
} catch (err) {
this.setState({ error: true });

View File

@@ -5,6 +5,8 @@ import React, {
import {
withRouter
} from 'react-router-dom';
import { I18n, i18nMark } from '@lingui/react';
import { Trans, t } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -25,9 +27,9 @@ import {
class Organizations extends Component {
columns = [
{ name: 'Name', key: 'name', isSortable: true },
{ name: 'Modified', key: 'modified', isSortable: true, isNumeric: true },
{ name: 'Created', key: 'created', isSortable: true, isNumeric: true },
{ 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 },
];
defaultParams = {
@@ -184,12 +186,14 @@ class Organizations extends Component {
selected,
} = this.state;
const { match } = this.props;
const parentBreadcrumb = { name: 'Organizations', url: match.url };
const parentBreadcrumb = { name: i18nMark('Organizations'), url: match.url };
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">Organizations</Title>
<Title size="2xl">
<Trans>Organizations</Trans>
</Title>
</PageSection>
<PageSection variant={medium}>
<DataListToolbar
@@ -202,22 +206,26 @@ class Organizations extends Component {
onSort={this.onSort}
onSelectAll={this.onSelectAll}
/>
<ul className="pf-c-data-list" aria-label="Organizations List">
{ results.map(o => (
<OrganizationListItem
key={o.id}
itemId={o.id}
name={o.name}
detailUrl={`${match.url}/${o.id}`}
parentBreadcrumb={parentBreadcrumb}
userCount={o.summary_fields.related_field_counts.users}
teamCount={o.summary_fields.related_field_counts.teams}
adminCount={o.summary_fields.related_field_counts.admins}
isSelected={selected.includes(o.id)}
onSelect={() => this.onSelect(o.id)}
/>
))}
</ul>
<I18n>
{({ i18n }) => (
<ul className="pf-c-data-list" aria-label={i18n._(t`Organizations List`)}>
{ results.map(o => (
<OrganizationListItem
key={o.id}
itemId={o.id}
name={o.name}
detailUrl={`${match.url}/${o.id}`}
parentBreadcrumb={parentBreadcrumb}
userCount={o.summary_fields.related_field_counts.users}
teamCount={o.summary_fields.related_field_counts.teams}
adminCount={o.summary_fields.related_field_counts.admins}
isSelected={selected.includes(o.id)}
onSelect={() => this.onSelect(o.id)}
/>
))}
</ul>
)}
</I18n>
<Pagination
count={count}
page={page}

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Portal extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">My View</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>My View</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Projects extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Projects</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Projects</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Schedules extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Schedules</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Schedules</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class SystemSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">System Settings</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>System Settings</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Teams extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Teams</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Teams</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Templates extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Templates</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Templates</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class UISettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">User Interface Settings</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>User Interface Settings</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);

View File

@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
import { Trans } from '@lingui/macro';
import {
PageSection,
PageSectionVariants,
@@ -11,7 +12,11 @@ class Users extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed"><Title size="2xl">Users</Title></PageSection>
<PageSection variant={light} className="pf-m-condensed">
<Title size="2xl">
<Trans>Users</Trans>
</Title>
</PageSection>
<PageSection variant={medium} />
</Fragment>
);