diff --git a/packages/strapi-admin/admin/src/containers/Users/ProtectedEditPage/index.js b/packages/strapi-admin/admin/src/containers/Users/ProtectedEditPage/index.js index 942e812527..1499074aff 100644 --- a/packages/strapi-admin/admin/src/containers/Users/ProtectedEditPage/index.js +++ b/packages/strapi-admin/admin/src/containers/Users/ProtectedEditPage/index.js @@ -1,6 +1,7 @@ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { useUserPermissions, LoadingIndicatorPage } from 'strapi-helper-plugin'; -import { Redirect } from 'react-router-dom'; +import { Redirect, useLocation } from 'react-router-dom'; +import { get } from 'lodash'; import adminPermissions from '../../../permissions'; import EditPage from '../EditPage'; @@ -16,13 +17,23 @@ const ProtectedEditPage = () => { isLoading, allowedActions: { canRead, canUpdate }, } = useUserPermissions(permissions); + const { state } = useLocation(); + const from = get(state, 'from', '/'); + + useEffect(() => { + if (!isLoading) { + if (!canRead && !canUpdate) { + strapi.notification.info('notification.permission.not-allowed-read'); + } + } + }, [isLoading, canRead, canUpdate]); if (isLoading) { return ; } if (!canRead && !canUpdate) { - return ; + return ; } return ; diff --git a/packages/strapi-admin/admin/src/translations/en.json b/packages/strapi-admin/admin/src/translations/en.json index b13202d80a..4356fbdb86 100644 --- a/packages/strapi-admin/admin/src/translations/en.json +++ b/packages/strapi-admin/admin/src/translations/en.json @@ -329,6 +329,7 @@ "notification.form.error.fields": "The form contains some errors", "notification.form.success.fields": "Changes saved", "notification.link-copied": "Link copied into the clipboard", + "notification.permission.not-allowed-read": "You are not allowed to see this document", "notification.success.delete": "The item has been deleted", "notification.success.saved": "Saved", "request.error.model.unknown": "This model doesn't exist" diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/ListItem.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/ListItem.js index 883d2d234f..79db535ae8 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/ListItem.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/ListItem.js @@ -1,8 +1,10 @@ -import React, { memo, useEffect } from 'react'; +import React, { memo, useEffect, useMemo } from 'react'; import PropTypes from 'prop-types'; import { useDrag, useDrop } from 'react-dnd'; import { getEmptyImage } from 'react-dnd-html5-backend'; import { has } from 'lodash'; +import { useGlobalContext } from 'strapi-helper-plugin'; +import pluralize from 'pluralize'; import pluginId from '../../pluginId'; import ItemTypes from '../../utils/ItemTypes'; @@ -18,7 +20,19 @@ function ListItem({ onRemove, targetModel, }) { - const to = `/plugins/${pluginId}/collectionType/${targetModel}/${data.id}`; + const { settingsBaseURL } = useGlobalContext(); + const to = useMemo(() => { + const isSettingsModel = targetModel.includes('strapi::'); + + if (isSettingsModel) { + const model = pluralize(targetModel.replace('strapi::', '')); + + return `${settingsBaseURL}/${model}/${data.id}`; + } + + return `/plugins/${pluginId}/collectionType/${targetModel}/${data.id}`; + }, [targetModel, data.id, settingsBaseURL]); + const hasDraftAndPublish = has(data, 'published_at'); const originalIndex = findRelation(data.id).index; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/Option.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/Option.js index 1d660d93c4..e42086d309 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/Option.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/Option.js @@ -46,7 +46,9 @@ const Option = props => { return ( - {props.label} + + {props.label} + ); }; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/index.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/index.js index 228c3f5723..57788f75cb 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectWrapper/index.js @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ import React, { useState, useEffect, useMemo, useRef, memo } from 'react'; import PropTypes from 'prop-types'; +import pluralize from 'pluralize'; import { FormattedMessage } from 'react-intl'; import { Link, useLocation } from 'react-router-dom'; import { cloneDeep, findIndex, get, isArray, isEmpty, set } from 'lodash'; -import { request } from 'strapi-helper-plugin'; +import { request, useGlobalContext } from 'strapi-helper-plugin'; import { Flex, Text, Padded } from '@buffetjs/core'; import pluginId from '../../pluginId'; import useDataManager from '../../hooks/useDataManager'; @@ -35,9 +35,12 @@ function SelectWrapper({ targetModel, placeholder, }) { + const { settingsBaseURL } = useGlobalContext(); + // Disable the input in case of a polymorphic relation const isMorph = relationType.toLowerCase().includes('morph'); const { addRelation, modifiedData, moveRelation, onChange, onRemoveRelation } = useDataManager(); + const { isDraggingComponent } = useEditView(); // This is needed for making requests when used in a component @@ -149,6 +152,7 @@ function SelectWrapper({ return () => { abortController.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state._contains, isFieldAllowed]); useEffect(() => { @@ -159,6 +163,7 @@ function SelectWrapper({ return () => { abortController.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state._start]); const onInputChange = (inputValue, { action }) => { @@ -183,7 +188,18 @@ function SelectWrapper({ relationType ); - const to = `/plugins/${pluginId}/collectionType/${targetModel}/${value ? value.id : null}`; + const to = useMemo(() => { + const isSettingsModel = targetModel.includes('strapi::'); + + if (isSettingsModel) { + const model = pluralize(targetModel.replace('strapi::', '')); + + return `${settingsBaseURL}/${model}/${value ? value.id : null}`; + } + + return `/plugins/${pluginId}/collectionType/${targetModel}/${value ? value.id : null}`; + }, [targetModel, value, settingsBaseURL]); + const link = value === null || value === undefined || @@ -209,7 +225,7 @@ function SelectWrapper({ } return !editable; - }, [isMorph, isCreatingEntry, editable]); + }, [isMorph, isCreatingEntry, editable, isFieldAllowed, isFieldReadable]); if (!isFieldAllowed && isCreatingEntry) { return ;