@akemona-org/strapi-plugin-documentation 3.7.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 (64) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +170 -0
  3. package/admin/src/assets/images/logo.svg +1 -0
  4. package/admin/src/components/Block/components.js +26 -0
  5. package/admin/src/components/Block/index.js +39 -0
  6. package/admin/src/components/Row/ButtonContainer.js +53 -0
  7. package/admin/src/components/Row/components.js +83 -0
  8. package/admin/src/components/Row/index.js +57 -0
  9. package/admin/src/containers/App/index.js +30 -0
  10. package/admin/src/containers/HomePage/actions.js +72 -0
  11. package/admin/src/containers/HomePage/components.js +59 -0
  12. package/admin/src/containers/HomePage/constants.js +14 -0
  13. package/admin/src/containers/HomePage/index.js +283 -0
  14. package/admin/src/containers/HomePage/reducer.js +49 -0
  15. package/admin/src/containers/HomePage/saga.js +126 -0
  16. package/admin/src/containers/HomePage/selectors.js +34 -0
  17. package/admin/src/containers/Initializer/index.js +28 -0
  18. package/admin/src/containers/Initializer/tests/index.test.js +21 -0
  19. package/admin/src/index.js +57 -0
  20. package/admin/src/lifecycles.js +13 -0
  21. package/admin/src/permissions.js +19 -0
  22. package/admin/src/pluginId.js +5 -0
  23. package/admin/src/reducers.js +8 -0
  24. package/admin/src/translations/ar.json +23 -0
  25. package/admin/src/translations/cs.json +24 -0
  26. package/admin/src/translations/de.json +30 -0
  27. package/admin/src/translations/en.json +31 -0
  28. package/admin/src/translations/es.json +27 -0
  29. package/admin/src/translations/fr.json +29 -0
  30. package/admin/src/translations/id.json +28 -0
  31. package/admin/src/translations/index.js +49 -0
  32. package/admin/src/translations/it.json +29 -0
  33. package/admin/src/translations/ko.json +24 -0
  34. package/admin/src/translations/ms.json +26 -0
  35. package/admin/src/translations/nl.json +24 -0
  36. package/admin/src/translations/pl.json +27 -0
  37. package/admin/src/translations/pt-BR.json +24 -0
  38. package/admin/src/translations/pt.json +24 -0
  39. package/admin/src/translations/ru.json +31 -0
  40. package/admin/src/translations/sk.json +27 -0
  41. package/admin/src/translations/th.json +27 -0
  42. package/admin/src/translations/tr.json +23 -0
  43. package/admin/src/translations/uk.json +26 -0
  44. package/admin/src/translations/vi.json +27 -0
  45. package/admin/src/translations/zh-Hans.json +31 -0
  46. package/admin/src/translations/zh.json +27 -0
  47. package/admin/src/utils/getTrad.js +5 -0
  48. package/admin/src/utils/openWithNewTab.js +20 -0
  49. package/config/functions/bootstrap.js +138 -0
  50. package/config/policies/index.js +35 -0
  51. package/config/routes.json +74 -0
  52. package/config/settings.json +46 -0
  53. package/controllers/Documentation.js +303 -0
  54. package/middlewares/documentation/defaults.json +5 -0
  55. package/middlewares/documentation/index.js +59 -0
  56. package/package.json +89 -0
  57. package/public/index.html +57 -0
  58. package/public/login.html +135 -0
  59. package/services/Documentation.js +1861 -0
  60. package/services/Token.js +31 -0
  61. package/services/utils/components.json +25 -0
  62. package/services/utils/forms.json +29 -0
  63. package/services/utils/parametersOptions.json +134 -0
  64. package/services/utils/unknownComponent.json +11 -0
