@vegan-friendly/strapi-plugin-elasticsearch 0.0.11-alpha.6 → 0.1.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.
Files changed (63) hide show
  1. package/.prettierrc +7 -0
  2. package/.vscode/settings.json +24 -0
  3. package/README.md +0 -4
  4. package/admin/src/components/Initializer/index.js +26 -0
  5. package/admin/src/components/PluginIcon/index.js +12 -0
  6. package/admin/src/components/SubNavigation/index.js +48 -0
  7. package/admin/src/index.js +63 -0
  8. package/admin/src/pages/App/index.js +29 -0
  9. package/admin/src/pages/ConfigureCollection/index.js +225 -0
  10. package/admin/src/pages/ConfigureCollectionList/index.js +266 -0
  11. package/admin/src/pages/Homepage/index.js +168 -0
  12. package/admin/src/pages/ViewIndexingRunLog/index.js +124 -0
  13. package/admin/src/pluginId.js +5 -0
  14. package/admin/src/translations/en.json +1 -0
  15. package/admin/src/translations/fr.json +1 -0
  16. package/admin/src/utils/apiUrls.js +14 -0
  17. package/admin/src/utils/axiosInstance.js +40 -0
  18. package/admin/src/utils/getTrad.js +5 -0
  19. package/package.json +40 -80
  20. package/server/bootstrap.js +142 -0
  21. package/server/config/index.js +6 -0
  22. package/server/content-types/index.js +9 -0
  23. package/server/content-types/indexing-logs.js +35 -0
  24. package/server/content-types/name-prefix.js +0 -0
  25. package/server/content-types/tasks.js +52 -0
  26. package/server/controllers/configure-indexing.js +66 -0
  27. package/server/controllers/index.js +15 -0
  28. package/server/controllers/log-indexing.js +11 -0
  29. package/server/controllers/perform-indexing.js +28 -0
  30. package/server/controllers/perform-search.js +31 -0
  31. package/server/controllers/setup-info.js +14 -0
  32. package/server/destroy.js +5 -0
  33. package/server/index.js +25 -0
  34. package/server/middlewares/index.js +3 -0
  35. package/server/policies/index.js +3 -0
  36. package/server/register.js +5 -0
  37. package/server/routes/configure-indexing.js +42 -0
  38. package/server/routes/index.js +13 -0
  39. package/server/routes/perform-indexing.js +24 -0
  40. package/server/routes/perform-search.js +14 -0
  41. package/server/routes/run-log.js +12 -0
  42. package/server/routes/setup-info.js +12 -0
  43. package/server/services/configure-indexing.js +184 -0
  44. package/server/services/es-interface.js +187 -0
  45. package/server/services/helper.js +305 -0
  46. package/server/services/index.js +21 -0
  47. package/server/services/log-indexing.js +26 -0
  48. package/server/services/perform-indexing.js +173 -0
  49. package/server/services/schedule-indexing.js +65 -0
  50. package/server/services/transform-content.js +22 -0
  51. package/server/services/virtual-collections-registry.js +445 -0
  52. package/strapi-admin.js +3 -0
  53. package/strapi-server.js +3 -0
  54. package/dist/_chunks/App-Br53NnT1.mjs +0 -17315
  55. package/dist/_chunks/App-C3jMSu4l.js +0 -17314
  56. package/dist/_chunks/en-B4KWt_jN.js +0 -4
  57. package/dist/_chunks/en-Byx4XI2L.mjs +0 -4
  58. package/dist/_chunks/index-BlmgBQo2.js +0 -71
  59. package/dist/_chunks/index-CRnRLV0T.mjs +0 -72
  60. package/dist/admin/index.js +0 -3
  61. package/dist/admin/index.mjs +0 -4
  62. package/dist/server/index.js +0 -7330
  63. package/dist/server/index.mjs +0 -7307
