Merge pull request #6954 from jakemcdermott/5957-statics

Add basic static file building for ui_next

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
softwarefactory-project-zuul[bot] 2020-05-12 22:14:53 +00:00 committed by GitHub
commit d2acd15783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
558 changed files with 12453 additions and 18380 deletions

View File

@ -11,11 +11,6 @@
"plugins": ["react-hooks"],
"extends": ["airbnb", "prettier", "prettier/react"],
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.js"
}
},
"react": {
"version": "16.5.2"
}

View File

@ -1,5 +1,5 @@
{
"localeDir": "build/locales/",
"localeDir": "src/locales/",
"srcPathDirs": ["src/"],
"format": "po"
}

View File

@ -143,6 +143,7 @@ Inside these folders, the internal structure is:
- **/api** - All classes used to interact with API's are found here. See [AWX REST API Interaction](#awx-rest-api-interaction) for more information.
- **/components** - All generic components that are meant to be used in multiple contexts throughout awx. Things like buttons, tabs go here.
- **/contexts** - Components which utilize react's context api.
- **/locales** - [Internationalization](#internationalization) config and source files.
- **/screens** - Based on the various routes of awx.
- **/shared** - Components that are meant to be used specifically by a particular route, but might be sharable across pages of that route. For example, a form component which is used on both add and edit screens.
- **/util** - Stateless helper functions that aren't tied to react.
@ -315,7 +316,7 @@ You can learn more about the ways lingui and its React helpers at [this link](ht
### Setting up .po files to give to translation team
1) `npm run add-locale` to add the language that you want to translate to (we should only have to do this once and the commit to repo afaik). Example: `npm run add-locale en es fr` # Add English, Spanish and French locale
2) `npm run extract-strings` to create .po files for each language specified. The .po files will be placed in src/locales but this is configurable.
2) `npm run extract-strings` to create .po files for each language specified. The .po files will be placed in src/locales.
3) Open up the .po file for the language you want to test and add some translations. In production we would pass this .po file off to the translation team.
4) Once you've edited your .po file (or we've gotten a .po file back from the translation team) run `npm run compile-strings`. This command takes the .po files and turns them into a minified JSON object and can be seen in the `messages.js` file in each locale directory. These files get loaded at the App root level (see: App.jsx).
5) Change the language in your browser and reload the page. You should see your specified translations in place of English strings.

View File

@ -5,16 +5,13 @@ ARG TARGET_HOST='awx'
ENV TARGET_HOST=${TARGET_HOST}
ARG TARGET_PORT=8043
ENV TARGET_PORT=${TARGET_PORT}
ENV CI=true
WORKDIR /ui_next
ADD build build
ADD dist dist
ADD images images
ADD public public
ADD package.json package.json
ADD package-lock.json package-lock.json
COPY ${NPMRC_FILE} .npmrc
RUN npm install
ADD babel.config.js babel.config.js
ADD webpack.config.js webpack.config.js
ADD src src
EXPOSE 3001
CMD [ "npm", "run", "start" ]
CMD [ "npm", "start" ]

View File

