foreman_templates 7.0.1 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.babelrc +16 -0
- data/lib/foreman_templates/version.rb +1 -1
- data/package.json +68 -0
- data/webpack/ForemanTemplates.js +29 -0
- data/webpack/Routes.js +33 -0
- data/webpack/__mocks__/foremanReact/common/helpers.js +27 -0
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/forms/CommonForm.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/forms/Form.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/forms/TextField.js +2 -0
- data/webpack/__mocks__/foremanReact/redux/actions/common/forms.js +1 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +2 -0
- data/webpack/__tests__/__snapshots__/helpers.test.js.snap +5 -0
- data/webpack/__tests__/helpers.test.js +17 -0
- data/webpack/components/NewTemplateSync/NewTemplateSync.js +60 -0
- data/webpack/components/NewTemplateSync/NewTemplateSync.scss +19 -0
- data/webpack/components/NewTemplateSync/NewTemplateSyncActions.js +39 -0
- data/webpack/components/NewTemplateSync/NewTemplateSyncReducer.js +34 -0
- data/webpack/components/NewTemplateSync/NewTemplateSyncSelectors.js +7 -0
- data/webpack/components/NewTemplateSync/__fixtures__/templateSyncSettings.fixtures.js +71 -0
- data/webpack/components/NewTemplateSync/__tests__/NewTemplateSync.test.js +31 -0
- data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncReducer.test.js +55 -0
- data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncSelectors.test.js +28 -0
- data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSync.test.js.snap +53 -0
- data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncReducer.test.js.snap +74 -0
- data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncSelectors.test.js.snap +59 -0
- data/webpack/components/NewTemplateSync/components/ButtonTooltip.js +23 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js +145 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormConstants.js +1 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormSelectors.js +24 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncForm.test.js +42 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js +37 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncForm.test.js.snap +176 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncFormSelectors.test.js.snap +42 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/index.js +44 -0
- data/webpack/components/NewTemplateSync/components/SyncSettingField.js +54 -0
- data/webpack/components/NewTemplateSync/components/SyncSettingFields.js +69 -0
- data/webpack/components/NewTemplateSync/components/SyncTypeRadios.js +52 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/BlankOption.js +19 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/CheckboxField.js +15 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/FieldType.js +46 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/InputField.js +14 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/RenderField.js +74 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/SelectField.js +24 -0
- data/webpack/components/NewTemplateSync/components/TextButtonField/index.js +69 -0
- data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingField.test.js +34 -0
- data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingFields.test.js +33 -0
- data/webpack/components/NewTemplateSync/components/__tests__/SyncTypeRadios.test.js +20 -0
- data/webpack/components/NewTemplateSync/components/__tests__/TextButtonField.test.js +65 -0
- data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingField.test.js.snap +131 -0
- data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingFields.test.js.snap +94 -0
- data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncTypeRadios.test.js.snap +46 -0
- data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/TextButtonField.test.js.snap +112 -0
- data/webpack/components/NewTemplateSync/index.js +32 -0
- data/webpack/components/PageNotFound.js +13 -0
- data/webpack/components/PermissionDenied.js +33 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResult.js +61 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResult.scss +39 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResultActions.js +4 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResultHelpers.js +6 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResultReducer.js +33 -0
- data/webpack/components/TemplateSyncResult/TemplateSyncResultSelectors.js +1 -0
- data/webpack/components/TemplateSyncResult/__fixtures__/templateSyncResult.fixtures.js +86 -0
- data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResult.test.js +37 -0
- data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResultReducer.test.js +48 -0
- data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResult.test.js.snap +112 -0
- data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResultReducer.test.js.snap +88 -0
- data/webpack/components/TemplateSyncResult/components/EmptySyncResult.js +25 -0
- data/webpack/components/TemplateSyncResult/components/FinishedSyncResult.js +77 -0
- data/webpack/components/TemplateSyncResult/components/ListViewHeader.js +38 -0
- data/webpack/components/TemplateSyncResult/components/SyncResultList.js +41 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/EmptyInfoItem.js +16 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/IconInfoItem.js +21 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/InfoItem.js +34 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/LinkInfoItem.js +37 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/StringInfoItem.js +50 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/helpers.js +128 -0
- data/webpack/components/TemplateSyncResult/components/SyncedTemplate/index.js +33 -0
- data/webpack/components/TemplateSyncResult/components/__tests__/SyncResultList.test.js +27 -0
- data/webpack/components/TemplateSyncResult/components/__tests__/SyncedTemplate.test.js +30 -0
- data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncResultList.test.js.snap +102 -0
- data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncedTemplate.test.js.snap +548 -0
- data/webpack/components/TemplateSyncResult/index.js +13 -0
- data/webpack/consts.js +6 -0
- data/webpack/index.js +11 -0
- data/webpack/reducer.js +6 -0
- data/webpack/testSetup.js +11 -0
- data/webpack/withProtectedView.js +16 -0
- metadata +89 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 799e5dc7d9045fbb1bcb6571584f705e3965c324
|
|
4
|
+
data.tar.gz: 71e4088ec73d0f103ee812952acbe2333264eebc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 89b63e0f1f73daed9c3cdfd1d78092d6733656169370cf976590099c4263972ed274c1c9a5dddf7eb629b0b9e61207434f7bfb94664b5e62171e1e4f219c1295
|
|
7
|
+
data.tar.gz: 0ce7b7cd05ecbd305a16444d80e57ecc85251eff82d0eec8d36f29f49f311203308171831fb807461bed587f64635fc5c088dfa14abafbd7458cd2e5f9557236
|
data/.babelrc
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": ["env", "react"],
|
|
3
|
+
"plugins": [
|
|
4
|
+
"transform-class-properties",
|
|
5
|
+
"transform-object-rest-spread",
|
|
6
|
+
"transform-object-assign"
|
|
7
|
+
],
|
|
8
|
+
"env": {
|
|
9
|
+
"test": {
|
|
10
|
+
"presets": ["@theforeman/vendor-dev/babel.preset.js"]
|
|
11
|
+
},
|
|
12
|
+
"storybook": {
|
|
13
|
+
"presets": ["@theforeman/vendor-dev/babel.preset.js"]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
data/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "foreman_templates",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "This plugin will sync the contents of the Foreman Community Templates [repository](https://github.com/theforeman/community-templates/) (or a git repo of your choice) to your local Foreman instance",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"directories": {
|
|
7
|
+
"test": "test"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node node_modules/.bin/jest webpack",
|
|
11
|
+
"lint": "./node_modules/.bin/eslint -c .eslintrc webpack/"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/theforeman/foreman_templates.git"
|
|
16
|
+
},
|
|
17
|
+
"author": "The Foreman team",
|
|
18
|
+
"license": "GPL-3.0",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://projects.theforeman.org"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/theforeman/foreman_templates",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@theforeman/vendor": "^1.7.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@theforeman/vendor-dev": "^1.7.0",
|
|
28
|
+
"babel-eslint": "^8.2.1",
|
|
29
|
+
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
30
|
+
"babel-plugin-transform-object-assign": "^6.22.0",
|
|
31
|
+
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
|
32
|
+
"babel-preset-env": "^1.6.0",
|
|
33
|
+
"babel-preset-react": "^6.24.1",
|
|
34
|
+
"enzyme": "^3.7.0",
|
|
35
|
+
"enzyme-adapter-react-16": "^1.7.0",
|
|
36
|
+
"enzyme-to-json": "^3.3.5",
|
|
37
|
+
"eslint": "^4.18.1",
|
|
38
|
+
"eslint-config-airbnb": "^16.0.0",
|
|
39
|
+
"eslint-plugin-import": "^2.8.0",
|
|
40
|
+
"eslint-plugin-jest": "^21.2.0",
|
|
41
|
+
"eslint-plugin-jsx-a11y": "^6.0.2",
|
|
42
|
+
"eslint-plugin-patternfly-react": "^0.2.1",
|
|
43
|
+
"eslint-plugin-react": "^7.4.0",
|
|
44
|
+
"identity-obj-proxy": "^3.0.0",
|
|
45
|
+
"jest": "^23.6.0",
|
|
46
|
+
"prettier": "^1.16.4",
|
|
47
|
+
"react-redux-test-utils": "^0.1.1"
|
|
48
|
+
},
|
|
49
|
+
"jest": {
|
|
50
|
+
"verbose": true,
|
|
51
|
+
"moduleDirectories": [
|
|
52
|
+
"node_modules/@theforeman/vendor-core/node_modules",
|
|
53
|
+
"node_modules",
|
|
54
|
+
"webpack"
|
|
55
|
+
],
|
|
56
|
+
"setupFiles": [
|
|
57
|
+
"raf/polyfill",
|
|
58
|
+
"./webpack/testSetup.js"
|
|
59
|
+
],
|
|
60
|
+
"testPathIgnorePatterns": [
|
|
61
|
+
"/node_modules/",
|
|
62
|
+
"<rootDir>/foreman/"
|
|
63
|
+
],
|
|
64
|
+
"moduleNameMapper": {
|
|
65
|
+
"^.+\\.(css|scss)$": "identity-obj-proxy"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BrowserRouter as Router } from 'react-router-dom';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
|
|
5
|
+
import Routes from './Routes';
|
|
6
|
+
|
|
7
|
+
const ForemanTemplates = ({ data }) => (
|
|
8
|
+
<Router>
|
|
9
|
+
<Routes
|
|
10
|
+
apiUrls={data.apiUrls}
|
|
11
|
+
validationData={data.validationData}
|
|
12
|
+
editPaths={data.editPaths}
|
|
13
|
+
fileRepoStartWith={data.fileRepoStartWith}
|
|
14
|
+
userPermissions={data.userPermissions}
|
|
15
|
+
/>
|
|
16
|
+
</Router>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ForemanTemplates.propTypes = {
|
|
20
|
+
data: PropTypes.shape({
|
|
21
|
+
apiUrls: PropTypes.object,
|
|
22
|
+
validationData: PropTypes.object,
|
|
23
|
+
editPaths: PropTypes.object,
|
|
24
|
+
userPermissions: PropTypes.object,
|
|
25
|
+
fileRepoStartWith: PropTypes.array,
|
|
26
|
+
}).isRequired,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default ForemanTemplates;
|
data/webpack/Routes.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Route, Switch } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
import NewTemplateSync from './components/NewTemplateSync';
|
|
5
|
+
import TemplateSyncResult from './components/TemplateSyncResult';
|
|
6
|
+
import PageNotFound from './components/PageNotFound';
|
|
7
|
+
|
|
8
|
+
const links = [
|
|
9
|
+
{
|
|
10
|
+
title: 'New Template Sync',
|
|
11
|
+
path: 'template_syncs',
|
|
12
|
+
Component: NewTemplateSync,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: 'Template Sync Result',
|
|
16
|
+
path: 'template_syncs/result',
|
|
17
|
+
Component: TemplateSyncResult,
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default data => (
|
|
22
|
+
<Switch>
|
|
23
|
+
{links.map(({ path, Component }) => (
|
|
24
|
+
<Route
|
|
25
|
+
exact
|
|
26
|
+
key={path}
|
|
27
|
+
path={`/${path}`}
|
|
28
|
+
render={props => <Component {...props} {...data} />}
|
|
29
|
+
/>
|
|
30
|
+
))}
|
|
31
|
+
<Route component={PageNotFound} />
|
|
32
|
+
</Switch>
|
|
33
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { camelCase } from 'lodash';
|
|
2
|
+
|
|
3
|
+
export const propsToCamelCase = ob =>
|
|
4
|
+
propsToCase(camelCase, 'propsToCamelCase only takes objects', ob);
|
|
5
|
+
|
|
6
|
+
export const deepPropsToCamelCase = obj => {
|
|
7
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
8
|
+
return obj;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(obj)) {
|
|
11
|
+
return obj.map(deepPropsToCamelCase);
|
|
12
|
+
}
|
|
13
|
+
const transformed = propsToCamelCase(obj);
|
|
14
|
+
return Object.keys(transformed).reduce((memo, key) => {
|
|
15
|
+
memo[key] = deepPropsToCamelCase(transformed[key]);
|
|
16
|
+
return memo;
|
|
17
|
+
}, {});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const propsToCase = (casingFn, errorMsg, ob) => {
|
|
21
|
+
if (typeof ob !== 'object') throw Error(errorMsg);
|
|
22
|
+
|
|
23
|
+
return Object.keys(ob).reduce((memo, key) => {
|
|
24
|
+
memo[casingFn(key)] = ob[key];
|
|
25
|
+
return memo;
|
|
26
|
+
}, {});
|
|
27
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
|
|
3
|
+
import withProtectedView from '../withProtectedView';
|
|
4
|
+
|
|
5
|
+
const ProtectedComponent = () => <div>Protected component</div>;
|
|
6
|
+
|
|
7
|
+
const ProtectionComponent = () => <div>Protection component</div>;
|
|
8
|
+
|
|
9
|
+
const fixtures = {
|
|
10
|
+
'should return protected component': () =>
|
|
11
|
+
withProtectedView(ProtectedComponent, ProtectionComponent, () => true)(),
|
|
12
|
+
'should return protection component': () =>
|
|
13
|
+
withProtectedView(ProtectedComponent, ProtectionComponent, () => false)(),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('withProtectedView', () =>
|
|
17
|
+
testSelectorsSnapshotWithFixtures(fixtures));
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LoadingState } from 'patternfly-react';
|
|
3
|
+
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
|
|
6
|
+
import NewTemplateSyncForm from './components/NewTemplateSyncForm';
|
|
7
|
+
import './NewTemplateSync.scss';
|
|
8
|
+
|
|
9
|
+
class NewTemplateSync extends React.Component {
|
|
10
|
+
componentDidMount() {
|
|
11
|
+
const {
|
|
12
|
+
apiUrls: { syncSettingsUrl },
|
|
13
|
+
getSyncSettings,
|
|
14
|
+
} = this.props;
|
|
15
|
+
getSyncSettings(syncSettingsUrl);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
const {
|
|
20
|
+
apiUrls: { importUrl, exportUrl },
|
|
21
|
+
loadingSettings,
|
|
22
|
+
history,
|
|
23
|
+
validationData,
|
|
24
|
+
userPermissions,
|
|
25
|
+
} = this.props;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<LoadingState loading={loadingSettings}>
|
|
29
|
+
<PageLayout
|
|
30
|
+
header={__('Import or Export Templates')}
|
|
31
|
+
searchable={false}
|
|
32
|
+
>
|
|
33
|
+
<NewTemplateSyncForm
|
|
34
|
+
validationData={validationData}
|
|
35
|
+
importUrl={importUrl}
|
|
36
|
+
exportUrl={exportUrl}
|
|
37
|
+
history={history}
|
|
38
|
+
userPermissions={userPermissions}
|
|
39
|
+
/>
|
|
40
|
+
</PageLayout>
|
|
41
|
+
</LoadingState>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
NewTemplateSync.propTypes = {
|
|
47
|
+
getSyncSettings: PropTypes.func.isRequired,
|
|
48
|
+
apiUrls: PropTypes.object.isRequired,
|
|
49
|
+
userPermissions: PropTypes.object.isRequired,
|
|
50
|
+
history: PropTypes.object,
|
|
51
|
+
validationData: PropTypes.object,
|
|
52
|
+
loadingSettings: PropTypes.bool.isRequired,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
NewTemplateSync.defaultProps = {
|
|
56
|
+
validationData: {},
|
|
57
|
+
history: {},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default NewTemplateSync;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@import '~@theforeman/vendor/scss/variables';
|
|
2
|
+
|
|
3
|
+
.left-padded {
|
|
4
|
+
padding-left: 3%;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
#foreman-templates {
|
|
8
|
+
.loading-state-pf.loading-state-pf-lg {
|
|
9
|
+
padding-top: 5%;
|
|
10
|
+
}
|
|
11
|
+
// No need to hide content, see #26122
|
|
12
|
+
#main > #content {
|
|
13
|
+
display: block;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.blank-slate-pf {
|
|
17
|
+
padding-top: 5%;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import api from 'foremanReact/API';
|
|
2
|
+
import { deepPropsToCamelCase } from 'foremanReact/common/helpers';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
SYNC_SETTINGS_REQUEST,
|
|
6
|
+
SYNC_SETTINGS_SUCCESS,
|
|
7
|
+
SYNC_SETTINGS_FAILURE,
|
|
8
|
+
SYNC_RESULT_PAGINATION_CHANGE,
|
|
9
|
+
} from '../../consts';
|
|
10
|
+
|
|
11
|
+
import { initialState } from '../TemplateSyncResult/TemplateSyncResultReducer';
|
|
12
|
+
|
|
13
|
+
export const getSyncSettings = url => async dispatch => {
|
|
14
|
+
dispatch({ type: SYNC_SETTINGS_REQUEST });
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const { data } = await api.get(url);
|
|
18
|
+
dispatch({
|
|
19
|
+
type: SYNC_RESULT_PAGINATION_CHANGE,
|
|
20
|
+
payload: { pagination: initialState.pagination },
|
|
21
|
+
});
|
|
22
|
+
return dispatch({
|
|
23
|
+
type: SYNC_SETTINGS_SUCCESS,
|
|
24
|
+
payload: {
|
|
25
|
+
...deepPropsToCamelCase(data),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return dispatch(errorHandler(SYNC_SETTINGS_FAILURE, error));
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const errorHandler = (msg, err) => {
|
|
34
|
+
const error = {
|
|
35
|
+
errorMsg: 'Failed to fetch Settings for template sync from server.',
|
|
36
|
+
statusText: err.response.statusText,
|
|
37
|
+
};
|
|
38
|
+
return { type: msg, payload: { error } };
|
|
39
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
SYNC_SETTINGS_REQUEST,
|
|
5
|
+
SYNC_SETTINGS_SUCCESS,
|
|
6
|
+
SYNC_SETTINGS_FAILURE,
|
|
7
|
+
} from '../../consts';
|
|
8
|
+
|
|
9
|
+
export const initialState = Immutable({
|
|
10
|
+
loadingSettings: false,
|
|
11
|
+
importSettings: [],
|
|
12
|
+
exportSettings: [],
|
|
13
|
+
error: '',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const syncSettings = (state = initialState, action) => {
|
|
17
|
+
const { payload } = action;
|
|
18
|
+
switch (action.type) {
|
|
19
|
+
case SYNC_SETTINGS_REQUEST:
|
|
20
|
+
return state.set('loadingSettings', true);
|
|
21
|
+
case SYNC_SETTINGS_SUCCESS:
|
|
22
|
+
return state.merge({
|
|
23
|
+
loadingSettings: false,
|
|
24
|
+
importSettings: payload.results.import,
|
|
25
|
+
exportSettings: payload.results.export,
|
|
26
|
+
});
|
|
27
|
+
case SYNC_SETTINGS_FAILURE:
|
|
28
|
+
return state.merge({ error: payload.error, loadingSettings: false });
|
|
29
|
+
default:
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default syncSettings;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const newSyncState = state => state.foremanTemplates.syncSettings;
|
|
2
|
+
|
|
3
|
+
export const selectImportSettings = state => newSyncState(state).importSettings;
|
|
4
|
+
export const selectExportSettings = state => newSyncState(state).exportSettings;
|
|
5
|
+
export const selectLoadingSettings = state =>
|
|
6
|
+
newSyncState(state).loadingSettings;
|
|
7
|
+
export const selectError = state => newSyncState(state).error;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
|
2
|
+
|
|
3
|
+
export const associateSetting = Immutable({
|
|
4
|
+
id: 45,
|
|
5
|
+
value: 'new',
|
|
6
|
+
settingsType: 'string',
|
|
7
|
+
name: 'associate',
|
|
8
|
+
selection: [
|
|
9
|
+
{ value: 'new', label: 'New' },
|
|
10
|
+
{ value: 'never', label: 'Never' },
|
|
11
|
+
{ value: 'always', label: 'Always' },
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const forceSetting = Immutable({
|
|
16
|
+
id: 46,
|
|
17
|
+
value: false,
|
|
18
|
+
settingsType: 'bool',
|
|
19
|
+
name: 'force',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const importSettings = [associateSetting, forceSetting];
|
|
23
|
+
|
|
24
|
+
export const filterSetting = Immutable({
|
|
25
|
+
id: 47,
|
|
26
|
+
value: '',
|
|
27
|
+
settingsType: 'string',
|
|
28
|
+
name: 'filter',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const negateSetting = Immutable({
|
|
32
|
+
id: 48,
|
|
33
|
+
value: false,
|
|
34
|
+
settingsType: 'bool',
|
|
35
|
+
name: 'negate',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const repoSetting = Immutable({
|
|
39
|
+
id: 49,
|
|
40
|
+
value: 'https://github.com/theforeman/community-templates.git',
|
|
41
|
+
settingsType: 'string',
|
|
42
|
+
name: 'repo',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export const exportSettings = [filterSetting, negateSetting, repoSetting];
|
|
46
|
+
|
|
47
|
+
const registeredSettings = settings =>
|
|
48
|
+
settings.reduce((memo, item) => {
|
|
49
|
+
memo[item.name] = item;
|
|
50
|
+
return memo;
|
|
51
|
+
}, {});
|
|
52
|
+
|
|
53
|
+
export const registeredImportSettings = {
|
|
54
|
+
registeredFields: registeredSettings(importSettings),
|
|
55
|
+
};
|
|
56
|
+
export const registeredExportSettings = {
|
|
57
|
+
registeredFields: registeredSettings(exportSettings),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const initialValues = {
|
|
61
|
+
initial: importSettings.concat(exportSettings).reduce((memo, item) => {
|
|
62
|
+
memo[item.name] = item.value;
|
|
63
|
+
return memo;
|
|
64
|
+
}, {}),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const stateFactory = obj => ({
|
|
68
|
+
foremanTemplates: {
|
|
69
|
+
syncSettings: obj,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
|
|
2
|
+
|
|
3
|
+
import NewTemplateSync from '../NewTemplateSync';
|
|
4
|
+
|
|
5
|
+
jest.mock('foremanReact/routes/common/PageLayout/PageLayout');
|
|
6
|
+
|
|
7
|
+
const noop = () => {};
|
|
8
|
+
|
|
9
|
+
const commonFixture = {
|
|
10
|
+
apiUrls: {},
|
|
11
|
+
getSyncSettings: noop,
|
|
12
|
+
validationData: {},
|
|
13
|
+
userPermissions: {
|
|
14
|
+
import: true,
|
|
15
|
+
export: true,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const fixtures = {
|
|
20
|
+
'should render when loaded': {
|
|
21
|
+
loadingSettings: false,
|
|
22
|
+
...commonFixture,
|
|
23
|
+
},
|
|
24
|
+
'should render when loading': {
|
|
25
|
+
loadingSettings: true,
|
|
26
|
+
...commonFixture,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
describe('NewTemplateSync', () =>
|
|
31
|
+
testComponentSnapshotsWithFixtures(NewTemplateSync, fixtures));
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { testReducerSnapshotWithFixtures } from 'react-redux-test-utils';
|
|
2
|
+
|
|
3
|
+
import reducer, { initialState } from '../NewTemplateSyncReducer';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
importSettings,
|
|
7
|
+
exportSettings,
|
|
8
|
+
} from '../__fixtures__/templateSyncSettings.fixtures';
|
|
9
|
+
import {
|
|
10
|
+
SYNC_SETTINGS_REQUEST,
|
|
11
|
+
SYNC_SETTINGS_SUCCESS,
|
|
12
|
+
SYNC_SETTINGS_FAILURE,
|
|
13
|
+
} from '../../../consts';
|
|
14
|
+
|
|
15
|
+
const successPayload = {
|
|
16
|
+
results: {
|
|
17
|
+
import: importSettings,
|
|
18
|
+
export: exportSettings,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const fixtures = {
|
|
23
|
+
'should return initial state': {
|
|
24
|
+
state: initialState,
|
|
25
|
+
action: {
|
|
26
|
+
type: undefined,
|
|
27
|
+
payload: {},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
'should start loading on setting values request': {
|
|
31
|
+
state: initialState,
|
|
32
|
+
action: {
|
|
33
|
+
type: SYNC_SETTINGS_REQUEST,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
'should stop loading on setting values success': {
|
|
37
|
+
state: initialState.set('loadingSettings', true),
|
|
38
|
+
action: {
|
|
39
|
+
type: SYNC_SETTINGS_SUCCESS,
|
|
40
|
+
payload: successPayload,
|
|
41
|
+
},
|
|
42
|
+
'should stop loading on setting values error': {
|
|
43
|
+
state: initialState.set('loadingSettings', true),
|
|
44
|
+
action: {
|
|
45
|
+
type: SYNC_SETTINGS_FAILURE,
|
|
46
|
+
payload: {
|
|
47
|
+
error: 'Failed to fetch setting values',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
describe('NewTemplateSyncReducer', () =>
|
|
55
|
+
testReducerSnapshotWithFixtures(reducer, fixtures));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
importSettings,
|
|
5
|
+
exportSettings,
|
|
6
|
+
stateFactory,
|
|
7
|
+
} from '../__fixtures__/templateSyncSettings.fixtures';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
selectImportSettings,
|
|
11
|
+
selectExportSettings,
|
|
12
|
+
selectLoadingSettings,
|
|
13
|
+
selectError,
|
|
14
|
+
} from '../NewTemplateSyncSelectors';
|
|
15
|
+
|
|
16
|
+
const fixtures = {
|
|
17
|
+
'should return import settings': () =>
|
|
18
|
+
selectImportSettings(stateFactory({ importSettings })),
|
|
19
|
+
'should return export settings': () =>
|
|
20
|
+
selectExportSettings(stateFactory({ exportSettings })),
|
|
21
|
+
'should return loading settings': () =>
|
|
22
|
+
selectLoadingSettings(stateFactory({ loadingSettings: true })),
|
|
23
|
+
'should return loading error': () =>
|
|
24
|
+
selectError(stateFactory({ error: 'Error' })),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
describe('NewTemplateSyncSelectors', () =>
|
|
28
|
+
testSelectorsSnapshotWithFixtures(fixtures));
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`NewTemplateSync should render when loaded 1`] = `
|
|
4
|
+
<LoadingState
|
|
5
|
+
additionalClasses=""
|
|
6
|
+
loading={false}
|
|
7
|
+
loadingText="Loading"
|
|
8
|
+
size="lg"
|
|
9
|
+
timeout={300}
|
|
10
|
+
>
|
|
11
|
+
<PageLayout
|
|
12
|
+
header="Import or Export Templates"
|
|
13
|
+
searchable={false}
|
|
14
|
+
>
|
|
15
|
+
<Connect(ReduxForm)
|
|
16
|
+
history={Object {}}
|
|
17
|
+
userPermissions={
|
|
18
|
+
Object {
|
|
19
|
+
"export": true,
|
|
20
|
+
"import": true,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
validationData={Object {}}
|
|
24
|
+
/>
|
|
25
|
+
</PageLayout>
|
|
26
|
+
</LoadingState>
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
exports[`NewTemplateSync should render when loading 1`] = `
|
|
30
|
+
<LoadingState
|
|
31
|
+
additionalClasses=""
|
|
32
|
+
loading={true}
|
|
33
|
+
loadingText="Loading"
|
|
34
|
+
size="lg"
|
|
35
|
+
timeout={300}
|
|
36
|
+
>
|
|
37
|
+
<PageLayout
|
|
38
|
+
header="Import or Export Templates"
|
|
39
|
+
searchable={false}
|
|
40
|
+
>
|
|
41
|
+
<Connect(ReduxForm)
|
|
42
|
+
history={Object {}}
|
|
43
|
+
userPermissions={
|
|
44
|
+
Object {
|
|
45
|
+
"export": true,
|
|
46
|
+
"import": true,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
validationData={Object {}}
|
|
50
|
+
/>
|
|
51
|
+
</PageLayout>
|
|
52
|
+
</LoadingState>
|
|
53
|
+
`;
|