diff --git a/packages/core/client/src/schema-component/antd/association-field/FileManager.tsx b/packages/core/client/src/schema-component/antd/association-field/FileManager.tsx index 5e2716582c26..1432296ecb79 100644 --- a/packages/core/client/src/schema-component/antd/association-field/FileManager.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/FileManager.tsx @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { RecursionField, connect, useField, useFieldSchema } from '@formily/react'; +import { RecursionField, connect, useExpressionScope, useField, useFieldSchema } from '@formily/react'; import { differenceBy, unionBy } from 'lodash'; import cls from 'classnames'; import React, { useContext, useEffect, useState } from 'react'; @@ -84,8 +84,9 @@ const useTableSelectorProps = () => { function FileSelector(props) { const { disabled, multiple, value, onChange, onSelect, quickUpload, selectFile } = props; const { wrapSSR, hashId, componentCls: prefixCls } = useStyles(); - const { scope } = useSchemaOptionsContext(); + const { useFileCollectionStorageRules } = useExpressionScope(); const { t } = useTranslation(); + const rules = useFileCollectionStorageRules(); // 兼容旧版本 const showSelectButton = selectFile === undefined && quickUpload === undefined; @@ -119,7 +120,7 @@ function FileSelector(props) { multiple={multiple} // onRemove={handleRemove} onChange={onChange} - useRules={scope.useFileCollectionStorageRules} + rules={rules} /> ) : null} {selectFile && (multiple || !value) ? ( diff --git a/packages/core/client/src/schema-component/antd/upload/Upload.tsx b/packages/core/client/src/schema-component/antd/upload/Upload.tsx index d54cd39f845e..b026fddf88c8 100644 --- a/packages/core/client/src/schema-component/antd/upload/Upload.tsx +++ b/packages/core/client/src/schema-component/antd/upload/Upload.tsx @@ -93,10 +93,11 @@ export const Upload: ComposedUpload = connect( Upload.ReadPretty = ReadPretty; -function useSizeHint(size: number = DEFAULT_MAX_FILE_SIZE) { +function useSizeHint(size: number) { + const s = size ?? DEFAULT_MAX_FILE_SIZE; const { t, i18n } = useTranslation(); - const sizeString = filesize(size, { base: 2, standard: 'jedec', locale: i18n.language }); - return size !== 0 ? t('File size should not exceed {{size}}.', { size: sizeString }) : ''; + const sizeString = filesize(s, { base: 2, standard: 'jedec', locale: i18n.language }); + return s !== 0 ? t('File size should not exceed {{size}}.', { size: sizeString }) : ''; } function AttachmentListItem(props) { @@ -342,11 +343,7 @@ export function AttachmentList(props) { ); } -function useDefaultRules(props) { - return props.rules; -} - -export function Uploader({ useRules = useDefaultRules, rules: propsRules, ...props }: UploadProps) { +export function Uploader({ rules, ...props }: UploadProps) { const { disabled, multiple, value, onChange } = props; const [pendingList, setPendingList] = useState([]); const { t } = useTranslation(); @@ -355,7 +352,6 @@ export function Uploader({ useRules = useDefaultRules, rules: propsRules, ...pro const uploadProps = useUploadProps(props); - const rules = useRules({ rules: propsRules, ...props }); const beforeUpload = useBeforeUpload(rules); useEffect(() => { @@ -446,18 +442,21 @@ export function Uploader({ useRules = useDefaultRules, rules: propsRules, ...pro ); } -Upload.Attachment = connect((props: UploadProps) => { - const { wrapSSR, hashId, componentCls: prefixCls } = useStyles(); +Upload.Attachment = withDynamicSchemaProps( + connect((props: UploadProps) => { + const { wrapSSR, hashId, componentCls: prefixCls } = useStyles(); - return wrapSSR( -
-
- - -
-
, - ); -}, mapReadPretty(ReadPretty.File)); + return wrapSSR( +
+
+ + +
+
, + ); + }, mapReadPretty(ReadPretty.File)), + { displayName: 'Upload.Attachment' }, +); Upload.Dragger = connect( (props: DraggerProps) => { @@ -485,7 +484,7 @@ Upload.Dragger = connect( Upload.DraggerV2 = withDynamicSchemaProps( connect( - ({ rules: propsRules, useRules = useDefaultRules, ...props }: DraggerV2Props) => { + ({ rules, ...props }: DraggerV2Props) => { const { t } = useTranslation(); const defaultTitle = t('Click or drag file to this area to upload'); @@ -495,7 +494,6 @@ Upload.DraggerV2 = withDynamicSchemaProps( const [loading, setLoading] = useState(false); const { wrapSSR, hashId, componentCls: prefixCls } = useStyles(); - const rules = useRules({ rules: propsRules }); const beforeUpload = useBeforeUpload(rules); const { size, mimetype: accept } = rules ?? {}; const sizeHint = useSizeHint(size); diff --git a/packages/core/client/src/schema-component/antd/upload/shared.ts b/packages/core/client/src/schema-component/antd/upload/shared.ts index 195c801cbd0a..14b5401fbef4 100644 --- a/packages/core/client/src/schema-component/antd/upload/shared.ts +++ b/packages/core/client/src/schema-component/antd/upload/shared.ts @@ -222,11 +222,12 @@ export const toValue = (fileList: any) => { }; const Rules: Record = { - size(file, options: number = DEFAULT_MAX_FILE_SIZE): null | string { - if (options === 0) { + size(file, options: number): null | string { + const size = options ?? DEFAULT_MAX_FILE_SIZE; + if (size === 0) { return null; } - return file.size <= options ? null : 'File size exceeds the limit'; + return file.size <= size ? null : 'File size exceeds the limit'; }, mimetype(file, options: string | string[] = '*'): null | string { const pattern = options.toString().trim(); diff --git a/packages/core/client/src/schema-component/antd/upload/type.d.ts b/packages/core/client/src/schema-component/antd/upload/type.d.ts index a33b4c874630..9987a5b8af0e 100644 --- a/packages/core/client/src/schema-component/antd/upload/type.d.ts +++ b/packages/core/client/src/schema-component/antd/upload/type.d.ts @@ -19,7 +19,6 @@ export type UploadProps = Omit & { value?: any; size?: string; rules?: PropsRules; - useRules?(rules: PropsRules): PropsRules; }; export type DraggerProps = Omit & { @@ -34,7 +33,6 @@ export type DraggerV2Props = Omit & { serviceErrorMessage?: string; title?: string; rules?: PropsRules; - useRules?(rules: PropsRules): PropsRules; children?: React.ReactNode; /** @deprecated */ useProps?: () => any; diff --git a/packages/core/client/src/system-settings/SystemSettingsShortcut.tsx b/packages/core/client/src/system-settings/SystemSettingsShortcut.tsx index a701be08a8cd..9839ca5149c9 100644 --- a/packages/core/client/src/system-settings/SystemSettingsShortcut.tsx +++ b/packages/core/client/src/system-settings/SystemSettingsShortcut.tsx @@ -103,9 +103,9 @@ const schema: ISchema = { 'x-component-props': { action: 'attachments:create', multiple: false, - useRules: '{{useCollectionFieldStorageRules}}', // accept: 'jpg,png' }, + 'x-use-component-props': 'useCollectionFieldStorageRules', }, enabledLanguages: { type: 'array', diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useStorageRules.ts b/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useStorageRules.ts index ac93f178a719..9570fee3207a 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useStorageRules.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useStorageRules.ts @@ -1,3 +1,12 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + import { useCollectionField, useCollectionManager, useRequest } from '@nocobase/client'; export function useStorageRules(name = '') { @@ -12,12 +21,13 @@ export function useStorageRules(name = '') { return (!loading && data?.data) || null; } -export function useCollectionFieldStorageRules(props) { +export function useCollectionFieldStorageRules() { const field = useCollectionField(); - return useStorageRules(field?.storage); + const rules = useStorageRules(field?.storage); + return { rules }; } -export function useFileCollectionStorageRules(props) { +export function useFileCollectionStorageRules() { const field = useCollectionField(); const collectionManager = useCollectionManager(); const collection = collectionManager.getCollection(field?.target); diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useUploadFiles.ts b/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useUploadFiles.ts index 6da5d4c7adc2..35c6fc9084e2 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useUploadFiles.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/client/hooks/useUploadFiles.ts @@ -23,6 +23,7 @@ export const useUploadFiles = () => { const { props: blockProps } = useBlockRequestContext(); const collection = useCollection(); const sourceId = useSourceIdFromParentRecord(); + const rules = useFileCollectionStorageRules(); const action = useMemo(() => { let action = `${collection.name}:create`; if (blockProps?.association) { @@ -60,6 +61,6 @@ export const useUploadFiles = () => { setVisible(false); } }, - useRules: useFileCollectionStorageRules, + rules, }; }; diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/client/interfaces/attachment.ts b/packages/plugins/@nocobase/plugin-file-manager/src/client/interfaces/attachment.ts index cc34badfdb62..e2da41368eb9 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/client/interfaces/attachment.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/client/interfaces/attachment.ts @@ -26,9 +26,7 @@ export class AttachmentFieldInterface extends CollectionFieldInterface { type: 'array', // title, 'x-component': 'Upload.Attachment', - 'x-component-props': { - useRules: '{{useCollectionFieldStorageRules}}', - }, + 'x-use-component-props': 'useCollectionFieldStorageRules', }, }; availableTypes = ['belongsToMany']; @@ -45,7 +43,7 @@ export class AttachmentFieldInterface extends CollectionFieldInterface { field.storage ? `?attachmentField=${field.collectionName}.${field.name}` : '' }`; - schema['x-component-props'].useRules = '{{useCollectionFieldStorageRules}}'; + schema['x-use-component-props'] = 'useCollectionFieldStorageRules'; } initialize(values: any) { if (!values.through) {