chore: change pw buttons, field readOnly prop, admin panel thumbnailURL fallback (#5694)

This commit is contained in:
Jarrod Flesch
2024-04-05 13:51:17 -04:00
committed by GitHub
parent ca2acee38a
commit 17352c9a56
24 changed files with 139 additions and 122 deletions

View File

@@ -106,43 +106,42 @@ export const Auth: React.FC<Props> = (props) => {
required
/>
<ConfirmPassword disabled={readOnly} />
{!requirePassword && (
<Button
buttonStyle="secondary"
disabled={readOnly}
onClick={() => handleChangePassword(false)}
size="small"
>
{t('general:cancel')}
</Button>
)}
</div>
)}
{((!changingPassword && !requirePassword) || operation === 'update') && (
<div className={`${baseClass}__controls`}>
{!changingPassword && !requirePassword && (
<Button
buttonStyle="secondary"
disabled={readOnly}
id="change-password"
onClick={() => handleChangePassword(true)}
size="small"
>
{t('authentication:changePassword')}
</Button>
)}
{operation === 'update' && (
<Button
buttonStyle="secondary"
disabled={readOnly}
onClick={() => unlock()}
size="small"
>
{t('authentication:forceUnlock')}
</Button>
)}
</div>
)}
<div className={`${baseClass}__controls`}>
{changingPassword && !requirePassword && (
<Button
buttonStyle="secondary"
disabled={readOnly}
onClick={() => handleChangePassword(false)}
size="small"
>
{t('general:cancel')}
</Button>
)}
{!changingPassword && !requirePassword && (
<Button
buttonStyle="secondary"
disabled={readOnly}
id="change-password"
onClick={() => handleChangePassword(true)}
size="small"
>
{t('authentication:changePassword')}
</Button>
)}
{operation === 'update' && (
<Button
buttonStyle="secondary"
disabled={readOnly}
onClick={() => unlock()}
size="small"
>
{t('authentication:forceUnlock')}
</Button>
)}
</div>
</React.Fragment>
)}
{useAPIKey && (

View File

@@ -26,36 +26,6 @@ const generateURL = ({ collectionSlug, config, filename }: GenerateURLArgs) => {
return undefined
}
type Args = {
collectionConfig?: CollectionConfig
config: Config
doc: Record<string, unknown>
}
const generateAdminThumbnails = ({ collectionConfig, config, doc }: Args) => {
const adminThumbnail =
typeof collectionConfig.upload !== 'boolean'
? collectionConfig.upload?.adminThumbnail
: undefined
if (typeof adminThumbnail === 'function') {
return adminThumbnail({ doc })
}
if ('sizes' in doc && doc.sizes?.[adminThumbnail]?.filename) {
return generateURL({
collectionSlug: collectionConfig.slug,
config,
filename: doc.sizes?.[adminThumbnail].filename as string,
})
}
return generateURL({
collectionSlug: collectionConfig.slug,
config,
filename: doc.filename as string,
})
}
type Options = {
collection: CollectionConfig
config: Config
@@ -74,16 +44,6 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
label: 'MIME Type',
}
const url: Field = {
name: 'url',
type: 'text',
admin: {
hidden: true,
readOnly: true,
},
label: 'URL',
}
const thumbnailURL: Field = {
name: 'thumbnailURL',
type: 'text',
@@ -93,12 +53,28 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
},
hooks: {
afterRead: [
({ data }) =>
generateAdminThumbnails({
collectionConfig: collection,
config,
doc: data,
}),
({ originalDoc }) => {
const adminThumbnail =
typeof collection.upload !== 'boolean' ? collection.upload?.adminThumbnail : undefined
if (typeof adminThumbnail === 'function') {
return adminThumbnail({ doc: originalDoc })
}
if (
typeof adminThumbnail === 'string' &&
'sizes' in originalDoc &&
originalDoc.sizes?.[adminThumbnail]?.filename
) {
return generateURL({
collectionSlug: collection.slug,
config,
filename: originalDoc.sizes?.[adminThumbnail].filename as string,
})
}
return null
},
],
},
label: 'Thumbnail URL',
@@ -147,6 +123,16 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
unique: true,
}
const url: Field = {
name: 'url',
type: 'text',
admin: {
hidden: true,
readOnly: true,
},
label: 'URL',
}
let uploadFields: Field[] = [
{
...url,

View File

@@ -75,7 +75,7 @@ const Component: React.FC<ElementProps> = (props) => {
{ initialParams },
)
const thumbnailSRC = data?.thumbnailURL
const thumbnailSRC = data?.thumbnailURL || data?.url
const removeUpload = useCallback(() => {
editor.update(() => {

View File

@@ -80,7 +80,7 @@ const UploadElement: React.FC<Props & { enabledCollectionSlugs?: string[] }> = (
{ initialParams },
)
const thumbnailSRC = data?.thumbnailURL
const thumbnailSRC = data?.thumbnailURL || data?.url
const removeUpload = useCallback(() => {
const elementPath = ReactEditor.findPath(editor, element)

View File

@@ -35,7 +35,7 @@ export const FileDetails: React.FC<FileDetailsProps> = (props) => {
<Thumbnail
collectionSlug={collectionSlug}
doc={doc}
fileSrc={thumbnailURL}
fileSrc={thumbnailURL || url}
imageCacheTag={imageCacheTag}
uploadConfig={uploadConfig}
/>

View File

@@ -26,7 +26,7 @@ export const FileCell: React.FC<FileCellProps> = ({
...rowData,
filename,
}}
fileSrc={rowData?.thumbnailURL}
fileSrc={rowData?.thumbnailURL || rowData?.url}
size="small"
uploadConfig={uploadConfig}
/>

View File

@@ -65,12 +65,13 @@ export const _ArrayField: React.FC<ArrayFieldProps> = (props) => {
minRows,
path: pathFromProps,
permissions,
readOnly,
readOnly: readOnlyFromProps,
required,
validate,
} = props
const { indexPath } = useFieldProps()
const { indexPath, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { setDocFieldPreferences } = useDocumentInfo()
const { addFieldRow, dispatchFields, setModified } = useForm()

View File

@@ -69,12 +69,13 @@ const _BlocksField: React.FC<BlocksFieldProps> = (props) => {
maxRows,
minRows,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
validate,
} = props
const { indexPath } = useFieldProps()
const { indexPath, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { setDocFieldPreferences } = useDocumentInfo()
const { addFieldRow, dispatchFields, setModified } = useForm()

View File

@@ -39,7 +39,7 @@ const CheckboxField: React.FC<CheckboxFieldProps> = (props) => {
onChange: onChangeFromProps,
partialChecked,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -57,7 +57,8 @@ const CheckboxField: React.FC<CheckboxFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, setValue, showError, value } = useField({
disableFormData,

View File

@@ -48,7 +48,7 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
labelProps,
language = 'javascript',
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -64,7 +64,8 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, setValue, showError, value } = useField({
path: pathFromContext || pathFromProps || name,

View File

@@ -43,12 +43,13 @@ const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
initCollapsed = false,
labelProps,
path: pathFromProps,
readOnly: readOnlyFromProps,
} = props
const {
indexPath,
path: pathFromContext,
readOnly,
readOnly: readOnlyFromContext,
schemaPath,
siblingPermissions,
} = useFieldProps()
@@ -110,6 +111,8 @@ const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
if (typeof collapsedOnMount !== 'boolean') return null
const readOnly = readOnlyFromProps || readOnlyFromContext
return (
<Fragment>
<WatchChildErrors fieldMap={fieldMap} path={path} setErrorCount={setErrorCount} />

View File

@@ -49,7 +49,7 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
labelProps,
path: pathFromProps,
placeholder,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -67,13 +67,15 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const { path, setValue, showError, value } = useField<Date>({
path: pathFromContext || pathFromProps || name,
validate: memoizedValidate,
})
const readOnly = readOnlyFromProps || readOnlyFromContext
return (
<div
className={[

View File

@@ -42,7 +42,7 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
labelProps,
path: pathFromProps,
placeholder,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -60,7 +60,8 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, setValue, showError, value } = useField({
path: pathFromContext || pathFromProps || name,
@@ -88,7 +89,7 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
{BeforeInput}
<input
autoComplete={autoComplete}
disabled={Boolean(readOnly)}
disabled={readOnly}
id={`field-${path.replace(/\./g, '__')}`}
name={path}
onChange={setValue}

View File

@@ -44,11 +44,12 @@ const GroupField: React.FC<GroupFieldProps> = (props) => {
fieldMap,
hideGutter,
labelProps,
readOnly: readOnlyFromProps,
style,
width,
} = props
const { path, permissions, readOnly, schemaPath } = useFieldProps()
const { path, permissions, readOnly: readOnlyFromContext, schemaPath } = useFieldProps()
const { i18n } = useTranslation()
const isWithinCollapsible = useCollapsible()
const isWithinGroup = useGroup()
@@ -58,6 +59,7 @@ const GroupField: React.FC<GroupFieldProps> = (props) => {
const submitted = useFormSubmitted()
const errorCount = errorPaths.length
const fieldHasErrors = submitted && errorCount > 0
const readOnly = readOnlyFromProps || readOnlyFromContext
const isTopLevel = !(isWithinCollapsible || isWithinGroup || isWithinRow)

View File

@@ -43,7 +43,7 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
label,
labelProps,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -62,7 +62,8 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
[validate, required, jsonError],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { initialValue, path, setValue, showError, value } = useField<string>({
path: pathFromContext || pathFromProps || name,

View File

@@ -54,7 +54,7 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
onChange: onChangeFromProps,
path: pathFromProps,
placeholder,
readOnly,
readOnly: readOnlyFromProps,
required,
step = 1,
style,
@@ -73,7 +73,8 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
[validate, min, max, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, setValue, showError, value } = useField<number | number[]>({
path: pathFromContext || pathFromProps || name,

View File

@@ -43,7 +43,7 @@ const PointField: React.FC<PointFieldProps> = (props) => {
labelProps,
path: pathFromProps,
placeholder,
readOnly,
readOnly: readOnlyFromProps,
required,
step,
style,
@@ -62,7 +62,8 @@ const PointField: React.FC<PointFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const {
path,
@@ -89,7 +90,8 @@ const PointField: React.FC<PointFieldProps> = (props) => {
const getCoordinateFieldLabel = (type: 'latitude' | 'longitude') => {
const suffix = type === 'longitude' ? t('fields:longitude') : t('fields:latitude')
const fieldLabel = labelProps && labelProps.label ? labelProps.label : ''
const fieldLabel = labelProps && labelProps.label ? getTranslation(labelProps.label, i18n) : ''
return {
...labelProps,
label: `${fieldLabel}${fieldLabel ? ' - ' : ''}${suffix}`,

View File

@@ -50,7 +50,7 @@ const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
onChange: onChangeFromProps,
options = [],
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -68,7 +68,8 @@ const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
[validate, options, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const {
path,

View File

@@ -52,7 +52,7 @@ const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
label,
labelProps,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
relationTo,
required,
sortOptions,
@@ -92,7 +92,8 @@ const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
},
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { filterOptions, initialValue, path, setValue, showError, value } = useField<
Value | Value[]

View File

@@ -62,7 +62,7 @@ const SelectField: React.FC<SelectFieldProps> = (props) => {
onChange: onChangeFromProps,
options: optionsFromProps = [],
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
required,
style,
validate,
@@ -81,7 +81,8 @@ const SelectField: React.FC<SelectFieldProps> = (props) => {
[validate, required, hasMany, options],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, setValue, showError, value } = useField({
path: pathFromContext || pathFromProps || name,

View File

@@ -43,11 +43,18 @@ const TabsField: React.FC<TabsFieldProps> = (props) => {
descriptionProps,
forceRender = false,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
tabs = [],
} = props
const { indexPath, path: pathFromContext, permissions, schemaPath } = useFieldProps()
const {
indexPath,
path: pathFromContext,
permissions,
readOnly: readOnlyFromContext,
schemaPath,
} = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const path = pathFromContext || pathFromProps || name
const { getPreference, setPreference } = usePreferences()
const { preferencesKey } = useDocumentInfo()

View File

@@ -39,6 +39,7 @@ const TextField: React.FC<TextFieldProps> = (props) => {
minRows,
path: pathFromProps,
placeholder,
readOnly: readOnlyFromProps,
required,
rtl,
style,
@@ -58,9 +59,10 @@ const TextField: React.FC<TextFieldProps> = (props) => {
[validate, minLength, maxLength, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, readOnly, setValue, showError, value } = useField({
const { formProcessing, path, setValue, showError, value } = useField({
path: pathFromContext || pathFromProps || name,
validate: memoizedValidate,
})
@@ -137,7 +139,7 @@ const TextField: React.FC<TextFieldProps> = (props) => {
}
path={path}
placeholder={placeholder}
readOnly={readOnly}
readOnly={formProcessing || readOnly}
required={required}
rtl={renderRTL}
showError={showError}

View File

@@ -36,6 +36,7 @@ const TextareaField: React.FC<TextareaFieldProps> = (props) => {
minLength,
path: pathFromProps,
placeholder,
readOnly: readOnlyFromProps,
required,
rows,
rtl,
@@ -63,9 +64,10 @@ const TextareaField: React.FC<TextareaFieldProps> = (props) => {
[validate, required, maxLength, minLength],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { path, readOnly, setValue, showError, value } = useField<string>({
const { path, setValue, showError, value } = useField<string>({
path: pathFromContext || pathFromProps || name,
validate: memoizedValidate,
})

View File

@@ -25,7 +25,7 @@ const _Upload: React.FC<UploadFieldProps> = (props) => {
label,
labelProps,
path: pathFromProps,
readOnly,
readOnly: readOnlyFromProps,
relationTo,
required,
style,
@@ -50,7 +50,8 @@ const _Upload: React.FC<UploadFieldProps> = (props) => {
[validate, required],
)
const { path: pathFromContext } = useFieldProps()
const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const readOnly = readOnlyFromProps || readOnlyFromContext
const { filterOptions, path, setValue, showError, value } = useField<string>({
path: pathFromContext || pathFromProps,
@@ -77,6 +78,7 @@ const _Upload: React.FC<UploadFieldProps> = (props) => {
descriptionProps={descriptionProps}
errorProps={errorProps}
filterOptions={filterOptions}
label={label}
labelProps={labelProps}
onChange={onChange}
path={path}