foreman_templates 7.0.1 → 7.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.babelrc +16 -0
  3. data/lib/foreman_templates/version.rb +1 -1
  4. data/package.json +68 -0
  5. data/webpack/ForemanTemplates.js +29 -0
  6. data/webpack/Routes.js +33 -0
  7. data/webpack/__mocks__/foremanReact/common/helpers.js +27 -0
  8. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
  9. data/webpack/__mocks__/foremanReact/components/common/forms/CommonForm.js +2 -0
  10. data/webpack/__mocks__/foremanReact/components/common/forms/Form.js +2 -0
  11. data/webpack/__mocks__/foremanReact/components/common/forms/TextField.js +2 -0
  12. data/webpack/__mocks__/foremanReact/redux/actions/common/forms.js +1 -0
  13. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +2 -0
  14. data/webpack/__tests__/__snapshots__/helpers.test.js.snap +5 -0
  15. data/webpack/__tests__/helpers.test.js +17 -0
  16. data/webpack/components/NewTemplateSync/NewTemplateSync.js +60 -0
  17. data/webpack/components/NewTemplateSync/NewTemplateSync.scss +19 -0
  18. data/webpack/components/NewTemplateSync/NewTemplateSyncActions.js +39 -0
  19. data/webpack/components/NewTemplateSync/NewTemplateSyncReducer.js +34 -0
  20. data/webpack/components/NewTemplateSync/NewTemplateSyncSelectors.js +7 -0
  21. data/webpack/components/NewTemplateSync/__fixtures__/templateSyncSettings.fixtures.js +71 -0
  22. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSync.test.js +31 -0
  23. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncReducer.test.js +55 -0
  24. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncSelectors.test.js +28 -0
  25. data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSync.test.js.snap +53 -0
  26. data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncReducer.test.js.snap +74 -0
  27. data/webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncSelectors.test.js.snap +59 -0
  28. data/webpack/components/NewTemplateSync/components/ButtonTooltip.js +23 -0
  29. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js +145 -0
  30. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormConstants.js +1 -0
  31. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormSelectors.js +24 -0
  32. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncForm.test.js +42 -0
  33. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js +37 -0
  34. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncForm.test.js.snap +176 -0
  35. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncFormSelectors.test.js.snap +42 -0
  36. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/index.js +44 -0
  37. data/webpack/components/NewTemplateSync/components/SyncSettingField.js +54 -0
  38. data/webpack/components/NewTemplateSync/components/SyncSettingFields.js +69 -0
  39. data/webpack/components/NewTemplateSync/components/SyncTypeRadios.js +52 -0
  40. data/webpack/components/NewTemplateSync/components/TextButtonField/BlankOption.js +19 -0
  41. data/webpack/components/NewTemplateSync/components/TextButtonField/CheckboxField.js +15 -0
  42. data/webpack/components/NewTemplateSync/components/TextButtonField/FieldType.js +46 -0
  43. data/webpack/components/NewTemplateSync/components/TextButtonField/InputField.js +14 -0
  44. data/webpack/components/NewTemplateSync/components/TextButtonField/RenderField.js +74 -0
  45. data/webpack/components/NewTemplateSync/components/TextButtonField/SelectField.js +24 -0
  46. data/webpack/components/NewTemplateSync/components/TextButtonField/index.js +69 -0
  47. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingField.test.js +34 -0
  48. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingFields.test.js +33 -0
  49. data/webpack/components/NewTemplateSync/components/__tests__/SyncTypeRadios.test.js +20 -0
  50. data/webpack/components/NewTemplateSync/components/__tests__/TextButtonField.test.js +65 -0
  51. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingField.test.js.snap +131 -0
  52. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncSettingFields.test.js.snap +94 -0
  53. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/SyncTypeRadios.test.js.snap +46 -0
  54. data/webpack/components/NewTemplateSync/components/__tests__/__snapshots__/TextButtonField.test.js.snap +112 -0
  55. data/webpack/components/NewTemplateSync/index.js +32 -0
  56. data/webpack/components/PageNotFound.js +13 -0
  57. data/webpack/components/PermissionDenied.js +33 -0
  58. data/webpack/components/TemplateSyncResult/TemplateSyncResult.js +61 -0
  59. data/webpack/components/TemplateSyncResult/TemplateSyncResult.scss +39 -0
  60. data/webpack/components/TemplateSyncResult/TemplateSyncResultActions.js +4 -0
  61. data/webpack/components/TemplateSyncResult/TemplateSyncResultHelpers.js +6 -0
  62. data/webpack/components/TemplateSyncResult/TemplateSyncResultReducer.js +33 -0
  63. data/webpack/components/TemplateSyncResult/TemplateSyncResultSelectors.js +1 -0
  64. data/webpack/components/TemplateSyncResult/__fixtures__/templateSyncResult.fixtures.js +86 -0
  65. data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResult.test.js +37 -0
  66. data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResultReducer.test.js +48 -0
  67. data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResult.test.js.snap +112 -0
  68. data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResultReducer.test.js.snap +88 -0
  69. data/webpack/components/TemplateSyncResult/components/EmptySyncResult.js +25 -0
  70. data/webpack/components/TemplateSyncResult/components/FinishedSyncResult.js +77 -0
  71. data/webpack/components/TemplateSyncResult/components/ListViewHeader.js +38 -0
  72. data/webpack/components/TemplateSyncResult/components/SyncResultList.js +41 -0
  73. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/EmptyInfoItem.js +16 -0
  74. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/IconInfoItem.js +21 -0
  75. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/InfoItem.js +34 -0
  76. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/LinkInfoItem.js +37 -0
  77. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/StringInfoItem.js +50 -0
  78. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/helpers.js +128 -0
  79. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/index.js +33 -0
  80. data/webpack/components/TemplateSyncResult/components/__tests__/SyncResultList.test.js +27 -0
  81. data/webpack/components/TemplateSyncResult/components/__tests__/SyncedTemplate.test.js +30 -0
  82. data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncResultList.test.js.snap +102 -0
  83. data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncedTemplate.test.js.snap +548 -0
  84. data/webpack/components/TemplateSyncResult/index.js +13 -0
  85. data/webpack/consts.js +6 -0
  86. data/webpack/index.js +11 -0
  87. data/webpack/reducer.js +6 -0
  88. data/webpack/testSetup.js +11 -0
  89. data/webpack/withProtectedView.js +16 -0
  90. metadata +89 -2
