diff --git a/awx/ui_next/package-lock.json b/awx/ui_next/package-lock.json index 4f294b6abd..772303d165 100644 --- a/awx/ui_next/package-lock.json +++ b/awx/ui_next/package-lock.json @@ -4910,6 +4910,201 @@ } } }, + "@jest/transform": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", + "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.3", + "jest-haste-map": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-util": "^25.1.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-regex-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", + "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", + "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@lingui/babel-plugin-extract-messages": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-2.7.4.tgz", @@ -5260,6 +5455,15 @@ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, + "@types/yargs": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "@types/yargs-parser": { "version": "15.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", @@ -6330,6 +6534,73 @@ } } }, + "babel-jest": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", + "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", + "dev": true, + "requires": { + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.1.0", + "chalk": "^3.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "babel-loader": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", @@ -6407,6 +6678,15 @@ "test-exclude": "^6.0.0" } }, + "babel-plugin-jest-hoist": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", + "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, "babel-plugin-macros": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.4.2.tgz", @@ -6451,6 +6731,17 @@ } } }, + "babel-preset-jest": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", + "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-bigint": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^25.1.0" + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -14622,6 +14913,99 @@ "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", "dev": true }, + "jest-haste-map": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", + "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", + "dev": true, + "requires": { + "@jest/types": "^25.1.0", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.3", + "jest-serializer": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "jest-jasmine2": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz", @@ -15941,6 +16325,12 @@ } } }, + "jest-serializer": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", + "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==", + "dev": true + }, "jest-snapshot": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz", @@ -16239,6 +16629,70 @@ } } }, + "jest-util": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", + "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "dev": true, + "requires": { + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "jest-validate": { "version": "23.6.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", diff --git a/awx/ui_next/src/components/LaunchButton/LaunchButton.jsx b/awx/ui_next/src/components/LaunchButton/LaunchButton.jsx index a99a38cf69..878945f8d8 100644 --- a/awx/ui_next/src/components/LaunchButton/LaunchButton.jsx +++ b/awx/ui_next/src/components/LaunchButton/LaunchButton.jsx @@ -15,6 +15,7 @@ import { WorkflowJobsAPI, WorkflowJobTemplatesAPI, } from '@api'; +import LaunchPrompt from '@components/LaunchPrompt'; function canLaunchWithoutPrompt(launchData) { return ( @@ -24,7 +25,8 @@ function canLaunchWithoutPrompt(launchData) { !launchData.ask_limit_on_launch && !launchData.ask_scm_branch_on_launch && !launchData.survey_enabled && - launchData.variables_needed_to_start.length === 0 + (!launchData.variables_needed_to_start || + launchData.variables_needed_to_start.length === 0) ); } @@ -39,11 +41,13 @@ class LaunchButton extends React.Component { super(props); this.state = { - launchError: null, - promptError: false, + showLaunchPrompt: false, + launchConfig: null, + launchError: false, }; this.handleLaunch = this.handleLaunch.bind(this); + this.launchWithParams = this.launchWithParams.bind(this); this.handleRelaunch = this.handleRelaunch.bind(this); this.handleLaunchErrorClose = this.handleLaunchErrorClose.bind(this); this.handlePromptErrorClose = this.handlePromptErrorClose.bind(this); @@ -54,41 +58,50 @@ class LaunchButton extends React.Component { } handlePromptErrorClose() { - this.setState({ promptError: false }); + this.setState({ showLaunchPrompt: false }); } async handleLaunch() { - const { history, resource } = this.props; - + const { resource } = this.props; const readLaunch = resource.type === 'workflow_job_template' ? WorkflowJobTemplatesAPI.readLaunch(resource.id) : JobTemplatesAPI.readLaunch(resource.id); - - const launchJob = - resource.type === 'workflow_job_template' - ? WorkflowJobTemplatesAPI.launch(resource.id) - : JobTemplatesAPI.launch(resource.id); - try { const { data: launchConfig } = await readLaunch; if (canLaunchWithoutPrompt(launchConfig)) { - const { data: job } = await launchJob; - - history.push( - `/${ - resource.type === 'workflow_job_template' ? 'jobs/workflow' : 'jobs' - }/${job.id}/output` - ); + this.launchWithParams(null); } else { - this.setState({ promptError: true }); + this.setState({ + showLaunchPrompt: true, + launchConfig, + }); } } catch (err) { this.setState({ launchError: err }); } } + async launchWithParams(params) { + try { + const { history, resource } = this.props; + const jobPromise = + resource.type === 'workflow_job_template' + ? WorkflowJobTemplatesAPI.launch(resource.id, params) + : JobTemplatesAPI.launch(resource.id, params); + + const { data: job } = await jobPromise; + history.push( + `/${ + resource.type === 'workflow_job_template' ? 'jobs/workflow' : 'jobs' + }/${job.id}/output` + ); + } catch (launchError) { + this.setState({ launchError }); + } + } + async handleRelaunch() { const { history, resource } = this.props; @@ -125,7 +138,12 @@ class LaunchButton extends React.Component { const { data: job } = await relaunch; history.push(`/jobs/${job.id}/output`); } else { - this.setState({ promptError: true }); + // TODO: restructure (async?) to send launch command after prompts + // TODO: does relaunch need different prompt treatment than launch? + this.setState({ + showLaunchPrompt: true, + launchConfig: relaunchConfig, + }); } } catch (err) { this.setState({ launchError: err }); @@ -133,8 +151,8 @@ class LaunchButton extends React.Component { } render() { - const { launchError, promptError } = this.state; - const { i18n, children } = this.props; + const { launchError, showLaunchPrompt, launchConfig } = this.state; + const { resource, i18n, children } = this.props; return ( {children({ @@ -152,17 +170,13 @@ class LaunchButton extends React.Component { )} - {promptError && ( - - {i18n._( - t`Launching jobs with promptable fields is not supported at this time.` - )} - + {showLaunchPrompt && ( + this.setState({ showLaunchPrompt: false })} + /> )} ); diff --git a/awx/ui_next/src/components/LaunchButton/LaunchButton.test.jsx b/awx/ui_next/src/components/LaunchButton/LaunchButton.test.jsx index b9bd3f7e53..8db633fd8c 100644 --- a/awx/ui_next/src/components/LaunchButton/LaunchButton.test.jsx +++ b/awx/ui_next/src/components/LaunchButton/LaunchButton.test.jsx @@ -30,7 +30,9 @@ describe('LaunchButton', () => { id: 1, type: 'job_template', }; + afterEach(() => jest.clearAllMocks()); + test('renders the expected content', () => { const wrapper = mountWithContexts( {children} @@ -60,9 +62,10 @@ describe('LaunchButton', () => { button.prop('onClick')(); expect(JobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1); await sleep(0); - expect(JobTemplatesAPI.launch).toHaveBeenCalledWith(1); + expect(JobTemplatesAPI.launch).toHaveBeenCalledWith(1, null); expect(history.location.pathname).toEqual('/jobs/9000/output'); }); + test('should launch the correct job type', async () => { WorkflowJobTemplatesAPI.readLaunch.mockResolvedValue({ data: { @@ -72,7 +75,7 @@ describe('LaunchButton', () => { const history = createMemoryHistory({ initialEntries: ['/jobs/9000'], }); - JobTemplatesAPI.launch.mockResolvedValue({ + WorkflowJobTemplatesAPI.launch.mockResolvedValue({ data: { id: 9000, }, @@ -96,9 +99,10 @@ describe('LaunchButton', () => { button.prop('onClick')(); expect(WorkflowJobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1); await sleep(0); - expect(WorkflowJobTemplatesAPI.launch).toHaveBeenCalledWith(1); - expect(history.location.pathname).toEqual('/jobs/9000'); + expect(WorkflowJobTemplatesAPI.launch).toHaveBeenCalledWith(1, null); + expect(history.location.pathname).toEqual('/jobs/workflow/9000/output'); }); + test('displays error modal after unsuccessful launch', async () => { const wrapper = mountWithContexts( {children} diff --git a/awx/ui_next/src/components/LaunchPrompt/CredentialsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/CredentialsStep.jsx new file mode 100644 index 0000000000..10872e311c --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/CredentialsStep.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function CredentialsStep() { + return
; +} + +export default CredentialsStep; diff --git a/awx/ui_next/src/components/LaunchPrompt/InventoryStep.jsx b/awx/ui_next/src/components/LaunchPrompt/InventoryStep.jsx new file mode 100644 index 0000000000..696dc445bc --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/InventoryStep.jsx @@ -0,0 +1,86 @@ +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 { InventoriesAPI } from '@api'; +import { getQSConfig, parseQueryString } from '@util/qs'; +import useRequest from '@util/useRequest'; +import OptionsList from '@components/OptionsList'; +import ContentLoading from '@components/ContentLoading'; + +const QS_CONFIG = getQSConfig('inventory', { + page: 1, + page_size: 5, + order_by: 'name', +}); + +function InventoryStep({ i18n }) { + const history = useHistory(); + const [field, , helpers] = useField('inventory'); + + const { + isLoading, + // error, + result: { inventories, count }, + request: fetchInventories, + } = useRequest( + useCallback(async () => { + const params = parseQueryString(QS_CONFIG, history.location.search); + const { data } = await InventoriesAPI.read(params); + return { + inventories: data.results, + count: data.count, + }; + }, [history.location]), + { + count: 0, + inventories: [], + } + ); + + useEffect(() => { + fetchInventories(); + }, [fetchInventories]); + + if (isLoading) { + return ; + } + + return ( + field.onChange(null)} + /> + ); +} + +export default withI18n()(InventoryStep); diff --git a/awx/ui_next/src/components/LaunchPrompt/InventoryStep.test.jsx b/awx/ui_next/src/components/LaunchPrompt/InventoryStep.test.jsx new file mode 100644 index 0000000000..4bac24478c --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/InventoryStep.test.jsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { Formik } from 'formik'; +import { mountWithContexts } from '@testUtils/enzymeHelpers'; +import InventoryStep from './InventoryStep'; +import { InventoriesAPI } from '@api'; + +jest.mock('@api/models/Inventories'); + +const inventories = [ + { id: 1, name: 'inv one', url: '/inventories/1' }, + { id: 2, name: 'inv two', url: '/inventories/2' }, + { id: 3, name: 'inv three', url: '/inventories/3' }, +]; + +describe('InventoryStep', () => { + beforeEach(() => { + InventoriesAPI.read.mockResolvedValue({ + data: { + results: inventories, + count: 3, + }, + }); + }); + + test('should load inventories', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + + + ); + }); + wrapper.update(); + + expect(InventoriesAPI.read).toHaveBeenCalled(); + expect(wrapper.find('OptionsList').prop('options')).toEqual(inventories); + }); +}); diff --git a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx new file mode 100644 index 0000000000..e4685262ec --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { Wizard } from '@patternfly/react-core'; +import { withI18n } from '@lingui/react'; +import { t } from '@lingui/macro'; +import { Formik } from 'formik'; +import InventoryStep from './InventoryStep'; +import CredentialsStep from './CredentialsStep'; +import OtherPromptsStep from './OtherPromptsStep'; +import SurveyStep from './SurveyStep'; +import PreviewStep from './PreviewStep'; + +function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) { + const steps = []; + const initialValues = {}; + if (config.ask_inventory_on_launch) { + initialValues.inventory = resource?.summary_fields?.inventory || null; + steps.push({ + name: i18n._(t`Inventory`), + component: , + }); + } + // TODO: match old UI Logic: + // if (vm.promptDataClone.launchConf.ask_credential_on_launch || + // (_.has(vm, 'promptDataClone.prompts.credentials.passwords.vault') && + // vm.promptDataClone.prompts.credentials.passwords.vault.length > 0) || + // _.has(vm, 'promptDataClone.prompts.credentials.passwords.ssh_key_unlock') || + // _.has(vm, 'promptDataClone.prompts.credentials.passwords.become_password') || + // _.has(vm, 'promptDataClone.prompts.credentials.passwords.ssh_password') + // ) { + if (config.ask_credential_on_launch) { + initialValues.credentials = resource?.summary_fields?.credentials || []; + steps.push({ + name: i18n._(t`Credential`), + component: , + }); + } + if ( + config.ask_scm_branch_on_launch || + (config.ask_variables_on_launch && !config.ignore_ask_variables) || + config.ask_tags_on_launch || + config.ask_diff_mode_on_launch || + config.ask_skip_tags_on_launch || + config.ask_job_type_on_launch || + config.ask_limit_on_launch || + config.ask_verbosity_on_launch + ) { + steps.push({ + name: i18n._(t`Other Prompts`), + component: , + }); + } + if (config.survey_enabled) { + steps.push({ + name: i18n._(t`Survey`), + component: , + }); + } + steps.push({ + name: i18n._(t`Preview`), + component: , + nextButtonText: i18n._(t`Launch`), + }); + + const submit = values => { + const postValues = {}; + if (values.inventory) { + postValues.inventory_id = values.inventory.id; + } + onLaunch(postValues); + }; + + return ( + + {({ handleSubmit }) => ( + + )} + + ); +} + +export { LaunchPrompt as _LaunchPrompt }; +export default withI18n()(LaunchPrompt); diff --git a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.test.jsx b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.test.jsx new file mode 100644 index 0000000000..edbb0cd7dc --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.test.jsx @@ -0,0 +1,100 @@ +import React from 'react'; +import { act, isElementOfType } from 'react-dom/test-utils'; +import { mountWithContexts } from '@testUtils/enzymeHelpers'; +import LaunchPrompt from './LaunchPrompt'; +import InventoryStep from './InventoryStep'; +import PreviewStep from './PreviewStep'; +import { InventoriesAPI } from '@api'; + +jest.mock('@api/models/Inventories'); + +let config; +const resource = { + id: 1, + type: 'job_template', +}; +const noop = () => {}; + +describe('LaunchPrompt', () => { + beforeEach(() => { + InventoriesAPI.read.mockResolvedValue({ + data: { + results: [{ id: 1, name: 'foo', url: '/inventories/1' }], + count: 1, + }, + }); + + config = { + can_start_without_user_input: false, + passwords_needed_to_start: [], + ask_scm_branch_on_launch: false, + ask_variables_on_launch: false, + ask_tags_on_launch: false, + ask_diff_mode_on_launch: false, + ask_skip_tags_on_launch: false, + ask_job_type_on_launch: false, + ask_limit_on_launch: false, + ask_verbosity_on_launch: false, + ask_inventory_on_launch: false, + ask_credential_on_launch: false, + survey_enabled: false, + variables_needed_to_start: [], + credential_needed_to_start: false, + inventory_needed_to_start: false, + job_template_data: { name: 'JT with prompts', id: 25, description: '' }, + }; + }); + + afterEach(() => jest.clearAllMocks()); + + test('should render Wizard with all steps', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); + const steps = wrapper.find('Wizard').prop('steps'); + + expect(steps).toHaveLength(5); + expect(steps[0].name).toEqual('Inventory'); + expect(steps[1].name).toEqual('Credential'); + expect(steps[2].name).toEqual('Other Prompts'); + expect(steps[3].name).toEqual('Survey'); + expect(steps[4].name).toEqual('Preview'); + }); + + test('should add inventory step', async () => { + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + ); + }); + const steps = wrapper.find('Wizard').prop('steps'); + + expect(steps).toHaveLength(2); + expect(steps[0].name).toEqual('Inventory'); + expect(isElementOfType(steps[0].component, InventoryStep)).toEqual(true); + expect(isElementOfType(steps[1].component, PreviewStep)).toEqual(true); + }); +}); diff --git a/awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.jsx new file mode 100644 index 0000000000..c0b8e6ec14 --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function InventoryStep() { + return
; +} + +export default InventoryStep; diff --git a/awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx b/awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx new file mode 100644 index 0000000000..b681a402bf --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function PreviewStep() { + return
Preview of selected values will appear here
; +} + +export default PreviewStep; diff --git a/awx/ui_next/src/components/LaunchPrompt/SurveyStep.jsx b/awx/ui_next/src/components/LaunchPrompt/SurveyStep.jsx new file mode 100644 index 0000000000..c0b8e6ec14 --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/SurveyStep.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function InventoryStep() { + return
; +} + +export default InventoryStep; diff --git a/awx/ui_next/src/components/LaunchPrompt/index.js b/awx/ui_next/src/components/LaunchPrompt/index.js new file mode 100644 index 0000000000..78a6912d1f --- /dev/null +++ b/awx/ui_next/src/components/LaunchPrompt/index.js @@ -0,0 +1 @@ +export { default } from './LaunchPrompt'; diff --git a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx index 72a587135f..50cf3c27e9 100644 --- a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx +++ b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx @@ -9,7 +9,7 @@ import { getQSConfig, parseQueryString, mergeParams } from '@util/qs'; import { FieldTooltip } from '@components/FormField'; import { FormGroup } from '@patternfly/react-core'; import Lookup from '@components/Lookup'; -import OptionsList from './shared/OptionsList'; +import OptionsList from '@components/OptionsList'; import LookupErrorMessage from './shared/LookupErrorMessage'; const QS_CONFIG = getQSConfig('credentials', { diff --git a/awx/ui_next/src/components/Lookup/InstanceGroupsLookup.jsx b/awx/ui_next/src/components/Lookup/InstanceGroupsLookup.jsx index f0c88576ca..d794ed252c 100644 --- a/awx/ui_next/src/components/Lookup/InstanceGroupsLookup.jsx +++ b/awx/ui_next/src/components/Lookup/InstanceGroupsLookup.jsx @@ -7,8 +7,8 @@ import { FormGroup } from '@patternfly/react-core'; import { InstanceGroupsAPI } from '@api'; import { getQSConfig, parseQueryString } from '@util/qs'; import { FieldTooltip } from '@components/FormField'; +import OptionsList from '@components/OptionsList'; import Lookup from './Lookup'; -import OptionsList from './shared/OptionsList'; import LookupErrorMessage from './shared/LookupErrorMessage'; const QS_CONFIG = getQSConfig('instance_groups', { diff --git a/awx/ui_next/src/components/Lookup/InventoryLookup.jsx b/awx/ui_next/src/components/Lookup/InventoryLookup.jsx index c80b0040fe..92815d943d 100644 --- a/awx/ui_next/src/components/Lookup/InventoryLookup.jsx +++ b/awx/ui_next/src/components/Lookup/InventoryLookup.jsx @@ -6,8 +6,8 @@ import { t } from '@lingui/macro'; import { InventoriesAPI } from '@api'; import { Inventory } from '@types'; import Lookup from '@components/Lookup'; +import OptionsList from '@components/OptionsList'; import { getQSConfig, parseQueryString } from '@util/qs'; -import OptionsList from './shared/OptionsList'; import LookupErrorMessage from './shared/LookupErrorMessage'; const QS_CONFIG = getQSConfig('inventory', { diff --git a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.jsx b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.jsx index 1bc80341b9..58bdf359cb 100644 --- a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.jsx +++ b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.jsx @@ -7,9 +7,9 @@ import { ToolbarItem, Alert } from '@patternfly/react-core'; import { CredentialsAPI, CredentialTypesAPI } from '@api'; import AnsibleSelect from '@components/AnsibleSelect'; import CredentialChip from '@components/CredentialChip'; +import OptionsList from '@components/OptionsList'; import { getQSConfig, parseQueryString } from '@util/qs'; import Lookup from './Lookup'; -import OptionsList from './shared/OptionsList'; const QS_CONFIG = getQSConfig('credentials', { page: 1, diff --git a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx index 7d208fb588..bf5a77aa0a 100644 --- a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx +++ b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx @@ -7,8 +7,8 @@ import { OrganizationsAPI } from '@api'; import { Organization } from '@types'; import { FormGroup } from '@patternfly/react-core'; import { getQSConfig, parseQueryString } from '@util/qs'; +import OptionsList from '@components/OptionsList'; import Lookup from './Lookup'; -import OptionsList from './shared/OptionsList'; import LookupErrorMessage from './shared/LookupErrorMessage'; const QS_CONFIG = getQSConfig('organizations', { diff --git a/awx/ui_next/src/components/Lookup/ProjectLookup.jsx b/awx/ui_next/src/components/Lookup/ProjectLookup.jsx index 1a16337e0f..4bd30a3db3 100644 --- a/awx/ui_next/src/components/Lookup/ProjectLookup.jsx +++ b/awx/ui_next/src/components/Lookup/ProjectLookup.jsx @@ -7,9 +7,9 @@ import { FormGroup } from '@patternfly/react-core'; import { ProjectsAPI } from '@api'; import { Project } from '@types'; import { FieldTooltip } from '@components/FormField'; +import OptionsList from '@components/OptionsList'; import { getQSConfig, parseQueryString } from '@util/qs'; import Lookup from './Lookup'; -import OptionsList from './shared/OptionsList'; import LookupErrorMessage from './shared/LookupErrorMessage'; const QS_CONFIG = getQSConfig('project', { diff --git a/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx b/awx/ui_next/src/components/OptionsList/OptionsList.jsx similarity index 92% rename from awx/ui_next/src/components/Lookup/shared/OptionsList.jsx rename to awx/ui_next/src/components/OptionsList/OptionsList.jsx index da0e1065e6..e19e85a97c 100644 --- a/awx/ui_next/src/components/Lookup/shared/OptionsList.jsx +++ b/awx/ui_next/src/components/OptionsList/OptionsList.jsx @@ -11,10 +11,10 @@ import { import styled from 'styled-components'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; -import SelectedList from '../../SelectedList'; -import PaginatedDataList from '../../PaginatedDataList'; -import CheckboxListItem from '../../CheckboxListItem'; -import DataListToolbar from '../../DataListToolbar'; +import SelectedList from '../SelectedList'; +import PaginatedDataList from '../PaginatedDataList'; +import CheckboxListItem from '../CheckboxListItem'; +import DataListToolbar from '../DataListToolbar'; import { QSConfig, SearchColumns, SortColumns } from '@types'; const ModalList = styled.div` diff --git a/awx/ui_next/src/components/Lookup/shared/OptionsList.test.jsx b/awx/ui_next/src/components/OptionsList/OptionsList.test.jsx similarity index 100% rename from awx/ui_next/src/components/Lookup/shared/OptionsList.test.jsx rename to awx/ui_next/src/components/OptionsList/OptionsList.test.jsx diff --git a/awx/ui_next/src/components/OptionsList/index.js b/awx/ui_next/src/components/OptionsList/index.js new file mode 100644 index 0000000000..477d3c08c3 --- /dev/null +++ b/awx/ui_next/src/components/OptionsList/index.js @@ -0,0 +1 @@ +export { default } from './OptionsList'; diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/AssociateModal.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/AssociateModal.jsx index 4efc5a5d00..493056b50e 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/AssociateModal.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/AssociateModal.jsx @@ -3,7 +3,7 @@ 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/Lookup/shared/OptionsList'; +import OptionsList from '@components/OptionsList'; import useRequest from '@util/useRequest'; import { getQSConfig, parseQueryString } from '@util/qs'; import useSelected from '@util/useSelected';