@ -3,31 +3,72 @@
## Requirements
- node 10.x LTS, npm 6.x LTS, make, git
## Usage
* `git clone git@github.com:ansible/awx.git`
* cd awx/ui_next
* npm install
* npm start
* visit `https://127.0.0.1:3001/`
**note:** These instructions assume you have the [awx](https://github.com/ansible/awx/blob/devel/CONTRIBUTING.md#running-the-environment) development api server up and running at `localhost:8043`. You can use a different backend server with the `TARGET_HOST` and `TARGET_PORT` environment variables when starting the development server:
## Development
The API development server will need to be running. See [CONTRIBUTING.md](../../CONTRIBUTING.md).
```shell
# use a non-default host and port when starting the development server
TARGET_HOST='ec2-awx.amazonaws.com' TARGET_PORT='443' npm run start
# Start the ui development server. While running, the ui will be reachable
# at https://127.0.01:3001 and updated automatically when code changes.
npm --prefix=awx/ui_next start
```
## Unit Tests
### Using an External Server
If you normally run awx on an external host/server (in this example, `awx.local`),
you'll need to update your django settings and use the `TARGET_HOST` and `TARGET_PORT` environment variables:
To run the unit tests on files that you've changed:
* `npm test`
```shell
echo "CSRF_TRUSTED_ORIGINS = ['awx.local:8043']" >> /awx/settings/development.py
TARGET_HOST='awx.local:8043' TARGET_PORT=8043 npm --prefix awx/ui_next start
```
To run a single test (in this case the login page test):
* `npm test -- src/screens/Login/Login.test.jsx`
## Testing
```shell
# run code formatting check
npm --prefix awx/ui_next run prettier-check
**note:** Once the test watcher is up and running you can hit `a` to run all the tests
# run lint checks
npm --prefix awx/ui_next run lint
# run all unit tests
npm --prefix awx/ui_next run test
# run a single test (in this case the login page test):
npm --prefix awx/ui_next test -- src/screens/Login/Login.test.jsx
# start the test watcher and run tests on files that you've changed
npm --prefix awx/ui_next run test-watch
```
#### Note:
- Once the test watcher is up and running you can hit `a` to run all the tests.
- All commands are run on your host machine and not in the api development containers.
## Adding Dependencies
```shell
# add an exact development or build dependency
npm --prefix awx/ui_next install --save-dev --save-exact dev-package@1.2.3
# add an exact production dependency
npm --prefix awx/ui_next install --save --save-exact prod-package@1.23
# add the updated package.json and package-lock.json files to scm
git add awx/ui_next_next/package.json awx/ui_next_next/package-lock.json
```
## Removing Dependencies
```shell
# remove a development or build dependency
npm --prefix awx/ui_next uninstall --save-dev dev-package
# remove a production dependency
npm --prefix awx/ui_next uninstall --save prod-package
```
## Building for Production
```shell
# built files are placed in awx/ui_next/build
npm --prefix awx/ui_next run build
```
## CI Container
@ -39,4 +80,4 @@ docker build -t awx-ui-next .
docker run --name tools_ui_next_1 --network tools_default --link 'tools_awx_1:awx' -e TARGET_HOST=awx -p '3001:3001' --rm -v $(pwd)/src:/ui_next/src awx-ui-next
```
**note:** This is for CI, test systems, zuul, etc. For local development, see [usage](https://github.com/ansible/awx/blob/devel/awx/ui_next/README.md#usage)
**Note:** This is for CI, test systems, zuul, etc. For local development, see [usage](https://github.com/ansible/awx/blob/devel/awx/ui_next/README.md#usage)

View File

@ -1,7 +0,0 @@
const path = require('path');
module.exports = {
process (src, filename) {
return `module.exports=${JSON.stringify(path.basename(filename))};`;
},
};

View File

@ -1 +0,0 @@
module.exports = {};

View File

@ -1,18 +0,0 @@
module.exports = api => {
api.cache(false);
return {
plugins: [
'babel-plugin-styled-components',
'@babel/plugin-proposal-class-properties',
'macros'
],
presets: [
['@babel/preset-env', {
targets: {
node: '8.11'
}
}],
'@babel/preset-react'
]
};
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<body>
<div id="app" style="height: 100%"></div>
<script src="/bundle.js"></script>
</body>
</html>

View File

@ -1,43 +0,0 @@
module.exports = {
collectCoverageFrom: [
'src/**/*.{js,jsx}',
'testUtils/**/*.{js,jsx}'
],
coveragePathIgnorePatterns: [
'<rootDir>/src/locales',
'index.js'
],
moduleNameMapper: {
'\\.(css|scss|less)$': '<rootDir>/__mocks__/styleMock.js',
'^@api(.*)$': '<rootDir>/src/api$1',
'^@components(.*)$': '<rootDir>/src/components$1',
'^@constants$': '<rootDir>/src/constants.js',
'^@contexts(.*)$': '<rootDir>/src/contexts$1',
'^@screens(.*)$': '<rootDir>/src/screens$1',
'^@util(.*)$': '<rootDir>/src/util$1',
'^@types(.*)$': '<rootDir>/src/types$1',
'^@testUtils(.*)$': '<rootDir>/testUtils$1',
},
setupFiles: [
'@nteract/mockument'
],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
snapshotSerializers: [
"enzyme-to-json/serializer"
],
testMatch: [
'<rootDir>/**/*.test.{js,jsx}'
],
testEnvironment: 'jsdom',
testURL: 'http://127.0.0.1:3001',
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/__mocks__/fileMock.js',
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.(?!(axios)/)(js|jsx)$'
],
watchPathIgnorePatterns: [
'<rootDir>/node_modules'
]
};

View File

@ -1,11 +0,0 @@
require('@babel/polyfill');
// eslint-disable-next-line import/prefer-default-export
export const asyncFlush = () => new Promise((resolve) => setImmediate(resolve));
const enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
jest.setTimeout(5000 * 4);
enzyme.configure({ adapter: new Adapter() });

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,41 @@
{
"name": "awx-react",
"version": "1.0.0",
"description": "",
"main": "index.jsx",
"name": "ui_next",
"version": "0.1.0",
"private": true,
"dependencies": {
"@lingui/react": "^2.9.1",
"@patternfly/patternfly": "^2.71.3",
"@patternfly/react-core": "^3.153.3",
"@patternfly/react-icons": "^3.15.15",
"@patternfly/react-tokens": "^2.8.12",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"ansi-to-html": "^0.6.11",
"axios": "^0.18.1",
"codemirror": "^5.47.0",
"d3": "^5.12.0",
"dagre": "^0.8.4",
"formik": "^2.1.2",
"has-ansi": "^3.0.0",
"html-entities": "^1.2.1",
"js-yaml": "^3.13.1",
"prop-types": "^15.6.2",
"react": "^16.13.1",
"react-codemirror2": "^6.0.0",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-virtualized": "^9.21.1",
"rrule": "^2.6.4",
"styled-components": "^4.2.0"
},
"scripts": {
"start": "webpack-dev-server --config ./webpack.config.js --mode development",
"test": "TZ='UTC' jest --coverage",
"test-watch": "TZ='UTC' jest --watch",
"start": "PORT=3001 HTTPS=true DANGEROUSLY_DISABLE_HOST_CHECK=true react-scripts start",
"build": "react-scripts build",
"test": "TZ='UTC' react-scripts test --coverage --watchAll=false",
"test-watch": "TZ='UTC' react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext .js --ext .jsx .",
"add-locale": "lingui add-locale",
"extract-strings": "lingui extract",
@ -14,25 +43,24 @@
"prettier": "prettier --write \"src/**/*.{js,jsx,scss}\"",
"prettier-check": "prettier --check \"src/**/*.{js,jsx,scss}\""
},
"keywords": [],
"author": "",
"license": "Apache",
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.8.3",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.8.3",
"@babel/preset-react": "^7.0.0",
"@lingui/cli": "^2.7.4",
"@lingui/macro": "^2.7.2",
"@babel/polyfill": "^7.8.7",
"@lingui/cli": "^2.9.1",
"@lingui/macro": "^2.9.1",
"@nteract/mockument": "^1.0.4",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^25.1.0",
"babel-loader": "^8.0.6",
"babel-plugin-macros": "^2.4.2",
"babel-plugin-styled-components": "^1.10.0",
"css-loader": "^1.0.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.3.5",
@ -44,40 +72,20 @@
"eslint-plugin-jsx-a11y": "^6.1.1",
"eslint-plugin-react": "^7.11.1",
"eslint-plugin-react-hooks": "^2.2.0",
"file-loader": "^2.0.0",
"history": "^4.9.0",
"jest": "^25.1.0",
"node-sass": "^4.13.1",
"prettier": "^1.18.2",
"react-hot-loader": "^4.3.3",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.14"
"http-proxy-middleware": "^1.0.3",
"prettier": "^1.18.2"
},
"dependencies": {
"@lingui/react": "^2.7.2",
"@patternfly/patternfly": "^2.71.3",
"@patternfly/react-core": "^3.153.3",
"@patternfly/react-icons": "^3.15.15",
"@patternfly/react-tokens": "^2.8.12",
"ansi-to-html": "^0.6.11",
"axios": "^0.18.1",
"codemirror": "^5.47.0",
"d3": "^5.12.0",
"dagre": "^0.8.4",
"formik": "^2.1.2",
"has-ansi": "^3.0.0",
"html-entities": "^1.2.1",
"js-yaml": "^3.13.1",
"prop-types": "^15.6.2",
"react": "^16.13.0",
"react-codemirror2": "^6.0.0",
"react-dom": "^16.13.0",
"react-router-dom": "^5.1.2",
"react-virtualized": "^9.21.1",
"rrule": "^2.6.4",
"styled-components": "^4.2.0"
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"testUtils/**/*.{js,jsx}"
],
"coveragePathIgnorePatterns": [
"<rootDir>/src/locales",
"index.js"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="AWX"
/>
<title>AWX</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app" style="height: 100%"></div>
</body>
</html>

View File

@ -12,14 +12,14 @@ import styled from 'styled-components';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
import { ConfigAPI, MeAPI, RootAPI } from '@api';
import About from '@components/About';
import AlertModal from '@components/AlertModal';
import NavExpandableGroup from '@components/NavExpandableGroup';
import BrandLogo from '@components/BrandLogo';
import PageHeaderToolbar from '@components/PageHeaderToolbar';
import ErrorDetail from '@components/ErrorDetail';
import { ConfigProvider } from '@contexts/Config';
import { ConfigAPI, MeAPI, RootAPI } from './api';
import About from './components/About';
import AlertModal from './components/AlertModal';
import NavExpandableGroup from './components/NavExpandableGroup';
import BrandLogo from './components/BrandLogo';
import PageHeaderToolbar from './components/PageHeaderToolbar';
import ErrorDetail from './components/ErrorDetail';
import { ConfigProvider } from './contexts/Config';
const PageHeader = styled(PFPageHeader)`
& .pf-c-page__header-brand-link {

View File

@ -1,8 +1,8 @@
import React from 'react';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import { ConfigAPI, MeAPI, RootAPI } from '@api';
import { asyncFlush } from '../jest.setup';
import { mountWithContexts, waitForElement } from '../testUtils/enzymeHelpers';
import { ConfigAPI, MeAPI, RootAPI } from './api';
import { asyncFlush } from './setupTests';
import App from './App';

View File

@ -3,9 +3,9 @@ import { I18nProvider } from '@lingui/react';
import { HashRouter } from 'react-router-dom';
import { getLanguageWithoutRegionCode } from '@util/language';
import ja from '../build/locales/ja/messages';
import en from '../build/locales/en/messages';
import { getLanguageWithoutRegionCode } from './util/language';
import ja from './locales/ja/messages';
import en from './locales/en/messages';
class RootProvider extends Component {
render() {

View File

@ -1,6 +1,6 @@
import axios from 'axios';
import { encodeQueryString } from '@util/qs';
import { encodeQueryString } from '../util/qs';
const defaultHttp = axios.create({
xsrfCookieName: 'csrftoken',

View File

@ -1,6 +1,9 @@
import CredentialTypes from './CredentialTypes';
const typesData = [{ id: 1, kind: 'machine' }, { id: 2, kind: 'cloud' }];
const typesData = [
{ id: 1, kind: 'machine' },
{ id: 2, kind: 'cloud' },
];
describe('CredentialTypesAPI', () => {
test('should load all types', async () => {

View File

@ -1,4 +1,4 @@
import { describeNotificationMixin } from '@testUtils/apiReusable';
import { describeNotificationMixin } from '../../../testUtils/apiReusable';
import Organizations from './Organizations';
describe('OrganizationsAPI', () => {

View File

@ -16,10 +16,9 @@ describe('TeamsAPI', () => {
await TeamsAPI.associateRole(teamId, roleId);
expect(mockHttp.post).toHaveBeenCalledTimes(1);
expect(mockHttp.post.mock.calls[0]).toContainEqual(
`/api/v2/teams/${teamId}/roles/`,
{ id: roleId }
);
expect(
mockHttp.post.mock.calls[0]
).toContainEqual(`/api/v2/teams/${teamId}/roles/`, { id: roleId });
done();
});

View File

@ -16,10 +16,9 @@ describe('UsersAPI', () => {
await UsersAPI.associateRole(userId, roleId);
expect(mockHttp.post).toHaveBeenCalledTimes(1);
expect(mockHttp.post.mock.calls[0]).toContainEqual(
`/api/v2/users/${userId}/roles/`,
{ id: roleId }
);
expect(
mockHttp.post.mock.calls[0]
).toContainEqual(`/api/v2/users/${userId}/roles/`, { id: roleId });
done();
});

View File

@ -10,7 +10,7 @@ import {
} from '@patternfly/react-core';
import { BrandName } from '../../variables';
import brandLogoImg from '../../../images/brand-logo.svg';
import brandLogoImg from './brand-logo.svg';
class About extends React.Component {
static createSpeechBubble(version) {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import About from './About';
describe('<About />', () => {

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -2,7 +2,7 @@ import React, { useState, useRef, useEffect } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { Dropdown, DropdownPosition } from '@patternfly/react-core';
import { ToolbarAddButton } from '@components/PaginatedDataList';
import { ToolbarAddButton } from '../PaginatedDataList';
function AddDropDownButton({ dropdownItems }) {
const [isOpen, setIsOpen] = useState(false);

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import AddDropDownButton from './AddDropDownButton';
describe('<AddDropDownButton />', () => {

View File

@ -2,8 +2,8 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import SelectableCard from '@components/SelectableCard';
import Wizard from '@components/Wizard';
import SelectableCard from '../SelectableCard';
import Wizard from '../Wizard';
import SelectResourceStep from './SelectResourceStep';
import SelectRoleStep from './SelectRoleStep';
import { TeamsAPI, UsersAPI } from '../../api';

View File

@ -1,17 +1,20 @@
/* eslint-disable react/jsx-pascal-case */
import React from 'react';
import { shallow } from 'enzyme';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import AddResourceRole, { _AddResourceRole } from './AddResourceRole';
import { TeamsAPI, UsersAPI } from '@api';
import { TeamsAPI, UsersAPI } from '../../api';
jest.mock('@api');
jest.mock('../../api');
describe('<_AddResourceRole />', () => {
UsersAPI.read.mockResolvedValue({
data: {
count: 2,
results: [{ id: 1, username: 'foo' }, { id: 2, username: 'bar' }],
results: [
{ id: 1, username: 'foo' },
{ id: 2, username: 'bar' },
],
},
});
const roles = {

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { SearchColumns, SortColumns } from '@types';
import { SearchColumns, SortColumns } from '../../types';
import PaginatedDataList from '../PaginatedDataList';
import DataListToolbar from '../DataListToolbar';
import CheckboxListItem from '../CheckboxListItem';

View File

@ -1,8 +1,8 @@
import React from 'react';
import { createMemoryHistory } from 'history';
import { shallow } from 'enzyme';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { sleep } from '@testUtils/testUtils';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { sleep } from '../../../testUtils/testUtils';
import SelectResourceStep from './SelectResourceStep';
describe('<SelectResourceStep />', () => {

View File

@ -1,6 +1,6 @@
import React from 'react';
import { shallow } from 'enzyme';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import SelectRoleStep from './SelectRoleStep';
describe('<SelectRoleStep />', () => {

View File

@ -1,3 +1,4 @@
import 'styled-components/macro';
import React from 'react';
import { Modal, Title } from '@patternfly/react-core';
import {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import AnsibleSelect, { _AnsibleSelect } from './AnsibleSelect';
const mockData = [

View File

@ -3,10 +3,10 @@ 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 '@components/OptionsList';
import useRequest from '@util/useRequest';
import { getQSConfig, parseQueryString } from '@util/qs';
import useSelected from '@util/useSelected';
import OptionsList from '../OptionsList';
import useRequest from '../../util/useRequest';
import { getQSConfig, parseQueryString } from '../../util/qs';
import useSelected from '../../util/useSelected';
const QS_CONFIG = getQSConfig('associate', {
page: 1,

View File

@ -1,11 +1,14 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import AssociateModal from './AssociateModal';
import mockHosts from './data.hosts.json';
jest.mock('@api');
jest.mock('../../api');
describe('<AssociateModal />', () => {
let wrapper;

View File

@ -1,15 +1,13 @@
import React, { Fragment } from 'react';
import { BackgroundImage, BackgroundImageSrc } from '@patternfly/react-core';
import bgFilter from '@patternfly/patternfly/assets/images/background-filter.svg';
const backgroundImageConfig = {
[BackgroundImageSrc.xs]: '/assets/images/pfbg_576.jpg',
[BackgroundImageSrc.xs2x]: '/assets/images/pfbg_576@2x.jpg',
[BackgroundImageSrc.sm]: '/assets/images/pfbg_768.jpg',
[BackgroundImageSrc.sm2x]: '/assets/images/pfbg_768@2x.jpg',
[BackgroundImageSrc.lg]: '/assets/images/pfbg_2000.jpg',
[BackgroundImageSrc.filter]: `${bgFilter}#image_overlay`,
[BackgroundImageSrc.xs]: './images/pfbg_576.jpg',
[BackgroundImageSrc.xs2x]: './images/pfbg_576@2x.jpg',
[BackgroundImageSrc.sm]: './images/pfbg_768.jpg',
[BackgroundImageSrc.sm2x]: './images/pfbg_768@2x.jpg',
[BackgroundImageSrc.lg]: './images/pfbg_2000.jpg',
};
export default ({ children }) => (

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import BrandLogo from './BrandLogo';
let logoWrapper;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import CardCloseButton from './CardCloseButton';
describe('<CardCloseButton>', () => {

View File

@ -7,7 +7,7 @@ import {
DataListCheck,
Radio,
} from '@patternfly/react-core';
import DataListCell from '@components/DataListCell';
import DataListCell from '../DataListCell';
const CheckboxListItem = ({
isDisabled = false,

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ChipGroup from './ChipGroup';
describe('ChipGroup', () => {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ClipboardCopyButton from './ClipboardCopyButton';
document.execCommand = jest.fn();

View File

@ -1,9 +1,10 @@
import 'styled-components/macro';
import React, { useState, useEffect } from 'react';
import { string, node, number } from 'prop-types';
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
import { DetailName, DetailValue } from '@components/DetailList';
import MultiButtonToggle from '@components/MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import { DetailName, DetailValue } from '../DetailList';
import MultiButtonToggle from '../MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '../../util/yaml';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -51,7 +52,10 @@ function VariablesDetail({ value, label, rows, fullHeight }) {
</SplitItem>
<SplitItem>
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
buttons={[
[YAML_MODE, 'YAML'],
[JSON_MODE, 'JSON'],
]}
value={mode}
onChange={newMode => {
try {

View File

@ -3,14 +3,14 @@ import { act } from 'react-dom/test-utils';
import { shallow, mount } from 'enzyme';
import VariablesDetail from './VariablesDetail';
jest.mock('@api');
jest.mock('../../api');
describe('<VariablesDetail>', () => {
test('should render readonly CodeMirrorInput', () => {
const wrapper = shallow(
<VariablesDetail value="---foo: bar" label="Variables" />
);
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input).toHaveLength(1);
expect(input.prop('mode')).toEqual('yaml');
expect(input.prop('value')).toEqual('---foo: bar');
@ -21,7 +21,7 @@ describe('<VariablesDetail>', () => {
const wrapper = shallow(
<VariablesDetail value='{"foo": "bar"}' label="Variables" />
);
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input).toHaveLength(1);
expect(input.prop('mode')).toEqual('javascript');
expect(input.prop('value')).toEqual('{"foo": "bar"}');
@ -32,19 +32,21 @@ describe('<VariablesDetail>', () => {
<VariablesDetail value="---foo: bar" label="Variables" />
);
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input.prop('mode')).toEqual('javascript');
expect(input.prop('value')).toEqual('{\n "foo": "bar"\n}');
wrapper.find('MultiButtonToggle').invoke('onChange')('yaml');
const input2 = wrapper.find('Styled(CodeMirrorInput)');
const input2 = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input2.prop('mode')).toEqual('yaml');
expect(input2.prop('value')).toEqual('foo: bar\n');
});
test('should render label and value= --- when there are no values', () => {
const wrapper = shallow(<VariablesDetail value="" label="Variables" />);
expect(wrapper.find('Styled(CodeMirrorInput)').length).toBe(1);
expect(wrapper.find('VariablesDetail___StyledCodeMirrorInput').length).toBe(
1
);
expect(wrapper.find('div.pf-c-form__label').text()).toBe('Variables');
});
@ -59,14 +61,14 @@ describe('<VariablesDetail>', () => {
value: '---bar: baz',
});
wrapper.update();
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input.prop('mode')).toEqual('javascript');
expect(input.prop('value')).toEqual('{\n "bar": "baz"\n}');
});
test('should default yaml value to "---"', () => {
const wrapper = shallow(<VariablesDetail value="" label="Variables" />);
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input.prop('value')).toEqual('---');
});
@ -76,7 +78,7 @@ describe('<VariablesDetail>', () => {
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
});
wrapper.setProps({ value: '' });
const input = wrapper.find('Styled(CodeMirrorInput)');
const input = wrapper.find('VariablesDetail___StyledCodeMirrorInput');
expect(input.prop('value')).toEqual('{}');
});
});

View File

@ -5,9 +5,9 @@ import { t } from '@lingui/macro';
import { useField } from 'formik';
import styled from 'styled-components';
import { Split, SplitItem } from '@patternfly/react-core';
import { CheckboxField, FieldTooltip } from '@components/FormField';
import MultiButtonToggle from '@components/MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import { CheckboxField, FieldTooltip } from '../FormField';
import MultiButtonToggle from '../MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '../../util/yaml';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -44,7 +44,10 @@ function VariablesField({
</SplitItem>
<SplitItem>
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
buttons={[
[YAML_MODE, 'YAML'],
[JSON_MODE, 'JSON'],
]}
value={mode}
onChange={newMode => {
try {

View File

@ -2,8 +2,8 @@ import React, { useState } from 'react';
import { string, func, bool, number } from 'prop-types';
import { Split, SplitItem } from '@patternfly/react-core';
import styled from 'styled-components';
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
import MultiButtonToggle from '@components/MultiButtonToggle';
import { yamlToJson, jsonToYaml, isJson } from '../../util/yaml';
import MultiButtonToggle from '../MultiButtonToggle';
import CodeMirrorInput from './CodeMirrorInput';
import { JSON_MODE, YAML_MODE } from './constants';
@ -43,7 +43,10 @@ function VariablesInput(props) {
</SplitItem>
<SplitItemRight>
<MultiButtonToggle
buttons={[[YAML_MODE, 'YAML'], [JSON_MODE, 'JSON']]}
buttons={[
[YAML_MODE, 'YAML'],
[JSON_MODE, 'JSON'],
]}
value={mode}
onChange={newMode => {
try {

View File

@ -3,7 +3,7 @@ import { bool, string } from 'prop-types';
import styled from 'styled-components';
import { Button } from '@patternfly/react-core';
import { AngleRightIcon } from '@patternfly/react-icons';
import omitProps from '@util/omitProps';
import omitProps from '../../util/omitProps';
import ExpandingContainer from './ExpandingContainer';
// Make button findable by tests

View File

@ -1,3 +1,4 @@
import 'styled-components/macro';
import React, { useState, useEffect, useRef } from 'react';
import { bool } from 'prop-types';
import styled from 'styled-components';

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ContentEmpty from './ContentEmpty';

View File

@ -10,8 +10,8 @@ import {
EmptyStateBody,
} from '@patternfly/react-core';
import { ExclamationTriangleIcon } from '@patternfly/react-icons';
import { RootAPI } from '@api';
import ErrorDetail from '@components/ErrorDetail';
import { RootAPI } from '../../api';
import ErrorDetail from '../ErrorDetail';
async function logout() {
await RootAPI.logout();

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ContentError from './ContentError';

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ContentLoading from './ContentLoading';

View File

@ -5,9 +5,9 @@ import PropTypes from 'prop-types';
import { Button, Tooltip } from '@patternfly/react-core';
import { CopyIcon } from '@patternfly/react-icons';
import useRequest, { useDismissableError } from '@util/useRequest';
import AlertModal from '@components/AlertModal';
import ErrorDetail from '@components/ErrorDetail';
import useRequest, { useDismissableError } from '../../util/useRequest';
import AlertModal from '../AlertModal';
import ErrorDetail from '../ErrorDetail';
function CopyButton({ i18n, copyItem, onLoading, onDoneLoading, helperText }) {
const { isLoading, error: copyError, request: copyItemToAPI } = useRequest(

View File

@ -1,8 +1,8 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import CopyButton from './CopyButton';
jest.mock('@api');
jest.mock('../../api');
describe('<CopyButton/>', () => {
test('shold mount properly', () => {

View File

@ -1,10 +1,10 @@
import React from 'react';
import { shape } from 'prop-types';
import { toTitleCase } from '@util/strings';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Credential } from '@types';
import { Chip } from '@patternfly/react-core';
import { Credential } from '../../types';
import { toTitleCase } from '../../util/strings';
function CredentialChip({ credential, i18n, ...props }) {
let type;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import CredentialChip from './CredentialChip';
describe('CredentialChip', () => {

View File

@ -1,9 +1,12 @@
import { DataListCell } from '@patternfly/react-core';
import { DataListCell as PFDataListCell } from '@patternfly/react-core';
import styled from 'styled-components';
DataListCell.displayName = 'PFDataListCell';
PFDataListCell.displayName = 'PFDataListCell';
// Once https://github.com/patternfly/patternfly-react/issues/3938
// has been resolved this component can be removed
export default styled(DataListCell)`
const DataListCell = styled(PFDataListCell)`
word-break: break-word;
`;
DataListCell.displayName = 'DataListCell';
export default DataListCell;

View File

@ -16,7 +16,7 @@ import ExpandCollapse from '../ExpandCollapse';
import Search from '../Search';
import Sort from '../Sort';
import { SearchColumns, SortColumns, QSConfig } from '@types';
import { SearchColumns, SortColumns, QSConfig } from '../../types';
const DataToolbarContent = styled(_DataToolbarContent)`
--pf-c-data-toolbar__content--PaddingLeft: 24px;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DataListToolbar from './DataListToolbar';
describe('<DataListToolbar />', () => {

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Button } from '@patternfly/react-core';
import AlertModal from '@components/AlertModal';
import AlertModal from '../AlertModal';
function DeleteButton({
onConfirm,

View File

@ -3,7 +3,7 @@ import { node, string } from 'prop-types';
import { Trans } from '@lingui/macro';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import { formatDateString } from '@util/dates';
import { formatDateString } from '../../util/dates';
import _Detail from './Detail';
import { SummaryFieldUser } from '../../types';

View File

@ -3,8 +3,8 @@ import { arrayOf, func, object, string } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Button, Tooltip } from '@patternfly/react-core';
import AlertModal from '@components/AlertModal';
import styled from 'styled-components';
import AlertModal from '../AlertModal';
const ModalNote = styled.div`
margin-bottom: var(--pf-global--spacer--xl);
@ -112,6 +112,12 @@ function DisassociateButton({
);
}
DisassociateButton.defaultProps = {
itemsToDisassociate: [],
modalNote: '',
modalTitle: '',
};
DisassociateButton.propTypes = {
itemsToDisassociate: arrayOf(object),
modalNote: string,

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DisassociateButton from './DisassociateButton';
describe('<DisassociateButton />', () => {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ErrorDetail from './ErrorDetail';

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import ExpandCollapse from './ExpandCollapse';
describe('<ExpandCollapse />', () => {

View File

@ -2,8 +2,8 @@ import React from 'react';
import { bool, node, string } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { CheckboxField, FieldTooltip } from '@components/FormField';
import styled from 'styled-components';
import { CheckboxField, FieldTooltip } from '../FormField';
const FieldHeader = styled.div`
display: flex;

View File

@ -1,6 +1,6 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { Field, Formik } from 'formik';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import FieldWithPrompt from './FieldWithPrompt';
describe('FieldWithPrompt', () => {

View File

@ -3,7 +3,7 @@ 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 '@components/FormLayout';
import { FormFullWidthLayout } from '../FormLayout';
const FormActionGroup = ({ onSubmit, submitDisabled, onCancel, i18n }) => (
<FormFullWidthLayout>

View File

@ -1,5 +1,5 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import FormActionGroup from './FormActionGroup';

View File

@ -1,7 +1,7 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { Formik } from 'formik';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import FormSubmitError from './FormSubmitError';
describe('<FormSubmitError>', () => {

View File

@ -1,7 +1,7 @@
import React from 'react';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { sleep } from '@testUtils/testUtils';
import { Formik } from 'formik';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { sleep } from '../../../testUtils/testUtils';
import PasswordField from './PasswordField';
describe('PasswordField', () => {

View File

@ -5,15 +5,12 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Form, FormGroup } from '@patternfly/react-core';
import FormField, {
FormSubmitError,
FieldTooltip,
} from '@components/FormField';
import FormActionGroup from '@components/FormActionGroup/FormActionGroup';
import { VariablesField } from '@components/CodeMirrorInput';
import { InventoryLookup } from '@components/Lookup';
import { FormColumnLayout, FormFullWidthLayout } from '@components/FormLayout';
import { required } from '@util/validators';
import FormField, { FormSubmitError, FieldTooltip } from '../FormField';
import FormActionGroup from '../FormActionGroup/FormActionGroup';
import { VariablesField } from '../CodeMirrorInput';
import { InventoryLookup } from '../Lookup';
import { FormColumnLayout, FormFullWidthLayout } from '../FormLayout';
import { required } from '../../util/validators';
const InventoryLookupField = withI18n()(({ i18n, host }) => {
const [inventory, setInventory] = useState(

View File

@ -1,10 +1,10 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import HostForm from './HostForm';
jest.mock('@api');
jest.mock('../../api');
const mockData = {
id: 1,

View File

@ -1,11 +1,12 @@
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 '@components/AlertModal';
import ErrorDetail from '@components/ErrorDetail';
import useRequest from '@util/useRequest';
import { HostsAPI } from '@api';
import AlertModal from '../AlertModal';
import ErrorDetail from '../ErrorDetail';
import useRequest from '../../util/useRequest';
import { HostsAPI } from '../../api';
function HostToggle({ host, onToggle, className, i18n }) {
const [isEnabled, setIsEnabled] = useState(host.enabled);

View File

@ -1,10 +1,10 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { HostsAPI } from '@api';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { HostsAPI } from '../../api';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import HostToggle from './HostToggle';
jest.mock('@api');
jest.mock('../../api');
const mockHost = {
id: 1,

View File

@ -4,14 +4,12 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Card } from '@patternfly/react-core';
import AlertModal from '@components/AlertModal';
import DatalistToolbar from '@components/DataListToolbar';
import ErrorDetail from '@components/ErrorDetail';
import PaginatedDataList, {
ToolbarDeleteButton,
} from '@components/PaginatedDataList';
import useRequest, { useDeleteItems } from '@util/useRequest';
import { getQSConfig, parseQueryString } from '@util/qs';
import AlertModal from '../AlertModal';
import DatalistToolbar from '../DataListToolbar';
import ErrorDetail from '../ErrorDetail';
import PaginatedDataList, { ToolbarDeleteButton } from '../PaginatedDataList';
import useRequest, { useDeleteItems } from '../../util/useRequest';
import { getQSConfig, parseQueryString } from '../../util/qs';
import JobListItem from './JobListItem';
import {
AdHocCommandsAPI,
@ -21,7 +19,7 @@ import {
SystemJobsAPI,
UnifiedJobsAPI,
WorkflowJobsAPI,
} from '@api';
} from '../../api';
function JobList({ i18n, defaultParams, showTypeColumn = false }) {
const QS_CONFIG = getQSConfig(

View File

@ -1,6 +1,9 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import {
AdHocCommandsAPI,
InventoryUpdatesAPI,
@ -9,10 +12,10 @@ import {
SystemJobsAPI,
UnifiedJobsAPI,
WorkflowJobsAPI,
} from '@api';
} from '../../api';
import JobList from './JobList';
jest.mock('@api');
jest.mock('../../api');
const mockResults = [
{

View File

@ -11,13 +11,13 @@ import {
DataListItemCells,
Tooltip,
} from '@patternfly/react-core';
import DataListCell from '@components/DataListCell';
import { RocketIcon } from '@patternfly/react-icons';
import LaunchButton from '@components/LaunchButton';
import StatusIcon from '@components/StatusIcon';
import { formatDateString } from '@util/dates';
import { JOB_TYPE_URL_SEGMENTS } from '@constants';
import styled from 'styled-components';
import DataListCell from '../DataListCell';
import LaunchButton from '../LaunchButton';
import StatusIcon from '../StatusIcon';
import { formatDateString } from '../../util/dates';
import { JOB_TYPE_URL_SEGMENTS } from '../../constants';
const DataListAction = styled(_DataListAction)`
align-items: center;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { createMemoryHistory } from 'history';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import JobListItem from './JobListItem';

View File

@ -4,8 +4,8 @@ import { number, shape } from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import AlertModal from '@components/AlertModal';
import ErrorDetail from '@components/ErrorDetail';
import AlertModal from '../AlertModal';
import ErrorDetail from '../ErrorDetail';
import {
AdHocCommandsAPI,
InventorySourcesAPI,
@ -14,8 +14,8 @@ import {
ProjectsAPI,
WorkflowJobsAPI,
WorkflowJobTemplatesAPI,
} from '@api';
import LaunchPrompt from '@components/LaunchPrompt';
} from '../../api';
import LaunchPrompt from '../LaunchPrompt';
function canLaunchWithoutPrompt(launchData) {
return (

View File

@ -1,13 +1,13 @@
import React from 'react';
import { createMemoryHistory } from 'history';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { sleep } from '@testUtils/testUtils';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { sleep } from '../../../testUtils/testUtils';
import LaunchButton from './LaunchButton';
import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '../../api';
jest.mock('@api/models/WorkflowJobTemplates');
jest.mock('@api/models/JobTemplates');
jest.mock('../../api/models/WorkflowJobTemplates');
jest.mock('../../api/models/JobTemplates');
describe('LaunchButton', () => {
JobTemplatesAPI.readLaunch.mockResolvedValue({

View File

@ -3,8 +3,8 @@ import { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Formik } from 'formik';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
import ContentError from '../ContentError';
import ContentLoading from '../ContentLoading';
import mergeExtraVars from './mergeExtraVars';
import useSteps from './useSteps';
import getSurveyValues from './getSurveyValues';
@ -36,7 +36,10 @@ function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
};
const surveyValues = getSurveyValues(values);
setValue('inventory_id', values.inventory?.id);
setValue('credentials', values.credentials?.map(c => c.id));
setValue(
'credentials',
values.credentials?.map(c => c.id)
);
setValue('job_type', values.job_type);
setValue('limit', values.limit);
setValue('job_tags', values.job_tags);

View File

@ -1,6 +1,9 @@
import React from 'react';
import { act, isElementOfType } from 'react-dom/test-utils';
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import LaunchPrompt from './LaunchPrompt';
import InventoryStep from './steps/InventoryStep';
import CredentialsStep from './steps/CredentialsStep';
@ -11,12 +14,12 @@ import {
CredentialsAPI,
CredentialTypesAPI,
JobTemplatesAPI,
} from '@api';
} from '../../api';
jest.mock('@api/models/Inventories');
jest.mock('@api/models/CredentialTypes');
jest.mock('@api/models/Credentials');
jest.mock('@api/models/JobTemplates');
jest.mock('../../api/models/Inventories');
jest.mock('../../api/models/CredentialTypes');
jest.mock('../../api/models/Credentials');
jest.mock('../../api/models/JobTemplates');
let config;
const resource = {

View File

@ -1,18 +1,19 @@
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 { ToolbarItem } from '@patternfly/react-core';
import { CredentialsAPI, CredentialTypesAPI } from '@api';
import AnsibleSelect from '@components/AnsibleSelect';
import OptionsList from '@components/OptionsList';
import ContentLoading from '@components/ContentLoading';
import CredentialChip from '@components/CredentialChip';
import ContentError from '@components/ContentError';
import { getQSConfig, parseQueryString } from '@util/qs';
import useRequest from '@util/useRequest';
import { required } from '@util/validators';
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
import AnsibleSelect from '../../AnsibleSelect';
import OptionsList from '../../OptionsList';
import ContentLoading from '../../ContentLoading';
import CredentialChip from '../../CredentialChip';
import ContentError from '../../ContentError';
import { getQSConfig, parseQueryString } from '../../../util/qs';
import useRequest from '../../../util/useRequest';
import { required } from '../../../util/validators';
const QS_CONFIG = getQSConfig('credential', {
page: 1,

View File

@ -1,12 +1,12 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Formik } from 'formik';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import CredentialsStep from './CredentialsStep';
import { CredentialsAPI, CredentialTypesAPI } from '@api';
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
jest.mock('@api/models/CredentialTypes');
jest.mock('@api/models/Credentials');
jest.mock('../../../api/models/CredentialTypes');
jest.mock('../../../api/models/Credentials');
const types = [
{ id: 1, kind: 'ssh', name: 'SSH' },

View File

@ -3,13 +3,13 @@ import { useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import { InventoriesAPI } from '@api';
import { getQSConfig, parseQueryString } from '@util/qs';
import useRequest from '@util/useRequest';
import OptionsList from '@components/OptionsList';
import ContentLoading from '@components/ContentLoading';
import ContentError from '@components/ContentError';
import { required } from '@util/validators';
import { InventoriesAPI } from '../../../api';
import { getQSConfig, parseQueryString } from '../../../util/qs';
import useRequest from '../../../util/useRequest';
import OptionsList from '../../OptionsList';
import ContentLoading from '../../ContentLoading';
import ContentError from '../../ContentError';
import { required } from '../../../util/validators';
const QS_CONFIG = getQSConfig('inventory', {
page: 1,

View File

@ -1,11 +1,11 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Formik } from 'formik';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import InventoryStep from './InventoryStep';
import { InventoriesAPI } from '@api';
import { InventoriesAPI } from '../../../api';
jest.mock('@api/models/Inventories');
jest.mock('../../../api/models/Inventories');
const inventories = [
{ id: 1, name: 'inv one', url: '/inventories/1' },

View File

@ -3,11 +3,11 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import { Form, FormGroup, Switch } from '@patternfly/react-core';
import FormField, { FieldTooltip } from '@components/FormField';
import { TagMultiSelect } from '@components/MultiSelect';
import AnsibleSelect from '@components/AnsibleSelect';
import { VariablesField } from '@components/CodeMirrorInput';
import styled from 'styled-components';
import FormField, { FieldTooltip } from '../../FormField';
import { TagMultiSelect } from '../../MultiSelect';
import AnsibleSelect from '../../AnsibleSelect';
import { VariablesField } from '../../CodeMirrorInput';
const FieldHeader = styled.div`
display: flex;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Formik } from 'formik';
import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
import OtherPromptsStep from './OtherPromptsStep';
describe('OtherPromptsStep', () => {

View File

@ -1,7 +1,7 @@
import React from 'react';
import { useFormikContext } from 'formik';
import yaml from 'js-yaml';
import PromptDetail from '@components/PromptDetail';
import PromptDetail from '../../PromptDetail';
import mergeExtraVars, { maskPasswords } from '../mergeExtraVars';
import getSurveyValues from '../getSurveyValues';

View File

@ -8,8 +8,8 @@ import {
SelectOption,
SelectVariant,
} from '@patternfly/react-core';
import FormField, { FieldTooltip } from '@components/FormField';
import AnsibleSelect from '@components/AnsibleSelect';
import FormField, { FieldTooltip } from '../../FormField';
import AnsibleSelect from '../../AnsibleSelect';
import {
required,
minMaxValue,
@ -17,8 +17,8 @@ import {
minLength,
integer,
combine,
} from '@util/validators';
import { Survey } from '@types';
} from '../../../util/validators';
import { Survey } from '../../../types';
function SurveyStep({ survey, i18n }) {
const fieldTypes = {

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react';
import { t } from '@lingui/macro';
import useRequest from '@util/useRequest';
import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
import useRequest from '../../../util/useRequest';
import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '../../../api';
import SurveyStep from './SurveyStep';
import StepName from './StepName';

View File

@ -6,7 +6,7 @@ import {
DataToolbar,
DataToolbarContent,
} from '@patternfly/react-core/dist/umd/experimental';
import DataListToolbar from '@components/DataListToolbar';
import DataListToolbar from '../DataListToolbar';
import {
encodeNonDefaultQueryString,
@ -14,8 +14,8 @@ import {
mergeParams,
replaceParams,
removeParams,
} from '@util/qs';
import { QSConfig, SearchColumns, SortColumns } from '@types';
} from '../../util/qs';
import { QSConfig, SearchColumns, SortColumns } from '../../types';
const EmptyStateControlsWrapper = styled.div`
display: flex;

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