@@ -0,0 +1,266 @@
1
+ /*
2
+ *
3
+ * HomePage
4
+ *
5
+ */
6
+
7
+ import React, { useState } from 'react';
8
+ // import PropTypes from 'prop-types';
9
+ import pluginId from '../../pluginId';
10
+ import { SubNavigation } from '../../components/SubNavigation';;
11
+ import { Box, Flex } from '@strapi/design-system';
12
+ import { useEffect } from 'react';
13
+ import { Loader } from '@strapi/design-system';
14
+ import { apiGetContentConfig, apiRequestCollectionIndexing,
15
+ apiImportContentConfig, apiExportContentConfig } from "../../utils/apiUrls";
16
+ import axiosInstance from '../../utils/axiosInstance';
17
+ import { Alert } from '@strapi/design-system';
18
+ import { Table, Thead, Tbody, Tr, Td, Th } from '@strapi/design-system';
19
+ import { Typography } from '@strapi/design-system';
20
+ import { Pencil, Server } from '@strapi/icons';
21
+ import { IconButton } from '@strapi/design-system';
22
+ import { useHistory } from "react-router-dom";
23
+ import { Button } from '@strapi/design-system';
24
+ import { ModalLayout, ModalBody, ModalHeader, ModalFooter } from '@strapi/design-system';
25
+ import { Textarea, TwoColsLayout, Divider } from '@strapi/design-system';
26
+ import {LoadingIndicatorPage, useNotification} from '@strapi/helper-plugin';
27
+
28
+ const exportContentConfig = () => {
29
+ return axiosInstance.get(apiGetContentConfig,
30
+ {
31
+ responseType: 'blob'
32
+ })
33
+ .then((response) => {
34
+ const href = URL.createObjectURL(response.data);
35
+ const link = document.createElement('a');
36
+ link.href = href;
37
+ link.setAttribute('download', 'strapi-plugin-elasticsearch-contentconfig.json');
38
+ document.body.appendChild(link);
39
+ link.click();
40
+ document.body.removeChild(link);
41
+ URL.revokeObjectURL(href);
42
+ });
43
+ }
44
+
45
+ const importContentConfig = (conf) => {
46
+ return axiosInstance.post(apiImportContentConfig, {
47
+ data : conf
48
+ });
49
+ }
50
+
51
+ const loadContentConfig = () => {
52
+ return axiosInstance.get(apiGetContentConfig)
53
+ .then((resp) => resp.data);
54
+ }
55
+
56
+ const scheduleCollectionIndexing = (collectionName) => {
57
+ return axiosInstance.get(apiRequestCollectionIndexing(collectionName))
58
+ }
59
+
60
+ const Configure = () => {
61
+ const [isInProgress, setIsInProgress] = useState(false);
62
+ const [displayImportModal, setDisplayImportModal] = useState(false);
63
+ const [isEnteredJsonValid, setIsEnteredJsonValid] = useState(true);
64
+ const [importJson, setImportJson] = useState(null);
65
+
66
+ const [config, setConfig] = useState(null);
67
+ const history = useHistory();
68
+ const toggleNotification = useNotification();
69
+
70
+ const performImport = () => {
71
+ const conf = importJson
72
+ console.log(conf && conf.length > 0)
73
+ if (conf && conf.length > 0) {
74
+ setIsInProgress(true);
75
+ importContentConfig(conf)
76
+ .then(() => {
77
+ toggleNotification({
78
+ type: "success", message: "Collections configuration imported. Please refresh this view.", timeout: 5000
79
+ });
80
+ })
81
+ .catch((err) => {
82
+ toggleNotification({
83
+ type: "warning", message: "Importing collections configuration failed. An error was encountered.", timeout: 5000
84
+ });
85
+ console.log(err);
86
+ })
87
+ .finally(() => setIsInProgress(false));
88
+ }
89
+ }
90
+ const performExport = () => {
91
+ setIsInProgress(true);
92
+ exportContentConfig()
93
+ .then(() => {
94
+ toggleNotification({
95
+ type: "success", message: "Collections configuration exported.", timeout: 5000
96
+ });
97
+ })
98
+ .catch((err) => {
99
+ toggleNotification({
100
+ type: "warning", message: "Exporting collections configuration failed. An error was encountered.", timeout: 5000
101
+ });
102
+ console.log(err);
103
+ })
104
+ .finally(() => setIsInProgress(false));
105
+ }
106
+
107
+ useEffect(() => {
108
+ if (importJson && importJson.length > 0)
109
+ {
110
+ try {
111
+ JSON.parse(importJson);
112
+ setIsEnteredJsonValid(true);
113
+ } catch (e) {
114
+ setIsEnteredJsonValid(false);
115
+ }
116
+ }
117
+ }, [importJson]);
118
+
119
+ useEffect(() => {
120
+ setIsInProgress(true);
121
+ loadContentConfig()
122
+ .then((resp) => {
123
+ const displayConfig = [];
124
+ for (let r=0; r < Object.keys(resp).length; r++)
125
+ {
126
+ const item = {collectionName: Object.keys(resp)[r], indexed: [], notIndexed: []};
127
+ const collectionName = item.collectionName;
128
+ for (let k=0; k < Object.keys(resp[collectionName]).length; k++)
129
+ {
130
+ const attribs = resp[collectionName];
131
+ for (let s=0; s < Object.keys(attribs).length; s++)
132
+ {
133
+ const attrName = Object.keys(attribs)[s]
134
+ const attr = attribs[attrName]
135
+ if (attr.index === false && !item.notIndexed.includes(attrName))
136
+ item.notIndexed.push(attrName)
137
+ else if (attr.index && !item.indexed.includes(attrName))
138
+ item.indexed.push(attrName)
139
+ }
140
+ }
141
+ displayConfig.push(item);
142
+ }
143
+ setConfig(displayConfig);
144
+ })
145
+ .catch((err) => {
146
+ toggleNotification({
147
+ type: "warning", message: "An error was encountered while fetching the configuration.", timeout: 5000
148
+ });
149
+ console.log(err);
150
+ })
151
+ .finally (() => {
152
+ setIsInProgress(false);
153
+ })
154
+ }, []);
155
+ if (config === null)
156
+ return <LoadingIndicatorPage />;
157
+ else
158
+ {
159
+ return (
160
+ <>
161
+ <Flex alignItems="stretch" gap={4}>
162
+ <SubNavigation activeUrl={'/configure-collections/'}/>
163
+ <Box padding={8} background="neutral100">
164
+ <Box paddingBottom={4}>
165
+ <Typography variant="alpha">Configure Collections</Typography>
166
+ </Box>
167
+ {
168
+ config && (
169
+ <TwoColsLayout startCol={
170
+ <Table colCount={4} rowCount={config.length}>
171
+ <Thead>
172
+ <Tr>
173
+ <Th style={{width: "250px"}}>
174
+ <Typography variant="sigma">Collection</Typography>
175
+ </Th>
176
+ <Th style={{width: "250px"}}>
177
+ <Typography variant="sigma">Index</Typography>
178
+ </Th>
179
+ <Th style={{width: "250px"}}>
180
+ <Typography variant="sigma">Do not Index</Typography>
181
+ </Th>
182
+ <Th>
183
+ <Typography variant="sigma">Actions</Typography>
184
+ </Th>
185
+ </Tr>
186
+ </Thead>
187
+ <Tbody>
188
+ {
189
+ config.map((collection, idx) => {
190
+ return (
191
+ <Tr key={idx}>
192
+ <Td>
193
+ <Typography textColor="neutral600">{collection.collectionName}
194
+ </Typography>
195
+ </Td>
196
+ <Td>
197
+ {collection.indexed.map((i) =>
198
+ <Box paddingBottom={2}>
199
+ <Typography textColor="neutral600">{i}
200
+ </Typography></Box>
201
+ )}
202
+ </Td>
203
+ <Td>
204
+ {collection.notIndexed.map((i) =>
205
+ <Box paddingBottom={2}>
206
+ <Typography textColor="neutral600">{i}
207
+ </Typography></Box>
208
+ )}
209
+ </Td>
210
+ <Td>
211
+ <IconButton onClick={() => history.push(`/plugins/${pluginId}/configure-collections/${collection.collectionName}`)} label="Edit collection configuration" noBorder icon={<Pencil />} />
212
+ <IconButton onClick={() => scheduleCollectionIndexing(collection.collectionName)} label="Schedule indexing for all items in this collection" noBorder icon={<Server />} />
213
+ </Td>
214
+ </Tr>
215
+ );
216
+ })
217
+ }
218
+ </Tbody>
219
+ </Table>}
220
+ endCol={<>
221
+ <Box paddingLeft={2} paddingRight={2} paddingTop={4} paddingBottom={4} >
222
+ <Box paddingTop={4} paddingBottom={4}>
223
+ <Typography variant="pi" fontWeight="bold" textColor="neutral600" >CONFIG ACTIONS</Typography>
224
+ </Box>
225
+ <Divider />
226
+ <Box paddingTop={4} paddingBottom={4}>
227
+ <Box paddingTop={2} paddingBottom={2}>
228
+ <Button loading={isInProgress} fullWidth variant="secondary" onClick={performExport}>Export</Button>
229
+ </Box>
230
+ <Box paddingTop={2} paddingBottom={2}>
231
+ <Button loading={isInProgress} fullWidth variant="secondary" onClick={() => setDisplayImportModal(true)}>Import</Button>
232
+ </Box>
233
+ </Box>
234
+ </Box>
235
+ </>
236
+ } />
237
+ )
238
+ }
239
+ {displayImportModal &&
240
+ <ModalLayout onClose={() => setDisplayImportModal(false)} labelledBy="title">
241
+ <ModalHeader>
242
+ <Typography fontWeight="bold" textColor="neutral800" as="h2" id="title">
243
+ Import Search Configuration
244
+ </Typography>
245
+ </ModalHeader>
246
+ <ModalBody>
247
+ <Textarea
248
+ label="Configuration Json"
249
+ error={!isEnteredJsonValid ? 'Invalid Json' : undefined}
250
+ onChange={e => setImportJson(e.target.value)}
251
+ >{importJson}</Textarea>
252
+ </ModalBody>
253
+ <ModalFooter startActions={<Button onClick={() => setDisplayImportModal(false)} variant="tertiary">
254
+ Cancel
255
+ </Button>} endActions={<>
256
+ <Button loading={isInProgress} onClick={performImport} disabled={!isEnteredJsonValid && !importJson.length>0}>Import</Button>
257
+ </>} />
258
+ </ModalLayout>}
259
+ </Box>
260
+ </Flex>
261
+ </>
262
+ );
263
+ }
264
+ };
265
+
266
+ export default Configure;
@@ -0,0 +1,168 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { SubNavigation } from '../../components/SubNavigation';;
3
+ import { Box, Flex, Tab } from '@strapi/design-system';
4
+ import { Typography } from '@strapi/design-system';
5
+ import { apiGetElasticsearchSetupInfo, apiRequestReIndexing,
6
+ apiTriggerIndexing } from '../../utils/apiUrls';
7
+ import axiosInstance from '../../utils/axiosInstance';
8
+ import { IconButton } from '@strapi/design-system';
9
+ import { Table, Tr, Td } from '@strapi/design-system';
10
+ import { Refresh } from '@strapi/icons';
11
+ import { TwoColsLayout, Button } from '@strapi/design-system';
12
+ import { Grid, GridItem, Divider } from '@strapi/design-system';
13
+ import {LoadingIndicatorPage, useNotification} from '@strapi/helper-plugin';
14
+
15
+ const loadElasticsearchSetupInfo = () => {
16
+ return axiosInstance.get(apiGetElasticsearchSetupInfo)
17
+ .then((resp) => resp.data)
18
+ .then((data) => {
19
+ return data;
20
+ });
21
+ }
22
+
23
+ const Homepage = () => {
24
+ const [setupInfo, setSetupInfo] = useState(null);
25
+ const [isInProgress, setIsInProgress] = useState(false);
26
+ const toggleNotification = useNotification();
27
+
28
+ const displayLabels = {'connected' : 'Connected',
29
+ 'elasticCertificate' : 'Certificate',
30
+ 'elasticHost' : 'Elasticsearch host',
31
+ 'elasticIndexAlias' : 'Elasticsearch index Alias name',
32
+ 'elasticUserName' : 'Elasticsearch username',
33
+ 'indexingCronSchedule' : 'Indexing cron schedule',
34
+ 'initialized' : 'Elasticsearch configuration loaded'};
35
+
36
+ const reloadElasticsearchSetupInfo = ({showNotification}) => {
37
+ setIsInProgress(true);
38
+ loadElasticsearchSetupInfo()
39
+ .then(setSetupInfo)
40
+ .then(() => {
41
+ if (showNotification)
42
+ toggleNotification({
43
+ type: "success", message: "Elasticsearch setup information reloaded.", timeout: 5000
44
+ });
45
+ })
46
+ .finally(() => setIsInProgress(false));
47
+ }
48
+
49
+ const requestFullSiteReindexing = () => {
50
+ setIsInProgress(true);
51
+ return axiosInstance.get(apiRequestReIndexing)
52
+ .then(() => {
53
+ toggleNotification({
54
+ type: "success", message: "Rebuilding the index is triggered.", timeout: 5000
55
+ });
56
+ })
57
+ .catch(() => {
58
+ toggleNotification({
59
+ type: "warning", message: "An error was encountered.", timeout: 5000
60
+ });
61
+ })
62
+ .finally(() => setIsInProgress(false));
63
+ }
64
+
65
+ const triggerIndexingRun = () => {
66
+ setIsInProgress(true);
67
+ return axiosInstance.get(apiTriggerIndexing)
68
+ .then(() => {
69
+ toggleNotification({
70
+ type: "success", message: "The indexing job to process the pending tasks is started.", timeout: 5000
71
+ });
72
+ })
73
+ .catch(() => {
74
+ toggleNotification({
75
+ type: "warning", message: "An error was encountered.", timeout: 5000
76
+ });
77
+ })
78
+ .finally(() => setIsInProgress(false));
79
+ }
80
+ useEffect(() => {
81
+ reloadElasticsearchSetupInfo({showNotification: false});
82
+ }, []);
83
+
84
+ if (setupInfo === null)
85
+ return <LoadingIndicatorPage />
86
+ else
87
+ return (
88
+ <Flex alignItems="stretch" gap={4}>
89
+ <SubNavigation />
90
+ <Box padding={8} background="neutral100" width="100%">
91
+ <Box paddingBottom={4}>
92
+ <Typography variant="alpha">Setup Information</Typography>
93
+ </Box>
94
+ <Box width="100%" paddingBottom={4}>
95
+ <TwoColsLayout startCol={
96
+ <>
97
+ <Table>
98
+ {
99
+ setupInfo && (
100
+ Object.keys(setupInfo).map((k, idx) => {
101
+ return (
102
+ <Tr key={idx}>
103
+ <Td><Box padding={2}>
104
+ <Typography textColor="neutral600">{displayLabels[k]} :</Typography>
105
+ </Box></Td>
106
+ <Td>
107
+ <Box padding={2}>
108
+ <Grid>
109
+ <GridItem padding={2}>
110
+ {
111
+ k === 'connected' && setupInfo[k] === true &&
112
+ (
113
+ <Typography fontWeight="bold" textColor="success500">Yes</Typography>
114
+ )
115
+ }
116
+ {
117
+ k === 'connected' && setupInfo[k] === false &&
118
+ (
119
+ <Typography fontWeight="bold" textColor="danger500">No</Typography>
120
+ )
121
+ }
122
+ {
123
+ k !== 'connected' &&
124
+ (
125
+ <Typography textColor="neutral600">{String(setupInfo[k])}</Typography>
126
+ )
127
+ }
128
+ </GridItem>
129
+ <GridItem padding={1}>
130
+ {
131
+ k === 'connected' ?
132
+ <IconButton disabled={isInProgress} onClick={() => reloadElasticsearchSetupInfo({showNotification: true})} label="Refresh" icon={<Refresh />} /> : null
133
+ }
134
+ </GridItem>
135
+ </Grid>
136
+ </Box>
137
+ </Td>
138
+ </Tr>
139
+ );
140
+ })
141
+ )
142
+ }
143
+ </Table></>}
144
+ endCol={<>
145
+ <Box paddingLeft={2} paddingRight={2} paddingTop={4} paddingBottom={4} >
146
+ <Box paddingTop={4} paddingBottom={4}>
147
+ <Typography variant="pi" fontWeight="bold" textColor="neutral600" >ACTIONS</Typography>
148
+ </Box>
149
+ <Divider />
150
+ <Box paddingTop={4} paddingBottom={4}>
151
+ <Box paddingTop={2} paddingBottom={2}>
152
+ <Button loading={isInProgress} fullWidth variant="secondary" onClick={requestFullSiteReindexing}>Rebuild Index</Button>
153
+ </Box>
154
+ <Box paddingTop={2} paddingBottom={2}>
155
+ <Button loading={isInProgress} fullWidth variant="secondary" onClick={triggerIndexingRun}>Trigger Indexing</Button>
156
+ </Box>
157
+ </Box>
158
+ </Box>
159
+ </>
160
+ } />
161
+ </Box>
162
+ </Box>
163
+ </Flex>
164
+ );
165
+ };
166
+
167
+
168
+ export default Homepage;
@@ -0,0 +1,124 @@
1
+ /*
2
+ *
3
+ * HomePage
4
+ *
5
+ */
6
+
7
+ import React, { useState, useEffect } from 'react';
8
+ // import PropTypes from 'prop-types';
9
+ import pluginId from '../../pluginId';
10
+ import { SubNavigation } from '../../components/SubNavigation';;
11
+ import { Box, Flex } from '@strapi/design-system';
12
+ import { apiFetchRecentIndexingRunLog } from "../../utils/apiUrls";
13
+ import axiosInstance from '../../utils/axiosInstance';
14
+ import { Table, Thead, Tbody, Tr, Td, Th } from '@strapi/design-system';
15
+ import { Typography } from '@strapi/design-system';
16
+ import {LoadingIndicatorPage} from '@strapi/helper-plugin';
17
+
18
+ const loadRecentIndexingRuns = () => {
19
+ return axiosInstance.get(apiFetchRecentIndexingRunLog)
20
+ .then((resp) => resp.data)
21
+ .then((data) => {
22
+ return data;
23
+ });
24
+ }
25
+
26
+ const formattedDate = (dateString) => {
27
+ const date = new Date(dateString);
28
+ const options = {
29
+ weekday: 'long',
30
+ year: 'numeric',
31
+ month: 'numeric',
32
+ day: 'numeric',
33
+ hour: 'numeric',
34
+ minute: 'numeric',
35
+ };
36
+
37
+ const dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
38
+ const parts = dateTimeFormat.formatToParts(date);
39
+
40
+ let formattedDate = '';
41
+ parts.forEach((part) => {
42
+ if (part.type === "weekday")
43
+ formattedDate+= `${part.value}, `;
44
+ if (part.type === "day")
45
+ formattedDate+= `${part.value}/`;
46
+ if (part.type === "month")
47
+ formattedDate+= `${part.value}/`;
48
+ if (part.type === "year")
49
+ formattedDate+= `${part.value} `;
50
+ if (part.type === "hour")
51
+ formattedDate+= `${part.value}:`;
52
+ if (part.type === "minute")
53
+ formattedDate+= `${part.value}`;
54
+ });
55
+
56
+ return formattedDate;
57
+ }
58
+
59
+ const ViewIndexingRunLog = () => {
60
+ const [logTable, setLogTable] = useState(null);
61
+ useEffect(() => {
62
+ loadRecentIndexingRuns()
63
+ .then(setLogTable)
64
+ }, []);
65
+
66
+ if (logTable === null)
67
+ return <LoadingIndicatorPage />
68
+ else
69
+ return (
70
+ <Flex alignItems="stretch" gap={4}>
71
+ <SubNavigation />
72
+ <Box padding={8} background="neutral100" width="100%">
73
+ <Box paddingBottom={4}>
74
+ <Typography variant="alpha">Recent Indexing Run Logs</Typography>
75
+ </Box>
76
+ {
77
+ logTable && logTable.length > 0 && (
78
+ <>
79
+ <Table colCount={3} rowCount={logTable.length}>
80
+ <Thead>
81
+ <Tr>
82
+ <Th>
83
+ <Typography variant="sigma">Date</Typography>
84
+ </Th>
85
+ <Th>
86
+ <Typography variant="sigma">Status</Typography>
87
+ </Th>
88
+ <Th>
89
+ <Typography variant="sigma">Details</Typography>
90
+ </Th>
91
+ </Tr>
92
+ </Thead>
93
+ <Tbody>
94
+ {
95
+ logTable.map((data, index) => {
96
+ return (
97
+ <Tr key={index}>
98
+ <Td>
99
+ <Typography textColor="neutral600">{formattedDate(data.createdAt)}</Typography>
100
+ </Td>
101
+ <Td>
102
+ <Typography textColor="neutral600">{data.status}</Typography>
103
+ </Td>
104
+ <Td>
105
+ <Typography textColor="neutral600">{data.details}</Typography>
106
+ </Td>
107
+ </Tr>
108
+ );
109
+ })
110
+ }
111
+ </Tbody>
112
+ </Table>
113
+ <Box paddingTop={2} paddingBottom={2}>
114
+ <Typography textColor="neutral600">This view lists the details of the 50 recent-most indexing runs.</Typography>
115
+ </Box>
116
+ </>
117
+ )
118
+ }
119
+ </Box>
120
+ </Flex>
121
+ );
122
+ };
123
+
124
+ export default ViewIndexingRunLog;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.strapi.name;
4
+
5
+ export default pluginId;
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,14 @@
1
+ import { collectionName } from "../../../server/content-types/tasks";
2
+ import pluginId from "../pluginId";
3
+ export const apiGetContentConfig = `/${pluginId}/content-config/`
4
+ export const apiGetCollectionConfig = (collectionName) => `/${pluginId}/collection-config/${collectionName}`
5
+ export const apiSaveCollectionConfig = (collectionName) => `/${pluginId}/collection-config/${collectionName}`
6
+ export const apiGetElasticsearchSetupInfo = `/${pluginId}/setup-info`
7
+ export const apiFetchRecentIndexingRunLog = `/${pluginId}/indexing-run-log`
8
+ export const apiRequestReIndexing = `/${pluginId}/reindex`
9
+ export const apiRequestCollectionIndexing = (collectionName) => `/${pluginId}/collection-reindex/${collectionName}`
10
+ export const apiTriggerIndexing = `/${pluginId}/trigger-indexing/`
11
+
12
+ export const apiExportContentConfig = `/${pluginId}/export-content-config/`
13
+ export const apiImportContentConfig = `/${pluginId}/import-content-config/`
14
+
@@ -0,0 +1,40 @@
1
+ /**
2
+ * axios with a custom config.
3
+ */
4
+
5
+ import axios from 'axios';
6
+ import { auth } from '@strapi/helper-plugin';
7
+
8
+ const instance = axios.create({
9
+ baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
10
+ });
11
+
12
+ instance.interceptors.request.use(
13
+ async config => {
14
+ config.headers = {
15
+ Authorization: `Bearer ${auth.getToken()}`,
16
+ Accept: 'application/json',
17
+ 'Content-Type': 'application/json',
18
+ };
19
+
20
+ return config;
21
+ },
22
+ error => {
23
+ Promise.reject(error);
24
+ }
25
+ );
26
+
27
+ instance.interceptors.response.use(
28
+ response => response,
29
+ error => {
30
+ // whatever you want to do with the error
31
+ if (error.response?.status === 401) {
32
+ auth.clearAppStorage();
33
+ window.location.reload();
34
+ }
35
+
36
+ throw error;
37
+ }
38
+ );
39
+
40
+ export default instance;
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getTrad = (id) => `${pluginId}.${id}`;
4
+
5
+ export default getTrad;