TaskEditorPopup = function( task, options ) { let instance = this; instance.taskId = task.taskId ? task.taskId : 0; instance.data = null; instance.taskData = null; instance.sourceTaskId = null; if( instance.taskId == 0 && task.sourceTaskId ) { instance.sourceTaskId = task.sourceTaskId } instance.connectedTo = null; instance.projectId = null; if( options ) { instance.connectedTo = options.connectedTo ? options.connectedTo : null; instance.projectId = options.projectId; } instance.form = null; instance.tabPanel = null; instance.detailFields = [ "taskId", "taskDescription", "requestedBy", "assignedTo", "dueDate", "priority", "projectId", "disposition", "dispositionDate", "dueDateNotification", "connectedTo" ]; instance.schedulingFields = [ "repeating", "frequency", "repeatFrom", "repeatUntil" ]; } TaskEditorPopup.prototype.constructor = TaskEditorPopup; TaskEditorPopup.prototype.getTaskData = function( taskId ) { let instance = this; let store = Fse.Data.newDataSource( { object : "WRK.tasks", keyField : "taskId" } ).store(); let keyTaskId = instance.taskId; if( keyTaskId == 0 && taskId ) { keyTaskId = taskId; } return store.byKey( keyTaskId ) } TaskEditorPopup.prototype.show = function() { let instance = this; instance.savePromise = $.Deferred(); let loadPromise = null; if( instance.taskId ) { loadPromise = instance.getTaskData(); } else if( instance.sourceTaskId ) { loadPromise = instance.getTaskData( instance.sourceTaskId ); } else { loadPromise = $.Deferred(); loadPromise.resolve( {} ); } loadPromise.done( function( taskData ) { if( ! instance.taskId && instance.sourceTaskId ) { // remove fields that will be set when the task is created delete taskData.sourceTaskId; delete taskData.taskId; delete taskData.dispositionDate; delete taskData.createDate; delete taskData.createdBy; delete taskData.updateDate; delete taskData.updatedBy; // change the status to open taskData.disposition = "?"; taskData.requestedBy = parseInt( Fse.Portal.appConfiguration.STP.userId ); } instance.taskData = taskData; }); loadPromise.done( function( taskData ) { // if( ! instance.taskId && instance.sourceTaskId ) { // // remove fields that will be set when the task is created // delete taskData.sourceTaskId; // delete taskData.taskId; // delete taskData.dispositionDate; // delete taskData.createDate; // delete taskData.createdBy; // delete taskData.updateDate; // delete taskData.updatedBy; // // change the status to open // taskData.disposition = "?"; // taskData.requestedBy = parseInt( Fse.Portal.appConfiguration.STP.userId ); // } instance._createPopup(); $("body").append( instance.popup.element() ) instance.popup.show(); }); return instance.savePromise; } TaskEditorPopup.prototype._createPopup = function(){ // instance.popup = null; let instance = this; let createToolbar = [ { toolbar : "bottom", location : "before", template : function() { return $("").css( { "color" : "silver"} ).text( "Task ID: new" ); } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Cancel", onClick : function( e ) { instance.popup.hide(); } } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Create & Edit", onClick : function( e ) { instance.saveTask().done( function( taskData ) { //let tabItems = instance.tabPanel.option( "items" ); //tabItems[1].disabled = false; // enable files tab instance.tabPanel.option( "items[1].disabled", false ); let loadPromise = instance.getTaskData(); loadPromise.done( function( taskData ) { instance.taskData = taskData; instance.tabPanel.repaint(); // change the title and toolbar instance.popup.option( { title : "Edit Task", "toolbarItems" : saveToolbar } ); instance.setFormData( instance.taskData ); }) }); } } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Create", type : "default", onClick : function( e ) { instance.saveTask().done( function( taskData ) { instance.savePromise.resolve( taskData ); instance.popup.hide(); }); } } } ]; let saveToolbar = [ { toolbar : "bottom", location : "before", template : function() { return $("").css( { "color" : "silver" } ).text( `Task ID: ${instance.taskId}` ); } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Cancel", onClick : function( e ) { instance.popup.hide(); } } }, { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Save", type : "default", onClick : function( e ) { instance.saveTask().done( function( taskData ) { instance.savePromise.resolve( taskData ); instance.popup.hide(); }); } } } ]; instance.popup = $("
").dxPopup( { title : instance.taskId ? "Edit Task" : "New Task", width : "80vw", height : "auto", contentTemplate : function() { instance.tabPanel = $("
").dxTabPanel( { height : 600, items : [ { id : "task", title : "Details", template : function( tabItem ) { let rightPanelItems = []; rightPanelItems.push( { baseSize : "auto", template : function() { let content = $("
") let schedulingContent = $("
").css( { "margin-left" : "10px", "padding-left" : "10px", "padding-bottom" : "10px", "background-color" : "#eef0f2" } ) instance.schedulingForm = instance.createSchedulingForm( instance.taskData ); schedulingContent.append( instance.schedulingForm.element() ); content.append( schedulingContent ); instance.commentForm = $("
").css( { "margin-left" : "10px", "margin-top" : "10px" } ).dxForm( { items : [ { label : { text : "Comment", location : "top" }, dataField : "postComment", editorType : "dxTextArea", editorOptions : { height : "50px" } } ] }).dxForm( "instance" ); content.append( instance.commentForm.element() ); return content; } } ); rightPanelItems.push( { ratio : 1, template : function() { let content = $("
").css( {"padding-left" : "10px", "padding-top" : "10px" } ); if( instance.taskId > 0 ) { let commentBoard = new CommentBoard( { subjectId : instance.taskId, subjectType : "WRT" }); content.append( commentBoard.element() ); } else { } // let uploadContent = $("
").css( { "margin-top" : "10px", "padding-left" : "3px", "padding-top" : "5px", "padding-bottom" : "5px", "background-color" : "#eef0f2" } ) // instance.fileForm = $("
").dxForm( { // items : [ // { // dataField : "taskFileUpload", // label : { visible : false }, // editorType : "dxFileUploader", // editorOptions : { // uploadMode : "useForm", // showFileList : false, // onValueChanged : function( e ) { // let file = null; // if( e.value && e.value.length ) { // file = e.value[0]; // } // if( file ) { // e.component.option( "labelText", file.name ); // } else { // e.component.option( "labelText", "or Drop file here" ) // } // } // } // } // ] // }).dxForm( "instance" ); // uploadContent.append( instance.fileForm.element() ) // content.append( uploadContent ) return content; } } ); // rightPanelItems.push( { // baseSize : 50, // template : function() { // let content = $("
").css( {"padding-left" : "10px", "padding-top" : "10px" } ) // instance.fileUploader = $("
").dxFileUploader( { // }).dxFileUploader( "instance" ); // content.append( instance.fileUploader.element() ) // return content; // } // }) let content = $("
").css( { "padding" : "5px", "padding-top" : "10px" } ).dxBox( { items : [ { baseSize : "50%", template : function() { instance.form = instance.createDetailsForm(); return $("
").css( { "padding-right" : "10px" } ).append( instance.form.element() ); } }, { baseSize : "50%", box : { direction : "col", items : rightPanelItems } } ] }); return content; } }, { id : "files", title : "Files", disabled : instance.taskId ? false : true, template : function( tabItem ) { let assetGrid = new AssetGrid( { contentDomain : "WRK", containerType : "WRT", containerId : instance.taskId, allowLinks : true, visibleColumns : [ "fileExt", "docTitle", "docDescription", "updateDate", "buttons" ], categoryEnabled : false }); return assetGrid.element(); } } ] }).dxTabPanel( "instance" ); return instance.tabPanel.element(); }, onHidden : function( e ) { e.component.dispose(); instance.popup = null; }, onShown : function( e ) { if( instance.taskId || instance.sourceTaskId ) { // loadPromise.done( function( taskData ) { if( instance.taskData ) { instance.setFormData( instance.taskData ); } // }) } if( instance.taskId == 0 ) { instance.form.getEditor( "taskDescription").focus(); } }, toolbarItems : instance.taskId ? saveToolbar : createToolbar }).dxPopup("instance"); } TaskEditorPopup.prototype.setFormData = function( data ) { let instance = this; let detailFormData = {}; instance.detailFields.forEach( function( dataField ) { detailFormData[dataField] = data[dataField]; }) detailFormData.dueDateNotification = detailFormData.dueDateNotification ? detailFormData.dueDateNotification : 0; instance.form.option( "formData", detailFormData ); let schedulingFormData = {}; instance.schedulingFields.forEach( function( dataField ) { schedulingFormData[dataField] = data[dataField]; }) schedulingFormData.repeating = schedulingFormData.repeating ? schedulingFormData.repeating : 0; schedulingFormData.frequency = schedulingFormData.frequency ? schedulingFormData.frequency : "M"; schedulingFormData.repeatFrom = schedulingFormData.repeatFrom; instance.schedulingForm.option( "formData", schedulingFormData ); instance.applyAccessControl( data ); } TaskEditorPopup.prototype.applyAccessControl = function( data ) { let instance = this; let ownerAccess = data.requestedBy == parseInt( Fse.Portal.appConfiguration.STP.userId ) || Fse.Portal.checkPermission( "TaskManagementAdmin"); instance.detailFields.forEach( function( dataField ) { if( dataField == "disposition" || dataField == "dueDateNotification" || dataField == "requestedBy" || dataField == "dispositionDate" ) return; // if( dataField == "assignedTo" && ! Fse.Portal.checkPermission( "TaskManagementReassign" ) ) return; // let editor = instance.form.getEditor( dataField ); // if( editor ) { // let editorOptions = { readOnly : ( ownerAccess || Fse.Portal.checkPermission( "TaskManagementReassign" )) ? false : true } // editor.option( editorOptions ); // } if( dataField == "assignedTo" && ! ownerAccess ) return; let editor = instance.form.getEditor( dataField ); if( editor ) { let editorOptions = { readOnly : ownerAccess ? false : true } editor.option( editorOptions ); } } ); instance.schedulingFields.forEach( function( dataField ) { let editor = instance.schedulingForm.getEditor( dataField ); if( editor ) { let editorOptions = { readOnly : ownerAccess ? false : true } editor.option( editorOptions ); } }) } TaskEditorPopup.prototype.saveTask = function() { let instance = this; let savePromise = $.Deferred(); let vr = instance.form.validate(); // console.log( "validationResult", vr ); if( ! vr.isValid ) { savePromise.reject(); return savePromise }; let formData = $.extend( true, {}, instance.form.option( "formData" ), instance.schedulingForm.option( "formData" ), instance.commentForm.option( "formData" )); // console.log( "formData To Save", formData ); let files = []; // let fileFormData = instance.fileForm.option( "formData" ); // let taskFileUpload = fileFormData.taskFileUpload; // if( taskFileUpload ) { // taskFileUpload.forEach( function( fe ) { // if( files.length ) return; // only one file // files.push( { fieldName : "taskFileUpload", data : fe } ) ; // }) // } Fse.Ajax.performAction( { object : "WRK.saveTask", data : formData, files : files }).done( function( result ) { instance.taskId = result.taskId; formData.taskId = result.taskId; instance.form.updateData( "taskId", instance.taskId ); savePromise.resolve( formData ); // instance.savePromise.resolve( formData ) }) return savePromise; } TaskEditorPopup.prototype.createDetailsForm = function() { let instance = this; let initialFormData = { disposition : "?", priority : 3, dueDateNotification : false, }; if( instance.connectedTo ) { initialFormData.connectedTo = $.extend( true, {}, instance.connectedTo ); } if( instance.projectId ) { initialFormData.projectId = instance.projectId; } if( !Fse.Portal.checkPermission( "TaskManagmentReassign" ) ) { initialFormData.assignedTo = parseInt( Fse.Portal.appConfiguration.STP.userId ); } if( instance.taskId == 0 ) { initialFormData.requestedBy = parseInt( Fse.Portal.appConfiguration.STP.userId ); } let form = $("
").dxForm( { validationGroup : "taskForm", formData : initialFormData, items : [ { itemType : "group", colCount : 1, items : [ { dataField : "taskDescription", label : { text : "Name"}, isRequired : true, editorType : "dxTextBox", editorOptions : { maxLength : 2000 } }, { dataField : "requestedBy", isRequired : true, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "FSPRO.members", keyField : "fspro_userId", paginate : true } ), valueExpr : "fspro_userId", displayExpr : "fullName", readOnly : true } }, { dataField : "assignedTo", isRequired : true, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "FSPRO.members", keyField : "fspro_userId", paginate : true } ), valueExpr : "fspro_userId", displayExpr : "fullName", searchEnabled : true, searchExpr : "fullName", searchMode : "contains", readOnly : Fse.Portal.checkPermission( "TaskManagementReassign" ) ? false : true } }, { dataField : "dueDate", isRequired : true, editorType : "dxDateBox", editorOptions : { min : instance.taskId ? null : new Date() } }, { dataField : "priority", editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : 1, text : "High" }, { value : 3, text : "Medium" }, { value : 5, text : "Low" } ], key : "value" }}, valueExpr : "value", displayExpr : "text" } }, { dataField : "connectedTo", label : { text : "Connected To" }, editorType : "dxDropDownBox", editorOptions : { disabled : initialFormData.connectedTo ? true : false, openOnFieldClick : false, showDropDownButton : false, placeholder : "Operator, Distributor or Contact...", fieldTemplate : function( value, fieldElement ){ // console.log( "fieldTemplate", value ); let ddbx = this; let valueReadyPromise = $.Deferred(); if( value ) { if( value.contactId ) { let ds = Fse.Data.newDataSource( { object : "CRM.contactList", keyField : "fspro_userId", objectParams : { partnerType : value.partnerType } } ).store(); ds.byKey( value.contactId ).done( function( contactData ) { if( contactData ) { valueReadyPromise.resolve( `${contactData.fullName} @ ${contactData.partnerName}` ); } else { valueReadyPromise.resolve( null ); } }) } else if( value.partnerType == "OPR" ) { let ds = Fse.Data.newDataSource( { object : "CRM.operatorList", keyField : "operatorId" } ).store(); ds.byKey( value.partnerId ).done( function( operatorData ) { if( operatorData ) { valueReadyPromise.resolve( operatorData.companyName ); } else { valueReadyPromise.resolve( null ); } }) } else if ( value.partnerType == "CDR" || value.partnerType == "DST" ) { let ds = Fse.Data.newDataSource( { object : "CRM.distributorList", keyField : "cdr_recordId" } ).store(); ds.byKey( value.partnerId ).done( function( distributorData ) { if( distributorData ) { valueReadyPromise.resolve( distributorData.cdr_dstname ); } else { valueReadyPromise.resolve( null ); } }) } else { valueReadyPromise.resolve( `${value.partnerType}:${value.partnerId}` ); } } else { valueReadyPromise.resolve( null ); } let fieldConfig = { placeholder : ddbx.option("placeholder"), readOnly: true } let field = $("
").dxTextBox( fieldConfig ).dxTextBox( "instance" ); fieldElement.append( field.element() ); valueReadyPromise.done( function( value ) { field.option( "value", value ); }) }, onValueChanged : function( e ) { // console.log( "valueChanged.connectedTo", e.value ) }, buttons : [ { name : "testing", location : "after", options : { icon : "more", onClick : function( e ) { let pp = new PartnerPicker( { allowAdd : true, partnerTypes : "OPR,OPRC,CDR,CDRC" }); pp.show().done( function( partnerData ) { let connectedTo = null; if( partnerData ) { if( partnerData.operatorId ) { connectedTo = { partnerType: "OPR", partnerId : partnerData.operatorId, contactId : null } } else if ( partnerData.cdr_recordId ) { connectedTo = { partnerType: "CDR", partnerId : partnerData.cdr_recordId, contactId : null } } else if ( partnerData.fspro_userId ) { connectedTo = { partnerType: partnerData.partnerType, partnerId : partnerData.partnerId, contactId : partnerData.fspro_userId } } } let editor = instance.form.getEditor( "connectedTo" ); editor.option( "value", connectedTo ); }); } } } ] } } ] }, { itemType : "group", colCount : 2, items : [ { colSpan : 2, dataField : "projectId", label : { text : "Project" }, editorType : "dxSelectBox", editorOptions : { dataSource : Fse.Data.newDataSource( { object : "WRK.projects", keyField : "projectId", paginate : true } ), valueExpr : "projectId", displayExpr : "projectName", showClearButton : true, searchEnabled : true, searchExpr : "projectName", searchMode : "contains", placeholder : "Select a Project...", disabled : initialFormData.projectId ? true : false, buttons : [ "dropDown", { name : "addProject", options : { icon : "plus", onClick : function( e ) { let pe = new ProjectEditorPopup(); pe.show().done( function( projectData ) { // console.log( "Project Data Returned", projectData ); if( projectData.projectId ) { let projectField = instance.form.getEditor( "projectId" ); if( projectField ) { projectField.option( "value", projectData.projectId ) } } }) } } } ], onSelectionChanged : function( e ) { let form = instance.form; let selectedItem = e.component.option( "selectedItem" ) if( selectedItem ) { form.updateData( { projectStartDate : selectedItem.startDate, projectEndDate : selectedItem.endDate } ) } else { form.updateData( { projectStartDate : null, projectEndDate : null } ) } } } }, { dataField : "projectStartDate", label : { text : "Project Start" }, editorType : "dxDateBox", editorOptions : { readOnly : true, } }, { dataField : "projectEndDate", label : { text : "Project End" }, editorType : "dxDateBox", editorOptions : { readOnly : true, } } ] }, { itemType : "group", colCount : 2, alignItemLabels : true, items : [ { dataField : "disposition", label : { text : "Status" }, editorType : "dxSelectBox", editorOptions : { dataSource : { store : { type : "array", data : [ { value : "?", text : "Open" }, { value : "X", text : "Complete" }, { value : "Z", text : "Cancelled" }, { value : "H", text : "On Hold" } ], key : "value" }}, valueExpr : "value", displayExpr : "text" } }, { dataField : "dispositionDate", label : { text : "Status Date"}, editorType : "dxDateBox", editorOptions : { readOnly : true } } ] }, { itemType : "group", items : [ { template : function( ) { return $("
").css( { "padding-top" : "10px" } ).text( "Assignee to receive Due Date email notifications, 1 week prior, 1 day prior and every day there after until this task is complete." ); }}, { dataField : "dueDateNotification", editorType : "dxSwitch", label : { text : "Due Date Notification" } } ] } ], onFieldDataChanged : function( e ) { if( e.dataField == "projectId" ) { /* if( e.value ) { let editor = e.component.getEditor( "projectId" ); let project = editor.option( "selectedItem" ); e.component.updateData( { projectStartDate : project.startDate, projectEndDate : project.endDate }) } else { e.component.updateData( { projectStartDate : null, projectEndDate : null }) } */ } if( e.dataField == "connectedTo" ) { //console.log( e ); } //console.log( "fieldDataChanged", e ); if( e.dataField == "dueDate" ) { if( instance.schedulingForm ) { instance.schedulingForm.updateData( { "repeatFrom" : e.value } ); } } } }).dxForm("instance"); return form; } TaskEditorPopup.prototype.createSchedulingForm = function( taskData ) { let instance = this; let schedulingForm = $("
").dxForm( { validationGroup : "taskForm", formData : { frequency : "W", repeating : false }, items : [ { dataField : "repeating", editorType : "dxSwitch", editorOptions : { disabled : taskData && taskData.sourceTaskId ? true : false } }, { dataField : "frequency", editorType : "dxRadioGroup", editorOptions : { disabled : true, items : [ { text : "Daily", id : "D" }, { text : "Weekly", id : "W" }, { text : "Monthly", id : "M" }, { text : "Yearly", id : "Y" } ], valueExpr : "id", displayExpr : "text", layout : "horizontal" } }, { itemType : "group", colCount : 4, items : [ { dataField : "repeatFrom", editorType : "dxDateBox", editorOptions : { showDropDownButton : false, disabled : true, width : 110 }, label : { text : "Start Date" } }, { dataField : "repeatUntil", editorType : "dxDateBox", editorOptions : { disabled : true, width : 110 }, label : { text : "End Date" }, isRequired : true } ] } ], onFieldDataChanged : function( e ) { if( e.dataField == "repeating" ) { let repeating = e.value; let frequencyField = e.component.getEditor( "frequency" ); let repeatUntilField = e.component.getEditor( "repeatUntil" ); let fieldOptions = { "disabled" : repeating ? false : true }; frequencyField.option( fieldOptions ); repeatUntilField.option( fieldOptions ); } if( e.dataField == "repeatFrom" ) { let repeatUntilField = e.component.getEditor( "repeatUntil" ); repeatUntilField.option( "min", e.value ); } } }).dxForm( "instance" ); return schedulingForm; } CommentBoard = function( options ) { let instance = this; instance.rootElement = null; instance.subjectId = options.subjectId; instance.subjectType = options.subjectType; instance.noForm = options.noForm ? true : false; } CommentBoard.prototype.constructor = CommentBoard; CommentBoard.prototype.addComment = function() { let instance = this; let savePromise = $.Deferred(); let formData = instance.form.option( "formData" ); if( instance.postComment || instance.postComment != "" ) { savePromise = Fse.Ajax.performAction( { object : "WEBLOG.savePartnerNote", data : formData }) savePromise.done( function( savePartnerResult ) { // console.log("savePartnerResult", savePartnerResult ); instance.form.updateData( "postComment", null ); instance.list.reload(); }) } else { savePromise.resolve(); } return savePromise; } CommentBoard.prototype.element = function() { let instance = this; if( instance.rootElement ) return instance.rootElement; instance.rootElement = $("
").addClass( "CommentBoard" ); if( false ) { instance.form = $("
").dxForm( { formData : { partnerType : instance.subjectType, partnerId : instance.subjectId, postComment : null, postId : 0, revise : "NO", ownerId : Fse.Portal.appConfiguration.STP.ownerId, ownerType : Fse.Portal.appConfiguration.STP.ownerType, userId : Fse.Portal.appConfiguration.STP.userId }, items : [ { label : { text : "Comment", location : "top" }, dataField : "postComment", editorType : "dxTextArea", editorOptions : { height : "50px", xonKeyUp : function( e ) { if( e.component.option( "value" )) { addCommentButton.option( "disabled", false ); } else { addCommentButton.option( "disabled", true ); } } } } ] }).dxForm( "instance" ); instance.rootElement.append( instance.form.element() ); let addCommentButton = $("
").dxButton( { type : "normal", xdisabled : true, text : "Add Comment", onClick : function( e ) { instance.addComment(); } }).dxButton( "instance" ); let toolbar = $("
").dxToolbar( { items: [ { location : "after", template : function() { return addCommentButton.element(); } } ] }).dxToolbar( "instance"); instance.rootElement.append( toolbar.element().css( { "margin-top" : "5px", "margin-bottom" : "5px" } ) ); } let postsDataSource = Fse.Data.newDataSource( { object : "WEBLOG.posts", keyField : "postId", paginate : false, objectParams : { partnerId : instance.subjectId, partnerType : instance.subjectType, postType : 'GEN' }} ); postsDataSource.sort( [ { selector: "postDateTime", desc: true }] ); let boldFirst = false; // this doesn't display well so it was requested that it be turned off instance.list = $("
").css( "border", "1px solid silver" ).dxList( { height : 225, selectionMode : "none", dataSource : postsDataSource, noDataText : "No Comments", itemTemplate : function( item ) { let css = { "display" : "flex", "flex-direction" : "column", "padding-bottom" : "8px" }; if( boldFirst ) { css["font-weight"] = "bold"; } boldFirst = false; let content = $("
").css( css ); let postDateTime = DevExpress.localization.formatDate( new Date( item.postDatetime ), "shortDateShortTime" ); content.append( $("
").text( `${postDateTime} | ${item.posterFirstName} ${item.posterLastName}` ).css( { "color" : "silver", "flex" : "auto" })); content.append( $("
").text( item.postComment ).css( { "flex" : "auto", "white-space" : "wrap" } ) ); return content; } }).dxList( "instance" ); instance.rootElement.append( instance.list.element() ); return instance.rootElement; }