diff --git a/app/controllers/forms.server.controller.js b/app/controllers/forms.server.controller.js index dc28ed73..600ef7b0 100644 --- a/app/controllers/forms.server.controller.js +++ b/app/controllers/forms.server.controller.js @@ -10,7 +10,13 @@ var mongoose = require('mongoose'), config = require('../../config/config'), diff = require('deep-diff'), _ = require('lodash'), - helpers = require('./helpers.server.controller'); + nodemailer = require('nodemailer'), + emailNotifications = require('../libs/send-email-notifications'), + constants = require('../libs/constants'), + helpers = require('./helpers.server.controller'), + async = require('async'); + +var smtpTransport = nodemailer.createTransport(config.mailer.options); /** * Delete a forms submissions @@ -70,7 +76,51 @@ exports.createSubmission = function(req, res) { message: errorHandler.getErrorMessage(err) }); } - res.status(200).send('Form submission successfully saved'); + var form = req.body + var formFieldDict = emailNotifications.createFieldDict(form.form_fields); + + 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(err){ + return callback({ + message: 'Failure sending submission self-notification email' + }); + } + + callback(); + }); + } else { + callback(); + } + }, + function(callback) { + if (form.respondentNotifications && form.respondentNotifications.enabled && form.respondentNotifications.toField) { + + form.respondentNotifications.toEmails = formFieldDict[form.respondentNotifications.toField]; + debugger; + emailNotifications.send(form.respondentNotifications, formFieldDict, smtpTransport, constants.varFormat, function(err){ + if(err){ + return callback({ + message: 'Failure sending submission respondent-notification email' + }); + } + + callback(); + }); + } else { + callback(); + } + } + ], function (err) { + if(err){ + return res.status(400).send(err); + } + res.status(200).send('Form submission successfully saved'); + }); }); }; @@ -95,14 +145,13 @@ exports.listSubmissions = function(req, res) { * Create a new form */ exports.create = function(req, res) { - if(!req.body.form){ return res.status(400).send({ message: 'Invalid Input' }); } + var form = new Form(req.body.form); - form.admin = req.user._id; form.save(function(err, createdForm) { @@ -173,7 +222,7 @@ exports.update = function(req, res) { form.analytics = { visitors: [], gaCode: '' - } + }; } if (req.body.changes) { @@ -302,7 +351,7 @@ exports.formByIDFast = function(req, res, next, id) { } Form.findById(id) .lean() - .select('title language form_fields startPage endPage hideFooter isLive design analytics.gaCode') + .select('title language form_fields startPage endPage hideFooter isLive design analytics.gaCode selfNotifications respondentNotifications') .exec(function(err, form) { if (err) { return next(err); diff --git a/app/controllers/helpers.server.controller.js b/app/controllers/helpers.server.controller.js index 42499b92..f769187f 100644 --- a/app/controllers/helpers.server.controller.js +++ b/app/controllers/helpers.server.controller.js @@ -1,3 +1,5 @@ +'use strict'; + module.exports = { removeSensitiveModelData: function(type, object){ var privateFields = { @@ -5,7 +7,7 @@ module.exports = { 'private_form': ['__v'], 'public_user': ['passwordHash', 'password', 'provider', 'salt', 'lastModified', 'created', 'resetPasswordToken', 'resetPasswordExpires', 'token', 'apiKey', '__v'], 'private_user': ['passwordHash', 'password', 'provider', 'salt', 'resetPasswordToken', 'resetPasswordExpires', 'token', '__v'] - } + }; function removeKeysFromDict(dict, keys){ for(var i=0; i()\[\]\\.,;:\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,}))$/ - } + 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,}))$/, + templateVariable: /(.|\n)*?<\/var>/g + }, + + varFormat: [']+)id=["\']{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 new file mode 100644 index 00000000..30af3aad --- /dev/null +++ b/app/libs/send-email-notifications.js @@ -0,0 +1,44 @@ +'use strict'; + +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); + var mailOptions = { + replyTo: emailSettings.fromEmails, + from: 'noreply@tellform.com', + cc: emailSettings.toEmails, + subject: parsedSubject, + html: parsedTemplate + }; + + console.log('HERE'); + smtpTransport.sendMail(mailOptions, function(){ + console.log('THERE'); + cb(); + }); + }, + + 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; + }, + + replaceTemplateVal: function(key, val, template, varFormat){ + return template.replace( new RegExp(varFormat[0] + key + varFormat[1], 'g'), val); + }, + + createFieldDict: function(form_fields){ + var formFieldDict = {}; + form_fields.forEach(function(field){ + if(field.hasOwnProperty('globalId') && field.hasOwnProperty('fieldValue')){ + formFieldDict[field.globalId] = field.fieldValue; + } + }); + return formFieldDict; + } +}; \ No newline at end of file diff --git a/app/libs/timestamp.server.plugin.js b/app/libs/timestamp.server.plugin.js index 084e2c1b..bba1649d 100644 --- a/app/libs/timestamp.server.plugin.js +++ b/app/libs/timestamp.server.plugin.js @@ -2,38 +2,36 @@ // Plugin module.exports = function timestamp (schema, options) { - options || (options = {}) + options = options || (options === {}); // Options - var fields = {} - , createdPath = options.createdPath || 'created' - , modifiedPath = options.modifiedPath || 'modified' - , useVirtual = (options.useVirtual !== undefined) - ? options.useVirtual - : true + var fields = {}, + createdPath = options.createdPath || 'created', + modifiedPath = options.modifiedPath || 'modified', + useVirtual = (options.useVirtual !== undefined) ? options.useVirtual : true; // Add paths to schema if not present if (!schema.paths[createdPath]) { - fields[modifiedPath] = { type: Date } + fields[modifiedPath] = { type: Date }; } if (useVirtual) { // Use the ObjectID for extracting the created time schema.virtual(createdPath).get(function () { - return new Date(this._id.generationTime * 1000) - }) + return new Date(this._id.generationTime * 1000); + }); } else { if (!schema.paths[createdPath]) { fields[createdPath] = { - type: Date - , default: Date.now - } + type: Date, + default: Date.now + }; } } - schema.add(fields) + schema.add(fields); // Update the modified timestamp on save schema.pre('save', function (next) { - this[modifiedPath] = new Date - next() - }) -} \ No newline at end of file + this[modifiedPath] = new Date(); + next(); + }); +}; \ No newline at end of file diff --git a/app/models/form.server.model.js b/app/models/form.server.model.js index 5f8321a0..7aaef85e 100644 --- a/app/models/form.server.model.js +++ b/app/models/form.server.model.js @@ -9,7 +9,8 @@ var mongoose = require('mongoose'), timeStampPlugin = require('../libs/timestamp.server.plugin'), async = require('async'), Random = require('random-js'), - mt = Random.engines.mt19937(); + mt = Random.engines.mt19937(), + constants = require('../libs/constants'); mt.autoSeed(); @@ -57,11 +58,12 @@ var VisitorDataSchema = new Schema({ type: Boolean }, language: { - type: String + type: String, + enum: constants.languageTypes, + default: 'en', }, ipAddr: { - type: String, - default: '' + type: String }, deviceType: { type: String, @@ -154,6 +156,47 @@ var FormSchema = new Schema({ buttons:[ButtonSchema] }, + selfNotifications: { + fromField: { + type: String + }, + toEmails: { + type: String + }, + subject: { + type: String + }, + htmlTemplate: { + type: String + }, + enabled: { + type: Boolean, + default: false + } + }, + + respondentNotifications: { + toField: { + type: String + }, + fromEmails: { + type: String, + match: [/.+\@.+\..+/, 'Please fill a valid email address'] + }, + subject: { + type: String, + default: 'Tellform: Thank you for filling out this TellForm' + }, + htmlTemplate: { + type: String, + default: 'Hello,

We’ve received your submission.

Thank you & have a nice day!', + }, + enabled: { + type: Boolean, + default: false + } + }, + hideFooter: { type: Boolean, default: false @@ -207,10 +250,6 @@ FormSchema.virtual('analytics.views').get(function () { } }); -FormSchema.virtual('analytics.submissions').get(function () { - return this.submissions.length; -}); - FormSchema.virtual('analytics.conversionRate').get(function () { if(this.analytics && this.analytics.visitors && this.analytics.visitors.length > 0){ return this.submissions.length/this.analytics.visitors.length*100; diff --git a/app/models/form_field.server.model.js b/app/models/form_field.server.model.js index 31f96e71..4df9c741 100644 --- a/app/models/form_field.server.model.js +++ b/app/models/form_field.server.model.js @@ -9,7 +9,8 @@ var mongoose = require('mongoose'), _ = require('lodash'), Schema = mongoose.Schema, LogicJumpSchema = require('./logic_jump.server.model'), - tokgen = require('../libs/tokenGenerator'); + tokgen = require('../libs/tokenGenerator'), + constants = require('../libs/constants'); var FieldOptionSchema = new Schema({ option_id: { @@ -34,21 +35,7 @@ var RatingFieldSchema = new Schema({ }, shape: { type: String, - enum: [ - 'Heart', - 'Star', - 'thumbs-up', - 'thumbs-down', - 'Circle', - 'Square', - 'Check Circle', - 'Smile Outlined', - 'Hourglass', - 'bell', - 'Paper Plane', - 'Comment', - 'Trash' - ] + enum: constants.ratingShapeTypes }, validShapes: { type: [String] @@ -103,29 +90,7 @@ function BaseFieldSchema(){ }, fieldType: { type: String, - enum: [ - 'textfield', - 'date', - 'email', - 'link', - 'legal', - 'url', - 'textarea', - 'statement', - 'welcome', - 'thankyou', - 'file', - 'dropdown', - 'scale', - 'rating', - 'radio', - 'checkbox', - 'hidden', - 'yes_no', - 'natural', - 'stripe', - 'number' - ] + enum: constants.fieldTypes }, fieldValue: Schema.Types.Mixed }); @@ -140,7 +105,7 @@ function BaseFieldSchema(){ this.validFieldTypes = mongoose.model('Field').schema.path('fieldType').enumValues; if(this.fieldType === 'rating' && this.ratingOptions.validShapes.length === 0){ - this.ratingOptions.validShapes = mongoose.model('RatingOptions').schema.path('shape').enumValues; + this.ratingOptions.validShapes = constants.ratingShapeTypes; } next(); diff --git a/app/models/form_submission.server.model.js b/app/models/form_submission.server.model.js index a3505f3a..6e77529f 100644 --- a/app/models/form_submission.server.model.js +++ b/app/models/form_submission.server.model.js @@ -55,18 +55,18 @@ FormSubmissionSchema.pre('save', function (next) { this.form_fields[i].fieldValue = this.form_fields[i].fieldValue.option_value; } - delete form_fields[i].validFieldTypes; - delete form_fields[i].disabled; - delete form_fields[i].required; - delete form_fields[i].isSubmission; - delete form_fields[i].title; - delete form_fields[i].fieldOptions; - delete form_fields[i].ratingOptions; - delete form_fields[i].logicJump; - delete form_fields[i].description; - delete form_fields[i].created; - delete form_fields[i].lastModified; - delete form_fields[i].deletePreserved; + delete this.form_fields[i].validFieldTypes; + delete this.form_fields[i].disabled; + delete this.form_fields[i].required; + delete this.form_fields[i].isSubmission; + delete this.form_fields[i].title; + delete this.form_fields[i].fieldOptions; + delete this.form_fields[i].ratingOptions; + delete this.form_fields[i].logicJump; + delete this.form_fields[i].description; + delete this.form_fields[i].created; + delete this.form_fields[i].lastModified; + delete this.form_fields[i].deletePreserved; } next(); }); diff --git a/app/models/user.server.model.js b/app/models/user.server.model.js index ab1d35b0..51fa3341 100755 --- a/app/models/user.server.model.js +++ b/app/models/user.server.model.js @@ -10,7 +10,8 @@ var mongoose = require('mongoose'), timeStampPlugin = require('../libs/timestamp.server.plugin'), path = require('path'), querystring = require('querystring'), - nodemailer = require('nodemailer'); + nodemailer = require('nodemailer'), + constants = require('../libs/constants'); var smtpTransport = nodemailer.createTransport(config.mailer.options); @@ -42,7 +43,7 @@ var UserSchema = new Schema({ trim: true, lowercase: true, unique: 'Account already exists with this email', - match: [/.+\@.+\..+/, 'Please fill a valid email address'], + match: [constants.regex.email, 'Please fill a valid email address'], required: [true, 'Email is required'] }, username: { @@ -66,13 +67,13 @@ var UserSchema = new Schema({ roles: { type: [{ type: String, - enum: ['user', 'admin', 'superuser'] + enum: constants.userRoleTypes }], default: ['user'] }, language: { type: String, - enum: ['en', 'fr', 'es', 'it', 'de'], + enum: constants.languageTypes, default: 'en', }, lastModified: { diff --git a/app/routes/forms.server.routes.js b/app/routes/forms.server.routes.js index 6798e525..fbb4335a 100644 --- a/app/routes/forms.server.routes.js +++ b/app/routes/forms.server.routes.js @@ -31,7 +31,7 @@ module.exports = function(app) { } app.route('/forms/:formIdFast([a-zA-Z0-9]+)') - .post(forms.createSubmission) + .post(forms.createSubmission); app.route('/forms') .get(auth.isAuthenticatedOrApiKey, forms.list) diff --git a/app/tests/form.server.routes.test.js b/app/tests/form.server.routes.test.js index 1ed05b06..a4c16889 100644 --- a/app/tests/form.server.routes.test.js +++ b/app/tests/form.server.routes.test.js @@ -166,7 +166,7 @@ describe('Form Routes Unit tests', function() { it(' > should not be able to create a Form if body is empty', function(done) { loginSession.post('/forms') .send({form: null}) - .expect(400, {"message":"Invalid Input"}) + .expect(400, {'message':'Invalid Input'}) .end(function(FormSaveErr, FormSaveRes) { // Call the assertion callback done(FormSaveErr); diff --git a/app/tests/form_submission.model.test.js b/app/tests/form_submission.model.test.js index d7874e5c..262fbf04 100644 --- a/app/tests/form_submission.model.test.js +++ b/app/tests/form_submission.model.test.js @@ -81,8 +81,8 @@ describe('FormSubmission Model Unit Tests:', function() { user = new User({ firstName: 'Full', lastName: 'Name', - email: 'test1@test.com'+Date.now(), - username: 'test1'+Date.now(), + email: 'test1@test.com', + username: 'test1', password: 'password', provider: 'local' }); diff --git a/app/tests/form_submission.routes.test.js b/app/tests/form_submission.routes.test.js index 13d5e780..6398828e 100644 --- a/app/tests/form_submission.routes.test.js +++ b/app/tests/form_submission.routes.test.js @@ -21,15 +21,14 @@ var credentials, user; * Form routes tests */ describe('Form Submission Routes Unit tests', function() { - var FormObj, _Submission, submissionSession, _SubmissionBody - + var FormObj, _Submission, submissionSession, _SubmissionBody; beforeEach(function(done) { // Create user credentials credentials = { - email: 'test@test.com', - username: 'test', + email: 'test423@test.com', + username: 'test534', password: 'password' }; @@ -45,7 +44,10 @@ describe('Form Submission Routes Unit tests', function() { // Save a user to the test db and create new Form user.save(function(err) { - if(err) return done(err); + if(err) { + return done(err); + } + FormObj = new Form({ title: 'Form Title', language: 'en', @@ -54,7 +56,22 @@ describe('Form Submission Routes Unit tests', function() { new Field({'fieldType':'textfield', 'title':'First Name', 'fieldValue': ''}), new Field({'fieldType':'checkbox', 'title':'nascar', 'fieldValue': ''}), new Field({'fieldType':'checkbox', 'title':'hockey', 'fieldValue': ''}) - ] + ], + selfNotifications: { + fromField: mongoose.Types.ObjectId(), + toEmails: 'john@smith.com', + subject: 'Hello there', + htmlTemplate: '

A form was submitted

', + enabled: true + }, + + respondentNotifications: { + toField: mongoose.Types.ObjectId(), + fromEmails: 'john@smith.com', + subject: 'Tellform: Thank you for filling out this TellForm', + htmlTemplate:'Hello,

We’ve received your submission.

Thank you & have a nice day!', + enabled: true + } }); FormObj.save(function(formSaveErr, form) { @@ -237,6 +254,4 @@ describe('Form Submission Routes Unit tests', function() { }); }); }); - - }); diff --git a/app/tests/libs/send-email-notifications.test.js b/app/tests/libs/send-email-notifications.test.js new file mode 100644 index 00000000..10f8d98f --- /dev/null +++ b/app/tests/libs/send-email-notifications.test.js @@ -0,0 +1,94 @@ +'use strict'; + +/** + * Module dependencies. + */ +const emailNotifications = require('../../libs/send-email-notifications'), + constants = require('../../libs/constants'), + mockTransport = require("nodemailer").createTransport("Stub"), + config = require('../../../config/config'); + +/** + * Globals + */ +const validFormFields = [ + {fieldType:'textfield', title:'First Name', fieldValue: 'John Smith', deletePreserved: false, globalId:'56340745f59a6fc9e22028e9'}, + {fieldType:'link', title:'Your Website', fieldValue: 'https://johnsmith.me', deletePreserved: false, globalId:'5c9e22028e907634f45f59a6'}, + {fieldType:'number', title:'Your Age', fieldValue: 45, deletePreserved: false, globalId:'56e90745f5934fc9e22028a6'} +]; + +const validFieldDict = { + '56340745f59a6fc9e22028e9': 'John Smith', + '5c9e22028e907634f45f59a6': 'https://johnsmith.me', + '56e90745f5934fc9e22028a6': 45 +}; + +const invalidFormFields = [ + {fieldType:'textfield', title:'First Name', fieldValue: 'John Smith', deletePreserved: false}, + {fieldType:'link', title:'Your Website', deletePreserved: false, _id:'5c9e22028e907634f45f59a6'}, + {fieldType:'number', title:'Your Age'} +]; + +const htmlTemplate = '

First Name \ +
Your Website \ +
Your Age

'; + +const renderedTemplate = '

John Smith \ +
https://johnsmith.me \ +
45

'; + +/** + * Unit tests + */ +describe('Send Email Notification Unit Tests', function() { + + describe('Method createFieldDict', function() { + it('should be return a fieldDict from valid form fields', function() { + var actualFieldDict = emailNotifications.createFieldDict(validFormFields); + actualFieldDict.should.deepEqual(validFieldDict); + }); + + it('should return empty object if form fields are invalid or empty ', function() { + var actualFieldDict = emailNotifications.createFieldDict(invalidFormFields); + actualFieldDict.should.be.empty(); + }); + }); + + describe('Method parseTemplate', function(){ + it('should properly render a template given a valid field dict', function() { + var actualRenderedTemplate = emailNotifications.parseTemplate(htmlTemplate, validFieldDict, constants.varFormat).replace((/ |\r\n|\n|\r|\t/gm),''); + actualRenderedTemplate.should.equal(renderedTemplate.replace((/ |\r\n|\n|\r|\t/gm),'')); + }); + }); + + describe('Method replaceTemplateVal', function() { + it('should properly replace a template var in a valid template', function() { + var expectedHtml = '

John Smith \ +
Your Website \ +
Your Age

'; + + var actualRenderedTemplate = emailNotifications.replaceTemplateVal('56340745f59a6fc9e22028e9', validFieldDict['56340745f59a6fc9e22028e9'], htmlTemplate, constants.varFormat).replace((/ |\r\n|\n|\r|\t/gm),''); + actualRenderedTemplate.should.equal(expectedHtml.replace((/ |\r\n|\n|\r|\t/gm),'')); + }); + }); + + describe('Method send', function() { + this.timeout(10000); + const emailSettings = { + fromEmails: 'somewhere@somewhere.com', + toEmails: 'there@there.com', + subject: 'Hello First Name!', + htmlTemplate: htmlTemplate + }; + + const emailTemplateVars = validFieldDict; + const varFormat = constants.varFormat; + + it('should properly replace a template var in a valid template', function(done) { + emailNotifications.send(emailSettings, emailTemplateVars, mockTransport, varFormat, function(err){ + should.not.exist(err); + done(); + }); + }); + }); +}); diff --git a/app/tests/libs/timestamp.server.plugin.test.js b/app/tests/libs/timestamp.server.plugin.test.js index 2901fe72..d943ec27 100644 --- a/app/tests/libs/timestamp.server.plugin.test.js +++ b/app/tests/libs/timestamp.server.plugin.test.js @@ -1,70 +1,72 @@ +'use strict'; + // Dependencies -var util = require('util') - , assert = require('assert') - , mongoose = require('mongoose') - , timestamp = require('../../libs/timestamp.server.plugin') - , Schema = mongoose.Schema - , ObjectId = Schema.ObjectId +var util = require('util'), + assert = require('assert'), + mongoose = require('mongoose'), + timestamp = require('../../libs/timestamp.server.plugin'), + Schema = mongoose.Schema, + ObjectId = Schema.ObjectId; // Run tests describe('Timestamp', function () { describe('#default()', function () { - var FooSchema = new Schema() - FooSchema.plugin(timestamp) - var FooModel = mongoose.model('timeFoo', FooSchema) - , bar = new FooModel() + var FooSchema = new Schema(); + FooSchema.plugin(timestamp); + var FooModel = mongoose.model('timeFoo', FooSchema), + bar = new FooModel(); before(function () { FooModel.remove(function (err) { - assert.strictEqual(err, null) - }) - }) + assert.strictEqual(err, null); + }); + }); it('should have custom properties', function (done) { - assert.strictEqual(typeof FooSchema.virtuals.created, 'object') - assert.strictEqual(typeof FooSchema.paths.modified, 'object') - done() - }) + assert.strictEqual(typeof FooSchema.virtuals.created, 'object'); + assert.strictEqual(typeof FooSchema.paths.modified, 'object'); + done(); + }); it('should create the default attributes', function (done) { bar.save(function (err, doc) { - assert.strictEqual(err, null) - assert.strictEqual(util.isDate(doc.created), true) - assert.strictEqual(util.isDate(doc.modified), true) - done() - }) - }) - }) + assert.strictEqual(err, null); + assert.strictEqual(util.isDate(doc.created), true); + assert.strictEqual(util.isDate(doc.modified), true); + done(); + }); + }); + }); describe('#custom()', function () { - var FooSchema = new Schema() + var FooSchema = new Schema(); FooSchema.plugin(timestamp, { - createdPath: 'oh' - , modifiedPath: 'hai' - , useVirtual: false - }) - var BarModel = mongoose.model('timeBar', FooSchema) - , bar = new BarModel() + createdPath: 'oh', + modifiedPath: 'hai', + useVirtual: false + }); + var BarModel = mongoose.model('timeBar', FooSchema), + bar = new BarModel(); before(function () { BarModel.remove(function (err) { - assert.strictEqual(err, null) - }) - }) + assert.strictEqual(err, null); + }); + }); it('should have custom properties', function (done) { - assert.strictEqual(typeof FooSchema.paths.oh, 'object') - assert.strictEqual(typeof FooSchema.paths.hai, 'object') - done() - }) + assert.strictEqual(typeof FooSchema.paths.oh, 'object'); + assert.strictEqual(typeof FooSchema.paths.hai, 'object'); + done(); + }); it('should create custom attributes', function (done) { bar.save(function (err, doc) { - assert.strictEqual(err, null) - assert.strictEqual(util.isDate(doc.oh), true) - assert.strictEqual(util.isDate(doc.hai), true) - done() - }) - }) - }) -}) \ No newline at end of file + assert.strictEqual(err, null); + assert.strictEqual(util.isDate(doc.oh), true); + assert.strictEqual(util.isDate(doc.hai), true); + done(); + }); + }); + }); +}); \ No newline at end of file diff --git a/app/tests/user.server.routes.test.js b/app/tests/user.server.routes.test.js index 12b7af76..7198d449 100644 --- a/app/tests/user.server.routes.test.js +++ b/app/tests/user.server.routes.test.js @@ -48,7 +48,7 @@ describe('User CRUD tests', function() { .send(_User) .expect(200) .end(function(err) { - callback(err) + callback(err); }); }, function(callback) { @@ -136,7 +136,7 @@ describe('User CRUD tests', function() { if(err){ callback(err); } - callback(null, user.resetPasswordToken) + callback(null, user.resetPasswordToken); }); }, function(resetPasswordToken, callback) { diff --git a/app/views/form.server.view.pug b/app/views/form.server.view.pug index 451536e7..2c44f399 100644 --- a/app/views/form.server.view.pug +++ b/app/views/form.server.view.pug @@ -78,13 +78,15 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml') //Socket.io Client Dependency script(src='/static/lib/socket.io-client/dist/socket.io.min.js') - script(src='/static/lib/jquery-ui/jquery-ui.js', type='text/javascript') //Minified Bower Dependencies script(src='/static/lib/angular/angular.min.js') script(src='/static/dist/vendor.min.js') script(src='/static/lib/angular-ui-date/src/date.js', type='text/javascript') + script(src='/static/lib/jquery-ui/jquery-ui.js', type='text/javascript') + script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js', integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa', crossorigin='anonymous') + //Application JavaScript Files each jsFile in formJSFiles script(type='text/javascript', src=jsFile) diff --git a/app/views/index.server.view.pug b/app/views/index.server.view.pug index 10c29935..0d0c17fc 100644 --- a/app/views/index.server.view.pug +++ b/app/views/index.server.view.pug @@ -3,7 +3,9 @@ extends layout.server.view.pug block content section.content(ui-view='', ng-cloak='') - script(src='/static/lib/file-saver.js/FileSaver.js', type='text/javascript') + + 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'). diff --git a/app/views/layout.server.view.pug b/app/views/layout.server.view.pug index 39ba97d5..7509f3a2 100644 --- a/app/views/layout.server.view.pug +++ b/app/views/layout.server.view.pug @@ -31,8 +31,8 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml') // Fav Icon link(href='/static/modules/core/img/brand/favicon.ico', rel='shortcut icon', type='image/x-icon') - link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css') - link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous') + 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') link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,900') //Bower CSS dependencies @@ -40,7 +40,6 @@ html(lang='en', xmlns='http://www.w3.org/1999/xhtml') link(rel='stylesheet', href=bowerCssFile) link(rel='stylesheet', href='/static/lib/angular-input-stars/angular-input-stars.css') link(rel='stylesheet', href='/static/lib/jquery-ui/themes/flick/jquery-ui.css') - link(rel='stylesheet', href='/static/modules/core/css/github-fork-ribbon.css') // end Bower CSS dependencies //Application CSS Files diff --git a/bower.json b/bower.json index afdaec71..4336c3ac 100755 --- a/bower.json +++ b/bower.json @@ -25,7 +25,6 @@ "angular-permission": "~1.1.1", "file-saver.js": "~1.20150507.2", "angular-bootstrap-colorpicker": "~3.0.19", - "angular-ui-router-tabs": "~1.7.0", "angular-scroll": "^1.0.0", "angular-sanitize": "1.4.14", "v-button": "^1.1.1", @@ -33,7 +32,6 @@ "raven-js": "^3.0.4", "tableExport.jquery.plugin": "^1.5.1", "js-yaml": "^3.6.1", - "angular-ui-select": "https://github.com/tellform/ui-select.git#compiled", "angular-translate": "~2.11.0", "ng-translate": "*", "deep-diff": "^0.3.4", @@ -42,17 +40,22 @@ "mobile-detect": "^1.3.3", "socket.io-client": "^1.7.2", "css-toggle-switch": "^4.0.2", - "angular-strap": "^2.3.12" + "angular-strap": "^2.3.12", + "textAngular": "^1.5.16", + "angular-ui-select": "^0.19.8", + "angular-bootstrap-switch": "^0.5.2", + "jquery": "^3.2.1" }, "resolutions": { "angular-bootstrap": "^0.14.0", "angular": "1.4.14", - "angular-ui-select": "compiled", "jspdf": "~1.0.178", "angular-sanitize": "1.4.14", "angular-ui-sortable": "^0.17.1", "angular-ui-date": "~0.0.11", - "angular-input-stars-directive": "master" + "angular-input-stars-directive": "master", + "angular-ui-select": "^0.19.8", + "jquery": "^3.2.1" }, "overrides": { "BOWER-PACKAGE": { diff --git a/config/express.js b/config/express.js index ae73bf16..99357774 100755 --- a/config/express.js +++ b/config/express.js @@ -39,8 +39,9 @@ var configureSocketIO = function (app, db) { var supportedLanguages = ['en', 'de', 'fr', 'it', 'es']; function containsAnySupportedLanguages(preferredLanguages){ - for (var i = 0; i < preferredLanguages.length; i++) { - var currIndex = supportedLanguages.indexOf(preferredLanguages[i]); + var i, currIndex; + for (i = 0; i < preferredLanguages.length; i++) { + currIndex = supportedLanguages.indexOf(preferredLanguages[i]); if (currIndex > -1) { return supportedLanguages[currIndex]; } @@ -226,7 +227,6 @@ module.exports = function(db) { // Setting the app router and static folder app.use('/static', express.static(path.resolve('./public'))); - app.use('/uploads', express.static(path.resolve('./uploads'))); // CookieParser should be above session app.use(cookieParser()); @@ -261,6 +261,7 @@ module.exports = function(db) { //Visitor Language Detection app.use(function(req, res, next) { var acceptLanguage = req.headers['accept-language']; + var languages, supportedLanguage; if(acceptLanguage){ @@ -270,13 +271,12 @@ module.exports = function(db) { if(!req.user && supportedLanguage !== null){ var currLanguage = res.cookie('userLang'); - if(currLanguage && currLanguage !== supportedLanguage || !currLanguage){ res.clearCookie('userLang'); res.cookie('userLang', supportedLanguage, { maxAge: 90000, httpOnly: true }); + } else if(req.user && (!req.cookies.hasOwnProperty('userLang') || req.cookies.userLang !== req.user.language) ){ + res.cookie('userLang', req.user.language, { maxAge: 90000, httpOnly: true }); } - } else if(req.user && (!req.cookies.hasOwnProperty('userLang') || req.cookies['userLang'] !== req.user.language) ){ - res.cookie('userLang', req.user.language, { maxAge: 90000, httpOnly: true }); } next(); }); diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 00000000..c6e61e2a Binary files /dev/null and b/dump.rdb differ diff --git a/gruntfile.js b/gruntfile.js index 943dc796..ad0e35b8 100755 --- a/gruntfile.js +++ b/gruntfile.js @@ -1,4 +1,4 @@ - +'use strict'; var bowerArray = ['public/lib/angular/angular.min.js', 'public/lib/angular-scroll/angular-scroll.min.js', diff --git a/package-lock.json b/package-lock.json index ad6d9b12..b3ee6f49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -442,22 +442,6 @@ "integrity": "sha1-PzQU84AyF0O/wQQvmoP/HVgk1GQ=", "dev": true }, - "bcrypt": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.8.7.tgz", - "integrity": "sha1-vDh1qa/Qp7LNIxpqfyGKXOFWsJM=", - "requires": { - "bindings": "1.2.1", - "nan": "2.3.5" - }, - "dependencies": { - "nan": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.3.5.tgz", - "integrity": "sha1-gioNwmYpDOTNOhIoLKPn42Rmigg=" - } - } - }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -485,11 +469,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=" }, - "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=" - }, "bl": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", @@ -2736,11 +2715,6 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, - "byt": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/byt/-/byt-0.1.0.tgz", - "integrity": "sha1-tyVTl3uMTciQ0mL9XiDzMAOdFUs=" - }, "bytes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", @@ -4406,6 +4380,15 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, "extendr": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/extendr/-/extendr-2.1.0.tgz", @@ -6260,14 +6243,6 @@ "jade": "1.11.0" } }, - "grunt-i18nlint": { - "version": "github:jwarby/grunt-i18nlint#6b398f775c8ca881a16f45a3cb94c5b79ee11e20", - "dev": true, - "requires": { - "chalk": "1.1.3", - "i18n-lint": "git://github.com/jwarby/i18n-lint.git#0a06373c0d880047ad680239c103d60ed414efc1" - } - }, "grunt-karma": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/grunt-karma/-/grunt-karma-0.12.2.tgz", @@ -6285,6 +6260,301 @@ } } }, + "grunt-lcov-merge": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/grunt-lcov-merge/-/grunt-lcov-merge-1.2.3.tgz", + "integrity": "sha1-hGb401OfCItGSaYP/F7dLeklVBE=", + "dev": true, + "requires": { + "async": "2.5.0", + "chalk": "1.1.3", + "lcov-result-merger": "1.2.0", + "through2": "0.6.5", + "vinyl": "1.2.0", + "vinyl-fs": "2.4.4" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + } + } + } + } + }, "grunt-legacy-log": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", @@ -6453,6 +6723,44 @@ "wiredep": "4.0.0" } }, + "gulp-sourcemaps": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, "gzip-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", @@ -6888,48 +7196,6 @@ "sprintf-js": "1.1.1" } }, - "i18n-lint": { - "version": "git://github.com/jwarby/i18n-lint.git#0a06373c0d880047ad680239c103d60ed414efc1", - "dev": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.8.1", - "glob": "5.0.15", - "htmlparser2": "3.8.3", - "lodash": "3.10.1", - "node.extend": "1.1.6" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - } - } - }, "iconv-lite": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", @@ -7114,12 +7380,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz", "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c=" }, - "is": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", - "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", - "dev": true - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -7349,6 +7609,12 @@ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -7662,6 +7928,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, "requires": { "graceful-fs": "4.1.11" }, @@ -7670,6 +7937,7 @@ "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, "optional": true } } @@ -7995,6 +8263,15 @@ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -8010,6 +8287,185 @@ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, + "lcov-result-merger": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lcov-result-merger/-/lcov-result-merger-1.2.0.tgz", + "integrity": "sha1-XeHmQm+IWSm3c1fwFN5f7h2tBVM=", + "dev": true, + "requires": { + "through2": "2.0.3", + "vinyl": "1.2.0", + "vinyl-fs": "2.4.4" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + } + } + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -8217,6 +8673,12 @@ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -8268,11 +8730,6 @@ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", "dev": true }, - "log-rotate": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/log-rotate/-/log-rotate-0.2.7.tgz", - "integrity": "sha1-qttkJZ7qSeVmiEI0LIZNCxQujC0=" - }, "log4js": { "version": "0.6.38", "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", @@ -8315,27 +8772,6 @@ } } }, - "logrotate-stream": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/logrotate-stream/-/logrotate-stream-0.2.5.tgz", - "integrity": "sha1-/dQueYKn7i64a1X18j3L/8ZuaZA=", - "requires": { - "byt": "0.1.0", - "log-rotate": "0.2.7", - "optimist": "0.6.1" - }, - "dependencies": { - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.2" - } - } - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -9253,15 +9689,6 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" }, - "node.extend": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", - "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", - "dev": true, - "requires": { - "is": "3.2.1" - } - }, "nodemailer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.0.1.tgz", @@ -9712,6 +10139,12 @@ "no-case": "2.3.2" } }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -9789,283 +10222,6 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "phantomjs": { - "version": "1.9.20", - "resolved": "https://registry.npmjs.org/phantomjs/-/phantomjs-1.9.20.tgz", - "integrity": "sha1-RCSsog4U0lXAsIia9va4lz2hDg0=", - "dev": true, - "requires": { - "extract-zip": "1.5.0", - "fs-extra": "0.26.7", - "hasha": "2.2.0", - "kew": "0.7.0", - "progress": "1.1.8", - "request": "2.67.0", - "request-progress": "2.0.1", - "which": "1.2.14" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "bl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", - "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", - "dev": true, - "requires": { - "readable-stream": "2.0.6" - } - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "concat-stream": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", - "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "debug": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", - "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", - "dev": true - }, - "extract-zip": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", - "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=", - "dev": true, - "requires": { - "concat-stream": "1.5.0", - "debug": "0.7.4", - "mkdirp": "0.5.0", - "yauzl": "2.4.1" - } - }, - "form-data": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", - "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", - "dev": true, - "requires": { - "async": "2.5.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.2.8" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.11.0", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true - }, - "qs": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.1.tgz", - "integrity": "sha1-gB/uAw4LlFDWOFrcSKTMVbRK7fw=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.67.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.67.0.tgz", - "integrity": "sha1-ivdHgOK/EeoK6aqWXBHxGv0nJ0I=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "bl": "1.0.3", - "caseless": "0.11.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "1.0.1", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "node-uuid": "1.4.8", - "oauth-sign": "0.8.2", - "qs": "5.2.1", - "stringstream": "0.0.5", - "tough-cookie": "2.2.2", - "tunnel-agent": "0.4.3" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "tough-cookie": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - } - } - }, "phantomjs-prebuilt": { "version": "2.1.15", "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz", @@ -11042,6 +11198,12 @@ "is-finite": "1.0.2" } }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, "request": { "version": "2.83.0", "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", @@ -11789,6 +11951,16 @@ "is-utf8": "0.2.1" } }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -11928,66 +12100,6 @@ "upper-case": "1.1.3" } }, - "swig": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/swig/-/swig-1.4.2.tgz", - "integrity": "sha1-QIXKBFM2kQS11IPihBs5t64aq6U=", - "requires": { - "optimist": "0.6.1", - "uglify-js": "2.4.24" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.2" - } - }, - "source-map": { - "version": "0.1.34", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz", - "integrity": "sha1-p8/omux7FoLDsZjQrPtH19CQVms=", - "requires": { - "amdefine": "1.0.1" - } - }, - "uglify-js": { - "version": "2.4.24", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz", - "integrity": "sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4=", - "requires": { - "async": "0.2.10", - "source-map": "0.1.34", - "uglify-to-browserify": "1.0.2", - "yargs": "3.5.4" - } - }, - "yargs": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz", - "integrity": "sha1-2K/49mXpTDS9JZvevRv68N3TU2E=", - "requires": { - "camelcase": "1.2.1", - "decamelize": "1.2.0", - "window-size": "0.1.0", - "wordwrap": "0.0.2" - } - } - } - }, "taskgroup": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/taskgroup/-/taskgroup-4.3.1.tgz", @@ -12092,6 +12204,15 @@ "os-tmpdir": "1.0.2" } }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", @@ -12428,6 +12549,12 @@ } } }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -12566,9 +12693,6 @@ "string-width": "1.0.2" } }, - "wildcard-subdomains": { - "version": "github:tellform/wildcard-subdomains#af33bb3e040da9f11387f920f3801c4d080c0423" - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -12599,40 +12723,6 @@ } } }, - "winston-logrotate": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/winston-logrotate/-/winston-logrotate-1.3.0.tgz", - "integrity": "sha1-Sy9cLqrvSS9bdcccpzd48wXI/4A=", - "requires": { - "bluebird": "2.9.30", - "fs-extra": "0.24.0", - "logrotate-stream": "0.2.5", - "winston": "2.4.0" - }, - "dependencies": { - "bluebird": { - "version": "2.9.30", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.30.tgz", - "integrity": "sha1-7dqHXsmq0fKc8fVtboL7qysN9VY=" - }, - "fs-extra": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.24.0.tgz", - "integrity": "sha1-1OQ0KpZnXLeEZjOmCZJJMytTmVI=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "path-is-absolute": "1.0.1", - "rimraf": "2.2.8" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - } - } - }, "wiredep": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/wiredep/-/wiredep-4.0.0.tgz", diff --git a/package.json b/package.json index d8bb61d2..06d3ff03 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "express": "~4.13.3", "express-session": "~1.12.1", "glob": "^7.0.3", - "grunt": "~0.4.1", + "grunt": "^0.4.5", "grunt-concurrent": "~2.3.0", "grunt-contrib-csslint": "~1.0.0", "grunt-contrib-cssmin": "~1.0.1", diff --git a/public/config.js b/public/config.js index d21482bf..dde967a4 100755 --- a/public/config.js +++ b/public/config.js @@ -4,7 +4,7 @@ var ApplicationConfiguration = (function() { // Init module configuration options var applicationModuleName = 'TellForm'; - var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate', 'view-form']; + var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate']; // Add a new vertical module var registerModule = function(moduleName, dependencies) { diff --git a/public/dist/application.js b/public/dist/application.js index 92f6ce4e..729936db 100644 --- a/public/dist/application.js +++ b/public/dist/application.js @@ -42,7 +42,7 @@ angular.element(document).ready(function() { var ApplicationConfiguration = (function() { // Init module configuration options var applicationModuleName = 'TellForm'; - var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate', 'view-form']; + var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate']; // Add a new vertical module var registerModule = function(moduleName, dependencies) { @@ -890,8 +890,6 @@ angular.module('view-form').directive('submitFormDirective', ["$http", "TimeCoun }; $rootScope.prevField = $scope.prevField = function(){ - console.log('prevField'); - console.log($scope.selected); var selected_index = $scope.selected.index - 1; if($scope.selected.index > 0){ $scope.setActiveField(null, selected_index, true); @@ -985,17 +983,6 @@ angular.module('view-form').directive('submitFormDirective', ["$http", "TimeCoun if($scope.myform.form_fields[i].fieldType === 'dropdown' && !$scope.myform.form_fields[i].deletePreserved){ $scope.myform.form_fields[i].fieldValue = $scope.myform.form_fields[i].fieldValue.option_value; } - - //Get rid of unnessecary attributes for each form field - delete form.form_fields[i].submissionId; - delete form.form_fields[i].disabled; - delete form.form_fields[i].ratingOptions; - delete form.form_fields[i].fieldOptions; - delete form.form_fields[i].logicJump; - delete form.form_fields[i].description; - delete form.form_fields[i].validFieldTypes; - delete form.form_fields[i].fieldType; - } setTimeout(function () { diff --git a/public/dist/application.min.css b/public/dist/application.min.css new file mode 100644 index 00000000..66157122 --- /dev/null +++ b/public/dist/application.min.css @@ -0,0 +1,4 @@ +.tag,.vcenter{vertical-align:middle}.navbar,.navbar-nav,.navbar-nav>li{min-height:60px}.image-background,.opacity-background{position:fixed;height:100%;width:100%;top:0;left:0}.btn-rounded,.field-title-row,section.auth .btn{text-transform:uppercase}.form-item .title-row>.list-group-item-heading{color:#34628a}.form-item.paused .title-row>.list-group-item-heading,.form-item:hover .title-row>.list-group-item-heading{color:#fff}.form-item:hover .title-row{text-decoration:none}body{overflow-x:hidden;font-family:'Source Sans Pro',sans-serif;font-size:16px}.vcenter{display:inline-block;float:none}.btn-rounded{border-radius:100px;font-size:14px;padding:10px 28px;margin:1em 2px 0;text-decoration:none!important}.current-fields .panel-heading a:hover,.current-fields .tool-panel.panel .panel-heading a:hover,.footer-basic-centered .footer-links a,.undecorated-link:hover{text-decoration:none}.btn-secondary{background:#DDD;color:#4c4c4c;border:2px solid #4c4c4c}.btn-secondary:hover{background:#cacaca;border-color:#cacaca}.navbar{padding:10px 0}.navbar-inverse{background-color:#3FA2F7;border:0;color:#fff!important}.navbar .navbar-brand{min-height:60px;padding:10px}.navbar-nav>li>a{padding-top:20px;color:#fff}.navbar-nav>li.active,.navbar-nav>li:hover{background-color:#4b7096}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{background-color:transparent;color:inherit;border:none}.navbar-inverse .navbar-nav>li>a{color:#fff}.navbar li.dropdown a.dropdown-toggle:hover>*{color:#f9f9f9}.navbar-inverse .navbar-toggle{border:none}.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.dropdown-menu>li>a{color:#515151}section.hero-section{width:100%}section.hero-section .jumbotron{background-color:transparent;color:#fff}.image-background{z-index:-98;background-image:url(http://yourplaceandmine.ie/wp-content/uploads/2014/09/Daingean-meeting-048_13-1080x675.jpg);background-repeat:no-repeat;background-position:0 50%;background-size:cover}.opacity-background{background-color:#000;background-color:rgba(0,0,0,.5);z-index:-97}section.hero-section .jumbotron .signup-btn{background-color:#FA787E;border:none;font-size:2em;padding:.3em .9em;color:#fff}.footer-basic-centered{background-color:#292c2f;box-shadow:0 1px 1px 0 rgba(0,0,0,.12);box-sizing:border-box;width:100%;text-align:center;font:400 18px sans-serif;padding:45px;margin-top:80px}.footer-basic-centered .footer-company-motto{color:#8d9093;font-size:24px;margin:0}.footer-basic-centered .footer-company-name{color:#8f9296;font-size:14px;margin:0}.footer-basic-centered .footer-links{list-style:none;font-weight:700;color:#fff;padding:35px 0 23px;margin:0}.footer-basic-centered .footer-links a{display:inline-block;color:inherit}@media (max-width:600px){.footer-basic-centered{padding:35px}.footer-basic-centered .footer-company-motto{font-size:18px}.footer-basic-centered .footer-company-name{font-size:12px}.footer-basic-centered .footer-links{font-size:14px;padding:25px 0 20px}.footer-basic-centered .footer-links a{line-height:1.8}}/*! + * "Fork me on GitHub" CSS ribbon v0.1.1 | MIT License + * https://github.com/simonwhitaker/github-fork-ribbon-css +*/.github-fork-ribbon{position:absolute;padding:2px 0;background-color:#a00;background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,.15)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,.15));background-image:-moz-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,.15));background-image:-ms-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,.15));background-image:-o-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,.15));background-image:linear-gradient(to bottom,rgba(0,0,0,0),rgba(0,0,0,.15));-webkit-box-shadow:0 2px 3px 0 rgba(0,0,0,.5);-moz-box-shadow:0 2px 3px 0 rgba(0,0,0,.5);box-shadow:0 2px 3px 0 rgba(0,0,0,.5);font:700 13px "Helvetica Neue",Helvetica,Arial,sans-serif;z-index:9999;pointer-events:auto}.github-fork-ribbon a,.github-fork-ribbon a:hover{color:#fff;text-decoration:none;text-shadow:0 -1px rgba(0,0,0,.5);text-align:center;width:200px;line-height:20px;display:inline-block;padding:2px 0;border-width:1px 0;border-style:dotted;border-color:#fff;border-color:rgba(255,255,255,.7)}.github-fork-ribbon-wrapper{width:150px;height:150px;position:absolute;overflow:hidden;top:0;z-index:9998;pointer-events:none}.github-fork-ribbon-wrapper.fixed{position:fixed}.github-fork-ribbon-wrapper.left{left:0}.github-fork-ribbon-wrapper.right{right:0}.github-fork-ribbon-wrapper.left-bottom{position:fixed;top:inherit;bottom:0;left:0}.github-fork-ribbon-wrapper.right-bottom{position:fixed;top:inherit;bottom:0;right:0}.github-fork-ribbon-wrapper.right .github-fork-ribbon{top:42px;right:-43px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.github-fork-ribbon-wrapper.left .github-fork-ribbon{top:42px;left:-43px;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon{top:80px;left:-43px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon{top:80px;right:-43px;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.custom-select{position:relative;display:block;padding:0}.custom-select select{width:100%;margin:0;background:0 0;border:1px solid transparent;border-radius:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;appearance:none;-webkit-appearance:none;-moz-appearance:none;font-size:1em;font-family:helvetica,sans-serif;font-weight:700;color:#444;padding:.6em 1.9em .5em .8em;line-height:1.3}.custom-select option,.modal-header{font-weight:400}.custom-select::after{content:"";position:absolute;width:9px;height:8px;top:50%;right:1em;margin-top:-4px;background-image:url(http://filamentgroup.com/files/select-arrow.png);background-repeat:no-repeat;background-size:100%;z-index:2;pointer-events:none}.custom-select:hover{border:1px solid #888}.custom-select select:focus{outline:0;box-shadow:0 0 1px 3px rgba(180,222,250,1);background-color:transparent;color:#222;border:1px solid #aaa}.custom-select::after,x:-o-prefocus{display:none}@media screen and (-ms-high-contrast:active),(-ms-high-contrast:none){.custom-select select::-ms-expand{display:none}.custom-select select:focus::-ms-value{background:0 0;color:#222}}.custom-select select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tag{background-color:#999;border-radius:3px;border:0;color:#FFF;font-style:inherit;font-size:11px;padding:4px 5px;margin:0 2px 2px;font-family:inherit;white-space:nowrap;cursor:pointer!important;pointer-events:none}.email-subject .ta-scroll-window.form-control,.email-subject.ta-root .ta-editor.ta-html{min-height:0;overflow:hidden;height:auto;border-radius:4px;box-shadow:none;font-size:18px;padding-top:10px}.email-subject.ta-root .ta-scroll-window>.ta-bind{min-height:0;outline:0}.ui-select input.form-control{height:34px;padding:6px}.config-form .btn-secondary{border-color:#DDD}.notification-toggle.toggle-switch{margin:5px 0}.pull-top{display:inline-block;vertical-align:top;float:none}.nav.nav-pills.nav-stacked,div.tab-content{position:relative;min-height:1px;float:left}.box{padding:0 5px!important}.current-fields .field-row{padding:5px 0}.current-fields .panel{background-color:#f1f1f1;margin-top:0!important}.current-fields .panel:hover{background-color:#fff;cursor:pointer}.current-fields .panel.tool-panel{background-color:#fff}.current-fields .panel-heading{background-color:#f1f1f1;position:relative}.current-fields .panel-heading:hover{background-color:#fff;cursor:pointer}.current-fields .tool-panel.panel:hover{border-color:#9d9d9d;background-color:#eee;cursor:pointer}.current-fields .tool-panel.panel:hover .panel-heading{background-color:inherit;color:#000;cursor:pointer}.current-fields .tool-panel.panel .panel-heading{background-color:#fff;color:#9d9d9d}.current-fields .tool-panel.panel .panel-heading a{color:inherit}.nav.nav-pills.nav-stacked{width:16.66666667%;padding-right:15px}div.tab-content{width:83.33333333%;padding-top:0!important}.panel-default.startPage{border-style:dashed;border-color:#a9a9a9;border-width:3px}.busy-updating-wrapper{text-align:center;font-size:20px;position:fixed;bottom:0;right:55px;z-index:1}.busy-submitting-wrapper{position:fixed;top:50%;left:0;right:0;bottom:0}.dropzone h4.panel-title{height:17px;overflow:hidden}.container.admin-form{margin-top:70px}.edit-modal-window .modal-dialog{width:90%}.edit-modal-window .modal-body{padding:0}.edit-modal-window .edit-panel{background-color:#F1F1F1;padding:0 35px}.edit-modal-window .preview-field-panel{display:flex;flex-direction:column;justify-content:center}.edit-modal-window .preview-field-panel form{padding-right:20px}.edit-modal-window .preview-field{resize:vertical}.admin-form .ui-sortable-placeholder{visibility:visible!important;border:none;padding:1px;background:rgba(0,0,0,.5)!important}.config-form{max-width:100%}.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}div.config-form .row.field{padding-top:1.5em}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form.design>.row>.container:nth-of-type(odd){border-right:none}div.config-form .row>.field-input{padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0;margin-top:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none;margin-top:none;margin-bottom:none}.admin-form .tab-content{padding-top:3em}.submissions-table .table-outer.row{margin:1.5em 0 2em!important}.submissions-table .table-outer .col-xs-12{padding-left:0!important;border:1px solid #ddd;overflow-x:scroll;border-radius:3px}.submissions-table .table>thead>tr>th{min-width:8em}.submissions-table .table>tbody>tr.selected{background-color:#efefef}.admin-form .add-field{background-color:#ddd;padding:0 2%;border-radius:3px}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.admin-form .oscar-field-select{margin:10px 0}.view-form-btn{border:none}.view-form-btn.span{padding-right:.6em}.notification-row{display:inline-block;padding:0 5px}.status-light{font-size:10px}.notification-row .status-light{padding-top:15px}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}.analytics .header-title{font-size:1em;color:#bab8b8}.analytics .header-numbers{font-size:4em;padding-bottom:.1em;margin-bottom:.5em;border-bottom:#fafafa solid 1px}.analytics .detailed-title{font-size:1.8em;margin-bottom:1.1em}.analytics .detailed-row{padding-bottom:.8em}.analytics .detailed-row .row{font-size:1.2em}.analytics .detailed-row .row.header{font-size:.8em;color:#bab8b8;text-transform:uppercase}.field-title-row{padding-top:2em;padding-bottom:1em;border-top:#fafafa solid 1px;font-size:1.2em;color:#bab8b8}.field-detailed-row{font-size:1.2em;padding-bottom:.3em}.table-tools{border-top:#fafafa solid 1px;padding-top:2.5em}.overlay{position:fixed;top:0;left:0;height:100%;width:100%;background-color:#000;background-color:rgba(0,0,0,.5);z-index:10}.overlay.submitform{background-color:#fff;background-color:rgba(256,256,256,.8)}.public-form.preview{border:none;box-shadow:0 0 10px 0 grey;overflow-y:scroll;overflow-x:hidden;height:400px;width:90%;position:absolute}.public-form input,.public-form textarea{background-color:#000;background-color:rgba(0,0,0,0);border-width:0}form .btn{border-color:grey}.public-form input.ng-untouched,.public-form input:focus,.public-form textarea.ng-untouched,.public-form textarea:focus{border-width:0 0 2px;border-color:rgba(246,255,181,.4);outline:0}.public-form input.ng-dirty,.public-form textarea.ng-dirty{border-width:0}.public-form input.empty,.public-form textarea.empty{border-width:0 0 2px;border-color:rgba(246,255,181,.4)}section.content p.breakwords{word-break:break-all}.public-form .btn[type=submit]{font-size:1.5em;padding:.35em 1.2em}section.content>section>section.container{margin-top:70px}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;font-size:18px}.public-form .input-block{display:block;width:100%}.modal-footer input[type=text]{min-height:34px;padding:7px 8px;font-size:13px;color:#333;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #ccc;border-radius:3px;box-shadow:inset 0 1px 2px rgba(0,0,0,.075)}.modal-body>.modal-body-alert{color:#796620;background-color:#f8eec7;border-color:#f2e09a;margin:-16px -15px 15px;padding:10px 15px;border-style:solid;border-width:1px 0}div.form-fields{position:relative;padding-top:10%}.public-form .letter{position:relative;display:-moz-inline-stack;display:inline-block;vertical-align:top;zoom:1;width:16px;padding:0;height:17px;font-size:12px;line-height:19px;border:1px solid #000;border:1px solid rgba(0,0,0,.2);margin-right:7px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;text-align:center;font-weight:700}div.form-submitted>.field.row{padding-bottom:2%;margin-top:10%}div.form-submitted>.field.row>div{font-size:1.7em}form .accordion-edit{width:inherit}.ui-datepicker.ui-widget{z-index:99!important}form .row.field .field-number{margin-right:.5em}form .row.field{padding:1em 0 0;width:inherit}form .row.field>.field-title{margin-top:.5em;font-size:1.2em;padding-bottom:.5em;width:inherit}form .row.field>.field-input{font-size:1.4em;color:#777}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1em;color:#ddd}form.submission-form .select.radio>.field-input input,form.submission-form .select>.field-input input{width:20%}form.submission-form .field.row.radio .btn.activeBtn{background-color:#000!important;background-color:rgba(0,0,0,.7)!important;color:#fff}form.submission-form .field.row.radio .btn{margin-right:1.2em}form.submission-form .select>.field-input .btn{text-align:left;margin-bottom:.7em}form.submission-form .select>.field-input .btn>span{font-size:1.1em}form .field-input>textarea{padding:.45em .9em;width:100%;line-height:160%}form .field-input>input.hasDatepicker{padding:.45em .9em;width:50%;line-height:160%}form .field-input>input.text-field-input{padding:.45em .9em;width:100%;line-height:160%}form .required-error{color:#ddd;font-size:.8em}form .dropdown>.field-input input{min-height:34px;border-width:0 0 2px;border-radius:5px}form .dropdown>.field-input input:focus{border:none}form .dropdown>.field-input .ui-select-choices-row-inner{border-radius:3px;margin:5px;padding:10px;background-color:#000;background-color:rgba(0,0,0,.05)}form .dropdown>.field-input .ui-select-choices-row-inner.active,form .dropdown>.field-input .ui-select-choices-row-inner.active:focus{background-color:#000;background-color:rgba(0,0,0,.1)}.current-fields .panel-body .row.description textarea,.current-fields .panel-body .row.question input[type=text]{width:100%}.current-fields .panel-body .row.options input[type=text]{width:80%}.ui-select-choices.ui-select-dropdown{top:2.5em!important}.ui-select-toggle{box-shadow:none!important;border:none!important}section.public-form field-directive .btn.btn-lg.btn-default{background:0 0}section.public-form field-directive .btn[disabled]{display:none}.form-item{border-radius:5px;text-align:center;width:180px;position:relative;height:215px;margin-bottom:45px}.form-item.paused{background-color:red;color:#fff}.form-item.paused:hover{background-color:#8b0000;color:#fff}.form-item.create-new input[type=text]{width:inherit;color:#000;border:none}.form-item.create-new{background-color:#3FA2F7;color:#fff}.form-item.new-form{background-color:#ff8383;z-index:11}.form-item.new-form:hover{background-color:#3079b5}.form-item.new-form input[type=text]{margin-top:.2em;width:inherit;color:#000;border:none;padding:.3em .6em}.form-item.new-form .custom-select{margin-top:.2em}.form-item.new-form .custom-select select{background-color:#fff}.form-item.new-form .details-row{margin-top:1em}.form-item.new-form .details-row.submit{margin-top:1.7em}.form-item.new-form .details-row.submit .btn{font-size:.95em}.form-item.new-form .title-row{margin-top:1em;top:0}.field-directive{opacity:.2;padding:2.5% 10%}.field-directive.activeField,.form-field-wrapper .form-actions.activeField{opacity:1}h3.forms-list-title{color:#3FA2F7;font-weight:600;margin-bottom:3em}.form-item{color:#71AADD;background-color:#E4F1FD}.form-item:hover{background-color:#3FA2F7;color:#23527C}.form-item.create-new:hover{color:#fff;background-color:#515151}.form-item>.row.footer{position:absolute;bottom:0;left:30%}.form-item .title-row{position:relative;top:15px;padding-top:3em;padding-bottom:1em}.form-item .title-row h4{font-size:1.3em}.form-item.create-new .title-row{padding:0}.form-item.create-new .title-row h4{font-size:7em}.form-item.create-new.new-button .details-row{padding-top:20%}.form-item .details-row small{font-size:.6em}.form-item.create-new .details-row small{font-size:.95em}.form-item.create-new input{max-width:100%}section.auth{padding:70px 0;position:absolute;min-height:100%;top:0;left:0;width:100%;color:#fff;background-color:#50B5C1;background:-moz-linear-gradient(137deg,#50B5C1 0,#6450A0 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#50B5C1),color-stop(100%,#6450A0));background:-webkit-linear-gradient(137deg,#50B5C1 0,#6450A0 100%);background:-o-linear-gradient(137deg,#50B5C1 0,#6450A0 100%);background:-ms-linear-gradient(137deg,#50B5C1 0,#6450A0 100%)}section.auth>h3{font-size:2em;font-weight:500}.valign-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.valign-wrapper .valign{display:block;width:100%}section.auth a{color:#fff;text-decoration:underline}section.auth.signup-view>h3{font-size:3em;padding-bottom:.5em}section.auth form .field-input select{padding:.45em .9em;width:100%;background:0 0;font-size:16px;border:1px solid #ccc;min-height:34px}section.auth input{color:#4c4c4c}section.auth .btn{border-radius:100px;font-size:14px;padding:12px 28px;margin-top:1em}.btn-rounded.btn-signup{background-color:#FFD747;color:#896D0B;border:2px solid #FFD747}.btn-rounded.btn-signup:hover{color:#FFD747;background-color:#896D0B;border:2px solid #896D0B}.btn-rounded.btn-default{background-color:transparent;color:#fff;border:2px solid #fff}.btn-rounded.btn-default:focus,.btn-rounded.btn-default:hover{color:#6450A0;background-color:#fff;border-color:#fff}@media (min-width:992px){.nav-users{position:fixed}}.remove-account-container{display:inline-block;position:relative}.btn-remove-account{top:10px;right:10px;position:absolute}section.auth input.form-control{min-height:30px!important;border:none}input.form-control{height:auto;border-radius:4px;box-shadow:none;font-size:18px;padding:20px 10px} \ No newline at end of file diff --git a/public/dist/application.min.js b/public/dist/application.min.js index 26eeac55..d60a88fc 100644 --- a/public/dist/application.min.js +++ b/public/dist/application.min.js @@ -1 +1 @@ -"use strict";angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function(a){a.hashPrefix("!")}]),angular.module(ApplicationConfiguration.applicationModuleName).constant("APP_PERMISSIONS",{viewAdminSettings:"viewAdminSettings",editAdminSettings:"editAdminSettings",editForm:"editForm",viewPrivateForm:"viewPrivateForm"}),angular.module(ApplicationConfiguration.applicationModuleName).constant("USER_ROLES",{admin:"admin",normal:"user",superuser:"superuser"}),angular.module(ApplicationConfiguration.applicationModuleName).constant("FORM_URL","/forms/:formId"),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])});var ApplicationConfiguration=function(){var a="TellForm",b=["duScroll","ui.select","ngSanitize","vButton","ngResource","TellForm.templates","ui.router","ui.bootstrap","ui.utils","pascalprecht.translate","view-form"],c=function(b,c){angular.module(b,c||[]),angular.module(a).requires.push(b)};return{applicationModuleName:a,applicationModuleVendorDependencies:b,registerModule:c}}();angular.module("view-form").filter("formValidity",function(){return function(a){if(a&&a.form_fields&&a.visible_form_fields){var b=Object.keys(a),c=(b.filter(function(a){return"$"!==a[0]}),a.form_fields),d=c.filter(function(a){return"object"==typeof a&&"rating"!==a.fieldType&&"statement"!==a.fieldType?!!a.fieldValue:"rating"===a.fieldType||void 0}).length;return d-(a.form_fields.length-a.visible_form_fields.length)}return 0}}),angular.module("view-form").value("supportedFields",["textfield","textarea","date","dropdown","hidden","password","radio","legal","statement","rating","yes_no","number","natural"]),angular.module("view-form").constant("VIEW_FORM_URL","/forms/:formId/render"),angular.module("view-form").config(["$translateProvider",function(a){a.translations("en",{FORM_SUCCESS:"Form entry successfully submitted!",REVIEW:"Review",BACK_TO_FORM:"Go back to Form",EDIT_FORM:"Edit this TellForm",CREATE_FORM:"Create this TellForm",ADVANCEMENT:"{{done}} out of {{total}} answered",CONTINUE_FORM:"Continue to Form",REQUIRED:"required",COMPLETING_NEEDED:"{{answers_not_completed}} answer(s) need completing",OPTIONAL:"optional",ERROR_EMAIL_INVALID:"Please enter a valid email address",ERROR_NOT_A_NUMBER:"Please enter valid numbers only",ERROR_URL_INVALID:"Please a valid url",OK:"OK",ENTER:"press ENTER",YES:"Yes",NO:"No",NEWLINE:"press SHIFT+ENTER to create a newline",CONTINUE:"Continue",LEGAL_ACCEPT:"I accept",LEGAL_NO_ACCEPT:"I don’t accept",DELETE:"Delete",CANCEL:"Cancel",SUBMIT:"Submit",UPLOAD_FILE:"Upload your File",Y:"Y",N:"N",OPTION_PLACEHOLDER:"Type or select an option",ADD_NEW_LINE_INSTR:"Press SHIFT+ENTER to add a newline",ERROR:"Error",FORM_404_HEADER:"404 - Form Does Not Exist",FORM_404_BODY:"The form you are trying to access does not exist. Sorry about that!",FORM_UNAUTHORIZED_HEADER:"Not Authorized to Access Form",FORM_UNAUTHORIZED_BODY1:"The form you are trying to access is currently private and not accesible publically.",FORM_UNAUTHORIZED_BODY2:'If you are the owner of the form, you can set it to "Public" in the "Configuration" panel in the form admin.'}),a.preferredLanguage("en").fallbackLanguage("en").useSanitizeValueStrategy("escape")}]),angular.module("view-form").config(["$translateProvider",function(a){a.translations("fr",{FORM_SUCCESS:"Votre formulaire a été enregistré!",REVIEW:"Incomplet",BACK_TO_FORM:"Retourner au formulaire",EDIT_FORM:"Éditer le Tellform",CREATE_FORM:"Créer un TellForm",ADVANCEMENT:"{{done}} complétés sur {{total}}",CONTINUE_FORM:"Aller au formulaire",REQUIRED:"obligatoire",COMPLETING_NEEDED:"{{answers_not_completed}} réponse(s) doive(nt) être complétée(s)",OPTIONAL:"facultatif",ERROR_EMAIL_INVALID:"Merci de rentrer une adresse mail valide",ERROR_NOT_A_NUMBER:"Merce de ne rentrer que des nombres",ERROR_URL_INVALID:"Merci de rentrer une url valide",OK:"OK",ENTER:"presser ENTRÉE",YES:"Oui",NO:"Non",NEWLINE:"presser SHIFT+ENTER pour créer une nouvelle ligne",CONTINUE:"Continuer",LEGAL_ACCEPT:"J’accepte",LEGAL_NO_ACCEPT:"Je n’accepte pas",DELETE:"Supprimer",CANCEL:"Réinitialiser",SUBMIT:"Enregistrer",UPLOAD_FILE:"Envoyer un fichier",Y:"O",N:"N",OPTION_PLACEHOLDER:"Tapez ou sélectionnez une option",ADD_NEW_LINE_INSTR:"Appuyez sur MAJ + ENTRÉE pour ajouter une nouvelle ligne",ERROR:"Erreur",FORM_404_HEADER:"404 - Le formulaire n'existe pas",FORM_404_BODY:"Le formulaire auquel vous essayez d'accéder n'existe pas. Désolé pour ça!",FORM_UNAUTHORIZED_HEADER:"Non autorisé à accéder au formulaire",FORM_UNAUTHORIZED_BODY1:"Le formulaire auquel vous essayez d'accéder est actuellement privé et inaccessible publiquement.",FORM_UNAUTHORIZED_BODY2:'Si vous êtes le propriétaire du formulaire, vous pouvez le définir sur "Public" dans le panneau "Configuration" du formulaire admin.'})}]),angular.module("view-form").config(["$translateProvider",function(a){a.translations("de",{FORM_SUCCESS:"Ihre Angaben wurden gespeichert.",REVIEW:"Unvollständig",BACK_TO_FORM:"Zurück zum Formular",EDIT_FORM:"Bearbeiten Sie diese TellForm",CREATE_FORM:"Dieses TellForm erstellen",ADVANCEMENT:"{{done}} von {{total}} beantwortet",CONTINUE_FORM:"Zum Formular",REQUIRED:"verpflichtend",COMPLETING_NEEDED:"Es fehlen/fehtl noch {{answers_not_completed}} Antwort(en)",OPTIONAL:"fakultativ",ERROR_EMAIL_INVALID:"Bitte gültige Mailadresse eingeben",ERROR_NOT_A_NUMBER:"Bitte nur Zahlen eingeben",ERROR_URL_INVALID:"Bitte eine gültige URL eingeben",OK:"Okay",ENTER:"Eingabetaste drücken",YES:"Ja",NO:"Nein",NEWLINE:"Für eine neue Zeile SHIFT+ENTER drücken",CONTINUE:"Weiter",LEGAL_ACCEPT:"I accept",LEGAL_NO_ACCEPT:"I don’t accept",DELETE:"Entfernen",CANCEL:"Canceln",SUBMIT:"Speichern",UPLOAD_FILE:"Datei versenden",Y:"J",N:"N",OPTION_PLACEHOLDER:"Geben oder wählen Sie eine Option aus",ADD_NEW_LINE_INSTR:"Drücken Sie UMSCHALT + EINGABETASTE, um eine neue Zeile hinzuzufügen",ERROR:"Fehler",FORM_404_HEADER:"404 - Formular existiert nicht",FORM_404_BODY:"Das Formular, auf das Sie zugreifen möchten, existiert nicht. Das tut mir leid!",FORM_UNAUTHORIZED_HEADER:"Nicht zum Zugriffsformular berechtigt' ",FORM_UNAUTHORIZED_BODY1:"Das Formular, auf das Sie zugreifen möchten, ist derzeit privat und nicht öffentlich zugänglich.",FORM_UNAUTHORIZED_BODY2:'Wenn Sie der Eigentümer des Formulars sind, können Sie es im Fenster "Konfiguration" im Formular admin auf "Öffentlich" setzen.'})}]),angular.module("view-form").config(["$translateProvider",function(a){a.translations("it",{FORM_SUCCESS:"Il formulario è stato inviato con successo!",REVIEW:"Incompleto",BACK_TO_FORM:"Ritorna al formulario",EDIT_FORM:"Modifica questo TellForm",CREATE_FORM:"Crea questo TellForm",ADVANCEMENT:"{{done}} su {{total}} completate",CONTINUE_FORM:"Vai al formulario",REQUIRED:"obbligatorio",COMPLETING_NEEDED:"{{answers_not_completed}} risposta/e deve/ono essere completata/e",OPTIONAL:"opzionale",ERROR_EMAIL_INVALID:"Si prega di inserire un indirizzo email valido",ERROR_NOT_A_NUMBER:"Si prega di inserire solo numeri",ERROR_URL_INVALID:"Grazie per inserire un URL valido",OK:"OK",ENTER:"premere INVIO",YES:"Sì",NO:"No",NEWLINE:"premere SHIFT+INVIO per creare una nuova linea",CONTINUE:"Continua",LEGAL_ACCEPT:"I accept",LEGAL_NO_ACCEPT:"I don’t accept",DELETE:"Cancella",CANCEL:"Reset",SUBMIT:"Registra",UPLOAD_FILE:"Invia un file",Y:"S",N:"N",OPTION_PLACEHOLDER:"Digitare o selezionare un'opzione",ADD_NEW_LINE_INSTR:"Premere SHIFT + INVIO per aggiungere una nuova riga",ERROR:"Errore",FORM_404_HEADER:"404 - Il modulo non esiste",FORM_404_BODY:"La forma che stai cercando di accedere non esiste. Ci dispiace!",FORM_UNAUTHORIZED_HEADER:"Non autorizzato per accedere al modulo",FORM_UNAUTHORIZED_BODY1:"Il modulo che si sta tentando di accedere è attualmente privato e non accessibile in pubblico.",FORM_UNAUTHORIZED_BODY2:'Se sei il proprietario del modulo, puoi impostarlo su "Pubblico" nel pannello "Configurazione" nell\'amministratore di moduli.'})}]),angular.module("view-form").config(["$translateProvider",function(a){a.translations("es",{FORM_SUCCESS:"¡El formulario ha sido enviado con éxito!",REVIEW:"Revisar",BACK_TO_FORM:"Regresar al formulario",EDIT_FORM:"Editar este TellForm",CREATE_FORM:"Crear este TellForm",ADVANCEMENT:"{{done}} de {{total}} contestadas",CONTINUE_FORM:"Continuar al formulario",REQUIRED:"Información requerida",COMPLETING_NEEDED:"{{answers_not_completed}} respuesta(s) necesita(n) ser completada(s)",OPTIONAL:"Opcional",ERROR_EMAIL_INVALID:"Favor de proporcionar un correo electrónico válido",ERROR_NOT_A_NUMBER:"Por favor, introduzca sólo números válidos",ERROR_URL_INVALID:"Favor de proporcionar un url válido",OK:"OK",ENTER:"pulse INTRO",YES:"Si",NO:"No",NEWLINE:"presione SHIFT+INTRO para crear una nueva línea",CONTINUE:"Continuar",LEGAL_ACCEPT:"Yo acepto",LEGAL_NO_ACCEPT:"Yo no acepto",DELETE:"Eliminar",CANCEL:"Cancelar",SUBMIT:"Registrar",UPLOAD_FILE:"Cargar el archivo",Y:"S",N:"N",OPTION_PLACEHOLDER:"Escriba o seleccione una opción",ADD_NEW_LINE_INSTR:"Presione MAYÚS + ENTRAR para agregar una nueva línea",ERROR:"Error",FORM_404_HEADER:"404 - La forma no existe",FORM_404_BODY:"El formulario al que intenta acceder no existe. ¡Lo siento por eso!",FORM_UNAUTHORIZED_HEADER:"Non autorizzato per accedere al modulo",FORM_UNAUTHORIZED_BODY1:"Il modulo che si sta tentando di accedere è attualmente privato e non accessibile in pubblico.",FORM_UNAUTHORIZED_BODY2:'Se sei il proprietario del modulo, puoi impostarlo su "Pubblico" nel pannello "Configurazione" nell\'amministratore di moduli.'})}]),angular.module("view-form").controller("SubmitFormController",["$scope","$rootScope","$state","$translate","myForm",function(a,b,c,d,e){a.myform=e,$(".loader").fadeOut("slow"),document.body.style.background=e.design.colors.backgroundColor,d.use(e.language)}]),angular.module("view-form").directive("fieldIconDirective",function(){return{template:'',restrict:"E",scope:{typeName:"@"},controller:["$scope",function(a){var b={textfield:"fa fa-pencil-square-o",dropdown:"fa fa-th-list",date:"fa fa-calendar",checkbox:"fa fa-check-square-o",radio:"fa fa-dot-circle-o",email:"fa fa-envelope-o",textarea:"fa fa-pencil-square",legal:"fa fa-legal",file:"fa fa-cloud-upload",rating:"fa fa-star-half-o",link:"fa fa-link",scale:"fa fa-sliders",stripe:"fa fa-credit-card",statement:"fa fa-quote-left",yes_no:"fa fa-toggle-on",number:"fa fa-slack"};a.typeIcon=b[a.typeName]}]}});var __indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b=0&&(c=c+b+".html"),d.get(c)};return{template:"
{{field.title}}
",restrict:"E",scope:{field:"=",required:"&",design:"=",index:"=",forms:"="},link:function(a,d){c.chooseDefaultOption=a.chooseDefaultOption=function(b){"yes_no"===b?a.field.fieldValue="true":"rating"===b?a.field.fieldValue=0:"radio"===a.field.fieldType?a.field.fieldValue=a.field.fieldOptions[0].option_value:"legal"===b&&(a.field.fieldValue="true",c.nextField())},a.nextField=c.nextField,a.setActiveField=c.setActiveField,"date"===a.field.fieldType&&(a.dateOptions={changeYear:!0,changeMonth:!0,altFormat:"mm/dd/yyyy",yearRange:"1900:-0",defaultDate:0});var e=a.field.fieldType;if("number"===a.field.fieldType||"textfield"===a.field.fieldType||"email"===a.field.fieldType||"link"===a.field.fieldType){switch(a.field.fieldType){case"textfield":a.input_type="text";break;case"email":a.input_type="email",a.placeholder="joesmith@example.com";break;case"number":a.input_type="text",a.validateRegex=/^-?\d+$/;break;default:a.input_type="url",a.placeholder="http://example.com"}e="textfield"}var g=f(e);d.html(g).show();b(d.contents())(a)}}}]),angular.module("view-form").directive("onEnterKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode,e=!1;null!==d.onEnterKeyDisabled&&(e=d.onEnterKeyDisabled),13!==c||b.shiftKey||e||(b.preventDefault(),a.$apply(function(){a.$eval(d.onEnterKey)}))})}}}]).directive("onTabKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keyup keypress",function(b){var c=b.which||b.keyCode;9!==c||b.shiftKey||(b.preventDefault(),a.$apply(function(){a.$eval(d.onTabKey)}))})}}}]).directive("onEnterOrTabKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode;13!==c&&9!==c||b.shiftKey||(b.preventDefault(),a.$apply(function(){a.$eval(d.onEnterOrTabKey)}))})}}}]).directive("onTabAndShiftKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode;9===c&&b.shiftKey&&(console.log("onTabAndShiftKey"),b.preventDefault(),a.$apply(function(){a.$eval(d.onTabAndShiftKey)}))})}}}]),angular.module("view-form").directive("onFinishRender",["$rootScope","$timeout",function(a,b){return{restrict:"A",link:function(b,c,d){if(c.attr("ng-repeat")||c.attr("data-ng-repeat")){var e=d.onFinishRender||"ngRepeat";b.$first&&!b.$last?b.$evalAsync(function(){a.$broadcast(e+" Started")}):b.$last&&b.$evalAsync(function(){a.$broadcast(e+" Finished")})}}}}]),jsep.addBinaryOp("contains",10),jsep.addBinaryOp("!contains",10),jsep.addBinaryOp("begins",10),jsep.addBinaryOp("!begins",10),jsep.addBinaryOp("ends",10),jsep.addBinaryOp("!ends",10),angular.module("view-form").directive("submitFormDirective",["$http","TimeCounter","$filter","$rootScope","SendVisitorData","$translate","$timeout",function(a,b,c,d,e,f,g){return{templateUrl:"form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html",restrict:"E",scope:{myform:"=",ispreview:"="},controller:["$document","$window","$scope",function(f,g,h){var i=!1,j="submit_field";h.forms={},h.ispreview&&b.restartClock();var k=h.myform.visible_form_fields.filter(function(a){return"statement"!==a.fieldType}).length,l=c("formValidity")(h.myform);h.translateAdvancementData={done:l,total:k,answers_not_completed:k-l},h.reloadForm=function(){h.myform.submitted=!1,h.myform.form_fields=_.chain(h.myform.visible_form_fields).map(function(a){return a.fieldValue="",a}).value(),h.loading=!1,h.error="",h.selected={_id:"",index:0},h.setActiveField(h.myform.visible_form_fields[0]._id,0,!1),b.restartClock()};var m=function(a){var b=a.logicJump;if(b.enabled&&b.expressionString&&b.valueB&&a.fieldValue){var c,d,e=jsep(b.expressionString);if("field"===e.left.name?(c=a.fieldValue,d=b.valueB):(c=b.valueB,d=a.fieldValue),"number"===a.fieldType||"scale"===a.fieldType||"rating"===a.fieldType)switch(e.operator){case"==":return parseInt(c)===parseInt(d);case"!==":return parseInt(c)!==parseInt(d);case">":return parseInt(c)>parseInt(d);case">=":return parseInt(c)>parseInt(d);case"<":return parseInt(c)-1;case"!contains":return!(c.indexOf(d)>-1);case"begins":return c.startsWith(d);case"!begins":return!c.startsWith(d);case"ends":return c.endsWith(d);case"!ends":return c.endsWith(d);default:return!1}}},n=function(){if(null===h.selected)throw console.error("current active field is null"),new Error("current active field is null");return h.selected._id===j?h.myform.form_fields.length-1:h.selected.index};h.isActiveField=function(a){return h.selected._id===a._id},h.setActiveField=d.setActiveField=function(a,b,d){if(null!==h.selected&&(a||null!==b)){if(a){if(null===b){b=h.myform.visible_form_fields.length;for(var e=0;e .field-directive:nth-of-type("+String(h.myform.visible_form_fields.length-1)+")"),m=$(l).height(),n=k-g-1.2*m,o=.9;h.selected.index===h.myform.visible_form_fields.length?bn?(a=h.selected.index+1,h.setActiveField(j,a,!1)):ef*o&&(a=h.selected.index-1,h.setActiveField(null,a,!1))}h.$apply()},d.nextField=h.nextField=function(){if(h.selected&&h.selected.index>-1)if(h.selected._id!==j){var a=h.myform.visible_form_fields[h.selected.index];a.logicJump&&a.logicJump.jumpTo&&m(a)?h.setActiveField(a.logicJump.jumpTo,null,!0):h.selected.index0&&h.setActiveField(null,a,!0)},d.goToInvalid=h.goToInvalid=function(){var a=$(".row.field-directive .ng-invalid.focusOn, .row.field-directive .ng-untouched.focusOn:not(.ng-valid)").first().parents(".row.field-directive").first().attr("data-id");h.setActiveField(a,null,!0)},h.exitStartPage=function(){h.myform.startPage.showStart=!1,h.myform.visible_form_fields.length>0&&(h.selected._id=h.myform.visible_form_fields[0]._id)};var o=function(){var a=new MobileDetect(window.navigator.userAgent),b="other";return a.tablet()?b="tablet":a.mobile()?b="mobile":a.is("bot")||(b="desktop"),{type:b,name:window.navigator.platform}},p=function(){$.ajaxSetup({async:!1});var a=$.getJSON("https://freegeoip.net/json/").responseJSON;return $.ajaxSetup({async:!0}),a&&a.ip||(a={ip:"Adblocker"}),{ipAddr:a.ip,geoLocation:{City:a.city,Country:a.country_name}}};d.submitForm=h.submitForm=function(){if(h.forms.myForm.$invalid)return void h.goToInvalid();var d=b.stopClock();h.loading=!0;var f=_.cloneDeep(h.myform),g=o();f.device=g;var i=p();f.ipAddr=i.ipAddr,f.geoLocation=i.geoLocation,f.timeElapsed=d,f.percentageComplete=c("formValidity")(h.myform)/h.myform.visible_form_fields.length*100,delete f.endPage,delete f.isLive,delete f.provider,delete f.startPage,delete f.visible_form_fields,delete f.analytics,delete f.design,delete f.submissions,delete f.submitted;for(var j=0;j',restrict:"E",scope:{typeName:"@"},controller:["$scope",function(a){var b={textfield:"fa fa-pencil-square-o",dropdown:"fa fa-th-list",date:"fa fa-calendar",checkbox:"fa fa-check-square-o",radio:"fa fa-dot-circle-o",email:"fa fa-envelope-o",textarea:"fa fa-pencil-square",legal:"fa fa-legal",file:"fa fa-cloud-upload",rating:"fa fa-star-half-o",link:"fa fa-link",scale:"fa fa-sliders",stripe:"fa fa-credit-card",statement:"fa fa-quote-left",yes_no:"fa fa-toggle-on",number:"fa fa-slack"};a.typeIcon=b[a.typeName]}]}});var __indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b=0&&(c=c+b+".html"),d.get(c)};return{template:"
{{field.title}}
",restrict:"E",scope:{field:"=",required:"&",design:"=",index:"=",forms:"="},link:function(a,d){c.chooseDefaultOption=a.chooseDefaultOption=function(b){"yes_no"===b?a.field.fieldValue="true":"rating"===b?a.field.fieldValue=0:"radio"===a.field.fieldType?a.field.fieldValue=a.field.fieldOptions[0].option_value:"legal"===b&&(a.field.fieldValue="true",c.nextField())},a.nextField=c.nextField,a.setActiveField=c.setActiveField,"date"===a.field.fieldType&&(a.dateOptions={changeYear:!0,changeMonth:!0,altFormat:"mm/dd/yyyy",yearRange:"1900:-0",defaultDate:0});var e=a.field.fieldType;if("number"===a.field.fieldType||"textfield"===a.field.fieldType||"email"===a.field.fieldType||"link"===a.field.fieldType){switch(a.field.fieldType){case"textfield":a.input_type="text";break;case"email":a.input_type="email",a.placeholder="joesmith@example.com";break;case"number":a.input_type="text",a.validateRegex=/^-?\d+$/;break;default:a.input_type="url",a.placeholder="http://example.com"}e="textfield"}var g=f(e);d.html(g).show();b(d.contents())(a)}}}]),angular.module("view-form").directive("onEnterKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode,e=!1;null!==d.onEnterKeyDisabled&&(e=d.onEnterKeyDisabled),13!==c||b.shiftKey||e||(b.preventDefault(),a.$apply(function(){a.$eval(d.onEnterKey)}))})}}}]).directive("onTabKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keyup keypress",function(b){var c=b.which||b.keyCode;9!==c||b.shiftKey||(b.preventDefault(),a.$apply(function(){a.$eval(d.onTabKey)}))})}}}]).directive("onEnterOrTabKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode;13!==c&&9!==c||b.shiftKey||(b.preventDefault(),a.$apply(function(){a.$eval(d.onEnterOrTabKey)}))})}}}]).directive("onTabAndShiftKey",["$rootScope",function(a){return{restrict:"A",link:function(b,c,d){c.bind("keydown keypress",function(b){var c=b.which||b.keyCode;9===c&&b.shiftKey&&(console.log("onTabAndShiftKey"),b.preventDefault(),a.$apply(function(){a.$eval(d.onTabAndShiftKey)}))})}}}]),angular.module("view-form").directive("onFinishRender",["$rootScope","$timeout",function(a,b){return{restrict:"A",link:function(b,c,d){if(c.attr("ng-repeat")||c.attr("data-ng-repeat")){var e=d.onFinishRender||"ngRepeat";b.$first&&!b.$last?b.$evalAsync(function(){a.$broadcast(e+" Started")}):b.$last&&b.$evalAsync(function(){a.$broadcast(e+" Finished")})}}}}]),jsep.addBinaryOp("contains",10),jsep.addBinaryOp("!contains",10),jsep.addBinaryOp("begins",10),jsep.addBinaryOp("!begins",10),jsep.addBinaryOp("ends",10),jsep.addBinaryOp("!ends",10),angular.module("view-form").directive("submitFormDirective",["$http","TimeCounter","$filter","$rootScope","SendVisitorData","$translate","$timeout",function(a,b,c,d,e,f,g){return{templateUrl:"form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html",restrict:"E",scope:{myform:"=",ispreview:"="},controller:["$document","$window","$scope",function(f,g,h){var i=!1,j="submit_field";h.forms={},h.ispreview&&b.restartClock();var k=h.myform.visible_form_fields.filter(function(a){return"statement"!==a.fieldType}).length,l=c("formValidity")(h.myform);h.translateAdvancementData={done:l,total:k,answers_not_completed:k-l},h.reloadForm=function(){h.myform.submitted=!1,h.myform.form_fields=_.chain(h.myform.visible_form_fields).map(function(a){return a.fieldValue="",a}).value(),h.loading=!1,h.error="",h.selected={_id:"",index:0},h.setActiveField(h.myform.visible_form_fields[0]._id,0,!1),b.restartClock()};var m=function(a){var b=a.logicJump;if(b.enabled&&b.expressionString&&b.valueB&&a.fieldValue){var c,d,e=jsep(b.expressionString);if("field"===e.left.name?(c=a.fieldValue,d=b.valueB):(c=b.valueB,d=a.fieldValue),"number"===a.fieldType||"scale"===a.fieldType||"rating"===a.fieldType)switch(e.operator){case"==":return parseInt(c)===parseInt(d);case"!==":return parseInt(c)!==parseInt(d);case">":return parseInt(c)>parseInt(d);case">=":return parseInt(c)>parseInt(d);case"<":return parseInt(c)-1;case"!contains":return!(c.indexOf(d)>-1);case"begins":return c.startsWith(d);case"!begins":return!c.startsWith(d);case"ends":return c.endsWith(d);case"!ends":return c.endsWith(d);default:return!1}}},n=function(){if(null===h.selected)throw console.error("current active field is null"),new Error("current active field is null");return h.selected._id===j?h.myform.form_fields.length-1:h.selected.index};h.isActiveField=function(a){return h.selected._id===a._id},h.setActiveField=d.setActiveField=function(a,b,d){if(null!==h.selected&&(a||null!==b)){if(a){if(null===b){b=h.myform.visible_form_fields.length;for(var e=0;e .field-directive:nth-of-type("+String(h.myform.visible_form_fields.length-1)+")"),m=$(l).height(),n=k-g-1.2*m,o=.9;h.selected.index===h.myform.visible_form_fields.length?bn?(a=h.selected.index+1,h.setActiveField(j,a,!1)):ef*o&&(a=h.selected.index-1,h.setActiveField(null,a,!1))}h.$apply()},d.nextField=h.nextField=function(){if(h.selected&&h.selected.index>-1)if(h.selected._id!==j){var a=h.myform.visible_form_fields[h.selected.index];a.logicJump&&a.logicJump.jumpTo&&m(a)?h.setActiveField(a.logicJump.jumpTo,null,!0):h.selected.index0&&h.setActiveField(null,a,!0)},d.goToInvalid=h.goToInvalid=function(){var a=$(".row.field-directive .ng-invalid.focusOn, .row.field-directive .ng-untouched.focusOn:not(.ng-valid)").first().parents(".row.field-directive").first().attr("data-id");h.setActiveField(a,null,!0)},h.exitStartPage=function(){h.myform.startPage.showStart=!1,h.myform.visible_form_fields.length>0&&(h.selected._id=h.myform.visible_form_fields[0]._id)};var o=function(){var a=new MobileDetect(window.navigator.userAgent),b="other";return a.tablet()?b="tablet":a.mobile()?b="mobile":a.is("bot")||(b="desktop"),{type:b,name:window.navigator.platform}},p=function(){$.ajaxSetup({async:!1});var a=$.getJSON("https://freegeoip.net/json/").responseJSON;return $.ajaxSetup({async:!0}),a&&a.ip||(a={ip:"Adblocker"}),{ipAddr:a.ip,geoLocation:{City:a.city,Country:a.country_name}}};d.submitForm=h.submitForm=function(){if(h.forms.myForm.$invalid)return void h.goToInvalid();var d=b.stopClock();h.loading=!0;var f=_.cloneDeep(h.myform),g=o();f.device=g;var i=p();f.ipAddr=i.ipAddr,f.geoLocation=i.geoLocation,f.timeElapsed=d,f.percentageComplete=c("formValidity")(h.myform)/h.myform.visible_form_fields.length*100,delete f.endPage,delete f.isLive,delete f.provider,delete f.startPage,delete f.visible_form_fields,delete f.analytics,delete f.design,delete f.submissions,delete f.submitted;for(var j=0;j$(\".loader\").fadeOut(\"slow\");

{{ 'FORM_404_HEADER' | translate }}

{{ 'FORM_404_BODY' | translate }}
"); + $templateCache.put("form_modules/forms/base/views/form-unauthorized.client.view.html", + "

{{ 'FORM_UNAUTHORIZED_HEADER' | translate }}

{{ 'FORM_UNAUTHORIZED_BODY1' | translate }}
{{ 'FORM_UNAUTHORIZED_BODY2' | translate }}
"); + $templateCache.put("form_modules/forms/base/views/submit-form.client.view.html", + "
"); + $templateCache.put("form_modules/forms/base/views/directiveViews/entryPage/startPage.html", + "

{{pageData.introTitle}}

{{pageData.introParagraph}}

"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/date.html", + "

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{field.description}}

"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/dropdown.html", + "
0\">

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{field.description}}


"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/hidden.html", + ""); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/legal.html", + "

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}


