"use strict"; /** * Value object for feed item. * * @author Igor Samulenko * @constructor */ function FeedItemVO() { // simple fields this.type = ''; this.priority = 0; this.isSystemGenerated = ''; this.attachmentCount = 0; // broadcast specific // complex fields this.author = null; this.relatedObject = null; this.event = null; this.note = null; this.attachments = null; // broadcast specific // derived fields this.createDateLabel = ''; this.message = ''; this.expanded = false; this.repliesExpanded = false; this.title = ''; this.tagLine = ''; } /** * Setup inheritance chain. */ FeedItemVO.prototype = Object.create(BaseVO.prototype); FeedItemVO.prototype.constructor = FeedItemVO; /** * Constants section. * Read-only state will be enforced later. */ FeedItemVO.prototype.TYPE_SYSTEM = 'system'; FeedItemVO.prototype.TYPE_COMMENT = 'comment'; FeedItemVO.prototype.TYPE_OUTAGE = 'outage'; FeedItemVO.prototype.TYPE_BROADCAST = 'broadcast'; FeedItemVO.WORK_INFO_TYPES = {}; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_INCIDENT] = 16000; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_TASK] = 16000; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_WORKORDER] = 31000; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_CHANGE] = 31000; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_RELEASE] = 31000; FeedItemVO.WORK_INFO_TYPES[EntityVO.TYPE_ACTIVITY] = 31000; /** * @override * @return {Array} */ FeedItemVO.prototype.getProps = function () { return BaseVO.prototype.getProps().concat('type', 'priority', 'isSystemGenerated', 'author', 'relatedObject', 'event', 'note', 'attachments', 'attachmentCount'); }; /** * Returns true if item is a system update. * @returns {Boolean} */ FeedItemVO.prototype.isSystemUpdate = function () { return this.type === FeedItemVO.prototype.TYPE_SYSTEM; }; /** * Returns true if item is an outage. * @returns {Boolean} */ FeedItemVO.prototype.isOutage = function () { return this.type === FeedItemVO.prototype.TYPE_OUTAGE; }; /** * Returns true if item is a broadcast. * @returns {Boolean} */ FeedItemVO.prototype.isBroadcast = function () { return this.type === FeedItemVO.prototype.TYPE_BROADCAST; }; /** * Returns true if item is associated with knowledge article * @returns {String} */ FeedItemVO.prototype.isKnowledge = function () { return this.relatedObject && this.relatedObject.type === EntityVO.TYPE_KNOWLEDGE; }; /** * Returns true if item is a comment. * @returns {Boolean} */ FeedItemVO.prototype.isComment = function () { return this.type === FeedItemVO.prototype.TYPE_COMMENT; }; /** * Returns true if item is a vendor comment. * @returns {Boolean} */ FeedItemVO.prototype.isVendorComment = function () { return this.event.eventType === EventVO.prototype.VENDOR_NOTE || this.event.eventType === EventVO.prototype.VENDOR_NOTE_V2; }; /** * Returns true if item is a service health status. * @returns {Boolean} */ FeedItemVO.prototype.isServiceHealthStatusActivity = function () { return this.event.eventType === EventVO.prototype.SERVICE_HEALTH_STATUS; }; /** * Returns true if item is a response for Unflagging. * @returns {Boolean} */ FeedItemVO.prototype.isUnflaggingResponse = function () { return this.event.eventType === EventVO.prototype.UNFLAG; }; /** * Returns true if item is a comment from MyIT. * @returns {Boolean} */ FeedItemVO.prototype.isMyITComment = function () { return this.type === FeedItemVO.prototype.TYPE_COMMENT && this.note && !!this.note.conversationRefId; }; /** * Returns true if item is a email. * @returns {Boolean} */ FeedItemVO.prototype.isEmail = function () { return this.event.eventType === EventVO.prototype.EMAIL || this.event.eventType === EventVO.prototype.RICH_EMAIL; }; /** * Returns true if item is a flag. * @returns {Boolean} */ FeedItemVO.prototype.isFlag = function () { return (this.event.eventType === EventVO.prototype.FLAG); }; FeedItemVO.prototype.isUnFlag = function () { return (this.event.eventType === EventVO.prototype.UNFLAG); }; /** * Returns true if item is a needs attention flag. * @returns {Boolean} */ FeedItemVO.prototype.isNeedsAttentionFlag = function () { return (this.event.eventType === EventVO.prototype.NEEDS_ATTENTION_FLAG); }; FeedItemVO.prototype.isNeedsAttentionUnFlag = function () { return (this.event.eventType === EventVO.prototype.NEEDS_ATTENTION_UNFLAG); }; /** * Returns true if item is a SLA change. * @returns {Boolean} */ FeedItemVO.prototype.isSlaChange = function () { return this.isSystemUpdate() && this.event.isSlaChange(); }; /** * Returns true if item is an approval rejection event. * @returns {Boolean} */ FeedItemVO.prototype.isApprovalReject = function () { return this.isSystemUpdate() && this.event.eventType === 'approval-reject-event'; }; /** * Returns true if item is an approval hold event. * @returns {Boolean} */ FeedItemVO.prototype.isApprovalHold = function () { return this.isSystemUpdate() && this.event.eventType === 'approval-hold-event'; }; /** * Returns true if item is an approval accept event. * @returns {Boolean} */ FeedItemVO.prototype.isApprovalAccept = function () { return this.isSystemUpdate() && this.event.eventType === 'approval-accept-event'; }; /** * Returns true if item is a relationship change event. * @returns {Boolean} */ FeedItemVO.prototype.isRelationshipChange = function () { return this.event.eventType === EventVO.prototype.RELATED_CHANGE || this.event.eventType === EventVO.prototype.UNRELATED_CHANGE; }; /** * Returns true if item is a location change event. * @returns {Boolean} */ FeedItemVO.prototype.isLocationChange = function () { return this.event.eventType === EventVO.prototype.LOCATION_CHANGE; }; /** * Returns true if item is a ownership change event. * @returns {Boolean} */ FeedItemVO.prototype.isOwnerChange = function () { return this.event.eventType === EventVO.prototype.OWNERSHIP_CHANGE; }; /** * Returns true if item is shared with vendor. * @returns {Boolean} */ FeedItemVO.prototype.isSharedWithVendor = function () { return this.note && (this.note.shareWithVendor || (_.isString(this.note.vendorTicketId) && this.note.vendorTicketId.length > 0)); }; /** * Returns fully qualified icon class name. * @returns {String} */ FeedItemVO.prototype.iconFunction = function () { var itemType = this.relatedObject && this.relatedObject.type || '', iconClass; switch (itemType) { case EntityVO.TYPE_INCIDENT: case EntityVO.TYPE_WORKORDER: case EntityVO.TYPE_PROBLEM: iconClass = 'icon-' + itemType; switch (this.event.eventType) { case EventVO.prototype.VENDOR_CREATE: case EventVO.prototype.VENDOR_CREATE_V2: case EventVO.prototype.VENDOR_CREATE_ITSM_TICKET: iconClass += '-brokered'; break; case EventVO.prototype.VENDOR_NOTE: case EventVO.prototype.VENDOR_NOTE_V2: case EventVO.prototype.VENDOR_STATUS_CHANGE: case EventVO.prototype.VENDOR_STATUS_CHANGE_V2: iconClass = 'icon-cloud_user'; break; case EventVO.prototype.TASK_RELATION: if (this.event.classId === EventVO.prototype.TASK_AUTOMATIC) { iconClass = 'icon-file_task_auto'; } else if (this.event.classId === EventVO.prototype.TASK_MANUAL) { iconClass = 'icon-file_task_o'; } break; } if (this.event.messageId === "51248") { iconClass = 'feed-item__cognitive-recommendation'; } break; case EntityVO.TYPE_CHANGE: if (this.event.classId === "Automation System") { iconClass = 'icon-files_change_auto'; } else if (this.event.classId === "Automatic") { iconClass = 'icon-file_task_auto'; } else if (this.event.classId === "Manual") { iconClass = 'icon-file_task_o'; } else { iconClass = 'icon-' + itemType; switch (this.event.eventType) { case EventVO.prototype.VENDOR_CREATE: case EventVO.prototype.VENDOR_CREATE_V2: case EventVO.prototype.VENDOR_CREATE_ITSM_TICKET: iconClass += '-brokered'; break; case EventVO.prototype.VENDOR_NOTE: case EventVO.prototype.VENDOR_NOTE_V2: case EventVO.prototype.VENDOR_STATUS_CHANGE: case EventVO.prototype.VENDOR_STATUS_CHANGE_V2: iconClass = 'icon-cloud_user'; break; } } break; case EntityVO.TYPE_TASK: iconClass = this.event.classId === "Automatic" ? 'icon-file_task_auto' : 'icon-task'; break; case EntityVO.TYPE_KNOWLEDGE: iconClass = this.event.classId === "RKM:DecisionTreeTemplate" ? 'icon-decision-tree' : 'icon-knowledge'; break; case EntityVO.TYPE_ASSET: case EntityVO.TYPE_SERVICEREQUEST: case EntityVO.TYPE_RELEASE: case EntityVO.TYPE_ACTIVITY: iconClass = 'icon-' + itemType; break; case EntityVO.TYPE_KNOWNERROR: if (this.event.classId === EventVO.prototype.TASK_AUTOMATIC) { iconClass = 'icon-file_task_auto'; } else if (this.event.classId === EventVO.prototype.TASK_MANUAL) { iconClass = 'icon-file_task_o'; } else { iconClass = 'icon-' + itemType; switch (this.event.eventType) { case EventVO.prototype.VENDOR_CREATE: case EventVO.prototype.VENDOR_CREATE_V2: case EventVO.prototype.VENDOR_CREATE_ITSM_TICKET: iconClass += '-brokered'; break; case EventVO.prototype.VENDOR_NOTE: case EventVO.prototype.VENDOR_NOTE_V2: case EventVO.prototype.VENDOR_STATUS_CHANGE: case EventVO.prototype.VENDOR_STATUS_CHANGE_V2: iconClass = 'icon-cloud_user'; break; } } break; default: iconClass = ''; } if (this.isBroadcast()) { iconClass = 'icon-speaker'; } if (this.isSlaChange()) { iconClass = 'icon-exclamation_triangle'; } if (this.isApprovalHold()) { iconClass = 'icon-sandglass'; } if (this.isApprovalReject()) { iconClass = 'icon-cross_square'; } if (this.isApprovalAccept()) { iconClass = 'icon-check_shield'; } if (this.isRelationshipChange()) { iconClass = 'icon-link'; } if (this.isLocationChange()) { iconClass = 'icon-mapmarker'; } return iconClass; }; /** * Returns true if item has attachments. * @returns {boolean} */ FeedItemVO.prototype.hasAttachments = function () { return (this.isComment() || this.isVendorComment() || this.isBroadcast()) && this.note.attachmentCount > 0; }; /** * Returns true if item has comments. * @returns {boolean} */ FeedItemVO.prototype.hasComments = function () { return this.isComment() && this.note.commentCount > 0; }; /** * Returns true if item has replies. * @returns {boolean} */ FeedItemVO.prototype.hasReplies = function () { return this.replies && this.note.repliesCount > 0; }; /** * Returns true if item has unflagging response. * @returns {boolean} */ FeedItemVO.prototype.hasUnflaggingResponse = function () { for (var response in this.replies) { if (this.replies[response].isUnflaggingResponse()) { return true; } } return false; }; /** * Toggle between expanded/collapsed state. */ FeedItemVO.prototype.toggle = function () { this.expanded = !this.expanded; }; /** * Toggle between response to the flagging events expanded/collapsed state. */ FeedItemVO.prototype.toggleRepliesView = function () { this.repliesExpanded = !this.repliesExpanded; }; /** * @override */ FeedItemVO.prototype.postBuild = function () { this.author = new UserVO().build(this.author); this.relatedObject = new RelatedObjectVO().build(this.relatedObject); this.event = new EventVO().build(this.event); this.event.createDate = new Date(this.createDate); this.createDateLabel = moment(this.createDate).fromNow(); if (this.relatedObject.type === EntityVO.SOCIAL_PROFILE_USER) { this.relatedObject.type = EntityVO.TYPE_PERSON; } if (this.isOutage()) { this.title = this.event.title; this.startDate = this.event.startDateHumanized; this.endDate = this.event.endDateHumanized; } if (this.isBroadcast()) { this.title = this.event.summary; //TODO: this should be title. Waiting for backend to change it this.summary = this.event.description; this.startDate = this.event.startDateHumanized; this.endDate = this.event.endDateHumanized; this.isBroadcastPriorityHigh = this.event.priority === 'High'; this.note = {}; this.note.attachmentCount = this.attachmentCount; this.note.attachments = this.attachments; } if (this.isComment() || this.isVendorComment()) { this.title = this.author.getFullName(); this.message = this.note.message || ''; } if (this.relatedObject.isAsset()) { this.relatedObject.id = this.relatedObject.displayId; this.relatedObject.showHeader = false; } if (this.isMyITComment()) { // remove mention to itself (from MyIT) var regExp = new RegExp('\\@\\[(' + this.relatedObject.title + ')\\]\\|(' + this.relatedObject.id + ')\\|\\((asset)\\)$', 'gi'); this.message = this.message.replace(regExp, ''); // now convert MyIT hyper link to Smart IT hyper link var mentionRegEx = /@\[(.*?)]\|(.*?)\|\(asset\)/gi; this.message = this.message.replace(mentionRegEx, function (match, displayName, id) { return '@[' + displayName + ']|' + id + '#POI' + '|(asset)'; }); this.note.myItLink = '../myitapp/#/activity-item/' + this.note.conversationRefId; // again we don't want link to inself this.relatedObject = null; } };