@@ -0,0 +1,283 @@
1
+ /*
2
+ *
3
+ * HomePage
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { connect } from 'react-redux';
10
+ import { CopyToClipboard } from 'react-copy-to-clipboard';
11
+ import { bindActionCreators, compose } from 'redux';
12
+ import { get, isEmpty } from 'lodash';
13
+ import { Header } from '@buffetjs/custom';
14
+ import { Button } from '@buffetjs/core';
15
+ import {
16
+ auth,
17
+ PopUpWarning,
18
+ LoadingIndicatorPage,
19
+ InputsIndex as Input,
20
+ GlobalContext,
21
+ CheckPermissions,
22
+ } from 'strapi-helper-plugin';
23
+
24
+ import pluginId from '../../pluginId';
25
+ import pluginPermissions from '../../permissions';
26
+ import getTrad from '../../utils/getTrad';
27
+
28
+ import Block from '../../components/Block';
29
+ import Row from '../../components/Row';
30
+
31
+ import openWithNewTab from '../../utils/openWithNewTab';
32
+ import { ContainerFluid, StyledRow, VersionWrapper } from './components';
33
+ // Actions
34
+ import {
35
+ getDocInfos,
36
+ onChange,
37
+ onClickDeleteDoc,
38
+ onConfirmDeleteDoc,
39
+ onSubmit,
40
+ onUpdateDoc,
41
+ } from './actions';
42
+ // Selectors
43
+ import selectHomePage from './selectors';
44
+ import saga from './saga';
45
+
46
+ export class HomePage extends React.Component {
47
+ static contextType = GlobalContext;
48
+
49
+ componentDidMount() {
50
+ this.props.getDocInfos();
51
+ }
52
+
53
+ getRestrictedAccessValue = () => {
54
+ const { form } = this.props;
55
+
56
+ return get(form, [0, 0, 'value'], false);
57
+ };
58
+
59
+ getPluginHeaderActions = () => {
60
+ const actions = [
61
+ {
62
+ color: 'none',
63
+ label: this.context.formatMessage({
64
+ id: getTrad('containers.HomePage.Button.open'),
65
+ }),
66
+ className: 'buttonOutline',
67
+ onClick: this.openCurrentDocumentation,
68
+ type: 'button',
69
+ key: 'button-open',
70
+ Component: props => (
71
+ <CheckPermissions permissions={pluginPermissions.open}>
72
+ <Button {...props} />
73
+ </CheckPermissions>
74
+ ),
75
+ },
76
+ {
77
+ label: this.context.formatMessage({
78
+ id: getTrad('containers.HomePage.Button.update'),
79
+ }),
80
+ color: 'success',
81
+ onClick: () => {},
82
+ type: 'submit',
83
+ key: 'button-submit',
84
+ Component: props => (
85
+ <CheckPermissions permissions={pluginPermissions.update}>
86
+ <Button {...props} />
87
+ </CheckPermissions>
88
+ ),
89
+ },
90
+ ];
91
+
92
+ return actions;
93
+ };
94
+
95
+ handleCopy = () => {
96
+ strapi.notification.toggle({
97
+ type: 'info',
98
+ message: { id: getTrad('containers.HomePage.copied') },
99
+ });
100
+ };
101
+
102
+ openCurrentDocumentation = () => {
103
+ const { currentDocVersion, prefix } = this.props;
104
+ const slash = prefix.startsWith('/') ? '' : '/';
105
+
106
+ return openWithNewTab(`${slash}${prefix}/v${currentDocVersion}`);
107
+ };
108
+
109
+ shouldHideInput = inputName => {
110
+ return !this.getRestrictedAccessValue() && inputName === 'password';
111
+ };
112
+
113
+ toggleModal = () => this.props.onClickDeleteDoc('');
114
+
115
+ renderForm = (array, i) => {
116
+ const { didCheckErrors, formErrors } = this.props;
117
+
118
+ return (
119
+ <div className="row" key={i}>
120
+ {array.map((input, j) => {
121
+ if (this.shouldHideInput(input.name)) {
122
+ return null;
123
+ }
124
+
125
+ return (
126
+ <Input
127
+ key={input.name}
128
+ {...input}
129
+ didCheckErrors={didCheckErrors}
130
+ errors={get(formErrors, [input.name], [])}
131
+ name={`form.${i}.${j}.value`}
132
+ onChange={this.props.onChange}
133
+ />
134
+ );
135
+ })}
136
+ </div>
137
+ );
138
+ };
139
+
140
+ renderRow = data => {
141
+ const { currentDocVersion, onClickDeleteDoc, onUpdateDoc } = this.props;
142
+
143
+ return (
144
+ <Row
145
+ currentDocVersion={currentDocVersion}
146
+ data={data}
147
+ key={data.generatedDate}
148
+ onClickDelete={onClickDeleteDoc}
149
+ onUpdateDoc={onUpdateDoc}
150
+ />
151
+ );
152
+ };
153
+
154
+ render() {
155
+ const {
156
+ docVersions,
157
+ form,
158
+ isLoading,
159
+ onConfirmDeleteDoc,
160
+ onSubmit,
161
+ versionToDelete,
162
+ } = this.props;
163
+
164
+ const { formatMessage } = this.context;
165
+
166
+ if (isLoading) {
167
+ return <LoadingIndicatorPage />;
168
+ }
169
+
170
+ return (
171
+ <ContainerFluid className="container-fluid">
172
+ <PopUpWarning
173
+ isOpen={!isEmpty(versionToDelete)}
174
+ toggleModal={this.toggleModal}
175
+ content={{
176
+ title: 'components.popUpWarning.title',
177
+ message: getTrad('containers.HomePage.PopUpWarning.message'),
178
+ cancel: 'app.components.Button.cancel',
179
+ confirm: getTrad('containers.HomePage.PopUpWarning.confirm'),
180
+ }}
181
+ popUpWarningType="danger"
182
+ onConfirm={onConfirmDeleteDoc}
183
+ />
184
+ <form onSubmit={onSubmit}>
185
+ <Header
186
+ actions={this.getPluginHeaderActions()}
187
+ title={{
188
+ label: formatMessage({
189
+ id: getTrad('containers.HomePage.PluginHeader.title'),
190
+ }),
191
+ }}
192
+ content={formatMessage({
193
+ id: getTrad('containers.HomePage.PluginHeader.description'),
194
+ })}
195
+ />
196
+ <StyledRow className="row">
197
+ <Block>
198
+ <CopyToClipboard text={auth.getToken()} onCopy={this.handleCopy}>
199
+ <div className="row" style={{ zIndex: '99' }}>
200
+ <Input
201
+ style={{ zIndex: '9', cursor: 'pointer' }}
202
+ inputStyle={{ cursor: 'pointer' }}
203
+ name="jwtToken"
204
+ value={auth.getToken()}
205
+ type="string"
206
+ onChange={() => {}}
207
+ label={{ id: getTrad('containers.HomePage.form.jwtToken') }}
208
+ inputDescription={{
209
+ id: getTrad('containers.HomePage.form.jwtToken.description'),
210
+ }}
211
+ />
212
+ </div>
213
+ </CopyToClipboard>
214
+ </Block>
215
+ <CheckPermissions permissions={pluginPermissions.update}>
216
+ <Block>{form.map(this.renderForm)}</Block>
217
+ </CheckPermissions>
218
+ <Block title={getTrad('containers.HomePage.Block.title')}>
219
+ <VersionWrapper>
220
+ <Row isHeader />
221
+ {docVersions.map(this.renderRow)}
222
+ </VersionWrapper>
223
+ </Block>
224
+ </StyledRow>
225
+ </form>
226
+ </ContainerFluid>
227
+ );
228
+ }
229
+ }
230
+
231
+ HomePage.defaultProps = {
232
+ currentDocVersion: '',
233
+ didCheckErrors: false,
234
+ docVersions: [],
235
+ form: [],
236
+ formErrors: {},
237
+ isLoading: true,
238
+ onChange: () => {},
239
+ onClickDeleteDoc: () => {},
240
+ onConfirmDeleteDoc: () => {},
241
+ onSubmit: () => {},
242
+ onUpdateDoc: () => {},
243
+ prefix: '/documentation',
244
+ versionToDelete: '',
245
+ };
246
+
247
+ HomePage.propTypes = {
248
+ currentDocVersion: PropTypes.string,
249
+ didCheckErrors: PropTypes.bool,
250
+ docVersions: PropTypes.array,
251
+ form: PropTypes.array,
252
+ formErrors: PropTypes.object,
253
+ getDocInfos: PropTypes.func.isRequired,
254
+ isLoading: PropTypes.bool,
255
+ onChange: PropTypes.func,
256
+ onClickDeleteDoc: PropTypes.func,
257
+ onConfirmDeleteDoc: PropTypes.func,
258
+ onSubmit: PropTypes.func,
259
+ onUpdateDoc: PropTypes.func,
260
+ prefix: PropTypes.string,
261
+ versionToDelete: PropTypes.string,
262
+ };
263
+
264
+ function mapDispatchToProps(dispatch) {
265
+ return bindActionCreators(
266
+ {
267
+ getDocInfos,
268
+ onChange,
269
+ onClickDeleteDoc,
270
+ onConfirmDeleteDoc,
271
+ onSubmit,
272
+ onUpdateDoc,
273
+ },
274
+ dispatch
275
+ );
276
+ }
277
+
278
+ const mapStateToProps = selectHomePage();
279
+
280
+ const withConnect = connect(mapStateToProps, mapDispatchToProps);
281
+ const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId });
282
+
283
+ export default compose(withSaga, withConnect)(HomePage);
@@ -0,0 +1,49 @@
1
+ /*
2
+ *
3
+ * HomePage reducer
4
+ *
5
+ */
6
+
7
+ import { fromJS, List } from 'immutable';
8
+ import {
9
+ GET_DOC_INFOS_SUCCEEDED,
10
+ ON_CHANGE,
11
+ ON_CLICK_DELETE_DOC,
12
+ SET_FORM_ERRORS,
13
+ } from './constants';
14
+
15
+ const initialState = fromJS({
16
+ currentDocVersion: '',
17
+ didCheckErrors: false,
18
+ docVersions: List([]),
19
+ form: fromJS([]),
20
+ formErrors: fromJS({}),
21
+ isLoading: true,
22
+ prefix: '/documentation',
23
+ versionToDelete: '',
24
+ });
25
+
26
+ function homePageReducer(state = initialState, action) {
27
+ switch (action.type) {
28
+ case GET_DOC_INFOS_SUCCEEDED:
29
+ return state
30
+ .update('docVersions', () => List(action.data.docVersions))
31
+ .update('currentDocVersion', () => action.data.currentVersion)
32
+ .update('isLoading', () => false)
33
+ .update('prefix', () => action.data.prefix)
34
+ .update('form', () => fromJS(action.data.form))
35
+ .update('versionToDelete', () => '');
36
+ case ON_CHANGE:
37
+ return state.updateIn(action.keys, () => action.value);
38
+ case ON_CLICK_DELETE_DOC:
39
+ return state.update('versionToDelete', () => action.version);
40
+ case SET_FORM_ERRORS:
41
+ return state
42
+ .update('didCheckErrors', v => !v)
43
+ .update('formErrors', () => fromJS(action.errors));
44
+ default:
45
+ return state;
46
+ }
47
+ }
48
+
49
+ export default homePageReducer;
@@ -0,0 +1,126 @@
1
+ import { cloneDeep, isArray } from 'lodash';
2
+ import { all, takeLatest, put, fork, call, select } from 'redux-saga/effects';
3
+ import { request } from 'strapi-helper-plugin';
4
+ import { GET_DOC_INFOS, ON_CONFIRM_DELETE_DOC, ON_UPDATE_DOC, ON_SUBMIT } from './constants';
5
+ import { getDocInfosSucceeded, setFormErrors } from './actions';
6
+ import { makeSelectVersionToDelete, makeSelectPrefix, makeSelectForm } from './selectors';
7
+ import getTrad from '../../utils/getTrad';
8
+
9
+ /* eslint-disable consistent-return */
10
+
11
+ function* getData() {
12
+ try {
13
+ const response = yield call(request, '/documentation/getInfos', {
14
+ method: 'GET',
15
+ });
16
+ yield put(getDocInfosSucceeded(response));
17
+ } catch (err) {
18
+ strapi.notification.toggle({
19
+ type: 'warning',
20
+ message: { id: 'notification.error' },
21
+ });
22
+ }
23
+ }
24
+
25
+ function* deleteDoc() {
26
+ try {
27
+ const prefix = yield select(makeSelectPrefix());
28
+ const version = yield select(makeSelectVersionToDelete());
29
+ const url = `${prefix}/deleteDoc/${version}`;
30
+ const response = yield call(request, url, { method: 'DELETE' });
31
+
32
+ if (response.ok) {
33
+ yield call(getData);
34
+ strapi.notification.toggle({
35
+ type: 'info',
36
+ message: { id: getTrad('notification.delete.success') },
37
+ });
38
+ }
39
+ } catch (err) {
40
+ strapi.notification.toggle({
41
+ type: 'warning',
42
+ message: err.response.payload.message,
43
+ });
44
+ }
45
+ }
46
+
47
+ function* submit() {
48
+ try {
49
+ const form = yield select(makeSelectForm());
50
+ const prefix = yield select(makeSelectPrefix());
51
+ const createBody = (data, init = {}) => {
52
+ return data.reduce((acc, current) => {
53
+ if (isArray(current)) {
54
+ return createBody(current, acc);
55
+ }
56
+
57
+ acc[current.name] = current.value;
58
+
59
+ return acc;
60
+ }, init);
61
+ };
62
+ const body = createBody(cloneDeep(form));
63
+
64
+ if (body.restrictedAccess && body.password === '') {
65
+ return yield put(
66
+ setFormErrors({
67
+ password: [{ id: 'components.Input.error.validation.required' }],
68
+ })
69
+ );
70
+ }
71
+
72
+ yield call(request, `${prefix}/updateSettings`, { method: 'PUT', body });
73
+ yield put(setFormErrors({}));
74
+
75
+ strapi.notification.toggle({
76
+ type: 'success',
77
+ message: { id: getTrad('notification.update.success') },
78
+ });
79
+ } catch (err) {
80
+ strapi.notification.toggle({
81
+ type: 'warning',
82
+ message: err.response.payload.message,
83
+ });
84
+ }
85
+ }
86
+
87
+ function* updateDoc(action) {
88
+ try {
89
+ const body = { version: action.version };
90
+ const prefix = yield select(makeSelectPrefix());
91
+ const response = yield call(request, `${prefix}/regenerateDoc`, {
92
+ method: 'POST',
93
+ body,
94
+ });
95
+
96
+ if (response.ok) {
97
+ yield call(getData);
98
+ strapi.notification.toggle({
99
+ type: 'info',
100
+ message: { id: getTrad('notification.generate.success') },
101
+ });
102
+ }
103
+ } catch (err) {
104
+ strapi.notification.toggle({
105
+ type: 'warning',
106
+ message: err.response.payload.message,
107
+ });
108
+ }
109
+ }
110
+
111
+ // Individual exports for testing
112
+ export function* defaultSaga() {
113
+ try {
114
+ yield all([
115
+ fork(takeLatest, GET_DOC_INFOS, getData),
116
+ fork(takeLatest, ON_CONFIRM_DELETE_DOC, deleteDoc),
117
+ fork(takeLatest, ON_SUBMIT, submit),
118
+ fork(takeLatest, ON_UPDATE_DOC, updateDoc),
119
+ ]);
120
+ } catch (err) {
121
+ // Do nothing
122
+ }
123
+ }
124
+
125
+ // All sagas to be loaded
126
+ export default defaultSaga;
@@ -0,0 +1,34 @@
1
+ import { createSelector } from 'reselect';
2
+ import pluginId from '../../pluginId';
3
+
4
+ /**
5
+ * Direct selector to the homePage state domain
6
+ */
7
+ const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`);
8
+
9
+ /**
10
+ * Default selector used by HomePage
11
+ */
12
+
13
+ const selectHomePage = () => createSelector(
14
+ selectHomePageDomain(),
15
+ (substate) => substate.toJS(),
16
+ );
17
+
18
+ const makeSelectForm = () => createSelector(
19
+ selectHomePageDomain(),
20
+ substate => substate.get('form').toJS(),
21
+ );
22
+
23
+ const makeSelectPrefix = () => createSelector(
24
+ selectHomePageDomain(),
25
+ substate => substate.get('prefix'),
26
+ );
27
+
28
+ const makeSelectVersionToDelete = () => createSelector(
29
+ selectHomePageDomain(),
30
+ substate => substate.get('versionToDelete'),
31
+ );
32
+
33
+ export default selectHomePage;
34
+ export { makeSelectForm, makeSelectVersionToDelete, makeSelectPrefix };
@@ -0,0 +1,28 @@
1
+ /**
2
+ *
3
+ * Initializer
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+
10
+ import pluginId from '../../pluginId';
11
+
12
+ class Initializer extends React.PureComponent {
13
+ // eslint-disable-line react/prefer-stateless-function
14
+ componentDidMount() {
15
+ // Emit the event 'pluginReady'
16
+ this.props.updatePlugin(pluginId, 'isReady', true);
17
+ }
18
+
19
+ render() {
20
+ return null;
21
+ }
22
+ }
23
+
24
+ Initializer.propTypes = {
25
+ updatePlugin: PropTypes.func.isRequired,
26
+ };
27
+
28
+ export default Initializer;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { mount, shallow } from 'enzyme';
3
+
4
+ import Initializer from '../index';
5
+
6
+ describe('<Initializer />', () => {
7
+ it('Should not crash', () => {
8
+ const updatePlugin = jest.fn();
9
+ const renderedComponent = shallow(<Initializer updatePlugin={updatePlugin} />);
10
+
11
+ expect(renderedComponent.children()).toHaveLength(0);
12
+ });
13
+
14
+ it('should call the updatePlugin props when mounted', () => {
15
+ const updatePlugin = jest.fn();
16
+
17
+ const wrapper = mount(<Initializer updatePlugin={updatePlugin} />);
18
+
19
+ expect(wrapper.prop('updatePlugin')).toHaveBeenCalledWith('documentation', 'isReady', true);
20
+ });
21
+ });
@@ -0,0 +1,57 @@
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
+
8
+ import pluginPkg from '../../package.json';
9
+ import pluginPermissions from './permissions';
10
+ import pluginId from './pluginId';
11
+ import pluginLogo from './assets/images/logo.svg';
12
+ import App from './containers/App';
13
+ import Initializer from './containers/Initializer';
14
+ import lifecycles from './lifecycles';
15
+ import reducers from './reducers';
16
+ import trads from './translations';
17
+
18
+ export default strapi => {
19
+ const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
20
+ const icon = pluginPkg.strapi.icon;
21
+ const name = pluginPkg.strapi.name;
22
+ const plugin = {
23
+ blockerComponent: null,
24
+ blockerComponentProps: {},
25
+ description: pluginDescription,
26
+ icon,
27
+ id: pluginId,
28
+ initializer: Initializer,
29
+ injectedComponents: [],
30
+ isReady: false,
31
+ isRequired: pluginPkg.strapi.required || false,
32
+ layout: null,
33
+ lifecycles,
34
+ mainComponent: App,
35
+ name,
36
+ pluginLogo,
37
+ preventComponentRendering: false,
38
+ reducers,
39
+ trads,
40
+ menu: {
41
+ pluginsSectionLinks: [
42
+ {
43
+ destination: `/plugins/${pluginId}`,
44
+ icon,
45
+ label: {
46
+ id: `${pluginId}.plugin.name`,
47
+ defaultMessage: 'Documentation',
48
+ },
49
+ name,
50
+ permissions: pluginPermissions.main,
51
+ },
52
+ ],
53
+ },
54
+ };
55
+
56
+ return strapi.registerPlugin(plugin);
57
+ };
@@ -0,0 +1,13 @@
1
+ /*
2
+ *
3
+ * SET THE HOOKS TO ENABLE THE MAGIC OF STRAPI.
4
+ * -------------------------------------------
5
+ *
6
+ * Secure, customise and enhance your project by setting
7
+ * the hooks via this file.
8
+ *
9
+ */
10
+
11
+ function lifecycles() {}
12
+
13
+ export default lifecycles;
@@ -0,0 +1,19 @@
1
+ const pluginPermissions = {
2
+ // This permission regards the main component (App) and is used to tell
3
+ // If the plugin link should be displayed in the menu
4
+ // And also if the plugin is accessible. This use case is found when a user types the url of the
5
+ // plugin directly in the browser
6
+ main: [
7
+ { action: 'plugins::documentation.read', subject: null },
8
+ { action: 'plugins::documentation.settings.regenerate', subject: null },
9
+ { action: 'plugins::documentation.settings.update', subject: null },
10
+ ],
11
+ open: [
12
+ { action: 'plugins::documentation.read', subject: null },
13
+ { action: 'plugins::documentation.settings.regenerate', subject: null },
14
+ ],
15
+ regenerate: [{ action: 'plugins::documentation.settings.regenerate', subject: null }],
16
+ update: [{ action: 'plugins::documentation.settings.update', subject: null }],
17
+ };
18
+
19
+ export default pluginPermissions;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.name.replace(/^strapi-plugin-/i, '');
4
+
5
+ export default pluginId;
@@ -0,0 +1,8 @@
1
+ import homePageReducer from './containers/HomePage/reducer';
2
+ import pluginId from './pluginId';
3
+
4
+ const reducers = {
5
+ [`${pluginId}_homePage`]: homePageReducer,
6
+ };
7
+
8
+ export default reducers;
@@ -0,0 +1,23 @@
1
+ {
2
+ "components.Row.generatedDate": "Last generation",
3
+ "components.Row.open": "Open",
4
+ "components.Row.regenerate": "Regenerate",
5
+ "containers.HomePage.Block.title": "Versions",
6
+ "containers.HomePage.Button.open": "Open the documentation",
7
+ "containers.HomePage.Button.update": "Update",
8
+ "containers.HomePage.PluginHeader.description": "Configure the documentation plugin",
9
+ "containers.HomePage.PluginHeader.title": "Documentation - Settings",
10
+ "containers.HomePage.PopUpWarning.confirm": "I understand",
11
+ "containers.HomePage.PopUpWarning.message": "Are you sure you want to delete this version?",
12
+ "containers.HomePage.form.password": "Password",
13
+ "containers.HomePage.form.password.inputDescription": "Set the password to access the documentation",
14
+ "containers.HomePage.form.restrictedAccess": "Restricted access",
15
+ "containers.HomePage.form.restrictedAccess.inputDescription": "Make the documentation endpoint private. By default, the access is public",
16
+ "containers.HomePage.form.showGeneratedFiles": "Show generated files",
17
+ "containers.HomePage.form.showGeneratedFiles.inputDescription": "Useful when you want to override the generated documentation. \nThe plugin will generate files split by model and plugin. \nBy enabling this option it will be easier to customize your documentation",
18
+ "error.deleteDoc.versionMissing": "The version you are trying to delete does not exist.",
19
+ "error.noVersion": "A version is required",
20
+ "error.regenerateDoc": "An error occurred while regenerating the doc",
21
+ "error.regenerateDoc.versionMissing": "The version you are trying to generate doesn't exist",
22
+ "notification.update.success": "Settings updated successfully"
23
+ }