foreman_webhooks 5.0.1 → 5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27a02852b9247c1b74c362b9e84f72b7585e45976b9c58bc3d50bd81278467c3
4
- data.tar.gz: 99fbe30a245a5594b955c25ab64818ee81f23248d1de2a17aadf61041becf974
3
+ metadata.gz: b0e6639b74aa9598f8a7961d48dd5c2bf81714bb6f6111e9f9bbb65a2393a4d2
4
+ data.tar.gz: fbe6d793527bf76fd9c3d73e357c7a4da87e3a77b1a8636652569e47955ef928
5
5
  SHA512:
6
- metadata.gz: ad3089c50b01e80b35a9e35f63c8fee7752f06a4ca1be6528eff178a9e679da6412b2ed7f518745a265ecb651d5f2e6feff27686aa63a145a8ea512fe21f4846
7
- data.tar.gz: 2834fe2d67940bcecab03cf62df919b77682cbe1df7bc05411c92e19158f4a39e33ccafae16baa9f5736424b1aa433cb9ea7f4063d424ef898222a2835ca4ea1
6
+ metadata.gz: 7de4a54540a300b0d0f5de39b79275074c403f4d74ccf1a5d53fa22f77ae6bfba2788f26824b8642608da39ef09e4bd99be88fdf7a615e527cb1070066730631
7
+ data.tar.gz: 752cb5d63594e68e313b9a91a4fce2955a0fce47ad51a25351c0f9c43df4104ad2a456dd1e9651b2d7b51a65daef196c1f39ddf726e7b701ad146455238b00d0
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ForemanWebhooks
4
- VERSION = "5.0.1"
4
+ VERSION = "5.0.2"
5
5
  end
@@ -118,6 +118,101 @@ class WebhooksIntegrationTest < IntegrationTestWithJavascript
118
118
  assert webhook.password.present?, 'Password was cleared after update'
119
119
  end
120
120
 
