Files
payloadcms/packages/ui/src/fields/Relationship/select-components/MultiValueLabel/index.tsx
Paul 26ffbca914 feat: sanitise access endpoint (#7335)
Protects the `/api/access` endpoint behind authentication and sanitizes
the result, making it more secure and significantly smaller. To do this:

1. The `permission` keyword is completely omitted from the result
2. Only _truthy_ access results are returned
3. All nested permissions are consolidated when possible

---------

Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Co-authored-by: James <james@trbl.design>
2024-11-15 15:08:06 -05:00

81 lines
2.7 KiB
TypeScript

'use client'
import type { MultiValueProps } from 'react-select'
import React, { Fragment, useState } from 'react'
import { components } from 'react-select'
import type { ReactSelectAdapterProps } from '../../../../elements/ReactSelect/types.js'
import type { Option } from '../../types.js'
import { Tooltip } from '../../../../elements/Tooltip/index.js'
import { EditIcon } from '../../../../icons/Edit/index.js'
import { useAuth } from '../../../../providers/Auth/index.js'
import { useTranslation } from '../../../../providers/Translation/index.js'
import './index.scss'
const baseClass = 'relationship--multi-value-label'
export const MultiValueLabel: React.FC<
{
selectProps: {
// TODO Fix this - moduleResolution 16 breaks our declare module
customProps: ReactSelectAdapterProps['customProps']
}
} & MultiValueProps<Option>
> = (props) => {
const {
data: { allowEdit, label, relationTo, value },
selectProps: { customProps: { draggableProps, onDocumentDrawerOpen } = {} } = {},
} = props
const { permissions } = useAuth()
const [showTooltip, setShowTooltip] = useState(false)
const { t } = useTranslation()
const hasReadPermission = Boolean(permissions?.collections?.[relationTo]?.read)
return (
<div className={baseClass}>
<div className={`${baseClass}__content`}>
<components.MultiValueLabel
{...props}
innerProps={{
className: `${baseClass}__text`,
...(draggableProps || {}),
}}
/>
</div>
{relationTo && hasReadPermission && allowEdit !== false && (
<Fragment>
<button
aria-label={`Edit ${label}`}
className={`${baseClass}__drawer-toggler`}
onClick={() => {
setShowTooltip(false)
onDocumentDrawerOpen({
id: value,
collectionSlug: relationTo,
hasReadPermission,
})
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.stopPropagation()
}
}}
onMouseDown={(e) => e.stopPropagation()} // prevents react-select dropdown from opening
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
onTouchEnd={(e) => e.stopPropagation()} // prevents react-select dropdown from opening
type="button"
>
<Tooltip className={`${baseClass}__tooltip`} show={showTooltip}>
{t('general:editLabel', { label: '' })}
</Tooltip>
<EditIcon className={`${baseClass}__icon`} />
</button>
</Fragment>
)}
</div>
)
}