strapi-plugin-meilisearch 0.11.0 → 0.11.1
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/useAlert.js +17 -0
- package/admin/src/Hooks/useCollection.js +69 -56
- package/admin/src/Hooks/useCredential.js +24 -20
- package/admin/src/components/Initializer/index.js +27 -0
- package/admin/src/constants.js +34 -0
- package/admin/src/containers/Collection/CollectionColumn.js +34 -26
- package/admin/src/containers/Collection/CollectionTable.js +3 -5
- package/admin/src/containers/Collection/CollectionTableHeader.js +12 -6
- package/admin/src/containers/HomePage/index.js +8 -5
- package/admin/src/containers/PluginTabs/index.js +12 -6
- package/admin/src/containers/Settings/Credentials.js +22 -20
- package/admin/src/index.js +4 -2
- package/package.json +10 -10
- package/server/__tests__/configuration-validation.test.js +22 -22
- package/server/__tests__/configuration.test.js +1 -1
- package/server/__tests__/content-types.test.js +5 -5
- package/server/__tests__/meilisearch.test.js +4 -4
- package/server/bootstrap.js +45 -0
- package/server/configuration-validation.js +18 -18
- package/server/constants.js +13 -0
- package/server/controllers/reload.js +1 -2
- package/server/policies/isAdmin.js +1 -1
- package/server/routes/index.js +37 -7
- package/server/services/content-types/content-types.js +3 -3
- package/server/services/lifecycle/lifecycle.js +5 -5
- package/server/services/meilisearch/config.js +6 -6
- package/server/services/meilisearch/connector.js +24 -27
- package/server/services/store/credential.js +4 -7
- package/admin/src/containers/Collection/utils/getTrad.js +0 -5
|
@@ -14,8 +14,11 @@ export function useAlert() {
|
|
|
14
14
|
message = 'Something occured in Meilisearch',
|
|
15
15
|
link,
|
|
16
16
|
blockTransition = true,
|
|
17
|
+
title,
|
|
17
18
|
}) => {
|
|
18
19
|
toggleNotification({
|
|
20
|
+
// optional
|
|
21
|
+
title,
|
|
19
22
|
// required
|
|
20
23
|
// type: 'info|success|warning',
|
|
21
24
|
type,
|
|
@@ -32,8 +35,22 @@ export function useAlert() {
|
|
|
32
35
|
onClose: () => localStorage.setItem('STRAPI_UPDATE_NOTIF', true),
|
|
33
36
|
})
|
|
34
37
|
}
|
|
38
|
+
|
|
39
|
+
const checkForbiddenError = ({ response }) => {
|
|
40
|
+
const status = response?.payload?.error?.status
|
|
41
|
+
if (status && status === 403) {
|
|
42
|
+
handleNotification({
|
|
43
|
+
title: 'Forbidden',
|
|
44
|
+
type: 'warning',
|
|
45
|
+
message: 'You do not have permission to do this action',
|
|
46
|
+
blockTransition: false,
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
return {
|
|
36
52
|
handleNotification,
|
|
53
|
+
checkForbiddenError,
|
|
37
54
|
}
|
|
38
55
|
}
|
|
39
56
|
|
|
@@ -16,7 +16,7 @@ export function useCollection() {
|
|
|
16
16
|
const [reloadNeeded, setReloadNeeded] = useState(false)
|
|
17
17
|
const [realTimeReports, setRealTimeReports] = useState(false)
|
|
18
18
|
|
|
19
|
-
const { handleNotification } = useAlert()
|
|
19
|
+
const { handleNotification, checkForbiddenError } = useAlert()
|
|
20
20
|
|
|
21
21
|
const refetchCollection = () =>
|
|
22
22
|
setRefetchIndex(prevRefetchIndex => !prevRefetchIndex)
|
|
@@ -41,7 +41,7 @@ export function useCollection() {
|
|
|
41
41
|
return collection
|
|
42
42
|
})
|
|
43
43
|
const reload = collections.find(
|
|
44
|
-
col => col.reloadNeeded === 'Reload needed'
|
|
44
|
+
col => col.reloadNeeded === 'Reload needed',
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
const isIndexing = collections.find(col => col.isIndexing === true)
|
|
@@ -57,71 +57,84 @@ export function useCollection() {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const deleteCollection = async ({ contentType }) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
try {
|
|
61
|
+
const { error } = await request(
|
|
62
|
+
`/${pluginId}/content-type/${contentType}`,
|
|
63
|
+
{
|
|
64
|
+
method: 'DELETE',
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
if (error) {
|
|
68
|
+
handleNotification({
|
|
69
|
+
type: 'warning',
|
|
70
|
+
message: error.message,
|
|
71
|
+
link: error.link,
|
|
72
|
+
})
|
|
73
|
+
} else {
|
|
74
|
+
refetchCollection()
|
|
75
|
+
handleNotification({
|
|
76
|
+
type: 'success',
|
|
77
|
+
message: 'Request to delete content-type is successful',
|
|
78
|
+
blockTransition: false,
|
|
79
|
+
})
|
|
64
80
|
}
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
handleNotification({
|
|
68
|
-
type: 'warning',
|
|
69
|
-
message: error.message,
|
|
70
|
-
link: error.link,
|
|
71
|
-
})
|
|
72
|
-
} else {
|
|
73
|
-
refetchCollection()
|
|
74
|
-
handleNotification({
|
|
75
|
-
type: 'success',
|
|
76
|
-
message: 'Request to delete content-type is successful',
|
|
77
|
-
blockTransition: false,
|
|
78
|
-
})
|
|
81
|
+
} catch (error) {
|
|
82
|
+
checkForbiddenError(error)
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
const addCollection = async ({ contentType }) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (error) {
|
|
90
|
-
handleNotification({
|
|
91
|
-
type: 'warning',
|
|
92
|
-
message: error.message,
|
|
93
|
-
link: error.link,
|
|
94
|
-
})
|
|
95
|
-
} else {
|
|
96
|
-
refetchCollection()
|
|
97
|
-
handleNotification({
|
|
98
|
-
type: 'success',
|
|
99
|
-
message: 'Request to add a content-type is successful',
|
|
100
|
-
blockTransition: false,
|
|
87
|
+
try {
|
|
88
|
+
const { error } = await request(`/${pluginId}/content-type`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
body: {
|
|
91
|
+
contentType,
|
|
92
|
+
},
|
|
101
93
|
})
|
|
94
|
+
if (error) {
|
|
95
|
+
handleNotification({
|
|
96
|
+
type: 'warning',
|
|
97
|
+
message: error.message,
|
|
98
|
+
link: error.link,
|
|
99
|
+
})
|
|
100
|
+
} else {
|
|
101
|
+
refetchCollection()
|
|
102
|
+
handleNotification({
|
|
103
|
+
type: 'success',
|
|
104
|
+
message: 'Request to add a content-type is successful',
|
|
105
|
+
blockTransition: false,
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
checkForbiddenError(error)
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
const updateCollection = async ({ contentType }) => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (error) {
|
|
113
|
-
handleNotification({
|
|
114
|
-
type: 'warning',
|
|
115
|
-
message: error.message,
|
|
116
|
-
link: error.link,
|
|
117
|
-
})
|
|
118
|
-
} else {
|
|
119
|
-
refetchCollection()
|
|
120
|
-
handleNotification({
|
|
121
|
-
type: 'success',
|
|
122
|
-
message: 'Request to update content-type is successful',
|
|
123
|
-
blockTransition: false,
|
|
114
|
+
try {
|
|
115
|
+
const { error } = await request(`/${pluginId}/content-type`, {
|
|
116
|
+
method: 'PUT',
|
|
117
|
+
body: {
|
|
118
|
+
contentType,
|
|
119
|
+
},
|
|
124
120
|
})
|
|
121
|
+
|
|
122
|
+
if (error) {
|
|
123
|
+
handleNotification({
|
|
124
|
+
type: 'warning',
|
|
125
|
+
message: error.message,
|
|
126
|
+
link: error.link,
|
|
127
|
+
})
|
|
128
|
+
} else {
|
|
129
|
+
refetchCollection()
|
|
130
|
+
handleNotification({
|
|
131
|
+
type: 'success',
|
|
132
|
+
message: 'Request to update content-type is successful',
|
|
133
|
+
blockTransition: false,
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
checkForbiddenError(error)
|
|
125
138
|
}
|
|
126
139
|
}
|
|
127
140
|
|
|
@@ -13,32 +13,36 @@ export function useCredential() {
|
|
|
13
13
|
const [refetchIndex, setRefetchIndex] = useState(true)
|
|
14
14
|
const [host, setHost] = useState('')
|
|
15
15
|
const [apiKey, setApiKey] = useState('')
|
|
16
|
-
const { handleNotification } = useAlert()
|
|
16
|
+
const { handleNotification, checkForbiddenError } = useAlert()
|
|
17
17
|
|
|
18
18
|
const refetchCredentials = () =>
|
|
19
19
|
setRefetchIndex(prevRefetchIndex => !prevRefetchIndex)
|
|
20
20
|
|
|
21
21
|
const updateCredentials = async () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (error) {
|
|
30
|
-
handleNotification({
|
|
31
|
-
type: 'warning',
|
|
32
|
-
message: error.message,
|
|
33
|
-
link: error.link,
|
|
34
|
-
})
|
|
35
|
-
} else {
|
|
36
|
-
refetchCredentials()
|
|
37
|
-
handleNotification({
|
|
38
|
-
type: 'success',
|
|
39
|
-
message: 'Credentials sucessfully updated!',
|
|
40
|
-
blockTransition: false,
|
|
22
|
+
try {
|
|
23
|
+
const { error } = await request(`/${pluginId}/credential`, {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
body: {
|
|
26
|
+
apiKey: apiKey,
|
|
27
|
+
host: host,
|
|
28
|
+
},
|
|
41
29
|
})
|
|
30
|
+
if (error) {
|
|
31
|
+
handleNotification({
|
|
32
|
+
type: 'warning',
|
|
33
|
+
message: error.message,
|
|
34
|
+
link: error.link,
|
|
35
|
+
})
|
|
36
|
+
} else {
|
|
37
|
+
refetchCredentials()
|
|
38
|
+
handleNotification({
|
|
39
|
+
type: 'success',
|
|
40
|
+
message: 'Credentials sucessfully updated!',
|
|
41
|
+
blockTransition: false,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
} catch (error) {
|
|
45
|
+
checkForbiddenError(error)
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Initializer
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import PropTypes from 'prop-types'
|
|
8
|
+
import { useEffect, useRef } from 'react'
|
|
9
|
+
|
|
10
|
+
import pluginId from '../../pluginId'
|
|
11
|
+
|
|
12
|
+
const Initializer = ({ setPlugin }) => {
|
|
13
|
+
const ref = useRef()
|
|
14
|
+
ref.current = setPlugin
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
ref.current(pluginId)
|
|
18
|
+
}, [])
|
|
19
|
+
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Initializer.propTypes = {
|
|
24
|
+
setPlugin: PropTypes.func.isRequired,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default Initializer
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const PERMISSIONS = {
|
|
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: 'plugin::meilisearch.read', subject: null },
|
|
8
|
+
{ action: 'plugin::meilisearch.collections.create', subject: null },
|
|
9
|
+
{ action: 'plugin::meilisearch.collections.update', subject: null },
|
|
10
|
+
{ action: 'plugin::meilisearch.collections.delete', subject: null },
|
|
11
|
+
{ action: 'plugin::meilisearch.settings.edit', subject: null },
|
|
12
|
+
],
|
|
13
|
+
collections: [
|
|
14
|
+
{ action: 'plugin::meilisearch.read', subject: null },
|
|
15
|
+
{ action: 'plugin::meilisearch.collections.create', subject: null },
|
|
16
|
+
{ action: 'plugin::meilisearch.collections.update', subject: null },
|
|
17
|
+
{ action: 'plugin::meilisearch.collections.delete', subject: null },
|
|
18
|
+
],
|
|
19
|
+
settings: [
|
|
20
|
+
{ action: 'plugin::meilisearch.read', subject: null },
|
|
21
|
+
{ action: 'plugin::meilisearch.settings.edit', subject: null },
|
|
22
|
+
],
|
|
23
|
+
read: [{ action: 'plugin::meilisearch.read', subject: null }],
|
|
24
|
+
create: [{ action: 'plugin::meilisearch.collections.create', subject: null }],
|
|
25
|
+
update: [{ action: 'plugin::meilisearch.collections.update', subject: null }],
|
|
26
|
+
delete: [{ action: 'plugin::meilisearch.collections.delete', subject: null }],
|
|
27
|
+
settingsEdit: [
|
|
28
|
+
{ action: 'plugin::meilisearch.settings.edit', subject: null },
|
|
29
|
+
],
|
|
30
|
+
createAndDelete: [
|
|
31
|
+
{ action: 'plugin::meilisearch.collections.create', subject: null },
|
|
32
|
+
{ action: 'plugin::meilisearch.collections.delete', subject: null },
|
|
33
|
+
],
|
|
34
|
+
}
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
Tr,
|
|
9
9
|
Typography,
|
|
10
10
|
} from '@strapi/design-system'
|
|
11
|
+
import { CheckPermissions } from '@strapi/helper-plugin'
|
|
12
|
+
import { PERMISSIONS } from '../../constants'
|
|
11
13
|
|
|
12
14
|
const CollectionColumn = ({
|
|
13
15
|
entry,
|
|
@@ -17,17 +19,19 @@ const CollectionColumn = ({
|
|
|
17
19
|
}) => {
|
|
18
20
|
return (
|
|
19
21
|
<Tr key={entry.contentType}>
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
<CheckPermissions permissions={PERMISSIONS.createAndDelete}>
|
|
23
|
+
<Td>
|
|
24
|
+
<BaseCheckbox
|
|
25
|
+
aria-label={`Select ${entry.collection}`}
|
|
26
|
+
onValueChange={() => {
|
|
27
|
+
if (entry.indexed)
|
|
28
|
+
deleteCollection({ contentType: entry.contentType })
|
|
29
|
+
else addCollection({ contentType: entry.contentType })
|
|
30
|
+
}}
|
|
31
|
+
value={entry.indexed}
|
|
32
|
+
/>
|
|
33
|
+
</Td>
|
|
34
|
+
</CheckPermissions>
|
|
31
35
|
{/* // Name */}
|
|
32
36
|
<Td>
|
|
33
37
|
<Typography textColor="neutral800">{entry.collection}</Typography>
|
|
@@ -58,21 +62,25 @@ const CollectionColumn = ({
|
|
|
58
62
|
<Td>
|
|
59
63
|
<Typography textColor="neutral800">{entry.reloadNeeded}</Typography>
|
|
60
64
|
</Td>
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
<CheckPermissions permissions={PERMISSIONS.update}>
|
|
66
|
+
<Td>
|
|
67
|
+
<Flex>
|
|
68
|
+
<Box paddingLeft={1}>
|
|
69
|
+
{entry.indexed && (
|
|
70
|
+
<Button
|
|
71
|
+
onClick={() =>
|
|
72
|
+
updateCollection({ contentType: entry.contentType })
|
|
73
|
+
}
|
|
74
|
+
size="S"
|
|
75
|
+
variant="secondary"
|
|
76
|
+
>
|
|
77
|
+
Update
|
|
78
|
+
</Button>
|
|
79
|
+
)}
|
|
80
|
+
</Box>
|
|
81
|
+
</Flex>
|
|
82
|
+
</Td>
|
|
83
|
+
</CheckPermissions>
|
|
76
84
|
</Tr>
|
|
77
85
|
)
|
|
78
86
|
}
|
|
@@ -15,10 +15,8 @@ const Collection = () => {
|
|
|
15
15
|
reloadNeeded,
|
|
16
16
|
refetchCollection,
|
|
17
17
|
} = useCollection()
|
|
18
|
-
const {
|
|
19
|
-
|
|
20
|
-
unlockAppWithAutoreload,
|
|
21
|
-
} = useAutoReloadOverlayBlocker()
|
|
18
|
+
const { lockAppWithAutoreload, unlockAppWithAutoreload } =
|
|
19
|
+
useAutoReloadOverlayBlocker()
|
|
22
20
|
const [reload, setReload] = useState(false)
|
|
23
21
|
|
|
24
22
|
const ROW_COUNT = 6
|
|
@@ -35,7 +33,7 @@ const Collection = () => {
|
|
|
35
33
|
{
|
|
36
34
|
method: 'GET',
|
|
37
35
|
},
|
|
38
|
-
true
|
|
36
|
+
true,
|
|
39
37
|
)
|
|
40
38
|
setReload(false)
|
|
41
39
|
} catch (err) {
|
|
@@ -6,14 +6,18 @@ import {
|
|
|
6
6
|
Typography,
|
|
7
7
|
VisuallyHidden,
|
|
8
8
|
} from '@strapi/design-system'
|
|
9
|
+
import { CheckPermissions } from '@strapi/helper-plugin'
|
|
10
|
+
import { PERMISSIONS } from '../../constants'
|
|
9
11
|
|
|
10
12
|
const CollectionTableHeader = () => {
|
|
11
13
|
return (
|
|
12
14
|
<Thead>
|
|
13
15
|
<Tr>
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
16
|
+
<CheckPermissions permissions={PERMISSIONS.createAndDelete}>
|
|
17
|
+
<Th>
|
|
18
|
+
<VisuallyHidden>INDEX</VisuallyHidden>
|
|
19
|
+
</Th>
|
|
20
|
+
</CheckPermissions>
|
|
17
21
|
<Th>
|
|
18
22
|
<Typography variant="sigma">NAME</Typography>
|
|
19
23
|
</Th>
|
|
@@ -32,9 +36,11 @@ const CollectionTableHeader = () => {
|
|
|
32
36
|
<Th>
|
|
33
37
|
<Typography variant="sigma">HOOKS</Typography>
|
|
34
38
|
</Th>
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
|
|
39
|
+
<CheckPermissions permissions={PERMISSIONS.update}>
|
|
40
|
+
<Th>
|
|
41
|
+
<VisuallyHidden>Actions</VisuallyHidden>
|
|
42
|
+
</Th>
|
|
43
|
+
</CheckPermissions>
|
|
38
44
|
</Tr>
|
|
39
45
|
</Thead>
|
|
40
46
|
)
|
|
@@ -3,17 +3,20 @@
|
|
|
3
3
|
* HomePage
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
import { CheckPagePermissions } from '@strapi/helper-plugin'
|
|
7
7
|
import React, { memo } from 'react'
|
|
8
8
|
import PluginTabs from '../PluginTabs'
|
|
9
9
|
import PluginHeader from '../PluginHeader'
|
|
10
|
+
import { PERMISSIONS } from '../../constants'
|
|
10
11
|
|
|
11
12
|
const HomePage = () => {
|
|
12
13
|
return (
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
<CheckPagePermissions permissions={PERMISSIONS.main}>
|
|
15
|
+
<div>
|
|
16
|
+
<PluginHeader />
|
|
17
|
+
<PluginTabs />
|
|
18
|
+
</div>
|
|
19
|
+
</CheckPagePermissions>
|
|
17
20
|
)
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
} from '@strapi/design-system'
|
|
10
10
|
import { CollectionTable } from '../Collection'
|
|
11
11
|
import { Settings } from '../Settings'
|
|
12
|
+
import { CheckPermissions } from '@strapi/helper-plugin'
|
|
13
|
+
import { PERMISSIONS } from '../../constants'
|
|
12
14
|
|
|
13
15
|
const PluginTabs = () => {
|
|
14
16
|
return (
|
|
@@ -20,14 +22,18 @@ const PluginTabs = () => {
|
|
|
20
22
|
</Tabs>
|
|
21
23
|
<TabPanels>
|
|
22
24
|
<TabPanel>
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
25
|
+
<CheckPermissions permissions={PERMISSIONS.collections}>
|
|
26
|
+
<Box color="neutral800" padding={4} background="neutral0">
|
|
27
|
+
<CollectionTable />
|
|
28
|
+
</Box>
|
|
29
|
+
</CheckPermissions>
|
|
26
30
|
</TabPanel>
|
|
27
31
|
<TabPanel>
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
32
|
+
<CheckPermissions permissions={PERMISSIONS.settings}>
|
|
33
|
+
<Box color="neutral800" padding={4} background="neutral0">
|
|
34
|
+
<Settings />
|
|
35
|
+
</Box>
|
|
36
|
+
</CheckPermissions>
|
|
31
37
|
</TabPanel>
|
|
32
38
|
</TabPanels>
|
|
33
39
|
</TabGroup>
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import React, { memo } from 'react'
|
|
2
2
|
import { Box, Button, TextInput, Typography } from '@strapi/design-system'
|
|
3
3
|
import { useCredential } from '../../Hooks/useCredential'
|
|
4
|
+
import { CheckPermissions } from '@strapi/helper-plugin'
|
|
5
|
+
import { PERMISSIONS } from '../../constants'
|
|
4
6
|
|
|
5
7
|
const Credentials = () => {
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
apiKey,
|
|
9
|
-
credentials,
|
|
10
|
-
setHost,
|
|
11
|
-
setApiKey,
|
|
12
|
-
updateCredentials,
|
|
13
|
-
} = useCredential()
|
|
14
|
-
|
|
8
|
+
const { host, apiKey, credentials, setHost, setApiKey, updateCredentials } =
|
|
9
|
+
useCredential()
|
|
15
10
|
return (
|
|
16
11
|
<Box>
|
|
17
12
|
<Box padding={2}>
|
|
@@ -42,23 +37,30 @@ const Credentials = () => {
|
|
|
42
37
|
<Typography variant="pi" style={{ color: 'red' }}>
|
|
43
38
|
Do not use this API key on your front-end as it has too much rights.
|
|
44
39
|
Instead, use the public key available using{' '}
|
|
45
|
-
<a
|
|
40
|
+
<a
|
|
41
|
+
href="https://www.meilisearch.com/docs/reference/api/keys#get-keys"
|
|
42
|
+
target="_blank"
|
|
43
|
+
rel="noreferrer"
|
|
44
|
+
>
|
|
46
45
|
the key route
|
|
47
46
|
</a>
|
|
48
47
|
.
|
|
49
48
|
</Typography>
|
|
50
49
|
</Box>
|
|
50
|
+
|
|
51
51
|
<Box paddingTop={2} paddingLeft={2} paddingRight={2} paddingBottom={2}>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
<CheckPermissions permissions={PERMISSIONS.settingsEdit}>
|
|
53
|
+
<Button
|
|
54
|
+
variant="secondary"
|
|
55
|
+
onClick={() => updateCredentials()}
|
|
56
|
+
disabled={
|
|
57
|
+
credentials.ApiKeyIsFromConfigFile &&
|
|
58
|
+
credentials.HostIsFromConfigFile
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
Save
|
|
62
|
+
</Button>
|
|
63
|
+
</CheckPermissions>
|
|
62
64
|
</Box>
|
|
63
65
|
</Box>
|
|
64
66
|
)
|
package/admin/src/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import pluginPkg from '../../package.json'
|
|
2
2
|
import pluginId from './pluginId'
|
|
3
3
|
import PluginIcon from './components/PluginIcon'
|
|
4
|
+
import Initializer from './components/Initializer'
|
|
5
|
+
import { PERMISSIONS } from './constants'
|
|
4
6
|
|
|
5
7
|
const name = pluginPkg.strapi.name
|
|
6
8
|
|
|
@@ -8,9 +10,9 @@ export default {
|
|
|
8
10
|
register(app) {
|
|
9
11
|
app.registerPlugin({
|
|
10
12
|
id: pluginId,
|
|
13
|
+
initializer: Initializer,
|
|
11
14
|
isReady: true,
|
|
12
15
|
name,
|
|
13
|
-
description: 'TEST',
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
app.addMenuLink({
|
|
@@ -27,7 +29,7 @@ export default {
|
|
|
27
29
|
|
|
28
30
|
return component
|
|
29
31
|
},
|
|
30
|
-
permissions:
|
|
32
|
+
permissions: PERMISSIONS.main,
|
|
31
33
|
})
|
|
32
34
|
},
|
|
33
35
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-meilisearch",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Synchronise and search in your Strapi content-types with Meilisearch",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"playground:dev": "yarn --cwd ./playground && yarn --cwd ./playground dev",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@strapi/utils": "^4.
|
|
28
|
+
"@strapi/utils": "^4.21.1",
|
|
29
29
|
"@strapi/icons": "^1.12.2",
|
|
30
30
|
"@strapi/design-system": "^1.13.2",
|
|
31
|
-
"meilisearch": "^0.
|
|
31
|
+
"meilisearch": "^0.38.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@strapi/strapi": "^4.0.0"
|
|
@@ -61,18 +61,18 @@
|
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://github.com/meilisearch/strapi-plugin-meilisearch#readme",
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@types/jest": "^
|
|
65
|
-
"concurrently": "^
|
|
64
|
+
"@types/jest": "^29.5.12",
|
|
65
|
+
"concurrently": "^8.2.2",
|
|
66
66
|
"cypress": "^7.3.0",
|
|
67
67
|
"eslint": "^8.2.0",
|
|
68
|
-
"eslint-config-prettier": "^
|
|
68
|
+
"eslint-config-prettier": "^9.1.0",
|
|
69
69
|
"eslint-plugin-cypress": "^2.12.1",
|
|
70
70
|
"eslint-plugin-import": "^2.25.3",
|
|
71
71
|
"eslint-plugin-node": "^11.1.0",
|
|
72
|
-
"eslint-plugin-prettier": "^
|
|
73
|
-
"eslint-plugin-promise": "^
|
|
72
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
73
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
74
74
|
"eslint-plugin-react": "^7.27.0",
|
|
75
|
-
"jest": "^
|
|
76
|
-
"prettier": "
|
|
75
|
+
"jest": "^29.7.0",
|
|
76
|
+
"prettier": "3.2.5"
|
|
77
77
|
}
|
|
78
78
|
}
|