From 650b4e1844bb039c055cb3dc5010c8b89fee7b7e Mon Sep 17 00:00:00 2001 From: Johann Levesque Date: Thu, 18 Jan 2018 16:16:34 -0500 Subject: [PATCH] fix(form): Fix user feedback needs Closes #128, #127, #126, #135 --- src/app/ui/forms/form.service.js | 27 ++++++++++++++++++++++++- src/app/ui/forms/ui/ui.directive.js | 2 +- src/app/ui/header/header.directive.js | 14 ++++++++++++- src/app/ui/header/header.html | 5 +++++ src/content/styles/modules/_header.scss | 5 +++++ src/locales/translations.csv | 4 +++- src/schemas/schemaForm/map.en-CA.json | 7 +++---- src/schemas/schemaForm/map.fr-CA.json | 7 +++---- src/schemas/schemaForm/ui.en-CA.json | 1 + src/schemas/schemaForm/ui.fr-CA.json | 1 + 10 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/app/ui/forms/form.service.js b/src/app/ui/forms/form.service.js index c01ffbb0..be65b7de 100644 --- a/src/app/ui/forms/form.service.js +++ b/src/app/ui/forms/form.service.js @@ -11,7 +11,7 @@ angular .module('app.ui') .factory('formService', formService); -function formService($timeout, events, $mdDialog, commonService, constants, projectionService) { +function formService($timeout, events, $mdDialog, $translate, commonService, constants, projectionService) { const service = { showAdvance, @@ -19,6 +19,7 @@ function formService($timeout, events, $mdDialog, commonService, constants, proj toggleSection, toggleAll, setExtent, + setErrorMessage, copyValueToForm, copyValueToFormIndex, initValueToFormIndex, @@ -144,6 +145,30 @@ function formService($timeout, events, $mdDialog, commonService, constants, proj } } + /** + * Set custom validation error message + * inside translation.csv the variable to replace needs to be there inside {} + * @function setErrorMessage + * @param {Object} form form object to get value from + * @param {String} message message to get from translation.csv + * @param {Array} variables variables to replace + * @return {String} mess the updated message + */ + function setErrorMessage(form, message, variables) { + let mess = $translate.instant(message); + + for (let variable of variables) { + // get the replacing value from form object + let replace = form; + variable.split('.').map(item => { replace = replace[item] }); + + // replace value in the message + mess = mess.replace(`{${variable}}`, replace); + } + + return mess; + } + /** * Copy a value from the model to a form element. If the form element is an array, use copyValueToFormIndex instead * @function copyValueToForm diff --git a/src/app/ui/forms/ui/ui.directive.js b/src/app/ui/forms/ui/ui.directive.js index 5fa8e7d7..84cabbef 100644 --- a/src/app/ui/forms/ui/ui.directive.js +++ b/src/app/ui/forms/ui/ui.directive.js @@ -138,7 +138,7 @@ function Controller($scope, $translate, events, modelManager, formService) { { 'key': 'navBar' } ] }, { 'title': $translate.instant('form.ui.sidemenu'), 'items': [ - { 'key': 'title' }, + { 'key': 'title', 'validationMessage': form => { return self.formService.setErrorMessage(form, 'form.ui.titlevalidation', ['viewValue.length', 'schema.maxLength']) } }, { 'key': 'sideMenu.logo' }, { 'key': 'logoUrl', 'condition': 'model.sideMenu.logo' }, { 'key': 'sideMenu.items', 'title': $translate.instant('form.ui.items'), 'add': $translate.instant('button.add'), 'onChange': checkMenu }, diff --git a/src/app/ui/header/header.directive.js b/src/app/ui/header/header.directive.js index 80d4f811..61c94c84 100644 --- a/src/app/ui/header/header.directive.js +++ b/src/app/ui/header/header.directive.js @@ -59,6 +59,9 @@ function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelM self.templates = getTemplates(); self.template = self.templates[0]; + // set active file name + self.saveName = self.template; + /** * When create is clicked, broadcast a newModel event * @function create @@ -66,6 +69,9 @@ function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelM function create() { // show splash with update event as parameter events.$broadcast(events.avShowSplash, events.avSchemaUpdate); + + // set active file name + self.saveName = self.template; } /** @@ -106,6 +112,9 @@ function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelM // show splash when new model load events.$broadcast(events.avShowSplash); + // set active file name + self.saveName = files[0].name.replace('.json', ''); + // read the file but add a timeout for the animation to start const file = files[0]; $timeout(() => { @@ -144,6 +153,8 @@ function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelM * @function save */ function save() { + // FIXME: we can't know the real saved file name because FileSaver.onwriteend doesn/t workaround + // so if there is duplicate name the name will become nyname(1) on disk but will be myname on display $mdDialog.show({ controller: SaveController, controllerAs: 'self', @@ -151,7 +162,8 @@ function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelM parent: $('.fgpa'), disableParentScroll: false, clickOutsideToClose: true, - fullscreen: false + fullscreen: false, + onRemoving: element => { self.saveName = element[0].getElementsByTagName('input')[0].value; } }); } diff --git a/src/app/ui/header/header.html b/src/app/ui/header/header.html index b7590287..84dacbb9 100644 --- a/src/app/ui/header/header.html +++ b/src/app/ui/header/header.html @@ -49,5 +49,10 @@

{{ 'app.title' | translate }}

