@strapi/admin 4.11.0-beta.1 → 4.11.0-exp.0

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.
Files changed (115) hide show
  1. package/admin/src/content-manager/components/ComponentIcon/ComponentIcon.js +16 -26
  2. package/admin/src/content-manager/components/ComponentIcon/constants.js +133 -0
  3. package/admin/src/content-manager/components/DynamicZone/components/AddComponentButton.js +32 -95
  4. package/admin/src/content-manager/components/DynamicZone/components/ComponentCard.js +10 -2
  5. package/admin/src/content-manager/components/DynamicZone/components/ComponentCategory.js +63 -15
  6. package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker.js +50 -63
  7. package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +132 -58
  8. package/admin/src/content-manager/components/DynamicZone/components/DynamicZoneLabel.js +29 -37
  9. package/admin/src/content-manager/components/DynamicZone/index.js +131 -83
  10. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +28 -6
  11. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +18 -6
  12. package/admin/src/content-manager/pages/EditSettingsView/components/DynamicZoneList.js +7 -1
  13. package/admin/src/content-manager/pages/EditView/index.js +1 -1
  14. package/admin/src/hooks/useContentTypes/useContentTypes.js +0 -2
  15. package/admin/src/index.js +4 -3
  16. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  17. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableCE.js +13 -0
  18. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
  19. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/Events/index.js +331 -0
  20. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/Combobox.js +54 -4
  21. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/index.js +12 -23
  22. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +129 -116
  23. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +62 -0
  24. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +59 -64
  25. package/admin/src/translations/en.json +6 -0
  26. package/build/1887.6f71e8b2.chunk.js +39 -0
  27. package/build/3081.7e9329cb.chunk.js +105 -0
  28. package/build/371.6e4e2c1f.chunk.js +71 -0
  29. package/build/5542.64b623c9.chunk.js +63 -0
  30. package/build/{5563.79950369.chunk.js → 5563.badbffde.chunk.js} +2 -2
  31. package/build/{6970.7ea35fbd.chunk.js → 6970.d456705f.chunk.js} +1 -1
  32. package/build/{7259.5cc67413.chunk.js → 7259.5d0de931.chunk.js} +1 -1
  33. package/build/8976.a85384ce.chunk.js +155 -0
  34. package/build/{1657.ca8562dd.chunk.js → 9932.5ef475c5.chunk.js} +54 -62
  35. package/build/{Admin-authenticatedApp.990df65d.chunk.js → Admin-authenticatedApp.c985d4a0.chunk.js} +2 -2
  36. package/build/{Admin_InternalErrorPage.96ceaae1.chunk.js → Admin_InternalErrorPage.f25f04f3.chunk.js} +1 -1
  37. package/build/Admin_homePage.05063e43.chunk.js +73 -0
  38. package/build/Admin_marketplace.23ea289f.chunk.js +55 -0
  39. package/build/Admin_pluginsPage.b1031a00.chunk.js +6 -0
  40. package/build/{Admin_profilePage.75bc083a.chunk.js → Admin_profilePage.e7ccee9f.chunk.js} +2 -2
  41. package/build/Admin_settingsPage.07a6a5f0.chunk.js +79 -0
  42. package/build/{Upload_ConfigureTheView.aa64ed9a.chunk.js → Upload_ConfigureTheView.121deffb.chunk.js} +1 -1
  43. package/build/admin-app.8644c322.chunk.js +63 -0
  44. package/build/{admin-edit-roles-page.0d12b741.chunk.js → admin-edit-roles-page.bfe3304d.chunk.js} +3 -3
  45. package/build/{admin-edit-users.f9ce7844.chunk.js → admin-edit-users.6efe0382.chunk.js} +2 -2
  46. package/build/admin-roles-list.b2577370.chunk.js +23 -0
  47. package/build/admin-users.4af49ccf.chunk.js +26 -0
  48. package/build/{api-tokens-create-page.973d2816.chunk.js → api-tokens-create-page.65411a36.chunk.js} +1 -1
  49. package/build/{api-tokens-edit-page.29725c5e.chunk.js → api-tokens-edit-page.60312cb6.chunk.js} +1 -1
  50. package/build/{api-tokens-list-page.66c4fbdd.chunk.js → api-tokens-list-page.01a4d5cd.chunk.js} +2 -2
  51. package/build/audit-logs-settings-page.09c75037.chunk.js +121 -0
  52. package/build/content-manager.04fa9c14.chunk.js +1094 -0
  53. package/build/content-type-builder-list-view.58f9ed20.chunk.js +211 -0
  54. package/build/{content-type-builder-translation-en-json.af293c9e.chunk.js → content-type-builder-translation-en-json.f592325b.chunk.js} +1 -1
  55. package/build/content-type-builder.baeb0413.chunk.js +132 -0
  56. package/build/email-settings-page.85b71afc.chunk.js +11 -0
  57. package/build/en-json.a8f34002.chunk.js +1 -0
  58. package/build/i18n-settings-page.c0da2362.chunk.js +114 -0
  59. package/build/index.html +1 -1
  60. package/build/main.8605d88e.js +2633 -0
  61. package/build/{review-workflows-settings.4b39b837.chunk.js → review-workflows-settings.3a7bae25.chunk.js} +1 -1
  62. package/build/{runtime~main.55d43bd7.js → runtime~main.36375726.js} +2 -2
  63. package/build/{sso-settings-page.265e3d72.chunk.js → sso-settings-page.4bb073e0.chunk.js} +1 -1
  64. package/build/{transfer-tokens-create-page.170acee6.chunk.js → transfer-tokens-create-page.9ec277d7.chunk.js} +1 -1
  65. package/build/{transfer-tokens-edit-page.6cf23295.chunk.js → transfer-tokens-edit-page.fa5ade14.chunk.js} +1 -1
  66. package/build/{transfer-tokens-list-page.c3fec4c1.chunk.js → transfer-tokens-list-page.5d68d590.chunk.js} +2 -2
  67. package/build/upload-settings.2c1565d6.chunk.js +14 -0
  68. package/build/upload.257b2aef.chunk.js +26 -0
  69. package/build/users-advanced-settings-page.dda58320.chunk.js +9 -0
  70. package/build/users-email-settings-page.a0c08594.chunk.js +24 -0
  71. package/build/users-providers-settings-page.14a82632.chunk.js +29 -0
  72. package/build/{users-roles-settings-page.c773086b.chunk.js → users-roles-settings-page.1f408276.chunk.js} +1 -1
  73. package/build/webhook-edit-page.b9a13be7.chunk.js +136 -0
  74. package/build/webhook-list-page.84e5abc9.chunk.js +63 -0
  75. package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/EventTableEE.js +23 -0
  76. package/ee/admin/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable/index.js +3 -0
  77. package/ee/server/services/review-workflows/review-workflows.js +4 -0
  78. package/package.json +19 -21
  79. package/server/controllers/webhooks.js +6 -6
  80. package/admin/src/content-manager/components/DynamicZone/utils/connect.js +0 -12
  81. package/admin/src/content-manager/components/DynamicZone/utils/select.js +0 -53
  82. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/EventRow.js +0 -70
  83. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +0 -174
  84. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/HeadersInput/keys.js +0 -39
  85. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/fieldsRegex.js +0 -4
  86. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/utils/schema.js +0 -35
  87. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/reducer.js +0 -100
  88. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/utils/formatData.js +0 -20
  89. package/build/3081.c2cdfac8.chunk.js +0 -108
  90. package/build/456.9b85d4c6.chunk.js +0 -39
  91. package/build/462.a073ff1f.chunk.js +0 -71
  92. package/build/5542.002522eb.chunk.js +0 -71
  93. package/build/617.87b2fe96.chunk.js +0 -155
  94. package/build/Admin_homePage.107a9fe0.chunk.js +0 -73
  95. package/build/Admin_marketplace.1436fc2b.chunk.js +0 -55
  96. package/build/Admin_pluginsPage.e1afd5ed.chunk.js +0 -6
  97. package/build/Admin_settingsPage.bd715ed3.chunk.js +0 -79
  98. package/build/admin-app.8b102fe2.chunk.js +0 -63
  99. package/build/admin-roles-list.e8bf9685.chunk.js +0 -31
  100. package/build/admin-users.751b28b2.chunk.js +0 -34
  101. package/build/audit-logs-settings-page.3c6cea81.chunk.js +0 -129
  102. package/build/content-manager.89099707.chunk.js +0 -1123
  103. package/build/content-type-builder-list-view.1e821eb9.chunk.js +0 -215
  104. package/build/content-type-builder.b10576e7.chunk.js +0 -126
  105. package/build/email-settings-page.4368689f.chunk.js +0 -11
  106. package/build/en-json.0f5cc115.chunk.js +0 -1
  107. package/build/i18n-settings-page.7988d872.chunk.js +0 -114
  108. package/build/main.5a232c3d.js +0 -2630
  109. package/build/upload-settings.63d99bf5.chunk.js +0 -14
  110. package/build/upload.c50d8c7a.chunk.js +0 -34
  111. package/build/users-advanced-settings-page.2cfb5d24.chunk.js +0 -9
  112. package/build/users-email-settings-page.bd6c774a.chunk.js +0 -24
  113. package/build/users-providers-settings-page.528f0036.chunk.js +0 -29
  114. package/build/webhook-edit-page.ddd5963d.chunk.js +0 -128
  115. package/build/webhook-list-page.b0f5a02c.chunk.js +0 -71
