Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@uppy/dashboard

Package Overview
Dependencies
Maintainers
6
Versions
140
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uppy/dashboard - npm Package Compare versions

Comparing version 3.3.1 to 3.3.2

lib/components/FileCard/RenderMetaFields.js

296

lib/components/FileCard/index.js

@@ -1,2 +0,3 @@

import { h, Component } from 'preact';
import { h } from 'preact';
import { useEffect, useState, useCallback } from 'preact/hooks';
import classNames from 'classnames';

@@ -7,181 +8,130 @@ import { nanoid } from 'nanoid/non-secure';

import FilePreview from "../FilePreview.js";
import RenderMetaFields from "./RenderMetaFields.js";
export default function FileCard(props) {
var _getMetaFields;
class FileCard extends Component {
constructor(props) {
super(props);
this.form = document.createElement('form');
const {
uppy,
files,
fileCardFor,
toggleFileCard,
saveFileCard,
metaFields,
requiredMetaFields,
openFileEditor,
i18n,
i18nArray,
className,
canEditFile
} = props;
this.updateMeta = (newVal, name) => {
this.setState(_ref => {
let {
formState
} = _ref;
return {
formState: { ...formState,
[name]: newVal
}
};
});
};
const getMetaFields = () => {
return typeof metaFields === 'function' ? metaFields(files[fileCardFor]) : metaFields;
};
this.handleSave = e => {
e.preventDefault();
const fileID = this.props.fileCardFor;
this.props.saveFileCard(this.state.formState, fileID);
};
const file = files[fileCardFor];
const computedMetaFields = (_getMetaFields = getMetaFields()) != null ? _getMetaFields : [];
const showEditButton = canEditFile(file);
const storedMetaData = {};
computedMetaFields.forEach(field => {
var _file$meta$field$id;
this.handleCancel = () => {
const file = this.props.files[this.props.fileCardFor];
this.props.uppy.emit('file-editor:cancel', file);
this.props.toggleFileCard(false);
};
storedMetaData[field.id] = (_file$meta$field$id = file.meta[field.id]) != null ? _file$meta$field$id : '';
});
const [formState, setFormState] = useState(storedMetaData);
const handleSave = useCallback(ev => {
ev.preventDefault();
saveFileCard(formState, fileCardFor);
}, [saveFileCard, formState, fileCardFor]);
this.saveOnEnter = ev => {
if (ev.keyCode === 13) {
ev.stopPropagation();
ev.preventDefault();
const file = this.props.files[this.props.fileCardFor];
this.props.saveFileCard(this.state.formState, file.id);
}
};
const updateMeta = (newVal, name) => {
setFormState({
[name]: newVal
});
};
this.renderMetaFields = () => {
const metaFields = this.getMetaFields() || [];
const fieldCSSClasses = {
text: 'uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input'
};
return metaFields.map(field => {
const id = `uppy-Dashboard-FileCard-input-${field.id}`;
const required = this.props.requiredMetaFields.includes(field.id);
return h("fieldset", {
key: field.id,
className: "uppy-Dashboard-FileCard-fieldset"
}, h("label", {
className: "uppy-Dashboard-FileCard-label",
htmlFor: id
}, field.name), field.render !== undefined ? field.render({
value: this.state.formState[field.id],
onChange: newVal => this.updateMeta(newVal, field.id),
fieldCSSClasses,
required,
form: this.form.id
}, h) : h("input", {
className: fieldCSSClasses.text,
id: id,
form: this.form.id,
type: field.type || 'text',
required: required,
value: this.state.formState[field.id],
placeholder: field.placeholder // If `form` attribute is not supported, we need to capture pressing Enter to avoid bubbling in case Uppy is
// embedded inside a <form>.
,
onKeyUp: 'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter,
onKeyDown: 'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter,
onKeyPress: 'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter,
onInput: ev => this.updateMeta(ev.target.value, field.id),
"data-uppy-super-focusable": true
}));
});
};
const handleCancel = () => {
uppy.emit('file-editor:cancel', file);
toggleFileCard(false);
};
const _file = this.props.files[this.props.fileCardFor];
const _metaFields = this.getMetaFields() || [];
const storedMetaData = {};
_metaFields.forEach(field => {
storedMetaData[field.id] = _file.meta[field.id] || '';
});
this.state = {
formState: storedMetaData
const [form] = useState(() => {
const formEl = document.createElement('form');
formEl.setAttribute('tabindex', '-1');
formEl.id = nanoid();
return formEl;
});
useEffect(() => {
document.body.appendChild(form);
form.addEventListener('submit', handleSave);
return () => {
form.removeEventListener('submit', handleSave);
document.body.removeChild(form);
};
this.form.id = nanoid();
} // TODO(aduh95): move this to `UNSAFE_componentWillMount` when updating to Preact X+.
componentWillMount() {
// eslint-disable-line react/no-deprecated
this.form.addEventListener('submit', this.handleSave);
document.body.appendChild(this.form);
}
componentWillUnmount() {
this.form.removeEventListener('submit', this.handleSave);
document.body.removeChild(this.form);
}
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);
return h("div", {
className: classNames('uppy-Dashboard-FileCard', this.props.className),
"data-uppy-panelType": "FileCard",
onDragOver: ignoreEvent,
onDragLeave: ignoreEvent,
onDrop: ignoreEvent,
onPaste: ignoreEvent
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, this.props.i18nArray('editing', {
file: h("span", {
className: "uppy-DashboardContent-titleFile"
}, file.meta ? file.meta.name : file.name)
})), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
form: this.form.id,
title: this.props.i18n('finishEditingFile'),
onClick: this.handleCancel
}, this.props.i18n('cancel'))), h("div", {
className: "uppy-Dashboard-FileCard-inner"
}, h("div", {
className: "uppy-Dashboard-FileCard-preview",
style: {
backgroundColor: getFileTypeIcon(file.type).color
}
}, h(FilePreview, {
file: file
}), showEditButton && h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-Dashboard-FileCard-edit",
onClick: event => {
// When opening the image editor we want to save any meta fields changes.
// Otherwise it's confusing for the user to click save in the editor,
// but the changes here are discarded. This bypasses validation,
// but we are okay with that.
this.handleSave(event);
this.props.openFileEditor(file);
},
form: this.form.id
}, this.props.i18n('editFile'))), h("div", {
className: "uppy-Dashboard-FileCard-info"
}, this.renderMetaFields()), h("div", {
className: "uppy-Dashboard-FileCard-actions"
}, h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn" // If `form` attribute is supported, we want a submit button to trigger the form validation.
// Otherwise, fallback to a classic button with a onClick event handler.
,
type: 'form' in HTMLButtonElement.prototype ? 'submit' : 'button',
onClick: 'form' in HTMLButtonElement.prototype ? undefined : this.handleSave,
form: this.form.id
}, this.props.i18n('saveChanges')), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn",
type: "button",
onClick: this.handleCancel,
form: this.form.id
}, this.props.i18n('cancel')))));
}
}
export default FileCard;
}, [form, handleSave]);
return h("div", {
className: classNames('uppy-Dashboard-FileCard', className),
"data-uppy-panelType": "FileCard",
onDragOver: ignoreEvent,
onDragLeave: ignoreEvent,
onDrop: ignoreEvent,
onPaste: ignoreEvent
}, h("div", {
className: "uppy-DashboardContent-bar"
}, h("div", {
className: "uppy-DashboardContent-title",
role: "heading",
"aria-level": "1"
}, i18nArray('editing', {
file: h("span", {
className: "uppy-DashboardContent-titleFile"
}, file.meta ? file.meta.name : file.name)
})), h("button", {
className: "uppy-DashboardContent-back",
type: "button",
form: form.id,
title: i18n('finishEditingFile'),
onClick: handleCancel
}, i18n('cancel'))), h("div", {
className: "uppy-Dashboard-FileCard-inner"
}, h("div", {
className: "uppy-Dashboard-FileCard-preview",
style: {
backgroundColor: getFileTypeIcon(file.type).color
}
}, h(FilePreview, {
file: file
}), showEditButton && h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-Dashboard-FileCard-edit",
onClick: event => {
// When opening the image editor we want to save any meta fields changes.
// Otherwise it's confusing for the user to click save in the editor,
// but the changes here are discarded. This bypasses validation,
// but we are okay with that.
handleSave(event);
openFileEditor(file);
}
}, i18n('editFile'))), h("div", {
className: "uppy-Dashboard-FileCard-info"
}, h(RenderMetaFields, {
computedMetaFields: computedMetaFields,
requiredMetaFields: requiredMetaFields,
updateMeta: updateMeta,
form: form,
formState: formState
})), h("div", {
className: "uppy-Dashboard-FileCard-actions"
}, h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn" // If `form` attribute is supported, we want a submit button to trigger the form validation.
// Otherwise, fallback to a classic button with a onClick event handler.
,
type: "submit",
form: form.id
}, i18n('saveChanges')), h("button", {
className: "uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn",
type: "button",
onClick: handleCancel,
form: form.id
}, i18n('cancel')))));
}

