mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 09:27:36 -02:30
adds translation linting and addresses issues the linter found
This commit is contained in:
@@ -8,8 +8,8 @@
|
|||||||
"modules": true
|
"modules": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": ["react-hooks", "jsx-a11y"],
|
"plugins": ["react-hooks", "jsx-a11y", "i18next"],
|
||||||
"extends": ["airbnb", "prettier", "prettier/react", "plugin:jsx-a11y/strict"],
|
"extends": ["airbnb", "prettier", "prettier/react", "plugin:jsx-a11y/strict", "plugin:i18next/recommended"],
|
||||||
"settings": {
|
"settings": {
|
||||||
"react": {
|
"react": {
|
||||||
"version": "16.5.2"
|
"version": "16.5.2"
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
"window": true
|
"window": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"i18next/no-literal-string": [2, {"markupOnly": true, "ignoreAttribute": ["to", "streamType", "path", "component", "variant", "key", "position", "promptName", "color","promptId", "headingLevel", "size", "target", "autoComplete","trigger", "from", "name", "fieldId", "css", "gutter", "dataCy", "tooltipMaxWidth", "mode", "aria-labelledby","aria-hidden","sortKey", "ouiaId", "credentialTypeNamespace", "link", "value", "credentialTypeKind", "linkTo", "scrollToAlignment", "displayKey", "sortedColumnKey", "maxHeight", "role", "aria-haspopup", "dropDirection", "resizeOrientation", "src", "theme"], "ignore":["Ansible", "Tower", "JSON", "YAML", "lg", "START"],"ignoreComponent":["code", "Omit","PotentialLink", "TypeRedirect", "Radio", "RunOnRadio", "NodeTypeLetter", "SelectableItem", "Dash"], "ignoreCallee": ["describe"] }],
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
"arrow-parens": "off",
|
"arrow-parens": "off",
|
||||||
"comma-dangle": "off",
|
"comma-dangle": "off",
|
||||||
|
|||||||
15
awx/ui_next/package-lock.json
generated
15
awx/ui_next/package-lock.json
generated
@@ -7172,6 +7172,15 @@
|
|||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint-plugin-i18next": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-i18next/-/eslint-plugin-i18next-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-ixbgSMrSb0dZsO6WPElg4JvPiQKLDA3ZpBuayxToADan1TKcbzKXT2A42Vyc0lEDhJRPL6uZnmm8vPjODDJypg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"requireindex": "~1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"eslint-plugin-import": {
|
"eslint-plugin-import": {
|
||||||
"version": "2.22.1",
|
"version": "2.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz",
|
||||||
@@ -15163,6 +15172,12 @@
|
|||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"requireindex": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"requires-port": {
|
"requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
"eslint-config-airbnb": "^17.1.0",
|
"eslint-config-airbnb": "^17.1.0",
|
||||||
"eslint-config-prettier": "^5.0.0",
|
"eslint-config-prettier": "^5.0.0",
|
||||||
"eslint-import-resolver-webpack": "0.11.1",
|
"eslint-import-resolver-webpack": "0.11.1",
|
||||||
|
"eslint-plugin-i18next": "^5.0.0",
|
||||||
"eslint-plugin-import": "^2.14.0",
|
"eslint-plugin-import": "^2.14.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||||
"eslint-plugin-react": "^7.11.1",
|
"eslint-plugin-react": "^7.11.1",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'styled-components/macro';
|
import 'styled-components/macro';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types';
|
import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types';
|
||||||
|
import { Trans, withI18n } from '@lingui/react';
|
||||||
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
||||||
import { DetailName, DetailValue } from '../DetailList';
|
import { DetailName, DetailValue } from '../DetailList';
|
||||||
import MultiButtonToggle from '../MultiButtonToggle';
|
import MultiButtonToggle from '../MultiButtonToggle';
|
||||||
@@ -111,7 +112,7 @@ function VariablesDetail({ dataCy, helpText, value, label, rows, fullHeight }) {
|
|||||||
css="color: var(--pf-global--danger-color--100);
|
css="color: var(--pf-global--danger-color--100);
|
||||||
font-size: var(--pf-global--FontSize--sm"
|
font-size: var(--pf-global--FontSize--sm"
|
||||||
>
|
>
|
||||||
Error: {error.message}
|
<Trans>Error:</Trans> {error.message}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</DetailValue>
|
</DetailValue>
|
||||||
@@ -131,4 +132,4 @@ VariablesDetail.defaultProps = {
|
|||||||
helpText: '',
|
helpText: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VariablesDetail;
|
export default withI18n()(VariablesDetail);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||||
import VariablesDetail from './VariablesDetail';
|
import VariablesDetail from './VariablesDetail';
|
||||||
|
|
||||||
jest.mock('../../api');
|
jest.mock('../../api');
|
||||||
|
|
||||||
describe('<VariablesDetail>', () => {
|
describe('<VariablesDetail>', () => {
|
||||||
test('should render readonly CodeMirrorInput', () => {
|
test('should render readonly CodeMirrorInput', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = mountWithContexts(
|
||||||
<VariablesDetail value="---foo: bar" label="Variables" />
|
<VariablesDetail value="---foo: bar" label="Variables" />
|
||||||
);
|
);
|
||||||
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
||||||
@@ -18,7 +18,7 @@ describe('<VariablesDetail>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should detect JSON', () => {
|
test('should detect JSON', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = mountWithContexts(
|
||||||
<VariablesDetail value='{"foo": "bar"}' label="Variables" />
|
<VariablesDetail value='{"foo": "bar"}' label="Variables" />
|
||||||
);
|
);
|
||||||
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
||||||
@@ -28,7 +28,7 @@ describe('<VariablesDetail>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should convert between modes', () => {
|
test('should convert between modes', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = mountWithContexts(
|
||||||
<VariablesDetail value="---foo: bar" label="Variables" />
|
<VariablesDetail value="---foo: bar" label="Variables" />
|
||||||
);
|
);
|
||||||
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
|
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
|
||||||
@@ -43,7 +43,9 @@ describe('<VariablesDetail>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should render label and value= --- when there are no values', () => {
|
test('should render label and value= --- when there are no values', () => {
|
||||||
const wrapper = shallow(<VariablesDetail value="" label="Variables" />);
|
const wrapper = mountWithContexts(
|
||||||
|
<VariablesDetail value="" label="Variables" />
|
||||||
|
);
|
||||||
expect(wrapper.find('VariablesDetail___StyledCodeMirrorInput').length).toBe(
|
expect(wrapper.find('VariablesDetail___StyledCodeMirrorInput').length).toBe(
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
@@ -51,7 +53,7 @@ describe('<VariablesDetail>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should update value if prop changes', () => {
|
test('should update value if prop changes', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mountWithContexts(
|
||||||
<VariablesDetail value="---foo: bar" label="Variables" />
|
<VariablesDetail value="---foo: bar" label="Variables" />
|
||||||
);
|
);
|
||||||
act(() => {
|
act(() => {
|
||||||
@@ -67,13 +69,17 @@ describe('<VariablesDetail>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should default yaml value to "---"', () => {
|
test('should default yaml value to "---"', () => {
|
||||||
const wrapper = shallow(<VariablesDetail value="" label="Variables" />);
|
const wrapper = mountWithContexts(
|
||||||
|
<VariablesDetail value="" label="Variables" />
|
||||||
|
);
|
||||||
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
|
||||||
expect(input.prop('value')).toEqual('---');
|
expect(input.prop('value')).toEqual('---');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should default empty json to "{}"', () => {
|
test('should default empty json to "{}"', () => {
|
||||||
const wrapper = mount(<VariablesDetail value="" label="Variables" />);
|
const wrapper = mountWithContexts(
|
||||||
|
<VariablesDetail value="" label="Variables" />
|
||||||
|
);
|
||||||
act(() => {
|
act(() => {
|
||||||
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
|
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
|||||||
key="delete"
|
key="delete"
|
||||||
onDelete={handleJobDelete}
|
onDelete={handleJobDelete}
|
||||||
itemsToDelete={selected}
|
itemsToDelete={selected}
|
||||||
pluralizedItemName="Jobs"
|
pluralizedItemName={i18n._(t`Jobs`)}
|
||||||
/>,
|
/>,
|
||||||
<JobListCancelButton
|
<JobListCancelButton
|
||||||
key="cancel"
|
key="cancel"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { Button, Chip } from '@patternfly/react-core';
|
import { Button, Chip } from '@patternfly/react-core';
|
||||||
import { Tr, Td, ExpandableRowContent } from '@patternfly/react-table';
|
import { Tr, Td, ExpandableRowContent } from '@patternfly/react-table';
|
||||||
import { RocketIcon } from '@patternfly/react-icons';
|
import { RocketIcon } from '@patternfly/react-icons';
|
||||||
|
import styled from 'styled-components';
|
||||||
import { ActionsTd, ActionItem } from '../PaginatedTable';
|
import { ActionsTd, ActionItem } from '../PaginatedTable';
|
||||||
import LaunchButton from '../LaunchButton';
|
import LaunchButton from '../LaunchButton';
|
||||||
import StatusLabel from '../StatusLabel';
|
import StatusLabel from '../StatusLabel';
|
||||||
@@ -14,6 +15,7 @@ import CredentialChip from '../CredentialChip';
|
|||||||
import { formatDateString } from '../../util/dates';
|
import { formatDateString } from '../../util/dates';
|
||||||
import { JOB_TYPE_URL_SEGMENTS } from '../../constants';
|
import { JOB_TYPE_URL_SEGMENTS } from '../../constants';
|
||||||
|
|
||||||
|
const Dash = styled.span``;
|
||||||
function JobListItem({
|
function JobListItem({
|
||||||
i18n,
|
i18n,
|
||||||
job,
|
job,
|
||||||
@@ -58,7 +60,7 @@ function JobListItem({
|
|||||||
<span>
|
<span>
|
||||||
<Link to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}>
|
<Link to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}>
|
||||||
<b>
|
<b>
|
||||||
{job.id} — {job.name}
|
{job.id} <Dash>—</Dash> {job.name}
|
||||||
</b>
|
</b>
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ function Lookup(props) {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<InputGroup onBlur={onBlur}>
|
<InputGroup onBlur={onBlur}>
|
||||||
<Button
|
<Button
|
||||||
aria-label="Search"
|
aria-label={i18n._(t`Search`)}
|
||||||
id={id}
|
id={id}
|
||||||
onClick={() => dispatch({ type: 'TOGGLE_MODAL' })}
|
onClick={() => dispatch({ type: 'TOGGLE_MODAL' })}
|
||||||
variant={ButtonVariant.control}
|
variant={ButtonVariant.control}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ function NotificationListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={`items-list-item-${notification.id}`}
|
aria-labelledby={`items-list-item-${notification.id}`}
|
||||||
id={`items-list-item-${notification.id}`}
|
id={`items-list-item-${notification.id}`}
|
||||||
columns={showApprovalsToggle ? 4 : 3}
|
columns={showApprovalsToggle ? 4 : 3}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
|
|||||||
<>
|
<>
|
||||||
<Divider css="margin-top: var(--pf-global--spacer--lg)" />
|
<Divider css="margin-top: var(--pf-global--spacer--lg)" />
|
||||||
<PromptHeader>{i18n._(t`Prompted Values`)}</PromptHeader>
|
<PromptHeader>{i18n._(t`Prompted Values`)}</PromptHeader>
|
||||||
<DetailList aria-label="Prompt Overrides">
|
<DetailList aria-label={i18n._(t`Prompt Overrides`)}>
|
||||||
{launchConfig.ask_job_type_on_launch && (
|
{launchConfig.ask_job_type_on_launch && (
|
||||||
<Detail
|
<Detail
|
||||||
label={i18n._(t`Job Type`)}
|
label={i18n._(t`Job Type`)}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ function ScheduleListItem({ i18n, isSelected, onSelect, schedule }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
key="actions"
|
key="actions"
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function ApplicationListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ function CredentialListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ function CredentialTypeListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ function DashboardTemplateList({ i18n }) {
|
|||||||
key="delete"
|
key="delete"
|
||||||
onDelete={handleTemplateDelete}
|
onDelete={handleTemplateDelete}
|
||||||
itemsToDelete={selected}
|
itemsToDelete={selected}
|
||||||
pluralizedItemName="Templates"
|
pluralizedItemName={i18n._(t`Templates`)}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -111,7 +111,10 @@ function DashboardTemplateListItem({
|
|||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction aria-label="actions" aria-labelledby={labelId}>
|
<DataListAction
|
||||||
|
aria-label={i18n._(t`actions`)}
|
||||||
|
aria-labelledby={labelId}
|
||||||
|
>
|
||||||
{template.type === 'workflow_job_template' && (
|
{template.type === 'workflow_job_template' && (
|
||||||
<Tooltip content={i18n._(t`Visualizer`)} position="top">
|
<Tooltip content={i18n._(t`Visualizer`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function HostGroupItem({ i18n, group, inventoryId, isSelected, onSelect }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function HostListItem({ i18n, host, isSelected, onSelect, detailUrl }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ function InstanceGroupListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ function InstanceListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ function InventoryGroupHostListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function InventoryGroupItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function InventoryHostGroupItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function InventoryHostItem(props) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ function InventoryRelatedGroupListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ function InventorySourceListItem({
|
|||||||
<DataListAction
|
<DataListAction
|
||||||
id="actions"
|
id="actions"
|
||||||
aria-labelledby="actions"
|
aria-labelledby="actions"
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
>
|
>
|
||||||
{source.summary_fields.user_capabilities.start && (
|
{source.summary_fields.user_capabilities.start && (
|
||||||
<InventorySourceSyncButton source={source} />
|
<InventorySourceSyncButton source={source} />
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ function SmartInventoryDetail({ inventory, i18n }) {
|
|||||||
{user_capabilities?.edit && (
|
{user_capabilities?.edit && (
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
aria-label="edit"
|
aria-label={i18n._(t`edit`)}
|
||||||
to={`/inventories/smart_inventory/${id}/edit`}
|
to={`/inventories/smart_inventory/${id}/edit`}
|
||||||
>
|
>
|
||||||
{i18n._(t`Edit`)}
|
{i18n._(t`Edit`)}
|
||||||
|
|||||||
@@ -127,7 +127,10 @@ function NotificationTemplateListItem({
|
|||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction aria-label="actions" aria-labelledby={labelId}>
|
<DataListAction
|
||||||
|
aria-label={i18n._(t`actions`)}
|
||||||
|
aria-labelledby={labelId}
|
||||||
|
>
|
||||||
<Tooltip content={i18n._(t`Test Notification`)} position="top">
|
<Tooltip content={i18n._(t`Test Notification`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
aria-label={i18n._(t`Test Notification`)}
|
aria-label={i18n._(t`Test Notification`)}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'styled-components/macro';
|
import 'styled-components/macro';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { withI18n } from '@lingui/react';
|
import { Trans, withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { useField, useFormikContext } from 'formik';
|
import { useField, useFormikContext } from 'formik';
|
||||||
import { Switch, Text } from '@patternfly/react-core';
|
import { Switch, Text } from '@patternfly/react-core';
|
||||||
@@ -69,9 +69,11 @@ function CustomMessagesSubForm({ defaultMessages, type, i18n }) {
|
|||||||
css="margin-bottom: var(--pf-c-content--MarginBottom)"
|
css="margin-bottom: var(--pf-c-content--MarginBottom)"
|
||||||
>
|
>
|
||||||
<small>
|
<small>
|
||||||
Use custom messages to change the content of notifications sent
|
<Trans>
|
||||||
when a job starts, succeeds, or fails. Use curly braces to access
|
Use custom messages to change the content of notifications sent
|
||||||
information about the job:{' '}
|
when a job starts, succeeds, or fails. Use curly braces to
|
||||||
|
access information about the job:{' '}
|
||||||
|
</Trans>
|
||||||
<code>
|
<code>
|
||||||
{'{{'} job_friendly_name {'}}'}
|
{'{{'} job_friendly_name {'}}'}
|
||||||
</code>
|
</code>
|
||||||
@@ -79,12 +81,15 @@ function CustomMessagesSubForm({ defaultMessages, type, i18n }) {
|
|||||||
<code>
|
<code>
|
||||||
{'{{'} url {'}}'}
|
{'{{'} url {'}}'}
|
||||||
</code>
|
</code>
|
||||||
, or attributes of the job such as{' '}
|
, <Trans>or attributes of the job such as</Trans>{' '}
|
||||||
<code>
|
<code>
|
||||||
{'{{'} job.status {'}}'}
|
{'{{'} job.status {'}}'}
|
||||||
</code>
|
</code>
|
||||||
. You may apply a number of possible variables in the message.
|
.{' '}
|
||||||
Refer to the{' '}
|
<Trans>
|
||||||
|
You may apply a number of possible variables in the message.
|
||||||
|
Refer to the{' '}
|
||||||
|
</Trans>{' '}
|
||||||
<a
|
<a
|
||||||
href="https://docs.ansible.com/ansible-tower/latest/html/userguide/notifications.html#create-custom-notifications"
|
href="https://docs.ansible.com/ansible-tower/latest/html/userguide/notifications.html#create-custom-notifications"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -92,7 +97,7 @@ function CustomMessagesSubForm({ defaultMessages, type, i18n }) {
|
|||||||
>
|
>
|
||||||
Ansible Tower documentation
|
Ansible Tower documentation
|
||||||
</a>{' '}
|
</a>{' '}
|
||||||
for more details.
|
<Trans>for more details.</Trans>
|
||||||
</small>
|
</small>
|
||||||
</Text>
|
</Text>
|
||||||
<FormFullWidthLayout>
|
<FormFullWidthLayout>
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ function OrganizationsList({ i18n }) {
|
|||||||
key="delete"
|
key="delete"
|
||||||
onDelete={handleOrgDelete}
|
onDelete={handleOrgDelete}
|
||||||
itemsToDelete={selected}
|
itemsToDelete={selected}
|
||||||
pluralizedItemName="Organizations"
|
pluralizedItemName={i18n._(t`Organizations`)}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function OrganizationTeamListItem({ i18n, team, detailUrl }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ function ProjectJobTemplateListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ function ProjectListItem({
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -21,8 +21,16 @@ const ArchiveSubForm = ({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Example URLs for Remote Archive Source Control include:`)}
|
{i18n._(t`Example URLs for Remote Archive Source Control include:`)}
|
||||||
<ul css={{ margin: '10px 0 10px 20px' }}>
|
<ul css={{ margin: '10px 0 10px 20px' }}>
|
||||||
<li>https://github.com/username/project/archive/v0.0.1.tar.gz</li>
|
<li>
|
||||||
<li>https://github.com/username/project/archive/v0.0.2.zip</li>
|
<code>
|
||||||
|
https://github.com/username/project/archive/v0.0.1.tar.gz
|
||||||
|
</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>
|
||||||
|
https://github.com/username/project/archive/v0.0.2.zip
|
||||||
|
</code>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,15 @@ const GitSubForm = ({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Example URLs for GIT Source Control include:`)}
|
{i18n._(t`Example URLs for GIT Source Control include:`)}
|
||||||
<ul css="margin: 10px 0 10px 20px">
|
<ul css="margin: 10px 0 10px 20px">
|
||||||
<li>https://github.com/ansible/ansible.git</li>
|
<li>
|
||||||
<li>git@github.com:ansible/ansible.git</li>
|
<code>https://github.com/ansible/ansible.git</code>
|
||||||
<li>git://servername.example.com/ansible.git</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>git@github.com:ansible/ansible.git</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>git://servername.example.com/ansible.git</code>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{i18n._(t`Note: When using SSH protocol for GitHub or
|
{i18n._(t`Note: When using SSH protocol for GitHub or
|
||||||
Bitbucket, enter an SSH key only, do not enter a username
|
Bitbucket, enter an SSH key only, do not enter a username
|
||||||
@@ -58,8 +64,12 @@ const GitSubForm = ({
|
|||||||
<br />
|
<br />
|
||||||
{i18n._(t`Examples include:`)}
|
{i18n._(t`Examples include:`)}
|
||||||
<ul css={{ margin: '10px 0 10px 20px' }}>
|
<ul css={{ margin: '10px 0 10px 20px' }}>
|
||||||
<li>refs/*:refs/remotes/origin/*</li>
|
<li>
|
||||||
<li>refs/pull/62/head:refs/remotes/origin/pull/62/head</li>
|
<code>refs/*:refs/remotes/origin/*</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>refs/pull/62/head:refs/remotes/origin/pull/62/head</code>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{i18n._(t`The first fetches all references. The second
|
{i18n._(t`The first fetches all references. The second
|
||||||
fetches the Github pull request number 62, in this example
|
fetches the Github pull request number 62, in this example
|
||||||
|
|||||||
@@ -22,9 +22,15 @@ const SvnSubForm = ({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Example URLs for Subversion Source Control include:`)}
|
{i18n._(t`Example URLs for Subversion Source Control include:`)}
|
||||||
<ul css={{ margin: '10px 0 10px 20px' }}>
|
<ul css={{ margin: '10px 0 10px 20px' }}>
|
||||||
<li>https://github.com/ansible/ansible</li>
|
<li>
|
||||||
<li>svn://servername.example.com/path</li>
|
<code>https://github.com/ansible/ansible</code>
|
||||||
<li>svn+ssh://servername.example.com/path</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>svn://servername.example.com/path</code>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>svn+ssh://servername.example.com/path</code>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ function TeamListItem({ team, isSelected, onSelect, detailUrl, i18n }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`Actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ function TemplateList({ i18n }) {
|
|||||||
key="delete"
|
key="delete"
|
||||||
onDelete={handleTemplateDelete}
|
onDelete={handleTemplateDelete}
|
||||||
itemsToDelete={selected}
|
itemsToDelete={selected}
|
||||||
pluralizedItemName="Templates"
|
pluralizedItemName={i18n._(t`Templates`)}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -112,7 +112,10 @@ function TemplateListItem({
|
|||||||
</DataListCell>,
|
</DataListCell>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction aria-label="actions" aria-labelledby={labelId}>
|
<DataListAction
|
||||||
|
aria-label={i18n._(t`actions`)}
|
||||||
|
aria-labelledby={labelId}
|
||||||
|
>
|
||||||
{template.type === 'workflow_job_template' && (
|
{template.type === 'workflow_job_template' && (
|
||||||
<Tooltip content={i18n._(t`Visualizer`)} position="top">
|
<Tooltip content={i18n._(t`Visualizer`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function LinkDeleteModal({ i18n }) {
|
|||||||
return (
|
return (
|
||||||
<AlertModal
|
<AlertModal
|
||||||
variant="danger"
|
variant="danger"
|
||||||
title="Remove Link"
|
title={i18n._(t`Remove Link`)}
|
||||||
isOpen={linkToDelete}
|
isOpen={linkToDelete}
|
||||||
onClose={() => dispatch({ type: 'SET_LINK_TO_DELETE', value: null })}
|
onClose={() => dispatch({ type: 'SET_LINK_TO_DELETE', value: null })}
|
||||||
actions={[
|
actions={[
|
||||||
|
|||||||
@@ -293,10 +293,14 @@ describe('<JobTemplateForm />', () => {
|
|||||||
).toBe(true);
|
).toBe(true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('input[aria-label="wfjt-webhook-key"]').prop('readOnly')
|
wrapper
|
||||||
|
.find('input[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('readOnly')
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('input[aria-label="wfjt-webhook-key"]').prop('value')
|
wrapper
|
||||||
|
.find('input[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('value')
|
||||||
).toBe('webhook key');
|
).toBe('webhook key');
|
||||||
await act(() =>
|
await act(() =>
|
||||||
wrapper.find('Button[aria-label="Update webhook key"]').prop('onClick')()
|
wrapper.find('Button[aria-label="Update webhook key"]').prop('onClick')()
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ function WebhookSubForm({ i18n, templateType }) {
|
|||||||
<TextInput
|
<TextInput
|
||||||
id="template-webhook_key"
|
id="template-webhook_key"
|
||||||
isReadOnly
|
isReadOnly
|
||||||
aria-label="wfjt-webhook-key"
|
aria-label={i18n._(t`workflow job template webhook key`)}
|
||||||
value={webhookKeyField.value}
|
value={webhookKeyField.value}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ describe('<WebhookSubForm />', () => {
|
|||||||
wrapper.find('TextInputBase[aria-label="Webhook URL"]').prop('value')
|
wrapper.find('TextInputBase[aria-label="Webhook URL"]').prop('value')
|
||||||
).toContain('/api/v2/job_templates/51/github/');
|
).toContain('/api/v2/job_templates/51/github/');
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('TextInputBase[aria-label="wfjt-webhook-key"]').prop('value')
|
wrapper
|
||||||
|
.find('TextInputBase[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('value')
|
||||||
).toBe('webhook key');
|
).toBe('webhook key');
|
||||||
expect(
|
expect(
|
||||||
wrapper
|
wrapper
|
||||||
@@ -89,7 +91,9 @@ describe('<WebhookSubForm />', () => {
|
|||||||
wrapper.find('TextInputBase[aria-label="Webhook URL"]').prop('value')
|
wrapper.find('TextInputBase[aria-label="Webhook URL"]').prop('value')
|
||||||
).toContain('/api/v2/job_templates/51/gitlab/');
|
).toContain('/api/v2/job_templates/51/gitlab/');
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('TextInputBase[aria-label="wfjt-webhook-key"]').prop('value')
|
wrapper
|
||||||
|
.find('TextInputBase[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('value')
|
||||||
).toBe('A NEW WEBHOOK KEY WILL BE GENERATED ON SAVE.');
|
).toBe('A NEW WEBHOOK KEY WILL BE GENERATED ON SAVE.');
|
||||||
});
|
});
|
||||||
test('should have disabled button to update webhook key', async () => {
|
test('should have disabled button to update webhook key', async () => {
|
||||||
|
|||||||
@@ -221,10 +221,14 @@ describe('<WorkflowJobTemplateForm/>', () => {
|
|||||||
wrapper.find('Checkbox[aria-label="Enable Webhook"]').prop('isChecked')
|
wrapper.find('Checkbox[aria-label="Enable Webhook"]').prop('isChecked')
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('input[aria-label="wfjt-webhook-key"]').prop('readOnly')
|
wrapper
|
||||||
|
.find('input[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('readOnly')
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('input[aria-label="wfjt-webhook-key"]').prop('value')
|
wrapper
|
||||||
|
.find('input[aria-label="workflow job template webhook key"]')
|
||||||
|
.prop('value')
|
||||||
).toBe('sdfghjklmnbvcdsew435678iokjhgfd');
|
).toBe('sdfghjklmnbvcdsew435678iokjhgfd');
|
||||||
await act(() =>
|
await act(() =>
|
||||||
wrapper.find('Button[aria-label="Update webhook key"]').prop('onClick')()
|
wrapper.find('Button[aria-label="Update webhook key"]').prop('onClick')()
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ function UserList({ i18n }) {
|
|||||||
key="delete"
|
key="delete"
|
||||||
onDelete={handleUserDelete}
|
onDelete={handleUserDelete}
|
||||||
itemsToDelete={selected}
|
itemsToDelete={selected}
|
||||||
pluralizedItemName="Users"
|
pluralizedItemName={i18n._(t`Users`)}
|
||||||
/>,
|
/>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ function UserListItem({ user, isSelected, onSelect, detailUrl, i18n }) {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<DataListAction
|
<DataListAction
|
||||||
aria-label="actions"
|
aria-label={i18n._(t`actions`)}
|
||||||
aria-labelledby={labelId}
|
aria-labelledby={labelId}
|
||||||
id={labelId}
|
id={labelId}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user