From 98d874783f3fd110e84138761d2e0d860740c38a Mon Sep 17 00:00:00 2001 From: David Baldwynn Date: Wed, 15 Nov 2017 02:46:54 -0800 Subject: [PATCH] got email notifications to work with quilljs --- app/controllers/forms.server.controller.js | 14 +- app/libs/constants.js | 3 +- app/libs/send-email-notifications.js | 45 ++-- app/views/form.server.view.pug | 1 - app/views/index.server.view.pug | 8 +- bower.json | 8 +- package-lock.json | 242 +++++++++++++++++- package.json | 1 + .../forms/admin/css/edit-form-configure.css | 12 + public/modules/forms/admin/css/ta-theme.css | 7 +- .../configure-form.client.directive.js | 14 + .../respondent-notifications.html | 19 +- .../configureTabs/self-notifications.html | 22 +- 13 files changed, 330 insertions(+), 66 deletions(-) diff --git a/app/controllers/forms.server.controller.js b/app/controllers/forms.server.controller.js index 28d2c3f4..79459f8c 100644 --- a/app/controllers/forms.server.controller.js +++ b/app/controllers/forms.server.controller.js @@ -81,10 +81,14 @@ exports.createSubmission = function(req, res) { async.waterfall([ function(callback) { - if (form.selfNotifications && form.selfNotifications.enabled && form.selfNotifications.fromField) { - form.selfNotifications.fromEmails = formFieldDict[form.selfNotifications.fromField]; - - emailNotifications.send(form.selfNotifications, formFieldDict, smtpTransport, constants.varFormat, function(err){ + if (form.selfNotifications && form.selfNotifications.enabled) { + if(form.selfNotifications.fromField){ + form.selfNotifications.fromEmails = formFieldDict[form.selfNotifications.fromField]; + } else { + form.selfNotifications.fromEmails = config.mailer.options.from; + } + + emailNotifications.send(form.selfNotifications, formFieldDict, smtpTransport, function(err){ if(err){ return callback({ message: 'Failure sending submission self-notification email' @@ -102,7 +106,7 @@ exports.createSubmission = function(req, res) { form.respondentNotifications.toEmails = formFieldDict[form.respondentNotifications.toField]; debugger; - emailNotifications.send(form.respondentNotifications, formFieldDict, smtpTransport, constants.varFormat, function(err){ + emailNotifications.send(form.respondentNotifications, formFieldDict, smtpTransport, function(err){ if(err){ return callback({ message: 'Failure sending submission respondent-notification email' diff --git a/app/libs/constants.js b/app/libs/constants.js index 96a05966..9e5d92e8 100644 --- a/app/libs/constants.js +++ b/app/libs/constants.js @@ -74,6 +74,5 @@ module.exports = { url: /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/, hexCode: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/, email: /^(([^<>()\[\]\\.,;:\s@']+(\.[^<>()\[\]\\.,;:\s@']+)*)|('.+'))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, - }, - varFormat: [']+)class=["\']{1}.*field-', '["\']{1}.*>([^<>]+)*?<\/var>'], + } }; \ No newline at end of file diff --git a/app/libs/send-email-notifications.js b/app/libs/send-email-notifications.js index 0cf9590a..9b44b297 100644 --- a/app/libs/send-email-notifications.js +++ b/app/libs/send-email-notifications.js @@ -1,9 +1,11 @@ 'use strict'; +const jsdom = require("jsdom"); +var JSDOM = jsdom.JSDOM; module.exports = { - send: function(emailSettings, emailTemplateVars, smtpTransport, varFormat, cb){ - var parsedTemplate = this.parseTemplate(emailSettings.htmlTemplate, emailTemplateVars, varFormat); - var parsedSubject = this.parseTemplate(emailSettings.subject, emailTemplateVars, varFormat); + send: function(emailSettings, emailTemplateVars, smtpTransport, cb){ + var parsedTemplate = this.parseTemplate(emailSettings.htmlTemplate, emailTemplateVars); + var parsedSubject = this.parseTemplate(emailSettings.subject, emailTemplateVars); var mailOptions = { replyTo: emailSettings.fromEmails, from: 'noreply@tellform.com', @@ -12,29 +14,40 @@ module.exports = { html: parsedTemplate }; - smtpTransport.sendMail(mailOptions, function(){ - cb(); + smtpTransport.sendMail(mailOptions, function(err){ + cb(err); }); }, - parseTemplate: function(emailTemplate, emailAttrs, varFormat){ - var resolvedTemplate = emailTemplate; - var that = this; - Object.keys(emailAttrs).forEach(function (key) { - resolvedTemplate = that.replaceTemplateVal(key, emailAttrs[key], resolvedTemplate, varFormat); - }); - return resolvedTemplate; - }, + parseTemplate: function(emailTemplate, emailTemplateVars){ + var dom = new JSDOM(''+emailTemplate); + debugger; - replaceTemplateVal: function(key, val, template, varFormat){ - return template.replace( new RegExp(varFormat[0] + key + varFormat[1], 'g'), val); + Object.keys(emailTemplateVars).forEach(function (key) { + var elem = dom.window.document.querySelector("span.placeholder-tag[data-id='" + key + "']"); + if(elem !== null){ + elem.outerHTML = emailTemplateVars[key]; + } + }); + + debugger; + //Removed unused variables + //TODO: Currently querySelectorAll not working in JSDOM + /* + dom.window.document.querySelectorAll("span[data-id]").forEach(function(elem){ + if(elem !== null){ + elem.outerHTML = ''; + } + }) + */ + return dom.serialize(); }, createFieldDict: function(form_fields){ var formFieldDict = {}; form_fields.forEach(function(field){ if(field.hasOwnProperty('globalId') && field.hasOwnProperty('fieldValue')){ - formFieldDict[field.globalId] = field.fieldValue; + formFieldDict[field.globalId+''] = field.fieldValue+''; } }); return formFieldDict; diff --git a/app/views/form.server.view.pug b/app/views/form.server.view.pug index fa807c5f..9dbad5b2 100644 --- a/app/views/form.server.view.pug +++ b/app/views/form.server.view.pug @@ -59,7 +59,6 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml') script(type='text/javascript'). socketUrl = "!{socketUrl}" - script(src='/static/lib/jquery/dist/jquery.min.js', type='text/javascript') link(rel='stylesheet', href='/static/lib/font-awesome/css/font-awesome.min.css') link(rel='stylesheet', href='/static/lib/bootstrap/dist/css/bootstrap.min.css') diff --git a/app/views/index.server.view.pug b/app/views/index.server.view.pug index ba5f5d34..1c08be19 100644 --- a/app/views/index.server.view.pug +++ b/app/views/index.server.view.pug @@ -3,9 +3,9 @@ extends layout.server.view.pug block content section.content(ui-view='', ng-cloak='') - + link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.snow.min.css') + link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.bubble.min.css') link(rel='stylesheet', href='/static/lib/jquery-ui/themes/flick/jquery-ui.min.css') - script(src='/static/lib/jquery/jquery.min.js') //Embedding The User Object script(type='text/javascript'). @@ -44,7 +44,9 @@ block content script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.8/angular-strap.min.js') - script(src='https://cdnjs.cloudflare.com/ajax/libs/ng-quill/3.5.1/ng-quill.min.js') + script(src='https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.4/quill.min.js') + script(src='https://cdnjs.cloudflare.com/ajax/libs/ng-quill/3.5.1/ng-quill.js') + script(src='https://unpkg.com/quill-placeholder-module@0.2.0/dist/placeholder-module.js') //Application JavaScript Files each jsFile in jsFiles diff --git a/bower.json b/bower.json index c12eb2e5..1de6a8fb 100755 --- a/bower.json +++ b/bower.json @@ -49,14 +49,8 @@ }, "resolutions": { "angular-bootstrap": "^0.14.0", - "angular-sanitize": "1.4.14", - "angular-ui-sortable": "^0.17.1", - "angular-ui-date": "~0.0.11", - "angular-input-stars-directive": "master", - "angular-ui-select": "^0.19.8", "jquery": "^3.2.1", - "angular-ui-router": "^1.0.11", - "angular-permission": "^5.3.2" + "angular-ui-router": "^1.0.11" }, "overrides": { "BOWER-PACKAGE": { diff --git a/package-lock.json b/package-lock.json index ab46ade9..8516edc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "8.0.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.52.tgz", + "integrity": "sha512-wOU/VRodnI/4Chxuu6R6bcyN9aE3rztO0i8R76PZO7+DxTXWy60nseGN4ujspucmxrfj5mzgCYPXiXqrD6KC3Q==" + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -304,6 +314,11 @@ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -3194,6 +3209,11 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==" + }, "convert-source-map": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", @@ -3545,6 +3565,19 @@ "parserlib": "0.2.5" } }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=" + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "requires": { + "cssom": "0.3.2" + } + }, "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", @@ -3639,8 +3672,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "degenerator": { "version": "1.0.4", @@ -3767,6 +3799,11 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" }, + "domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.0.tgz", + "integrity": "sha512-WpwuBlZ2lQRFa4H/4w49deb9rJLot9KmqrKKjMc9qBl7CID+DdC2swoa34ccRl+anL2B6bLp6TjFdIdnzekMBQ==" + }, "domhandler": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", @@ -4160,8 +4197,7 @@ "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.7.0", @@ -4533,8 +4569,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "faye-websocket": { "version": "0.4.4", @@ -7062,6 +7097,14 @@ "core-util-is": "1.0.2" } }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "1.0.3" + } + }, "html-minifier": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.0.3.tgz", @@ -7893,6 +7936,78 @@ "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==", "dev": true }, + "jsdom": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.3.0.tgz", + "integrity": "sha512-aPZTDl4MplzQhx5bLztk6nzjbEslmO3Q3+z0WpCMutL1XJDhZIRzir6R1Y8S84LgeT/7jhQvgtUMkY6oPwvlUw==", + "requires": { + "abab": "1.0.4", + "acorn": "5.2.1", + "acorn-globals": "4.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.2", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "domexception": "1.0.0", + "escodegen": "1.9.0", + "html-encoding-sniffer": "1.0.2", + "nwmatcher": "1.4.3", + "parse5": "3.0.3", + "pn": "1.0.0", + "request": "2.83.0", + "request-promise-native": "1.0.5", + "sax": "1.2.4", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.3", + "webidl-conversions": "4.0.2", + "whatwg-encoding": "1.0.3", + "whatwg-url": "6.3.0", + "xml-name-validator": "2.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==" + }, + "acorn-globals": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", + "requires": { + "acorn": "5.2.1" + } + }, + "escodegen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "requires": { + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.5.7" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, "jshint": { "version": "2.9.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", @@ -8502,7 +8617,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "1.1.2", "type-check": "0.3.2" @@ -8761,6 +8875,11 @@ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "log-driver": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", @@ -9849,6 +9968,11 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwmatcher": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" + }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", @@ -9916,7 +10040,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "0.1.3", "fast-levenshtein": "2.0.6", @@ -9929,8 +10052,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" } } }, @@ -10093,6 +10215,14 @@ "error-ex": "1.3.1" } }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "8.0.52" + } + }, "parsejson": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", @@ -10492,11 +10622,15 @@ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz", "integrity": "sha1-ZGx3ARiZhwtqCQPnXpl+jlHadGE=" }, + "pn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.0.0.tgz", + "integrity": "sha1-HPWjCw2AbNGPiPxBprXUrWFbO6k=" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", @@ -11286,6 +11420,24 @@ "throttleit": "1.0.0" } }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "4.17.4" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.3" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11386,6 +11538,11 @@ "graceful-fs": "1.2.3" } }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "scandirectory": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/scandirectory/-/scandirectory-2.5.0.tgz", @@ -11931,6 +12088,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -12144,6 +12306,11 @@ "upper-case": "1.1.3" } }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + }, "taskgroup": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/taskgroup/-/taskgroup-4.3.1.tgz", @@ -12289,6 +12456,21 @@ "punycode": "1.4.1" } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, "transformers": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", @@ -12364,7 +12546,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "1.1.2" } @@ -12723,6 +12904,36 @@ "typechecker": "2.1.0" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + } + } + }, + "whatwg-url": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.3.0.tgz", + "integrity": "sha512-rM+hE5iYKGPAOu05mIdJR47pYSR2vDzfrTEFRc/S8D3L60yW8BuXmUJ7Kog7x/DrokFN7JNaHKadpzjouKRRAw==", + "requires": { + "lodash.sortby": "4.7.0", + "tr46": "1.0.1", + "webidl-conversions": "4.0.2" + } + }, "which": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", @@ -12887,6 +13098,11 @@ "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=" }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" + }, "xmlhttprequest-ssl": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", diff --git a/package.json b/package.json index 5f3ba4c4..1602d47e 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "helmet": "3.5.0", "i18n": "^0.8.3", "jit-grunt": "^0.9.1", + "jsdom": "^11.3.0", "lodash": "^4.17.4", "main-bower-files": "~2.9.0", "method-override": "~2.3.0", diff --git a/public/modules/forms/admin/css/edit-form-configure.css b/public/modules/forms/admin/css/edit-form-configure.css index 6e16af14..56e28133 100644 --- a/public/modules/forms/admin/css/edit-form-configure.css +++ b/public/modules/forms/admin/css/edit-form-configure.css @@ -9,4 +9,16 @@ .notification-toggle.toggle-switch { margin: 5px 0; +} + +.ql-picker.ql-placeholder { + width: 118px; +} + +.ql-picker.ql-placeholder > span.ql-picker-label::before { + content: 'Placeholders'; +} + +.ql-picker.ql-placeholder > span.ql-picker-options > span.ql-picker-item::before { + content: attr(data-label); } \ No newline at end of file diff --git a/public/modules/forms/admin/css/ta-theme.css b/public/modules/forms/admin/css/ta-theme.css index def3a72c..bb54fa78 100644 --- a/public/modules/forms/admin/css/ta-theme.css +++ b/public/modules/forms/admin/css/ta-theme.css @@ -1,9 +1,4 @@ -.ta-editor > div.ta-bind p { - display: inline-block; - min-width: 1px; -} - -.tag { +.placeholder-tag { background-color: #999; border-radius: 3px 3px 3px 3px; border: 0; diff --git a/public/modules/forms/admin/directives/configure-form.client.directive.js b/public/modules/forms/admin/directives/configure-form.client.directive.js index d04f6293..ebdda385 100644 --- a/public/modules/forms/admin/directives/configure-form.client.directive.js +++ b/public/modules/forms/admin/directives/configure-form.client.directive.js @@ -14,6 +14,20 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope', '$fil $scope.resetForm = $rootScope.resetForm; $scope.update = $rootScope.update; + Quill.register('modules/placeholder', PlaceholderModule.default(Quill)) + $scope.customModules = { + placeholder: { + placeholders: $scope.myform.visible_form_fields.map(function(field){ + return { + id: field.globalId, + label: field.title + }; + }), + className: 'placeholder-tag', + delimiters: ['', ''], + } + }; + $scope.configureTabs = [ { heading: $filter('translate')('GENERAL_TAB'), diff --git a/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html b/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html index 79eca037..184eaff4 100644 --- a/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html +++ b/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html @@ -74,20 +74,21 @@
- - + -
+
+ + +
diff --git a/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html b/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html index 1ca61f0d..ba9fa80d 100644 --- a/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html +++ b/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html @@ -70,10 +70,24 @@
- - + + +
+ + + + + + + +
+
+