@@ -32,25 +32,19 @@ const HeadersInput = () => {
32
32
  name="headers"
33
33
  render={({ push, remove }) => (
34
34
  <Grid gap={4}>
35
- {values.headers?.map((header, i) => (
35
+ {values.headers.map((header, index) => (
36
36
  // eslint-disable-next-line
37
- <React.Fragment key={i}>
37
+ <React.Fragment key={`${index}.${header.key}`}>
38
38
  <GridItem col={6}>
39
39
  <Field
40
40
  as={Combobox}
41
- name={`headers.${i}.key`}
42
- aria-label={`row ${i + 1} key`}
41
+ name={`headers.${index}.key`}
42
+ aria-label={`row ${index + 1} key`}
43
43
  label={formatMessage({
44
44
  id: 'Settings.webhooks.key',
45
45
  defaultMessage: 'Key',
46
46
  })}
47
- error={
48
- errors.headers?.[i]?.key &&
49
- formatMessage({
50
- id: errors.headers[i]?.key,
51
- defaultMessage: errors.headers[i]?.key,
52
- })
53
- }
47
+ error={errors.headers?.[index]?.key && errors.headers[index].key}
54
48
  />
55
49
  </GridItem>
56
50
  <GridItem col={6}>
@@ -58,34 +52,29 @@ const HeadersInput = () => {
58
52
  <Box style={{ flex: 1 }}>
59
53
  <Field
60
54
  as={TextInput}
61
- aria-label={`row ${i + 1} value`}
55
+ name={`headers.${index}.value`}
56
+ aria-label={`row ${index + 1} value`}
62
57
  label={formatMessage({
63
58
  id: 'Settings.webhooks.value',
64
59
  defaultMessage: 'Value',
65
60
  })}
66
- name={`headers.${i}.value`}
67
- error={
68
- errors.headers?.[i]?.value &&
69
- formatMessage({
70
- id: errors.headers[i]?.value,
71
- defaultMessage: errors.headers[i]?.value,
72
- })
73
- }
61
+ error={errors.headers?.[index]?.value && errors.headers[index].value}
74
62
  />
75
63
  </Box>
76
64
  <Flex
77
65
  paddingLeft={2}
78
66
  style={{ alignSelf: 'center' }}
79
- paddingTop={errors.headers?.[i]?.value ? 0 : 5}
67
+ paddingTop={errors.headers?.[index]?.value ? 0 : 5}
80
68
  >
81
69
  <RemoveRoundedButton
82
- onClick={() => values.headers.length !== 1 && remove(i)}
70
+ disabled={values.headers.length === 1}
71
+ onClick={() => remove(index)}
83
72
  label={formatMessage(
84
73
  {
85
74
  id: 'Settings.webhooks.headers.remove',
86
75
  defaultMessage: 'Remove header row {number}',
87
76
  },
88
- { number: i + 1 }
77
+ { number: index + 1 }
89
78
  )}
90
79
  />
91
80
  </Flex>
@@ -1,145 +1,159 @@
1
1
  import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import { Field, FormikProvider, useFormik } from 'formik';
4
+ import { useIntl } from 'react-intl';
3
5
  import { Form, Link } from '@strapi/helper-plugin';
4
6
  import { ArrowLeft, Check, Play as Publish } from '@strapi/icons';
5
7
  import {
6
- ContentLayout,
7
- HeaderLayout,
8
- Box,
8
+ Grid,
9
+ GridItem,
9
10
  Button,
10
11
  Flex,
11
12
  TextInput,
12
- Grid,
13
- GridItem,
13
+ HeaderLayout,
14
+ ContentLayout,
15
+ Box,
14
16
  } from '@strapi/design-system';
15
- import { Field, Formik } from 'formik';
16
17
 
17
- import { useIntl } from 'react-intl';
18
- import EventInput from '../EventInput';
18
+ import EventTable from 'ee_else_ce/pages/SettingsPage/pages/Webhooks/EditView/components/EventTable';
19
+ import { makeWebhookValidationSchema } from './utils/makeWebhookValidationSchema';
19
20
  import HeadersInput from '../HeadersInput';
20
21
  import TriggerContainer from '../TriggerContainer';
21
- import schema from '../utils/schema';
22
22
 
23
23
  const WebhookForm = ({
24
24
  handleSubmit,
25
- data,
26
25
  triggerWebhook,
27
26
  isCreating,
28
27
  isTriggering,
29
28
  triggerResponse,
30
- isDraftAndPublishEvents,
29
+ data,
31
30
  }) => {
32
31
  const { formatMessage } = useIntl();
33
32
  const [showTriggerResponse, setShowTriggerResponse] = useState(false);
34
33
 
34
+ /**
35
+ * Map the headers into a form that can be used within the formik form
36
+ * @param {Object} headers
37
+ * @returns {Array}
38
+ */
39
+ const mapHeaders = (headers) => {
40
+ if (!Object.keys(headers).length) {
41
+ return [{ key: '', value: '' }];
42
+ }
43
+
44
+ return Object.entries(headers).map(([key, value]) => ({ key, value }));
45
+ };
46
+
47
+ const formik = useFormik({
48
+ initialValues: {
49
+ name: data?.name || '',
50
+ url: data?.url || '',
51
+ headers: mapHeaders(data?.headers || {}),
52
+ events: data?.events || [],
53
+ },
54
+ onSubmit: handleSubmit,
55
+ validationSchema: makeWebhookValidationSchema({ formatMessage }),
56
+ validateOnChange: false,
57
+ validateOnBlur: false,
58
+ });
59
+
35
60
  return (
36
- <Formik
37
- onSubmit={handleSubmit}
38
- initialValues={{
39
- name: data?.name || '',
40
- url: data?.url || '',
41
- headers: Object.keys(data?.headers || []).length
42
- ? Object.entries(data.headers).map(([key, value]) => ({ key, value }))
43
- : [{ key: '', value: '' }],
44
- events: data?.events || [],
45
- }}
46
- validationSchema={schema}
47
- validateOnChange={false}
48
- validateOnBlur={false}
49
- >
50
- {({ handleSubmit, errors }) => (
51
- <Form noValidate>
52
- <HeaderLayout
53
- primaryAction={
54
- <Flex gap={2}>
55
- <Button
56
- onClick={() => {
57
- triggerWebhook();
58
- setShowTriggerResponse(true);
59
- }}
60
- variant="tertiary"
61
- startIcon={<Publish />}
62
- disabled={isCreating || isTriggering}
63
- size="L"
64
- >
65
- {formatMessage({
66
- id: 'Settings.webhooks.trigger',
67
- defaultMessage: 'Trigger',
68
- })}
69
- </Button>
70
- <Button startIcon={<Check />} onClick={handleSubmit} type="submit" size="L">
71
- {formatMessage({
72
- id: 'global.save',
73
- defaultMessage: 'Save',
74
- })}
75
- </Button>
76
- </Flex>
77
- }
78
- title={
79
- isCreating
80
- ? formatMessage({
81
- id: 'Settings.webhooks.create',
82
- defaultMessage: 'Create a webhook',
83
- })
84
- : data?.name
85
- }
86
- navigationAction={
87
- <Link startIcon={<ArrowLeft />} to="/settings/webhooks">
61
+ <FormikProvider value={formik}>
62
+ <Form onSubmit={formik.handleSubmit}>
63
+ <HeaderLayout
64
+ primaryAction={
65
+ <Flex gap={2}>
66
+ <Button
67
+ onClick={() => {
68
+ triggerWebhook();
69
+ setShowTriggerResponse(true);
70
+ }}
71
+ variant="tertiary"
72
+ startIcon={<Publish />}
73
+ disabled={isCreating || isTriggering}
74
+ size="L"
75
+ >
88
76
  {formatMessage({
89
- id: 'global.back',
90
- defaultMessage: 'Back',
77
+ id: 'Settings.webhooks.trigger',
78
+ defaultMessage: 'Trigger',
91
79
  })}
92
- </Link>
93
- }
94
- />
95
- <ContentLayout>
96
- <Flex direction="column" alignItems="stretch" gap={4}>
97
- {showTriggerResponse && (
98
- <div className="trigger-wrapper">
99
- <TriggerContainer
100
- isPending={isTriggering}
101
- response={triggerResponse}
102
- onCancel={() => setShowTriggerResponse(false)}
103
- />
104
- </div>
105
- )}
106
- <Box background="neutral0" padding={8} shadow="filterShadow" hasRadius>
107
- <Flex direction="column" alignItems="stretch" gap={6}>
108
- <Grid gap={6}>
109
- <GridItem col={6}>
110
- <Field
111
- as={TextInput}
112
- name="name"
113
- error={errors.name && formatMessage({ id: errors.name })}
114
- label={formatMessage({
115
- id: 'global.name',
116
- defaultMessage: 'Name',
117
- })}
118
- required
119
- />
120
- </GridItem>
121
- <GridItem col={12}>
122
- <Field
123
- as={TextInput}
124
- name="url"
125
- error={errors.url && formatMessage({ id: errors.url })}
126
- label={formatMessage({
127
- id: 'Settings.roles.form.input.url',
128
- defaultMessage: 'Url',
129
- })}
130
- required
131
- />
132
- </GridItem>
133
- </Grid>
134
- <HeadersInput />
135
- <EventInput isDraftAndPublish={isDraftAndPublishEvents} />
136
- </Flex>
137
- </Box>
80
+ </Button>
81
+ <Button
82
+ startIcon={<Check />}
83
+ type="submit"
84
+ size="L"
85
+ disabled={!formik.dirty}
86
+ loading={formik.isSubmitting}
87
+ >
88
+ {formatMessage({
89
+ id: 'global.save',
90
+ defaultMessage: 'Save',
91
+ })}
92
+ </Button>
138
93
  </Flex>
139
- </ContentLayout>
140
- </Form>
141
- )}
142
- </Formik>
94
+ }
95
+ title={
96
+ isCreating
97
+ ? formatMessage({
98
+ id: 'Settings.webhooks.create',
99
+ defaultMessage: 'Create a webhook',
100
+ })
101
+ : data?.name
102
+ }
103
+ navigationAction={
104
+ <Link startIcon={<ArrowLeft />} to="/settings/webhooks">
105
+ {formatMessage({
106
+ id: 'global.back',
107
+ defaultMessage: 'Back',
108
+ })}
109
+ </Link>
110
+ }
111
+ />
112
+ <ContentLayout>
113
+ <Flex direction="column" alignItems="stretch" gap={4}>
114
+ {showTriggerResponse && (
115
+ <TriggerContainer
116
+ isPending={isTriggering}
117
+ response={triggerResponse}
118
+ onCancel={() => setShowTriggerResponse(false)}
119
+ />
120
+ )}
121
+ <Box background="neutral0" padding={8} shadow="filterShadow" hasRadius>
122
+ <Flex direction="column" alignItems="stretch" gap={6}>
123
+ <Grid gap={6}>
124
+ <GridItem col={6}>
125
+ <Field
126
+ as={TextInput}
127
+ name="name"
128
+ error={formik?.errors?.name && formik.errors.name}
129
+ label={formatMessage({
130
+ id: 'global.name',
131
+ defaultMessage: 'Name',
132
+ })}
133
+ required
134
+ />
135
+ </GridItem>
136
+ <GridItem col={12}>
137
+ <Field
138
+ as={TextInput}
139
+ name="url"
140
+ error={formik?.errors?.url && formik.errors.url}
141
+ label={formatMessage({
142
+ id: 'Settings.roles.form.input.url',
143
+ defaultMessage: 'Url',
144
+ })}
145
+ required
146
+ />
147
+ </GridItem>
148
+ </Grid>
149
+ <HeadersInput />
150
+ <EventTable />
151
+ </Flex>
152
+ </Box>
153
+ </Flex>
154
+ </ContentLayout>
155
+ </Form>
156
+ </FormikProvider>
143
157
  );
144
158
  };
145
159
 
@@ -148,7 +162,6 @@ WebhookForm.propTypes = {
148
162
  handleSubmit: PropTypes.func.isRequired,
149
163
  triggerWebhook: PropTypes.func.isRequired,
150
164
  isCreating: PropTypes.bool.isRequired,
151
- isDraftAndPublishEvents: PropTypes.bool.isRequired,
152
165
  isTriggering: PropTypes.bool.isRequired,
153
166
  triggerResponse: PropTypes.object,
154
167
  };
@@ -0,0 +1,62 @@
1
+ import * as yup from 'yup';
2
+ import { translatedErrors } from '@strapi/helper-plugin';
3
+
4
+ const NAME_REGEX = /(^$)|(^[A-Za-z][_0-9A-Za-z ]*$)/;
5
+ const URL_REGEX = /(^$)|((https?:\/\/.*)(d*)\/?(.*))/;
6
+
7
+ export const makeWebhookValidationSchema = ({ formatMessage }) =>
8
+ yup.object().shape({
9
+ name: yup
10
+ .string()
11
+ .required(
12
+ formatMessage({
13
+ id: 'Settings.webhooks.validation.name',
14
+ defaultMessage: 'Name is required',
15
+ })
16
+ )
17
+ .matches(NAME_REGEX, translatedErrors.regex),
18
+ url: yup
19
+ .string()
20
+ .required(
21
+ formatMessage({
22
+ id: 'Settings.webhooks.validation.url.required',
23
+ defaultMessage: 'Url is required',
24
+ })
25
+ )
26
+ .matches(
27
+ URL_REGEX,
28
+ formatMessage({
29
+ id: translatedErrors.regex,
30
+ defaultMessage: 'The value does not match the regex',
31
+ })
32
+ ),
33
+ headers: yup.lazy((array) => {
34
+ let baseSchema = yup.array();
35
+
36
+ if (array.length === 1) {
37
+ const { key, value } = array[0];
38
+
39
+ if (!key && !value) {
40
+ return baseSchema;
41
+ }
42
+ }
43
+
44
+ return baseSchema.of(
45
+ yup.object().shape({
46
+ key: yup.string().required(
47
+ formatMessage({
48
+ id: 'Settings.webhooks.validation.key',
49
+ defaultMessage: 'Key is required',
50
+ })
51
+ ),
52
+ value: yup.string().required(
53
+ formatMessage({
54
+ id: 'Settings.webhooks.validation.value',
55
+ defaultMessage: 'Value is required',
56
+ })
57
+ ),
58
+ })
59
+ );
60
+ }),
61
+ events: yup.array(),
62
+ });
@@ -1,60 +1,68 @@
1
- /**
2
- *
3
- * EditView
4
- *
5
- */
6
1
  import * as React from 'react';
7
2
  import {
8
3
  LoadingIndicatorPage,
9
4
  SettingsPageTitle,
10
5
  useNotification,
11
- useOverlayBlocker,
12
6
  useFetchClient,
7
+ useAPIErrorHandler,
13
8
  } from '@strapi/helper-plugin';
14
9
  import { Main } from '@strapi/design-system';
15
10
  import { useMutation, useQuery, useQueryClient } from 'react-query';
16
11
  import { useHistory, useRouteMatch } from 'react-router-dom';
17
12
  import { useContentTypes } from '../../../../../hooks/useContentTypes';
18
13
  import WebhookForm from './components/WebhookForm';
19
- import cleanData from './utils/formatData';
14
+
15
+ const cleanData = (data) => ({
16
+ ...data,
17
+ headers: data.headers.reduce((acc, { key, value }) => {
18
+ if (key !== '') {
19
+ acc[key] = value;
20
+ }
21
+
22
+ return acc;
23
+ }, {}),
24
+ });
20
25
 
21
26
  const EditView = () => {
22
27
  const {
23
28
  params: { id },
24
29
  } = useRouteMatch('/settings/webhooks/:id');
30
+ const isCreating = id === 'create';
25
31
 
26
32
  const { replace } = useHistory();
27
- const { lockApp, unlockApp } = useOverlayBlocker();
28
33
  const toggleNotification = useNotification();
34
+ const { formatAPIError } = useAPIErrorHandler();
29
35
  const queryClient = useQueryClient();
30
- const { isLoading: isLoadingForModels, collectionTypes } = useContentTypes();
36
+ const { isLoading: isLoadingForModels } = useContentTypes();
31
37
  const { put, get, post } = useFetchClient();
32
38
 
33
- const isCreating = id === 'create';
34
-
35
- const { isLoading, data } = useQuery(
36
- ['get-webhook', id],
39
+ const {
40
+ isLoading,
41
+ data: webhookData,
42
+ error: webhookError,
43
+ } = useQuery(
44
+ ['webhooks', id],
37
45
  async () => {
38
- try {
39
- const {
40
- data: { data },
41
- } = await get(`/admin/webhooks/${id}`);
46
+ const {
47
+ data: { data },
48
+ } = await get(`/admin/webhooks/${id}`);
42
49
 
43
- return data;
44
- } catch (err) {
45
- toggleNotification({
46
- type: 'warning',
47
- message: { id: 'notification.error' },
48
- });
49
-
50
- return null;
51
- }
50
+ return data;
52
51
  },
53
52
  {
54
53
  enabled: !isCreating,
55
54
  }
56
55
  );
57
56
 
57
+ React.useEffect(() => {
58
+ if (webhookError) {
59
+ toggleNotification({
60
+ type: 'warning',
61
+ message: formatAPIError(webhookError),
62
+ });
63
+ }
64
+ }, [webhookError, toggleNotification, formatAPIError]);
65
+
58
66
  const {
59
67
  isLoading: isTriggering,
60
68
  data: triggerResponse,
@@ -64,10 +72,10 @@ const EditView = () => {
64
72
 
65
73
  const triggerWebhook = () =>
66
74
  mutate(null, {
67
- onError() {
75
+ onError(error) {
68
76
  toggleNotification({
69
77
  type: 'warning',
70
- message: { id: 'notification.error' },
78
+ message: formatAPIError(error),
71
79
  });
72
80
  },
73
81
  });
@@ -78,7 +86,6 @@ const EditView = () => {
78
86
 
79
87
  const handleSubmit = async (data) => {
80
88
  if (isCreating) {
81
- lockApp();
82
89
  createWebhookMutation.mutate(cleanData(data), {
83
90
  onSuccess({ data: result }) {
84
91
  toggleNotification({
@@ -86,48 +93,37 @@ const EditView = () => {
86
93
  message: { id: 'Settings.webhooks.created' },
87
94
  });
88
95
  replace(`/settings/webhooks/${result.data.id}`);
89
- unlockApp();
90
96
  },
91
- onError(e) {
97
+ onError(error) {
92
98
  toggleNotification({
93
99
  type: 'warning',
94
- message: { id: 'notification.error' },
100
+ message: formatAPIError(error),
95
101
  });
96
- console.log(e);
97
- unlockApp();
98
102
  },
99
103
  });
100
- } else {
101
- lockApp();
102
- updateWebhookMutation.mutate(
103
- { id, body: cleanData(data) },
104
- {
105
- onSuccess() {
106
- queryClient.invalidateQueries(['get-webhook', id]);
107
- toggleNotification({
108
- type: 'success',
109
- message: { id: 'notification.form.success.fields' },
110
- });
111
- unlockApp();
112
- },
113
- onError(e) {
114
- toggleNotification({
115
- type: 'warning',
116
- message: { id: 'notification.error' },
117
- });
118
- console.log(e);
119
- unlockApp();
120
- },
121
- }
122
- );
104
+
105
+ return;
123
106
  }
107
+ updateWebhookMutation.mutate(
108
+ { id, body: cleanData(data) },
109
+ {
110
+ onSuccess() {
111
+ queryClient.invalidateQueries(['webhooks', id]);
112
+ toggleNotification({
113
+ type: 'success',
114
+ message: { id: 'notification.form.success.fields' },
115
+ });
116
+ },
117
+ onError(error) {
118
+ toggleNotification({
119
+ type: 'warning',
120
+ message: formatAPIError(error),
121
+ });
122
+ },
123
+ }
124
+ );
124
125
  };
125
126
 
126
- const isDraftAndPublishEvents = React.useMemo(
127
- () => collectionTypes.some((ct) => ct.options.draftAndPublish === true),
128
- [collectionTypes]
129
- );
130
-
131
127
  if (isLoading || isLoadingForModels) {
132
128
  return <LoadingIndicatorPage />;
133
129
  }
@@ -137,14 +133,13 @@ const EditView = () => {
137
133
  <SettingsPageTitle name="Webhooks" />
138
134
  <WebhookForm
139
135
  {...{
136
+ data: webhookData,
140
137
  handleSubmit,
141
- data,
142
138
  triggerWebhook,
143
139
  isCreating,
144
140
  isTriggering,
145
141
  isTriggerIdle,
146
142
  triggerResponse: triggerResponse?.data.data,
147
- isDraftAndPublishEvents,
148
143
  }}
149
144
  />
150
145
  </Main>
@@ -285,6 +285,8 @@
285
285
  "Settings.webhooks.create.header": "Create new header",
286
286
  "Settings.webhooks.created": "Webhook created",
287
287
  "Settings.webhooks.event.publish-tooltip": "This event only exists for contents with Draft/Publish system enabled",
288
+ "Settings.webhooks.event.select": "Select event",
289
+ "Settings.webhooks.events.isLoading": "Events loading",
288
290
  "Settings.webhooks.events.create": "Create",
289
291
  "Settings.webhooks.events.update": "Update",
290
292
  "Settings.webhooks.events.delete": "Delete webhook",
@@ -313,6 +315,10 @@
313
315
  "Settings.webhooks.trigger.test": "Test-trigger",
314
316
  "Settings.webhooks.trigger.title": "Save before Trigger",
315
317
  "Settings.webhooks.value": "Value",
318
+ "Settings.webhooks.validation.name": "Name is required",
319
+ "Settings.webhooks.validation.url.required": "Url is required",
320
+ "Settings.webhooks.validation.key": "Key is required",
321
+ "Settings.webhooks.validation.value": "Value is required",
316
322
  "Usecase.back-end": "Back-end developer",
317
323
  "Usecase.button.skip": "Skip this question",
318
324
  "Usecase.content-creator": "Content Creator",