From 90c6b6785bfa2ebed1c07519ed4b3915c65b7ad6 Mon Sep 17 00:00:00 2001 From: jojohoch <joachim.hoch@iqb.hu-berlin.de> Date: Tue, 25 Jan 2022 13:42:13 +0100 Subject: [PATCH] [editor] Implement ImportModuleVersion to handle backwards compatibility ImportModuleVersion stores the unitDefinitionType of the loaded unit definition. During the initialization of the unit, the individual elements can react to the stored value. --- docs/release-notes-player.txt | 8 +-- .../common/classes/importModuleVersion.ts | 62 +++++++++++++++++++ projects/common/models/unit.ts | 3 + .../ui-elements/dropdown/dropdown-element.ts | 6 +- .../ui-elements/likert/likert-element-row.ts | 6 +- .../radio-with-images/radio-group-images.ts | 6 +- .../radio/radio-button-group-element.ts | 6 +- .../toggle-button/toggle-button.ts | 6 +- 8 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 projects/common/classes/importModuleVersion.ts diff --git a/docs/release-notes-player.txt b/docs/release-notes-player.txt index ee6704784..2c674cf60 100644 --- a/docs/release-notes-player.txt +++ b/docs/release-notes-player.txt @@ -2,15 +2,15 @@ Player ====== 1.16.0 - Start the valid value range for DropDown, Likert, RadioGroup, RadioGroupImages and ToggleButton at 1 - Attention! This may cause incompatibility with tasks created with Editor < 1.22.0 or saved with Player < 1.16.0. - Preset and saved values for these elements will not be displayed correctly. -- Improve the centering of the layout + Attention! This can lead to incompatibilities when reloading units that were answered in IQB - TestCenter + with AspectPlayer < 1.16.0. Already saved results are displayed incorrectly for these elements. +- Improve centering of layout - Disable logs to console in production - Enable autostart of audios/videos when reloading the unit - Mark text without selecting first - Show marking options as popup when text is selected - Implement virtual keyboards for 'place value', 'numbers and basic operators', 'square, dash and dot' -- Show virtual keyboard optionally on the right side of the screen +- Show virtual keyboard optionally on the right side of the view 1.15.0 - Fix restoring of toggle buttons diff --git a/projects/common/classes/importModuleVersion.ts b/projects/common/classes/importModuleVersion.ts new file mode 100644 index 000000000..e5da40381 --- /dev/null +++ b/projects/common/classes/importModuleVersion.ts @@ -0,0 +1,62 @@ +export class ImportModuleVersion { + private static unitLoaded: boolean; + private static version: string; + + static setVersion(importedModuleVersion: string): void { + ImportModuleVersion.unitLoaded = false; + ImportModuleVersion.version = importedModuleVersion; + } + + static setUnitLoaded(): void { + ImportModuleVersion.unitLoaded = true; + } + + static isUnitLoaded(): boolean { + return ImportModuleVersion.unitLoaded; + } + + static getVersion(): { fullName: string, type: string, version: number[] } { + return { + fullName: ImportModuleVersion.version, + type: ImportModuleVersion.getVersionType(), + version: ImportModuleVersion.getVersionNumbers() + }; + } + + private static getVersionType(): string { + if (ImportModuleVersion.version && ImportModuleVersion.version.length) { + const importedModuleVersionArray = ImportModuleVersion.version.split('@'); + if (importedModuleVersionArray.length === 2) { + return importedModuleVersionArray[0]; + } + } + return 'none'; + } + + private static getVersionNumbers(): number[] { + if (ImportModuleVersion.version && ImportModuleVersion.version.length) { + const importedModuleVersionArray = ImportModuleVersion.version.split('@'); + if (importedModuleVersionArray.length === 2) { + const versionArray = importedModuleVersionArray[1].split('.'); + if (versionArray.length === 3) { + return versionArray.map(number => Number(number)); + } + } + } + return [0, 0, 0]; + } + + static verifyVersion(): boolean { + if (!ImportModuleVersion.getVersion().fullName) { + return false; + } + if (ImportModuleVersion.getVersionType() !== 'iqb-aspect-definition') { + return false; + } + const numbers = ImportModuleVersion.getVersionNumbers(); + if (numbers[0] < 1) { + return false; + } + return numbers[1] >= 1; + } +} diff --git a/projects/common/models/unit.ts b/projects/common/models/unit.ts index cba6a3b6e..fc6b21866 100644 --- a/projects/common/models/unit.ts +++ b/projects/common/models/unit.ts @@ -1,5 +1,6 @@ import { Page } from './page'; import { moveArrayItem } from '../util/array'; +import { ImportModuleVersion } from '../classes/importModuleVersion'; export const EXPORTED_MODULE_VERSION = 'iqb-aspect-definition@1.1.0'; @@ -9,9 +10,11 @@ export class Unit { constructor(serializedUnit?: Unit) { if (serializedUnit && serializedUnit.pages.length > 0) { + ImportModuleVersion.setVersion(serializedUnit.unitDefinitionType || ''); serializedUnit?.pages.forEach((page: Page) => { this.pages.push(new Page(page)); }); + ImportModuleVersion.setUnitLoaded(); } else { this.pages.push(new Page()); } diff --git a/projects/common/ui-elements/dropdown/dropdown-element.ts b/projects/common/ui-elements/dropdown/dropdown-element.ts index e03817807..d6ae6f2ea 100644 --- a/projects/common/ui-elements/dropdown/dropdown-element.ts +++ b/projects/common/ui-elements/dropdown/dropdown-element.ts @@ -8,6 +8,7 @@ import { UIElement } from '../../models/uI-element'; import { initFontElement, initPositionedElement, initSurfaceElement } from '../../util/unit-interface-initializer'; +import { ImportModuleVersion } from '../../classes/importModuleVersion'; export class DropdownElement extends InputElement implements PositionedElement, FontElement, SurfaceElement { options: string[] = []; @@ -30,8 +31,9 @@ export class DropdownElement extends InputElement implements PositionedElement, } handleBackwardsCompatibility(serializedElement: Partial<UIElement>): void { - if (serializedElement.value === 0 && serializedElement.options && serializedElement.options.length) { - this.value = 1; + if ((serializedElement.value || serializedElement.value === 0) && + !ImportModuleVersion.isUnitLoaded() && !ImportModuleVersion.verifyVersion()) { + this.value = Number(this.value) + 1; } } } diff --git a/projects/common/ui-elements/likert/likert-element-row.ts b/projects/common/ui-elements/likert/likert-element-row.ts index 5d0203656..b49b2bf0d 100644 --- a/projects/common/ui-elements/likert/likert-element-row.ts +++ b/projects/common/ui-elements/likert/likert-element-row.ts @@ -1,4 +1,5 @@ import { InputElement, LikertRow, UIElement } from '../../models/uI-element'; +import { ImportModuleVersion } from '../../classes/importModuleVersion'; export class LikertElementRow extends InputElement implements LikertRow { text: string = ''; @@ -12,8 +13,9 @@ export class LikertElementRow extends InputElement implements LikertRow { } handleBackwardsCompatibility(serializedElement: Partial<UIElement>): void { - if (serializedElement.value === 0 && serializedElement.columnCount) { - this.value = 1; + if ((serializedElement.value || serializedElement.value === 0) && + !ImportModuleVersion.isUnitLoaded() && !ImportModuleVersion.verifyVersion()) { + this.value = Number(this.value) + 1; } } } diff --git a/projects/common/ui-elements/radio-with-images/radio-group-images.ts b/projects/common/ui-elements/radio-with-images/radio-group-images.ts index 6c9987158..1a321d267 100644 --- a/projects/common/ui-elements/radio-with-images/radio-group-images.ts +++ b/projects/common/ui-elements/radio-with-images/radio-group-images.ts @@ -8,6 +8,7 @@ import { UIElement } from '../../models/uI-element'; import { initFontElement, initPositionedElement, initSurfaceElement } from '../../util/unit-interface-initializer'; +import { ImportModuleVersion } from '../../classes/importModuleVersion'; export class RadioGroupImagesElement extends InputElement implements PositionedElement, FontElement, SurfaceElement { columns: LikertColumn[] = []; // TODO @@ -32,8 +33,9 @@ export class RadioGroupImagesElement extends InputElement implements PositionedE } handleBackwardsCompatibility(serializedElement: Partial<UIElement>): void { - if (serializedElement.value === 0 && serializedElement.columns && serializedElement.columns.length) { - this.value = 1; + if ((serializedElement.value || serializedElement.value === 0) && + !ImportModuleVersion.isUnitLoaded() && !ImportModuleVersion.verifyVersion()) { + this.value = Number(this.value) + 1; } } } diff --git a/projects/common/ui-elements/radio/radio-button-group-element.ts b/projects/common/ui-elements/radio/radio-button-group-element.ts index c7f07e9fa..816b65a66 100644 --- a/projects/common/ui-elements/radio/radio-button-group-element.ts +++ b/projects/common/ui-elements/radio/radio-button-group-element.ts @@ -8,6 +8,7 @@ import { UIElement } from '../../models/uI-element'; import { initFontElement, initPositionedElement, initSurfaceElement } from '../../util/unit-interface-initializer'; +import { ImportModuleVersion } from '../../classes/importModuleVersion'; export class RadioButtonGroupElement extends InputElement implements PositionedElement, FontElement, SurfaceElement { options: string[] = []; @@ -41,8 +42,9 @@ export class RadioButtonGroupElement extends InputElement implements PositionedE } handleBackwardsCompatibility(serializedElement: Partial<UIElement>): void { - if (serializedElement.value === 0 && serializedElement.options && serializedElement.options.length) { - this.value = 1; + if ((serializedElement.value || serializedElement.value === 0) && + !ImportModuleVersion.isUnitLoaded() && !ImportModuleVersion.verifyVersion()) { + this.value = Number(this.value) + 1; } } } diff --git a/projects/common/ui-elements/toggle-button/toggle-button.ts b/projects/common/ui-elements/toggle-button/toggle-button.ts index e86578c1b..f582bbf47 100644 --- a/projects/common/ui-elements/toggle-button/toggle-button.ts +++ b/projects/common/ui-elements/toggle-button/toggle-button.ts @@ -6,6 +6,7 @@ import { FontProperties, SurfaceProperties } from '../../models/uI-element'; import { initFontElement, initSurfaceElement } from '../../util/unit-interface-initializer'; +import { ImportModuleVersion } from '../../classes/importModuleVersion'; export class ToggleButtonElement extends InputElement implements FontElement, SurfaceElement { options: string[] = ['A', 'B']; @@ -33,8 +34,9 @@ export class ToggleButtonElement extends InputElement implements FontElement, Su } handleBackwardsCompatibility(serializedElement: Partial<UIElement>): void { - if (serializedElement.value === 0 && serializedElement.options && serializedElement.options.length) { - this.value = 1; + if ((serializedElement.value || serializedElement.value === 0) && + !ImportModuleVersion.isUnitLoaded() && !ImportModuleVersion.verifyVersion()) { + this.value = Number(this.value) + 1; } } } -- GitLab