Selaa lähdekoodia

add dynamic metaFields option (#2834)

* add dynamic metaFields option

Fixes: https://github.com/transloadit/uppy/issues/2591

* fixup! add dynamic metaFields option

* fixup! add dynamic metaFields option

* Update website/src/docs/dashboard.md

Co-authored-by: Artur Paikin <artur@arturpaikin.com>
Antoine du Hamel 4 vuotta sitten
vanhempi
commit
9e82431a16

+ 8 - 2
packages/@uppy/dashboard/src/components/FileCard/index.js

@@ -9,7 +9,7 @@ class FileCard extends Component {
     super(props)
 
     const file = this.props.files[this.props.fileCardFor]
-    const metaFields = this.props.metaFields || []
+    const metaFields = this.getMetaFields() || []
 
     const storedMetaData = {}
     metaFields.forEach((field) => {
@@ -49,7 +49,7 @@ class FileCard extends Component {
   }
 
   renderMetaFields = () => {
-    const metaFields = this.props.metaFields || []
+    const metaFields = this.getMetaFields() || []
     const fieldCSSClasses = {
       text: 'uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input',
     }
@@ -84,6 +84,12 @@ class FileCard extends Component {
     })
   }
 
+  getMetaFields () {
+    return typeof this.props.metaFields === 'function'
+      ? this.props.metaFields(this.props.files[this.props.fileCardFor])
+      : this.props.metaFields
+  }
+
   render () {
     const file = this.props.files[this.props.fileCardFor]
     const showEditButton = this.props.canEditFile(file)

+ 19 - 1
packages/@uppy/dashboard/src/index.test.js

@@ -1,7 +1,7 @@
 const Core = require('@uppy/core')
-const DashboardPlugin = require('./index')
 const StatusBarPlugin = require('@uppy/status-bar')
 const GoogleDrivePlugin = require('@uppy/google-drive')
+const DashboardPlugin = require('./index')
 
 describe('Dashboard', () => {
   it('can safely be added together with the StatusBar without id conflicts', () => {
@@ -91,4 +91,22 @@ describe('Dashboard', () => {
       core.getPlugin('Dashboard').i18n('myDevice')
     ).toEqual('Май дивайс')
   })
+
+  it('should accept a callback as `metaFields` option', () => {
+    const core = new Core()
+    expect(() => {
+      core.use(DashboardPlugin, {
+        metaFields: (file) => {
+          const fields = [{ id: 'name', name: 'File name' }]
+          if (file.type.startsWith('image/')) {
+            fields.push({ id: 'location', name: 'Photo Location' })
+            fields.push({ id: 'alt', name: 'Alt text' })
+          }
+          return fields
+        },
+      })
+    }).not.toThrow()
+
+    core.close()
+  })
 })

+ 1 - 1
packages/@uppy/dashboard/types/index.d.ts

@@ -35,7 +35,7 @@ declare module Dashboard {
     hideUploadButton?: boolean
     inline?: boolean
     locale?: DashboardLocale & StatusBar.StatusBarLocale
-    metaFields?: MetaField[]
+    metaFields?: MetaField[] | ((file: Uppy.UppyFile) => MetaField[])
     note?: string | null
     onRequestCloseModal?: () => void
     plugins?: string[]

+ 28 - 1
website/src/docs/dashboard.md

@@ -228,7 +228,7 @@ Optionally, specify a string of text that explains something about the upload fo
 
 ### `metaFields: []`
 
-An array of UI field objects that will be shown when a user clicks the “edit” button on that file. Configuring this enables the “edit” button on file cards. Each object requires:
+An array of UI field objects, or a function that takes a [File Object](https://uppy.io/docs/uppy/#File-Objects) and returns an array of UI field objects, that will be shown when a user clicks the “edit” button on that file. Configuring this enables the “edit” button on file cards. Each object requires:
 
 - `id`, the name of the meta field. Note: this will also be used in CSS/HTML as part of the `id` attribute, so it’s better to [avoid using characters like periods, semicolons, etc](https://stackoverflow.com/a/79022).
 - `name`, the label shown in the interface.
@@ -252,6 +252,33 @@ It gets passed `({value, onChange}, h)` where `value` is the current value of th
 })
 ```
 
+If you’d like the meta fields to be dynamically assigned depending on, for instance, the file type, pass a function:
+
+```js
+.use(Dashboard, {
+  trigger: '#pick-files',
+  metaFields: (file) => {
+    const fields = [{ id: 'name', name: 'File name' }]
+    if (file.type.startsWith('image/')) {
+      fields.push({ id: 'location', name: 'Photo Location' })
+      fields.push({ id: 'alt', name: 'Alt text' })
+      fields.push({
+        id: 'public',
+        name: 'Public',
+        render: ({ value, onChange }, h) => {
+          return h('input', {
+            type: 'checkbox',
+            onChange: (ev) => onChange(ev.target.checked ? 'on' : 'off'),
+            defaultChecked: value === 'on',
+          })
+        },
+      })
+    }
+    return fields
+  },
+})
+```
+
 ![](/images/uppy-dashboard-meta-fields.jpg)
 
 Note that this metadata will only be set on a file object if it is entered by the user. If the user doesn't edit a file's metadata, it will not have default values; instead everything will be `undefined`. If you want to set a certain meta field to each file regardless of user actions, set [`meta` in the Uppy constructor options](/docs/uppy/#meta).