feffery_antd_components 0.1.7 → 0.1.8

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.
@@ -27,6 +27,7 @@ const AntdUpload = (props) => {
27
27
  multiple,
28
28
  directory,
29
29
  failedTooltipInfo,
30
+ listUploadTaskRecord,
30
31
  loading_state,
31
32
  setProps
32
33
  } = props;
@@ -34,7 +35,6 @@ const AntdUpload = (props) => {
34
35
  uploadId = uploadId || uuid;
35
36
 
36
37
  const [fileList, updateFileList] = useState([]);
37
- const [lastFileError, updateLastFileError] = useState(false);
38
38
 
39
39
  let uploadProps = {
40
40
  name: 'file',
@@ -52,87 +52,158 @@ const AntdUpload = (props) => {
52
52
  if (fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) === -1) {
53
53
  message.error(`上传失败,${file.name} 文件格式不符合要求!`);
54
54
  }
55
- updateLastFileError(!sizeCheck || fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) === -1)
55
+
56
56
  return sizeCheck && fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) !== -1;
57
57
  }
58
58
 
59
- updateLastFileError(!sizeCheck)
60
59
  return sizeCheck;
61
60
  },
62
61
  onChange(info) {
63
62
 
64
- if (info.file.status === 'done') {
63
+ // 计算最近一次任务的子任务数量
64
+ let lastTaskCount
65
+ if (info.file.status === 'removed') {
66
+ lastTaskCount = 0
67
+ } else {
68
+ lastTaskCount = info.fileList.length - listUploadTaskRecord.length;
69
+ }
70
+
71
+ // 当上传模式为multiple或directory时
72
+ if (multiple || directory) {
73
+ // 若当前事件为removed
74
+ if (info.file.status === 'removed') {
65
75
 
66
- // 检查是否为多文件上传模式
67
- if (multiple || directory) {
68
- // 检查上传列表中是否全部文件都已完成上传
69
- if (info.fileList.every(file => file.status === 'done')) {
70
- console.log(info.fileList)
71
- // 更新任务记录
72
- setProps({
73
- lastUploadTaskRecord: info.fileList.map(
74
- (file) => {
75
- return {
76
- fileName: file.name,
77
- fileSize: file.size,
78
- completeTimestamp: new Date().getTime(),
79
- taskStatus: 'success',
80
- taskId: uploadId
81
- }
76
+ // 更新任务记录
77
+ setProps({
78
+ listUploadTaskRecord: info.fileList.map(
79
+ (file) => {
80
+ return {
81
+ fileName: file.name,
82
+ fileSize: file.size,
83
+ completeTimestamp: new Date().getTime(),
84
+ taskStatus: file.status === 'done' ? 'success' : 'failed',
85
+ taskId: uploadId
82
86
  }
83
- )
84
- })
85
- }
87
+ }
88
+ )
89
+ })
86
90
  } else {
91
+ // 其他常规事件
92
+ // 判断此次任务所有文件是否已上传结束(done或error)
93
+ if (info.fileList.slice(-lastTaskCount).every(file => file.status !== 'uploading')) {
94
+
95
+ if (info.fileList.slice(-lastTaskCount).every(file => !file.status)) {
96
+ } else {
97
+ if (lastTaskCount > 0) {
98
+
99
+ // 更新任务记录
100
+ setProps({
101
+ lastUploadTaskRecord: info.fileList.slice(-lastTaskCount).map(
102
+ (file) => {
103
+ return {
104
+ fileName: file.name,
105
+ fileSize: file.size,
106
+ completeTimestamp: new Date().getTime(),
107
+ taskStatus: file.status === 'done' ? 'success' : 'failed',
108
+ taskId: uploadId
109
+ }
110
+ }
111
+ ),
112
+ listUploadTaskRecord: info.fileList.map(
113
+ (file) => {
114
+ return {
115
+ fileName: file.name,
116
+ fileSize: file.size,
117
+ completeTimestamp: new Date().getTime(),
118
+ taskStatus: file.status === 'done' ? 'success' : 'failed',
119
+ taskId: uploadId
120
+ }
121
+ }
122
+ )
123
+ })
124
+ }
125
+ }
126
+
127
+ }
128
+
129
+ }
130
+
131
+ } else {
132
+ // 单文件上传模式
133
+ // 若当前事件为removed
134
+ if (info.file.status === 'removed') {
135
+
87
136
  // 更新任务记录
137
+ setProps({
138
+ listUploadTaskRecord: info.fileList.map(
139
+ (file) => {
140
+ return {
141
+ fileName: file.name,
142
+ fileSize: file.size,
143
+ completeTimestamp: new Date().getTime(),
144
+ taskStatus: file.status === 'done' ? 'success' : 'failed',
145
+ taskId: uploadId
146
+ }
147
+ }
148
+ )
149
+ })
150
+ } else if (info.file.status === 'done' || info.file.status === 'error' || !info.file.status) {
88
151
  setProps({
89
152
  lastUploadTaskRecord: {
90
153
  fileName: info.file.name,
91
154
  fileSize: info.file.size,
92
155
  completeTimestamp: new Date().getTime(),
93
- taskStatus: 'success',
156
+ taskStatus: info.file.status === 'done' ? 'success' : 'failed',
94
157
  taskId: uploadId
95
- }
158
+ },
159
+ listUploadTaskRecord: info.fileList.map(
160
+ (file) => {
161
+ return {
162
+ fileName: file.name,
163
+ fileSize: file.size,
164
+ completeTimestamp: new Date().getTime(),
165
+ taskStatus: file.status === 'done' ? 'success' : 'failed',
166
+ taskId: uploadId
167
+ }
168
+ }
169
+ )
96
170
  })
97
171
  }
172
+ }
98
173
 
174
+ if (info.file.status === 'done') {
99
175
  message.success(`${info.file.name} 上传成功!`);
100
176
  } else if (info.file.status === 'error') {
101
-
102
- // 更新任务记录
103
- setProps({
104
- lastUploadTaskRecord: {
105
- fileName: info.file.name,
106
- fileSize: info.file.size,
107
- completeTimestamp: new Date().getTime(),
108
- taskStatus: 'failed'
109
- }
110
- })
111
177
  message.error(`${info.file.name} 上传失败!`);
112
178
  }
113
179
 
114
- if (lastFileError && info.fileList.length !== 0) {
115
- info.fileList[info.fileList.length - 1].status = 'error'
116
180
 
117
- updateLastFileError(false)
118
- }
181
+ // 获取当前上传文件列表
182
+ let _fileList = [...info.fileList];
119
183
 
120
- info.fileList = info.fileList.map(
121
- item => {
122
- if (item.status === 'error') {
123
- item.response = failedTooltipInfo ? failedTooltipInfo : '上传失败'
124
- }
125
- return item
126
- }
127
- )
128
-
129
- // 基于fileListMaxLength参数设置,对fileList状态进行更新
184
+ // 是否限制上传记录列表最大数量
130
185
  if (fileListMaxLength) {
131
- updateFileList(info.fileList.slice(-fileListMaxLength))
132
- } else {
133
- updateFileList(info.fileList)
186
+ _fileList = _fileList.slice(-fileListMaxLength);
134
187
  }
135
- },
188
+
189
+ if (lastTaskCount !== 0) {
190
+ _fileList = _fileList.slice(0, _fileList.length - lastTaskCount)
191
+ .concat(
192
+ _fileList.slice(-lastTaskCount).map(
193
+ item => {
194
+ if (item.status === 'error' || !item.status) {
195
+
196
+ item.status = 'error'
197
+ item.response = failedTooltipInfo ? failedTooltipInfo : '上传失败'
198
+ }
199
+ return item
200
+ }
201
+ )
202
+ )
203
+ }
204
+
205
+ updateFileList(_fileList)
206
+ }
136
207
  };
