@strapi/plugin-documentation 4.0.0-next.9 → 4.0.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/components/FieldActionWrapper/index.js +14 -0
- package/admin/src/components/PluginIcon/index.js +12 -0
- package/admin/src/index.js +23 -11
- package/admin/src/pages/PluginPage/index.js +199 -0
- package/admin/src/pages/PluginPage/tests/index.test.js +873 -0
- package/admin/src/pages/PluginPage/tests/server.js +23 -0
- package/admin/src/pages/SettingsPage/index.js +181 -0
- package/admin/src/pages/SettingsPage/tests/index.test.js +612 -0
- package/admin/src/pages/SettingsPage/tests/server.js +18 -0
- package/admin/src/pages/{HomePage/utils → utils}/api.js +5 -4
- package/admin/src/pages/{HomePage/utils → utils}/schema.js +0 -0
- package/admin/src/pages/utils/useReactQuery.js +46 -0
- package/admin/src/translations/ar.json +0 -3
- package/admin/src/translations/cs.json +0 -3
- package/admin/src/translations/de.json +0 -3
- package/admin/src/translations/en.json +14 -3
- package/admin/src/translations/es.json +0 -3
- package/admin/src/translations/fr.json +0 -3
- package/admin/src/translations/id.json +0 -3
- package/admin/src/translations/it.json +0 -3
- package/admin/src/translations/ko.json +0 -3
- package/admin/src/translations/ms.json +0 -3
- package/admin/src/translations/nl.json +0 -3
- package/admin/src/translations/pl.json +0 -3
- package/admin/src/translations/pt-BR.json +0 -3
- package/admin/src/translations/pt.json +0 -3
- package/admin/src/translations/ru.json +0 -3
- package/admin/src/translations/sk.json +0 -3
- package/admin/src/translations/th.json +0 -3
- package/admin/src/translations/tr.json +0 -3
- package/admin/src/translations/uk.json +0 -3
- package/admin/src/translations/vi.json +0 -3
- package/admin/src/translations/zh-Hans.json +3 -6
- package/admin/src/translations/zh.json +0 -3
- package/package.json +32 -47
- package/server/bootstrap.js +19 -105
- package/server/config/default-config.js +12 -15
- package/server/config/index.js +10 -2
- package/server/controllers/documentation.js +61 -127
- package/server/index.js +17 -0
- package/server/middlewares/documentation.js +18 -41
- package/server/{policies/index-policy.js → middlewares/restrict-access.js} +5 -16
- package/{public → server/public}/index.html +0 -0
- package/{public → server/public}/login.html +0 -0
- package/server/register.js +11 -0
- package/server/routes/index.js +18 -25
- package/server/services/documentation.js +125 -1835
- package/server/utils/builders/build-api-endpoint-path.js +174 -0
- package/server/utils/builders/build-api-requests.js +41 -0
- package/server/utils/builders/build-api-responses.js +108 -0
- package/server/utils/builders/index.js +11 -0
- package/server/utils/clean-schema-attributes.js +205 -0
- package/server/utils/error-response.js +22 -0
- package/server/utils/get-schema-data.js +32 -0
- package/server/utils/query-params.js +84 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +1 -19
- package/admin/src/assets/images/logo.svg +0 -1
- package/admin/src/components/Block/components.js +0 -26
- package/admin/src/components/Block/index.js +0 -39
- package/admin/src/components/Copy/index.js +0 -36
- package/admin/src/components/Header/index.js +0 -72
- package/admin/src/components/Row/ButtonContainer.js +0 -67
- package/admin/src/components/Row/components.js +0 -83
- package/admin/src/components/Row/index.js +0 -51
- package/admin/src/pages/App/index.js +0 -21
- package/admin/src/pages/HomePage/components.js +0 -59
- package/admin/src/pages/HomePage/index.js +0 -175
- package/admin/src/pages/HomePage/useHomePage.js +0 -56
- package/server/policies/index.js +0 -7
- package/server/services/utils/forms.json +0 -29
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { FieldAction } from '@strapi/design-system/Field';
|
|
3
|
+
|
|
4
|
+
const FieldActionWrapper = styled(FieldAction)`
|
|
5
|
+
svg {
|
|
6
|
+
height: 1rem;
|
|
7
|
+
width: 1rem;
|
|
8
|
+
path {
|
|
9
|
+
fill: ${({ theme }) => theme.colors.neutral600};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export default FieldActionWrapper;
|
package/admin/src/index.js
CHANGED
|
@@ -6,42 +6,54 @@
|
|
|
6
6
|
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
|
7
7
|
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
|
8
8
|
import pluginPkg from '../../package.json';
|
|
9
|
+
import PluginIcon from './components/PluginIcon';
|
|
9
10
|
import pluginPermissions from './permissions';
|
|
10
11
|
import pluginId from './pluginId';
|
|
11
|
-
import pluginLogo from './assets/images/logo.svg';
|
|
12
12
|
|
|
13
|
-
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
|
14
|
-
const icon = pluginPkg.strapi.icon;
|
|
15
13
|
const name = pluginPkg.strapi.name;
|
|
16
14
|
|
|
17
15
|
export default {
|
|
18
16
|
register(app) {
|
|
19
17
|
app.addMenuLink({
|
|
20
18
|
to: `/plugins/${pluginId}`,
|
|
21
|
-
icon,
|
|
19
|
+
icon: PluginIcon,
|
|
22
20
|
intlLabel: {
|
|
23
21
|
id: `${pluginId}.plugin.name`,
|
|
24
22
|
defaultMessage: 'Documentation',
|
|
25
23
|
},
|
|
26
24
|
permissions: pluginPermissions.main,
|
|
27
25
|
Component: async () => {
|
|
28
|
-
const component = await import(
|
|
26
|
+
const component = await import(
|
|
27
|
+
/* webpackChunkName: "documentation-page" */ './pages/PluginPage'
|
|
28
|
+
);
|
|
29
29
|
|
|
30
30
|
return component;
|
|
31
31
|
},
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
app.registerPlugin({
|
|
35
|
-
description: pluginDescription,
|
|
36
|
-
icon,
|
|
37
35
|
id: pluginId,
|
|
38
|
-
isReady: true,
|
|
39
|
-
isRequired: pluginPkg.strapi.required || false,
|
|
40
36
|
name,
|
|
41
|
-
pluginLogo,
|
|
42
37
|
});
|
|
43
38
|
},
|
|
44
|
-
bootstrap() {
|
|
39
|
+
bootstrap(app) {
|
|
40
|
+
app.addSettingsLink('global', {
|
|
41
|
+
intlLabel: {
|
|
42
|
+
id: `${pluginId}.plugin.name`,
|
|
43
|
+
defaultMessage: 'Documentation',
|
|
44
|
+
},
|
|
45
|
+
id: 'documentation',
|
|
46
|
+
to: `/settings/${pluginId}`,
|
|
47
|
+
Component: async () => {
|
|
48
|
+
const component = await import(
|
|
49
|
+
/* webpackChunkName: "documentation-settings" */ './pages/SettingsPage'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
return component;
|
|
53
|
+
},
|
|
54
|
+
permissions: pluginPermissions.main,
|
|
55
|
+
});
|
|
56
|
+
},
|
|
45
57
|
async registerTrads({ locales }) {
|
|
46
58
|
const importedTrads = await Promise.all(
|
|
47
59
|
locales.map(locale => {
|
|
@@ -0,0 +1,199 @@
|
|
|
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
|
+
import React, { useState } from 'react';
|
|
9
|
+
import { useIntl } from 'react-intl';
|
|
10
|
+
import {
|
|
11
|
+
CheckPermissions,
|
|
12
|
+
ConfirmDialog,
|
|
13
|
+
LoadingIndicatorPage,
|
|
14
|
+
stopPropagation,
|
|
15
|
+
EmptyStateLayout,
|
|
16
|
+
useFocusWhenNavigate,
|
|
17
|
+
} from '@strapi/helper-plugin';
|
|
18
|
+
import { Helmet } from 'react-helmet';
|
|
19
|
+
import { Button } from '@strapi/design-system/Button';
|
|
20
|
+
import { Layout, HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
|
|
21
|
+
import { Main } from '@strapi/design-system/Main';
|
|
22
|
+
import { IconButton } from '@strapi/design-system/IconButton';
|
|
23
|
+
import { Typography } from '@strapi/design-system/Typography';
|
|
24
|
+
import { Flex } from '@strapi/design-system/Flex';
|
|
25
|
+
import { Table, Tr, Thead, Th, Tbody, Td } from '@strapi/design-system/Table';
|
|
26
|
+
|
|
27
|
+
import Trash from '@strapi/icons/Trash';
|
|
28
|
+
import Show from '@strapi/icons/Eye';
|
|
29
|
+
import Reload from '@strapi/icons/Refresh';
|
|
30
|
+
|
|
31
|
+
import permissions from '../../permissions';
|
|
32
|
+
import { getTrad } from '../../utils';
|
|
33
|
+
import openWithNewTab from '../../utils/openWithNewTab';
|
|
34
|
+
import useReactQuery from '../utils/useReactQuery';
|
|
35
|
+
|
|
36
|
+
const PluginPage = () => {
|
|
37
|
+
useFocusWhenNavigate();
|
|
38
|
+
const { formatMessage } = useIntl();
|
|
39
|
+
const { data, isLoading, deleteMutation, regenerateDocMutation } = useReactQuery();
|
|
40
|
+
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
|
|
41
|
+
const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false);
|
|
42
|
+
const [versionToDelete, setVersionToDelete] = useState();
|
|
43
|
+
|
|
44
|
+
const colCount = 4;
|
|
45
|
+
const rowCount = (data?.docVersions?.length || 0) + 1;
|
|
46
|
+
|
|
47
|
+
const openDocVersion = () => {
|
|
48
|
+
const slash = data?.prefix.startsWith('/') ? '' : '/';
|
|
49
|
+
openWithNewTab(`${slash}${data?.prefix}/v${data?.currentVersion}`);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleRegenerateDoc = version => {
|
|
53
|
+
regenerateDocMutation.mutate({ version, prefix: data?.prefix });
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleShowConfirmDelete = () => {
|
|
57
|
+
setShowConfirmDelete(!showConfirmDelete);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleConfirmDelete = async () => {
|
|
61
|
+
setIsConfirmButtonLoading(true);
|
|
62
|
+
await deleteMutation.mutateAsync({ prefix: data?.prefix, version: versionToDelete });
|
|
63
|
+
setShowConfirmDelete(!showConfirmDelete);
|
|
64
|
+
setIsConfirmButtonLoading(false);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleClickDelete = version => {
|
|
68
|
+
setVersionToDelete(version);
|
|
69
|
+
setShowConfirmDelete(!showConfirmDelete);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const title = formatMessage({
|
|
73
|
+
id: getTrad('plugin.name'),
|
|
74
|
+
defaultMessage: 'Documentation',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<Layout>
|
|
79
|
+
<Helmet title={title} />
|
|
80
|
+
<Main aria-busy={isLoading}>
|
|
81
|
+
<HeaderLayout
|
|
82
|
+
title={title}
|
|
83
|
+
subtitle={formatMessage({
|
|
84
|
+
id: getTrad('pages.PluginPage.header.description'),
|
|
85
|
+
defaultMessage: 'Configure the documentation plugin',
|
|
86
|
+
})}
|
|
87
|
+
primaryAction={
|
|
88
|
+
// eslint-disable-next-line
|
|
89
|
+
<CheckPermissions permissions={permissions.open}>
|
|
90
|
+
<Button onClick={openDocVersion} startIcon={<Show />}>
|
|
91
|
+
{formatMessage({
|
|
92
|
+
id: getTrad('pages.PluginPage.Button.open'),
|
|
93
|
+
defaultMessage: 'Open Documentation',
|
|
94
|
+
})}
|
|
95
|
+
</Button>
|
|
96
|
+
</CheckPermissions>
|
|
97
|
+
}
|
|
98
|
+
/>
|
|
99
|
+
<ContentLayout>
|
|
100
|
+
{isLoading && <LoadingIndicatorPage>Plugin is loading</LoadingIndicatorPage>}
|
|
101
|
+
{data?.docVersions.length ? (
|
|
102
|
+
<Table colCount={colCount} rowCount={rowCount}>
|
|
103
|
+
<Thead>
|
|
104
|
+
<Tr>
|
|
105
|
+
<Th>
|
|
106
|
+
<Typography variant="sigma" textColor="neutral600">
|
|
107
|
+
{formatMessage({
|
|
108
|
+
id: getTrad('pages.PluginPage.table.version'),
|
|
109
|
+
defaultMessage: 'Version',
|
|
110
|
+
})}
|
|
111
|
+
</Typography>
|
|
112
|
+
</Th>
|
|
113
|
+
<Th>
|
|
114
|
+
<Typography variant="sigma" textColor="neutral600">
|
|
115
|
+
{formatMessage({
|
|
116
|
+
id: getTrad('pages.PluginPage.table.generated'),
|
|
117
|
+
defaultMessage: 'Last Generated',
|
|
118
|
+
})}
|
|
119
|
+
</Typography>
|
|
120
|
+
</Th>
|
|
121
|
+
</Tr>
|
|
122
|
+
</Thead>
|
|
123
|
+
<Tbody>
|
|
124
|
+
{data.docVersions
|
|
125
|
+
.sort((a, b) => (a.generatedDate < b.generatedDate ? 1 : -1))
|
|
126
|
+
.map(doc => (
|
|
127
|
+
<Tr key={doc.version}>
|
|
128
|
+
<Td width="50%">
|
|
129
|
+
<Typography>{doc.version}</Typography>
|
|
130
|
+
</Td>
|
|
131
|
+
<Td width="50%">
|
|
132
|
+
<Typography>{doc.generatedDate}</Typography>
|
|
133
|
+
</Td>
|
|
134
|
+
<Td>
|
|
135
|
+
<Flex justifyContent="end" {...stopPropagation}>
|
|
136
|
+
<IconButton
|
|
137
|
+
onClick={openDocVersion}
|
|
138
|
+
noBorder
|
|
139
|
+
icon={<Show />}
|
|
140
|
+
label={formatMessage(
|
|
141
|
+
{
|
|
142
|
+
id: getTrad('pages.PluginPage.table.icon.show'),
|
|
143
|
+
defaultMessage: 'Open {target}',
|
|
144
|
+
},
|
|
145
|
+
{ target: `${doc.version}` }
|
|
146
|
+
)}
|
|
147
|
+
/>
|
|
148
|
+
<CheckPermissions permissions={permissions.regenerate}>
|
|
149
|
+
<IconButton
|
|
150
|
+
onClick={() => handleRegenerateDoc(doc.version)}
|
|
151
|
+
noBorder
|
|
152
|
+
icon={<Reload />}
|
|
153
|
+
label={formatMessage(
|
|
154
|
+
{
|
|
155
|
+
id: getTrad('pages.PluginPage.table.icon.regenerate'),
|
|
156
|
+
defaultMessage: 'Regenerate {target}',
|
|
157
|
+
},
|
|
158
|
+
{ target: `${doc.version}` }
|
|
159
|
+
)}
|
|
160
|
+
/>
|
|
161
|
+
</CheckPermissions>
|
|
162
|
+
<CheckPermissions permissions={permissions.update}>
|
|
163
|
+
{doc.version !== data.currentVersion && (
|
|
164
|
+
<IconButton
|
|
165
|
+
onClick={() => handleClickDelete(doc.version)}
|
|
166
|
+
noBorder
|
|
167
|
+
icon={<Trash />}
|
|
168
|
+
label={formatMessage(
|
|
169
|
+
{
|
|
170
|
+
id: getTrad('pages.PluginPage.table.icon.delete'),
|
|
171
|
+
defaultMessage: 'Delete {target}',
|
|
172
|
+
},
|
|
173
|
+
{ target: `${doc.version}` }
|
|
174
|
+
)}
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
</CheckPermissions>
|
|
178
|
+
</Flex>
|
|
179
|
+
</Td>
|
|
180
|
+
</Tr>
|
|
181
|
+
))}
|
|
182
|
+
</Tbody>
|
|
183
|
+
</Table>
|
|
184
|
+
) : (
|
|
185
|
+
<EmptyStateLayout />
|
|
186
|
+
)}
|
|
187
|
+
</ContentLayout>
|
|
188
|
+
<ConfirmDialog
|
|
189
|
+
isConfirmButtonLoading={isConfirmButtonLoading}
|
|
190
|
+
onConfirm={handleConfirmDelete}
|
|
191
|
+
onToggleDialog={handleShowConfirmDelete}
|
|
192
|
+
isOpen={showConfirmDelete}
|
|
193
|
+
/>
|
|
194
|
+
</Main>
|
|
195
|
+
</Layout>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export default PluginPage;
|