@@ -93,2 +93,5 @@ import { h } from 'preact';

case 'error':
return i18n('error');
default:

@@ -95,0 +98,0 @@ }

@@ -21,3 +21,3 @@ function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }

const packageJson = {
"version": "3.3.1"
"version": "3.3.2"
};

@@ -24,0 +24,0 @@ import locale from './locale.js';

@@ -28,2 +28,4 @@ export default {

editing: 'Editing %{file}',
// Shown on the main upload screen when an upload error occurs
error: 'Error',
// Used as the screen reader label for the button that saves metadata edits and returns to the

@@ -30,0 +32,0 @@ // file list view.

{
"name": "@uppy/dashboard",
"description": "Universal UI plugin for Uppy.",
"version": "3.3.1",
"version": "3.3.2",
"license": "MIT",

@@ -28,6 +28,6 @@ "main": "lib/index.js",

"@uppy/informer": "^3.0.1",
"@uppy/provider-views": "^3.1.0",
"@uppy/status-bar": "^3.0.1",
"@uppy/provider-views": "^3.2.0",
"@uppy/status-bar": "^3.1.0",
"@uppy/thumbnail-generator": "^3.0.2",
"@uppy/utils": "^5.1.3",
"@uppy/utils": "^5.2.0",
"classnames": "^2.2.6",

@@ -43,8 +43,8 @@ "is-shallow-equal": "^1.0.1",

"@uppy/google-drive": "^3.1.0",
"@uppy/status-bar": "^3.0.1",
"@uppy/status-bar": "^3.1.0",
"resize-observer-polyfill": "^1.5.0"
},
"peerDependencies": {
"@uppy/core": "^3.1.1"
"@uppy/core": "^3.1.2"
}
}

