diff --git a/package-lock.json b/package-lock.json index ed750d69585d76c7d3f9d3c9af0b5b07b02e8126..aac4365c145df2276e626c9152f58a9009190219 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "geocontrib-frontend", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1104,6 +1104,54 @@ "to-fast-properties": "^2.0.0" } }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", + "integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==" + }, + "@fortawesome/fontawesome-free": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", + "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==", + "dev": true + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz", + "integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@fortawesome/free-brands-svg-icons": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.4.tgz", + "integrity": "sha512-f1witbwycL9cTENJegcmcZRYyawAFbm8+c6IirLmwbbpqz46wyjbQYLuxOc7weXFXfB7QR8/Vd2u5R3q6JYD9g==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.4.tgz", + "integrity": "sha512-9VNNnU3CXHy9XednJ3wzQp6SwNwT3XaM26oS4Rp391GsxVYA+0oDR2J194YCIWf7jNRCYKjUCOduxdceLrx+xw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz", + "integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@fortawesome/vue-fontawesome": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.6.tgz", + "integrity": "sha512-V3vT3flY15AKbUS31aZOP12awQI3aAzkr2B1KnqcHLmwrmy51DW3pwyBczKdypV8QxBZ8U68Hl2XxK2nudTxpg==" + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1154,6 +1202,19 @@ "postcss": "^7.0.0" } }, + "@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" + }, + "@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "requires": { + "@mapbox/point-geometry": "~0.1.0" + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -2174,6 +2235,12 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -3419,11 +3486,22 @@ "delayed-stream": "~1.0.0" } }, + "command-line-args": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.0.tgz", + "integrity": "sha512-4zqtU1hYsSJzcJBOcNZIbW5Fbk9BkjCp1pZVhQKoRaWL5J7N4XphDLwo8aWwdQpTugxwu+jf9u2ZhkXiqp5Z6A==", + "dev": true, + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, "commander": { "version": "2.17.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" }, "common-tags": { "version": "1.8.0", @@ -3766,6 +3844,16 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", @@ -5373,6 +5461,15 @@ "pkg-dir": "^4.1.0" } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + } + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -6084,8 +6181,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "iferr": { "version": "0.1.5", @@ -6882,6 +6978,17 @@ "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-1.0.4.tgz", "integrity": "sha512-rsQ6saQO5ST5Aj6XRFylr5zvarWgzWnrg46zQ1MEOEIHsppdC/8hnN8qMoFvACsPvTioAuysya/TVtog15tyAQ==" }, + "leaflet.vectorgrid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/leaflet.vectorgrid/-/leaflet.vectorgrid-1.3.0.tgz", + "integrity": "sha512-kWmj1pKM+MVdo/7Mg5zsB3YrGZvo/uIuiANV9MvWUFOG+Y2xAJzrteDhoIcCgTjHSSRJ36xdeGdIQVhuWjnCZw==", + "requires": { + "pbf": "^3.0.2", + "topojson-client": "^2.1.0", + "vector-tile": "^1.3.0", + "whatwg-fetch": "^2.0.3" + } + }, "less": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", @@ -7047,6 +7154,19 @@ } } }, + "local-cors-proxy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-cors-proxy/-/local-cors-proxy-1.1.0.tgz", + "integrity": "sha512-1UVrdG10HAT58TNZBhYSeMPkwQANuJunFsWBgEYOd1RChLDHGhvNPjUT8JsOlcqoJyr0QOH9cLx9IOLATf4j5w==", + "dev": true, + "requires": { + "chalk": "^2.3.2", + "command-line-args": "^5.0.2", + "cors": "^2.8.4", + "express": "^4.16.3", + "request": "^2.85.0" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7068,6 +7188,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -8213,6 +8339,15 @@ } } }, + "pbf": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "requires": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + } + }, "pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -8277,6 +8412,11 @@ "ts-pnp": "^1.1.6" } }, + "point-geometry": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/point-geometry/-/point-geometry-0.0.0.tgz", + "integrity": "sha1-b8vK16gDtkGCR91uScKFPFhNr/c=" + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -8952,6 +9092,11 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -9398,6 +9543,14 @@ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, + "resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "requires": { + "protocol-buffers-schema": "^3.3.1" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -10846,6 +10999,14 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "topojson-client": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-2.1.0.tgz", + "integrity": "sha1-/59784mRGF4LQoTCsGroNPDqxsg=", + "requires": { + "commander": "2" + } + }, "toposort": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", @@ -10932,6 +11093,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + }, "uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -11249,6 +11416,14 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, + "vector-tile": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/vector-tile/-/vector-tile-1.3.0.tgz", + "integrity": "sha1-BtUWqDsGPwTILvU5zxuxrr62lrQ=", + "requires": { + "point-geometry": "0.0.0" + } + }, "vendors": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", @@ -12075,6 +12250,11 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index b00e1bc1fb224879e7bf41aa88986e07e8b768e7..6288ae767b382e24b599d969739e7d3d9c545a0e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,11 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.36", + "@fortawesome/free-brands-svg-icons": "^5.15.4", + "@fortawesome/free-regular-svg-icons": "^5.15.4", + "@fortawesome/free-solid-svg-icons": "^5.15.4", + "@fortawesome/vue-fontawesome": "^2.0.6", "@mapbox/vector-tile": "^1.3.1", "@turf/flip": "^6.5.0", "axios": "^0.21.1", @@ -26,6 +31,7 @@ "vuex": "^3.6.2" }, "devDependencies": { + "@fortawesome/fontawesome-free": "^5.15.4", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-pwa": "~4.5.0", diff --git a/public/config/config.json b/public/config/config.json index 859464c3401983ee073000a70601cb67c0223024..65038a32551262edcccf998e4c66e7707f44de04 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -5,7 +5,7 @@ "VUE_APP_LOCALE":"fr-FR", "VUE_APP_APPLICATION_NAME":"GéoContrib", "VUE_APP_APPLICATION_ABSTRACT":"Application de saisie d'informations géographiques contributive", - "VUE_APP_LOGO_PATH":"@/assets/img/logo-neogeo-circle.png", + "VUE_APP_LOGO_PATH":"/geocontrib/img/logo-neogeo-circle.png", "VUE_APP_DJANGO_BASE":"http://localhost:8010", "VUE_APP_DJANGO_API_BASE":"http://localhost:8010/api/", "DEFAULT_BASE_MAP":{ diff --git a/public/img/icons/android-chrome-192x192.png b/public/img/icons/android-chrome-192x192.png index b02aa64d97167ad649e496908b35f14c603d9249..6cdb47eaf1fe19d451367d181cc4f817e65a655e 100644 Binary files a/public/img/icons/android-chrome-192x192.png and b/public/img/icons/android-chrome-192x192.png differ diff --git a/public/img/icons/android-chrome-512x512.png b/public/img/icons/android-chrome-512x512.png index 06088b011eccebb820b6e8de0cd244aa443208ba..226124806a29ad052689654f7e8fb70af5c72f9b 100644 Binary files a/public/img/icons/android-chrome-512x512.png and b/public/img/icons/android-chrome-512x512.png differ diff --git a/public/img/icons/android-chrome-maskable-192x192.png b/public/img/icons/android-chrome-maskable-192x192.png deleted file mode 100644 index 791e9c8c2c69ddb7be30cef2517dd6050b079cf0..0000000000000000000000000000000000000000 Binary files a/public/img/icons/android-chrome-maskable-192x192.png and /dev/null differ diff --git a/public/img/icons/android-chrome-maskable-512x512.png b/public/img/icons/android-chrome-maskable-512x512.png deleted file mode 100644 index 5f2098ed27e2f2878de62894b6c3bc31d07c585f..0000000000000000000000000000000000000000 Binary files a/public/img/icons/android-chrome-maskable-512x512.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon-120x120.png b/public/img/icons/apple-touch-icon-120x120.png deleted file mode 100644 index 1427cf62752646ad7217df0a61aa01fdef7475d1..0000000000000000000000000000000000000000 Binary files a/public/img/icons/apple-touch-icon-120x120.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon-152x152.png b/public/img/icons/apple-touch-icon-152x152.png deleted file mode 100644 index f24d454a2ecb8851bb893192b64ee09386d30e24..0000000000000000000000000000000000000000 Binary files a/public/img/icons/apple-touch-icon-152x152.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon-180x180.png b/public/img/icons/apple-touch-icon-180x180.png deleted file mode 100644 index 404e192a95ccccbede087203c42b1f25f6bc6e67..0000000000000000000000000000000000000000 Binary files a/public/img/icons/apple-touch-icon-180x180.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon-60x60.png b/public/img/icons/apple-touch-icon-60x60.png deleted file mode 100644 index cf10a5602e653bb126332934e2b7f34081c19a01..0000000000000000000000000000000000000000 Binary files a/public/img/icons/apple-touch-icon-60x60.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon-76x76.png b/public/img/icons/apple-touch-icon-76x76.png deleted file mode 100644 index c500769e3df9d6a6f1977ace8be4e63a8095e36a..0000000000000000000000000000000000000000 Binary files a/public/img/icons/apple-touch-icon-76x76.png and /dev/null differ diff --git a/public/img/icons/apple-touch-icon.png b/public/img/icons/apple-touch-icon.png index 03c0c5d5ec302ed7b0ee2c401df9427fb9d3c117..5ffc54a4f8b1f2a0b716fb4f5dc0cb045aa28b12 100644 Binary files a/public/img/icons/apple-touch-icon.png and b/public/img/icons/apple-touch-icon.png differ diff --git a/public/img/icons/favicon-16x16.png b/public/img/icons/favicon-16x16.png index 42af00963d81b8e39a30435c60ac482d1f8756e0..dfaab576ca4b539b968467eecdec33567bb0bafc 100644 Binary files a/public/img/icons/favicon-16x16.png and b/public/img/icons/favicon-16x16.png differ diff --git a/public/img/icons/favicon-32x32.png b/public/img/icons/favicon-32x32.png index 46ca04dee251a4fa85a2891a145fbe20cc619d96..c7dca04bdb68a81e35dd3d383097cc07a7f08604 100644 Binary files a/public/img/icons/favicon-32x32.png and b/public/img/icons/favicon-32x32.png differ diff --git a/public/img/icons/favicon.ico b/public/img/icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..05ea7edf1b8b946f3407db8b22353d908f31fd2d Binary files /dev/null and b/public/img/icons/favicon.ico differ diff --git a/public/img/icons/msapplication-icon-144x144.png b/public/img/icons/msapplication-icon-144x144.png deleted file mode 100644 index 7808237a18d4009501f950044f8388d13c5e1044..0000000000000000000000000000000000000000 Binary files a/public/img/icons/msapplication-icon-144x144.png and /dev/null differ diff --git a/public/img/icons/mstile-150x150.png b/public/img/icons/mstile-150x150.png deleted file mode 100644 index 3b37a43ae2fdef53050291d95da2e49f78cf398e..0000000000000000000000000000000000000000 Binary files a/public/img/icons/mstile-150x150.png and /dev/null differ diff --git a/public/img/icons/safari-pinned-tab.svg b/public/img/icons/safari-pinned-tab.svg deleted file mode 100644 index e44c0d5b0ff35e7facaed6353e0be801d4f3b10d..0000000000000000000000000000000000000000 --- a/public/img/icons/safari-pinned-tab.svg +++ /dev/null @@ -1,3 +0,0 @@ -<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/> -</svg> diff --git a/public/img/logo-neogeo-circle.png b/public/img/logo-neogeo-circle.png new file mode 100644 index 0000000000000000000000000000000000000000..427c1c63b8051722f05406349a48a073ac7ba927 Binary files /dev/null and b/public/img/logo-neogeo-circle.png differ diff --git a/src/App.vue b/src/App.vue index 940e4ea9c7ee80e27d188c66d6a644d4be5a1ef1..954fe28fa431592cd8f246ee7d8b0e35c8a0c703 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,10 +4,7 @@ <div class="menu container"> <div class="ui inverted icon menu"> <router-link to="/" class="header item"> - <img - class="ui mini right spaced image" - src="@/assets/img/logo-neogeo-circle.png" - /> + <img class="ui mini right spaced image" :src="logo" /> <span class="desktop"> {{ APPLICATION_NAME }} </span> @@ -202,16 +199,19 @@ export default { "loader", ]), ...mapGetters(["project"]), - APPLICATION_NAME: function () { + APPLICATION_NAME() { return this.configuration.VUE_APP_APPLICATION_NAME; }, PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || "0", - userFullname: function () { + logo() { + return this.configuration.VUE_APP_LOGO_PATH; + }, + userFullname() { if (this.user.first_name || this.user.last_name) return this.user.first_name + " " + this.user.last_name; return null; }, - isAdmin: function () { + isAdmin() { return this.USER_LEVEL_PROJECTS && this.USER_LEVEL_PROJECTS[this.project.slug] === "Administrateur projet" ? true diff --git a/src/assets/icons/fa-icons.js b/src/assets/icons/fa-icons.js new file mode 100644 index 0000000000000000000000000000000000000000..5e9fff5abcbe8853af77ce58452a4b98f77eb614 --- /dev/null +++ b/src/assets/icons/fa-icons.js @@ -0,0 +1,1005 @@ +const faIcons = [ + 'ad', + 'address-book', + 'address-card', + 'adjust', + 'air-freshener', + 'align-center', + 'align-justify', + 'align-left', + 'align-right', + 'allergies', + 'ambulance', + 'american-sign-language-interpreting', + 'anchor', + 'angle-double-down', + 'angle-double-left', + 'angle-double-right', + 'angle-double-up', + 'angle-down', + 'angle-left', + 'angle-right', + 'angle-up', + 'angry', + 'ankh', + 'apple-alt', + 'archive', + 'archway', + 'arrow-alt-circle-down', + 'arrow-alt-circle-left', + 'arrow-alt-circle-right', + 'arrow-alt-circle-up', + 'arrow-circle-down', + 'arrow-circle-left', + 'arrow-circle-right', + 'arrow-circle-up', + 'arrow-down', + 'arrow-left', + 'arrow-right', + 'arrow-up', + 'arrows-alt', + 'arrows-alt-h', + 'arrows-alt-v', + 'assistive-listening-systems', + 'asterisk', + 'at', + 'atlas', + 'atom', + 'audio-description', + 'award', + 'baby', + 'baby-carriage', + 'backspace', + 'backward', + 'bacon', + 'bacteria', + 'bacterium', + 'bahai', + 'balance-scale', + 'balance-scale-left', + 'balance-scale-right', + 'ban', + 'band-aid', + 'barcode', + 'bars', + 'baseball-ball', + 'basketball-ball', + 'bath', + 'battery-empty', + 'battery-full', + 'battery-half', + 'battery-quarter', + 'battery-three-quarters', + 'bed', + 'beer', + 'bell', + 'bell-slash', + 'bezier-curve', + 'bible', + 'bicycle', + 'biking', + 'binoculars', + 'biohazard', + 'birthday-cake', + 'blender', + 'blender-phone', + 'blind', + 'blog', + 'bold', + 'bolt', + 'bomb', + 'bone', + 'bong', + 'book', + 'book-dead', + 'book-medical', + 'book-open', + 'book-reader', + 'bookmark', + 'border-all', + 'border-none', + 'border-style', + 'bowling-ball', + 'box', + 'box-open', + 'box-tissue', + 'boxes', + 'braille', + 'brain', + 'bread-slice', + 'briefcase', + 'briefcase-medical', + 'broadcast-tower', + 'broom', + 'brush', + 'bug', + 'building', + 'bullhorn', + 'bullseye', + 'burn', + 'bus', + 'bus-alt', + 'business-time', + 'calculator', + 'calendar', + 'calendar-alt', + 'calendar-check', + 'calendar-day', + 'calendar-minus', + 'calendar-plus', + 'calendar-times', + 'calendar-week', + 'camera', + 'camera-retro', + 'campground', + 'candy-cane', + 'cannabis', + 'capsules', + 'car', + 'car-alt', + 'car-battery', + 'car-crash', + 'car-side', + 'caravan', + 'caret-down', + 'caret-left', + 'caret-right', + 'caret-square-down', + 'caret-square-left', + 'caret-square-right', + 'caret-square-up', + 'caret-up', + 'carrot', + 'cart-arrow-down', + 'cart-plus', + 'cash-register', + 'cat', + 'certificate', + 'chair', + 'chalkboard', + 'chalkboard-teacher', + 'charging-station', + 'chart-area', + 'chart-bar', + 'chart-line', + 'chart-pie', + 'check', + 'check-circle', + 'check-double', + 'check-square', + 'cheese', + 'chess', + 'chess-bishop', + 'chess-board', + 'chess-king', + 'chess-knight', + 'chess-pawn', + 'chess-queen', + 'chess-rook', + 'chevron-circle-down', + 'chevron-circle-left', + 'chevron-circle-right', + 'chevron-circle-up', + 'chevron-down', + 'chevron-left', + 'chevron-right', + 'chevron-up', + 'child', + 'church', + 'circle', + 'circle-notch', + 'city', + 'clinic-medical', + 'clipboard', + 'clipboard-check', + 'clipboard-list', + 'clock', + 'clone', + 'closed-captioning', + 'cloud', + 'cloud-download-alt', + 'cloud-meatball', + 'cloud-moon', + 'cloud-moon-rain', + 'cloud-rain', + 'cloud-showers-heavy', + 'cloud-sun', + 'cloud-sun-rain', + 'cloud-upload-alt', + 'cocktail', + 'code', + 'code-branch', + 'coffee', + 'cog', + 'cogs', + 'coins', + 'columns', + 'comment', + 'comment-alt', + 'comment-dollar', + 'comment-dots', + 'comment-medical', + 'comment-slash', + 'comments', + 'comments-dollar', + 'compact-disc', + 'compass', + 'compress', + 'compress-alt', + 'compress-arrows-alt', + 'concierge-bell', + 'cookie', + 'cookie-bite', + 'copy', + 'copyright', + 'couch', + 'credit-card', + 'crop', + 'crop-alt', + 'cross', + 'crosshairs', + 'crow', + 'crown', + 'crutch', + 'cube', + 'cubes', + 'cut', + 'database', + 'deaf', + 'democrat', + 'desktop', + 'dharmachakra', + 'diagnoses', + 'dice', + 'dice-d20', + 'dice-d6', + 'dice-five', + 'dice-four', + 'dice-one', + 'dice-six', + 'dice-three', + 'dice-two', + 'digital-tachograph', + 'directions', + 'disease', + 'divide', + 'dizzy', + 'dna', + 'dog', + 'dollar-sign', + 'dolly', + 'dolly-flatbed', + 'donate', + 'door-closed', + 'door-open', + 'dot-circle', + 'dove', + 'download', + 'drafting-compass', + 'dragon', + 'draw-polygon', + 'drum', + 'drum-steelpan', + 'drumstick-bite', + 'dumbbell', + 'dumpster', + 'dumpster-fire', + 'dungeon', + 'edit', + 'egg', + 'eject', + 'ellipsis-h', + 'ellipsis-v', + 'envelope', + 'envelope-open', + 'envelope-open-text', + 'envelope-square', + 'equals', + 'eraser', + 'ethernet', + 'euro-sign', + 'exchange-alt', + 'exclamation', + 'exclamation-circle', + 'exclamation-triangle', + 'expand', + 'expand-alt', + 'expand-arrows-alt', + 'external-link-alt', + 'external-link-square-alt', + 'eye', + 'eye-dropper', + 'eye-slash', + 'fan', + 'fast-backward', + 'fast-forward', + 'faucet', + 'fax', + 'feather', + 'feather-alt', + 'female', + 'fighter-jet', + 'file', + 'file-alt', + 'file-archive', + 'file-audio', + 'file-code', + 'file-contract', + 'file-csv', + 'file-download', + 'file-excel', + 'file-export', + 'file-image', + 'file-import', + 'file-invoice', + 'file-invoice-dollar', + 'file-medical', + 'file-medical-alt', + 'file-pdf', + 'file-powerpoint', + 'file-prescription', + 'file-signature', + 'file-upload', + 'file-video', + 'file-word', + 'fill', + 'fill-drip', + 'film', + 'filter', + 'fingerprint', + 'fire', + 'fire-alt', + 'fire-extinguisher', + 'first-aid', + 'fish', + 'fist-raised', + 'flag', + 'flag-checkered', + 'flag-usa', + 'flask', + 'flushed', + 'folder', + 'folder-minus', + 'folder-open', + 'folder-plus', + 'font', + 'football-ball', + 'forward', + 'frog', + 'frown', + 'frown-open', + 'funnel-dollar', + 'futbol', + 'gamepad', + 'gas-pump', + 'gavel', + 'gem', + 'genderless', + 'ghost', + 'gift', + 'gifts', + 'glass-cheers', + 'glass-martini', + 'glass-martini-alt', + 'glass-whiskey', + 'glasses', + 'globe', + 'globe-africa', + 'globe-americas', + 'globe-asia', + 'globe-europe', + 'golf-ball', + 'gopuram', + 'graduation-cap', + 'greater-than', + 'greater-than-equal', + 'grimace', + 'grin', + 'grin-alt', + 'grin-beam', + 'grin-beam-sweat', + 'grin-hearts', + 'grin-squint', + 'grin-squint-tears', + 'grin-stars', + 'grin-tears', + 'grin-tongue', + 'grin-tongue-squint', + 'grin-tongue-wink', + 'grin-wink', + 'grip-horizontal', + 'grip-lines', + 'grip-lines-vertical', + 'grip-vertical', + 'guitar', + 'h-square', + 'hamburger', + 'hammer', + 'hamsa', + 'hand-holding', + 'hand-holding-heart', + 'hand-holding-medical', + 'hand-holding-usd', + 'hand-holding-water', + 'hand-lizard', + 'hand-middle-finger', + 'hand-paper', + 'hand-peace', + 'hand-point-down', + 'hand-point-left', + 'hand-point-right', + 'hand-point-up', + 'hand-pointer', + 'hand-rock', + 'hand-scissors', + 'hand-sparkles', + 'hand-spock', + 'hands', + 'hands-helping', + 'hands-wash', + 'handshake', + 'handshake-alt-slash', + 'handshake-slash', + 'hanukiah', + 'hard-hat', + 'hashtag', + 'hat-cowboy', + 'hat-cowboy-side', + 'hat-wizard', + 'hdd', + 'head-side-cough', + 'head-side-cough-slash', + 'head-side-mask', + 'head-side-virus', + 'heading', + 'headphones', + 'headphones-alt', + 'headset', + 'heart', + 'heart-broken', + 'heartbeat', + 'helicopter', + 'highlighter', + 'hiking', + 'hippo', + 'history', + 'hockey-puck', + 'holly-berry', + 'home', + 'horse', + 'horse-head', + 'hospital', + 'hospital-alt', + 'hospital-symbol', + 'hospital-user', + 'hot-tub', + 'hotdog', + 'hotel', + 'hourglass', + 'hourglass-end', + 'hourglass-half', + 'hourglass-start', + 'house-damage', + 'house-user', + 'hryvnia', + 'i-cursor', + 'ice-cream', + 'icicles', + 'icons', + 'id-badge', + 'id-card', + 'id-card-alt', + 'igloo', + 'image', + 'images', + 'inbox', + 'indent', + 'industry', + 'infinity', + 'info', + 'info-circle', + 'italic', + 'jedi', + 'joint', + 'journal-whills', + 'kaaba', + 'key', + 'keyboard', + 'khanda', + 'kiss', + 'kiss-beam', + 'kiss-wink-heart', + 'kiwi-bird', + 'landmark', + 'language', + 'laptop', + 'laptop-code', + 'laptop-house', + 'laptop-medical', + 'laugh', + 'laugh-beam', + 'laugh-squint', + 'laugh-wink', + 'layer-group', + 'leaf', + 'lemon', + 'less-than', + 'less-than-equal', + 'level-down-alt', + 'level-up-alt', + 'life-ring', + 'lightbulb', + 'link', + 'lira-sign', + 'list', + 'list-alt', + 'list-ol', + 'list-ul', + 'location-arrow', + 'lock', + 'lock-open', + 'long-arrow-alt-down', + 'long-arrow-alt-left', + 'long-arrow-alt-right', + 'long-arrow-alt-up', + 'low-vision', + 'luggage-cart', + 'lungs', + 'lungs-virus', + 'magic', + 'magnet', + 'mail-bulk', + 'male', + 'map', + 'map-marked', + 'map-marked-alt', + 'map-marker', + 'map-marker-alt', + 'map-pin', + 'map-signs', + 'marker', + 'mars', + 'mars-double', + 'mars-stroke', + 'mars-stroke-h', + 'mars-stroke-v', + 'mask', + 'medal', + 'medkit', + 'meh', + 'meh-blank', + 'meh-rolling-eyes', + 'memory', + 'menorah', + 'mercury', + 'meteor', + 'microchip', + 'microphone', + 'microphone-alt', + 'microphone-alt-slash', + 'microphone-slash', + 'microscope', + 'minus', + 'minus-circle', + 'minus-square', + 'mitten', + 'mobile', + 'mobile-alt', + 'money-bill', + 'money-bill-alt', + 'money-bill-wave', + 'money-bill-wave-alt', + 'money-check', + 'money-check-alt', + 'monument', + 'moon', + 'mortar-pestle', + 'mosque', + 'motorcycle', + 'mountain', + 'mouse', + 'mouse-pointer', + 'mug-hot', + 'music', + 'network-wired', + 'neuter', + 'newspaper', + 'not-equal', + 'notes-medical', + 'object-group', + 'object-ungroup', + 'oil-can', + 'om', + 'otter', + 'outdent', + 'pager', + 'paint-brush', + 'paint-roller', + 'palette', + 'pallet', + 'paper-plane', + 'paperclip', + 'parachute-box', + 'paragraph', + 'parking', + 'passport', + 'pastafarianism', + 'paste', + 'pause', + 'pause-circle', + 'paw', + 'peace', + 'pen', + 'pen-alt', + 'pen-fancy', + 'pen-nib', + 'pen-square', + 'pencil-alt', + 'pencil-ruler', + 'people-arrows', + 'people-carry', + 'pepper-hot', + 'percent', + 'percentage', + 'person-booth', + 'phone', + 'phone-alt', + 'phone-slash', + 'phone-square', + 'phone-square-alt', + 'phone-volume', + 'photo-video', + 'piggy-bank', + 'pills', + 'pizza-slice', + 'place-of-worship', + 'plane', + 'plane-arrival', + 'plane-departure', + 'plane-slash', + 'play', + 'play-circle', + 'plug', + 'plus', + 'plus-circle', + 'plus-square', + 'podcast', + 'poll', + 'poll-h', + 'poo', + 'poo-storm', + 'poop', + 'portrait', + 'pound-sign', + 'power-off', + 'pray', + 'praying-hands', + 'prescription', + 'prescription-bottle', + 'prescription-bottle-alt', + 'print', + 'procedures', + 'project-diagram', + 'pump-medical', + 'pump-soap', + 'puzzle-piece', + 'qrcode', + 'question', + 'question-circle', + 'quidditch', + 'quote-left', + 'quote-right', + 'quran', + 'radiation', + 'radiation-alt', + 'rainbow', + 'random', + 'receipt', + 'record-vinyl', + 'recycle', + 'redo', + 'redo-alt', + 'registered', + 'remove-format', + 'reply', + 'reply-all', + 'republican', + 'restroom', + 'retweet', + 'ribbon', + 'ring', + 'road', + 'robot', + 'rocket', + 'route', + 'rss', + 'rss-square', + 'ruble-sign', + 'ruler', + 'ruler-combined', + 'ruler-horizontal', + 'ruler-vertical', + 'running', + 'rupee-sign', + 'sad-cry', + 'sad-tear', + 'satellite', + 'satellite-dish', + 'save', + 'school', + 'screwdriver', + 'scroll', + 'sd-card', + 'search', + 'search-dollar', + 'search-location', + 'search-minus', + 'search-plus', + 'seedling', + 'server', + 'shapes', + 'share', + 'share-alt', + 'share-alt-square', + 'share-square', + 'shekel-sign', + 'shield-alt', + 'shield-virus', + 'ship', + 'shipping-fast', + 'shoe-prints', + 'shopping-bag', + 'shopping-basket', + 'shopping-cart', + 'shower', + 'shuttle-van', + 'sign', + 'sign-in-alt', + 'sign-language', + 'sign-out-alt', + 'signal', + 'signature', + 'sim-card', + 'sink', + 'sitemap', + 'skating', + 'skiing', + 'skiing-nordic', + 'skull', + 'skull-crossbones', + 'slash', + 'sleigh', + 'sliders-h', + 'smile', + 'smile-beam', + 'smile-wink', + 'smog', + 'smoking', + 'smoking-ban', + 'sms', + 'snowboarding', + 'snowflake', + 'snowman', + 'snowplow', + 'soap', + 'socks', + 'solar-panel', + 'sort', + 'sort-alpha-down', + 'sort-alpha-down-alt', + 'sort-alpha-up', + 'sort-alpha-up-alt', + 'sort-amount-down', + 'sort-amount-down-alt', + 'sort-amount-up', + 'sort-amount-up-alt', + 'sort-down', + 'sort-numeric-down', + 'sort-numeric-down-alt', + 'sort-numeric-up', + 'sort-numeric-up-alt', + 'sort-up', + 'spa', + 'space-shuttle', + 'spell-check', + 'spider', + 'spinner', + 'splotch', + 'spray-can', + 'square', + 'square-full', + 'square-root-alt', + 'stamp', + 'star', + 'star-and-crescent', + 'star-half', + 'star-half-alt', + 'star-of-david', + 'star-of-life', + 'step-backward', + 'step-forward', + 'stethoscope', + 'sticky-note', + 'stop', + 'stop-circle', + 'stopwatch', + 'stopwatch-20', + 'store', + 'store-alt', + 'store-alt-slash', + 'store-slash', + 'stream', + 'street-view', + 'strikethrough', + 'stroopwafel', + 'subscript', + 'subway', + 'suitcase', + 'suitcase-rolling', + 'sun', + 'superscript', + 'surprise', + 'swatchbook', + 'swimmer', + 'swimming-pool', + 'synagogue', + 'sync', + 'sync-alt', + 'syringe', + 'table', + 'table-tennis', + 'tablet', + 'tablet-alt', + 'tablets', + 'tachometer-alt', + 'tag', + 'tags', + 'tape', + 'tasks', + 'taxi', + 'teeth', + 'teeth-open', + 'temperature-high', + 'temperature-low', + 'tenge', + 'terminal', + 'text-height', + 'text-width', + 'th', + 'th-large', + 'th-list', + 'theater-masks', + 'thermometer', + 'thermometer-empty', + 'thermometer-full', + 'thermometer-half', + 'thermometer-quarter', + 'thermometer-three-quarters', + 'thumbs-down', + 'thumbs-up', + 'thumbtack', + 'ticket-alt', + 'times', + 'times-circle', + 'tint', + 'tint-slash', + 'tired', + 'toggle-off', + 'toggle-on', + 'toilet', + 'toilet-paper', + 'toilet-paper-slash', + 'toolbox', + 'tools', + 'tooth', + 'torah', + 'torii-gate', + 'tractor', + 'trademark', + 'traffic-light', + 'trailer', + 'train', + 'tram', + 'transgender', + 'transgender-alt', + 'trash', + 'trash-alt', + 'trash-restore', + 'trash-restore-alt', + 'tree', + 'trophy', + 'truck', + 'truck-loading', + 'truck-monster', + 'truck-moving', + 'truck-pickup', + 'tshirt', + 'tty', + 'tv', + 'umbrella', + 'umbrella-beach', + 'underline', + 'undo', + 'undo-alt', + 'universal-access', + 'university', + 'unlink', + 'unlock', + 'unlock-alt', + 'upload', + 'user', + 'user-alt', + 'user-alt-slash', + 'user-astronaut', + 'user-check', + 'user-circle', + 'user-clock', + 'user-cog', + 'user-edit', + 'user-friends', + 'user-graduate', + 'user-injured', + 'user-lock', + 'user-md', + 'user-minus', + 'user-ninja', + 'user-nurse', + 'user-plus', + 'user-secret', + 'user-shield', + 'user-slash', + 'user-tag', + 'user-tie', + 'user-times', + 'users', + 'users-cog', + 'users-slash', + 'utensil-spoon', + 'utensils', + 'vector-square', + 'venus', + 'venus-double', + 'venus-mars', + 'vest', + 'vest-patches', + 'vial', + 'vials', + 'video', + 'video-slash', + 'vihara', + 'virus', + 'virus-slash', + 'viruses', + 'voicemail', + 'volleyball-ball', + 'volume-down', + 'volume-mute', + 'volume-off', + 'volume-up', + 'vote-yea', + 'vr-cardboard', + 'walking', + 'wallet', + 'warehouse', + 'water', + 'wave-square', + 'weight', + 'weight-hanging', + 'wheelchair', + 'wifi', + 'wind', + 'window-close', + 'window-maximize', + 'window-minimize', + 'window-restore', + 'wine-bottle', + 'wine-glass', + 'wine-glass-alt', + 'won-sign', + 'wrench', + 'x-ray', + 'yen-sign', + 'yin-yang' +]; + +export default faIcons; diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js index 3d948ff93327e48bb516b64e3f1487a161ff87bc..eab2239b783a756ba2d1fbc2f1e296d1db03495f 100644 --- a/src/assets/js/map-util.js +++ b/src/assets/js/map-util.js @@ -18,7 +18,7 @@ import { FillSymbolizer, PointSymbolizer, LineSymbolizer } from "@/assets/js/vec let map; let dictLayersToLeaflet = {}; var layerMVT; -let statusList=[ +let statusList = [ { name: "Brouillon", value: "draft", @@ -66,20 +66,20 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ params: params, //dataType: "json", } - ).then(response => { - let data=response.data; - var err = typeof data === 'object' ? null : data; - if (data.features || err) { - showResults(err, evt.latlng, data); - } - }) - .catch(error => { - throw (error) - //xhr.status; - //xhr.responseText; - //console.log(status) - } - ) + ).then(response => { + let data = response.data; + var err = typeof data === 'object' ? null : data; + if (data.features || err) { + showResults(err, evt.latlng, data); + } + }) + .catch(error => { + throw (error) + //xhr.status; + //xhr.responseText; + //console.log(status) + } + ) } } @@ -165,7 +165,7 @@ const mapUtil = { return map; }, - createMap: function (options) { + createMap: function (el, options) { const { lat, lng, @@ -175,8 +175,9 @@ const mapUtil = { zoomControl = true, } = options; - map = L.map('map', { + map = L.map(el, { maxZoom: 18, + minZoom: 1, zoomControl: false, }).setView( [ @@ -200,7 +201,7 @@ const mapUtil = { return map; }, - addGeocoders: function(configuration){ + addGeocoders: function (configuration) { let geocoder; const geocoderLabel = configuration.SELECTED_GEOCODER.PROVIDER; if (geocoderLabel) { @@ -278,7 +279,7 @@ const mapUtil = { } }); }, - + updateOrder(layers) { // First remove existing layers undefined layers = layers.filter(function (x) { @@ -298,87 +299,89 @@ const mapUtil = { this.addLayers(layers); }, // eslint-disable-next-line no-unused-vars - addVectorTileLayer: function (url,project_slug,featureTypes,form_filters) { + addVectorTileLayer: function (url, project_slug, featureTypes, form_filters) { layerMVT = L.vectorGrid.protobuf(url, { vectorTileLayerStyles: { - "default": function(properties, zoom) { - // console.log(properties); - - let featureType=featureTypes.find((x)=>x.slug.split('-')[0]===''+properties.feature_type_id); - let color=featureType.color; - if(featureType.colors_style && featureType.colors_style.custom_field_name){ - let currentValue=properties[featureType.colors_style.custom_field_name]; - let colorValue=featureType.colors_style.colors[currentValue]; - if(colorValue) { - color=colorValue; + "default": function (properties, zoom) { + // console.log(properties); + + let featureType = featureTypes.find((x) => x.slug.split('-')[0] === '' + properties.feature_type_id); + let color = featureType.color; + if (featureType.colors_style && featureType.colors_style.custom_field_name) { + let currentValue = properties[featureType.colors_style.custom_field_name]; + let colorValue = featureType.colors_style.colors[currentValue]; + if (colorValue) { + color = colorValue; } - } - let hiddenStyle=({ - radius: 0, - fillOpacity: 0.5, - weight: 0, - fill: false, - color: featureType.color, - }) - // Filtre sur le feature type - if (form_filters && form_filters.type.selected) { - if(featureType.title !== form_filters.type.selected){ - return hiddenStyle; - } + + } + let hiddenStyle = ({ + radius: 0, + fillOpacity: 0.5, + weight: 0, + fill: false, + color: featureType.color, + }) + // Filtre sur le feature type + if (form_filters && form_filters.type.selected) { + if (featureType.title !== form_filters.type.selected) { + return hiddenStyle; } + } // Filtre sur le statut if (form_filters && form_filters.status.selected.value) { - if(properties.status !== form_filters.status.selected.value){ + if (properties.status !== form_filters.status.selected.value) { return hiddenStyle; } } // Filtre sur le titre if (form_filters && form_filters.title) { - if(!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())){ + if (!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())) { return hiddenStyle; } } - return ({ - radius: 4, - fillOpacity: 0.5, - weight: 3, - fill: true, - color: color, - }); - + return ({ + radius: 4, + fillOpacity: 0.5, + weight: 3, + fill: true, + color: color, + }); + }, - }, + }, // subdomains: "0123", // key: 'abcdefghi01234567890', - interactive:true, + interactive: true, maxNativeZoom: 14, - getFeatureId: function(f) { - return f.properties.id; - } + getFeatureId: function (f) { + return f.properties.id; + } }); - let self=this; - layerMVT.on('click', function(e) { // The .on method attaches an event handler - console.log(e); - const popupContent = self._createContentPopup(e.layer,featureTypes,project_slug); + let self = this; + layerMVT.on('click', function (e) { // The .on method attaches an event handler + console.log("click on mvt", e); + const popupContent = self._createContentPopup(e.layer, featureTypes, project_slug); L.popup() - .setContent(popupContent) - .setLatLng(e.latlng) - .openOn(map) - }); + .setContent(popupContent) + .setLatLng(e.latlng) + .openOn(map) + }); layerMVT.addTo(map); - window.layerMVT=layerMVT; - }, + window.layerMVT = layerMVT; + }, - addFeatures: function (features, filter,addToMap=true,featureTypes) { + addFeatures: function (features, filter, addToMap = true, featureTypes) { let featureGroup = new L.FeatureGroup(); features.forEach((feature) => { - - let featureType=featureTypes.find((x)=>x.slug.split('-')[0]===''+feature.properties.feature_type_id); - if(feature.properties.feature_type != undefined){ - featureType=featureTypes.find((x)=>x.slug===''+feature.properties.feature_type); + + let featureType = featureTypes.find((x) => x.slug === feature.properties.feature_type.slug); + if (!featureType) { + featureType = feature.properties.feature_type; } + let filters = []; - + if (filter) { const typeCheck = filter.featureType && feature.properties.feature_type.slug === filter.featureType; const statusCheck = filter.featureStatus && feature.properties.status.value === filter.featureStatus; @@ -391,19 +394,54 @@ const mapUtil = { const geomJSON = flip(feature.geometry); const popupContent = this._createContentPopup(feature); - let color=feature.properties.color; - if(color==undefined){ - color=featureType.color; + + // Look for a custom field + let customField; + let customFieldOption; + if (Object.keys(feature.properties).some(el => featureType.customfield_set.map(e => e.name).includes(el))) { + customField = Object.keys(feature.properties).filter(el => featureType.customfield_set.map(e => e.name).includes(el)); + customFieldOption = feature.properties[customField[0]]; + } + + let color; + if (customFieldOption && featureType.colors_style) { + color = featureType.colors_style.value.colors[customFieldOption].value + } else { + color = feature.properties.color; + } + if (color == undefined) { + color = featureType.color; } if (geomJSON.type === 'Point') { - L.circleMarker(geomJSON.coordinates, { - color: color, - radius: 4, - fillOpacity: 0.5, - weight: 3, - }) - .bindPopup(popupContent) - .addTo(featureGroup); + if (customFieldOption && featureType.colors_style) { + const iconHTML = ` + <i + class="fas fa-${featureType.colors_style.value.icons[customFieldOption]} fa-2x" + style="color: ${color}" + ></i> + `; + const customMapIcon = L.divIcon({ + html: iconHTML, + iconSize: [20, 20], + className: 'myDivIcon', + }); + L.marker(geomJSON.coordinates, { + icon: customMapIcon, + color: color, + zIndexOffset: 100 + }) + .bindPopup(popupContent) + .addTo(featureGroup); + } else { + L.circleMarker(geomJSON.coordinates, { + color: color, + radius: 4, + fillOpacity: 0.5, + weight: 3, + }) + .bindPopup(popupContent) + .addTo(featureGroup); + } } else if (geomJSON.type === 'LineString') { L.polyline(geomJSON.coordinates, { color: color, @@ -422,39 +460,39 @@ const mapUtil = { } } }); - if(addToMap){ + if (addToMap) { map.addLayer(featureGroup); } - + return featureGroup; }, addMapEventListener: function (eventName, callback) { map.on(eventName, callback); }, - _createContentPopup: function (feature,featureTypes,project_slug) { - const formatDate = (current_datetime)=>{ - let formatted_date = current_datetime.getFullYear() + "-" + ("0" + (current_datetime.getMonth() + 1)).slice(-2) + "-" + ("0" + current_datetime.getDate()).slice(-2) + " " + + _createContentPopup: function (feature, featureTypes, project_slug) { + const formatDate = (current_datetime) => { + let formatted_date = current_datetime.getFullYear() + "-" + ("0" + (current_datetime.getMonth() + 1)).slice(-2) + "-" + ("0" + current_datetime.getDate()).slice(-2) + " " + ("0" + current_datetime.getHours()).slice(-2) + ":" + ("0" + current_datetime.getMinutes()).slice(-2); - return formatted_date; + return formatted_date; } let feature_type; - let status=feature.properties.status; - let date_maj=feature.properties.updated_on; - let feature_type_url=feature.properties.feature_type_url; - let feature_url=feature.properties.feature_url; - if(featureTypes){ // => VectorTile - feature_type=featureTypes.find((x)=>x.slug.split('-')[0]===''+feature.properties.feature_type_id); - status=statusList.find((x)=>x.value==feature.properties.status).name; - date_maj=formatDate(new Date(feature.properties.updated_on)); - feature_type_url='/geocontrib/projet/'+project_slug+'/type_signalement/'+feature_type.slug+'/'; - feature_url=feature_type_url+'signalement/'+feature.properties.feature_id+'/'; + let status = feature.properties.status; + let date_maj = feature.properties.updated_on; + let feature_type_url = feature.properties.feature_type_url; + let feature_url = feature.properties.feature_url; + if (featureTypes) { // => VectorTile + feature_type = featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.properties.feature_type_id); + status = statusList.find((x) => x.value == feature.properties.status).name; + date_maj = formatDate(new Date(feature.properties.updated_on)); + feature_type_url = '/geocontrib/projet/' + project_slug + '/type_signalement/' + feature_type.slug + '/'; + feature_url = feature_type_url + 'signalement/' + feature.properties.feature_id + '/'; //status=feature.properties.status; - }else{ - feature_type=feature.properties.feature_type; - status=feature.properties.status.label; + } else { + feature_type = feature.properties.feature_type; + status = feature.properties.status.label; } - + let author = ""; if (feature.properties.creator) { author = feature.properties.creator.full_name diff --git a/src/assets/styles/base.css b/src/assets/styles/base.css index 366f47bf0cdf9eb658d75a55f0261e18de9ed0e1..d49a7d4750077875a1d26d66f025feef2eba7b9d 100644 --- a/src/assets/styles/base.css +++ b/src/assets/styles/base.css @@ -52,6 +52,10 @@ main { word-wrap: normal; } +.ui.checkbox.disabled > input { + cursor: default !important; +} + /* Add basemap view */ #form-layers .ui.buttons{ diff --git a/src/components/feature/FeatureListTable.vue b/src/components/feature/FeatureListTable.vue index 47b2d1fd5507d95ace501dd54e5e480c6d3db262..d19aa0160cc080fc976e5a8adb21190885a1acef 100644 --- a/src/components/feature/FeatureListTable.vue +++ b/src/components/feature/FeatureListTable.vue @@ -77,12 +77,20 @@ <tbody> <tr v-for="(feature, index) in paginatedFeatures" :key="index"> <td class="center"> - <div class="ui checkbox"> + <div + class="ui checkbox" + :class=" + feature.properties.creator.username !== user.username && !user.is_superuser && !isUserProjectAdministrator ? + 'disabled' : + '' + " + > <input type="checkbox" :id="feature.id" :value="feature.id" v-model="checked" + :disabled="feature.properties.creator.username !== user.username && !user.is_superuser && !isUserProjectAdministrator" /> <label></label> </div> @@ -217,10 +225,12 @@ </template> <script> +import { mapState, mapGetters } from 'vuex'; + export default { name: "FeatureListTable", - props: ["filteredFeatures", "user", "checkedFeatures"], + props: ["filteredFeatures", "checkedFeatures"], data() { return { @@ -238,6 +248,18 @@ export default { }, computed: { + ...mapState([ + 'user', + ]), + ...mapGetters([ + 'project', + 'permissions' + ]), + + isUserProjectAdministrator() { + return this.permissions.is_project_administrator; + }, + paginatedFeatures() { let filterdFeatures = [...this.filteredFeatures]; // Ajout du tri diff --git a/src/components/feature_type/SymbologySelector.vue b/src/components/feature_type/SymbologySelector.vue new file mode 100644 index 0000000000000000000000000000000000000000..73d5ab4279e35eef88cc55a5d8c209f53da08460 --- /dev/null +++ b/src/components/feature_type/SymbologySelector.vue @@ -0,0 +1,196 @@ +<template> + <div> + <div class="three fields"> + <div class="row-title"> + {{ title }} + </div> + <div class="required inline field"> + <label :for="form.color.id_for_label">{{ form.color.label }}</label> + <input + type="color" + required + :name="form.color.html_name" + :id="form.color.id_for_label" + v-model.lazy="form.color.value" + /> + </div> + <div class="required inline field"> + <label>Symbole</label> + <button + class="ui icon button picker-button" + type="button" + @click="openIconSelectionModal" + > + <font-awesome-icon + :icon="['fas', form.icon]" + :style="{ color: form.color.value }" + class="icon alt" + /> + </button> + </div> + </div> + <div + :class="isIconPickerModalOpen ? 'active' : ''" + class="ui dimmer modal transition" + ref="iconsPickerModal" + > + <div class="header">Sélectionnez le symbole pour ce type de signalement :</div> + <div class="scrolling content"> + <div + v-for="icon of iconsNamesList" + :key="icon" + :class="form.icon === icon ? 'active' : ''" + class="icon-container" + @click="selectIcon(icon)" + > + <font-awesome-icon + :icon="['fas', icon]" + class="icon alt" + /> + </div> + </div> + <div class="actions"> + <div class="ui cancel button" @click="isIconPickerModalOpen = false;">Fermer</div> + </div> + </div> + </div> +</template> + +<script> +import faIconsNames from '@/assets/icons/fa-icons.js'; + +export default { + name: 'SymbologySelector', + + props: { + title: { + type: String, + default: 'Symbologie par défault :' + }, + initColor: { + type: String, + default: '#000000' + }, + initIcon: { + type: String, + default: 'circle' + }, + geomType: { + type: String, + default: 'Point' + } + }, + + data() { + return { + isIconPickerModalOpen: false, + iconsNamesList: faIconsNames, + form: { + icon: 'circle', + color: { + id_for_label: 'couleur', + label: 'Couleur', + field: { + max_length: 128, // ! Vérifier la valeur dans django + }, + html_name: 'couleur', + value: '#000000', + }, + } + } + }, + + watch: { + form: { + deep: true, + handler(newValue) { + this.$emit('set', { + name: this.title === 'Symbologie par défault :' ? null : this.title, + value: newValue + }); + } + } + }, + + created() { + this.form.color.value = this.initColor; + this.form.icon = this.initIcon; + this.$emit('set', { + name: this.title, + value: this.form + }); + }, + + methods: { + openIconSelectionModal() { + this.isIconPickerModalOpen = true; + }, + + selectIcon(icon) { + this.form.icon = icon; + } + } +} +</script> + +<style lang="less" scoped> + +.fields { + align-items: center; + justify-content: space-between; + margin-top: 3em !important; +} + +.row-title { + display: inline; + font-size: 1.4em; + width: 33%; + text-align: left; + margin-left: 0.5em; +} + +#couleur { + width: 66%; + cursor: pointer; + box-shadow: 0 0 1px 1px rgb(189, 189, 189); +} + +.picker-button { + height: 50px; + width: 50px; + border-radius: 3px; + box-shadow: 0 0 2px 1px rgb(131, 131, 131); + .icon.alt { + color: rgb(75, 75, 75); + width: 30px; + height: 30px; + } +} +.picker-button:hover { + box-shadow: 0 0 2px 1px rgb(165, 165, 165); +} + +.modal { + height: fit-content; + .content { + display: flex; + flex-flow: row wrap; + .icon-container { + padding: 7px; + .icon.alt { + color: rgb(75, 75, 75); + width: 30px; + height: 30px; + } + } + .icon-container:hover { + cursor: pointer; + background-color: rgba(130, 216, 219, 0.589); + } + .icon-container.active { + background-color: rgba(130, 216, 219, 0.589); + } + } +} + +</style> diff --git a/src/main.js b/src/main.js index edda9a1c273cc6f4ba771411c3e3ae8617dc3ed9..3e5f6956593ac0d53834bdcd46cf80970188613a 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,16 @@ import store from './store' import 'leaflet/dist/leaflet.css'; import 'leaflet-draw/dist/leaflet.draw.css'; import '@/assets/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.css'; +import '@fortawesome/fontawesome-free/css/all.css' +import '@fortawesome/fontawesome-free/js/all.js' +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fas } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; + +library.add(fas) + +Vue.component('font-awesome-icon', FontAwesomeIcon); + Vue.config.productionTip = false // gestion mise à jour du serviceWorker et du precache @@ -61,6 +71,3 @@ axios.get("./config/config.json") .catch((error) => { throw error; }); - - - diff --git a/src/router/index.js b/src/router/index.js index f0eb56d71e8a8442ffd6d914291a1114e2eb3281..ab603a745eef79c6de3269be2f61f017c08eb4e8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -92,6 +92,11 @@ const routes = [ name: 'editer-type-signalement', component: () => import('../views/feature_type/Feature_type_edit.vue') }, + { + path: '/projet/:slug/type-signalement/:slug_type_signal/symbologie/', + name: 'editer-symbologie-signalement', + component: () => import('../views/feature_type/Feature_type_symbology.vue') + }, // * FEATURE { path: '/projet/:slug/signalement/lister/', diff --git a/src/service-worker.js b/src/service-worker.js index 7497fb0ca7f6f2d73661d696f8fa189c69640695..c9c0d32fee26672dbdc0b2f24959aee7e9eb3381 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -13,7 +13,9 @@ if (workbox) { // Make sure to return a specific response for all navigation requests. // Since we have a SPA here, this should be index.html always. // https://stackoverflow.com/questions/49963982/vue-router-history-mode-with-pwa-in-offline-mode - workbox.routing.registerNavigationRoute('/geocontrib/index.html') + workbox.routing.registerNavigationRoute('/geocontrib/index.html', { + blacklist: [/\/api/,/\/admin/], + }) workbox.routing.registerRoute( new RegExp('.*/config/config.json'), diff --git a/src/services/map-api.js b/src/services/map-api.js index 1a877e6370cfb88ae7360aad200df69a05fa72a8..fa4c5ddba7178edc5d26a91095d1dedb3c976e46 100644 --- a/src/services/map-api.js +++ b/src/services/map-api.js @@ -1,5 +1,11 @@ import axios from 'axios'; -import store from '../store' +import store from '../store'; + +axios.defaults.headers.common['X-CSRFToken'] = (name => { + var re = new RegExp(name + "=([^;]+)"); + var value = re.exec(document.cookie); + return (value !== null) ? unescape(value[1]) : null; +})('csrftoken'); const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE; diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index 204776cbb1d252e9e058b931e40eddc267da535b..bed583d904949de35706a19a93ea4d10a95e725d 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -139,6 +139,26 @@ const feature_type = { } }, + async SEND_FEATURE_SYMBOLOGY({ getters, rootGetters }, symbology) { + const data = { + title: getters.feature_type.title, + project: rootGetters.project.slug, + ...symbology + }; + return axios + .put(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}feature-types/${getters.feature_type.slug}/`, data) + .then((response) => { + if (response) { + const feature_type_slug = response.data.slug; + const status = response.status; + return { feature_type_slug, status }; + } + }) + .catch((error) => { + throw (error); + }); + }, + SEND_FEATURES_FROM_GEOJSON({ state, dispatch }, payload) { const { feature_type_slug } = payload diff --git a/src/store/modules/map.js b/src/store/modules/map.js index d47afc9ef721f6a3201ff1db473b051c92552a1e..c8e5ce93eab03a485b06f5a409be781a95cbe313 100644 --- a/src/store/modules/map.js +++ b/src/store/modules/map.js @@ -110,11 +110,11 @@ const map = { }); }, - INITIATE_MAP({ state, rootGetters }) { + INITIATE_MAP({ state, rootGetters }, el) { const project = rootGetters.project let mapDefaultViewCenter = [46, 2]; // defaultMapView.center; let mapDefaultViewZoom = 5; // defaultMapView.zoom; - mapUtil.createMap({ + mapUtil.createMap(el, { mapDefaultViewCenter, mapDefaultViewZoom, }); diff --git a/src/views/Index.vue b/src/views/Index.vue index e199657757733fb9d0874e0c72e2a47fd9f04d8b..b751999169c005a0a90fc93e2df3ffc4156c7912 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -1,9 +1,6 @@ <template> <div class="fourteen wide column"> - <img - class="ui centered small image" - src="@/assets/img/logo-neogeo-circle.png" - /> + <img class="ui centered small image" :src="logo" /> <!-- :src="LOGO_PATH" --> <h2 class="ui center aligned icon header"> <div class="content"> @@ -15,14 +12,14 @@ <h4 id="les_projets" class="ui horizontal divider header">PROJETS</h4> <div class="flex"> <router-link - v-if="user && user.can_create_project && isOffline()!=true" + v-if="user && user.can_create_project && isOffline() != true" :to="{ name: 'project_create', params: { action: 'create' } }" class="ui green basic button" > <i class="plus icon"></i> Créer un nouveau projet </router-link> <router-link - v-if="user && user.can_create_project && isOffline()!=true" + v-if="user && user.can_create_project && isOffline() != true" :to="{ name: 'project_type_list', }" @@ -110,22 +107,26 @@ import { mapState } from "vuex"; export default { name: "Index", + computed: { ...mapState(["projects", "user", "USER_LEVEL_PROJECTS"]), - APPLICATION_NAME: function () { + APPLICATION_NAME() { return this.$store.state.configuration.VUE_APP_APPLICATION_NAME; }, - APPLICATION_ABSTRACT: function () { + APPLICATION_ABSTRACT() { return this.$store.state.configuration.VUE_APP_APPLICATION_ABSTRACT; }, - DJANGO_BASE_URL: function () { + DJANGO_BASE_URL() { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, + logo() { + return this.$store.state.configuration.VUE_APP_LOGO_PATH; + }, }, methods: { - isOffline(){ - return navigator.onLine==false; + isOffline() { + return navigator.onLine == false; }, refreshId() { //* change path of thumbnail to update image diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index f17ed17535733e41a07dd7627703bed7e7ba7ce5..24514f13d3786d43b7de0a829c2011b413a2a135 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -353,6 +353,12 @@ import { mapUtil } from "@/assets/js/map-util.js"; import featureAPI from "@/services/feature-api"; const axios = require("axios"); +axios.defaults.headers.common['X-CSRFToken'] = (name => { + var re = new RegExp(name + "=([^;]+)"); + var value = re.exec(document.cookie); + return (value !== null) ? unescape(value[1]) : null; +})('csrftoken'); + export default { name: "Feature_detail", @@ -573,7 +579,7 @@ export default { this.$store.state.configuration.DEFAULT_MAP_VIEW.center; var mapDefaultViewZoom = this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; - this.map = mapUtil.createMap({ + this.map = mapUtil.createMap(this.$refs.map, { mapDefaultViewCenter, mapDefaultViewZoom, }); @@ -680,12 +686,10 @@ export default { this.$store .dispatch("GET_PROJECT_INFO", this.$route.params.slug) .then(() => { - console.log("map", this.$refs.map); this.$store.commit("DISCARD_LOADER"); this.initMap(); }); } else { - console.log("map", this.$refs.map); this.$store.commit("DISCARD_LOADER"); this.initMap(); } diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index ef384ad43fb80e2802015cf24da2084c88b3975d..40e10c25703b2a6db077fb1bf2736aa092422899 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -187,7 +187,7 @@ @blur="updateStore" /> <div class="ui tab active map-container" data-tab="map"> - <div id="map"></div> + <div id="map" ref="map"></div> <!-- // todo: ajouter v-if --> <!-- {% if serialized_base_maps|length > 0 %} {% include "geocontrib/map-layers/sidebar-layers.html" with @@ -928,7 +928,7 @@ export default { this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; // Create the map, then init the layers and features - this.map = mapUtil.createMap({ + this.map = mapUtil.createMap(this.$refs.map, { mapDefaultViewCenter, mapDefaultViewZoom, }); @@ -959,7 +959,7 @@ export default { mapUtil.addFeatures( allFeaturesExceptCurrent, {}, - false, + true, this.$store.state.feature_type.feature_types ); if (this.currentRouteName === "editer-signalement") { diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue index 6190906d0f8f840a324e67679c09497d0e3c4f69..2263ae1eff68f3927df9a0d0822d792163fa7b0a 100644 --- a/src/views/feature/Feature_list.vue +++ b/src/views/feature/Feature_list.vue @@ -144,7 +144,6 @@ <FeatureListTable v-show="!showMap" :filteredFeatures="filteredFeatures" - :user="user" :checkedFeatures.sync="checkedFeatures" /> @@ -189,6 +188,12 @@ import FeatureListTable from "@/components/feature/FeatureListTable"; import Dropdown from "@/components/Dropdown.vue"; const axios = require("axios"); +axios.defaults.headers.common['X-CSRFToken'] = (name => { + var re = new RegExp(name + "=([^;]+)"); + var value = re.exec(document.cookie); + return (value !== null) ? unescape(value[1]) : null; +})('csrftoken'); + export default { name: "Feature_list", @@ -248,7 +253,6 @@ export default { computed: { ...mapGetters(["project", "permissions"]), - ...mapState(["user"]), ...mapState("feature", ["checkedFeatures"]), ...mapState("feature_type", ["feature_types"]), @@ -337,7 +341,7 @@ export default { this.featureGroup = mapUtil.addFeatures( features, {}, - false, + true, this.$store.state.feature_type.feature_types ); mapUtil.getMap().invalidateSize(); @@ -362,7 +366,7 @@ export default { var mapDefaultViewZoom = this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; - this.map = mapUtil.createMap({ + this.map = mapUtil.createMap(this.$refs.map, { zoom: this.zoom, lat: this.lat, lng: this.lng, @@ -428,7 +432,7 @@ export default { featureStatus, featureTitle, }, - false, + true, this.$store.state.feature_type.feature_types ); // Fit the map to bound only if no initial zoom and center are defined @@ -451,13 +455,11 @@ export default { created() { if (!this.project) { - //this.$store.dispatch("GET_PROJECT_MESSAGES", this.$route.params.slug); this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug, "noFeatures"); } }, mounted() { - console.log("map", this.$refs.map); this.initMap(); }, diff --git a/src/views/feature_type/Feature_type_symbology.vue b/src/views/feature_type/Feature_type_symbology.vue new file mode 100644 index 0000000000000000000000000000000000000000..f1d82fe21f8c5f0471e52bc4b8dd09090414b227 --- /dev/null +++ b/src/views/feature_type/Feature_type_symbology.vue @@ -0,0 +1,203 @@ +<template> + <div> + <div :class="{ active: loading }" class="ui inverted dimmer"> + <div class="ui loader" /> + </div> + <div id="message" class="fullwidth"> + <div v-if="error" class="ui negative message"> + <p><i class="cross icon"></i> {{ error }}</p> + </div> + </div> + <div class="fourteen wide column"> + <form + id="form-symbology-edit" + action="" + method="post" + enctype="multipart/form-data" + class="ui form" + > + <h1 v-if="feature_type"> + Éditer la symbologie du type de signalement "{{ feature_type.title }}" pour le + projet "{{ project.title }}" + </h1> + <SymbologySelector + v-if="feature_type" + :initColor="feature_type.color" + :geomType="feature_type.geom_type" + @set="setDefaultStyle" + /> + <div + v-if=" + feature_type && + feature_type.customfield_set.length > 0 && + feature_type.customfield_set.some(el => el.field_type === 'list') + " + > + <div class="ui divider" /> + <label + for="customfield-select" + id="customfield-select-label"> + Personnaliser la symbologie d'une liste de valeurs: + </label> + <select + v-model="selectedCustomfield" + id="customfield-select" + class="ui dropdown" + > + <option + v-for="customfieldList of feature_type.customfield_set.filter(el => el.field_type === 'list')" + :key="customfieldList.name" + :value="customfieldList.name" + > + {{ customfieldList.label }} + </option> + </select> + </div> + <div v-if="selectedCustomfield"> + <div + v-for="option of feature_type.customfield_set.find(el => el.name === selectedCustomfield).options" + :key="option" + > + <SymbologySelector + :title="option" + :initColor="feature_type.colors_style.value.colors[option].value" + :initIcon="feature_type.colors_style.value.icons[option]" + :geomType="feature_type.customfield_set.geomType" + @set="setColorsStyle" + /> + </div> + </div> + <div class="ui divider"></div> + <button + class="ui teal icon button margin-25" + type="button" + @click="sendFeatureSymbology" + > + <i class="white save icon"></i> + Sauvegarder la symbologie du type de signalement + </button> + </form> + </div> + </div> +</template> + +<script> +import frag from 'vue-frag'; + +import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'; + +import SymbologySelector from '@/components/feature_type/SymbologySelector.vue'; + +export default { + name: 'FeatureTypeSymbology', + + directives: { + frag, + }, + + components: { + SymbologySelector + }, + + data() { + return { + loading: false, + error: null, + selectedCustomfield: null, + form: { + color: '#000000', + icon: 'circle', + colors_style: { + fields: [], + value: { + colors: {}, + icons: {}, + custom_field_name: '', + }, + }, + } + } + }, + + computed: { + ...mapGetters(['project']), + ...mapState('feature_type', [ + 'customForms', + 'colorsStyleList' + ]), + ...mapGetters('feature_type', [ + 'feature_type' + ]), + }, + + watch: { + selectedCustomfield(newValue) { + this.form.colors_style.value.custom_field_name = newValue; + } + }, + + created() { + if (!this.project) { + this.GET_PROJECT_INFO(this.$route.params.slug); + } + this.SET_CURRENT_FEATURE_TYPE_SLUG(this.$route.params.slug_type_signal); + }, + + methods: { + ...mapMutations('feature_type', [ + 'SET_CURRENT_FEATURE_TYPE_SLUG' + ]), + ...mapActions('feature_type', [ + 'SEND_FEATURE_SYMBOLOGY' + ]), + ...mapActions([ + 'GET_PROJECT_INFO' + ]), + + setDefaultStyle(e) { + const value = e.value; + this.form.color = value.color.value; + this.form.icon = value.icon; + }, + + setColorsStyle(e) { + const { name, value } = e; + this.form.colors_style.value.colors[name] = value.color; + this.form.colors_style.value.icons[name] = value.icon; + }, + + sendFeatureSymbology() { + this.loading = true; + this.SEND_FEATURE_SYMBOLOGY(this.form) + .then(() => { + this.loading = false; + }) + .catch(() => { + this.loading = false; + }) + } + } +} +</script> + +<style lang="less" scoped> + +h1 { + margin-top: 1em; +} + +form { + text-align: left; + + #customfield-select-label { + cursor: pointer; + font-weight: 600; + font-size: 1.1em; + } + #customfield-select { + width: 50% !important; + } + +} + +</style> diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index 1efc2288a4dba7c83ec75172ca668f023dbb5e68..e866ac9cde74c9360d6b95906e846170198f9a7d 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -228,6 +228,33 @@ > <i class="inverted grey pencil alternate icon"></i> </router-link> + <router-link + :to="{ + name: 'editer-symbologie-signalement', + params: { slug_type_signal: type.slug }, + }" + v-if=" + project && + type.is_editable && + permissions && + permissions.can_create_feature_type && + isOffline() != true + " + class=" + ui + compact + small + icon + right + floated + button button-hover-green + " + data-tooltip="Éditer la symbologie du type de signalement" + data-position="left center" + data-variation="mini" + > + <i class="inverted grey paint brush alternate icon"></i> + </router-link> </div> </div> <div v-if="feature_types.length === 0"> @@ -298,7 +325,7 @@ </div> </div> <div class="seven wide column"> - <div id="map"></div> + <div id="map" ref="map"></div> </div> </div> @@ -483,7 +510,7 @@ <div class="content"> <button - @click="subsribeProject" + @click="subscribeProject" :class="['ui compact fluid button', is_suscriber ? 'red' : 'green']" > {{ @@ -506,6 +533,12 @@ import projectAPI from "@/services/project-api"; const axios = require("axios"); +axios.defaults.headers.common['X-CSRFToken'] = (name => { + var re = new RegExp(name + "=([^;]+)"); + var value = re.exec(document.cookie); + return (value !== null) ? unescape(value[1]) : null; +})('csrftoken'); + export default { name: "Project_details", @@ -549,9 +582,12 @@ export default { DJANGO_BASE_URL() { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, + API_BASE_URL() { + return this.$store.state.configuration.VUE_APP_DJANGO_API_BASE; + }, last_features() { // * limit to last five element of array (looks sorted chronologically, but not sure...) - return this.$store.state.feature.features.slice(-5); + return this.features.slice(-5); }, }, @@ -559,9 +595,11 @@ export default { refreshId() { return "?ver=" + Math.random(); }, + isOffline() { return navigator.onLine === false; }, + checkForOfflineFeature() { let arraysOffline = []; let localStorageArray = localStorage.getItem("geocontrib_offline"); @@ -572,6 +610,7 @@ export default { ); } }, + sendOfflineFeatures() { var promises = []; this.arraysOffline.forEach((feature, index, object) => { @@ -579,10 +618,7 @@ export default { if (feature.type === "post") { promises.push( axios - .post( - `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/`, - feature.geojson - ) + .post(`${this.API_BASE_URL}features/`, feature.geojson) .then((response) => { console.log(response); if (response.status === 201 && response.data) { @@ -597,7 +633,7 @@ export default { promises.push( axios .put( - `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/${feature.featureId}`, + `${this.API_BASE_URL}features/${feature.featureId}`, feature.geojson ) .then((response) => { @@ -617,6 +653,7 @@ export default { window.location.reload(); }); }, + updateLocalStorage() { let arraysOffline = []; let localStorageArray = localStorage.getItem("geocontrib_offline"); @@ -629,6 +666,7 @@ export default { arraysOffline = arraysOfflineOtherProject.concat(this.arraysOffline); localStorage.setItem("geocontrib_offline", JSON.stringify(arraysOffline)); }, + toNewFeatureType() { this.$router.push({ name: "ajouter-type-signalement", @@ -659,8 +697,7 @@ export default { } }, - subsribeProject() { - this.$store.state.configuration.VUE_APP_DJANGO_API_BASE; + subscribeProject() { projectAPI .subscribeProject({ suscribe: !this.is_suscriber, @@ -680,11 +717,11 @@ export default { }, initMap() { if (this.project && this.permissions.can_view_project) { - this.$store.dispatch("map/INITIATE_MAP"); - const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`; + this.$store.dispatch("map/INITIATE_MAP", this.$refs.map); + const url = `${this.API_BASE_URL}projects/${this.$route.params.slug}/feature/?output=geojson`; this.checkForOfflineFeature(); let project_id = this.$route.params.slug.split("-")[0]; - const mvtUrl = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; + const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; mapUtil.addVectorTileLayer( mvtUrl, this.$route.params.slug, @@ -703,7 +740,7 @@ export default { const featureGroup = mapUtil.addFeatures( features, {}, - false, + true, this.$store.state.feature_type.feature_types ); @@ -735,8 +772,9 @@ export default { mounted() { this.$store.dispatch("GET_PROJECT_INFO", this.slug).then(() => { this.featureTypeLoading = false; - setTimeout(() => this.initMap, 1000); + setTimeout(this.initMap, 1000); }); + if (this.message) { this.tempMessage = this.message; document diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue index 8076625edbacd260d3c379e9d32f03da064026f4..4779af2c603dd93c5694cb7646a466b049bdd265 100644 --- a/src/views/project/Project_edit.vue +++ b/src/views/project/Project_edit.vue @@ -409,52 +409,50 @@ export default { is_project_type: this.form.is_project_type, moderation: this.form.moderation, }; + let url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`; - if (this.action === "create" || this.action === "create_from") { - this.loading = true; + if (this.action === "edit") { await axios - .post( - `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`, - projectData - ) + .put((url += `${this.project.slug}/`), projectData) .then((response) => { - if (response && response.status === 201 && response.data) { - //* send thumbnail after feature_type was created + if (response && response.status === 200) { + //* send thumbnail after feature_type was updated if (this.fileToImport.size > 0) { - this.postProjectThumbnail(response.data.slug); + this.postProjectThumbnail(this.project.slug); } else { - this.goBackNrefresh(response.data.slug); + this.goBackNrefresh(this.project.slug); } } - this.loading = false; }) .catch((error) => { if (error.response && error.response.data.title[0]) { this.errors.title.push(error.response.data.title[0]); } - this.loading = false; throw error; }); - } else if (this.action === "edit") { + } else { + if (this.action === "create_from") { + url += `${this.project.slug}/duplicate/`; + } + this.loading = true; await axios - .put( - `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.project.slug}/`, - projectData - ) + .post(url, projectData) .then((response) => { - if (response && response.status === 200) { - //* send thumbnail after feature_type was updated + if (response && response.status === 201 && response.data) { + //* send thumbnail after feature_type was created if (this.fileToImport.size > 0) { - this.postProjectThumbnail(this.project.slug); + this.postProjectThumbnail(response.data.slug); } else { - this.goBackNrefresh(this.project.slug); + this.goBackNrefresh(response.data.slug); } } + this.loading = false; }) .catch((error) => { if (error.response && error.response.data.title[0]) { this.errors.title.push(error.response.data.title[0]); } + this.loading = false; throw error; }); } diff --git a/src/views/project/Project_members.vue b/src/views/project/Project_members.vue index ed96cae6d4cc9b97abb62ab97c64a1a41d9c63a0..34c89ac5718fa7b0dd64f1eeb0e3ac2ad83865d9 100644 --- a/src/views/project/Project_members.vue +++ b/src/views/project/Project_members.vue @@ -111,6 +111,12 @@ import frag from "vue-frag"; import { mapGetters } from "vuex"; import Dropdown from "@/components/Dropdown.vue"; +axios.defaults.headers.common['X-CSRFToken'] = (name => { + var re = new RegExp(name + "=([^;]+)"); + var value = re.exec(document.cookie); + return (value !== null) ? unescape(value[1]) : null; +})('csrftoken'); + export default { name: "Project_members",