121
+ test 'edit webhook modal shows selected webhook instead of previous one' do
122
+ first_webhook = FactoryBot.create(:webhook,
123
+ name: 'FirstWebhook',
124
+ target_url: 'http://example.com/webhook1',
125
+ http_method: 'POST',
126
+ webhook_template: webhook_template)
127
+ second_webhook = FactoryBot.create(:webhook,
128
+ name: 'SecondWebhook',
129
+ target_url: 'http://example.com/webhook2',
130
+ http_method: 'POST',
131
+ webhook_template: webhook_template)
132
+
133
+ visit '/webhooks'
134
+ wait_for_ajax
135
+ click_webhook_name(first_webhook.name)
136
+ assert_selector '.pf-v5-c-modal-box'
137
+ click_cancel_button
138
+ wait_for_ajax
139
+ click_webhook_name(second_webhook.name)
140
+ assert_selector '.pf-v5-c-modal-box'
141
+ assert_field_value('id-name', second_webhook.name)
142
+ click_cancel_button
143
+ assert_no_selector '.pf-v5-c-modal-box'
144
+ end
145
+
146
+ test 'should update password' do
147
+ webhook = FactoryBot.create(:webhook,
148
+ name: 'PasswordUpdateWebhook',
149
+ target_url: 'http://example.com/webhook',
150
+ http_method: 'POST',
151
+ webhook_template: webhook_template,
152
+ password: 'oldpassword123')
153
+ new_password = 'newpassword456'
154
+ visit '/webhooks'
155
+ wait_for_ajax
156
+ click_webhook_name(webhook.name)
157
+ assert_selector '.pf-v5-c-modal-box'
158
+ click_tab('Credentials')
159
+ click_change_password_button
160
+ fill_in 'id-password', with: new_password
161
+ click_submit_button
162
+ wait_for_success_toast
163
+ webhook.reload
164
+ assert_equal new_password, webhook.password, 'Password was not updated in database'
165
+ end
166
+
167
+ test 'edit submission triggers PUT /api/webhooks/id and GET /api/webhooks only' do
168
+ first_webhook = FactoryBot.create(:webhook,
169
+ name: 'FirstWebhook',
170
+ target_url: 'http://example.com/webhook1',
171
+ http_method: 'POST',
172
+ webhook_template: webhook_template)
173
+ second_webhook = FactoryBot.create(:webhook,
174
+ name: 'SecondWebhook',
175
+ target_url: 'http://example.com/webhook2',
176
+ http_method: 'POST',
177
+ webhook_template: webhook_template)
178
+
179
+ visit '/webhooks'
180
+ wait_for_ajax
181
+ click_webhook_name(first_webhook.name)
182
+ assert_selector '.pf-v5-c-modal-box'
183
+
184
+ click_cancel_button
185
+ wait_for_ajax
186
+ click_webhook_name(second_webhook.name)
187
+ assert_selector '.pf-v5-c-modal-box'
188
+
189
+ fill_in 'id-name', with: '', fill_options: { clear: :backspace }
190
+ fill_in 'id-name', with: 'UpdatedAPITestWebhook'
191
+
192
+ api_requests = []
193
+ callback = lambda { |_name, _started, _finished, _unique_id, payload|
194
+ api_requests << { method: payload[:method], controller: payload[:controller], action: payload[:action], path: payload[:path] } if payload[:controller]&.start_with?('Api::')
195
+ }
196
+
197
+ ActiveSupport::Notifications.subscribed(callback, 'process_action.action_controller') do
198
+ click_submit_button
199
+ wait_for_success_toast
200
+ wait_for_ajax
201
+ end
202
+
203
+ assert api_requests.any? { |r| r[:method] == 'PUT' && r[:controller] == 'Api::V2::WebhooksController' && r[:action] == 'update' },
204
+ "Expected PUT webhooks#update, got: #{api_requests.inspect}"
205
+ assert api_requests.any? { |r| r[:method] == 'GET' && r[:controller] == 'Api::V2::WebhooksController' && r[:action] == 'index' },
206
+ "Expected GET webhooks#index, got: #{api_requests.inspect}"
207
+
208
+ assert api_requests.none? { |r| r[:controller] == 'Api::V2::WebhooksController' && r[:action] == 'events' },
209
+ "Unexpected call to webhooks#events: #{api_requests.inspect}"
210
+ assert api_requests.none? { |r| r[:controller] == 'Api::V2::WebhookTemplatesController' },
211
+ "Unexpected call to webhook_templates: #{api_requests.inspect}"
212
+ assert api_requests.none? { |r| r[:controller] == 'Api::V2::WebhooksController' && r[:action] == 'show' },
213
+ "Unexpected call to webhooks#show: #{api_requests.inspect}"
214
+ end
215
+
121
216
  test 'delete webhook via UI' do
