From c3b679c73d82cf41437ab378024b1c063904bc1d Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Mon, 22 Apr 2024 14:20:01 +0200 Subject: [PATCH 01/20] Added unit tests for WelcomeWidget --- gulpfile.js | 11 +- package.json | 3 +- .../bundles/dn_welcome/WelcomeWidget.ts.vue | 13 +- .../dn_welcome/WelcomeWidgetFactory.ts | 2 +- .../dn_welcome/tests/WelcomeWidgetTest.ts | 132 ++++++++++++++++++ src/main/js/bundles/dn_welcome/tests/all.js | 1 + .../dn_welcome/tests/test-modules.d.ts | 25 ++++ tsconfig.json | 6 +- 8 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts create mode 100644 src/main/js/bundles/dn_welcome/tests/test-modules.d.ts diff --git a/gulpfile.js b/gulpfile.js index 334562f..9d4b8c7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -107,7 +107,16 @@ mapappsBrowserSync.registerTask({ npmModules: [ "mocha", "chai", - "@conterra/mapapps-mocha-runner" + "@conterra/mapapps-mocha-runner", + [ + "@vue/test-utils", + { + // need to overwrite main to load it into the browser + main: "dist/vue-test-utils.umd" + } + ], + // required as peer dependency of @vue/test-utils + "vue-template-compiler" ] }, // prevent reload by browser sync (reload triggered on watch end) diff --git a/package.json b/package.json index af3b813..44de337 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "tsx": "^4.6.0", "typescript": "5.2.2", "vue": "2.7.15", - "vue-template-compiler": "2.7.15" + "vue-template-compiler": "2.7.15", + "@vue/test-utils": "1.3.5" } } diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue b/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue index b4f26dd..9284f13 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue +++ b/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue @@ -16,7 +16,7 @@ --> diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts index 71265d7..28aec21 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts +++ b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts @@ -24,7 +24,7 @@ export default class WelcomeWidgetFactory { #config: Config; #windowToggleTool: any; #doNotShowStorageKey = "dn_welcome.doNotShow"; - #widget: Vue | undefined; + #widget: any; constructor(config?: Config) { this.#config = config || new Config(); diff --git a/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts b/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts new file mode 100644 index 0000000..7d2625d --- /dev/null +++ b/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts @@ -0,0 +1,132 @@ +/// +/// Copyright (C) 2023 con terra GmbH (info@conterra.de) +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import module from "module"; +import { assert } from "chai"; +import WelcomeWidget from "../WelcomeWidget.ts.vue"; +import "vue-test-support/initVue"; // This registers Vuetify in Vue +import { mount } from "@vue/test-utils"; + +describe(module.id, function () { + const elementExistenceTestCases = [ + { + message: "Button is visible when 'showButton' is true", + propName: "showButton", // If the data property with this name... + propValue: true, // ...has this value... + cssClassSelector: ".v-btn", // ...then look for the element in the Vue component under test matching this selector + shouldExist: true // and check if the element exists + }, + { + message: "Button is invisible when 'showButton' is false", + cssClassSelector: ".v-btn", + propName: "showButton", + propValue: false, + shouldExist: false + }, + { + message: "Checkbox is visible when 'showCheckbox' is true", + cssClassSelector: ".v-input--checkbox", + propName: "showCheckbox", + propValue: true, + shouldExist: true + }, + { + message: "Checkbox is invisible when 'showCheckbox' is false", + cssClassSelector: ".v-input--checkbox", + propName: "showCheckbox", + propValue: false, + shouldExist: false + }, + { + message: "Checkbox is selected when 'checkboxChecked' is true", + cssClassSelector: ".v-input--checkbox", + propName: "showCheckbox", + propValue: false, + shouldExist: false + }, + { + message: "Image is visible when 'showImage' is true", + cssClassSelector: ".v-image", + propName: "showImage", + propValue: true, + shouldExist: true + }, + { + message: "Heading should be visible if 'heading' property is set", + cssClassSelector: "h3", + propName: "heading", + propValue: "Welcome", + shouldExist: true + }, + { + message: "Heading should be invisible if 'heading' property is an empty string", + cssClassSelector: "h3", + propName: "heading", + propValue: "", + shouldExist: false + }, + { + message: "Info text should be visible if 'infoText' property is set", + cssClassSelector: ".dn-welcome-widget__info-text", + propName: "infoText", + propValue: "Lorem ipsum", + shouldExist: true + }, + { + message: "Info text should be invisible if 'infoText' property is an empty string", + cssClassSelector: ".dn-welcome-widget__info-text", + propName: "infoText", + propValue: "", + shouldExist: false + } + ]; + + elementExistenceTestCases.forEach(testCase => { + it(testCase.message, async function () { + const wrapper = mount(WelcomeWidget as any); + await wrapper.setData({ + [testCase.propName]: testCase.propValue + }); + + const element = wrapper.find(testCase.cssClassSelector); + assert.equal(element.exists(), testCase.shouldExist); + }); + + }); + + it("When 'buttonDependsOnCheckbox' is true and checkbox is not checked, the button should be disabled", async function () { + const wrapper = mount(WelcomeWidget as any); + await wrapper.setData({ + buttonDependsOnCheckbox: true, + checkboxChecked: false + }); + + const buttonWrapper = wrapper.findComponent({ name: 'v-btn' }); + assert.isTrue(buttonWrapper.vm.$props.disabled); + }); + + it("When 'buttonDependsOnCheckbox' is true and checkbox is checked, the button should be enabled", async function () { + const wrapper = mount(WelcomeWidget as any); + await wrapper.setData({ + buttonDependsOnCheckbox: true, + checkboxChecked: true + }); + + const buttonWrapper = wrapper.findComponent({ name: 'v-btn' }); + assert.isFalse(buttonWrapper.vm.$props.disabled); + }); + +}); diff --git a/src/main/js/bundles/dn_welcome/tests/all.js b/src/main/js/bundles/dn_welcome/tests/all.js index 7ecb546..22fda6e 100644 --- a/src/main/js/bundles/dn_welcome/tests/all.js +++ b/src/main/js/bundles/dn_welcome/tests/all.js @@ -13,3 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import "./WelcomeWidgetTest"; diff --git a/src/main/js/bundles/dn_welcome/tests/test-modules.d.ts b/src/main/js/bundles/dn_welcome/tests/test-modules.d.ts new file mode 100644 index 0000000..73bf155 --- /dev/null +++ b/src/main/js/bundles/dn_welcome/tests/test-modules.d.ts @@ -0,0 +1,25 @@ +/// +/// Copyright (C) 2023 con terra GmbH (info@conterra.de) +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +/* + * Copyright (C) con terra GmbH + */ + +// TODO: This module is really problematic because node's own "module" is also picked up by the compiler +declare module "module" { + export const id: string; +} +declare module "require"; diff --git a/tsconfig.json b/tsconfig.json index c1df1bb..26f5526 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,11 @@ "moduleResolution": "node", "baseUrl": ".", "paths": { - "*": ["./src/main/js/bundles/*", "./node_modules/@conterra/ct-mapapps-typings/*"] + "*": [ + "./src/main/js/bundles/*", + "./node_modules/@conterra/ct-mapapps-typings/*", + "./node_modules/@vue/test-utils/types/*" + ] }, "allowJs": true, "noEmit": true, From 5c8e59b76cbcf655d961ebc79eb0b5db9f93ce65 Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Mon, 22 Apr 2024 16:03:41 +0200 Subject: [PATCH 02/20] DN-31: Improved layout in WelcomeWidget.ts.vue --- .../bundles/dn_welcome/WelcomeWidget.ts.vue | 19 +++++++++++++------ src/main/js/bundles/dn_welcome/css/styles.css | 8 ++++++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue b/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue index 9284f13..44a7dc7 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue +++ b/src/main/js/bundles/dn_welcome/WelcomeWidget.ts.vue @@ -16,16 +16,23 @@ --> diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts index 35bff48..fd79efe 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts +++ b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts @@ -17,7 +17,6 @@ import WelcomeWidget from "./WelcomeWidget.ts.vue"; import Vue from "apprt-vue/Vue"; import VueDijit from "apprt-vue/VueDijit"; -import {DOMPurify} from "dompurify-bundle"; import Config from "./Config"; export default class WelcomeWidgetFactory { @@ -45,7 +44,7 @@ export default class WelcomeWidgetFactory { const config = this.#config; const vm = this.#widget = new Vue(WelcomeWidget); vm.heading = config.heading; - vm.infoText = this.#sanitizeInfoText(config.infoText); + vm.infoText = config.infoText; vm.infoTextUrl = config.infoTextUrl; vm.showButton = config.showButton; vm.buttonText = config.buttonText; @@ -74,10 +73,6 @@ export default class WelcomeWidgetFactory { } } - #sanitizeInfoText(infotext: string): string { - return DOMPurify.sanitize(infotext); - } - set config(config: Config) { this.#config = config; } From cdc0274a72fdd3d739d54352f60c42df91b5fcef Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 07:55:52 +0200 Subject: [PATCH 13/20] DN-26: Added unit test for HTML sanitizing --- .../dn_welcome/tests/WelcomeWidgetTest.ts | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts b/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts index f8f8258..0cf6c9d 100644 --- a/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts +++ b/src/main/js/bundles/dn_welcome/tests/WelcomeWidgetTest.ts @@ -142,4 +142,73 @@ describe(module.id, function () { const buttonWrapper = wrapper.findComponent({ name: 'v-btn' }); assert.isFalse(buttonWrapper.vm.$props.disabled); }); + + const sanitizerTests = [ + { + message: "Event attributes should be removed from info text", + testInfoText: "Welcome!

Click here!

", + shouldNotInclude: "onclick" + }, + { + message: "'script' tags should be removed from info text", + testInfoText: "Welcome! ", + shouldNotInclude: "script" + }, + { + message: "Uppercase 'SCRIPT' tags should be removed from info text", + testInfoText: "Welcome! ", + shouldNotInclude: "SCRIPT" + }, + { + message: "'iframe' tags should be removed from info text", + testInfoText: "Welcome! ", + shouldNotInclude: "iframe" + }, + { + message: "'object' tags should be removed from info text", + testInfoText: "Welcome! ", + shouldNotInclude: "object" + }, + { + message: "'embed' tags should be removed from info text", + testInfoText: "Welcome! ", + shouldNotInclude: "embed" + }, + { + message: "'i' tags should be preserved in info text", + testInfoText: "Welcome!", + shouldInclude: "" + }, + { + message: "'style' attributes on tags should be preserved in info text", + testInfoText: "

Welcome

", + shouldInclude: "style" + } + ] as SanitizerTestCase[]; + + sanitizerTests.forEach(testCase => { + it(testCase.message, async function () { + const wrapper = mount(WelcomeWidget); + await wrapper.setData({ + infoText: testCase.testInfoText + }); + const infoTextWrapper = wrapper.find(".dn-welcome-widget__info-text"); + + const html = infoTextWrapper.html(); + + if (testCase.shouldNotInclude) { + assert.notInclude(html, testCase.shouldNotInclude); + } + if (testCase.shouldInclude) { + assert.include(html, testCase.shouldInclude); + } + }); + }); }); + +interface SanitizerTestCase { + message: string; + testInfoText: string; + shouldNotInclude?: string; + shouldInclude?: string; +} From 1d6789563ae21c0059c5e04673c7c1f8f3763ed6 Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 08:15:59 +0200 Subject: [PATCH 14/20] DN-26: Removed drop shadow of main v-card element. --- src/main/js/bundles/dn_welcome/css/styles.css | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/js/bundles/dn_welcome/css/styles.css b/src/main/js/bundles/dn_welcome/css/styles.css index 4a1292a..18433a8 100644 --- a/src/main/js/bundles/dn_welcome/css/styles.css +++ b/src/main/js/bundles/dn_welcome/css/styles.css @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -.ctAppRoot .ctWindow.dn_welcome-widget .vue-base, -.ctAppRoot .ctWindow.dn_welcome-widget .layout { - height: 100%; -} - -.dn-welcome-widget__info-text--iframe { +.ctWindow .vue-base .dn-welcome-widget__info-text--iframe { border: none; width: 100%; height: 185px; } + +.ctWindow .vue-base .v-card.dn_welcome-widget__card-main { + box-shadow: none; +} From c3fd1eef7ef3b64964aeafc4b252bc663137cfd4 Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 08:26:45 +0200 Subject: [PATCH 15/20] DN-26: Removed comments from app.json --- src/main/js/apps/sample/app.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/js/apps/sample/app.json b/src/main/js/apps/sample/app.json index 8a350e3..85f46d2 100644 --- a/src/main/js/apps/sample/app.json +++ b/src/main/js/apps/sample/app.json @@ -35,13 +35,10 @@ "dn_welcome": { "Config": { "heading": "${welcome.heading}", -// "heading": "", "infoText": "${welcome.infoText}", -// "infoTextUrl": "resource('${app}:external-test-resources/infotext-with-heading.html')", -// "infoText": "", "showButton": true, "buttonText": "${welcome.buttonText}", - "buttonDependsOnCheckbox": true, + "buttonDependsOnCheckbox": false, "showCheckbox": true, "checkboxChecked": true, "checkboxText": "${welcome.checkboxText}", From 41adf196917aa28e1a743a81343782ae73a5a10b Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 09:17:56 +0200 Subject: [PATCH 16/20] DN-26: Moved configuration from Config to WelcomeWidgetFactory.ts --- src/main/js/apps/sample/app.json | 2 +- src/main/js/bundles/dn_welcome/Config.ts | 34 ----------------- .../dn_welcome/WelcomeWidgetFactory.ts | 37 ++++++++++++------- src/main/js/bundles/dn_welcome/manifest.json | 16 ++------ src/main/js/bundles/dn_welcome/module.ts | 3 +- 5 files changed, 28 insertions(+), 64 deletions(-) delete mode 100644 src/main/js/bundles/dn_welcome/Config.ts diff --git a/src/main/js/apps/sample/app.json b/src/main/js/apps/sample/app.json index 85f46d2..62b98bc 100644 --- a/src/main/js/apps/sample/app.json +++ b/src/main/js/apps/sample/app.json @@ -40,7 +40,7 @@ "buttonText": "${welcome.buttonText}", "buttonDependsOnCheckbox": false, "showCheckbox": true, - "checkboxChecked": true, + "checkboxChecked": false, "checkboxText": "${welcome.checkboxText}", "showImage": true, "imageHeight": "300px", diff --git a/src/main/js/bundles/dn_welcome/Config.ts b/src/main/js/bundles/dn_welcome/Config.ts deleted file mode 100644 index cdf998e..0000000 --- a/src/main/js/bundles/dn_welcome/Config.ts +++ /dev/null @@ -1,34 +0,0 @@ -/// -/// Copyright (C) 2024 con terra GmbH (info@conterra.de) -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -export default class Config { - constructor(props?: Partial) { - Object.assign(this, props); - } - - heading = "Welcome"; - infoText = ""; - infoTextUrl = ""; - showButton = true; - buttonText = ""; - buttonDependsOnCheckbox = false; - showCheckbox = false; - checkboxText = ""; - checkboxChecked = false; - showImage = true; - imageUrl = ""; - imageHeight = "200px"; -} diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts index fd79efe..607e18c 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts +++ b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts @@ -17,20 +17,17 @@ import WelcomeWidget from "./WelcomeWidget.ts.vue"; import Vue from "apprt-vue/Vue"; import VueDijit from "apprt-vue/VueDijit"; -import Config from "./Config"; export default class WelcomeWidgetFactory { - #config: Config; #windowToggleTool: any; #doNotShowStorageKey = "dn_welcome.doNotShow"; #widget: any; - constructor(config?: Config) { - this.#config = config || new Config(); + constructor(props: Partial) { + this.#widget = this.#createWelcomeWidget(props); } activate(): void { - this.#initComponent(); this.#applySavedDoNotShowWindowState(); } @@ -40,9 +37,8 @@ export default class WelcomeWidgetFactory { } } - #initComponent(): void { - const config = this.#config; - const vm = this.#widget = new Vue(WelcomeWidget); + #createWelcomeWidget(config: Partial): any { + const vm: any = new Vue(WelcomeWidget); vm.heading = config.heading; vm.infoText = config.infoText; vm.infoTextUrl = config.infoTextUrl; @@ -62,22 +58,35 @@ export default class WelcomeWidgetFactory { } else { localStorage.removeItem(this.#doNotShowStorageKey); } - this.#windowToggleTool.set("active", false); + this.#windowToggleTool?.set("active", false); }); + + return vm; } #applySavedDoNotShowWindowState(): void { const doNotShowAgain = localStorage.getItem(this.#doNotShowStorageKey); if (doNotShowAgain !== "1") { - this.#windowToggleTool.set("active", true); + this.#windowToggleTool?.set("active", true); } } - set config(config: Config) { - this.#config = config; - } - set windowToggleTool(tool: any) { this.#windowToggleTool = tool; } } + +interface Config { + heading: string; + infoText: string; + infoTextUrl: string; + showButton: boolean; + buttonText: string; + buttonDependsOnCheckbox: boolean; + showCheckbox: boolean; + checkboxText: string; + checkboxChecked: boolean; + showImage: boolean; + imageUrl: string; + imageHeight: string; +} diff --git a/src/main/js/bundles/dn_welcome/manifest.json b/src/main/js/bundles/dn_welcome/manifest.json index 540d2f1..0f68e84 100644 --- a/src/main/js/bundles/dn_welcome/manifest.json +++ b/src/main/js/bundles/dn_welcome/manifest.json @@ -57,9 +57,11 @@ "components": [ { "name": "Config", - "provides": "dn_welcome.Config", + "provides": "dijit.Widget", + "instanceFactory": true, "propertiesConstructor": true, "properties": { + "widgetRole": "welcomeWidget", "heading": "", "infoText": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", "infoTextUrl": "", @@ -72,20 +74,8 @@ "showImage": true, "imageHeight": "300px", "imageUrl": "" - } - }, - { - "name": "WelcomeWidgetFactory", - "provides": "dijit.Widget", - "instanceFactory": true, - "properties": { - "widgetRole": "welcomeWidget" }, "references": [ - { - "name": "config", - "providing": "dn_welcome.Config" - }, { "name": "windowToggleTool", "providing": "ct.tools.Tool", diff --git a/src/main/js/bundles/dn_welcome/module.ts b/src/main/js/bundles/dn_welcome/module.ts index e23eab2..f9a722a 100644 --- a/src/main/js/bundles/dn_welcome/module.ts +++ b/src/main/js/bundles/dn_welcome/module.ts @@ -14,5 +14,4 @@ /// limitations under the License. /// -export {default as WelcomeWidgetFactory} from "./WelcomeWidgetFactory"; -export {default as Config} from "./Config"; +export {default as Config} from "./WelcomeWidgetFactory"; From b17465486be8ad34f60677ec216033b525f570bf Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 09:25:01 +0200 Subject: [PATCH 17/20] DN-26: Migrated bundle.js files in dn_welcome bundle to TypeScript --- src/main/js/bundles/dn_welcome/nls/bundle.js | 26 ---------------- src/main/js/bundles/dn_welcome/nls/bundle.ts | 30 +++++++++++++++++++ .../js/bundles/dn_welcome/nls/de/bundle.js | 23 -------------- .../js/bundles/dn_welcome/nls/de/bundle.ts | 28 +++++++++++++++++ 4 files changed, 58 insertions(+), 49 deletions(-) delete mode 100644 src/main/js/bundles/dn_welcome/nls/bundle.js create mode 100644 src/main/js/bundles/dn_welcome/nls/bundle.ts delete mode 100644 src/main/js/bundles/dn_welcome/nls/de/bundle.js create mode 100644 src/main/js/bundles/dn_welcome/nls/de/bundle.ts diff --git a/src/main/js/bundles/dn_welcome/nls/bundle.js b/src/main/js/bundles/dn_welcome/nls/bundle.js deleted file mode 100644 index 73335bc..0000000 --- a/src/main/js/bundles/dn_welcome/nls/bundle.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2024 con terra GmbH (info@conterra.de) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -module.exports = { - root: ({ - bundleName: "Welcome", - bundleDescription: "The Welcome Bundle is a new widget for displaying a welcome screen with a Do-Not-Show-Again option", - tool: { - title: "Welcome Info", - tooltip: "Welcome Info" - } - }), - "de": true -}; diff --git a/src/main/js/bundles/dn_welcome/nls/bundle.ts b/src/main/js/bundles/dn_welcome/nls/bundle.ts new file mode 100644 index 0000000..ea68cd6 --- /dev/null +++ b/src/main/js/bundles/dn_welcome/nls/bundle.ts @@ -0,0 +1,30 @@ +/// +/// Copyright (C) 2024 con terra GmbH (info@conterra.de) +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +const i18n = { + root: ({ + bundleName: "Welcome", + bundleDescription: "The Welcome Bundle is a widget for displaying a welcome screen with a Do-Not-Show-Again option", + tool: { + title: "Welcome Info", + tooltip: "Welcome Info" + } + }), + "de": true +}; + +export type Messages = (typeof i18n)["root"]; +export default i18n; diff --git a/src/main/js/bundles/dn_welcome/nls/de/bundle.js b/src/main/js/bundles/dn_welcome/nls/de/bundle.js deleted file mode 100644 index 43c4589..0000000 --- a/src/main/js/bundles/dn_welcome/nls/de/bundle.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2024 con terra GmbH (info@conterra.de) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -module.exports = { - bundleName: "Welcome", - bundleDescription: "Das Welcome Bundle ist ein neues Widget mit dem man ein Startfenster konfigurieren kann.", - tool: { - title: "Welcome Info", - tooltip: "Welcome Info" - } -}; diff --git a/src/main/js/bundles/dn_welcome/nls/de/bundle.ts b/src/main/js/bundles/dn_welcome/nls/de/bundle.ts new file mode 100644 index 0000000..7608bb7 --- /dev/null +++ b/src/main/js/bundles/dn_welcome/nls/de/bundle.ts @@ -0,0 +1,28 @@ +/// +/// Copyright (C) 2024 con terra GmbH (info@conterra.de) +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { type Messages } from "../bundle"; + +const i18n = { + bundleName: "Welcome", + bundleDescription: "Das Welcome Bundle ist ein Widget mit dem man ein Startfenster konfigurieren kann.", + tool: { + title: "Welcome Info", + tooltip: "Welcome Info" + } +} satisfies Messages; + +export default i18n; From 1f740f307a3c6a760a45cf2fa4157c4e8d21904f Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 10:13:30 +0200 Subject: [PATCH 18/20] DN-26: Added docs for including external resources. --- src/main/js/bundles/dn_welcome/README.md | 38 +++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/js/bundles/dn_welcome/README.md b/src/main/js/bundles/dn_welcome/README.md index 1be95df..56efce9 100644 --- a/src/main/js/bundles/dn_welcome/README.md +++ b/src/main/js/bundles/dn_welcome/README.md @@ -28,11 +28,47 @@ All configuration is performed on the `Config` component as show in the followin "checkboxChecked": true, "showImage": true, "imageUrl": "resource('${app}:images/welcome.jpg')", - "imageHeight": "300px" + "imageHeight": "300px" } } } ``` + +### Including external resources + +In some cases, it is helpful to be able to include text or an image from an external location. +For example, if the info text in the dialog changes frequently, it may be easier to include the text from an external HTML file. +The file can then be edited by the responsible people without requiring access to the map.apps Manager. +Including the info text from an HTML file also allows for a much more sophisticated layout, if you include CSS. + +To do this, create an HTML file on a publicly accessible web server. The file should look something like this: + +````html + + +

Welcome IFrame

+

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.

+ + +```` + +In your `app.json`, configure the `infoTextUrl` property to the URL of that HTML file: + +````json +{ + "dn_welcome": { + "Config": { + "infoTextUrl": "https://www.example.com/resources/infotext.html" + } + } +} +```` + +The HTML file is then embedded within an Iframe in the welcome dialog. + +The same is possible for images at the top of the dialog. +Simply set the `imageUrl` to the URL of an external image, e.g. https://www.example.com/resources/myimage.jpg + #### Available properties All of these properties are optional. From db2245bc7df04e5cf2b52e4bc943b36daea3b307 Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 10:35:44 +0200 Subject: [PATCH 19/20] DN-26: Use "private" keyword for private members --- .../dn_welcome/WelcomeWidgetFactory.ts | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts index 607e18c..b060029 100644 --- a/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts +++ b/src/main/js/bundles/dn_welcome/WelcomeWidgetFactory.ts @@ -19,25 +19,25 @@ import Vue from "apprt-vue/Vue"; import VueDijit from "apprt-vue/VueDijit"; export default class WelcomeWidgetFactory { - #windowToggleTool: any; - #doNotShowStorageKey = "dn_welcome.doNotShow"; - #widget: any; + private _windowToggleTool: WindowToggleTool | undefined; + private doNotShowStorageKey = "dn_welcome.doNotShow"; + private widget: any; constructor(props: Partial) { - this.#widget = this.#createWelcomeWidget(props); + this.widget = this.createWelcomeWidget(props); } activate(): void { - this.#applySavedDoNotShowWindowState(); + this.applySavedDoNotShowWindowState(); } createInstance(): void | typeof VueDijit { - if (this.#widget) { - return VueDijit(this.#widget); + if (this.widget) { + return VueDijit(this.widget); } } - #createWelcomeWidget(config: Partial): any { + private createWelcomeWidget(config: Partial): any { const vm: any = new Vue(WelcomeWidget); vm.heading = config.heading; vm.infoText = config.infoText; @@ -54,25 +54,25 @@ export default class WelcomeWidgetFactory { vm.$on('close', () => { if (config.showCheckbox && vm.checkboxChecked) { - localStorage.setItem(this.#doNotShowStorageKey, "1"); + localStorage.setItem(this.doNotShowStorageKey, "1"); } else { - localStorage.removeItem(this.#doNotShowStorageKey); + localStorage.removeItem(this.doNotShowStorageKey); } - this.#windowToggleTool?.set("active", false); + this._windowToggleTool?.set("active", false); }); return vm; } - #applySavedDoNotShowWindowState(): void { - const doNotShowAgain = localStorage.getItem(this.#doNotShowStorageKey); + private applySavedDoNotShowWindowState(): void { + const doNotShowAgain = localStorage.getItem(this.doNotShowStorageKey); if (doNotShowAgain !== "1") { - this.#windowToggleTool?.set("active", true); + this._windowToggleTool?.set("active", true); } } - set windowToggleTool(tool: any) { - this.#windowToggleTool = tool; + set windowToggleTool(tool: WindowToggleTool) { + this._windowToggleTool = tool; } } @@ -90,3 +90,8 @@ interface Config { imageUrl: string; imageHeight: string; } + + +interface WindowToggleTool { + set(propName: "active", value: boolean): void; +} From 97676e65f6a3844d992c4d397d5d3533eb3b45e6 Mon Sep 17 00:00:00 2001 From: Marius Austerschulte Date: Wed, 24 Apr 2024 10:44:51 +0200 Subject: [PATCH 20/20] DN-26: Removed app.js file from sample app --- src/main/js/apps/sample/app.js | 16 ---------------- src/main/js/apps/sample/app.json | 3 --- 2 files changed, 19 deletions(-) delete mode 100644 src/main/js/apps/sample/app.js diff --git a/src/main/js/apps/sample/app.js b/src/main/js/apps/sample/app.js deleted file mode 100644 index b793db5..0000000 --- a/src/main/js/apps/sample/app.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2024 con terra GmbH (info@conterra.de) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import i18n from "dojo/i18n!./nls/bundle"; diff --git a/src/main/js/apps/sample/app.json b/src/main/js/apps/sample/app.json index 62b98bc..bf1e426 100644 --- a/src/main/js/apps/sample/app.json +++ b/src/main/js/apps/sample/app.json @@ -24,9 +24,6 @@ "toolset", "dn_welcome" ], - "require": [ - "${app}/app" - ], "i18n": [ "bundle" ]