diff --git a/client/src/lib/decorator-helpers.js b/client/src/lib/decorator-helpers.js index f5b0f3ab..f17d1569 100644 --- a/client/src/lib/decorator-helpers.js +++ b/client/src/lib/decorator-helpers.js @@ -11,7 +11,7 @@ export function createComponentMixin(opts) { }; } -export function withComponentMixins(mixins, delegateFuns) { +export function withComponentMixins(mixins, delegateFuns, delegateStaticFuns) { const mixinsClosure = new Set(); for (const mixin of mixins) { console.assert(mixin); @@ -53,6 +53,7 @@ export function withComponentMixins(mixins, delegateFuns) { return self; } + TargetClassWithCtors.displayName = TargetClass.name; TargetClassWithCtors.prototype = TargetClass.prototype; @@ -61,6 +62,20 @@ export function withComponentMixins(mixins, delegateFuns) { TargetClassWithCtors[attr] = TargetClass[attr]; } + function addStaticMethodsToClass(clazz) { + if (delegateStaticFuns) { + for (const staticFuncName of delegateStaticFuns) { + if (!clazz[staticFuncName]) { + Object.defineProperty( + clazz, + staticFuncName, + Object.getOwnPropertyDescriptor(TargetClass, staticFuncName) + ); + } + } + } + } + function incorporateMixins(DecoratedInner) { for (const mixin of mixinsClosure.values()) { if (mixin.decoratorFn) { @@ -102,6 +117,7 @@ export function withComponentMixins(mixins, delegateFuns) { this._decoratorInnerInstanceRefFn = node => this._decoratorInnerInstance = node } + render() { let innerFn = parentProps => { const props = { @@ -136,6 +152,7 @@ export function withComponentMixins(mixins, delegateFuns) { } } + addStaticMethodsToClass(ComponentMixinsOuter); return ComponentMixinsOuter; } else { @@ -163,6 +180,7 @@ export function withComponentMixins(mixins, delegateFuns) { return innerFn(props); } + addStaticMethodsToClass(ComponentContextProvider); return ComponentContextProvider; } diff --git a/client/src/lib/files.js b/client/src/lib/files.js index 9792e55c..3b64b760 100644 --- a/client/src/lib/files.js +++ b/client/src/lib/files.js @@ -45,7 +45,7 @@ export default class Files extends Component { usePublicDownloadUrls: true } - getFilesUploadedMessage(response){ + getFilesUploadedMessage(response) { const t = this.props.t; const details = []; if (response.data.added) { @@ -61,7 +61,7 @@ export default class Files extends Component { return t('countFileUploaded', {count: response.data.uploaded}) + detailsMessage; } - onDrop(files){ + onDrop(files) { const t = this.props.t; if (files.length > 0) { this.setFlashMessage('info', t('uploadingCountFile', {count: files.length})); @@ -70,23 +70,22 @@ export default class Files extends Component { data.append('files[]', file) } axios.post(getUrl(`rest/files/${this.props.entityTypeId}/${this.props.entitySubTypeId}/${this.props.entity.id}`), data) - .then(res => { - this.filesTable.refresh(); - const message = this.getFilesUploadedMessage(res); - this.setFlashMessage('info', message); - }) - .catch(res => this.setFlashMessage('danger', t('fileUploadFailed') + ' ' + res.message)); - } - else{ + .then(res => { + this.filesTable.refresh(); + const message = this.getFilesUploadedMessage(res); + this.setFlashMessage('info', message); + }) + .catch(res => this.setFlashMessage('danger', t('fileUploadFailed') + ' ' + res.message)); + } else { this.setFlashMessage('info', t('noFilesToUpload')); } } - deleteFile(fileId, fileName){ + deleteFile(fileId, fileName) { this.setState({fileToDeleteId: fileId, fileToDeleteName: fileName}) } - async hideDeleteFile(){ + async hideDeleteFile() { this.setState({fileToDeleteId: null, fileToDeleteName: null}) } diff --git a/client/src/lib/form.js b/client/src/lib/form.js index 9e5f1bda..de68464d 100644 --- a/client/src/lib/form.js +++ b/client/src/lib/form.js @@ -248,7 +248,7 @@ function wrapInput(id, htmlId, owner, format, rightContainerClass, label, help, if (format === 'inline') { return ( -