122
217
  webhook = FactoryBot.create(:webhook,
123
218
  name: 'WebhookToDelete',
@@ -190,6 +285,13 @@ class WebhooksIntegrationTest < IntegrationTestWithJavascript
190
285
  page.execute_script('arguments[0].click()', button.native)
191
286
  end
192
287
 
288
+ def click_change_password_button
289
+ modal = find('.pf-v5-c-modal-box', wait: 10)
290
+ button = modal.find(:ouia_component_id, 'reset-password', wait: 10, visible: :all)
291
+ page.execute_script('arguments[0].scrollIntoView({block: "center"})', button.native)
292
+ page.execute_script('arguments[0].click()', button.native)
293
+ end
294
+
193
295
  def click_webhook_name(name)
194
296
  row = find(:xpath, "//tbody//tr[contains(., '#{name}')]", wait: 15, match: :first)
195
297
  within(row) do
@@ -28,7 +28,6 @@ const FormField = ({
28
28
  type,
29
29
  required,
30
30
  options,
31
- isLoading,
32
31
  validated,
33
32
  value,
34
33
  disabled,
@@ -36,11 +35,11 @@ const FormField = ({
36
35
  placeholder,
37
36
  errMsg,
38
37
  fieldId,
38
+ setIsPasswordDisabled,
39
39
  ...props
40
40
  }) => {
41
41
  const [fieldValidated, setFieldValidated] = useState('default');
42
42
  const [firstLoad, setFirstLoad] = useState(true);
43
- const [isDisabled, setIsDisabled] = useState(disabled);
44
43
 
45
44
  const requiredValidate = () => {
46
45
  if (firstLoad || !required) return;
@@ -57,10 +56,6 @@ const FormField = ({
57
56
  setFirstLoad(false);
58
57
  }, []);
59
58
 
60
- useEffect(() => {
61
- setIsDisabled(disabled);
62
- }, [disabled]);
63
-
64
59
  useEffect(() => {
65
60
  requiredValidate();
66
61
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -76,7 +71,7 @@ const FormField = ({
76
71
  onChange={(_, newValue) => {
77
72
  setValue(name, newValue);
78
73
  }}
79
- isDisabled={isLoading || isDisabled}
74
+ isDisabled={disabled}
80
75
  isRequired={required}
81
76
  type={type}
82
77
  validated={fieldValidated}
@@ -94,7 +89,7 @@ const FormField = ({
94
89
  value={value ?? ''}
95
90
  onChange={(_, newValue) => setValue(name, newValue)}
96
91
  isRequired={required}
97
- isDisabled={isLoading || isDisabled}
92
+ isDisabled={disabled}
98
93
  type={type}
99
94
  validated={fieldValidated}
100
95
  placeholder={placeholder}
@@ -121,7 +116,7 @@ const FormField = ({
121
116
  }
122
117
  return (
123
118
  <>
124
- {name === 'password' && (isDisabled || disabled) ? (
119
+ {name === 'password' && disabled && setIsPasswordDisabled ? (
125
120
  <Grid hasGutter={false}>
126
121
  <GridItem span={11}>
127
122
  <TextInput
@@ -129,7 +124,7 @@ const FormField = ({
129
124
  value={value ?? ''}
130
125
  id={fieldId ?? `id-${name}`}
131
126
  onChange={localHandler}
132
- isDisabled={isLoading || isDisabled}
127
+ isDisabled={disabled}
133
128
  isRequired={required}
134
129
  type={type}
135
130
  validated={fieldValidated}
@@ -141,7 +136,7 @@ const FormField = ({
141
136
  <GridItem span={1}>
142
137
  <Button
143
138
  ouiaId={`reset-${name}`}
144
- onClick={() => setIsDisabled(false)}
139
+ onClick={() => setIsPasswordDisabled(!disabled)}
145
140
  variant="control"
146
141
  icon={<PencilAltIcon />}
147
142
  />
@@ -153,11 +148,9 @@ const FormField = ({
153
148
  value={value ?? ''}
154
149
  id={fieldId ?? `id-${name}`}
155
150
  onChange={localHandler}
156
- isDisabled={isLoading || isDisabled}
157
151
  isRequired={required}
158
152
  type={type}
159
153
  validated={fieldValidated}
160
- placeholder={placeholder}
161
154
  onBlur={requiredValidate}
162
155
  autoComplete={type === 'password' ? 'new-password' : null}
163
156
  />
@@ -283,7 +276,6 @@ FormField.propTypes = {
283
276
  label: PropTypes.string.isRequired,
284
277
  })
285
278
  ),
286
- isLoading: PropTypes.bool,
287
279
  validated: PropTypes.string,
288
280
  placeholder: PropTypes.string,
289
281
  errMsg: PropTypes.string,
@@ -303,7 +295,6 @@ FormField.defaultProps = {
303
295
  required: false,
304
296
  allowClear: false,
305
297
  options: [],
306
- isLoading: false,
307
298
  disabled: false,
308
299
  value: '',
309
300
  fieldId: undefined,
@@ -18,6 +18,7 @@ const WebhookFormTabs = ({
18
18
  isTemplatesLoading,
19
19
  isEventsLoading,
20
20
  isPasswordDisabled,
21
+ setIsPasswordDisabled,
21
22
  urlValidated,
22
23
  }) => {
23
24
  const updateFieldValue = (key, value) => {
@@ -141,6 +142,8 @@ const WebhookFormTabs = ({
141
142
  labelHelp={__('Authentication credentials')}
142
143
  disabled={isPasswordDisabled}
143
144
  setValue={updateFieldValue}
145
+ setIsPasswordDisabled={setIsPasswordDisabled}
146
+ placeholder="********"
144
147
  />
145
148
  <FieldConstructor
146
149
  name="verify_ssl"
@@ -218,11 +221,13 @@ WebhookFormTabs.propTypes = {
218
221
  isTemplatesLoading: PropTypes.bool.isRequired,
219
222
  isEventsLoading: PropTypes.bool.isRequired,
220
223
  isPasswordDisabled: PropTypes.bool,
224
+ setIsPasswordDisabled: PropTypes.func,
221
225
  urlValidated: PropTypes.func.isRequired,
222
226
  };
223
227
 
224
228
  WebhookFormTabs.defaultProps = {
225
229
  isPasswordDisabled: false,
230
+ setIsPasswordDisabled: null,
226
231
  };
227
232
 
228
233
  export default WebhookFormTabs;
@@ -60,10 +60,10 @@ describe('FieldConstructor RTL Tests', () => {
60
60
  );
61
61
  });
62
62
 
63
- test('renders as disabled when loading', () => {
63
+ test('renders as enabled when loading', () => {
64
64
  render(<FieldConstructor {...defaultProps} type="text" isLoading />);
65
65
 
66
- expect(document.getElementById('id-test-field')).toBeDisabled();
66
+ expect(document.getElementById('id-test-field')).toBeEnabled();
67
67
  });
68
68
  });
69
69
 
@@ -8,7 +8,6 @@ import { HTTP_METHODS } from './constants';
8
8
 
9
9
  const WebhookForm = ({
10
10
  onCancel,
11
- isLoading,
12
11
  handleSubmit,
13
12
  initialValues,
14
13
  templates,
@@ -16,6 +15,8 @@ const WebhookForm = ({
16
15
  isTemplatesLoading,
17
16
  isEventsLoading,
18
17
  isPasswordDisabled,
18
+ setIsPasswordDisabled,
19
+ isSubmitting,
19
20
  }) => {
20
21
  const webhookTemplates = templates.map(t => ({ value: t.id, label: t.name }));
21
22
 
@@ -71,18 +72,24 @@ const WebhookForm = ({
71
72
  isEventsLoading={isEventsLoading}
72
73
  isTemplatesLoading={isTemplatesLoading}
73
74
  isPasswordDisabled={isPasswordDisabled}
75
+ setIsPasswordDisabled={setIsPasswordDisabled}
74
76
  urlValidated={urlValidated}
75
77
  />
76
78
  <ActionGroup>
77
79
  <Button
78
80
  ouiaId="submit-webhook-form"
79
- isDisabled={verifyFields() || isLoading}
81
+ isDisabled={verifyFields() || isSubmitting}
80
82
  variant="primary"
81
83
  onClick={() => handleSubmit(inputValues)}
82
84
  >
83
85
  {__('Submit')}
84
86
  </Button>
85
- <Button ouiaId="cancel-webhook-form" variant="link" onClick={onCancel}>
87
+ <Button
88
+ ouiaId="cancel-webhook-form"
89
+ variant="link"
90
+ onClick={onCancel}
91
+ isDisabled={isSubmitting}
92
+ >
86
93
  {__('Cancel')}
87
94
  </Button>
88
95
  </ActionGroup>
@@ -91,7 +98,6 @@ const WebhookForm = ({
91
98
  };
92
99
 
93
100
  WebhookForm.propTypes = {
94
- isLoading: PropTypes.bool.isRequired,
95
101
  onCancel: PropTypes.func.isRequired,
96
102
  handleSubmit: PropTypes.func.isRequired,
97
103
  initialValues: PropTypes.object.isRequired,
@@ -100,10 +106,14 @@ WebhookForm.propTypes = {
100
106
  isEventsLoading: PropTypes.bool.isRequired,
101
107
  isTemplatesLoading: PropTypes.bool.isRequired,
102
108
  isPasswordDisabled: PropTypes.bool,
109
+ setIsPasswordDisabled: PropTypes.func,
110
+ isSubmitting: PropTypes.bool,
103
111
  };
104
112
 
105
113
  WebhookForm.defaultProps = {
106
114
  isPasswordDisabled: false,
115
+ setIsPasswordDisabled: null,
116
+ isSubmitting: false,
107
117
  };
108
118
 
109
119
  export default WebhookForm;
@@ -25,11 +25,12 @@ import {
25
25
  const params = { page: 1, search: 'snippet = false', per_page: 'all' };
26
26
 
27
27
  const ConnectedWebhookForm = ({
28
- isLoading,
29
28
  onCancel,
30
29
  handleSubmit,
31
30
  initialValues,
32
31
  isPasswordDisabled,
32
+ setIsPasswordDisabled,
33
+ isSubmitting,
33
34
  }) => {
34
35
  const dispatch = useDispatch();
35
36
 
@@ -59,7 +60,6 @@ const ConnectedWebhookForm = ({
59
60
 
60
61
  return (
61
62
  <WebhookForm
62
- isLoading={isLoading}
63
63
  templates={templates}
64
64
  availableEvents={availableEvents}
65
65
  onCancel={onCancel}
@@ -68,20 +68,25 @@ const ConnectedWebhookForm = ({
68
68
  isTemplatesLoading={isTemplatesLoading}
69
69
  isEventsLoading={isEventsLoading}
70
70
  isPasswordDisabled={isPasswordDisabled}
71
+ setIsPasswordDisabled={setIsPasswordDisabled}
72
+ isSubmitting={isSubmitting}
71
73
  />
72
74
  );
73
75
  };
74
76
 
75
77
  ConnectedWebhookForm.propTypes = {
76
- isLoading: PropTypes.bool.isRequired,
77
78
  onCancel: PropTypes.func.isRequired,
78
79
  handleSubmit: PropTypes.func.isRequired,
79
80
  initialValues: PropTypes.object.isRequired,
80
81
  isPasswordDisabled: PropTypes.bool,
82
+ setIsPasswordDisabled: PropTypes.func,
83
+ isSubmitting: PropTypes.bool,
81
84
  };
82
85
 
83
86
  ConnectedWebhookForm.defaultProps = {
84
87
  isPasswordDisabled: false,
88
+ setIsPasswordDisabled: null,
89
+ isSubmitting: false,
85
90
  };
86
91
 
87
92
  export default ConnectedWebhookForm;
@@ -15,8 +15,8 @@ import './WebhookModal.scss';
15
15
 
16
16
  const WebhookCreateModal = ({ onSuccess, onCancel, isOpen }) => {
17
17
  const dispatch = useDispatch();
18
+ const [isSubmitting, setIsSubmitting] = useState(false);
18
19
 
19
- const [isLoading, setIsLoading] = useState(false);
20
20
  const initialWebhookValues = {
21
21
  name: '',
22
22
  target_url: '',
@@ -34,7 +34,7 @@ const WebhookCreateModal = ({ onSuccess, onCancel, isOpen }) => {
34
34
  };
35
35
 
36
36
  const handleSubmit = values => {
37
- setIsLoading(true);
37
+ setIsSubmitting(true);
38
38
  dispatch(
39
39
  APIActions.post({
40
40
  url: foremanUrl(`/api${WEBHOOKS_PATH}`),
@@ -43,9 +43,8 @@ const WebhookCreateModal = ({ onSuccess, onCancel, isOpen }) => {
43
43
  successToast: () => __('Webhook was successfully created.'),
44
44
  handleSuccess: () => {
45
45
  onSuccess();
46
- setIsLoading(false);
47
46
  },
48
- handleError: () => setIsLoading(false),
47
+ handleError: () => setIsSubmitting(false),
49
48
  errorToast: ({ response }) =>
50
49
  // eslint-disable-next-line camelcase
51
50
  response?.data?.error?.full_messages?.[0] || response,
@@ -64,10 +63,10 @@ const WebhookCreateModal = ({ onSuccess, onCancel, isOpen }) => {
64
63
  title={__('Create Webhook')}
65
64
  >
66
65
  <ConnectedWebhookForm
67
- isLoading={isLoading}
68
66
  handleSubmit={handleSubmit}
69
67
  initialValues={initialWebhookValues}
70
68
  onCancel={onCancel}
69
+ isSubmitting={isSubmitting}
71
70
  />
72
71
  </Modal>
73
72
  );
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  import { APIActions } from 'foremanReact/redux/API';
@@ -12,8 +12,10 @@ import { WEBHOOK_DELETE_MODAL_ID } from '../../constants';
12
12
  const WebhookDeleteModal = ({ toDelete, onSuccess, modalState }) => {
13
13
  const { id, name } = toDelete;
14
14
 
15
+ const [isSubmitting, setIsSubmitting] = useState(false);
15
16
  const dispatch = useDispatch();
16
- const handleSubmit = () =>
17
+ const handleSubmit = () => {
18
+ setIsSubmitting(true);
17
19
  dispatch(
18
20
  APIActions.delete({
19
21
  url: foremanUrl(`/api/v2/webhooks/${id}`),
@@ -24,8 +26,10 @@ const WebhookDeleteModal = ({ toDelete, onSuccess, modalState }) => {
24
26
  // eslint-disable-next-line camelcase
25
27
  response?.response?.data?.error?.full_messages?.[0] || response,
26
28
  handleSuccess: onSuccess,
29
+ handleError: () => setIsSubmitting(false),
27
30
  })
28
31
  );
32
+ };
29
33
 
30
34
  return (
31
35
  <Modal
@@ -45,6 +49,7 @@ const WebhookDeleteModal = ({ toDelete, onSuccess, modalState }) => {
45
49
  ouiaId="submitBtn"
46
50
  key="confirm"
47
51
  variant="danger"
52
+ isDisabled={isSubmitting}
48
53
  onClick={handleSubmit}
49
54
  >
50
55
  {__('Delete')}
@@ -53,6 +58,7 @@ const WebhookDeleteModal = ({ toDelete, onSuccess, modalState }) => {
53
58
  ouiaId="cancelBtn"
54
59
  key="cancel"
55
60
  variant="link"
61
+ isDisabled={isSubmitting}
56
62
  onClick={modalState.closeModal}
57
63
  >
58
64
  {__('Cancel')}
@@ -15,9 +15,11 @@ import {
15
15
  WEBHOOK_API_REQUEST_KEY,
16
16
  WEBHOOK_EDIT_MODAL_ID,
17
17
  WEBHOOKS_API_PLAIN_PATH,
18
+ WEBHOOK_API_UPDATE_KEY,
18
19
  } from '../../constants';
19
20
 
20
21
  import {
22
+ selectIsLoading,
21
23
  selectWebhookValues,
22
24
  selectWebhookTemplateId,
23
25
  } from './WebhookEditModalSelectors';
@@ -27,8 +29,10 @@ import './WebhookModal.scss';
27
29
  const WebhookEditModal = ({ toEdit, onSuccess, modalState }) => {
28
30
  const dispatch = useDispatch();
29
31
 
32
+ const isLoading = useSelector(selectIsLoading);
33
+
34
+ const [isSubmitting, setIsSubmitting] = useState(false);
30
35
  const [isPasswordDisabled, setIsPasswordDisabled] = useState(false);
31
- const [isLoading, setIsLoading] = useState(true);
32
36
  const id = toEdit;
33
37
 
34
38
  const isPasswordSet = useSelector(selectWebhookValues).passwordSet;
@@ -54,20 +58,20 @@ const WebhookEditModal = ({ toEdit, onSuccess, modalState }) => {
54
58
  }, [isPasswordSet]);
55
59
 
56
60
  const handleSubmit = values => {
57
- setIsLoading(true);
61
+ setIsSubmitting(true);
58
62
  if (isPasswordDisabled) {
59
63
  delete values.password;
60
64
  }
61
65
  dispatch(
62
66
  put({
63
67
  url: foremanUrl(`/api${WEBHOOKS_PATH}/${id}`),
64
- key: WEBHOOK_API_REQUEST_KEY,
68
+ key: WEBHOOK_API_UPDATE_KEY,
65
69
  params: { ...values, controller: 'webhooks' },
66
70
  successToast: () => __('Webhook was successfully updated.'),
67
71
  handleSuccess: () => {
68
72
  onSuccess();
69
- setIsLoading(false);
70
73
  },
74
+ handleError: () => setIsSubmitting(false),
71
75
  errorToast: ({ response }) =>
72
76
  // eslint-disable-next-line camelcase
73
77
  response?.data?.error?.full_messages?.[0] || response,
@@ -75,10 +79,6 @@ const WebhookEditModal = ({ toEdit, onSuccess, modalState }) => {
75
79
  );
76
80
  };
77
81
 
78
- useEffect(() => {
79
- if (initialWebhookValues.id) setIsLoading(false);
80
- }, [initialWebhookValues.id]);
81
-
82
82
  useEffect(() => {
83
83
  if (id) {
84
84
  dispatch(
@@ -111,12 +111,12 @@ const WebhookEditModal = ({ toEdit, onSuccess, modalState }) => {
111
111
  <Loading />
112
112
  ) : (
113
113
  <ConnectedWebhookForm
114
- isLoading={isLoading}
115
114
  handleSubmit={handleSubmit}
116
115
  initialValues={initialWebhookValues}
117
116
  onCancel={onEditCancel}
118
117
  isPasswordDisabled={isPasswordDisabled}
119
118
  setIsPasswordDisabled={setIsPasswordDisabled}
119
+ isSubmitting={isSubmitting}
120
120
  />
121
121
  )}
122
122
  </Modal>
@@ -41,15 +41,24 @@ const WrappedWebhooksTable = props => {
41
41
  modalsStates={{
42
42
  testModal: {
43
43
  isOpen: isTestModalOpen,
44
- closeModal: () => setIsTestModalOpen(false),
44
+ closeModal: () => {
45
+ setToTest({});
46
+ setIsTestModalOpen(false);
47
+ },
45
48
  },
46
49
  deleteModal: {
47
50
  isOpen: isDeleteModalOpen,
48
- closeModal: () => setIsDeleteModalOpen(false),
51
+ closeModal: () => {
52
+ setToDelete({});
53
+ setIsDeleteModalOpen(false);
54
+ },
49
55
  },
50
56
  editModal: {
51
57
  isOpen: isEditModalOpen,
52
- closeModal: () => setIsEditModalOpen(false),
58
+ closeModal: () => {
59
+ setToEdit(0);
60
+ setIsEditModalOpen(false);
61
+ },
53
62
  },
54
63
  }}
55
64
  webhookActions={webhookActions}
@@ -13,6 +13,7 @@ export const WEBHOOK_TEMPLATES_API_PATH =
13
13
  export const WEBHOOKS_API_PLAIN_PATH = '/api/v2/webhooks';
14
14
  export const WEBHOOK_TEMPLATES_API_REQUEST_KEY = 'WEBHOOK_TEMPLATES';
15
15
  export const WEBHOOK_API_REQUEST_KEY = 'WEBHOOK';
16
+ export const WEBHOOK_API_UPDATE_KEY = 'WEBHOOK_UPDATE';
16
17
  export const WEBHOOK_EVENTS_API_REQUEST_KEY = 'WEBHOOK_EVENTS';
17
18
 
18
19
  export const WEBHOOK_CREATE_MODAL_ID = 'webhookCreateModal';
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_webhooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timo Goebel