137
208
 
138
209
  // 添加accept参数
@@ -248,6 +319,48 @@ AntdUpload.propTypes = {
248
319
  )
249
320
  ]),
250
321
 
322
+ // 用于在每次的上传任务完成后,更新当前文件列表中全部文件的上传信息
323
+ listUploadTaskRecord: PropTypes.oneOfType([
324
+ // 单文件
325
+ PropTypes.exact({
326
+ // 记录文件名称
327
+ fileName: PropTypes.string,
328
+
329
+ // 记录文件大小
330
+ fileSize: PropTypes.number,
331
+
332
+ // 记录完成时间戳信息
333
+ completeTimestamp: PropTypes.number,
334
+
335
+ // 记录此次上传任务的状态信息,'success'表示成功,'failed'表示失败
336
+ taskStatus: PropTypes.string,
337
+
338
+ // 记录本次任务的id信息,若最近一次任务状态为'failed',则不会携带此信息
339
+ taskId: PropTypes.string
340
+
341
+ }),
342
+ // 文件夹或多文件上传
343
+ PropTypes.arrayOf(
344
+ PropTypes.exact({
345
+ // 记录文件名称
346
+ fileName: PropTypes.string,
347
+
348
+ // 记录文件大小
349
+ fileSize: PropTypes.number,
350
+
351
+ // 记录完成时间戳信息
352
+ completeTimestamp: PropTypes.number,
353
+
354
+ // 记录此次上传任务的状态信息,'success'表示成功,'failed'表示失败
355
+ taskStatus: PropTypes.string,
356
+
357
+ // 记录本次任务的id信息,若最近一次任务状态为'failed',则不会携带此信息
358
+ taskId: PropTypes.string
359
+
360
+ })
361
+ )
362
+ ]),
363
+
251
364
  loading_state: PropTypes.shape({
252
365
  /**
253
366
  * Determines if the component is loading or not
@@ -274,7 +387,8 @@ AntdUpload.propTypes = {
274
387
  AntdUpload.defaultProps = {
275
388
  fileListMaxLength: null,
276
389
  fileMaxSize: 500,
277
- lastUploadTaskRecord: {},
390
+ lastUploadTaskRecord: null,
391
+ listUploadTaskRecord: [],
278
392
  locale: 'zh-cn'
279
393
  }
280
394
 
package/usage.py CHANGED
@@ -8,145 +8,120 @@ from dash.dependencies import Input, Output, State
8
8
  app = dash.Dash(__name__)
9
9
 
10
10
 
11
- @app.server.route('/upload/', methods=['POST'])
12
- def upload():
13
- '''
14
- 构建文件上传服务
15
- :return:
16
- '''
17
-
18
- # 获取上传id参数,用于指向保存路径
19
- uploadId = request.values.get('uploadId')
20
-
21
- # 获取上传的文件名称
22
- filename = request.files['file'].filename
23
-
24
- print({'filename': filename})
25
-
26
- return {'filename': filename}
27
-
28
-
29
- @app.callback(
30
- Output('output', 'children'),
31
- Input('input', 'lastUploadTaskRecord')
32
- )
33
- def test(lastUploadTaskRecord):
34
- if lastUploadTaskRecord:
35
- print(lastUploadTaskRecord)
36
-
37
- return dash.no_update
38
-
39
11
  app.layout = html.Div(
40
12
  [
41
13
 
42
- fac.AntdUpload(
43
- id='input',
44
- apiUrl='/upload/',
45
- directory=True
46
- ),
47
-
48
- html.Div(
49
- id='output'
50
- ),
51
-
52
14
  fac.AntdTable(
53
15
  columns=[
54
16
  {
55
- 'title': '图片字段测试',
56
- 'dataIndex': '图片字段测试',
57
- 'width': '200px',
17
+ 'title': '超链接示例',
18
+ 'dataIndex': '超链接示例',
58
19
  'renderOptions': {
59
- 'renderType': 'image'
20
+ 'renderType': 'link',
21
+ 'renderLinkText': '点击跳转'
60
22
  }
61
23
  }
62
24
  ],
63
25
  data=[
64
26
  {
65
- '图片字段测试': {
66
- 'src': 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
67
- 'height': '100%'
27
+ 'key': i,
28
+ '超链接示例': {
29
+ 'href': 'https://github.com/CNFeffery/feffery-antd-components'
68
30
  }
69
31
  }
70
- ] * 100,
32
+ for i in range(3)
33
+ ],
71
34
  bordered=True,
72
35
  style={
73
- 'width': '300px'
36
+ 'width': '250px'
74
37
  }
75
38
  ),
76
39
 
77
40
  fac.AntdTable(
78
- selectedRowKeys=['2', '4'],
79
- rowSelectionWidth='4rem',
80
41
  columns=[
81
42
  {
82
43
  'title': '默认的checkbox模式',
83
- 'dataIndex': f'默认的checkbox模式',
84
- 'width': '33.33%',
85
- 'conditionStyle': '''
86
- (record, index) => {
87
- if (record.默认的checkbox模式 >= 10) {
88
- return {
89
- style: {
90
- color: "red"
91
- }
92
- }
93
- }
94
- if (record.默认的checkbox模式 % 2 === 0) {
95
- return {
96
- style: {
97
- backgroundColor: "#ffe7ba"
98
- }
99
- }
100
- }
101
- return {
102
- style: {
103
- fontWeight: "bold"
104
- }
105
- }
106
- }
107
- '''
108
- # 'fixed': 'left'
44
+ 'dataIndex': '默认的checkbox模式',
45
+ 'width': '25%'
109
46
  },
110
47
  {
111
48
  'title': '自定义选项的checkbox模式',
112
49
  'dataIndex': '自定义选项的checkbox模式',
113
- 'width': '33.33%'
50
+ 'width': '25%'
114
51
  },
115
52
  {
116
53
  'title': 'keyword模式',
117
54
  'dataIndex': 'keyword模式',
118
- 'width': '33.33%'
55
+ 'width': '25%'
56
+ },
57
+ {
58
+ 'title': '数值测试',
59
+ 'dataIndex': '数值测试',
60
+ 'width': '25%',
61
+ 'renderOptions': {
62
+ 'renderType': 'custom-format'
63
+ }
119
64
  }
120
65
  ],
121
- sticky=True,
122
- pagination={
123
- 'pageSize': 100
124
- },
125
66
  data=[
126
67
  {
127
68
  '默认的checkbox模式': i,
128
69
  '自定义选项的checkbox模式': i,
129
- 'keyword模式': i
70
+ 'keyword模式': i,
71
+ '数值测试': np.random.rand()
130
72
  }
131
- for i in range(500)
73
+ for i in range(20)
132
74
  ],
75
+ bordered=True,
133
76
  filterOptions={
134
- '默认的checkbox模式': {
135
- 'filterMode': 'keyword'
136
- },
77
+ '默认的checkbox模式': {},
137
78
  '自定义选项的checkbox模式': {
138
- 'filterMode': 'keyword'
79
+ 'filterMode': 'checkbox',
80
+ 'filterCustomItems': [1, 2, 3],
81
+ 'filterMultiple': False,
82
+ 'filterSearch': True
139
83
  },
140
84
  'keyword模式': {
141
85
  'filterMode': 'keyword'
142
86
  }
143
87
  },
144
- rowSelectionType='checkbox',
145
- bordered=True,
146
- # maxHeight=200,
147
- maxWidth=1000,
148
- style={
149
- # 'width': '800px'
88
+ pagination={
89
+ 'pageSize': 20
90
+ },
91
+ customFormatFuncs={
92
+ '数值测试': '(x) => `${(x*100).toFixed(2)}%`'
93
+ },
94
+ conditionalStyleFuncs={
95
+ **{
96
+ key: '''
97
+ (record, index) => {
98
+ if ( index % 2 === 1 ) {
99
+ return {
100
+ style: {
101
+ backgroundColor: "rgb(250, 250, 250)"
102
+ }
103
+ }
104
+ }
105
+ }
106
+ '''
107
+ for key in ['默认的checkbox模式', '自定义选项的checkbox模式', 'keyword模式']
108
+ },
109
+ '数值测试': '''
110
+ (record, index) => {
111
+ if ( record['数值测试'] <= 0.5 ) {
112
+ return {
113
+ style: {
114
+ background: `linear-gradient(90deg, rgb(61, 153, 112) 0%, rgb(61, 153, 112) ${record['数值测试']*100}%, white ${record['数值测试']*100}%, white 100%)`
115
+ }
116
+ };
117
+ }
118
+ return {
119
+ style: {
120
+ background: `linear-gradient(90deg, rgb(255, 65, 54) 0%, rgb(255, 65, 54) ${record['数值测试']*100}%, white ${record['数值测试']*100}%, white 100%)`
121
+ }
122
+ };
123
+ }
124
+ '''
150
125
  }
151
126
  )
152
127
  ],