From 393de42fec4462588390c1fcb3a3d7958bf7fccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Tue, 28 Sep 2021 15:08:29 +0200 Subject: [PATCH] Add client part --- .dockerignore | 4 + .github/dependabot.yaml | 8 ++ .gitignore | 1 + Dockerfile | 23 ++++- docker-compose.override.sample.yaml | 7 ++ geoportal/vars.yaml | 5 + package.json | 14 +++ tsconfig.json | 9 ++ vite.config.ts | 17 ++++ webcomponents/feedback.ts | 144 ++++++++++++++++++++++++++++ webcomponents/index.ts | 1 + webcomponents/window.d.ts | 3 + 12 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 vite.config.ts create mode 100644 webcomponents/feedback.ts create mode 100644 webcomponents/index.ts create mode 100644 webcomponents/window.d.ts diff --git a/.dockerignore b/.dockerignore index 8f2c1fa6a..493341346 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,3 +10,7 @@ !geoportal/geomapfish_geoportal/static !geoportal/geomapfish_geoportal/locale geoportal/geomapfish_geoportal/locale/*.pot +!webcomponents +!package.json +!tsconfig.json +!vite.config.ts diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 24364c134..087c65a0d 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -7,3 +7,11 @@ updates: time: '04:00' ignore: - dependency-name: none + + - package-ecosystem: npm + directory: / + schedule: + interval: daily + open-pull-requests-limit: 20 + ignore: + - dependency-name: none diff --git a/.gitignore b/.gitignore index 4a27d5f3f..8d9de830a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ __pycache__/ !/CONST_create_template/geoportal/geomapfish_geoportal/locale/ !/CONST_create_template/geoportal/geomapfish_geoportal/static/ /yandex +/node_modules diff --git a/Dockerfile b/Dockerfile index c1e7dd7a0..e31c4b614 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ ENV SIMPLE=$SIMPLE RUN build-l10n "geomapfish" +# hadolint ignore=DL3059 RUN \ cd /tmp/config/geoportal/ && \ c2c-template --vars ${VARS_FILE} \ @@ -30,7 +31,7 @@ RUN \ ############################################################################### -FROM camptocamp/geomapfish-config:2.7 +FROM camptocamp/geomapfish-config:2.7 AS gmf-config ARG PGSCHEMA ENV PGSCHEMA=$PGSCHEMA @@ -66,3 +67,23 @@ VOLUME /etc/geomapfish \ /etc/gunicorn \ /etc/haproxy_dev \ /etc/haproxy + +############################################################################### + +FROM node:16-slim AS custom-build + +WORKDIR /app +COPY package.json ./ + +RUN npm install + +COPY package.json tsconfig.json vite.config.ts ./ +COPY webcomponents/ ./webcomponents/ +RUN npm run build + +CMD [ "npm", "run", "dev" ] + +############################################################################### + +FROM gmf-config AS config +COPY --from=custom-build /app/dist/ /etc/geomapfish/ diff --git a/docker-compose.override.sample.yaml b/docker-compose.override.sample.yaml index 920fb414e..d220feb56 100644 --- a/docker-compose.override.sample.yaml +++ b/docker-compose.override.sample.yaml @@ -77,3 +77,10 @@ services: extends: file: docker-compose-lib.yaml service: webpack_dev_server + + vite_dev_server: + build: + context: '.' + target: custom-build + volumes: + - ./:/app/ diff --git a/geoportal/vars.yaml b/geoportal/vars.yaml index f2e6ea299..6e16530fd 100644 --- a/geoportal/vars.yaml +++ b/geoportal/vars.yaml @@ -125,6 +125,11 @@ vars: gmfContextualDataOptions: projections: *alternate_projections rasterParams: {} + # For dev, the corresponding value in static should also be removed. + gmfCustomJavascriptUrl: https://localhost:8484/vite/custom.js + static: + gmfCustomJavascriptUrl: + name: '' desktop_alt: extends: desktop diff --git a/package.json b/package.json new file mode 100644 index 000000000..dbf25f306 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "custom", + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "tsc && vite build" + }, + "dependencies": {}, + "devDependencies": { + "lit": "2.0.0-rc.3", + "typescript": "4.3.2", + "vite": "2.5.4" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..0739e798f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["es2020", "dom"], + "moduleResolution": "node", + "experimentalDecorators": true + }, + "include": ["webcomponents/**/*.ts"], + "files": ["webcomponents/window.d.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 000000000..678cfbcb0 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,17 @@ +import {defineConfig} from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + server: { + port: 3001, + https: true, + open: 'webcomponents/index.js', + }, + build: { + lib: { + entry: 'webcomponents/index.ts', + formats: ['es'], + }, + sourcemap: true, + }, +}); diff --git a/webcomponents/feedback.ts b/webcomponents/feedback.ts new file mode 100644 index 000000000..102201323 --- /dev/null +++ b/webcomponents/feedback.ts @@ -0,0 +1,144 @@ +import {customElement, state} from 'lit/decorators.js'; +import {LitElement, html} from 'lit'; + +@customElement('proj-feedback') +export class ProjFeedback extends LitElement { + @state() + private show_modal = true; + @state() + private permalink: string; + private email: string; + private email_optional: string; + private feedback_text: string; + private url_: string; + private subscriptions_ = []; + + connectedCallback(): void { + super.connectedCallback(); + this.subscriptions_.push( + window.gmf.config.getConfig().subscribe({ + next: (configuration) => { + this.url_ = configuration.sitnFeedbackUrl; + }, + }) + ); + } + + render() { + return html` + ${this.show_modal + ? html` + ` + : html`
+
+

En cours d'envoi...

+
`}`; + } + + private feedbackSubmit() { + if ( + (this.email && this.email.indexOf('@') === -1) || + (this.email_optional && this.email_optional.indexOf('@') === -1) + ) { + alert("Une adresse email n'est pas valide"); + return; + } + + if (!this.feedback_text) { + alert('Veuillez saisir une descritption du problème.'); + return; + } + + if (this.feedback_text.length > 1000) { + alert('Votre texte est trop long (max 1000 caractères).'); + return; + } + this.show_modal = false; + + let url = new URL(this.url_); + let params = new URLSearchParams(url.search.slice(1)); + let formdata = new FormData(); + formdata.set('permalink', this.permalink.toString()); + formdata.set('ua', navigator.userAgent); + formdata.set('email', this.email); + formdata.set('email_optional', this.email_optional); + formdata.set('feedback', this.feedback_text); + + fetch(this.url_, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', + }, + body: formdata, + }).then( + () => { + this.show_modal = false; + alert( + [ + 'Merci! Votre demande est bien partie.', + '\n\n', + 'Suivant votre demande, une personne du SITN ', + 'prendra bientôt contact avec vous.', + ].join('') + ); + }, + () => { + alert('Une erreur est survenue. Merci de contacter le SITN (sitn@ne.ch)'); + } + ); + } + + // Disable shadow DOM + protected createRenderRoot(): LitElement { + return this; + } +} diff --git a/webcomponents/index.ts b/webcomponents/index.ts new file mode 100644 index 000000000..1377bd2c3 --- /dev/null +++ b/webcomponents/index.ts @@ -0,0 +1 @@ +import './feedback.ts'; diff --git a/webcomponents/window.d.ts b/webcomponents/window.d.ts new file mode 100644 index 000000000..46458f8ef --- /dev/null +++ b/webcomponents/window.d.ts @@ -0,0 +1,3 @@ +interface Window { + gmf: any; +}