Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin-fm): make rules configurable #4118

Merged
merged 36 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fab02f5
feat(plugin-fm): make rules configurable
mytharcher Apr 20, 2024
9768bb4
fix(client): fix upload test cases
mytharcher Apr 21, 2024
e2a4b46
refactor(client): remove dulicated code
mytharcher Apr 22, 2024
844eaeb
refactor(client): upload component
mytharcher Apr 23, 2024
d9dad71
refactor(client): remove a lot of duplicated code
mytharcher Apr 25, 2024
809f401
fix(client): fix upload in system settings
mytharcher Apr 25, 2024
1573e63
Merge branch 'main' into T-251
mytharcher Apr 25, 2024
2d1870d
fix(client): fix test case
mytharcher Apr 26, 2024
45fb8d9
fix(client): fix test case
mytharcher Apr 26, 2024
c82313f
fix(client): fix test case
mytharcher Apr 26, 2024
86b790f
Merge branch 'main' into T-251
mytharcher Apr 29, 2024
69ba0cd
chore: update yarn.lock
mytharcher Apr 29, 2024
9970e91
fix(client): fix test case
mytharcher Apr 29, 2024
ec027b4
Merge branch 'main' into T-251
mytharcher Apr 30, 2024
d16181a
fix: api mock
chenos May 6, 2024
f8a19fb
Merge branch 'main' into T-251
mytharcher May 12, 2024
9dd0bfa
refactor(client): refactor hooks
mytharcher May 12, 2024
90b549c
docs(client): add demo code
mytharcher May 13, 2024
241516b
Merge branch 'main' into T-251
chenos May 18, 2024
4a60f13
fix: ci
chenos May 18, 2024
2840c9d
fix(client): fix import package
mytharcher May 18, 2024
97988fe
fix: filesize
chenos May 18, 2024
09f8abc
Merge branch 'T-251' of github.com:nocobase/nocobase into T-251
chenos May 18, 2024
708570c
fix(client): fix upload component
mytharcher May 18, 2024
8a9d74f
fix(client): deprecate preview component and move to file-manager
mytharcher May 19, 2024
07d8017
fix(plugin-fm): fix storage changes in attachment field and locales
mytharcher May 22, 2024
08b4175
refactor(plugin-fm): add migration for attachment field storage
mytharcher May 22, 2024
2017c2c
Merge branch 'main' into T-251
mytharcher May 27, 2024
515f8e6
test(plugin-fm): add test case
mytharcher May 27, 2024
dee392a
feat(plugin-fm): add storage size component
mytharcher May 27, 2024
7bdb1d9
fix(plugin-fm): fix component
mytharcher May 27, 2024
6f032bc
refactor(plugin-fm): adjust constant
mytharcher May 28, 2024
43a6663
fix(plugin-fm): fix default local size limit
mytharcher May 28, 2024
2163105
fix(plugin-fm): fix test cases
mytharcher May 28, 2024
a171051
fix(plugin-fm): fix test case
mytharcher May 28, 2024
f25ec53
fix(plugin-fm): fix rule hook
mytharcher May 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/deploy-client-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ on:
branches:
- '**'
paths:
- 'packages/core/client/**'
- 'packages/core/client/docs/**'
- '.github/workflows/deploy-client-docs.yml'