{{field.description}}


"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/radio.html", + "
0\">

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{field.description}}


"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/rating.html", + "

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{field.description}}

"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/statement.html", + "

{{field.title}}

{{field.description}}

{{field.description}}


"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/textarea.html", + "

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{ 'NEWLINE' | translate }}

{{field.description}}

{{ 'ADD_NEW_LINE_INSTR' | translate }}
{{ 'ENTER' | translate }}
"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/textfield.html", + "

{{index+1}} {{field.title}} ({{ 'OPTIONAL' | translate }})

{{field.description}}

{{ 'ENTER' | translate }}
"); + $templateCache.put("form_modules/forms/base/views/directiveViews/field/yes_no.html", + "

{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}

{{field.description}}


"); + $templateCache.put("form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html", + "
{{ 'COMPLETING_NEEDED' | translate:translateAdvancementData }}
{{ 'ENTER' | translate }}

{{ 'ADVANCEMENT' | translate:translateAdvancementData }}

"); +}]); diff --git a/public/form_modules/forms/base/css/form.css b/public/form_modules/forms/base/css/form.css index 2a9665bd..f8dbfdf6 100644 --- a/public/form_modules/forms/base/css/form.css +++ b/public/form_modules/forms/base/css/form.css @@ -372,7 +372,6 @@ div.config-form .row.field { background-color:#efefef; } - /*Styles for add fields tab*/ .admin-form .add-field { background-color: #ddd; @@ -389,10 +388,6 @@ div.config-form .row.field { border-radius: 4px; } - .admin-form .oscar-field-select { - margin: 10px 0 10px; - } - .view-form-btn.span { padding-right:0.6em; } diff --git a/public/form_modules/forms/base/directives/submit-form.client.directive.js b/public/form_modules/forms/base/directives/submit-form.client.directive.js index 3798eb40..53b9005a 100644 --- a/public/form_modules/forms/base/directives/submit-form.client.directive.js +++ b/public/form_modules/forms/base/directives/submit-form.client.directive.js @@ -285,8 +285,6 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun }; $rootScope.prevField = $scope.prevField = function(){ - console.log('prevField'); - console.log($scope.selected); var selected_index = $scope.selected.index - 1; if($scope.selected.index > 0){ $scope.setActiveField(null, selected_index, true); @@ -380,17 +378,6 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun if($scope.myform.form_fields[i].fieldType === 'dropdown' && !$scope.myform.form_fields[i].deletePreserved){ $scope.myform.form_fields[i].fieldValue = $scope.myform.form_fields[i].fieldValue.option_value; } - - //Get rid of unnessecary attributes for each form field - delete form.form_fields[i].submissionId; - delete form.form_fields[i].disabled; - delete form.form_fields[i].ratingOptions; - delete form.form_fields[i].fieldOptions; - delete form.form_fields[i].logicJump; - delete form.form_fields[i].description; - delete form.form_fields[i].validFieldTypes; - delete form.form_fields[i].fieldType; - } setTimeout(function () { diff --git a/public/form_modules/forms/base/views/directiveViews/field/dropdown.html b/public/form_modules/forms/base/views/directiveViews/field/dropdown.html index 64d2863c..b3ac8087 100755 --- a/public/form_modules/forms/base/views/directiveViews/field/dropdown.html +++ b/public/form_modules/forms/base/views/directiveViews/field/dropdown.html @@ -15,11 +15,10 @@
>>>>>> 2.20 //Redirect to listForms if user is authenticated if(statesToIgnore.indexOf(toState.name) > 0){ if(Auth.isAuthenticated()){ diff --git a/public/modules/forms/admin/config/i18n/english.js b/public/modules/forms/admin/config/i18n/english.js index 3759d236..bdaa3b46 100644 --- a/public/modules/forms/admin/config/i18n/english.js +++ b/public/modules/forms/admin/config/i18n/english.js @@ -6,16 +6,30 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid //Configure Form Tab View ADVANCED_SETTINGS: 'Advanced Settings', - FORM_NAME: 'Form Name', - FORM_STATUS: 'Form Status', + FORM_NAME: 'Your tellform is called', + FORM_STATUS: 'Status', PUBLIC: 'Public', PRIVATE: 'Private', GA_TRACKING_CODE: 'Google Analytics Tracking Code', - DISPLAY_FOOTER: 'Display Form Footer?', + DISPLAY_FOOTER: 'Form Footer', SAVE_CHANGES: 'Save Changes', CANCEL: 'Cancel', - DISPLAY_START_PAGE: 'Display Start Page?', - DISPLAY_END_PAGE: 'Display Custom End Page?', + DISPLAY_START_PAGE: 'Start Page', + DISPLAY_END_PAGE: 'Custom End Page', + GENERAL_TAB: 'General', + SELF_NOTIFICATIONS_TAB: 'Self notifications', + RESPONDENT_NOTIFICATIONS_TAB: 'Respondent notifications', + + SEND_NOTIFICATION_TO: 'Send to', + NO_EMAIL_FIELD_WARNING: 'Error: You need an email field in your form to send the email to your form respondent', + REPLY_TO: 'Reply to', + EMAIL_SUBJECT: 'Subject', + EMAIL_MESSAGE: 'Message', + ENABLE_RESPONDENT_NOTIFICATIONS: 'Respondent Notifications are currently', + ENABLE_SELF_NOTIFICATIONS: 'Self Notifications are currently', + TOGGLE_ENABLED: 'Enabled', + TOGGLE_DISABLED: 'Disabled', + ADD_VARIABLE_BUTTON: 'Add variable', //List Forms View CREATE_A_NEW_FORM: 'Create a new form', @@ -47,7 +61,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid DELETE_FORM_MD: 'Delete Form', DELETE: 'Delete', FORM: 'Form', - VIEW: 'View', + VIEW_MY_TELLFORM: 'View my tellform', LIVE: 'Live', PREVIEW: 'Preview', COPY: 'Copy', diff --git a/public/modules/forms/admin/config/i18n/french.js b/public/modules/forms/admin/config/i18n/french.js index d9675934..5cee1263 100644 --- a/public/modules/forms/admin/config/i18n/french.js +++ b/public/modules/forms/admin/config/i18n/french.js @@ -5,16 +5,31 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid $translateProvider.translations('fr', { // Configurer la vue de l'onglet Formulaire ADVANCED_SETTINGS: 'Paramètres avancés', - FORM_NAME: "Nom du formulaire", - FORM_STATUS: 'Statut du formulaire', + FORM_NAME: "Votre tellform est appelé", + FORM_STATUS: 'Statut', PUBLIC: 'Public', PRIVATE: "Privé", GA_TRACKING_CODE: "Code de suivi Google Analytics", - DISPLAY_FOOTER: "Afficher le pied de formulaire?", + DISPLAY_FOOTER: "Pied de formulaire", SAVE_CHANGES: 'Enregistrer les modifications', CANCEL: 'Annuler', - DISPLAY_START_PAGE: "Afficher la page de démarrage?", - DISPLAY_END_PAGE: "Afficher la page de fin personnalisée?", + DISPLAY_START_PAGE: "Page de démarrage", + DISPLAY_END_PAGE: "Page de fin personnalisée", + + GENERAL_TAB: 'General', + SELF_NOTIFICATIONS_TAB: 'Self notifications', + RESPONDANT_NOTIFICATIONS_TAB: 'Respondent notifications', + + SEND_NOTIFICATION_TO: 'Envoyer à', + NO_EMAIL_FIELD_WARNING: 'Erreur: Vous avez besoin d\'un champ e-mail dans votre formulaire pour envoyer l\'e-mail au répondant de votre formulaire', + REPLY_TO: "Répondre à", + EMAIL_SUBJECT: 'Sujet', + EMAIL_MESSAGE: "Message", + ENABLE_RESPONDENT_NOTIFICATIONS: 'Les notifications des répondants sont actuellement', + ENABLE_SELF_NOTIFICATIONS: 'Les notifications automatiques sont actuellement', + TOGGLE_ENABLED: 'Activé', + TOGGLE_DISABLED: 'Désactivé', + ADD_VARIABLE_BUTTON: "Ajouter une variable", // Afficher les formulaires CREATE_A_NEW_FORM: "Créer un nouveau formulaire", @@ -46,7 +61,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid DELETE_FORM_MD: "Supprimer le formulaire", DELETE: "Supprimer", FORM: 'Formulaire', - VIEW: "Afficher", + VIEW_MY_TELLFORM: "Afficher ma forme", LIVE: "Live", PREVIEW: 'Aperçu', COPY: "Copier", diff --git a/public/modules/forms/admin/config/i18n/german.js b/public/modules/forms/admin/config/i18n/german.js index fa3dd2b3..bea90bd3 100644 --- a/public/modules/forms/admin/config/i18n/german.js +++ b/public/modules/forms/admin/config/i18n/german.js @@ -5,16 +5,31 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid $translateProvider.translations('de', { // Konfigurieren der Formularregisterkarte ADVANCED_SETTINGS: 'Erweiterte Einstellungen', - FORM_NAME: 'Formularname', - FORM_STATUS: 'Formularstatus', + FORM_NAME: 'Ihr tellform heißt', + FORM_STATUS: 'Status', PUBLIC: 'Öffentlich', PRIVATE: 'Privat', GA_TRACKING_CODE: 'Google Analytics Tracking-Code', - DISPLAY_FOOTER: 'Formularfußzeile anzeigen?', + DISPLAY_FOOTER: 'Fußzeile', SAVE_CHANGES: 'Änderungen speichern', CANCEL: 'Abbrechen', - DISPLAY_START_PAGE: 'Startseite anzeigen?', - DISPLAY_END_PAGE: 'Benutzerdefinierte Endseite anzeigen?', + DISPLAY_START_PAGE: 'Startseite', + DISPLAY_END_PAGE: 'Benutzerdefinierte Endseite', + + GENERAL_TAB: 'Allgemein', + SELF_NOTIFICATIONS_TAB: 'Selbstbenachrichtigungen', + RESPONDANT_NOTIFICATIONS_TAB: 'Beantwortungsbenachrichtigungen', + + SEND_NOTIFICATION_TO: 'Senden an', + NO_EMAIL_FIELD_WARNING: 'Fehler: Sie benötigen ein E-Mail-Feld in Ihrem Formular, um die E-Mail an Ihr Formular zu senden.', + REPLY_TO: 'Antworten auf', + EMAIL_SUBJECT: "Betreff", + EMAIL_MESSAGE: 'Nachricht', + ENABLE_RESPONDENT_NOTIFICATIONS: 'Antwortbenachrichtigungen sind derzeit', + ENABLE_SELF_NOTIFICATIONS: 'Selbstbenachrichtigungen sind derzeit', + TOGGLE_ENABLED: 'Aktiviert', + TOGGLE_DISABLED: 'Deaktiviert', + ADD_VARIABLE_BUTTON: 'Variable hinzufügen', // Listenformularansicht CREATE_A_NEW_FORM: 'Erstelle ein neues Formular', @@ -46,7 +61,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid DELETE_FORM_MD: 'Formular löschen', DELETE: 'Löschen', FORM: 'Formular', - VIEW: 'Ansicht', + VIEW_MY_TELLFORM: 'Mein tellform anzeigen', LIVE: 'Leben', PREVIEW: 'Vorschau', COPY: 'Kopieren', diff --git a/public/modules/forms/admin/config/i18n/italian.js b/public/modules/forms/admin/config/i18n/italian.js index 1414e891..f1695356 100644 --- a/public/modules/forms/admin/config/i18n/italian.js +++ b/public/modules/forms/admin/config/i18n/italian.js @@ -5,16 +5,31 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid $translateProvider.translations('it', { // Configura la visualizzazione scheda modulo ADVANCED_SETTINGS: 'Impostazioni avanzate', - FORM_NAME: 'Nome modulo', - FORM_STATUS: 'Stato modulo', + FORM_NAME: 'Il tuo tellform è chiamato', + FORM_STATUS: 'Stato', PUBLIC: 'pubblico', PRIVATE: 'Privato', GA_TRACKING_CODE: 'Codice di monitoraggio di Google Analytics', - DISPLAY_FOOTER: 'Visualizza piè di pagina?', + DISPLAY_FOOTER: 'Piè di pagina', SAVE_CHANGES: 'Salva modifiche', CANCEL: 'Annulla', - DISPLAY_START_PAGE: 'Visualizza pagina iniziale?', - DISPLAY_END_PAGE: 'Mostra pagina finale personalizzata?', + DISPLAY_START_PAGE: 'Pagina iniziale', + DISPLAY_END_PAGE: 'Pagina finale personalizzata', + + GENERAL_TAB: 'Generale', + SELF_NOTIFICATIONS_TAB: 'Autodiagnosi', + RESPONDANT_NOTIFICATIONS_TAB: 'Notifiche rispondenti', + + SEND_NOTIFICATION_TO: 'Invia a', + NO_EMAIL_FIELD_WARNING: 'Errore: Hai bisogno di un campo e-mail nel tuo modulo per inviare l\'email al tuo interlocutore', + REPLY_TO: 'Rispondi a', + EMAIL_SUBJECT: 'Oggetto', + EMAIL_MESSAGE: 'Messaggio', + ENABLE_RESPONDENT_NOTIFICATIONS: 'Notifiche rispondenti sono attualmente', + ENABLE_SELF_NOTIFICATIONS: 'Le notifiche auto sono attualmente', + TOGGLE_ENABLED: 'Abilitato', + TOGGLE_DISABLED: 'disabilitato', + ADD_VARIABLE_BUTTON: 'Aggiungi variabile', // Visualizzazione dei moduli di elenco CREATE_A_NEW_FORM: 'Crea un nuovo modulo', @@ -46,7 +61,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid DELETE_FORM_MD: 'Elimina modulo', DELETE: 'Elimina', FORM: 'Forma', - VIEW: 'Visualizza', + VIEW_MY_TELLFORM: 'Visualizza la mia informazione', LIVE: 'Live', PREVIEW: 'Anteprima', COPY: 'Copia', diff --git a/public/modules/forms/admin/config/i18n/spanish.js b/public/modules/forms/admin/config/i18n/spanish.js index 26c7199d..c61d8e25 100644 --- a/public/modules/forms/admin/config/i18n/spanish.js +++ b/public/modules/forms/admin/config/i18n/spanish.js @@ -3,19 +3,33 @@ angular.module('forms').config(['$translateProvider', function ($translateProvider) { $translateProvider.translations('es', { - //Configure Form Tab View ADVANCED_SETTINGS: 'Configuraciones avanzadas', - FORM_NAME: 'Nombre del formulario', - FORM_STATUS: 'Estado del formulario', + FORM_NAME: 'Tu tellform se llama', + FORM_STATUS: 'Estado', PUBLIC: 'Público', PRIVATE: 'Privado', GA_TRACKING_CODE: 'Código de Google Analytics', - DISPLAY_FOOTER: '¿Mostrar pie de página?', + DISPLAY_FOOTER: 'Pie de página', SAVE_CHANGES: 'Grabar', CANCEL: 'Cancelar', - DISPLAY_START_PAGE: '¿Mostrar página de inicio?', - DISPLAY_END_PAGE: '¿Mostrar paǵina de fin?', + DISPLAY_START_PAGE: 'Página de inicio', + DISPLAY_END_PAGE: 'Página final personalizada', + + SELF_NOTIFICATIONS_TAB: 'Auto notificaciones', + RESPONDANT_NOTIFICATIONS_TAB: 'Notificaciones de los demandados', + GENERAL_TAB: 'Général', + + SEND_NOTIFICATION_TO: 'Enviar a', + NO_EMAIL_FIELD_WARNING: 'Error: necesita un campo de correo electrónico en su formulario para enviar el correo electrónico a su encuestado', + REPLY_TO: 'Responder a', + EMAIL_SUBJECT: 'Asunto', + EMAIL_MESSAGE: 'Mensaje', + ENABLE_RESPONDENT_NOTIFICATIONS: 'Las notificaciones de los demandados son actualmente', + ENABLE_SELF_NOTIFICATIONS: 'Las notificaciones automáticas están actualmente', + TOGGLE_ENABLED: 'Habilitado', + TOGGLE_DISABLED: 'Desactivado', + ADD_VARIABLE_BUTTON: 'Agregar variable', //List Forms View CREATE_A_NEW_FORM: 'Crear formulario', @@ -47,7 +61,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid DELETE_FORM_MD: 'Borrar formulario', DELETE: 'Borrar', FORM: 'Formulario', - VIEW: 'Vista', + VIEW_MY_TELLFORM: 'Ver mi tellform', LIVE: 'Online', PREVIEW: 'Vista previa', COPY: 'Copiar', diff --git a/public/modules/forms/admin/controllers/admin-form.client.controller.js b/public/modules/forms/admin/controllers/admin-form.client.controller.js index 12c85f3c..7326426a 100644 --- a/public/modules/forms/admin/controllers/admin-form.client.controller.js +++ b/public/modules/forms/admin/controllers/admin-form.client.controller.js @@ -4,19 +4,12 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$window', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm', '$http', '$uibModal', 'myForm', '$filter', '$translate', function($rootScope, $window, $scope, $stateParams, $state, Forms, CurrentForm, $http, $uibModal, myForm, $filter, $translate) { - //Set active tab to Create - $scope.activePill = 0; - - $scope.copied = false; - $scope.onCopySuccess = function (e) { - $scope.copied = true; - }; - $scope = $rootScope; $scope.animationsEnabled = true; $scope.myform = myForm; $rootScope.saveInProgress = false; $scope.oldForm = _.cloneDeep($scope.myform); + $scope.designTabActive = false CurrentForm.setForm($scope.myform); @@ -36,7 +29,6 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$windo $scope.actualFormURL = window.location.protocol + '//' + window.location.host + $scope.formURL; } - var refreshFrame = $scope.refreshFrame = function(){ if(document.getElementById('iframe')) { document.getElementById('iframe').contentWindow.location.reload(); @@ -44,13 +36,59 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$windo }; $scope.tabData = [ + { + heading: $filter('translate')('CREATE_TAB'), + route: 'viewForm.create', + active: false + }, { heading: $filter('translate')('CONFIGURE_TAB'), - templateName: 'configure' + route: 'viewForm.configure.general', + active: false + }, + { + heading: $filter('translate')('ANALYZE_TAB'), + route: 'viewForm.analyze', + active: false + }, + { + heading: $filter('translate')('SHARE_TAB'), + route: 'viewForm.share', + active: false + }, + { + heading: $filter('translate')('DESIGN_TAB'), + route: 'viewForm.design', + active: false } ]; - $scope.designTabActive = false + $scope.go = function(tab){ + var currParentState = $state.current.name.split('.').slice(0,2).join('.'); + var tabParentState = tab.route.split('.').slice(0,2).join('.'); + + if(currParentState !== tabParentState && tabParentState !== 'viewForm.configure.general'){ + $state.go(tab.route); + } + }; + + function setActiveTab() { + $scope.tabData.forEach(function(tab) { + var currentTabState = $state.current.name.split('.').slice(0,2).join('.'); + var tabRouteState = tab.route.split('.').slice(0,2).join('.'); + tab.active = (currentTabState === tabRouteState); + + if(tab.active && tab.route === 'viewForm.design'){ + $scope.designTabActive = true; + } else { + $scope.designTabActive = false; + } + }); + } + + setActiveTab(); + + $scope.$on("$stateChangeSuccess", setActiveTab()); $scope.deactivateDesignTab = function(){ $scope.designTabActive = false diff --git a/public/modules/forms/admin/css/edit-form-configure.css b/public/modules/forms/admin/css/edit-form-configure.css new file mode 100644 index 00000000..afe5b2b2 --- /dev/null +++ b/public/modules/forms/admin/css/edit-form-configure.css @@ -0,0 +1,43 @@ +.tag { + background-color: #999; + border-radius: 3px 3px 3px 3px; + border: 0; + color: #FFFFFF; + font-style: inherit; + font-size: 11px; + padding: 4px 5px; + margin: 0 2px 2px 2px; + font-family: inherit; + white-space: nowrap; + vertical-align: middle; + cursor: pointer !important; + pointer-events: none; +} + +.email-subject.ta-root .ta-editor.ta-html, .email-subject .ta-scroll-window.form-control { + min-height: 0; + overflow: hidden; + height: auto; + border-radius: 4px; + box-shadow: none; + font-size: 18px; + padding-top: 10px; +} + +.email-subject.ta-root .ta-scroll-window > .ta-bind { + min-height: 0; + outline: 0; +} + +.ui-select input.form-control { + height: 34px; + padding: 6px; +} + +.config-form .btn-secondary { + border-color: #DDDDDD; +} + +.notification-toggle.toggle-switch { + margin: 5px 0; +} \ No newline at end of file diff --git a/public/modules/forms/admin/css/edit-form.css b/public/modules/forms/admin/css/edit-form.css index 4d8923ae..3ac8a10a 100644 --- a/public/modules/forms/admin/css/edit-form.css +++ b/public/modules/forms/admin/css/edit-form.css @@ -247,9 +247,25 @@ div.config-form .row.field { margin: 10px 0 10px; } +.view-form-btn { + border: none; +} .view-form-btn.span { padding-right:0.6em; } + +.notification-row { + display: inline-block; + padding: 0 5px; +} + +.status-light { + font-size: 10px; +} + +.notification-row .status-light { + padding-top: 15px; +} .status-light.status-light-off { color: #BE0000; } 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 fe60f778..a1caa7c5 100644 --- a/public/modules/forms/admin/directives/configure-form.client.directive.js +++ b/public/modules/forms/admin/directives/configure-form.client.directive.js @@ -1,23 +1,79 @@ 'use strict'; -angular.module('forms').directive('configureFormDirective', ['$rootScope', '$http', 'Upload', 'CurrentForm', - function ($rootScope, $http, Upload, CurrentForm) { +angular.module('forms').directive('configureFormDirective', ['$rootScope', '$filter', '$state', + function ($rootScope, $filter, $state) { return { templateUrl: 'modules/forms/admin/views/directiveViews/form/configure-form.client.view.html', restrict: 'E', scope: { - myform:'=', - user:'=', - pdfFields:'@', - formFields:'@' + myform:'=' }, controller: function($scope){ - $scope.log = ''; + $rootScope.myform = $scope.myform; $scope.languages = $rootScope.languages; - $scope.resetForm = $rootScope.resetForm; $scope.update = $rootScope.update; + $scope.$evalAsync(function() { + angular.element('.tag') + }); + + $scope.languages = ['en', 'fr', 'es', 'it', 'de']; + + $scope.langCodeToWord = { + 'en': 'English', + 'fr': 'Français', + 'es': 'Español', + 'it': 'Italiàno', + 'de': 'Deutsch' + }; + + $scope.wordToLangCode = { + 'English': 'en', + 'Français': 'fr', + 'Español': 'es', + 'Italiàno': 'it', + 'Deutsch': 'de' + }; + + $scope.configureTabs = [ + { + heading: $filter('translate')('GENERAL_TAB'), + route: 'viewForm.configure.general', + active: false + }, + { + heading: $filter('translate')('SELF_NOTIFICATIONS_TAB'), + route: 'viewForm.configure.self_notifications', + active: false + }, + { + heading: $filter('translate')('RESPONDENT_NOTIFICATIONS_TAB'), + route: 'viewForm.configure.respondent_notifications', + active: false + } + ]; + + $scope.emailFields = $scope.myform.form_fields.filter(function(field){ + return field.fieldType === 'email'; + }); + + $scope.formHasEmailField = ($scope.emailFields.length > 0); + + $scope.go = function(tab){ + tab.active = true; + $state.go(tab.route); + }; + + function setActiveTab() { + $scope.configureTabs.forEach(function(tab) { + tab.active = ($state.current.name === tab.route); + }); + } + + setActiveTab(); + + $scope.$on("$stateChangeSuccess", setActiveTab()); } }; } diff --git a/public/modules/forms/admin/directives/design-form.client.directive.js b/public/modules/forms/admin/directives/design-form.client.directive.js new file mode 100644 index 00000000..d786c91e --- /dev/null +++ b/public/modules/forms/admin/directives/design-form.client.directive.js @@ -0,0 +1,14 @@ +'use strict'; + +angular.module('forms').directive('designFormDirective', [ + function () { + return { + templateUrl: 'modules/forms/admin/views/directiveViews/form/design-form.client.view.html', + restrict: 'E', + scope: { + myform:'=', + formurl: '=' + } + } + } +]); \ No newline at end of file diff --git a/public/modules/forms/admin/directives/edit-form.client.directive.js b/public/modules/forms/admin/directives/edit-form.client.directive.js index 28cd0d6b..79f39e48 100644 --- a/public/modules/forms/admin/directives/edit-form.client.directive.js +++ b/public/modules/forms/admin/directives/edit-form.client.directive.js @@ -1,4 +1,3 @@ - 'use strict'; angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormFields', '$uibModal', diff --git a/public/modules/forms/admin/directives/share-form.client.directive.js b/public/modules/forms/admin/directives/share-form.client.directive.js new file mode 100644 index 00000000..ad8d1536 --- /dev/null +++ b/public/modules/forms/admin/directives/share-form.client.directive.js @@ -0,0 +1,16 @@ +'use strict'; + +angular.module('forms').directive('shareFormDirective', ['$rootScope', + function ($rootScope) { + return { + templateUrl: 'modules/forms/admin/views/directiveViews/form/share-form.client.view.html', + restrict: 'E', + scope: { + actualformurl:'=' + }, + controller: function($scope){ + $scope.actualFormURL = $scope.actualformurl; + } + }; + } +]); \ No newline at end of file diff --git a/public/modules/forms/admin/services/form-fields.client.service.js b/public/modules/forms/admin/services/form-fields.client.service.js index 302603ae..be6ff3c9 100644 --- a/public/modules/forms/admin/services/form-fields.client.service.js +++ b/public/modules/forms/admin/services/form-fields.client.service.js @@ -1,11 +1,18 @@ 'use strict'; //TODO: DAVID: URGENT: Make this a $resource that fetches valid field types from server +<<<<<<< HEAD +angular.module('forms').service('FormFields', [ '$rootScope', '$translate', '$window', + function($rootScope, $translate, $window) { + console.log($window.user); + $translate.use($window.user.language); +======= angular.module('forms').service('FormFields', [ '$rootScope', '$translate', 'Auth', function($rootScope, $translate, Auth) { var language = Auth.ensureHasCurrentUser().language; $translate.use(language); +>>>>>>> 2.20 this.types = [ { diff --git a/public/modules/forms/admin/views/admin-form.client.view.html b/public/modules/forms/admin/views/admin-form.client.view.html index bbcc183b..9d922ee1 100644 --- a/public/modules/forms/admin/views/admin-form.client.view.html +++ b/public/modules/forms/admin/views/admin-form.client.view.html @@ -42,158 +42,26 @@
-
- - - - - -
-
- - - - -
-
-
- - -
-
- {{ 'TELLFORM_URL' | translate }} -
-
- -
-
- -
-
-
- -
-
- {{ 'COPY_AND_PASTE' | translate }} -
-
- - - -
-
- -
-
-
-
-
-
-
-
- -
-
-
-
-
-
{{ 'BACKGROUND_COLOR' | translate }}
-
-
- -
-
- -
-
-
{{ 'QUESTION_TEXT_COLOR' | translate }}
-
- -
- -
-
- -
-
-
{{ 'ANSWER_TEXT_COLOR' | translate }}
-
- -
- -
-
- -
-
-
{{ 'BTN_BACKGROUND_COLOR' | translate }}
-
- -
- -
-
-
-
-
{{ 'BTN_TEXT_COLOR' | translate }}
-
- -
- -
-
-
- -
- -
-
- -
-
- -
-
-
+
+ +
+
+
+
diff --git a/public/modules/forms/admin/views/adminTabs/configure.html b/public/modules/forms/admin/views/adminTabs/configure.html index f4a971ff..e8b52e02 100644 --- a/public/modules/forms/admin/views/adminTabs/configure.html +++ b/public/modules/forms/admin/views/adminTabs/configure.html @@ -1,2 +1,4 @@ + + \ No newline at end of file diff --git a/public/modules/forms/admin/views/adminTabs/configureTabs/general.html b/public/modules/forms/admin/views/adminTabs/configureTabs/general.html new file mode 100644 index 00000000..2815e6f3 --- /dev/null +++ b/public/modules/forms/admin/views/adminTabs/configureTabs/general.html @@ -0,0 +1,106 @@ + +
+
+
+
+

