Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // There are a lot of uses of `default` in switch statements here.
- // This makes that ok.
- // =================
- // L I B R A R I E S
- // =================
- const ABC = require("@akitabox/constants");
- const _ = require("underscore");
- const mongoose = require("mongoose");
- // =================
- // H E L P E R S
- // =================
- const displayDates = include("src/plugins/mongoose/displayDates");
- const toJSONAsync = include("src/plugins/mongoose/toJSONAsync");
- /**
- * Model representing a user action.
- *
- * @constructs UserActionModel
- *
- * @property {String} route_name Route name - the name of the action the user took
- * @property {Date} time Timestamp of the action
- * @property {Number} status Status code returned for this request. Should be 200 unless
- * there was an error or a redirect.
- * @property {String} url_pathname URL pathname
- * @property {String} method Method: GET, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, CONNECT
- * @property {Boolean} is_api_call True if action is API call
- * @property {String} ip IP address
- * @property {Application} calling_app App that made this request
- * @property {String} email_domain Domain of the user's email address saved separately for easy
- * querying
- * @property {Account} user _id of the user taking the action's account
- * @property {Object} body Request body
- * @property {Object} query Query
- * @property {String} browser Browser used
- * @property {String} operating_system Operating System
- * @property {String} user_agent User agent
- * @property {String} action Action
- * @property {Number} page Page
- * @property {String} tab Tab
- * @property {Account} account Building owner, NOT the user
- * @property {Application} application Application
- * @property {Attachment} attachment Attachment
- * @property {Comment} comment Comment
- * @property {Commit} commit Commit
- * @property {Document} document Document
- * @property {FutureTask} future_task Future task
- * @property {Building} building Building _id
- * @property {Level} level Level
- * @property {ObjectId} portal Portal - references a building, but cannot be populated
- * @property {QRCode} qrcode QR Code
- * @property {Request} request Request
- * @property {Commit} revision Commit ID containing the revision for the document
- * @property {Role} role Role
- * @property {Tag} tag Tag
- * @property {TagCategory} tag_category Tag category
- * @property {TagCategoryValue} tag_category_value Tag category value
- * @property {Task} task Task
- * @property {PinType} pin_type Pin type
- * @property {PinTypeColor} pin_type_color Pin type color
- * @property {PinField} pin_field Pin field
- * @property {Asset} asset Asset
- * @property {Room} room Room
- * @property {PinValue} pin_value Pin value
- * @property {FMRedirect} fm_redirect FM redirect
- */
- let UserAction = new mongoose.Schema({
- // Required Fields
- route_name: { type: String, required: true, lowercase: true },
- time: { type: Date, required: true, default: Date.now },
- duration_ms: { type: Number, required: true, Min: 0 },
- status: { type: Number, required: true, default: 200 },
- url_pathname: { type: String, required: true },
- method: {
- type: String,
- required: true,
- uppercase: true,
- enum: [
- "GET",
- "POST",
- "PUT",
- "DELETE",
- "PATCH",
- "OPTIONS",
- "TRACE",
- "CONNECT",
- ],
- },
- is_api_call: { type: Boolean, required: true },
- ip: { type: String, required: true },
- // Optional Non-URL Fields
- calling_app: { type: String, ref: "Application", default: null },
- email_domain: { type: String, default: null },
- user: { type: String, ref: "Account", default: null },
- body: { type: Object, default: {} },
- query: { type: Object, default: {} },
- browser: { type: String, default: null },
- operating_system: { type: String, default: null },
- user_agent: { type: String, default: null },
- // String URL Parameters
- action: String,
- page: Number,
- tab: String,
- // Mongo ID URL Parameters
- account: { type: String, ref: "Account" },
- attachment: { type: mongoose.Schema.Types.ObjectId, ref: "Attachment" },
- application: { type: String, ref: "Application" },
- comment: { type: mongoose.Schema.Types.ObjectId, ref: "Comment" },
- commit: { type: mongoose.Schema.Types.ObjectId, ref: "Commit" },
- document: { type: mongoose.Schema.Types.ObjectId, ref: "Document" },
- future_task: { type: mongoose.Schema.Types.ObjectId, ref: "FutureTask" },
- issue_type: { type: mongoose.Schema.Types.ObjectId, ref: "IssueType" },
- building: { type: mongoose.Schema.Types.ObjectId, ref: "Building" },
- level: { type: mongoose.Schema.Types.ObjectId, ref: "Level" },
- maintenance_type: {
- type: mongoose.Schema.Types.ObjectId,
- ref: "MaintenanceType",
- },
- organization: { type: mongoose.Schema.Types.ObjectId, ref: "Organization" },
- portal: { type: mongoose.Schema.Types.ObjectId },
- qrcode: { type: mongoose.Schema.Types.ObjectId, ref: "QRCode" },
- request: { type: mongoose.Schema.Types.ObjectId, ref: "Request" },
- revision: { type: mongoose.Schema.Types.ObjectId, ref: "Commit" },
- role: { type: mongoose.Schema.Types.ObjectId, ref: "Role" },
- tag: { type: mongoose.Schema.Types.ObjectId, ref: "Tag" },
- tag_category: { type: mongoose.Schema.Types.ObjectId, ref: "TagCategory" },
- tag_category_value: {
- type: mongoose.Schema.Types.ObjectId,
- ref: "TagCategoryValue",
- },
- task: { type: mongoose.Schema.Types.ObjectId, ref: "Task" },
- trade: { type: mongoose.Schema.Types.ObjectId, ref: "Trade" },
- pin_type: { type: mongoose.Schema.Types.ObjectId, ref: "PinType" },
- pin_type_color: { type: mongoose.Schema.Types.ObjectId, ref: "PinTypeColor" },
- pin_field: { type: mongoose.Schema.Types.ObjectId, ref: "PinField" },
- asset: { type: mongoose.Schema.Types.ObjectId, ref: "Asset" },
- pin: { type: mongoose.Schema.Types.ObjectId, ref: "Pin" }, // FIXME: LEAVE THIS IN OR WE CAN'T MIGRATE ANYTHING!!!!!!!!!
- room: { type: mongoose.Schema.Types.ObjectId, ref: "Room" },
- pin_value: { type: mongoose.Schema.Types.ObjectId, ref: "PinValue" },
- fm_redirect: { type: mongoose.Schema.Types.ObjectId, ref: "FMRedirect" },
- });
- // INDICES =========================================================================================================
- UserAction.index({ route_name: 1 });
- UserAction.index({ time: -1 });
- UserAction.index({ status: 1 });
- UserAction.index({ method: 1 });
- UserAction.index({ user: 1 });
- UserAction.index({ account: 1 });
- UserAction.index({ building: 1 });
- // PLUGINS =========================================================================================================
- UserAction.plugin(toJSONAsync);
- UserAction.plugin(displayDates, {
- addDisplayAlt: true,
- });
- // VIRTUALS ========================================================================================================
- /**
- * Creates a human-readable sentence for the action performed in this user_action to be used in entity-level
- * activity feeds.
- *
- * @function getEntityActionDisplay
- * @memberof UserActionModel.prototype
- *
- * @return {String} Action HTML
- */
- UserAction.virtual("entity_action_display").get(
- function getEntityActionDisplay() {
- let importantMethods = ["PATCH", "POST", "PUT"];
- let displayHelpers = this.model("UserAction").route_name()[
- this.route_name.toUpperCase()
- ];
- if (
- !_.contains(importantMethods, this.method) ||
- this.status !== 200 ||
- _.isUndefined(displayHelpers)
- ) {
- /*
- * Do not care about GET, POST, DELETE, HEAD, OPTIONS, etc user_actions for entity activity feeds.
- * Do not care about unsuccessful requests for entity activity feeds.
- * If displayHelpers is undefined, missing route name.
- */
- return "";
- }
- let type = "entity";
- let isHtml = false;
- if ((this.method === "PATCH" || this.method === "PUT") && displayHelpers.updateActionDisplay) {
- return displayHelpers.updateActionDisplay(type, isHtml, this);
- } else if (this.method === "POST" && displayHelpers.createActionDisplay) {
- return displayHelpers.createActionDisplay(type, isHtml, this);
- }
- // We had a display helper for the route_name but not the method.
- return "";
- }
- );
- /**
- * Creates an html element for the action performed in this user_action to be used in entity-level activity feeds.
- *
- * @function getEntityActionHTML
- * @memberof UserActionModel.prototype
- *
- * @return {String} Action HTML
- */
- UserAction.virtual("entity_action_html").get(function getEntityActionHTML() {
- let importantMethods = ["PATCH", "POST", "PUT"];
- let displayHelpers = this.model("UserAction").route_name()[
- this.route_name.toUpperCase()
- ];
- if (
- !_.contains(importantMethods, this.method) ||
- this.status !== 200 ||
- _.isUndefined(displayHelpers)
- ) {
- /*
- * Do not care about GET, POST, DELETE, HEAD, OPTIONS, etc user_actions for entity activity feeds.
- * Do not care about unsuccessful requests for entity activity feeds.
- * If displayHelpers is undefined, missing route name.
- */
- return "";
- }
- let type = "entity";
- let isHtml = true;
- if ((this.method === "PATCH" || this.method === "PUT") && displayHelpers.updateActionDisplay) {
- return displayHelpers.updateActionDisplay(type, isHtml, this);
- } else if (this.method === "POST" && displayHelpers.createActionDisplay) {
- return displayHelpers.createActionDisplay(type, isHtml, this);
- }
- // We had a display helper for the route_name but not the method.
- return "";
- });
- /**
- * Creates a human-readable sentence for the action performed in this user_action to be used in building-level
- * activity feeds.
- *
- * @function getBuildingActionDisplay
- * @memberof UserActionModel.prototype
- *
- * @return {String} Action HTML
- */
- UserAction.virtual("building_action_display").get(
- function getBuildingActionDisplay() {
- let importantMethods = ["POST", "PUT", "PATCH", "DELETE"];
- let displayHelpers = this.model("UserAction").route_name()[
- this.route_name.toUpperCase()
- ];
- if (
- !_.contains(importantMethods, this.method) ||
- this.status !== 200 ||
- _.isUndefined(displayHelpers)
- ) {
- /*
- * Do not care about GET, HEAD, OPTIONS, etc user_actions for building activity feeds.
- * Do not care about unsuccessful requests for building activity feeds.
- * If displayHelpers is undefined, missing route name.
- */
- return "";
- }
- let type = "building";
- let isHtml = false;
- if (this.method === "DELETE" && displayHelpers.deleteActionDisplay) {
- return displayHelpers.deleteActionDisplay(type, isHtml, this);
- } else if (this.method === "POST" && displayHelpers.createActionDisplay) {
- return displayHelpers.createActionDisplay(type, isHtml, this);
- } else if (
- (this.method === "PUT" || this.method === "PATCH") &&
- displayHelpers.updateActionDisplay
- ) {
- return displayHelpers.updateActionDisplay(type, isHtml, this);
- }
- // We had a display helper for the route_name but not the method.
- return "";
- }
- );
- /**
- * Creates an html element for the action performed in this user_action to be used in building-level activity .
- *
- * @function getBuildingActionHTML
- * @memberof UserActionModel.prototype
- *
- * @return {String} Action HTML
- */
- UserAction.virtual("building_action_html").get(
- function getBuildingActionHTML() {
- let importantMethods = ["POST", "PUT", "PATCH", "DELETE"];
- let displayHelpers = this.model("UserAction").route_name()[
- this.route_name.toUpperCase()
- ];
- if (!_.contains(importantMethods, this.method) || this.status !== 200) {
- /*
- * Do not care about GET, HEAD, OPTIONS, etc user_actions for building activity feeds.
- * Do not care about unsuccessful requests for building activity feeds.
- */
- return "";
- } else if (_.isUndefined(displayHelpers)) {
- /*
- * Missing route name.
- * This shouldn't happen, but if it does then it's fucked and we should just go away.
- */
- return "";
- }
- let type = "building";
- let isHtml = true;
- if (this.method === "DELETE" && displayHelpers.deleteActionDisplay) {
- return displayHelpers.deleteActionDisplay(type, isHtml, this);
- } else if (this.method === "POST" && displayHelpers.createActionDisplay) {
- return displayHelpers.createActionDisplay(type, isHtml, this);
- } else if (
- (this.method === "PUT" || this.method === "PATCH") &&
- displayHelpers.updateActionDisplay
- ) {
- return displayHelpers.updateActionDisplay(type, isHtml, this);
- }
- // We had a display helper for the route_name but not the method.
- return "";
- }
- );
- // TODO account_action_display for account activity feeds
- // TODO organization_action_display for organization activity feeds
- /**
- * Returns JSON string of body.
- *
- * @function getStringifiedBody
- * @memberof UserActionModel.prototype
- *
- * @return {String} JSON string of body
- */
- UserAction.virtual("stringified_body").get(function getStringifiedBody() {
- return JSON.stringify(this.body);
- });
- /**
- * Returns JSON string of query.
- *
- * @function getStringifiedQuery
- * @memberof UserActionModel.prototype
- *
- * @return {String} JSON string of query
- */
- UserAction.virtual("stringified_query").get(function getStringifiedQuery() {
- return JSON.stringify(this.query);
- });
- /**
- * Returns true if status is 200, false otherwise.
- *
- * @function isStatusOK
- * @memberof UserActionModel.prototype
- *
- * @return {Boolean} True when status is 200
- */
- UserAction.virtual("is_200").get(function isStatusOK() {
- return this.status === 200;
- });
- /**
- * Returns true if status is not 200, false if it is.
- *
- * @function isStatusNotOK
- * @memberof UserActionModel.prototype
- *
- * @return {Boolean} True when status is not 200
- */
- UserAction.virtual("is_not_200").get(function isStatusNotOK() {
- return this.status !== 200;
- });
- /**
- * Returns true if status is 500, false otherwise.
- *
- * @function isInternalServerError
- * @memberof UserActionModel.prototype
- *
- * @return {Boolean} True when status is 500
- */
- UserAction.virtual("is_500").get(function isInternalServerError() {
- return this.status === 500;
- });
- /**
- * Returns true if user exists, false otherwise.
- *
- * @function hasUser
- * @memberof UserActionModel.prototype
- *
- * @return {Boolean} True when has user
- */
- UserAction.virtual("has_user").get(function hasUser() {
- return Boolean(this.user);
- });
- // VALIDATORS ======================================================================================================
- require("./UserAction.validators").load(UserAction);
- // STATIC METHODS ==================================================================================================
- /**
- * Gets constants associated with this model
- *
- * @returns {Object}
- */
- UserAction.static("constants", function() {
- return ABC.MODELS.USER_ACTION;
- });
- /**
- * Returns fields required to be provided by the user on creation. Called at the router level on a CREATE action.
- * If a field is not provided by the user, a 400 is returned. Other fields are required for creation but are set
- * by the application. If these fields are not set, a 500 should be returned.
- *
- * @function requiredCreateFields
- * @memberof UserActionModel
- * @static
- *
- * @return {Array} List of required create fields.
- */
- UserAction.static("requiredCreateFields", function() {
- return ["route_name", "url_pathname", "method", "is_api_call", "ip"];
- });
- /**
- * Returns fields that cannot be set (by the user or application) during creation. These fields are removed from
- * the data provided to the Model just prior to creation at the controller level.
- *
- * @function badCreateFields
- * @memberof UserActionModel
- * @static
- *
- * @return {Array} List of bad create fields
- */
- UserAction.static("badCreateFields", function() {
- return ["_id", "__v", "time"];
- });
- // badUpdateFields N/A user does not make API calls to update User Actions
- /**
- * Returns fields to populate during a query.
- *
- * @function populateFields
- * @memberof UserActionModel
- * @static
- *
- * @return {String} Fields to populate
- */
- UserAction.static("populateFields", function() {
- return (
- "asset application comment commit document future_task level pin_field pin_type + " +
- "qrcode request role room tag_category task user"
- );
- });
- /**
- * Returns object of routes and their helper functions.
- *
- * @function route_name
- * @memberof UserActionModel
- * @static
- *
- * @return {Object} Route helpers
- */
- UserAction.static("route_name", function() {
- const Asset = mongoose.model("Asset");
- const Application = mongoose.model("Application");
- const Attachment = mongoose.model("Attachment");
- const Comment = mongoose.model("Comment");
- const Document = mongoose.model("Document");
- const FutureTask = mongoose.model("FutureTask");
- const IssueType = mongoose.model("IssueType");
- const Level = mongoose.model("Level");
- const MaintenanceType = mongoose.model("MaintenanceType");
- const Organization = mongoose.model("Organization");
- const PinField = mongoose.model("PinField");
- const PinType = mongoose.model("PinType");
- const PinTypeColor = mongoose.model("PinTypeColor");
- const Building = mongoose.model("Building");
- const Request = mongoose.model("Request");
- const Role = mongoose.model("Role");
- const Room = mongoose.model("Room");
- const Tag = mongoose.model("Tag");
- const TagCategory = mongoose.model("TagCategory");
- const TagCategoryValue = mongoose.model("TagCategoryValue");
- const Task = mongoose.model("Task");
- const Trade = mongoose.model("Trade");
- // The list of accepted action names
- let routeHelpers = {
- ACCOUNT_DETAIL: {
- updateActionDisplay: function() {
- // Do not have an account-level activity feed... yet.
- return "";
- },
- // Currently do not support deleting accounts.
- },
- ACCOUNT_LIST: {
- // Accounts are created through the registration route.
- },
- ACCOUNT_SETTINGS: {
- // Route only renders account settings (account updates are made to account_detail).
- },
- APPLICATION_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- // Don't really care about the special update cases for applications at the moment.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- userAction.application,
- Application
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- Application
- );
- },
- },
- APPLICATION_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(
- type,
- isHtml,
- userAction,
- Application
- );
- },
- },
- ASSET_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- return routeHelpers.PIN_DETAIL.updateActionDisplay(
- type,
- isHtml,
- userAction,
- Asset
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Asset);
- },
- },
- ASSET_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, Asset);
- },
- },
- ASSET_VALUE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- return routeHelpers.PIN_VALUE_DETAIL.updateActionDisplay(
- type,
- isHtml,
- userAction,
- Asset
- );
- },
- /*
- * Values are not deleted through this route (deleted when parent pin field is removed from the pin
- * type).
- */
- },
- ASSET_VALUE_LIST: {
- /*
- * Values are not created through this route (created when the parent pin field is created in the pin
- * type).
- */
- },
- ATTACHMENT_DETAIL: {},
- ATTACHMENT_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- let user = userAction ? userAction.user : null;
- let username = user ? user.email : "Unknown User";
- let document = userAction.document;
- let filename = document ? document.path : `Unknown file`;
- let url = document ? `${ABC.getDesktop().URL_BASE}${document.media_uri}` : ``;
- let options = {
- target: "_blank",
- };
- if (isHtml) {
- return `${addBoldHtmlTag(isHtml, username)} added 1 ${addBoldHtmlTag(isHtml, "photo")}<br>${toHTMLAnchor(filename, url, options)}`;
- } else {
- return `${username} added 1 photo \n ${filename}`;
- }
- },
- },
- BUILDING_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Building;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.building;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) + " updated ";
- let patchString = null;
- if (userAction.method === "PATCH") {
- // PATCH, so we can guess what was changed.
- let getAlias = ABC.MODELS.BUILDING.getAlias;
- let schema = _.keys(Model.schema.paths);
- let body = _.keys(userAction.body);
- let keys = _.intersection(body, schema);
- if (_.intersection(keys, Model.addressFields()).length > 0) {
- patchString = addBoldHtmlTag(isHtml, "Address");
- } else {
- patchString = getUpdateFieldString(isHtml, keys, getAlias);
- }
- }
- switch (type) {
- // The building is the entity.
- case "entity":
- case "building":
- if (patchString) {
- actionHtml +=
- "this " +
- addBoldHtmlTag(isHtml, entityAlias) +
- "'s " +
- patchString;
- } else {
- actionHtml +=
- "this " + addBoldHtmlTag(isHtml, entityAlias) + "'s settings";
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- let Model = Building;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.building;
- let actionHtml;
- // Archived a building (unarchive is below in BUILDING_SETTINGS).
- switch (type) {
- // The building is the entity.
- case "entity":
- case "building":
- actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " archived this " +
- addBoldHtmlTag(isHtml, entityAlias);
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- },
- BUILDING_LIST: {
- createActionDisplay: function() {
- // Do not have an account- or organization-level activity feed... yet.
- return "";
- },
- },
- BUILDING_SETTINGS: {
- /*
- * Route only renders building settings (building updates are made to building_detail and other routes).
- * ... except for restoring an archived building.
- */
- createActionDisplay: function(type, isHtml, userAction) {
- // Building unarchive may be a post and land here in 'create' instead of 'update' :(
- return routeHelpers.BUILDING_SETTINGS.updateActionDisplay(
- type,
- isHtml,
- userAction
- );
- },
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Building;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.building;
- let actionHtml;
- switch (type) {
- // The building is the entity.
- case "entity":
- case "building":
- actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " restored this " +
- addBoldHtmlTag(isHtml, entityAlias);
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- },
- // Comments are queried for separately in the activity feeds.
- COMMENT_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- /*
- * entity: user updated a Note on this Item.
- * building: user updated a Note on a Item.
- */
- let Model = Comment;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.comment;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " updated a " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " on";
- if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * So just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += " this ";
- break;
- case "building":
- if (entity.entity_alias.toLowerCase() === "building") {
- actionHtml += " this ";
- } else {
- actionHtml += " a ";
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- // Fake some things so we can (try to) make a link.
- if (
- entity.entity &&
- entity[entity.entity] &&
- entity.entity_alias.toLowerCase() !== "building"
- ) {
- let _commentEntity = {
- _id: entity[entity.entity],
- };
- actionHtml += addAnchorTag(
- isHtml,
- entity.entity_alias,
- _commentEntity
- );
- } else {
- // For whatever reason, we cant make the link, so just make it bold.
- actionHtml += addBoldHtmlTag(isHtml, entity.entity_alias);
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- /*
- * Entity was deleted.
- * So just use the standard helper.
- */
- return standardDeleteActionDisplay(type, isHtml, userAction, Comment);
- },
- },
- COMMENT_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- /*
- * entity: user added a Note to this Item.
- * building: user added a Note to a Item.
- */
- let Model = Comment;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " added a " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " to";
- // Fake create the item (without saving of course).
- let _entity = new Model(userAction.body);
- if (!_entity || !_entity.entity_alias) {
- /*
- * Looks like population failed because the entity was deleted.
- * So just use the standard helper.
- */
- return standardCreateActionDisplay(type, isHtml, userAction, Model);
- }
- switch (type) {
- case "entity":
- actionHtml += " this ";
- break;
- case "building":
- if (_entity.entity_alias.toLowerCase() === "building") {
- actionHtml += " this ";
- } else {
- actionHtml += " a ";
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardCreateActionDisplay(type, isHtml, userAction, Model);
- }
- // Fake some things so we can (try to) make a link.
- if (
- _entity.entity &&
- _entity[_entity.entity] &&
- _entity.entity_alias.toLowerCase() !== "building"
- ) {
- let _commentEntity = {
- _id: _entity[_entity.entity],
- };
- actionHtml += addAnchorTag(
- isHtml,
- _entity.entity_alias,
- _commentEntity
- );
- } else {
- // For whatever reason, we cant make the link, so just make it bold.
- actionHtml += addBoldHtmlTag(isHtml, _entity.entity_alias);
- }
- return actionHtml;
- },
- },
- CONTACT_US: {},
- DEVELOPER_DOCUMENTATION: {},
- DOCUMENT_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Document;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.document;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let patchString = null;
- let name = null;
- if (entity.job || entity.step) {
- return null;
- }
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "rename":
- actionHtml += " renamed ";
- break;
- case "archive":
- actionHtml += " archived ";
- break;
- case "unarchive":
- actionHtml += " restored ";
- break;
- case "revert":
- actionHtml += " reverted ";
- break;
- case "rotate":
- actionHtml += " rotated ";
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- "the " +
- patchString +
- " of " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Document);
- },
- },
- DOCUMENT_DOWNLOAD: {},
- DOCUMENT_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return routeHelpers.UPLOAD.createActionDisplay(
- type,
- isHtml,
- userAction
- );
- },
- },
- // Tracks document views in the fac.
- DOCUMENT_VIEW: {},
- FM_REDIRECT_DETAIL: {},
- FM_REDIRECT_LIST: {},
- FORGOT_PASSWORD: {
- createActionDisplay: function() {
- /*
- * POST to forget password.
- * Do not have an account-level activity feed... yet.
- */
- return "";
- },
- },
- FUTURE_TASK_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = FutureTask;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.future_task;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let patchString = null;
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "update":
- actionHtml += " updated ";
- if (userAction.method === "PATCH") {
- // PATCH, so we can guess what was changed.
- let getAlias = ABC.MODELS.MAINTENANCE_SCHEDULE.getAlias;
- let schema = _.keys(Model.schema.paths);
- let body = _.keys(userAction.body);
- let keys = _.intersection(body, schema);
- if (
- _.intersection(keys, Model.repeatingConditionFields()).length >
- 0
- ) {
- patchString = "Frequency";
- } else {
- patchString = getUpdateFieldString(isHtml, keys, getAlias);
- }
- }
- break;
- case "cancel":
- actionHtml += " canceled ";
- break;
- case "reopen":
- actionHtml += " reopened ";
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- patchString +
- " in " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- FutureTask
- );
- },
- },
- FUTURE_TASK_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(
- type,
- isHtml,
- userAction,
- FutureTask
- );
- },
- },
- HELP: {},
- HOME: {},
- IS_AD_DOMAIN: {},
- ISSUE_TYPE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = IssueType;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.issue_type;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "archive":
- actionHtml += " archived ";
- break;
- case "restore":
- actionHtml += " restored ";
- break;
- case "update":
- actionHtml += " updated ";
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- break;
- case "building":
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, IssueType);
- },
- },
- ISSUE_TYPE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, IssueType);
- },
- },
- LANDING: {},
- LEVEL_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Level;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.level;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let patchString = null;
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- actionHtml += " updated ";
- switch (userAction.body.action) {
- case "updateDocument":
- patchString = "Floor Plan";
- break;
- default: {
- if (userAction.method !== "PATCH") {
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- // PATCH, so we can guess what was changed.
- let getAlias = ABC.MODELS.FLOOR.getAlias;
- let schema = _.keys(Model.schema.paths);
- let body = _.keys(userAction.body);
- let keys = _.intersection(body, schema);
- patchString = getUpdateFieldString(isHtml, keys, getAlias);
- break;
- }
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- "the " +
- patchString +
- " of " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Level);
- },
- },
- LEVEL_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, Level);
- },
- },
- LOGIN: {
- createActionDisplay: function() {
- /*
- * POST to login.
- * Do not have an account-level activity feed... yet.
- */
- return "";
- },
- },
- // GET to logout.
- LOGOUT: {},
- LOGOUT_APP: {},
- MAINTENANCE_TYPE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = MaintenanceType;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.maintenance_type;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "archive":
- actionHtml += " archived ";
- break;
- case "restore":
- actionHtml += " restored ";
- break;
- case "update":
- actionHtml += " updated ";
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- break;
- case "building":
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- MaintenanceType
- );
- },
- },
- MAINTENANCE_TYPE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(
- type,
- isHtml,
- userAction,
- MaintenanceType
- );
- },
- },
- ORGANIZATION_LIST: {
- // no reason to have a createActionDisplay
- },
- ORGANIZATION_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Organization;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.organization;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) + " updated ";
- let patchString = null;
- if (userAction.method === "PATCH") {
- // PATCH, so we can guess what was changed.
- let getAlias = ABC.MODELS.ORGANIZATION.getAlias;
- let schema = _.keys(Model.schema.paths);
- let body = _.keys(userAction.body);
- let keys = _.intersection(body, schema);
- patchString = getUpdateFieldString(isHtml, keys, getAlias);
- }
- switch (type) {
- // The organization is the entity.
- case "entity":
- case "organization":
- if (patchString) {
- actionHtml +=
- "this " +
- addBoldHtmlTag(isHtml, entityAlias) +
- "'s " +
- patchString;
- } else {
- actionHtml +=
- "this " + addBoldHtmlTag(isHtml, entityAlias) + "'s settings";
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- },
- OAUTH2_SETUP: {},
- PIN_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction, Model) {
- if (_.isEmpty(Model)) {
- if (userAction.asset) Model = Asset;
- else if (userAction.room) Model = Room;
- }
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction[modelConstants.MODEL];
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let patchString = null;
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "update":
- actionHtml += " updated ";
- break;
- case "setLocation":
- actionHtml += " updated ";
- patchString = addBoldHtmlTag(isHtml, "Location");
- break;
- case "updateRoom":
- // Can only be an Asset for this action.
- entityAlias = ABC.MODELS.ASSET.SINGULAR;
- actionHtml += " updated ";
- patchString = addBoldHtmlTag(isHtml, ABC.MODELS.ROOM.SINGULAR);
- break;
- case "updateLevel":
- actionHtml += " updated ";
- patchString = addBoldHtmlTag(isHtml, ABC.MODELS.FLOOR.SINGULAR);
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- "the " +
- patchString +
- " in " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- },
- PIN_FIELD_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- // TODO get all the special update cases
- return childUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- userAction.pin_field,
- PinField,
- userAction.pin_type,
- PinType
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return childDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- PinField,
- userAction.pin_type,
- PinType
- );
- },
- },
- PIN_FIELD_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return childCreateActionDisplay(
- type,
- isHtml,
- userAction,
- PinField,
- userAction.pin_type,
- PinType
- );
- },
- },
- // Only GET calls for hard-coded trees not stored in the pin field itself.
- PIN_FIELD_TREE: {},
- PIN_TYPE_COLOR_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- // TODO get all the special update cases
- return childUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- userAction.pin_type_color,
- PinTypeColor,
- userAction.pin_type,
- PinType
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return childDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- PinTypeColor,
- userAction.pin_type,
- PinType
- );
- },
- },
- PIN_TYPE_COLOR_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return childCreateActionDisplay(
- type,
- isHtml,
- userAction,
- PinTypeColor,
- userAction.pin_type,
- PinType
- );
- },
- },
- PIN_TYPE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- // TODO get all the special update cases
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- userAction.pin_type,
- PinType
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, PinType);
- },
- },
- PIN_TYPE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, PinType);
- },
- },
- PIN_VALUE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction, Model) {
- if (_.isEmpty(Model)) {
- if (userAction.asset) Model = Asset;
- else if (userAction.room) Model = Room;
- }
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction[modelConstants.MODEL];
- let parentEntity = userAction.pin_type;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) + " updated ";
- let patchString = null;
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- // Try to set patchString to the pin field corresponding to the value that was updated.
- if (
- entity &&
- _.isArray(entity.values) &&
- parentEntity &&
- _.isArray(parentEntity.fields) &&
- userAction.pin_value
- ) {
- // Find the value so we can get its pin field id.
- let pinValue = entity.values.id(userAction.pin_value);
- if (pinValue) {
- // Find the value's pin field in the pin type.
- let pinField = parentEntity.fields.id(pinValue.pinField);
- if (pinField && pinField.name) {
- // Finally have the pin field name.
- patchString = addBoldHtmlTag(isHtml, pinField.name);
- }
- }
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- "the " +
- patchString +
- " in " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- /*
- * Values are not deleted through this route (deleted when parent pin field is removed from the pin
- * type).
- */
- },
- // Values are not created through this route (created when the parent pin field is created in the pin type).
- PIN_VALUE_LIST: {},
- PORTAL_TOKEN: {},
- PRIVACY_POLICY: {},
- // Only GET calls.
- QRCODE_LIST: {},
- // Only GET calls.
- QRCODE_REDIRECT: {},
- REGISTER: {
- createActionDisplay: function() {
- /*
- * POST to register new accounts.
- * Do not have an account-level activity feed... yet.
- */
- return "";
- },
- },
- REQUEST_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Request;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let entity = userAction.request;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "deny":
- actionHtml += " denied ";
- break;
- case "reopen":
- actionHtml += " reopened ";
- break;
- case "update":
- default:
- // Send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- break;
- case "building":
- actionHtml +=
- "the " +
- addAnchorTag(isHtml, entityAlias, entity) +
- " submitted by " +
- addBoldHtmlTag(isHtml, entity.requester_email) +
- " on " +
- entity.cre_date;
- break;
- // case 'account':
- // case 'organization':
- default:
- // Send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Request);
- },
- },
- REQUEST_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- /*
- * Cannot use standardCreateActionDisplay (Request.nameField() is not
- * applicable and want a different verb 'submitted'). And user may not
- * be set for requests made from Portal.
- */
- let Model = Request;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let user;
- if (userAction.user && _.isString(userAction.user.email)) {
- user = addBoldHtmlTag(isHtml, userAction.user.email);
- } else {
- // from the portal
- user = "A building occupant";
- }
- return user + " submitted a new " + addBoldHtmlTag(isHtml, entityAlias);
- },
- },
- // Only GET calls for request portals.
- REQUEST_PORTAL: {},
- RESET_PASSWORD: {
- createActionDisplay: function() {
- /*
- * POST to reset passwords.
- * Do not have an account-level activity feed... yet.
- */
- return "";
- },
- },
- // Only GET calls.
- REVISION_DETAIL: {},
- // Only GET calls.
- REVISION_LIST: {},
- ROLE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Role;
- let entity = userAction.role;
- if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "update":
- /*
- * Updating role notification preferences.
- * Do not care about these updates for the building or entity activity feeds.
- * We will later if we have an account-level feed.
- */
- return "";
- default:
- // Updating role permissions.
- switch (type) {
- case "entity":
- // Do not have feeds for individual roles.
- return "";
- case "building": {
- // Need to get the display role based on the perms in the body.
- let _body = entity.toJSON();
- if (userAction.body.type) {
- _body.type = userAction.body.type;
- }
- let _role = new Model(_body);
- return (
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " updated the building permissions for " +
- addBoldHtmlTag(isHtml, entity.email) +
- " to " +
- addBoldHtmlTag(isHtml, _role.display_role)
- );
- }
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- }
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- // Archive / expire a role.
- let Model = Role;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) + " removed ";
- // Fake create the item (without saving of course) to get the display_role.
- let _role = new Model(userAction.body);
- // Need to get the created role's email... but our data is really fucked up...
- let email = userAction.body.email;
- if (!email && _role.email) {
- email = _role.email;
- } else if (!email && userAction.role) {
- email = userAction.role.email;
- }
- actionHtml += addBoldHtmlTag(isHtml, email) + " from the Building";
- return actionHtml;
- },
- },
- ROLE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- let Model = Role;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) + " invited ";
- // Fake create the item (without saving of course) to get the display_role.
- let _role = new Model(userAction.body);
- // Need to get the created role's email... but our data is really fucked up...
- let email = userAction.body.email;
- if (!email && _role.email) {
- email = _role.email;
- } else if (!email && userAction.role) {
- email = userAction.role.email;
- }
- actionHtml +=
- addBoldHtmlTag(isHtml, email) +
- " to the Building with " +
- addBoldHtmlTag(isHtml, _role.display_role) +
- " permissions";
- return actionHtml;
- },
- },
- ROOM_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- return routeHelpers.PIN_DETAIL.updateActionDisplay(
- type,
- isHtml,
- userAction,
- Room
- );
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Room);
- },
- },
- ROOM_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, Room);
- },
- },
- // Values are not deleted through this route (deleted when parent pin field is removed from the pin type).
- ROOM_VALUE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- return routeHelpers.PIN_VALUE_DETAIL.updateActionDisplay(
- type,
- isHtml,
- userAction,
- Room
- );
- },
- },
- // Values are not created through this route (created when the parent pin field is created in the pin type).
- ROOM_VALUE_LIST: {},
- // GET to send validation.
- SEND_VALIDATION: {},
- // Tags cannot be updated.
- TAG_DETAIL: {
- deleteActionDisplay: function(type, isHtml, userAction) {
- return childDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- Tag,
- userAction.document,
- Document
- );
- },
- },
- TAG_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return childCreateActionDisplay(
- type,
- isHtml,
- userAction,
- Tag,
- userAction.document,
- Document
- );
- },
- },
- // Tag categories cannot be updated.
- TAG_CATEGORY_DETAIL: {
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- TagCategory
- );
- },
- },
- TAG_CATEGORY_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(
- type,
- isHtml,
- userAction,
- TagCategory
- );
- },
- },
- // Tag category values cannot be updated.
- TAG_VALUE_DETAIL: {
- deleteActionDisplay: function(type, isHtml, userAction) {
- return childDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- TagCategoryValue,
- userAction.tag_category,
- TagCategory
- );
- },
- },
- TAG_VALUE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return childCreateActionDisplay(
- type,
- isHtml,
- userAction,
- TagCategoryValue,
- userAction.tag_category,
- TagCategory
- );
- },
- },
- TASK_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Task;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.task;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let patchString = null;
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "update":
- actionHtml += " updated ";
- if (userAction.method === "PATCH") {
- // PATCH, so we can guess what was changed,
- let getAlias = ABC.MODELS.WORK_ORDER.getAlias;
- let schema = _.keys(Model.schema.paths);
- let body = _.keys(userAction.body);
- let keys = _.intersection(body, schema);
- patchString = getUpdateFieldString(isHtml, keys, getAlias);
- }
- break;
- case "cancel":
- actionHtml += " canceled ";
- break;
- case "complete":
- actionHtml += " completed ";
- break;
- case "reopen":
- actionHtml += " reopened ";
- break;
- case "assign":
- if (userAction.body.assignee) {
- actionHtml += " reassigned ";
- } else {
- actionHtml += " unassigned ";
- }
- break;
- default:
- // Send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- if (patchString) {
- actionHtml += "'s " + patchString;
- }
- break;
- case "building":
- if (patchString) {
- actionHtml +=
- patchString +
- " in " +
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- } else {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- // Send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- // Message was added with Task/Work Order was completed
- const messageToRequestor = userAction.body.message_to_requestor;
- if (messageToRequestor) {
- actionHtml +=
- " with message: " +
- addItalicHtmlTag(isHtml, `"${messageToRequestor}"`);
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Task);
- },
- },
- TASK_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- /*
- * No way to get the correct task.number (that is part of the task name) so we can't use
- * standardCreateActionDisplay.
- */
- let Model = Task;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " created a new " +
- addBoldHtmlTag(isHtml, entityAlias);
- // Fake create the item (without saving of course).
- let _entity = new Model(userAction.body);
- // Add the name of the item if can be pulled out of the fake entity.
- let name = _entity[nameField];
- if (name) {
- /*
- * Can't add an anchor tag (do not have the id of the created thing...) so just add the name
- * in bold.
- */
- actionHtml += " - " + addBoldHtmlTag(isHtml, name);
- }
- if (_entity.is_from_request) {
- // Add an extra bit if the task was created in response to a service request.
- let _serviceRequest = {
- _id: _entity.request,
- };
- actionHtml +=
- " in response to a " +
- addAnchorTag(isHtml, "Service Request", _serviceRequest);
- }
- /*
- * Tasks created as part of a task schedule are not created through the API so their creation will
- * not have associated user actions.
- */
- return actionHtml;
- },
- },
- TERMS_OF_USE: {},
- TRADE_DETAIL: {
- updateActionDisplay: function(type, isHtml, userAction) {
- let Model = Trade;
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let nameField = modelConstants.NAME_FIELD;
- let entity = userAction.trade;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email);
- let name = null;
- if (entity && entity[nameField]) {
- name = entity[nameField];
- } else if (!entity) {
- /*
- * Looks like population failed because the entity was deleted.
- * Just use the standard helper.
- */
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (userAction.body.action) {
- case "archive":
- actionHtml += " archived ";
- break;
- case "restore":
- actionHtml += " restored ";
- break;
- case "update":
- actionHtml += " updated ";
- break;
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- break;
- case "building":
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, name, entity);
- break;
- // case 'account':
- // case 'organization':
- default:
- // Just send off the standard update message.
- return standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- }
- return actionHtml;
- },
- deleteActionDisplay: function(type, isHtml, userAction) {
- return standardDeleteActionDisplay(type, isHtml, userAction, Trade);
- },
- },
- TRADE_LIST: {
- createActionDisplay: function(type, isHtml, userAction) {
- return standardCreateActionDisplay(type, isHtml, userAction, Trade);
- },
- },
- // Only GET calls.
- TRANSACTION_DETAIL: {},
- // Only GET calls.
- TRANSACTION_LIST: {},
- UPGRADE_BROWSER: {},
- UPLOAD: {
- // GET POST and DELETE calls for multipart uploads.
- createActionDisplay: function(type, isHtml, userAction) {
- // TODO put more info in the userAction about the files that were uploaded
- const modelConstants = ABC.MODELS.DOCUMENT;
- let entityAlias = modelConstants.SINGULAR;
- return (
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " uploaded a " +
- addBoldHtmlTag(isHtml, entityAlias)
- );
- },
- },
- };
- return routeHelpers;
- });
- /**
- * Adds bold HTML tag to string.
- *
- * @function addBoldHtmlTag
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {Boolean} isHtml True when string is HTML
- * @param {String} str String
- *
- * @return {String} HTML string
- */
- function addBoldHtmlTag(isHtml, str) {
- return isHtml ? addHtmlTag(isHtml, str, "b") : str;
- }
- /**
- * Adds italic HTML tag to string.
- *
- * @function addItalicHtmlTag
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {Boolean} isHtml True when string is HTML
- * @param {String} str String
- *
- * @return {String} HTML string
- */
- function addItalicHtmlTag(isHtml, str) {
- return isHtml ? addHtmlTag(isHtml, str, "i") : str;
- }
- /**
- * Adds HTML tag to string.
- *
- * @function addHtmlTag
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {Boolean} isHtml True when string is HTML
- * @param {string} str String
- * @param {string} tag HTML tag to add
- *
- * @return {String} HTML string
- */
- function addHtmlTag(isHtml, str, tag) {
- return isHtml ? "<" + tag + ">" + str + "</" + tag + ">" : str;
- }
- /**
- * Adds anchor tag.
- *
- * @param {Boolean} isHtml True if content is HTML
- * @param {String} content Content
- * @param {Object} model Model
- *
- * @return {String} HTML
- */
- function addAnchorTag(isHtml, content, model) {
- if (!model || model.deleted || model.is_deleted || model.expired) {
- // Can't send a link for these (will give 404), just return bold content.
- return isHtml
- ? addBoldHtmlTag(isHtml, content) + " (deleted)"
- : content + " (deleted)";
- } else if (!isHtml) {
- return content;
- }
- let uri = model ? model.uri : null;
- if (uri && (/\/pin_types$/.test(uri) || /\/pin_types\//.test(uri))) {
- // Looks like we need to open a new tab (for pin types)
- let parts = uri.split("/pin_types");
- uri = parts.join("/settings/pin_types");
- return '<a target="_blank" href="' + uri + '">' + content + "</a>";
- } else if (uri) {
- // Looks like we can render on the dashboard.
- return '<a href="' + uri + '">' + content + "</a>";
- }
- // Return bold content.
- return addBoldHtmlTag(isHtml, content);
- }
- /**
- *
- * @param {string} [text] The actual text to display
- * @param {string} [url] The value of the href attribute
- * @param {Object} [options] Contains all the allowed options
- * @param {string} [options.target] Value for the target HTML attribute
- * @param {string} [options.title] Value for the title HTML attribute
- *
- * @return {string}
- */
- function toHTMLAnchor(text = "", url = "", options = {}) {
- let href= `href="${url}"`;
- let target = ``;
- let title = `title="${text}"`;
- if (options.target) {
- target = `target="${options.target}"`;
- }
- if (options.title) {
- title = `title="${options.title}"`;
- }
- return `<a ${target} ${href} ${title}>${text}</a>`;
- }
- /**
- * Generates a standard human-readable create action display that occurred in the provided user action.
- *
- * @function standardCreateActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building (entity N/A for creates)
- * @param {Boolean} isHtml If true, return an HTML string
- * @param {UserAction} userAction User action
- * @param {Object} Model Model
- *
- * @return {String} HTML
- */
- function standardCreateActionDisplay(type, isHtml, userAction, Model) {
- const modelConstants = Model.constants();
- let entityAlias = modelConstants.SINGULAR;
- let actionHtml =
- addBoldHtmlTag(isHtml, userAction.user.email) +
- " created a new " +
- addBoldHtmlTag(isHtml, entityAlias);
- // Fake create the item (without saving of course).
- let _entity = new Model(userAction.body);
- // Add the name of the item if can be pulled out of the fake entity.
- let nameField = modelConstants.NAME_FIELD;
- let name = _entity[nameField];
- if (name) {
- /*
- * Can't add an anchor tag (do not have the id of the created thing...), so add the name in bold.
- */
- actionHtml += " - " + addBoldHtmlTag(isHtml, name);
- }
- return actionHtml;
- }
- /**
- * Generates a human-readable create action display for the child element in the provided user action.
- *
- * @function childCreateActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building (entity N/A for creates)
- * @param {Boolean} isHtml If true, return an Html string
- * @param {UserAction} userAction User Action
- * @param {Object} Model Model
- * @param {Object} parentEntity Parent entity
- * @param {Object} ParentModel Parent Model
- *
- * @return {String} Create action display
- */
- function childCreateActionDisplay(
- type,
- isHtml,
- userAction,
- Model,
- parentEntity,
- ParentModel
- ) {
- let actionHtml = standardCreateActionDisplay(type, isHtml, userAction, Model);
- // Add some info about the parent if we can.
- const parentModelConstants = ParentModel.constants();
- let parentNameField = parentModelConstants.NAME_FIELD;
- let parentName = parentEntity ? parentEntity[parentNameField] : null;
- if (parentName) {
- // Add the stuff about the parent and the anchor tag for the parent.
- actionHtml +=
- " in " +
- addBoldHtmlTag(isHtml, parentModelConstants.SINGULAR) +
- " - " +
- addAnchorTag(isHtml, parentName, parentEntity);
- }
- return actionHtml;
- }
- /**
- * Generates a standard human-readable update action display that occurred in the provided user action.
- *
- * @function standardUpdateActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building or entity
- * @param {boolean} isHtml If true, return an Html string
- * @param {UserAction} userAction User action
- * @param {Object} entity Entity
- * @param {Object} Model Model
- *
- * @return {String} Update action display
- */
- function standardUpdateActionDisplay(type, isHtml, userAction, entity, Model) {
- const modelConstants = Model.constants();
- let nameField = modelConstants.NAME_FIELD;
- let entityAlias = modelConstants.SINGULAR;
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email) + " updated ";
- switch (type) {
- case "entity":
- actionHtml += "this " + addBoldHtmlTag(isHtml, entityAlias);
- break;
- case "building":
- if (entity && entity[nameField]) {
- actionHtml +=
- addBoldHtmlTag(isHtml, entityAlias) +
- " - " +
- addAnchorTag(isHtml, entity[nameField], entity);
- } else {
- actionHtml += "a " + addBoldHtmlTag(isHtml, entityAlias);
- }
- break;
- // case 'account':
- // case 'organization':
- default:
- return "";
- }
- return actionHtml;
- }
- /**
- * Generates a human-readable update action display for the child element in the provided user action.
- *
- * @function childUpdateActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building or entity
- * @param {Boolean} isHtml If true, return an Html string
- * @param {UserAction} userAction User action
- * @param {Object} entity Entity
- * @param {Object} Model Model
- * @param {Object} parentEntity Parent entity
- * @param {Object} ParentModel Parent Model
- *
- * @return {String} Update action display
- */
- function childUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model,
- parentEntity,
- ParentModel
- ) {
- let actionHtml = standardUpdateActionDisplay(
- type,
- isHtml,
- userAction,
- entity,
- Model
- );
- switch (type) {
- case "entity":
- // Nothing to add.
- break;
- case "building": {
- // Add some info about the parent if we can.
- const parentModelConstants = ParentModel.constants();
- let parentNameField = parentModelConstants.NAME_FIELD;
- let parentName = parentEntity ? parentEntity[parentNameField] : null;
- if (parentName) {
- // Add the stuff about the parent and the anchor tag for the parent.
- actionHtml +=
- " in " +
- addBoldHtmlTag(isHtml, parentModelConstants.SINGULAR) +
- " - " +
- addAnchorTag(isHtml, parentName, parentEntity);
- }
- break;
- }
- // case 'account':
- // case 'organization':
- default:
- return "";
- }
- return actionHtml;
- }
- /**
- * Generates a standard human-readable delete action display that occurred in the provided user action.
- *
- * @function standardDeleteActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building or entity
- * @param {boolean} isHtml If true, return an Html string
- * @param {UserAction} userAction User action
- * @param {Object} Model Model
- *
- * @return {String} Delete action display
- */
- function standardDeleteActionDisplay(type, isHtml, userAction, Model) {
- /*
- * Entity is null in the userAction (because it was deleted).
- * There is no way that we can get the name of the entity out of the userAction.
- */
- const modelConstants = Model.constants();
- let actionHtml = addBoldHtmlTag(isHtml, userAction.user.email) + " deleted a";
- let entityAlias = modelConstants.SINGULAR;
- if (/a|e|i|o|u/i.test(entityAlias.charAt(0))) {
- actionHtml += "n ";
- } else {
- actionHtml += " ";
- }
- actionHtml += addBoldHtmlTag(isHtml, entityAlias);
- return actionHtml;
- }
- /**
- * Generates a human-readable delete action display for the child element in the provided user action.
- *
- * @function childDeleteActionDisplay
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {String} type Building or entity
- * @param {Boolean} isHtml If true, return an Html string
- * @param {UserAction} userAction User action
- * @param {Object} Model Model
- * @param {Object} parentEntity Parent entity
- * @param {Object} ParentModel ParentModel
- *
- * @return {String} Delete action display
- */
- function childDeleteActionDisplay(
- type,
- isHtml,
- userAction,
- Model,
- parentEntity,
- ParentModel
- ) {
- let actionHtml = standardDeleteActionDisplay(type, isHtml, userAction, Model);
- // Add some info about the parent if we can.
- const parentModelConstants = ParentModel.constants();
- let parentNameField = parentModelConstants.NAME_FIELD;
- let parentName = parentEntity ? parentEntity[parentNameField] : null;
- if (parentName) {
- // Add the stuff about the parent and the anchor tag for the parent.
- actionHtml +=
- " from " +
- addBoldHtmlTag(isHtml, parentModelConstants.SINGULAR) +
- " - " +
- addAnchorTag(isHtml, parentName, parentEntity);
- }
- return actionHtml;
- }
- /**
- * Generates human-readable action_display sentences provided a list of fields that were updated.
- *
- * @function getUpdateFieldString
- * @memberof UserActionModel.prototype
- * @private
- *
- * @param {Boolean} isHtml If true, return an Html string
- * @param {Array} keys Array of fields that were updated
- * @param {Function} getAlias Function that when given a schema
- * key, returns a human-readable string.
- *
- * @return {String} Update field string
- */
- function getUpdateFieldString(isHtml, keys, getAlias) {
- let fieldString = "";
- // Cycle through the provided keys (for fields that were updated).
- for (let i = 0; i < keys.length; i++) {
- /*
- * Append the phrase with appropriate punctuation depending on the number of fields that were updated and
- * the position of this field.
- */
- let alias = getAlias(keys[i]);
- if (keys.length === 1 || i === 0) {
- // Do not include starting ' '.
- fieldString += addBoldHtmlTag(isHtml, alias);
- } else if (i < keys.length - 1) {
- fieldString += ", " + addBoldHtmlTag(isHtml, alias);
- } else {
- fieldString += " and " + addBoldHtmlTag(isHtml, alias);
- }
- }
- return fieldString;
- }
- // METHODS =========================================================================================================
- // OTHER ===========================================================================================================
- UserAction.pre("save", function preSave(next) {
- // Make sure we don't store things we aren't supposed to know.
- let blacklistedFields = [
- "password",
- "secret",
- "new_password",
- "existing_password",
- "encrypted_credentials",
- "credentials",
- ];
- if (this.body) {
- this.body = _.omit(this.body, blacklistedFields);
- }
- if (this.query) {
- this.query = _.omit(this.query, blacklistedFields);
- }
- return next();
- });
- if (!UserAction.options.toJSON) {
- UserAction.options.toJSON = {};
- }
- UserAction.options.toJSON.transform = function(doc, ret, options) {
- delete ret.__v;
- delete ret.ip;
- if (options.includeDisplayDates) {
- let utcOffset = options.utcOffset || null;
- let format = options.dateFormat || null;
- ret = _.extend(ret, doc.getDisplayDates(utcOffset, format));
- }
- ret.entity_action_display = doc.entity_action_display;
- ret.building_action_display = doc.building_action_display;
- ret.entity_action_html = doc.entity_action_html;
- ret.building_action_html = doc.building_action_html;
- ret.is_200 = doc.is_200;
- ret.is_not_200 = doc.is_not_200;
- ret.is_500 = doc.is_500;
- ret.has_user = doc.has_user;
- ret.stringified_body = doc.stringified_body;
- ret.stringified_query = doc.stringified_query;
- if (options && options.stringify) {
- // For the popovers in admin dashboard.
- ret.stringified = JSON.stringify(_.clone(ret));
- }
- };
- // read user actions from the secondary databases instead of the primary
- UserAction.set("read", "secondaryPreferred");
- module.exports = mongoose.model("UserAction", UserAction);
- function a() {
- var courses = [];
- var studentRecords = openStudentEnrollmentRecords();
- while (studentRecords.readNextRecord()) {
- var courseNumber = studentRecords.getCourseNumber();
- var studentName = studentRecords.getStudentName();
- // lets say, courseNumber is 3
- if (!courses[courseNumber]) {
- // courseNumber = 3
- // courses[3] do you e
- courses[courseNumber]= [];
- // okay, courses = [null, null, null, ["bob", "jack"]]
- }
- maleStudents[courseNumber].push(studentName);
- femaleStudents[courseNumber].push(studentName);
- }
- // we should export all the names and the croues tob e storted out
- // now we just need to print
- // <table>
- // <th>.courtsers students total m/f .....
- for (var i = 18000; i < courses.length; i++) {
- var courseNumber = i;
- var students = courses[courseNumber];
- if (!students) {
- continue;
- }
- innerHtml += "<tr><td>" + courseNumber + "</td>";
- innerHtml += "<td>";
- for (var a = 0; a < students.length; a++) {
- var student = students[a];
- innerHtml += student + ", ";
- }
- innerHtml += "</td><td>" + students.length + "</td></tr>";
- }
- // </table>
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement