@strapi/plugin-documentation 4.12.0-beta.3 → 4.12.0-beta.5
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 +77 -0
- package/admin/src/index.js +2 -2
- package/admin/src/pages/PluginPage/index.js +59 -49
- package/admin/src/pages/PluginPage/tests/index.test.js +152 -807
- package/admin/src/pages/SettingsPage/index.js +36 -15
- package/admin/src/pages/SettingsPage/tests/index.test.js +86 -587
- package/jest.config.front.js +1 -0
- package/package.json +6 -12
- package/tests/server.js +37 -0
- package/tests/setup.js +15 -0
- package/admin/src/components/FieldActionWrapper/index.js +0 -14
- package/admin/src/components/PluginIcon/index.js +0 -13
- package/admin/src/pages/PluginPage/tests/server.js +0 -23
- package/admin/src/pages/SettingsPage/tests/server.js +0 -18
- package/admin/src/pages/utils/schema.js +0 -11
- package/admin/src/pages/utils/useReactQuery.js +0 -67
- package/admin/src/utils/openWithNewTab.js +0 -19
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useFetchClient, useNotification, useAPIErrorHandler } from '@strapi/helper-plugin';
|
|
4
|
+
import { useMutation, useQuery } from 'react-query';
|
|
5
|
+
|
|
6
|
+
import pluginId from '../pluginId';
|
|
7
|
+
import getTrad from '../utils/getTrad';
|
|
8
|
+
|
|
9
|
+
export const useDocumentation = () => {
|
|
10
|
+
const toggleNotification = useNotification();
|
|
11
|
+
const { del, post, put, get } = useFetchClient();
|
|
12
|
+
|
|
13
|
+
const { formatAPIError } = useAPIErrorHandler();
|
|
14
|
+
|
|
15
|
+
const { isLoading, isError, data, refetch, error } = useQuery(
|
|
16
|
+
['get-documentation', pluginId],
|
|
17
|
+
async () => {
|
|
18
|
+
const { data } = await get(`/${pluginId}/getInfos`);
|
|
19
|
+
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (isError && error) {
|
|
26
|
+
toggleNotification({
|
|
27
|
+
type: 'warning',
|
|
28
|
+
message: error ? formatAPIError(error) : { id: 'notification.error' },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}, [isError, error, toggleNotification, formatAPIError]);
|
|
32
|
+
|
|
33
|
+
const handleError = (err) => {
|
|
34
|
+
toggleNotification({
|
|
35
|
+
type: 'warning',
|
|
36
|
+
message: formatAPIError(err),
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleSuccess = (type, tradId, defaultMessage) => {
|
|
41
|
+
refetch();
|
|
42
|
+
toggleNotification({
|
|
43
|
+
type,
|
|
44
|
+
message: { id: getTrad(tradId), defaultMessage },
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const deleteMutation = useMutation(
|
|
49
|
+
({ prefix, version }) => del(`${prefix}/deleteDoc/${version}`),
|
|
50
|
+
{
|
|
51
|
+
onSuccess: () =>
|
|
52
|
+
handleSuccess('info', 'notification.delete.success', 'Successfully deleted documentation'),
|
|
53
|
+
onError: handleError,
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const submit = useMutation(({ prefix, body }) => put(`${prefix}/updateSettings`, body), {
|
|
58
|
+
onSuccess: () =>
|
|
59
|
+
handleSuccess('success', 'notification.update.success', 'Successfully updated settings'),
|
|
60
|
+
onError: handleError,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const regenerate = useMutation(
|
|
64
|
+
({ prefix, version }) => post(`${prefix}/regenerateDoc`, { version }),
|
|
65
|
+
{
|
|
66
|
+
onSuccess: () =>
|
|
67
|
+
handleSuccess(
|
|
68
|
+
'info',
|
|
69
|
+
'notification.generate.success',
|
|
70
|
+
'Successfully generated documentation'
|
|
71
|
+
),
|
|
72
|
+
onError: handleError,
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return { data, isLoading, isError, remove: deleteMutation, submit, regenerate };
|
|
77
|
+
};
|
package/admin/src/index.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
|
6
6
|
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
|
7
7
|
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
|
8
|
+
import { Information } from '@strapi/icons';
|
|
8
9
|
|
|
9
10
|
import pluginPkg from '../../package.json';
|
|
10
11
|
|
|
11
|
-
import PluginIcon from './components/PluginIcon';
|
|
12
12
|
import { PERMISSIONS } from './constants';
|
|
13
13
|
import pluginId from './pluginId';
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ export default {
|
|
|
18
18
|
register(app) {
|
|
19
19
|
app.addMenuLink({
|
|
20
20
|
to: `/plugins/${pluginId}`,
|
|
21
|
-
icon:
|
|
21
|
+
icon: Information,
|
|
22
22
|
intlLabel: {
|
|
23
23
|
id: `${pluginId}.plugin.name`,
|
|
24
24
|
defaultMessage: 'Documentation',
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* This component is the skeleton around the actual pages, and should only
|
|
4
|
-
* contain code that should be seen on all pages. (e.g. navigation bar)
|
|
5
|
-
*
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
1
|
import React, { useState } from 'react';
|
|
9
2
|
|
|
10
3
|
import {
|
|
11
4
|
Box,
|
|
12
|
-
|
|
5
|
+
LinkButton,
|
|
13
6
|
ContentLayout,
|
|
14
7
|
Flex,
|
|
15
8
|
HeaderLayout,
|
|
@@ -26,40 +19,35 @@ import {
|
|
|
26
19
|
} from '@strapi/design-system';
|
|
27
20
|
import {
|
|
28
21
|
AnErrorOccurred,
|
|
29
|
-
CheckPermissions,
|
|
30
22
|
ConfirmDialog,
|
|
31
23
|
EmptyStateLayout,
|
|
32
24
|
LoadingIndicatorPage,
|
|
33
|
-
stopPropagation,
|
|
34
25
|
useFocusWhenNavigate,
|
|
26
|
+
useRBAC,
|
|
35
27
|
} from '@strapi/helper-plugin';
|
|
36
28
|
import { Eye as Show, Refresh as Reload, Trash } from '@strapi/icons';
|
|
37
29
|
import { Helmet } from 'react-helmet';
|
|
38
30
|
import { useIntl } from 'react-intl';
|
|
31
|
+
import styled from 'styled-components';
|
|
39
32
|
|
|
40
33
|
import { PERMISSIONS } from '../../constants';
|
|
34
|
+
import { useDocumentation } from '../../hooks/useDocumentation';
|
|
41
35
|
import { getTrad } from '../../utils';
|
|
42
|
-
import openWithNewTab from '../../utils/openWithNewTab';
|
|
43
|
-
import useReactQuery from '../utils/useReactQuery';
|
|
44
36
|
|
|
45
37
|
const PluginPage = () => {
|
|
46
38
|
useFocusWhenNavigate();
|
|
47
39
|
const { formatMessage } = useIntl();
|
|
48
|
-
const { data, isLoading, isError,
|
|
40
|
+
const { data, isLoading, isError, remove, regenerate } = useDocumentation();
|
|
49
41
|
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
|
50
42
|
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
|
|
51
43
|
const [versionToDelete, setVersionToDelete] = useState();
|
|
44
|
+
const { allowedActions } = useRBAC(PERMISSIONS);
|
|
52
45
|
|
|
53
46
|
const colCount = 4;
|
|
54
47
|
const rowCount = (data?.docVersions?.length || 0) + 1;
|
|
55
48
|
|
|
56
|
-
const openDocVersion = (version) => {
|
|
57
|
-
const slash = data?.prefix.startsWith('/') ? '' : '/';
|
|
58
|
-
openWithNewTab(`${slash}${data?.prefix}/v${version}`);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
49
|
const handleRegenerateDoc = (version) => {
|
|
62
|
-
|
|
50
|
+
regenerate.mutate({ version, prefix: data?.prefix });
|
|
63
51
|
};
|
|
64
52
|
|
|
65
53
|
const handleShowConfirmDelete = () => {
|
|
@@ -68,7 +56,7 @@ const PluginPage = () => {
|
|
|
68
56
|
|
|
69
57
|
const handleConfirmDelete = async () => {
|
|
70
58
|
setIsConfirmButtonLoading(true);
|
|
71
|
-
await
|
|
59
|
+
await remove.mutateAsync({ prefix: data?.prefix, version: versionToDelete });
|
|
72
60
|
setShowConfirmDelete(!showConfirmDelete);
|
|
73
61
|
setIsConfirmButtonLoading(false);
|
|
74
62
|
};
|
|
@@ -106,15 +94,16 @@ const PluginPage = () => {
|
|
|
106
94
|
defaultMessage: 'Configure the documentation plugin',
|
|
107
95
|
})}
|
|
108
96
|
primaryAction={
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
97
|
+
<OpenDocLink
|
|
98
|
+
disabled={!allowedActions.canOpen || !data?.currentVersion || !data?.prefix}
|
|
99
|
+
href={createDocumentationHref(`${data?.prefix}/v${data?.currentVersion}`)}
|
|
100
|
+
startIcon={<Show />}
|
|
101
|
+
>
|
|
102
|
+
{formatMessage({
|
|
103
|
+
id: getTrad('pages.PluginPage.Button.open'),
|
|
104
|
+
defaultMessage: 'Open Documentation',
|
|
105
|
+
})}
|
|
106
|
+
</OpenDocLink>
|
|
118
107
|
}
|
|
119
108
|
/>
|
|
120
109
|
<ContentLayout>
|
|
@@ -153,11 +142,15 @@ const PluginPage = () => {
|
|
|
153
142
|
<Typography>{doc.generatedDate}</Typography>
|
|
154
143
|
</Td>
|
|
155
144
|
<Td>
|
|
156
|
-
<Flex justifyContent="end" {
|
|
145
|
+
<Flex justifyContent="end" onClick={(e) => e.stopPropagation()}>
|
|
157
146
|
<IconButton
|
|
158
|
-
|
|
147
|
+
forwardedAs="a"
|
|
148
|
+
disabled={!allowedActions.canOpen}
|
|
149
|
+
href={createDocumentationHref(`${data.prefix}/v${doc.version}`)}
|
|
159
150
|
noBorder
|
|
160
151
|
icon={<Show />}
|
|
152
|
+
target="_blank"
|
|
153
|
+
rel="noopener noreferrer"
|
|
161
154
|
label={formatMessage(
|
|
162
155
|
{
|
|
163
156
|
id: getTrad('pages.PluginPage.table.icon.show'),
|
|
@@ -166,7 +159,7 @@ const PluginPage = () => {
|
|
|
166
159
|
{ target: `${doc.version}` }
|
|
167
160
|
)}
|
|
168
161
|
/>
|
|
169
|
-
|
|
162
|
+
{allowedActions.canRegenerate ? (
|
|
170
163
|
<IconButton
|
|
171
164
|
onClick={() => handleRegenerateDoc(doc.version)}
|
|
172
165
|
noBorder
|
|
@@ -179,23 +172,21 @@ const PluginPage = () => {
|
|
|
179
172
|
{ target: `${doc.version}` }
|
|
180
173
|
)}
|
|
181
174
|
/>
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
)}
|
|
198
|
-
</CheckPermissions>
|
|
175
|
+
) : null}
|
|
176
|
+
{allowedActions.canUpdate && doc.version !== data.currentVersion ? (
|
|
177
|
+
<IconButton
|
|
178
|
+
onClick={() => handleClickDelete(doc.version)}
|
|
179
|
+
noBorder
|
|
180
|
+
icon={<Trash />}
|
|
181
|
+
label={formatMessage(
|
|
182
|
+
{
|
|
183
|
+
id: 'global.delete-target',
|
|
184
|
+
defaultMessage: 'Delete {target}',
|
|
185
|
+
},
|
|
186
|
+
{ target: `${doc.version}` }
|
|
187
|
+
)}
|
|
188
|
+
/>
|
|
189
|
+
) : null}
|
|
199
190
|
</Flex>
|
|
200
191
|
</Td>
|
|
201
192
|
</Tr>
|
|
@@ -217,4 +208,23 @@ const PluginPage = () => {
|
|
|
217
208
|
);
|
|
218
209
|
};
|
|
219
210
|
|
|
211
|
+
/**
|
|
212
|
+
* TODO: should this be fixed in the DS?
|
|
213
|
+
*/
|
|
214
|
+
const OpenDocLink = styled(LinkButton)`
|
|
215
|
+
text-decoration: none;
|
|
216
|
+
`;
|
|
217
|
+
|
|
218
|
+
const createDocumentationHref = (path) => {
|
|
219
|
+
if (path.startsWith('http')) {
|
|
220
|
+
return path;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (path.startsWith('/')) {
|
|
224
|
+
return `${window.strapi.backendURL}${path}`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return `${window.strapi.backendURL}/${path}`;
|
|
228
|
+
};
|
|
229
|
+
|
|
220
230
|
export default PluginPage;
|