Removes remaining I18n props, HOCs and mics objects

This commit is contained in:
Alex Corey 2021-04-30 08:48:11 -04:00
parent 72a940bef1
commit 7a9bcc1e1e
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:
- 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.
- 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).

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/* eslint-disable react/no-unescaped-entities */
import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import PropTypes from 'prop-types';
import { useField } from 'formik';
@ -28,10 +28,10 @@ const TooltipWrapper = styled.div`
// in failing tests.
const brandName = BrandName;
function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
const [moduleNameField, moduleNameMeta, moduleNameHelpers] = useField({
name: 'module_name',
validate: required(null, i18n),
validate: required(null),
});
const [variablesField] = useField('extra_vars');
@ -41,14 +41,14 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
);
const [verbosityField, verbosityMeta, verbosityHelpers] = useField({
name: 'verbosity',
validate: required(null, i18n),
validate: required(null),
});
const argumentsRequired =
moduleNameField.value === 'command' || moduleNameField.value === 'shell';
const [, argumentsMeta, argumentsHelpers] = useField({
name: 'module_args',
validate: argumentsRequired && required(null, i18n),
validate: argumentsRequired && required(null),
});
const isValid = !argumentsMeta.error || !argumentsMeta.touched;
@ -59,8 +59,8 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
<FormFullWidthLayout>
<FormGroup
fieldId="module_name"
aria-label={i18n._(t`select module`)}
label={i18n._(t`Module`)}
aria-label={t`select module`}
label={t`Module`}
isRequired
helperTextInvalid={moduleNameMeta.error}
validated={
@ -70,22 +70,20 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
}
labelIcon={
<Popover
content={i18n._(
t`These are the modules that ${brandName} supports running commands against.`
)}
content={t`These are the modules that ${brandName} supports running commands against.`}
/>
}
>
<AnsibleSelect
{...moduleNameField}
placeHolder={i18n._(t`Select a module`)}
placeHolder={t`Select a module`}
isValid={!moduleNameMeta.touched || !moduleNameMeta.error}
id="module_name"
data={[
{
value: '',
key: '',
label: i18n._(t`Choose a module`),
label: t`Choose a module`,
isDisabled: true,
},
...moduleOptions.map(value => ({
@ -105,9 +103,9 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
<FormField
id="module_args"
name="module_args"
aria-label={i18n._(t`Arguments`)}
aria-label={t`Arguments`}
type="text"
label={i18n._(t`Arguments`)}
label={t`Arguments`}
validated={isValid ? 'default' : 'error'}
onBlur={() => argumentsHelpers.setTouched(true)}
isRequired={
@ -117,27 +115,25 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
tooltip={
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
href={`https://docs.ansible.com/ansible/latest/modules/${moduleNameField.value}_module.html`}
target="_blank"
rel="noopener noreferrer"
>
{' '}
{i18n._(t`here.`)}
{t`here.`}
</a>
</>
) : (
i18n._(t`These arguments are used with the specified module.`)
t`These arguments are used with the specified module.`
)
}
/>
<FormGroup
fieldId="verbosity"
aria-label={i18n._(t`select verbosity`)}
label={i18n._(t`Verbosity`)}
aria-label={t`select verbosity`}
label={t`Verbosity`}
isRequired
validated={
!verbosityMeta.touched || !verbosityMeta.error
@ -147,9 +143,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
helperTextInvalid={verbosityMeta.error}
labelIcon={
<Popover
content={i18n._(
t`These are the verbosity levels for standard out of the command run that are supported.`
)}
content={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"
name="limit"
type="text"
label={i18n._(t`Limit`)}
aria-label={i18n._(t`Limit`)}
label={t`Limit`}
aria-label={t`Limit`}
tooltip={
<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
href="https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html"
target="_blank"
rel="noopener noreferrer"
>
{i18n._(t`here`)}
{t`here`}
</a>
</span>
}
@ -189,67 +181,63 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
name="forks"
type="number"
min="0"
label={i18n._(t`Forks`)}
aria-label={i18n._(t`Forks`)}
label={t`Forks`}
aria-label={t`Forks`}
tooltip={
<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
href="https://docs.ansible.com/ansible/latest/installation_guide/intro_configuration.html#the-ansible-configuration-file"
target="_blank"
rel="noopener noreferrer"
>
{i18n._(t`here.`)}
{t`here.`}
</a>
</span>
}
/>
<FormColumnLayout>
<FormGroup
label={i18n._(t`Show changes`)}
aria-label={i18n._(t`Show changes`)}
label={t`Show changes`}
aria-label={t`Show changes`}
labelIcon={
<Popover
content={i18n._(
t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansibles --diff mode.`
)}
content={t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansibles --diff mode.`}
/>
}
>
<Switch
css="display: inline-flex;"
id="diff_mode"
label={i18n._(t`On`)}
labelOff={i18n._(t`Off`)}
label={t`On`}
labelOff={t`Off`}
isChecked={diffModeField.value}
onChange={() => {
diffModeHelpers.setValue(!diffModeField.value);
}}
aria-label={i18n._(t`toggle changes`)}
aria-label={t`toggle changes`}
/>
</FormGroup>
<FormGroup name="become_enabled" fieldId="become_enabled">
<FormCheckboxLayout>
<Checkbox
aria-label={i18n._(t`Enable privilege escalation`)}
aria-label={t`Enable privilege escalation`}
label={
<span>
{i18n._(t`Enable privilege escalation`)}
{t`Enable privilege escalation`}
&nbsp;
<Popover
content={
<p>
{i18n._(t`Enables creation of a provisioning
{t`Enables creation of a provisioning
callback URL. Using the URL a host can contact ${brandName}
and request a configuration update using this job
template`)}
template`}
&nbsp;
<code>--become </code>
{i18n._(t`option to the`)} &nbsp;
{t`option to the`} &nbsp;
<code>ansible </code>
{i18n._(t`command`)}
{t`command`}
</p>
}
/>
@ -275,14 +263,12 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
tooltip={
<TooltipWrapper>
<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 />
<code>-e</code>, <code>--extra-vars </code>
<br />
{i18n._(t`Provide key/value pairs using either
YAML or JSON.`)}
{t`Provide key/value pairs using either
YAML or JSON.`}
</p>
JSON:
<br />
@ -306,8 +292,8 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
</code>
</TooltipWrapper>
}
label={i18n._(t`Extra variables`)}
aria-label={i18n._(t`Extra variables`)}
label={t`Extra variables`}
aria-label={t`Extra variables`}
/>
</FormFullWidthLayout>
</FormColumnLayout>
@ -320,4 +306,4 @@ AdHocDetailsStep.propTypes = {
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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import PropTypes from 'prop-types';
import { Dropdown, DropdownPosition } from '@patternfly/react-core';
import { ToolbarAddButton } from '../PaginatedDataList';
import { useKebabifiedMenu } from '../../contexts/Kebabified';
function AddDropDownButton({ dropdownItems, i18n }) {
function AddDropDownButton({ dropdownItems }) {
const { isKebabified } = useKebabifiedMenu();
const [isOpen, setIsOpen] = useState(false);
const element = useRef(null);
@ -36,7 +35,7 @@ function AddDropDownButton({ dropdownItems, i18n }) {
position={DropdownPosition.right}
toggle={
<ToolbarAddButton
aria-label={i18n._(t`Add`)}
aria-label={t`Add`}
showToggleIndicator
onClick={() => setIsOpen(!isOpen)}
/>
@ -52,4 +51,4 @@ AddDropDownButton.propTypes = {
};
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 PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import SelectableCard from '../SelectableCard';
import Wizard from '../Wizard';
@ -18,7 +17,7 @@ const readTeams = async queryParams => TeamsAPI.read(queryParams);
const readTeamsOptions = async () => TeamsAPI.readOptions();
function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
function AddResourceRole({ onSave, onClose, roles, resource, onError }) {
const history = useHistory();
const [selectedResource, setSelectedResource] = useState(null);
@ -122,52 +121,52 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
const userSearchColumns = [
{
name: i18n._(t`Username`),
name: t`Username`,
key: 'username__icontains',
isDefault: true,
},
{
name: i18n._(t`First Name`),
name: t`First Name`,
key: 'first_name__icontains',
},
{
name: i18n._(t`Last Name`),
name: t`Last Name`,
key: 'last_name__icontains',
},
];
const userSortColumns = [
{
name: i18n._(t`Username`),
name: t`Username`,
key: 'username',
},
{
name: i18n._(t`First Name`),
name: t`First Name`,
key: 'first_name',
},
{
name: i18n._(t`Last Name`),
name: t`Last Name`,
key: 'last_name',
},
];
const teamSearchColumns = [
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username',
},
];
const teamSortColumns = [
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
];
@ -176,30 +175,28 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
switch (selectedResource) {
case 'users':
wizardTitle = i18n._(t`Add User Roles`);
wizardTitle = t`Add User Roles`;
break;
case 'teams':
wizardTitle = i18n._(t`Add Team Roles`);
wizardTitle = t`Add Team Roles`;
break;
default:
wizardTitle = i18n._(t`Add Roles`);
wizardTitle = t`Add Roles`;
}
const steps = [
{
id: 1,
name: i18n._(t`Select a Resource Type`),
name: t`Select a Resource Type`,
component: (
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<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>
<SelectableCard
isSelected={selectedResource === 'users'}
label={i18n._(t`Users`)}
ariaLabel={i18n._(t`Users`)}
label={t`Users`}
ariaLabel={t`Users`}
dataCy="add-role-users"
onClick={() => handleResourceSelect('users')}
/>
@ -208,8 +205,8 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
!resource?.organization) ? null : (
<SelectableCard
isSelected={selectedResource === 'teams'}
label={i18n._(t`Teams`)}
ariaLabel={i18n._(t`Teams`)}
label={t`Teams`}
ariaLabel={t`Teams`}
dataCy="add-role-teams"
onClick={() => handleResourceSelect('teams')}
/>
@ -220,7 +217,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
},
{
id: 2,
name: i18n._(t`Select Items from List`),
name: t`Select Items from List`,
component: (
<Fragment>
{selectedResource === 'users' && (
@ -231,7 +228,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
onRowClick={handleResourceCheckboxClick}
fetchItems={readUsers}
fetchOptions={readUsersOptions}
selectedLabel={i18n._(t`Selected`)}
selectedLabel={t`Selected`}
selectedResourceRows={selectedResourceRows}
sortedColumnKey="username"
/>
@ -243,7 +240,7 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
onRowClick={handleResourceCheckboxClick}
fetchItems={readTeams}
fetchOptions={readTeamsOptions}
selectedLabel={i18n._(t`Selected`)}
selectedLabel={t`Selected`}
selectedResourceRows={selectedResourceRows}
/>
)}
@ -254,18 +251,18 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
},
{
id: 3,
name: i18n._(t`Select Roles to Apply`),
name: t`Select Roles to Apply`,
component: (
<SelectRoleStep
onRolesClick={handleRoleCheckboxClick}
roles={selectableRoles}
selectedListKey={selectedResource === 'users' ? 'username' : 'name'}
selectedListLabel={i18n._(t`Selected`)}
selectedListLabel={t`Selected`}
selectedResourceRows={selectedResourceRows}
selectedRoleRows={selectedRoleRows}
/>
),
nextButtonText: i18n._(t`Save`),
nextButtonText: t`Save`,
enableNext: selectedRoleRows.length > 0,
canJumpTo: maxEnabledStep >= 3,
},
@ -285,8 +282,8 @@ function AddResourceRole({ onSave, onClose, roles, i18n, resource, onError }) {
steps={steps}
title={wizardTitle}
nextButtonText={currentStep.nextButtonText || undefined}
backButtonText={i18n._(t`Back`)}
cancelButtonText={i18n._(t`Cancel`)}
backButtonText={t`Back`}
cancelButtonText={t`Cancel`}
/>
);
}
@ -304,4 +301,4 @@ AddResourceRole.defaultProps = {
};
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 PropTypes from 'prop-types';
import { withRouter, useLocation } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import useRequest from '../../util/useRequest';
@ -30,7 +29,6 @@ function SelectResourceStep({
selectedResourceRows,
fetchItems,
fetchOptions,
i18n,
}) {
const location = useLocation();
@ -78,9 +76,7 @@ function SelectResourceStep({
return (
<Fragment>
<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>
{selectedResourceRows.length > 0 && (
<SelectedList
@ -139,4 +135,4 @@ SelectResourceStep.defaultProps = {
};
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 PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import CheckboxCard from './CheckboxCard';
@ -14,21 +13,18 @@ function RolesStep({
selectedListLabel,
selectedResourceRows,
selectedRoleRows,
i18n,
}) {
return (
<Fragment>
<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>
{selectedResourceRows.length > 0 && (
<SelectedList
displayKey={selectedListKey}
isReadOnly
label={selectedListLabel || i18n._(t`Selected`)}
label={selectedListLabel || t`Selected`}
selected={selectedResourceRows}
/>
)}
@ -75,4 +71,4 @@ RolesStep.defaultProps = {
selectedRoleRows: [],
};
export default withI18n()(RolesStep);
export default RolesStep;

View File

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

View File

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

View File

@ -12,7 +12,7 @@ import {
PageSidebar,
} from '@patternfly/react-core';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import styled from 'styled-components';
import { MeAPI, RootAPI } from '../../api';
@ -85,7 +85,7 @@ function useStorage(key) {
return [storageVal, setValue];
}
function AppContainer({ i18n, navRouteConfig = [], children }) {
function AppContainer({ navRouteConfig = [], children }) {
const history = useHistory();
const config = useConfig();
@ -139,7 +139,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
}, [handleLogout, timeRemaining]);
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 = (
<PageHeader
@ -165,7 +165,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
<PageHeaderToolsGroup>
<PageHeaderToolsItem>
<Button onClick={handleLogout} variant="tertiary" ouiaId="logout">
{i18n._(t`Logout`)}
{t`Logout`}
</Button>
</PageHeaderToolsItem>
</PageHeaderToolsGroup>
@ -178,7 +178,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
<PageSidebar
theme="dark"
nav={
<Nav aria-label={i18n._(t`Navigation`)} theme="dark">
<Nav aria-label={t`Navigation`} theme="dark">
<NavList>
{navRouteConfig.map(({ groupId, groupTitle, routes }) => (
<NavExpandableGroup
@ -210,7 +210,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
/>
<AlertModal
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}
onClose={handleLogout}
showClose={false}
@ -222,7 +222,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
variant="primary"
onClick={handleSessionContinue}
>
{i18n._(t`Continue`)}
{t`Continue`}
</Button>,
<Button
ouiaId="session-expiration-logout-button"
@ -230,19 +230,17 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
variant="secondary"
onClick={handleLogout}
>
{i18n._(t`Logout`)}
{t`Logout`}
</Button>,
]}
>
{i18n._(
t`You will be logged out in ${Number(
Math.max(Math.floor(timeRemaining / 1000), 0)
)} seconds due to inactivity.`
)}
{t`You will be logged out in ${Number(
Math.max(Math.floor(timeRemaining / 1000), 0)
)} seconds due to inactivity.`}
</AlertModal>
</>
);
}
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 PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
@ -42,7 +42,6 @@ function PageHeaderToolbar({
onAboutClick,
onLogoutClick,
loggedInUser,
i18n,
}) {
const [isHelpOpen, setIsHelpOpen] = useState(false);
const [isUserOpen, setIsUserOpen] = useState(false);
@ -83,10 +82,7 @@ function PageHeaderToolbar({
return (
<PageHeaderTools>
<PageHeaderToolsGroup>
<Tooltip
position="bottom"
content={i18n._(t`Pending Workflow Approvals`)}
>
<Tooltip position="bottom" content={t`Pending Workflow Approvals`}>
<PageHeaderToolsItem>
<Link to="/workflow_approvals?workflow_approvals.status=pending">
<PendingWorkflowApprovals>
@ -108,10 +104,7 @@ function PageHeaderToolbar({
position={DropdownPosition.right}
onSelect={handleHelpSelect}
toggle={
<DropdownToggle
onToggle={setIsHelpOpen}
aria-label={i18n._(t`Info`)}
>
<DropdownToggle onToggle={setIsHelpOpen} aria-label={t`Info`}>
<QuestionCircleIcon />
</DropdownToggle>
}
@ -121,7 +114,7 @@ function PageHeaderToolbar({
target="_blank"
href={`${getDocsBaseUrl(config)}/html/userguide/index.html`}
>
{i18n._(t`Help`)}
{t`Help`}
</DropdownItem>,
<DropdownItem
key="about"
@ -129,12 +122,12 @@ function PageHeaderToolbar({
isDisabled={isAboutDisabled}
onClick={onAboutClick}
>
{i18n._(t`About`)}
{t`About`}
</DropdownItem>,
]}
/>
</PageHeaderToolsItem>
<Tooltip position="left" content={<div>{i18n._(t`User`)}</div>}>
<Tooltip position="left" content={<div>{t`User`}</div>}>
<PageHeaderToolsItem>
<Dropdown
id="toolbar-user-dropdown"
@ -155,14 +148,14 @@ function PageHeaderToolbar({
dropdownItems={[
<DropdownItem
key="user"
aria-label={i18n._(t`User details`)}
aria-label={t`User details`}
href={
loggedInUser
? `/#/users/${loggedInUser.id}/details`
: '/#/home'
}
>
{i18n._(t`User Details`)}
{t`User Details`}
</DropdownItem>,
<DropdownItem
key="logout"
@ -170,7 +163,7 @@ function PageHeaderToolbar({
onClick={onLogoutClick}
id="logout-button"
>
{i18n._(t`Logout`)}
{t`Logout`}
</DropdownItem>,
]}
/>
@ -191,4 +184,4 @@ PageHeaderToolbar.defaultProps = {
isAboutDisabled: false,
};
export default withI18n()(PageHeaderToolbar);
export default PageHeaderToolbar;

View File

@ -1,6 +1,6 @@
import React, { Fragment, useEffect, useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Button, Modal } from '@patternfly/react-core';
import OptionsList from '../OptionsList';
@ -17,9 +17,8 @@ const QS_CONFIG = (order_by = 'name') => {
};
function AssociateModal({
i18n,
header = i18n._(t`Items`),
title = i18n._(t`Select Items`),
header = t`Items`,
title = t`Select Items`,
onClose,
onAssociate,
fetchRequest,
@ -96,28 +95,28 @@ function AssociateModal({
<Modal
variant="large"
title={title}
aria-label={i18n._(t`Association modal`)}
aria-label={t`Association modal`}
isOpen={isModalOpen}
onClose={handleClose}
actions={[
<Button
ouiaId="associate-modal-save"
aria-label={i18n._(t`Save`)}
aria-label={t`Save`}
key="select"
variant="primary"
onClick={handleSave}
isDisabled={selected.length === 0}
>
{i18n._(t`Save`)}
{t`Save`}
</Button>,
<Button
ouiaId="associate-modal-cancel"
aria-label={i18n._(t`Cancel`)}
aria-label={t`Cancel`}
key="cancel"
variant="link"
onClick={handleClose}
>
{i18n._(t`Cancel`)}
{t`Cancel`}
</Button>,
]}
>
@ -136,22 +135,22 @@ function AssociateModal({
value={selected}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: `${displayKey}__icontains`,
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
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 (
<PFChipGroup
{...props}
numChips={numChips}
expandedText={i18n._(t`Show less`)}
collapsedText={i18n._(t`${totalChips - numChips} more`)}
expandedText={t`Show less`}
collapsedText={t`${totalChips - numChips} more`}
/>
);
}
@ -18,7 +18,6 @@ function ChipGroup({ i18n, numChips, totalChips, i18nHash, ...props }) {
ChipGroup.propTypes = {
numChips: 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-django';
import 'ace-builds/src-noconflict/theme-github';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import styled from 'styled-components';
import debounce from '../../util/debounce';
@ -81,7 +81,6 @@ function CodeEditor({
rows,
fullHeight,
className,
i18n,
}) {
if (rows && typeof rows !== 'number' && rows !== 'auto') {
// eslint-disable-next-line no-console
@ -185,7 +184,7 @@ function CodeEditor({
className="pf-c-form__helper-text keyboard-help-text"
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>
)}
</>
@ -210,4 +209,4 @@ CodeEditor.defaultProps = {
className: '',
};
export default withI18n()(CodeEditor);
export default CodeEditor;

View File

@ -1,7 +1,7 @@
import 'styled-components/macro';
import React, { useState } from 'react';
import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Split,
@ -23,15 +23,7 @@ import {
import CodeEditor from './CodeEditor';
import { JSON_MODE, YAML_MODE } from './constants';
function VariablesDetail({
dataCy,
helpText,
value,
label,
rows,
fullHeight,
i18n,
}) {
function VariablesDetail({ dataCy, helpText, value, label, rows, fullHeight }) {
const [mode, setMode] = useState(
isJsonObject(value) || isJsonString(value) ? JSON_MODE : YAML_MODE
);
@ -84,7 +76,6 @@ function VariablesDetail({
setMode={setMode}
currentValue={currentValue}
onExpand={() => setIsExpanded(true)}
i18n={i18n}
/>
</DetailName>
<DetailValue
@ -107,7 +98,7 @@ function VariablesDetail({
css="color: var(--pf-global--danger-color--100);
font-size: var(--pf-global--FontSize--sm"
>
{i18n._(t`Error:`)} {error.message}
{t`Error:`} {error.message}
</div>
)}
</DetailValue>
@ -118,13 +109,13 @@ function VariablesDetail({
onClose={() => setIsExpanded(false)}
actions={[
<Button
aria-label={i18n._(t`Done`)}
aria-label={t`Done`}
key="select"
variant="primary"
onClick={() => setIsExpanded(false)}
ouiaId={`${dataCy}-unexpand`}
>
{i18n._(t`Done`)}
{t`Done`}
</Button>,
]}
>
@ -137,7 +128,6 @@ function VariablesDetail({
mode={mode}
setMode={setMode}
currentValue={currentValue}
i18n={i18n}
/>
<CodeEditor
id={`${dataCy}-preview-expanded`}
@ -166,16 +156,7 @@ VariablesDetail.defaultProps = {
helpText: '',
};
function ModeToggle({
id,
label,
helpText,
dataCy,
mode,
setMode,
onExpand,
i18n,
}) {
function ModeToggle({ id, label, helpText, dataCy, mode, setMode, onExpand }) {
return (
<Split hasGutter>
<SplitItem isFilled>
@ -211,7 +192,7 @@ function ModeToggle({
<SplitItem>
<Button
variant="plain"
aria-label={i18n._(t`Expand input`)}
aria-label={t`Expand input`}
onClick={onExpand}
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 { string, bool } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import styled from 'styled-components';
@ -24,15 +24,7 @@ const StyledCheckboxField = styled(CheckboxField)`
margin-left: auto;
`;
function VariablesField({
i18n,
id,
name,
label,
readOnly,
promptId,
tooltip,
}) {
function VariablesField({ id, name, label, readOnly, promptId, tooltip }) {
// track focus manually, because the Code Editor library doesn't wire
// into Formik completely
const [shouldValidate, setShouldValidate] = useState(false);
@ -112,7 +104,6 @@ function VariablesField({
return (
<div>
<VariablesFieldInternals
i18n={i18n}
id={id}
name={name}
label={label}
@ -132,19 +123,18 @@ function VariablesField({
onClose={() => setIsExpanded(false)}
actions={[
<Button
aria-label={i18n._(t`Done`)}
aria-label={t`Done`}
key="select"
variant="primary"
onClick={() => setIsExpanded(false)}
ouiaId={`${id}-variables-unexpand`}
>
{i18n._(t`Done`)}
{t`Done`}
</Button>,
]}
>
<div className="pf-c-form">
<VariablesFieldInternals
i18n={i18n}
id={`${id}-expanded`}
name={name}
label={label}
@ -180,7 +170,6 @@ VariablesField.defaultProps = {
};
function VariablesFieldInternals({
i18n,
id,
name,
label,
@ -227,14 +216,14 @@ function VariablesFieldInternals({
{promptId && (
<StyledCheckboxField
id="template-ask-variables-on-launch"
label={i18n._(t`Prompt on launch`)}
label={t`Prompt on launch`}
name="ask_variables_on_launch"
/>
)}
{onExpand && (
<Button
variant="plain"
aria-label={i18n._(t`Expand input`)}
aria-label={t`Expand input`}
onClick={onExpand}
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 { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import {
Title,
EmptyState,
@ -9,15 +9,15 @@ import {
} from '@patternfly/react-core';
import { CubesIcon } from '@patternfly/react-icons';
const ContentEmpty = ({ i18n, title = '', message = '' }) => (
const ContentEmpty = ({ title = '', message = '' }) => (
<EmptyState variant="full">
<EmptyStateIcon icon={CubesIcon} />
<Title size="lg" headingLevel="h3">
{title || i18n._(t`No items found.`)}
{title || t`No items found.`}
</Title>
<EmptyStateBody>{message}</EmptyStateBody>
</EmptyState>
);
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 { bool, instanceOf } from 'prop-types';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import {
Title,
EmptyState,
@ -18,7 +18,7 @@ async function logout() {
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.response.headers['session-timeout']) {
logout();
@ -36,17 +36,13 @@ function ContentError({ error, children, isNotFound, i18n }) {
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} />
<Title size="lg" headingLevel="h3">
{is404 ? i18n._(t`Not Found`) : i18n._(t`Something went wrong...`)}
{is404 ? t`Not Found` : t`Something went wrong...`}
</Title>
<EmptyStateBody>
{is404
? i18n._(t`The page you requested could not be found.`)
: i18n._(
t`There was an error loading this content. Please reload the page.`
)}{' '}
{children || (
<Link to="/home">{i18n._(t`Back to Dashboard.`)}</Link>
)}
? t`The page you requested could not be found.`
: t`There was an error loading this content. Please reload the page.`}{' '}
{children || <Link to="/home">{t`Back to Dashboard.`}</Link>}
</EmptyStateBody>
{error && <ErrorDetail error={error} />}
</EmptyState>
@ -64,4 +60,4 @@ ContentError.defaultProps = {
};
export { ContentError as _ContentError };
export default withI18n()(ContentError);
export default ContentError;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import 'styled-components/macro';
import React, { Fragment, useState, useEffect, useCallback } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../AlertModal';
@ -9,16 +9,13 @@ import useRequest from '../../util/useRequest';
import { HostsAPI } from '../../api';
function HostToggle({
i18n,
className,
host,
isDisabled = false,
onToggle,
tooltip = i18n._(
t`Indicates if a host is available and should be included in running
tooltip = 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
reset by the inventory sync process.`
),
reset by the inventory sync process.`,
}) {
const [isEnabled, setIsEnabled] = useState(host.enabled);
const [showError, setShowError] = useState(false);
@ -55,8 +52,8 @@ function HostToggle({
className={className}
css="display: inline-flex;"
id={`host-${host.id}-toggle`}
label={i18n._(t`On`)}
labelOff={i18n._(t`Off`)}
label={t`On`}
labelOff={t`Off`}
isChecked={isEnabled}
isDisabled={
isLoading ||
@ -64,17 +61,17 @@ function HostToggle({
!host.summary_fields.user_capabilities.edit
}
onChange={toggleHost}
aria-label={i18n._(t`Toggle host`)}
aria-label={t`Toggle host`}
/>
</Tooltip>
{showError && error && !isLoading && (
<AlertModal
variant="error"
title={i18n._(t`Error!`)}
title={t`Error!`}
isOpen={error && !isLoading}
onClose={() => setShowError(false)}
>
{i18n._(t`Failed to toggle host.`)}
{t`Failed to toggle host.`}
<ErrorDetail error={error} />
</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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../AlertModal';
@ -8,13 +8,7 @@ import useRequest from '../../util/useRequest';
import { InstancesAPI } from '../../api';
import { useConfig } from '../../contexts/Config';
function InstanceToggle({
className,
fetchInstances,
instance,
onToggle,
i18n,
}) {
function InstanceToggle({ className, fetchInstances, instance, onToggle }) {
const { me = {} } = useConfig();
const [isEnabled, setIsEnabled] = useState(instance.enabled);
const [showError, setShowError] = useState(false);
@ -46,31 +40,29 @@ function InstanceToggle({
return (
<>
<Tooltip
content={i18n._(
t`Set the instance online or offline. If offline, jobs will not be assigned to this instance.`
)}
content={t`Set the instance online or offline. If offline, jobs will not be assigned to this instance.`}
position="top"
>
<Switch
className={className}
css="display: inline-flex;"
id={`host-${instance.id}-toggle`}
label={i18n._(t`On`)}
labelOff={i18n._(t`Off`)}
label={t`On`}
labelOff={t`Off`}
isChecked={isEnabled}
isDisabled={isLoading || !me?.is_superuser}
onChange={toggleInstance}
aria-label={i18n._(t`Toggle instance`)}
aria-label={t`Toggle instance`}
/>
</Tooltip>
{showError && error && !isLoading && (
<AlertModal
variant="error"
title={i18n._(t`Error!`)}
title={t`Error!`}
isOpen={error && !isLoading}
onClose={() => setShowError(false)}
>
{i18n._(t`Failed to toggle instance.`)}
{t`Failed to toggle instance.`}
<ErrorDetail error={error} />
</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 { withI18n } from '@lingui/react';
import { t, Plural } from '@lingui/macro';
import { arrayOf, func } from 'prop-types';
import { Button, DropdownItem, Tooltip } from '@patternfly/react-core';
@ -18,7 +18,7 @@ function cannotCancelBecauseNotRunning(job) {
return !isJobRunning(job.status);
}
function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
function JobListCancelButton({ jobsToCancel, onCancel }) {
const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext);
const [isModalOpen, setIsModalOpen] = useState(false);
const numJobsToCancel = jobsToCancel.length;
@ -90,12 +90,12 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
return (
<Plural
value={numJobsToCancel}
one={i18n._(t`Cancel selected job`)}
other={i18n._(t`Cancel selected jobs`)}
one={t`Cancel selected job`}
other={t`Cancel selected jobs`}
/>
);
}
return i18n._(t`Select a job to cancel`);
return t`Select a job to cancel`;
};
const isDisabled =
@ -156,10 +156,10 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
id="cancel-job-return-button"
key="cancel"
variant="secondary"
aria-label={i18n._(t`Return`)}
aria-label={t`Return`}
onClick={toggleModal}
>
{i18n._(t`Return`)}
{t`Return`}
</Button>,
]}
>
@ -192,4 +192,4 @@ JobListCancelButton.defaultProps = {
onCancel: () => {},
};
export default withI18n()(JobListCancelButton);
export default JobListCancelButton;

View File

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

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Dropdown,
@ -15,7 +15,7 @@ function ReLaunchDropDown({
isPrimary = false,
handleRelaunch,
isLaunching,
i18n,
ouiaId,
}) {
const [isOpen, setIsOpen] = useState(false);
@ -27,38 +27,38 @@ function ReLaunchDropDown({
const dropdownItems = [
<DropdownItem
ouiaId={`${ouiaId}-on`}
aria-label={i18n._(t`Relaunch on`)}
aria-label={t`Relaunch on`}
key="relaunch_on"
component="div"
isPlainText
>
{i18n._(t`Relaunch on`)}
{t`Relaunch on`}
</DropdownItem>,
<DropdownSeparator key="separator" />,
<DropdownItem
ouiaId={`${ouiaId}-all`}
key="relaunch_all"
aria-label={i18n._(t`Relaunch all hosts`)}
aria-label={t`Relaunch all hosts`}
component="button"
onClick={() => {
handleRelaunch({ hosts: 'all' });
}}
isDisabled={isLaunching}
>
{i18n._(t`All`)}
{t`All`}
</DropdownItem>,
<DropdownItem
ouiaId={`${ouiaId}-failed`}
key="relaunch_failed"
aria-label={i18n._(t`Relaunch failed hosts`)}
aria-label={t`Relaunch failed hosts`}
component="button"
onClick={() => {
handleRelaunch({ hosts: 'failed' });
}}
isDisabled={isLaunching}
>
{i18n._(t`Failed hosts`)}
{t`Failed hosts`}
</DropdownItem>,
];
@ -74,11 +74,11 @@ function ReLaunchDropDown({
<DropdownToggle
toggleIndicator={null}
onToggle={onToggle}
aria-label={i18n._(t`relaunch jobs`)}
aria-label={t`relaunch jobs`}
id="relaunch_jobs"
isPrimary
>
{i18n._(t`Relaunch`)}
{t`Relaunch`}
</DropdownToggle>
}
/>
@ -96,7 +96,7 @@ function ReLaunchDropDown({
<DropdownToggle
toggleIndicator={null}
onToggle={onToggle}
aria-label={i18n._(t`relaunch jobs`)}
aria-label={t`relaunch jobs`}
id="relaunch_jobs"
>
<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 { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Formik, useFormikContext } from 'formik';
import ContentError from '../ContentError';
@ -13,7 +13,7 @@ import AlertModal from '../AlertModal';
function PromptModalForm({
launchConfig,
i18n,
onCancel,
onSubmit,
resource,
@ -33,7 +33,7 @@ function PromptModalForm({
launchConfig,
surveyConfig,
resource,
i18n,
resourceDefaultCredentials
);
@ -70,7 +70,7 @@ function PromptModalForm({
<AlertModal
isOpen={error}
variant="error"
title={i18n._(t`Error!`)}
title={t`Error!`}
onClose={() => {
dismissError();
}}
@ -104,27 +104,27 @@ function PromptModalForm({
validateStep(nextStep.id);
}
}}
title={i18n._(t`Prompts`)}
title={t`Prompts`}
steps={
isReady
? steps
: [
{
name: i18n._(t`Content Loading`),
name: t`Content Loading`,
component: <ContentLoading />,
},
]
}
backButtonText={i18n._(t`Back`)}
cancelButtonText={i18n._(t`Cancel`)}
nextButtonText={i18n._(t`Next`)}
backButtonText={t`Back`}
cancelButtonText={t`Cancel`}
nextButtonText={t`Next`}
/>
);
}
function LaunchPrompt({
launchConfig,
i18n,
onCancel,
onLaunch,
resource = {},
@ -136,7 +136,6 @@ function LaunchPrompt({
<PromptModalForm
onSubmit={values => onLaunch(values)}
onCancel={onCancel}
i18n={i18n}
launchConfig={launchConfig}
surveyConfig={surveyConfig}
resource={resource}
@ -147,4 +146,4 @@ function LaunchPrompt({
}
export { LaunchPrompt as _LaunchPrompt };
export default withI18n()(LaunchPrompt);
export default LaunchPrompt;

View File

@ -1,11 +1,11 @@
import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Form } from '@patternfly/react-core';
import { useFormikContext } from 'formik';
import { PasswordField } from '../../FormField';
function CredentialPasswordsStep({ launchConfig, i18n }) {
function CredentialPasswordsStep({ launchConfig }) {
const {
values: { credentials },
} = useFormikContext();
@ -92,7 +92,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordSsh && (
<PasswordField
id="launch-ssh-password"
label={i18n._(t`SSH password`)}
label={t`SSH password`}
name="credential_passwords.ssh_password"
isRequired
/>
@ -100,7 +100,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordPrivateKeyPassphrase && (
<PasswordField
id="launch-private-key-passphrase"
label={i18n._(t`Private key passphrase`)}
label={t`Private key passphrase`}
name="credential_passwords.ssh_key_unlock"
isRequired
/>
@ -108,7 +108,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
{showcredentialPasswordPrivilegeEscalation && (
<PasswordField
id="launch-privilege-escalation-password"
label={i18n._(t`Privilege escalation password`)}
label={t`Privilege escalation password`}
name="credential_passwords.become_password"
isRequired
/>
@ -118,9 +118,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) {
id={`launch-vault-password-${credId}`}
key={credId}
label={
credId === ''
? i18n._(t`Vault password`)
: i18n._(t`Vault password | ${credId}`)
credId === '' ? t`Vault password` : t`Vault password | ${credId}`
}
name={`credential_passwords['vault_password${
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 React, { useState, useCallback, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import styled from 'styled-components';
@ -27,7 +27,6 @@ const QS_CONFIG = getQSConfig('credential', {
});
function CredentialsStep({
i18n,
allowCredentialsWithPasswords,
defaultCredentials = [],
}) {
@ -35,7 +34,6 @@ function CredentialsStep({
name: 'credentials',
validate: val => {
return credentialsValidator(
i18n,
defaultCredentials,
allowCredentialsWithPasswords,
val
@ -106,7 +104,6 @@ function CredentialsStep({
useEffect(() => {
helpers.setError(
credentialsValidator(
i18n,
defaultCredentials,
allowCredentialsWithPasswords,
field.value
@ -145,12 +142,12 @@ function CredentialsStep({
{types && types.length > 0 && (
<ToolbarItem css=" display: flex; align-items: center;">
<div css="flex: 0 0 25%; margin-right: 32px">
{i18n._(t`Selected Category`)}
{t`Selected Category`}
</div>
<AnsibleSelect
css="flex: 1 1 75%;"
id="multiCredentialsLookUp-select"
label={i18n._(t`Selected Category`)}
label={t`Selected Category`}
data={types.map(type => ({
key: type.id,
value: type.id,
@ -171,29 +168,29 @@ function CredentialsStep({
optionCount={count}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys}
multiple={isVault}
header={i18n._(t`Credentials`)}
header={t`Credentials`}
name="credentials"
qsConfig={QS_CONFIG}
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 { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import styled from 'styled-components';
@ -22,7 +22,7 @@ const QS_CONFIG = getQSConfig('inventory', {
order_by: 'name',
});
function InventoryStep({ i18n, warningMessage = null }) {
function InventoryStep({ warningMessage = null }) {
const [field, meta, helpers] = useField({
name: 'inventory',
});
@ -83,28 +83,28 @@ function InventoryStep({ i18n, warningMessage = null }) {
optionCount={count}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys}
header={i18n._(t`Inventory`)}
header={t`Inventory`}
name="inventory"
qsConfig={QS_CONFIG}
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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import { Form, FormGroup, Switch } from '@patternfly/react-core';
@ -20,88 +20,84 @@ const FieldHeader = styled.div`
}
`;
function OtherPromptsStep({ launchConfig, i18n }) {
function OtherPromptsStep({ launchConfig }) {
return (
<Form
onSubmit={e => {
e.preventDefault();
}}
>
{launchConfig.ask_job_type_on_launch && <JobTypeField i18n={i18n} />}
{launchConfig.ask_job_type_on_launch && <JobTypeField />}
{launchConfig.ask_limit_on_launch && (
<FormField
id="prompt-limit"
name="limit"
label={i18n._(t`Limit`)}
tooltip={i18n._(t`Provide a host pattern to further constrain the list
label={t`Limit`}
tooltip={t`Provide a host pattern to further constrain the list
of hosts that will be managed or affected by the playbook. Multiple
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 && (
<FormField
id="prompt-scm-branch"
name="scm_branch"
label={i18n._(t`Source Control Branch`)}
tooltip={i18n._(
t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch`
)}
label={t`Source Control Branch`}
tooltip={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_diff_mode_on_launch && (
<ShowChangesToggle i18n={i18n} />
)}
{launchConfig.ask_verbosity_on_launch && <VerbosityField />}
{launchConfig.ask_diff_mode_on_launch && <ShowChangesToggle />}
{launchConfig.ask_tags_on_launch && (
<TagField
id="prompt-job-tags"
name="job_tags"
label={i18n._(t`Job Tags`)}
aria-label={i18n._(t`Job Tags`)}
tooltip={i18n._(t`Tags are useful when you have a large
label={t`Job Tags`}
aria-label={t`Job Tags`}
tooltip={t`Tags are useful when you have a large
playbook, and you want to run a specific part of a play or task.
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 && (
<TagField
id="prompt-skip-tags"
name="skip_tags"
label={i18n._(t`Skip Tags`)}
aria-label={i18n._(t`Skip Tags`)}
tooltip={i18n._(t`Skip tags are useful when you have a large
label={t`Skip Tags`}
aria-label={t`Skip Tags`}
tooltip={t`Skip tags are useful when you have a large
playbook, and you want to skip specific parts of a play or task.
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 && (
<VariablesField
id="prompt-variables"
name="extra_vars"
label={i18n._(t`Variables`)}
label={t`Variables`}
/>
)}
</Form>
);
}
function JobTypeField({ i18n }) {
function JobTypeField() {
const [field, meta, helpers] = useField('job_type');
const options = [
{
value: '',
key: '',
label: i18n._(t`Choose a job type`),
label: t`Choose a job type`,
isDisabled: true,
},
{ value: 'run', key: 'run', label: i18n._(t`Run`), isDisabled: false },
{ value: 'run', key: 'run', label: t`Run`, isDisabled: false },
{
value: 'check',
key: 'check',
label: i18n._(t`Check`),
label: t`Check`,
isDisabled: false,
},
];
@ -109,12 +105,12 @@ function JobTypeField({ i18n }) {
return (
<FormGroup
fieldId="propmt-job-type"
label={i18n._(t`Job Type`)}
label={t`Job Type`}
labelIcon={
<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,
and report problems without executing the playbook.`)}
and report problems without executing the playbook.`}
/>
}
isRequired
@ -130,14 +126,14 @@ function JobTypeField({ i18n }) {
);
}
function VerbosityField({ i18n }) {
function VerbosityField() {
const [field, meta, helpers] = useField('verbosity');
const options = [
{ value: '0', key: '0', label: i18n._(t`0 (Normal)`) },
{ value: '1', key: '1', label: i18n._(t`1 (Verbose)`) },
{ value: '2', key: '2', label: i18n._(t`2 (More Verbose)`) },
{ value: '3', key: '3', label: i18n._(t`3 (Debug)`) },
{ value: '4', key: '4', label: i18n._(t`4 (Connection Debug)`) },
{ value: '0', key: '0', label: t`0 (Normal)` },
{ value: '1', key: '1', label: t`1 (Verbose)` },
{ value: '2', key: '2', label: t`2 (More Verbose)` },
{ value: '3', key: '3', label: t`3 (Debug)` },
{ value: '4', key: '4', label: t`4 (Connection Debug)` },
];
const isValid = !(meta.touched && meta.error);
@ -146,11 +142,11 @@ function VerbosityField({ i18n }) {
<FormGroup
fieldId="prompt-verbosity"
validated={isValid ? 'default' : 'error'}
label={i18n._(t`Verbosity`)}
label={t`Verbosity`}
labelIcon={
<Popover
content={i18n._(t`Control the level of output ansible
will produce as the playbook executes.`)}
content={t`Control the level of output ansible
will produce as the playbook executes.`}
/>
}
>
@ -164,7 +160,7 @@ function VerbosityField({ i18n }) {
);
}
function ShowChangesToggle({ i18n }) {
function ShowChangesToggle() {
const [field, , helpers] = useField('diff_mode');
return (
<FormGroup fieldId="prompt-show-changes">
@ -172,20 +168,20 @@ function ShowChangesToggle({ i18n }) {
{' '}
<label className="pf-c-form__label" htmlFor="prompt-show-changes">
<span className="pf-c-form__label-text">
{i18n._(t`Show Changes`)}
{t`Show Changes`}
<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
--diff mode.`)}
--diff mode.`}
/>
</span>
</label>
</FieldHeader>
<Switch
aria-label={field.value ? i18n._(t`On`) : i18n._(t`Off`)}
aria-label={field.value ? t`On` : t`Off`}
id="prompt-show-changes"
label={i18n._(t`On`)}
labelOff={i18n._(t`Off`)}
label={t`On`}
labelOff={t`Off`}
isChecked={field.value}
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 { t } from '@lingui/macro';
import { useFormikContext } from 'formik';
import { withI18n } from '@lingui/react';
import yaml from 'js-yaml';
import mergeExtraVars, {
maskPasswords,
@ -25,13 +25,7 @@ const ErrorMessageWrapper = styled.div`
margin-bottom: 10px;
`;
function PreviewStep({
resource,
launchConfig,
surveyConfig,
formErrors,
i18n,
}) {
function PreviewStep({ resource, launchConfig, surveyConfig, formErrors }) {
const { values } = useFormikContext();
const surveyValues = getSurveyValues(values);
@ -61,10 +55,10 @@ function PreviewStep({
<Fragment>
{formErrors && (
<ErrorMessageWrapper>
{i18n._(t`Some of the previous step(s) have errors`)}
{t`Some of the previous step(s) have errors`}
<Tooltip
position="right"
content={i18n._(t`See errors on the left`)}
content={t`See errors on the left`}
trigger="click mouseenter focus"
>
<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 styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Tooltip } from '@patternfly/react-core';
import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons';
@ -14,7 +14,7 @@ const ExclamationCircleIcon = styled(PFExclamationCircleIcon)`
margin-left: 10px;
`;
function StepName({ hasErrors, children, i18n, id }) {
function StepName({ hasErrors, children, id }) {
if (!hasErrors) {
return <div id={id}>{children}</div>;
}
@ -24,7 +24,7 @@ function StepName({ hasErrors, children, i18n, id }) {
{children}
<Tooltip
position="right"
content={i18n._(t`This step contains errors`)}
content={t`This step contains errors`}
trigger="click mouseenter focus"
>
<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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import {
@ -22,7 +22,7 @@ import {
} from '../../../util/validators';
import { Survey } from '../../../types';
function SurveyStep({ surveyConfig, i18n }) {
function SurveyStep({ surveyConfig }) {
const fieldTypes = {
text: TextField,
textarea: TextField,
@ -40,9 +40,7 @@ function SurveyStep({ surveyConfig, i18n }) {
>
{surveyConfig.spec.map(question => {
const Field = fieldTypes[question.type];
return (
<Field key={question.variable} question={question} i18n={i18n} />
);
return <Field key={question.variable} question={question} />;
})}
</Form>
);
@ -51,11 +49,11 @@ SurveyStep.propTypes = {
surveyConfig: Survey.isRequired,
};
function TextField({ question, i18n }) {
function TextField({ question }) {
const validators = [
question.required ? required(null, i18n) : null,
question.required && question.min ? minLength(question.min, i18n) : null,
question.required && question.max ? maxLength(question.max, i18n) : null,
question.required ? required(null) : null,
question.required && question.min ? minLength(question.min) : null,
question.required && question.max ? maxLength(question.max) : null,
];
return (
<FormField
@ -72,11 +70,11 @@ function TextField({ question, i18n }) {
);
}
function NumberField({ question, i18n }) {
function NumberField({ question }) {
const validators = [
question.required ? required(null, i18n) : null,
minMaxValue(question.min, question.max, i18n),
question.type === 'integer' ? integer(i18n) : null,
question.required ? required(null) : null,
minMaxValue(question.min, question.max),
question.type === 'integer' ? integer() : null,
];
return (
<FormField
@ -120,11 +118,11 @@ function MultipleChoiceField({ question }) {
);
}
function MultiSelectField({ question, i18n }) {
function MultiSelectField({ question }) {
const [isOpen, setIsOpen] = useState(false);
const [field, meta, helpers] = useField({
name: `survey_${question.variable}`,
validate: question.required ? required(null, i18n) : null,
validate: question.required ? required(null) : null,
});
const id = `survey-question-${question.variable}`;
const hasActualValue = !question.required || meta.value?.length > 0;
@ -134,8 +132,7 @@ function MultiSelectField({ question, i18n }) {
<FormGroup
fieldId={id}
helperTextInvalid={
meta.error ||
i18n._(t`At least one value must be selected for this field.`)
meta.error || t`At least one value must be selected for this field.`
}
isRequired={question.required}
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';
export default function credentialsValidator(
i18n,
defaultCredentials = [],
allowCredentialsWithPasswords,
selectedCredentials
@ -38,11 +37,9 @@ export default function credentialsValidator(
});
if (missingCredentialTypes.length > 0) {
return i18n._(
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(
', '
)}`
);
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(
', '
)}`;
}
}
@ -54,11 +51,9 @@ export default function credentialsValidator(
}
});
if (credentialsThatPrompt.length > 0) {
return i18n._(
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(
', '
)}`
);
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(
', '
)}`;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,35 +43,34 @@ export default function useLaunchSteps(
launchConfig,
surveyConfig,
resource,
i18n,
resourceDefaultCredentials
) {
const [visited, setVisited] = useState({});
const [isReady, setIsReady] = useState(false);
const { touched, values: formikValues } = useFormikContext();
const steps = [
useInventoryStep(launchConfig, resource, i18n, visited),
useInventoryStep(launchConfig, resource, visited),
useCredentialsStep(
launchConfig,
resource,
resourceDefaultCredentials,
i18n,
true
),
useCredentialPasswordsStep(
launchConfig,
i18n,
showCredentialPasswordsStep(formikValues.credentials, launchConfig),
visited
),
useOtherPromptsStep(launchConfig, resource, i18n),
useSurveyStep(launchConfig, surveyConfig, resource, i18n, visited),
useOtherPromptsStep(launchConfig, resource),
useSurveyStep(launchConfig, surveyConfig, resource, visited),
];
const { resetForm } = useFormikContext();
const hasErrors = steps.some(step => step.hasError);
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);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
DataListItem,
@ -10,7 +10,7 @@ import {
} from '@patternfly/react-core';
import DataListCell from '../DataListCell';
function HostListItem({ item, i18n }) {
function HostListItem({ item }) {
return (
<DataListItem
aria-labelledby={`items-list-item-${item.id}`}
@ -20,14 +20,14 @@ function HostListItem({ item, i18n }) {
<DataListItemRow>
<DataListItemCells
dataListCells={[
<DataListCell key="name" aria-label={i18n._(t`name`)}>
<DataListCell key="name" aria-label={t`name`}>
<TextContent>
<Link to={{ pathname: item.url }}>
<b id={`items-list-item-${item.id}`}>{item.name}</b>
</Link>
</TextContent>
</DataListCell>,
<DataListCell key="inventory" aria-label={i18n._(t`inventory`)}>
<DataListCell key="inventory" aria-label={t`inventory`}>
{item.summary_fields.inventory.name}
</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 { arrayOf, string, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core';
import { InstanceGroupsAPI } from '../../api';
@ -20,15 +20,7 @@ const QS_CONFIG = getQSConfig('instance-groups', {
});
function InstanceGroupsLookup(props) {
const {
value,
onChange,
tooltip,
className,
required,
history,
i18n,
} = props;
const { value, onChange, tooltip, className, required, history } = props;
const {
result: { instanceGroups, count, relatedSearchableKeys, searchableKeys },
@ -68,13 +60,13 @@ function InstanceGroupsLookup(props) {
return (
<FormGroup
className={className}
label={i18n._(t`Instance Groups`)}
label={t`Instance Groups`}
labelIcon={tooltip && <Popover content={tooltip} />}
fieldId="org-instance-groups"
>
<Lookup
id="org-instance-groups"
header={i18n._(t`Instance Groups`)}
header={t`Instance Groups`}
value={value}
onChange={onChange}
qsConfig={QS_CONFIG}
@ -88,25 +80,25 @@ function InstanceGroupsLookup(props) {
optionCount={count}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Credential Name`),
name: t`Credential Name`,
key: 'credential__name__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys}
multiple={state.multiple}
header={i18n._(t`Instance Groups`)}
header={t`Instance Groups`}
name="instanceGroups"
qsConfig={QS_CONFIG}
readOnly={!canDelete}
@ -134,4 +126,4 @@ InstanceGroupsLookup.defaultProps = {
required: false,
};
export default withI18n()(withRouter(InstanceGroupsLookup));
export default withRouter(InstanceGroupsLookup);

View File

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

View File

@ -17,7 +17,7 @@ import {
InputGroup,
Modal,
} from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import styled from 'styled-components';
import ChipGroup from '../ChipGroup';
@ -44,7 +44,7 @@ function Lookup(props) {
renderItemChip,
renderOptionsList,
history,
i18n,
isDisabled,
} = props;
@ -103,7 +103,7 @@ function Lookup(props) {
<Fragment>
<InputGroup onBlur={onBlur}>
<Button
aria-label={i18n._(t`Search`)}
aria-label={t`Search`}
id={id}
onClick={() => dispatch({ type: 'TOGGLE_MODAL' })}
variant={ButtonVariant.control}
@ -126,8 +126,8 @@ function Lookup(props) {
<Modal
variant="large"
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)}
aria-label={i18n._(t`Lookup modal`)}
title={t`Select ${header || t`Items`}`}
aria-label={t`Lookup modal`}
isOpen={isModalOpen}
onClose={closeModal}
actions={[
@ -138,16 +138,16 @@ function Lookup(props) {
onClick={save}
isDisabled={required && selectedItems.length === 0}
>
{i18n._(t`Select`)}
{t`Select`}
</Button>,
<Button
ouiaId="modal-cancel-button"
key="cancel"
variant="link"
onClick={closeModal}
aria-label={i18n._(t`Cancel lookup`)}
aria-label={t`Cancel lookup`}
>
{i18n._(t`Cancel`)}
{t`Cancel`}
</Button>,
]}
>
@ -197,4 +197,4 @@ Lookup.defaultProps = {
};
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 { withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { ToolbarItem, Alert } from '@patternfly/react-core';
import { CredentialsAPI, CredentialTypesAPI } from '../../api';
@ -27,7 +27,7 @@ async function loadCredentials(params, selectedCredentialTypeId) {
}
function MultiCredentialsLookup(props) {
const { value, onChange, onError, history, i18n } = props;
const { value, onChange, onError, history } = props;
const [selectedType, setSelectedType] = useState(null);
const isMounted = useIsMounted();
@ -128,7 +128,7 @@ function MultiCredentialsLookup(props) {
return (
<Lookup
id="multiCredential"
header={i18n._(t`Credentials`)}
header={t`Credentials`}
value={value}
multiple
onChange={onChange}
@ -143,20 +143,18 @@ function MultiCredentialsLookup(props) {
variant="info"
isInline
css="margin-bottom: 20px;"
title={i18n._(
t`You cannot select multiple vault credentials with the same vault ID. Doing so will automatically deselect the other with the same vault ID.`
)}
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.`}
/>
)}
{credentialTypes && credentialTypes.length > 0 && (
<ToolbarItem css=" display: flex; align-items: center;">
<div css="flex: 0 0 25%; margin-right: 32px">
{i18n._(t`Selected Category`)}
{t`Selected Category`}
</div>
<AnsibleSelect
css="flex: 1 1 75%;"
id="multiCredentialsLookUp-select"
label={i18n._(t`Selected Category`)}
label={t`Selected Category`}
data={credentialTypes.map(type => ({
key: type.id,
value: type.id,
@ -178,29 +176,29 @@ function MultiCredentialsLookup(props) {
optionCount={credentialsCount}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
searchableKeys={searchableKeys}
relatedSearchableKeys={relatedSearchableKeys}
multiple={isVault}
header={i18n._(t`Credentials`)}
header={t`Credentials`}
displayKey={isVault ? 'label' : 'name'}
name="credentials"
qsConfig={QS_CONFIG}
@ -249,4 +247,4 @@ MultiCredentialsLookup.defaultProps = {
};
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 { node, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core';
import { OrganizationsAPI } from '../../api';
@ -21,7 +21,7 @@ const QS_CONFIG = getQSConfig('organizations', {
function OrganizationLookup({
helperTextInvalid,
i18n,
isValid,
onBlur,
onChange,
@ -79,13 +79,13 @@ function OrganizationLookup({
helperTextInvalid={helperTextInvalid}
isRequired={required}
validated={isValid ? 'default' : 'error'}
label={i18n._(t`Organization`)}
label={t`Organization`}
helperText={helperText}
>
<Lookup
isDisabled={isDisabled}
id="organization"
header={i18n._(t`Organization`)}
header={t`Organization`}
value={value}
onBlur={onBlur}
onChange={onChange}
@ -98,27 +98,27 @@ function OrganizationLookup({
options={organizations}
optionCount={itemCount}
multiple={state.multiple}
header={i18n._(t`Organization`)}
header={t`Organization`}
name="organization"
qsConfig={QS_CONFIG}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
@ -157,4 +157,4 @@ OrganizationLookup.defaultProps = {
};
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 { node, string, func, bool } from 'prop-types';
import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { FormGroup } from '@patternfly/react-core';
import { ProjectsAPI } from '../../api';
@ -24,7 +24,7 @@ const QS_CONFIG = getQSConfig('project', {
function ProjectLookup({
helperTextInvalid,
autoPopulate,
i18n,
isValid,
onChange,
required,
@ -83,12 +83,12 @@ function ProjectLookup({
helperTextInvalid={helperTextInvalid}
isRequired={required}
validated={isValid ? 'default' : 'error'}
label={i18n._(t`Project`)}
label={t`Project`}
labelIcon={tooltip && <Popover content={tooltip} />}
>
<Lookup
id="project"
header={i18n._(t`Project`)}
header={t`Project`}
name="project"
value={value}
onBlur={onBlur}
@ -102,37 +102,37 @@ function ProjectLookup({
value={state.selectedItems}
searchColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name__icontains',
isDefault: true,
},
{
name: i18n._(t`Type`),
name: t`Type`,
key: 'or__scm_type',
options: [
[``, i18n._(t`Manual`)],
[`git`, i18n._(t`Git`)],
[`svn`, i18n._(t`Subversion`)],
[`archive`, i18n._(t`Remote Archive`)],
[`insights`, i18n._(t`Red Hat Insights`)],
[``, t`Manual`],
[`git`, t`Git`],
[`svn`, t`Subversion`],
[`archive`, t`Remote Archive`],
[`insights`, t`Red Hat Insights`],
],
},
{
name: i18n._(t`Source Control URL`),
name: t`Source Control URL`,
key: 'scm_url__icontains',
},
{
name: i18n._(t`Modified By (Username)`),
name: t`Modified By (Username)`,
key: 'modified_by__username__icontains',
},
{
name: i18n._(t`Created By (Username)`),
name: t`Created By (Username)`,
key: 'created_by__username__icontains',
},
]}
sortColumns={[
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
]}
@ -141,7 +141,7 @@ function ProjectLookup({
options={projects}
optionCount={count}
multiple={state.multiple}
header={i18n._(t`Project`)}
header={t`Project`}
name="project"
qsConfig={QS_CONFIG}
readOnly={!canDelete}
@ -179,4 +179,4 @@ ProjectLookup.defaultProps = {
};
export { ProjectLookup as _ProjectLookup };
export default withI18n()(withRouter(ProjectLookup));
export default withRouter(ProjectLookup);

View File

@ -1,17 +1,17 @@
import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
function LookupErrorMessage({ error, i18n }) {
function LookupErrorMessage({ error }) {
if (!error) {
return null;
}
return (
<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>
);
}
export default withI18n()(LookupErrorMessage);
export default LookupErrorMessage;

View File

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

View File

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

View File

@ -9,7 +9,7 @@ import {
oneOfType,
} from 'prop-types';
import styled from 'styled-components';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import SelectedList from '../SelectedList';
import PaginatedDataList from '../PaginatedDataList';
@ -41,14 +41,14 @@ function OptionsList({
deselectItem,
renderItemChip,
isLoading,
i18n,
displayKey,
}) {
return (
<ModalList>
{value.length > 0 && (
<SelectedList
label={i18n._(t`Selected`)}
label={t`Selected`}
selected={value}
onRemove={item => deselectItem(item)}
isReadOnly={readOnly}
@ -113,4 +113,4 @@ OptionsList.defaultProps = {
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 { DataList } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { withRouter, useHistory, useLocation } from 'react-router-dom';
@ -40,7 +40,7 @@ function PaginatedDataList({
pluralizedItemName,
showPageSizeOptions,
location,
i18n,
renderToolbar,
}) {
const { search, pathname } = useLocation();
@ -74,7 +74,7 @@ function PaginatedDataList({
? toolbarSearchColumns
: [
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
isDefault: true,
},
@ -83,17 +83,15 @@ function PaginatedDataList({
? toolbarSortColumns
: [
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
},
];
const queryParams = parseQueryString(qsConfig, location.search);
const dataListLabel = i18n._(t`${pluralizedItemName} List`);
const emptyContentMessage = i18n._(
t`Please add ${pluralizedItemName} to populate this list `
);
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
const dataListLabel = t`${pluralizedItemName} List`;
const emptyContentMessage = t`Please add ${pluralizedItemName} to populate this list `;
const emptyContentTitle = t`No ${pluralizedItemName} Found `;
let Content;
if (hasContentLoading && items.length <= 0) {
@ -218,4 +216,4 @@ PaginatedDataList.defaultProps = {
};
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 { Button, DropdownItem, Tooltip } from '@patternfly/react-core';
import CaretDownIcon from '@patternfly/react-icons/dist/js/icons/caret-down-icon';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useKebabifiedMenu } from '../../contexts/Kebabified';
function ToolbarAddButton({
linkTo,
onClick,
i18n,
isDisabled,
defaultLabel = i18n._(t`Add`),
defaultLabel = t`Add`,
showToggleIndicator,
}) {
const { isKebabified } = useKebabifiedMenu();
@ -72,4 +72,4 @@ ToolbarAddButton.defaultProps = {
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 PropTypes from 'prop-types';
import { TableComposable, Tbody } from '@patternfly/react-table';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useHistory } from 'react-router-dom';
@ -35,7 +35,7 @@ function PaginatedTable({
toolbarRelatedSearchableKeys,
pluralizedItemName,
showPageSizeOptions,
i18n,
renderToolbar,
emptyContentMessage,
ouiaId,
@ -67,15 +67,15 @@ function PaginatedTable({
? toolbarSearchColumns
: [
{
name: i18n._(t`Name`),
name: t`Name`,
key: 'name',
isDefault: true,
},
];
const queryParams = parseQueryString(qsConfig, history.location.search);
const dataListLabel = i18n._(t`${pluralizedItemName} List`);
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
const dataListLabel = t`${pluralizedItemName} List`;
const emptyContentTitle = t`No ${pluralizedItemName} Found `;
let Content;
if (hasContentLoading && items.length <= 0) {
@ -88,7 +88,7 @@ function PaginatedTable({
title={emptyContentTitle}
message={
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 default withI18n()(PaginatedTable);
export default PaginatedTable;

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import React from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Link } from 'react-router-dom';
@ -10,7 +10,7 @@ import CredentialChip from '../CredentialChip';
import ChipGroup from '../ChipGroup';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
function PromptInventorySourceDetail({ i18n, resource }) {
function PromptInventorySourceDetail({ resource }) {
const {
custom_virtualenv,
group_by,
@ -29,11 +29,11 @@ function PromptInventorySourceDetail({ i18n, resource }) {
} = resource;
const VERBOSITY = {
0: i18n._(t`0 (Normal)`),
1: i18n._(t`1 (Verbose)`),
2: i18n._(t`2 (More Verbose)`),
3: i18n._(t`3 (Debug)`),
4: i18n._(t`4 (Connection Debug)`),
0: t`0 (Normal)`,
1: t`1 (Verbose)`,
2: t`2 (More Verbose)`,
3: t`3 (Debug)`,
4: t`4 (Connection Debug)`,
};
let optionsList = '';
@ -45,13 +45,11 @@ function PromptInventorySourceDetail({ i18n, resource }) {
) {
optionsList = (
<List>
{overwrite && <ListItem>{i18n._(t`Overwrite`)}</ListItem>}
{overwrite_vars && (
<ListItem>{i18n._(t`Overwrite Variables`)}</ListItem>
)}
{update_on_launch && <ListItem>{i18n._(t`Update on Launch`)}</ListItem>}
{overwrite && <ListItem>{t`Overwrite`}</ListItem>}
{overwrite_vars && <ListItem>{t`Overwrite Variables`}</ListItem>}
{update_on_launch && <ListItem>{t`Update on Launch`}</ListItem>}
{update_on_project_update && (
<ListItem>{i18n._(t`Update on Project Update`)}</ListItem>
<ListItem>{t`Update on Project Update`}</ListItem>
)}
</List>
);
@ -61,7 +59,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
<>
{summary_fields?.organization ? (
<Detail
label={i18n._(t`Organization`)}
label={t`Organization`}
value={
<Link
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 && (
<Detail
label={i18n._(t`Inventory`)}
label={t`Inventory`}
value={
<Link to={`/inventories/${summary_fields.inventory?.id}/details`}>
{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 && (
<Detail
label={i18n._(t`Project`)}
label={t`Project`}
value={
<Link to={`/projects/${summary_fields.source_project?.id}/details`}>
{summary_fields.source_project?.name}
@ -98,16 +96,16 @@ function PromptInventorySourceDetail({ i18n, resource }) {
virtualEnvironment={custom_virtualenv}
executionEnvironment={summary_fields?.execution_environment}
/>
<Detail label={i18n._(t`Inventory File`)} value={source_path} />
<Detail label={i18n._(t`Verbosity`)} value={VERBOSITY[verbosity]} />
<Detail label={t`Inventory File`} value={source_path} />
<Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
<Detail
label={i18n._(t`Cache Timeout`)}
value={`${update_cache_timeout} ${i18n._(t`Seconds`)}`}
label={t`Cache Timeout`}
value={`${update_cache_timeout} ${t`Seconds`}`}
/>
{summary_fields?.credentials?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Credential`)}
label={t`Credential`}
value={summary_fields.credentials.map(cred => (
<CredentialChip key={cred?.id} credential={cred} isReadOnly />
))}
@ -116,7 +114,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{source_regions && (
<Detail
fullWidth
label={i18n._(t`Regions`)}
label={t`Regions`}
value={
<ChipGroup
numChips={5}
@ -134,7 +132,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{instance_filters && (
<Detail
fullWidth
label={i18n._(t`Instance Filters`)}
label={t`Instance Filters`}
value={
<ChipGroup
numChips={5}
@ -152,7 +150,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
{group_by && (
<Detail
fullWidth
label={i18n._(t`Only Group By`)}
label={t`Only Group By`}
value={
<ChipGroup numChips={5} totalChips={group_by.split(',').length}>
{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 && (
<VariablesDetail
label={i18n._(t`Source Variables`)}
label={t`Source Variables`}
rows={4}
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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Link } from 'react-router-dom';
@ -12,7 +12,7 @@ import { VariablesDetail } from '../CodeEditor';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
import { toTitleCase } from '../../util/strings';
function PromptJobTemplateDetail({ i18n, resource }) {
function PromptJobTemplateDetail({ resource }) {
const {
allow_simultaneous,
ask_inventory_on_launch,
@ -39,11 +39,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
} = resource;
const VERBOSITY = {
0: i18n._(t`0 (Normal)`),
1: i18n._(t`1 (Verbose)`),
2: i18n._(t`2 (More Verbose)`),
3: i18n._(t`3 (Debug)`),
4: i18n._(t`4 (Connection Debug)`),
0: t`0 (Normal)`,
1: t`1 (Verbose)`,
2: t`2 (More Verbose)`,
3: t`3 (Debug)`,
4: t`4 (Connection Debug)`,
};
let optionsList = '';
@ -56,15 +56,13 @@ function PromptJobTemplateDetail({ i18n, resource }) {
optionsList = (
<List>
{become_enabled && (
<ListItem>{i18n._(t`Enable Privilege Escalation`)}</ListItem>
<ListItem>{t`Enable Privilege Escalation`}</ListItem>
)}
{host_config_key && (
<ListItem>{i18n._(t`Allow Provisioning Callbacks`)}</ListItem>
<ListItem>{t`Allow Provisioning Callbacks`}</ListItem>
)}
{allow_simultaneous && (
<ListItem>{i18n._(t`Enable Concurrent Jobs`)}</ListItem>
)}
{use_fact_cache && <ListItem>{i18n._(t`Use Fact Storage`)}</ListItem>}
{allow_simultaneous && <ListItem>{t`Enable Concurrent Jobs`}</ListItem>}
{use_fact_cache && <ListItem>{t`Use Fact Storage`}</ListItem>}
</List>
);
}
@ -82,15 +80,12 @@ function PromptJobTemplateDetail({ i18n, resource }) {
return (
<>
{summary_fields.recent_jobs?.length > 0 && (
<Detail
value={<Sparkline jobs={recentJobs} />}
label={i18n._(t`Activity`)}
/>
<Detail value={<Sparkline jobs={recentJobs} />} label={t`Activity`} />
)}
<Detail label={i18n._(t`Job Type`)} value={toTitleCase(job_type)} />
<Detail label={t`Job Type`} value={toTitleCase(job_type)} />
{summary_fields?.organization ? (
<Detail
label={i18n._(t`Organization`)}
label={t`Organization`}
value={
<Link
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 ? (
<Detail
label={i18n._(t`Inventory`)}
label={t`Inventory`}
value={
<Link
to={`/${inventoryKind}/${summary_fields.inventory?.id}/details`}
@ -114,13 +109,11 @@ function PromptJobTemplateDetail({ i18n, resource }) {
}
/>
) : (
!ask_inventory_on_launch && (
<DeletedDetail label={i18n._(t`Inventory`)} />
)
!ask_inventory_on_launch && <DeletedDetail label={t`Inventory`} />
)}
{summary_fields?.project ? (
<Detail
label={i18n._(t`Project`)}
label={t`Project`}
value={
<Link to={`/projects/${summary_fields.project?.id}/details`}>
{summary_fields.project?.name}
@ -128,46 +121,40 @@ function PromptJobTemplateDetail({ i18n, resource }) {
}
/>
) : (
<DeletedDetail label={i18n._(t`Project`)} />
<DeletedDetail label={t`Project`} />
)}
<ExecutionEnvironmentDetail
virtualEnvironment={custom_virtualenv}
executionEnvironment={summary_fields?.execution_environment}
/>
<Detail label={i18n._(t`Source Control Branch`)} value={scm_branch} />
<Detail label={i18n._(t`Playbook`)} value={playbook} />
<Detail label={i18n._(t`Forks`)} value={forks || '0'} />
<Detail label={i18n._(t`Limit`)} value={limit} />
<Detail label={i18n._(t`Verbosity`)} value={VERBOSITY[verbosity]} />
<Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={t`Playbook`} value={playbook} />
<Detail label={t`Forks`} value={forks || '0'} />
<Detail label={t`Limit`} value={limit} />
<Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
{typeof diff_mode === 'boolean' && (
<Detail
label={i18n._(t`Show Changes`)}
value={diff_mode ? i18n._(t`On`) : i18n._(t`Off`)}
/>
<Detail label={t`Show Changes`} value={diff_mode ? t`On` : t`Off`} />
)}
<Detail label={i18n._(t` Job Slicing`)} value={job_slice_count} />
<Detail label={i18n._(t`Host Config Key`)} value={host_config_key} />
<Detail label={t` Job Slicing`} value={job_slice_count} />
<Detail label={t`Host Config Key`} value={host_config_key} />
{related?.callback && (
<Detail
label={i18n._(t`Provisioning Callback URL`)}
label={t`Provisioning Callback URL`}
value={`${window.location.origin}${related.callback}`}
/>
)}
<Detail
label={i18n._(t`Webhook Service`)}
value={toTitleCase(webhook_service)}
/>
<Detail label={t`Webhook Service`} value={toTitleCase(webhook_service)} />
{related?.webhook_receiver && (
<Detail
label={i18n._(t`Webhook URL`)}
label={t`Webhook URL`}
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 && (
<Detail
fullWidth
label={i18n._(t`Webhook Credential`)}
label={t`Webhook Credential`}
value={
<CredentialChip
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 && (
<Detail
fullWidth
label={i18n._(t`Credentials`)}
label={t`Credentials`}
value={
<ChipGroup
numChips={5}
@ -197,7 +184,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{summary_fields?.labels?.results?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Labels`)}
label={t`Labels`}
value={
<ChipGroup
numChips={5}
@ -215,7 +202,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{instance_groups?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Instance Groups`)}
label={t`Instance Groups`}
value={
<ChipGroup numChips={5} totalChips={instance_groups.length}>
{instance_groups.map(ig => (
@ -230,7 +217,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{job_tags?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Job Tags`)}
label={t`Job Tags`}
value={
<ChipGroup numChips={5} totalChips={job_tags.split(',').length}>
{job_tags.split(',').map(jobTag => (
@ -245,7 +232,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
{skip_tags?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Skip Tags`)}
label={t`Skip Tags`}
value={
<ChipGroup numChips={5} totalChips={skip_tags.split(',').length}>
{skip_tags.split(',').map(skipTag => (
@ -258,14 +245,10 @@ function PromptJobTemplateDetail({ i18n, resource }) {
/>
)}
{extra_vars && (
<VariablesDetail
label={i18n._(t`Variables`)}
rows={4}
value={extra_vars}
/>
<VariablesDetail label={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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { List, ListItem } from '@patternfly/react-core';
import { Link } from 'react-router-dom';
@ -10,7 +10,7 @@ import CredentialChip from '../CredentialChip';
import { toTitleCase } from '../../util/strings';
import ExecutionEnvironmentDetail from '../ExecutionEnvironmentDetail';
function PromptProjectDetail({ i18n, resource }) {
function PromptProjectDetail({ resource }) {
const {
allow_override,
custom_virtualenv,
@ -37,21 +37,15 @@ function PromptProjectDetail({ i18n, resource }) {
) {
optionsList = (
<List>
{scm_clean && <ListItem>{i18n._(t`Clean`)}</ListItem>}
{scm_delete_on_update && (
<ListItem>{i18n._(t`Delete on Update`)}</ListItem>
)}
{scm_clean && <ListItem>{t`Clean`}</ListItem>}
{scm_delete_on_update && <ListItem>{t`Delete on Update`}</ListItem>}
{scm_track_submodules && (
<ListItem>
{i18n._(t`Track submodules latest commit on branch`)}
</ListItem>
<ListItem>{t`Track submodules latest commit on branch`}</ListItem>
)}
{scm_update_on_launch && (
<ListItem>{i18n._(t`Update Revision on Launch`)}</ListItem>
)}
{allow_override && (
<ListItem>{i18n._(t`Allow Branch Override`)}</ListItem>
<ListItem>{t`Update Revision on Launch`}</ListItem>
)}
{allow_override && <ListItem>{t`Allow Branch Override`}</ListItem>}
</List>
);
}
@ -60,7 +54,7 @@ function PromptProjectDetail({ i18n, resource }) {
<>
{summary_fields?.organization ? (
<Detail
label={i18n._(t`Organization`)}
label={t`Organization`}
value={
<Link
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
virtualEnvironment={custom_virtualenv}
@ -78,15 +72,15 @@ function PromptProjectDetail({ i18n, resource }) {
isDefaultEnvironment
/>
<Detail
label={i18n._(t`Source Control Type`)}
value={scm_type === '' ? i18n._(t`Manual`) : toTitleCase(scm_type)}
label={t`Source Control Type`}
value={scm_type === '' ? t`Manual` : toTitleCase(scm_type)}
/>
<Detail label={i18n._(t`Source Control URL`)} value={scm_url} />
<Detail label={i18n._(t`Source Control Branch`)} value={scm_branch} />
<Detail label={i18n._(t`Source Control Refspec`)} value={scm_refspec} />
<Detail label={t`Source Control URL`} value={scm_url} />
<Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={t`Source Control Refspec`} value={scm_refspec} />
{summary_fields?.credential?.id && (
<Detail
label={i18n._(t`Source Control Credential`)}
label={t`Source Control Credential`}
value={
<CredentialChip
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
label={i18n._(t`Cache Timeout`)}
value={`${scm_update_cache_timeout} ${i18n._(t`Seconds`)}`}
label={t`Cache Timeout`}
value={`${scm_update_cache_timeout} ${t`Seconds`}`}
/>
<Config>
{({ project_base_dir }) => (
<Detail
label={i18n._(t`Project Base Path`)}
value={project_base_dir}
/>
<Detail label={t`Project Base Path`} value={project_base_dir} />
)}
</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 { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Link } from 'react-router-dom';
@ -11,7 +11,7 @@ import { VariablesDetail } from '../CodeEditor';
import Sparkline from '../Sparkline';
import { toTitleCase } from '../../util/strings';
function PromptWFJobTemplateDetail({ i18n, resource }) {
function PromptWFJobTemplateDetail({ resource }) {
const {
allow_simultaneous,
extra_vars,
@ -27,10 +27,8 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
if (allow_simultaneous || webhook_service) {
optionsList = (
<List>
{allow_simultaneous && (
<ListItem>{i18n._(t`Enable Concurrent Jobs`)}</ListItem>
)}
{webhook_service && <ListItem>{i18n._(t`Enable Webhooks`)}</ListItem>}
{allow_simultaneous && <ListItem>{t`Enable Concurrent Jobs`}</ListItem>}
{webhook_service && <ListItem>{t`Enable Webhooks`}</ListItem>}
</List>
);
}
@ -48,14 +46,11 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
return (
<>
{summary_fields?.recent_jobs?.length > 0 && (
<Detail
value={<Sparkline jobs={recentJobs} />}
label={i18n._(t`Activity`)}
/>
<Detail value={<Sparkline jobs={recentJobs} />} label={t`Activity`} />
)}
{summary_fields?.organization && (
<Detail
label={i18n._(t`Organization`)}
label={t`Organization`}
value={
<Link
to={`/organizations/${summary_fields.organization.id}/details`}
@ -67,7 +62,7 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
)}
{summary_fields?.inventory && (
<Detail
label={i18n._(t`Inventory`)}
label={t`Inventory`}
value={
<Link
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={i18n._(t`Limit`)} value={limit} />
<Detail
label={i18n._(t`Webhook Service`)}
value={toTitleCase(webhook_service)}
/>
<Detail label={i18n._(t`Webhook Key`)} value={webhook_key} />
<Detail label={t`Source Control Branch`} value={scm_branch} />
<Detail label={t`Limit`} value={limit} />
<Detail label={t`Webhook Service`} value={toTitleCase(webhook_service)} />
<Detail label={t`Webhook Key`} value={webhook_key} />
{related?.webhook_receiver && (
<Detail
label={i18n._(t`Webhook URL`)}
label={t`Webhook URL`}
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 && (
<Detail
fullWidth
label={i18n._(t`Webhook Credential`)}
label={t`Webhook Credential`}
value={
<CredentialChip
key={summary_fields.webhook_credential?.id}
@ -107,7 +99,7 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
{summary_fields?.labels?.results?.length > 0 && (
<Detail
fullWidth
label={i18n._(t`Labels`)}
label={t`Labels`}
value={
<ChipGroup
numChips={5}
@ -123,14 +115,10 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
/>
)}
{extra_vars && (
<VariablesDetail
label={i18n._(t`Variables`)}
rows={4}
value={extra_vars}
/>
<VariablesDetail label={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 { func, string } from 'prop-types';
import { Button } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import AlertModal from '../AlertModal';
import { Role } from '../../types';
function DeleteRoleConfirmationModal({
role,
username,
onCancel,
onConfirm,
i18n,
}) {
function DeleteRoleConfirmationModal({ role, username, onCancel, onConfirm }) {
const isTeamRole = () => {
return typeof role.team_id !== 'undefined'
? i18n._(t`Team`)
: i18n._(t`User`);
return typeof role.team_id !== 'undefined' ? t`Team` : t`User`;
};
const title = i18n._(t`Remove ${isTeamRole()} Access`);
const title = t`Remove ${isTeamRole()} Access`;
return (
<AlertModal
variant="danger"
@ -32,10 +24,10 @@ function DeleteRoleConfirmationModal({
ouiaId="delete-role-modal-delete-button"
key="delete"
variant="danger"
aria-label={i18n._(t`Confirm delete`)}
aria-label={t`Confirm delete`}
onClick={onConfirm}
>
{i18n._(t`Delete`)}
{t`Delete`}
</Button>,
<Button
ouiaId="delete-role-modal-cancel-button"
@ -43,26 +35,20 @@ function DeleteRoleConfirmationModal({
variant="link"
onClick={onCancel}
>
{i18n._(t`Cancel`)}
{t`Cancel`}
</Button>,
]}
>
{isTeamRole() ? (
<Fragment>
{i18n._(
t`Are you sure you want to remove ${role.name} access from ${role.team_name}? Doing so affects all members of the team.`
)}
{t`Are you sure you want to remove ${role.name} access from ${role.team_name}? Doing so affects all members of the team.`}
<br />
<br />
{i18n._(
t`If you 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>
{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>
)}
</AlertModal>
@ -80,4 +66,4 @@ DeleteRoleConfirmationModal.defaultProps = {
username: '',
};
export default withI18n()(DeleteRoleConfirmationModal);
export default DeleteRoleConfirmationModal;

View File

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

View File

@ -1,7 +1,7 @@
import 'styled-components/macro';
import React from 'react';
import { func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Chip,
@ -24,7 +24,7 @@ const DataListItemCells = styled(PFDataListItemCells)`
align-items: start;
`;
function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
function ResourceAccessListItem({ accessRecord, onRoleDelete }) {
ResourceAccessListItem.propTypes = {
accessRecord: AccessRecord.isRequired,
onRoleDelete: func.isRequired,
@ -57,7 +57,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
}}
isReadOnly={!role.user_capabilities.unattach}
ouiaId={`${role.name}-${role.id}`}
closeBtnAriaLabel={i18n._(t`Remove ${role.name} chip`)}
closeBtnAriaLabel={t`Remove ${role.name} chip`}
>
{role.name}
</Chip>
@ -97,7 +97,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
{accessRecord.first_name || accessRecord.last_name ? (
<DetailList stacked>
<Detail
label={i18n._(t`Name`)}
label={t`Name`}
value={`${accessRecord.first_name} ${accessRecord.last_name}`}
/>
</DetailList>
@ -107,7 +107,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
<DetailList stacked>
{userRoles.length > 0 && (
<Detail
label={i18n._(t`User Roles`)}
label={t`User Roles`}
value={
<ChipGroup numChips={5} totalChips={userRoles.length}>
{userRoles.map(renderChip)}
@ -117,7 +117,7 @@ function ResourceAccessListItem({ accessRecord, onRoleDelete, i18n }) {
)}
{teamRoles.length > 0 && (
<Detail
label={i18n._(t`Team Roles`)}
label={t`Team Roles`}
value={
<ChipGroup numChips={5} totalChips={teamRoles.length}>
{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 { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import {
Switch,
@ -20,7 +19,6 @@ import { SchedulesAPI } from '../../api';
import useRequest from '../../util/useRequest';
function Schedule({
i18n,
setBreadcrumb,
resource,
launchConfig,
@ -58,14 +56,14 @@ function Schedule({
name: (
<>
<CaretLeftIcon />
{i18n._(t`Back to Schedules`)}
{t`Back to Schedules`}
</>
),
link: `${pathRoot}schedules`,
id: 99,
},
{
name: i18n._(t`Details`),
name: t`Details`,
link: `${pathRoot}schedules/${schedule && schedule.id}/details`,
id: 0,
},
@ -82,7 +80,7 @@ function Schedule({
return (
<ContentError>
{schedule && (
<Link to={`${pathRoot}schedules`}>{i18n._(t`View Schedules`)}</Link>
<Link to={`${pathRoot}schedules`}>{t`View Schedules`}</Link>
)}
</ContentError>
);
@ -132,7 +130,7 @@ function Schedule({
<Route key="not-found" path="*">
<ContentError>
{resource && (
<Link to={`${pathRoot}details`}>{i18n._(t`View Details`)}</Link>
<Link to={`${pathRoot}details`}>{t`View Details`}</Link>
)}
</ContentError>
</Route>
@ -142,4 +140,4 @@ function Schedule({
}
export { Schedule as _Schedule };
export default withI18n()(Schedule);
export default Schedule;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import 'styled-components/macro';
import React, { Fragment, useState, useEffect, useCallback } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Switch, Tooltip } from '@patternfly/react-core';
import AlertModal from '../../AlertModal';
@ -8,7 +8,7 @@ import ErrorDetail from '../../ErrorDetail';
import useRequest from '../../../util/useRequest';
import { SchedulesAPI } from '../../../api';
function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
function ScheduleToggle({ schedule, onToggle, className, isDisabled }) {
const [isEnabled, setIsEnabled] = useState(schedule.enabled);
const [showError, setShowError] = useState(false);
@ -41,9 +41,7 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
<Fragment>
<Tooltip
content={
schedule.enabled
? i18n._(t`Schedule is active`)
: i18n._(t`Schedule is inactive`)
schedule.enabled ? t`Schedule is active` : t`Schedule is inactive`
}
position="top"
>
@ -51,8 +49,8 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
className={className}
css="display: inline-flex;"
id={`schedule-${schedule.id}-toggle`}
label={i18n._(t`On`)}
labelOff={i18n._(t`Off`)}
label={t`On`}
labelOff={t`Off`}
isChecked={isEnabled}
isDisabled={
isLoading ||
@ -60,17 +58,17 @@ function ScheduleToggle({ schedule, onToggle, className, i18n, isDisabled }) {
isDisabled
}
onChange={toggleSchedule}
aria-label={i18n._(t`Toggle schedule`)}
aria-label={t`Toggle schedule`}
/>
</Tooltip>
{showError && error && !isLoading && (
<AlertModal
variant="error"
title={i18n._(t`Error!`)}
title={t`Error!`}
isOpen={error && !isLoading}
onClose={() => setShowError(false)}
>
{i18n._(t`Failed to toggle schedule.`)}
{t`Failed to toggle schedule.`}
<ErrorDetail error={error} />
</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 { withI18n } from '@lingui/react';
import { Switch, Route, useRouteMatch } from 'react-router-dom';
import Schedule from './Schedule';
import ScheduleAdd from './ScheduleAdd';
@ -60,4 +60,4 @@ function 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 styled from 'styled-components';
import { useField } from 'formik';
import { withI18n } from '@lingui/react';
import { t, Trans, Plural } from '@lingui/macro';
import { RRule } from 'rrule';
import {
@ -41,24 +41,24 @@ const Checkbox = styled(_Checkbox)`
}
`;
export function requiredPositiveInteger(i18n) {
export function requiredPositiveInteger() {
return value => {
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
return i18n._(t`This field must be an integer`);
return t`This field must be an integer`;
}
if (value < 1) {
return i18n._(t`This field must be greater than 0`);
return t`This field must be greater than 0`;
}
}
if (!value) {
return i18n._(t`Select a value for this field`);
return t`Select a value for this field`;
}
return undefined;
};
}
const FrequencyDetailSubform = ({ i18n }) => {
const FrequencyDetailSubform = () => {
const [runOnDayMonth] = useField({
name: 'runOnDayMonth',
});
@ -79,92 +79,92 @@ const FrequencyDetailSubform = ({ i18n }) => {
});
const [daysOfWeek, daysOfWeekMeta, daysOfWeekHelpers] = useField({
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({
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({
name: 'interval',
validate: requiredPositiveInteger(i18n),
validate: requiredPositiveInteger(),
});
const [runOn, runOnMeta] = useField({
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({
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({
name: 'frequency',
});
useField({
name: 'occurrences',
validate: requiredPositiveInteger(i18n),
validate: requiredPositiveInteger(),
});
const monthOptions = [
{
key: 'january',
value: 1,
label: i18n._(t`January`),
label: t`January`,
},
{
key: 'february',
value: 2,
label: i18n._(t`February`),
label: t`February`,
},
{
key: 'march',
value: 3,
label: i18n._(t`March`),
label: t`March`,
},
{
key: 'april',
value: 4,
label: i18n._(t`April`),
label: t`April`,
},
{
key: 'may',
value: 5,
label: i18n._(t`May`),
label: t`May`,
},
{
key: 'june',
value: 6,
label: i18n._(t`June`),
label: t`June`,
},
{
key: 'july',
value: 7,
label: i18n._(t`July`),
label: t`July`,
},
{
key: 'august',
value: 8,
label: i18n._(t`August`),
label: t`August`,
},
{
key: 'september',
value: 9,
label: i18n._(t`September`),
label: t`September`,
},
{
key: 'october',
value: 10,
label: i18n._(t`October`),
label: t`October`,
},
{
key: 'november',
value: 11,
label: i18n._(t`November`),
label: t`November`,
},
{
key: 'december',
value: 12,
label: i18n._(t`December`),
label: t`December`,
},
];
@ -197,7 +197,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
case 'year':
return <Plural value={intervalValue} one="year" other="years" />;
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={
!intervalMeta.touched || !intervalMeta.error ? 'default' : 'error'
}
label={i18n._(t`Run every`)}
label={t`Run every`}
>
<div css="display: flex">
<TextInput
@ -240,76 +240,76 @@ const FrequencyDetailSubform = ({ i18n }) => {
? 'default'
: 'error'
}
label={i18n._(t`On days`)}
label={t`On days`}
>
<div css="display: flex">
<Checkbox
label={i18n._(t`Sun`)}
label={t`Sun`}
isChecked={daysOfWeek.value.includes(RRule.SU)}
onChange={checked => {
updateDaysOfWeek(RRule.SU, checked);
}}
aria-label={i18n._(t`Sunday`)}
aria-label={t`Sunday`}
id="schedule-days-of-week-sun"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Mon`)}
label={t`Mon`}
isChecked={daysOfWeek.value.includes(RRule.MO)}
onChange={checked => {
updateDaysOfWeek(RRule.MO, checked);
}}
aria-label={i18n._(t`Monday`)}
aria-label={t`Monday`}
id="schedule-days-of-week-mon"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Tue`)}
label={t`Tue`}
isChecked={daysOfWeek.value.includes(RRule.TU)}
onChange={checked => {
updateDaysOfWeek(RRule.TU, checked);
}}
aria-label={i18n._(t`Tuesday`)}
aria-label={t`Tuesday`}
id="schedule-days-of-week-tue"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Wed`)}
label={t`Wed`}
isChecked={daysOfWeek.value.includes(RRule.WE)}
onChange={checked => {
updateDaysOfWeek(RRule.WE, checked);
}}
aria-label={i18n._(t`Wednesday`)}
aria-label={t`Wednesday`}
id="schedule-days-of-week-wed"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Thu`)}
label={t`Thu`}
isChecked={daysOfWeek.value.includes(RRule.TH)}
onChange={checked => {
updateDaysOfWeek(RRule.TH, checked);
}}
aria-label={i18n._(t`Thursday`)}
aria-label={t`Thursday`}
id="schedule-days-of-week-thu"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Fri`)}
label={t`Fri`}
isChecked={daysOfWeek.value.includes(RRule.FR)}
onChange={checked => {
updateDaysOfWeek(RRule.FR, checked);
}}
aria-label={i18n._(t`Friday`)}
aria-label={t`Friday`}
id="schedule-days-of-week-fri"
name="daysOfWeek"
/>
<Checkbox
label={i18n._(t`Sat`)}
label={t`Sat`}
isChecked={daysOfWeek.value.includes(RRule.SA)}
onChange={checked => {
updateDaysOfWeek(RRule.SA, checked);
}}
aria-label={i18n._(t`Saturday`)}
aria-label={t`Saturday`}
id="schedule-days-of-week-sat"
name="daysOfWeek"
/>
@ -326,7 +326,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
validated={
!runOnMeta.touched || !runOnMeta.error ? 'default' : 'error'
}
label={i18n._(t`Run on`)}
label={t`Run on`}
>
<RunOnRadio
id="schedule-run-on-day"
@ -386,20 +386,20 @@ const FrequencyDetailSubform = ({ i18n }) => {
id="schedule-run-on-the-occurrence"
isDisabled={runOn.value !== 'the'}
data={[
{ value: 1, key: 'first', label: i18n._(t`First`) },
{ value: 1, key: 'first', label: t`First` },
{
value: 2,
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,
key: 'fourth',
label: i18n._(t`Fourth`),
label: t`Fourth`,
},
{ value: 5, key: 'fifth', label: i18n._(t`Fifth`) },
{ value: -1, key: 'last', label: i18n._(t`Last`) },
{ value: 5, key: 'fifth', label: t`Fifth` },
{ value: -1, key: 'last', label: t`Last` },
]}
{...runOnTheOccurrence}
/>
@ -410,48 +410,48 @@ const FrequencyDetailSubform = ({ i18n }) => {
{
value: 'sunday',
key: 'sunday',
label: i18n._(t`Sunday`),
label: t`Sunday`,
},
{
value: 'monday',
key: 'monday',
label: i18n._(t`Monday`),
label: t`Monday`,
},
{
value: 'tuesday',
key: 'tuesday',
label: i18n._(t`Tuesday`),
label: t`Tuesday`,
},
{
value: 'wednesday',
key: 'wednesday',
label: i18n._(t`Wednesday`),
label: t`Wednesday`,
},
{
value: 'thursday',
key: 'thursday',
label: i18n._(t`Thursday`),
label: t`Thursday`,
},
{
value: 'friday',
key: 'friday',
label: i18n._(t`Friday`),
label: t`Friday`,
},
{
value: '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',
key: 'weekday',
label: i18n._(t`Weekday`),
label: t`Weekday`,
},
{
value: 'weekendDay',
key: 'weekendDay',
label: i18n._(t`Weekend day`),
label: t`Weekend day`,
},
]}
{...runOnTheDay}
@ -489,12 +489,12 @@ const FrequencyDetailSubform = ({ i18n }) => {
helperTextInvalid={endMeta.error}
isRequired
validated={!endMeta.touched || !endMeta.error ? 'default' : 'error'}
label={i18n._(t`End`)}
label={t`End`}
>
<Radio
id="end-never"
name="end"
label={i18n._(t`Never`)}
label={t`Never`}
value="never"
isChecked={end.value === 'never'}
onChange={(value, event) => {
@ -505,7 +505,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
<Radio
id="end-after"
name="end"
label={i18n._(t`After number of occurrences`)}
label={t`After number of occurrences`}
value="after"
isChecked={end.value === 'after'}
onChange={(value, event) => {
@ -516,7 +516,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
<Radio
id="end-on-date"
name="end"
label={i18n._(t`On date`)}
label={t`On date`}
value="onDate"
isChecked={end.value === 'onDate'}
onChange={(value, event) => {
@ -528,12 +528,12 @@ const FrequencyDetailSubform = ({ i18n }) => {
{end?.value === 'after' && (
<FormField
id="schedule-occurrences"
label={i18n._(t`Occurrences`)}
label={t`Occurrences`}
name="occurrences"
type="number"
min="1"
step="1"
validate={required(null, i18n)}
validate={required(null)}
isRequired
/>
)}
@ -547,7 +547,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
? 'default'
: 'error'
}
label={i18n._(t`End date/time`)}
label={t`End date/time`}
>
<input
className="pf-c-form-control"
@ -563,4 +563,4 @@ const FrequencyDetailSubform = ({ i18n }) => {
/* 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 { shape, func } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Formik, useField } from 'formik';
import { RRule } from 'rrule';
@ -78,36 +78,33 @@ const generateRunOnTheDay = (days = []) => {
return null;
};
function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
function ScheduleFormFields({ hasDaysToKeepField, zoneOptions }) {
const [startDateTime, startDateTimeMeta] = useField({
name: 'startDateTime',
validate: required(
i18n._(t`Select a valid date and time for this field`),
i18n
),
validate: required(t`Select a valid date and time for this field`),
});
const [timezone, timezoneMeta] = useField({
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({
name: 'frequency',
validate: required(i18n._(t`Select a value for this field`), i18n),
validate: required(t`Select a value for this field`),
});
return (
<>
<FormField
id="schedule-name"
label={i18n._(t`Name`)}
label={t`Name`}
name="name"
type="text"
validate={required(null, i18n)}
validate={required(null)}
isRequired
/>
<FormField
id="schedule-description"
label={i18n._(t`Description`)}
label={t`Description`}
name="description"
type="text"
/>
@ -120,7 +117,7 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
? 'default'
: 'error'
}
label={i18n._(t`Start date/time`)}
label={t`Start date/time`}
>
<input
className="pf-c-form-control"
@ -138,7 +135,7 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
validated={
!timezoneMeta.touched || !timezoneMeta.error ? 'default' : 'error'
}
label={i18n._(t`Local time zone`)}
label={t`Local time zone`}
>
<AnsibleSelect
id="schedule-timezone"
@ -154,18 +151,18 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
validated={
!frequencyMeta.touched || !frequencyMeta.error ? 'default' : 'error'
}
label={i18n._(t`Run frequency`)}
label={t`Run frequency`}
>
<AnsibleSelect
id="schedule-frequency"
data={[
{ value: 'none', key: 'none', label: i18n._(t`None (run once)`) },
{ value: 'minute', key: 'minute', label: i18n._(t`Minute`) },
{ value: 'hour', key: 'hour', label: i18n._(t`Hour`) },
{ value: 'day', key: 'day', label: i18n._(t`Day`) },
{ value: 'week', key: 'week', label: i18n._(t`Week`) },
{ value: 'month', key: 'month', label: i18n._(t`Month`) },
{ value: 'year', key: 'year', label: i18n._(t`Year`) },
{ value: 'none', key: 'none', label: t`None (run once)` },
{ value: 'minute', key: 'minute', label: t`Minute` },
{ value: 'hour', key: 'hour', label: t`Hour` },
{ value: 'day', key: 'day', label: t`Day` },
{ value: 'week', key: 'week', label: t`Week` },
{ value: 'month', key: 'month', label: t`Month` },
{ value: 'year', key: 'year', label: t`Year` },
]}
{...frequency}
/>
@ -173,17 +170,17 @@ function ScheduleFormFields({ i18n, hasDaysToKeepField, zoneOptions }) {
{hasDaysToKeepField ? (
<FormField
id="schedule-days-to-keep"
label={i18n._(t`Days of Data to Keep`)}
label={t`Days of Data to Keep`}
name="daysToKeep"
type="number"
validate={required(null, i18n)}
validate={required(null)}
isRequired
/>
) : null}
{frequency.value !== 'none' && (
<SubFormLayout>
<Title size="md" headingLevel="h4">
{i18n._(t`Frequency Details`)}
{t`Frequency Details`}
</Title>
<FormColumnLayout>
<FrequencyDetailSubform />
@ -198,7 +195,7 @@ function ScheduleForm({
hasDaysToKeepField,
handleCancel,
handleSubmit,
i18n,
schedule,
submitError,
resource,
@ -531,7 +528,7 @@ function ScheduleForm({
rruleError = error;
}
} 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' &&
new Date(startDateTime) > new Date(endDateTime)
) {
errors.endDateTime = i18n._(
t`Please select an end date/time that comes after the start date/time.`
);
errors.endDateTime = t`Please select an end date/time that comes after the start date/time.`;
}
if (
@ -577,9 +572,7 @@ function ScheduleForm({
runOn === 'day' &&
(runOnDayNumber < 1 || runOnDayNumber > 31)
) {
errors.runOn = i18n._(
t`Please select a day number between 1 and 31.`
);
errors.runOn = t`Please select a day number between 1 and 31.`;
}
return errors;
@ -590,7 +583,6 @@ function ScheduleForm({
<FormColumnLayout>
<ScheduleFormFields
hasDaysToKeepField={hasDaysToKeepField}
i18n={i18n}
zoneOptions={zoneOptions}
{...rest}
/>
@ -616,13 +608,13 @@ function ScheduleForm({
<ActionGroup>
<Button
ouiaId="schedule-form-save-button"
aria-label={i18n._(t`Save`)}
aria-label={t`Save`}
variant="primary"
type="button"
onClick={formik.handleSubmit}
isDisabled={isSaveDisabled}
>
{i18n._(t`Save`)}
{t`Save`}
</Button>
{isTemplate && showPromptButton && (
@ -630,20 +622,20 @@ function ScheduleForm({
ouiaId="schedule-form-prompt-button"
variant="secondary"
type="button"
aria-label={i18n._(t`Prompt`)}
aria-label={t`Prompt`}
onClick={() => setIsWizardOpen(true)}
>
{i18n._(t`Prompt`)}
{t`Prompt`}
</Button>
)}
<Button
ouiaId="schedule-form-cancel-button"
aria-label={i18n._(t`Cancel`)}
aria-label={t`Cancel`}
variant="secondary"
type="button"
onClick={handleCancel}
>
{i18n._(t`Cancel`)}
{t`Cancel`}
</Button>
</ActionGroup>
</FormFullWidthLayout>
@ -669,4 +661,4 @@ ScheduleForm.defaultProps = {
submitError: null,
};
export default withI18n()(ScheduleForm);
export default ScheduleForm;

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useFormikContext } from 'formik';
import AlertModal from '../../AlertModal';
@ -18,7 +18,6 @@ function SchedulePromptableFields({
credentials,
resource,
resourceDefaultCredentials,
i18n,
}) {
const {
setFieldTouched,
@ -38,7 +37,7 @@ function SchedulePromptableFields({
launchConfig,
schedule,
resource,
i18n,
credentials,
resourceDefaultCredentials
);
@ -74,7 +73,7 @@ function SchedulePromptableFields({
<AlertModal
isOpen={error}
variant="error"
title={i18n._(t`Error!`)}
title={t`Error!`}
onClose={() => {
dismissError();
onCloseWizard();
@ -108,22 +107,22 @@ function SchedulePromptableFields({
validateStep(nextStep.id);
}
}}
title={i18n._(t`Prompts`)}
title={t`Prompts`}
steps={
isReady
? steps
: [
{
name: i18n._(t`Content Loading`),
name: t`Content Loading`,
component: <ContentLoading />,
},
]
}
backButtonText={i18n._(t`Back`)}
cancelButtonText={i18n._(t`Cancel`)}
nextButtonText={i18n._(t`Next`)}
backButtonText={t`Back`}
cancelButtonText={t`Cancel`}
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 { getRRuleDayConstants } from '../../../util/dates';
export default function buildRuleObj(values, i18n) {
export default function buildRuleObj(values) {
const [startDate, startTime] = values.startDateTime.split('T');
// Dates are formatted like "YYYY-MM-DD"
const [startYear, startMonth, startDay] = startDate.split('-');
@ -51,7 +51,7 @@ export default function buildRuleObj(values, i18n) {
ruleObj.bymonthday = values.runOnDayNumber;
} else if (values.runOn === 'the') {
ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay, i18n);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay);
}
break;
case 'year':
@ -61,12 +61,12 @@ export default function buildRuleObj(values, i18n) {
ruleObj.bymonthday = values.runOnDayNumber;
} else if (values.runOn === 'the') {
ruleObj.bysetpos = parseInt(values.runOnTheOccurrence, 10);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay, i18n);
ruleObj.byweekday = getRRuleDayConstants(values.runOnTheDay);
ruleObj.bymonth = parseInt(values.runOnTheMonth, 10);
}
break;
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') {
@ -93,7 +93,7 @@ export default function buildRuleObj(values, i18n) {
break;
}
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,
schedule,
resource,
i18n,
scheduleCredentials,
resourceDefaultCredentials
) {
@ -22,15 +22,14 @@ export default function useSchedulePromptSteps(
const [visited, setVisited] = useState({});
const steps = [
useInventoryStep(launchConfig, sourceOfValues, i18n, visited),
useInventoryStep(launchConfig, sourceOfValues, visited),
useCredentialsStep(
launchConfig,
sourceOfValues,
resourceDefaultCredentials,
i18n
resourceDefaultCredentials
),
useOtherPromptsStep(launchConfig, sourceOfValues, i18n),
useSurveyStep(launchConfig, surveyConfig, sourceOfValues, i18n, visited),
useOtherPromptsStep(launchConfig, sourceOfValues),
useSurveyStep(launchConfig, surveyConfig, sourceOfValues, visited),
];
const hasErrors = steps.some(step => step.hasError);
@ -38,12 +37,12 @@ export default function useSchedulePromptSteps(
steps.push(
usePreviewStep(
launchConfig,
i18n,
resource,
surveyConfig,
hasErrors,
true,
i18n._(t`Save`)
t`Save`
)
);

View File

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