beer-assembly-biz 1.1.3-alpha.1 → 1.1.3-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,461 +1,172 @@
1
- "use strict";
2
- // import React, { CSSProperties, ReactNode, useEffect, useRef, useState } from 'react';
3
- // import { css } from '@emotion/css';
4
- // import { Breadcrumb, Button, Dropdown, Input, message, Modal, Popconfirm, Space, Spin, theme, Typography } from 'antd';
5
- // import ElementUtils from 'beer-network/elementUtils';
6
- // import Flux from 'beer-assembly/Flux';
7
- // import { CloudDownloadOutlined, CopyOutlined, DeleteOutlined, ExclamationCircleFilled, HighlightOutlined, RightCircleOutlined, ScissorOutlined } from '@ant-design/icons';
8
- // import DirectorySelect, { DirectorySelectProps } from 'beer-assembly/DirectorySelect';
9
- // import InlineContainer from './InlineContainer';
10
- // import IconDirectory from './icon/directory.svg';
11
- // import IconMedia from './icon/media.png';
12
- //
13
- // export type Handler<T> = {
14
- // ok: (callback?: (params: T) => void) => void
15
- // }
16
- // type DirectoryRequest = NonNullable<DirectorySelectProps['request']>;
17
- // export declare type MediaItem = {
18
- // id: string
19
- // name: string
20
- // type: 'DIRECTORY' | 'FILE'
21
- // url: string
22
- // active: boolean
23
- // };
24
- // export declare type RequestParams = {
25
- // /**
26
- // * 获取列表数据.
27
- // * @param parentId 父类ID.
28
- // */
29
- // requestList: (parentId: string) => Promise<MediaItem[]>
30
- // rename: (id: string, name: string) => Promise<Boolean>
31
- // copy: (id: string) => Promise<Boolean>
32
- // move: (moveId: string, targetId: string) => Promise<Boolean>
33
- // remove: (id: string) => Promise<Boolean>
34
- // createDirectory: (parentId: string, name: string) => Promise<Boolean>
35
- // putFile: (parentId: string, files: FileList) => Promise<Boolean>
36
- // } & {
37
- // directory: DirectoryRequest
38
- // };
39
- //
40
- // export class MediaModals {
41
- // public static useMedia(request?: RequestParams): [Handler<string[]>, ReactNode] {
42
- // const [messageApi, contextHolder] = message.useMessage();
43
- // const { token } = theme.useToken();
44
- // const [isOpenModal, setIsOpenModal] = useState(false);
45
- // const [isOpenMoveModal, setIsOpenMoveModal] = useState(false);
46
- // const [isOpenRenameModal, setIsOpenRenameModal] = useState(false);
47
- // const [isOpenConfirmModal, setIsOpenConfirmModal] = useState(false);
48
- // const [isLoading, setIsLoading] = useState(false);
49
- // const [path, setPath] = useState<{ id: string, name: string }[]>([]);
50
- // const [dataList, setDataList] = useState<MediaItem[][]>([]);
51
- // const [selectId, setSelectId] = useState('');
52
- // const [selectName, setSelectName] = useState('');
53
- // const callbackRef = useRef<((params: string[]) => void) | undefined>(undefined);
54
- // const refreshData = (force?: boolean) => {
55
- // const item = path[path.length - 1];
56
- // const chunkArray = (array: any[], size: number): any[][] => {
57
- // const result: any[][] = [];
58
- // for (let i = 0; i < array.length; i += size) {
59
- // result.push(array.slice(i, i + size));
60
- // }
61
- // return result;
62
- // };
63
- // setIsLoading(true);
64
- // if (force === true) {
65
- // setDataList([]);
66
- // }
67
- // request?.requestList?.(item.id)
68
- // .then(result => {
69
- // setIsLoading(false);
70
- // setDataList(chunkArray(result || [], 5));
71
- // })
72
- // .catch(() => {
73
- // setIsLoading(false);
74
- // });
75
- // };
76
- // const onActiveItem = (id: string) => {
77
- // setDataList(dataList?.map(item => {
78
- // return item.map(it => {
79
- // return {
80
- // ...it,
81
- // active: it.id === id
82
- // };
83
- // });
84
- // }));
85
- // };
86
- // const onDownload = async (name: string, url?: string) => {
87
- // if ((url || '').trim() === '') {
88
- // return;
89
- // }
90
- // ElementUtils.download(url || '', name);
91
- // };
92
- // const onPutFile = async () => {
93
- // const files = await ElementUtils.selectFile();
94
- // if (files === null) {
95
- // return;
96
- // }
97
- // for (let i = 0; i < files.length; i += 1) {
98
- // const file = files[i];
99
- // if (file.size > (1048576 * 15)) {
100
- // messageApi.error(`文件 ${file.name} 太大,不能超过 15MB`);
101
- // return;
102
- // }
103
- // if (!['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(file.type)) {
104
- // messageApi.error(`文件 ${file.name} 不是有效的图片格式`);
105
- // return;
106
- // }
107
- // }
108
- // const parentId = path[path.length - 1]?.id;
109
- // setIsLoading(true);
110
- // const result = await request?.putFile(parentId, files);
111
- // setIsLoading(false);
112
- // if (result === true) {
113
- // refreshData();
114
- // }
115
- // };
116
- // const onCreateDirectory = async (name: string) => {
117
- // const parentId = path[path.length - 1]?.id;
118
- // setIsLoading(true);
119
- // const result = await request?.createDirectory(parentId, name);
120
- // setIsLoading(false);
121
- // if (result === true) {
122
- // refreshData();
123
- // }
124
- // setSelectName('');
125
- // return true;
126
- // };
127
- // const onOpenDirectory = async (id: string, name: string) => {
128
- // if (isLoading) {
129
- // return;
130
- // }
131
- // const paths = [...getPaths(), {
132
- // id,
133
- // name
134
- // }];
135
- // setPaths(paths);
136
- // };
137
- // const onBackDirectory = async (id: string) => {
138
- // if (isLoading) {
139
- // return;
140
- // }
141
- // const paths = getPaths();
142
- // const index = paths.findIndex(it => it.id === id);
143
- // if (index < 0) {
144
- // return;
145
- // }
146
- // paths.splice(index + 1);
147
- // setPaths(paths);
148
- // };
149
- // const onSelectItem = async (id: string, name: string, url?: string) => {
150
- // const current = callbackRef?.current;
151
- // if (current === undefined) {
152
- // return;
153
- // }
154
- // current?.([url || '']);
155
- // setIsOpenModal(false);
156
- // };
157
- // const onRename = async (id: string, name: string) => {
158
- // setIsOpenRenameModal(true);
159
- // setSelectId(id);
160
- // setSelectName(name);
161
- // };
162
- // const onConfirmRename = async () => {
163
- // if (await request?.rename(selectId, selectName)) {
164
- // refreshData();
165
- // setSelectName('');
166
- // setIsOpenRenameModal(false);
167
- // }
168
- // };
169
- // const onCopy = async (id: string) => {
170
- // const result = await request?.copy(id);
171
- // if (result === true) {
172
- // refreshData();
173
- // }
174
- // return result;
175
- // };
176
- // const onMove = async (id: string) => {
177
- // setIsOpenMoveModal(true);
178
- // setSelectId(id);
179
- // };
180
- // const onConfirmMove = async (targetId: string) => {
181
- // const result = await request?.move(selectId, targetId);
182
- // if (result === true) {
183
- // setIsOpenMoveModal(false);
184
- // refreshData();
185
- // }
186
- // };
187
- // const onRemove = async (id: string) => {
188
- // setIsOpenConfirmModal(true);
189
- // setSelectId(id);
190
- // };
191
- // const onConfirmRemove = async () => {
192
- // const result = await request?.remove(selectId);
193
- // if (result === true) {
194
- // setIsOpenConfirmModal(false);
195
- // refreshData();
196
- // }
197
- // return result;
198
- // };
199
- // const setPaths = (items: { id: string, name: string }[]) => {
200
- // setPath(items);
201
- // sessionStorage.setItem('MEDIA_MODALS_PATHS', JSON.stringify(items));
202
- // };
203
- // const getPaths = (): { id: string, name: string }[] => {
204
- // const paths = JSON.parse(sessionStorage.getItem('MEDIA_MODALS_PATHS') || '[]');
205
- // if (paths.length <= 0) {
206
- // paths.push({
207
- // id: '0',
208
- // name: '根目录'
209
- // });
210
- // }
211
- // return paths;
212
- // };
213
- // const Item = (props: {
214
- // id: string
215
- // name: string
216
- // type: 'DIRECTORY' | 'FILE'
217
- // src?: string,
218
- // style?: CSSProperties,
219
- // active?: boolean
220
- // }) => {
221
- // const directoryMenusItem = props.type === 'DIRECTORY' ? [
222
- // {
223
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onOpenDirectory(props.id, props.name)}><RightCircleOutlined/>打开目录</Space>,
224
- // key: '0'
225
- // },
226
- // {
227
- // type: 'divider'
228
- // }
229
- // ] : [
230
- // {
231
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onDownload(props.name, props.src)}><CloudDownloadOutlined/>下载文件</Space>,
232
- // key: '0'
233
- // },
234
- // {
235
- // type: 'divider'
236
- // }
237
- // ];
238
- // const menusItems = [
239
- // ...directoryMenusItem,
240
- // {
241
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onRename(props.id, props.name)}><HighlightOutlined/>重命名</Space>,
242
- // key: '1'
243
- // },
244
- // {
245
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onCopy(props.id)}><CopyOutlined/>{props?.type === 'DIRECTORY' ? '复制目录' : '复制文件'}</Space>,
246
- // key: '2'
247
- // },
248
- // {
249
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onMove(props.id)}><ScissorOutlined/>{props?.type === 'DIRECTORY' ? '移动目录' : '移动文件'}</Space>,
250
- // key: '3'
251
- // },
252
- // {
253
- // type: 'divider'
254
- // },
255
- // {
256
- // label: <Space style={{ width: 100 }} size={5} onClick={() => onRemove(props.id)}><DeleteOutlined/>{props?.type === 'DIRECTORY' ? '删除目录' : '删除文件'}</Space>,
257
- // key: '4',
258
- // danger: true
259
- // }
260
- // ];
261
- // return <Dropdown menu={{
262
- // items: menusItems as never
263
- // }} trigger={['contextMenu']}>
264
- // <div
265
- // style={{
266
- // padding: '8px 12px',
267
- // backgroundColor: props?.active ? '#e6f1ff' : undefined,
268
- // display: 'block',
269
- // cursor: 'pointer',
270
- // userSelect: 'none',
271
- // position: 'relative',
272
- // ...props.style
273
- // }}
274
- // className={css`
275
- // border: ${props?.active ? '1px solid #cddef5' : '1px solid #fff'};
276
- //
277
- // &:hover {
278
- // background-color: #eef1f5;
279
- // border: 1px solid ${props.active ? '#cddef5' : '#e6e6e6'};
280
- // }
281
- // `}
282
- // onClick={() => {
283
- // setTimeout(() => onActiveItem(props.id), 10);
284
- // }}
285
- // onDoubleClick={() => {
286
- // if (props.type === 'DIRECTORY') {
287
- // onOpenDirectory(props.id, props.name)
288
- // .then();
289
- // return;
290
- // }
291
- // onSelectItem(props.id, props.name, props.src)
292
- // .then();
293
- // }}>
294
- // <img src={props?.type === 'DIRECTORY' ? IconDirectory : props?.src} alt="" style={{
295
- // width: 56,
296
- // height: 56,
297
- // margin: 'auto',
298
- // display: 'block',
299
- // overflow: 'hidden',
300
- // objectFit: props?.type === 'DIRECTORY' ? undefined : 'cover'
301
- // }}/>
302
- // <Typography.Text style={{
303
- // width: 70,
304
- // fontSize: token.fontSize - 2,
305
- // display: 'block',
306
- // textAlign: 'center',
307
- // color: '#323232',
308
- // marginTop: props?.type === 'DIRECTORY' ? undefined : 1
309
- // }} ellipsis={true}>{props?.name}</Typography.Text>
310
- // </div>
311
- // </Dropdown>;
312
- // };
313
- // const handler: Handler<string[]> = {
314
- // ok: (callback?: (params: string[]) => void) => {
315
- // setPath(getPaths());
316
- // setIsOpenModal(true);
317
- // if (callbackRef !== undefined) {
318
- // callbackRef.current = callback;
319
- // }
320
- // }
321
- // };
322
- // useEffect(() => {
323
- // if ((path || []).length <= 0) {
324
- // return;
325
- // }
326
- // refreshData(true);
327
- // }, [path]);
328
- // return [handler, <>
329
- // <InlineContainer>
330
- // <Modal
331
- // width={565}
332
- // footer={null}
333
- // styles={{
334
- // content: { padding: 0 }
335
- // }}
336
- // open={isOpenModal}
337
- // maskClosable={false}
338
- // onCancel={() => {
339
- // if (isLoading) {
340
- // return;
341
- // }
342
- // setIsOpenModal(false);
343
- // }}
344
- // title={<div style={{
345
- // padding: '16px 0 0 0'
346
- // }}>
347
- // <img style={{
348
- // marginInlineStart: 20,
349
- // display: 'block',
350
- // height: '17px',
351
- // padding: '2px 0 0 0'
352
- // }} alt="" src={IconMedia}/>
353
- // </div>}>
354
- // <Flux style={{
355
- // marginBottom: 6,
356
- // padding: '0 20px 10px 20px',
357
- // borderBottom: '1px solid #f3f3f3',
358
- // justifyContent: 'space-between'
359
- // }}>
360
- // <Breadcrumb
361
- // items={path?.map((it, index) => {
362
- // return {
363
- // title: (index + 1 === path.length
364
- // ? <Typography.Text style={{
365
- // maxWidth: 70,
366
- // fontSize: token.fontSize - 1
367
- // }} ellipsis={true}>{it.name}</Typography.Text>
368
- // : <a onClick={() => onBackDirectory(it.id)}><Typography.Text style={{
369
- // maxWidth: 70,
370
- // fontSize: token.fontSize - 1,
371
- // color: 'rgba(0, 0, 0, 0.45)'
372
- // }} ellipsis={true}>{it.name}</Typography.Text></a>)
373
- // };
374
- // })}
375
- // />
376
- // <Space>
377
- // <Button type="primary" onClick={() => onPutFile()} size="small" style={{
378
- // height: 24,
379
- // fontSize: token.fontSize - 1
380
- // }} loading={isLoading}>上传文件</Button>
381
- // <Popconfirm
382
- // title="请输入目录名称"
383
- // description={<Input value={selectName} onChange={(e) => setSelectName(e.currentTarget.value)}></Input>}
384
- // onCancel={() => setSelectName('')}
385
- // onConfirm={() => onCreateDirectory(selectName)}
386
- // okText="确定"
387
- // cancelText="取消"
388
- // >
389
- // <Button size="small" style={{
390
- // height: 24,
391
- // fontSize: token.fontSize - 1
392
- // }} loading={isLoading}>新建目录</Button>
393
- // </Popconfirm>
394
- // </Space>
395
- // </Flux>
396
- // <Spin spinning={isLoading}>
397
- // <div style={{
398
- // padding: '6px 0 24px 0',
399
- // height: 333,
400
- // maxHeight: 333,
401
- // overflowY: 'auto',
402
- // overflowX: 'hidden'
403
- // }}>
404
- // {dataList?.map((group, index) => (
405
- // <div key={index} style={{
406
- // padding: '0 20px 10px 20px',
407
- // display: 'flex'
408
- // }}>
409
- // {group?.map((item) => (
410
- // <Item
411
- // id={item.id}
412
- // key={item.id}
413
- // active={item.active}
414
- // style={{ marginRight: 10 }}
415
- // type={item.type}
416
- // src={item.url}
417
- // name={item.name}/>
418
- // ))}
419
- // </div>
420
- // ))}
421
- // </div>
422
- // </Spin>
423
- // </Modal>
424
- // </InlineContainer>
425
- // <Modal
426
- // title="重命名"
427
- // width={340}
428
- // open={isOpenRenameModal}
429
- // onOk={() => onConfirmRename()}
430
- // onCancel={() => setIsOpenRenameModal(false)}
431
- // okText="确定"
432
- // cancelText="取消">
433
- // <Input value={selectName} onChange={(e) => setSelectName(e.currentTarget.value)}></Input>
434
- // </Modal>
435
- // <Modal
436
- // title={<><ExclamationCircleFilled style={{
437
- // marginRight: 6,
438
- // fontSize: token.fontSize + 3,
439
- // color: '#faad14'
440
- // }}/>是否确认删除?</>}
441
- // width={400}
442
- // open={isOpenConfirmModal}
443
- // onOk={() => onConfirmRemove()}
444
- // onCancel={() => setIsOpenConfirmModal(false)}
445
- // okText="确定"
446
- // cancelText="取消">
447
- // 删除操作不能回复,确定要删除选中的文件或文件夹吗?
448
- // </Modal>
449
- // <DirectorySelect
450
- // open={isOpenMoveModal}
451
- // onCancel={() => {
452
- // refreshData();
453
- // setIsOpenMoveModal(false);
454
- // }}
455
- // request={request?.directory}
456
- // onOk={(value) => onConfirmMove(value)}>
457
- // </DirectorySelect>
458
- // {contextHolder}
459
- // </>];
460
- // }
461
- // }
1
+ import React, { useRef, useState } from 'react';
2
+ import { Button, message, Modal, Progress, Space, theme } from 'antd';
3
+ import { Flux } from 'beer-assembly-plus';
4
+ import { Media } from './Media';
5
+ import { UploadModals } from '../UploadModals';
6
+ /**
7
+ * 图片空间模态框.
8
+ */
9
+ export class MediaModals {
10
+ /**
11
+ * 打开图片选择模态框.
12
+ * @param request 请求接口.
13
+ */
14
+ static use(request) {
15
+ const { token } = theme.useToken();
16
+ const directoryGroupRef = useRef({});
17
+ const directoryCurrentRef = useRef('');
18
+ const directoryCurrentSortTypeRef = useRef('');
19
+ const mediaCallbackRef = useRef(null);
20
+ const [messageApi, contextHolder] = message.useMessage();
21
+ const [uploadModal, contextUploadHolder] = UploadModals.useUpload(['IMAGE']);
22
+ const [isOpenModal, setIsOpenModal] = useState(false);
23
+ const [maxLength, setMaxLength] = useState(1);
24
+ const [directorySelectMaxLength, setDirectorySelectMaxLength] = useState(1);
25
+ const [selectItems, setSelectItems] = useState([]);
26
+ const [directoryItem, setDirectoryItem] = useState([]);
27
+ const [mediaItem, setMediaItem] = useState([]);
28
+ const [progress, setProgress] = useState(0);
29
+ const callbackRef = useRef(undefined);
30
+ const getSelectKeyLength = () => {
31
+ const numbers = Object.keys(directoryGroupRef.current)
32
+ .map(it => directoryGroupRef.current[it])
33
+ .map(it => it.length) ?? [];
34
+ return numbers.reduce((value, current) => value + current, 0);
35
+ };
36
+ const refreshMedia = () => {
37
+ mediaCallbackRef?.current?.(true);
38
+ request.getItems(directoryCurrentRef.current, directoryCurrentSortTypeRef.current)
39
+ .then(items => {
40
+ mediaCallbackRef?.current?.(false);
41
+ setMediaItem(items);
42
+ });
43
+ };
44
+ const onConfirm = async () => {
45
+ if (callbackRef.current) {
46
+ const selectItems = Object.keys(directoryGroupRef.current)
47
+ .map(key => directoryGroupRef.current[key] ?? [])
48
+ .flat();
49
+ if (await callbackRef.current(selectItems)) {
50
+ setIsOpenModal(false);
51
+ }
52
+ }
53
+ else {
54
+ setIsOpenModal(false);
55
+ }
56
+ };
57
+ const handler = {
58
+ ok: (callback, args) => {
59
+ setIsOpenModal(true);
60
+ setMaxLength(args?.maxLength ?? 1);
61
+ if (args?.directoryItem !== undefined) {
62
+ setDirectoryItem(args.directoryItem);
63
+ }
64
+ else {
65
+ request.getDirectory()
66
+ .then(directoryItems => {
67
+ setDirectoryItem(directoryItems);
68
+ });
69
+ }
70
+ setProgress(0);
71
+ callbackRef.current = callback;
72
+ }
73
+ };
74
+ return [handler, React.createElement(React.Fragment, null,
75
+ React.createElement(Modal, { maskClosable: false, title: React.createElement(Space, { size: 24 },
76
+ React.createElement("span", null, "\u56FE\u7247\u7A7A\u95F4"),
77
+ progress > 0 ? React.createElement(Flux, { style: {
78
+ fontSize: token.fontSize - 1,
79
+ fontWeight: 'normal'
80
+ } },
81
+ React.createElement(Progress, { percent: progress, style: { width: 120 } }),
82
+ React.createElement("span", { style: {
83
+ marginBlockStart: 3,
84
+ fontWeight: 500
85
+ } }, "\u6587\u4EF6\u6B63\u5728\u4E0A\u4F20\uFF0C\u8BF7\u4E0D\u8981\u5173\u95ED\u7A97\u53E3")) : undefined), open: isOpenModal, width: 1035, styles: {
86
+ content: {
87
+ padding: 0
88
+ },
89
+ header: {
90
+ paddingBlock: '16px 12px',
91
+ paddingInline: 24,
92
+ marginInlineStart: 0,
93
+ marginBlockEnd: 0,
94
+ borderBottom: '1px solid rgba(0,0,0,0.08)'
95
+ },
96
+ wrapper: {
97
+ padding: 0
98
+ },
99
+ body: {
100
+ paddingInline: 12
101
+ },
102
+ footer: {
103
+ margin: 0
104
+ }
105
+ }, onCancel: () => setIsOpenModal(false), footer: React.createElement(Flux, { style: {
106
+ justifyContent: 'space-between',
107
+ borderTop: '1px solid rgba(0,0,0,0.08)',
108
+ paddingInline: 24,
109
+ paddingBlock: 12
110
+ } },
111
+ React.createElement("a", null, "\u8FDB\u5165\u56FE\u7247\u7A7A\u95F4"),
112
+ React.createElement(Space, { size: 12 },
113
+ React.createElement(Space, { style: {
114
+ fontSize: 12,
115
+ marginInlineEnd: 8,
116
+ color: 'rgba(0,0,0,0.6)'
117
+ }, size: 2 },
118
+ "\u6700\u591A\u9009",
119
+ React.createElement("span", { style: { color: '#FF7700' } }, maxLength),
120
+ "\u5F20\uFF0C\u5DF2\u9009",
121
+ React.createElement("span", { style: { color: '#FF7700' } }, getSelectKeyLength()),
122
+ "\u5F20"),
123
+ React.createElement(Button, { type: "primary", onClick: () => onConfirm() }, "\u786E\u5B9A"),
124
+ React.createElement(Button, { onClick: () => setIsOpenModal(false) }, "\u53D6\u6D88"))) },
125
+ React.createElement(Media, { directoryItems: directoryItem, items: mediaItem, onUpload: () => {
126
+ if (progress > 0) {
127
+ return;
128
+ }
129
+ uploadModal.ok(async (files) => {
130
+ if (files === undefined || files.length <= 0) {
131
+ return true;
132
+ }
133
+ setProgress(5);
134
+ const async = async () => {
135
+ const total = files.length;
136
+ let index = 0;
137
+ for (const file of files) {
138
+ index += 1;
139
+ // eslint-disable-next-line no-await-in-loop
140
+ await request.uploadFile(file);
141
+ setProgress(Math.min(5 + Math.floor(95 / total) * index, 100));
142
+ }
143
+ messageApi?.success('文件上传成功!');
144
+ setTimeout(() => {
145
+ setProgress(0);
146
+ }, 500);
147
+ // 刷新页面
148
+ refreshMedia();
149
+ };
150
+ async()
151
+ .then();
152
+ return true;
153
+ });
154
+ }, onDirectoryChange: (key, sortType, callback) => {
155
+ directoryCurrentRef.current = key.toString();
156
+ directoryCurrentSortTypeRef.current = sortType;
157
+ mediaCallbackRef.current = callback;
158
+ const selectItems = directoryGroupRef.current?.[directoryCurrentRef.current] ?? [];
159
+ setDirectorySelectMaxLength(maxLength - getSelectKeyLength() + selectItems.length);
160
+ setSelectItems(selectItems);
161
+ refreshMedia();
162
+ }, onFileChange: (items) => {
163
+ directoryGroupRef.current = {
164
+ ...(directoryGroupRef.current ?? {}),
165
+ [directoryCurrentRef.current]: items
166
+ };
167
+ setSelectItems(items);
168
+ }, value: selectItems, maxLength: directorySelectMaxLength })),
169
+ contextHolder,
170
+ contextUploadHolder)];
171
+ }
172
+ }