From 1b02ab8d38e7f995b5640410d14c1a413411f6f0 Mon Sep 17 00:00:00 2001 From: Martin Schuhmacher <55735359+MartinSchuhmacher@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:07:40 +0200 Subject: [PATCH 1/4] BC-8074 - Typo in Lernstore (#3402) - fixing typo in lernstore message --- src/locales/de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/de.ts b/src/locales/de.ts index 134f5ef0e2..ab661e990d 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -1464,7 +1464,7 @@ export default { "pages.content.index.search.placeholder": "Lern-Store durchsuchen", "pages.content.init_state.img_alt": "Initial state Image", "pages.content.init_state.message": - "Hier findest du hochwertige, auf dein Bundesland abgestimmte Inhalte.
Unser Team erschließt fortlaufend neue Materialen, um so dein Lernerlebnis weiter zu verbessern.

Hinweis:

Die im Lernstore angezeigten Materialien liegen nicht auf unserem Server, sondern werden über Schnittstellen zu anderen Servern verfügbar gemacht (Quellen sind zum Beispiel einzelne Bildungsserver, WirLernenOnline, Mundo u.a.).
Aus diesem Grund hat unser Team auch keinen Einfluss auf die dauerhafte Verfügbarkeit einzelner Materialien und auf das vollumfängliche Materialangebot der einzelnen Quellen.

Im Rahmen der Nutzung in Bildungseinrichtungen ist das Kopieren der Online-Medien auf Speichermedien, auf ein privates Endgerät oder auf Lernplattformen für einen geschlossenen Benutzerkreis ggf. erlaubt, soweit dies für die interne Verteilung und/oder Nutzung erforderlich ist.
Nach Beendigung der Arbeiten mit den jeweiligen Online-Medien sind diese von den privaten Endgeräten, Datenträgern und Lernplattformen zu löschen; spätestens beim Verlassen der Bildungseinrichtung.
Eine grundsätzliche Veröffentlichung (z.B. im Internet) der Online-Medien oder mit Teilen daraus neu hergestellten neuen und/oder bearbeiteten Werken ist grundsätzlich nicht zulässig, bzw. bedarf der Zustimmung des Rechtegebers.", + "Hier findest du hochwertige, auf dein Bundesland abgestimmte Inhalte.
Unser Team erschließt fortlaufend neue Materialien, um so dein Lernerlebnis weiter zu verbessern.

Hinweis:

Die im Lernstore angezeigten Materialien liegen nicht auf unserem Server, sondern werden über Schnittstellen zu anderen Servern verfügbar gemacht (Quellen sind zum Beispiel einzelne Bildungsserver, WirLernenOnline, Mundo u.a.).
Aus diesem Grund hat unser Team auch keinen Einfluss auf die dauerhafte Verfügbarkeit einzelner Materialien und auf das vollumfängliche Materialangebot der einzelnen Quellen.

Im Rahmen der Nutzung in Bildungseinrichtungen ist das Kopieren der Online-Medien auf Speichermedien, auf ein privates Endgerät oder auf Lernplattformen für einen geschlossenen Benutzerkreis ggf. erlaubt, soweit dies für die interne Verteilung und/oder Nutzung erforderlich ist.
Nach Beendigung der Arbeiten mit den jeweiligen Online-Medien sind diese von den privaten Endgeräten, Datenträgern und Lernplattformen zu löschen; spätestens beim Verlassen der Bildungseinrichtung.
Eine grundsätzliche Veröffentlichung (z.B. im Internet) der Online-Medien oder mit Teilen daraus neu hergestellten neuen und/oder bearbeiteten Werken ist grundsätzlich nicht zulässig, bzw. bedarf der Zustimmung des Rechtegebers.", "pages.content.init_state.title": "Willkommen im Lern-Store!", "pages.content.label.chooseACourse": "Wähle einen Kurs / Fach", "pages.content.label.chooseALessonTopic": "Wähle ein Unterrichtsthema", From 6e0ed21728715a87b3d86bcb67a6276ae0ec2f6a Mon Sep 17 00:00:00 2001 From: Gordon Nicholas <160246213+GordonNicholasCap@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:54:12 +0200 Subject: [PATCH 2/4] N21 2089 placeholder element media shelf (#3401) --- src/locales/de.ts | 1 + src/locales/en.ts | 1 + src/locales/es.ts | 1 + src/locales/uk.ts | 1 + .../DeletedElement.unit.ts | 31 ++---- .../media-shelf/MediaBoardElementDisplay.vue | 35 +++--- ...diaBoardExternalToolDeletedElement.unit.ts | 104 ++++++++++++++++++ .../MediaBoardExternalToolDeletedElement.vue | 46 ++++++++ .../media-shelf/MediaBoardLine.unit.ts | 61 +++++++++- .../feature/media-shelf/MediaBoardLine.vue | 21 +++- .../data/mediaBoardState.composable.ts | 13 ++- src/serverApi/v3/api.ts | 10 +- .../factory/deletedElementContentFactory.ts | 9 ++ .../factory/deletedElementResponseFactory.ts | 13 +++ tests/test-utils/factory/index.ts | 1 + 15 files changed, 304 insertions(+), 44 deletions(-) create mode 100644 src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.unit.ts create mode 100644 src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.vue create mode 100644 tests/test-utils/factory/deletedElementContentFactory.ts create mode 100644 tests/test-utils/factory/deletedElementResponseFactory.ts diff --git a/src/locales/de.ts b/src/locales/de.ts index ab661e990d..3efc985edd 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -97,6 +97,7 @@ export default { "common.medium.chip.deactivated": "Deaktiviert", "common.medium.chip.notLicensed": "Nicht freigeschaltet", "common.medium.chip.incomplete": "Konfiguration unvollständig", + "common.medium.chip.noLongerAvailable": "Nicht mehr verfügbar", "common.medium.information.admin": "Bitte Einstellungen überprüfen.", "common.medium.information.student": "Bitte an eine Lehrkraft wenden.", "common.medium.information.teacher": "Bitte an Schuladministrator:in wenden.", diff --git a/src/locales/en.ts b/src/locales/en.ts index f146b7dc3a..49ce83b3c6 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -97,6 +97,7 @@ export default { "common.medium.chip.deactivated": "Disabled", "common.medium.chip.notLicensed": "Not activated", "common.medium.chip.incomplete": "Configuration incomplete", + "common.medium.chip.noLongerAvailable": "No longer available", "common.medium.information.admin": "Please check settings.", "common.medium.information.student": "Please contact a teacher.", "common.medium.information.teacher": diff --git a/src/locales/es.ts b/src/locales/es.ts index cfd02ecde9..577a8f3423 100644 --- a/src/locales/es.ts +++ b/src/locales/es.ts @@ -97,6 +97,7 @@ export default { "common.medium.chip.deactivated": "Desactivado", "common.medium.chip.notLicensed": "No esta activado", "common.medium.chip.incomplete": "Configuración incompleta", + "common.medium.chip.noLongerAvailable": "Ya no está disponible", "common.medium.information.admin": "Por favor verifique la configuración.", "common.medium.information.student": "Por favor contacte a un maestro.", "common.medium.information.teacher": diff --git a/src/locales/uk.ts b/src/locales/uk.ts index 0bdc71c9f3..677427a7af 100644 --- a/src/locales/uk.ts +++ b/src/locales/uk.ts @@ -97,6 +97,7 @@ export default { "common.medium.chip.deactivated": "Вимкнено", "common.medium.chip.notLicensed": "Не активовано", "common.medium.chip.incomplete": "Конфігурація не завершена", + "common.medium.chip.noLongerAvailable": "Більше не доступний", "common.medium.information.admin": "Перевірте налаштування.", "common.medium.information.student": "Будь ласка, зверніться до вчителя.", "common.medium.information.teacher": diff --git a/src/modules/feature/board-deleted-element/DeletedElement.unit.ts b/src/modules/feature/board-deleted-element/DeletedElement.unit.ts index b573e6c11d..cca12dbf06 100644 --- a/src/modules/feature/board-deleted-element/DeletedElement.unit.ts +++ b/src/modules/feature/board-deleted-element/DeletedElement.unit.ts @@ -1,5 +1,4 @@ -import { ContentElementType, DeletedElementResponse } from "@/serverApi/v3"; -import { timestampsResponseFactory } from "@@/tests/test-utils"; +import { deletedElementResponseFactory } from "@@/tests/test-utils"; import { createTestingI18n, createTestingVuetify, @@ -15,16 +14,6 @@ import DeletedElementMenu from "./DeletedElementMenu.vue"; jest.mock("@data-board"); -const DELETED_ELEMENT: DeletedElementResponse = { - id: "deleted-element-id", - content: { - deletedElementType: ContentElementType.ExternalTool, - title: "Deleted Tool", - }, - type: ContentElementType.Deleted, - timestamps: timestampsResponseFactory.build(), -}; - describe("DeletedElement", () => { let useBoardFocusHandlerMock: DeepMocked< ReturnType @@ -50,7 +39,7 @@ describe("DeletedElement", () => { const getWrapper = ( props: ComponentProps = { - element: DELETED_ELEMENT, + element: deletedElementResponseFactory.build(), isEditMode: false, } ) => { @@ -75,7 +64,7 @@ describe("DeletedElement", () => { useBoardPermissionsMock.isTeacher = false; const { wrapper } = getWrapper({ - element: DELETED_ELEMENT, + element: deletedElementResponseFactory.build(), isEditMode: true, }); @@ -97,7 +86,7 @@ describe("DeletedElement", () => { describe("when in edit mode", () => { const setup = () => { const { wrapper } = getWrapper({ - element: DELETED_ELEMENT, + element: deletedElementResponseFactory.build(), isEditMode: true, }); @@ -118,7 +107,7 @@ describe("DeletedElement", () => { describe("when not in edit mode", () => { const setup = () => { const { wrapper } = getWrapper({ - element: DELETED_ELEMENT, + element: deletedElementResponseFactory.build(), isEditMode: false, }); @@ -138,24 +127,26 @@ describe("DeletedElement", () => { describe("when deleting the element", () => { const setup = () => { + const deletedElement = deletedElementResponseFactory.build(); const { wrapper } = getWrapper({ - element: DELETED_ELEMENT, + element: deletedElement, isEditMode: true, }); return { wrapper, + deletedElement, }; }; it("should emit an event", async () => { - const { wrapper } = setup(); + const { wrapper, deletedElement } = setup(); wrapper.findComponent(DeletedElementMenu).vm.$emit("delete:element"); await nextTick(); expect(wrapper.emitted("delete:element")).toEqual([ - [DELETED_ELEMENT.id], + [deletedElement.id], ]); }); }); @@ -165,7 +156,7 @@ describe("DeletedElement", () => { describe("when the deleted element was an external tool element", () => { const setup = () => { const { wrapper } = getWrapper({ - element: DELETED_ELEMENT, + element: deletedElementResponseFactory.build(), isEditMode: true, }); diff --git a/src/modules/feature/media-shelf/MediaBoardElementDisplay.vue b/src/modules/feature/media-shelf/MediaBoardElementDisplay.vue index 844dc9e25c..93cda800a9 100644 --- a/src/modules/feature/media-shelf/MediaBoardElementDisplay.vue +++ b/src/modules/feature/media-shelf/MediaBoardElementDisplay.vue @@ -18,20 +18,23 @@ :ripple="false" >
- - +
+ + +
+
@@ -70,6 +73,10 @@ defineProps({ element: { type: Object as PropType, }, + isUnavailable: { + type: Boolean, + default: false, + }, }); const card = ref(null); diff --git a/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.unit.ts b/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.unit.ts new file mode 100644 index 0000000000..24abee6797 --- /dev/null +++ b/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.unit.ts @@ -0,0 +1,104 @@ +import { + createTestingI18n, + createTestingVuetify, +} from "@@/tests/test-utils/setup"; +import { deletedElementResponseFactory } from "@@/tests/test-utils"; +import { mount } from "@vue/test-utils"; +import { BoardMenuActionDelete } from "@ui-board"; +import { nextTick } from "vue"; +import { ComponentProps } from "vue-component-type-helpers"; +import { VBtn } from "vuetify/lib/components/index.mjs"; +import MediaBoardExternalToolElementMenu from "./MediaBoardExternalToolElementMenu.vue"; +import MediaBoardDeletedElement from "./MediaBoardExternalToolDeletedElement.vue"; + +describe("MediaBoardDeletedElement", () => { + const getWrapper = ( + props: ComponentProps, + stubThreeDotMenu = true + ) => { + const wrapper = mount(MediaBoardDeletedElement, { + global: { + plugins: [createTestingVuetify(), createTestingI18n()], + }, + props, + stubs: { + MediaBoardExternalToolElementMenu: stubThreeDotMenu, + }, + }); + + return { + wrapper, + }; + }; + + describe("three dot menu", () => { + describe("when clicking on the the three dot menu", () => { + const setupOverlayDiv = () => { + const overlayDiv = document.createElement("div"); + overlayDiv.className = "v-overlay-container"; + document.body.append(); + }; + + const setup = () => { + const deletedElement = deletedElementResponseFactory.build(); + + const { wrapper } = getWrapper( + { + element: deletedElement, + }, + false + ); + + setupOverlayDiv(); + + return { + wrapper, + }; + }; + + afterEach(() => { + document.body.innerHTML = ""; + }); + + it("should show the delete action", async () => { + const { wrapper } = setup(); + + const menuBtn = wrapper + .getComponent(MediaBoardExternalToolElementMenu) + .getComponent(VBtn); + await menuBtn.trigger("click"); + + const deleteAction = wrapper.findComponent(BoardMenuActionDelete); + + expect(deleteAction.exists()).toEqual(true); + }); + }); + + describe("when deleting the element from the menu", () => { + const setup = () => { + const deletedElement = deletedElementResponseFactory.build(); + + const { wrapper } = getWrapper({ + element: deletedElement, + }); + + return { + wrapper, + deletedElement, + }; + }; + + it("should emit a delete event", async () => { + const { wrapper, deletedElement } = setup(); + + const menu = wrapper.getComponent(MediaBoardExternalToolElementMenu); + menu.vm.$emit("delete:element"); + await nextTick(); + + expect(wrapper.emitted("delete:element")).toEqual([ + [deletedElement.id], + ]); + }); + }); + }); +}); diff --git a/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.vue b/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.vue new file mode 100644 index 0000000000..a89fdc3cff --- /dev/null +++ b/src/modules/feature/media-shelf/MediaBoardExternalToolDeletedElement.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/modules/feature/media-shelf/MediaBoardLine.unit.ts b/src/modules/feature/media-shelf/MediaBoardLine.unit.ts index ac7daacce9..a30a07362a 100644 --- a/src/modules/feature/media-shelf/MediaBoardLine.unit.ts +++ b/src/modules/feature/media-shelf/MediaBoardLine.unit.ts @@ -1,5 +1,9 @@ import { MediaBoardLayoutType } from "@/serverApi/v3"; -import { mediaLineResponseFactory } from "@@/tests/test-utils"; +import { + deletedElementResponseFactory, + mediaExternalToolElementResponseFactory, + mediaLineResponseFactory, +} from "@@/tests/test-utils"; import { createTestingI18n, createTestingVuetify, @@ -18,6 +22,7 @@ import MediaBoardExternalToolElement from "./MediaBoardExternalToolElement.vue"; import MediaBoardLine from "./MediaBoardLine.vue"; import MediaBoardLineHeader from "./MediaBoardLineHeader.vue"; import MediaBoardLineMenu from "./MediaBoardLineMenu.vue"; +import MediaBoardExternalToolDeletedElement from "./MediaBoardExternalToolDeletedElement.vue"; jest.mock("@vueuse/core", () => { return { @@ -519,4 +524,58 @@ describe("MediaBoardLine", () => { expect(wrapper.emitted("delete:element")).toEqual([["elementId"]]); }); }); + + describe("when rendering an element", () => { + describe("when the element response is a DeletedElementResponse", () => { + const setup = () => { + const { wrapper } = getWrapper({ + line: mediaLineResponseFactory.build({ + elements: deletedElementResponseFactory.buildList(1), + }), + layout: MediaBoardLayoutType.List, + index: 0, + }); + + return { + wrapper, + }; + }; + + it("should render the element as MediaBoardExternalToolDeletedElement", () => { + const { wrapper } = setup(); + + const deletedElement = wrapper.findComponent( + MediaBoardExternalToolDeletedElement + ); + + expect(deletedElement.exists()).toEqual(true); + }); + }); + + describe("when the element response is a MediaExternalToolElementResponse", () => { + const setup = () => { + const { wrapper } = getWrapper({ + line: mediaLineResponseFactory.build({ + elements: mediaExternalToolElementResponseFactory.buildList(1), + }), + layout: MediaBoardLayoutType.List, + index: 0, + }); + + return { + wrapper, + }; + }; + + it("should render the element as MediaBoardExternalToolElement", () => { + const { wrapper } = setup(); + + const externalToolElement = wrapper.findComponent( + MediaBoardExternalToolElement + ); + + expect(externalToolElement.exists()).toEqual(true); + }); + }); + }); }); diff --git a/src/modules/feature/media-shelf/MediaBoardLine.vue b/src/modules/feature/media-shelf/MediaBoardLine.vue index 32bbe7526e..ba3165ee9a 100644 --- a/src/modules/feature/media-shelf/MediaBoardLine.vue +++ b/src/modules/feature/media-shelf/MediaBoardLine.vue @@ -53,9 +53,15 @@ @end="onElementDragEnd" >