ProjectEditorPopup = function( project ) { let instance = this; instance.projectId = 0; if( project ) { instance.projectId = project.projectId ? project.projectId : 0; } instance.data = null; instance.projectForm = null; instance.savePromise = null; instance.adminAccess = Fse.Portal.checkPermission( "TaskProjectAdmin") ? true : false; instance.ownerAccess = true; // true until we load data then we can use the projectOwnerUserId to determine let now = new Date(); let firstDayNextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1); let lastDayNextMonth = new Date(now.getFullYear(), now.getMonth() + 2, 0); instance.projectDefaults = { projectOwnerUserId : parseInt( Fse.Portal.appConfiguration.STP.userId ), startDate : firstDayNextMonth, endDate : lastDayNextMonth } instance.fspro_userId = parseInt( Fse.Portal.appConfiguration.STP.userId ); instance.sharedWithData = null; instance.sharedWithDataGrid = null; instance.saveButton = null; } ProjectEditorPopup.prototype.constructor = ProjectEditorPopup; ProjectEditorPopup.prototype.getProjectData = function() { let instance = this; let store = Fse.Data.newDataSource( { object : "WRK.projects", keyField : "projectId" } ).store(); return store.byKey( instance.projectId ) } ProjectEditorPopup.prototype.show = function() { let instance = this; instance.savePromise = $.Deferred(); let projectDataPromise = $.Deferred(); if( instance.projectId ) { instance.getProjectData().done( function( data ) { projectDataPromise.resolve( data ); }) } else { projectDataPromise.resolve( $.extend( true, {}, instance.projectDefaults ) ) } projectDataPromise.done( function( projectData ) { instance.projectData = projectData; instance.ownerAccess = instance.adminAccess || instance.projectData.projectOwnerUserId == parseInt( Fse.Portal.appConfiguration.STP.userId ); let title = "New Project"; if( projectData.projectId ) { if( instance.ownerAccess ) { title = "Edit Project" } else { title = "View Project" } } let saveToolbar = [ { toolbar : "bottom", location : "after", visible : ! instance.ownerAccess, widget : "dxButton", options : { text : "Close", onClick : function( e ) { popup.hide(); } } }, { toolbar : "bottom", location : "after", visible : instance.ownerAccess, widget : "dxButton", options : { text : "Cancel", onClick : function( e ) { popup.hide(); } } }, { toolbar : "bottom", location : "after", visible : instance.ownerAccess, template : function() { instance.saveButton = $("
").dxButton( { text : "Save", type : "default", onClick : function( e ) { instance.saveProject().done( function( projectData ) { instance.savePromise.resolve( projectData ); popup.hide(); }); } }).dxButton( "instance" ); return instance.saveButton.element(); } // widget : "dxButton", options : { // text : "Save", // type : "default", // onClick : function( e ) { // instance.saveProject().done( function( projectData ) { // instance.savePromise.resolve( projectData ); // popup.hide(); // }); // } // } } ]; let createToolbar = [ { toolbar : "bottom", location : "after", visible : instance.ownerAccess, widget : "dxButton", options : { text : "Cancel", onClick : function( e ) { popup.hide(); } } }, { toolbar : "bottom", location : "after", visible : instance.ownerAccess, widget : "dxButton", options : { text : "Create & Edit", onClick : function( e ) { instance.saveProject().done( function( projectData ) { tabItems[1].disabled = false; // enable visibility tab tabItems[2].disabled = false; // enable files tab tabItems[3].disabled = false; // enable tasks tab tabPanel.option( "items", tabItems ); // change the title and toolbar popup.option( { title : "Edit Project", "toolbarItems" : saveToolbar } ); }); } } }, { toolbar : "bottom", location : "after", visible : instance.ownerAccess, widget : "dxButton", options : { text : "Create", type : "default", onClick : function( e ) { instance.saveProject().done( function( projectData ) { instance.savePromise.resolve( projectData ); popup.hide(); }); } } } ]; let tabPanel = null; let tabHeight = "450px"; let tabItems = [ { title : "Details", template : function( itemData ) { instance.projectForm = instance.createProjectForm( instance.projectData ); return $("
").css( "height", tabHeight ).append( instance.projectForm.element() ) } }, { title : "Visibility", disabled : ! instance.projectData.projectId, template : function( itemData ) { instance.sharedWithData = []; instance.sharedWithDataGrid = $("
").dxDataGrid( { showBorders : true, scrolling : { mode : "virtual" }, height : "100%", noDataText : "This project is only visible to the owner", rowAlternationEnabled : true, dataSource : { store : { type : "array", data : instance.sharedWithData, key : [ "linkType", "linkId" ] }}, columns : [ { dataField : "text", caption : "Shared With" }, { width : 30, name : "buttons", type : "buttons", buttons : [ { icon : "trash", onClick : function( e ) { instance.removeSharedWithData( e.row.data ); } } ]} ], masterDetail : { enabled : true, template : function( container, info ) { let dataGrid = $("
").dxDataGrid( { columns : [ "fullName", "email" ], height : "100%", showBorders : true, }).dxDataGrid( "instance" ); container.append( dataGrid.element() ); if( info.data.linkType == "GRP" ) { let dataSource = Fse.Data.newDataSource( { object : "SEC.groupMembers", paginate : false, keyField : "fspro_userId", objectParams : { groupId : info.data.linkId } } ); dataGrid.option( "dataSource", dataSource ); } else { let dataStore = Fse.Data.newDataSource( { object : "SEC.users", paginate : false, keyField : "fspro_userId" } ).store(); dataStore.byKey( info.data.linkId ).done( function( memberData ) { dataGrid.option( "dataSource", [ memberData ]); }) } } }, onToolbarPreparing : function( e ) { if( ! e.toolbarOptions.items ) { e.toolbarOptions.items = []; } e.toolbarOptions.items.push( { location : "after", widget : "dxButton", options : { text : "Add Users", icon : "plus", onClick : function( e ) { instance.addUsers(); } }}, { location : "after", widget : "dxButton", options : { text : "Add Groups", icon : "plus", onClick : function( e ) { instance.addGroups(); } }} ) } }).dxDataGrid( "instance" ); let ds = Fse.Data.newDataSource( { object : "SEC.sharing", paginate : false, objectParams : { objectType : "WRP", objectId : instance.projectData.projectId } } ); let loadPromise = ds.load() loadPromise.done( function( data ) { data.forEach( function( i ) { instance.sharedWithData.push( i ); }) instance.sharedWithDataGrid.refresh(); }) return $("
").css( { "height" : tabHeight , "padding" : "5px" } ).append( instance.sharedWithDataGrid.element() ); } }, { title : "Files", disabled : ! instance.projectData.projectId, template : function( itemData ) { let assetGrid = new AssetGrid( { height : 450, contentDomain : "WRK", containerType : "WRP", containerId : instance.projectData.projectId, allowLinks : true, visibleColumns : [ "fileExt", "docTitle", "docDescription", "updateDate", "buttons" ], categoryEnabled : false }); return $("
").css( "height", tabHeight ).append( assetGrid.element() ); } }, { title : "Tasks", disabled : ! instance.projectData.projectId, template : function( itemData ) { let taskList = new TaskList( { projectId : instance.projectData.projectId } ) return $("
").css( "height", tabHeight ).append( taskList.element() ); } }, ]; let popup = $("
").dxPopup( { title : title, width : "60vw", height : 600, hideOnOutsideClick: true, showCloseButton: false, contentTemplate : function() { tabPanel = $("
").dxTabPanel( { items : tabItems, swipeEnabled : false }).dxTabPanel( "instance" ) return $("
").append( tabPanel.element() ); }, onHidden : function( e ) { e.component.dispose(); }, onShown : function( e ) { if( instance.projectId == 0 ) { instance.projectForm.getEditor( "projectName").focus(); } }, toolbarItems : instance.projectData.projectId ? saveToolbar : createToolbar // toolbarItems : [ // { toolbar : "bottom", location : "after", visible : ! instance.ownerAccess, // widget : "dxButton", // options : { // text : "Close", // onClick : function( e ) { // popup.hide(); // } // } // }, // { toolbar : "bottom", location : "after", visible : instance.ownerAccess, // widget : "dxButton", // options : { // text : "Cancel", // onClick : function( e ) { // popup.hide(); // } // } // }, // { // toolbar : "bottom", location : "after", visible : instance.ownerAccess, // widget : "dxButton", options : { // text : "Save Project", // type : "default", // onClick : function( e ) { // let creating = ! instance.projectData.projectId; // instance.saveProject().done( function( projectData ) { // if( creating ) { // tabItems[1].disabled = false; // enable files tab // tabItems[2].disabled = false; // enable tasks tab // tabPanel.option( "items", tabItems ); // } else { // instance.savePromise.resolve( projectData ); // popup.hide(); // } // }); // } // } // } // ] }).dxPopup("instance"); // instance.savePromise.done( function() { // popup.hide(); // }) $("body").append( popup.element() ) popup.show(); }) return instance.savePromise; } ProjectEditorPopup.prototype.getProjectData = function() { let instance = this; let store = Fse.Data.newDataSource( { object : "WRK.projects", keyField : "projectId" } ).store(); return store.byKey( instance.projectId ) } ProjectEditorPopup.prototype.saveProject= function() { let instance = this; let savePromise = $.Deferred(); let vr = instance.projectForm.validate(); //console.log( "validationResult", vr ); if( ! vr.isValid ) { savePromise.reject(); return savePromise; } let formData = instance.projectForm.option( "formData" ); //console.log( "formData To Save", formData ); if( instance.sharedWithData ) { formData.sharedWith = instance.sharedWithData; formData.saveSharedWith = true; } else { formData.saveSharedWith = false; } Fse.Ajax.performAction( { object : "WRK.saveProject", data : formData }).done( function( result ) { instance.projectData = result.project; // instance.savePromise.resolve( result.project ) savePromise.resolve( result.project ); }) return savePromise; } ProjectEditorPopup.prototype.createProjectForm = function( projectData ) { let instance = this; let form = $("
").dxForm( { validationGroup : "projectForm", formData : projectData, items : [ { dataField : "projectName", label : { text : "Project Name"}, isRequired : true, editorType : "dxTextBox", editorOptions : { maxLength : 100, readOnly : instance.ownerAccess ? false : true } }, { dataField : "projectOwnerUserId", isRequired : true, label : { text : "Project Owner" }, 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 : instance.adminAccess ? false : true } }, { dataField : "startDate", isRequired : true, editorType : "dxDateBox", editorOptions : { readOnly : instance.ownerAccess ? false : true }}, { dataField : "endDate", isRequired : true, editorType : "dxDateBox", editorOptions : { readOnly : instance.ownerAccess ? false : true }} ] }).dxForm("instance"); return form; } ProjectEditorPopup.prototype.addUsers = function() { let instance = this; let popup = null; let userList = null; let selectionCountElement = $("
"); let addButton = $("
").dxButton( { text : "Add Selected", type : "default", dislabled : true, onClick : function( e ) { let refresh = false; let selectedItems = userList.option( "selectedItems" ); selectedItems.forEach( function( i ) { let item = { text : i.fullName, linkId : i.fspro_userId, linkType : 'USR' } if( instance.addSharedWithData( item ) ) { refresh = true; } }) if( refresh ) { instance.sharedWithDataGrid.refresh(); } popup.hide(); } }).dxButton( "instance" ); userList = $("
").dxList( { dataSource : Fse.Data.newDataSource( { object : "SEC.users", keyField : "fspro_userId", paginate : false } ), displayExpr : "fullName", keyExpr : "fspro_userId", selectionMode : "multiple", searchEnabled : true, searchExpr : "fullName", searchMode : "contains", showSelectionControls : true, onOptionChanged : function( e ) { if( e.name == "selectedItems" ) { if( e.value && e.value.length ) { selectionCountElement.text( `${e.value.length} users selected` ); addButton.option( "disabled", false ); } else { selectionCountElement.empty(); addButton.option( "disabled", true ); } } } }).dxList( "instance" ); popup = $("
").dxPopup( { title : "Add Users", hideOnOutsideClick : true, width : 400, height : 400, contentTemplate : function() { return userList.element(); }, toolbarItems : [ { toolbar : "bottom", location : "before", template : function() { return selectionCountElement; } }, { toolbar : "bottom", location : "after", template : function() { return addButton.element(); } } ], onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).dxPopup( "instance" ); popup.element().appendTo( $("body")); popup.show(); } ProjectEditorPopup.prototype.addGroups = function() { let instance = this; let popup = null; let selectionCountElement = $("
"); let groupsDataSource = Fse.Data.newDataSource( { object : "SEC.groups", keyField : "groupId", paginate : false } ); // groupsDataSource.filter( [ "reportDistributionGroup", "=", "Y" ] ); let addButton = $("
").dxButton( { text : "Add Selected", type : "default", dislabled : true, onClick : function( e ) { let refresh = false; let selectedItems = groupList.option( "selectedItems" ); selectedItems.forEach( function( i ) { let item = { text : i.groupName, linkId : i.groupId, linkType : 'GRP' } if( instance.addSharedWithData( item ) ) { refresh = true; } }) if( refresh ) { instance.sharedWithDataGrid.refresh(); } popup.hide(); } }).dxButton( "instance" ); let groupList = $("
").dxList( { dataSource : groupsDataSource, displayExpr : "groupName", keyExpr : "groupId", selectionMode : "multiple", searchEnabled : true, searchExpr : "groupName", searchMode : "contains", showSelectionControls : true, onOptionChanged : function( e ) { if( e.name == "selectedItems" ) { if( e.value && e.value.length ) { selectionCountElement.text( `${e.value.length} groups selected` ); addButton.option( "disabled", false ); } else { selectionCountElement.empty(); addButton.option( "disabled", true ); } } } }).dxList( "instance" ); popup = $("
").dxPopup( { title : "Add Groups", hideOnOutsideClick : true, width : 400, height : 400, contentTemplate : function() { return groupList.element(); }, toolbarItems : [ { toolbar : "bottom", location : "before", template : function() { return selectionCountElement; } }, { toolbar : "bottom", location : "after", template : function() { return addButton.element(); } } ], onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).dxPopup( "instance" ); popup.element().appendTo( $("body")); popup.show(); } ProjectEditorPopup.prototype.addSharedWithData = function( data ) { let instance = this; let store = instance.sharedWithDataGrid.getDataSource().store(); let added = false; store.byKey( { linkId : data.linkId, linkType : data.linkType } ) .fail( function( ) { // this one is not aready there so we can add it instance.sharedWithData.push( data ); added = true; }) if( added ) { instance.saveButton.option( { disabled : false } ) } return added; } ProjectEditorPopup.prototype.removeSharedWithData = function( data ){ let instance = this; let deleteIdx = -1; for( let idx = 0; idx < instance.sharedWithData.length; idx++ ) { let item = instance.sharedWithData[idx]; if( item.linkId === data.linkId && item.linkType === data.linkType ) { deleteIdx = idx; break; } } if( deleteIdx >= 0 ) { instance.sharedWithData.splice(deleteIdx, 1); instance.sharedWithDataGrid.refresh(); instance.saveButton.option( { disabled : false } ) } }