diff --git a/admin/src/components/PermalinkInput/AncestorsPath.js b/admin/src/components/PermalinkInput/AncestorsPath.js index f692af5..bac929a 100644 --- a/admin/src/components/PermalinkInput/AncestorsPath.js +++ b/admin/src/components/PermalinkInput/AncestorsPath.js @@ -1,24 +1,42 @@ -import React, { Fragment } from 'react'; +import React, { Fragment, useState } from 'react'; import PropTypes from 'prop-types'; -import { Delimiter, PathLabel } from './styled'; +import { More } from '@strapi/icons'; +import { Delimiter, ExpandButton, HideButton, PathLabel } from './styled'; const AncestorsPath = ({ hasError, path }) => { - return ( - - {path.split('/').map((part, i) => ( - - {part} - / - - ))} - - ); + const [expanded, setExpanded] = useState(false); + + if (expanded) { + return ( + setExpanded(false)} label="Show ancestor path"> + + {path.split(/(?:\/|~)+/).map((part, i) => ( + + {part} + / + + ))} + + + ); + } else { + return ( + setExpanded(true)} + > + + + ); + } }; AncestorsPath.defaultProps = { diff --git a/admin/src/components/PermalinkInput/index.js b/admin/src/components/PermalinkInput/index.js index dc4a6a3..bf0bc25 100644 --- a/admin/src/components/PermalinkInput/index.js +++ b/admin/src/components/PermalinkInput/index.js @@ -24,7 +24,13 @@ import { } from '../../utils'; import AncestorsPath from './AncestorsPath'; -import { EndActionWrapper, FieldActionWrapper, LoadingWrapper, TextValidation } from './styled'; +import { + EndActionWrapper, + FieldActionWrapper, + LoadingWrapper, + RelativeInputWrapper, + TextValidation, +} from './styled'; /** * @TODO - Refactor this component to NOT rely on disabling the eslint rule for @@ -67,6 +73,7 @@ const PermalinkInput = forwardRef((props, ref) => { !isCreatingEntry && !hasDifferentRelationUID && targetRelationValue?.id === modifiedData.id; const initialValue = initialData[name]; + const locale = initialData.locale; const initialRelationValue = getRelationValue(initialData, targetFieldConfig.targetRelation); const initialAncestorsPath = getPermalinkAncestors(initialValue); const initialSlug = getPermalinkSlug(initialValue); @@ -140,10 +147,14 @@ const PermalinkInput = forwardRef((props, ref) => { if (!newSlug) { setIsLoading(false); + return; } - const params = `${contentTypeUID}/${encodeURIComponent(newSlug)}`; + const params = `${contentTypeUID}/${encodeURIComponent(newSlug)}${ + locale ? `/${locale}` : '' + }`; + const endpoint = getApiUrl(`${pluginId}/check-availability/${params}`); const { data } = await fetchClient.get(endpoint); @@ -220,6 +231,7 @@ const PermalinkInput = forwardRef((props, ref) => { if (!targetRelationValue) { removeAncestorsPath(); setIsLoading(false); + return; } @@ -322,6 +334,7 @@ const PermalinkInput = forwardRef((props, ref) => { setIsOrphan(false); setAncestorsPath(null); setFieldError(null); + return; } @@ -451,24 +464,6 @@ const PermalinkInput = forwardRef((props, ref) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [isCreatingEntry, isCustomized, debouncedTargetValue]); - /* - This use effect clashes with the check connection use effect, - effectively overwriting the ancestors path when changing locales. - I am leaving this here for now as I dont know what other potential - side effects this has, but it is not needed for the ancestors path - to be correctly set. - */ - - // useEffect(() => { - // // This is required for scenarios like switching between locales to ensure - // // the field value updates with the locale change. - // const newAncestorsPath = getPermalinkAncestors(initialValue); - // const newSlug = getPermalinkSlug(initialValue); - - // setFieldState(newAncestorsPath, newSlug, true); - // // eslint-disable-next-line react-hooks/exhaustive-deps - // }, [initialData.id]); - useEffect(() => { // Remove ancestors path if we have selected the current entity as the parent. if (selectedSelfRelation) { @@ -503,71 +498,73 @@ const PermalinkInput = forwardRef((props, ref) => { }, [initialRelationValue, targetRelationValue]); return ( - - ) : null - } - endAction={ - - {!regenerateLabel && availability && availability?.isAvailable && ( - - - - {formatMessage({ - id: 'content-manager.components.uid.available', - defaultMessage: 'Available', - })} - - - )} - {!regenerateLabel && availability && !availability?.isAvailable && ( - - - - {formatMessage({ - id: 'content-manager.components.uid.unavailable', - defaultMessage: 'Unavailable', - })} - - - )} - {regenerateLabel && ( - - - {regenerateLabel} - - - )} - - {isLoading ? ( - - - - ) : ( - + + + ) : null + } + endAction={ + + {!regenerateLabel && availability && availability?.isAvailable && ( + + + + {formatMessage({ + id: 'content-manager.components.uid.available', + defaultMessage: 'Available', + })} + + )} - - - } - /> + {!regenerateLabel && availability && !availability?.isAvailable && ( + + + + {formatMessage({ + id: 'content-manager.components.uid.unavailable', + defaultMessage: 'Unavailable', + })} + + + )} + {regenerateLabel && ( + + + {regenerateLabel} + + + )} + + {isLoading ? ( + + + + ) : ( + + )} + + + } + /> + ); }); diff --git a/admin/src/components/PermalinkInput/styled.js b/admin/src/components/PermalinkInput/styled.js index 92097a0..85901d2 100644 --- a/admin/src/components/PermalinkInput/styled.js +++ b/admin/src/components/PermalinkInput/styled.js @@ -2,6 +2,7 @@ import styled, { keyframes } from 'styled-components'; import { Box } from '@strapi/design-system/Box'; import { FieldAction } from '@strapi/design-system/Field'; import { Flex } from '@strapi/design-system/Flex'; +import { Button, IconButton } from '@strapi/design-system'; const rotation = keyframes` from { @@ -16,14 +17,34 @@ export const LoadingWrapper = styled(Flex)` animation: ${rotation} 2s infinite linear; `; +export const ExpandButton = styled(IconButton)` + height: 1rem; + width: 1.5rem; + border: none; + background: ${({ theme, hasError }) => theme.colors[hasError ? 'danger100' : 'primary100']}; + color: ${({ theme, hasError }) => theme.colors[hasError ? 'danger700' : 'primary700']}; +`; + +export const HideButton = styled(Button)` + padding: 0; + height: fit-content; + background-color: transparent; + color: transparent; + border: none; + + :hover { + border: none; + } +`; + export const PathLabel = styled.span` margin-right: -4px; padding: 1px 4px 2px 4px; background: ${({ theme, hasError }) => theme.colors[hasError ? 'danger100' : 'primary100']}; border-radius: ${({ theme }) => theme.borderRadius}; color: ${({ theme, hasError }) => theme.colors[hasError ? 'danger700' : 'primary700']}; - font-weight: ${({ theme }) => theme.fontWeights.normal}; font-size: ${({ theme }) => theme.fontSizes[2]}; + font-weight: ${({ theme }) => theme.fontWeights.regular}; line-height: normal; white-space: nowrap; display: inline-flex; @@ -40,10 +61,14 @@ export const Delimiter = styled.span` } `; -export const EndActionWrapper = styled(Box)` +export const RelativeInputWrapper = styled.div` + display: flex; + flex-direction: column; position: relative; `; +export const EndActionWrapper = styled(Box)``; + export const FieldActionWrapper = styled(FieldAction)` svg { height: 1rem; @@ -62,7 +87,8 @@ export const FieldActionWrapper = styled(FieldAction)` export const TextValidation = styled(Flex)` position: absolute; - right: ${({ theme }) => theme.spaces[6]}; + right: 0; + top: 0; width: 100px; pointer-events: none; diff --git a/admin/src/utils/get-permalink-ancestors.js b/admin/src/utils/get-permalink-ancestors.js index 7dd345a..ad5c54a 100644 --- a/admin/src/utils/get-permalink-ancestors.js +++ b/admin/src/utils/get-permalink-ancestors.js @@ -3,7 +3,7 @@ const getPermalinkAncestors = (path) => { return null; } - const parts = path.split('/').filter((i) => i); + const parts = path.split(/(?:\/|~)+/).filter((i) => i); const len = parts.length - 1; if (!len) {