@strapi/plugin-documentation 4.20.4 → 5.0.0-alpha.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.
- package/admin/src/hooks/useDocumentation.js +10 -7
- package/admin/src/index.js +4 -18
- package/admin/src/pages/PluginPage/index.jsx +10 -24
- package/admin/src/pages/PluginPage/tests/index.test.jsx +13 -14
- package/admin/src/pages/SettingsPage/index.jsx +138 -142
- package/admin/src/pages/SettingsPage/tests/index.test.jsx +6 -13
- package/dist/_chunks/EditViewPage-xYzUSAwS-NigDiZi1.js +84396 -0
- package/dist/_chunks/EditViewPage-xYzUSAwS-NigDiZi1.js.map +1 -0
- package/dist/_chunks/EditViewPage-xYzUSAwS-OCSjk-Vt.mjs +84368 -0
- package/dist/_chunks/EditViewPage-xYzUSAwS-OCSjk-Vt.mjs.map +1 -0
- package/dist/_chunks/ListViewPage-xOVa04T_-JQSQJ0aH.js +1618 -0
- package/dist/_chunks/ListViewPage-xOVa04T_-JQSQJ0aH.js.map +1 -0
- package/dist/_chunks/ListViewPage-xOVa04T_-MAsyJIvQ.mjs +1595 -0
- package/dist/_chunks/ListViewPage-xOVa04T_-MAsyJIvQ.mjs.map +1 -0
- package/dist/_chunks/ReviewWorkflowsColumn-FDxVKdto-9EdyIGCi.js +33 -0
- package/dist/_chunks/ReviewWorkflowsColumn-FDxVKdto-9EdyIGCi.js.map +1 -0
- package/dist/_chunks/ReviewWorkflowsColumn-FDxVKdto-E7QaAVIp.mjs +33 -0
- package/dist/_chunks/ReviewWorkflowsColumn-FDxVKdto-E7QaAVIp.mjs.map +1 -0
- package/dist/_chunks/constants-WjN6I3sL-1yTyGpl5.mjs +190 -0
- package/dist/_chunks/constants-WjN6I3sL-1yTyGpl5.mjs.map +1 -0
- package/dist/_chunks/constants-WjN6I3sL-5vTd1Y1g.js +209 -0
- package/dist/_chunks/constants-WjN6I3sL-5vTd1Y1g.js.map +1 -0
- package/dist/_chunks/index--rtz8bZh.mjs +17798 -0
- package/dist/_chunks/index--rtz8bZh.mjs.map +1 -0
- package/dist/_chunks/index-FiShd2zI.js +17823 -0
- package/dist/_chunks/index-FiShd2zI.js.map +1 -0
- package/dist/_chunks/{index-RtHTnuE1.mjs → index-Qt8XLNQZ.mjs} +11 -8
- package/dist/_chunks/index-Qt8XLNQZ.mjs.map +1 -0
- package/dist/_chunks/{index-xwpmk0Y9.mjs → index-h-OcS50W.mjs} +19 -25
- package/dist/_chunks/index-h-OcS50W.mjs.map +1 -0
- package/dist/_chunks/{index-PR_fql8f.js → index-m8HLcGmV.js} +15 -12
- package/dist/_chunks/index-m8HLcGmV.js.map +1 -0
- package/dist/_chunks/{index-ku5QIWHo.js → index-vWzO1snG.js} +21 -27
- package/dist/_chunks/index-vWzO1snG.js.map +1 -0
- package/dist/_chunks/{useDocumentation-glNqpmZO.mjs → useDocumentation-EsufCjtn.mjs} +12 -9
- package/dist/_chunks/useDocumentation-EsufCjtn.mjs.map +1 -0
- package/dist/_chunks/{useDocumentation-jpgzaGlD.js → useDocumentation-hOQyphRS.js} +14 -11
- package/dist/_chunks/useDocumentation-hOQyphRS.js.map +1 -0
- package/dist/_chunks/useSyncRbac-Kt8Li0Yf-f6LRUqJf.js +57 -0
- package/dist/_chunks/useSyncRbac-Kt8Li0Yf-f6LRUqJf.js.map +1 -0
- package/dist/_chunks/useSyncRbac-Kt8Li0Yf-mDaHJCOQ.mjs +39 -0
- package/dist/_chunks/useSyncRbac-Kt8Li0Yf-mDaHJCOQ.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/style.css +84 -0
- package/package.json +15 -15
- package/server/controllers/documentation.js +2 -2
- package/server/middlewares/restrict-access.js +1 -1
- package/server/services/__mocks__/mock-content-types.js +0 -5
- package/server/services/documentation.js +2 -3
- package/server/services/override.js +1 -1
- package/dist/_chunks/index-990q37Xx.mjs +0 -167
- package/dist/_chunks/index-990q37Xx.mjs.map +0 -1
- package/dist/_chunks/index-PR_fql8f.js.map +0 -1
- package/dist/_chunks/index-RtHTnuE1.mjs.map +0 -1
- package/dist/_chunks/index-U4uH9lyg.js +0 -169
- package/dist/_chunks/index-U4uH9lyg.js.map +0 -1
- package/dist/_chunks/index-ku5QIWHo.js.map +0 -1
- package/dist/_chunks/index-xwpmk0Y9.mjs.map +0 -1
- package/dist/_chunks/useDocumentation-glNqpmZO.mjs.map +0 -1
- package/dist/_chunks/useDocumentation-jpgzaGlD.js.map +0 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import { useFetchClient
|
|
3
|
+
import { useFetchClient } from '@strapi/helper-plugin';
|
|
4
|
+
import { useAPIErrorHandler, useNotification } from '@strapi/strapi/admin';
|
|
5
|
+
import { useIntl } from 'react-intl';
|
|
4
6
|
import { useMutation, useQuery } from 'react-query';
|
|
5
7
|
|
|
6
8
|
import pluginId from '../pluginId';
|
|
7
9
|
import getTrad from '../utils/getTrad';
|
|
8
10
|
|
|
9
11
|
export const useDocumentation = () => {
|
|
10
|
-
const toggleNotification = useNotification();
|
|
12
|
+
const { toggleNotification } = useNotification();
|
|
13
|
+
const { formatMessage } = useIntl();
|
|
11
14
|
const { del, post, put, get } = useFetchClient();
|
|
12
15
|
|
|
13
16
|
const { formatAPIError } = useAPIErrorHandler();
|
|
@@ -24,15 +27,15 @@ export const useDocumentation = () => {
|
|
|
24
27
|
useEffect(() => {
|
|
25
28
|
if (isError && error) {
|
|
26
29
|
toggleNotification({
|
|
27
|
-
type: '
|
|
28
|
-
message: error ? formatAPIError(error) : { id: 'notification.error' },
|
|
30
|
+
type: 'danger',
|
|
31
|
+
message: error ? formatAPIError(error) : formatMessage({ id: 'notification.error' }),
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
|
-
}, [isError, error, toggleNotification, formatAPIError]);
|
|
34
|
+
}, [isError, error, toggleNotification, formatAPIError, formatMessage]);
|
|
32
35
|
|
|
33
36
|
const handleError = (err) => {
|
|
34
37
|
toggleNotification({
|
|
35
|
-
type: '
|
|
38
|
+
type: 'danger',
|
|
36
39
|
message: formatAPIError(err),
|
|
37
40
|
});
|
|
38
41
|
};
|
|
@@ -41,7 +44,7 @@ export const useDocumentation = () => {
|
|
|
41
44
|
refetch();
|
|
42
45
|
toggleNotification({
|
|
43
46
|
type,
|
|
44
|
-
message: { id: getTrad(tradId), defaultMessage },
|
|
47
|
+
message: formatMessage({ id: getTrad(tradId), defaultMessage }),
|
|
45
48
|
});
|
|
46
49
|
};
|
|
47
50
|
|
package/admin/src/index.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
// NOTE TO PLUGINS DEVELOPERS:
|
|
2
|
-
// If you modify this file by adding new options to the plugin entry point
|
|
3
|
-
// Here's the file: strapi/docs/3.0.0-beta.x/plugin-development/frontend-field-api.md
|
|
4
|
-
// Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
|
|
5
|
-
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
|
6
|
-
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
|
7
1
|
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
|
8
2
|
import { Information } from '@strapi/icons';
|
|
9
3
|
|
|
@@ -17,18 +11,14 @@ const name = pluginPkg.strapi.name;
|
|
|
17
11
|
export default {
|
|
18
12
|
register(app) {
|
|
19
13
|
app.addMenuLink({
|
|
20
|
-
to:
|
|
14
|
+
to: `plugins/${pluginId}`,
|
|
21
15
|
icon: Information,
|
|
22
16
|
intlLabel: {
|
|
23
17
|
id: `${pluginId}.plugin.name`,
|
|
24
18
|
defaultMessage: 'Documentation',
|
|
25
19
|
},
|
|
26
20
|
permissions: PERMISSIONS.main,
|
|
27
|
-
|
|
28
|
-
const component = await import('./pages/PluginPage');
|
|
29
|
-
|
|
30
|
-
return component;
|
|
31
|
-
},
|
|
21
|
+
Component: () => import('./pages/PluginPage'),
|
|
32
22
|
});
|
|
33
23
|
|
|
34
24
|
app.registerPlugin({
|
|
@@ -43,12 +33,8 @@ export default {
|
|
|
43
33
|
defaultMessage: 'Documentation',
|
|
44
34
|
},
|
|
45
35
|
id: 'documentation',
|
|
46
|
-
to:
|
|
47
|
-
|
|
48
|
-
const component = await import('./pages/SettingsPage');
|
|
49
|
-
|
|
50
|
-
return component;
|
|
51
|
-
},
|
|
36
|
+
to: pluginId,
|
|
37
|
+
Component: () => import('./pages/SettingsPage'),
|
|
52
38
|
permissions: PERMISSIONS.main,
|
|
53
39
|
});
|
|
54
40
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
|
|
3
|
+
import { ConfirmDialog } from '@strapi/admin/strapi-admin';
|
|
3
4
|
import {
|
|
4
|
-
Box,
|
|
5
5
|
LinkButton,
|
|
6
6
|
ContentLayout,
|
|
7
7
|
Flex,
|
|
@@ -16,16 +16,11 @@ import {
|
|
|
16
16
|
Thead,
|
|
17
17
|
Tr,
|
|
18
18
|
Typography,
|
|
19
|
-
} from '@strapi/design-system';
|
|
20
|
-
import {
|
|
21
|
-
AnErrorOccurred,
|
|
22
|
-
ConfirmDialog,
|
|
23
19
|
EmptyStateLayout,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
useRBAC,
|
|
27
|
-
} from '@strapi/helper-plugin';
|
|
20
|
+
} from '@strapi/design-system';
|
|
21
|
+
import { useFocusWhenNavigate, useRBAC } from '@strapi/helper-plugin';
|
|
28
22
|
import { Eye as Show, Refresh as Reload, Trash } from '@strapi/icons';
|
|
23
|
+
import { Page } from '@strapi/strapi/admin';
|
|
29
24
|
import { Helmet } from 'react-helmet';
|
|
30
25
|
import { useIntl } from 'react-intl';
|
|
31
26
|
import styled from 'styled-components';
|
|
@@ -39,7 +34,6 @@ const PluginPage = () => {
|
|
|
39
34
|
const { formatMessage } = useIntl();
|
|
40
35
|
const { data, isLoading, isError, remove, regenerate } = useDocumentation();
|
|
41
36
|
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
|
42
|
-
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
|
|
43
37
|
const [versionToDelete, setVersionToDelete] = useState();
|
|
44
38
|
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
45
39
|
|
|
@@ -55,10 +49,8 @@ const PluginPage = () => {
|
|
|
55
49
|
};
|
|
56
50
|
|
|
57
51
|
const handleConfirmDelete = async () => {
|
|
58
|
-
setIsConfirmButtonLoading(true);
|
|
59
52
|
await remove.mutateAsync({ prefix: data?.prefix, version: versionToDelete });
|
|
60
53
|
setShowConfirmDelete(!showConfirmDelete);
|
|
61
|
-
setIsConfirmButtonLoading(false);
|
|
62
54
|
};
|
|
63
55
|
|
|
64
56
|
const handleClickDelete = (version) => {
|
|
@@ -71,16 +63,12 @@ const PluginPage = () => {
|
|
|
71
63
|
defaultMessage: 'Documentation',
|
|
72
64
|
});
|
|
73
65
|
|
|
66
|
+
if (isLoading) {
|
|
67
|
+
return <Page.Loading />;
|
|
68
|
+
}
|
|
69
|
+
|
|
74
70
|
if (isError) {
|
|
75
|
-
return
|
|
76
|
-
<Layout>
|
|
77
|
-
<ContentLayout>
|
|
78
|
-
<Box paddingTop={8}>
|
|
79
|
-
<AnErrorOccurred />
|
|
80
|
-
</Box>
|
|
81
|
-
</ContentLayout>
|
|
82
|
-
</Layout>
|
|
83
|
-
);
|
|
71
|
+
return <Page.Error />;
|
|
84
72
|
}
|
|
85
73
|
|
|
86
74
|
return (
|
|
@@ -107,7 +95,6 @@ const PluginPage = () => {
|
|
|
107
95
|
}
|
|
108
96
|
/>
|
|
109
97
|
<ContentLayout>
|
|
110
|
-
{isLoading && <LoadingIndicatorPage>Plugin is loading</LoadingIndicatorPage>}
|
|
111
98
|
{data?.docVersions.length ? (
|
|
112
99
|
<Table colCount={colCount} rowCount={rowCount}>
|
|
113
100
|
<Thead>
|
|
@@ -198,9 +185,8 @@ const PluginPage = () => {
|
|
|
198
185
|
)}
|
|
199
186
|
</ContentLayout>
|
|
200
187
|
<ConfirmDialog
|
|
201
|
-
isConfirmButtonLoading={isConfirmButtonLoading}
|
|
202
188
|
onConfirm={handleConfirmDelete}
|
|
203
|
-
|
|
189
|
+
onClose={handleShowConfirmDelete}
|
|
204
190
|
isOpen={showConfirmDelete}
|
|
205
191
|
/>
|
|
206
192
|
</Main>
|
|
@@ -2,7 +2,8 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { fixtures } from '@strapi/admin-test-utils';
|
|
4
4
|
import { lightTheme, ThemeProvider } from '@strapi/design-system';
|
|
5
|
-
import {
|
|
5
|
+
import { RBACContext } from '@strapi/helper-plugin';
|
|
6
|
+
import { NotificationsProvider } from '@strapi/strapi/admin';
|
|
6
7
|
import { render as renderRTL, waitFor } from '@testing-library/react';
|
|
7
8
|
import userEvent from '@testing-library/user-event';
|
|
8
9
|
import { IntlProvider } from 'react-intl';
|
|
@@ -54,16 +55,15 @@ describe('PluginPage', () => {
|
|
|
54
55
|
it('render the plugin page correctly', async () => {
|
|
55
56
|
const { getByRole, queryByText, getByText } = render();
|
|
56
57
|
|
|
58
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
59
|
+
|
|
57
60
|
expect(getByRole('heading', { name: 'Documentation' })).toBeInTheDocument();
|
|
58
61
|
expect(getByText('Configure the documentation plugin')).toBeInTheDocument();
|
|
59
|
-
expect(queryByText('Plugin is loading')).toBeInTheDocument();
|
|
60
62
|
expect(getByRole('link', { name: 'Open Documentation' })).toHaveAttribute(
|
|
61
63
|
'aria-disabled',
|
|
62
|
-
'
|
|
64
|
+
'false'
|
|
63
65
|
);
|
|
64
66
|
|
|
65
|
-
await waitFor(() => expect(queryByText('Plugin is loading')).not.toBeInTheDocument());
|
|
66
|
-
|
|
67
67
|
expect(getByRole('heading', { name: 'Documentation' })).toBeInTheDocument();
|
|
68
68
|
expect(getByText('Configure the documentation plugin')).toBeInTheDocument();
|
|
69
69
|
expect(getByRole('link', { name: 'Open Documentation' })).toBeInTheDocument();
|
|
@@ -90,7 +90,7 @@ describe('PluginPage', () => {
|
|
|
90
90
|
it('should open the documentation', async () => {
|
|
91
91
|
const { getByRole, queryByText, user } = render();
|
|
92
92
|
|
|
93
|
-
await waitFor(() => expect(queryByText('
|
|
93
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
94
94
|
|
|
95
95
|
expect(getByRole('link', { name: 'Open Documentation' })).toHaveAttribute(
|
|
96
96
|
'href',
|
|
@@ -110,7 +110,7 @@ describe('PluginPage', () => {
|
|
|
110
110
|
it('should regenerate the documentation', async () => {
|
|
111
111
|
const { getByRole, queryByText, user, getByText } = render();
|
|
112
112
|
|
|
113
|
-
await waitFor(() => expect(queryByText('
|
|
113
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
114
114
|
|
|
115
115
|
expect(getByRole('button', { name: 'Regenerate 2.0.0' })).toBeInTheDocument();
|
|
116
116
|
|
|
@@ -122,7 +122,7 @@ describe('PluginPage', () => {
|
|
|
122
122
|
it('should delete the documentation', async () => {
|
|
123
123
|
const { getByRole, queryByText, user, getByText } = render();
|
|
124
124
|
|
|
125
|
-
await waitFor(() => expect(queryByText('
|
|
125
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
126
126
|
|
|
127
127
|
expect(getByRole('button', { name: 'Delete 2.0.0' })).toBeInTheDocument();
|
|
128
128
|
|
|
@@ -144,14 +144,13 @@ describe('PluginPage', () => {
|
|
|
144
144
|
permissions: [],
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
expect(queryByText('
|
|
147
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
148
|
+
|
|
148
149
|
expect(getByRole('link', { name: 'Open Documentation' })).toHaveAttribute(
|
|
149
150
|
'aria-disabled',
|
|
150
151
|
'true'
|
|
151
152
|
);
|
|
152
153
|
|
|
153
|
-
await waitFor(() => expect(queryByText('Plugin is loading')).not.toBeInTheDocument());
|
|
154
|
-
|
|
155
154
|
expect(getByRole('link', { name: 'Open Documentation' })).toHaveAttribute(
|
|
156
155
|
'aria-disabled',
|
|
157
156
|
'true'
|
|
@@ -163,7 +162,7 @@ describe('PluginPage', () => {
|
|
|
163
162
|
permissions: [],
|
|
164
163
|
});
|
|
165
164
|
|
|
166
|
-
await waitFor(() => expect(queryByText('
|
|
165
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
167
166
|
|
|
168
167
|
versions.forEach((version) => {
|
|
169
168
|
expect(getByRole('gridcell', { name: version })).toBeInTheDocument();
|
|
@@ -180,7 +179,7 @@ describe('PluginPage', () => {
|
|
|
180
179
|
permissions: [],
|
|
181
180
|
});
|
|
182
181
|
|
|
183
|
-
await waitFor(() => expect(queryByText('
|
|
182
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
184
183
|
|
|
185
184
|
versions.forEach((version) => {
|
|
186
185
|
expect(getByRole('gridcell', { name: version })).toBeInTheDocument();
|
|
@@ -194,7 +193,7 @@ describe('PluginPage', () => {
|
|
|
194
193
|
permissions: [],
|
|
195
194
|
});
|
|
196
195
|
|
|
197
|
-
await waitFor(() => expect(queryByText('
|
|
196
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
198
197
|
|
|
199
198
|
versions.forEach((version) => {
|
|
200
199
|
expect(getByRole('gridcell', { name: version })).toBeInTheDocument();
|
|
@@ -14,16 +14,12 @@ import {
|
|
|
14
14
|
Typography,
|
|
15
15
|
FieldAction,
|
|
16
16
|
} from '@strapi/design-system';
|
|
17
|
-
import {
|
|
18
|
-
Form,
|
|
19
|
-
LoadingIndicatorPage,
|
|
20
|
-
useFocusWhenNavigate,
|
|
21
|
-
translatedErrors,
|
|
22
|
-
useRBAC,
|
|
23
|
-
} from '@strapi/helper-plugin';
|
|
24
|
-
// Strapi Icons
|
|
17
|
+
import { useFocusWhenNavigate, useRBAC } from '@strapi/helper-plugin';
|
|
25
18
|
import { Check, Eye as Show, EyeStriked as Hide } from '@strapi/icons';
|
|
26
|
-
import {
|
|
19
|
+
import { translatedErrors } from '@strapi/strapi/admin';
|
|
20
|
+
// Strapi Icons
|
|
21
|
+
import { Page } from '@strapi/strapi/admin';
|
|
22
|
+
import { Form, Formik } from 'formik';
|
|
27
23
|
import { useIntl } from 'react-intl';
|
|
28
24
|
import styled from 'styled-components';
|
|
29
25
|
import * as yup from 'yup';
|
|
@@ -35,7 +31,7 @@ import { getTrad } from '../../utils';
|
|
|
35
31
|
const schema = yup.object().shape({
|
|
36
32
|
restrictedAccess: yup.boolean(),
|
|
37
33
|
password: yup.string().when('restrictedAccess', (value, initSchema) => {
|
|
38
|
-
return value ? initSchema.required(translatedErrors.required) : initSchema;
|
|
34
|
+
return value ? initSchema.required(translatedErrors.required.id) : initSchema;
|
|
39
35
|
}),
|
|
40
36
|
});
|
|
41
37
|
|
|
@@ -53,147 +49,147 @@ const SettingsPage = () => {
|
|
|
53
49
|
});
|
|
54
50
|
};
|
|
55
51
|
|
|
52
|
+
if (isLoading) {
|
|
53
|
+
return <Page.Loading />;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
56
|
return (
|
|
57
57
|
<Main>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
58
|
+
<Formik
|
|
59
|
+
initialValues={{
|
|
60
|
+
restrictedAccess: data?.documentationAccess.restrictedAccess || false,
|
|
61
|
+
password: '',
|
|
62
|
+
}}
|
|
63
|
+
onSubmit={handleUpdateSettingsSubmit}
|
|
64
|
+
validationSchema={schema}
|
|
65
|
+
>
|
|
66
|
+
{({
|
|
67
|
+
handleSubmit,
|
|
68
|
+
values,
|
|
69
|
+
handleChange,
|
|
70
|
+
errors,
|
|
71
|
+
setFieldTouched,
|
|
72
|
+
setFieldValue,
|
|
73
|
+
dirty,
|
|
74
|
+
}) => {
|
|
75
|
+
return (
|
|
76
|
+
<Form noValidate onSubmit={handleSubmit}>
|
|
77
|
+
<HeaderLayout
|
|
78
|
+
title={formatMessage({
|
|
79
|
+
id: getTrad('plugin.name'),
|
|
80
|
+
defaultMessage: 'Documentation',
|
|
81
|
+
})}
|
|
82
|
+
subtitle={formatMessage({
|
|
83
|
+
id: getTrad('pages.SettingsPage.header.description'),
|
|
84
|
+
defaultMessage: 'Configure the documentation plugin',
|
|
85
|
+
})}
|
|
86
|
+
primaryAction={
|
|
87
|
+
<Button
|
|
88
|
+
type="submit"
|
|
89
|
+
startIcon={<Check />}
|
|
90
|
+
disabled={!dirty && allowedActions.canUpdate}
|
|
91
|
+
>
|
|
92
|
+
{formatMessage({
|
|
93
|
+
id: getTrad('pages.SettingsPage.Button.save'),
|
|
94
|
+
defaultMessage: 'Save',
|
|
95
|
+
})}
|
|
96
|
+
</Button>
|
|
97
|
+
}
|
|
98
|
+
/>
|
|
99
|
+
<ContentLayout>
|
|
100
|
+
<Box
|
|
101
|
+
background="neutral0"
|
|
102
|
+
hasRadius
|
|
103
|
+
shadow="filterShadow"
|
|
104
|
+
paddingTop={6}
|
|
105
|
+
paddingBottom={6}
|
|
106
|
+
paddingLeft={7}
|
|
107
|
+
paddingRight={7}
|
|
108
|
+
>
|
|
109
|
+
<Flex direction="column" alignItems="stretch" gap={4}>
|
|
110
|
+
<Typography variant="delta" as="h2">
|
|
95
111
|
{formatMessage({
|
|
96
|
-
id:
|
|
97
|
-
defaultMessage: '
|
|
112
|
+
id: 'global.settings',
|
|
113
|
+
defaultMessage: 'Settings',
|
|
98
114
|
})}
|
|
99
|
-
</
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
</Typography>
|
|
116
|
+
<Grid gap={4}>
|
|
117
|
+
<GridItem col={6} s={12}>
|
|
118
|
+
<ToggleInput
|
|
119
|
+
name="restrictedAccess"
|
|
120
|
+
label={formatMessage({
|
|
121
|
+
id: getTrad('pages.SettingsPage.toggle.label'),
|
|
122
|
+
defaultMessage: 'Restricted Access',
|
|
123
|
+
})}
|
|
124
|
+
hint={formatMessage({
|
|
125
|
+
id: getTrad('pages.SettingsPage.toggle.hint'),
|
|
126
|
+
defaultMessage: 'Make the documentation endpoint private',
|
|
127
|
+
})}
|
|
128
|
+
checked={values.restrictedAccess}
|
|
129
|
+
onChange={() => {
|
|
130
|
+
if (values.restrictedAccess === true) {
|
|
131
|
+
setFieldValue('password', '', false);
|
|
132
|
+
setFieldTouched('password', false, false);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
setFieldValue('restrictedAccess', !values.restrictedAccess, false);
|
|
136
|
+
}}
|
|
137
|
+
onLabel="On"
|
|
138
|
+
offLabel="Off"
|
|
139
|
+
/>
|
|
140
|
+
</GridItem>
|
|
141
|
+
{values.restrictedAccess && (
|
|
120
142
|
<GridItem col={6} s={12}>
|
|
121
|
-
<
|
|
122
|
-
name="restrictedAccess"
|
|
143
|
+
<TextInput
|
|
123
144
|
label={formatMessage({
|
|
124
|
-
id:
|
|
125
|
-
defaultMessage: '
|
|
145
|
+
id: 'global.password',
|
|
146
|
+
defaultMessage: 'Password',
|
|
126
147
|
})}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
name="password"
|
|
149
|
+
placeholder="**********"
|
|
150
|
+
type={passwordShown ? 'text' : 'password'}
|
|
151
|
+
value={values.password}
|
|
152
|
+
onChange={handleChange}
|
|
153
|
+
error={
|
|
154
|
+
errors.password
|
|
155
|
+
? formatMessage({
|
|
156
|
+
id: errors.password,
|
|
157
|
+
defaultMessage: 'Invalid value',
|
|
158
|
+
})
|
|
159
|
+
: null
|
|
160
|
+
}
|
|
161
|
+
endAction={
|
|
162
|
+
<FieldActionWrapper
|
|
163
|
+
onClick={(e) => {
|
|
164
|
+
e.stopPropagation();
|
|
165
|
+
setPasswordShown((prev) => !prev);
|
|
166
|
+
}}
|
|
167
|
+
label={formatMessage(
|
|
168
|
+
passwordShown
|
|
169
|
+
? {
|
|
170
|
+
id: 'Auth.form.password.show-password',
|
|
171
|
+
defaultMessage: 'Show password',
|
|
172
|
+
}
|
|
173
|
+
: {
|
|
174
|
+
id: 'Auth.form.password.hide-password',
|
|
175
|
+
defaultMessage: 'Hide password',
|
|
176
|
+
}
|
|
177
|
+
)}
|
|
178
|
+
>
|
|
179
|
+
{passwordShown ? <Show /> : <Hide />}
|
|
180
|
+
</FieldActionWrapper>
|
|
181
|
+
}
|
|
142
182
|
/>
|
|
143
183
|
</GridItem>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
type={passwordShown ? 'text' : 'password'}
|
|
154
|
-
value={values.password}
|
|
155
|
-
onChange={handleChange}
|
|
156
|
-
error={
|
|
157
|
-
errors.password
|
|
158
|
-
? formatMessage({
|
|
159
|
-
id: errors.password,
|
|
160
|
-
defaultMessage: 'Invalid value',
|
|
161
|
-
})
|
|
162
|
-
: null
|
|
163
|
-
}
|
|
164
|
-
endAction={
|
|
165
|
-
<FieldActionWrapper
|
|
166
|
-
onClick={(e) => {
|
|
167
|
-
e.stopPropagation();
|
|
168
|
-
setPasswordShown((prev) => !prev);
|
|
169
|
-
}}
|
|
170
|
-
label={formatMessage(
|
|
171
|
-
passwordShown
|
|
172
|
-
? {
|
|
173
|
-
id: 'Auth.form.password.show-password',
|
|
174
|
-
defaultMessage: 'Show password',
|
|
175
|
-
}
|
|
176
|
-
: {
|
|
177
|
-
id: 'Auth.form.password.hide-password',
|
|
178
|
-
defaultMessage: 'Hide password',
|
|
179
|
-
}
|
|
180
|
-
)}
|
|
181
|
-
>
|
|
182
|
-
{passwordShown ? <Show /> : <Hide />}
|
|
183
|
-
</FieldActionWrapper>
|
|
184
|
-
}
|
|
185
|
-
/>
|
|
186
|
-
</GridItem>
|
|
187
|
-
)}
|
|
188
|
-
</Grid>
|
|
189
|
-
</Flex>
|
|
190
|
-
</Box>
|
|
191
|
-
</ContentLayout>
|
|
192
|
-
</Form>
|
|
193
|
-
);
|
|
194
|
-
}}
|
|
195
|
-
</Formik>
|
|
196
|
-
)}
|
|
184
|
+
)}
|
|
185
|
+
</Grid>
|
|
186
|
+
</Flex>
|
|
187
|
+
</Box>
|
|
188
|
+
</ContentLayout>
|
|
189
|
+
</Form>
|
|
190
|
+
);
|
|
191
|
+
}}
|
|
192
|
+
</Formik>
|
|
197
193
|
</Main>
|
|
198
194
|
);
|
|
199
195
|
};
|
|
@@ -2,7 +2,8 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { fixtures } from '@strapi/admin-test-utils';
|
|
4
4
|
import { lightTheme, ThemeProvider } from '@strapi/design-system';
|
|
5
|
-
import {
|
|
5
|
+
import { RBACContext } from '@strapi/helper-plugin';
|
|
6
|
+
import { NotificationsProvider } from '@strapi/strapi/admin';
|
|
6
7
|
import { fireEvent, render as renderRTL, waitFor } from '@testing-library/react';
|
|
7
8
|
import userEvent from '@testing-library/user-event';
|
|
8
9
|
import { rest } from 'msw';
|
|
@@ -54,9 +55,7 @@ describe('SettingsPage', () => {
|
|
|
54
55
|
it('renders the setting page correctly', async () => {
|
|
55
56
|
const { getByRole, queryByText, getByText } = render();
|
|
56
57
|
|
|
57
|
-
expect(queryByText('
|
|
58
|
-
|
|
59
|
-
await waitFor(() => expect(queryByText('Plugin settings are loading')).not.toBeInTheDocument());
|
|
58
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
60
59
|
|
|
61
60
|
expect(getByRole('heading', { name: 'Documentation' })).toBeInTheDocument();
|
|
62
61
|
expect(getByText('Configure the documentation plugin')).toBeInTheDocument();
|
|
@@ -81,9 +80,7 @@ describe('SettingsPage', () => {
|
|
|
81
80
|
|
|
82
81
|
const { getByLabelText, queryByText } = render();
|
|
83
82
|
|
|
84
|
-
expect(queryByText('
|
|
85
|
-
|
|
86
|
-
await waitFor(() => expect(queryByText('Plugin settings are loading')).not.toBeInTheDocument());
|
|
83
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
87
84
|
|
|
88
85
|
expect(getByLabelText('Password')).toBeInTheDocument();
|
|
89
86
|
|
|
@@ -93,9 +90,7 @@ describe('SettingsPage', () => {
|
|
|
93
90
|
it('should render the password field when the Restricted Access checkbox is checked', async () => {
|
|
94
91
|
const { getByRole, getByLabelText, queryByText } = render();
|
|
95
92
|
|
|
96
|
-
expect(queryByText('
|
|
97
|
-
|
|
98
|
-
await waitFor(() => expect(queryByText('Plugin settings are loading')).not.toBeInTheDocument());
|
|
93
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
99
94
|
|
|
100
95
|
fireEvent.click(getByRole('checkbox', { name: 'Restricted Access' }));
|
|
101
96
|
|
|
@@ -107,9 +102,7 @@ describe('SettingsPage', () => {
|
|
|
107
102
|
it('should allow me to type a password and save that settings change successfully', async () => {
|
|
108
103
|
const { getByRole, getByLabelText, queryByText, user, getByText } = render();
|
|
109
104
|
|
|
110
|
-
expect(queryByText('
|
|
111
|
-
|
|
112
|
-
await waitFor(() => expect(queryByText('Plugin settings are loading')).not.toBeInTheDocument());
|
|
105
|
+
await waitFor(() => expect(queryByText('Loading content.')).not.toBeInTheDocument());
|
|
113
106
|
|
|
114
107
|
fireEvent.click(getByRole('checkbox', { name: 'Restricted Access' }));
|
|
115
108
|
|