@@ -0,0 +1,131 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`SyncSettingField should render boolean setting as checkbox 1`] = `
4
+ <TextButtonField
5
+ blank={Object {}}
6
+ buttonAttrs={
7
+ Object {
8
+ "buttonAction": [Function],
9
+ "buttonText": <ButtonTooltip
10
+ tooltipId="force"
11
+ />,
12
+ }
13
+ }
14
+ className=""
15
+ disabled={false}
16
+ fieldRequired={false}
17
+ fieldSelector={[Function]}
18
+ inputClassName="col-md-6"
19
+ item={
20
+ Object {
21
+ "id": 46,
22
+ "name": "force",
23
+ "settingsType": "bool",
24
+ "value": false,
25
+ }
26
+ }
27
+ label="undefined "
28
+ name="force"
29
+ tooltipHelp={
30
+ <FieldLevelHelp
31
+ buttonClass=""
32
+ content={null}
33
+ placement="top"
34
+ rootClose={true}
35
+ />
36
+ }
37
+ validate={Array []}
38
+ />
39
+ `;
40
+
41
+ exports[`SyncSettingField should render setting with input field 1`] = `
42
+ <TextButtonField
43
+ blank={Object {}}
44
+ buttonAttrs={
45
+ Object {
46
+ "buttonAction": [Function],
47
+ "buttonText": <ButtonTooltip
48
+ tooltipId="filter"
49
+ />,
50
+ }
51
+ }
52
+ className=""
53
+ disabled={false}
54
+ fieldRequired={false}
55
+ fieldSelector={[Function]}
56
+ inputClassName="col-md-6"
57
+ item={
58
+ Object {
59
+ "id": 47,
60
+ "name": "filter",
61
+ "settingsType": "string",
62
+ "value": "",
63
+ }
64
+ }
65
+ label="undefined "
66
+ name="filter"
67
+ tooltipHelp={
68
+ <FieldLevelHelp
69
+ buttonClass=""
70
+ content={null}
71
+ placement="top"
72
+ rootClose={true}
73
+ />
74
+ }
75
+ validate={Array []}
76
+ />
77
+ `;
78
+
79
+ exports[`SyncSettingField should render setting with select choices 1`] = `
80
+ <TextButtonField
81
+ blank={Object {}}
82
+ buttonAttrs={
83
+ Object {
84
+ "buttonAction": [Function],
85
+ "buttonText": <ButtonTooltip
86
+ tooltipId="associate"
87
+ />,
88
+ }
89
+ }
90
+ className=""
91
+ disabled={false}
92
+ fieldRequired={false}
93
+ fieldSelector={[Function]}
94
+ inputClassName="col-md-6"
95
+ item={
96
+ Object {
97
+ "id": 45,
98
+ "name": "associate",
99
+ "selection": Array [
100
+ Object {
101
+ "label": "New",
102
+ "value": "new",
103
+ },
104
+ Object {
105
+ "label": "Never",
106
+ "value": "never",
107
+ },
108
+ Object {
109
+ "label": "Always",
110
+ "value": "always",
111
+ },
112
+ ],
113
+ "settingsType": "string",
114
+ "value": "new",
115
+ }
116
+ }
117
+ label="undefined "
118
+ name="associate"
119
+ tooltipHelp={
120
+ <FieldLevelHelp
121
+ buttonClass=""
122
+ content={null}
123
+ placement="top"
124
+ rootClose={true}
125
+ />
126
+ }
127
+ validate={Array []}
128
+ >
129
+ new
130
+ </TextButtonField>
131
+ `;
@@ -0,0 +1,94 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`SyncSettingFields should show export settings 1`] = `
4
+ <Fragment>
5
+ <SyncSettingField
6
+ disabled={false}
7
+ key="filter"
8
+ resetField={[Function]}
9
+ setting={
10
+ Object {
11
+ "id": 47,
12
+ "name": "filter",
13
+ "settingsType": "string",
14
+ "value": "",
15
+ }
16
+ }
17
+ />
18
+ <SyncSettingField
19
+ disabled={false}
20
+ key="negate"
21
+ resetField={[Function]}
22
+ setting={
23
+ Object {
24
+ "id": 48,
25
+ "name": "negate",
26
+ "settingsType": "bool",
27
+ "value": false,
28
+ }
29
+ }
30
+ />
31
+ <SyncSettingField
32
+ disabled={false}
33
+ key="repo"
34
+ resetField={[Function]}
35
+ setting={
36
+ Object {
37
+ "id": 49,
38
+ "name": "repo",
39
+ "required": true,
40
+ "settingsType": "string",
41
+ "validate": Array [
42
+ [Function],
43
+ ],
44
+ "value": "https://github.com/theforeman/community-templates.git",
45
+ }
46
+ }
47
+ />
48
+ </Fragment>
49
+ `;
50
+
51
+ exports[`SyncSettingFields should show import settings 1`] = `
52
+ <Fragment>
53
+ <SyncSettingField
54
+ disabled={false}
55
+ key="associate"
56
+ resetField={[Function]}
57
+ setting={
58
+ Object {
59
+ "id": 45,
60
+ "name": "associate",
61
+ "selection": Array [
62
+ Object {
63
+ "label": "New",
64
+ "value": "new",
65
+ },
66
+ Object {
67
+ "label": "Never",
68
+ "value": "never",
69
+ },
70
+ Object {
71
+ "label": "Always",
72
+ "value": "always",
73
+ },
74
+ ],
75
+ "settingsType": "string",
76
+ "value": "new",
77
+ }
78
+ }
79
+ />
80
+ <SyncSettingField
81
+ disabled={false}
82
+ key="force"
83
+ resetField={[Function]}
84
+ setting={
85
+ Object {
86
+ "id": 46,
87
+ "name": "force",
88
+ "settingsType": "bool",
89
+ "value": false,
90
+ }
91
+ }
92
+ />
93
+ </Fragment>
94
+ `;
@@ -0,0 +1,46 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`SyncTypeRadios should render 1`] = `
4
+ <CommonForm
5
+ className=""
6
+ inputClassName="col-md-6"
7
+ label="Test radios"
8
+ >
9
+ <Radio
10
+ bsClass="radio"
11
+ checked={false}
12
+ disabled={false}
13
+ inline={true}
14
+ key="0"
15
+ onChange={[Function]}
16
+ title="A"
17
+ value="a"
18
+ >
19
+ A
20
+ </Radio>
21
+ <Radio
22
+ bsClass="radio"
23
+ checked={true}
24
+ disabled={false}
25
+ inline={true}
26
+ key="1"
27
+ onChange={[Function]}
28
+ title="B"
29
+ value="b"
30
+ >
31
+ B
32
+ </Radio>
33
+ <Radio
34
+ bsClass="radio"
35
+ checked={false}
36
+ disabled={false}
37
+ inline={true}
38
+ key="2"
39
+ onChange={[Function]}
40
+ title="C"
41
+ value="c"
42
+ >
43
+ C
44
+ </Radio>
45
+ </CommonForm>
46
+ `;
@@ -0,0 +1,112 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TextButtonField should render checkbox item 1`] = `
4
+ <Field
5
+ blank={Object {}}
6
+ buttonAttrs={
7
+ Object {
8
+ "buttonAction": [Function],
9
+ "buttonText": "Button",
10
+ }
11
+ }
12
+ component={[Function]}
13
+ disabled={false}
14
+ fieldRequired={false}
15
+ fieldSelector={[Function]}
16
+ item={
17
+ Object {
18
+ "type": "checkbox",
19
+ }
20
+ }
21
+ label="Checkbox"
22
+ name="Checkbox field"
23
+ tooltipHelp={null}
24
+ />
25
+ `;
26
+
27
+ exports[`TextButtonField should render select item with custom blank opt 1`] = `
28
+ <Field
29
+ blank={
30
+ Object {
31
+ "label": "Bare Metal",
32
+ "value": "bareMetal",
33
+ }
34
+ }
35
+ buttonAttrs={
36
+ Object {
37
+ "buttonAction": [Function],
38
+ "buttonText": "Button",
39
+ }
40
+ }
41
+ component={[Function]}
42
+ disabled={false}
43
+ fieldRequired={false}
44
+ fieldSelector={[Function]}
45
+ item={
46
+ Object {
47
+ "selection": Array [
48
+ Object {
49
+ "label": "A",
50
+ "value": "a",
51
+ },
52
+ Object {
53
+ "label": "B",
54
+ "value": "b",
55
+ },
56
+ Object {
57
+ "label": "C",
58
+ "value": "c",
59
+ },
60
+ ],
61
+ "type": "select",
62
+ }
63
+ }
64
+ label="Select"
65
+ name="select field"
66
+ tooltipHelp={null}
67
+ />
68
+ `;
69
+
70
+ exports[`TextButtonField should render text field without field selector 1`] = `
71
+ <Field
72
+ blank={Object {}}
73
+ buttonAttrs={
74
+ Object {
75
+ "buttonAction": [Function],
76
+ "buttonText": "Button",
77
+ }
78
+ }
79
+ component={[Function]}
80
+ disabled={false}
81
+ fieldRequired={false}
82
+ fieldSelector={[Function]}
83
+ item={Object {}}
84
+ label="Text field"
85
+ name="no selector"
86
+ tooltipHelp={null}
87
+ />
88
+ `;
89
+
90
+ exports[`TextButtonField should render text item 1`] = `
91
+ <Field
92
+ blank={Object {}}
93
+ buttonAttrs={
94
+ Object {
95
+ "buttonAction": [Function],
96
+ "buttonText": "Button",
97
+ }
98
+ }
99
+ component={[Function]}
100
+ disabled={false}
101
+ fieldRequired={false}
102
+ fieldSelector={[Function]}
103
+ item={
104
+ Object {
105
+ "type": "text",
106
+ }
107
+ }
108
+ label="Text"
109
+ name="Text field"
110
+ tooltipHelp={null}
111
+ />
112
+ `;
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+
4
+ import * as TemplateSyncActions from './NewTemplateSyncActions';
5
+ import NewTemplateSync from './NewTemplateSync';
6
+ import { selectLoadingSettings, selectError } from './NewTemplateSyncSelectors';
7
+ import withProtectedView from '../../withProtectedView';
8
+ import PermissionDenied from '../PermissionDenied';
9
+
10
+ const mapStateToProps = state => ({
11
+ loadingSettings: selectLoadingSettings(state),
12
+ error: selectError(state),
13
+ });
14
+
15
+ const permissionList = (
16
+ <ul className="list-unstyled">
17
+ <li>import_templates</li>
18
+ <li>export_templates</li>
19
+ </ul>
20
+ );
21
+
22
+ export default withProtectedView(
23
+ connect(
24
+ mapStateToProps,
25
+ TemplateSyncActions
26
+ )(NewTemplateSync),
27
+ PermissionDenied,
28
+ props =>
29
+ props.userPermissions &&
30
+ (props.userPermissions.import || props.userPermissions.export),
31
+ { doc: permissionList }
32
+ );
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { EmptyStatePattern as EmptyState } from 'foremanReact/components/common/EmptyState';
3
+
4
+ const PageNotFound = props => (
5
+ <EmptyState
6
+ iconType="fa"
7
+ icon="exclamation-triangle"
8
+ header={__('Page Not Found')}
9
+ description={__('The page you are looking for does not exist')}
10
+ />
11
+ );
12
+
13
+ export default PageNotFound;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { EmptyStatePattern as EmptyState } from 'foremanReact/components/common/EmptyState';
5
+
6
+ const PermissionDenied = props => {
7
+ const description = (
8
+ <span>
9
+ {__('You are not authorized to perform this action.')}
10
+ <br />
11
+ {__(
12
+ 'Please request one of the required permissions listed below from a Foreman administrator:'
13
+ )}
14
+ <br />
15
+ </span>
16
+ );
17
+
18
+ return (
19
+ <EmptyState
20
+ iconType="fa"
21
+ icon="lock"
22
+ header={__('Permission Denied')}
23
+ description={description}
24
+ documentation={props.doc}
25
+ />
26
+ );
27
+ };
28
+
29
+ PermissionDenied.propTypes = {
30
+ doc: PropTypes.node.isRequired,
31
+ };
32
+
33
+ export default PermissionDenied;
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import { isEmpty } from 'lodash';
3
+ import PropTypes from 'prop-types';
4
+
5
+ import EmptySyncResult from './components/EmptySyncResult';
6
+ import FinishedSyncResult from './components/FinishedSyncResult';
7
+
8
+ import './TemplateSyncResult.scss';
9
+
10
+ const TemplateSyncResult = ({
11
+ syncResult: { templates, resultAction, repo, branch, gitUser, pagination },
12
+ history,
13
+ syncedTemplatesPageChange,
14
+ editPaths,
15
+ fileRepoStartWith,
16
+ }) => {
17
+ const redirectBack = () => history.push({ pathname: '/template_syncs' });
18
+
19
+ return isEmpty(templates) ? (
20
+ <EmptySyncResult primaryAction={redirectBack} />
21
+ ) : (
22
+ <FinishedSyncResult
23
+ templates={templates}
24
+ type={resultAction}
25
+ repo={repo}
26
+ branch={branch}
27
+ gitUser={gitUser}
28
+ fileRepoStartWith={fileRepoStartWith}
29
+ editPaths={editPaths}
30
+ pagination={pagination}
31
+ pageChange={syncedTemplatesPageChange}
32
+ />
33
+ );
34
+ };
35
+
36
+ TemplateSyncResult.propTypes = {
37
+ syncResult: PropTypes.shape({
38
+ templates: PropTypes.array,
39
+ resultAction: PropTypes.string,
40
+ repo: PropTypes.string,
41
+ branch: PropTypes.string,
42
+ gitUser: PropTypes.string,
43
+ pagination: PropTypes.shape({
44
+ page: PropTypes.number,
45
+ perPage: PropTypes.number,
46
+ }),
47
+ syncedTemplatesPageChange: PropTypes.func,
48
+ }).isRequired,
49
+ history: PropTypes.object.isRequired,
50
+ editPaths: PropTypes.object,
51
+ fileRepoStartWith: PropTypes.array,
52
+ syncedTemplatesPageChange: PropTypes.func,
53
+ };
54
+
55
+ TemplateSyncResult.defaultProps = {
56
+ editPaths: {},
57
+ syncedTemplatesPageChange: () => {},
58
+ fileRepoStartWith: [],
59
+ };
60
+
61
+ export default TemplateSyncResult;
@@ -0,0 +1,39 @@
1
+ #foreman-templates {
2
+ .list-view-pf-body {
3
+ .list-view-pf-description {
4
+ width: 20%;
5
+ }
6
+ }
7
+
8
+ .list-view-pf-additional-info-item.additional-info-wide {
9
+ width: 15%;
10
+ }
11
+
12
+ .list-group-item-heading {
13
+ font-weight: normal;
14
+ font-size: 12px;
15
+ }
16
+
17
+ .list-view-header {
18
+ border-top: 0px;
19
+ background-color: #fff;
20
+ border-left-color: #fff;
21
+ border-right-color: #fff;
22
+
23
+ .list-view-pf-main-info {
24
+ padding-bottom: 0px;
25
+ }
26
+
27
+ .list-group-item-heading {
28
+ font-weight: 600;
29
+ }
30
+
31
+ .list-view-pf-left {
32
+ visibility: hidden;
33
+ }
34
+ .list-view-pf-expand {
35
+ visibility: hidden;
36
+ margin-bottom: 0px;
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,4 @@
1
+ import { SYNC_RESULT_PAGINATION_CHANGE } from '../../consts';
2
+
3
+ export const syncedTemplatesPageChange = pagination => dispatch =>
4
+ dispatch({ type: SYNC_RESULT_PAGINATION_CHANGE, payload: { pagination } });
@@ -0,0 +1,6 @@
1
+ // move to some sort of pagination helper in core
2
+ export const templatesPage = (templates, pagination) => {
3
+ const offset = (pagination.page - 1) * pagination.perPage;
4
+
5
+ return templates.slice(offset, offset + pagination.perPage);
6
+ };
@@ -0,0 +1,33 @@
1
+ import Immutable from 'seamless-immutable';
2
+ import { deepPropsToCamelCase } from 'foremanReact/common/helpers';
3
+
4
+ import {
5
+ TEMPLATESYNC_FORM_SUBMITTED,
6
+ SYNC_RESULT_PAGINATION_CHANGE,
7
+ } from '../../consts';
8
+
9
+ export const initialState = Immutable({
10
+ resultAction: '',
11
+ templates: [],
12
+
13
+ pagination: {
14
+ page: 1,
15
+ perPage: 20,
16
+ },
17
+ });
18
+
19
+ const syncResult = (state = initialState, action) => {
20
+ const { payload } = action;
21
+ switch (action.type) {
22
+ case TEMPLATESYNC_FORM_SUBMITTED:
23
+ return state.merge({
24
+ ...deepPropsToCamelCase(payload.data),
25
+ });
26
+ case SYNC_RESULT_PAGINATION_CHANGE:
27
+ return state.set('pagination', payload.pagination);
28
+ default:
29
+ return state;
30
+ }
31
+ };
32
+
33
+ export default syncResult;
@@ -0,0 +1 @@
1
+ export const selectSyncResult = state => state.foremanTemplates.syncResult;
@@ -0,0 +1,86 @@
1
+ export const exportTemplates = [
2
+ {
3
+ name: 'random template',
4
+ templateFile: 'random_template.erb',
5
+ additionalErrors: null,
6
+ errors: {},
7
+ snippet: true,
8
+ locked: true,
9
+ className: 'JobTemplate',
10
+ humanizedClassName: 'Job Template',
11
+ },
12
+ {
13
+ name: 'CoreOS default',
14
+ templateFile: 'coreos_default.erb',
15
+ additionalErrors: null,
16
+ errors: {},
17
+ snippet: false,
18
+ locked: false,
19
+ className: 'Ptable',
20
+ humanizedClassName: 'Ptable',
21
+ },
22
+ ];
23
+
24
+ export const noName = {
25
+ name: null,
26
+ templateFile: 'random_template.erb',
27
+ additionalErrors: 'No "name" found in metadata',
28
+ errors: null,
29
+ };
30
+
31
+ export const epel = {
32
+ name: 'EPEL',
33
+ templateFile: 'epel.erb',
34
+ additionalErrors: null,
35
+ errors: { base: ['This template is locked'] },
36
+ snippet: true,
37
+ locked: true,
38
+ className: 'ProvisioningTemplate',
39
+ kind: 'Provision',
40
+ humanizedClassName: 'Provisioning Template',
41
+ };
42
+
43
+ export const coreos = {
44
+ name: 'CoreOS default',
45
+ templateFile: 'coreos_default.erb',
46
+ additionalErrors: null,
47
+ errors: {},
48
+ snippet: false,
49
+ locked: false,
50
+ className: 'Ptable',
51
+ humanizedClassName: 'Ptable',
52
+ };
53
+
54
+ export const filteredOut = {
55
+ name: 'CoreOS default',
56
+ templateFile: 'coreos_default.erb',
57
+ additionalErrors: null,
58
+ additionalInfo: 'Skipping, this template was filtered out.',
59
+ errors: {},
60
+ snippet: false,
61
+ locked: false,
62
+ className: 'Ptable',
63
+ humanizedClassName: 'Ptable',
64
+ };
65
+
66
+ export const importTemplates = [
67
+ noName,
68
+ epel,
69
+ coreos,
70
+ {
71
+ name: null,
72
+ templateFile: 'no_model.erb',
73
+ additionalErrors: 'No "model" found in metadata',
74
+ errors: null,
75
+ },
76
+ {
77
+ name: 'Kickstart fake',
78
+ templateFile: 'kickstart_fake.erb',
79
+ additionalErrors: null,
80
+ errors: { name: ['has already been taken'] },
81
+ snippet: true,
82
+ locked: true,
83
+ className: 'ProvisioningTemplate',
84
+ humanizedClassName: 'Provisioning Template',
85
+ },
86
+ ];