Merge pull request #10059 from AlexSCorey/RemoveI18nStuff

Removes remaining I18n props, HOCs and misc objects

SUMMARY
This Removes withI18n, the i18n object and all the places that it is passed around as a prop, or argument.
E2E Tests have been triggered.  There should be no functional or visual impact. E2E results
ISSUE TYPE
-Dependency Upgrade
COMPONENT NAME

UI

AWX VERSION



ADDITIONAL INFORMATION

Reviewed-by: Kersom <None>
Reviewed-by: Keith Grant <keithjgrant@gmail.com>
Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
This commit is contained in:
softwarefactory-project-zuul[bot]
2021-05-03 15:24:50 +00:00
committed by GitHub
397 changed files with 5383 additions and 6511 deletions

View File

@@ -336,16 +336,14 @@ Internationalization leans on the [lingui](https://github.com/lingui/js-lingui)
The lingui library provides various React helpers for dealing with both marking strings for translation, and replacing strings that have been translated. For consistency and ease of use, we have consolidated on one pattern for the codebase. To set strings to be translated in the UI: The lingui library provides various React helpers for dealing with both marking strings for translation, and replacing strings that have been translated. For consistency and ease of use, we have consolidated on one pattern for the codebase. To set strings to be translated in the UI:
- import the withI18n function and wrap the export of your component in it (i.e. `export default withI18n()(Foo)`)
- doing the above gives you access to the i18n object on props. Make sure to put it in the scope of the function that contains strings needed to be translated (i.e. `const { i18n } = this.props;`)
- import the t template tag function from the @lingui/macro package. - import the t template tag function from the @lingui/macro package.
- wrap your string using the following format: `` i18n._(t`String to be translated`) `` - wrap your string using the following format: `` t`String to be translated` ``
**Note:** Variables that are put inside the t-marked template tag will not be translated. If you have a variable string with text that needs translating, you must wrap it in ` i18n._(t``) ` where it is defined. **Note:** If you have a variable string with text that needs translating, you must wrap it in `` t`${variable} string` `` where it is defined. Then you must run `npm run extract-strings` to generate new `.po` files and submit those files along with your pull request.
**Note:** We try to avoid the `I18n` consumer, `i18nMark` function, or `<Trans>` component lingui gives us access to in this repo. i18nMark does not actually replace the string in the UI (leading to the potential for untranslated bugs), and the other helpers are redundant. Settling on a consistent, single pattern helps us ease the mental overhead of the need to understand the ins and outs of the lingui API. **Note:** We try to avoid the `I18n` consumer, or `i18nMark` function lingui gives us access to in this repo. i18nMark does not actually replace the string in the UI (leading to the potential for untranslated bugs), and the other helpers are redundant. Settling on a consistent, single pattern helps us ease the mental overhead of the need to understand the ins and outs of the lingui API.
**Note:** Pluralization can be complicated so it is best to allow lingui handle cases where we have a string that may need to be pluralized based on number of items, or count. In that case lingui provides a `<Plural>` component, and a `plural()` function. See documentation [here](https://lingui.js.org/guides/plurals.html?highlight=pluralization). **Note:** Pluralization can be complicated so it is best to allow lingui handle cases where we have a string that may need to be pluralized based on number of items, or count. In that case lingui provides a `<Plural>` component, and a `plural()` function. When adding or updating strings in a `<Plural/>` tag you must run `npm run extra-strings` and submit the new `.po` files with your pull request. See documentation [here](https://lingui.js.org/guides/plurals.html?highlight=pluralization).
You can learn more about the ways lingui and its React helpers at [this link](https://lingui.js.org/tutorials/react-patterns.html). You can learn more about the ways lingui and its React helpers at [this link](https://lingui.js.org/tutorials/react-patterns.html).

View File

@@ -105,8 +105,8 @@ function App() {
</Route> </Route>
<ProtectedRoute> <ProtectedRoute>
<ConfigProvider> <ConfigProvider>
<AppContainer navRouteConfig={getRouteConfig(i18n)}> <AppContainer navRouteConfig={getRouteConfig()}>
<AuthorizedRoutes routeConfig={getRouteConfig(i18n)} /> <AuthorizedRoutes routeConfig={getRouteConfig()} />
</AppContainer> </AppContainer>
</ConfigProvider> </ConfigProvider>
</ProtectedRoute> </ProtectedRoute>

View File

@@ -1,12 +1,11 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { AboutModal } from '@patternfly/react-core'; import { AboutModal } from '@patternfly/react-core';
import { BrandName } from '../../variables'; import { BrandName } from '../../variables';
function About({ version, isOpen, onClose, i18n }) { function About({ version, isOpen, onClose }) {
const createSpeechBubble = () => { const createSpeechBubble = () => {
let text = `${BrandName} ${version}`; let text = `${BrandName} ${version}`;
let top = ''; let top = '';
@@ -25,8 +24,8 @@ function About({ version, isOpen, onClose, i18n }) {
}; };
const speechBubble = createSpeechBubble(); const speechBubble = createSpeechBubble();
const copyright = i18n._(t`Copyright`); const copyright = t`Copyright`;
const redHatInc = i18n._(t`Red Hat, Inc.`); const redHatInc = t`Red Hat, Inc.`;
return ( return (
<AboutModal <AboutModal
@@ -35,7 +34,7 @@ function About({ version, isOpen, onClose, i18n }) {
productName={`Ansible ${BrandName}`} productName={`Ansible ${BrandName}`}
trademark={`${copyright} ${new Date().getFullYear()} ${redHatInc}`} trademark={`${copyright} ${new Date().getFullYear()} ${redHatInc}`}
brandImageSrc="/static/media/logo-header.svg" brandImageSrc="/static/media/logo-header.svg"
brandImageAlt={i18n._(t`Brand Image`)} brandImageAlt={t`Brand Image`}
> >
<pre> <pre>
{speechBubble} {speechBubble}
@@ -63,4 +62,4 @@ About.defaultProps = {
version: null, version: null,
}; };
export default withI18n()(About); export default About;

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState, useContext } from 'react'; import React, { useCallback, useEffect, useState, useContext } from 'react';
import { useHistory, useParams } from 'react-router-dom'; import { useHistory, useParams } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, DropdownItem } from '@patternfly/react-core'; import { Button, DropdownItem } from '@patternfly/react-core';
@@ -14,7 +14,7 @@ import AdHocCommandsWizard from './AdHocCommandsWizard';
import { KebabifiedContext } from '../../contexts/Kebabified'; import { KebabifiedContext } from '../../contexts/Kebabified';
import ContentError from '../ContentError'; import ContentError from '../ContentError';
function AdHocCommands({ adHocItems, i18n, hasListItems, onLaunchLoading }) { function AdHocCommands({ adHocItems, hasListItems, onLaunchLoading }) {
const history = useHistory(); const history = useHistory();
const { id } = useParams(); const { id } = useParams();
@@ -22,11 +22,11 @@ function AdHocCommands({ adHocItems, i18n, hasListItems, onLaunchLoading }) {
const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext); const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext);
const verbosityOptions = [ const verbosityOptions = [
{ value: '0', key: '0', label: i18n._(t`0 (Normal)`) }, { value: '0', key: '0', label: t`0 (Normal)` },
{ value: '1', key: '1', label: i18n._(t`1 (Verbose)`) }, { value: '1', key: '1', label: t`1 (Verbose)` },
{ value: '2', key: '2', label: i18n._(t`2 (More Verbose)`) }, { value: '2', key: '2', label: t`2 (More Verbose)` },
{ value: '3', key: '3', label: i18n._(t`3 (Debug)`) }, { value: '3', key: '3', label: t`3 (Debug)` },
{ value: '4', key: '4', label: i18n._(t`4 (Connection Debug)`) }, { value: '4', key: '4', label: t`4 (Connection Debug)` },
]; ];
useEffect(() => { useEffect(() => {
if (isKebabified) { if (isKebabified) {
@@ -102,7 +102,7 @@ function AdHocCommands({ adHocItems, i18n, hasListItems, onLaunchLoading }) {
<AlertModal <AlertModal
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={() => { onClose={() => {
dismissError(); dismissError();
setIsWizardOpen(false); setIsWizardOpen(false);
@@ -110,7 +110,7 @@ function AdHocCommands({ adHocItems, i18n, hasListItems, onLaunchLoading }) {
> >
{launchError ? ( {launchError ? (
<> <>
{i18n._(t`Failed to launch job.`)} {t`Failed to launch job.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</> </>
) : ( ) : (
@@ -128,20 +128,20 @@ function AdHocCommands({ adHocItems, i18n, hasListItems, onLaunchLoading }) {
key="cancel-job" key="cancel-job"
isDisabled={isAdHocDisabled || !hasListItems} isDisabled={isAdHocDisabled || !hasListItems}
component="button" component="button"
aria-label={i18n._(t`Run Command`)} aria-label={t`Run Command`}
onClick={() => setIsWizardOpen(true)} onClick={() => setIsWizardOpen(true)}
> >
{i18n._(t`Run Command`)} {t`Run Command`}
</DropdownItem> </DropdownItem>
) : ( ) : (
<Button <Button
ouiaId="run-command-button" ouiaId="run-command-button"
variant="secondary" variant="secondary"
aria-label={i18n._(t`Run Command`)} aria-label={t`Run Command`}
onClick={() => setIsWizardOpen(true)} onClick={() => setIsWizardOpen(true)}
isDisabled={isAdHocDisabled || !hasListItems} isDisabled={isAdHocDisabled || !hasListItems}
> >
{i18n._(t`Run Command`)} {t`Run Command`}
</Button> </Button>
)} )}
@@ -166,4 +166,4 @@ AdHocCommands.propTypes = {
hasListItems: PropTypes.bool.isRequired, hasListItems: PropTypes.bool.isRequired,
}; };
export default withI18n()(AdHocCommands); export default AdHocCommands;

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useCallback } from 'react'; import React, { useEffect, useCallback } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useField } from 'formik'; import { useField } from 'formik';
@@ -21,7 +21,7 @@ const QS_CONFIG = getQSConfig('credentials', {
order_by: 'name', order_by: 'name',
}); });
function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) { function AdHocCredentialStep({ credentialTypeId, onEnableLaunch }) {
const history = useHistory(); const history = useHistory();
const { const {
error, error,
@@ -52,7 +52,7 @@ function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
const [credentialField, credentialMeta, credentialHelpers] = useField({ const [credentialField, credentialMeta, credentialHelpers] = useField({
name: 'credential', name: 'credential',
validate: required(null, i18n), validate: required(null),
}); });
if (error) { if (error) {
return <ContentError error={error} />; return <ContentError error={error} />;
@@ -64,8 +64,8 @@ function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
<Form> <Form>
<FormGroup <FormGroup
fieldId="credential" fieldId="credential"
label={i18n._(t`Machine Credential`)} label={t`Machine Credential`}
aria-label={i18n._(t`Machine Credential`)} aria-label={t`Machine Credential`}
isRequired isRequired
validated={ validated={
!credentialMeta.touched || !credentialMeta.error ? 'default' : 'error' !credentialMeta.touched || !credentialMeta.error ? 'default' : 'error'
@@ -73,9 +73,7 @@ function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
helperTextInvalid={credentialMeta.error} helperTextInvalid={credentialMeta.error}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`Select the credential you want to use when accessing the remote hosts to run the command. Choose the credential containing the username and SSH key or password that Ansible will need to log into the remote hosts.`}
t`Select the credential you want to use when accessing the remote hosts to run the command. Choose the credential containing the username and SSH key or password that Ansible will need to log into the remote hosts.`
)}
/> />
} }
> >
@@ -83,27 +81,27 @@ function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
value={credentialField.value || []} value={credentialField.value || []}
options={credentials} options={credentials}
optionCount={credentialCount} optionCount={credentialCount}
header={i18n._(t`Machine Credential`)} header={t`Machine Credential`}
readOnly readOnly
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username', key: 'created_by__username',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username', key: 'modified_by__username',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
@@ -125,4 +123,4 @@ AdHocCredentialStep.propTypes = {
credentialTypeId: PropTypes.number.isRequired, credentialTypeId: PropTypes.number.isRequired,
onEnableLaunch: PropTypes.func.isRequired, onEnableLaunch: PropTypes.func.isRequired,
}; };
export default withI18n()(AdHocCredentialStep); export default AdHocCredentialStep;

View File

@@ -1,6 +1,6 @@
/* eslint-disable react/no-unescaped-entities */ /* eslint-disable react/no-unescaped-entities */
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useField } from 'formik'; import { useField } from 'formik';
@@ -28,10 +28,10 @@ const TooltipWrapper = styled.div`
// in failing tests. // in failing tests.
const brandName = BrandName; const brandName = BrandName;
function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) { function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
const [moduleNameField, moduleNameMeta, moduleNameHelpers] = useField({ const [moduleNameField, moduleNameMeta, moduleNameHelpers] = useField({
name: 'module_name', name: 'module_name',
validate: required(null, i18n), validate: required(null),
}); });
const [variablesField] = useField('extra_vars'); const [variablesField] = useField('extra_vars');
@@ -41,14 +41,14 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
); );
const [verbosityField, verbosityMeta, verbosityHelpers] = useField({ const [verbosityField, verbosityMeta, verbosityHelpers] = useField({
name: 'verbosity', name: 'verbosity',
validate: required(null, i18n), validate: required(null),
}); });
const argumentsRequired = const argumentsRequired =
moduleNameField.value === 'command' || moduleNameField.value === 'shell'; moduleNameField.value === 'command' || moduleNameField.value === 'shell';
const [, argumentsMeta, argumentsHelpers] = useField({ const [, argumentsMeta, argumentsHelpers] = useField({
name: 'module_args', name: 'module_args',
validate: argumentsRequired && required(null, i18n), validate: argumentsRequired && required(null),
}); });
const isValid = !argumentsMeta.error || !argumentsMeta.touched; const isValid = !argumentsMeta.error || !argumentsMeta.touched;
@@ -59,8 +59,8 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
<FormFullWidthLayout> <FormFullWidthLayout>
<FormGroup <FormGroup
fieldId="module_name" fieldId="module_name"
aria-label={i18n._(t`select module`)} aria-label={t`select module`}
label={i18n._(t`Module`)} label={t`Module`}
isRequired isRequired
helperTextInvalid={moduleNameMeta.error} helperTextInvalid={moduleNameMeta.error}
validated={ validated={
@@ -70,22 +70,20 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
} }
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`These are the modules that ${brandName} supports running commands against.`}
t`These are the modules that ${brandName} supports running commands against.`
)}
/> />
} }
> >
<AnsibleSelect <AnsibleSelect
{...moduleNameField} {...moduleNameField}
placeHolder={i18n._(t`Select a module`)} placeHolder={t`Select a module`}
isValid={!moduleNameMeta.touched || !moduleNameMeta.error} isValid={!moduleNameMeta.touched || !moduleNameMeta.error}
id="module_name" id="module_name"
data={[ data={[
{ {
value: '', value: '',
key: '', key: '',
label: i18n._(t`Choose a module`), label: t`Choose a module`,
isDisabled: true, isDisabled: true,
}, },
...moduleOptions.map(value => ({ ...moduleOptions.map(value => ({
@@ -105,9 +103,9 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
<FormField <FormField
id="module_args" id="module_args"
name="module_args" name="module_args"
aria-label={i18n._(t`Arguments`)} aria-label={t`Arguments`}
type="text" type="text"
label={i18n._(t`Arguments`)} label={t`Arguments`}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
onBlur={() => argumentsHelpers.setTouched(true)} onBlur={() => argumentsHelpers.setTouched(true)}
isRequired={ isRequired={
@@ -117,27 +115,25 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
tooltip={ tooltip={
moduleNameField.value ? ( moduleNameField.value ? (
<> <>
{i18n._( {t`These arguments are used with the specified module. You can find information about ${moduleNameField.value} by clicking `}
t`These arguments are used with the specified module. You can find information about ${moduleNameField.value} by clicking `
)}
<a <a
href={`https://docs.ansible.com/ansible/latest/modules/${moduleNameField.value}_module.html`} href={`https://docs.ansible.com/ansible/latest/modules/${moduleNameField.value}_module.html`}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{' '} {' '}
{i18n._(t`here.`)} {t`here.`}
</a> </a>
</> </>
) : ( ) : (
i18n._(t`These arguments are used with the specified module.`) t`These arguments are used with the specified module.`
) )
} }
/> />
<FormGroup <FormGroup
fieldId="verbosity" fieldId="verbosity"
aria-label={i18n._(t`select verbosity`)} aria-label={t`select verbosity`}
label={i18n._(t`Verbosity`)} label={t`Verbosity`}
isRequired isRequired
validated={ validated={
!verbosityMeta.touched || !verbosityMeta.error !verbosityMeta.touched || !verbosityMeta.error
@@ -147,9 +143,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
helperTextInvalid={verbosityMeta.error} helperTextInvalid={verbosityMeta.error}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`These are the verbosity levels for standard out of the command run that are supported.`}
t`These are the verbosity levels for standard out of the command run that are supported.`
)}
/> />
} }
> >
@@ -167,19 +161,17 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
id="limit" id="limit"
name="limit" name="limit"
type="text" type="text"
label={i18n._(t`Limit`)} label={t`Limit`}
aria-label={i18n._(t`Limit`)} aria-label={t`Limit`}
tooltip={ tooltip={
<span> <span>
{i18n._( {t`The pattern used to target hosts in the inventory. Leaving the field blank, all, and * will all target all hosts in the inventory. You can find more information about Ansible's host patterns`}{' '}
t`The pattern used to target hosts in the inventory. Leaving the field blank, all, and * will all target all hosts in the inventory. You can find more information about Ansible's host patterns`
)}{' '}
<a <a
href="https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html" href="https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{i18n._(t`here`)} {t`here`}
</a> </a>
</span> </span>
} }
@@ -189,67 +181,63 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
name="forks" name="forks"
type="number" type="number"
min="0" min="0"
label={i18n._(t`Forks`)} label={t`Forks`}
aria-label={i18n._(t`Forks`)} aria-label={t`Forks`}
tooltip={ tooltip={
<span> <span>
{i18n._( {t`The number of parallel or simultaneous processes to use while executing the playbook. Inputting no value will use the default value from the ansible configuration file. You can find more information`}{' '}
t`The number of parallel or simultaneous processes to use while executing the playbook. Inputting no value will use the default value from the ansible configuration file. You can find more information`
)}{' '}
<a <a
href="https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html#the-ansible-configuration-file" href="https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html#the-ansible-configuration-file"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{i18n._(t`here.`)} {t`here.`}
</a> </a>
</span> </span>
} }
/> />
<FormColumnLayout> <FormColumnLayout>
<FormGroup <FormGroup
label={i18n._(t`Show changes`)} label={t`Show changes`}
aria-label={i18n._(t`Show changes`)} aria-label={t`Show changes`}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansibles --diff mode.`}
t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansibles --diff mode.`
)}
/> />
} }
> >
<Switch <Switch
css="display: inline-flex;" css="display: inline-flex;"
id="diff_mode" id="diff_mode"
label={i18n._(t`On`)} label={t`On`}
labelOff={i18n._(t`Off`)} labelOff={t`Off`}
isChecked={diffModeField.value} isChecked={diffModeField.value}
onChange={() => { onChange={() => {
diffModeHelpers.setValue(!diffModeField.value); diffModeHelpers.setValue(!diffModeField.value);
}} }}
aria-label={i18n._(t`toggle changes`)} aria-label={t`toggle changes`}
/> />
</FormGroup> </FormGroup>
<FormGroup name="become_enabled" fieldId="become_enabled"> <FormGroup name="become_enabled" fieldId="become_enabled">
<FormCheckboxLayout> <FormCheckboxLayout>
<Checkbox <Checkbox
aria-label={i18n._(t`Enable privilege escalation`)} aria-label={t`Enable privilege escalation`}
label={ label={
<span> <span>
{i18n._(t`Enable privilege escalation`)} {t`Enable privilege escalation`}
&nbsp; &nbsp;
<Popover <Popover
content={ content={
<p> <p>
{i18n._(t`Enables creation of a provisioning {t`Enables creation of a provisioning
callback URL. Using the URL a host can contact ${brandName} callback URL. Using the URL a host can contact ${brandName}
and request a configuration update using this job and request a configuration update using this job
template`)} template`}
&nbsp; &nbsp;
<code>--become </code> <code>--become </code>
{i18n._(t`option to the`)} &nbsp; {t`option to the`} &nbsp;
<code>ansible </code> <code>ansible </code>
{i18n._(t`command`)} {t`command`}
</p> </p>
} }
/> />
@@ -275,14 +263,12 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
tooltip={ tooltip={
<TooltipWrapper> <TooltipWrapper>
<p> <p>
{i18n._( {t`Pass extra command line changes. There are two ansible command line parameters: `}
t`Pass extra command line changes. There are two ansible command line parameters: `
)}
<br /> <br />
<code>-e</code>, <code>--extra-vars </code> <code>-e</code>, <code>--extra-vars </code>
<br /> <br />
{i18n._(t`Provide key/value pairs using either {t`Provide key/value pairs using either
YAML or JSON.`)} YAML or JSON.`}
</p> </p>
JSON: JSON:
<br /> <br />
@@ -306,8 +292,8 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
</code> </code>
</TooltipWrapper> </TooltipWrapper>
} }
label={i18n._(t`Extra variables`)} label={t`Extra variables`}
aria-label={i18n._(t`Extra variables`)} aria-label={t`Extra variables`}
/> />
</FormFullWidthLayout> </FormFullWidthLayout>
</FormColumnLayout> </FormColumnLayout>
@@ -320,4 +306,4 @@ AdHocDetailsStep.propTypes = {
verbosityOptions: PropTypes.arrayOf(PropTypes.object).isRequired, verbosityOptions: PropTypes.arrayOf(PropTypes.object).isRequired,
}; };
export default withI18n()(AdHocDetailsStep); export default AdHocDetailsStep;

View File

@@ -1,12 +1,11 @@
import React, { useState, useRef, useEffect, Fragment } from 'react'; import React, { useState, useRef, useEffect, Fragment } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Dropdown, DropdownPosition } from '@patternfly/react-core'; import { Dropdown, DropdownPosition } from '@patternfly/react-core';
import { ToolbarAddButton } from '../PaginatedDataList'; import { ToolbarAddButton } from '../PaginatedDataList';
import { useKebabifiedMenu } from '../../contexts/Kebabified'; import { useKebabifiedMenu } from '../../contexts/Kebabified';
function AddDropDownButton({ dropdownItems, i18n }) { function AddDropDownButton({ dropdownItems }) {
const { isKebabified } = useKebabifiedMenu(); const { isKebabified } = useKebabifiedMenu();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const element = useRef(null); const element = useRef(null);
@@ -36,7 +35,7 @@ function AddDropDownButton({ dropdownItems, i18n }) {
position={DropdownPosition.right} position={DropdownPosition.right}
toggle={ toggle={
<ToolbarAddButton <ToolbarAddButton
aria-label={i18n._(t`Add`)} aria-label={t`Add`}
showToggleIndicator showToggleIndicator
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
/> />
@@ -52,4 +51,4 @@ AddDropDownButton.propTypes = {
}; };
export { AddDropDownButton as _AddDropDownButton }; export { AddDropDownButton as _AddDropDownButton };
export default withI18n()(AddDropDownButton); export default AddDropDownButton;

View File

@@ -1,7 +1,6 @@
import React, { Fragment, useState, useEffect } from 'react'; import React, { Fragment, useState, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import SelectableCard from '../SelectableCard'; import SelectableCard from '../SelectableCard';
import Wizard from '../Wizard'; import Wizard from '../Wizard';
@@ -18,7 +17,7 @@ const readTeams = async queryParams => TeamsAPI.read(queryParams);
const readTeamsOptions = async () => TeamsAPI.readOptions(); const readTeamsOptions = async () => TeamsAPI.readOptions();
function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) { function AddResourceRole({ onSave, onClose, roles, resource, onError }) {
const history = useHistory(); const history = useHistory();
const [selectedResource, setSelectedResource] = useState(null); const [selectedResource, setSelectedResource] = useState(null);
@@ -122,52 +121,52 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
const userSearchColumns = [ const userSearchColumns = [
{ {
name: i18n._(t`Username`), name: t`Username`,
key: 'username__icontains', key: 'username__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`First Name`), name: t`First Name`,
key: 'first_name__icontains', key: 'first_name__icontains',
}, },
{ {
name: i18n._(t`Last Name`), name: t`Last Name`,
key: 'last_name__icontains', key: 'last_name__icontains',
}, },
]; ];
const userSortColumns = [ const userSortColumns = [
{ {
name: i18n._(t`Username`), name: t`Username`,
key: 'username', key: 'username',
}, },
{ {
name: i18n._(t`First Name`), name: t`First Name`,
key: 'first_name', key: 'first_name',
}, },
{ {
name: i18n._(t`Last Name`), name: t`Last Name`,
key: 'last_name', key: 'last_name',
}, },
]; ];
const teamSearchColumns = [ const teamSearchColumns = [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username', key: 'created_by__username',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username', key: 'modified_by__username',
}, },
]; ];
const teamSortColumns = [ const teamSortColumns = [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]; ];
@@ -176,30 +175,28 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
switch (selectedResource) { switch (selectedResource) {
case 'users': case 'users':
wizardTitle = i18n._(t`Add User Roles`); wizardTitle = t`Add User Roles`;
break; break;
case 'teams': case 'teams':
wizardTitle = i18n._(t`Add Team Roles`); wizardTitle = t`Add Team Roles`;
break; break;
default: default:
wizardTitle = i18n._(t`Add Roles`); wizardTitle = t`Add Roles`;
} }
const steps = [ const steps = [
{ {
id: 1, id: 1,
name: i18n._(t`Select a Resource Type`), name: t`Select a Resource Type`,
component: ( component: (
<div style={{ display: 'flex', flexWrap: 'wrap' }}> <div style={{ display: 'flex', flexWrap: 'wrap' }}>
<div style={{ width: '100%', marginBottom: '10px' }}> <div style={{ width: '100%', marginBottom: '10px' }}>
{i18n._( {t`Choose the type of resource that will be receiving new roles. For example, if you'd like to add new roles to a set of users please choose Users and click Next. You'll be able to select the specific resources in the next step.`}
t`Choose the type of resource that will be receiving new roles. For example, if you'd like to add new roles to a set of users please choose Users and click Next. You'll be able to select the specific resources in the next step.`
)}
</div> </div>
<SelectableCard <SelectableCard
isSelected={selectedResource === 'users'} isSelected={selectedResource === 'users'}
label={i18n._(t`Users`)} label={t`Users`}
ariaLabel={i18n._(t`Users`)} ariaLabel={t`Users`}
dataCy="add-role-users" dataCy="add-role-users"
onClick={() => handleResourceSelect('users')} onClick={() => handleResourceSelect('users')}
/> />
@@ -208,8 +205,8 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
!resource?.organization) ? null : ( !resource?.organization) ? null : (
<SelectableCard <SelectableCard
isSelected={selectedResource === 'teams'} isSelected={selectedResource === 'teams'}
label={i18n._(t`Teams`)} label={t`Teams`}
ariaLabel={i18n._(t`Teams`)} ariaLabel={t`Teams`}
dataCy="add-role-teams" dataCy="add-role-teams"
onClick={() => handleResourceSelect('teams')} onClick={() => handleResourceSelect('teams')}
/> />
@@ -220,7 +217,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
}, },
{ {
id: 2, id: 2,
name: i18n._(t`Select Items from List`), name: t`Select Items from List`,
component: ( component: (
<Fragment> <Fragment>
{selectedResource === 'users' && ( {selectedResource === 'users' && (
@@ -231,7 +228,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
onRowClick={handleResourceCheckboxClick} onRowClick={handleResourceCheckboxClick}
fetchItems={readUsers} fetchItems={readUsers}
fetchOptions={readUsersOptions} fetchOptions={readUsersOptions}
selectedLabel={i18n._(t`Selected`)} selectedLabel={t`Selected`}
selectedResourceRows={selectedResourceRows} selectedResourceRows={selectedResourceRows}
sortedColumnKey="username" sortedColumnKey="username"
/> />
@@ -243,7 +240,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
onRowClick={handleResourceCheckboxClick} onRowClick={handleResourceCheckboxClick}
fetchItems={readTeams} fetchItems={readTeams}
fetchOptions={readTeamsOptions} fetchOptions={readTeamsOptions}
selectedLabel={i18n._(t`Selected`)} selectedLabel={t`Selected`}
selectedResourceRows={selectedResourceRows} selectedResourceRows={selectedResourceRows}
/> />
)} )}
@@ -254,18 +251,18 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
}, },
{ {
id: 3, id: 3,
name: i18n._(t`Select Roles to Apply`), name: t`Select Roles to Apply`,
component: ( component: (
<SelectRoleStep <SelectRoleStep
onRolesClick={handleRoleCheckboxClick} onRolesClick={handleRoleCheckboxClick}
roles={selectableRoles} roles={selectableRoles}
selectedListKey={selectedResource === 'users' ? 'username' : 'name'} selectedListKey={selectedResource === 'users' ? 'username' : 'name'}
selectedListLabel={i18n._(t`Selected`)} selectedListLabel={t`Selected`}
selectedResourceRows={selectedResourceRows} selectedResourceRows={selectedResourceRows}
selectedRoleRows={selectedRoleRows} selectedRoleRows={selectedRoleRows}
/> />
), ),
nextButtonText: i18n._(t`Save`), nextButtonText: t`Save`,
enableNext: selectedRoleRows.length > 0, enableNext: selectedRoleRows.length > 0,
canJumpTo: maxEnabledStep >= 3, canJumpTo: maxEnabledStep >= 3,
}, },
@@ -285,8 +282,8 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
steps={steps} steps={steps}
title={wizardTitle} title={wizardTitle}
nextButtonText={currentStep.nextButtonText || undefined} nextButtonText={currentStep.nextButtonText || undefined}
backButtonText={i18n._(t`Back`)} backButtonText={t`Back`}
cancelButtonText={i18n._(t`Cancel`)} cancelButtonText={t`Cancel`}
/> />
); );
} }
@@ -304,4 +301,4 @@ AddResourceRole.defaultProps = {
}; };
export { AddResourceRole as _AddResourceRole }; export { AddResourceRole as _AddResourceRole };
export default withI18n()(AddResourceRole); export default AddResourceRole;

View File

@@ -1,7 +1,6 @@
import React, { Fragment, useCallback, useEffect } from 'react'; import React, { Fragment, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter, useLocation } from 'react-router-dom'; import { withRouter, useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import useRequest from '../../util/useRequest'; import useRequest from '../../util/useRequest';
@@ -30,7 +29,6 @@ function SelectResourceStep({
selectedResourceRows, selectedResourceRows,
fetchItems, fetchItems,
fetchOptions, fetchOptions,
i18n,
}) { }) {
const location = useLocation(); const location = useLocation();
@@ -78,9 +76,7 @@ function SelectResourceStep({
return ( return (
<Fragment> <Fragment>
<div> <div>
{i18n._( {t`Choose the resources that will be receiving new roles. You'll be able to select the roles to apply in the next step. Note that the resources chosen here will receive all roles chosen in the next step.`}
t`Choose the resources that will be receiving new roles. You'll be able to select the roles to apply in the next step. Note that the resources chosen here will receive all roles chosen in the next step.`
)}
</div> </div>
{selectedResourceRows.length > 0 && ( {selectedResourceRows.length > 0 && (
<SelectedList <SelectedList
@@ -139,4 +135,4 @@ SelectResourceStep.defaultProps = {
}; };
export { SelectResourceStep as _SelectResourceStep }; export { SelectResourceStep as _SelectResourceStep };
export default withI18n()(withRouter(SelectResourceStep)); export default withRouter(SelectResourceStep);

View File

@@ -1,7 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import CheckboxCard from './CheckboxCard'; import CheckboxCard from './CheckboxCard';
@@ -14,21 +13,18 @@ function RolesStep({
selectedListLabel, selectedListLabel,
selectedResourceRows, selectedResourceRows,
selectedRoleRows, selectedRoleRows,
i18n,
}) { }) {
return ( return (
<Fragment> <Fragment>
<div> <div>
{i18n._( {t`Choose roles to apply to the selected resources. Note that all selected roles will be applied to all selected resources.`}
t`Choose roles to apply to the selected resources. Note that all selected roles will be applied to all selected resources.`
)}
</div> </div>
<div> <div>
{selectedResourceRows.length > 0 && ( {selectedResourceRows.length > 0 && (
<SelectedList <SelectedList
displayKey={selectedListKey} displayKey={selectedListKey}
isReadOnly isReadOnly
label={selectedListLabel || i18n._(t`Selected`)} label={selectedListLabel || t`Selected`}
selected={selectedResourceRows} selected={selectedResourceRows}
/> />
)} )}
@@ -75,4 +71,4 @@ RolesStep.defaultProps = {
selectedRoleRows: [], selectedRoleRows: [],
}; };
export default withI18n()(RolesStep); export default RolesStep;

View File

@@ -8,7 +8,7 @@ import {
InfoCircleIcon, InfoCircleIcon,
TimesCircleIcon, TimesCircleIcon,
} from '@patternfly/react-icons'; } from '@patternfly/react-icons';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -20,13 +20,11 @@ const Header = styled.div`
`; `;
function AlertModal({ function AlertModal({
i18n,
isOpen = null, isOpen = null,
title, title,
label, label,
variant, variant,
children, children,
i18nHash,
...props ...props
}) { }) {
const variantIcons = { const variantIcons = {
@@ -74,7 +72,7 @@ function AlertModal({
return ( return (
<Modal <Modal
header={customHeader} header={customHeader}
aria-label={label || i18n._(t`Alert modal`)} aria-label={label || t`Alert modal`}
aria-labelledby="alert-modal-header-label" aria-labelledby="alert-modal-header-label"
isOpen={Boolean(isOpen)} isOpen={Boolean(isOpen)}
variant="small" variant="small"
@@ -86,4 +84,4 @@ function AlertModal({
); );
} }
export default withI18n()(AlertModal); export default AlertModal;

View File

@@ -8,14 +8,14 @@ import {
shape, shape,
bool, bool,
} from 'prop-types'; } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormSelect, FormSelectOption } from '@patternfly/react-core'; import { FormSelect, FormSelectOption } from '@patternfly/react-core';
function AnsibleSelect({ function AnsibleSelect({
id, id,
data, data,
i18n,
isValid, isValid,
onBlur, onBlur,
value, value,
@@ -35,7 +35,7 @@ function AnsibleSelect({
value={value} value={value}
onChange={onSelectChange} onChange={onSelectChange}
onBlur={onBlur} onBlur={onBlur}
aria-label={i18n._(t`Select Input`)} aria-label={t`Select Input`}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
className={className} className={className}
isDisabled={isDisabled} isDisabled={isDisabled}
@@ -79,4 +79,4 @@ AnsibleSelect.propTypes = {
}; };
export { AnsibleSelect as _AnsibleSelect }; export { AnsibleSelect as _AnsibleSelect };
export default withI18n()(AnsibleSelect); export default AnsibleSelect;

View File

@@ -12,7 +12,7 @@ import {
PageSidebar, PageSidebar,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import styled from 'styled-components'; import styled from 'styled-components';
import { MeAPI, RootAPI } from '../../api'; import { MeAPI, RootAPI } from '../../api';
@@ -85,7 +85,7 @@ function useStorage(key) {
return [storageVal, setValue]; return [storageVal, setValue];
} }
function AppContainer({ i18n, navRouteConfig = [], children }) { function AppContainer({ navRouteConfig = [], children }) {
const history = useHistory(); const history = useHistory();
const config = useConfig(); const config = useConfig();
@@ -139,7 +139,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
}, [handleLogout, timeRemaining]); }, [handleLogout, timeRemaining]);
const brandName = config?.license_info?.product_name; const brandName = config?.license_info?.product_name;
const alt = brandName ? i18n._(t`${brandName} logo`) : i18n._(t`brand logo`); const alt = brandName ? t`${brandName} logo` : t`brand logo`;
const header = ( const header = (
<PageHeader <PageHeader
@@ -165,7 +165,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
<PageHeaderToolsGroup> <PageHeaderToolsGroup>
<PageHeaderToolsItem> <PageHeaderToolsItem>
<Button onClick={handleLogout} variant="tertiary" ouiaId="logout"> <Button onClick={handleLogout} variant="tertiary" ouiaId="logout">
{i18n._(t`Logout`)} {t`Logout`}
</Button> </Button>
</PageHeaderToolsItem> </PageHeaderToolsItem>
</PageHeaderToolsGroup> </PageHeaderToolsGroup>
@@ -178,7 +178,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
<PageSidebar <PageSidebar
theme="dark" theme="dark"
nav={ nav={
<Nav aria-label={i18n._(t`Navigation`)} theme="dark"> <Nav aria-label={t`Navigation`} theme="dark">
<NavList> <NavList>
{navRouteConfig.map(({ groupId, groupTitle, routes }) => ( {navRouteConfig.map(({ groupId, groupTitle, routes }) => (
<NavExpandableGroup <NavExpandableGroup
@@ -210,7 +210,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
/> />
<AlertModal <AlertModal
ouiaId="session-expiration-modal" ouiaId="session-expiration-modal"
title={i18n._(t`Your session is about to expire`)} title={t`Your session is about to expire`}
isOpen={timeoutWarning && sessionTimeout > 0 && timeRemaining !== null} isOpen={timeoutWarning && sessionTimeout > 0 && timeRemaining !== null}
onClose={handleLogout} onClose={handleLogout}
showClose={false} showClose={false}
@@ -222,7 +222,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
variant="primary" variant="primary"
onClick={handleSessionContinue} onClick={handleSessionContinue}
> >
{i18n._(t`Continue`)} {t`Continue`}
</Button>, </Button>,
<Button <Button
ouiaId="session-expiration-logout-button" ouiaId="session-expiration-logout-button"
@@ -230,19 +230,17 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
variant="secondary" variant="secondary"
onClick={handleLogout} onClick={handleLogout}
> >
{i18n._(t`Logout`)} {t`Logout`}
</Button>, </Button>,
]} ]}
> >
{i18n._( {t`You will be logged out in ${Number(
t`You will be logged out in ${Number( Math.max(Math.floor(timeRemaining / 1000), 0)
Math.max(Math.floor(timeRemaining / 1000), 0) )} seconds due to inactivity.`}
)} seconds due to inactivity.`
)}
</AlertModal> </AlertModal>
</> </>
); );
} }
export { AppContainer as _AppContainer }; export { AppContainer as _AppContainer };
export default withI18n()(withRouter(AppContainer)); export default withRouter(AppContainer);

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -42,7 +42,6 @@ function PageHeaderToolbar({
onAboutClick, onAboutClick,
onLogoutClick, onLogoutClick,
loggedInUser, loggedInUser,
i18n,
}) { }) {
const [isHelpOpen, setIsHelpOpen] = useState(false); const [isHelpOpen, setIsHelpOpen] = useState(false);
const [isUserOpen, setIsUserOpen] = useState(false); const [isUserOpen, setIsUserOpen] = useState(false);
@@ -83,10 +82,7 @@ function PageHeaderToolbar({
return ( return (
<PageHeaderTools> <PageHeaderTools>
<PageHeaderToolsGroup> <PageHeaderToolsGroup>
<Tooltip <Tooltip position="bottom" content={t`Pending Workflow Approvals`}>
position="bottom"
content={i18n._(t`Pending Workflow Approvals`)}
>
<PageHeaderToolsItem> <PageHeaderToolsItem>
<Link to="/workflow_approvals?workflow_approvals.status=pending"> <Link to="/workflow_approvals?workflow_approvals.status=pending">
<PendingWorkflowApprovals> <PendingWorkflowApprovals>
@@ -108,10 +104,7 @@ function PageHeaderToolbar({
position={DropdownPosition.right} position={DropdownPosition.right}
onSelect={handleHelpSelect} onSelect={handleHelpSelect}
toggle={ toggle={
<DropdownToggle <DropdownToggle onToggle={setIsHelpOpen} aria-label={t`Info`}>
onToggle={setIsHelpOpen}
aria-label={i18n._(t`Info`)}
>
<QuestionCircleIcon /> <QuestionCircleIcon />
</DropdownToggle> </DropdownToggle>
} }
@@ -121,7 +114,7 @@ function PageHeaderToolbar({
target="_blank" target="_blank"
href={`${getDocsBaseUrl(config)}/html/userguide/index.html`} href={`${getDocsBaseUrl(config)}/html/userguide/index.html`}
> >
{i18n._(t`Help`)} {t`Help`}
</DropdownItem>, </DropdownItem>,
<DropdownItem <DropdownItem
key="about" key="about"
@@ -129,12 +122,12 @@ function PageHeaderToolbar({
isDisabled={isAboutDisabled} isDisabled={isAboutDisabled}
onClick={onAboutClick} onClick={onAboutClick}
> >
{i18n._(t`About`)} {t`About`}
</DropdownItem>, </DropdownItem>,
]} ]}
/> />
</PageHeaderToolsItem> </PageHeaderToolsItem>
<Tooltip position="left" content={<div>{i18n._(t`User`)}</div>}> <Tooltip position="left" content={<div>{t`User`}</div>}>
<PageHeaderToolsItem> <PageHeaderToolsItem>
<Dropdown <Dropdown
id="toolbar-user-dropdown" id="toolbar-user-dropdown"
@@ -155,14 +148,14 @@ function PageHeaderToolbar({
dropdownItems={[ dropdownItems={[
<DropdownItem <DropdownItem
key="user" key="user"
aria-label={i18n._(t`User details`)} aria-label={t`User details`}
href={ href={
loggedInUser loggedInUser
? `/#/users/${loggedInUser.id}/details` ? `/#/users/${loggedInUser.id}/details`
: '/#/home' : '/#/home'
} }
> >
{i18n._(t`User Details`)} {t`User Details`}
</DropdownItem>, </DropdownItem>,
<DropdownItem <DropdownItem
key="logout" key="logout"
@@ -170,7 +163,7 @@ function PageHeaderToolbar({
onClick={onLogoutClick} onClick={onLogoutClick}
id="logout-button" id="logout-button"
> >
{i18n._(t`Logout`)} {t`Logout`}
</DropdownItem>, </DropdownItem>,
]} ]}
/> />
@@ -191,4 +184,4 @@ PageHeaderToolbar.defaultProps = {
isAboutDisabled: false, isAboutDisabled: false,
}; };
export default withI18n()(PageHeaderToolbar); export default PageHeaderToolbar;

View File

@@ -1,6 +1,6 @@
import React, { Fragment, useEffect, useCallback } from 'react'; import React, { Fragment, useEffect, useCallback } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Button, Modal } from '@patternfly/react-core'; import { Button, Modal } from '@patternfly/react-core';
import OptionsList from '../OptionsList'; import OptionsList from '../OptionsList';
@@ -17,9 +17,8 @@ const QS_CONFIG = (order_by = 'name') => {
}; };
function AssociateModal({ function AssociateModal({
i18n, header = t`Items`,
header = i18n._(t`Items`), title = t`Select Items`,
title = i18n._(t`Select Items`),
onClose, onClose,
onAssociate, onAssociate,
fetchRequest, fetchRequest,
@@ -96,28 +95,28 @@ function AssociateModal({
<Modal <Modal
variant="large" variant="large"
title={title} title={title}
aria-label={i18n._(t`Association modal`)} aria-label={t`Association modal`}
isOpen={isModalOpen} isOpen={isModalOpen}
onClose={handleClose} onClose={handleClose}
actions={[ actions={[
<Button <Button
ouiaId="associate-modal-save" ouiaId="associate-modal-save"
aria-label={i18n._(t`Save`)} aria-label={t`Save`}
key="select" key="select"
variant="primary" variant="primary"
onClick={handleSave} onClick={handleSave}
isDisabled={selected.length === 0} isDisabled={selected.length === 0}
> >
{i18n._(t`Save`)} {t`Save`}
</Button>, </Button>,
<Button <Button
ouiaId="associate-modal-cancel" ouiaId="associate-modal-cancel"
aria-label={i18n._(t`Cancel`)} aria-label={t`Cancel`}
key="cancel" key="cancel"
variant="link" variant="link"
onClick={handleClose} onClick={handleClose}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
@@ -136,22 +135,22 @@ function AssociateModal({
value={selected} value={selected}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: `${displayKey}__icontains`, key: `${displayKey}__icontains`,
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: `${displayKey}`, key: `${displayKey}`,
}, },
]} ]}
@@ -163,4 +162,4 @@ function AssociateModal({
); );
} }
export default withI18n()(AssociateModal); export default AssociateModal;

View File

@@ -1,16 +1,16 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { ChipGroup as PFChipGroup } from '@patternfly/react-core'; import { ChipGroup as PFChipGroup } from '@patternfly/react-core';
import { number, shape } from 'prop-types'; import { number } from 'prop-types';
function ChipGroup({ i18n, numChips, totalChips, i18nHash, ...props }) { function ChipGroup({ numChips, totalChips, ...props }) {
return ( return (
<PFChipGroup <PFChipGroup
{...props} {...props}
numChips={numChips} numChips={numChips}
expandedText={i18n._(t`Show less`)} expandedText={t`Show less`}
collapsedText={i18n._(t`${totalChips - numChips} more`)} collapsedText={t`${totalChips - numChips} more`}
/> />
); );
} }
@@ -18,7 +18,6 @@ function ChipGroup({ i18n, numChips, totalChips, i18nHash, ...props }) {
ChipGroup.propTypes = { ChipGroup.propTypes = {
numChips: number.isRequired, numChips: number.isRequired,
totalChips: number.isRequired, totalChips: number.isRequired,
i18n: shape({}).isRequired,
}; };
export default withI18n()(ChipGroup); export default ChipGroup;

View File

@@ -8,7 +8,7 @@ import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/mode-yaml'; import 'ace-builds/src-noconflict/mode-yaml';
import 'ace-builds/src-noconflict/mode-django'; import 'ace-builds/src-noconflict/mode-django';
import 'ace-builds/src-noconflict/theme-github'; import 'ace-builds/src-noconflict/theme-github';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
import debounce from '../../util/debounce'; import debounce from '../../util/debounce';
@@ -81,7 +81,6 @@ function CodeEditor({
rows, rows,
fullHeight, fullHeight,
className, className,
i18n,
}) { }) {
if (rows && typeof rows !== 'number' && rows !== 'auto') { if (rows && typeof rows !== 'number' && rows !== 'auto') {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
@@ -185,7 +184,7 @@ function CodeEditor({
className="pf-c-form__helper-text keyboard-help-text" className="pf-c-form__helper-text keyboard-help-text"
aria-live="polite" aria-live="polite"
> >
{i18n._(t`Press Enter to edit. Press ESC to stop editing.`)} {t`Press Enter to edit. Press ESC to stop editing.`}
</div> </div>
)} )}
</> </>
@@ -210,4 +209,4 @@ CodeEditor.defaultProps = {
className: '', className: '',
}; };
export default withI18n()(CodeEditor); export default CodeEditor;

View File

@@ -1,7 +1,7 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types'; import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Split, Split,
@@ -23,15 +23,7 @@ import {
import CodeEditor from './CodeEditor'; import CodeEditor from './CodeEditor';
import { JSON_MODE, YAML_MODE } from './constants'; import { JSON_MODE, YAML_MODE } from './constants';
function VariablesDetail({ function VariablesDetail({ dataCy, helpText, value, label, rows, fullHeight }) {
dataCy,
helpText,
value,
label,
rows,
fullHeight,
i18n,
}) {
const [mode, setMode] = useState( const [mode, setMode] = useState(
isJsonObject(value) || isJsonString(value) ? JSON_MODE : YAML_MODE isJsonObject(value) || isJsonString(value) ? JSON_MODE : YAML_MODE
); );
@@ -84,7 +76,6 @@ function VariablesDetail({
setMode={setMode} setMode={setMode}
currentValue={currentValue} currentValue={currentValue}
onExpand={() => setIsExpanded(true)} onExpand={() => setIsExpanded(true)}
i18n={i18n}
/> />
</DetailName> </DetailName>
<DetailValue <DetailValue
@@ -107,7 +98,7 @@ function VariablesDetail({
css="color: var(--pf-global--danger-color--100); css="color: var(--pf-global--danger-color--100);
font-size: var(--pf-global--FontSize--sm" font-size: var(--pf-global--FontSize--sm"
> >
{i18n._(t`Error:`)} {error.message} {t`Error:`} {error.message}
</div> </div>
)} )}
</DetailValue> </DetailValue>
@@ -118,13 +109,13 @@ function VariablesDetail({
onClose={() => setIsExpanded(false)} onClose={() => setIsExpanded(false)}
actions={[ actions={[
<Button <Button
aria-label={i18n._(t`Done`)} aria-label={t`Done`}
key="select" key="select"
variant="primary" variant="primary"
onClick={() => setIsExpanded(false)} onClick={() => setIsExpanded(false)}
ouiaId={`${dataCy}-unexpand`} ouiaId={`${dataCy}-unexpand`}
> >
{i18n._(t`Done`)} {t`Done`}
</Button>, </Button>,
]} ]}
> >
@@ -137,7 +128,6 @@ function VariablesDetail({
mode={mode} mode={mode}
setMode={setMode} setMode={setMode}
currentValue={currentValue} currentValue={currentValue}
i18n={i18n}
/> />
<CodeEditor <CodeEditor
id={`${dataCy}-preview-expanded`} id={`${dataCy}-preview-expanded`}
@@ -166,16 +156,7 @@ VariablesDetail.defaultProps = {
helpText: '', helpText: '',
}; };
function ModeToggle({ function ModeToggle({ id, label, helpText, dataCy, mode, setMode, onExpand }) {
id,
label,
helpText,
dataCy,
mode,
setMode,
onExpand,
i18n,
}) {
return ( return (
<Split hasGutter> <Split hasGutter>
<SplitItem isFilled> <SplitItem isFilled>
@@ -211,7 +192,7 @@ function ModeToggle({
<SplitItem> <SplitItem>
<Button <Button
variant="plain" variant="plain"
aria-label={i18n._(t`Expand input`)} aria-label={t`Expand input`}
onClick={onExpand} onClick={onExpand}
ouiaId={`${dataCy}-expand`} ouiaId={`${dataCy}-expand`}
> >
@@ -223,4 +204,4 @@ function ModeToggle({
); );
} }
export default withI18n()(VariablesDetail); export default VariablesDetail;

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { string, bool } from 'prop-types'; import { string, bool } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -24,15 +24,7 @@ const StyledCheckboxField = styled(CheckboxField)`
margin-left: auto; margin-left: auto;
`; `;
function VariablesField({ function VariablesField({ id, name, label, readOnly, promptId, tooltip }) {
i18n,
id,
name,
label,
readOnly,
promptId,
tooltip,
}) {
// track focus manually, because the Code Editor library doesn't wire // track focus manually, because the Code Editor library doesn't wire
// into Formik completely // into Formik completely
const [shouldValidate, setShouldValidate] = useState(false); const [shouldValidate, setShouldValidate] = useState(false);
@@ -112,7 +104,6 @@ function VariablesField({
return ( return (
<div> <div>
<VariablesFieldInternals <VariablesFieldInternals
i18n={i18n}
id={id} id={id}
name={name} name={name}
label={label} label={label}
@@ -132,19 +123,18 @@ function VariablesField({
onClose={() => setIsExpanded(false)} onClose={() => setIsExpanded(false)}
actions={[ actions={[
<Button <Button
aria-label={i18n._(t`Done`)} aria-label={t`Done`}
key="select" key="select"
variant="primary" variant="primary"
onClick={() => setIsExpanded(false)} onClick={() => setIsExpanded(false)}
ouiaId={`${id}-variables-unexpand`} ouiaId={`${id}-variables-unexpand`}
> >
{i18n._(t`Done`)} {t`Done`}
</Button>, </Button>,
]} ]}
> >
<div className="pf-c-form"> <div className="pf-c-form">
<VariablesFieldInternals <VariablesFieldInternals
i18n={i18n}
id={`${id}-expanded`} id={`${id}-expanded`}
name={name} name={name}
label={label} label={label}
@@ -180,7 +170,6 @@ VariablesField.defaultProps = {
}; };
function VariablesFieldInternals({ function VariablesFieldInternals({
i18n,
id, id,
name, name,
label, label,
@@ -227,14 +216,14 @@ function VariablesFieldInternals({
{promptId && ( {promptId && (
<StyledCheckboxField <StyledCheckboxField
id="template-ask-variables-on-launch" id="template-ask-variables-on-launch"
label={i18n._(t`Prompt on launch`)} label={t`Prompt on launch`}
name="ask_variables_on_launch" name="ask_variables_on_launch"
/> />
)} )}
{onExpand && ( {onExpand && (
<Button <Button
variant="plain" variant="plain"
aria-label={i18n._(t`Expand input`)} aria-label={t`Expand input`}
onClick={onExpand} onClick={onExpand}
ouiaId={`${id}-variables-expand`} ouiaId={`${id}-variables-expand`}
> >
@@ -257,4 +246,4 @@ function VariablesFieldInternals({
); );
} }
export default withI18n()(VariablesField); export default VariablesField;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { import {
Title, Title,
EmptyState, EmptyState,
@@ -9,15 +9,15 @@ import {
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { CubesIcon } from '@patternfly/react-icons'; import { CubesIcon } from '@patternfly/react-icons';
const ContentEmpty = ({ i18n, title = '', message = '' }) => ( const ContentEmpty = ({ title = '', message = '' }) => (
<EmptyState variant="full"> <EmptyState variant="full">
<EmptyStateIcon icon={CubesIcon} /> <EmptyStateIcon icon={CubesIcon} />
<Title size="lg" headingLevel="h3"> <Title size="lg" headingLevel="h3">
{title || i18n._(t`No items found.`)} {title || t`No items found.`}
</Title> </Title>
<EmptyStateBody>{message}</EmptyStateBody> <EmptyStateBody>{message}</EmptyStateBody>
</EmptyState> </EmptyState>
); );
export { ContentEmpty as _ContentEmpty }; export { ContentEmpty as _ContentEmpty };
export default withI18n()(ContentEmpty); export default ContentEmpty;

View File

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import { Link, Redirect } from 'react-router-dom'; import { Link, Redirect } from 'react-router-dom';
import { bool, instanceOf } from 'prop-types'; import { bool, instanceOf } from 'prop-types';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { import {
Title, Title,
EmptyState, EmptyState,
@@ -18,7 +18,7 @@ async function logout() {
window.location.replace('/#/login'); window.location.replace('/#/login');
} }
function ContentError({ error, children, isNotFound, i18n }) { function ContentError({ error, children, isNotFound }) {
if (error && error.response && error.response.status === 401) { if (error && error.response && error.response.status === 401) {
if (!error.response.headers['session-timeout']) { if (!error.response.headers['session-timeout']) {
logout(); logout();
@@ -36,17 +36,13 @@ function ContentError({ error, children, isNotFound, i18n }) {
<EmptyState variant="full"> <EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} /> <EmptyStateIcon icon={ExclamationTriangleIcon} />
<Title size="lg" headingLevel="h3"> <Title size="lg" headingLevel="h3">
{is404 ? i18n._(t`Not Found`) : i18n._(t`Something went wrong...`)} {is404 ? t`Not Found` : t`Something went wrong...`}
</Title> </Title>
<EmptyStateBody> <EmptyStateBody>
{is404 {is404
? i18n._(t`The page you requested could not be found.`) ? t`The page you requested could not be found.`
: i18n._( : t`There was an error loading this content. Please reload the page.`}{' '}
t`There was an error loading this content. Please reload the page.` {children || <Link to="/home">{t`Back to Dashboard.`}</Link>}
)}{' '}
{children || (
<Link to="/home">{i18n._(t`Back to Dashboard.`)}</Link>
)}
</EmptyStateBody> </EmptyStateBody>
{error && <ErrorDetail error={error} />} {error && <ErrorDetail error={error} />}
</EmptyState> </EmptyState>
@@ -64,4 +60,4 @@ ContentError.defaultProps = {
}; };
export { ContentError as _ContentError }; export { ContentError as _ContentError };
export default withI18n()(ContentError); export default ContentError;

View File

@@ -1,5 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@@ -16,7 +16,7 @@ function CopyButton({
onCopyStart, onCopyStart,
onCopyFinish, onCopyFinish,
errorMessage, errorMessage,
i18n,
ouiaId, ouiaId,
}) { }) {
const { isLoading, error: copyError, request: copyItemToAPI } = useRequest( const { isLoading, error: copyError, request: copyItemToAPI } = useRequest(
@@ -38,17 +38,17 @@ function CopyButton({
id={id} id={id}
ouiaId={ouiaId} ouiaId={ouiaId}
isDisabled={isLoading || isDisabled} isDisabled={isLoading || isDisabled}
aria-label={i18n._(t`Copy`)} aria-label={t`Copy`}
variant="plain" variant="plain"
onClick={copyItemToAPI} onClick={copyItemToAPI}
> >
<CopyIcon /> <CopyIcon />
</Button> </Button>
<AlertModal <AlertModal
aria-label={i18n._(t`Copy Error`)} aria-label={t`Copy Error`}
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={dismissError} onClose={dismissError}
> >
{errorMessage} {errorMessage}
@@ -72,4 +72,4 @@ CopyButton.defaultProps = {
ouiaId: null, ouiaId: null,
}; };
export default withI18n()(CopyButton); export default CopyButton;

View File

@@ -1,15 +1,14 @@
import React from 'react'; import React from 'react';
import { shape } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Chip } from '@patternfly/react-core'; import { Chip } from '@patternfly/react-core';
import { Credential } from '../../types'; import { Credential } from '../../types';
import { toTitleCase } from '../../util/strings'; import { toTitleCase } from '../../util/strings';
function CredentialChip({ credential, i18n, i18nHash, ...props }) { function CredentialChip({ credential, ...props }) {
let type; let type;
if (credential.cloud) { if (credential.cloud) {
type = i18n._(t`Cloud`); type = t`Cloud`;
} else if (credential.kind === 'aws' || credential.kind === 'ssh') { } else if (credential.kind === 'aws' || credential.kind === 'ssh') {
type = credential.kind.toUpperCase(); type = credential.kind.toUpperCase();
} else { } else {
@@ -32,8 +31,7 @@ function CredentialChip({ credential, i18n, i18nHash, ...props }) {
} }
CredentialChip.propTypes = { CredentialChip.propTypes = {
credential: Credential.isRequired, credential: Credential.isRequired,
i18n: shape({}).isRequired,
}; };
export { CredentialChip as _CredentialChip }; export { CredentialChip as _CredentialChip };
export default withI18n()(CredentialChip); export default CredentialChip;

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Checkbox, Checkbox,
@@ -37,7 +37,7 @@ function DataListToolbar({
onExpand, onExpand,
onSelectAll, onSelectAll,
additionalControls, additionalControls,
i18n,
qsConfig, qsConfig,
pagination, pagination,
}) { }) {
@@ -62,7 +62,7 @@ function DataListToolbar({
id={`${qsConfig.namespace}-list-toolbar`} id={`${qsConfig.namespace}-list-toolbar`}
clearAllFilters={clearAllFilters} clearAllFilters={clearAllFilters}
collapseListedFiltersBreakpoint="lg" collapseListedFiltersBreakpoint="lg"
clearFiltersButtonText={i18n._(t`Clear all filters`)} clearFiltersButtonText={t`Clear all filters`}
> >
<ToolbarContent> <ToolbarContent>
{showSelectAll && ( {showSelectAll && (
@@ -71,7 +71,7 @@ function DataListToolbar({
<Checkbox <Checkbox
isChecked={isAllSelected} isChecked={isAllSelected}
onChange={onSelectAll} onChange={onSelectAll}
aria-label={i18n._(t`Select all`)} aria-label={t`Select all`}
id="select-all" id="select-all"
/> />
</ToolbarItem> </ToolbarItem>
@@ -83,7 +83,7 @@ function DataListToolbar({
qsConfig={qsConfig} qsConfig={qsConfig}
columns={[ columns={[
...searchColumns, ...searchColumns,
{ name: i18n._(t`Advanced`), key: 'advanced' }, { name: t`Advanced`, key: 'advanced' },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
@@ -190,4 +190,4 @@ DataListToolbar.defaultProps = {
additionalControls: [], additionalControls: [],
}; };
export default withI18n()(DataListToolbar); export default DataListToolbar;

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
import { Button, Badge, Alert, Tooltip } from '@patternfly/react-core'; import { Button, Badge, Alert, Tooltip } from '@patternfly/react-core';
@@ -20,7 +20,7 @@ function DeleteButton({
onConfirm, onConfirm,
modalTitle, modalTitle,
name, name,
i18n,
variant, variant,
children, children,
isDisabled, isDisabled,
@@ -54,7 +54,7 @@ function DeleteButton({
return ( return (
<AlertModal <AlertModal
isOpen={deleteMessageError} isOpen={deleteMessageError}
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={() => { onClose={() => {
toggleModal(false); toggleModal(false);
setDeleteMessageError(); setDeleteMessageError();
@@ -73,12 +73,12 @@ function DeleteButton({
isLoading={isLoading} isLoading={isLoading}
spinnerAriaValueText={isLoading ? 'Loading' : undefined} spinnerAriaValueText={isLoading ? 'Loading' : undefined}
variant={variant || 'secondary'} variant={variant || 'secondary'}
aria-label={i18n._(t`Delete`)} aria-label={t`Delete`}
isDisabled={isDisabled} isDisabled={isDisabled}
onClick={() => toggleModal(true)} onClick={() => toggleModal(true)}
ouiaId={ouiaId} ouiaId={ouiaId}
> >
{children || i18n._(t`Delete`)} {children || t`Delete`}
</Button> </Button>
</div> </div>
</Tooltip> </Tooltip>
@@ -88,11 +88,11 @@ function DeleteButton({
isLoading={isLoading} isLoading={isLoading}
spinnerAriaValueText={isLoading ? 'Loading' : undefined} spinnerAriaValueText={isLoading ? 'Loading' : undefined}
variant={variant || 'secondary'} variant={variant || 'secondary'}
aria-label={i18n._(t`Delete`)} aria-label={t`Delete`}
isDisabled={isDisabled} isDisabled={isDisabled}
onClick={() => toggleModal(true)} onClick={() => toggleModal(true)}
> >
{children || i18n._(t`Delete`)} {children || t`Delete`}
</Button> </Button>
)} )}
<AlertModal <AlertModal
@@ -105,27 +105,27 @@ function DeleteButton({
ouiaId="delete-modal-confirm" ouiaId="delete-modal-confirm"
key="delete" key="delete"
variant="danger" variant="danger"
aria-label={i18n._(t`Confirm Delete`)} aria-label={t`Confirm Delete`}
isDisabled={isDisabled} isDisabled={isDisabled}
onClick={() => { onClick={() => {
onConfirm(); onConfirm();
toggleModal(false); toggleModal(false);
}} }}
> >
{i18n._(t`Delete`)} {t`Delete`}
</Button>, </Button>,
<Button <Button
ouiaId="delete-modal-cancel" ouiaId="delete-modal-cancel"
key="cancel" key="cancel"
variant="link" variant="link"
aria-label={i18n._(t`Cancel`)} aria-label={t`Cancel`}
onClick={() => toggleModal(false)} onClick={() => toggleModal(false)}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
{i18n._(t`Are you sure you want to delete:`)} {t`Are you sure you want to delete:`}
<br /> <br />
<strong>{name}</strong> <strong>{name}</strong>
{Object.values(deleteDetails).length > 0 && ( {Object.values(deleteDetails).length > 0 && (
@@ -158,4 +158,4 @@ DeleteButton.defaultProps = {
ouiaId: null, ouiaId: null,
}; };
export default withI18n()(DeleteButton); export default DeleteButton;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { node } from 'prop-types'; import { node } from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -11,12 +11,12 @@ const Detail = styled(_Detail)`
} }
`; `;
function DeletedDetail({ i18n, label }) { function DeletedDetail({ label }) {
return <Detail label={label} value={i18n._(t`Deleted`)} />; return <Detail label={label} value={t`Deleted`} />;
} }
DeletedDetail.propTypes = { DeletedDetail.propTypes = {
label: node.isRequired, label: node.isRequired,
}; };
export default withI18n()(DeletedDetail); export default DeletedDetail;

View File

@@ -32,13 +32,13 @@ const getLaunchedByDetails = ({ summary_fields = {}, related = {} }) => {
return { link, value }; return { link, value };
}; };
export default function LaunchedByDetail({ job, i18n }) { export default function LaunchedByDetail({ job }) {
const { value: launchedByValue, link: launchedByLink } = const { value: launchedByValue, link: launchedByLink } =
getLaunchedByDetails(job) || {}; getLaunchedByDetails(job) || {};
return ( return (
<Detail <Detail
label={i18n._(t`Launched By`)} label={t`Launched By`}
value={ value={
launchedByLink ? ( launchedByLink ? (
<Link to={`${launchedByLink}`}>{launchedByValue}</Link> <Link to={`${launchedByLink}`}>{launchedByValue}</Link>

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext } from 'react';
import { arrayOf, func, shape, string, oneOfType, number } from 'prop-types'; import { arrayOf, func, shape, string, oneOfType, number } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Button, Tooltip, DropdownItem } from '@patternfly/react-core'; import { Button, Tooltip, DropdownItem } from '@patternfly/react-core';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -13,10 +13,9 @@ const ModalNote = styled.div`
`; `;
function DisassociateButton({ function DisassociateButton({
i18n,
itemsToDisassociate = [], itemsToDisassociate = [],
modalNote = '', modalNote = '',
modalTitle = i18n._(t`Disassociate?`), modalTitle = t`Disassociate?`,
onDisassociate, onDisassociate,
verifyCannotDisassociate = true, verifyCannotDisassociate = true,
}) { }) {
@@ -48,18 +47,16 @@ function DisassociateButton({
if (itemsToDisassociate.some(cannotDisassociate)) { if (itemsToDisassociate.some(cannotDisassociate)) {
return ( return (
<div> <div>
{i18n._( {t`You do not have permission to disassociate the following: ${itemsUnableToDisassociate}`}
t`You do not have permission to disassociate the following: ${itemsUnableToDisassociate}`
)}
</div> </div>
); );
} }
} }
if (itemsToDisassociate.length) { if (itemsToDisassociate.length) {
return i18n._(t`Disassociate`); return t`Disassociate`;
} }
return i18n._(t`Select a row to disassociate`); return t`Select a row to disassociate`;
} }
let isDisabled = false; let isDisabled = false;
@@ -79,12 +76,12 @@ function DisassociateButton({
{isKebabified ? ( {isKebabified ? (
<DropdownItem <DropdownItem
key="add" key="add"
aria-label={i18n._(t`disassociate`)} aria-label={t`disassociate`}
isDisabled={isDisabled} isDisabled={isDisabled}
component="button" component="button"
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
> >
{i18n._(t`Disassociate`)} {t`Disassociate`}
</DropdownItem> </DropdownItem>
) : ( ) : (
<Tooltip content={renderTooltip()} position="top"> <Tooltip content={renderTooltip()} position="top">
@@ -92,11 +89,11 @@ function DisassociateButton({
<Button <Button
ouiaId="disassociate-button" ouiaId="disassociate-button"
variant="secondary" variant="secondary"
aria-label={i18n._(t`Disassociate`)} aria-label={t`Disassociate`}
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
isDisabled={isDisabled} isDisabled={isDisabled}
> >
{i18n._(t`Disassociate`)} {t`Disassociate`}
</Button> </Button>
</div> </div>
</Tooltip> </Tooltip>
@@ -113,25 +110,25 @@ function DisassociateButton({
ouiaId="disassociate-modal-confirm" ouiaId="disassociate-modal-confirm"
key="disassociate" key="disassociate"
variant="danger" variant="danger"
aria-label={i18n._(t`confirm disassociate`)} aria-label={t`confirm disassociate`}
onClick={handleDisassociate} onClick={handleDisassociate}
> >
{i18n._(t`Disassociate`)} {t`Disassociate`}
</Button>, </Button>,
<Button <Button
ouiaId="disassociate-modal-cancel" ouiaId="disassociate-modal-cancel"
key="cancel" key="cancel"
variant="link" variant="link"
aria-label={i18n._(t`Cancel`)} aria-label={t`Cancel`}
onClick={() => setIsOpen(false)} onClick={() => setIsOpen(false)}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
{modalNote && <ModalNote>{modalNote}</ModalNote>} {modalNote && <ModalNote>{modalNote}</ModalNote>}
<div>{i18n._(t`This action will disassociate the following:`)}</div> <div>{t`This action will disassociate the following:`}</div>
{itemsToDisassociate.map(item => ( {itemsToDisassociate.map(item => (
<span key={item.id}> <span key={item.id}>
@@ -171,4 +168,4 @@ DisassociateButton.propTypes = {
onDisassociate: func.isRequired, onDisassociate: func.isRequired,
}; };
export default withI18n()(DisassociateButton); export default DisassociateButton;

View File

@@ -1,7 +1,7 @@
import React, { useState, Fragment } from 'react'; import React, { useState, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
@@ -32,7 +32,7 @@ const Expandable = styled(PFExpandable)`
} }
`; `;
function ErrorDetail({ error, i18n }) { function ErrorDetail({ error }) {
const { response } = error; const { response } = error;
const [isExpanded, setIsExpanded] = useState(false); const [isExpanded, setIsExpanded] = useState(false);
@@ -70,7 +70,7 @@ function ErrorDetail({ error, i18n }) {
return ( return (
<Expandable <Expandable
toggleText={i18n._(t`Details`)} toggleText={t`Details`}
onToggle={handleToggle} onToggle={handleToggle}
isExpanded={isExpanded} isExpanded={isExpanded}
> >
@@ -87,4 +87,4 @@ ErrorDetail.propTypes = {
error: PropTypes.instanceOf(Error).isRequired, error: PropTypes.instanceOf(Error).isRequired,
}; };
export default withI18n()(ErrorDetail); export default ErrorDetail;

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { bool, string } from 'prop-types'; import { bool, string } from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Tooltip } from '@patternfly/react-core'; import { Tooltip } from '@patternfly/react-core';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -20,11 +20,10 @@ function ExecutionEnvironmentDetail({
virtualEnvironment, virtualEnvironment,
executionEnvironment, executionEnvironment,
isDefaultEnvironment, isDefaultEnvironment,
i18n,
}) { }) {
const label = isDefaultEnvironment const label = isDefaultEnvironment
? i18n._(t`Default Execution Environment`) ? t`Default Execution Environment`
: i18n._(t`Execution Environment`); : t`Execution Environment`;
if (executionEnvironment) { if (executionEnvironment) {
return ( return (
@@ -47,12 +46,10 @@ function ExecutionEnvironmentDetail({
label={label} label={label}
value={ value={
<> <>
{i18n._(t`Missing resource`)} {t`Missing resource`}
<span> <span>
<Tooltip <Tooltip
content={i18n._( content={t`Custom virtual environment ${virtualEnvironment} must be replaced by an execution environment.`}
t`Custom virtual environment ${virtualEnvironment} must be replaced by an execution environment.`
)}
position="right" position="right"
> >
<ExclamationTriangleIcon /> <ExclamationTriangleIcon />
@@ -79,4 +76,4 @@ ExecutionEnvironmentDetail.defaultProps = {
virtualEnvironment: '', virtualEnvironment: '',
}; };
export default withI18n()(ExecutionEnvironmentDetail); export default ExecutionEnvironmentDetail;

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button as PFButton, Button as PFButton,
@@ -31,14 +31,14 @@ const ToolbarItem = styled(PFToolbarItem)`
// TODO: Recommend renaming this component to avoid confusion // TODO: Recommend renaming this component to avoid confusion
// with ExpandingContainer // with ExpandingContainer
function ExpandCollapse({ isCompact, onCompact, onExpand, i18n }) { function ExpandCollapse({ isCompact, onCompact, onExpand }) {
return ( return (
<Fragment> <Fragment>
<ToolbarItem> <ToolbarItem>
<Button <Button
ouiaId="toolbar-collapse-button" ouiaId="toolbar-collapse-button"
variant="plain" variant="plain"
aria-label={i18n._(t`Collapse`)} aria-label={t`Collapse`}
onClick={onCompact} onClick={onCompact}
isActive={isCompact} isActive={isCompact}
> >
@@ -49,7 +49,7 @@ function ExpandCollapse({ isCompact, onCompact, onExpand, i18n }) {
<Button <Button
ouiaId="toolbar-expand-button" ouiaId="toolbar-expand-button"
variant="plain" variant="plain"
aria-label={i18n._(t`Expand`)} aria-label={t`Expand`}
onClick={onExpand} onClick={onExpand}
isActive={!isCompact} isActive={!isCompact}
> >
@@ -70,4 +70,4 @@ ExpandCollapse.defaultProps = {
isCompact: true, isCompact: true,
}; };
export default withI18n()(ExpandCollapse); export default ExpandCollapse;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { bool, node, string } from 'prop-types'; import { bool, node, string } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
import { CheckboxField } from '../FormField'; import { CheckboxField } from '../FormField';
@@ -19,7 +19,7 @@ const StyledCheckboxField = styled(CheckboxField)`
function FieldWithPrompt({ function FieldWithPrompt({
children, children,
fieldId, fieldId,
i18n,
isRequired, isRequired,
label, label,
promptId, promptId,
@@ -44,7 +44,7 @@ function FieldWithPrompt({
<StyledCheckboxField <StyledCheckboxField
isDisabled={isDisabled} isDisabled={isDisabled}
id={promptId} id={promptId}
label={i18n._(t`Prompt on launch`)} label={t`Prompt on launch`}
name={promptName} name={promptName}
/> />
</FieldHeader> </FieldHeader>
@@ -67,4 +67,4 @@ FieldWithPrompt.defaultProps = {
tooltip: null, tooltip: null,
}; };
export default withI18n()(FieldWithPrompt); export default FieldWithPrompt;

View File

@@ -1,32 +1,32 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { ActionGroup, Button } from '@patternfly/react-core'; import { ActionGroup, Button } from '@patternfly/react-core';
import { FormFullWidthLayout } from '../FormLayout'; import { FormFullWidthLayout } from '../FormLayout';
const FormActionGroup = ({ onCancel, onSubmit, submitDisabled, i18n }) => { const FormActionGroup = ({ onCancel, onSubmit, submitDisabled }) => {
return ( return (
<FormFullWidthLayout> <FormFullWidthLayout>
<ActionGroup> <ActionGroup>
<Button <Button
ouiaId="form-save-button" ouiaId="form-save-button"
aria-label={i18n._(t`Save`)} aria-label={t`Save`}
variant="primary" variant="primary"
type="button" type="button"
onClick={onSubmit} onClick={onSubmit}
isDisabled={submitDisabled} isDisabled={submitDisabled}
> >
{i18n._(t`Save`)} {t`Save`}
</Button> </Button>
<Button <Button
ouiaId="form-cancel-button" ouiaId="form-cancel-button"
aria-label={i18n._(t`Cancel`)} aria-label={t`Cancel`}
variant="link" variant="link"
type="button" type="button"
onClick={onCancel} onClick={onCancel}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button> </Button>
</ActionGroup> </ActionGroup>
</FormFullWidthLayout> </FormFullWidthLayout>
@@ -43,4 +43,4 @@ FormActionGroup.defaultProps = {
submitDisabled: false, submitDisabled: false,
}; };
export default withI18n()(FormActionGroup); export default FormActionGroup;

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import { import {
@@ -12,15 +12,7 @@ import {
import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons'; import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons';
function PasswordInput(props) { function PasswordInput(props) {
const { const { autocomplete, id, name, validate, isRequired, isDisabled } = props;
autocomplete,
id,
name,
validate,
isRequired,
isDisabled,
i18n,
} = props;
const [inputType, setInputType] = useState('password'); const [inputType, setInputType] = useState('password');
const [field, meta] = useField({ name, validate }); const [field, meta] = useField({ name, validate });
@@ -32,13 +24,11 @@ function PasswordInput(props) {
return ( return (
<> <>
<Tooltip <Tooltip content={inputType === 'password' ? t`Show` : t`Hide`}>
content={inputType === 'password' ? i18n._(t`Show`) : i18n._(t`Hide`)}
>
<Button <Button
ouiaId={`${id}-toggle`} ouiaId={`${id}-toggle`}
variant={ButtonVariant.control} variant={ButtonVariant.control}
aria-label={i18n._(t`Toggle Password`)} aria-label={t`Toggle Password`}
onClick={handlePasswordToggle} onClick={handlePasswordToggle}
isDisabled={isDisabled} isDisabled={isDisabled}
> >
@@ -80,4 +70,4 @@ PasswordInput.defaultProps = {
isDisabled: false, isDisabled: false,
}; };
export default withI18n()(PasswordInput); export default PasswordInput;

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { bool, func, shape } from 'prop-types'; import { bool, func, shape } from 'prop-types';
import { Formik, useField } from 'formik'; import { Formik, useField } from 'formik';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Form, FormGroup } from '@patternfly/react-core'; import { Form, FormGroup } from '@patternfly/react-core';
@@ -13,24 +13,22 @@ import { FormColumnLayout, FormFullWidthLayout } from '../FormLayout';
import Popover from '../Popover'; import Popover from '../Popover';
import { required } from '../../util/validators'; import { required } from '../../util/validators';
const InventoryLookupField = withI18n()(({ i18n, host }) => { const InventoryLookupField = ({ host }) => {
const [inventory, setInventory] = useState( const [inventory, setInventory] = useState(
host ? host.summary_fields.inventory : '' host ? host.summary_fields.inventory : ''
); );
const [, inventoryMeta, inventoryHelpers] = useField({ const [, inventoryMeta, inventoryHelpers] = useField({
name: 'inventory', name: 'inventory',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
return ( return (
<FormGroup <FormGroup
label={i18n._(t`Inventory`)} label={t`Inventory`}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`Select the inventory that this host will belong to.`}
t`Select the inventory that this host will belong to.`
)}
/> />
} }
isRequired isRequired
@@ -44,7 +42,7 @@ const InventoryLookupField = withI18n()(({ i18n, host }) => {
fieldId="inventory-lookup" fieldId="inventory-lookup"
value={inventory} value={inventory}
onBlur={() => inventoryHelpers.setTouched()} onBlur={() => inventoryHelpers.setTouched()}
tooltip={i18n._(t`Select the inventory that this host will belong to.`)} tooltip={t`Select the inventory that this host will belong to.`}
isValid={!inventoryMeta.touched || !inventoryMeta.error} isValid={!inventoryMeta.touched || !inventoryMeta.error}
helperTextInvalid={inventoryMeta.error} helperTextInvalid={inventoryMeta.error}
onChange={value => { onChange={value => {
@@ -57,14 +55,14 @@ const InventoryLookupField = withI18n()(({ i18n, host }) => {
/> />
</FormGroup> </FormGroup>
); );
}); };
const HostForm = ({ const HostForm = ({
handleCancel, handleCancel,
handleSubmit, handleSubmit,
host, host,
isInventoryVisible, isInventoryVisible,
i18n,
submitError, submitError,
}) => { }) => {
return ( return (
@@ -84,22 +82,22 @@ const HostForm = ({
id="host-name" id="host-name"
name="name" name="name"
type="text" type="text"
label={i18n._(t`Name`)} label={t`Name`}
validate={required(null, i18n)} validate={required(null)}
isRequired isRequired
/> />
<FormField <FormField
id="host-description" id="host-description"
name="description" name="description"
type="text" type="text"
label={i18n._(t`Description`)} label={t`Description`}
/> />
{isInventoryVisible && <InventoryLookupField host={host} />} {isInventoryVisible && <InventoryLookupField host={host} />}
<FormFullWidthLayout> <FormFullWidthLayout>
<VariablesField <VariablesField
id="host-variables" id="host-variables"
name="variables" name="variables"
label={i18n._(t`Variables`)} label={t`Variables`}
/> />
</FormFullWidthLayout> </FormFullWidthLayout>
{submitError && <FormSubmitError error={submitError} />} {submitError && <FormSubmitError error={submitError} />}
@@ -137,4 +135,4 @@ HostForm.defaultProps = {
}; };
export { HostForm as _HostForm }; export { HostForm as _HostForm };
export default withI18n()(HostForm); export default HostForm;

View File

@@ -1,6 +1,6 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React, { Fragment, useState, useEffect, useCallback } from 'react'; import React, { Fragment, useState, useEffect, useCallback } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core'; import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
@@ -9,16 +9,13 @@ import useRequest from '../../util/useRequest';
import { HostsAPI } from '../../api'; import { HostsAPI } from '../../api';
function HostToggle({ function HostToggle({
i18n,
className, className,
host, host,
isDisabled = false, isDisabled = false,
onToggle, onToggle,
tooltip = i18n._( tooltip = t`Indicates if a host is available and should be included in running
t`Indicates if a host is available and should be included in running
jobs. For hosts that are part of an external inventory, this may be jobs. For hosts that are part of an external inventory, this may be
reset by the inventory sync process.` reset by the inventory sync process.`,
),
}) { }) {
const [isEnabled, setIsEnabled] = useState(host.enabled); const [isEnabled, setIsEnabled] = useState(host.enabled);
const [showError, setShowError] = useState(false); const [showError, setShowError] = useState(false);
@@ -55,8 +52,8 @@ function HostToggle({
className={className} className={className}
css="display: inline-flex;" css="display: inline-flex;"
id={`host-${host.id}-toggle`} id={`host-${host.id}-toggle`}
label={i18n._(t`On`)} label={t`On`}
labelOff={i18n._(t`Off`)} labelOff={t`Off`}
isChecked={isEnabled} isChecked={isEnabled}
isDisabled={ isDisabled={
isLoading || isLoading ||
@@ -64,17 +61,17 @@ function HostToggle({
!host.summary_fields.user_capabilities.edit !host.summary_fields.user_capabilities.edit
} }
onChange={toggleHost} onChange={toggleHost}
aria-label={i18n._(t`Toggle host`)} aria-label={t`Toggle host`}
/> />
</Tooltip> </Tooltip>
{showError && error && !isLoading && ( {showError && error && !isLoading && (
<AlertModal <AlertModal
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
isOpen={error && !isLoading} isOpen={error && !isLoading}
onClose={() => setShowError(false)} onClose={() => setShowError(false)}
> >
{i18n._(t`Failed to toggle host.`)} {t`Failed to toggle host.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</AlertModal> </AlertModal>
)} )}
@@ -82,4 +79,4 @@ function HostToggle({
); );
} }
export default withI18n()(HostToggle); export default HostToggle;

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core'; import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
@@ -8,13 +8,7 @@ import useRequest from '../../util/useRequest';
import { InstancesAPI } from '../../api'; import { InstancesAPI } from '../../api';
import { useConfig } from '../../contexts/Config'; import { useConfig } from '../../contexts/Config';
function InstanceToggle({ function InstanceToggle({ className, fetchInstances, instance, onToggle }) {
className,
fetchInstances,
instance,
onToggle,
i18n,
}) {
const { me = {} } = useConfig(); const { me = {} } = useConfig();
const [isEnabled, setIsEnabled] = useState(instance.enabled); const [isEnabled, setIsEnabled] = useState(instance.enabled);
const [showError, setShowError] = useState(false); const [showError, setShowError] = useState(false);
@@ -46,31 +40,29 @@ function InstanceToggle({
return ( return (
<> <>
<Tooltip <Tooltip
content={i18n._( content={t`Set the instance online or offline. If offline, jobs will not be assigned to this instance.`}
t`Set the instance online or offline. If offline, jobs will not be assigned to this instance.`
)}
position="top" position="top"
> >
<Switch <Switch
className={className} className={className}
css="display: inline-flex;" css="display: inline-flex;"
id={`host-${instance.id}-toggle`} id={`host-${instance.id}-toggle`}
label={i18n._(t`On`)} label={t`On`}
labelOff={i18n._(t`Off`)} labelOff={t`Off`}
isChecked={isEnabled} isChecked={isEnabled}
isDisabled={isLoading || !me?.is_superuser} isDisabled={isLoading || !me?.is_superuser}
onChange={toggleInstance} onChange={toggleInstance}
aria-label={i18n._(t`Toggle instance`)} aria-label={t`Toggle instance`}
/> />
</Tooltip> </Tooltip>
{showError && error && !isLoading && ( {showError && error && !isLoading && (
<AlertModal <AlertModal
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
isOpen={error && !isLoading} isOpen={error && !isLoading}
onClose={() => setShowError(false)} onClose={() => setShowError(false)}
> >
{i18n._(t`Failed to toggle instance.`)} {t`Failed to toggle instance.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</AlertModal> </AlertModal>
)} )}
@@ -78,4 +70,4 @@ function InstanceToggle({
); );
} }
export default withI18n()(InstanceToggle); export default InstanceToggle;

View File

@@ -1,5 +1,5 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { withI18n } from '@lingui/react';
import { t, Plural } from '@lingui/macro'; import { t, Plural } from '@lingui/macro';
import { arrayOf, func } from 'prop-types'; import { arrayOf, func } from 'prop-types';
import { Button, DropdownItem, Tooltip } from '@patternfly/react-core'; import { Button, DropdownItem, Tooltip } from '@patternfly/react-core';
@@ -18,7 +18,7 @@ function cannotCancelBecauseNotRunning(job) {
return !isJobRunning(job.status); return !isJobRunning(job.status);
} }
function JobListCancelButton({ i18n, jobsToCancel, onCancel }) { function JobListCancelButton({ jobsToCancel, onCancel }) {
const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext); const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const numJobsToCancel = jobsToCancel.length; const numJobsToCancel = jobsToCancel.length;
@@ -90,12 +90,12 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
return ( return (
<Plural <Plural
value={numJobsToCancel} value={numJobsToCancel}
one={i18n._(t`Cancel selected job`)} one={t`Cancel selected job`}
other={i18n._(t`Cancel selected jobs`)} other={t`Cancel selected jobs`}
/> />
); );
} }
return i18n._(t`Select a job to cancel`); return t`Select a job to cancel`;
}; };
const isDisabled = const isDisabled =
@@ -156,10 +156,10 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
id="cancel-job-return-button" id="cancel-job-return-button"
key="cancel" key="cancel"
variant="secondary" variant="secondary"
aria-label={i18n._(t`Return`)} aria-label={t`Return`}
onClick={toggleModal} onClick={toggleModal}
> >
{i18n._(t`Return`)} {t`Return`}
</Button>, </Button>,
]} ]}
> >
@@ -192,4 +192,4 @@ JobListCancelButton.defaultProps = {
onCancel: () => {}, onCancel: () => {},
}; };
export default withI18n()(JobListCancelButton); export default JobListCancelButton;

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Button, Chip } from '@patternfly/react-core'; import { Button, Chip } from '@patternfly/react-core';
import { Tr, Td, ExpandableRowContent } from '@patternfly/react-table'; import { Tr, Td, ExpandableRowContent } from '@patternfly/react-table';
@@ -18,7 +18,6 @@ import { JOB_TYPE_URL_SEGMENTS } from '../../constants';
const Dash = styled.span``; const Dash = styled.span``;
function JobListItem({ function JobListItem({
i18n,
job, job,
rowIndex, rowIndex,
isSelected, isSelected,
@@ -29,12 +28,12 @@ function JobListItem({
const [isExpanded, setIsExpanded] = useState(false); const [isExpanded, setIsExpanded] = useState(false);
const jobTypes = { const jobTypes = {
project_update: i18n._(t`Source Control Update`), project_update: t`Source Control Update`,
inventory_update: i18n._(t`Inventory Sync`), inventory_update: t`Inventory Sync`,
job: i18n._(t`Playbook Run`), job: t`Playbook Run`,
ad_hoc_command: i18n._(t`Command`), ad_hoc_command: t`Command`,
system_job: i18n._(t`Management Job`), system_job: t`Management Job`,
workflow_job: i18n._(t`Workflow Job`), workflow_job: t`Workflow Job`,
}; };
const { const {
@@ -64,9 +63,9 @@ function JobListItem({
isSelected, isSelected,
onSelect, onSelect,
}} }}
dataLabel={i18n._(t`Select`)} dataLabel={t`Select`}
/> />
<Td id={labelId} dataLabel={i18n._(t`Name`)}> <Td id={labelId} dataLabel={t`Name`}>
<span> <span>
<Link to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}> <Link to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}>
<b> <b>
@@ -75,19 +74,15 @@ function JobListItem({
</Link> </Link>
</span> </span>
</Td> </Td>
<Td dataLabel={i18n._(t`Status`)}> <Td dataLabel={t`Status`}>
{job.status && <StatusLabel status={job.status} />} {job.status && <StatusLabel status={job.status} />}
</Td> </Td>
{showTypeColumn && ( {showTypeColumn && <Td dataLabel={t`Type`}>{jobTypes[job.type]}</Td>}
<Td dataLabel={i18n._(t`Type`)}>{jobTypes[job.type]}</Td> <Td dataLabel={t`Start Time`}>{formatDateString(job.started)}</Td>
)} <Td dataLabel={t`Finish Time`}>
<Td dataLabel={i18n._(t`Start Time`)}>
{formatDateString(job.started)}
</Td>
<Td dataLabel={i18n._(t`Finish Time`)}>
{job.finished ? formatDateString(job.finished) : ''} {job.finished ? formatDateString(job.finished) : ''}
</Td> </Td>
<ActionsTd dataLabel={i18n._(t`Actions`)}> <ActionsTd dataLabel={t`Actions`}>
<ActionItem <ActionItem
visible={ visible={
job.type !== 'system_job' && job.type !== 'system_job' &&
@@ -95,8 +90,8 @@ function JobListItem({
} }
tooltip={ tooltip={
job.status === 'failed' && job.type === 'job' job.status === 'failed' && job.type === 'job'
? i18n._(t`Relaunch using host parameters`) ? t`Relaunch using host parameters`
: i18n._(t`Relaunch Job`) : t`Relaunch Job`
} }
> >
{job.status === 'failed' && job.type === 'job' ? ( {job.status === 'failed' && job.type === 'job' ? (
@@ -115,7 +110,7 @@ function JobListItem({
ouiaId={`${job.id}-relaunch-button`} ouiaId={`${job.id}-relaunch-button`}
variant="plain" variant="plain"
onClick={handleRelaunch} onClick={handleRelaunch}
aria-label={i18n._(t`Relaunch`)} aria-label={t`Relaunch`}
isDisabled={isLaunching} isDisabled={isLaunching}
> >
<RocketIcon /> <RocketIcon />
@@ -131,10 +126,10 @@ function JobListItem({
<Td colSpan={showTypeColumn ? 6 : 5}> <Td colSpan={showTypeColumn ? 6 : 5}>
<ExpandableRowContent> <ExpandableRowContent>
<DetailList> <DetailList>
<LaunchedByDetail job={job} i18n={i18n} /> <LaunchedByDetail job={job} />
{job_template && ( {job_template && (
<Detail <Detail
label={i18n._(t`Job Template`)} label={t`Job Template`}
value={ value={
<Link to={`/templates/job_template/${job_template.id}`}> <Link to={`/templates/job_template/${job_template.id}`}>
{job_template.name} {job_template.name}
@@ -144,7 +139,7 @@ function JobListItem({
)} )}
{workflow_job_template && ( {workflow_job_template && (
<Detail <Detail
label={i18n._(t`Workflow Job Template`)} label={t`Workflow Job Template`}
value={ value={
<Link <Link
to={`/templates/workflow_job_template/${workflow_job_template.id}`} to={`/templates/workflow_job_template/${workflow_job_template.id}`}
@@ -156,7 +151,7 @@ function JobListItem({
)} )}
{source_workflow_job && ( {source_workflow_job && (
<Detail <Detail
label={i18n._(t`Source Workflow Job`)} label={t`Source Workflow Job`}
value={ value={
<Link to={`/jobs/workflow/${source_workflow_job.id}`}> <Link to={`/jobs/workflow/${source_workflow_job.id}`}>
{source_workflow_job.id} - {source_workflow_job.name} {source_workflow_job.id} - {source_workflow_job.name}
@@ -166,7 +161,7 @@ function JobListItem({
)} )}
{inventory && ( {inventory && (
<Detail <Detail
label={i18n._(t`Inventory`)} label={t`Inventory`}
value={ value={
<Link <Link
to={ to={
@@ -182,7 +177,7 @@ function JobListItem({
)} )}
{project && ( {project && (
<Detail <Detail
label={i18n._(t`Project`)} label={t`Project`}
value={ value={
<Link to={`/projects/${project.id}/details`}> <Link to={`/projects/${project.id}/details`}>
{project.name} {project.name}
@@ -198,7 +193,7 @@ function JobListItem({
{credentials && credentials.length > 0 && ( {credentials && credentials.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credentials`)} label={t`Credentials`}
value={ value={
<ChipGroup numChips={5} totalChips={credentials.length}> <ChipGroup numChips={5} totalChips={credentials.length}>
{credentials.map(c => ( {credentials.map(c => (
@@ -211,7 +206,7 @@ function JobListItem({
{labels && labels.count > 0 && ( {labels && labels.count > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Labels`)} label={t`Labels`}
value={ value={
<ChipGroup numChips={5} totalChips={labels.results.length}> <ChipGroup numChips={5} totalChips={labels.results.length}>
{labels.results.map(l => ( {labels.results.map(l => (
@@ -226,7 +221,7 @@ function JobListItem({
{job.job_explanation && ( {job.job_explanation && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Explanation`)} label={t`Explanation`}
value={job.job_explanation} value={job.job_explanation}
/> />
)} )}
@@ -239,4 +234,4 @@ function JobListItem({
} }
export { JobListItem as _JobListItem }; export { JobListItem as _JobListItem };
export default withI18n()(JobListItem); export default JobListItem;

View File

@@ -1,7 +1,7 @@
import React, { Fragment, useState } from 'react'; import React, { Fragment, useState } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { number, shape } from 'prop-types'; import { number, shape } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
@@ -32,7 +32,7 @@ function canLaunchWithoutPrompt(launchData) {
); );
} }
function LaunchButton({ resource, i18n, children, history }) { function LaunchButton({ resource, children, history }) {
const [showLaunchPrompt, setShowLaunchPrompt] = useState(false); const [showLaunchPrompt, setShowLaunchPrompt] = useState(false);
const [launchConfig, setLaunchConfig] = useState(null); const [launchConfig, setLaunchConfig] = useState(null);
const [surveyConfig, setSurveyConfig] = useState(null); const [surveyConfig, setSurveyConfig] = useState(null);
@@ -168,10 +168,10 @@ function LaunchButton({ resource, i18n, children, history }) {
<AlertModal <AlertModal
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={() => setError(null)} onClose={() => setError(null)}
> >
{i18n._(t`Failed to launch job.`)} {t`Failed to launch job.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</AlertModal> </AlertModal>
)} )}
@@ -195,4 +195,4 @@ LaunchButton.propTypes = {
}).isRequired, }).isRequired,
}; };
export default withI18n()(withRouter(LaunchButton)); export default withRouter(LaunchButton);

View File

@@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Dropdown, Dropdown,
@@ -15,7 +15,7 @@ function ReLaunchDropDown({
isPrimary = false, isPrimary = false,
handleRelaunch, handleRelaunch,
isLaunching, isLaunching,
i18n,
ouiaId, ouiaId,
}) { }) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
@@ -27,38 +27,38 @@ function ReLaunchDropDown({
const dropdownItems = [ const dropdownItems = [
<DropdownItem <DropdownItem
ouiaId={`${ouiaId}-on`} ouiaId={`${ouiaId}-on`}
aria-label={i18n._(t`Relaunch on`)} aria-label={t`Relaunch on`}
key="relaunch_on" key="relaunch_on"
component="div" component="div"
isPlainText isPlainText
> >
{i18n._(t`Relaunch on`)} {t`Relaunch on`}
</DropdownItem>, </DropdownItem>,
<DropdownSeparator key="separator" />, <DropdownSeparator key="separator" />,
<DropdownItem <DropdownItem
ouiaId={`${ouiaId}-all`} ouiaId={`${ouiaId}-all`}
key="relaunch_all" key="relaunch_all"
aria-label={i18n._(t`Relaunch all hosts`)} aria-label={t`Relaunch all hosts`}
component="button" component="button"
onClick={() => { onClick={() => {
handleRelaunch({ hosts: 'all' }); handleRelaunch({ hosts: 'all' });
}} }}
isDisabled={isLaunching} isDisabled={isLaunching}
> >
{i18n._(t`All`)} {t`All`}
</DropdownItem>, </DropdownItem>,
<DropdownItem <DropdownItem
ouiaId={`${ouiaId}-failed`} ouiaId={`${ouiaId}-failed`}
key="relaunch_failed" key="relaunch_failed"
aria-label={i18n._(t`Relaunch failed hosts`)} aria-label={t`Relaunch failed hosts`}
component="button" component="button"
onClick={() => { onClick={() => {
handleRelaunch({ hosts: 'failed' }); handleRelaunch({ hosts: 'failed' });
}} }}
isDisabled={isLaunching} isDisabled={isLaunching}
> >
{i18n._(t`Failed hosts`)} {t`Failed hosts`}
</DropdownItem>, </DropdownItem>,
]; ];
@@ -74,11 +74,11 @@ function ReLaunchDropDown({
<DropdownToggle <DropdownToggle
toggleIndicator={null} toggleIndicator={null}
onToggle={onToggle} onToggle={onToggle}
aria-label={i18n._(t`relaunch jobs`)} aria-label={t`relaunch jobs`}
id="relaunch_jobs" id="relaunch_jobs"
isPrimary isPrimary
> >
{i18n._(t`Relaunch`)} {t`Relaunch`}
</DropdownToggle> </DropdownToggle>
} }
/> />
@@ -96,7 +96,7 @@ function ReLaunchDropDown({
<DropdownToggle <DropdownToggle
toggleIndicator={null} toggleIndicator={null}
onToggle={onToggle} onToggle={onToggle}
aria-label={i18n._(t`relaunch jobs`)} aria-label={t`relaunch jobs`}
id="relaunch_jobs" id="relaunch_jobs"
> >
<RocketIcon /> <RocketIcon />
@@ -106,4 +106,4 @@ function ReLaunchDropDown({
); );
} }
export default withI18n()(ReLaunchDropDown); export default ReLaunchDropDown;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Wizard } from '@patternfly/react-core'; import { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Formik, useFormikContext } from 'formik'; import { Formik, useFormikContext } from 'formik';
import ContentError from '../ContentError'; import ContentError from '../ContentError';
@@ -13,7 +13,7 @@ import AlertModal from '../AlertModal';
function PromptModalForm({ function PromptModalForm({
launchConfig, launchConfig,
i18n,
onCancel, onCancel,
onSubmit, onSubmit,
resource, resource,
@@ -33,7 +33,7 @@ function PromptModalForm({
launchConfig, launchConfig,
surveyConfig, surveyConfig,
resource, resource,
i18n,
resourceDefaultCredentials resourceDefaultCredentials
); );
@@ -70,7 +70,7 @@ function PromptModalForm({
<AlertModal <AlertModal
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={() => { onClose={() => {
dismissError(); dismissError();
}} }}
@@ -104,27 +104,27 @@ function PromptModalForm({
validateStep(nextStep.id); validateStep(nextStep.id);
} }
}} }}
title={i18n._(t`Prompts`)} title={t`Prompts`}
steps={ steps={
isReady isReady
? steps ? steps
: [ : [
{ {
name: i18n._(t`Content Loading`), name: t`Content Loading`,
component: <ContentLoading />, component: <ContentLoading />,
}, },
] ]
} }
backButtonText={i18n._(t`Back`)} backButtonText={t`Back`}
cancelButtonText={i18n._(t`Cancel`)} cancelButtonText={t`Cancel`}
nextButtonText={i18n._(t`Next`)} nextButtonText={t`Next`}
/> />
); );
} }
function LaunchPrompt({ function LaunchPrompt({
launchConfig, launchConfig,
i18n,
onCancel, onCancel,
onLaunch, onLaunch,
resource = {}, resource = {},
@@ -136,7 +136,6 @@ function LaunchPrompt({
<PromptModalForm <PromptModalForm
onSubmit={values => onLaunch(values)} onSubmit={values => onLaunch(values)}
onCancel={onCancel} onCancel={onCancel}
i18n={i18n}
launchConfig={launchConfig} launchConfig={launchConfig}
surveyConfig={surveyConfig} surveyConfig={surveyConfig}
resource={resource} resource={resource}
@@ -147,4 +146,4 @@ function LaunchPrompt({
} }
export { LaunchPrompt as _LaunchPrompt }; export { LaunchPrompt as _LaunchPrompt };
export default withI18n()(LaunchPrompt); export default LaunchPrompt;

View File

@@ -1,11 +1,11 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Form } from '@patternfly/react-core'; import { Form } from '@patternfly/react-core';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { PasswordField } from '../../FormField'; import { PasswordField } from '../../FormField';
function CredentialPasswordsStep({ launchConfig, i18n }) { function CredentialPasswordsStep({ launchConfig }) {
const { const {
values: { credentials }, values: { credentials },
} = useFormikContext(); } = useFormikContext();
@@ -92,7 +92,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordSsh && ( {showcredentialPasswordSsh && (
<PasswordField <PasswordField
id="launch-ssh-password" id="launch-ssh-password"
label={i18n._(t`SSH password`)} label={t`SSH password`}
name="credential_passwords.ssh_password" name="credential_passwords.ssh_password"
isRequired isRequired
/> />
@@ -100,7 +100,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordPrivateKeyPassphrase && ( {showcredentialPasswordPrivateKeyPassphrase && (
<PasswordField <PasswordField
id="launch-private-key-passphrase" id="launch-private-key-passphrase"
label={i18n._(t`Private key passphrase`)} label={t`Private key passphrase`}
name="credential_passwords.ssh_key_unlock" name="credential_passwords.ssh_key_unlock"
isRequired isRequired
/> />
@@ -108,7 +108,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordPrivilegeEscalation && ( {showcredentialPasswordPrivilegeEscalation && (
<PasswordField <PasswordField
id="launch-privilege-escalation-password" id="launch-privilege-escalation-password"
label={i18n._(t`Privilege escalation password`)} label={t`Privilege escalation password`}
name="credential_passwords.become_password" name="credential_passwords.become_password"
isRequired isRequired
/> />
@@ -118,9 +118,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
id={`launch-vault-password-${credId}`} id={`launch-vault-password-${credId}`}
key={credId} key={credId}
label={ label={
credId === '' credId === '' ? t`Vault password` : t`Vault password | ${credId}`
? i18n._(t`Vault password`)
: i18n._(t`Vault password | ${credId}`)
} }
name={`credential_passwords['vault_password${ name={`credential_passwords['vault_password${
credId !== '' ? `.${credId}` : '' credId !== '' ? `.${credId}` : ''
@@ -132,4 +130,4 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
); );
} }
export default withI18n()(CredentialPasswordsStep); export default CredentialPasswordsStep;

View File

@@ -1,7 +1,7 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React, { useState, useCallback, useEffect } from 'react'; import React, { useState, useCallback, useEffect } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -27,7 +27,6 @@ const QS_CONFIG = getQSConfig('credential', {
}); });
function CredentialsStep({ function CredentialsStep({
i18n,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
defaultCredentials = [], defaultCredentials = [],
}) { }) {
@@ -35,7 +34,6 @@ function CredentialsStep({
name: 'credentials', name: 'credentials',
validate: val => { validate: val => {
return credentialsValidator( return credentialsValidator(
i18n,
defaultCredentials, defaultCredentials,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
val val
@@ -106,7 +104,6 @@ function CredentialsStep({
useEffect(() => { useEffect(() => {
helpers.setError( helpers.setError(
credentialsValidator( credentialsValidator(
i18n,
defaultCredentials, defaultCredentials,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
field.value field.value
@@ -145,12 +142,12 @@ function CredentialsStep({
{types && types.length > 0 && ( {types && types.length > 0 && (
<ToolbarItem css=" display: flex; align-items: center;"> <ToolbarItem css=" display: flex; align-items: center;">
<div css="flex: 0 0 25%; margin-right: 32px"> <div css="flex: 0 0 25%; margin-right: 32px">
{i18n._(t`Selected Category`)} {t`Selected Category`}
</div> </div>
<AnsibleSelect <AnsibleSelect
css="flex: 1 1 75%;" css="flex: 1 1 75%;"
id="multiCredentialsLookUp-select" id="multiCredentialsLookUp-select"
label={i18n._(t`Selected Category`)} label={t`Selected Category`}
data={types.map(type => ({ data={types.map(type => ({
key: type.id, key: type.id,
value: type.id, value: type.id,
@@ -171,29 +168,29 @@ function CredentialsStep({
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={isVault} multiple={isVault}
header={i18n._(t`Credentials`)} header={t`Credentials`}
name="credentials" name="credentials"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={false} readOnly={false}
@@ -218,4 +215,4 @@ function CredentialsStep({
); );
} }
export default withI18n()(CredentialsStep); export default CredentialsStep;

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -22,7 +22,7 @@ const QS_CONFIG = getQSConfig('inventory', {
order_by: 'name', order_by: 'name',
}); });
function InventoryStep({ i18n, warningMessage = null }) { function InventoryStep({ warningMessage = null }) {
const [field, meta, helpers] = useField({ const [field, meta, helpers] = useField({
name: 'inventory', name: 'inventory',
}); });
@@ -83,28 +83,28 @@ function InventoryStep({ i18n, warningMessage = null }) {
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
header={i18n._(t`Inventory`)} header={t`Inventory`}
name="inventory" name="inventory"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly readOnly
@@ -115,4 +115,4 @@ function InventoryStep({ i18n, warningMessage = null }) {
); );
} }
export default withI18n()(InventoryStep); export default InventoryStep;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import { Form, FormGroup, Switch } from '@patternfly/react-core'; import { Form, FormGroup, Switch } from '@patternfly/react-core';
@@ -20,88 +20,84 @@ const FieldHeader = styled.div`
} }
`; `;
function OtherPromptsStep({ launchConfig, i18n }) { function OtherPromptsStep({ launchConfig }) {
return ( return (
<Form <Form
onSubmit={e => { onSubmit={e => {
e.preventDefault(); e.preventDefault();
}} }}
> >
{launchConfig.ask_job_type_on_launch && <JobTypeField i18n={i18n} />} {launchConfig.ask_job_type_on_launch && <JobTypeField />}
{launchConfig.ask_limit_on_launch && ( {launchConfig.ask_limit_on_launch && (
<FormField <FormField
id="prompt-limit" id="prompt-limit"
name="limit" name="limit"
label={i18n._(t`Limit`)} label={t`Limit`}
tooltip={i18n._(t`Provide a host pattern to further constrain the list tooltip={t`Provide a host pattern to further constrain the list
of hosts that will be managed or affected by the playbook. Multiple of hosts that will be managed or affected by the playbook. Multiple
patterns are allowed. Refer to Ansible documentation for more patterns are allowed. Refer to Ansible documentation for more
information and examples on patterns.`)} information and examples on patterns.`}
/> />
)} )}
{launchConfig.ask_scm_branch_on_launch && ( {launchConfig.ask_scm_branch_on_launch && (
<FormField <FormField
id="prompt-scm-branch" id="prompt-scm-branch"
name="scm_branch" name="scm_branch"
label={i18n._(t`Source Control Branch`)} label={t`Source Control Branch`}
tooltip={i18n._( tooltip={t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch`}
t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch`
)}
/> />
)} )}
{launchConfig.ask_verbosity_on_launch && <VerbosityField i18n={i18n} />} {launchConfig.ask_verbosity_on_launch && <VerbosityField />}
{launchConfig.ask_diff_mode_on_launch && ( {launchConfig.ask_diff_mode_on_launch && <ShowChangesToggle />}
<ShowChangesToggle i18n={i18n} />
)}
{launchConfig.ask_tags_on_launch && ( {launchConfig.ask_tags_on_launch && (
<TagField <TagField
id="prompt-job-tags" id="prompt-job-tags"
name="job_tags" name="job_tags"
label={i18n._(t`Job Tags`)} label={t`Job Tags`}
aria-label={i18n._(t`Job Tags`)} aria-label={t`Job Tags`}
tooltip={i18n._(t`Tags are useful when you have a large tooltip={t`Tags are useful when you have a large
playbook, and you want to run a specific part of a play or task. playbook, and you want to run a specific part of a play or task.
Use commas to separate multiple tags. Refer to Ansible Tower Use commas to separate multiple tags. Refer to Ansible Tower
documentation for details on the usage of tags.`)} documentation for details on the usage of tags.`}
/> />
)} )}
{launchConfig.ask_skip_tags_on_launch && ( {launchConfig.ask_skip_tags_on_launch && (
<TagField <TagField
id="prompt-skip-tags" id="prompt-skip-tags"
name="skip_tags" name="skip_tags"
label={i18n._(t`Skip Tags`)} label={t`Skip Tags`}
aria-label={i18n._(t`Skip Tags`)} aria-label={t`Skip Tags`}
tooltip={i18n._(t`Skip tags are useful when you have a large tooltip={t`Skip tags are useful when you have a large
playbook, and you want to skip specific parts of a play or task. playbook, and you want to skip specific parts of a play or task.
Use commas to separate multiple tags. Refer to Ansible Tower Use commas to separate multiple tags. Refer to Ansible Tower
documentation for details on the usage of tags.`)} documentation for details on the usage of tags.`}
/> />
)} )}
{launchConfig.ask_variables_on_launch && ( {launchConfig.ask_variables_on_launch && (
<VariablesField <VariablesField
id="prompt-variables" id="prompt-variables"
name="extra_vars" name="extra_vars"
label={i18n._(t`Variables`)} label={t`Variables`}
/> />
)} )}
</Form> </Form>
); );
} }
function JobTypeField({ i18n }) { function JobTypeField() {
const [field, meta, helpers] = useField('job_type'); const [field, meta, helpers] = useField('job_type');
const options = [ const options = [
{ {
value: '', value: '',
key: '', key: '',
label: i18n._(t`Choose a job type`), label: t`Choose a job type`,
isDisabled: true, isDisabled: true,
}, },
{ value: 'run', key: 'run', label: i18n._(t`Run`), isDisabled: false }, { value: 'run', key: 'run', label: t`Run`, isDisabled: false },
{ {
value: 'check', value: 'check',
key: 'check', key: 'check',
label: i18n._(t`Check`), label: t`Check`,
isDisabled: false, isDisabled: false,
}, },
]; ];
@@ -109,12 +105,12 @@ function JobTypeField({ i18n }) {
return ( return (
<FormGroup <FormGroup
fieldId="propmt-job-type" fieldId="propmt-job-type"
label={i18n._(t`Job Type`)} label={t`Job Type`}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._(t`For job templates, select run to execute the playbook. content={t`For job templates, select run to execute the playbook.
Select check to only check playbook syntax, test environment setup, Select check to only check playbook syntax, test environment setup,
and report problems without executing the playbook.`)} and report problems without executing the playbook.`}
/> />
} }
isRequired isRequired
@@ -130,14 +126,14 @@ function JobTypeField({ i18n }) {
); );
} }
function VerbosityField({ i18n }) { function VerbosityField() {
const [field, meta, helpers] = useField('verbosity'); const [field, meta, helpers] = useField('verbosity');
const options = [ const options = [
{ value: '0', key: '0', label: i18n._(t`0 (Normal)`) }, { value: '0', key: '0', label: t`0 (Normal)` },
{ value: '1', key: '1', label: i18n._(t`1 (Verbose)`) }, { value: '1', key: '1', label: t`1 (Verbose)` },
{ value: '2', key: '2', label: i18n._(t`2 (More Verbose)`) }, { value: '2', key: '2', label: t`2 (More Verbose)` },
{ value: '3', key: '3', label: i18n._(t`3 (Debug)`) }, { value: '3', key: '3', label: t`3 (Debug)` },
{ value: '4', key: '4', label: i18n._(t`4 (Connection Debug)`) }, { value: '4', key: '4', label: t`4 (Connection Debug)` },
]; ];
const isValid = !(meta.touched && meta.error); const isValid = !(meta.touched && meta.error);
@@ -146,11 +142,11 @@ function VerbosityField({ i18n }) {
<FormGroup <FormGroup
fieldId="prompt-verbosity" fieldId="prompt-verbosity"
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
label={i18n._(t`Verbosity`)} label={t`Verbosity`}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._(t`Control the level of output ansible content={t`Control the level of output ansible
will produce as the playbook executes.`)} will produce as the playbook executes.`}
/> />
} }
> >
@@ -164,7 +160,7 @@ function VerbosityField({ i18n }) {
); );
} }
function ShowChangesToggle({ i18n }) { function ShowChangesToggle() {
const [field, , helpers] = useField('diff_mode'); const [field, , helpers] = useField('diff_mode');
return ( return (
<FormGroup fieldId="prompt-show-changes"> <FormGroup fieldId="prompt-show-changes">
@@ -172,20 +168,20 @@ function ShowChangesToggle({ i18n }) {
{' '} {' '}
<label className="pf-c-form__label" htmlFor="prompt-show-changes"> <label className="pf-c-form__label" htmlFor="prompt-show-changes">
<span className="pf-c-form__label-text"> <span className="pf-c-form__label-text">
{i18n._(t`Show Changes`)} {t`Show Changes`}
<Popover <Popover
content={i18n._(t`If enabled, show the changes made content={t`If enabled, show the changes made
by Ansible tasks, where supported. This is equivalent to Ansibles by Ansible tasks, where supported. This is equivalent to Ansibles
--diff mode.`)} --diff mode.`}
/> />
</span> </span>
</label> </label>
</FieldHeader> </FieldHeader>
<Switch <Switch
aria-label={field.value ? i18n._(t`On`) : i18n._(t`Off`)} aria-label={field.value ? t`On` : t`Off`}
id="prompt-show-changes" id="prompt-show-changes"
label={i18n._(t`On`)} label={t`On`}
labelOff={i18n._(t`Off`)} labelOff={t`Off`}
isChecked={field.value} isChecked={field.value}
onChange={helpers.setValue} onChange={helpers.setValue}
/> />
@@ -206,4 +202,4 @@ function TagField({ id, name, label, tooltip }) {
); );
} }
export default withI18n()(OtherPromptsStep); export default OtherPromptsStep;

View File

@@ -4,7 +4,7 @@ import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/re
import { Tooltip } from '@patternfly/react-core'; import { Tooltip } from '@patternfly/react-core';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { withI18n } from '@lingui/react';
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import mergeExtraVars, { import mergeExtraVars, {
maskPasswords, maskPasswords,
@@ -25,13 +25,7 @@ const ErrorMessageWrapper = styled.div`
margin-bottom: 10px; margin-bottom: 10px;
`; `;
function PreviewStep({ function PreviewStep({ resource, launchConfig, surveyConfig, formErrors }) {
resource,
launchConfig,
surveyConfig,
formErrors,
i18n,
}) {
const { values } = useFormikContext(); const { values } = useFormikContext();
const surveyValues = getSurveyValues(values); const surveyValues = getSurveyValues(values);
@@ -61,10 +55,10 @@ function PreviewStep({
<Fragment> <Fragment>
{formErrors && ( {formErrors && (
<ErrorMessageWrapper> <ErrorMessageWrapper>
{i18n._(t`Some of the previous step(s) have errors`)} {t`Some of the previous step(s) have errors`}
<Tooltip <Tooltip
position="right" position="right"
content={i18n._(t`See errors on the left`)} content={t`See errors on the left`}
trigger="click mouseenter focus" trigger="click mouseenter focus"
> >
<ExclamationCircleIcon /> <ExclamationCircleIcon />
@@ -80,4 +74,4 @@ function PreviewStep({
); );
} }
export default withI18n()(PreviewStep); export default PreviewStep;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Tooltip } from '@patternfly/react-core'; import { Tooltip } from '@patternfly/react-core';
import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons'; import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons';
@@ -14,7 +14,7 @@ const ExclamationCircleIcon = styled(PFExclamationCircleIcon)`
margin-left: 10px; margin-left: 10px;
`; `;
function StepName({ hasErrors, children, i18n, id }) { function StepName({ hasErrors, children, id }) {
if (!hasErrors) { if (!hasErrors) {
return <div id={id}>{children}</div>; return <div id={id}>{children}</div>;
} }
@@ -24,7 +24,7 @@ function StepName({ hasErrors, children, i18n, id }) {
{children} {children}
<Tooltip <Tooltip
position="right" position="right"
content={i18n._(t`This step contains errors`)} content={t`This step contains errors`}
trigger="click mouseenter focus" trigger="click mouseenter focus"
> >
<ExclamationCircleIcon css="color: var(--pf-global--danger-color--100)" /> <ExclamationCircleIcon css="color: var(--pf-global--danger-color--100)" />
@@ -34,4 +34,4 @@ function StepName({ hasErrors, children, i18n, id }) {
); );
} }
export default withI18n()(StepName); export default StepName;

View File

@@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import { import {
@@ -22,7 +22,7 @@ import {
} from '../../../util/validators'; } from '../../../util/validators';
import { Survey } from '../../../types'; import { Survey } from '../../../types';
function SurveyStep({ surveyConfig, i18n }) { function SurveyStep({ surveyConfig }) {
const fieldTypes = { const fieldTypes = {
text: TextField, text: TextField,
textarea: TextField, textarea: TextField,
@@ -40,9 +40,7 @@ function SurveyStep({ surveyConfig, i18n }) {
> >
{surveyConfig.spec.map(question => { {surveyConfig.spec.map(question => {
const Field = fieldTypes[question.type]; const Field = fieldTypes[question.type];
return ( return <Field key={question.variable} question={question} />;
<Field key={question.variable} question={question} i18n={i18n} />
);
})} })}
</Form> </Form>
); );
@@ -51,11 +49,11 @@ SurveyStep.propTypes = {
surveyConfig: Survey.isRequired, surveyConfig: Survey.isRequired,
}; };
function TextField({ question, i18n }) { function TextField({ question }) {
const validators = [ const validators = [
question.required ? required(null, i18n) : null, question.required ? required(null) : null,
question.required && question.min ? minLength(question.min, i18n) : null, question.required && question.min ? minLength(question.min) : null,
question.required && question.max ? maxLength(question.max, i18n) : null, question.required && question.max ? maxLength(question.max) : null,
]; ];
return ( return (
<FormField <FormField
@@ -72,11 +70,11 @@ function TextField({ question, i18n }) {
); );
} }
function NumberField({ question, i18n }) { function NumberField({ question }) {
const validators = [ const validators = [
question.required ? required(null, i18n) : null, question.required ? required(null) : null,
minMaxValue(question.min, question.max, i18n), minMaxValue(question.min, question.max),
question.type === 'integer' ? integer(i18n) : null, question.type === 'integer' ? integer() : null,
]; ];
return ( return (
<FormField <FormField
@@ -120,11 +118,11 @@ function MultipleChoiceField({ question }) {
); );
} }
function MultiSelectField({ question, i18n }) { function MultiSelectField({ question }) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [field, meta, helpers] = useField({ const [field, meta, helpers] = useField({
name: `survey_${question.variable}`, name: `survey_${question.variable}`,
validate: question.required ? required(null, i18n) : null, validate: question.required ? required(null) : null,
}); });
const id = `survey-question-${question.variable}`; const id = `survey-question-${question.variable}`;
const hasActualValue = !question.required || meta.value?.length > 0; const hasActualValue = !question.required || meta.value?.length > 0;
@@ -134,8 +132,7 @@ function MultiSelectField({ question, i18n }) {
<FormGroup <FormGroup
fieldId={id} fieldId={id}
helperTextInvalid={ helperTextInvalid={
meta.error || meta.error || t`At least one value must be selected for this field.`
i18n._(t`At least one value must be selected for this field.`)
} }
isRequired={question.required} isRequired={question.required}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
@@ -169,4 +166,4 @@ function MultiSelectField({ question, i18n }) {
); );
} }
export default withI18n()(SurveyStep); export default SurveyStep;

View File

@@ -7,7 +7,6 @@ const credentialPromptsForPassword = credential =>
credential?.inputs?.vault_password === 'ASK'; credential?.inputs?.vault_password === 'ASK';
export default function credentialsValidator( export default function credentialsValidator(
i18n,
defaultCredentials = [], defaultCredentials = [],
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
selectedCredentials selectedCredentials
@@ -38,11 +37,9 @@ export default function credentialsValidator(
}); });
if (missingCredentialTypes.length > 0) { if (missingCredentialTypes.length > 0) {
return i18n._( return t`Job Template default credentials must be replaced with one of the same type. Please select a credential for the following types in order to proceed: ${missingCredentialTypes.join(
t`Job Template default credentials must be replaced with one of the same type. Please select a credential for the following types in order to proceed: ${missingCredentialTypes.join( ', '
', ' )}`;
)}`
);
} }
} }
@@ -54,11 +51,9 @@ export default function credentialsValidator(
} }
}); });
if (credentialsThatPrompt.length > 0) { if (credentialsThatPrompt.length > 0) {
return i18n._( return t`Credentials that require passwords on launch are not permitted. Please remove or replace the following credentials with a credential of the same type in order to proceed: ${credentialsThatPrompt.join(
t`Credentials that require passwords on launch are not permitted. Please remove or replace the following credentials with a credential of the same type in order to proceed: ${credentialsThatPrompt.join( ', '
', ' )}`;
)}`
);
} }
} }

View File

@@ -12,7 +12,7 @@ const isValueMissing = val => {
export default function useCredentialPasswordsStep( export default function useCredentialPasswordsStep(
launchConfig, launchConfig,
i18n,
showStep, showStep,
visitedSteps visitedSteps
) { ) {
@@ -27,12 +27,10 @@ export default function useCredentialPasswordsStep(
id: STEP_ID, id: STEP_ID,
name: ( name: (
<StepName hasErrors={hasError} id="credential-passwords-step"> <StepName hasErrors={hasError} id="credential-passwords-step">
{i18n._(t`Credential passwords`)} {t`Credential passwords`}
</StepName> </StepName>
), ),
component: ( component: <CredentialPasswordsStep launchConfig={launchConfig} />,
<CredentialPasswordsStep launchConfig={launchConfig} i18n={i18n} />
),
enableNext: true, enableNext: true,
} }
: null, : null,
@@ -51,7 +49,7 @@ export default function useCredentialPasswordsStep(
}, },
validate: () => { validate: () => {
const setPasswordFieldError = fieldName => { const setPasswordFieldError = fieldName => {
setFieldError(fieldName, i18n._(t`This field may not be blank`)); setFieldError(fieldName, t`This field may not be blank`);
}; };
if ( if (

View File

@@ -11,7 +11,7 @@ export default function useCredentialsStep(
launchConfig, launchConfig,
resource, resource,
resourceDefaultCredentials, resourceDefaultCredentials,
i18n,
allowCredentialsWithPasswords = false allowCredentialsWithPasswords = false
) { ) {
const [field, meta, helpers] = useField('credentials'); const [field, meta, helpers] = useField('credentials');
@@ -22,7 +22,7 @@ export default function useCredentialsStep(
return { return {
step: getStep( step: getStep(
launchConfig, launchConfig,
i18n,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
formError, formError,
resourceDefaultCredentials resourceDefaultCredentials
@@ -37,7 +37,6 @@ export default function useCredentialsStep(
validate: () => { validate: () => {
helpers.setError( helpers.setError(
credentialsValidator( credentialsValidator(
i18n,
resourceDefaultCredentials, resourceDefaultCredentials,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
field.value field.value
@@ -49,7 +48,7 @@ export default function useCredentialsStep(
function getStep( function getStep(
launchConfig, launchConfig,
i18n,
allowCredentialsWithPasswords, allowCredentialsWithPasswords,
formError, formError,
resourceDefaultCredentials resourceDefaultCredentials
@@ -62,12 +61,11 @@ function getStep(
key: 4, key: 4,
name: ( name: (
<StepName hasErrors={formError} id="credentials-step"> <StepName hasErrors={formError} id="credentials-step">
{i18n._(t`Credentials`)} {t`Credentials`}
</StepName> </StepName>
), ),
component: ( component: (
<CredentialsStep <CredentialsStep
i18n={i18n}
allowCredentialsWithPasswords={allowCredentialsWithPasswords} allowCredentialsWithPasswords={allowCredentialsWithPasswords}
defaultCredentials={resourceDefaultCredentials} defaultCredentials={resourceDefaultCredentials}
/> />

View File

@@ -15,7 +15,7 @@ const STEP_ID = 'inventory';
export default function useInventoryStep( export default function useInventoryStep(
launchConfig, launchConfig,
resource, resource,
i18n,
visitedSteps visitedSteps
) { ) {
const [, meta, helpers] = useField('inventory'); const [, meta, helpers] = useField('inventory');
@@ -27,7 +27,7 @@ export default function useInventoryStep(
!meta.value; !meta.value;
return { return {
step: getStep(launchConfig, i18n, formError, resource), step: getStep(launchConfig, formError, resource),
initialValues: getInitialValues(launchConfig, resource), initialValues: getInitialValues(launchConfig, resource),
isReady: true, isReady: true,
contentError: null, contentError: null,
@@ -37,12 +37,12 @@ export default function useInventoryStep(
}, },
validate: () => { validate: () => {
if (meta.touched && !meta.value && resource.type === 'job_template') { if (meta.touched && !meta.value && resource.type === 'job_template') {
helpers.setError(i18n._(t`An inventory must be selected`)); helpers.setError(t`An inventory must be selected`);
} }
}, },
}; };
} }
function getStep(launchConfig, i18n, formError, resource) { function getStep(launchConfig, formError, resource) {
if (!launchConfig.ask_inventory_on_launch) { if (!launchConfig.ask_inventory_on_launch) {
return null; return null;
} }
@@ -50,21 +50,18 @@ function getStep(launchConfig, i18n, formError, resource) {
id: STEP_ID, id: STEP_ID,
name: ( name: (
<StepName hasErrors={formError} id="inventory-step"> <StepName hasErrors={formError} id="inventory-step">
{i18n._(t`Inventory`)} {t`Inventory`}
</StepName> </StepName>
), ),
component: ( component: (
<InventoryStep <InventoryStep
i18n={i18n}
warningMessage={ warningMessage={
resource.type === 'workflow_job_template' ? ( resource.type === 'workflow_job_template' ? (
<InventoryAlert <InventoryAlert
ouiaId="InventoryStep-alert" ouiaId="InventoryStep-alert"
variant="warning" variant="warning"
isInline isInline
title={i18n._( title={t`This inventory is applied to all job template nodes within this workflow (${resource.name}) that prompt for an inventory.`}
t`This inventory is applied to all job template nodes within this workflow (${resource.name}) that prompt for an inventory.`
)}
/> />
) : null ) : null
} }

View File

@@ -16,9 +16,9 @@ const getVariablesData = resource => {
return '---'; return '---';
}; };
export default function useOtherPromptsStep(launchConfig, resource, i18n) { export default function useOtherPromptsStep(launchConfig, resource) {
return { return {
step: getStep(launchConfig, i18n), step: getStep(launchConfig),
initialValues: getInitialValues(launchConfig, resource), initialValues: getInitialValues(launchConfig, resource),
isReady: true, isReady: true,
contentError: null, contentError: null,
@@ -38,7 +38,7 @@ export default function useOtherPromptsStep(launchConfig, resource, i18n) {
}; };
} }
function getStep(launchConfig, i18n) { function getStep(launchConfig) {
if (!shouldShowPrompt(launchConfig)) { if (!shouldShowPrompt(launchConfig)) {
return null; return null;
} }
@@ -47,10 +47,10 @@ function getStep(launchConfig, i18n) {
key: 5, key: 5,
name: ( name: (
<StepName hasErrors={false} id="other-prompts-step"> <StepName hasErrors={false} id="other-prompts-step">
{i18n._(t`Other prompts`)} {t`Other prompts`}
</StepName> </StepName>
), ),
component: <OtherPromptsStep launchConfig={launchConfig} i18n={i18n} />, component: <OtherPromptsStep launchConfig={launchConfig} />,
enableNext: true, enableNext: true,
}; };
} }

View File

@@ -7,7 +7,7 @@ const STEP_ID = 'preview';
export default function usePreviewStep( export default function usePreviewStep(
launchConfig, launchConfig,
i18n,
resource, resource,
surveyConfig, surveyConfig,
hasErrors, hasErrors,
@@ -20,7 +20,7 @@ export default function usePreviewStep(
id: STEP_ID, id: STEP_ID,
name: ( name: (
<StepName hasErrors={false} id="preview-step"> <StepName hasErrors={false} id="preview-step">
{i18n._(t`Preview`)} {t`Preview`}
</StepName> </StepName>
), ),
component: ( component: (
@@ -32,7 +32,7 @@ export default function usePreviewStep(
/> />
), ),
enableNext: !hasErrors, enableNext: !hasErrors,
nextButtonText: nextButtonText || i18n._(t`Launch`), nextButtonText: nextButtonText || t`Launch`,
} }
: null, : null,
initialValues: {}, initialValues: {},

View File

@@ -10,7 +10,7 @@ export default function useSurveyStep(
launchConfig, launchConfig,
surveyConfig, surveyConfig,
resource, resource,
i18n,
visitedSteps visitedSteps
) { ) {
const { setFieldError, values } = useFormikContext(); const { setFieldError, values } = useFormikContext();
@@ -24,10 +24,10 @@ export default function useSurveyStep(
id: STEP_ID, id: STEP_ID,
name: ( name: (
<StepName hasErrors={hasError} id="survey-step"> <StepName hasErrors={hasError} id="survey-step">
{i18n._(t`Survey`)} {t`Survey`}
</StepName> </StepName>
), ),
component: <SurveyStep surveyConfig={surveyConfig} i18n={i18n} />, component: <SurveyStep surveyConfig={surveyConfig} />,
enableNext: true, enableNext: true,
} }
: null, : null,
@@ -49,8 +49,7 @@ export default function useSurveyStep(
surveyConfig.spec.forEach(question => { surveyConfig.spec.forEach(question => {
const errMessage = validateSurveyField( const errMessage = validateSurveyField(
question, question,
values[`survey_${question.variable}`], values[`survey_${question.variable}`]
i18n
); );
if (errMessage) { if (errMessage) {
setFieldError(`survey_${question.variable}`, errMessage); setFieldError(`survey_${question.variable}`, errMessage);
@@ -96,26 +95,24 @@ function getInitialValues(launchConfig, surveyConfig, resource) {
return values; return values;
} }
function validateSurveyField(question, value, i18n) { function validateSurveyField(question, value) {
const isTextField = ['text', 'textarea'].includes(question.type); const isTextField = ['text', 'textarea'].includes(question.type);
const isNumeric = ['integer', 'float'].includes(question.type); const isNumeric = ['integer', 'float'].includes(question.type);
if (isTextField && (value || value === 0)) { if (isTextField && (value || value === 0)) {
if (question.min && value.length < question.min) { if (question.min && value.length < question.min) {
return i18n._(t`This field must be at least ${question.min} characters`); return t`This field must be at least ${question.min} characters`;
} }
if (question.max && value.length > question.max) { if (question.max && value.length > question.max) {
return i18n._(t`This field must not exceed ${question.max} characters`); return t`This field must not exceed ${question.max} characters`;
} }
} }
if (isNumeric && (value || value === 0)) { if (isNumeric && (value || value === 0)) {
if (value < question.min || value > question.max) { if (value < question.min || value > question.max) {
return i18n._( return t`This field must be a number and have a value between ${question.min} and ${question.max}`;
t`This field must be a number and have a value between ${question.min} and ${question.max}`
);
} }
} }
if (question.required && !value && value !== 0) { if (question.required && !value && value !== 0) {
return i18n._(t`This field must not be blank`); return t`This field must not be blank`;
} }
return null; return null;
} }

View File

@@ -43,35 +43,34 @@ export default function useLaunchSteps(
launchConfig, launchConfig,
surveyConfig, surveyConfig,
resource, resource,
i18n,
resourceDefaultCredentials resourceDefaultCredentials
) { ) {
const [visited, setVisited] = useState({}); const [visited, setVisited] = useState({});
const [isReady, setIsReady] = useState(false); const [isReady, setIsReady] = useState(false);
const { touched, values: formikValues } = useFormikContext(); const { touched, values: formikValues } = useFormikContext();
const steps = [ const steps = [
useInventoryStep(launchConfig, resource, i18n, visited), useInventoryStep(launchConfig, resource, visited),
useCredentialsStep( useCredentialsStep(
launchConfig, launchConfig,
resource, resource,
resourceDefaultCredentials, resourceDefaultCredentials,
i18n,
true true
), ),
useCredentialPasswordsStep( useCredentialPasswordsStep(
launchConfig, launchConfig,
i18n,
showCredentialPasswordsStep(formikValues.credentials, launchConfig), showCredentialPasswordsStep(formikValues.credentials, launchConfig),
visited visited
), ),
useOtherPromptsStep(launchConfig, resource, i18n), useOtherPromptsStep(launchConfig, resource),
useSurveyStep(launchConfig, surveyConfig, resource, i18n, visited), useSurveyStep(launchConfig, surveyConfig, resource, visited),
]; ];
const { resetForm } = useFormikContext(); const { resetForm } = useFormikContext();
const hasErrors = steps.some(step => step.hasError); const hasErrors = steps.some(step => step.hasError);
steps.push( steps.push(
usePreviewStep(launchConfig, i18n, resource, surveyConfig, hasErrors, true) usePreviewStep(launchConfig, resource, surveyConfig, hasErrors, true)
); );
const pfSteps = steps.map(s => s.step).filter(s => s != null); const pfSteps = steps.map(s => s.step).filter(s => s != null);

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { func, node } from 'prop-types'; import { func, node } from 'prop-types';
import { withRouter, useLocation } from 'react-router-dom'; import { withRouter, useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core'; import { FormGroup } from '@patternfly/react-core';
import { ApplicationsAPI } from '../../api'; import { ApplicationsAPI } from '../../api';
@@ -18,7 +18,7 @@ const QS_CONFIG = getQSConfig('applications', {
order_by: 'name', order_by: 'name',
}); });
function ApplicationLookup({ i18n, onChange, value, label }) { function ApplicationLookup({ onChange, value, label }) {
const location = useLocation(); const location = useLocation();
const { const {
error, error,
@@ -62,7 +62,7 @@ function ApplicationLookup({ i18n, onChange, value, label }) {
<FormGroup fieldId="application" label={label}> <FormGroup fieldId="application" label={label}>
<Lookup <Lookup
id="application" id="application"
header={i18n._(t`Application`)} header={t`Application`}
value={value} value={value}
onChange={onChange} onChange={onChange}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
@@ -71,34 +71,34 @@ function ApplicationLookup({ i18n, onChange, value, label }) {
value={state.selectedItems} value={state.selectedItems}
options={applications} options={applications}
optionCount={itemCount} optionCount={itemCount}
header={i18n._(t`Applications`)} header={t`Applications`}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Description`), name: t`Description`,
key: 'description__icontains', key: 'description__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
{ {
name: i18n._(t`Created`), name: t`Created`,
key: 'created', key: 'created',
}, },
{ {
name: i18n._(t`Organization`), name: t`Organization`,
key: 'organization', key: 'organization',
}, },
{ {
name: i18n._(t`Description`), name: t`Description`,
key: 'description', key: 'description',
}, },
]} ]}
@@ -125,4 +125,4 @@ ApplicationLookup.defaultProps = {
value: null, value: null,
}; };
export default withI18n()(withRouter(ApplicationLookup)); export default withRouter(ApplicationLookup);

View File

@@ -9,7 +9,7 @@ import {
string, string,
oneOfType, oneOfType,
} from 'prop-types'; } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core'; import { FormGroup } from '@patternfly/react-core';
import { CredentialsAPI } from '../../api'; import { CredentialsAPI } from '../../api';
@@ -39,7 +39,7 @@ function CredentialLookup({
credentialTypeKind, credentialTypeKind,
credentialTypeNamespace, credentialTypeNamespace,
value, value,
i18n,
tooltip, tooltip,
isDisabled, isDisabled,
autoPopulate, autoPopulate,
@@ -145,22 +145,22 @@ function CredentialLookup({
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
@@ -228,4 +228,4 @@ CredentialLookup.defaultProps = {
}; };
export { CredentialLookup as _CredentialLookup }; export { CredentialLookup as _CredentialLookup };
export default withI18n()(CredentialLookup); export default CredentialLookup;

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { string, func, bool, oneOfType, number } from 'prop-types'; import { string, func, bool, oneOfType, number } from 'prop-types';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup, Tooltip } from '@patternfly/react-core'; import { FormGroup, Tooltip } from '@patternfly/react-core';
@@ -23,7 +23,7 @@ const QS_CONFIG = getQSConfig('execution_environments', {
function ExecutionEnvironmentLookup({ function ExecutionEnvironmentLookup({
globallyAvailable, globallyAvailable,
i18n,
isDefaultEnvironment, isDefaultEnvironment,
isGlobalDefaultEnvironment, isGlobalDefaultEnvironment,
isDisabled, isDisabled,
@@ -121,7 +121,7 @@ function ExecutionEnvironmentLookup({
<> <>
<Lookup <Lookup
id="execution-environments" id="execution-environments"
header={i18n._(t`Execution Environments`)} header={t`Execution Environments`}
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
onChange={onChange} onChange={onChange}
@@ -135,21 +135,21 @@ function ExecutionEnvironmentLookup({
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Execution Environment`)} header={t`Execution Environment`}
name="executionEnvironments" name="executionEnvironments"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={!canDelete} readOnly={!canDelete}
@@ -166,12 +166,12 @@ function ExecutionEnvironmentLookup({
defaultExecutionEnvironment defaultExecutionEnvironment
) => { ) => {
if (globalDefaultEnvironment) { if (globalDefaultEnvironment) {
return i18n._(t`Global Default Execution Environment`); return t`Global Default Execution Environment`;
} }
if (defaultExecutionEnvironment) { if (defaultExecutionEnvironment) {
return i18n._(t`Default Execution Environment`); return t`Default Execution Environment`;
} }
return i18n._(t`Execution Environment`); return t`Execution Environment`;
}; };
return ( return (
@@ -210,4 +210,4 @@ ExecutionEnvironmentLookup.defaultProps = {
organizationId: null, organizationId: null,
}; };
export default withI18n()(ExecutionEnvironmentLookup); export default ExecutionEnvironmentLookup;

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { withRouter, useHistory, useLocation } from 'react-router-dom'; import { withRouter, useHistory, useLocation } from 'react-router-dom';
import { number, func, bool, string } from 'prop-types'; import { number, func, bool, string } from 'prop-types';
import { withI18n } from '@lingui/react';
import styled from 'styled-components'; import styled from 'styled-components';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { SearchIcon } from '@patternfly/react-icons'; import { SearchIcon } from '@patternfly/react-icons';
@@ -72,46 +72,46 @@ const QS_CONFIG = getQSConfig(
['id', 'page', 'page_size', 'inventory'] ['id', 'page', 'page_size', 'inventory']
); );
const buildSearchColumns = i18n => [ const buildSearchColumns = () => [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`ID`), name: t`ID`,
key: 'id', key: 'id',
}, },
{ {
name: i18n._(t`Group`), name: t`Group`,
key: 'groups__name__icontains', key: 'groups__name__icontains',
}, },
{ {
name: i18n._(t`Inventory ID`), name: t`Inventory ID`,
key: 'inventory', key: 'inventory',
}, },
{ {
name: i18n._(t`Enabled`), name: t`Enabled`,
key: 'enabled', key: 'enabled',
isBoolean: true, isBoolean: true,
}, },
{ {
name: i18n._(t`Instance ID`), name: t`Instance ID`,
key: 'instance_id', key: 'instance_id',
}, },
{ {
name: i18n._(t`Last job`), name: t`Last job`,
key: 'last_job', key: 'last_job',
}, },
{ {
name: i18n._(t`Insights system ID`), name: t`Insights system ID`,
key: 'insights_system_id', key: 'insights_system_id',
}, },
]; ];
function HostFilterLookup({ function HostFilterLookup({
helperTextInvalid, helperTextInvalid,
i18n,
isValid, isValid,
isDisabled, isDisabled,
onBlur, onBlur,
@@ -124,7 +124,7 @@ function HostFilterLookup({
const [chips, setChips] = useState({}); const [chips, setChips] = useState({});
const [queryString, setQueryString] = useState(''); const [queryString, setQueryString] = useState('');
const { isModalOpen, toggleModal, closeModal } = useModal(); const { isModalOpen, toggleModal, closeModal } = useModal();
const searchColumns = buildSearchColumns(i18n); const searchColumns = buildSearchColumns();
const { const {
result: { count, hosts, relatedSearchableKeys, searchableKeys }, result: { count, hosts, relatedSearchableKeys, searchableKeys },
@@ -248,7 +248,7 @@ function HostFilterLookup({
<InputGroup onBlur={onBlur}> <InputGroup onBlur={onBlur}>
<Button <Button
ouiaId="host-filter-search-button" ouiaId="host-filter-search-button"
aria-label={i18n._(t`Search`)} aria-label={t`Search`}
id="host-filter" id="host-filter"
isDisabled={isDisabled} isDisabled={isDisabled}
onClick={handleOpenModal} onClick={handleOpenModal}
@@ -280,24 +280,21 @@ function HostFilterLookup({
fieldId="host-filter" fieldId="host-filter"
helperTextInvalid={helperTextInvalid} helperTextInvalid={helperTextInvalid}
isRequired isRequired
label={i18n._(t`Smart host filter`)} label={t`Smart host filter`}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
labelIcon={ labelIcon={
<Popover <Popover
content={i18n._( content={t`Populate the hosts for this inventory by using a search
t`Populate the hosts for this inventory by using a search
filter. Example: ansible_facts.ansible_distribution:"RedHat". filter. Example: ansible_facts.ansible_distribution:"RedHat".
Refer to the documentation for further syntax and Refer to the documentation for further syntax and
examples.` examples. Refer to the Ansible Tower documentation for further syntax and
)} examples.`}
/> />
} }
> >
{isDisabled ? ( {isDisabled ? (
<Tooltip <Tooltip
content={i18n._( content={t`Please select an organization before editing the host filter`}
t`Please select an organization before editing the host filter`
)}
> >
{renderLookup()} {renderLookup()}
</Tooltip> </Tooltip>
@@ -305,10 +302,10 @@ function HostFilterLookup({
renderLookup() renderLookup()
)} )}
<Modal <Modal
aria-label={i18n._(t`Lookup modal`)} aria-label={t`Lookup modal`}
isOpen={isModalOpen} isOpen={isModalOpen}
onClose={handleClose} onClose={handleClose}
title={i18n._(t`Perform a search to define a host filter`)} title={t`Perform a search to define a host filter`}
variant="large" variant="large"
actions={[ actions={[
<Button <Button
@@ -318,7 +315,7 @@ function HostFilterLookup({
onClick={save} onClick={save}
variant="primary" variant="primary"
> >
{i18n._(t`Select`)} {t`Select`}
</Button>, </Button>,
<Button <Button
ouiaId="host-filter-modal-cancel-button" ouiaId="host-filter-modal-cancel-button"
@@ -326,7 +323,7 @@ function HostFilterLookup({
variant="link" variant="link"
onClick={handleClose} onClick={handleClose}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
@@ -337,7 +334,7 @@ function HostFilterLookup({
itemCount={count} itemCount={count}
items={hosts} items={hosts}
onRowClick={() => {}} onRowClick={() => {}}
pluralizedItemName={i18n._(t`hosts`)} pluralizedItemName={t`hosts`}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
renderItem={item => ( renderItem={item => (
<HostListItem <HostListItem
@@ -349,15 +346,15 @@ function HostFilterLookup({
toolbarSearchColumns={searchColumns} toolbarSearchColumns={searchColumns}
toolbarSortColumns={[ toolbarSortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
{ {
name: i18n._(t`Created`), name: t`Created`,
key: 'created', key: 'created',
}, },
{ {
name: i18n._(t`Modified`), name: t`Modified`,
key: 'modified', key: 'modified',
}, },
]} ]}
@@ -386,4 +383,4 @@ HostFilterLookup.defaultProps = {
value: '', value: '',
}; };
export default withI18n()(withRouter(HostFilterLookup)); export default withRouter(HostFilterLookup);

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
DataListItem, DataListItem,
@@ -10,7 +10,7 @@ import {
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import DataListCell from '../DataListCell'; import DataListCell from '../DataListCell';
function HostListItem({ item, i18n }) { function HostListItem({ item }) {
return ( return (
<DataListItem <DataListItem
aria-labelledby={`items-list-item-${item.id}`} aria-labelledby={`items-list-item-${item.id}`}
@@ -20,14 +20,14 @@ function HostListItem({ item, i18n }) {
<DataListItemRow> <DataListItemRow>
<DataListItemCells <DataListItemCells
dataListCells={[ dataListCells={[
<DataListCell key="name" aria-label={i18n._(t`name`)}> <DataListCell key="name" aria-label={t`name`}>
<TextContent> <TextContent>
<Link to={{ pathname: item.url }}> <Link to={{ pathname: item.url }}>
<b id={`items-list-item-${item.id}`}>{item.name}</b> <b id={`items-list-item-${item.id}`}>{item.name}</b>
</Link> </Link>
</TextContent> </TextContent>
</DataListCell>, </DataListCell>,
<DataListCell key="inventory" aria-label={i18n._(t`inventory`)}> <DataListCell key="inventory" aria-label={t`inventory`}>
{item.summary_fields.inventory.name} {item.summary_fields.inventory.name}
</DataListCell>, </DataListCell>,
]} ]}
@@ -37,4 +37,4 @@ function HostListItem({ item, i18n }) {
); );
} }
export default withI18n()(HostListItem); export default HostListItem;

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { arrayOf, string, func, bool } from 'prop-types'; import { arrayOf, string, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core'; import { FormGroup } from '@patternfly/react-core';
import { InstanceGroupsAPI } from '../../api'; import { InstanceGroupsAPI } from '../../api';
@@ -20,15 +20,7 @@ const QS_CONFIG = getQSConfig('instance-groups', {
}); });
function InstanceGroupsLookup(props) { function InstanceGroupsLookup(props) {
const { const { value, onChange, tooltip, className, required, history } = props;
value,
onChange,
tooltip,
className,
required,
history,
i18n,
} = props;
const { const {
result: { instanceGroups, count, relatedSearchableKeys, searchableKeys }, result: { instanceGroups, count, relatedSearchableKeys, searchableKeys },
@@ -68,13 +60,13 @@ function InstanceGroupsLookup(props) {
return ( return (
<FormGroup <FormGroup
className={className} className={className}
label={i18n._(t`Instance Groups`)} label={t`Instance Groups`}
labelIcon={tooltip && <Popover content={tooltip} />} labelIcon={tooltip && <Popover content={tooltip} />}
fieldId="org-instance-groups" fieldId="org-instance-groups"
> >
<Lookup <Lookup
id="org-instance-groups" id="org-instance-groups"
header={i18n._(t`Instance Groups`)} header={t`Instance Groups`}
value={value} value={value}
onChange={onChange} onChange={onChange}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
@@ -88,25 +80,25 @@ function InstanceGroupsLookup(props) {
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Credential Name`), name: t`Credential Name`,
key: 'credential__name__icontains', key: 'credential__name__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Instance Groups`)} header={t`Instance Groups`}
name="instanceGroups" name="instanceGroups"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={!canDelete} readOnly={!canDelete}
@@ -134,4 +126,4 @@ InstanceGroupsLookup.defaultProps = {
required: false, required: false,
}; };
export default withI18n()(withRouter(InstanceGroupsLookup)); export default withRouter(InstanceGroupsLookup);

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { func, bool } from 'prop-types'; import { func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { InventoriesAPI } from '../../api'; import { InventoriesAPI } from '../../api';
import { Inventory } from '../../types'; import { Inventory } from '../../types';
@@ -23,7 +23,7 @@ function InventoryLookup({
value, value,
onChange, onChange,
onBlur, onBlur,
i18n,
history, history,
required, required,
isPromptableField, isPromptableField,
@@ -82,16 +82,16 @@ function InventoryLookup({
<FieldWithPrompt <FieldWithPrompt
fieldId={fieldId} fieldId={fieldId}
isRequired={required} isRequired={required}
label={i18n._(t`Inventory`)} label={t`Inventory`}
promptId={promptId} promptId={promptId}
promptName={promptName} promptName={promptName}
isDisabled={!canEdit} isDisabled={!canEdit}
tooltip={i18n._(t`Select the inventory containing the hosts tooltip={t`Select the inventory containing the hosts
you want this job to manage.`)} you want this job to manage.`}
> >
<Lookup <Lookup
id="inventory-lookup" id="inventory-lookup"
header={i18n._(t`Inventory`)} header={t`Inventory`}
value={value} value={value}
onChange={onChange} onChange={onChange}
onBlur={onBlur} onBlur={onBlur}
@@ -106,29 +106,29 @@ function InventoryLookup({
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Inventory`)} header={t`Inventory`}
name="inventory" name="inventory"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={!canDelete} readOnly={!canDelete}
@@ -144,7 +144,7 @@ function InventoryLookup({
<> <>
<Lookup <Lookup
id="inventory-lookup" id="inventory-lookup"
header={i18n._(t`Inventory`)} header={t`Inventory`}
value={value} value={value}
onChange={onChange} onChange={onChange}
onBlur={onBlur} onBlur={onBlur}
@@ -159,29 +159,29 @@ function InventoryLookup({
optionCount={count} optionCount={count}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Inventory`)} header={t`Inventory`}
name="inventory" name="inventory"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={!canDelete} readOnly={!canDelete}
@@ -208,4 +208,4 @@ InventoryLookup.defaultProps = {
isOverrideDisabled: false, isOverrideDisabled: false,
}; };
export default withI18n()(withRouter(InventoryLookup)); export default withRouter(InventoryLookup);

View File

@@ -17,7 +17,7 @@ import {
InputGroup, InputGroup,
Modal, Modal,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import styled from 'styled-components'; import styled from 'styled-components';
import ChipGroup from '../ChipGroup'; import ChipGroup from '../ChipGroup';
@@ -44,7 +44,7 @@ function Lookup(props) {
renderItemChip, renderItemChip,
renderOptionsList, renderOptionsList,
history, history,
i18n,
isDisabled, isDisabled,
} = props; } = props;
@@ -103,7 +103,7 @@ function Lookup(props) {
<Fragment> <Fragment>
<InputGroup onBlur={onBlur}> <InputGroup onBlur={onBlur}>
<Button <Button
aria-label={i18n._(t`Search`)} aria-label={t`Search`}
id={id} id={id}
onClick={() => dispatch({ type: 'TOGGLE_MODAL' })} onClick={() => dispatch({ type: 'TOGGLE_MODAL' })}
variant={ButtonVariant.control} variant={ButtonVariant.control}
@@ -126,8 +126,8 @@ function Lookup(props) {
<Modal <Modal
variant="large" variant="large"
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)} title={t`Select ${header || t`Items`}`}
aria-label={i18n._(t`Lookup modal`)} aria-label={t`Lookup modal`}
isOpen={isModalOpen} isOpen={isModalOpen}
onClose={closeModal} onClose={closeModal}
actions={[ actions={[
@@ -138,16 +138,16 @@ function Lookup(props) {
onClick={save} onClick={save}
isDisabled={required && selectedItems.length === 0} isDisabled={required && selectedItems.length === 0}
> >
{i18n._(t`Select`)} {t`Select`}
</Button>, </Button>,
<Button <Button
ouiaId="modal-cancel-button" ouiaId="modal-cancel-button"
key="cancel" key="cancel"
variant="link" variant="link"
onClick={closeModal} onClick={closeModal}
aria-label={i18n._(t`Cancel lookup`)} aria-label={t`Cancel lookup`}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
@@ -197,4 +197,4 @@ Lookup.defaultProps = {
}; };
export { Lookup as _Lookup }; export { Lookup as _Lookup };
export default withI18n()(withRouter(Lookup)); export default withRouter(Lookup);

View File

@@ -2,7 +2,7 @@ import 'styled-components/macro';
import React, { Fragment, useState, useCallback, useEffect } from 'react'; import React, { Fragment, useState, useCallback, useEffect } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { ToolbarItem, Alert } from '@patternfly/react-core'; import { ToolbarItem, Alert } from '@patternfly/react-core';
import { CredentialsAPI, CredentialTypesAPI } from '../../api'; import { CredentialsAPI, CredentialTypesAPI } from '../../api';
@@ -27,7 +27,7 @@ async function loadCredentials(params, selectedCredentialTypeId) {
} }
function MultiCredentialsLookup(props) { function MultiCredentialsLookup(props) {
const { value, onChange, onError, history, i18n } = props; const { value, onChange, onError, history } = props;
const [selectedType, setSelectedType] = useState(null); const [selectedType, setSelectedType] = useState(null);
const isMounted = useIsMounted(); const isMounted = useIsMounted();
@@ -128,7 +128,7 @@ function MultiCredentialsLookup(props) {
return ( return (
<Lookup <Lookup
id="multiCredential" id="multiCredential"
header={i18n._(t`Credentials`)} header={t`Credentials`}
value={value} value={value}
multiple multiple
onChange={onChange} onChange={onChange}
@@ -143,20 +143,18 @@ function MultiCredentialsLookup(props) {
variant="info" variant="info"
isInline isInline
css="margin-bottom: 20px;" css="margin-bottom: 20px;"
title={i18n._( title={t`You cannot select multiple vault credentials with the same vault ID. Doing so will automatically deselect the other with the same vault ID.`}
t`You cannot select multiple vault credentials with the same vault ID. Doing so will automatically deselect the other with the same vault ID.`
)}
/> />
)} )}
{credentialTypes && credentialTypes.length > 0 && ( {credentialTypes && credentialTypes.length > 0 && (
<ToolbarItem css=" display: flex; align-items: center;"> <ToolbarItem css=" display: flex; align-items: center;">
<div css="flex: 0 0 25%; margin-right: 32px"> <div css="flex: 0 0 25%; margin-right: 32px">
{i18n._(t`Selected Category`)} {t`Selected Category`}
</div> </div>
<AnsibleSelect <AnsibleSelect
css="flex: 1 1 75%;" css="flex: 1 1 75%;"
id="multiCredentialsLookUp-select" id="multiCredentialsLookUp-select"
label={i18n._(t`Selected Category`)} label={t`Selected Category`}
data={credentialTypes.map(type => ({ data={credentialTypes.map(type => ({
key: type.id, key: type.id,
value: type.id, value: type.id,
@@ -178,29 +176,29 @@ function MultiCredentialsLookup(props) {
optionCount={credentialsCount} optionCount={credentialsCount}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
searchableKeys={searchableKeys} searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys} relatedSearchableKeys={relatedSearchableKeys}
multiple={isVault} multiple={isVault}
header={i18n._(t`Credentials`)} header={t`Credentials`}
displayKey={isVault ? 'label' : 'name'} displayKey={isVault ? 'label' : 'name'}
name="credentials" name="credentials"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
@@ -249,4 +247,4 @@ MultiCredentialsLookup.defaultProps = {
}; };
export { MultiCredentialsLookup as _MultiCredentialsLookup }; export { MultiCredentialsLookup as _MultiCredentialsLookup };
export default withI18n()(withRouter(MultiCredentialsLookup)); export default withRouter(MultiCredentialsLookup);

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { node, func, bool } from 'prop-types'; import { node, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core'; import { FormGroup } from '@patternfly/react-core';
import { OrganizationsAPI } from '../../api'; import { OrganizationsAPI } from '../../api';
@@ -21,7 +21,7 @@ const QS_CONFIG = getQSConfig('organizations', {
function OrganizationLookup({ function OrganizationLookup({
helperTextInvalid, helperTextInvalid,
i18n,
isValid, isValid,
onBlur, onBlur,
onChange, onChange,
@@ -79,13 +79,13 @@ function OrganizationLookup({
helperTextInvalid={helperTextInvalid} helperTextInvalid={helperTextInvalid}
isRequired={required} isRequired={required}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
label={i18n._(t`Organization`)} label={t`Organization`}
helperText={helperText} helperText={helperText}
> >
<Lookup <Lookup
isDisabled={isDisabled} isDisabled={isDisabled}
id="organization" id="organization"
header={i18n._(t`Organization`)} header={t`Organization`}
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
onChange={onChange} onChange={onChange}
@@ -98,27 +98,27 @@ function OrganizationLookup({
options={organizations} options={organizations}
optionCount={itemCount} optionCount={itemCount}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Organization`)} header={t`Organization`}
name="organization" name="organization"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
@@ -157,4 +157,4 @@ OrganizationLookup.defaultProps = {
}; };
export { OrganizationLookup as _OrganizationLookup }; export { OrganizationLookup as _OrganizationLookup };
export default withI18n()(withRouter(OrganizationLookup)); export default withRouter(OrganizationLookup);

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { node, string, func, bool } from 'prop-types'; import { node, string, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core'; import { FormGroup } from '@patternfly/react-core';
import { ProjectsAPI } from '../../api'; import { ProjectsAPI } from '../../api';
@@ -24,7 +24,7 @@ const QS_CONFIG = getQSConfig('project', {
function ProjectLookup({ function ProjectLookup({
helperTextInvalid, helperTextInvalid,
autoPopulate, autoPopulate,
i18n,
isValid, isValid,
onChange, onChange,
required, required,
@@ -83,12 +83,12 @@ function ProjectLookup({
helperTextInvalid={helperTextInvalid} helperTextInvalid={helperTextInvalid}
isRequired={required} isRequired={required}
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
label={i18n._(t`Project`)} label={t`Project`}
labelIcon={tooltip && <Popover content={tooltip} />} labelIcon={tooltip && <Popover content={tooltip} />}
> >
<Lookup <Lookup
id="project" id="project"
header={i18n._(t`Project`)} header={t`Project`}
name="project" name="project"
value={value} value={value}
onBlur={onBlur} onBlur={onBlur}
@@ -102,37 +102,37 @@ function ProjectLookup({
value={state.selectedItems} value={state.selectedItems}
searchColumns={[ searchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Type`), name: t`Type`,
key: 'or__scm_type', key: 'or__scm_type',
options: [ options: [
[``, i18n._(t`Manual`)], [``, t`Manual`],
[`git`, i18n._(t`Git`)], [`git`, t`Git`],
[`svn`, i18n._(t`Subversion`)], [`svn`, t`Subversion`],
[`archive`, i18n._(t`Remote Archive`)], [`archive`, t`Remote Archive`],
[`insights`, i18n._(t`Red Hat Insights`)], [`insights`, t`Red Hat Insights`],
], ],
}, },
{ {
name: i18n._(t`Source Control URL`), name: t`Source Control URL`,
key: 'scm_url__icontains', key: 'scm_url__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
]} ]}
sortColumns={[ sortColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]} ]}
@@ -141,7 +141,7 @@ function ProjectLookup({
options={projects} options={projects}
optionCount={count} optionCount={count}
multiple={state.multiple} multiple={state.multiple}
header={i18n._(t`Project`)} header={t`Project`}
name="project" name="project"
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
readOnly={!canDelete} readOnly={!canDelete}
@@ -179,4 +179,4 @@ ProjectLookup.defaultProps = {
}; };
export { ProjectLookup as _ProjectLookup }; export { ProjectLookup as _ProjectLookup };
export default withI18n()(withRouter(ProjectLookup)); export default withRouter(ProjectLookup);

View File

@@ -1,17 +1,17 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
function LookupErrorMessage({ error, i18n }) { function LookupErrorMessage({ error }) {
if (!error) { if (!error) {
return null; return null;
} }
return ( return (
<div className="pf-c-form__helper-text pf-m-error" aria-live="polite"> <div className="pf-c-form__helper-text pf-m-error" aria-live="polite">
{error.message || i18n._(t`An error occurred`)} {error.message || t`An error occurred`}
</div> </div>
); );
} }
export default withI18n()(LookupErrorMessage); export default LookupErrorMessage;

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useCallback, useState } from 'react'; import React, { useEffect, useCallback, useState } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { number, shape, bool } from 'prop-types'; import { number, shape, bool } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
import ErrorDetail from '../ErrorDetail'; import ErrorDetail from '../ErrorDetail';
@@ -21,7 +21,7 @@ function NotificationList({
apiModel, apiModel,
canToggleNotifications, canToggleNotifications,
id, id,
i18n,
showApprovalsToggle, showApprovalsToggle,
}) { }) {
const location = useLocation(); const location = useLocation();
@@ -174,40 +174,40 @@ function NotificationList({
hasContentLoading={isLoading} hasContentLoading={isLoading}
items={notifications} items={notifications}
itemCount={itemCount} itemCount={itemCount}
pluralizedItemName={i18n._(t`Notifications`)} pluralizedItemName={t`Notifications`}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
toolbarSearchColumns={[ toolbarSearchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Description`), name: t`Description`,
key: 'description__icontains', key: 'description__icontains',
}, },
{ {
name: i18n._(t`Notification type`), name: t`Notification type`,
key: 'or__notification_type', key: 'or__notification_type',
options: [ options: [
['email', i18n._(t`Email`)], ['email', t`Email`],
['grafana', i18n._(t`Grafana`)], ['grafana', t`Grafana`],
['hipchat', i18n._(t`Hipchat`)], ['hipchat', t`Hipchat`],
['irc', i18n._(t`IRC`)], ['irc', t`IRC`],
['mattermost', i18n._(t`Mattermost`)], ['mattermost', t`Mattermost`],
['pagerduty', i18n._(t`Pagerduty`)], ['pagerduty', t`Pagerduty`],
['rocketchat', i18n._(t`Rocket.Chat`)], ['rocketchat', t`Rocket.Chat`],
['slack', i18n._(t`Slack`)], ['slack', t`Slack`],
['twilio', i18n._(t`Twilio`)], ['twilio', t`Twilio`],
['webhook', i18n._(t`Webhook`)], ['webhook', t`Webhook`],
], ],
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
@@ -215,11 +215,9 @@ function NotificationList({
toolbarRelatedSearchableKeys={relatedSearchableKeys} toolbarRelatedSearchableKeys={relatedSearchableKeys}
headerRow={ headerRow={
<HeaderRow qsConfig={QS_CONFIG} isSelectable={false}> <HeaderRow qsConfig={QS_CONFIG} isSelectable={false}>
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell> <HeaderCell sortKey="name">{t`Name`}</HeaderCell>
<HeaderCell sortKey="notification_type"> <HeaderCell sortKey="notification_type">{t`Type`}</HeaderCell>
{i18n._(t`Type`)} <HeaderCell>{t`Options`}</HeaderCell>
</HeaderCell>
<HeaderCell>{i18n._(t`Options`)}</HeaderCell>
</HeaderRow> </HeaderRow>
} }
renderRow={(notification, index) => ( renderRow={(notification, index) => (
@@ -245,11 +243,11 @@ function NotificationList({
{toggleError && ( {toggleError && (
<AlertModal <AlertModal
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
isOpen={loadingToggleIds.length === 0} isOpen={loadingToggleIds.length === 0}
onClose={() => setToggleError(null)} onClose={() => setToggleError(null)}
> >
{i18n._(t`Failed to toggle notification.`)} {t`Failed to toggle notification.`}
<ErrorDetail error={toggleError} /> <ErrorDetail error={toggleError} />
</AlertModal> </AlertModal>
)} )}
@@ -268,4 +266,4 @@ NotificationList.defaultProps = {
showApprovalsToggle: false, showApprovalsToggle: false,
}; };
export default withI18n()(NotificationList); export default NotificationList;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { shape, number, string, bool, func } from 'prop-types'; import { shape, number, string, bool, func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Switch } from '@patternfly/react-core'; import { Switch } from '@patternfly/react-core';
@@ -16,29 +16,24 @@ function NotificationListItem({
successTurnedOn, successTurnedOn,
errorTurnedOn, errorTurnedOn,
toggleNotification, toggleNotification,
i18n,
typeLabels, typeLabels,
showApprovalsToggle, showApprovalsToggle,
}) { }) {
return ( return (
<Tr id={`notification-row-${notification.id}`}> <Tr id={`notification-row-${notification.id}`}>
<Td id={`notification-${notification.id}`} dataLabel={i18n._(t`Name`)}> <Td id={`notification-${notification.id}`} dataLabel={t`Name`}>
<Link to={`${detailUrl}`}> <Link to={`${detailUrl}`}>
<b>{notification.name}</b> <b>{notification.name}</b>
</Link> </Link>
</Td> </Td>
<Td dataLabel={i18n._(t`Type`)}> <Td dataLabel={t`Type`}>{typeLabels[notification.notification_type]}</Td>
{typeLabels[notification.notification_type]} <ActionsTd dataLabel={t`Options`} gridColumns="120px 120px 120px 120px">
</Td>
<ActionsTd
dataLabel={i18n._(t`Options`)}
gridColumns="120px 120px 120px 120px"
>
<ActionItem visible={showApprovalsToggle}> <ActionItem visible={showApprovalsToggle}>
<Switch <Switch
id={`notification-${notification.id}-approvals-toggle`} id={`notification-${notification.id}-approvals-toggle`}
label={i18n._(t`Approval`)} label={t`Approval`}
labelOff={i18n._(t`Approval`)} labelOff={t`Approval`}
isChecked={approvalsTurnedOn} isChecked={approvalsTurnedOn}
isDisabled={!canToggleNotifications} isDisabled={!canToggleNotifications}
onChange={() => onChange={() =>
@@ -48,46 +43,46 @@ function NotificationListItem({
'approvals' 'approvals'
) )
} }
aria-label={i18n._(t`Toggle notification approvals`)} aria-label={t`Toggle notification approvals`}
/> />
</ActionItem> </ActionItem>
<ActionItem visible> <ActionItem visible>
<Switch <Switch
id={`notification-${notification.id}-started-toggle`} id={`notification-${notification.id}-started-toggle`}
label={i18n._(t`Start`)} label={t`Start`}
labelOff={i18n._(t`Start`)} labelOff={t`Start`}
isChecked={startedTurnedOn} isChecked={startedTurnedOn}
isDisabled={!canToggleNotifications} isDisabled={!canToggleNotifications}
onChange={() => onChange={() =>
toggleNotification(notification.id, startedTurnedOn, 'started') toggleNotification(notification.id, startedTurnedOn, 'started')
} }
aria-label={i18n._(t`Toggle notification start`)} aria-label={t`Toggle notification start`}
/> />
</ActionItem> </ActionItem>
<ActionItem visible> <ActionItem visible>
<Switch <Switch
id={`notification-${notification.id}-success-toggle`} id={`notification-${notification.id}-success-toggle`}
label={i18n._(t`Success`)} label={t`Success`}
labelOff={i18n._(t`Success`)} labelOff={t`Success`}
isChecked={successTurnedOn} isChecked={successTurnedOn}
isDisabled={!canToggleNotifications} isDisabled={!canToggleNotifications}
onChange={() => onChange={() =>
toggleNotification(notification.id, successTurnedOn, 'success') toggleNotification(notification.id, successTurnedOn, 'success')
} }
aria-label={i18n._(t`Toggle notification success`)} aria-label={t`Toggle notification success`}
/> />
</ActionItem> </ActionItem>
<ActionItem visible> <ActionItem visible>
<Switch <Switch
id={`notification-${notification.id}-error-toggle`} id={`notification-${notification.id}-error-toggle`}
label={i18n._(t`Failure`)} label={t`Failure`}
labelOff={i18n._(t`Failure`)} labelOff={t`Failure`}
isChecked={errorTurnedOn} isChecked={errorTurnedOn}
isDisabled={!canToggleNotifications} isDisabled={!canToggleNotifications}
onChange={() => onChange={() =>
toggleNotification(notification.id, errorTurnedOn, 'error') toggleNotification(notification.id, errorTurnedOn, 'error')
} }
aria-label={i18n._(t`Toggle notification failure`)} aria-label={t`Toggle notification failure`}
/> />
</ActionItem> </ActionItem>
</ActionsTd> </ActionsTd>
@@ -120,4 +115,4 @@ NotificationListItem.defaultProps = {
showApprovalsToggle: false, showApprovalsToggle: false,
}; };
export default withI18n()(NotificationListItem); export default NotificationListItem;

View File

@@ -9,7 +9,7 @@ import {
oneOfType, oneOfType,
} from 'prop-types'; } from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import SelectedList from '../SelectedList'; import SelectedList from '../SelectedList';
import PaginatedDataList from '../PaginatedDataList'; import PaginatedDataList from '../PaginatedDataList';
@@ -41,14 +41,14 @@ function OptionsList({
deselectItem, deselectItem,
renderItemChip, renderItemChip,
isLoading, isLoading,
i18n,
displayKey, displayKey,
}) { }) {
return ( return (
<ModalList> <ModalList>
{value.length > 0 && ( {value.length > 0 && (
<SelectedList <SelectedList
label={i18n._(t`Selected`)} label={t`Selected`}
selected={value} selected={value}
onRemove={item => deselectItem(item)} onRemove={item => deselectItem(item)}
isReadOnly={readOnly} isReadOnly={readOnly}
@@ -113,4 +113,4 @@ OptionsList.defaultProps = {
displayKey: 'name', displayKey: 'name',
}; };
export default withI18n()(OptionsList); export default OptionsList;

View File

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { DataList } from '@patternfly/react-core'; import { DataList } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withRouter, useHistory, useLocation } from 'react-router-dom'; import { withRouter, useHistory, useLocation } from 'react-router-dom';
@@ -40,7 +40,7 @@ function PaginatedDataList({
pluralizedItemName, pluralizedItemName,
showPageSizeOptions, showPageSizeOptions,
location, location,
i18n,
renderToolbar, renderToolbar,
}) { }) {
const { search, pathname } = useLocation(); const { search, pathname } = useLocation();
@@ -74,7 +74,7 @@ function PaginatedDataList({
? toolbarSearchColumns ? toolbarSearchColumns
: [ : [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
isDefault: true, isDefault: true,
}, },
@@ -83,17 +83,15 @@ function PaginatedDataList({
? toolbarSortColumns ? toolbarSortColumns
: [ : [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
}, },
]; ];
const queryParams = parseQueryString(qsConfig, location.search); const queryParams = parseQueryString(qsConfig, location.search);
const dataListLabel = i18n._(t`${pluralizedItemName} List`); const dataListLabel = t`${pluralizedItemName} List`;
const emptyContentMessage = i18n._( const emptyContentMessage = t`Please add ${pluralizedItemName} to populate this list `;
t`Please add ${pluralizedItemName} to populate this list ` const emptyContentTitle = t`No ${pluralizedItemName} Found `;
);
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
let Content; let Content;
if (hasContentLoading && items.length <= 0) { if (hasContentLoading && items.length <= 0) {
@@ -218,4 +216,4 @@ PaginatedDataList.defaultProps = {
}; };
export { PaginatedDataList as _PaginatedDataList }; export { PaginatedDataList as _PaginatedDataList };
export default withI18n()(withRouter(PaginatedDataList)); export default withRouter(PaginatedDataList);

View File

@@ -3,16 +3,16 @@ import { string, func } from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Button, DropdownItem, Tooltip } from '@patternfly/react-core'; import { Button, DropdownItem, Tooltip } from '@patternfly/react-core';
import CaretDownIcon from '@patternfly/react-icons/dist/js/icons/caret-down-icon'; import CaretDownIcon from '@patternfly/react-icons/dist/js/icons/caret-down-icon';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useKebabifiedMenu } from '../../contexts/Kebabified'; import { useKebabifiedMenu } from '../../contexts/Kebabified';
function ToolbarAddButton({ function ToolbarAddButton({
linkTo, linkTo,
onClick, onClick,
i18n,
isDisabled, isDisabled,
defaultLabel = i18n._(t`Add`), defaultLabel = t`Add`,
showToggleIndicator, showToggleIndicator,
}) { }) {
const { isKebabified } = useKebabifiedMenu(); const { isKebabified } = useKebabifiedMenu();
@@ -72,4 +72,4 @@ ToolbarAddButton.defaultProps = {
onClick: null, onClick: null,
}; };
export default withI18n()(ToolbarAddButton); export default ToolbarAddButton;

View File

@@ -2,7 +2,7 @@ import 'styled-components/macro';
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { TableComposable, Tbody } from '@patternfly/react-table'; import { TableComposable, Tbody } from '@patternfly/react-table';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
@@ -35,7 +35,7 @@ function PaginatedTable({
toolbarRelatedSearchableKeys, toolbarRelatedSearchableKeys,
pluralizedItemName, pluralizedItemName,
showPageSizeOptions, showPageSizeOptions,
i18n,
renderToolbar, renderToolbar,
emptyContentMessage, emptyContentMessage,
ouiaId, ouiaId,
@@ -67,15 +67,15 @@ function PaginatedTable({
? toolbarSearchColumns ? toolbarSearchColumns
: [ : [
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name', key: 'name',
isDefault: true, isDefault: true,
}, },
]; ];
const queryParams = parseQueryString(qsConfig, history.location.search); const queryParams = parseQueryString(qsConfig, history.location.search);
const dataListLabel = i18n._(t`${pluralizedItemName} List`); const dataListLabel = t`${pluralizedItemName} List`;
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `); const emptyContentTitle = t`No ${pluralizedItemName} Found `;
let Content; let Content;
if (hasContentLoading && items.length <= 0) { if (hasContentLoading && items.length <= 0) {
@@ -88,7 +88,7 @@ function PaginatedTable({
title={emptyContentTitle} title={emptyContentTitle}
message={ message={
emptyContentMessage || emptyContentMessage ||
i18n._(t`Please add ${pluralizedItemName} to populate this list `) t`Please add ${pluralizedItemName} to populate this list `
} }
/> />
); );
@@ -201,4 +201,4 @@ PaginatedTable.defaultProps = {
}; };
export { PaginatedTable as _PaginatedTable }; export { PaginatedTable as _PaginatedTable };
export default withI18n()(PaginatedTable); export default PaginatedTable;

View File

@@ -4,7 +4,7 @@ import {
Pagination as PFPagination, Pagination as PFPagination,
DropdownDirection, DropdownDirection,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import { i18n } from '@lingui/core'; import {} from '@lingui/core';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
const AWXPagination = styled(PFPagination)` const AWXPagination = styled(PFPagination)`
@@ -21,18 +21,18 @@ const AWXPagination = styled(PFPagination)`
export default props => ( export default props => (
<AWXPagination <AWXPagination
titles={{ titles={{
items: i18n._(t`items`), items: t`items`,
page: i18n._(t`page`), page: t`page`,
pages: i18n._(t`pages`), pages: t`pages`,
itemsPerPage: i18n._(t`Items per page`), itemsPerPage: t`Items per page`,
perPageSuffix: i18n._(t`per page`), perPageSuffix: t`per page`,
toFirstPage: i18n._(t`Go to first page`), toFirstPage: t`Go to first page`,
toPreviousPage: i18n._(t`Go to previous page`), toPreviousPage: t`Go to previous page`,
toLastPage: i18n._(t`Go to last page`), toLastPage: t`Go to last page`,
toNextPage: i18n._(t`Go to next page`), toNextPage: t`Go to next page`,
optionsToggle: i18n._(t`Select`), optionsToggle: t`Select`,
currPage: i18n._(t`Current page`), currPage: t`Current page`,
paginationTitle: i18n._(t`Pagination`), paginationTitle: t`Pagination`,
}} }}
dropDirection={DropdownDirection.up} dropDirection={DropdownDirection.up}
{...props} {...props}

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { node, string } from 'prop-types'; import { node, string } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Popover as PFPopover } from '@patternfly/react-core'; import { Popover as PFPopover } from '@patternfly/react-core';
import { HelpIcon } from '@patternfly/react-icons'; import { HelpIcon } from '@patternfly/react-icons';
@@ -12,16 +12,7 @@ const PopoverButton = styled.button`
font-size: var(--pf-global--FontSize--sm); font-size: var(--pf-global--FontSize--sm);
`; `;
function Popover({ function Popover({ ariaLabel, content, header, id, maxWidth, ...rest }) {
i18n,
i18nHash,
ariaLabel,
content,
header,
id,
maxWidth,
...rest
}) {
if (!content) { if (!content) {
return null; return null;
} }
@@ -36,7 +27,7 @@ function Popover({
{...rest} {...rest}
> >
<PopoverButton <PopoverButton
aria-label={ariaLabel ?? i18n._(t`More information`)} aria-label={ariaLabel ?? t`More information`}
aria-haspopup="true" aria-haspopup="true"
className="pf-c-form__group-label-help" className="pf-c-form__group-label-help"
onClick={e => e.preventDefault()} onClick={e => e.preventDefault()}
@@ -63,4 +54,4 @@ Popover.defaultProps = {
maxWidth: '', maxWidth: '',
}; };
export default withI18n()(Popover); export default Popover;

View File

@@ -1,7 +1,7 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React from 'react'; import React from 'react';
import { shape } from 'prop-types'; import { shape } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t, Trans } from '@lingui/macro'; import { t, Trans } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -90,13 +90,13 @@ function omitOverrides(resource, overrides, defaultConfig) {
return clonedResource; return clonedResource;
} }
function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) { function PromptDetail({ resource, launchConfig = {}, overrides = {} }) {
const VERBOSITY = { const VERBOSITY = {
0: i18n._(t`0 (Normal)`), 0: t`0 (Normal)`,
1: i18n._(t`1 (Verbose)`), 1: t`1 (Verbose)`,
2: i18n._(t`2 (More Verbose)`), 2: t`2 (More Verbose)`,
3: i18n._(t`3 (Debug)`), 3: t`3 (Debug)`,
4: i18n._(t`4 (Connection Debug)`), 4: t`4 (Connection Debug)`,
}; };
const details = omitOverrides(resource, overrides, launchConfig.defaults); const details = omitOverrides(resource, overrides, launchConfig.defaults);
@@ -106,16 +106,13 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
return ( return (
<> <>
<DetailList gutter="sm"> <DetailList gutter="sm">
<Detail label={i18n._(t`Name`)} value={buildResourceLink(resource)} /> <Detail label={t`Name`} value={buildResourceLink(resource)} />
<Detail label={i18n._(t`Description`)} value={details.description} /> <Detail label={t`Description`} value={details.description} />
<Detail <Detail
label={i18n._(t`Type`)} label={t`Type`}
value={toTitleCase(details.unified_job_type || details.type)} value={toTitleCase(details.unified_job_type || details.type)}
/> />
<Detail <Detail label={t`Timeout`} value={formatTimeout(details?.timeout)} />
label={i18n._(t`Timeout`)}
value={formatTimeout(details?.timeout)}
/>
{details?.type === 'project' && ( {details?.type === 'project' && (
<PromptProjectDetail resource={details} /> <PromptProjectDetail resource={details} />
)} )}
@@ -130,14 +127,14 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
)} )}
{details?.created && ( {details?.created && (
<UserDateDetail <UserDateDetail
label={i18n._(t`Created`)} label={t`Created`}
date={details.created} date={details.created}
user={details?.summary_fields?.created_by} user={details?.summary_fields?.created_by}
/> />
)} )}
{details?.modified && ( {details?.modified && (
<UserDateDetail <UserDateDetail
label={i18n._(t`Last Modified`)} label={t`Last Modified`}
date={details?.modified} date={details?.modified}
user={details?.summary_fields?.modified_by} user={details?.summary_fields?.modified_by}
/> />
@@ -146,21 +143,19 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
{hasPromptData(launchConfig) && hasOverrides && ( {hasPromptData(launchConfig) && hasOverrides && (
<> <>
<PromptTitle headingLevel="h2"> <PromptTitle headingLevel="h2">{t`Prompted Values`}</PromptTitle>
{i18n._(t`Prompted Values`)}
</PromptTitle>
<PromptDivider /> <PromptDivider />
<PromptDetailList aria-label={i18n._(t`Prompt Overrides`)}> <PromptDetailList aria-label={t`Prompt Overrides`}>
{launchConfig.ask_job_type_on_launch && ( {launchConfig.ask_job_type_on_launch && (
<Detail <Detail
label={i18n._(t`Job Type`)} label={t`Job Type`}
value={toTitleCase(overrides.job_type)} value={toTitleCase(overrides.job_type)}
/> />
)} )}
{launchConfig.ask_credential_on_launch && ( {launchConfig.ask_credential_on_launch && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credentials`)} label={t`Credentials`}
rows={4} rows={4}
value={ value={
<ChipGroup <ChipGroup
@@ -179,31 +174,28 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
/> />
)} )}
{launchConfig.ask_inventory_on_launch && ( {launchConfig.ask_inventory_on_launch && (
<Detail <Detail label={t`Inventory`} value={overrides.inventory?.name} />
label={i18n._(t`Inventory`)}
value={overrides.inventory?.name}
/>
)} )}
{launchConfig.ask_scm_branch_on_launch && ( {launchConfig.ask_scm_branch_on_launch && (
<Detail <Detail
label={i18n._(t`Source Control Branch`)} label={t`Source Control Branch`}
value={overrides.scm_branch} value={overrides.scm_branch}
/> />
)} )}
{launchConfig.ask_limit_on_launch && ( {launchConfig.ask_limit_on_launch && (
<Detail label={i18n._(t`Limit`)} value={overrides.limit} /> <Detail label={t`Limit`} value={overrides.limit} />
)} )}
{Object.prototype.hasOwnProperty.call(overrides, 'verbosity') && {Object.prototype.hasOwnProperty.call(overrides, 'verbosity') &&
launchConfig.ask_verbosity_on_launch ? ( launchConfig.ask_verbosity_on_launch ? (
<Detail <Detail
label={i18n._(t`Verbosity`)} label={t`Verbosity`}
value={VERBOSITY[overrides.verbosity]} value={VERBOSITY[overrides.verbosity]}
/> />
) : null} ) : null}
{launchConfig.ask_tags_on_launch && ( {launchConfig.ask_tags_on_launch && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Job Tags`)} label={t`Job Tags`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -226,7 +218,7 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
{launchConfig.ask_skip_tags_on_launch && ( {launchConfig.ask_skip_tags_on_launch && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Skip Tags`)} label={t`Skip Tags`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -248,16 +240,14 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
)} )}
{launchConfig.ask_diff_mode_on_launch && ( {launchConfig.ask_diff_mode_on_launch && (
<Detail <Detail
label={i18n._(t`Show Changes`)} label={t`Show Changes`}
value={ value={overrides.diff_mode === true ? t`On` : t`Off`}
overrides.diff_mode === true ? i18n._(t`On`) : i18n._(t`Off`)
}
/> />
)} )}
{(launchConfig.survey_enabled || {(launchConfig.survey_enabled ||
launchConfig.ask_variables_on_launch) && ( launchConfig.ask_variables_on_launch) && (
<VariablesDetail <VariablesDetail
label={i18n._(t`Variables`)} label={t`Variables`}
rows={4} rows={4}
value={overrides.extra_vars} value={overrides.extra_vars}
/> />
@@ -278,4 +268,4 @@ PromptDetail.propTypes = {
launchConfig: shape({}), launchConfig: shape({}),
}; };
export default withI18n()(PromptDetail); export default PromptDetail;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@@ -10,7 +10,7 @@ import CredentialChip from '../CredentialChip';
import ChipGroup from '../ChipGroup'; import ChipGroup from '../ChipGroup';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail'; import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
function PromptInventorySourceDetail({ i18n, resource }) { function PromptInventorySourceDetail({ resource }) {
const { const {
custom_virtualenv, custom_virtualenv,
group_by, group_by,
@@ -29,11 +29,11 @@ function PromptInventorySourceDetail({ i18n, resource }) {
} = resource; } = resource;
const VERBOSITY = { const VERBOSITY = {
0: i18n._(t`0 (Normal)`), 0: t`0 (Normal)`,
1: i18n._(t`1 (Verbose)`), 1: t`1 (Verbose)`,
2: i18n._(t`2 (More Verbose)`), 2: t`2 (More Verbose)`,
3: i18n._(t`3 (Debug)`), 3: t`3 (Debug)`,
4: i18n._(t`4 (Connection Debug)`), 4: t`4 (Connection Debug)`,
}; };
let optionsList = ''; let optionsList = '';
@@ -45,13 +45,11 @@ function PromptInventorySourceDetail({ i18n, resource }) {
) { ) {
optionsList = ( optionsList = (
<List> <List>
{overwrite && <ListItem>{i18n._(t`Overwrite`)}</ListItem>} {overwrite && <ListItem>{t`Overwrite`}</ListItem>}
{overwrite_vars && ( {overwrite_vars && <ListItem>{t`Overwrite Variables`}</ListItem>}
<ListItem>{i18n._(t`Overwrite Variables`)}</ListItem> {update_on_launch && <ListItem>{t`Update on Launch`}</ListItem>}
)}
{update_on_launch && <ListItem>{i18n._(t`Update on Launch`)}</ListItem>}
{update_on_project_update && ( {update_on_project_update && (
<ListItem>{i18n._(t`Update on Project Update`)}</ListItem> <ListItem>{t`Update on Project Update`}</ListItem>
)} )}
</List> </List>
); );
@@ -61,7 +59,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
<> <>
{summary_fields?.organization ? ( {summary_fields?.organization ? (
<Detail <Detail
label={i18n._(t`Organization`)} label={t`Organization`}
value={ value={
<Link <Link
to={`/organizations/${summary_fields.organization.id}/details`} to={`/organizations/${summary_fields.organization.id}/details`}
@@ -71,11 +69,11 @@ function PromptInventorySourceDetail({ i18n, resource }) {
} }
/> />
) : ( ) : (
<DeletedDetail label={i18n._(t`Organization`)} /> <DeletedDetail label={t`Organization`} />
)} )}
{summary_fields?.inventory && ( {summary_fields?.inventory && (
<Detail <Detail
label={i18n._(t`Inventory`)} label={t`Inventory`}
value={ value={
<Link to={`/inventories/${summary_fields.inventory?.id}/details`}> <Link to={`/inventories/${summary_fields.inventory?.id}/details`}>
{summary_fields?.inventory?.name} {summary_fields?.inventory?.name}
@@ -83,10 +81,10 @@ function PromptInventorySourceDetail({ i18n, resource }) {
} }
/> />
)} )}
<Detail label={i18n._(t`Source`)} value={source} /> <Detail label={t`Source`} value={source} />
{summary_fields?.source_project && ( {summary_fields?.source_project && (
<Detail <Detail
label={i18n._(t`Project`)} label={t`Project`}
value={ value={
<Link to={`/projects/${summary_fields.source_project?.id}/details`}> <Link to={`/projects/${summary_fields.source_project?.id}/details`}>
{summary_fields.source_project?.name} {summary_fields.source_project?.name}
@@ -98,16 +96,16 @@ function PromptInventorySourceDetail({ i18n, resource }) {
virtualEnvironment={custom_virtualenv} virtualEnvironment={custom_virtualenv}
executionEnvironment={summary_fields?.execution_environment} executionEnvironment={summary_fields?.execution_environment}
/> />
<Detail label={i18n._(t`Inventory File`)} value={source_path} /> <Detail label={t`Inventory File`} value={source_path} />
<Detail label={i18n._(t`Verbosity`)} value={VERBOSITY[verbosity]} /> <Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
<Detail <Detail
label={i18n._(t`Cache Timeout`)} label={t`Cache Timeout`}
value={`${update_cache_timeout} ${i18n._(t`Seconds`)}`} value={`${update_cache_timeout} ${t`Seconds`}`}
/> />
{summary_fields?.credentials?.length > 0 && ( {summary_fields?.credentials?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credential`)} label={t`Credential`}
value={summary_fields.credentials.map(cred => ( value={summary_fields.credentials.map(cred => (
<CredentialChip key={cred?.id} credential={cred} isReadOnly /> <CredentialChip key={cred?.id} credential={cred} isReadOnly />
))} ))}
@@ -116,7 +114,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{source_regions && ( {source_regions && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Regions`)} label={t`Regions`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -134,7 +132,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{instance_filters && ( {instance_filters && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Instance Filters`)} label={t`Instance Filters`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -152,7 +150,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{group_by && ( {group_by && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Only Group By`)} label={t`Only Group By`}
value={ value={
<ChipGroup numChips={5} totalChips={group_by.split(',').length}> <ChipGroup numChips={5} totalChips={group_by.split(',').length}>
{group_by.split(',').map(group => ( {group_by.split(',').map(group => (
@@ -164,10 +162,10 @@ function PromptInventorySourceDetail({ i18n, resource }) {
} }
/> />
)} )}
{optionsList && <Detail label={i18n._(t`Options`)} value={optionsList} />} {optionsList && <Detail label={t`Options`} value={optionsList} />}
{source_vars && ( {source_vars && (
<VariablesDetail <VariablesDetail
label={i18n._(t`Source Variables`)} label={t`Source Variables`}
rows={4} rows={4}
value={source_vars} value={source_vars}
/> />
@@ -176,4 +174,4 @@ function PromptInventorySourceDetail({ i18n, resource }) {
); );
} }
export default withI18n()(PromptInventorySourceDetail); export default PromptInventorySourceDetail;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@@ -12,7 +12,7 @@ import { VariablesDetail } from '../CodeEditor';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail'; import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
import { toTitleCase } from '../../util/strings'; import { toTitleCase } from '../../util/strings';
function PromptJobTemplateDetail({ i18n, resource }) { function PromptJobTemplateDetail({ resource }) {
const { const {
allow_simultaneous, allow_simultaneous,
ask_inventory_on_launch, ask_inventory_on_launch,
@@ -39,11 +39,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} = resource; } = resource;
const VERBOSITY = { const VERBOSITY = {
0: i18n._(t`0 (Normal)`), 0: t`0 (Normal)`,
1: i18n._(t`1 (Verbose)`), 1: t`1 (Verbose)`,
2: i18n._(t`2 (More Verbose)`), 2: t`2 (More Verbose)`,
3: i18n._(t`3 (Debug)`), 3: t`3 (Debug)`,
4: i18n._(t`4 (Connection Debug)`), 4: t`4 (Connection Debug)`,
}; };
let optionsList = ''; let optionsList = '';
@@ -56,15 +56,13 @@ function PromptJobTemplateDetail({ i18n, resource }) {
optionsList = ( optionsList = (
<List> <List>
{become_enabled && ( {become_enabled && (
<ListItem>{i18n._(t`Enable Privilege Escalation`)}</ListItem> <ListItem>{t`Enable Privilege Escalation`}</ListItem>
)} )}
{host_config_key && ( {host_config_key && (
<ListItem>{i18n._(t`Allow Provisioning Callbacks`)}</ListItem> <ListItem>{t`Allow Provisioning Callbacks`}</ListItem>
)} )}
{allow_simultaneous && ( {allow_simultaneous && <ListItem>{t`Enable Concurrent Jobs`}</ListItem>}
<ListItem>{i18n._(t`Enable Concurrent Jobs`)}</ListItem> {use_fact_cache && <ListItem>{t`Use Fact Storage`}</ListItem>}
)}
{use_fact_cache && <ListItem>{i18n._(t`Use Fact Storage`)}</ListItem>}
</List> </List>
); );
} }
@@ -82,15 +80,12 @@ function PromptJobTemplateDetail({ i18n, resource }) {
return ( return (
<> <>
{summary_fields.recent_jobs?.length > 0 && ( {summary_fields.recent_jobs?.length > 0 && (
<Detail <Detail value={<Sparkline jobs={recentJobs} />} label={t`Activity`} />
value={<Sparkline jobs={recentJobs} />}
label={i18n._(t`Activity`)}
/>
)} )}
<Detail label={i18n._(t`Job Type`)} value={toTitleCase(job_type)} /> <Detail label={t`Job Type`} value={toTitleCase(job_type)} />
{summary_fields?.organization ? ( {summary_fields?.organization ? (
<Detail <Detail
label={i18n._(t`Organization`)} label={t`Organization`}
value={ value={
<Link <Link
to={`/organizations/${summary_fields.organization.id}/details`} to={`/organizations/${summary_fields.organization.id}/details`}
@@ -100,11 +95,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} }
/> />
) : ( ) : (
<DeletedDetail label={i18n._(t`Organization`)} /> <DeletedDetail label={t`Organization`} />
)} )}
{summary_fields?.inventory ? ( {summary_fields?.inventory ? (
<Detail <Detail
label={i18n._(t`Inventory`)} label={t`Inventory`}
value={ value={
<Link <Link
to={`/${inventoryKind}/${summary_fields.inventory?.id}/details`} to={`/${inventoryKind}/${summary_fields.inventory?.id}/details`}
@@ -114,13 +109,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} }
/> />
) : ( ) : (
!ask_inventory_on_launch && ( !ask_inventory_on_launch && <DeletedDetail label={t`Inventory`} />
<DeletedDetail label={i18n._(t`Inventory`)} />
)
)} )}
{summary_fields?.project ? ( {summary_fields?.project ? (
<Detail <Detail
label={i18n._(t`Project`)} label={t`Project`}
value={ value={
<Link to={`/projects/${summary_fields.project?.id}/details`}> <Link to={`/projects/${summary_fields.project?.id}/details`}>
{summary_fields.project?.name} {summary_fields.project?.name}
@@ -128,46 +121,40 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} }
/> />
) : ( ) : (
<DeletedDetail label={i18n._(t`Project`)} /> <DeletedDetail label={t`Project`} />
)} )}
<ExecutionEnvironmentDetail <ExecutionEnvironmentDetail
virtualEnvironment={custom_virtualenv} virtualEnvironment={custom_virtualenv}
executionEnvironment={summary_fields?.execution_environment} executionEnvironment={summary_fields?.execution_environment}
/> />
<Detail label={i18n._(t`Source Control Branch`)} value={scm_branch} /> <Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={i18n._(t`Playbook`)} value={playbook} /> <Detail label={t`Playbook`} value={playbook} />
<Detail label={i18n._(t`Forks`)} value={forks || '0'} /> <Detail label={t`Forks`} value={forks || '0'} />
<Detail label={i18n._(t`Limit`)} value={limit} /> <Detail label={t`Limit`} value={limit} />
<Detail label={i18n._(t`Verbosity`)} value={VERBOSITY[verbosity]} /> <Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
{typeof diff_mode === 'boolean' && ( {typeof diff_mode === 'boolean' && (
<Detail <Detail label={t`Show Changes`} value={diff_mode ? t`On` : t`Off`} />
label={i18n._(t`Show Changes`)}
value={diff_mode ? i18n._(t`On`) : i18n._(t`Off`)}
/>
)} )}
<Detail label={i18n._(t` Job Slicing`)} value={job_slice_count} /> <Detail label={t` Job Slicing`} value={job_slice_count} />
<Detail label={i18n._(t`Host Config Key`)} value={host_config_key} /> <Detail label={t`Host Config Key`} value={host_config_key} />
{related?.callback && ( {related?.callback && (
<Detail <Detail
label={i18n._(t`Provisioning Callback URL`)} label={t`Provisioning Callback URL`}
value={`${window.location.origin}${related.callback}`} value={`${window.location.origin}${related.callback}`}
/> />
)} )}
<Detail <Detail label={t`Webhook Service`} value={toTitleCase(webhook_service)} />
label={i18n._(t`Webhook Service`)}
value={toTitleCase(webhook_service)}
/>
{related?.webhook_receiver && ( {related?.webhook_receiver && (
<Detail <Detail
label={i18n._(t`Webhook URL`)} label={t`Webhook URL`}
value={`${window.location.origin}${related.webhook_receiver}`} value={`${window.location.origin}${related.webhook_receiver}`}
/> />
)} )}
<Detail label={i18n._(t`Webhook Key`)} value={webhook_key} /> <Detail label={t`Webhook Key`} value={webhook_key} />
{summary_fields?.webhook_credential && ( {summary_fields?.webhook_credential && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Webhook Credential`)} label={t`Webhook Credential`}
value={ value={
<CredentialChip <CredentialChip
key={summary_fields.webhook_credential?.id} key={summary_fields.webhook_credential?.id}
@@ -177,11 +164,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} }
/> />
)} )}
{optionsList && <Detail label={i18n._(t`Options`)} value={optionsList} />} {optionsList && <Detail label={t`Options`} value={optionsList} />}
{summary_fields?.credentials?.length > 0 && ( {summary_fields?.credentials?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credentials`)} label={t`Credentials`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -197,7 +184,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{summary_fields?.labels?.results?.length > 0 && ( {summary_fields?.labels?.results?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Labels`)} label={t`Labels`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -215,7 +202,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{instance_groups?.length > 0 && ( {instance_groups?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Instance Groups`)} label={t`Instance Groups`}
value={ value={
<ChipGroup numChips={5} totalChips={instance_groups.length}> <ChipGroup numChips={5} totalChips={instance_groups.length}>
{instance_groups.map(ig => ( {instance_groups.map(ig => (
@@ -230,7 +217,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{job_tags?.length > 0 && ( {job_tags?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Job Tags`)} label={t`Job Tags`}
value={ value={
<ChipGroup numChips={5} totalChips={job_tags.split(',').length}> <ChipGroup numChips={5} totalChips={job_tags.split(',').length}>
{job_tags.split(',').map(jobTag => ( {job_tags.split(',').map(jobTag => (
@@ -245,7 +232,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{skip_tags?.length > 0 && ( {skip_tags?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Skip Tags`)} label={t`Skip Tags`}
value={ value={
<ChipGroup numChips={5} totalChips={skip_tags.split(',').length}> <ChipGroup numChips={5} totalChips={skip_tags.split(',').length}>
{skip_tags.split(',').map(skipTag => ( {skip_tags.split(',').map(skipTag => (
@@ -258,14 +245,10 @@ function PromptJobTemplateDetail({ i18n, resource }) {
/> />
)} )}
{extra_vars && ( {extra_vars && (
<VariablesDetail <VariablesDetail label={t`Variables`} rows={4} value={extra_vars} />
label={i18n._(t`Variables`)}
rows={4}
value={extra_vars}
/>
)} )}
</> </>
); );
} }
export default withI18n()(PromptJobTemplateDetail); export default PromptJobTemplateDetail;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { List, ListItem } from '@patternfly/react-core'; import { List, ListItem } from '@patternfly/react-core';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@@ -10,7 +10,7 @@ import CredentialChip from '../CredentialChip';
import { toTitleCase } from '../../util/strings'; import { toTitleCase } from '../../util/strings';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail'; import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
function PromptProjectDetail({ i18n, resource }) { function PromptProjectDetail({ resource }) {
const { const {
allow_override, allow_override,
custom_virtualenv, custom_virtualenv,
@@ -37,21 +37,15 @@ function PromptProjectDetail({ i18n, resource }) {
) { ) {
optionsList = ( optionsList = (
<List> <List>
{scm_clean && <ListItem>{i18n._(t`Clean`)}</ListItem>} {scm_clean && <ListItem>{t`Clean`}</ListItem>}
{scm_delete_on_update && ( {scm_delete_on_update && <ListItem>{t`Delete on Update`}</ListItem>}
<ListItem>{i18n._(t`Delete on Update`)}</ListItem>
)}
{scm_track_submodules && ( {scm_track_submodules && (
<ListItem> <ListItem>{t`Track submodules latest commit on branch`}</ListItem>
{i18n._(t`Track submodules latest commit on branch`)}
</ListItem>
)} )}
{scm_update_on_launch && ( {scm_update_on_launch && (
<ListItem>{i18n._(t`Update Revision on Launch`)}</ListItem> <ListItem>{t`Update Revision on Launch`}</ListItem>
)}
{allow_override && (
<ListItem>{i18n._(t`Allow Branch Override`)}</ListItem>
)} )}
{allow_override && <ListItem>{t`Allow Branch Override`}</ListItem>}
</List> </List>
); );
} }
@@ -60,7 +54,7 @@ function PromptProjectDetail({ i18n, resource }) {
<> <>
{summary_fields?.organization ? ( {summary_fields?.organization ? (
<Detail <Detail
label={i18n._(t`Organization`)} label={t`Organization`}
value={ value={
<Link <Link
to={`/organizations/${summary_fields.organization.id}/details`} to={`/organizations/${summary_fields.organization.id}/details`}
@@ -70,7 +64,7 @@ function PromptProjectDetail({ i18n, resource }) {
} }
/> />
) : ( ) : (
<DeletedDetail label={i18n._(t`Organization`)} /> <DeletedDetail label={t`Organization`} />
)} )}
<ExecutionEnvironmentDetail <ExecutionEnvironmentDetail
virtualEnvironment={custom_virtualenv} virtualEnvironment={custom_virtualenv}
@@ -78,15 +72,15 @@ function PromptProjectDetail({ i18n, resource }) {
isDefaultEnvironment isDefaultEnvironment
/> />
<Detail <Detail
label={i18n._(t`Source Control Type`)} label={t`Source Control Type`}
value={scm_type === '' ? i18n._(t`Manual`) : toTitleCase(scm_type)} value={scm_type === '' ? t`Manual` : toTitleCase(scm_type)}
/> />
<Detail label={i18n._(t`Source Control URL`)} value={scm_url} /> <Detail label={t`Source Control URL`} value={scm_url} />
<Detail label={i18n._(t`Source Control Branch`)} value={scm_branch} /> <Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={i18n._(t`Source Control Refspec`)} value={scm_refspec} /> <Detail label={t`Source Control Refspec`} value={scm_refspec} />
{summary_fields?.credential?.id && ( {summary_fields?.credential?.id && (
<Detail <Detail
label={i18n._(t`Source Control Credential`)} label={t`Source Control Credential`}
value={ value={
<CredentialChip <CredentialChip
key={resource.summary_fields.credential.id} key={resource.summary_fields.credential.id}
@@ -96,22 +90,19 @@ function PromptProjectDetail({ i18n, resource }) {
} }
/> />
)} )}
{optionsList && <Detail label={i18n._(t`Options`)} value={optionsList} />} {optionsList && <Detail label={t`Options`} value={optionsList} />}
<Detail <Detail
label={i18n._(t`Cache Timeout`)} label={t`Cache Timeout`}
value={`${scm_update_cache_timeout} ${i18n._(t`Seconds`)}`} value={`${scm_update_cache_timeout} ${t`Seconds`}`}
/> />
<Config> <Config>
{({ project_base_dir }) => ( {({ project_base_dir }) => (
<Detail <Detail label={t`Project Base Path`} value={project_base_dir} />
label={i18n._(t`Project Base Path`)}
value={project_base_dir}
/>
)} )}
</Config> </Config>
<Detail label={i18n._(t`Playbook Directory`)} value={local_path} /> <Detail label={t`Playbook Directory`} value={local_path} />
</> </>
); );
} }
export default withI18n()(PromptProjectDetail); export default PromptProjectDetail;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@@ -11,7 +11,7 @@ import { VariablesDetail } from '../CodeEditor';
import Sparkline from '../Sparkline'; import Sparkline from '../Sparkline';
import { toTitleCase } from '../../util/strings'; import { toTitleCase } from '../../util/strings';
function PromptWFJobTemplateDetail({ i18n, resource }) { function PromptWFJobTemplateDetail({ resource }) {
const { const {
allow_simultaneous, allow_simultaneous,
extra_vars, extra_vars,
@@ -27,10 +27,8 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
if (allow_simultaneous || webhook_service) { if (allow_simultaneous || webhook_service) {
optionsList = ( optionsList = (
<List> <List>
{allow_simultaneous && ( {allow_simultaneous && <ListItem>{t`Enable Concurrent Jobs`}</ListItem>}
<ListItem>{i18n._(t`Enable Concurrent Jobs`)}</ListItem> {webhook_service && <ListItem>{t`Enable Webhooks`}</ListItem>}
)}
{webhook_service && <ListItem>{i18n._(t`Enable Webhooks`)}</ListItem>}
</List> </List>
); );
} }
@@ -48,14 +46,11 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
return ( return (
<> <>
{summary_fields?.recent_jobs?.length > 0 && ( {summary_fields?.recent_jobs?.length > 0 && (
<Detail <Detail value={<Sparkline jobs={recentJobs} />} label={t`Activity`} />
value={<Sparkline jobs={recentJobs} />}
label={i18n._(t`Activity`)}
/>
)} )}
{summary_fields?.organization && ( {summary_fields?.organization && (
<Detail <Detail
label={i18n._(t`Organization`)} label={t`Organization`}
value={ value={
<Link <Link
to={`/organizations/${summary_fields.organization.id}/details`} to={`/organizations/${summary_fields.organization.id}/details`}
@@ -67,7 +62,7 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
)} )}
{summary_fields?.inventory && ( {summary_fields?.inventory && (
<Detail <Detail
label={i18n._(t`Inventory`)} label={t`Inventory`}
value={ value={
<Link <Link
to={`/${inventoryKind}/${summary_fields.inventory?.id}/details`} to={`/${inventoryKind}/${summary_fields.inventory?.id}/details`}
@@ -77,24 +72,21 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
} }
/> />
)} )}
<Detail label={i18n._(t`Source Control Branch`)} value={scm_branch} /> <Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={i18n._(t`Limit`)} value={limit} /> <Detail label={t`Limit`} value={limit} />
<Detail <Detail label={t`Webhook Service`} value={toTitleCase(webhook_service)} />
label={i18n._(t`Webhook Service`)} <Detail label={t`Webhook Key`} value={webhook_key} />
value={toTitleCase(webhook_service)}
/>
<Detail label={i18n._(t`Webhook Key`)} value={webhook_key} />
{related?.webhook_receiver && ( {related?.webhook_receiver && (
<Detail <Detail
label={i18n._(t`Webhook URL`)} label={t`Webhook URL`}
value={`${window.location.origin}${related.webhook_receiver}`} value={`${window.location.origin}${related.webhook_receiver}`}
/> />
)} )}
{optionsList && <Detail label={i18n._(t`Options`)} value={optionsList} />} {optionsList && <Detail label={t`Options`} value={optionsList} />}
{summary_fields?.webhook_credential && ( {summary_fields?.webhook_credential && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Webhook Credential`)} label={t`Webhook Credential`}
value={ value={
<CredentialChip <CredentialChip
key={summary_fields.webhook_credential?.id} key={summary_fields.webhook_credential?.id}
@@ -107,7 +99,7 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
{summary_fields?.labels?.results?.length > 0 && ( {summary_fields?.labels?.results?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Labels`)} label={t`Labels`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -123,14 +115,10 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
/> />
)} )}
{extra_vars && ( {extra_vars && (
<VariablesDetail <VariablesDetail label={t`Variables`} rows={4} value={extra_vars} />
label={i18n._(t`Variables`)}
rows={4}
value={extra_vars}
/>
)} )}
</> </>
); );
} }
export default withI18n()(PromptWFJobTemplateDetail); export default PromptWFJobTemplateDetail;

View File

@@ -1,26 +1,18 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { func, string } from 'prop-types'; import { func, string } from 'prop-types';
import { Button } from '@patternfly/react-core'; import { Button } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import AlertModal from '../AlertModal'; import AlertModal from '../AlertModal';
import { Role } from '../../types'; import { Role } from '../../types';
function DeleteRoleConfirmationModal({ function DeleteRoleConfirmationModal({ role, username, onCancel, onConfirm }) {
role,
username,
onCancel,
onConfirm,
i18n,
}) {
const isTeamRole = () => { const isTeamRole = () => {
return typeof role.team_id !== 'undefined' return typeof role.team_id !== 'undefined' ? t`Team` : t`User`;
? i18n._(t`Team`)
: i18n._(t`User`);
}; };
const title = i18n._(t`Remove ${isTeamRole()} Access`); const title = t`Remove ${isTeamRole()} Access`;
return ( return (
<AlertModal <AlertModal
variant="danger" variant="danger"
@@ -32,10 +24,10 @@ function DeleteRoleConfirmationModal({
ouiaId="delete-role-modal-delete-button" ouiaId="delete-role-modal-delete-button"
key="delete" key="delete"
variant="danger" variant="danger"
aria-label={i18n._(t`Confirm delete`)} aria-label={t`Confirm delete`}
onClick={onConfirm} onClick={onConfirm}
> >
{i18n._(t`Delete`)} {t`Delete`}
</Button>, </Button>,
<Button <Button
ouiaId="delete-role-modal-cancel-button" ouiaId="delete-role-modal-cancel-button"
@@ -43,26 +35,20 @@ function DeleteRoleConfirmationModal({
variant="link" variant="link"
onClick={onCancel} onClick={onCancel}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button>, </Button>,
]} ]}
> >
{isTeamRole() ? ( {isTeamRole() ? (
<Fragment> <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.`}
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 />
<br /> <br />
{i18n._( {t`If you only want to remove access for this particular user, please remove them from the team.`}
t`If you only want to remove access for this particular user, please remove them from the team.`
)}
</Fragment> </Fragment>
) : ( ) : (
<Fragment> <Fragment>
{i18n._( {t`Are you sure you want to remove ${role.name} access from ${username}?`}
t`Are you sure you want to remove ${role.name} access from ${username}?`
)}
</Fragment> </Fragment>
)} )}
</AlertModal> </AlertModal>
@@ -80,4 +66,4 @@ DeleteRoleConfirmationModal.defaultProps = {
username: '', username: '',
}; };
export default withI18n()(DeleteRoleConfirmationModal); export default DeleteRoleConfirmationModal;

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { RolesAPI, TeamsAPI, UsersAPI } from '../../api'; import { RolesAPI, TeamsAPI, UsersAPI } from '../../api';
import AddResourceRole from '../AddRole/AddResourceRole'; import AddResourceRole from '../AddRole/AddResourceRole';
@@ -19,7 +19,7 @@ const QS_CONFIG = getQSConfig('access', {
order_by: 'first_name', order_by: 'first_name',
}); });
function ResourceAccessList({ i18n, apiModel, resource }) { function ResourceAccessList({ apiModel, resource }) {
const [submitError, setSubmitError] = useState(null); const [submitError, setSubmitError] = useState(null);
const [deletionRecord, setDeletionRecord] = useState(null); const [deletionRecord, setDeletionRecord] = useState(null);
const [deletionRole, setDeletionRole] = useState(null); const [deletionRole, setDeletionRole] = useState(null);
@@ -124,23 +124,23 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
); );
const toolbarSearchColumns = [ const toolbarSearchColumns = [
{ {
name: i18n._(t`Username`), name: t`Username`,
key: 'username__icontains', key: 'username__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`First Name`), name: t`First Name`,
key: 'first_name__icontains', key: 'first_name__icontains',
}, },
{ {
name: i18n._(t`Last Name`), name: t`Last Name`,
key: 'last_name__icontains', key: 'last_name__icontains',
}, },
]; ];
if (organizationRoles?.length > 0) { if (organizationRoles?.length > 0) {
toolbarSearchColumns.push({ toolbarSearchColumns.push({
name: i18n._(t`Roles`), name: t`Roles`,
key: `or__roles__in`, key: `or__roles__in`,
options: organizationRoles, options: organizationRoles,
}); });
@@ -153,20 +153,20 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
hasContentLoading={isLoading || isDeleteLoading} hasContentLoading={isLoading || isDeleteLoading}
items={accessRecords} items={accessRecords}
itemCount={itemCount} itemCount={itemCount}
pluralizedItemName={i18n._(t`Roles`)} pluralizedItemName={t`Roles`}
qsConfig={QS_CONFIG} qsConfig={QS_CONFIG}
toolbarSearchColumns={toolbarSearchColumns} toolbarSearchColumns={toolbarSearchColumns}
toolbarSortColumns={[ toolbarSortColumns={[
{ {
name: i18n._(t`Username`), name: t`Username`,
key: 'username', key: 'username',
}, },
{ {
name: i18n._(t`First Name`), name: t`First Name`,
key: 'first_name', key: 'first_name',
}, },
{ {
name: i18n._(t`Last Name`), name: t`Last Name`,
key: 'last_name', key: 'last_name',
}, },
]} ]}
@@ -197,7 +197,6 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
setDeletionRole(role); setDeletionRole(role);
setShowDeleteModal(true); setShowDeleteModal(true);
}} }}
i18n={i18n}
/> />
)} )}
/> />
@@ -233,11 +232,11 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
{submitError && ( {submitError && (
<AlertModal <AlertModal
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
isOpen={submitError} isOpen={submitError}
onClose={() => setSubmitError(null)} onClose={() => setSubmitError(null)}
> >
{i18n._(t`Failed to assign roles properly`)} {t`Failed to assign roles properly`}
<ErrorDetail error={submitError} /> <ErrorDetail error={submitError} />
</AlertModal> </AlertModal>
)} )}
@@ -245,13 +244,13 @@ function ResourceAccessList({ i18n, apiModel, resource }) {
<AlertModal <AlertModal
isOpen={deletionError} isOpen={deletionError}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={clearDeletionError} onClose={clearDeletionError}
> >
{i18n._(t`Failed to delete role`)} {t`Failed to delete role`}
</AlertModal> </AlertModal>
)} )}
</> </>
); );
} }
export default withI18n()(ResourceAccessList); export default ResourceAccessList;

View File

@@ -1,7 +1,7 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React from 'react'; import React from 'react';
import { func } from 'prop-types'; import { func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Chip, Chip,
@@ -24,7 +24,7 @@ const DataListItemCells = styled(PFDataListItemCells)`
align-items: start; align-items: start;
`; `;
function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) { function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
ResourceAccessListItem.propTypes = { ResourceAccessListItem.propTypes = {
accessRecord: AccessRecord.isRequired, accessRecord: AccessRecord.isRequired,
onRoleDelete: func.isRequired, onRoleDelete: func.isRequired,
@@ -57,7 +57,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
}} }}
isReadOnly={!role.user_capabilities.unattach} isReadOnly={!role.user_capabilities.unattach}
ouiaId={`${role.name}-${role.id}`} ouiaId={`${role.name}-${role.id}`}
closeBtnAriaLabel={i18n._(t`Remove ${role.name} chip`)} closeBtnAriaLabel={t`Remove ${role.name} chip`}
> >
{role.name} {role.name}
</Chip> </Chip>
@@ -97,7 +97,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
{accessRecord.first_name || accessRecord.last_name ? ( {accessRecord.first_name || accessRecord.last_name ? (
<DetailList stacked> <DetailList stacked>
<Detail <Detail
label={i18n._(t`Name`)} label={t`Name`}
value={`${accessRecord.first_name} ${accessRecord.last_name}`} value={`${accessRecord.first_name} ${accessRecord.last_name}`}
/> />
</DetailList> </DetailList>
@@ -107,7 +107,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
<DetailList stacked> <DetailList stacked>
{userRoles.length > 0 && ( {userRoles.length > 0 && (
<Detail <Detail
label={i18n._(t`User Roles`)} label={t`User Roles`}
value={ value={
<ChipGroup numChips={5} totalChips={userRoles.length}> <ChipGroup numChips={5} totalChips={userRoles.length}>
{userRoles.map(renderChip)} {userRoles.map(renderChip)}
@@ -117,7 +117,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
)} )}
{teamRoles.length > 0 && ( {teamRoles.length > 0 && (
<Detail <Detail
label={i18n._(t`Team Roles`)} label={t`Team Roles`}
value={ value={
<ChipGroup numChips={5} totalChips={teamRoles.length}> <ChipGroup numChips={5} totalChips={teamRoles.length}>
{teamRoles.map(renderChip)} {teamRoles.map(renderChip)}
@@ -134,4 +134,4 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
); );
} }
export default withI18n()(ResourceAccessListItem); export default ResourceAccessListItem;

View File

@@ -1,6 +1,5 @@
import React, { useEffect, useCallback } from 'react'; import React, { useEffect, useCallback } from 'react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { import {
Switch, Switch,
@@ -20,7 +19,6 @@ import { SchedulesAPI } from '../../api';
import useRequest from '../../util/useRequest'; import useRequest from '../../util/useRequest';
function Schedule({ function Schedule({
i18n,
setBreadcrumb, setBreadcrumb,
resource, resource,
launchConfig, launchConfig,
@@ -58,14 +56,14 @@ function Schedule({
name: ( name: (
<> <>
<CaretLeftIcon /> <CaretLeftIcon />
{i18n._(t`Back to Schedules`)} {t`Back to Schedules`}
</> </>
), ),
link: `${pathRoot}schedules`, link: `${pathRoot}schedules`,
id: 99, id: 99,
}, },
{ {
name: i18n._(t`Details`), name: t`Details`,
link: `${pathRoot}schedules/${schedule && schedule.id}/details`, link: `${pathRoot}schedules/${schedule && schedule.id}/details`,
id: 0, id: 0,
}, },
@@ -82,7 +80,7 @@ function Schedule({
return ( return (
<ContentError> <ContentError>
{schedule && ( {schedule && (
<Link to={`${pathRoot}schedules`}>{i18n._(t`View Schedules`)}</Link> <Link to={`${pathRoot}schedules`}>{t`View Schedules`}</Link>
)} )}
</ContentError> </ContentError>
); );
@@ -132,7 +130,7 @@ function Schedule({
<Route key="not-found" path="*"> <Route key="not-found" path="*">
<ContentError> <ContentError>
{resource && ( {resource && (
<Link to={`${pathRoot}details`}>{i18n._(t`View Details`)}</Link> <Link to={`${pathRoot}details`}>{t`View Details`}</Link>
)} )}
</ContentError> </ContentError>
</Route> </Route>
@@ -142,4 +140,4 @@ function Schedule({
} }
export { Schedule as _Schedule }; export { Schedule as _Schedule };
export default withI18n()(Schedule); export default Schedule;

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { func, shape } from 'prop-types'; import { func, shape } from 'prop-types';
import { withI18n } from '@lingui/react';
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import { RRule } from 'rrule'; import { RRule } from 'rrule';
import { Card } from '@patternfly/react-core'; import { Card } from '@patternfly/react-core';
@@ -16,7 +16,6 @@ import getSurveyValues from '../../../util/prompt/getSurveyValues';
import { getAddedAndRemoved } from '../../../util/lists'; import { getAddedAndRemoved } from '../../../util/lists';
function ScheduleAdd({ function ScheduleAdd({
i18n,
resource, resource,
apiModel, apiModel,
launchConfig, launchConfig,
@@ -77,7 +76,7 @@ function ScheduleAdd({
} }
try { try {
const rule = new RRule(buildRuleObj(values, i18n)); const rule = new RRule(buildRuleObj(values));
const requestData = { const requestData = {
...submitValues, ...submitValues,
rrule: rule.toString().replace(/\n/g, ' '), rrule: rule.toString().replace(/\n/g, ' '),
@@ -131,4 +130,4 @@ ScheduleAdd.propTypes = {
ScheduleAdd.defaultProps = {}; ScheduleAdd.defaultProps = {};
export default withI18n()(ScheduleAdd); export default ScheduleAdd;

View File

@@ -3,7 +3,7 @@ import React, { useCallback, useEffect } from 'react';
import { Link, useHistory, useLocation } from 'react-router-dom'; import { Link, useHistory, useLocation } from 'react-router-dom';
import { RRule, rrulestr } from 'rrule'; import { RRule, rrulestr } from 'rrule';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Chip, Divider, Title, Button } from '@patternfly/react-core'; import { Chip, Divider, Title, Button } from '@patternfly/react-core';
import { Schedule } from '../../../types'; import { Schedule } from '../../../types';
@@ -43,7 +43,7 @@ const PromptDetailList = styled(DetailList)`
padding: 0px 20px; padding: 0px 20px;
`; `;
function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) { function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
const { const {
id, id,
created, created,
@@ -72,11 +72,11 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
const pathRoot = pathname.substr(0, pathname.indexOf('schedules')); const pathRoot = pathname.substr(0, pathname.indexOf('schedules'));
const VERBOSITY = { const VERBOSITY = {
0: i18n._(t`0 (Normal)`), 0: t`0 (Normal)`,
1: i18n._(t`1 (Verbose)`), 1: t`1 (Verbose)`,
2: i18n._(t`2 (More Verbose)`), 2: t`2 (More Verbose)`,
3: i18n._(t`3 (Debug)`), 3: t`3 (Debug)`,
4: i18n._(t`4 (Connection Debug)`), 4: t`4 (Connection Debug)`,
}; };
const { const {
@@ -144,7 +144,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
const rule = rrulestr(rrule); const rule = rrulestr(rrule);
const repeatFrequency = const repeatFrequency =
rule.options.freq === RRule.MINUTELY && dtstart === dtend rule.options.freq === RRule.MINUTELY && dtstart === dtend
? i18n._(t`None (Run Once)`) ? t`None (Run Once)`
: rule.toText().replace(/^\w/, c => c.toUpperCase()); : rule.toText().replace(/^\w/, c => c.toUpperCase());
const { const {
@@ -252,47 +252,39 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
isDisabled={isDisabled} isDisabled={isDisabled}
/> />
<DetailList gutter="sm"> <DetailList gutter="sm">
<Detail label={i18n._(t`Name`)} value={name} /> <Detail label={t`Name`} value={name} />
<Detail label={i18n._(t`Description`)} value={description} /> <Detail label={t`Description`} value={description} />
<Detail <Detail label={t`First Run`} value={formatDateString(dtstart)} />
label={i18n._(t`First Run`)} <Detail label={t`Next Run`} value={formatDateString(next_run)} />
value={formatDateString(dtstart)} <Detail label={t`Last Run`} value={formatDateString(dtend)} />
/> <Detail label={t`Local Time Zone`} value={timezone} />
<Detail <Detail label={t`Repeat Frequency`} value={repeatFrequency} />
label={i18n._(t`Next Run`)}
value={formatDateString(next_run)}
/>
<Detail label={i18n._(t`Last Run`)} value={formatDateString(dtend)} />
<Detail label={i18n._(t`Local Time Zone`)} value={timezone} />
<Detail label={i18n._(t`Repeat Frequency`)} value={repeatFrequency} />
{hasDaysToKeepField ? ( {hasDaysToKeepField ? (
<Detail label={i18n._(t`Days of Data to Keep`)} value={daysToKeep} /> <Detail label={t`Days of Data to Keep`} value={daysToKeep} />
) : null} ) : null}
<ScheduleOccurrences preview={preview} /> <ScheduleOccurrences preview={preview} />
<UserDateDetail <UserDateDetail
label={i18n._(t`Created`)} label={t`Created`}
date={created} date={created}
user={summary_fields.created_by} user={summary_fields.created_by}
/> />
<UserDateDetail <UserDateDetail
label={i18n._(t`Last Modified`)} label={t`Last Modified`}
date={modified} date={modified}
user={summary_fields.modified_by} user={summary_fields.modified_by}
/> />
</DetailList> </DetailList>
{showPromptedFields && ( {showPromptedFields && (
<> <>
<PromptTitle headingLevel="h2"> <PromptTitle headingLevel="h2">{t`Prompted Values`}</PromptTitle>
{i18n._(t`Prompted Values`)}
</PromptTitle>
<PromptDivider /> <PromptDivider />
<PromptDetailList> <PromptDetailList>
{ask_job_type_on_launch && ( {ask_job_type_on_launch && (
<Detail label={i18n._(t`Job Type`)} value={job_type} /> <Detail label={t`Job Type`} value={job_type} />
)} )}
{showInventoryDetail && ( {showInventoryDetail && (
<Detail <Detail
label={i18n._(t`Inventory`)} label={t`Inventory`}
value={ value={
summary_fields?.inventory ? ( summary_fields?.inventory ? (
<Link <Link
@@ -311,30 +303,22 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
/> />
)} )}
{ask_verbosity_on_launch && ( {ask_verbosity_on_launch && (
<Detail <Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
label={i18n._(t`Verbosity`)}
value={VERBOSITY[verbosity]}
/>
)} )}
{ask_scm_branch_on_launch && ( {ask_scm_branch_on_launch && (
<Detail <Detail label={t`Source Control Branch`} value={scm_branch} />
label={i18n._(t`Source Control Branch`)}
value={scm_branch}
/>
)}
{ask_limit_on_launch && (
<Detail label={i18n._(t`Limit`)} value={limit} />
)} )}
{ask_limit_on_launch && <Detail label={t`Limit`} value={limit} />}
{showDiffModeDetail && ( {showDiffModeDetail && (
<Detail <Detail
label={i18n._(t`Show Changes`)} label={t`Show Changes`}
value={diff_mode ? i18n._(t`On`) : i18n._(t`Off`)} value={diff_mode ? t`On` : t`Off`}
/> />
)} )}
{showCredentialsDetail && ( {showCredentialsDetail && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credentials`)} label={t`Credentials`}
value={ value={
<ChipGroup numChips={5} totalChips={credentials.length}> <ChipGroup numChips={5} totalChips={credentials.length}>
{credentials.map(c => ( {credentials.map(c => (
@@ -347,7 +331,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
{showTagsDetail && ( {showTagsDetail && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Job Tags`)} label={t`Job Tags`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -365,7 +349,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
{showSkipTagsDetail && ( {showSkipTagsDetail && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Skip Tags`)} label={t`Skip Tags`}
value={ value={
<ChipGroup <ChipGroup
numChips={5} numChips={5}
@@ -384,7 +368,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
<VariablesDetail <VariablesDetail
value={extra_data} value={extra_data}
rows={4} rows={4}
label={i18n._(t`Variables`)} label={t`Variables`}
/> />
)} )}
</PromptDetailList> </PromptDetailList>
@@ -394,21 +378,21 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
{summary_fields?.user_capabilities?.edit && ( {summary_fields?.user_capabilities?.edit && (
<Button <Button
ouiaId="schedule-detail-edit-button" ouiaId="schedule-detail-edit-button"
aria-label={i18n._(t`Edit`)} aria-label={t`Edit`}
component={Link} component={Link}
to={pathname.replace('details', 'edit')} to={pathname.replace('details', 'edit')}
> >
{i18n._(t`Edit`)} {t`Edit`}
</Button> </Button>
)} )}
{summary_fields?.user_capabilities?.delete && ( {summary_fields?.user_capabilities?.delete && (
<DeleteButton <DeleteButton
name={name} name={name}
modalTitle={i18n._(t`Delete Schedule`)} modalTitle={t`Delete Schedule`}
onConfirm={deleteSchedule} onConfirm={deleteSchedule}
isDisabled={isDeleteLoading} isDisabled={isDeleteLoading}
> >
{i18n._(t`Delete`)} {t`Delete`}
</DeleteButton> </DeleteButton>
)} )}
</CardActionsRow> </CardActionsRow>
@@ -416,10 +400,10 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, i18n, surveyConfig }) {
<AlertModal <AlertModal
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={dismissError} onClose={dismissError}
> >
{i18n._(t`Failed to delete schedule.`)} {t`Failed to delete schedule.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</AlertModal> </AlertModal>
)} )}
@@ -431,4 +415,4 @@ ScheduleDetail.propTypes = {
schedule: Schedule.isRequired, schedule: Schedule.isRequired,
}; };
export default withI18n()(ScheduleDetail); export default ScheduleDetail;

View File

@@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import { RRule } from 'rrule'; import { RRule } from 'rrule';
import { shape } from 'prop-types'; import { shape } from 'prop-types';
@@ -16,7 +16,6 @@ import mergeExtraVars from '../../../util/prompt/mergeExtraVars';
import getSurveyValues from '../../../util/prompt/getSurveyValues'; import getSurveyValues from '../../../util/prompt/getSurveyValues';
function ScheduleEdit({ function ScheduleEdit({
i18n,
hasDaysToKeepField, hasDaysToKeepField,
schedule, schedule,
resource, resource,
@@ -84,7 +83,7 @@ function ScheduleEdit({
} }
try { try {
const rule = new RRule(buildRuleObj(values, i18n)); const rule = new RRule(buildRuleObj(values));
const requestData = { const requestData = {
...submitValues, ...submitValues,
rrule: rule.toString().replace(/\n/g, ' '), rrule: rule.toString().replace(/\n/g, ' '),
@@ -145,4 +144,4 @@ ScheduleEdit.propTypes = {
ScheduleEdit.defaultProps = {}; ScheduleEdit.defaultProps = {};
export default withI18n()(ScheduleEdit); export default ScheduleEdit;

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { bool, func } from 'prop-types'; import { bool, func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { SchedulesAPI } from '../../../api'; import { SchedulesAPI } from '../../../api';
import AlertModal from '../../AlertModal'; import AlertModal from '../../AlertModal';
@@ -20,7 +20,6 @@ const QS_CONFIG = getQSConfig('schedule', {
}); });
function ScheduleList({ function ScheduleList({
i18n,
loadSchedules, loadSchedules,
loadScheduleOptions, loadScheduleOptions,
hideAddButton, hideAddButton,
@@ -128,7 +127,7 @@ function ScheduleList({
) { ) {
return null; return null;
} }
return i18n._(t`This schedule is missing an Inventory`); return t`This schedule is missing an Inventory`;
}; };
const hasMissingSurveyValue = schedule => { const hasMissingSurveyValue = schedule => {
@@ -153,10 +152,7 @@ function ScheduleList({
} }
}); });
} }
return ( return missingValues && t`This schedule is missing required survey values`;
missingValues &&
i18n._(t`This schedule is missing required survey values`)
);
}; };
return ( return (
@@ -170,10 +166,10 @@ function ScheduleList({
onRowClick={handleSelect} onRowClick={handleSelect}
headerRow={ headerRow={
<HeaderRow qsConfig={QS_CONFIG}> <HeaderRow qsConfig={QS_CONFIG}>
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell> <HeaderCell sortKey="name">{t`Name`}</HeaderCell>
<HeaderCell>{i18n._(t`Type`)}</HeaderCell> <HeaderCell>{t`Type`}</HeaderCell>
<HeaderCell sortKey="next_run">{i18n._(t`Next Run`)}</HeaderCell> <HeaderCell sortKey="next_run">{t`Next Run`}</HeaderCell>
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell> <HeaderCell>{t`Actions`}</HeaderCell>
</HeaderRow> </HeaderRow>
} }
renderRow={(item, index) => ( renderRow={(item, index) => (
@@ -189,20 +185,20 @@ function ScheduleList({
)} )}
toolbarSearchColumns={[ toolbarSearchColumns={[
{ {
name: i18n._(t`Name`), name: t`Name`,
key: 'name__icontains', key: 'name__icontains',
isDefault: true, isDefault: true,
}, },
{ {
name: i18n._(t`Description`), name: t`Description`,
key: 'description__icontains', key: 'description__icontains',
}, },
{ {
name: i18n._(t`Created By (Username)`), name: t`Created By (Username)`,
key: 'created_by__username__icontains', key: 'created_by__username__icontains',
}, },
{ {
name: i18n._(t`Modified By (Username)`), name: t`Modified By (Username)`,
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
@@ -228,7 +224,7 @@ function ScheduleList({
key="delete" key="delete"
onDelete={handleDelete} onDelete={handleDelete}
itemsToDelete={selected} itemsToDelete={selected}
pluralizedItemName={i18n._(t`Schedules`)} pluralizedItemName={t`Schedules`}
/>, />,
]} ]}
/> />
@@ -238,10 +234,10 @@ function ScheduleList({
<AlertModal <AlertModal
isOpen={deletionError} isOpen={deletionError}
variant="danger" variant="danger"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={clearDeletionError} onClose={clearDeletionError}
> >
{i18n._(t`Failed to delete one or more schedules.`)} {t`Failed to delete one or more schedules.`}
<ErrorDetail error={deletionError} /> <ErrorDetail error={deletionError} />
</AlertModal> </AlertModal>
)} )}
@@ -258,4 +254,4 @@ ScheduleList.defaultProps = {
hideAddButton: false, hideAddButton: false,
}; };
export default withI18n()(ScheduleList); export default ScheduleList;

View File

@@ -1,7 +1,7 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React from 'react'; import React from 'react';
import { bool, func } from 'prop-types'; import { bool, func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Button, Tooltip } from '@patternfly/react-core'; import { Button, Tooltip } from '@patternfly/react-core';
@@ -23,7 +23,6 @@ const ExclamationTriangleIcon = styled(PFExclamationTriangleIcon)`
`; `;
function ScheduleListItem({ function ScheduleListItem({
i18n,
rowIndex, rowIndex,
isSelected, isSelected,
onSelect, onSelect,
@@ -34,11 +33,11 @@ function ScheduleListItem({
const labelId = `check-action-${schedule.id}`; const labelId = `check-action-${schedule.id}`;
const jobTypeLabels = { const jobTypeLabels = {
inventory_update: i18n._(t`Inventory Sync`), inventory_update: t`Inventory Sync`,
job: i18n._(t`Playbook Run`), job: t`Playbook Run`,
project_update: i18n._(t`Source Control Update`), project_update: t`Source Control Update`,
system_job: i18n._(t`Management Job`), system_job: t`Management Job`,
workflow_job: i18n._(t`Workflow Job`), workflow_job: t`Workflow Job`,
}; };
let scheduleBaseUrl; let scheduleBaseUrl;
@@ -73,9 +72,9 @@ function ScheduleListItem({
onSelect, onSelect,
disable: false, disable: false,
}} }}
dataLabel={i18n._(t`Selected`)} dataLabel={t`Selected`}
/> />
<Td id={labelId} dataLabel={i18n._(t`Name`)}> <Td id={labelId} dataLabel={t`Name`}>
<Link to={`${scheduleBaseUrl}/details`}> <Link to={`${scheduleBaseUrl}/details`}>
<b>{schedule.name}</b> <b>{schedule.name}</b>
</Link> </Link>
@@ -92,32 +91,32 @@ function ScheduleListItem({
</span> </span>
)} )}
</Td> </Td>
<Td dataLabel={i18n._(t`Type`)}> <Td dataLabel={t`Type`}>
{ {
jobTypeLabels[ jobTypeLabels[
schedule.summary_fields.unified_job_template.unified_job_type schedule.summary_fields.unified_job_template.unified_job_type
] ]
} }
</Td> </Td>
<Td dataLabel={i18n._(t`Next Run`)}> <Td dataLabel={t`Next Run`}>
{schedule.next_run && ( {schedule.next_run && (
<DetailList stacked> <DetailList stacked>
<Detail <Detail
label={i18n._(t`Next Run`)} label={t`Next Run`}
value={formatDateString(schedule.next_run)} value={formatDateString(schedule.next_run)}
/> />
</DetailList> </DetailList>
)} )}
</Td> </Td>
<ActionsTd dataLabel={i18n._(t`Actions`)} gridColumns="auto 40px"> <ActionsTd dataLabel={t`Actions`} gridColumns="auto 40px">
<ScheduleToggle schedule={schedule} isDisabled={isDisabled} /> <ScheduleToggle schedule={schedule} isDisabled={isDisabled} />
<ActionItem <ActionItem
visible={schedule.summary_fields.user_capabilities.edit} visible={schedule.summary_fields.user_capabilities.edit}
tooltip={i18n._(t`Edit Schedule`)} tooltip={t`Edit Schedule`}
> >
<Button <Button
ouiaId={`${schedule.id}-edit-button`} ouiaId={`${schedule.id}-edit-button`}
aria-label={i18n._(t`Edit Schedule`)} aria-label={t`Edit Schedule`}
css="grid-column: 2" css="grid-column: 2"
variant="plain" variant="plain"
component={Link} component={Link}
@@ -137,4 +136,4 @@ ScheduleListItem.propTypes = {
schedule: Schedule.isRequired, schedule: Schedule.isRequired,
}; };
export default withI18n()(ScheduleListItem); export default ScheduleListItem;

View File

@@ -2,7 +2,7 @@ import 'styled-components/macro';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { shape } from 'prop-types'; import { shape } from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core'; import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
import { formatDateString, formatDateStringUTC } from '../../../util/dates'; import { formatDateString, formatDateStringUTC } from '../../../util/dates';
@@ -22,7 +22,7 @@ const OccurrencesLabel = styled.div`
} }
`; `;
function ScheduleOccurrences({ preview = { local: [], utc: [] }, i18n }) { function ScheduleOccurrences({ preview = { local: [], utc: [] } }) {
const [mode, setMode] = useState('local'); const [mode, setMode] = useState('local');
if (preview.local.length < 2) { if (preview.local.length < 2) {
@@ -39,8 +39,8 @@ function ScheduleOccurrences({ preview = { local: [], utc: [] }, i18n }) {
<Split hasGutter> <Split hasGutter>
<SplitItem> <SplitItem>
<OccurrencesLabel> <OccurrencesLabel>
<span>{i18n._(t`Occurrences`)}</span> <span>{t`Occurrences`}</span>
<span>{i18n._(t`(Limited to first 10)`)}</span> <span>{t`(Limited to first 10)`}</span>
</OccurrencesLabel> </OccurrencesLabel>
</SplitItem> </SplitItem>
<SplitItem> <SplitItem>
@@ -80,4 +80,4 @@ ScheduleOccurrences.defaultProps = {
preview: { local: [], utc: [] }, preview: { local: [], utc: [] },
}; };
export default withI18n()(ScheduleOccurrences); export default ScheduleOccurrences;

View File

@@ -1,6 +1,6 @@
import 'styled-components/macro'; import 'styled-components/macro';
import React, { Fragment, useState, useEffect, useCallback } from 'react'; import React, { Fragment, useState, useEffect, useCallback } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core'; import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../../AlertModal'; import AlertModal from '../../AlertModal';
@@ -8,7 +8,7 @@ import ErrorDetail from '../../ErrorDetail';
import useRequest from '../../../util/useRequest'; import useRequest from '../../../util/useRequest';
import { SchedulesAPI } from '../../../api'; import { SchedulesAPI } from '../../../api';
function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) { function ScheduleToggle({ schedule, onToggle, className, isDisabled }) {
const [isEnabled, setIsEnabled] = useState(schedule.enabled); const [isEnabled, setIsEnabled] = useState(schedule.enabled);
const [showError, setShowError] = useState(false); const [showError, setShowError] = useState(false);
@@ -41,9 +41,7 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
<Fragment> <Fragment>
<Tooltip <Tooltip
content={ content={
schedule.enabled schedule.enabled ? t`Schedule is active` : t`Schedule is inactive`
? i18n._(t`Schedule is active`)
: i18n._(t`Schedule is inactive`)
} }
position="top" position="top"
> >
@@ -51,8 +49,8 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
className={className} className={className}
css="display: inline-flex;" css="display: inline-flex;"
id={`schedule-${schedule.id}-toggle`} id={`schedule-${schedule.id}-toggle`}
label={i18n._(t`On`)} label={t`On`}
labelOff={i18n._(t`Off`)} labelOff={t`Off`}
isChecked={isEnabled} isChecked={isEnabled}
isDisabled={ isDisabled={
isLoading || isLoading ||
@@ -60,17 +58,17 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
isDisabled isDisabled
} }
onChange={toggleSchedule} onChange={toggleSchedule}
aria-label={i18n._(t`Toggle schedule`)} aria-label={t`Toggle schedule`}
/> />
</Tooltip> </Tooltip>
{showError && error && !isLoading && ( {showError && error && !isLoading && (
<AlertModal <AlertModal
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
isOpen={error && !isLoading} isOpen={error && !isLoading}
onClose={() => setShowError(false)} onClose={() => setShowError(false)}
> >
{i18n._(t`Failed to toggle schedule.`)} {t`Failed to toggle schedule.`}
<ErrorDetail error={error} /> <ErrorDetail error={error} />
</AlertModal> </AlertModal>
)} )}
@@ -78,4 +76,4 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
); );
} }
export default withI18n()(ScheduleToggle); export default ScheduleToggle;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { withI18n } from '@lingui/react';
import { Switch, Route, useRouteMatch } from 'react-router-dom'; import { Switch, Route, useRouteMatch } from 'react-router-dom';
import Schedule from './Schedule'; import Schedule from './Schedule';
import ScheduleAdd from './ScheduleAdd'; import ScheduleAdd from './ScheduleAdd';
@@ -60,4 +60,4 @@ function Schedules({
} }
export { Schedules as _Schedules }; export { Schedules as _Schedules };
export default withI18n()(Schedules); export default Schedules;

View File

@@ -2,7 +2,7 @@ import 'styled-components/macro';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { useField } from 'formik'; import { useField } from 'formik';
import { withI18n } from '@lingui/react';
import { t, Trans, Plural } from '@lingui/macro'; import { t, Trans, Plural } from '@lingui/macro';
import { RRule } from 'rrule'; import { RRule } from 'rrule';
import { import {
@@ -41,24 +41,24 @@ const Checkbox = styled(_Checkbox)`
} }
`; `;
export function requiredPositiveInteger(i18n) { export function requiredPositiveInteger() {
return value => { return value => {
if (typeof value === 'number') { if (typeof value === 'number') {
if (!Number.isInteger(value)) { if (!Number.isInteger(value)) {
return i18n._(t`This field must be an integer`); return t`This field must be an integer`;
} }
if (value < 1) { if (value < 1) {
return i18n._(t`This field must be greater than 0`); return t`This field must be greater than 0`;
} }
} }
if (!value) { if (!value) {
return i18n._(t`Select a value for this field`); return t`Select a value for this field`;
} }
return undefined; return undefined;
}; };
} }
const FrequencyDetailSubform = ({ i18n }) => { const FrequencyDetailSubform = () => {
const [runOnDayMonth] = useField({ const [runOnDayMonth] = useField({
name: 'runOnDayMonth', name: 'runOnDayMonth',
}); });
@@ -79,92 +79,92 @@ const FrequencyDetailSubform = ({ i18n }) => {
}); });
const [daysOfWeek, daysOfWeekMeta, daysOfWeekHelpers] = useField({ const [daysOfWeek, daysOfWeekMeta, daysOfWeekHelpers] = useField({
name: 'daysOfWeek', name: 'daysOfWeek',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
const [end, endMeta] = useField({ const [end, endMeta] = useField({
name: 'end', name: 'end',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
const [interval, intervalMeta] = useField({ const [interval, intervalMeta] = useField({
name: 'interval', name: 'interval',
validate: requiredPositiveInteger(i18n), validate: requiredPositiveInteger(),
}); });
const [runOn, runOnMeta] = useField({ const [runOn, runOnMeta] = useField({
name: 'runOn', name: 'runOn',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
const [endDateTime, endDateTimeMeta] = useField({ const [endDateTime, endDateTimeMeta] = useField({
name: 'endDateTime', name: 'endDateTime',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
const [frequency] = useField({ const [frequency] = useField({
name: 'frequency', name: 'frequency',
}); });
useField({ useField({
name: 'occurrences', name: 'occurrences',
validate: requiredPositiveInteger(i18n), validate: requiredPositiveInteger(),
}); });
const monthOptions = [ const monthOptions = [
{ {
key: 'january', key: 'january',
value: 1, value: 1,
label: i18n._(t`January`), label: t`January`,
}, },
{ {
key: 'february', key: 'february',
value: 2, value: 2,
label: i18n._(t`February`), label: t`February`,
}, },
{ {
key: 'march', key: 'march',
value: 3, value: 3,
label: i18n._(t`March`), label: t`March`,
}, },
{ {
key: 'april', key: 'april',
value: 4, value: 4,
label: i18n._(t`April`), label: t`April`,
}, },
{ {
key: 'may', key: 'may',
value: 5, value: 5,
label: i18n._(t`May`), label: t`May`,
}, },
{ {
key: 'june', key: 'june',
value: 6, value: 6,
label: i18n._(t`June`), label: t`June`,
}, },
{ {
key: 'july', key: 'july',
value: 7, value: 7,
label: i18n._(t`July`), label: t`July`,
}, },
{ {
key: 'august', key: 'august',
value: 8, value: 8,
label: i18n._(t`August`), label: t`August`,
}, },
{ {
key: 'september', key: 'september',
value: 9, value: 9,
label: i18n._(t`September`), label: t`September`,
}, },
{ {
key: 'october', key: 'october',
value: 10, value: 10,
label: i18n._(t`October`), label: t`October`,
}, },
{ {
key: 'november', key: 'november',
value: 11, value: 11,
label: i18n._(t`November`), label: t`November`,
}, },
{ {
key: 'december', key: 'december',
value: 12, value: 12,
label: i18n._(t`December`), label: t`December`,
}, },
]; ];
@@ -197,7 +197,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
case 'year': case 'year':
return <Plural value={intervalValue} one="year" other="years" />; return <Plural value={intervalValue} one="year" other="years" />;
default: default:
throw new Error(i18n._(t`Frequency did not match an expected value`)); throw new Error(t`Frequency did not match an expected value`);
} }
}; };
@@ -212,7 +212,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
validated={ validated={
!intervalMeta.touched || !intervalMeta.error ? 'default' : 'error' !intervalMeta.touched || !intervalMeta.error ? 'default' : 'error'
} }
label={i18n._(t`Run every`)} label={t`Run every`}
> >
<div css="display: flex"> <div css="display: flex">
<TextInput <TextInput
@@ -240,76 +240,76 @@ const FrequencyDetailSubform = ({ i18n }) => {
? 'default' ? 'default'
: 'error' : 'error'
} }
label={i18n._(t`On days`)} label={t`On days`}
> >
<div css="display: flex"> <div css="display: flex">
<Checkbox <Checkbox
label={i18n._(t`Sun`)} label={t`Sun`}
isChecked={daysOfWeek.value.includes(RRule.SU)} isChecked={daysOfWeek.value.includes(RRule.SU)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.SU, checked); updateDaysOfWeek(RRule.SU, checked);
}} }}
aria-label={i18n._(t`Sunday`)} aria-label={t`Sunday`}
id="schedule-days-of-week-sun" id="schedule-days-of-week-sun"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Mon`)} label={t`Mon`}
isChecked={daysOfWeek.value.includes(RRule.MO)} isChecked={daysOfWeek.value.includes(RRule.MO)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.MO, checked); updateDaysOfWeek(RRule.MO, checked);
}} }}
aria-label={i18n._(t`Monday`)} aria-label={t`Monday`}
id="schedule-days-of-week-mon" id="schedule-days-of-week-mon"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Tue`)} label={t`Tue`}
isChecked={daysOfWeek.value.includes(RRule.TU)} isChecked={daysOfWeek.value.includes(RRule.TU)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.TU, checked); updateDaysOfWeek(RRule.TU, checked);
}} }}
aria-label={i18n._(t`Tuesday`)} aria-label={t`Tuesday`}
id="schedule-days-of-week-tue" id="schedule-days-of-week-tue"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Wed`)} label={t`Wed`}
isChecked={daysOfWeek.value.includes(RRule.WE)} isChecked={daysOfWeek.value.includes(RRule.WE)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.WE, checked); updateDaysOfWeek(RRule.WE, checked);
}} }}
aria-label={i18n._(t`Wednesday`)} aria-label={t`Wednesday`}
id="schedule-days-of-week-wed" id="schedule-days-of-week-wed"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Thu`)} label={t`Thu`}
isChecked={daysOfWeek.value.includes(RRule.TH)} isChecked={daysOfWeek.value.includes(RRule.TH)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.TH, checked); updateDaysOfWeek(RRule.TH, checked);
}} }}
aria-label={i18n._(t`Thursday`)} aria-label={t`Thursday`}
id="schedule-days-of-week-thu" id="schedule-days-of-week-thu"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Fri`)} label={t`Fri`}
isChecked={daysOfWeek.value.includes(RRule.FR)} isChecked={daysOfWeek.value.includes(RRule.FR)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.FR, checked); updateDaysOfWeek(RRule.FR, checked);
}} }}
aria-label={i18n._(t`Friday`)} aria-label={t`Friday`}
id="schedule-days-of-week-fri" id="schedule-days-of-week-fri"
name="daysOfWeek" name="daysOfWeek"
/> />
<Checkbox <Checkbox
label={i18n._(t`Sat`)} label={t`Sat`}
isChecked={daysOfWeek.value.includes(RRule.SA)} isChecked={daysOfWeek.value.includes(RRule.SA)}
onChange={checked => { onChange={checked => {
updateDaysOfWeek(RRule.SA, checked); updateDaysOfWeek(RRule.SA, checked);
}} }}
aria-label={i18n._(t`Saturday`)} aria-label={t`Saturday`}
id="schedule-days-of-week-sat" id="schedule-days-of-week-sat"
name="daysOfWeek" name="daysOfWeek"
/> />
@@ -326,7 +326,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
validated={ validated={
!runOnMeta.touched || !runOnMeta.error ? 'default' : 'error' !runOnMeta.touched || !runOnMeta.error ? 'default' : 'error'
} }
label={i18n._(t`Run on`)} label={t`Run on`}
> >
<RunOnRadio <RunOnRadio
id="schedule-run-on-day" id="schedule-run-on-day"
@@ -386,20 +386,20 @@ const FrequencyDetailSubform = ({ i18n }) => {
id="schedule-run-on-the-occurrence" id="schedule-run-on-the-occurrence"
isDisabled={runOn.value !== 'the'} isDisabled={runOn.value !== 'the'}
data={[ data={[
{ value: 1, key: 'first', label: i18n._(t`First`) }, { value: 1, key: 'first', label: t`First` },
{ {
value: 2, value: 2,
key: 'second', key: 'second',
label: i18n._(t`Second`), label: t`Second`,
}, },
{ value: 3, key: 'third', label: i18n._(t`Third`) }, { value: 3, key: 'third', label: t`Third` },
{ {
value: 4, value: 4,
key: 'fourth', key: 'fourth',
label: i18n._(t`Fourth`), label: t`Fourth`,
}, },
{ value: 5, key: 'fifth', label: i18n._(t`Fifth`) }, { value: 5, key: 'fifth', label: t`Fifth` },
{ value: -1, key: 'last', label: i18n._(t`Last`) }, { value: -1, key: 'last', label: t`Last` },
]} ]}
{...runOnTheOccurrence} {...runOnTheOccurrence}
/> />
@@ -410,48 +410,48 @@ const FrequencyDetailSubform = ({ i18n }) => {
{ {
value: 'sunday', value: 'sunday',
key: 'sunday', key: 'sunday',
label: i18n._(t`Sunday`), label: t`Sunday`,
}, },
{ {
value: 'monday', value: 'monday',
key: 'monday', key: 'monday',
label: i18n._(t`Monday`), label: t`Monday`,
}, },
{ {
value: 'tuesday', value: 'tuesday',
key: 'tuesday', key: 'tuesday',
label: i18n._(t`Tuesday`), label: t`Tuesday`,
}, },
{ {
value: 'wednesday', value: 'wednesday',
key: 'wednesday', key: 'wednesday',
label: i18n._(t`Wednesday`), label: t`Wednesday`,
}, },
{ {
value: 'thursday', value: 'thursday',
key: 'thursday', key: 'thursday',
label: i18n._(t`Thursday`), label: t`Thursday`,
}, },
{ {
value: 'friday', value: 'friday',
key: 'friday', key: 'friday',
label: i18n._(t`Friday`), label: t`Friday`,
}, },
{ {
value: 'saturday', value: 'saturday',
key: 'saturday', key: 'saturday',
label: i18n._(t`Saturday`), label: t`Saturday`,
}, },
{ value: 'day', key: 'day', label: i18n._(t`Day`) }, { value: 'day', key: 'day', label: t`Day` },
{ {
value: 'weekday', value: 'weekday',
key: 'weekday', key: 'weekday',
label: i18n._(t`Weekday`), label: t`Weekday`,
}, },
{ {
value: 'weekendDay', value: 'weekendDay',
key: 'weekendDay', key: 'weekendDay',
label: i18n._(t`Weekend day`), label: t`Weekend day`,
}, },
]} ]}
{...runOnTheDay} {...runOnTheDay}
@@ -489,12 +489,12 @@ const FrequencyDetailSubform = ({ i18n }) => {
helperTextInvalid={endMeta.error} helperTextInvalid={endMeta.error}
isRequired isRequired
validated={!endMeta.touched || !endMeta.error ? 'default' : 'error'} validated={!endMeta.touched || !endMeta.error ? 'default' : 'error'}
label={i18n._(t`End`)} label={t`End`}
> >
<Radio <Radio
id="end-never" id="end-never"
name="end" name="end"
label={i18n._(t`Never`)} label={t`Never`}
value="never" value="never"
isChecked={end.value === 'never'} isChecked={end.value === 'never'}
onChange={(value, event) => { onChange={(value, event) => {
@@ -505,7 +505,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
<Radio <Radio
id="end-after" id="end-after"
name="end" name="end"
label={i18n._(t`After number of occurrences`)} label={t`After number of occurrences`}
value="after" value="after"
isChecked={end.value === 'after'} isChecked={end.value === 'after'}
onChange={(value, event) => { onChange={(value, event) => {
@@ -516,7 +516,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
<Radio <Radio
id="end-on-date" id="end-on-date"
name="end" name="end"
label={i18n._(t`On date`)} label={t`On date`}
value="onDate" value="onDate"
isChecked={end.value === 'onDate'} isChecked={end.value === 'onDate'}
onChange={(value, event) => { onChange={(value, event) => {
@@ -528,12 +528,12 @@ const FrequencyDetailSubform = ({ i18n }) => {
{end?.value === 'after' && ( {end?.value === 'after' && (
<FormField <FormField
id="schedule-occurrences" id="schedule-occurrences"
label={i18n._(t`Occurrences`)} label={t`Occurrences`}
name="occurrences" name="occurrences"
type="number" type="number"
min="1" min="1"
step="1" step="1"
validate={required(null, i18n)} validate={required(null)}
isRequired isRequired
/> />
)} )}
@@ -547,7 +547,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
? 'default' ? 'default'
: 'error' : 'error'
} }
label={i18n._(t`End date/time`)} label={t`End date/time`}
> >
<input <input
className="pf-c-form-control" className="pf-c-form-control"
@@ -563,4 +563,4 @@ const FrequencyDetailSubform = ({ i18n }) => {
/* eslint-enable no-restricted-globals */ /* eslint-enable no-restricted-globals */
}; };
export default withI18n()(FrequencyDetailSubform); export default FrequencyDetailSubform;

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useCallback, useState } from 'react'; import React, { useEffect, useCallback, useState } from 'react';
import { shape, func } from 'prop-types'; import { shape, func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Formik, useField } from 'formik'; import { Formik, useField } from 'formik';
import { RRule } from 'rrule'; import { RRule } from 'rrule';
@@ -78,36 +78,33 @@ const generateRunOnTheDay = (days = []) => {
return null; return null;
}; };
function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) { function ScheduleFormFields({ hasDaysToKeepField, zoneOptions }) {
const [startDateTime, startDateTimeMeta] = useField({ const [startDateTime, startDateTimeMeta] = useField({
name: 'startDateTime', name: 'startDateTime',
validate: required( validate: required(t`Select a valid date and time for this field`),
i18n._(t`Select a valid date and time for this field`),
i18n
),
}); });
const [timezone, timezoneMeta] = useField({ const [timezone, timezoneMeta] = useField({
name: 'timezone', name: 'timezone',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
const [frequency, frequencyMeta] = useField({ const [frequency, frequencyMeta] = useField({
name: 'frequency', name: 'frequency',
validate: required(i18n._(t`Select a value for this field`), i18n), validate: required(t`Select a value for this field`),
}); });
return ( return (
<> <>
<FormField <FormField
id="schedule-name" id="schedule-name"
label={i18n._(t`Name`)} label={t`Name`}
name="name" name="name"
type="text" type="text"
validate={required(null, i18n)} validate={required(null)}
isRequired isRequired
/> />
<FormField <FormField
id="schedule-description" id="schedule-description"
label={i18n._(t`Description`)} label={t`Description`}
name="description" name="description"
type="text" type="text"
/> />
@@ -120,7 +117,7 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
? 'default' ? 'default'
: 'error' : 'error'
} }
label={i18n._(t`Start date/time`)} label={t`Start date/time`}
> >
<input <input
className="pf-c-form-control" className="pf-c-form-control"
@@ -138,7 +135,7 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
validated={ validated={
!timezoneMeta.touched || !timezoneMeta.error ? 'default' : 'error' !timezoneMeta.touched || !timezoneMeta.error ? 'default' : 'error'
} }
label={i18n._(t`Local time zone`)} label={t`Local time zone`}
> >
<AnsibleSelect <AnsibleSelect
id="schedule-timezone" id="schedule-timezone"
@@ -154,18 +151,18 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
validated={ validated={
!frequencyMeta.touched || !frequencyMeta.error ? 'default' : 'error' !frequencyMeta.touched || !frequencyMeta.error ? 'default' : 'error'
} }
label={i18n._(t`Run frequency`)} label={t`Run frequency`}
> >
<AnsibleSelect <AnsibleSelect
id="schedule-frequency" id="schedule-frequency"
data={[ data={[
{ value: 'none', key: 'none', label: i18n._(t`None (run once)`) }, { value: 'none', key: 'none', label: t`None (run once)` },
{ value: 'minute', key: 'minute', label: i18n._(t`Minute`) }, { value: 'minute', key: 'minute', label: t`Minute` },
{ value: 'hour', key: 'hour', label: i18n._(t`Hour`) }, { value: 'hour', key: 'hour', label: t`Hour` },
{ value: 'day', key: 'day', label: i18n._(t`Day`) }, { value: 'day', key: 'day', label: t`Day` },
{ value: 'week', key: 'week', label: i18n._(t`Week`) }, { value: 'week', key: 'week', label: t`Week` },
{ value: 'month', key: 'month', label: i18n._(t`Month`) }, { value: 'month', key: 'month', label: t`Month` },
{ value: 'year', key: 'year', label: i18n._(t`Year`) }, { value: 'year', key: 'year', label: t`Year` },
]} ]}
{...frequency} {...frequency}
/> />
@@ -173,17 +170,17 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
{hasDaysToKeepField ? ( {hasDaysToKeepField ? (
<FormField <FormField
id="schedule-days-to-keep" id="schedule-days-to-keep"
label={i18n._(t`Days of Data to Keep`)} label={t`Days of Data to Keep`}
name="daysToKeep" name="daysToKeep"
type="number" type="number"
validate={required(null, i18n)} validate={required(null)}
isRequired isRequired
/> />
) : null} ) : null}
{frequency.value !== 'none' && ( {frequency.value !== 'none' && (
<SubFormLayout> <SubFormLayout>
<Title size="md" headingLevel="h4"> <Title size="md" headingLevel="h4">
{i18n._(t`Frequency Details`)} {t`Frequency Details`}
</Title> </Title>
<FormColumnLayout> <FormColumnLayout>
<FrequencyDetailSubform /> <FrequencyDetailSubform />
@@ -198,7 +195,7 @@ function ScheduleForm({
hasDaysToKeepField, hasDaysToKeepField,
handleCancel, handleCancel,
handleSubmit, handleSubmit,
i18n,
schedule, schedule,
submitError, submitError,
resource, resource,
@@ -531,7 +528,7 @@ function ScheduleForm({
rruleError = error; rruleError = error;
} }
} else { } else {
rruleError = new Error(i18n._(t`Schedule is missing rrule`)); rruleError = new Error(t`Schedule is missing rrule`);
} }
} }
@@ -567,9 +564,7 @@ function ScheduleForm({
end === 'onDate' && end === 'onDate' &&
new Date(startDateTime) > new Date(endDateTime) new Date(startDateTime) > new Date(endDateTime)
) { ) {
errors.endDateTime = i18n._( errors.endDateTime = t`Please select an end date/time that comes after the start date/time.`;
t`Please select an end date/time that comes after the start date/time.`
);
} }
if ( if (
@@ -577,9 +572,7 @@ function ScheduleForm({
runOn === 'day' && runOn === 'day' &&
(runOnDayNumber < 1 || runOnDayNumber > 31) (runOnDayNumber < 1 || runOnDayNumber > 31)
) { ) {
errors.runOn = i18n._( errors.runOn = t`Please select a day number between 1 and 31.`;
t`Please select a day number between 1 and 31.`
);
} }
return errors; return errors;
@@ -590,7 +583,6 @@ function ScheduleForm({
<FormColumnLayout> <FormColumnLayout>
<ScheduleFormFields <ScheduleFormFields
hasDaysToKeepField={hasDaysToKeepField} hasDaysToKeepField={hasDaysToKeepField}
i18n={i18n}
zoneOptions={zoneOptions} zoneOptions={zoneOptions}
{...rest} {...rest}
/> />
@@ -616,13 +608,13 @@ function ScheduleForm({
<ActionGroup> <ActionGroup>
<Button <Button
ouiaId="schedule-form-save-button" ouiaId="schedule-form-save-button"
aria-label={i18n._(t`Save`)} aria-label={t`Save`}
variant="primary" variant="primary"
type="button" type="button"
onClick={formik.handleSubmit} onClick={formik.handleSubmit}
isDisabled={isSaveDisabled} isDisabled={isSaveDisabled}
> >
{i18n._(t`Save`)} {t`Save`}
</Button> </Button>
{isTemplate && showPromptButton && ( {isTemplate && showPromptButton && (
@@ -630,20 +622,20 @@ function ScheduleForm({
ouiaId="schedule-form-prompt-button" ouiaId="schedule-form-prompt-button"
variant="secondary" variant="secondary"
type="button" type="button"
aria-label={i18n._(t`Prompt`)} aria-label={t`Prompt`}
onClick={() => setIsWizardOpen(true)} onClick={() => setIsWizardOpen(true)}
> >
{i18n._(t`Prompt`)} {t`Prompt`}
</Button> </Button>
)} )}
<Button <Button
ouiaId="schedule-form-cancel-button" ouiaId="schedule-form-cancel-button"
aria-label={i18n._(t`Cancel`)} aria-label={t`Cancel`}
variant="secondary" variant="secondary"
type="button" type="button"
onClick={handleCancel} onClick={handleCancel}
> >
{i18n._(t`Cancel`)} {t`Cancel`}
</Button> </Button>
</ActionGroup> </ActionGroup>
</FormFullWidthLayout> </FormFullWidthLayout>
@@ -669,4 +661,4 @@ ScheduleForm.defaultProps = {
submitError: null, submitError: null,
}; };
export default withI18n()(ScheduleForm); export default ScheduleForm;

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Wizard } from '@patternfly/react-core'; import { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import AlertModal from '../../AlertModal'; import AlertModal from '../../AlertModal';
@@ -18,7 +18,6 @@ function SchedulePromptableFields({
credentials, credentials,
resource, resource,
resourceDefaultCredentials, resourceDefaultCredentials,
i18n,
}) { }) {
const { const {
setFieldTouched, setFieldTouched,
@@ -38,7 +37,7 @@ function SchedulePromptableFields({
launchConfig, launchConfig,
schedule, schedule,
resource, resource,
i18n,
credentials, credentials,
resourceDefaultCredentials resourceDefaultCredentials
); );
@@ -74,7 +73,7 @@ function SchedulePromptableFields({
<AlertModal <AlertModal
isOpen={error} isOpen={error}
variant="error" variant="error"
title={i18n._(t`Error!`)} title={t`Error!`}
onClose={() => { onClose={() => {
dismissError(); dismissError();
onCloseWizard(); onCloseWizard();
@@ -108,22 +107,22 @@ function SchedulePromptableFields({
validateStep(nextStep.id); validateStep(nextStep.id);
} }
}} }}
title={i18n._(t`Prompts`)} title={t`Prompts`}
steps={ steps={
isReady isReady
? steps ? steps
: [ : [
{ {
name: i18n._(t`Content Loading`), name: t`Content Loading`,
component: <ContentLoading />, component: <ContentLoading />,
}, },
] ]
} }
backButtonText={i18n._(t`Back`)} backButtonText={t`Back`}
cancelButtonText={i18n._(t`Cancel`)} cancelButtonText={t`Cancel`}
nextButtonText={i18n._(t`Next`)} nextButtonText={t`Next`}
/> />
); );
} }
export default withI18n()(SchedulePromptableFields); export default SchedulePromptableFields;

View File

@@ -2,7 +2,7 @@ import { t } from '@lingui/macro';
import { RRule } from 'rrule'; import { RRule } from 'rrule';
import { getRRuleDayConstants } from '../../../util/dates'; import { getRRuleDayConstants } from '../../../util/dates';
export default function buildRuleObj(values, i18n) { export default function buildRuleObj(values) {
const [startDate, startTime] = values.startDateTime.split('T'); const [startDate, startTime] = values.startDateTime.split('T');
// Dates are formatted like "YYYY-MM-DD" // Dates are formatted like "YYYY-MM-DD"
const [startYear, startMonth, startDay] = startDate.split('-'); const [startYear, startMonth, startDay] = startDate.split('-');
@@ -51,7 +51,7 @@ export default function buildRuleObj(values, i18n) {
ruleObj.bymonthday = values.runOnDayNumber; ruleObj.bymonthday = values.runOnDayNumber;
} else if (values.runOn === 'the') { } else if (values.runOn === 'the') {
ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10); ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay, i18n); ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay);
} }
break; break;
case 'year': case 'year':
@@ -61,12 +61,12 @@ export default function buildRuleObj(values, i18n) {
ruleObj.bymonthday = values.runOnDayNumber; ruleObj.bymonthday = values.runOnDayNumber;
} else if (values.runOn === 'the') { } else if (values.runOn === 'the') {
ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10); ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay, i18n); ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay);
ruleObj.bymonth = parseInt(values.runOnTheMonth, 10); ruleObj.bymonth = parseInt(values.runOnTheMonth, 10);
} }
break; break;
default: default:
throw new Error(i18n._(t`Frequency did not match an expected value`)); throw new Error(t`Frequency did not match an expected value`);
} }
if (values.frequency !== 'none') { if (values.frequency !== 'none') {
@@ -93,7 +93,7 @@ export default function buildRuleObj(values, i18n) {
break; break;
} }
default: default:
throw new Error(i18n._(t`End did not match an expected value`)); throw new Error(t`End did not match an expected value`);
} }
} }

View File

@@ -12,7 +12,7 @@ export default function useSchedulePromptSteps(
launchConfig, launchConfig,
schedule, schedule,
resource, resource,
i18n,
scheduleCredentials, scheduleCredentials,
resourceDefaultCredentials resourceDefaultCredentials
) { ) {
@@ -22,15 +22,14 @@ export default function useSchedulePromptSteps(
const [visited, setVisited] = useState({}); const [visited, setVisited] = useState({});
const steps = [ const steps = [
useInventoryStep(launchConfig, sourceOfValues, i18n, visited), useInventoryStep(launchConfig, sourceOfValues, visited),
useCredentialsStep( useCredentialsStep(
launchConfig, launchConfig,
sourceOfValues, sourceOfValues,
resourceDefaultCredentials, resourceDefaultCredentials
i18n
), ),
useOtherPromptsStep(launchConfig, sourceOfValues, i18n), useOtherPromptsStep(launchConfig, sourceOfValues),
useSurveyStep(launchConfig, surveyConfig, sourceOfValues, i18n, visited), useSurveyStep(launchConfig, surveyConfig, sourceOfValues, visited),
]; ];
const hasErrors = steps.some(step => step.hasError); const hasErrors = steps.some(step => step.hasError);
@@ -38,12 +37,12 @@ export default function useSchedulePromptSteps(
steps.push( steps.push(
usePreviewStep( usePreviewStep(
launchConfig, launchConfig,
i18n,
resource, resource,
surveyConfig, surveyConfig,
hasErrors, hasErrors,
true, true,
i18n._(t`Save`) t`Save`
) )
); );

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import {
Button, Button,
@@ -14,7 +14,7 @@ import {
import { HistoryIcon } from '@patternfly/react-icons'; import { HistoryIcon } from '@patternfly/react-icons';
import { Link, Route, useRouteMatch } from 'react-router-dom'; import { Link, Route, useRouteMatch } from 'react-router-dom';
const ScreenHeader = ({ breadcrumbConfig, i18n, streamType }) => { const ScreenHeader = ({ breadcrumbConfig, streamType }) => {
const { light } = PageSectionVariants; const { light } = PageSectionVariants;
const oneCrumbMatch = useRouteMatch({ const oneCrumbMatch = useRouteMatch({
path: Object.keys(breadcrumbConfig)[0], path: Object.keys(breadcrumbConfig)[0],
@@ -51,10 +51,10 @@ const ScreenHeader = ({ breadcrumbConfig, i18n, streamType }) => {
</div> </div>
{streamType !== 'none' && ( {streamType !== 'none' && (
<div> <div>
<Tooltip content={i18n._(t`View activity stream`)} position="top"> <Tooltip content={t`View activity stream`} position="top">
<Button <Button
ouiaId="activity-stream-button" ouiaId="activity-stream-button"
aria-label={i18n._(t`View activity stream`)} aria-label={t`View activity stream`}
variant="plain" variant="plain"
component={Link} component={Link}
to={`/activity_stream${ to={`/activity_stream${
@@ -133,4 +133,4 @@ Crumb.propTypes = {
breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired, breadcrumbConfig: PropTypes.objectOf(PropTypes.string).isRequired,
}; };
export default withI18n()(ScreenHeader); export default ScreenHeader;

Some files were not shown because too many files have changed in this diff Show More