From 542dd9c02bb75da76e91df57a1948c3863eeb0d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:12:15 +0300 Subject: [PATCH] chore: release v0.28.0 (#548) * chore: release v0.28.0 * chore: refactor * chore(lr-data-output): extract validation messages from the files * chrore: update changelog * chore: reorder native form validation messages * chore: improve condition for `isUploaded` flag * chore: make common progress bar fixed instead of absolute * chore: add `uploadProgress` property * chore: update changelog * Update CHANGELOG.md Co-authored-by: Kamilla Garifullina <92852785+KamillaGarifullina@users.noreply.github.com> * Update CHANGELOG.md Co-authored-by: Kamilla Garifullina <92852785+KamillaGarifullina@users.noreply.github.com> * Update CHANGELOG.md Co-authored-by: Kamilla Garifullina <92852785+KamillaGarifullina@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] Co-authored-by: nd0ut Co-authored-by: Kamilla Garifullina <92852785+KamillaGarifullina@users.noreply.github.com> --- CHANGELOG.md | 68 +++++++++++++++++++ abstract/UploaderBlock.js | 4 +- blocks/DataOutput/DataOutput.js | 43 +++++++----- .../ProgressBarCommon/progress-bar-common.css | 2 +- env.js | 2 +- package-lock.json | 4 +- package.json | 2 +- types/exported.d.ts | 1 + 8 files changed, 102 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 466470a0d..ed512bb70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,71 @@ +# [0.28.0](https://github.com/uploadcare/blocks/compare/v0.27.6...v0.28.0) (2023-10-26) + +### BREAKING CHANGES + +#### `LR_DATA_OUTPUT` event on window + +Before: The `LR_DATA_OUTPUT` event only contained uploaded files and fired only when a file was uploaded, deleted, or edited. + +Now: The `LR_DATA_OUTPUT` event now includes all the files in the upload list, including those not yet uploaded, and it fires whenever there is any change in the file list. +The event firing is debounced with a 100ms delay. So, in this event, you receive a complete snapshot of the upload list's state. \*_Please note_ that if the file hasn't been uploaded yet, the data will be incomplete. Properties such as `uuid`, `cdnUrl` and others will not be accessible. Before accessing them, you should check the `isUploaded` flag, which is described below. + +```js +window.addEventListener('LR_DATA_OUTPUT', (e) => { + const entries = e.detail.data; + for (const entry of entries) { + if (entry.isUploaded) { + console.log('Uploaded', entry.uuid); + } else { + console.log('Not uploaded', entry.uploadProgress); + } + } +}); +``` + +- make `LR_DATA_OUTPUT` event frequent and contain all the files ([69105e4](https://github.com/uploadcare/blocks/commit/69105e4806e9ca2d4254bce297c48e0990663212)) + +#### `lr-data-output` event on `lr-data-output` block (tag) + +Before: The `lr-data-output` event mirrors the `LR_DATA_OUTPUT` event. When the `group-output` option is enabled or the `use-group` attribute is present, it always creates a group for the file list. + +Now: The `lr-data-output` event mirrors the `LR_DATA_OUTPUT` event. When the `group-output` option is enabled or the `use-group` attribute is present, a group is only created if all files are uploaded, and there are no validation errors. +Otherwise, the event contains undefined `groupData` and a list of files. + +### Features + +#### New file properties for the events payload + +The following events are affected: + +- `LR_DATA_OUTPUT` +- `LR_UPLOAD_FINISH` +- `LR_REMOVE` +- `LR_UPLOAD_START` +- `lr-data-output` + +What file properties have been added: + +```ts +validationErrorMessage: string | null; // message with the validation error +uploadError: Error | null; // error object with the upload error +file: File | Blob | null; // file object +externalUrl: string | null; // external URL for the file (when uploading from URL or external source) +isValid: boolean; // is file valid (passed validation checks) +isUploaded: boolean; // is file uploaded +uploadProgress: number; // upload progress in percents +``` + +- add new properties to the output file entry ([2821bf3](https://github.com/uploadcare/blocks/commit/2821bf381b7ed32c1ffe8908d8c71a86eaef9fde)) + +#### `lr-data-output` now uses native validation to show errors + +- **lr-data-output:** improve native form validation ([c329d4c](https://github.com/uploadcare/blocks/commit/c329d4c89b6735af373e234e6580a80fc830e320)) + +### Bug Fixes + +- **lr-config:** validate passed settings ([6012581](https://github.com/uploadcare/blocks/commit/60125813b6b4d6ff16fbecf96e0b6178c4ef106f)) +- show inline validation message for the `multiple-min` requirement check fail ([8af0fec](https://github.com/uploadcare/blocks/commit/8af0fec7015516a94791f30be48863fa10488a8b)) + ## [0.27.6](https://github.com/uploadcare/blocks/compare/v0.27.5...v0.27.6) (2023-10-20) ### Bug Fixes diff --git a/abstract/UploaderBlock.js b/abstract/UploaderBlock.js index e3ce66066..e8f3e2915 100644 --- a/abstract/UploaderBlock.js +++ b/abstract/UploaderBlock.js @@ -661,15 +661,17 @@ export class UploaderBlock extends ActivityBlock { isImage: uploadEntryData.isImage, mimeType: uploadEntryData.mimeType, }; + /** @type {import('../types/exported.js').OutputFileEntry} */ let outputItem = { ...fileInfo, file: uploadEntryData.file, externalUrl: uploadEntryData.externalUrl, cdnUrlModifiers: uploadEntryData.cdnUrlModifiers, cdnUrl: uploadEntryData.cdnUrl ?? fileInfo.cdnUrl ?? null, + uploadProgress: uploadEntryData.uploadProgress, validationErrorMessage: uploadEntryData.validationErrorMsg, uploadError: uploadEntryData.uploadError, - isUploaded: !!uploadEntryData.uuid && !!uploadEntryData.fileInfo, + isUploaded: !!uploadEntryData.uuid && !!uploadEntryData.fileInfo && !uploadEntryData.uploadError, isValid: !uploadEntryData.validationErrorMsg && !uploadEntryData.uploadError, }; data.push(outputItem); diff --git a/blocks/DataOutput/DataOutput.js b/blocks/DataOutput/DataOutput.js index b00691ef5..28c016d1e 100644 --- a/blocks/DataOutput/DataOutput.js +++ b/blocks/DataOutput/DataOutput.js @@ -73,15 +73,17 @@ export class DataOutput extends UploaderBlock { if (this.hasAttribute(this.dict.FORM_INPUT_ATTR) && this._dynamicInputsContainer) { this._dynamicInputsContainer.innerHTML = ''; /** @type {string[]} */ - let values; + let cdnUrls = []; + /** @type {import('../../index.js').OutputFileEntry[]} */ + let files = []; if (Array.isArray(data)) { - values = data.map((file) => /** @type {string} */ (file.cdnUrl)); - } else if (data?.groupData) { - values = [data.groupData.cdnUrl]; - } else { - values = []; + cdnUrls = data.map((file) => /** @type {string} */ (file.cdnUrl)); + files = data; + } else if (data?.files) { + cdnUrls = data.groupData ? [data.groupData.cdnUrl] : []; + files = data.files; } - for (let value of values) { + for (let value of cdnUrls) { let input = document.createElement('input'); input.type = 'hidden'; input.name = this.getAttribute(this.dict.INPUT_NAME_ATTR) || this.ctxName; @@ -89,10 +91,15 @@ export class DataOutput extends UploaderBlock { this._dynamicInputsContainer.appendChild(input); } if (this._validationInputElement) { - this._validationInputElement.value = values.length ? '__VALUE__' : ''; - const msg = this.$['*message']; - if (msg?.isError) { - this._validationInputElement.setCustomValidity(`${msg.caption}. ${msg.text}`); + this._validationInputElement.value = cdnUrls.length ? '__VALUE__' : ''; + const firstInvalidFile = files.find((file) => !file.isValid); + const firstInvalidFileMsg = + firstInvalidFile?.validationErrorMessage ?? firstInvalidFile?.uploadError?.message; + let globalMsg = this.$['*message']; + globalMsg = globalMsg?.isError ? `${globalMsg.caption}. ${globalMsg.text}` : undefined; + const msg = firstInvalidFileMsg ?? globalMsg; + if (msg) { + this._validationInputElement.setCustomValidity(msg); } else { this._validationInputElement.setCustomValidity(''); } @@ -113,20 +120,20 @@ export class DataOutput extends UploaderBlock { this.$.output = null; return; } - const allUploaded = data.every((item) => item.isUploaded); - if (allUploaded && (this.cfg.groupOutput || this.hasAttribute(this.dict.GROUP_ATTR))) { - let uuidList = data.map((fileDesc) => { - return fileDesc.uuid + (fileDesc.cdnUrlModifiers ? `/${fileDesc.cdnUrlModifiers}` : ''); - }); - const validationOk = data.every((item) => item.isValid); - if (!validationOk) { + if (this.cfg.groupOutput || this.hasAttribute(this.dict.GROUP_ATTR)) { + const isAllUploadedAndValid = data.every((item) => item.isUploaded && item.isValid); + if (!isAllUploadedAndValid) { this.$.output = { groupData: undefined, files: data, }; return; } + const uploadClientOptions = await this.getUploadClientOptions(); + const uuidList = data.map((fileDesc) => { + return fileDesc.uuid + (fileDesc.cdnUrlModifiers ? `/${fileDesc.cdnUrlModifiers}` : ''); + }); const resp = await uploadFileGroup(uuidList, uploadClientOptions); this.$.output = { groupData: resp, diff --git a/blocks/ProgressBarCommon/progress-bar-common.css b/blocks/ProgressBarCommon/progress-bar-common.css index 7ae80c467..297bcb164 100644 --- a/blocks/ProgressBarCommon/progress-bar-common.css +++ b/blocks/ProgressBarCommon/progress-bar-common.css @@ -1,5 +1,5 @@ lr-progress-bar-common { - position: absolute; + position: fixed; right: 0; bottom: 0; left: 0; diff --git a/env.js b/env.js index c858bf245..4b0e0e114 100644 --- a/env.js +++ b/env.js @@ -1,3 +1,3 @@ /** Do not edit this file manually. It's generated during build process. */ export const PACKAGE_NAME = 'blocks'; -export const PACKAGE_VERSION = '0.27.6'; +export const PACKAGE_VERSION = '0.28.0'; diff --git a/package-lock.json b/package-lock.json index e337b141f..7d416ba74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@uploadcare/blocks", - "version": "0.27.6", + "version": "0.28.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@uploadcare/blocks", - "version": "0.27.6", + "version": "0.28.0", "license": "MIT", "dependencies": { "@symbiotejs/symbiote": "^1.11.7", diff --git a/package.json b/package.json index 09bebf623..d098e342e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@uploadcare/blocks", - "version": "0.27.6", + "version": "0.28.0", "description": "Building blocks for Uploadcare products integration", "keywords": [ "web components", diff --git a/types/exported.d.ts b/types/exported.d.ts index a2ea1f724..18784984b 100644 --- a/types/exported.d.ts +++ b/types/exported.d.ts @@ -68,6 +68,7 @@ export type OutputFileEntry = Pick & externalUrl: string | null; isValid: boolean; isUploaded: boolean; + uploadProgress: number; }; export {};