{{ 'FORM_NAME' | translate }}

+
+ +
+ +
+
+ +
+

{{ 'LANGUAGE' | translate }}

+
+ + + {{ langCodeToWord[$select.selected] }} + + + + + + + * {{ 'REQUIRED_FIELD' | translate }} +
+
+ +
+
+

{{ 'FORM_STATUS' | translate }}

+
+ +
+ +
+
+ +
+
+

{{ 'GA_TRACKING_CODE' | translate }}

+
+ +
+ +
+
+
+
+

{{ 'DISPLAY_FOOTER' | translate }}

+
+ +
+ +
+
+ +
+
+

{{ 'DISPLAY_START_PAGE' | translate }}

+
+ +
+ +
+
+ +
+
+

{{ 'DISPLAY_END_PAGE' | translate }}

+
+ +
+ +
+
+
+
\ No newline at end of file diff --git a/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html b/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html new file mode 100644 index 00000000..a15da9ce --- /dev/null +++ b/public/modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html @@ -0,0 +1,81 @@ +
+
+
+
+ + +
+
+
{{ 'ENABLE_RESPONDENT_NOTIFICATIONS' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'SEND_NOTIFICATION_TO' | translate }}:
+
+ +
+ + + {{$select.selected.title}} + + + + + + +
+
+ +
+ + {{ 'NO_EMAIL_FIELD_WARNING' | translate }} + +
+ +
+
+
{{ 'REPLY_TO' | translate }}:
+
+ +
+ +
+
+ +
+
+
{{ 'EMAIL_SUBJECT' | translate }}:
+
+
+ +
+
+ +
+
+
{{ 'EMAIL_MESSAGE' | translate }}
+
+ +
+ +
+
+
+
+
\ No newline at end of file diff --git a/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html b/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html new file mode 100644 index 00000000..adc03dbd --- /dev/null +++ b/public/modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html @@ -0,0 +1,74 @@ +
+
+ +
+
+ + +
+ +
+
{{ 'ENABLE_SELF_NOTIFICATIONS' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'SEND_NOTIFICATION_TO' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'REPLY_TO' | translate }}
+
+ +
+ + + {{$select.selected.title}} + + + + + + +
+
+ +
+
+
{{ 'EMAIL_SUBJECT' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'EMAIL_MESSAGE' | translate }}
+
+ +
+ +
+
+
+
\ No newline at end of file diff --git a/public/modules/forms/admin/views/adminTabs/design.html b/public/modules/forms/admin/views/adminTabs/design.html new file mode 100644 index 00000000..06a465bf --- /dev/null +++ b/public/modules/forms/admin/views/adminTabs/design.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/modules/forms/admin/views/adminTabs/share.html b/public/modules/forms/admin/views/adminTabs/share.html new file mode 100644 index 00000000..5e005983 --- /dev/null +++ b/public/modules/forms/admin/views/adminTabs/share.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/modules/forms/admin/views/directiveViews/form/configure-form.client.view.html b/public/modules/forms/admin/views/directiveViews/form/configure-form.client.view.html index 67397b66..1120e475 100644 --- a/public/modules/forms/admin/views/directiveViews/form/configure-form.client.view.html +++ b/public/modules/forms/admin/views/directiveViews/form/configure-form.client.view.html @@ -1,133 +1,13 @@
- +
-
-
-
-
{{ 'FORM_NAME' | translate }}
-
+ + +
+
+
+
-
- -
-
- -
-
-
{{ 'FORM_STATUS' | translate }}
-
- -
- - - - - -
-
- -
-
{{ 'LANGUAGE' | translate }}
-
- - * {{ 'REQUIRED_FIELD' | translate }} -
-
-
-
-
-
-
{{ 'GA_TRACKING_CODE' | translate }}
-
- -
- -
-
-
-
-
{{ 'DISPLAY_FOOTER' | translate }}
-
- -
- - - -
-
- -
-
-
{{ 'DISPLAY_START_PAGE' | translate }}
-
- -
- - - - - -
-
- -
-
-
{{ 'DISPLAY_END_PAGE' | translate }}
-
- -
- - - - - -
-
-
-
diff --git a/public/modules/forms/admin/views/directiveViews/form/design-form.client.view.html b/public/modules/forms/admin/views/directiveViews/form/design-form.client.view.html new file mode 100644 index 00000000..8c0783c0 --- /dev/null +++ b/public/modules/forms/admin/views/directiveViews/form/design-form.client.view.html @@ -0,0 +1,76 @@ +
+
+
+
+
+
{{ 'BACKGROUND_COLOR' | translate }}
+
+
+ +
+
+ +
+
+
{{ 'QUESTION_TEXT_COLOR' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'ANSWER_TEXT_COLOR' | translate }}
+
+ +
+ +
+
+ +
+
+
{{ 'BTN_BACKGROUND_COLOR' | translate }}
+
+ +
+ +
+
+
+
+
{{ 'BTN_TEXT_COLOR' | translate }}
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/public/modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html b/public/modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html index d33d81d6..5a68b652 100644 --- a/public/modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html +++ b/public/modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html @@ -1,4 +1,4 @@ -
+
diff --git a/public/modules/forms/admin/views/directiveViews/form/share-form.client.view.html b/public/modules/forms/admin/views/directiveViews/form/share-form.client.view.html new file mode 100644 index 00000000..cc795b54 --- /dev/null +++ b/public/modules/forms/admin/views/directiveViews/form/share-form.client.view.html @@ -0,0 +1,44 @@ +
+
+
+ + +
+
+ {{ 'TELLFORM_URL' | translate }} +
+
+ +
+
+ +
+
+
+ +
+
+ {{ 'COPY_AND_PASTE' | translate }} +
+
+ + + +
+
+ +
+
+
+
+
+
+
\ No newline at end of file diff --git a/public/modules/forms/base/css/form.css b/public/modules/forms/base/css/form.css index 03537d98..a3e97b4e 100644 --- a/public/modules/forms/base/css/form.css +++ b/public/modules/forms/base/css/form.css @@ -224,13 +224,13 @@ form .row.field { font-size:0.8em; } - form .row.field.dropdown > .field-input input { + form .dropdown > .field-input input { min-height: 34px; border-width: 0 0 2px 0; border-radius: 5px; } - form .row.field.dropdown > .field-input input:focus { + form .dropdown > .field-input input:focus { border: none; } diff --git a/public/modules/forms/config/forms.client.config.js b/public/modules/forms/config/forms.client.config.js index dec0f715..bbf01063 100644 --- a/public/modules/forms/config/forms.client.config.js +++ b/public/modules/forms/config/forms.client.config.js @@ -6,6 +6,15 @@ angular.module('forms').run(['Menus', // Set top bar menu items Menus.addMenuItem('topbar', 'My Forms', 'forms', '', '/forms', false); } +]).run(['$rootScope', '$state', + function($rootScope, $state) { + $rootScope.$on('$stateChangeStart', function(evt, to, params) { + if (to.redirectTo) { + evt.preventDefault(); + $state.go(to.redirectTo, params) + } + }); + } ]).filter('secondsToDateTime', [function() { return function(seconds) { return new Date(1970, 0, 1).setSeconds(seconds); @@ -46,4 +55,31 @@ angular.module('forms').run(['Menus', directive.replace = true; return $delegate; }); -}]); +}]).config(['$provide', function ($provide){ + $provide.decorator('taOptions', ['$delegate', 'taRegisterTool', '$translate', '$window', function(taOptions, taRegisterTool, $translate, $window) { + taRegisterTool('insertField', { + display: '', + onClickField: function(field_id, field_name){ + this.$editor().wrapSelection('insertHTML', '' + field_name + '', false); + }, + action: function(){ + } + }); + + taOptions.defaultTagAttributes['var'] = { + 'contenteditable': 'false' + }; + + return taOptions; + }]); +}]); \ No newline at end of file diff --git a/public/modules/forms/config/forms.client.routes.js b/public/modules/forms/config/forms.client.routes.js index aa38bde0..a01d4d91 100644 --- a/public/modules/forms/config/forms.client.routes.js +++ b/public/modules/forms/config/forms.client.routes.js @@ -43,6 +43,7 @@ angular.module('forms').config(['$stateProvider', controller: 'SubmitFormController', controllerAs: 'ctrl' }).state('viewForm', { + abstract: true, url: '/forms/:formId/admin', templateUrl: 'modules/forms/admin/views/admin-form.client.view.html', data: { @@ -63,18 +64,35 @@ angular.module('forms').config(['$stateProvider', }] }, controller: 'AdminFormController' - }).state('viewForm.configure', { + }).state('viewForm.create', { + url: '/create', + templateUrl: 'modules/forms/admin/views/adminTabs/create.html' + }) + + .state('viewForm.configure', { + abstract: true, url: '/configure', templateUrl: 'modules/forms/admin/views/adminTabs/configure.html' - }).state('viewForm.design', { + }).state('viewForm.configure.general', { + url: '/general', + templateUrl: 'modules/forms/admin/views/adminTabs/configureTabs/general.html' + }).state('viewForm.configure.self_notifications', { + url: '/self_notifications', + templateUrl: 'modules/forms/admin/views/adminTabs/configureTabs/self-notifications.html' + }).state('viewForm.configure.respondent_notifications', { + url: '/respondent_notifications', + templateUrl: 'modules/forms/admin/views/adminTabs/configureTabs/respondent-notifications.html' + }) + + .state('viewForm.design', { url: '/design', templateUrl: 'modules/forms/admin/views/adminTabs/design.html' + }).state('viewForm.share', { + url: '/share', + templateUrl: 'modules/forms/admin/views/adminTabs/share.html' }).state('viewForm.analyze', { url: '/analyze', templateUrl: 'modules/forms/admin/views/adminTabs/analyze.html' - }).state('viewForm.create', { - url: '/create', - templateUrl: 'modules/forms/admin/views/adminTabs/create.html' }); } ]); diff --git a/public/modules/forms/forms.client.module.js b/public/modules/forms/forms.client.module.js index 07d98366..1c7fb122 100644 --- a/public/modules/forms/forms.client.module.js +++ b/public/modules/forms/forms.client.module.js @@ -3,5 +3,10 @@ // Use Application configuration module to register a new module ApplicationConfiguration.registerModule('forms', [ 'ngFileUpload', 'ui.date', 'ui.sortable', +<<<<<<< HEAD + 'angular-input-stars', 'users', 'ngclipboard', 'textAngular', + 'frapontillo.bootstrap-switch' +======= 'angular-input-stars', 'users', 'ngclipboard' +>>>>>>> 2.20 ]);//, 'colorpicker.module' @TODO reactivate this module diff --git a/public/modules/forms/tests/unit/controllers/admin-form.client.controller.test.js b/public/modules/forms/tests/unit/controllers/admin-form.client.controller.test.js index d49d8914..99a1c438 100644 --- a/public/modules/forms/tests/unit/controllers/admin-form.client.controller.test.js +++ b/public/modules/forms/tests/unit/controllers/admin-form.client.controller.test.js @@ -10,7 +10,8 @@ $httpBackend, $stateParams, $location, - $state; + $state, + $timeout; var sampleUser = { firstName: 'Full', @@ -175,7 +176,7 @@ // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). // This allows us to inject a service but then attach it to a variable // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$state_, _$location_, _$stateParams_, _$httpBackend_, CurrentForm, Forms) { + beforeEach(inject(function($controller, $rootScope, _$state_, _$location_, _$stateParams_, _$httpBackend_, CurrentForm, Forms, _$timeout_) { // Set a new global scope scope = $rootScope.$new(); @@ -187,6 +188,7 @@ $httpBackend = _$httpBackend_; $location = _$location_; $state = _$state_; + $timeout = _$timeout_; $httpBackend.whenGET(/\.html$/).respond(''); $httpBackend.whenGET('/users/me/').respond(''); @@ -197,60 +199,70 @@ }; })); - it('AdminFormController should fetch current Form when instantiated', function() { - // Run controller functionality - var controller = createAdminFormController(); + it('AdminFormController should fetch current Form when instantiated', inject(function($timeout) { + $timeout(function() { + // Run controller functionality + var controller = createAdminFormController(); - // Test scope value - expect(scope.myform).toEqualData(sampleForm); - }); - - it('$scope.removeCurrentForm() with valid form data should send a DELETE request with the id of form', inject(function($uibModal) { - var controller = createAdminFormController(); - - //Set $state transition - $state.expectTransitionTo('listForms'); - - // Set DELETE response - $httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); - - //Run controller functionality - scope.openDeleteModal(); - scope.removeCurrentForm(); - - $httpBackend.flush(); - $state.ensureAllTransitionsHappened(); + // Test scope value + expect(scope.myform).toEqualData(sampleForm); + }); })); - it('$scope.update() should send a PUT request with the id of form', function() { - var controller = createAdminFormController(); + it('$scope.removeCurrentForm() with valid form data should send a DELETE request with the id of form', inject(function($timeout, $uibModal) { + $timeout(function() { + var controller = createAdminFormController(); - //Set PUT response - $httpBackend.expect('PUT', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); + //Set $state transition + $state.expectTransitionTo('listForms'); - //Run controller functionality - scope.update(false, sampleForm, false, false); + // Set DELETE response + $httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); - $httpBackend.flush(); - }); + //Run controller functionality + scope.openDeleteModal(); + scope.removeCurrentForm(); - it('$scope.openDeleteModal() should open scope.deleteModal', function() { - var controller = createAdminFormController(); + $httpBackend.flush(); + $state.ensureAllTransitionsHappened(); + }); + })); - //Run controller functionality - scope.openDeleteModal(); - expect(scope.deleteModal.opened).toEqual(true); - }); + it('$scope.update() should send a PUT request with the id of form', inject(function($timeout) { + $timeout(function() { + var controller = createAdminFormController(); - it('$scope.cancelDeleteModal() should close $scope.deleteModal', inject(function($uibModal) { - var controller = createAdminFormController(); + //Set PUT response + $httpBackend.expect('PUT', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); - //Run controller functionality - scope.openDeleteModal(); + //Run controller functionality + scope.update(false, sampleForm, false, false); - //Run controller functionality - scope.cancelDeleteModal(); - expect( scope.deleteModal.opened ).toEqual(false); + $httpBackend.flush(); + }); + })); + + it('$scope.openDeleteModal() should open scope.deleteModal', inject(function($timeout) { + $timeout(function() { + var controller = createAdminFormController(); + + //Run controller functionality + scope.openDeleteModal(); + expect(scope.deleteModal.opened).toEqual(true); + }); + })); + + it('$scope.cancelDeleteModal() should close $scope.deleteModal', inject(function($uibModal, $timeout) { + $timeout(function() { + var controller = createAdminFormController(); + + //Run controller functionality + scope.openDeleteModal(); + + //Run controller functionality + scope.cancelDeleteModal(); + expect( scope.deleteModal.opened ).toEqual(false); + }); })); }); }()); diff --git a/public/modules/users/controllers/authentication.client.controller.js b/public/modules/users/controllers/authentication.client.controller.js index ac2979ff..811e855f 100755 --- a/public/modules/users/controllers/authentication.client.controller.js +++ b/public/modules/users/controllers/authentication.client.controller.js @@ -11,7 +11,7 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca var statesToIgnore = ['', 'home', 'signin', 'resendVerifyEmail', 'verify', 'signup', 'signup-success', 'forgot', 'reset-invalid', 'reset', 'reset-success']; $scope.signin = function() { - if($scope.forms && $scope.forms.hasOwnProperty('siginForm') && !$scope.forms.signinForm.$invalid){ + if($scope.forms && $scope.forms.signinForm.$valid){ User.login($scope.credentials).then( function(response) { Auth.login(response); @@ -40,7 +40,7 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca return; } - if(!$scope.forms.signupForm.$invalid){ + if($scope.forms && $scope.forms.signupForm.$valid){ User.signup($scope.credentials).then( function(response) { $state.go('signup-success');