@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.
@@ -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
+ };
@@ -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: PluginIcon,
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
- Button,
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, deleteMutation, regenerateDocMutation } = useReactQuery();
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
- regenerateDocMutation.mutate({ version, prefix: data?.prefix });
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 deleteMutation.mutateAsync({ prefix: data?.prefix, version: versionToDelete });
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
- // eslint-disable-next-line
110
- <CheckPermissions permissions={PERMISSIONS.open}>
111
- <Button onClick={() => openDocVersion(data?.currentVersion)} startIcon={<Show />}>
112
- {formatMessage({
113
- id: getTrad('pages.PluginPage.Button.open'),
114
- defaultMessage: 'Open Documentation',
115
- })}
116
- </Button>
117
- </CheckPermissions>
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" {...stopPropagation}>
145
+ <Flex justifyContent="end" onClick={(e) => e.stopPropagation()}>
157
146
  <IconButton
158
- onClick={() => openDocVersion(doc.version)}
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
- <CheckPermissions permissions={PERMISSIONS.regenerate}>
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
- </CheckPermissions>
183
- <CheckPermissions permissions={PERMISSIONS.update}>
184
- {doc.version !== data.currentVersion && (
185
- <IconButton
186
- onClick={() => handleClickDelete(doc.version)}
187
- noBorder
188
- icon={<Trash />}
189
- label={formatMessage(
190
- {
191
- id: 'global.delete-target',
192
- defaultMessage: 'Delete {target}',
193
- },
194
- { target: `${doc.version}` }
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;