{{ 'header.save' | translate }} + +
+ + +
diff --git a/src/content/styles/modules/_header.scss b/src/content/styles/modules/_header.scss index 1af89172..f07865c5 100644 --- a/src/content/styles/modules/_header.scss +++ b/src/content/styles/modules/_header.scss @@ -2,4 +2,9 @@ .av-title { padding: 0 15px 0 15px; } + + .av-savename { + display: inline-block; + margin-left: 50px; + } } diff --git a/src/locales/translations.csv b/src/locales/translations.csv index be38caa2..49aa8955 100644 --- a/src/locales/translations.csv +++ b/src/locales/translations.csv @@ -21,6 +21,7 @@ header save dialog title,header.savedialog.title,Save Configuration File,0,Sauve header save dialog desc,header.savedialog.desc,Enter file name. It will be save inside your download folder,0,Entrez un nom de fichier. Il sera sauvegardé dans le répertoire téléchargement.,0 header save dialog hint,header.savedialog.hint,* no extension,0,* sans extension,0 header tempalte,header.template,Template,0,Gabarit,0 +header file name,header.filename,File Name: ,0,Nom du fichier: ,0 summary expand,summary.expand,Expand,0,Ouvrir,0 summary collapse,summary.collapse,Collapse,0,Fermer,0 summary preview,summary.preview,Preview,0,Aperçu,0 @@ -31,8 +32,9 @@ form ui,form.ui.nav,Navigation,0,Navigation,0 form ui,form.ui.sidemenu,Side Menu,0,Menu latéral,0 form ui,form.ui.items,Side Menu Items,0,Items du menu latéral,0 form ui,form.ui.about,About Map,0,À propos de cette carte,0 -form ui, form.ui.aboutChoice, About source,0,Source de l'à propos,0 +form ui,form.ui.aboutChoice, About source,0,Source de l'à propos,0 form ui,form.ui.aboutstring,String content,0,Texte,0 +form ui,form.ui.titlevalidation,"String is too long ({viewValue.length} chars), maximum {schema.maxLength} chars.",0,"La chaîne est trop longue ({viewValue.length} caractères), maximum {schema.maxLength} caractères." form ui,form.ui.aboutfile,File content,0,Contenu dans un fichier,0 form service,form.service.urls,Service End Points,0,Liens pour les services,0 form service,form.service.geosearch,Geo Search,0,Rechercher par lieux,0 diff --git a/src/schemas/schemaForm/map.en-CA.json b/src/schemas/schemaForm/map.en-CA.json index 0b2a035c..2e2735a0 100644 --- a/src/schemas/schemaForm/map.en-CA.json +++ b/src/schemas/schemaForm/map.en-CA.json @@ -206,8 +206,7 @@ "additionalProperties": false }, "description": "Level of detail for a specific tile schema", - "title": "Level of Detail set", - "default": "[]" + "title": "Level of Detail set" } }, "required": [ @@ -215,8 +214,7 @@ "lods" ], "additionalProperties": false, - "title": "Level of Detail sets", - "default": "" + "title": "Level of Detail sets" }, "description": "The levels of detail (zoom scales) available for the map", "title": "Level of detail sets", @@ -355,6 +353,7 @@ }, "expandFactor": { "type": "number", + "description": "The ratio between the size of the overview map and the extent rectangle displayed on the overview map. The default value is 2, meaning the overview map will be at least twice the size of the extent rectangle.", "default": 2, "title": "Expand Factor" }, diff --git a/src/schemas/schemaForm/map.fr-CA.json b/src/schemas/schemaForm/map.fr-CA.json index 637bfb8f..ae4e9e1d 100644 --- a/src/schemas/schemaForm/map.fr-CA.json +++ b/src/schemas/schemaForm/map.fr-CA.json @@ -206,8 +206,7 @@ "additionalProperties": false }, "description": "Niveau de détail pour un schéma de tuiles spécifique", - "title": "Niveaux de détail", - "default": "[]" + "title": "Niveaux de détail" } }, "required": [ @@ -215,8 +214,7 @@ "lods" ], "additionalProperties": false, - "title": "Lot de niveaux de détail", - "default": "" + "title": "Lot de niveaux de détail" }, "description": "Les niveaux de détail selon l'échelle offerts pour la carte", "title": "Lots de niveaux de détail", @@ -355,6 +353,7 @@ }, "expandFactor": { "type": "number", + "description": "Le rapport entre la taille de la carte d'aperçu et le rectangle d'étendue affiché sur cette carte. La valeur par défaut est 2, ce qui signifie que la carte d'aperçu aura au moins deux fois la taille du rectangle d'étendue.", "default": 2, "title": "Facteur d'expansion" }, diff --git a/src/schemas/schemaForm/ui.en-CA.json b/src/schemas/schemaForm/ui.en-CA.json index 3a837a7d..0b652a5f 100644 --- a/src/schemas/schemaForm/ui.en-CA.json +++ b/src/schemas/schemaForm/ui.en-CA.json @@ -47,6 +47,7 @@ "type": "string", "description": "An optional title to be used in the place of the default viewer title", "title": "Title", + "maxLength": 20, "default": "" }, "appBar": { diff --git a/src/schemas/schemaForm/ui.fr-CA.json b/src/schemas/schemaForm/ui.fr-CA.json index 0ed230f0..599bc92b 100644 --- a/src/schemas/schemaForm/ui.fr-CA.json +++ b/src/schemas/schemaForm/ui.fr-CA.json @@ -47,6 +47,7 @@ "type": "string", "description": "(Optionnel) - Un titre pour remplacer celui utilisé par défaut par le visualisateur.", "title": "Titre", + "maxLength": 20, "default": "" }, "appBar": {