mirror of
https://github.com/atlanticbiomedical/biomedjs.git
synced 2025-07-02 00:47:26 -04:00
sync
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,2 +1,8 @@
|
||||
node_modules
|
||||
node
|
||||
logs/
|
||||
*.log
|
||||
*.log.old
|
||||
*.bac
|
||||
*.old
|
||||
*.save
|
||||
|
@ -6,7 +6,7 @@ var mongoose = require('mongoose'),
|
||||
|
||||
var log = require('log4node');
|
||||
|
||||
var frequencies = ["annual","semi","quarterly","sterilizer","tg","ert","rae","medgas","imaging","neptune","anesthesia"];
|
||||
var frequencies = ["Medical Device","Sterilizer - TT","Vaporizer","Ice Maker","Anesthesia","Waste Management System","Imaging","Medical Gas Systems","RAE","ERT","N2O Trace Gas","Sterilizer - F","Quarterly","Semi","Annual","legacy","DLLR"];
|
||||
|
||||
exports.index = function(req, res) {
|
||||
log.info("clients.index");
|
||||
|
@ -4,16 +4,34 @@ var mongoose = require('mongoose'),
|
||||
Workorder = mongoose.model('Workorder');
|
||||
|
||||
exports.index = function(req, res) {
|
||||
var date = moment(req.query.date);
|
||||
var start = date.clone().startOf('day').toDate();
|
||||
var end = date.clone().endOf('day').toDate();
|
||||
|
||||
var start, end;
|
||||
|
||||
|
||||
if (req.query.start && req.query.end) {
|
||||
start = moment(req.query.start).toDate();
|
||||
end = moment(req.query.end).toDate();
|
||||
} else {
|
||||
var date = moment(req.query.date);
|
||||
start = date.clone().startOf('day').toDate();
|
||||
end = date.clone().endOf('day').toDate();
|
||||
}
|
||||
|
||||
var tech = req.query.tech;
|
||||
|
||||
var query = {
|
||||
deleted: false,
|
||||
'scheduling.start': { '$lte': end },
|
||||
'scheduling.end': { '$gte': start }
|
||||
};
|
||||
|
||||
if (tech) {
|
||||
query['techs'] = tech;
|
||||
}
|
||||
|
||||
|
||||
Workorder
|
||||
.find({
|
||||
deleted: false,
|
||||
'scheduling.start': { '$lte': end },
|
||||
'scheduling.end': { '$gte': start }
|
||||
})
|
||||
.find(query)
|
||||
.populate('techs', 'name')
|
||||
.populate('client', 'name identifier address')
|
||||
.select('scheduling techs client')
|
||||
|
@ -1,25 +1,190 @@
|
||||
|
||||
var mongoose = require('mongoose'),
|
||||
async = require('async'),
|
||||
User = mongoose.model('User');
|
||||
|
||||
exports.index = function(req, res) {
|
||||
var criteria = { deleted: false };
|
||||
var log = require('log4node');
|
||||
|
||||
if (req.query.group) {
|
||||
criteria.groups = req.query.group;
|
||||
}
|
||||
module.exports = function(config, directory) {
|
||||
|
||||
if (req.query.perms) {
|
||||
criteria.perms = req.query.perms;
|
||||
}
|
||||
|
||||
var query = User.find(criteria)
|
||||
.select('name groups')
|
||||
.exec(function(err, results) {
|
||||
if (err) {
|
||||
res.json(500, err);
|
||||
} else {
|
||||
res.json(results);
|
||||
function fetch_all_users(callback) {
|
||||
async.parallel({
|
||||
gapps: directory.listUsers,
|
||||
local: function(callback) {
|
||||
User.find({ deleted: false }).select('name email groups perms deleted').exec(callback);
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function map_local_users(data, results) {
|
||||
return function(callback) {
|
||||
async.each(data, function(item, callback) {
|
||||
var key = item.email.toLowerCase();
|
||||
|
||||
if (blacklist.indexOf(key) == -1)
|
||||
results[key] = item;
|
||||
|
||||
callback();
|
||||
},
|
||||
callback);
|
||||
};
|
||||
}
|
||||
|
||||
function map_gapps_users(data, results) {
|
||||
return function(callback) {
|
||||
async.each(data, function(item, callback) {
|
||||
var key = item.primaryEmail.toLowerCase();
|
||||
|
||||
// Ignore if blacklisted
|
||||
if (blacklist.indexOf(key) != -1) return callback();
|
||||
|
||||
if (!(key in results))
|
||||
results[key] = {
|
||||
email: item.primaryEmail,
|
||||
deleted: false,
|
||||
perms: [ ],
|
||||
groups: [ ],
|
||||
name: {
|
||||
first: item.name.givenName,
|
||||
last: item.name.familyName
|
||||
},
|
||||
};
|
||||
|
||||
callback();
|
||||
},
|
||||
callback);
|
||||
};
|
||||
}
|
||||
|
||||
function reduce_array(data, results) {
|
||||
return function(callback) {
|
||||
for (var item in data) {
|
||||
results.push(data[item]);
|
||||
}
|
||||
|
||||
results.sort(function(a, b) {
|
||||
var result = a.name.first.toLowerCase().localeCompare(b.name.first.toLowerCase());
|
||||
if (result == 0)
|
||||
result = a.name.last.toLowerCase().localeCompare(b.name.last.toLowerCase());
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
callback();
|
||||
};
|
||||
}
|
||||
|
||||
function merge_sources(data, callback) {
|
||||
var map = {};
|
||||
var reduce = [];
|
||||
|
||||
async.series([
|
||||
map_local_users(data.local, map),
|
||||
map_gapps_users(data.gapps.users, map),
|
||||
reduce_array(map, reduce),
|
||||
],
|
||||
function(err) {
|
||||
callback(err, reduce);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
index: function(req, res) {
|
||||
var criteria = { deleted: false };
|
||||
|
||||
if (req.query.group) {
|
||||
criteria.groups = req.query.group;
|
||||
}
|
||||
|
||||
if (req.query.perms) {
|
||||
criteria.perms = req.query.perms;
|
||||
}
|
||||
|
||||
if (req.query.userid) {
|
||||
criteria._id = req.query.userid;
|
||||
}
|
||||
|
||||
var query = User.find(criteria)
|
||||
.select('name groups')
|
||||
.exec(function(err, results) {
|
||||
if (err) {
|
||||
res.json(500, err);
|
||||
} else {
|
||||
res.json(results);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
details: function(req, res) {
|
||||
|
||||
async.waterfall([
|
||||
fetch_all_users,
|
||||
merge_sources,
|
||||
],
|
||||
function(err, results) {
|
||||
if (err) return res.json(500, err);
|
||||
res.json(results);
|
||||
});
|
||||
},
|
||||
|
||||
create: function(req, res) {
|
||||
log.info("users.create %j", req.body);
|
||||
|
||||
var user = new User({
|
||||
email: req.body.email,
|
||||
name: req.body.name,
|
||||
groups: req.body.groups,
|
||||
perms: req.body.perms,
|
||||
deleted: false
|
||||
});
|
||||
|
||||
return user.save(function(err) {
|
||||
if (err)
|
||||
log.error("Error: %s", err);
|
||||
|
||||
return res.json(user);
|
||||
});
|
||||
},
|
||||
|
||||
update: function(req, res) {
|
||||
var id = req.param('user_id');
|
||||
log.info("users.update %s %j", id, req.body);
|
||||
|
||||
return User.findById(id, function(err, user) {
|
||||
user.email = req.body.email;
|
||||
user.name = req.body.name;
|
||||
user.groups = req.body.groups;
|
||||
user.perms = req.body.perms;
|
||||
|
||||
return user.save(function(err) {
|
||||
if (err)
|
||||
log.err("Error: %s", err);
|
||||
|
||||
return res.json(user);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var blacklist = [
|
||||
"system@atlanticbiomedical.com",
|
||||
"admin@atlanticbiomedical.com",
|
||||
"amazons3@atlanticbiomedical.com",
|
||||
"api@atlanticbiomedical.com",
|
||||
"biodexservice@atlanticbiomedical.com",
|
||||
"cerberusapp@atlanticbiomedical.com",
|
||||
"chattservice@atlanticbiomedical.com",
|
||||
"dropbox@atlanticbiomedical.com",
|
||||
"inquiries@atlanticbiomedical.com",
|
||||
"office@atlanticbiomedical.com",
|
||||
"parts@atlanticbiomedical.com",
|
||||
"schedule@atlanticbiomedical.com",
|
||||
"webapp@atlanticbiomedical.com",
|
||||
"banfieldservice@atlanticbiomedical.com",
|
||||
"chris.sewell@atlanticbiomedical.com",
|
||||
"devel@atlanticbiomedical.com",
|
||||
"dobie@atlanticbiomedical.com",
|
||||
"akirayasha@gmail.com",
|
||||
"receipts@atlanticbiomedical.com",
|
||||
];
|
||||
|
@ -67,6 +67,7 @@ module.exports = function(config, calendar) {
|
||||
|
||||
var workorder = new Workorder({
|
||||
client: req.body.client,
|
||||
emails: req.body.emails,
|
||||
createdOn: date,
|
||||
createdBy: req.user,
|
||||
reason: req.body.reason,
|
||||
@ -117,7 +118,7 @@ module.exports = function(config, calendar) {
|
||||
location: generateLocation(client),
|
||||
start: workorder.scheduling.start,
|
||||
end: workorder.scheduling.end,
|
||||
attendees: generateAttendees(techs)
|
||||
attendees: generateAttendees(techs, workorder)
|
||||
}, function(err, result) {
|
||||
if (result) {
|
||||
workorder.calendarId = result.id;
|
||||
@ -129,7 +130,7 @@ module.exports = function(config, calendar) {
|
||||
if (!notify)
|
||||
return callback(null);
|
||||
|
||||
var to = generateToLine(techs);
|
||||
var to = generateToLine(techs).concat(req.body.emails);
|
||||
if (!to)
|
||||
return callback(null);
|
||||
|
||||
@ -197,6 +198,7 @@ module.exports = function(config, calendar) {
|
||||
Workorder.findById(id, function(err, result) {
|
||||
workorder = result;
|
||||
|
||||
workorder.emails = req.body.emails;
|
||||
workorder.modifiedBy = req.user;
|
||||
workorder.modifiedOn = modifiedOn;
|
||||
workorder.reason = req.body.reason;
|
||||
@ -253,7 +255,7 @@ module.exports = function(config, calendar) {
|
||||
location: generateLocation(client),
|
||||
start: workorder.scheduling.start,
|
||||
end: workorder.scheduling.end,
|
||||
attendees: generateAttendees(techs),
|
||||
attendees: generateAttendees(techs, workorder),
|
||||
eventId: workorder.calendarId
|
||||
}, function(err, result) {
|
||||
callback(err);
|
||||
@ -335,6 +337,9 @@ function generateDescription(client, workorder, createdBy, modifiedBy) {
|
||||
"Workorder ID:\n" +
|
||||
" %(biomedId)s\n" +
|
||||
"\n" +
|
||||
"Scheduled Time:\n" +
|
||||
" %(scheduleStart)s - %(scheduleEnd)s\n" +
|
||||
"\n" +
|
||||
"Created By:\n" +
|
||||
" %(createdBy)s\n" +
|
||||
"\n" +
|
||||
@ -362,6 +367,11 @@ function generateDescription(client, workorder, createdBy, modifiedBy) {
|
||||
"Remarks:\n" +
|
||||
" %(remarks)s\n";
|
||||
|
||||
var format = "MMMM Do YYYY, h:mm a"
|
||||
|
||||
var scheduleStart = moment(workorder.scheduling.start).format(format);
|
||||
var scheduleEnd = moment(workorder.scheduling.end).format(format);
|
||||
|
||||
var resources = {
|
||||
biomedId: workorder.biomedId || '',
|
||||
name: client.name || '',
|
||||
@ -374,6 +384,8 @@ function generateDescription(client, workorder, createdBy, modifiedBy) {
|
||||
reason: workorder.reason || '',
|
||||
status: workorder.status || '',
|
||||
remarks: workorder.remarks || '',
|
||||
scheduleStart: scheduleStart,
|
||||
scheduleEnd: scheduleEnd,
|
||||
phone: '',
|
||||
contact: '',
|
||||
createdBy: '',
|
||||
@ -396,8 +408,9 @@ function generateDescription(client, workorder, createdBy, modifiedBy) {
|
||||
return sprintf(template, resources);
|
||||
}
|
||||
|
||||
function generateAttendees(techs) {
|
||||
return techs.map(function(t) { return t.email; });
|
||||
function generateAttendees(techs, workorder) {
|
||||
console.log('here');
|
||||
return techs.map(function(t) { return t.email; }).concat(workorder.emails);
|
||||
}
|
||||
|
||||
function generateToLine(techs) {
|
||||
|
@ -5,6 +5,7 @@ var mongoose = require('mongoose')
|
||||
var workorderSchema = new Schema({
|
||||
biomedId: Number,
|
||||
client: { type: ObjectId, ref: 'Client' },
|
||||
emails: [String],
|
||||
createdOn: Date,
|
||||
createdBy: { type: ObjectId, ref: 'User' },
|
||||
modifiedBy: { type: ObjectId, ref: 'User' },
|
||||
|
@ -9,7 +9,7 @@ html(lang="en", ng-app="biomed", ng-controller="biomed.PageCtrl")
|
||||
.navbar-inner
|
||||
a.brand(href='/', target='_self') Atlantic Biomedical
|
||||
progress-panel
|
||||
ul.nav.pull-right(ng-controller='biomed.AccountCtrl')
|
||||
ul.nav.pull-right
|
||||
li
|
||||
a(href='https://docs.google.com/a/atlanticbiomedical.com/forms/d/1i7CyNR2lcrz7bOL7u9ssKiMB2iBmXqOdvVKC0GRzRtY/viewform', target='_blank')
|
||||
i.icon-shopping-cart
|
||||
@ -23,9 +23,9 @@ html(lang="en", ng-app="biomed", ng-controller="biomed.PageCtrl")
|
||||
i.icon-fire
|
||||
| Tickets
|
||||
li
|
||||
a(ng-click="openDialog()")
|
||||
a(ng-click="disabledopenDialog()")
|
||||
i.icon-envelope
|
||||
| Messages
|
||||
| Messages (disabled)
|
||||
li
|
||||
a(href='/logout', target='_self')
|
||||
i.icon-share-alt
|
||||
@ -53,6 +53,11 @@ html(lang="en", ng-app="biomed", ng-controller="biomed.PageCtrl")
|
||||
a(href='/workorders')
|
||||
i.icon-wrench
|
||||
| Workorders
|
||||
|
||||
li(data-match-route='/admin.*', ng-show="accountHasPermission('system.admin')")
|
||||
a(href='/admin')
|
||||
i.icon-wrench
|
||||
| Admin
|
||||
.container-fluid
|
||||
ng-view
|
||||
!{js}
|
||||
|
@ -55,6 +55,10 @@ html(lang="en", ng-app="tags", ng-controller="tags.PageCtrl")
|
||||
dd {{payload.tag.client.name}} ({{payload.tag.client.identifier}})
|
||||
dt Client Device ID
|
||||
dd {{tag.clientDeviceId}}
|
||||
span(ng-repeat='field in fields')
|
||||
dt(ng-show='{{field.value}}') {{field.label}}
|
||||
dt(ng-show='{{field.value}}') {{field.value}}
|
||||
|
||||
dt Device
|
||||
dd {{tag.device}}
|
||||
dt Manufacturer
|
||||
|
@ -1,3 +1,5 @@
|
||||
var log = require('log4node');
|
||||
|
||||
module.exports = function(app, passport) {
|
||||
app.get('/auth', function(req, res, next) {
|
||||
console.dir(req.headers);
|
||||
@ -16,13 +18,15 @@ module.exports = function(app, passport) {
|
||||
var options = {
|
||||
callbackURL: 'http://' + req.headers['x-forwarded-host'] + '/auth/callback'
|
||||
};
|
||||
console.log(options);
|
||||
passport.authenticate('google', options, function(err, user, info) {
|
||||
var redirectUrl = '/';
|
||||
|
||||
if (err) { return next(err); }
|
||||
if (!user) { return res.redirect('/login/error'); }
|
||||
|
||||
log.setPrefix("[%d] %l ");
|
||||
log.info("User Logged In: %s %s", user.name.first, user.name.last);
|
||||
|
||||
if (req.session.redirectUrl) {
|
||||
redirectUrl = req.session.redirectUrl;
|
||||
req.session.redirectUrl = null;
|
||||
@ -43,15 +47,22 @@ module.exports = function(app, passport) {
|
||||
return {
|
||||
requiresUiLogin: function(req, res, next) {
|
||||
if (!req.isAuthenticated()) {
|
||||
// req.session.redirectUrl = req.url;
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
log.setPrefix(function(level) {
|
||||
return '[' + new Date().toUTCString() + '] ' + level.toUpperCase() + ' ' + req.user.name.first + ' ' + req.user.name.last + ' | ';
|
||||
});
|
||||
next();
|
||||
},
|
||||
requiresApiAccess: function(req, res, next) {
|
||||
if (!req.isAuthenticated()) {
|
||||
return res.send(403);
|
||||
}
|
||||
|
||||
log.setPrefix(function(level) {
|
||||
return '[' + new Date().toUTCString() + '] ' + level.toUpperCase() + ' ' + req.user.name.first + ' ' + req.user.name.last + ' | ';
|
||||
});
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
@ -29,8 +29,11 @@ module.exports = {
|
||||
clientId: '333768673996-8epedo3je5h59n4l97v4dv8nofs7qnee.apps.googleusercontent.com',
|
||||
clientSecret: 'afu9KhKxckWJ3Tk6uxzp9Pg6',
|
||||
callback: 'http://portal.atlanticbiomedical.com/auth/callback',
|
||||
accessToken: 'ya29.AHES6ZT1Sj1vpgidR2I_ksLdlV_VeZUjkitnZ01cP6VRrknjUEVbuw',
|
||||
refreshToken: '1/XQW9P9FNYm6jikTsV8HOIuPAo1APYhwTH5CLhq9263g'
|
||||
// accessToken: 'ya29.AHES6ZT1Sj1vpgidR2I_ksLdlV_VeZUjkitnZ01cP6VRrknjUEVbuw',
|
||||
// refreshToken: '1/XQW9P9FNYm6jikTsV8HOIuPAo1APYhwTH5CLhq9263g'
|
||||
|
||||
accessToken: 'ya29.1.AADtN_Xjt0PK6YVs8q5csiQFXQg2ZDtrVhsH6P4a5zm0mHqhGx0Nnjx4Jk68Gw',
|
||||
refreshToken: '1/_5SkDLYmsi4XNaQyAzld-W5-GEqEqt5byH6VkI-j5QI',
|
||||
},
|
||||
email: {
|
||||
user: 'api@atlanticbiomedical.com',
|
||||
|
72
config/directory.js
Normal file
72
config/directory.js
Normal file
@ -0,0 +1,72 @@
|
||||
var googleapis = require('googleapis'),
|
||||
sprintf = require('sprintf'),
|
||||
OAuth2Client = googleapis.OAuth2Client;
|
||||
|
||||
var apiClient;
|
||||
|
||||
module.exports = function(config) {
|
||||
|
||||
var oauth2Client = new OAuth2Client(
|
||||
config.auth.clientId, config.auth.clientSecret, config.auth.callback);
|
||||
|
||||
oauth2Client.credentials = {
|
||||
access_token: config.auth.accessToken,
|
||||
refresh_token: config.auth.refreshToken
|
||||
};
|
||||
|
||||
function toIsoDate(d) {
|
||||
function pad(n) { return n < 10 ? '0' + n : n }
|
||||
return d.getUTCFullYear()+'-'
|
||||
+ pad(d.getUTCMonth()+1)+'-'
|
||||
+ pad(d.getUTCDate())+'T'
|
||||
+ pad(d.getUTCHours())+':'
|
||||
+ pad(d.getUTCMinutes())+':'
|
||||
+ pad(d.getUTCSeconds())+'Z';
|
||||
}
|
||||
|
||||
return {
|
||||
listUsers: function(callback) {
|
||||
api(function(client, callback) {
|
||||
var params = {
|
||||
domain: 'atlanticbiomedical.com',
|
||||
fields: 'users(name,primaryEmail)',
|
||||
};
|
||||
|
||||
var request = client.admin.users.list();
|
||||
request.params = params;
|
||||
request.withAuthClient(oauth2Client).execute(function(err, result) {
|
||||
callback(err, result);
|
||||
});
|
||||
}, callback);
|
||||
}
|
||||
};
|
||||
|
||||
function api(workorder, callback) {
|
||||
var handler = function(client) {
|
||||
workorder(client, function(err, result) {
|
||||
if (oauth2Client.credentials.access_token != config.auth.accessToken) {
|
||||
console.log("Updating access token");
|
||||
config.auth.accessToken = oauth2Client.credentials.access_token;
|
||||
}
|
||||
|
||||
callback(err, result);
|
||||
});
|
||||
};
|
||||
|
||||
if (apiClient) {
|
||||
console.log("Using cached api client");
|
||||
handler(apiClient);
|
||||
} else {
|
||||
console.log("Getting api client");
|
||||
googleapis.discover('admin', 'directory_v1').execute(function(err, client) {
|
||||
console.log(err);
|
||||
|
||||
if (err) return callback(err);
|
||||
apiClient = client;
|
||||
|
||||
handler(apiClient);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
@ -16,17 +16,22 @@ module.exports = function(passport, config) {
|
||||
passport.use(new GoogleStrategy({
|
||||
clientID: config.auth.clientId,
|
||||
clientSecret: config.auth.clientSecret,
|
||||
// callbackURL: config.auth.callback
|
||||
// callbackURL: config.auth.callback,
|
||||
passReqToCallback: true
|
||||
},
|
||||
function(accessToken, refreshToken, profile, done) {
|
||||
console.log(profile);
|
||||
console.log(accessToken);
|
||||
console.log(refreshToken);
|
||||
|
||||
function(req, accessToken, refreshToken, profile, done) {
|
||||
profile = profile._json;
|
||||
User.findOne({ email: profile.email.toLowerCase() }, function(err, user) {
|
||||
if (err) { return done(err); }
|
||||
if (!user || !user.hasPermission("system.login")) {
|
||||
|
||||
var source = req.headers['x-forwarded-host'];
|
||||
|
||||
|
||||
if (
|
||||
!user ||
|
||||
(source == 'portal.atlanticbiomedical.com' && !user.hasPermission("system.login")) ||
|
||||
(source == 'n.atlb.co' && !user.hasPermission("system.tags"))
|
||||
) {
|
||||
return done(null, false, { message: "You are not authorized to access this portal." });
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
var log = require('log4node');
|
||||
|
||||
module.exports = function(app, auth, piler, calendar, config) {
|
||||
module.exports = function(app, auth, piler, calendar, directory, config) {
|
||||
|
||||
piler.addCssUrl("//fonts.googleapis.com/css?family=Open+Sans:400,300");
|
||||
piler.addCssFile("/css/biomed.less");
|
||||
@ -30,7 +31,7 @@ module.exports = function(app, auth, piler, calendar, config) {
|
||||
app.post('/api/clients/:client_id', clients.update);
|
||||
app.del('/api/clients/:client_id', clients.destroy);
|
||||
|
||||
var workorders = require('../app/controllers/workorders')(calendar);
|
||||
var workorders = require('../app/controllers/workorders')(config, calendar);
|
||||
app.get('/api/workorders', workorders.index);
|
||||
app.get('/api/workorders/:workorder_id', workorders.get);
|
||||
app.post('/api/workorders', workorders.create);
|
||||
@ -40,8 +41,11 @@ module.exports = function(app, auth, piler, calendar, config) {
|
||||
var schedule = require('../app/controllers/schedule');
|
||||
app.get('/api/schedule', schedule.index);
|
||||
|
||||
var users = require('../app/controllers/users');
|
||||
var users = require('../app/controllers/users')(config, directory);
|
||||
app.get('/api/users', users.index);
|
||||
app.get('/api/users/details', users.details);
|
||||
app.post('/api/users', users.create);
|
||||
app.post('/api/users/:user_id', users.update);
|
||||
|
||||
var account = require('../app/controllers/account');
|
||||
app.get('/api/account', account.profile);
|
||||
|
126
logs/crash.log
126
logs/crash.log
@ -1,126 +0,0 @@
|
||||
Server was reset on 06.07.2013 at 00:32:52
|
||||
Server was reset on 06.07.2013 at 00:32:52
|
||||
Server was reset on 06.07.2013 at 00:32:52
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.24.2013 at 10:40:55
|
||||
Server was reset on 06.26.2013 at 07:24:10
|
||||
Server was reset on 06.26.2013 at 07:24:10
|
||||
Server was reset on 06.26.2013 at 07:24:10
|
||||
Server was reset on 06.26.2013 at 07:24:10
|
||||
Server was reset on 06.26.2013 at 07:24:10
|
||||
Server was reset on 07.01.2013 at 02:38:49
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.01.2013 at 02:44:36
|
||||
Server was reset on 07.19.2013 at 08:33:09
|
||||
Server was reset on 07.19.2013 at 08:33:09
|
||||
Server was reset on 07.19.2013 at 09:03:11
|
||||
Server was reset on 07.19.2013 at 09:03:11
|
||||
Server was reset on 07.19.2013 at 10:01:07
|
||||
Server was reset on 07.19.2013 at 10:01:07
|
||||
Server was reset on 07.19.2013 at 10:01:07
|
||||
Server was reset on 07.19.2013 at 10:01:07
|
||||
Server was reset on 07.19.2013 at 10:01:07
|
||||
Server was reset on 07.19.2013 at 10:35:47
|
||||
Server was reset on 07.19.2013 at 10:35:47
|
||||
Server was reset on 07.19.2013 at 10:35:47
|
||||
Server was reset on 07.19.2013 at 10:35:47
|
||||
Server was reset on 07.19.2013 at 10:35:47
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:09:00
|
||||
Server was reset on 07.19.2013 at 11:59:11
|
||||
Server was reset on 07.19.2013 at 11:59:11
|
||||
Server was reset on 07.19.2013 at 11:59:11
|
||||
Server was reset on 07.19.2013 at 11:59:11
|
||||
Server was reset on 07.19.2013 at 11:59:11
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.19.2013 at 12:19:27
|
||||
Server was reset on 07.22.2013 at 00:15:15
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 07.28.2013 at 21:14:04
|
||||
Server was reset on 08.07.2013 at 00:39:34
|
||||
Server was reset on 08.07.2013 at 17:07:18
|
||||
Server was reset on 08.07.2013 at 22:05:41
|
||||
Server was reset on 08.07.2013 at 22:05:41
|
||||
Server was reset on 08.07.2013 at 22:05:41
|
||||
Server was reset on 08.07.2013 at 22:06:43
|
||||
Server was reset on 08.07.2013 at 22:06:43
|
||||
Server was reset on 08.24.2013 at 13:17:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 08.27.2013 at 10:54:23
|
||||
Server was reset on 09.02.2013 at 06:42:51
|
||||
Server was reset on 09.02.2013 at 06:42:51
|
||||
Server was reset on 09.02.2013 at 06:42:51
|
File diff suppressed because it is too large
Load Diff
@ -73,6 +73,7 @@ header {
|
||||
font-weight: 500;
|
||||
color: #999999;
|
||||
margin: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +161,42 @@ header {
|
||||
}
|
||||
}
|
||||
|
||||
.users {
|
||||
th, td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-start {
|
||||
border-left: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
.name, .email { text-align: left; white-space: nowrap; }
|
||||
|
||||
.false {
|
||||
.icon {
|
||||
.icon-remove;
|
||||
}
|
||||
}
|
||||
|
||||
.true {
|
||||
background-color: #DFF0D8 !important;
|
||||
|
||||
.icon {
|
||||
.icon-ok;
|
||||
}
|
||||
}
|
||||
|
||||
.new {
|
||||
background-color: #49cced;
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
padding: 2px 5px;
|
||||
margin: 2px;
|
||||
.border-radius(2px);
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.axis path,
|
||||
@ -248,6 +285,7 @@ header {
|
||||
|
||||
.tech-label {
|
||||
float: left;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.enteries {
|
||||
|
BIN
public/img/select2-spinner.gif
Normal file
BIN
public/img/select2-spinner.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
public/img/select2.png
Normal file
BIN
public/img/select2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 613 B |
BIN
public/img/select2x2.png
Normal file
BIN
public/img/select2x2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 845 B |
@ -22,8 +22,9 @@ angular.module('biomed', ['biomed.filters', 'biomed.services', 'biomed.directive
|
||||
data = data.replace(PROTECTION_PREFIX, '');
|
||||
if (JSON_START.test(data) && JSON_END.test(data)) {
|
||||
data = JSON.parse(data, function(key, val) {
|
||||
if (DATE_MATCHER.test(val))
|
||||
return new Date(val);
|
||||
if (DATE_MATCHER.test(val)) {
|
||||
return new moment(val).zone(-5).toDate();
|
||||
}
|
||||
return val;
|
||||
})
|
||||
}
|
||||
@ -68,6 +69,15 @@ angular.module('biomed', ['biomed.filters', 'biomed.services', 'biomed.directive
|
||||
templateUrl: '/partials/workorders/edit.html',
|
||||
controller: biomed.WorkorderEditCtrl
|
||||
})
|
||||
.when('/techs/:id', {
|
||||
templateUrl: '/partials/techs/schedule.html',
|
||||
controller: biomed.TechScheduleCtrl
|
||||
})
|
||||
.when('/admin', {
|
||||
templateUrl: '/partials/users/index.html',
|
||||
controller: biomed.UsersIndexCtrl,
|
||||
reloadOnSearch: false
|
||||
})
|
||||
.otherwise({
|
||||
redirectTo: '/schedule'
|
||||
});
|
||||
|
@ -1,5 +1,29 @@
|
||||
biomed.AccountCtrl = function($scope, Account) {
|
||||
$scope.account = Account.get();
|
||||
|
||||
biomed.TechScheduleCtrl = function($scope, $routeParams, $location, Schedule, Users, LocationBinder) {
|
||||
|
||||
if (!$scope.date) {
|
||||
$scope.date = new Date();
|
||||
}
|
||||
|
||||
Users.index({userid: $routeParams.id}, function(result) {
|
||||
$scope.tech = result[0];
|
||||
});
|
||||
|
||||
$scope.$watch('date', updateDate);
|
||||
|
||||
$scope.onEntryClick = function(entry) {
|
||||
$location.path('/workorders/' + entry.workorder._id);
|
||||
};
|
||||
|
||||
function updateDate() {
|
||||
Schedule.index({
|
||||
tech: $routeParams.id,
|
||||
start: $scope.date.toJSON(),
|
||||
end: moment($scope.date).add('days', 7).toDate().toJSON()
|
||||
}, function(result) {
|
||||
$scope.schedule = result;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
biomed.ScheduleIndexCtrl = function($scope, $location, Users, Schedule, LocationBinder) {
|
||||
@ -64,6 +88,90 @@ biomed.SchedulePmsCtrl = function($scope, Clients) {
|
||||
$scope.$watch('month', filter);
|
||||
};
|
||||
|
||||
biomed.UsersIndexCtrl = function($scope, $filter, $routeParams, $location, Users, LocationBinder) {
|
||||
$scope.loading = true;
|
||||
|
||||
$scope.account.$then(function(value) {
|
||||
if (!$scope.accountHasPermission('system.admin'))
|
||||
return $location.path('/');
|
||||
});
|
||||
|
||||
|
||||
var allData = Users.details(function() {
|
||||
$scope.loading = false;
|
||||
$scope.filter();
|
||||
});
|
||||
|
||||
var filteredData = [];
|
||||
var index = 0;
|
||||
var initialPageSize = 100;
|
||||
var pageSize = 5;
|
||||
|
||||
$scope.canLoad = true;
|
||||
$scope.$watch('query', function() {
|
||||
$scope.filter();
|
||||
});
|
||||
|
||||
LocationBinder($scope, ['query']);
|
||||
|
||||
$scope.filter = function() {
|
||||
filteredData = $filter('filter')(allData, $scope.query);
|
||||
index = initialPageSize;
|
||||
$scope.canLoad = true;
|
||||
$scope.users = filteredData.slice(0, initialPageSize);
|
||||
};
|
||||
|
||||
$scope.addItems = function() {
|
||||
$scope.users = $scope.users.concat(filteredData.slice(index, index + pageSize));
|
||||
index += pageSize;
|
||||
$scope.canLoad = index < filteredData.length;
|
||||
};
|
||||
|
||||
function save(user) {
|
||||
if ('_id' in user) {
|
||||
Users.update({id: user._id}, user, function(result) {
|
||||
angular.copy(result, user);
|
||||
});
|
||||
} else {
|
||||
Users.create(user, function(result) {
|
||||
angular.copy(result, user);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.toggleGroup = function(user, group) {
|
||||
var index = user.groups.indexOf(group);
|
||||
if (index > -1)
|
||||
user.groups.splice(index, 1);
|
||||
else
|
||||
user.groups.push(group);
|
||||
|
||||
save(user);
|
||||
}
|
||||
|
||||
$scope.checkGroup = function(user, group) {
|
||||
return $.inArray(group, user.groups) > -1;
|
||||
};
|
||||
|
||||
$scope.togglePerm = function(user, perm) {
|
||||
var index = user.perms.indexOf(perm);
|
||||
if (index > -1)
|
||||
user.perms.splice(index, 1);
|
||||
else
|
||||
user.perms.push(perm);
|
||||
|
||||
save(user);
|
||||
};
|
||||
|
||||
$scope.checkPerm = function(user, perm) {
|
||||
return $.inArray(perm, user.perms) > -1;
|
||||
};
|
||||
|
||||
$scope.isNew = function(user) {
|
||||
return !('_id' in user);
|
||||
};
|
||||
};
|
||||
|
||||
biomed.ClientIndexCtrl = function($scope, $filter, $routeParams, Clients, LocationBinder) {
|
||||
$scope.loading = true;
|
||||
|
||||
@ -295,13 +403,21 @@ biomed.WorkorderIndexCtrl = function($scope, $filter, $routeParams, Workorders,
|
||||
|
||||
biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clients, Users) {
|
||||
|
||||
$scope.emailsOptions = {
|
||||
'multiple': true,
|
||||
'simple_tags': true,
|
||||
'tags': [],
|
||||
'formatNoMatches': function() { return 'Type an e-mail address and press return to add it.'; }
|
||||
};
|
||||
|
||||
$scope.group = 'all';
|
||||
$scope.model = {};
|
||||
$scope.picker = {
|
||||
start: '09:00:00',
|
||||
end: '17:00:00'
|
||||
startTime: '09:00:00',
|
||||
endTime: '09:45:00'
|
||||
};
|
||||
$scope.picker.date = new Date();
|
||||
$scope.picker.startDate = new Date();
|
||||
$scope.picker.endDate = new Date();
|
||||
|
||||
var search = $location.search();
|
||||
|
||||
@ -311,6 +427,13 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie
|
||||
$scope.model.maintenanceType = search.type;
|
||||
|
||||
$scope.workorderType = 'pm';
|
||||
} else if (search.workorderType == "meeting") {
|
||||
$scope.model.reason = "Meeting";
|
||||
$scope.workorderType = 'meeting';
|
||||
|
||||
if (search.clientId) {
|
||||
$scope.model.client = search.clientId;
|
||||
}
|
||||
} else {
|
||||
if (search.clientId) {
|
||||
$scope.model.client = search.clientId;
|
||||
@ -334,23 +457,94 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie
|
||||
$scope.clients = result;
|
||||
});
|
||||
|
||||
$scope.$watch('picker.date', function() {
|
||||
function convertToDate(date, time) {
|
||||
return moment(moment(date).format('YYYY-MM-DD') + 'T' + time).toDate();
|
||||
}
|
||||
|
||||
function datesOverlap() {
|
||||
var start = convertToDate($scope.picker.startDate, $scope.picker.startTime);
|
||||
var end = convertToDate($scope.picker.endDate, $scope.picker.endTime);
|
||||
return start >= end;
|
||||
}
|
||||
|
||||
function updateDuration() {
|
||||
var start = convertToDate($scope.picker.startDate, $scope.picker.startTime);
|
||||
var end = convertToDate($scope.picker.endDate, $scope.picker.endTime);
|
||||
|
||||
var duration = moment.duration(end - start);
|
||||
|
||||
var days = duration.days()
|
||||
var hours = duration.hours();
|
||||
var minutes = duration.minutes();
|
||||
|
||||
var result = "";
|
||||
|
||||
if (days == 1) {
|
||||
result += "1 Day ";
|
||||
}
|
||||
if (days > 1) {
|
||||
result += days + " Days ";
|
||||
}
|
||||
if (hours == 1) {
|
||||
result += "1 Hour ";
|
||||
}
|
||||
if (hours > 1) {
|
||||
result += hours + " Hours ";
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result += minutes + " Minutes";
|
||||
}
|
||||
|
||||
$scope.picker.duration = result;
|
||||
}
|
||||
|
||||
|
||||
$scope.$watch('picker.startDate', function() {
|
||||
Schedule.index({
|
||||
date: $scope.picker.date.toJSON()
|
||||
date: $scope.picker.startDate.toJSON()
|
||||
}, function(result) {
|
||||
$scope.schedule = result;
|
||||
});
|
||||
|
||||
if (datesOverlap()) {
|
||||
$scope.picker.endDate = $scope.picker.startDate;
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.save = function() {
|
||||
$scope.$watch('picker.endDate', function() {
|
||||
if (datesOverlap()) {
|
||||
$scope.picker.startDate = $scope.picker.endDate;
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.$watch('picker.startTime', function() {
|
||||
$scope.picker.endTime = moment($scope.picker.startTime, "HH:mm:ss").add('minutes', 45).format("HH:mm:ss");
|
||||
$scope.picker.endDate = $scope.picker.startDate;
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.$watch('picker.endTime', function() {
|
||||
if (datesOverlap()) {
|
||||
$scope.picker.startTime = moment($scope.picker.endTime, "HH:mm:ss").subtract('minutes', 15).format("HH:mm:ss");
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.save = function(notify) {
|
||||
var picker = $scope.picker;
|
||||
var model = $scope.model;
|
||||
|
||||
var date = moment(picker.date).format('YYYY-MM-DD');
|
||||
var startDate = moment(picker.startDate).format('YYYY-MM-DD');
|
||||
var endDate = moment(picker.endDate).format('YYYY-MM-DD');
|
||||
|
||||
model.status = 'scheduled';
|
||||
model.scheduling = {};
|
||||
model.scheduling.start = moment(date + 'T' + picker.start).toDate();
|
||||
model.scheduling.end = moment(date + 'T' + picker.end).toDate();
|
||||
model.scheduling.start = moment(startDate + 'T' + picker.startTime).toDate();
|
||||
model.scheduling.end = moment(endDate + 'T' + picker.endTime).toDate();
|
||||
|
||||
model._notify = notify;
|
||||
|
||||
Workorders.create(model, function(result) {
|
||||
$location.path("/workorders/" + result._id);
|
||||
@ -368,6 +562,14 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie
|
||||
var criteria = {};
|
||||
|
||||
Users.index(criteria, function(result) {
|
||||
result.sort(function(a,b) {
|
||||
var r = a.name.first.localeCompare(b.name.first);
|
||||
if (r == 0) {
|
||||
r = a.name.last.localeCompare(b.name.last);
|
||||
}
|
||||
return r;
|
||||
});
|
||||
|
||||
$scope.allUsers = result;
|
||||
|
||||
$scope.usersMap = {};
|
||||
@ -379,6 +581,13 @@ biomed.WorkorderAddCtrl = function($scope, $location, Workorders, Schedule, Clie
|
||||
}
|
||||
|
||||
biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule, Users) {
|
||||
$scope.emailsOptions = {
|
||||
'multiple': true,
|
||||
'simple_tags': true,
|
||||
'tags': [],
|
||||
'formatNoMatches': function() { return 'Type an e-mail address and press return to add it.'; }
|
||||
};
|
||||
|
||||
$scope.group = 'all';
|
||||
$scope.route = $routeParams;
|
||||
$scope.loading = true;
|
||||
@ -390,8 +599,13 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
|
||||
$scope.master = Workorders.get($routeParams, function() {
|
||||
$scope.loading = false;
|
||||
|
||||
if ($scope.master.reason == "Meeting") {
|
||||
$scope.workorderType = "meeting";
|
||||
}
|
||||
});
|
||||
|
||||
$scope.emails = createController();
|
||||
$scope.status = createController();
|
||||
$scope.remarks = createController();
|
||||
$scope.scheduling = createSchedulingController();
|
||||
@ -410,7 +624,9 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
$scope.editing = true;
|
||||
}
|
||||
},
|
||||
save: function() {
|
||||
save: function(notify) {
|
||||
controller.model._notify = notify;
|
||||
|
||||
Workorders.update({id: $scope.master._id}, controller.model);
|
||||
angular.copy(controller.model, $scope.master);
|
||||
controller.visible = false;
|
||||
@ -434,9 +650,11 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
if (!$scope.editing) {
|
||||
angular.copy($scope.master, controller.model);
|
||||
|
||||
controller.date = moment(controller.model.scheduling.start).startOf('day').toDate();
|
||||
controller.start = moment(controller.model.scheduling.start).format('HH:mm:ss');
|
||||
controller.end = moment(controller.model.scheduling.end).format('HH:mm:ss');
|
||||
controller.startDate = moment(controller.model.scheduling.start).startOf('day').toDate();
|
||||
controller.endDate = moment(controller.model.scheduling.end).startOf('day').toDate();
|
||||
|
||||
controller.startTime = moment(controller.model.scheduling.start).format('HH:mm:ss');
|
||||
controller.endTime = moment(controller.model.scheduling.end).format('HH:mm:ss');
|
||||
|
||||
controller.techs = controller.model.techs.map(function(t) { return t._id; });
|
||||
|
||||
@ -444,13 +662,17 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
$scope.editing = true;
|
||||
}
|
||||
},
|
||||
save: function() {
|
||||
var date = moment(controller.date).format('YYYY-MM-DD');
|
||||
controller.model.scheduling.start = moment(date + 'T' + controller.start).toDate();
|
||||
controller.model.scheduling.end = moment(date + 'T' + controller.end).toDate();
|
||||
save: function(notify) {
|
||||
var startDate = moment(controller.startDate).format('YYYY-MM-DD');
|
||||
var endDate = moment(controller.endDate).format('YYYY-MM-DD');
|
||||
|
||||
controller.model.scheduling.start = moment(startDate + 'T' + controller.startTime).toDate();
|
||||
controller.model.scheduling.end = moment(endDate + 'T' + controller.endTime).toDate();
|
||||
|
||||
controller.model.techs = controller.techs.map(function(t) { return $scope.usersMap[t]; });
|
||||
|
||||
controller.model._notify = notify;
|
||||
|
||||
Workorders.update({id: $scope.master._id}, controller.model);
|
||||
angular.copy(controller.model, $scope.master);
|
||||
controller.visible = false;
|
||||
@ -466,15 +688,80 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
};
|
||||
|
||||
|
||||
$scope.$watch('scheduling.date', function() {
|
||||
function convertToDate(date, time) {
|
||||
return moment(moment(date).format('YYYY-MM-DD') + 'T' + time).toDate();
|
||||
}
|
||||
|
||||
function datesOverlap() {
|
||||
var start = convertToDate($scope.scheduling.startDate, $scope.scheduling.startTime);
|
||||
var end = convertToDate($scope.scheduling.endDate, $scope.scheduling.endTime);
|
||||
return start >= end;
|
||||
}
|
||||
|
||||
function updateDuration() {
|
||||
var start = convertToDate($scope.scheduling.startDate, $scope.scheduling.startTime);
|
||||
var end = convertToDate($scope.scheduling.endDate, $scope.scheduling.endTime);
|
||||
|
||||
var duration = moment.duration(end - start);
|
||||
|
||||
var days = duration.days()
|
||||
var hours = duration.hours();
|
||||
var minutes = duration.minutes();
|
||||
|
||||
var result = "";
|
||||
|
||||
if (days == 1) {
|
||||
result += "1 Day ";
|
||||
}
|
||||
if (days > 1) {
|
||||
result += days + " Days ";
|
||||
}
|
||||
if (hours == 1) {
|
||||
result += "1 Hour ";
|
||||
}
|
||||
if (hours > 1) {
|
||||
result += hours + " Hours ";
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result += minutes + " Minutes";
|
||||
}
|
||||
|
||||
$scope.scheduling.duration = result;
|
||||
}
|
||||
|
||||
$scope.$watch('scheduling.startDate', function() {
|
||||
Schedule.index({
|
||||
date: $scope.scheduling.date.toJSON()
|
||||
date: $scope.scheduling.startDate.toJSON()
|
||||
}, function(result) {
|
||||
$scope.scheduling.schedule = result;
|
||||
});
|
||||
|
||||
if (datesOverlap()) {
|
||||
$scope.scheduling.endDate = $scope.scheduling.startDate;
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.$watch('scheduling.endDate', function() {
|
||||
if (datesOverlap()) {
|
||||
$scope.scheduling.startDate = $scope.scheduling.endDate;
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.$watch('scheduling.startTime', function() {
|
||||
$scope.scheduling.endTime = moment($scope.scheduling.startTime, "HH:mm:ss").add('minutes', 45).format("HH:mm:ss");
|
||||
$scope.scheduling.endDate = $scope.scheduling.startDate;
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
$scope.$watch('scheduling.endTime', function() {
|
||||
if (datesOverlap()) {
|
||||
$scope.scheduling.startTime = moment($scope.scheduling.endTime, "HH:mm:ss").subtract('minutes', 15).format("HH:mm:ss");
|
||||
}
|
||||
updateDuration();
|
||||
});
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
@ -488,6 +775,14 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
var criteria = {};
|
||||
|
||||
Users.index(criteria, function(result) {
|
||||
result.sort(function(a,b) {
|
||||
var r = a.name.first.localeCompare(b.name.first);
|
||||
if (r == 0) {
|
||||
r = a.name.last.localeCompare(b.name.last);
|
||||
}
|
||||
return r;
|
||||
});
|
||||
|
||||
$scope.allUsers = result;
|
||||
|
||||
$scope.usersMap = {};
|
||||
@ -499,7 +794,7 @@ biomed.WorkorderEditCtrl = function($scope, $routeParams, Workorders, Schedule,
|
||||
};
|
||||
|
||||
|
||||
biomed.PageCtrl = function($scope, $dialog) {
|
||||
biomed.PageCtrl = function($scope, $dialog, Account) {
|
||||
$scope.opts = {
|
||||
backdrop: true,
|
||||
keyboard: true,
|
||||
@ -514,6 +809,17 @@ biomed.PageCtrl = function($scope, $dialog) {
|
||||
var d = $dialog.dialog($scope.opts);
|
||||
d.open();
|
||||
};
|
||||
|
||||
$scope.accountHasPermission = function(perm) {
|
||||
console.log($scope);
|
||||
if ($scope.account && $scope.account.perms) {
|
||||
return $scope.account.perms.indexOf(perm) > -1;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.account = Account.get();
|
||||
};
|
||||
|
||||
biomed.MessagesCtrl = function($scope, dialog, Users, Messages) {
|
||||
|
@ -168,16 +168,16 @@ angular.module('biomed.directives', [])
|
||||
}
|
||||
|
||||
// Use native interface for touch devices
|
||||
if(isTouch && element.prop('type') === 'text') {
|
||||
// if(isTouch && element.prop('type') === 'text') {
|
||||
//
|
||||
// element.prop('type', 'date');
|
||||
// element.on('change', function(ev) {
|
||||
// scope.$apply(function () {
|
||||
// controller.$setViewValue(moment(element.val()).toDate());
|
||||
// });
|
||||
// });
|
||||
|
||||
element.prop('type', 'date');
|
||||
element.on('change', function(ev) {
|
||||
scope.$apply(function () {
|
||||
controller.$setViewValue(moment(element.val()).toDate());
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
// } else {
|
||||
|
||||
// If we have a controller (i.e. ngModelController) then wire it up
|
||||
if(controller) {
|
||||
@ -208,7 +208,7 @@ angular.module('biomed.directives', [])
|
||||
forceParse: attrs.forceParse || false
|
||||
});
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// Support add-on
|
||||
var component = element.siblings('[data-toggle="datepicker"]');
|
||||
@ -219,8 +219,143 @@ angular.module('biomed.directives', [])
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('techpicker', function() {
|
||||
.directive('techschedule', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
schedule: '=',
|
||||
date: '=',
|
||||
onEntryClick: '&'
|
||||
},
|
||||
templateUrl: '/partials/techSchedule.html',
|
||||
replace: true,
|
||||
link: function($scope, element, attrs) {
|
||||
var x, rangeDate, rangeStart, rangeEnd;
|
||||
|
||||
function setupScale() {
|
||||
x = d3.scale.linear()
|
||||
.range([0, 100])
|
||||
.domain([420, 1320])
|
||||
.clamp(true);
|
||||
}
|
||||
|
||||
setupScale();
|
||||
|
||||
var color = d3.scale.category20();
|
||||
var hourWidth = 100 / 15;
|
||||
|
||||
$scope.hourMarkers = [];
|
||||
for (var i = 7; i < 22; i++) {
|
||||
$scope.hourMarkers.push({
|
||||
date: moment({ hour: i }).toDate(),
|
||||
style: {
|
||||
left: x(i * 60) + '%',
|
||||
width: hourWidth + '%'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('schedule', function(newVal, oldVal) {
|
||||
generateDate();
|
||||
});
|
||||
|
||||
$scope.$watch('date', function(newVal, oldVal) {
|
||||
setupScale();
|
||||
});
|
||||
|
||||
function generateDate() {
|
||||
var range = moment($scope.date);
|
||||
var data = {};
|
||||
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var day = range.clone().add(i, 'days');
|
||||
var key = day.format('MM-DD-YYYY');
|
||||
var label = day.format('ddd MMM Do YYYY');
|
||||
|
||||
data[key] = {
|
||||
label: label,
|
||||
values: []
|
||||
};
|
||||
}
|
||||
|
||||
var c = 0;
|
||||
|
||||
angular.forEach($scope.schedule, function(workorder) {
|
||||
var start = moment(workorder.scheduling.start);
|
||||
var startMinutes = start.diff(start.clone().startOf('day'), 'minutes');
|
||||
|
||||
var end = moment(workorder.scheduling.end);
|
||||
var endMinutes = end.diff(end.clone().startOf('day'), 'minutes');
|
||||
|
||||
var length = end.diff(start, 'days') + 1;
|
||||
|
||||
console.log('length: ' + length + ' start: ' + startMinutes + ' end: ' + endMinutes);
|
||||
|
||||
var backgroundColor = color(c++);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
var adjStart, adjEnd;
|
||||
|
||||
var key = start.clone().add(i, 'days').format('MM-DD-YYYY');
|
||||
|
||||
if (i == 0) {
|
||||
adjStart = startMinutes;
|
||||
} else {
|
||||
adjStart = 420;
|
||||
}
|
||||
|
||||
if (i == length - 1) {
|
||||
adjEnd = endMinutes;
|
||||
} else {
|
||||
adjEnd = 1320;
|
||||
}
|
||||
|
||||
if (data[key]) {
|
||||
data[key].values.push({
|
||||
style: {
|
||||
backgroundColor: color(c),
|
||||
left: x(adjStart) + '%',
|
||||
width: (x(adjEnd) - x(adjStart)) + '%'
|
||||
},
|
||||
workorder: workorder
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
angular.forEach(workorder.techs, function(tech) {
|
||||
var key = tech.name.first + ' ' + tech.name.last;
|
||||
|
||||
if (!data[key])
|
||||
return;
|
||||
|
||||
var start = moment(workorder.scheduling.start);
|
||||
var end = moment(workorder.scheduling.end);
|
||||
|
||||
data[key].values.push({
|
||||
style: {
|
||||
backgroundColor: color(key),
|
||||
left: x(start) + "%",
|
||||
width: (x(end) - x(start)) + "%"
|
||||
},
|
||||
workorder: workorder
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
$scope.data = data;
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.filter('pretty', function() {
|
||||
return function(input) {
|
||||
return "\n" + angular.toJson(input, true);
|
||||
}
|
||||
})
|
||||
.directive('techpicker', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
@ -232,24 +367,31 @@ angular.module('biomed.directives', [])
|
||||
templateUrl: '/partials/techPicker.html',
|
||||
replace: true,
|
||||
link: function($scope, element, attrs) {
|
||||
var timePickerParser = d3.time.format('%I:%M%p');
|
||||
|
||||
var rangeStart = timePickerParser.parse('7:00am');
|
||||
var rangeEnd = timePickerParser.parse('10:00pm');
|
||||
var x, rangeDate, rangeStart, rangeEnd;
|
||||
|
||||
var x = d3.time.scale()
|
||||
.range([0, 100])
|
||||
.domain([rangeStart, rangeEnd]);
|
||||
function setupScale() {
|
||||
rangeDate = moment($scope.date).startOf('day');
|
||||
|
||||
rangeStart = moment(rangeDate).add('hours', 7);
|
||||
rangeEnd = moment(rangeDate).add('hours', 22);
|
||||
|
||||
x = d3.time.scale()
|
||||
.range([0, 100])
|
||||
.domain([rangeStart.toDate(), rangeEnd.toDate()])
|
||||
.clamp(true);
|
||||
}
|
||||
|
||||
setupScale();
|
||||
|
||||
var color = d3.scale.category20();
|
||||
|
||||
var totalHours = moment.duration(moment(rangeEnd) - moment(rangeStart)).hours();
|
||||
var totalHours = moment.duration(rangeEnd - rangeStart).hours();
|
||||
var hourWidth = 100 / totalHours;
|
||||
|
||||
$scope.hourMarkers = [];
|
||||
for (var i = 0; i < totalHours; i++) {
|
||||
var date = moment(rangeStart).add('hours', i).toDate();
|
||||
|
||||
$scope.hourMarkers.push({
|
||||
date: date,
|
||||
style: {
|
||||
@ -267,6 +409,10 @@ angular.module('biomed.directives', [])
|
||||
generateDate();
|
||||
});
|
||||
|
||||
$scope.$watch('date', function(newVal, oldVal) {
|
||||
setupScale();
|
||||
});
|
||||
|
||||
function generateDate() {
|
||||
var data = {};
|
||||
|
||||
@ -275,7 +421,10 @@ angular.module('biomed.directives', [])
|
||||
angular.forEach($scope.users, function(user) {
|
||||
var key = user.name.first + ' ' + user.name.last;
|
||||
labels.push(key);
|
||||
data[key] = [];
|
||||
data[key] = {
|
||||
id: user._id,
|
||||
values: []
|
||||
};
|
||||
});
|
||||
|
||||
labels.sort();
|
||||
@ -285,13 +434,13 @@ angular.module('biomed.directives', [])
|
||||
angular.forEach(workorder.techs, function(tech) {
|
||||
var key = tech.name.first + ' ' + tech.name.last;
|
||||
|
||||
if (!data[key])
|
||||
return;
|
||||
if (!data[key])
|
||||
return;
|
||||
|
||||
var start = moment(workorder.scheduling.start).year(1900).month(0).date(1).toDate();
|
||||
var end = moment(workorder.scheduling.end).year(1900).month(0).date(1).toDate();
|
||||
var start = moment(workorder.scheduling.start);
|
||||
var end = moment(workorder.scheduling.end);
|
||||
|
||||
data[key].push({
|
||||
data[key].values.push({
|
||||
style: {
|
||||
backgroundColor: color(key),
|
||||
left: x(start) + "%",
|
||||
@ -306,7 +455,224 @@ angular.module('biomed.directives', [])
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('uiSelect2', function ($timeout) {
|
||||
.value('uiSelect2Config', {})
|
||||
.directive('uiSelect2', ['uiSelect2Config', '$timeout', function (uiSelect2Config, $timeout) {
|
||||
var options = {};
|
||||
if (uiSelect2Config) {
|
||||
angular.extend(options, uiSelect2Config);
|
||||
}
|
||||
return {
|
||||
require: 'ngModel',
|
||||
priority: 1,
|
||||
compile: function (tElm, tAttrs) {
|
||||
var watch,
|
||||
repeatOption,
|
||||
repeatAttr,
|
||||
isSelect = tElm.is('select'),
|
||||
isMultiple = angular.isDefined(tAttrs.multiple);
|
||||
|
||||
// Enable watching of the options dataset if in use
|
||||
if (tElm.is('select')) {
|
||||
repeatOption = tElm.find( 'optgroup[ng-repeat], optgroup[data-ng-repeat], option[ng-repeat], option[data-ng-repeat]');
|
||||
|
||||
if (repeatOption.length) {
|
||||
repeatAttr = repeatOption.attr('ng-repeat') || repeatOption.attr('data-ng-repeat');
|
||||
watch = jQuery.trim(repeatAttr.split('|')[0]).split(' ').pop();
|
||||
}
|
||||
}
|
||||
|
||||
return function (scope, elm, attrs, controller) {
|
||||
// instance-specific options
|
||||
var opts = angular.extend({}, options, scope.$eval(attrs.uiSelect2));
|
||||
|
||||
/*
|
||||
Convert from Select2 view-model to Angular view-model.
|
||||
*/
|
||||
var convertToAngularModel = function(select2_data) {
|
||||
var model;
|
||||
if (opts.simple_tags) {
|
||||
model = [];
|
||||
angular.forEach(select2_data, function(value, index) {
|
||||
model.push(value.id);
|
||||
});
|
||||
} else {
|
||||
model = select2_data;
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
||||
/*
|
||||
Convert from Angular view-model to Select2 view-model.
|
||||
*/
|
||||
var convertToSelect2Model = function(angular_data) {
|
||||
var model = [];
|
||||
if (!angular_data) {
|
||||
return model;
|
||||
}
|
||||
|
||||
if (opts.simple_tags) {
|
||||
model = [];
|
||||
angular.forEach(
|
||||
angular_data,
|
||||
function(value, index) {
|
||||
model.push({'id': value, 'text': value});
|
||||
});
|
||||
} else {
|
||||
model = angular_data;
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
||||
if (isSelect) {
|
||||
// Use <select multiple> instead
|
||||
delete opts.multiple;
|
||||
delete opts.initSelection;
|
||||
} else if (isMultiple) {
|
||||
opts.multiple = true;
|
||||
}
|
||||
if (controller) {
|
||||
// Watch the model for programmatic changes
|
||||
scope.$watch(tAttrs.ngModel, function(current, old) {
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
if (current === old) {
|
||||
return;
|
||||
}
|
||||
blah();
|
||||
// controller.$render();
|
||||
}, true);
|
||||
|
||||
var blah = controller.$render = function () {
|
||||
if (isSelect) {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
} else {
|
||||
if (opts.multiple) {
|
||||
var viewValue = controller.$viewValue;
|
||||
if (angular.isString(viewValue)) {
|
||||
viewValue = viewValue.split(',');
|
||||
}
|
||||
elm.select2(
|
||||
'data', convertToSelect2Model(viewValue));
|
||||
} else {
|
||||
if (angular.isObject(controller.$viewValue)) {
|
||||
elm.select2('data', controller.$viewValue);
|
||||
} else if (!controller.$viewValue) {
|
||||
elm.select2('data', null);
|
||||
} else {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Watch the options dataset for changes
|
||||
if (watch) {
|
||||
scope.$watch(watch, function (newVal, oldVal, scope) {
|
||||
if (angular.equals(newVal, oldVal)) {
|
||||
return;
|
||||
}
|
||||
// Delayed so that the options have time to be rendered
|
||||
$timeout(function () {
|
||||
elm.select2('val', controller.$viewValue);
|
||||
// Refresh angular to remove the superfluous option
|
||||
elm.trigger('change');
|
||||
if(newVal && !oldVal && controller.$setPristine) {
|
||||
controller.$setPristine(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Update valid and dirty statuses
|
||||
controller.$parsers.push(function (value) {
|
||||
var div = elm.prev();
|
||||
div
|
||||
.toggleClass('ng-invalid', !controller.$valid)
|
||||
.toggleClass('ng-valid', controller.$valid)
|
||||
.toggleClass('ng-invalid-required', !controller.$valid)
|
||||
.toggleClass('ng-valid-required', controller.$valid)
|
||||
.toggleClass('ng-dirty', controller.$dirty)
|
||||
.toggleClass('ng-pristine', controller.$pristine);
|
||||
return value;
|
||||
});
|
||||
|
||||
if (!isSelect) {
|
||||
// Set the view and model value and update the angular template manually for the ajax/multiple select2.
|
||||
elm.bind("change", function (e) {
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
if (scope.$$phase || scope.$root.$$phase) {
|
||||
return;
|
||||
}
|
||||
scope.$apply(function () {
|
||||
controller.$setViewValue(
|
||||
convertToAngularModel(elm.select2('data')));
|
||||
});
|
||||
});
|
||||
|
||||
if (opts.initSelection) {
|
||||
var initSelection = opts.initSelection;
|
||||
opts.initSelection = function (element, callback) {
|
||||
initSelection(element, function (value) {
|
||||
var isPristine = controller.$pristine;
|
||||
controller.$setViewValue(convertToAngularModel(value));
|
||||
callback(value);
|
||||
if (isPristine) {
|
||||
controller.$setPristine();
|
||||
}
|
||||
elm.prev().toggleClass('ng-pristine', controller.$pristine);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elm.bind("$destroy", function() {
|
||||
elm.select2("destroy");
|
||||
});
|
||||
|
||||
attrs.$observe('disabled', function (value) {
|
||||
elm.select2('enable', !value);
|
||||
});
|
||||
|
||||
attrs.$observe('readonly', function (value) {
|
||||
elm.select2('readonly', !!value);
|
||||
});
|
||||
|
||||
if (attrs.ngMultiple) {
|
||||
scope.$watch(attrs.ngMultiple, function(newVal) {
|
||||
attrs.$set('multiple', !!newVal);
|
||||
elm.select2(opts);
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize the plugin late so that the injected DOM does not disrupt the template compiler
|
||||
$timeout(function () {
|
||||
elm.select2(opts);
|
||||
|
||||
// Set initial value - I'm not sure about this but it seems to need to be there
|
||||
elm.select2('data', controller.$modelValue);
|
||||
// important!
|
||||
controller.$render();
|
||||
|
||||
// Not sure if I should just check for !isSelect OR if I should check for 'tags' key
|
||||
if (!opts.initSelection && !isSelect) {
|
||||
var isPristine = controller.$pristine;
|
||||
controller.$setViewValue(
|
||||
convertToAngularModel(elm.select2('data'))
|
||||
);
|
||||
if (isPristine) {
|
||||
controller.$setPristine();
|
||||
}
|
||||
elm.prev().toggleClass('ng-pristine', controller.$pristine);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
}])
|
||||
.directive('uiSelect2-old', function ($timeout) {
|
||||
var options = {};
|
||||
|
||||
return {
|
||||
@ -421,4 +787,4 @@ angular.module('biomed.directives', [])
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -12,5 +12,13 @@ angular.module('biomed.filters', [])
|
||||
return function(time) {
|
||||
return moment(time).format('h:mma');
|
||||
};
|
||||
})
|
||||
.filter('email', function() {
|
||||
return function(email) {
|
||||
var parts = email.split("@", 2);
|
||||
if (parts[1].toLowerCase() == "atlanticbiomedical.com")
|
||||
return parts[0] + "@";
|
||||
else
|
||||
return email;
|
||||
}
|
||||
});
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -25,9 +25,13 @@ angular.module('biomed.services', [])
|
||||
});
|
||||
})
|
||||
.factory("Users", function($resource) {
|
||||
return $resource('/api/users', { },
|
||||
return $resource('/api/users/:id/:cmd',
|
||||
{ id: "@id", cmd: "@cmd" },
|
||||
{
|
||||
index: { method: 'GET', isArray: true },
|
||||
details: { method: 'GET', params: { cmd: 'details' }, isArray: true },
|
||||
create: { method: 'POST', params: {} },
|
||||
update: { method: 'POST', params: { id: 0 } },
|
||||
});
|
||||
})
|
||||
.factory("Schedule", function($resource) {
|
||||
@ -112,4 +116,4 @@ angular.module('biomed.services', [])
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,8 @@
|
||||
<header ng-hide="loading">
|
||||
<h1>{{master.name}}</h1>
|
||||
<p class="lead">{{master.identifier}}</p>
|
||||
<a href="/workorders/add?clientId={{master._id}}">Create new Workorder</a>
|
||||
<a class="btn btn-primary" href="/workorders/add?clientId={{master._id}}">Create new Workorder</a>
|
||||
<a class="btn" href="/workorders/add?workorderType=meeting&clientId={{master._id}}">Create new Meeting</a>
|
||||
</header>
|
||||
<div ng-hide="loading" class="tabbable">
|
||||
<div class="tab-content">
|
||||
@ -214,7 +215,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div class="form-section" ng-show="accountHasPermission('system.admin')">
|
||||
<div class="section-label">Other</div>
|
||||
<div class="section-container">
|
||||
<button ng-click="other.destroy()" type="button" class="btn btn-danger">Remove client</button>
|
||||
@ -289,21 +290,33 @@
|
||||
<table class="biomed-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">Device ID</th>
|
||||
<th style="width: 15%">Device</th>
|
||||
<th style="width: 15%">Make</th>
|
||||
<th style="width: 15%">Model</th>
|
||||
<th style="width: 15%">Serial No.</th>
|
||||
<th style="width: 7%">Device ID</th>
|
||||
<th style="width: 6%">Device</th>
|
||||
<th style="width: 5%">Make</th>
|
||||
<th style="width: 5%">Model</th>
|
||||
<th style="width: 5%">Serial No.</th>
|
||||
<th style="width: 8%">Purchase Date</th>
|
||||
<th style="width: 6%">Warranty Expiration</th>
|
||||
<th style="width: 8%">PM Test</th>
|
||||
<th style="width: 4%">Room #</th>
|
||||
<th style="width: 4%">PO Number</th>
|
||||
<th style="width: 4%">Move to</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-hide="tags.length"><td colspan="4" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-hide="tags.length"><td colspan="11" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-repeat="tag in tags">
|
||||
<td><a href="http://n.atlb.co/{{tag._id}}">{{tag.data.clientDeviceId}} - (Tag:{{tag._id}})</a></td>
|
||||
<td>{{tag.data.device}}</td>
|
||||
<td>{{tag.data.make}}</td>
|
||||
<td>{{tag.data.model}}</td>
|
||||
<td>{{tag.data.serialNumber}}</td>
|
||||
<td>{{tag.data.purchaseDate}}</td>
|
||||
<td>{{tag.data.deviceWarrantyExpiration}}</td>
|
||||
<td>{{tag.data.test}}</td>
|
||||
<td>{{tag.data.roomNumber}}</td>
|
||||
<td>{{tag.data.poNumber}}</td>
|
||||
<td>{{tag.data.MoveTo}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -355,6 +368,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b>Notice:</b>
|
||||
<p>Changes to the notes for a client does not automatically update every workorder that currently exists for the client. Only new workorders will contain the changed / updated notes. If you need to update the notes for a specific workorder you should go to the work order and re-save the workorder. This will push the updated notes to the techs calendar.</p>
|
||||
</div>
|
||||
|
@ -70,6 +70,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button ng-click="send()" class="btn btn-primary" >Send</button>
|
||||
<button ng-click="send()" class="btn btn-primary">Send</button>
|
||||
<button ng-click="cancel()" class="btn" >Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,7 +9,8 @@
|
||||
<div class="span12">
|
||||
<div class="toolbelt">
|
||||
<a href="/workorders/add" class="btn btn-primary">Create new Workorder</a>
|
||||
<a href="/schedule/pms" class="btn btn-primary">View PMs</a>
|
||||
<a href="/workorders/add?workorderType=meeting" class="btn">Create new Meeting</a>
|
||||
<a href="/schedule/pms" class="btn">View PMs</a>
|
||||
<div class="pull-right">
|
||||
<span class="toolbelt-text">Group: </span>
|
||||
<div class="input-append">
|
||||
@ -31,4 +32,4 @@
|
||||
date="date"
|
||||
on-entry-click="onEntryClick(entry)"></techpicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,9 +12,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div ng-repeat="(name, values) in data" class="tech">
|
||||
<div class="tech-label">{{name}}</div>
|
||||
<div class="tech-label"><a href="/techs/{{values.id}}">{{name}}</a></div>
|
||||
<div class="enteries">
|
||||
<div ng-repeat="entry in values" ng-style="entry.style" class="entry" ng-click="onEntryClick({entry: entry})" title="{{entry.workorder.client.name}} ({{entry.workorder.client.identifier}}) - {{entry.workorder.client.address.city}}">{{entry.workorder.client.identifier}}</div>
|
||||
<div ng-repeat="entry in values.values" ng-style="entry.style" class="entry" ng-click="onEntryClick({entry: entry})" title="{{entry.workorder.client.name}} ({{entry.workorder.client.identifier}}) - {{entry.workorder.client.address.city}}">{{entry.workorder.client.identifier}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
20
public/partials/techSchedule.html
Normal file
20
public/partials/techSchedule.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div class="techpicker">
|
||||
<div class="hour-labels">
|
||||
<div ng-repeat="hour in hourMarkers" class="hour-label" ng-style="hour.style">
|
||||
{{ hour.date | date:'h a'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="schedule">
|
||||
<div class="hour-markers">
|
||||
<div ng-repeat="hour in hourMarkers" class="marker" ng-style="hour.style">
|
||||
<div class="half-hour-marker"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-repeat="(name, values) in data" class="tech">
|
||||
<div class="tech-label text-right">{{values.label}}</div>
|
||||
<div class="enteries">
|
||||
<div ng-repeat="entry in values.values" ng-style="entry.style" class="entry" ng-click="onEntryClick({entry: entry})" title="{{entry.workorder.client.name}} ({{entry.workorder.client.identifier}}) - {{entry.workorder.client.address.city}}">{{entry.workorder.client.identifier}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
24
public/partials/techs/schedule.html
Normal file
24
public/partials/techs/schedule.html
Normal file
@ -0,0 +1,24 @@
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/clients"><i class="icon-calendar"></i> Schedule</a><li>
|
||||
</ul>
|
||||
<header>
|
||||
<h1>Schedule for {{tech.name.first}} {{tech.name.last}}</h1>
|
||||
</header>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="toolbelt">
|
||||
<div class="pull-right"
|
||||
<span class="toolbelt-text">Date: </span>
|
||||
<div class="input-append">
|
||||
<input ng-model="date" datepicker type="text" class="input-medium">
|
||||
<span class="add-on"><i class="icon-calendar"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<techschedule
|
||||
schedule="schedule"
|
||||
date="date"
|
||||
on-entry-click="onEntryClick(entry)"></techschedule>
|
||||
</div>
|
||||
</div>
|
61
public/partials/users/index.html
Normal file
61
public/partials/users/index.html
Normal file
@ -0,0 +1,61 @@
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/users"><i class="icon-briefcase"></i> Admin</a><li>
|
||||
</ul>
|
||||
<header>
|
||||
<h1>Admin</h1>
|
||||
</header>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="toolbelt">
|
||||
<div class="pull-right">
|
||||
<span class="toolbelt-text">Search:</span>
|
||||
<div class="input-append">
|
||||
<input type="text" ng-model="query" class="input-large" placeholder="Search">
|
||||
<span class="add-on"><i class="icon-search"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="biomed-table users" infinite-scroll="addItems()" can-load="canLoad" threshold="300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2"></th>
|
||||
<th colspan="5">Groups</th>
|
||||
<th colspan="4">Permissions</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width: 15%">Name</th>
|
||||
<th style="width: 7%">E-Mail</th>
|
||||
<th style="width: 5%" class="group-start">All</th>
|
||||
<th style="width: 5%">Biomed</th>
|
||||
<th style="width: 5%">Ice</th>
|
||||
<th style="width: 5%">Others</th>
|
||||
<th style="width: 5%">Sales</th>
|
||||
<th style="width: 5%" class="group-start">Portal</th>
|
||||
<th style="width: 5%">Tags</th>
|
||||
<th style="width: 5%">Messages</th>
|
||||
<th style="width: 5%">Admin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-show="loading"><td colspan="11" class="table-loading"><i class="loader"></i></td></tr>
|
||||
<tr ng-hide="loading || users.length"><td colspan="11" class="table-message">There is no information to display.</td></tr>
|
||||
<tr ng-hide="loading" ng-repeat="user in users">
|
||||
<td class="name">{{user.name.first}} {{user.name.last}} <span class="new" ng-show="isNew(user)">NEW</span></td>
|
||||
<td class="email"><a href="mailto:{{user.email}}">{{user.email | email}}</a></td>
|
||||
|
||||
<td class="group-start {{ checkGroup(user, 'all') }}"><a ng-click="toggleGroup(user, 'all')"><i ng-class="{ 'icon-ok': checkGroup(user, 'all'), 'icon-remove': !checkGroup(user, 'all')}"></i></a></td>
|
||||
<td class="{{ checkGroup(user, 'biomed') }}"><a ng-click="toggleGroup(user, 'biomed')"><i ng-class="{ 'icon-ok': checkGroup(user, 'biomed'), 'icon-remove': !checkGroup(user, 'biomed')}"></i></a></td>
|
||||
<td class="{{ checkGroup(user, 'ice') }}"><a ng-click="toggleGroup(user, 'ice')"><i ng-class="{ 'icon-ok': checkGroup(user, 'ice'), 'icon-remove': !checkGroup(user, 'ice')}"></i></a></td>
|
||||
<td class="{{ checkGroup(user, 'others') }}"><a ng-click="toggleGroup(user, 'others')"><i ng-class="{ 'icon-ok': checkGroup(user, 'others'), 'icon-remove': !checkGroup(user, 'others')}"></i></a></td>
|
||||
<td class="{{ checkGroup(user, 'sales') }}"><a ng-click="toggleGroup(user, 'sales')"><i ng-class="{ 'icon-ok': checkGroup(user, 'sales'), 'icon-remove': !checkGroup(user, 'sales')}"></i></a></td>
|
||||
<td class="group-start {{ checkPerm(user, 'system.login') }}"><a ng-click="togglePerm(user, 'system.login')"><i ng-class="{ 'icon-ok': checkPerm(user, 'system.login'), 'icon-remove': !checkPerm(user, 'system.login')}"></i></a></td>
|
||||
<td class="{{ checkPerm(user, 'system.tags') }}"><a ng-click="togglePerm(user, 'system.tags')"><i ng-class="{ 'icon-ok': checkPerm(user, 'system.tags'), 'icon-remove': !checkPerm(user, 'system.tags')}"></i></a></td>
|
||||
<td class="{{ checkPerm(user, 'messages.receive') }}"><a ng-click="togglePerm(user, 'messages.receive')"><i ng-class="{ 'icon-ok': checkPerm(user, 'messages.receive'), 'icon-remove': !checkPerm(user, 'messages.receive')}"></i></a></td>
|
||||
<td class="{{ checkPerm(user, 'system.admin') }}"><a ng-click="togglePerm(user, 'system.admin')"><i ng-class="{ 'icon-ok': checkPerm(user, 'system.admin'), 'icon-remove': !checkPerm(user, 'system.admin')}"></i></a></td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
@ -1,10 +1,12 @@
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/clients"><i class="icon-briefcase"></i> Workorders</a><span class="divider"></span><li>
|
||||
<li ng-hide="loading" class="active">New Workorder<li>
|
||||
<li ng-hide="loading || workorderType == 'meeting'" class="active">New Workorder<li>
|
||||
<li ng-hide="loading || workorderType != 'meeting'" class="active">New Meeting</li>
|
||||
</ul>
|
||||
|
||||
<header>
|
||||
<h1>New Workorder</h1>
|
||||
<h1 ng-show="workorderType != 'meeting'">New Workorder</h1>
|
||||
<h1 ng-show="workorderType == 'meeting'">New Meeting</h1>
|
||||
</header>
|
||||
<div class="form">
|
||||
<div class="form-section">
|
||||
@ -19,6 +21,12 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Additional E-Mails</label>
|
||||
<div class="controls">
|
||||
<input type="text" ui-select2="emailsOptions" ng-model="model.emails" class="input-xxlarge" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -30,7 +38,7 @@
|
||||
<div class="control-group">
|
||||
<label class="control-label">Reason</label>
|
||||
<div class="controls">
|
||||
<select ng-model="model.reason" name="reason" class="input-xlarge" ng-disabled="{{workorderType == 'pm'}}">
|
||||
<select ng-model="model.reason" name="reason" class="input-xlarge" ng-disabled="{{workorderType == 'pm' || workorderType == 'meeting'}}">
|
||||
<option value="Add New Equipment">Add New Equipment</option>
|
||||
<option value="As Directed">As Directed</option>
|
||||
<option value="Autoclave Repair">Autoclave Repair</option>
|
||||
@ -38,6 +46,7 @@
|
||||
<option value="Delivery">Delivery</option>
|
||||
<option value="Diagnose Problem">Diagnose Problem</option>
|
||||
<option value="Install Parts">Install Parts</option>
|
||||
<option value="Meeting">Meeting</option>
|
||||
<option value="New Opportunity">New Opportunity</option>
|
||||
<option value="Off">Off</option>
|
||||
<option value="PM Reschedule">PM Reschedule</option>
|
||||
@ -51,18 +60,23 @@
|
||||
<label class="control-label">Maintenance Type</label>
|
||||
<div class="controls">
|
||||
<select ng-model="model.maintenanceType" name="maintenanceType" class="input-xlarge" ng-disabled="{{workorderType == 'pm'}}">
|
||||
<option value="anesthesia">anesthesia</option>
|
||||
<option value="annual">annual</option>
|
||||
<option value="ert">ert</option>
|
||||
<option value="imaging">imaging</option>
|
||||
<option value="medgas">medgas</option>
|
||||
<option value="neptune">neptune</option>
|
||||
<option value="quarterly">quarterly</option>
|
||||
<option value="rae">rae</option>
|
||||
<option value="semi">semi</option>
|
||||
<option value="sterilizer">sterilizer</option>
|
||||
<option value="tg">tg</option>
|
||||
<option value="legacy" disabled>legacy</option>
|
||||
<option value="Anesthesia">Anesthesia</option>
|
||||
<option value="Annual">Annual</option>
|
||||
<option value="DLLR">DLLR</option>
|
||||
<option value="ERT">ERT</option>
|
||||
<option value="Ice Maker">Ice Maker</option>
|
||||
<option value="Imaging">Imaging</option>
|
||||
<option value="Medical Device">Medical Device</option>
|
||||
<option value="Medical Gas Systems">Medical Gas Systems</option>
|
||||
<option value="N2O Trace Gas">N2O Trace Gas</option>
|
||||
<option value="Quarterly">Quarterly</option>
|
||||
<option value="RAE">RAE</option>
|
||||
<option value="Semi">Semi</option>
|
||||
<option value="Sterilizer -F">Sterilizer -F</option>
|
||||
<option value="Sterilizer - TT">Sterilizer - TT</option>
|
||||
<option value="Vaporizer">Vaporizer</option>
|
||||
<option value="Waste Management System">Waste Management System</option>
|
||||
<option value="legacy" disabled>legacy</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,86 +96,161 @@
|
||||
<div class="control-group">
|
||||
<label class="control-label">Date</label>
|
||||
<div class="controls">
|
||||
<input ng-model="picker.date" datepicker type="text" class="input-small">
|
||||
<select ng-model="picker.start" name="start" class="input-small">
|
||||
<option value="05:00:00">5:00am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<span><input ng-model="picker.startDate" datepicker type="text" class="input-small"></span>
|
||||
<select ng-model="picker.startTime" name="start" class="input-small">
|
||||
<option value="05:00:00">5:00am</option>
|
||||
<option value="05:15:00">5:15am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="05:45:00">5:45am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:15:00">6:15am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="06:45:00">6:45am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:15:00">7:15am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="07:45:00">7:45am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:15:00">8:15am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="08:45:00">8:45am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:15:00">9:15am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="09:45:00">9:45am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:15:00">10:15am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="10:45:00">10:45am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:15:00">11:15am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="11:45:00">11:45am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:15:00">12:15pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="12:45:00">12:45pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:15:00">1:15pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="13:45:00">1:45pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:15:00">2:15pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="14:45:00">2:45pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:15:00">3:15pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="15:45:00">3:45pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:15:00">4:15pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="16:45:00">4:45pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:15:00">5:15pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="17:45:00">5:45pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:15:00">6:15pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="18:45:00">6:45pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:15:00">7:15pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="19:45:00">7:45pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:15:00">8:15pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="20:45:00">8:45pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:15:00">9:15pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="21:45:00">9:45pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
</select>
|
||||
<span>to</span>
|
||||
<select ng-model="picker.end" name="end" class="input-small">
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<span><input ng-model="picker.endDate" datepicker type="text" class="input-small"></span>
|
||||
<select ng-model="picker.endTime" name="end" class="input-small">
|
||||
<option value="05:15:00">5:15am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="05:45:00">5:45am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:15:00">6:15am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="06:45:00">6:45am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:15:00">7:15am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="07:45:00">7:45am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:15:00">8:15am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="08:45:00">8:45am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:15:00">9:15am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="09:45:00">9:45am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:15:00">10:15am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="10:45:00">10:45am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:15:00">11:15am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="11:45:00">11:45am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:15:00">12:15pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="12:45:00">12:45pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:15:00">1:15pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="13:45:00">1:45pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:15:00">2:15pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="14:45:00">2:45pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:15:00">3:15pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="15:45:00">3:45pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:15:00">4:15pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="16:45:00">4:45pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:15:00">5:15pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="17:45:00">5:45pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:15:00">6:15pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="18:45:00">6:45pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:15:00">7:15pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="19:45:00">7:45pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:15:00">8:15pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="20:45:00">8:45pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:15:00">9:15pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="21:45:00">9:45pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<option value="22:15:00">10:15pm</option>
|
||||
<option value="22:30:00">10:30pm</option>
|
||||
<option value="22:45:00">10:45pm</option>
|
||||
</select>
|
||||
<span>{{picker.duration}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Techs</label>
|
||||
<div class="control-group">
|
||||
<label ng-show="workorderType != 'meeting'" class="control-label">Techs</label>
|
||||
<label ng-show="workorderType == 'meeting'" class="control-label">Attendees</label>
|
||||
<div class="controls">
|
||||
<select multiple ui-select2 ng-model="model.techs" data-placeholder="Choose a Tech - Check the schedule below before scheduling." class="input-xxlarge">
|
||||
<select multiple ui-select2 ng-model="model.techs" data-placeholder="Choose Employee(s) - Check the schedule below before scheduling." class="input-xxlarge">
|
||||
<option ng-repeat="tech in allUsers" value="{{tech._id}}">{{tech.name.first}} {{tech.name.last}}</option>
|
||||
</select>
|
||||
</div>
|
||||
@ -177,17 +266,17 @@
|
||||
<techpicker
|
||||
users="users"
|
||||
schedule="schedule"
|
||||
date="picker.date"
|
||||
start="picker.start"
|
||||
end="picker.end"></techpicker>
|
||||
date="picker.startDate"
|
||||
start="picker.startTime"
|
||||
end="picker.endTime"></techpicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div class="section-label"> </div>
|
||||
<div class="section-container">
|
||||
<button ng-click="save()" type="button" class="btn btn-primary">Save</button>
|
||||
|
||||
<button ng-click="save(false)" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="save(true)" type="button" class="btn" disabled>Save & Notify</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,6 +6,8 @@
|
||||
<header ng-hide="loading">
|
||||
<h1>#{{master.biomedId}} - {{master.reason}}</h1>
|
||||
<p class="lead"><a ng-href="/clients/{{master.client._id}}">{{master.client.name}} ({{master.client.identifier}})</a></p>
|
||||
<div ng-show="master.createdBy">Created By: <b>{{master.createdBy.name.first}} {{master.createdBy.name.last}}</b> On <b>{{master.createdOn | date}} {{master.createdOn | time}}</b></div>
|
||||
<div ng-show="master.modifiedBy">Last Modified By: <b>{{master.modifiedBy.name.first}} {{master.modifiedBy.name.last}}</b> On <b>{{master.modifiedOn | date}} {{master.modifiedOn | time}}</b></div>
|
||||
</header>
|
||||
<div ng-hide="loading" class="tabbable">
|
||||
<div class="tab-content">
|
||||
@ -26,16 +28,42 @@
|
||||
<option value="invoiced">Invoiced</option>
|
||||
<option value="paid">Paid</option>
|
||||
<option value="submitted">Submitted</option>
|
||||
<option value="n/a">N/A</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button ng-click="status.save()" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="status.save(false)" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="status.save(true)" type="button" class="btn" disabled>Save & Notify</button>
|
||||
<button ng-click="status.reset()" type="button" class="btn">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<div class="section-label">Additional E-Mails</div>
|
||||
<div class="section-container">
|
||||
<div ng-hide="emails.visible" class="form-preview">
|
||||
<span ng-repeat="email in master.emails"><b>{{email}}</b><span ng-show="!$last">, </span></span>
|
||||
<a ng-click="emails.edit()" ng-class="{disabled: editing}">Edit</a>
|
||||
</div>
|
||||
<div ng-show="emails.visible" class="form-editor">
|
||||
<div class="control-group">
|
||||
<label class="control-label">E-Mails</label>
|
||||
<div class="controls">
|
||||
<input type="text" ui-select2="emailsOptions" ng-model="emails.model.emails" class="input-xxlarge" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button ng-click="emails.save(false)" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="emails.save(true)" type="button" class="btn" disabled>Save & Notify</button>
|
||||
<button ng-click="emails.reset()" type="button" class="btn">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<div class="section-label">Remarks</div>
|
||||
<div class="section-container">
|
||||
@ -56,6 +84,7 @@
|
||||
<option value="Delivery">Delivery</option>
|
||||
<option value="Diagnose Problem">Diagnose Problem</option>
|
||||
<option value="Install Parts">Install Parts</option>
|
||||
<option value="Meeting">Meeting</option>
|
||||
<option value="New Opportunity">New Opportunity</option>
|
||||
<option value="Off">Off</option>
|
||||
<option value="PM Reschedule">PM Reschedule</option>
|
||||
@ -68,20 +97,25 @@
|
||||
<div class="control-group" ng-show="remarks.model.reason == 'Preventive Maintenance'">
|
||||
<label class="control-label">Maintenance Type</label>
|
||||
<div class="controls">
|
||||
<select ng-model="remarks.model.maintenanceType" name="maintenanceType" class="input-xlarge">
|
||||
<option value="anesthesia">anesthesia</option>
|
||||
<option value="annual">annual</option>
|
||||
<option value="ert">ert</option>
|
||||
<option value="imaging">imaging</option>
|
||||
<option value="medgas">medgas</option>
|
||||
<option value="neptune">neptune</option>
|
||||
<option value="quarterly">quarterly</option>
|
||||
<option value="rae">rae</option>
|
||||
<option value="semi">semi</option>
|
||||
<option value="sterilizer">sterilizer</option>
|
||||
<option value="tg">tg</option>
|
||||
<option value="legacy" disabled>legacy</option>
|
||||
</select>
|
||||
<select ng-model="remarks.model.maintenanceType" name="maintenanceType" class="input-xlarge">
|
||||
<option value="Anesthesia">Anesthesia</option>
|
||||
<option value="Annual">Annual</option>
|
||||
<option value="DLLR">DLLR</option>
|
||||
<option value="ERT">ERT</option>
|
||||
<option value="Ice Maker">Ice Maker</option>
|
||||
<option value="Imaging">Imaging</option>
|
||||
<option value="Medical Device">Medical Device</option>
|
||||
<option value="Medical Gas Systems">Medical Gas Systems</option>
|
||||
<option value="N2O Trace Gas">N2O Trace Gas</option>
|
||||
<option value="Quarterly">Quarterly</option>
|
||||
<option value="RAE">RAE</option>
|
||||
<option value="Semi">Semi</option>
|
||||
<option value="Sterilizer -F">Sterilizer -F</option>
|
||||
<option value="Sterilizer - TT">Sterilizer - TT</option>
|
||||
<option value="Vaporizer">Vaporizer</option>
|
||||
<option value="Waste Management System">Waste Management System</option>
|
||||
<option value="legacy" disabled>legacy</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -92,7 +126,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button ng-click="remarks.save()" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="remarks.save(false)" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="remarks.save(true)" type="button" class="btn" disabled>Save & Notify</button>
|
||||
<button ng-click="remarks.reset()" type="button" class="btn">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -102,95 +137,169 @@
|
||||
<div class="section-label">Scheduling</div>
|
||||
<div class="section-container">
|
||||
<div ng-hide="scheduling.visible" class="form-preview">
|
||||
<strong>{{master.scheduling.start | date}}</strong><br>
|
||||
From <strong>{{master.scheduling.start | time}}</strong> to <strong>{{master.scheduling.end | time}}</strong><br>
|
||||
Techs: <strong>{{ master.techs | techs }}</strong><br>
|
||||
From <strong>{{master.scheduling.start | date}} {{master.scheduling.start | time}}</strong> to <strong>{{master.scheduling.end | date}} {{master.scheduling.end | time}}</strong><br>
|
||||
<span ng-show="workorderType != 'meeting'">Techs</span><span ng-show="workorderType == 'meeting'">Attendees</span>: <strong>{{ master.techs | techs }}</strong><br>
|
||||
<a ng-click="scheduling.edit()">Edit</a>
|
||||
</div>
|
||||
<div ng-show="scheduling.visible" class="form-editor">
|
||||
<div class="control-group">
|
||||
<label class="control-label">Date</label>
|
||||
<div class="controls">
|
||||
<input ng-model="scheduling.date" datepicker type="text" class="input-small">
|
||||
<select ng-model="scheduling.start" name="start" class="input-small">
|
||||
<option value="05:00:00">5:00am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<span><input ng-model="scheduling.startDate" datepicker type="text" class="input-small"></span>
|
||||
<select ng-model="scheduling.startTime" name="start" class="input-small">
|
||||
<option value="05:00:00">5:00am</option>
|
||||
<option value="05:15:00">5:15am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="05:45:00">5:45am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:15:00">6:15am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="06:45:00">6:45am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:15:00">7:15am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="07:45:00">7:45am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:15:00">8:15am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="08:45:00">8:45am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:15:00">9:15am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="09:45:00">9:45am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:15:00">10:15am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="10:45:00">10:45am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:15:00">11:15am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="11:45:00">11:45am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:15:00">12:15pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="12:45:00">12:45pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:15:00">1:15pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="13:45:00">1:45pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:15:00">2:15pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="14:45:00">2:45pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:15:00">3:15pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="15:45:00">3:45pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:15:00">4:15pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="16:45:00">4:45pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:15:00">5:15pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="17:45:00">5:45pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:15:00">6:15pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="18:45:00">6:45pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:15:00">7:15pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="19:45:00">7:45pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:15:00">8:15pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="20:45:00">8:45pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:15:00">9:15pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="21:45:00">9:45pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
</select>
|
||||
<span>to</span>
|
||||
<select ng-model="scheduling.end" name="end" class="input-small">
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<span><input ng-model="scheduling.endDate" datepicker type="text" class="input-small"></span>
|
||||
<select ng-model="scheduling.endTime" name="end" class="input-small">
|
||||
<option value="05:15:00">5:15am</option>
|
||||
<option value="05:30:00">5:30am</option>
|
||||
<option value="05:45:00">5:45am</option>
|
||||
<option value="06:00:00">6:00am</option>
|
||||
<option value="06:15:00">6:15am</option>
|
||||
<option value="06:30:00">6:30am</option>
|
||||
<option value="06:45:00">6:45am</option>
|
||||
<option value="07:00:00">7:00am</option>
|
||||
<option value="07:15:00">7:15am</option>
|
||||
<option value="07:30:00">7:30am</option>
|
||||
<option value="07:45:00">7:45am</option>
|
||||
<option value="08:00:00">8:00am</option>
|
||||
<option value="08:15:00">8:15am</option>
|
||||
<option value="08:30:00">8:30am</option>
|
||||
<option value="08:45:00">8:45am</option>
|
||||
<option value="09:00:00">9:00am</option>
|
||||
<option value="09:15:00">9:15am</option>
|
||||
<option value="09:30:00">9:30am</option>
|
||||
<option value="09:45:00">9:45am</option>
|
||||
<option value="10:00:00">10:00am</option>
|
||||
<option value="10:15:00">10:15am</option>
|
||||
<option value="10:30:00">10:30am</option>
|
||||
<option value="10:45:00">10:45am</option>
|
||||
<option value="11:00:00">11:00am</option>
|
||||
<option value="11:15:00">11:15am</option>
|
||||
<option value="11:30:00">11:30am</option>
|
||||
<option value="11:45:00">11:45am</option>
|
||||
<option value="12:00:00">12:00pm</option>
|
||||
<option value="12:15:00">12:15pm</option>
|
||||
<option value="12:30:00">12:30pm</option>
|
||||
<option value="12:45:00">12:45pm</option>
|
||||
<option value="13:00:00">1:00pm</option>
|
||||
<option value="13:15:00">1:15pm</option>
|
||||
<option value="13:30:00">1:30pm</option>
|
||||
<option value="13:45:00">1:45pm</option>
|
||||
<option value="14:00:00">2:00pm</option>
|
||||
<option value="14:15:00">2:15pm</option>
|
||||
<option value="14:30:00">2:30pm</option>
|
||||
<option value="14:45:00">2:45pm</option>
|
||||
<option value="15:00:00">3:00pm</option>
|
||||
<option value="15:15:00">3:15pm</option>
|
||||
<option value="15:30:00">3:30pm</option>
|
||||
<option value="15:45:00">3:45pm</option>
|
||||
<option value="16:00:00">4:00pm</option>
|
||||
<option value="16:15:00">4:15pm</option>
|
||||
<option value="16:30:00">4:30pm</option>
|
||||
<option value="16:45:00">4:45pm</option>
|
||||
<option value="17:00:00">5:00pm</option>
|
||||
<option value="17:15:00">5:15pm</option>
|
||||
<option value="17:30:00">5:30pm</option>
|
||||
<option value="17:45:00">5:45pm</option>
|
||||
<option value="18:00:00">6:00pm</option>
|
||||
<option value="18:15:00">6:15pm</option>
|
||||
<option value="18:30:00">6:30pm</option>
|
||||
<option value="18:45:00">6:45pm</option>
|
||||
<option value="19:00:00">7:00pm</option>
|
||||
<option value="19:15:00">7:15pm</option>
|
||||
<option value="19:30:00">7:30pm</option>
|
||||
<option value="19:45:00">7:45pm</option>
|
||||
<option value="20:00:00">8:00pm</option>
|
||||
<option value="20:15:00">8:15pm</option>
|
||||
<option value="20:30:00">8:30pm</option>
|
||||
<option value="20:45:00">8:45pm</option>
|
||||
<option value="21:00:00">9:00pm</option>
|
||||
<option value="21:15:00">9:15pm</option>
|
||||
<option value="21:30:00">9:30pm</option>
|
||||
<option value="21:45:00">9:45pm</option>
|
||||
<option value="22:00:00">10:00pm</option>
|
||||
<option value="22:15:00">10:15pm</option>
|
||||
<option value="22:30:00">10:30pm</option>
|
||||
<option value="22:45:00">10:45pm</option>
|
||||
</select>
|
||||
<span>{{scheduling.duration}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Techs</label>
|
||||
<label class="control-label"><span ng-show="workorderType != 'meeting'">Techs</span><span ng-show="workorderType == 'meeting'">Attendees</span></label>
|
||||
<div class="controls">
|
||||
<select multiple ui-select2 ng-model="scheduling.techs" data-placeholder="Choose a Tech- Check the schedule below before scheduling" class="input-xxlarge">
|
||||
<select multiple ui-select2 ng-model="scheduling.techs" data-placeholder="Choose Employee(s) - Check the schedule below before scheduling" class="input-xxlarge">
|
||||
<option ng-repeat="tech in allUsers" value="{{tech._id}}">{{tech.name.first}} {{tech.name.last}}</option>
|
||||
</select>
|
||||
</div>
|
||||
@ -206,11 +315,12 @@
|
||||
<techpicker
|
||||
users="users"
|
||||
schedule="scheduling.schedule"
|
||||
date="scheduling.date"
|
||||
start="scheduling.start"
|
||||
end="scheduling.end"></techpicker>
|
||||
date="scheduling.startDate"
|
||||
start="scheduling.startTime"
|
||||
end="scheduling.endTime"></techpicker>
|
||||
<div class="form-actions">
|
||||
<button ng-click="scheduling.save()" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="scheduling.save(false)" type="button" class="btn btn-primary">Save</button>
|
||||
<button ng-click="scheduling.save(true)" type="button" class="btn" disabled>Save & Notify</button>
|
||||
<button ng-click="scheduling.reset()" type="button" class="btn">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -219,12 +329,9 @@
|
||||
<div class="form-section">
|
||||
<div class="section-label">Other</div>
|
||||
<div class="section-container">
|
||||
<button ng-click="destroy()" type="button" class="btn btn-danger">Remove workorder</button>
|
||||
<button ng-click="destroy()" type="button" class="btn btn-danger">Remove <span ng-show="workorderType != 'meeting'">workorder</span><span ng-show="workorderType == 'meeting'">meeting</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane form" title="History">
|
||||
No history is currently available.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,8 @@
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="toolbelt">
|
||||
<a href="/workorders/add" class="btn btn-primary">Create new workorder</a>
|
||||
<a href="/workorders/add" class="btn btn-primary">Create new workorder</a>
|
||||
<a href="/workorders/add?workorderType=meeting" class="btn">Create new meeting</a>
|
||||
<div class="pull-right">
|
||||
<div class="input-append">
|
||||
<input type="text" ng-model="query" class="input-large" placeholder="Search">
|
||||
@ -42,7 +43,7 @@
|
||||
<strong>Techs:</strong> {{ workorder.techs | techs }}<br>
|
||||
{{workorder.remarks}}
|
||||
</td>
|
||||
<td>{{workorder.client.name}} ({{workorder.client.identifier}})</td>
|
||||
<td><a ng-href="/clients/{{workorder.client._id}}">{{workorder.client.name}} ({{workorder.client.identifier}})</a></td>
|
||||
<td>{{workorder.scheduling.start | date}}</td>
|
||||
<td>{{workorder.status}}</td>
|
||||
</tr>
|
||||
|
@ -1,5 +1,18 @@
|
||||
var tags = {}
|
||||
|
||||
var fields = [
|
||||
{ field: 'device', label: 'Device' },
|
||||
{ field: 'make', label: 'Manufacture' },
|
||||
{ field: 'model', label: 'Model' },
|
||||
{ field: 'serialNumber', label: 'Serial Number' },
|
||||
{ field: 'purchaseDate', label: 'Purchase Date' },
|
||||
{ field: 'deviceWarrantyExpiration', label: 'Warranty Expiration' },
|
||||
{ field: 'test', label: 'PM Test' },
|
||||
{ field: 'roomNumber', label: 'Room #' },
|
||||
{ field: 'poNumber', label: 'PO Number' },
|
||||
{ field: 'MoveTo', label: 'Move To' }
|
||||
];
|
||||
|
||||
angular.module('tags', ['ngResource', 'biomed.directives'])
|
||||
.factory("Tag", function($resource) {
|
||||
return $resource('/api/tags');
|
||||
@ -11,6 +24,7 @@ angular.module('tags', ['ngResource', 'biomed.directives'])
|
||||
index: { method: 'GET', params: {}, isArray: true },
|
||||
});
|
||||
})
|
||||
|
||||
tags.PageCtrl = function($scope, $window, Tag, Clients) {
|
||||
console.log($window.payload)
|
||||
|
||||
@ -38,4 +52,15 @@ tags.PageCtrl = function($scope, $window, Tag, Clients) {
|
||||
alert('Your changes have been saved.');
|
||||
});
|
||||
}
|
||||
|
||||
$scope.fields = [];
|
||||
|
||||
if ($scope.tag) {
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
fields[i].value = $scope.tag[fields[i].field];
|
||||
$scope.fields.push(fields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
console.log($scope.fields);
|
||||
}
|
||||
|
13
server.js
13
server.js
@ -6,6 +6,13 @@ var env = process.env.NODE_ENV || 'development',
|
||||
config = require('./config/config')[env],
|
||||
mongoose = require('mongoose');
|
||||
|
||||
var log = require('log4node');
|
||||
log.reconfigure({
|
||||
level: 'info',
|
||||
file: 'server.log'
|
||||
});
|
||||
|
||||
log.info("----- Server Started -----");
|
||||
|
||||
// bootstrap db connection
|
||||
mongoose.set('debug', config.debug);
|
||||
@ -34,11 +41,13 @@ var auth = require('./config/auth')(app, passport);
|
||||
|
||||
var calendar = require('./config/calendar')(config);
|
||||
|
||||
var directory = require('./config/directory')(config);
|
||||
|
||||
// Bootstrap routes
|
||||
require('./config/routes')(app, auth, piler, calendar, config);
|
||||
require('./config/routes')(app, auth, piler, calendar, directory, config);
|
||||
|
||||
GLOBAL.health = 'OK'
|
||||
|
||||
var port = process.env.PORT || 8000
|
||||
server.listen(port)
|
||||
console.log('Express app started on port ' + port)
|
||||
console.log('Express app started on port ' + port)
|
||||
|
23
test.js
23
test.js
@ -1,21 +1,10 @@
|
||||
var env = process.env.NODE_ENV || 'development',
|
||||
config = require('./config/config')[env],
|
||||
fs = require('fs'),
|
||||
calendar = require('./config/calendar')(config),
|
||||
moment = require('moment');
|
||||
config = require('./config/config')[env];
|
||||
|
||||
var event = {
|
||||
summary: 'Summary',
|
||||
location: 'Location',
|
||||
start: moment().hour(5).minute(30).toDate(),
|
||||
end: moment().hour(6).minute(0).toDate(),
|
||||
attendees: [ 'akirayasha@gmail.com' ]
|
||||
};
|
||||
config.auth.accessToken = "ya29.1.AADtN_Xjt0PK6YVs8q5csiQFXQg2ZDtrVhsH6P4a5zm0mHqhGx0Nnjx4Jk68Gw";
|
||||
config.auth.refreshToken = "1/_5SkDLYmsi4XNaQyAzld-W5-GEqEqt5byH6VkI-j5QI";
|
||||
|
||||
console.log(event);
|
||||
var directory = require('./config/directory')(config);
|
||||
|
||||
calendar.scheduleEvent(event, function(err, res) {
|
||||
console.log("Result");
|
||||
console.log(err);
|
||||
console.log(res);
|
||||
});
|
||||
|
||||
directory.listUsers(function(err, result) { console.log(result); console.log(err); console.log('Done.'); });
|
||||
|
Reference in New Issue
Block a user