Expand Down
4 changes: 0 additions & 4 deletions packages/core/client/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,6 @@ export default defineConfig({
"title": "Pagination",
"link": "/components/pagination"
},
{
"title": "Preview",
"link": "/components/preview"
},
]
},
]
Expand Down
1 change: 1 addition & 0 deletions packages/core/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"classnames": "^2.3.1",
"cronstrue": "^2.11.0",
"file-saver": "^2.0.5",
"filesize": "9.0.11",
"flat": "^5.0.2",
"i18next": "^22.4.9",
"i18next-http-backend": "^2.1.1",
Expand Down
7 changes: 6 additions & 1 deletion packages/core/client/src/locale/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,13 @@
"Render Failed": "渲染失败",
"Feedback": "反馈问题",
"Try again": "重试一下",
"Download": "下载",
"Click or drag file to this area to upload": "点击或拖拽文件到此区域上传",
"Support for a single or bulk upload, file size should not exceed": "支持单个或批量上传,文件大小不能超过",
"Support for a single or bulk upload.": "支持单个或批量上传",
"File size should not exceed {{size}}.": "文件大小不能超过 {{size}}",
"File size exceeds the limit": "文件大小超过限制",
"File type is not allowed": "文件类型不允许",
"Incomplete uploading files need to be resolved": "未完成上传的文件需要处理",
"Default title for each record": "用作数据的默认标题",
"If collection inherits, choose inherited collections as templates": "当前表有继承关系时,可选择继承链路上的表作为模板来源",
"Select an existing piece of data as the initialization data for the form": "选择一条已有的数据作为表单的初始化数据",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@
* 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';
import { Upload as AntdUpload } from 'antd';
import {
AttachmentList,
FormProvider,
RecordPickerContext,
RecordPickerProvider,
SchemaComponentOptions,
Uploader,
useActionContext,
useSchemaOptionsContext,
} from '../..';
import {
TableSelectorParamsProvider,
Expand All @@ -29,11 +34,13 @@ import {
import { useCompile } from '../../hooks';
import { ActionContextProvider } from '../action';
import { EllipsisWithTooltip } from '../input';
import { FileSelector, Preview } from '../preview';
import { ReadPrettyInternalViewer } from './InternalViewer';
import { Upload } from '../upload';
import { useFieldNames, useInsertSchema } from './hooks';
import schema from './schema';
import { flatData, getLabelFormatValue, isShowFilePicker, useLabelUiSchema } from './util';
import { flatData, getLabelFormatValue, useLabelUiSchema } from './util';
import { useTranslation } from 'react-i18next';
import { PlusOutlined } from '@ant-design/icons';
import { useStyles } from '../upload/style';

const useTableSelectorProps = () => {
const field: any = useField();
Expand Down Expand Up @@ -73,6 +80,75 @@ const useTableSelectorProps = () => {
},
};
};

function FileSelector(props) {
const { disabled, multiple, value, onChange, action, onSelect, quickUpload, selectFile } = props;
const { wrapSSR, hashId, componentCls: prefixCls } = useStyles();
const { useFileCollectionStorageRules } = useExpressionScope();
const { t } = useTranslation();
const rules = useFileCollectionStorageRules();
// 兼容旧版本
const showSelectButton = selectFile === undefined && quickUpload === undefined;

return wrapSSR(
<div className={cls(`${prefixCls}-wrapper`, `${prefixCls}-picture-card-wrapper`, 'nb-upload', hashId)}>
<div className={cls(`${prefixCls}-list`, `${prefixCls}-list-picture-card`)}>
<AttachmentList disabled={disabled} multiple={multiple} value={value} onChange={onChange} />
{showSelectButton ? (
<div className={cls(`${prefixCls}-list-picture-card-container`, `${prefixCls}-list-item-container`)}>
<AntdUpload disabled={disabled} multiple={multiple} listType={'picture-card'} showUploadList={false}>
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
onClick={onSelect}
>
<PlusOutlined />
{t('Select')}
</div>
</AntdUpload>
</div>
) : null}
{quickUpload ? (
<Uploader
value={value}
multiple={multiple}
// onRemove={handleRemove}
onChange={onChange}
action={action}
rules={rules}
/>
) : null}
{selectFile && (multiple || !value) ? (
<div className={cls(`${prefixCls}-list-picture-card-container`, `${prefixCls}-list-item-container`)}>
<AntdUpload disabled={disabled} multiple={multiple} listType={'picture-card'} showUploadList={false}>
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
onClick={onSelect}
>
<PlusOutlined />
{t('Select')}
</div>
</AntdUpload>
</div>
) : null}
</div>
</div>,
);
}

const InternalFileManager = (props) => {
const { value, multiple, onChange, ...others } = props;
const fieldSchema = useFieldSchema();
Expand All @@ -87,13 +163,9 @@ const InternalFileManager = (props) => {
const labelUiSchema = useLabelUiSchema(collectionField?.target, fieldNames?.label || 'label');
const compile = useCompile();
const { modalProps } = useActionContext();
const getFilter = () => {
const targetKey = collectionField?.targetKey || 'id';
const list = options.map((option) => option[targetKey]).filter(Boolean);
const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {};
return filter;
};
const handleSelect = () => {
const handleSelect = (ev) => {
ev.stopPropagation();
ev.preventDefault();
insertSelector(schema.Selector);
setVisibleSelector(true);
setSelectedRows([]);
Expand All @@ -114,14 +186,6 @@ const InternalFileManager = (props) => {
}
}, [value, fieldNames?.label]);

const handleRemove = (file) => {
const newOptions = options.filter((option) => option.id !== file.id);
setOptions(newOptions);
if (newOptions.length === 0) {
return onChange(null);
}
onChange(newOptions);
};
const pickerProps = {
size: 'small',
fieldNames,
Expand Down Expand Up @@ -152,23 +216,13 @@ const InternalFileManager = (props) => {
return (
<div style={{ width: '100%', overflow: 'auto' }}>
<FileSelector
value={options}
value={multiple ? options : options?.[0]}
multiple={multiple}
quickUpload={fieldSchema['x-component-props']?.quickUpload !== false}
selectFile={fieldSchema['x-component-props']?.selectFile !== false}
action={`${collectionField?.target}:create`}
onSelect={handleSelect}
onRemove={handleRemove}
onChange={(changed) => {
if (changed.every((file) => file.status !== 'uploading')) {
changed = changed.filter((file) => file.status === 'done').map((file) => file.response.data);
if (multiple) {
onChange([...options, ...changed]);
} else {
onChange(changed[0]);
}
}
}}
onChange={onChange}
/>
<ActionContextProvider
value={{
Expand All @@ -184,7 +238,7 @@ const InternalFileManager = (props) => {
<RecordPickerProvider {...pickerProps}>
<CollectionProvider_deprecated name={collectionField?.target}>
<FormProvider>
<TableSelectorParamsProvider params={{ filter: getFilter() }}>
<TableSelectorParamsProvider params={{}}>
<SchemaComponentOptions scope={{ usePickActionProps, useTableSelectorProps }}>
<RecursionField
onlyRenderProperties
Expand All @@ -209,7 +263,9 @@ const FileManageReadPretty = connect((props) => {
const { getField } = useCollection_deprecated();
const { getCollectionJoinField } = useCollectionManager_deprecated();
const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema['x-collection-field']);
return <EllipsisWithTooltip ellipsis>{collectionField ? <Preview {...props} /> : null}</EllipsisWithTooltip>;
return (
<EllipsisWithTooltip ellipsis>{collectionField ? <Upload.ReadPretty {...props} /> : null}</EllipsisWithTooltip>
);
});

export { FileManageReadPretty, InternalFileManager };