@@ -1,202 +0,153 @@

import { h, Component } from 'preact'
import { h } from 'preact'
import { useEffect, useState, useCallback } from 'preact/hooks'
import classNames from 'classnames'
import { nanoid } from 'nanoid/non-secure'
import { nanoid } from 'nanoid/non-secure'
import getFileTypeIcon from '../../utils/getFileTypeIcon.jsx'
import ignoreEvent from '../../utils/ignoreEvent.js'
import FilePreview from '../FilePreview.jsx'
import RenderMetaFields from './RenderMetaFields.jsx'
class FileCard extends Component {
form = document.createElement('form')
export default function FileCard (props) {
const {
uppy,
files,
fileCardFor,
toggleFileCard,
saveFileCard,
metaFields,
requiredMetaFields,
openFileEditor,
i18n,
i18nArray,
className,
canEditFile,
} = props
constructor (props) {
super(props)
const file = this.props.files[this.props.fileCardFor]
const metaFields = this.getMetaFields() || []
const storedMetaData = {}
metaFields.forEach((field) => {
storedMetaData[field.id] = file.meta[field.id] || ''
})
this.state = {
formState: storedMetaData,
}
this.form.id = nanoid()
const getMetaFields = () => {
return typeof metaFields === 'function'
? metaFields(files[fileCardFor])
: metaFields
}
// TODO(aduh95): move this to `UNSAFE_componentWillMount` when updating to Preact X+.
componentWillMount () { // eslint-disable-line react/no-deprecated
this.form.addEventListener('submit', this.handleSave)
document.body.appendChild(this.form)
}
const file = files[fileCardFor]
const computedMetaFields = getMetaFields() ?? []
const showEditButton = canEditFile(file)
componentWillUnmount () {
this.form.removeEventListener('submit', this.handleSave)
document.body.removeChild(this.form)
}
const storedMetaData = {}
computedMetaFields.forEach((field) => {
storedMetaData[field.id] = file.meta[field.id] ?? ''
})
getMetaFields () {
return typeof this.props.metaFields === 'function'
? this.props.metaFields(this.props.files[this.props.fileCardFor])
: this.props.metaFields
}
const [formState, setFormState] = useState(storedMetaData)
updateMeta = (newVal, name) => {
this.setState(({ formState }) => ({
formState: {
...formState,
[name]: newVal,
},
}))
}
const handleSave = useCallback((ev) => {
ev.preventDefault()
saveFileCard(formState, fileCardFor)
}, [saveFileCard, formState, fileCardFor])
handleSave = (e) => {
e.preventDefault()
const fileID = this.props.fileCardFor
this.props.saveFileCard(this.state.formState, fileID)
const updateMeta = (newVal, name) => {
setFormState({ [name]: newVal })
}
handleCancel = () => {
const file = this.props.files[this.props.fileCardFor]
this.props.uppy.emit('file-editor:cancel', file)
this.props.toggleFileCard(false)
const handleCancel = () => {
uppy.emit('file-editor:cancel', file)
toggleFileCard(false)
}
saveOnEnter = (ev) => {
if (ev.keyCode === 13) {
ev.stopPropagation()
ev.preventDefault()
const file = this.props.files[this.props.fileCardFor]
this.props.saveFileCard(this.state.formState, file.id)
}
}
const [form] = useState(() => {
const formEl = document.createElement('form')
formEl.setAttribute('tabindex', '-1')
formEl.id = nanoid()
return formEl
})
renderMetaFields = () => {
const metaFields = this.getMetaFields() || []
const fieldCSSClasses = {
text: 'uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input',
useEffect(() => {
document.body.appendChild(form)
form.addEventListener('submit', handleSave)
return () => {
form.removeEventListener('submit', handleSave)
document.body.removeChild(form)
}
}, [form, handleSave])
return metaFields.map((field) => {
const id = `uppy-Dashboard-FileCard-input-${field.id}`
const required = this.props.requiredMetaFields.includes(field.id)
return (
<fieldset key={field.id} className="uppy-Dashboard-FileCard-fieldset">
<label className="uppy-Dashboard-FileCard-label" htmlFor={id}>{field.name}</label>
{field.render !== undefined
? field.render({
value: this.state.formState[field.id],
onChange: (newVal) => this.updateMeta(newVal, field.id),
fieldCSSClasses,
required,
form: this.form.id,
}, h)
: (
<input
className={fieldCSSClasses.text}
id={id}
form={this.form.id}
type={field.type || 'text'}
required={required}
value={this.state.formState[field.id]}
placeholder={field.placeholder}
// If `form` attribute is not supported, we need to capture pressing Enter to avoid bubbling in case Uppy is
// embedded inside a <form>.
onKeyUp={'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter}
onKeyDown={'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter}
onKeyPress={'form' in HTMLInputElement.prototype ? undefined : this.saveOnEnter}
onInput={ev => this.updateMeta(ev.target.value, field.id)}
data-uppy-super-focusable
/>
return (
<div
className={classNames('uppy-Dashboard-FileCard', className)}
data-uppy-panelType="FileCard"
onDragOver={ignoreEvent}
onDragLeave={ignoreEvent}
onDrop={ignoreEvent}
onPaste={ignoreEvent}
>
<div className="uppy-DashboardContent-bar">
<div className="uppy-DashboardContent-title" role="heading" aria-level="1">
{i18nArray('editing', {
file: <span className="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span>,
})}
</div>
<button
className="uppy-DashboardContent-back"
type="button"
form={form.id}
title={i18n('finishEditingFile')}
onClick={handleCancel}
>
{i18n('cancel')}
</button>
</div>
<div className="uppy-Dashboard-FileCard-inner">
<div className="uppy-Dashboard-FileCard-preview" style={{ backgroundColor: getFileTypeIcon(file.type).color }}>
<FilePreview file={file} />
{showEditButton
&& (
<button
type="button"
className="uppy-u-reset uppy-c-btn uppy-Dashboard-FileCard-edit"
onClick={(event) => {
// When opening the image editor we want to save any meta fields changes.
// Otherwise it's confusing for the user to click save in the editor,
// but the changes here are discarded. This bypasses validation,
// but we are okay with that.
handleSave(event)
openFileEditor(file)
}}
>
{i18n('editFile')}
</button>
)}
</fieldset>
)
})
}
</div>
render () {
const file = this.props.files[this.props.fileCardFor]
const showEditButton = this.props.canEditFile(file)
<div className="uppy-Dashboard-FileCard-info">
<RenderMetaFields
computedMetaFields={computedMetaFields}
requiredMetaFields={requiredMetaFields}
updateMeta={updateMeta}
form={form}
formState={formState}
/>
</div>
return (
<div
className={classNames('uppy-Dashboard-FileCard', this.props.className)}
data-uppy-panelType="FileCard"
onDragOver={ignoreEvent}
onDragLeave={ignoreEvent}
onDrop={ignoreEvent}
onPaste={ignoreEvent}
>
<div className="uppy-DashboardContent-bar">
<div className="uppy-DashboardContent-title" role="heading" aria-level="1">
{this.props.i18nArray('editing', {
file: <span className="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span>,
})}
</div>
<div className="uppy-Dashboard-FileCard-actions">
<button
className="uppy-DashboardContent-back"
className="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn"
// If `form` attribute is supported, we want a submit button to trigger the form validation.
// Otherwise, fallback to a classic button with a onClick event handler.
type="submit"
form={form.id}
>
{i18n('saveChanges')}
</button>
<button
className="uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn"
type="button"
form={this.form.id}
title={this.props.i18n('finishEditingFile')}
onClick={this.handleCancel}
onClick={handleCancel}
form={form.id}
>
{this.props.i18n('cancel')}
{i18n('cancel')}
</button>
</div>
<div className="uppy-Dashboard-FileCard-inner">
<div className="uppy-Dashboard-FileCard-preview" style={{ backgroundColor: getFileTypeIcon(file.type).color }}>
<FilePreview file={file} />
{showEditButton
&& (
<button
type="button"
className="uppy-u-reset uppy-c-btn uppy-Dashboard-FileCard-edit"
onClick={(event) => {
// When opening the image editor we want to save any meta fields changes.
// Otherwise it's confusing for the user to click save in the editor,
// but the changes here are discarded. This bypasses validation,
// but we are okay with that.
this.handleSave(event)
this.props.openFileEditor(file)
}}
form={this.form.id}
>
{this.props.i18n('editFile')}
</button>
)}
</div>
<div className="uppy-Dashboard-FileCard-info">
{this.renderMetaFields()}
</div>
<div className="uppy-Dashboard-FileCard-actions">
<button
className="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn"
// If `form` attribute is supported, we want a submit button to trigger the form validation.
// Otherwise, fallback to a classic button with a onClick event handler.
type={'form' in HTMLButtonElement.prototype ? 'submit' : 'button'}
onClick={'form' in HTMLButtonElement.prototype ? undefined : this.handleSave}
form={this.form.id}
>
{this.props.i18n('saveChanges')}
</button>
<button
className="uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn"
type="button"
onClick={this.handleCancel}
form={this.form.id}
>
{this.props.i18n('cancel')}
</button>
</div>
</div>
</div>
)
}
</div>
)
}
export default FileCard

@@ -71,2 +71,4 @@ import { h } from 'preact'

return i18n('uploadComplete')
case 'error':
return i18n('error')
default:

@@ -73,0 +75,0 @@ }

@@ -28,2 +28,4 @@ export default {

editing: 'Editing %{file}',
// Shown on the main upload screen when an upload error occurs
error: 'Error',
// Used as the screen reader label for the button that saves metadata edits and returns to the

@@ -30,0 +32,0 @@ // file list view.

@@ -18,2 +18,3 @@ /* eslint-disable */

| 'editing'
| 'error'
| 'finishEditingFile'

@@ -20,0 +21,0 @@ | 'saveChanges'

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc