diff --git a/addon/components/multi-document-details.hbs b/addon/components/multi-document-details.hbs index 589a9b06..1df957d4 100644 --- a/addon/components/multi-document-details.hbs +++ b/addon/components/multi-document-details.hbs @@ -34,6 +34,7 @@ @color="danger" class="uk-width-1" {{on "click" showDialog}} + {{did-insert (fn this.registerDeleteDialog showDialog)}} > {{t "alexandria.delete"}} diff --git a/addon/components/multi-document-details.js b/addon/components/multi-document-details.js index a0f55eba..0f7133cb 100644 --- a/addon/components/multi-document-details.js +++ b/addon/components/multi-document-details.js @@ -1,7 +1,39 @@ +import { action } from "@ember/object"; import { inject as service } from "@ember/service"; import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; + export default class MultiDocumentDetailsComponent extends Component { @service("alexandria-side-panel") sidePanel; + @service("alexandria-documents") documents; + @tracked deleteDialog = null; + + constructor(parent, args) { + super(parent, args); + + this.boundHandleKeyDown = this.handleKeyDown.bind(this); + window.addEventListener("keydown", this.boundHandleKeyDown); + } + + @action + registerDeleteDialog(showDialog) { + this.deleteDialog = showDialog; + } + + willDestroy() { + super.willDestroy(); + window.removeEventListener("keydown", this.boundHandleKeyDown); + } + + handleKeyDown(event) { + if (this.documents.shortcutsDisabled) { + return; + } + + if (event.key === "Delete" && this.deleteDialog) { + this.deleteDialog(); + } + } get mergedTags() { const tags = []; diff --git a/addon/components/single-document-details.hbs b/addon/components/single-document-details.hbs index 58355c56..1e064142 100644 --- a/addon/components/single-document-details.hbs +++ b/addon/components/single-document-details.hbs @@ -249,6 +249,7 @@ @color="danger" class="uk-width-1" {{on "click" showDialog}} + {{did-insert (fn this.registerDeleteDialog showDialog)}} > {{t "alexandria.delete"}} diff --git a/addon/components/single-document-details.js b/addon/components/single-document-details.js index 4c71d5af..698c5666 100644 --- a/addon/components/single-document-details.js +++ b/addon/components/single-document-details.js @@ -20,6 +20,34 @@ export default class SingleDocumentDetailsComponent extends Component { @tracked editDescription = false; @tracked editDate = false; @tracked validTitle = true; + @tracked deleteDialog = null; + + constructor(parent, args) { + super(parent, args); + + this.boundHandleKeyDown = this.handleKeyDown.bind(this); + window.addEventListener("keydown", this.boundHandleKeyDown); + } + + @action + registerDeleteDialog(showDialog) { + this.deleteDialog = showDialog; + } + + willDestroy() { + super.willDestroy(); + window.removeEventListener("keydown", this.boundHandleKeyDown); + } + + handleKeyDown(event) { + if (this.documents.shortcutsDisabled) { + return; + } + + if (event.key === "Delete" && this.deleteDialog) { + this.deleteDialog(); + } + } get locale() { return this.intl.primaryLocale.split("-")[0]; diff --git a/tests/acceptance/documents-test.js b/tests/acceptance/documents-test.js index bf9f33bb..ddebd87d 100644 --- a/tests/acceptance/documents-test.js +++ b/tests/acceptance/documents-test.js @@ -5,6 +5,7 @@ import { fillIn, triggerEvent, settled, + waitFor, } from "@ember/test-helpers"; import { setupApplicationTest } from "dummy/tests/helpers"; import { setupMirage } from "ember-cli-mirage/test-support"; @@ -286,4 +287,73 @@ module("Acceptance | documents", function (hooks) { .dom("[data-test-document-list-item].document-list-item--selected") .doesNotExist(); }); + + test.each( + `trigger document delete with keyboard shortcut`, + ["single", "multiple"], + async function (assert, type) { + const documents = this.server.createList("document", 3); + + function isVisible(element) { + if (!element) { + return false; + } + + const style = window.getComputedStyle(element); + + return style.display !== "none"; + } + + await visit("/"); + assert.dom(".uk-modal").doesNotExist(); + + if (type === "single") { + // select first document and check the single document details + await click("[data-test-document-list-item]:first-child"); + + assert + .dom("[data-test-document-list-item].document-list-item--selected") + .exists({ count: 1 }); + assert.dom("[data-test-single-doc-details]").exists(); + } else { + // select multiple documents and check the multi document details + await click("[data-test-document-list-item]:first-child", { + shiftKey: true, + }); + await click("[data-test-document-list-item]:nth-child(3)", { + shiftKey: true, + }); + + assert + .dom("[data-test-document-list-item].document-list-item--selected") + .exists({ count: 3 }); + assert.dom("[data-test-multi-doc-details]").exists(); + } + + // assert modal visibility on keyboard shortcut + await waitFor(".uk-modal"); + assert.dom(".uk-modal").exists({ count: 1 }); + const modal = document.querySelector(".uk-modal"); + + assert.false(isVisible(modal)); + window.dispatchEvent(new KeyboardEvent("keydown", { key: "Delete" })); + await triggerEvent(window, "keydown", "Delete"); + assert.ok(isVisible(modal)); + + // assert modal body text + if (type === "single") { + assert + .dom(modal) + .containsText( + `Do you really want to delete the document "${documents[0].title}" and its complete history?`, + ); + } else { + assert + .dom(modal) + .containsText( + "Do you really want to delete 3 documents and their complete history?", + ); + } + }, + ); });