got table submissions to display correctly

This commit is contained in:
David Baldwynn 2015-07-21 16:25:45 -07:00
parent ca9af627a5
commit 79dfbbc8a7
52 changed files with 1417 additions and 943 deletions

View file

@ -79,7 +79,6 @@ exports.createSubmission = function(req, res) {
submission.form_fields = req.body.form_fields;
submission.title = req.body.title;
submission.timeElapsed = req.body.timeElapsed;
// console.log(req.body);s
// submission.ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if(form.autofillPDFs){
@ -126,8 +125,8 @@ exports.createSubmission = function(req, res) {
message: errorHandler.getErrorMessage(err)
});
}
console.log(results);
console.log(that.form_fields);
// console.log(results);
// console.log(that.form_fields);
res.status(200).send('Form submission successfully saved');
});
};
@ -137,21 +136,31 @@ exports.createSubmission = function(req, res) {
*/
exports.listSubmissions = function(req, res) {
var _form = req.form;
var _user = req.user;
// console.log(_form);
// if(_form.submissions.length){
// res.json(_form.submissions);
// }else{
FormSubmission.find({ form: req.form }).populate('admin', 'form').exec(function(err, _submissions) {
FormSubmission.find({ form: req.form, admin: _user }).populate('admin', 'form').exec(function(err, _submissions) {
if (err) {
console.log(err);
res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
// _form.submissions = _submissions;
_form.update({ $set : { submissions: _submissions }});
res.status(200);
}
_form.update({ $set : { submissions: _submissions }}).exec(function(err, form){
if (err) {
console.log(err);
res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
}
res.json(_submissions);
});
// res.status(200).send('Updated forms');
});
// }
};
@ -192,10 +201,21 @@ exports.read = function(req, res) {
exports.update = function(req, res) {
console.log('in form.update()');
var form = req.form;
form = _.extend(form, req.body.form);
form.admin = req.user;
console.log(req.body.form.form_fields);
var form = req.form;
delete req.body.form.__v;
delete req.body.form._id;
delete req.body.form.created;
delete req.body.form.lastModified;
//Unless we have 'admin' priviledges, updating form admin is disabled
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
form = _.extend(form, req.body.form);
// console.log(req.body.form);
// form.form_fields = req.body.form.form_fields;
form.save(function(err) {
if (err) {
console.log(err);
@ -267,28 +287,6 @@ exports.formByID = function(req, res, next, id) {
});
}
else {
if(!form.admin){
form.admin = req.user;
form.save(function(err) {
if (err) {
console.log(err);
res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
//Remove sensitive information from User object
form.admin.password = null;
form.admin.created = null;
form.admin.salt = null;
req.form = form;
next();
}
});
}
console.log(form.submissions);
//Remove sensitive information from User object
form.admin.password = null;
form.admin.created = null;

View file

@ -7,8 +7,94 @@ var _ = require('lodash'),
errorHandler = require('../errors.server.controller'),
mongoose = require('mongoose'),
passport = require('passport'),
async = require('async'),
config = require('../../../config/config'),
nodemailer = require('nodemailer'),
crypto = require('crypto'),
User = mongoose.model('User');
var smtpTransport = nodemailer.createTransport(config.mailer.options);
/**
* Reset password GET from email token
*/
exports.validateResetToken = function(req, res) {
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: {
$gt: Date.now()
}
}, function(err, user) {
if (!user) {
return res.redirect('/#!/password/reset/invalid');
}
res.redirect('/#!/password/reset/' + req.params.token);
});
};
/**
* Send verification email
*/
var sendVerificationEmail = function(req, res, next) {
// Init Variables
var passwordDetails = req.body;
async.waterfall([
// Generate random token
function(done) {
crypto.randomBytes(20, function(err, buffer) {
var token = buffer.toString('hex');
done(err, token);
});
},
function(token, done) {
// For security measurement we remove the roles from the req.body object
delete req.body.roles;
// Init Variables
var user = new User(req.body);
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
// Add missing user fields
user.provider = 'local';
user.displayName = user.firstName + ' ' + user.lastName;
// Then save the user
user.save(function(err) {
done(err, token, user);
});
},
function(token, user, done) {
res.render('templates/verify-account-email', {
name: user.displayName,
url: 'http://' + req.headers.host + '/auth/activate/' + token,
appName: config.app.title
}, function(err, emailHTML) {
done(err, emailHTML, user);
});
},
// If valid email, send reset email using service
function(emailHTML, user, done) {
var mailOptions = {
to: user.email,
from: config.mailer.from,
subject: 'Please verify your email',
html: emailHTML
};
smtpTransport.sendMail(mailOptions, function(err) {
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
res.status(200).send('new user successfully registered');
});
};
/**
* Signup
*/
@ -34,14 +120,15 @@ exports.signup = function(req, res) {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
res.status(200).send('new user successfully registered');
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.status(200).send('user successfully loggedin');
}
});
// req.login(user, function(err) {
// if (err) {
// res.status(400).send(err);
// } else {
// res.status(200).send('new user successfully registered');
// }
// });
}
});
};
@ -60,7 +147,9 @@ exports.signin = function(req, res, next) {
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(user);
}
@ -74,8 +163,8 @@ exports.signin = function(req, res, next) {
*/
exports.signout = function(req, res) {
req.logout();
// res.status(200).send('user successfully logged out');
res.redirect('/');
res.status(200).send('user successfully logged out');
// res.redirect('/');
};
/**

View file

@ -52,5 +52,13 @@ exports.update = function(req, res) {
* Send User
*/
exports.me = function(req, res) {
var _user = req.user;
delete _user.password;
delete _user.salt;
delete _user.provider;
delete _user.__v;
delete _user.created;
res.json(req.user || null);
};

View file

@ -5,14 +5,16 @@
*/
var mongoose = require('mongoose'),
FieldSchema = require('./form_field.server.model.js'),
FormSubmissionSchema = require('./form_submission.server.model.js'),
Schema = mongoose.Schema,
pdfFiller = require('pdffiller'),
_ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
fs = require('fs-extra'),
async = require('async'),
Field = mongoose.model('Field', FieldSchema);
async = require('async');
var Field = mongoose.model('Field', FieldSchema);
var FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema);
/**
@ -44,7 +46,7 @@ var FormSchema = new Schema({
default: '',
},
form_fields: {
type: [Schema.Types.Mixed],
type: [FieldSchema],
set: function(form_fields) {
this._previousFormFields = this.form_fields;
return form_fields;
@ -58,7 +60,8 @@ var FormSchema = new Schema({
admin: {
type: Schema.Types.ObjectId,
ref: 'User'
ref: 'User',
required: 'Form must have an Admin'
},
pdf: {
@ -67,6 +70,7 @@ var FormSchema = new Schema({
pdfFieldMap: {
type: Schema.Types.Mixed
},
hideFooter: {
type: Boolean,
default: false,
@ -85,6 +89,10 @@ var FormSchema = new Schema({
},
});
FormSchema.post('init', function() {
this._original = this.toObject();
});
//Delete template PDF of current Form
FormSchema.pre('remove', function (next) {
if(this.pdf){
@ -109,6 +117,7 @@ FormSchema.pre('save', function (next) {
//Concatenate submission and form's form_fields
// FormSchema.pre('save', function (next) {
// if(this.isModified('form_fields')){
// if(this.submissions.length){
// for(var i=0; i<this.submissions.length; i++){
// var submission = this.submissions[i];
@ -116,11 +125,119 @@ FormSchema.pre('save', function (next) {
// this.submissions[i].form_fields = submission.form_fields.concat(_.difference(this.form_fields, this._previousFormFields));
// }
// }
// this.form_fields = this._previousFormFields.concat(_.difference(this.form_fields, this._previousFormFields));
// }
// next();
// });
function getDeletedIndexes(needle, haystack){
var deletedIndexes = [];
if(haystack.length > 0){
for(var i = 0; i < needle.length; i++){
if(haystack.indexOf(needle[i]) <= -1){
deletedIndexes.push(i);
}
}
}
return deletedIndexes;
}
FormSchema.pre('save', function (next) {
if(this.isModified('form_fields')){
var old_form_fields = this._original.form_fields,
old_ids = _.pluck(this.form_fields, '_id'),
new_ids = _.pluck(old_form_fields, '_id'),
deletedIds = getDeletedIndexes(old_ids, new_ids),
that = this;
// console.log(deletedIds);
// console.log('old_ids\n--------');
// console.log(old_ids);
// console.log('new_ids\n--------');
// console.log(new_ids);
//Preserve fields that have at least one submission
if( deletedIds.length > 0 ){
var modifiedSubmissions;
async.forEachOfSeries(deletedIds, function (deletedIdIndex, key, callback) {
var deleted_id = old_ids[deletedIdIndex];
//Search for submissions with deleted form_field
FormSubmission.
find({ form: that, admin: that.admin, form_fields: {$elemMatch: {_id: deleted_id} } }).
exec(function(err, submissions){
if(err){
console.error(err);
return callback(err);
}
//Delete field if there are no submission(s) found
if(submissions.length > 0) {
//Push old form_field to start of array
that.form_fields.unshift(old_form_fields[deletedIdIndex]);
modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
console.log(modifiedSubmissions);
}
callback(null, modifiedSubmissions);
}
);
}, function (err, submissions) {
if(err){
console.error(err.message);
next(err);
}
console.log('preserved deleted fields');
console.log(submissions);
async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
for(var i = 0; i < deletedIds.length; i++){
var tmpField = _.find(submission.form_fields, function(field){
return field._id === deletedIds[i];
});
var index = submission.form_fields.indexOf(tmpField);
if(tmpField){
//Delete old form_field
submission.form_fields.splice(index, 1);
//Move old form_field to start
submission.form_fields.unshift(tmpField);
}
}
submission.save(function (err) {
if (err) callback(err);
callback();
});
}, function (err) {
if(err){
console.error(err.message);
next(err);
}
next();
});
});
}
}
next();
});
//Move PDF to permanent location after new template is uploaded
FormSchema.pre('save', function (next) {
@ -129,7 +246,6 @@ FormSchema.pre('save', function (next) {
async.series([
function(callback){
if(that.isModified('pdf')){
// console.log('about to move PDF');
var new_filename = that.title.replace(/ /g,'')+'_template.pdf';
@ -142,26 +258,21 @@ FormSchema.pre('save', function (next) {
fs.mkdirSync(newDestination);
}
if (stat && !stat.isDirectory()) {
// console.log('Directory '+newDestination+' cannot be created');
callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"') );
callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"'), null);
}
// console.log('about to move PDF');
fs.move(that.pdf.path, path.join(newDestination, new_filename), function (err) {
if (err) {
console.error(err);
callback( new Error(err.message) );
callback( new Error(err.message), null);
}
that.pdf.path = path.join(newDestination, new_filename);
that.pdf.name = new_filename;
// console.log('\n\n PDF file:'+that.pdf.name+' successfully moved to: '+that.pdf.path);
callback(null,'task1');
});
}
callback(null,null);
callback(null,'task1');
},
function(callback){
if(that.isGenerated){
@ -182,9 +293,9 @@ FormSchema.pre('save', function (next) {
pdfFiller.generateFieldJson(that.pdf.path, function(err, _form_fields){
if(err){
next( new Error(err.message), null);
}else if(!_form_fields.length){
next( new Error('Generated formfields is empty'), null);
callback( new Error(err.message), null);
}else if(!_form_fields.length || _form_fields === undefined || _form_fields === null){
callback( new Error('Generated formfields is empty'), null);
}
//Map PDF field names to FormField field names
@ -196,21 +307,8 @@ FormSchema.pre('save', function (next) {
field.fieldType = _typeConvMap[ field.fieldType+'' ];
}
field.fieldValue = '';
field.created = Date.now();
field.required = true;
field.disabled = false;
// field = new Field(field);
// field.save(function(err) {
// if (err) {
// console.error(err.message);
// throw new Error(err.message);
// });
// } else {
// _form_fields[i] = that;
// }
// });
field = new Field(field);
field.required = false;
_form_fields[i] = field;
}
@ -310,28 +408,7 @@ FormSchema.pre('save', function (next) {
// next();
// });
// FormSchema.methods.generateSubmissionsCSV = function (cb) {
// if(this.submissions.length){
// submissions = this.submissions
// }else{
// submissions =
// }
// _values.forEach(function(val){
// if(val === true){
// val = 'Yes';
// }else if(val === false) {
// val = 'Off';
// }
// });
// var jsonObj = _.zipObject(_keys, _values);
// return jsonObj;
// };
FormSchema.methods.generateFDFTemplate = function (cb) {
FormSchema.methods.generateFDFTemplate = function() {
var _keys = _.pluck(this.form_fields, 'title'),
_values = _.pluck(this.form_fields, 'fieldValue');

View file

@ -8,7 +8,7 @@ var mongoose = require('mongoose'),
// questionType Validation
function validateFormFieldType(value) {
if (!value || typeof myVar !== 'string' ) { return false; }
if (!value) { return false; }
var validTypes = [
'textfield',
@ -17,20 +17,16 @@ function validateFormFieldType(value) {
'legal',
'url',
'number',
'textarea',
'statement',
'welcome',
'thankyou',
'file',
'dropdown',
'scale',
'rating',
'radio',
'checkbox',
'hidden',
];
@ -49,7 +45,11 @@ var FormFieldSchema = new Schema({
type: Date,
default: Date.now
},
name: {
lastModified: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
@ -60,7 +60,7 @@ var FormFieldSchema = new Schema({
default: '',
},
fieldOptions: [{
type: String
type: Schema.Types.Mixed
}],
required: {
type: Boolean,
@ -75,7 +75,7 @@ var FormFieldSchema = new Schema({
required: 'Field type cannot be blank',
validate: [validateFormFieldType, 'Invalid field type']
},
value: Schema.Types.Mixed
fieldValue: Schema.Types.Mixed
});

View file

@ -10,9 +10,6 @@ var mongoose = require('mongoose'),
_ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
Form = mongoose.model('Form'),
FieldSchema = require('./form_field.server.model.js'),
Field = mongoose.model('Field', FieldSchema),
fs = require('fs-extra');
/**
@ -119,4 +116,6 @@ FormSubmissionSchema.pre('save', function (next) {
});
mongoose.model('FormSubmission', FormSubmissionSchema);
module.exports = FormSubmissionSchema;
// mongoose.model('FormSubmission', FormSubmissionSchema);

View file

@ -74,7 +74,7 @@ var UserSchema = new Schema({
roles: {
type: [{
type: String,
enum: ['user', 'admin']
enum: ['user', 'admin', 'superuser']
}],
default: ['user']
},
@ -91,6 +91,15 @@ var UserSchema = new Schema({
type: Date,
default: Date.now
},
/* For account activation */
activationToken: {
type: String
},
activationTokenExpires: {
type: Date
},
/* For reset password */
resetPasswordToken: {
type: String

View file

@ -22,7 +22,7 @@ module.exports = function(app) {
.delete(users.requiresLogin, forms.hasAuthorization, forms.delete);
app.route('/forms/:formId([a-zA-Z0-9]+)/submissions')
.get(forms.listSubmissions);
.get(users.requiresLogin, forms.hasAuthorization, forms.listSubmissions);
// Finish by binding the form middleware
app.param('formId', forms.formByID);

View file

@ -14,6 +14,10 @@ module.exports = function(app) {
app.route('/users').put(users.requiresLogin, users.update);
app.route('/users/accounts').delete(users.requiresLogin, users.removeOAuthProvider);
// Account activation reset token
app.route('/auth/reset/:token').get(users.validateResetToken);
app.route('/auth/reset/:token').post(users.reset);
// Setting up the users password api
app.route('/users/password').post(users.requiresLogin, users.changePassword);
app.route('/auth/forgot').post(users.forgot);

View file

@ -0,0 +1,83 @@
'use strict';
/**
* Module dependencies.
*/
var should = require('should'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
Form = mongoose.model('Form');
/**
* Globals
*/
var user, Form,
FormFDF;
/**
* Unit tests
*/
describe('Form Model Unit Tests:', function() {
beforeEach(function(done) {
user = new User({
firstName: 'Full',
lastName: 'Name',
displayName: 'Full Name',
email: 'test@test.com',
username: 'username',
password: 'password'
});
user.save(function() {
Form = new Form({
title: 'Form Title',
admin: user,
form_fields: [{'title':'Short Text2','fieldType':'textfield','fieldValue':'','disabled':false},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'nascar'},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'hockey'}]
});
done();
});
});
describe('Method Save', function() {
it('should be able to save without problems', function(done) {
return Form.save(function(err) {
should.not.exist(err);
done();
});
});
it('should be able to show an error when try to save without title', function(done) {
Form.title = '';
return Form.save(function(err) {
should.exist(err);
done();
});
});
});
describe('Method generateFDFTemplate', function() {
it('should be able to generate one that is correct', function(done) {
return Form.generateFDFTemplate(function(err) {
should.not.exist(err);
done();
});
});
it('should be able to show an error when try to save without title', function(done) {
Form.title = '';
return Form.save(function(err) {
should.exist(err);
done();
});
});
});
afterEach(function(done) {
Form.remove().exec(function() {
User.remove().exec(done);
});
});
});

BIN
app/tests/test.pdf Normal file

Binary file not shown.

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<p>Dear {{name}},</p>
<br>
<p>
You have just created a new account at {{appName}}. To use your account you must activate it.s
</p>
<p>Please visit this url to activate your account:</p>
<p>{{url}}</p>
<strong>If you didn't make this request, you can ignore this email.</strong>
<br>
<br>
<p>The {{appName}} Support Team</p>
</body>
</html>

View file

@ -23,7 +23,10 @@
"restangular": "~1.5.1",
"fontawesome": "~4.3.0",
"ng-file-upload": "~5.0.9",
"angular-raven": "~0.5.11"
"angular-raven": "~0.5.11",
"angular-ui-date": "~0.0.8",
"lodash": "~3.10.0",
"angular-ui-sortable": "~0.13.4"
},
"resolutions": {
"angular": "^1.2.21",

View file

@ -150,6 +150,25 @@ module.exports = function(db) {
require(path.resolve(routePath))(app);
});
// Add headers for Sentry
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://sentry.polydaic.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
// Sentry (Raven) middleware
app.use(raven.middleware.express.requestHandler(config.DSN));

View file

@ -0,0 +1,96 @@
[
[{
"fieldType": "textfield",
"fieldValue": "snthsnth",
"_id": "55aec5d284bae1a1996210bd",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Short Text2",
"lastModified": "2015-07-21T22:21:06.653Z",
"created": "2015-07-21T22:21:06.653Z",
"$$hashKey": "02J"
}, {
"fieldType": "textfield",
"fieldValue": "duieedi",
"_id": "55aec5b084bae1a1996210b4",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Last Name",
"lastModified": "2015-07-21T22:20:32.053Z",
"created": "2015-07-21T22:20:32.053Z",
"$$hashKey": "02K"
}],
[{
"fieldType": "textfield",
"fieldValue": "snthsnth",
"_id": "55aec5d284bae1a1996210bd",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Short Text2",
"lastModified": "2015-07-21T22:21:06.653Z",
"created": "2015-07-21T22:21:06.653Z",
"$$hashKey": "02J"
}, {
"fieldType": "textfield",
"fieldValue": "duieedi",
"_id": "55aec5b084bae1a1996210b4",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Last Name",
"lastModified": "2015-07-21T22:20:32.053Z",
"created": "2015-07-21T22:20:32.053Z",
"$$hashKey": "02K"
}],
[{
"fieldType": "textfield",
"fieldValue": "snthsnth",
"_id": "55aec5d284bae1a1996210bd",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Short Text2",
"lastModified": "2015-07-21T22:21:06.653Z",
"created": "2015-07-21T22:21:06.653Z",
"$$hashKey": "02J"
}, {
"fieldType": "textfield",
"fieldValue": "duieedi",
"_id": "55aec5b084bae1a1996210b4",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Last Name",
"lastModified": "2015-07-21T22:20:32.053Z",
"created": "2015-07-21T22:20:32.053Z",
"$$hashKey": "02K"
}],
[{
"fieldType": "textfield",
"fieldValue": "snthsnth",
"_id": "55aec5d284bae1a1996210bd",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Short Text2",
"lastModified": "2015-07-21T22:21:06.653Z",
"created": "2015-07-21T22:21:06.653Z",
"$$hashKey": "02J"
}, {
"fieldType": "textfield",
"fieldValue": "duieedi",
"_id": "55aec5b084bae1a1996210b4",
"disabled": false,
"fieldOptions": [],
"description": "",
"title": "Last Name",
"lastModified": "2015-07-21T22:20:32.053Z",
"created": "2015-07-21T22:20:32.053Z",
"$$hashKey": "02K"
}]
]

View file

@ -0,0 +1,22 @@
##First Form Auto-Update
1. Added field CLIENT
time: 2553
2. Finding form SERVER
time: 2841
3. Update form CLIENT
time: 2870
4.Updated form SERVER
time: 2863
##Second Form Auto-Update
1. Added field CLIENT
time: 2755
2. Finding form SERVER
time: 2898

View file

@ -114,13 +114,13 @@ module.exports = function(grunt) {
}
}
},
ngAnnotate: {
production: {
files: {
'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
}
}
},
// ngAnnotate: {
// production: {
// files: {
// 'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
// }
// }
// },
concurrent: {
default: ['nodemon', 'watch'],
debug: ['nodemon', 'watch', 'node-inspector'],
@ -179,7 +179,7 @@ module.exports = function(grunt) {
grunt.registerTask('lint', ['newer:jshint', 'newer:csslint']);
// Build task(s).
grunt.registerTask('build', ['lint', 'loadConfig', 'ngAnnotate', 'uglify', 'cssmin']);
grunt.registerTask('build', ['lint', 'loadConfig', 'uglify', 'cssmin']); //'ngAnnotate', ]);
// Test task.
grunt.registerTask('test', ['test:server', 'test:client']);

View file

@ -39,7 +39,7 @@ module.exports = function(config) {
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['PhantomJS'],
browsers: ['Chrome'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,

View file

@ -21,7 +21,7 @@
"postinstall": "bower install --config.interactive=false; grunt build"
},
"dependencies": {
"async": "~0.9.0",
"async": "^1.4.0",
"body-parser": "~1.9.0",
"bower": "~1.3.8",
"chalk": "~1.0.0",
@ -63,6 +63,7 @@
"method-override": "~2.3.0",
"mocha": ">=1.20.0",
"mongoose": "~3.8.8",
"mongoose-datatable": "^1.0.2",
"morgan": "~1.4.1",
"multer": "~0.1.8",
"nodemailer": "~1.3.0",
@ -80,5 +81,9 @@
"supertest": "~0.14.0",
"swig": "~1.4.1",
"then-fs": "~2.0.0"
},
"devDependencies": {
"karma-chrome-launcher": "^0.1.12",
"karma-jasmine": "^0.2.3"
}
}

View file

@ -9,20 +9,34 @@ angular.module(ApplicationConfiguration.applicationModuleName).config(['$locatio
$locationProvider.hashPrefix('!');
}
]);
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', '$state', '$stateParams',
function($rootScope, $state, $stateParams) {
//Permission Constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('APP_PERMISSIONS', {
viewAdminSettings: 'viewAdminSettings',
editAdminSettings: 'editAdminSettings',
editForm: 'editForm',
viewPrivateForm: 'viewPrivateForm',
});
//User Role constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('USER_ROLES', {
admin: 'admin',
normal: 'user',
superuser: 'superuser',
});
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', '$state', '$stateParams',
function($rootScope, Auth, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
// add previous state property
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
console.log(fromState);
$state.previous = fromState;
//Redirect home to listForms if user is authenticated
if(toState.name === 'home'){
if($rootScope.authentication.isAuthenticated()){
if(Auth.isAuthenticated()){
event.preventDefault(); // stop current execution
$state.go('listForms'); // go to login
}
@ -32,6 +46,31 @@ angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope'
}
]);
//Page access/authorization logic
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', 'User', 'Authorizer', '$state', '$stateParams',
function($rootScope, Auth, User, Authorizer, $state, $stateParams) {
$rootScope.$on('$stateChangeStart', function(event, next) {
var authenticator, permissions, user;
permissions = next && next.data && next.data.permissions ? next.data.permissions : null;
Auth.ensureHasCurrentUser(User);
user = Auth.currentUser;
if(user){
authenticator = new Authorizer(user);
// console.log('Permissions');
// console.log(permissions);
if( (permissions !== null) && !authenticator.canAccess(permissions) ){
event.preventDefault();
console.log('access denied')
$state.go('access_denied');
}
}
});
}]);
//Then define the init function for starting up the application
angular.element(document).ready(function() {
//Fixing facebook bug with redirect

View file

@ -32,28 +32,66 @@ angular.module(ApplicationConfiguration.applicationModuleName).config(['$locatio
$locationProvider.hashPrefix('!');
}
]);
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', '$state', '$stateParams',
function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
//Permission Constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('APP_PERMISSIONS', {
viewAdminSettings: 'viewAdminSettings',
editAdminSettings: 'editAdminSettings',
editForm: 'editForm',
viewPrivateForm: 'viewPrivateForm',
});
//User Role constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('USER_ROLES', {
admin: 'admin',
normal: 'user',
superuser: 'superuser',
});
// add previous state property
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
console.log(fromState);
$state.previous = fromState;
// angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', '$state', '$stateParams',
// function($rootScope, Auth, $state, $stateParams) {
//Redirect home to listForms if user is authenticated
if(toState.name === 'home'){
if($rootScope.authentication.isAuthenticated()){
event.preventDefault(); // stop current execution
$state.go('listForms'); // go to login
}
}
});
// $rootScope.$state = $state;
// $rootScope.$stateParams = $stateParams;
}
]);
// // add previous state property
// $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
// // console.log(fromState);
// $state.previous = fromState;
// //Redirect home to listForms if user is authenticated
// if(toState.name === 'home'){
// if(Auth.isAuthenticated()){
// event.preventDefault(); // stop current execution
// $state.go('listForms'); // go to login
// }
// }
// });
// }
// ]);
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', 'User', 'Authorizer', '$state', '$stateParams',
function($rootScope, Auth, User, Authorizer, $state, $stateParams) {
$rootScope.$on('$stateChangeStart', function(event, next) {
var authenticator, permissions, user;
permissions = next && next.data ? next.data.permissions : null;
Auth.ensureCurrentUser(User);
user = Auth.currentUser;
// if(user){}
authenticator = new Authorizer(user);
if( (permissions !== null) && !authenticator.canAccess(permissions) ){
event.preventDefault();
if (!user) {
$state.go('sigin');
} else {
$state.go('access_denied');
}
}
});
}]);
//Then define the init function for starting up the application
angular.element(document).ready(function() {
@ -71,7 +109,7 @@ ApplicationConfiguration.registerModule('core', ['users']);
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('forms', ['ngFileUpload', 'users']);
ApplicationConfiguration.registerModule('forms', ['ngFileUpload', 'ui.date', 'users']);
'use strict';
// Use Application configuration module to register a new module
@ -454,131 +492,128 @@ angular.module('forms').config(['$stateProvider',
});
}
]);
'use strict';
// 'use strict';
angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
$scope.form = {};
$scope.isNewForm = false;
$scope.log = '';
$scope.pdfLoading = false;
var _current_upload = null;
// angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
// function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
// $scope.form = {};
// $scope.isNewForm = false;
// $scope.log = '';
// $scope.pdfLoading = false;
// var _current_upload = null;
// Get current form if it exists, or create new one
if($stateParams.formId){
Forms.get({ formId: $stateParams.formId}, function(form){
$scope.form = angular.fromJson(angular.toJson(form));
console.log($scope.form);
});
} else {
$scope.form.form_fields = [];
$scope.isNewForm = true;
}
// // Get current form if it exists, or create new one
// if($stateParams.formId){
// Forms.get({ formId: $stateParams.formId}, function(form){
// $scope.form = angular.fromJson(angular.toJson(form));
// console.log($scope.form);
// });
// } else {
// $scope.form.form_fields = [];
// $scope.isNewForm = true;
// }
//PDF Functions
$scope.cancelUpload = function(){
_current_upload.abort();
$scope.pdfLoading = false;
$scope.removePDF();
};
// //PDF Functions
// $scope.cancelUpload = function(){
// _current_upload.abort();
// $scope.pdfLoading = false;
// $scope.removePDF();
// };
$scope.removePDF = function(){
$scope.form.pdf = null;
$scope.form.isGenerated = false;
$scope.form.autofillPDFs = false;
// $scope.removePDF = function(){
// $scope.form.pdf = null;
// $scope.form.isGenerated = false;
// $scope.form.autofillPDFs = false;
console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
};
// console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
// };
$scope.uploadPDF = function(files) {
// $scope.uploadPDF = function(files) {
if (files && files.length) {
// for (var i = 0; i < files.length; i++) {
var file = files[0];
_current_upload = Upload.upload({
url: '/upload/pdf',
fields: {
'user': $scope.user,
'form': $scope.form
},
file: file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
$scope.log = 'progress: ' + progressPercentage + '% ' +
evt.config.file.name + '\n' + $scope.log;
$scope.pdfLoading = true;
}).success(function (data, status, headers, config) {
$scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
console.log($scope.form.pdf);
$scope.form.pdf = angular.fromJson(angular.toJson(data));
$scope.pdfLoading = false;
// if (files && files.length) {
// // for (var i = 0; i < files.length; i++) {
// var file = files[0];
// _current_upload = Upload.upload({
// url: '/upload/pdf',
// fields: {
// 'user': $scope.user,
// 'form': $scope.form
// },
// file: file
// }).progress(function (evt) {
// var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
// $scope.log = 'progress: ' + progressPercentage + '% ' +
// evt.config.file.name + '\n' + $scope.log;
// $scope.pdfLoading = true;
// }).success(function (data, status, headers, config) {
// $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
// console.log($scope.form.pdf);
// $scope.form.pdf = angular.fromJson(angular.toJson(data));
// $scope.pdfLoading = false;
console.log($scope.log);
console.log('$scope.pdf: '+$scope.form.pdf.name);
if(!$scope.$$phase){
$scope.$apply();
}
}).error(function(err){
$scope.pdfLoading = false;
console.log('Error occured during upload.\n');
console.log(err);
});
// }
}
};
// console.log($scope.log);
// console.log('$scope.pdf: '+$scope.form.pdf.name);
// if(!$scope.$$phase){
// $scope.$apply();
// }
// }).error(function(err){
// $scope.pdfLoading = false;
// console.log('Error occured during upload.\n');
// console.log(err);
// });
// // }
// }
// };
$rootScope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
// $rootScope.goToWithId = function(route, id) {
// $state.go(route, {'formId': id}, {reload: true});
// };
// Create new Form
$rootScope.createOrUpdate = function() {
// // Create new Form
// $rootScope.createOrUpdate = function() {
if($scope.isNewForm){
// Create new Form object
var form = new Forms($scope.form);
// if($scope.isNewForm){
// // Create new Form object
// var form = new Forms($scope.form);
$http.post('/forms', {form: $scope.form})
.success(function(data, status, headers){
console.log('form created');
// $http.post('/forms', {form: $scope.form})
// .success(function(data, status, headers){
// console.log('form created');
// Clear form fields
$scope.form = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.form._id);
}).error(function(errorResponse){
console.log(errorResponse);
$scope.error = errorResponse;
});
} else{
$scope.update();
}
};
// // Clear form fields
// $scope.form = {};
// // Redirect after save
// $scope.goToWithId('viewForm', $scope.form._id);
// }).error(function(errorResponse){
// console.log(errorResponse);
// $scope.error = errorResponse;
// });
// } else{
// $scope.update(function(err){
// console.log('done updating');
// });
// }
// };
// Update existing Form
$rootScope.update = function() {
var form = new Forms($scope.form);
console.log('update form');
console.log($scope.form);
// // Update existing Form
// $rootScope.update = function(cb) {
// var form = new Forms($scope.form);
// console.log('update form');
// console.log($scope.form);
$http.put('/forms/'+$scope.form._id, {form: $scope.form})
.success(function(data, status, headers){
console.log('form updated successfully');
$scope.goToWithId('viewForm', $scope.form._id);
}).error(function(err){
console.log('Error occured during form UPDATE.\n');
console.log(err);
});
// form.$update({formId: $scope.form._id}, function(response) {
// console.log('form successfully updated');
// $scope.goToWithId('viewForm', response._id);
// }, function(errorResponse) {
// console.log(errorResponse.data.message);
// $scope.error = errorResponse.data.message;
// });
};
}
]);
// $http.put('/forms/'+$scope.form._id, {form: $scope.form})
// .success(function(data, status, headers){
// console.log('form updated successfully');
// $scope.goToWithId('viewForm', $scope.form._id);
// cb(null);
// }).error(function(err){
// console.log('Error occured during form UPDATE.\n');
// console.log(err);
// cb(err);
// });
// };
// }
// ]);
'use strict';
@ -652,10 +687,30 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
rows: []
};
// Return all user's Forms
$scope.findAll = function() {
$scope.myforms = Forms.query();
};
// Find a specific Form
$scope.findOne = function() {
$scope.myform = Forms.get({
formId: $stateParams.formId
});
CurrentForm.setForm($scope.myform);
};
$scope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
$scope.setForm = function (form) {
$scope.myForm = form;
};
//Modal functions
$scope.openCreateModal = function(){
if(!$scope.showCreateModal){
$scope.showCreateModal = true;
@ -667,53 +722,9 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
}
};
//Create new form
$scope.createNew = function(){
var form = {};
form.title = $scope.myForm.name.$modelValue;
form.language = $scope.myForm.language.$modelValue;
console.log(form);
$scope.showCreateModal = true;
console.log($scope.myForm);
if($scope.myForm.$valid && $scope.myForm.$dirty){
$http.post('/forms', {form: form})
.success(function(data, status, headers){
console.log('form created');
// Clear form fields
$scope.myForm = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.myform._id);
}).error(function(errorResponse){
console.log(errorResponse);
// $scope.error = errorResponse.data.message;
});
}
};
$scope.saveInProgress = false;
$scope.update = function() {
if(!$scope.saveInProgress){
$scope.saveInProgress = true;
console.log('start update()');
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
console.log('form updated successfully');
console.log('$scope.saveInProgress: '+$scope.saveInProgress);
// $rootScope.goToWithId('viewForm', $scope.myform._id);
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
}).finally(function() {
$scope.saveInProgress = false;
});
}
};
//Table Functions
/*
* Table Functions
*/
$scope.toggleAllCheckers = function(){
console.log('toggleAllCheckers');
for(var i=0; i<$scope.table.rows.length; i++){
@ -723,12 +734,11 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
$scope.toggleObjSelection = function($event, description) {
$event.stopPropagation();
console.log('checkbox clicked');
};
$scope.rowClicked = function(obj) {
};
$scope.rowClicked = function(obj) {
console.log('row clicked');
obj.selected = !obj.selected;
};
};
//show submissions of Form
$scope.showSubmissions = function(){
@ -758,24 +768,12 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
}
console.log($scope.submissions);
};
//hide submissions of Form
$scope.hideSubmissions = function(){
$scope.viewSubmissions = false;
};
// Return all user's Forms
$scope.findAll = function() {
$scope.myforms = Forms.query();
};
// Find a specific Form
$scope.findOne = function() {
$scope.myform = Forms.get({
formId: $stateParams.formId
});
CurrentForm.setForm($scope.myform);
};
// Remove existing Form
$scope.remove = function(form_id) {
@ -806,56 +804,55 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
});
};
$scope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
// Create new Form
$rootScope.createOrUpdate = function() {
if($scope.isNewForm){
// Create new Form object
var form = new Forms($scope.myform);
$scope.createNew = function(){
var form = {};
form.title = $scope.myForm.name.$modelValue;
form.language = $scope.myForm.language.$modelValue;
console.log(form);
$scope.showCreateModal = true;
$http.post('/forms', {form: $scope.myform})
console.log($scope.myForm);
if($scope.myForm.$valid && $scope.myForm.$dirty){
$http.post('/forms', {form: form})
.success(function(data, status, headers){
console.log('form created');
// Clear form fields
$scope.myform = {};
$scope.myForm = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.myform._id);
}).error(function(errorResponse){
console.log(errorResponse.data.message);
$scope.error = errorResponse.data.message;
console.log(errorResponse);
// $scope.error = errorResponse.data.message;
});
} else{
$rootScope.update();
}
};
// $rootScope.saveInProgress = false;
var saveFinished = function() {
$rootScope.saveInProgress = false;
console.log('update form');
};
// Update existing Form
$rootScope.update = function() {
$scope.saveInProgress = false;
$scope.update = $rootScope.update = function(cb) {
if(!$scope.saveInProgress){
$scope.saveInProgress = true;
$rootScope.saveInProgress = true;
console.log('update form');
$rootScope.saveInProgress = true;
console.log('begin updating form');
var err = null;
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
console.log('form updated successfully');
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
}).finally(function() {
$rootScope.saveInProgress = false;
console.log('update form');
});
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
console.log('form updated successfully');
console.log(response.status);
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
err = response.data;
}).finally(function() {
console.log('finished updating');
$scope.saveInProgress = false;
cb(err);
});
}
};
$rootScope.resetForm = function(){
@ -872,11 +869,15 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
return {
require: ['^form'],
// scope: {
// callback: '&autoSaveCallback'
// },
link: function($scope, $element, $attrs, $ctrls) {
if(!$rootScope.watchCount === undefined){
if($rootScope.watchCount === undefined){
$rootScope.watchCount = 0;
}
var difference = function(array){
var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
@ -896,7 +897,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
var expression = $attrs.autoSaveForm || 'true';
$scope.$on('ngRepeatStarted', function(ngRepeatFinishedEvent) {
$scope.finishedRender = false;
// $scope.finishedRender = false;
$rootScope.watchCount = 0;
});
$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
@ -904,20 +905,20 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
});
$scope.$watch('myform.form_fields', function(newValue, oldValue) {
console.log('watchCount: '+$rootScope.watchCount);
if(difference(oldValue,newValue).length === 0 || oldValue === undefined){
return;
}
// console.log('\n\n-------\n$pristine: '+( $formCtrl.$pristine ) );
// console.log('$dirty: '+( $formCtrl.$dirty ) );
// console.log('form_fields changed: '+difference(oldValue.form_fields,newValue.form_fields).length );
console.log('\n\n----------\n$dirty: '+( $formCtrl.$dirty ) );
console.log('form_fields changed: '+difference(oldValue,newValue).length );
// console.log('$valid: '+$formCtrl.$valid);
// console.log('finishedRender: '+$scope.finishedRender);
console.log('finishedRender: '+$scope.finishedRender);
// console.log('saveInProgress: '+$scope.saveInProgress);
if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) ) {
$rootScope.watchCount++;
if($rootScope.watchCount === 1) {
if(savePromise) {
@ -927,15 +928,22 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
savePromise = $timeout(function() {
savePromise = null;
// Still valid?
// if($formCtrl.$valid) {
if($scope.$eval(expression) !== false) {
console.log('Form data persisted -- setting pristine flag');
$formCtrl.$setPristine();
}
// }
$rootScope[$attrs.autoSaveCallback](
function(err){
if(!err){
// console.log('Form data persisted -- setting pristine flag');
console.log('\n\n---------\nUpdate form CLIENT');
console.log(Date.now());
$rootScope.watchCount = 0;
$formCtrl.$setPristine();
}else{
console.log('Error form data NOT persisted');
console.log(err);
}
});
});
}
}
@ -1103,7 +1111,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// console.log($scope.addField.types[i].name === fieldType);
if($scope.addField.types[i].name === fieldType){
$scope.addField.types[i].lastAddedID++;
console.log($scope.addField.types[i].lastAddedID);
// console.log($scope.addField.types[i].lastAddedID);
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
break;
}
@ -1118,14 +1126,16 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// put newField into fields array
$scope.myform.form_fields.unshift(newField);
console.log($scope.myform.form_fields.length);
console.log('\n\n---------\nAdded field CLIENT');
console.log(Date.now());
// console.log($scope.myform.form_fields.length);
};
// deletes particular field on button click
$scope.deleteField = function (hashKey){
console.log($scope.myform.form_fields);
// console.log($scope.myform.form_fields);
for(var i = 0; i < $scope.myform.form_fields.length; i++){
console.log($scope.myform.form_fields[i].$$hashKey === hashKey);
// console.log($scope.myform.form_fields[i].$$hashKey === hashKey);
if($scope.myform.form_fields[i].$$hashKey === hashKey){
$scope.myform.form_fields.splice(i, 1);
break;
@ -1230,7 +1240,7 @@ var __indexOf = [].indexOf || function(item) {
};
angular.module('forms').directive('fieldDirective', function($http, $compile) {
var getTemplateUrl = function(field) {
@ -1254,6 +1264,17 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
var linker = function(scope, element) {
scope.field.required = scope.required;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
$scope.dateOptions = {
changeYear: true,
changeMonth: true,
altFormat: "mm/dd/yyyy",
yearRange: '1900:-0',
defaultDate: 0,
};
}
// GET template content from path
var templateUrl = getTemplateUrl(scope.field);
@ -1546,7 +1567,7 @@ angular.module('users').config(['$httpProvider',
};
});
}]);
'use strict';
// Setting up route
angular.module('users').config(['$stateProvider',
@ -1620,7 +1641,7 @@ angular.module('users').config(['$stateProvider',
}).
state('signup-success', {
url: '/signup-success',
templateUrl: 'modules/users/views/authentication/signup.client.view.html'
templateUrl: 'modules/users/views/authentication/signup-success.client.view.html'
}).
state('signin', {
url: '/signin',
@ -1662,14 +1683,12 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
if ($scope.authentication.isAuthenticated()) $state.go('home');
$scope.signin = function() {
// console.log("signin");
// console.log($scope.credentials);
Auth.currentUser = User.login($scope.credentials).then(
function(response) {
Auth.login(response);
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
if($state.previous.name !== 'home'){
if($state.previous.name !== 'home' && $state.previous.name !== ''){
$state.go($state.previous.name);
}else{
$state.go('home');
@ -1687,8 +1706,9 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
};
$scope.signup = function() {
User.save($scope.registration,
function() {
User.signup($scope.credentials).then(
function(response) {
console.log('signup-success');
$state.go('signup-success');
},
function(error) {
@ -1986,6 +2006,39 @@ angular.module('users')
// // };
// }
// ]);
'use strict';
app.service('Authorizer', function(APP_PERMISSIONS, USER_ROLES) {
return function(user) {
return {
canAccess: function(permissions) {
var i, len, permission;
if (!angular.isArray(permissions)) {
permissions = [permissions];
}
for (i = 0, len = permissions.length; i < len; i++) {
permission = permissions[i];
if (APP_PERMISSIONS[permission] === null) {
throw 'Bad permission value';
}
if (user && user.role) {
switch (permission) {
case APP_PERMISSIONS.viewAdminSettings:
case APP_PERMISSIONS.editAdminSettings:
return user.role === USER_ROLES.admin;
case APP_PERMISSIONS.viewPrivateForm:
case APP_PERMISSIONS.editForm:
return user.role === USER_ROLES.admin || user.role === USER_ROLES.normal;
}
} else {
return false;
}
}
return false;
}
};
};
});
// 'use strict';
// angular.module('users').factory('AuthenticationService', function($http, $timeout, $q) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
'use strict';
// Configuring the Articles module
// Configuring the Forms drop-down menus
angular.module('forms').run(['Menus',
function(Menus) {
// Set top bar menu items
@ -30,4 +30,10 @@ angular.module('forms').run(['Menus',
}).length;
return valid_count;
};
});
}).config(['$provide', function ($provide){
$provide.decorator('accordionDirective', function($delegate) {
var directive = $delegate[0];
directive.replace = true;
return $delegate;
});
}]);

View file

@ -17,13 +17,15 @@ angular.module('forms').config(['$stateProvider',
state('viewForm', {
url: '/forms/:formId/admin',
templateUrl: 'modules/forms/views/view-form.client.view.html',
data: {
permissions: [ 'editForm' ]
}
}).
state('viewPublicForm', {
url: '/forms/:formId',
templateUrl: 'modules/forms/views/view-public-form.client.view.html',
data: {
hideNav: true,
hideFooter: false
},
}).
state('editForm', {

View file

@ -1,125 +1,122 @@
'use strict';
// 'use strict';
angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
$scope.form = {};
$scope.isNewForm = false;
$scope.log = '';
$scope.pdfLoading = false;
var _current_upload = null;
// angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
// function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
// $scope.form = {};
// $scope.isNewForm = false;
// $scope.log = '';
// $scope.pdfLoading = false;
// var _current_upload = null;
// Get current form if it exists, or create new one
if($stateParams.formId){
Forms.get({ formId: $stateParams.formId}, function(form){
$scope.form = angular.fromJson(angular.toJson(form));
console.log($scope.form);
});
} else {
$scope.form.form_fields = [];
$scope.isNewForm = true;
}
// // Get current form if it exists, or create new one
// if($stateParams.formId){
// Forms.get({ formId: $stateParams.formId}, function(form){
// $scope.form = angular.fromJson(angular.toJson(form));
// console.log($scope.form);
// });
// } else {
// $scope.form.form_fields = [];
// $scope.isNewForm = true;
// }
//PDF Functions
$scope.cancelUpload = function(){
_current_upload.abort();
$scope.pdfLoading = false;
$scope.removePDF();
};
// //PDF Functions
// $scope.cancelUpload = function(){
// _current_upload.abort();
// $scope.pdfLoading = false;
// $scope.removePDF();
// };
$scope.removePDF = function(){
$scope.form.pdf = null;
$scope.form.isGenerated = false;
$scope.form.autofillPDFs = false;
// $scope.removePDF = function(){
// $scope.form.pdf = null;
// $scope.form.isGenerated = false;
// $scope.form.autofillPDFs = false;
console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
};
// console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
// };
$scope.uploadPDF = function(files) {
// $scope.uploadPDF = function(files) {
if (files && files.length) {
// for (var i = 0; i < files.length; i++) {
var file = files[0];
_current_upload = Upload.upload({
url: '/upload/pdf',
fields: {
'user': $scope.user,
'form': $scope.form
},
file: file
}).progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
$scope.log = 'progress: ' + progressPercentage + '% ' +
evt.config.file.name + '\n' + $scope.log;
$scope.pdfLoading = true;
}).success(function (data, status, headers, config) {
$scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
console.log($scope.form.pdf);
$scope.form.pdf = angular.fromJson(angular.toJson(data));
$scope.pdfLoading = false;
// if (files && files.length) {
// // for (var i = 0; i < files.length; i++) {
// var file = files[0];
// _current_upload = Upload.upload({
// url: '/upload/pdf',
// fields: {
// 'user': $scope.user,
// 'form': $scope.form
// },
// file: file
// }).progress(function (evt) {
// var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
// $scope.log = 'progress: ' + progressPercentage + '% ' +
// evt.config.file.name + '\n' + $scope.log;
// $scope.pdfLoading = true;
// }).success(function (data, status, headers, config) {
// $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
// console.log($scope.form.pdf);
// $scope.form.pdf = angular.fromJson(angular.toJson(data));
// $scope.pdfLoading = false;
console.log($scope.log);
console.log('$scope.pdf: '+$scope.form.pdf.name);
if(!$scope.$$phase){
$scope.$apply();
}
}).error(function(err){
$scope.pdfLoading = false;
console.log('Error occured during upload.\n');
console.log(err);
});
// }
}
};
// console.log($scope.log);
// console.log('$scope.pdf: '+$scope.form.pdf.name);
// if(!$scope.$$phase){
// $scope.$apply();
// }
// }).error(function(err){
// $scope.pdfLoading = false;
// console.log('Error occured during upload.\n');
// console.log(err);
// });
// // }
// }
// };
$rootScope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
// $rootScope.goToWithId = function(route, id) {
// $state.go(route, {'formId': id}, {reload: true});
// };
// Create new Form
$rootScope.createOrUpdate = function() {
// // Create new Form
// $rootScope.createOrUpdate = function() {
if($scope.isNewForm){
// Create new Form object
var form = new Forms($scope.form);
// if($scope.isNewForm){
// // Create new Form object
// var form = new Forms($scope.form);
$http.post('/forms', {form: $scope.form})
.success(function(data, status, headers){
console.log('form created');
// $http.post('/forms', {form: $scope.form})
// .success(function(data, status, headers){
// console.log('form created');
// Clear form fields
$scope.form = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.form._id);
}).error(function(errorResponse){
console.log(errorResponse);
$scope.error = errorResponse;
});
} else{
$scope.update();
}
};
// // Clear form fields
// $scope.form = {};
// // Redirect after save
// $scope.goToWithId('viewForm', $scope.form._id);
// }).error(function(errorResponse){
// console.log(errorResponse);
// $scope.error = errorResponse;
// });
// } else{
// $scope.update(function(err){
// console.log('done updating');
// });
// }
// };
// Update existing Form
$rootScope.update = function() {
var form = new Forms($scope.form);
console.log('update form');
console.log($scope.form);
// // Update existing Form
// $rootScope.update = function(cb) {
// var form = new Forms($scope.form);
// console.log('update form');
// console.log($scope.form);
$http.put('/forms/'+$scope.form._id, {form: $scope.form})
.success(function(data, status, headers){
console.log('form updated successfully');
$scope.goToWithId('viewForm', $scope.form._id);
}).error(function(err){
console.log('Error occured during form UPDATE.\n');
console.log(err);
});
// form.$update({formId: $scope.form._id}, function(response) {
// console.log('form successfully updated');
// $scope.goToWithId('viewForm', response._id);
// }, function(errorResponse) {
// console.log(errorResponse.data.message);
// $scope.error = errorResponse.data.message;
// });
};
}
]);
// $http.put('/forms/'+$scope.form._id, {form: $scope.form})
// .success(function(data, status, headers){
// console.log('form updated successfully');
// $scope.goToWithId('viewForm', $scope.form._id);
// cb(null);
// }).error(function(err){
// console.log('Error occured during form UPDATE.\n');
// console.log(err);
// cb(err);
// });
// };
// }
// ]);

View file

@ -14,10 +14,30 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
rows: []
};
// Return all user's Forms
$scope.findAll = function() {
$scope.myforms = Forms.query();
};
// Find a specific Form
$scope.findOne = function() {
$scope.myform = Forms.get({
formId: $stateParams.formId
});
CurrentForm.setForm($scope.myform);
};
$scope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
$scope.setForm = function (form) {
$scope.myForm = form;
};
//Modal functions
$scope.openCreateModal = function(){
if(!$scope.showCreateModal){
$scope.showCreateModal = true;
@ -29,53 +49,9 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
}
};
//Create new form
$scope.createNew = function(){
var form = {};
form.title = $scope.myForm.name.$modelValue;
form.language = $scope.myForm.language.$modelValue;
console.log(form);
$scope.showCreateModal = true;
console.log($scope.myForm);
if($scope.myForm.$valid && $scope.myForm.$dirty){
$http.post('/forms', {form: form})
.success(function(data, status, headers){
console.log('form created');
// Clear form fields
$scope.myForm = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.myform._id);
}).error(function(errorResponse){
console.log(errorResponse);
// $scope.error = errorResponse.data.message;
});
}
};
$scope.saveInProgress = false;
$scope.update = function() {
if(!$scope.saveInProgress){
$scope.saveInProgress = true;
console.log('start update()');
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
console.log('form updated successfully');
console.log('$scope.saveInProgress: '+$scope.saveInProgress);
// $rootScope.goToWithId('viewForm', $scope.myform._id);
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
}).finally(function() {
$scope.saveInProgress = false;
});
}
};
//Table Functions
/*
* Table Functions
*/
$scope.toggleAllCheckers = function(){
console.log('toggleAllCheckers');
for(var i=0; i<$scope.table.rows.length; i++){
@ -85,59 +61,72 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
$scope.toggleObjSelection = function($event, description) {
$event.stopPropagation();
console.log('checkbox clicked');
};
$scope.rowClicked = function(obj) {
console.log('row clicked');
};
$scope.rowClicked = function(obj) {
// console.log('row clicked');
obj.selected = !obj.selected;
};
};
//show submissions of Form
$scope.showSubmissions = function(){
$scope.viewSubmissions = true;
if(!$scope.table.rows.length){
$http.get('/forms/'+$scope.myform._id+'/submissions')
.success(function(data, status, headers){
console.log(data);
$scope.submissions = data;
$scope.table.rows = data;
console.log('form submissions successfully fetched');
})
.error(function(err){
console.log('Could not fetch form submissions.\nError: '+err);
});
} else if(!$scope.submissions.length){
$http.get('/forms/'+$scope.myform._id+'/submissions')
.success(function(data, status, headers){
$scope.submissions = data;
$scope.table.rows = data;
console.log($scope.table.rows);
console.log('form submissions successfully fetched');
})
.error(function(err){
console.log('Could not fetch form submissions.\nError: '+err);
});
}
console.log($scope.submissions);
};
$http.get('/forms/'+$scope.myform._id+'/submissions')
.success(function(data, status, headers){
console.log(data[0].form_fields);
var _data = Array();
for(var i=0; i<data.length; i++){
var _tmpSubFormFields = JSON.parse(JSON.stringify($scope.myform.form_fields));
for(var x=0; x<_tmpSubFormFields.length; x++){
var currField__id = _tmpSubFormFields[x]._id,
currField = undefined;
_.find(data[i].form_fields, function(fieldItem, fieldIdx){
if(fieldItem._id === currField__id){
currField = fieldItem;
console.log(fieldItem.fieldValue);
return true;
};
});
if(currField !== undefined){
_tmpSubFormFields[x].fieldValue = currField.fieldValue;
_tmpSubFormFields[x].$$hashKey = currField.$$hashKey;
}else {
_tmpSubFormFields[x].fieldValue = '';
}
}
// _tmpSubFormFields.order = i;
_data[i] = data[i];
_data[i].form_fields = _tmpSubFormFields;
};
console.log(JSON.stringify(_data));
$scope.submissions = _data;
$scope.table.rows = _data;
// console.log('form submissions successfully fetched');
// console.log( JSON.parse(JSON.stringify($scope.submissions)) ) ;
// console.log( JSON.parse(JSON.stringify($scope.myform.form_fields)) );
})
.error(function(err){
console.log('Could not fetch form submissions.\nError: '+err);
});
};
//hide submissions of Form
$scope.hideSubmissions = function(){
$scope.viewSubmissions = false;
};
// Return all user's Forms
$scope.findAll = function() {
$scope.myforms = Forms.query();
};
// Find a specific Form
$scope.findOne = function() {
$scope.myform = Forms.get({
formId: $stateParams.formId
});
CurrentForm.setForm($scope.myform);
};
// Remove existing Form
$scope.remove = function(form_id) {
@ -168,56 +157,55 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
});
};
$scope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
// Create new Form
$rootScope.createOrUpdate = function() {
if($scope.isNewForm){
// Create new Form object
var form = new Forms($scope.myform);
$scope.createNew = function(){
var form = {};
form.title = $scope.myForm.name.$modelValue;
form.language = $scope.myForm.language.$modelValue;
console.log(form);
$scope.showCreateModal = true;
$http.post('/forms', {form: $scope.myform})
console.log($scope.myForm);
if($scope.myForm.$valid && $scope.myForm.$dirty){
$http.post('/forms', {form: form})
.success(function(data, status, headers){
console.log('form created');
// Clear form fields
$scope.myform = {};
$scope.myForm = {};
// Redirect after save
$scope.goToWithId('viewForm', $scope.myform._id);
}).error(function(errorResponse){
console.log(errorResponse.data.message);
$scope.error = errorResponse.data.message;
console.log(errorResponse);
// $scope.error = errorResponse.data.message;
});
} else{
$rootScope.update();
}
};
// $rootScope.saveInProgress = false;
var saveFinished = function() {
$rootScope.saveInProgress = false;
console.log('update form');
};
// Update existing Form
$rootScope.update = function() {
$scope.saveInProgress = false;
$scope.update = $rootScope.update = function(cb) {
if(!$scope.saveInProgress){
$scope.saveInProgress = true;
$rootScope.saveInProgress = true;
console.log('update form');
$rootScope.saveInProgress = true;
// console.log('begin updating form');
var err = null;
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
console.log('form updated successfully');
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
}).finally(function() {
$rootScope.saveInProgress = false;
console.log('update form');
});
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
.then(function(response){
// console.log('form updated successfully');
// console.log(response.status);
}).catch(function(response){
console.log('Error occured during form UPDATE.\n');
console.log(response.data);
err = response.data;
}).finally(function() {
// console.log('finished updating');
$scope.saveInProgress = false;
cb(err);
});
}
};
$rootScope.resetForm = function(){

View file

@ -1,3 +1,7 @@
.btn {
border: 1px solid #c6c6c6!important;
}
/* Styles for form submission view (/forms/:formID) */
form .row.field {
padding: 1em 0 3em 0;
@ -14,14 +18,28 @@ form .row.field {
color:#ddd;
}
form.submission-form .row.field > .field-input input {
width:500px;
width:100%;
}
form.submission-form .row.field .field-input > input:focus {
font-size:1em;
}
form .row.field.textfield > .field-input > input{
padding:0.45em 0.9em;
width:600px;
width:100%;
line-height:160%;
}
form .row.field.dropdown > .field-input {
height: 34px;
overflow: hidden;
}
form .row.field.dropdown > .field-input > select{
padding:0.45em 0.9em;
width:100%;
background: transparent;
font-size: 16px;
border: 1px solid #ccc;
height: 34px;
}
div.config-form > .row {

View file

@ -4,16 +4,20 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
return {
require: ['^form'],
// scope: {
// callback: '&autoSaveCallback'
// },
link: function($scope, $element, $attrs, $ctrls) {
if(!$rootScope.watchCount === undefined){
if($rootScope.watchCount === undefined){
$rootScope.watchCount = 0;
}
var difference = function(array){
var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
var containsEquals = function(obj, target) {
if (obj == null) return false;
if (obj === null) return false;
return _.any(obj, function(value) {
return _.isEqual(value, target);
});
@ -28,7 +32,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
var expression = $attrs.autoSaveForm || 'true';
$scope.$on('ngRepeatStarted', function(ngRepeatFinishedEvent) {
$scope.finishedRender = false;
// $scope.finishedRender = false;
$rootScope.watchCount = 0;
});
$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
@ -36,20 +40,20 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
});
$scope.$watch('myform.form_fields', function(newValue, oldValue) {
// console.log('watchCount: '+$rootScope.watchCount);
if(difference(oldValue,newValue).length === 0 || oldValue === undefined){
return;
}
// console.log('\n\n-------\n$pristine: '+( $formCtrl.$pristine ) );
// console.log('$dirty: '+( $formCtrl.$dirty ) );
// console.log('form_fields changed: '+difference(oldValue.form_fields,newValue.form_fields).length );
// console.log('\n\n----------\n$dirty: '+( $formCtrl.$dirty ) );
// console.log('form_fields changed: '+difference(oldValue,newValue).length );
// console.log('$valid: '+$formCtrl.$valid);
// console.log('finishedRender: '+$scope.finishedRender);
// console.log('saveInProgress: '+$scope.saveInProgress);
if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) ) {
$rootScope.watchCount++;
if($rootScope.watchCount === 1) {
if(savePromise) {
@ -59,15 +63,22 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
savePromise = $timeout(function() {
savePromise = null;
// Still valid?
// if($formCtrl.$valid) {
if($scope.$eval(expression) !== false) {
console.log('Form data persisted -- setting pristine flag');
$formCtrl.$setPristine();
}
// }
$rootScope[$attrs.autoSaveCallback](
function(err){
if(!err){
console.log('Form data persisted -- setting pristine flag');
console.log('\n\n---------\nUpdate form CLIENT');
console.log(Date.now());
$rootScope.watchCount = 0;
$formCtrl.$setPristine();
}else{
console.log('Error form data NOT persisted');
console.log(err);
}
});
});
}
}

View file

@ -7,9 +7,10 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
$scope.log = '';
$scope.pdfLoading = false;
$scope.languages = $rootScope.languages;
var _current_upload = null;
$scope.createOrUpdate = $rootScope.createOrUpdate;
$scope.resetForm = $rootScope.resetForm;
$scope.update = $rootScope.update;
var _unbindedPdfFields = $scope.pdfFields;

View file

@ -13,6 +13,58 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
//Populate local scope with rootScope methods/variables
$scope.update = $rootScope.update;
/*
** FormFields (ui-sortable) drag-and-drop configuration
*/
$scope.dropzone = {
handle: ' .handle'
}
// $scope.draggable = {
// connectWith: ".dropzone",
// start: function (e, ui) {
// // $scope.$apply(function() {
// // $scope.dragging = true
// // });
// $('.dropzone').sortable('refresh');
// },
// update: function (e, ui) {
// var isInDropzone = $(e.target).parentsUntil('.panel-group').hasClass('dropzone');
// console.log('isInDropzone: '+isInDropzone);
// //Disable drag and drop if we aren't in dropzone
// if(!isInDropzone){
// ui.item.sortable.cancel();
// }
// },
// stop: function (e, ui) {
// var isInDropzone = $(e.target).parentsUntil('.panel-group').hasClass('dropzone');
// //Disable drag and drop if we aren't in dropzone
// if(isInDropzone){
// console.log($(e.target));
// }
// // if (ui.item.sortable.droptarget === undefined) {
// // $scope.$apply($scope.dragging = false);
// // return;
// // }else if (ui.item.sortable.droptarget[0].classList[0] === "dropzone") {
// // // run code when item is dropped in the dropzone
// // $scope.$apply($scope.dragging = false);
// // }else{
// // // $scope.$apply($scope.dragging = false);
// // }
// // console.log('has class .dropzone :'+);
// // if ($(e.target).hasClass('dropzone') && ui.item.sortable.droptarget && e.target != ui.item.sortable.droptarget[0] ) {
// // // restore original types
// // $scope.addField.types = FormFields.fields;
// // }
// }
// };
//Populate AddField with all available form field types
$scope.addField = {};
$scope.addField.types = FormFields.fields;
@ -37,7 +89,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// console.log($scope.addField.types[i].name === fieldType);
if($scope.addField.types[i].name === fieldType){
$scope.addField.types[i].lastAddedID++;
console.log($scope.addField.types[i].lastAddedID);
// console.log($scope.addField.types[i].lastAddedID);
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
break;
}
@ -52,14 +104,16 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// put newField into fields array
$scope.myform.form_fields.unshift(newField);
console.log($scope.myform.form_fields.length);
console.log('\n\n---------\nAdded field CLIENT');
console.log(Date.now());
// console.log($scope.myform.form_fields.length);
};
// deletes particular field on button click
$scope.deleteField = function (hashKey){
console.log($scope.myform.form_fields);
// console.log($scope.myform.form_fields);
for(var i = 0; i < $scope.myform.form_fields.length; i++){
console.log($scope.myform.form_fields[i].$$hashKey === hashKey);
// console.log($scope.myform.form_fields[i].$$hashKey === hashKey);
if($scope.myform.form_fields[i].$$hashKey === hashKey){
$scope.myform.form_fields.splice(i, 1);
break;
@ -77,13 +131,12 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// add new option to the field
$scope.addOption = function (field){
if(!field.field_options)
field.field_options = [];
if(!field.fieldOptions) field.fieldOptions = [];
var lastOptionID = 0;
if(field.field_options[field.field_options.length-1])
lastOptionID = field.field_options[field.field_options.length-1].option_id;
if(field.fieldOptions[field.fieldOptions.length-1])
lastOptionID = field.fieldOptions[field.fieldOptions.length-1].option_id;
// new option's id
var option_id = lastOptionID + 1;
@ -94,15 +147,15 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
'option_value' : option_id
};
// put new option into field_options array
field.field_options.push(newOption);
// put new option into fieldOptions array
field.fieldOptions.push(newOption);
};
// delete particular option
$scope.deleteOption = function (field, option){
for(var i = 0; i < field.field_options.length; i++){
if(field.field_options[i].option_id === option.option_id){
field.field_options.splice(i, 1);
for(var i = 0; i < field.fieldOptions.length; i++){
if(field.fieldOptions[i].option_id === option.option_id){
field.fieldOptions.splice(i, 1);
break;
}
}
@ -110,10 +163,11 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showAddOptions = function (field){
if(field.fieldType == 'dropdown' || field.fieldType == 'checkbox' || field.fieldType == 'scale' || field.fieldType == 'rating' || field.fieldType == 'radio')
if(field.fieldType === 'dropdown' || field.fieldType === 'checkbox' || field.fieldType === 'scale' || field.fieldType === 'rating' || field.fieldType === 'radio'){
return true;
else
} else {
return false;
}
};
},

View file

@ -10,20 +10,20 @@ angular.module('forms').directive('fieldIconDirective', function($http, $compile
},
controller: function($scope){
var iconTypeMap = {
"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",
'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',
}
$scope.typeIcon = iconTypeMap[$scope.typeName];
},

View file

@ -9,7 +9,7 @@ var __indexOf = [].indexOf || function(item) {
};
angular.module('forms').directive('fieldDirective', function($http, $compile) {
var getTemplateUrl = function(field) {
@ -33,6 +33,17 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
var linker = function(scope, element) {
scope.field.required = scope.required;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
scope.dateOptions = {
changeYear: true,
changeMonth: true,
altFormat: "mm/dd/yyyy",
yearRange: '1900:-0',
defaultDate: 0,
};
}
// GET template content from path
var templateUrl = getTemplateUrl(scope.field);

View file

@ -4,5 +4,5 @@ angular.module('forms').directive('formLocator', function() {
link: function(scope) {
scope.$emit('formLocator');
}
}
};
});

View file

@ -29,6 +29,10 @@ angular.module('forms').directive('formDirective', ['$http', '$timeout', 'timeCo
alert('Form canceled..');
};
$scope.reloadForm = function(){
$scope.form.submitted = false;
}
},
templateUrl: './modules/forms/views/directiveViews/form/form.html',
restrict: 'E',

View file

@ -16,5 +16,5 @@ angular.module('forms').directive('onFinishRender', function ($rootScope, $timeo
}, 500);
}
}
}
};
});

View file

@ -1,4 +1,4 @@
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('forms', ['ngFileUpload', 'users']);
ApplicationConfiguration.registerModule('forms', ['ngFileUpload', 'ui.date', 'ui.sortable', 'users']);

View file

@ -1,231 +0,0 @@
<link rel="stylesheet" href="./modules/forms/css/form.css">
<section data-ng-controller="EditFormController">
<div ng-if="isNewForm">
<h1>Create your form</h1> <br>
<blockquote>
<p>Select field type you want to add to the form below and click on 'Add Field' button. Don't forget to set field properties. After you finish creating the form, you can preview the form by clicking Preview Form button.</p>
</blockquote>
</div>
<div ng-if="!isNewForm">
<h2>Edit your form</h2> <br>
</div>
<div class="well">
<div class="form-fields" ng-hide="previewMode">
<div class="form-properties row">
<div class="col-sm-12"><h3>Form Title</h3></div>
</div>
<div class="row">
<div class="col-sm-4"><p style="margin-top:20px;"><input type="text" name="form-name" ng-disabled="previewMode" ng-model="form.title" style="width:200px; height:30px;"></p></div>
</div>
<div class="row">
<div class="col-sm-12">
<h3>Fields</h3>
</div>
</div>
<div class="row">
<div class="add-field col-md-3 col-sm-12">
<select ng-model="addField.new" ng-options="type.name as type.value for type in addField.types"></select>
<button type="submit" class="btn" ng-click="addNewField()">
<i class="icon-plus"></i> Add Field
</button>
</div>
<div class="col-sm-3 col-md-8 col-md-offset-1">
<p ng-show="form.form_fields.length == 0">No fields added yet.</p>
<accordion close-others="accordion.oneAtATime">
<accordion-group heading="{{field.title}}" ng-repeat="field in form.form_fields">
<div class="accordion-edit">
<button class="btn btn-danger pull-right" type="button" ng-click="deleteField(field.client_id)"><i class="icon-trash icon-white"></i> Delete</button>
<div class="row">
<div class="col-xs-2">Field ID: </div>
<div class="col-xs-4">{{field.client_id}}</div>
</div>
<div class="row">
<div class="col-xs-2">Field Type:</div>
<div class="col-xs-4">{{field.fieldType}}</div>
</div>
<div class="clear"></div> <hr>
<div class="row">
<div class="col-xs-2">Field Title:</div>
<div class="col-xs-4"><input type="text" ng-model="field.title" value="{{field.title}}"></div>
</div>
<div class="row">
<div class="col-xs-2">Field Default Value:</div>
<div class="col-xs-4"><input type="text" ng-model="field.fieldValue" value="{{field.fieldValue}}"></div>
</div>
<div class="row" ng-show="showAddOptions(field)">
<div class="col-xs-2">Field Options:</div>
<div class="col-xs-6">
<div ng-repeat="option in field.field_options">
<input type="text" ng-model="option.option_title" value="{{option.option_title}}">
<a class="btn btn-danger btn-mini right" type="button" ng-click="deleteOption(field, option)"><i class="icon-minus icon-white"></i></a>
<span class="label label-inverse">Value: {{ option.option_value }}</span>
</div>
<button class="btn btn-primary btn-small" type="button" ng-click="addOption(field)"><i class="icon-plus icon-white"></i> Add Option</button>
</div>
</div>
<div class="clear"></div> <hr>
<div class="row">
<div class="col-xs-2">Required:</div>
<div class="col-xs-4">
<label>
<input type="radio" ng-value="true" ng-selected ng-model="field.required"/>
&nbsp; Yes
</label>
<label>
<input type="radio" ng-value="false" ng-model="field.required"/>
&nbsp; No
</label>
</div>
</div>
<div class="clear"></div> <hr>
<div class="row">
<div class="col-xs-2">Disabled:</div>
<div class="col-xs-4">
<label>
<input type="radio" ng-value="true" ng-selected ng-model="field.disabled"/>
&nbsp; Yes
</label>
<label>
<input type="radio" ng-value="false" ng-model="field.disabled"/>
&nbsp; No
</label>
</div>
</div>
</div>
</accordion-group>
</accordion>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h3>Form PDF</h3>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h5>Upload your PDF</h5>
</div>
<div class="col-sm-12">
<div class="input-group ">
<div tabindex="-1" class="form-control file-caption">
<span class="file-caption-ellipsis" ng-if="!form.pdf"></span>
<div class="file-caption-name" ng-if="form.pdf">
{{form.pdf.originalname}}
</div>
</div>
<div class="input-group-btn">
<button type="button" ng-if="form.pdf" ng-click="removePDF();" title="Clear selected files" class="btn btn-danger fileinput-remove fileinput-remove-button">
<i class="glyphicon glyphicon-trash" ></i>
Delete
</button>
<button type="button" ng-if="pdfLoading" title="Abort ongoing upload" class="btn btn-default" ng-click="cancelUpload()">
<i class="glyphicon glyphicon-ban-circle"></i>
Cancel
</button>
<div class="btn btn-success btn-file" ngf-select ngf-change="uploadPDF($files)" ng-if="!form.pdf">
<i class="glyphicon glyphicon-upload"></i>
Upload your PDF
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h5>Autogenerate Form?</h5>
</div>
<br><br>
<div class="col-sm-4">
<label>
<input type="radio" data-ng-value="true" ng-model="form.isGenerated" ng-required="true" />
&nbsp;<span>Yes</span>
</label>
<label>
<input type="radio" data-ng-value="false" ng-model="form.isGenerated" ng-required="true" />
&nbsp;<span>No</span>
</label>
<!-- <span class="required-error" ng-show="field.required && !field.fieldValue">* required</span> -->
</div>
</div>
<div class="row" ng-if="form.isGenerated">
<div class="col-sm-12">
<h5>Save Submissions as PDFs?</h5>
</div>
<br><br>
<div class="col-sm-4">
<label>
<input type="radio" data-ng-value="true" ng-model="form.autofillPDFs" ng-required="true" />
&nbsp;<span>Yes</span>
</label>
<label>
<input type="radio" data-ng-value="false" ng-model="form.autofillPDFs" ng-required="true" />
&nbsp;<span>No</span>
</label>
<!-- <span class="required-error" ng-show="field.required && !field.fieldValue">* required</span> -->
</div>
</div>
<br><br>
<div class="row">
<div class="col-sm-offset-3 col-sm-2">
<button class="btn btn-primary btn-large" type="button" ng-click="createOrUpdate()"><i class="icon-arrow-left icon-white"></i> Save Changes</button>
</div>
<div class="col-sm-1">
<button class="btn btn-primary" type="button" ng-data-href="#!/forms/{{form._id}}/admin"><i class="icon-eye-open icon-white"></i> Cancel</button>
</div>
<div class="col-sm-1 col-sm-offset-1">
<button class="btn btn-secondary" type="button" ng-click="previewOn()"><i class="icon-eye-open icon-white"></i> Preview Form</button>
</div>
</div>
<br><hr>
<!-- <div class="text-center">
<a class="btn btn-small btn-primary" ng-show="!showJson" ng-click="showJson = true">Show form json object</a>
<a class="btn btn-small btn-inverse" ng-show="showJson" ng-click="showJson = false">Hide form json object</a><br><br>
</div>
<div ng-show="showJson">
<h4>Form object content:</h4>
<pre>{{ form | json }}</pre>
</div> -->
</div>
<div class="form-fields-preview" ng-show="previewMode">
<form-directive form="previewForm"></form-directive>
<p class="text-center">
<button class="btn btn-primary btn-large right" type="button" ng-click="previewOff()"><i class="icon-arrow-left icon-white"></i> Back to Create Mode</button>
</p>
</div>
</div>
</section>

View file

@ -3,7 +3,7 @@
<span class="required-error" ng-show="field.required && !field.fieldValue">* required </span>
<div class="col-xs-7 field-input">
<div class="control-group input-append">
<input type="text" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" data-date-format="mm/dd/yyyy" bs-datepicker ng-required="field.required" ng-disabled="field.disabled">
<input ui-date="dateOptions" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled">
<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>
</div>
</div>

View file

@ -1,8 +1,8 @@
<div class="field row">
<div class="col-xs-7 field-title">{{field.title}} </div>
<div class="col-xs-5 field-input">
<div class="field row dropdown">
<div class="col-xs-5 field-title">{{field.title}} </div>
<div class="col-xs-7 field-input ">
<select ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled">
<option ng-repeat="option in field.field_options"
<option ng-repeat="option in field.fieldOptions"
ng-selected="option.option_value == field.fieldValue"
value="{{option.option_id}}">
{{option.option_title}}

View file

@ -1,7 +1,7 @@
<div class="field row">
<div class="col-xs-5 field-title">{{field.title}} </div>
<div class="col-xs-7 field-input">
<div ng-repeat="option in field.field_options" class="row-fluid">
<div ng-repeat="option in field.fieldOptions" class="row-fluid">
<label>
<input type="radio" value="{{option.option_value}}" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled"/>
&nbsp;<span ng-bind="option.option_title"></span>

View file

@ -180,7 +180,7 @@
</div>
<div class="row">
<div class="col-sm-offset-4 col-sm-2">
<button class="btn btn-primary btn-large" type="button" ng-click="createOrUpdate()"><i class="icon-arrow-left icon-white"></i> Save Changes</button>
<button class="btn btn-primary btn-large" type="button" ng-click="update()"><i class="icon-arrow-left icon-white"></i> Save Changes</button>
</div>
<div class="col-sm-1">
<button class="btn btn-primary" type="button" ng-click="resetForm()"><i class="icon-eye-open icon-white"></i> Cancel</button>

View file

@ -1,4 +1,5 @@
<form class="row" name="fieldForm" form-locator auto-save-form="update()" form="myform" novalidation>
<form class="row" name="fieldForm" form-locator auto-save-form auto-save-callback="update" form="myform" novalidation>
<div class="col-xs-5 add-field">
<!-- <select ng-model="addField.new" ng-options="type.name as type.value for type in addField.types"></select>
<button type="submit" class="btn" ng-click="addNewField()">
@ -8,7 +9,7 @@
<h3 class="col-xs-12">Add New Field</h3>
<span ng-if="form.$dirty && form.$valid" class="help-block">Updating ...</span>
</div>
<div class="panel-group row">
<div class="panel-group row" class="draggable" ng-model="addField.types">
<div class="col-xs-6" ng-repeat="type in addField.types" on-finish-render>
<div class="panel panel-default" style="background-color:#f5f5f5;">
<div class="panel-heading" ng-click="addNewField(type.name)" style="cursor: pointer; font-size:14px;">
@ -27,23 +28,26 @@
<!-- <p ng-show="form.form_fields.length == 0">No fields added yet.</p> -->
<div class="row">
<div class="col-xs-10">
<accordion close-others="accordion.oneAtATime">
<accordion close-others="accordion.oneAtATime" ui-sortable="dropzone" ng-model="myform.form_fields" class="dropzone">
<accordion-group ng-repeat="field in myform.form_fields" is-open="accordion[$index].isOpen" on-finish-render="setFormValid()">
<accordion-heading>
<span class="pull-left" ng-switch="field.fieldType">
<field-icon-directive type-name="{{field.fieldType}}"></field-icon-directive>
</span>
<span style="padding-left:1.2em;">{{field.title}}</span>
<span class="pull-right">
<i class="fa fa-chevron-right" ng-hide="accordion[$index].isOpen">
</i>
<i class="fa fa-chevron-down" ng-show="accordion[$index].isOpen">
</i>
</span>
<div class="handle">
<span class="pull-left" ng-switch="field.fieldType">
<field-icon-directive type-name="{{field.fieldType}}"></field-icon-directive>
</span>
<span style="padding-left:1.2em;">{{field.title}}</span>
<span class="pull-right">
<i class="fa fa-chevron-right" ng-hide="accordion[$index].isOpen">
</i>
<i class="fa fa-chevron-down" ng-show="accordion[$index].isOpen">
</i>
</span>
</div>
</accordion-heading>
<div class="accordion-edit container">
<!-- <button class="btn btn-danger pull-right" type="button" ng-click="deleteField(field.client_id)"><i class="icon-trash icon-white"></i> Delete</button> -->
<div class="row">
<div class="col-xs-12">
<h4>Preview</h4>
@ -55,7 +59,9 @@
</field-directive>
</ul>
</div>
<div class="clear"></div> <hr>
<div class="row">
<div class="col-xs-2">Field Type:</div>
<div class="col-xs-4">{{field.fieldType}}</div>
@ -69,7 +75,7 @@
<div class="row" ng-show="showAddOptions(field)">
<div class="col-xs-2">Field Options:</div>
<div class="col-xs-6 container">
<div ng-repeat="option in field.field_options" class="row">
<div ng-repeat="option in field.fieldOptions" class="row">
<input type="text" name="{{option.option_title}}" ng-model="option.option_title" value="{{option.option_title}}" class="col-xs-4">
<a class="btn btn-danger btn-mini right" type="button" ng-click="deleteOption(field, option)" class="col-xs-3"><i class="fa fa-trash-o"></i></a>
@ -114,6 +120,7 @@
</div>
</accordion-group>
<div class="panel panel-default" style="border-style: dashed; border-color: #a9a9a9;">
<div class="panel-heading">
<h4 class="panel-title text-center" style="color: #a9a9a9;">
@ -121,6 +128,7 @@
</h4>
</div>
</div>
</accordion>
</div>
<div class="col-xs-1" style="padding:0 5px;" >

View file

@ -41,7 +41,7 @@
<div class="row form-actions">
<p class="text-center col-xs-3 col-xs-offset-4">
<button class="btn btn-success left" type="button">
<a href="/#!/forms/{{form._id}}" style="color:white;"> Submit again?</a>
<a href="#" ng-click="reloadForm()" style="color:white;"> Submit again?</a>
</button>
</p>
<p class="text-center col-xs-2" ng-if="authentication.isAuthenticated()">

View file

@ -10,7 +10,7 @@
</div>
<div class="col-xs-2">
<small class=" pull-right">
<a class="btn btn-default" href="/#!/forms/{{form._id}}">
<a class="btn btn-default" href="/#!/forms/{{myform._id}}">
<span ng-show="myform.isLive">View Live</span> <span ng-hide="myform.isLive">Preview</span> Form
<i class="status-light status-light-on fa fa-dot-circle-o" ng-show="myform.isLive"></i>
<i class="status-light status-light-off fa fa-dot-circle-o" ng-hide="myform.isLive"></i>
@ -53,7 +53,7 @@
<input ng-model="table.masterChecker" ng-change="toggleAllCheckers()" type="checkbox"/>
</th>
<th>#</th>
<th data-ng-repeat="(key, value) in submissions[0].form_fields">
<th data-ng-repeat="(key, value) in myform.form_fields">
{{value.title}}
</th>
<th>
@ -70,7 +70,7 @@
<tbody>
<tr data-ng-repeat="row in table.rows" ng-click="rowClicked(row)">
<td>
<!-- <input ng-model="row.selected" type="checkbox"/> -->
<input ng-model="row.selected" type="checkbox"/>
</td>
<th class="scope">{{$index+1}}</th>
<td data-ng-repeat="(key, value) in row.form_fields">

View file

@ -72,7 +72,7 @@ angular.module('users').config(['$stateProvider',
}).
state('signup-success', {
url: '/signup-success',
templateUrl: 'modules/users/views/authentication/signup.client.view.html'
templateUrl: 'modules/users/views/authentication/signup-success.client.view.html'
}).
state('signin', {
url: '/signin',

View file

@ -11,14 +11,12 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
if ($scope.authentication.isAuthenticated()) $state.go('home');
$scope.signin = function() {
// console.log("signin");
// console.log($scope.credentials);
Auth.currentUser = User.login($scope.credentials).then(
function(response) {
Auth.login(response);
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
if($state.previous.name !== 'home'){
if($state.previous.name !== 'home' && $state.previous.name !== ''){
$state.go($state.previous.name);
}else{
$state.go('home');
@ -36,8 +34,9 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
};
$scope.signup = function() {
User.save($scope.registration,
function() {
User.signup($scope.credentials).then(
function(response) {
console.log('signup-success');
$state.go('signup-success');
},
function(error) {

View file

@ -27,6 +27,6 @@ section.auth {
padding-bottom: 0.5em;
}
section.auth.signup-view.success > h3 {
/* section.auth.signup-view.success > h3 {
padding-bottom: 1.2em;
}
}*/

View file

@ -0,0 +1,34 @@
'use strict';
angular.module('users').service('Authorizer', function(APP_PERMISSIONS, USER_ROLES) {
return function(user) {
return {
canAccess: function(permissions) {
var i, len, permission;
if (!angular.isArray(permissions)) {
permissions = [permissions];
}
for (i = 0, len = permissions.length; i < len; i++) {
permission = permissions[i];
if (APP_PERMISSIONS[permission] === null) {
throw 'Bad permission value';
}
if (user && user.roles) {
switch (permission) {
case APP_PERMISSIONS.viewAdminSettings:
case APP_PERMISSIONS.editAdminSettings:
return user.roles.indexOf(USER_ROLES.admin) > -1;
case APP_PERMISSIONS.viewPrivateForm:
case APP_PERMISSIONS.editForm:
return user.roles.indexOf(USER_ROLES.admin) > -1 || user.roles.indexOf(USER_ROLES.normal) > -1;
}
} else {
return false;
}
}
return false;
}
};
};
});

View file

@ -1,8 +1,62 @@
'use strict';
(function() {
// Principal controller Spec for E2E Tests
describe('AuthenticationController E2E Tests', function() {
describe('/signup should work for a unique username', function() {
beforeEach(function() {
var ptor = protractor.getInstance();
ptor.get('http://localhost:3000/#!/signup');
});
it('should show the signup panel on page load', function() {
expect($('section > section.row.auth > .col-md-12.text-center')).toEqual('Signup with your email');
});
//Jasmine it statement : What "it" will do.
it('Verify that the user is logged in', function() {
//Delete all cookies
browser.driver.manage().deleteAllCookies();
//Enter UserName
element.all(by.model('username')).get(0).sendKeys('abc@wingify.com');
//Enter Password
element(by.model('password')).sendKeys('test');
//Click Submit button
element(by.css('.login-form button[type="submit"]')).click();
//Wait for the current URL to change to welcome
browser.driver.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return (/welcome/).test(url);
});
});
var firstname = element(by.model('credentials.firstname')),
lastname = element(by.model('credentials.lastname')),
email = element(by.model('credentials.email')),
password = element(by.model('credentials.password')),
username = element(by.model('credentials.username'));
email.sendKeys('admin@app.com');
username.sendKeys('admin');
firstname.sendKeys('admin_first');
firstname.sendKeys('admin_last');
password.sendKeys('1234');
//Click signup button
element(by.css('.btn.btn-large.btn-primary')).click().then(function () {
expect(browser.getCurrentUrl()).toEqual('http://localhost:3000/#!/signup-success');
});
});
});
});
// Principal controller Spec
describe('AuthenticationController', function() {
describe('AuthenticationController Unit Tests', function() {
// Initialize global variables
var AuthenticationController,
scope,

View file

@ -17,17 +17,15 @@
<img src="/modules/users/img/buttons/github.png">
</a>
</div> -->
<h3 class="col-xs-offset-2 col-xs-8 col-md-offset-3 col-md-6 text-center">Signup with your email</h3>
<h3 class="col-xs-offset-2 col-xs-8 col-md-offset-3 col-md-6 text-center">Signup Successful</h3>
<div class="col-xs-offset-2 col-xs-8 col-md-offset-3 col-md-6">
<h2>Congrats! You've successfully registered an account at MedForms. </h2>
<p>Before you continue, make sure to check your email for our verification email. If you don't receive it within 24h drop us a line</p>
<ul>
<li>
Click
<em href="#!/">Here</em>
to continue
</li>
</ul>
<h2>
Congrats! You've successfully registered an account at MedForms. <br>But your account is <b>not verified yet</b>
</h2>
<p>Before you continue, make sure to check your email for our verification email. If you don't receive it within 24h drop us a line at <a href="mail:hi@medforms.com">hi@medforms.com</a></p>
<div class="text-center form-group">
<button type="submit" class="btn btn-large btn-primary"><a href="/">Continue</a></button>
</div>
</div>
</div>
</section>

View file

@ -48,8 +48,7 @@
<input type="password" id="password" name="password" class="form-control" data-ng-model="credentials.password" placeholder="Password">
</div>
<div class="text-center form-group">
<button type="submit" class="btn btn-large btn-primary">Sign up</button>&nbsp; or&nbsp;
<a href="/#!/signin" class="show-signup">Sign in</a>
<button type="submit" class="btn btn-large btn-primary">Sign up</button>
</div>
</fieldset>