From 01cc2848ff766c218085290590bd3ad83e5d71e3 Mon Sep 17 00:00:00 2001 From: Petar Dimov Date: Thu, 4 Jul 2024 15:01:53 +0300 Subject: [PATCH 1/3] fix(ui5-upload-collection-item): delete can be triggered by keyboard now --- packages/fiori/src/UploadCollectionItem.ts | 15 +++++++++++++- .../fiori/test/pages/UploadCollection.html | 17 ++++++++++++++++ .../fiori/test/specs/UploadCollection.spec.js | 14 ++++++++++++- packages/main/package-scripts.cjs | 1 + packages/tools/components-package/nps.js | 6 +++--- .../tools/lib/buildTest/buildTemplates.js | 20 +++++++++++++++++++ packages/tools/lib/copy-and-watch/index.js | 13 ++++++++++++ 7 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/tools/lib/buildTest/buildTemplates.js diff --git a/packages/fiori/src/UploadCollectionItem.ts b/packages/fiori/src/UploadCollectionItem.ts index 34ea99335727..5f152871ff7d 100644 --- a/packages/fiori/src/UploadCollectionItem.ts +++ b/packages/fiori/src/UploadCollectionItem.ts @@ -14,7 +14,12 @@ import ProgressIndicator from "@ui5/webcomponents/dist/ProgressIndicator.js"; import ListItem from "@ui5/webcomponents/dist/ListItem.js"; import getFileExtension from "@ui5/webcomponents-base/dist/util/getFileExtension.js"; import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js"; -import { isEnter, isEscape, isSpace } from "@ui5/webcomponents-base/dist/Keys.js"; +import { + isDelete, + isEnter, + isEscape, + isSpace, +} from "@ui5/webcomponents-base/dist/Keys.js"; import UploadState from "./types/UploadState.js"; import "@ui5/webcomponents-icons/dist/refresh.js"; import "@ui5/webcomponents-icons/dist/stop.js"; @@ -243,6 +248,14 @@ class UploadCollectionItem extends ListItem { } } + _onkeyup(e: KeyboardEvent) { + super._onkeyup(e); + + if (isDelete(e) && !this.disableDeleteButton && !this.hideDeleteButton && !this.disabled) { + this._onDelete(); + } + } + _onDetailKeyup(e: KeyboardEvent) { if (isSpace(e)) { this.onDetailClick(); diff --git a/packages/fiori/test/pages/UploadCollection.html b/packages/fiori/test/pages/UploadCollection.html index 20bfc2ab41b1..caa784119cee 100644 --- a/packages/fiori/test/pages/UploadCollection.html +++ b/packages/fiori/test/pages/UploadCollection.html @@ -76,6 +76,23 @@ Some description. + + + Some description. + + + + Some description. + { it("upload collection should fire 'item-delete' regardless of the selectionMode", async () => { const uploadCollection = await browser.$("#uploadCollection"); const item = await browser.$("#latestReportsPdf"); + const itemsLength = (await uploadCollection.getProperty("items")).length; await uploadCollection.setAttribute("selection-mode", "None"); const deleteBtn = await item.shadow$(".ui5-upload-collection-deletebtn"); await deleteBtn.click(); - assert.strictEqual((await uploadCollection.getProperty("items")).length, 4, "item should be deleted when 'item-delete' event is fired"); + assert.strictEqual((await uploadCollection.getProperty("items")).length, itemsLength - 1, "item should be deleted when 'item-delete' event is fired"); + }); + + it("upload collection should fire 'item-delete' when 'DELETE' key is pressed on item", async () => { + const uploadCollection = await browser.$("#uploadCollection"); + const item = await browser.$("#reportPdf"); + const itemsLength = (await uploadCollection.getProperty("items")).length; + + await item.click(); + await browser.keys("Delete"); + + assert.strictEqual((await uploadCollection.getProperty("items")).length, itemsLength - 1, "item should be deleted when 'item-delete' event is fired"); }); it("item should fire 'retry'", async () => { diff --git a/packages/main/package-scripts.cjs b/packages/main/package-scripts.cjs index 1b3a58a91359..865cfbb9eb07 100644 --- a/packages/main/package-scripts.cjs +++ b/packages/main/package-scripts.cjs @@ -5,6 +5,7 @@ const options = { portStep: 2, noWatchTS: true, dev: true, + packageName: "main" }; const scripts = getScripts(options); diff --git a/packages/tools/components-package/nps.js b/packages/tools/components-package/nps.js index 86a06b9b3e9d..c0c06f7eb514 100644 --- a/packages/tools/components-package/nps.js +++ b/packages/tools/components-package/nps.js @@ -75,7 +75,7 @@ const getScripts = (options) => { }, build: { default: "nps prepare lint build.bundle", // build.bundle2 - templates: `mkdirp src/generated/templates && ${tsCrossEnv} node "${LIB}/hbs2ui5/index.js" -d src/ -o src/generated/templates`, + templates: `node "${LIB}/buildTest/buildTemplates.js" --packageName=${options.packageName}`, styles: { default: `concurrently "nps build.styles.themes" "nps build.styles.components" "nps build.styles.componentStyles"`, themes: `node "${LIB}/css-processors/css-processor-themes.mjs"`, @@ -102,9 +102,9 @@ const getScripts = (options) => { }, copy: { default: "nps copy.src copy.props", - src: `node "${LIB}/copy-and-watch/index.js" --silent "src/**/*.{js,json}" dist/`, + src: `node "${LIB}/copy-and-watch/index.js" --packageName=${options.packageName} --silent "src/**/*.{js,json}" dist/`, // srcGenerated2: `node "${LIB}/copy-and-watch/index.js" --silent "src/generated/**/*.{js,json}" dist/generated/`, - props: `node "${LIB}/copy-and-watch/index.js" --silent "src/**/*.properties" dist/`, + props: `node "${LIB}/copy-and-watch/index.js" --packageName=${options.packageName} --silent "src/**/*.properties" dist/`, }, watch: { default: `${tsCrossEnv} concurrently "nps watch.templates" "nps watch.typescript" "nps watch.src" "nps watch.styles" "nps watch.i18n" "nps watch.props"`, diff --git a/packages/tools/lib/buildTest/buildTemplates.js b/packages/tools/lib/buildTest/buildTemplates.js new file mode 100644 index 000000000000..133eb2a4aff4 --- /dev/null +++ b/packages/tools/lib/buildTest/buildTemplates.js @@ -0,0 +1,20 @@ +const mkdirp = require("mkdirp"); +const child_process = require("child_process"); +const path = require("path"); +const LIB = path.join(__dirname, `../../lib/`); + + +let packageName = process.argv.find((value) => { + return value.includes("packageName"); +}); + +if (packageName) { + packageName = packageName.replace("--packageName=", ""); +} + +console.log(`${packageName}:[build-templates][pid${process.pid}]: Taking ${JSON.stringify(process.memoryUsage().rss / 1024 / 1024)}MB memory`) + +mkdirp("src/generated/templates").then(() => { + child_process.execSync(`cross-env UI5_TS=true node ${LIB}/hbs2ui5/index.js -d src/ -o src/generated/templates`, { stdio: "inherit" }); + console.log(`${packageName}:[build-templates][pid${process.pid}]: Taking ${JSON.stringify(process.memoryUsage().rss / 1024 / 1024)}MB memory`) +}) \ No newline at end of file diff --git a/packages/tools/lib/copy-and-watch/index.js b/packages/tools/lib/copy-and-watch/index.js index ae974f511b95..18776bf4d848 100644 --- a/packages/tools/lib/copy-and-watch/index.js +++ b/packages/tools/lib/copy-and-watch/index.js @@ -55,6 +55,15 @@ const target = args.pop(); const sources = args; const parents = [...new Set(sources.map(globParent))]; +let packageName = process.argv.find((value) => { + return value.includes("packageName"); +}); + +if (packageName) { + packageName = packageName.replace("--packageName=", ""); +} + + const findTarget = from => { const parent = parents .filter(p => from.indexOf(p) >= 0) @@ -80,6 +89,7 @@ const createDirIfNotExist = to => { }); }; const copy = from => { + console.log(`${packageName}:[copy-and-watch][pid${process.pid}][copy]${sources}: Taking ${JSON.stringify(process.memoryUsage().rss / 1024 / 1024)}MB memory`) const to = findTarget(from); createDirIfNotExist(to); const stats = fs.statSync(from); @@ -90,11 +100,14 @@ const copy = from => { options.silent || console.log('[COPY]'.yellow, from, 'to'.yellow, to); }; const remove = from => { + console.log(`${packageName}:[copy-and-watch][pid${process.pid}][remove]${sources}: Taking ${JSON.stringify(process.memoryUsage().rss / 1024 / 1024)}MB memory`) const to = findTarget(from); fs.unlinkSync(to); options.silent || console.log('[DELETE]'.yellow, to); }; + const rimraf = dir => { + console.log(`${packageName}:[copy-and-watch][pid${process.pid}][rimraf]${sources}: Taking ${JSON.stringify(process.memoryUsage().rss / 1024 / 1024)}MB memory`) if (fs.existsSync(dir)) { fs.readdirSync(dir).forEach(entry => { const entryPath = path.join(dir, entry); From 87a8ed2b3ebd9d4b505b14c4c0831c117d0f2349 Mon Sep 17 00:00:00 2001 From: Petar Dimov Date: Thu, 4 Jul 2024 15:32:25 +0300 Subject: [PATCH 2/3] fix: prevent click on disabled item --- packages/fiori/src/themes/UploadCollectionItem.css | 1 - packages/fiori/test/specs/UploadCollection.spec.js | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/fiori/src/themes/UploadCollectionItem.css b/packages/fiori/src/themes/UploadCollectionItem.css index 8c328817ef5b..02241f08107a 100644 --- a/packages/fiori/src/themes/UploadCollectionItem.css +++ b/packages/fiori/src/themes/UploadCollectionItem.css @@ -17,7 +17,6 @@ .ui5-uci-buttons { display: flex; - pointer-events: all; margin-inline-start: 1rem; gap: 0.5rem; } diff --git a/packages/fiori/test/specs/UploadCollection.spec.js b/packages/fiori/test/specs/UploadCollection.spec.js index 9381972cb1ca..d5ff6ae6f5b5 100644 --- a/packages/fiori/test/specs/UploadCollection.spec.js +++ b/packages/fiori/test/specs/UploadCollection.spec.js @@ -127,6 +127,13 @@ describe("UploadCollection", () => { await browser.keys("Enter") }); + it("Disabled item", async () => { + const item = await browser.$("#disabledPdf"); + const deleteBtn = await item.shadow$(".ui5-upload-collection-deletebtn"); + + assert.notOk(await item.isClickable(), "Item shouldn't be clickable"); + assert.notOk(await deleteBtn.isClickable(), "Delete button shouldn't be clickable"); + }); }); describe("Events", () => { From e1c2be1bd5fc64f0e8ca4fd2116a172e5dad79a3 Mon Sep 17 00:00:00 2001 From: Petar Dimov Date: Fri, 5 Jul 2024 10:09:34 +0300 Subject: [PATCH 3/3] fix: tab index of delete button --- packages/fiori/src/UploadCollectionItem.hbs | 2 -- .../fiori/test/specs/UploadCollection.spec.js | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/fiori/src/UploadCollectionItem.hbs b/packages/fiori/src/UploadCollectionItem.hbs index f5ec24b2ea98..89f1b9edf5d8 100644 --- a/packages/fiori/src/UploadCollectionItem.hbs +++ b/packages/fiori/src/UploadCollectionItem.hbs @@ -99,8 +99,6 @@ {{#unless hideDeleteButton}} { }); }); + describe("Keyboard handling", () => { + it("Tab chain", async () => { + const isActiveElement = (element) => { + return browser.executeAsync((expectedActiveElem, done) => { + const activeElement = document.activeElement; + done(activeElement.shadowRoot.activeElement === expectedActiveElem); + }, element); + }; + + const item = await browser.$("#hiddenFileName"); + + await item.click(); + assert.ok(await item.isFocused(), "Item should be focused"); + + await browser.keys("Tab"); + assert.ok(await isActiveElement(await item.shadow$("[ui5-button][icon=refresh]")), "Retry button should be focused"); + + await browser.keys("Tab"); + assert.ok(await isActiveElement(await item.shadow$(".ui5-uci-edit")), "Edit button should be focused"); + + await browser.keys("Tab"); + assert.ok(await isActiveElement(await item.shadow$(".ui5-upload-collection-deletebtn")), "Delete button should be focused"); + }); + }); + describe("Edit - various file names", async () => { before(async () => { await browser.url(`test/pages/UploadCollection.html`);