New Project Server CSOM API features released by MS

Microsoft posted an update to the CSOM API on Nuget last week, see the full announcement here: New SharePoint CSOM version released for SharePoint Online – January 2017

Significantly for those of us in the world of Project Server is the addition of a handful of new classes and methods for managing Enterprise Resource Cost Rates:

  • public class Microsoft.ProjectServer.Client.CostRateCreationInformation
  • public enum Microsoft.ProjectServer.Client.CostRateTableName
  • public property Microsoft.ProjectServer.Client.DraftAssignment.CostRateTable
  • public property Microsoft.ProjectServer.Client.EnterpriseResource.CostRateTables
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRate
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRateCollection
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRatePropertyNames
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRateTable
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRateTableCollection
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRateTableObjectPropertyNames
  • public class Microsoft.ProjectServer.Client.EnterpriseResourceCostRateTablePropertyNames
  • public class Microsoft.ProjectServer.Client.PageSizes
  • public class Microsoft.ProjectServer.Client.PageSizesPropertyNames
  • public property Microsoft.ProjectServer.Client.ProjectContext.PageSizes
  • public property Microsoft.ProjectServer.Client.PublishedAssignment.CostRateTable

(Copied from the Office Blog above)

Good news as that is one more step closer to CSOM / JSOM API parity with the now legacy PSI, also great news to see something new from MS for us poor neglected Project developers. ;)

New Project CSOM library sneak-peak

After reading all about the new SharePoint CSOM release but unfortunately not being able to read about the changes to the Project Online CSOM library included in the SharePoint release, I decided to take a sneak-peek myself to see what’s new.

Fortunately my favourite .Net Reflector tool (JetBrains dotPeek) came in handy here in addition to a diff tool (WinMerge) it is possible to identify the changes to the Microsoft.ProjectServer.Client.dll file immediately!

What’s new?

Well, below I have extracted from the differences the new properties and methods available, the list is probably not 100% complete as I focused most on the areas I use: Projects, Tasks, Assignments, Workflows and Timesheets, err so let’s say it’s pretty complete, however I may have missed some things.

In short the obvious new items relate to previously announced changes, such as the Project ID feature now available in Project Online; DraftProject.ProjectIdentifier, and the Create Project Site from workflow feature; PublishedProject.CreateProjectSite(string siteName).

However notably missing is the bulk update of custom fields method I would have expected (previously released for Project Online workflows), that’s slightly annoying if say you have an App that updates projects in bulk or something similar (*ahem*).

What else is interesting?

Some new Public Properties made available to developers:

  • (DateTime) DraftProject.UtilizationDate
  • (ProjectUtilizationType) DraftProject.UtilizationType
  • (ProjectSummaryTask) Project.ProjectSummaryTask
  • (StatusApprovalType) StatusAssignment.ApprovalStatus
  • (StatusAssignmentHistoryLineCollection) StatusAssignment.History
  • (Guid) StatusText.ProjectTaskId

As well as one new Public Method made available:

  • ProjectContext.GetDeletedPublishedAssignments(deletedDate)

Based on the names I think it’s safe to assume that most of those relate to the new 2016 Resource Engagements feature which is already available on Project Online, however apart from the new ProjectSummaryTask property unfortunately there doesn’t seem to be any breaking news here to report! :(

I guess we’ll just have to wait for the official announcement to hear any more..

(Mostly) Complete list of modified classes

Note: I’ve ignored a lot of minor changes that appear to be simple refactoring’s and focused only on the new Public Properties and Methods while ignoring a few Internal methods and such.

Assignment.cs

  • public WorkContourType WorkContourType

DraftProject.cs

  • public string ProjectIdentifier
  • public DateTime UtilizationDate
  • public ProjectUtilizationType UtilizationType

Project.cs

  • public ProjectSummaryTask ProjectSummaryTask

ProjectContext.cs

  • public DeletedPublishedAssignmentCollection GetDeletedPublishedAssignments(DateTime deletedDate)

ProjectServer.cs

  • public DeletedPublishedAssignmentCollection GetDeletedPublishedAssignments(DateTime deletedDate)

PublishedProject.cs

  • public string ProjectIdentifier
  • public DateTime UtilizationDate
  • public ProjectUtilizationType UtilizationType
  • public void CreateProjectSite(string siteName)

StatusAssignment.cs

  • public StatusApprovalType ApprovalStatus
  • public StatusAssignmentHistoryLineCollection History
  • public DateTime Modified

StatusText.cs

  • public Guid ProjectTaskId

(Mostly) Complete list of new classes and enumerations

  • public class DeletedPublishedAssignment : ClientObject
  • public class DeletedPublishedAssignmentCollection : ClientObjectCollection
  • public class ProjectSummaryTask : Task
  • public enum ProjectUtilizationType
  • public class StatusAssignmentHistoryLine : ClientObject
  • public class StatusAssignmentHistoryLineCollection : ClientObjectCollection
  • public enum StatusUpdateType
  • public enum WorkContourType

Hope that satisfied your curiosity…

CICONotCheckedOut queue errors when updating projects via JSOM

I’ve written many times before about working with projects using the JSOM and CSOM API’s, and this is another issue in the API that I’ve had to resolve for one of my apps (in this case Bulk Edit).

Issue

When updating built in fields (I haven’t observed this for custom fields) using the client side library (JSOM or CSOM or REST) in the normal way the following error can be reported in the queue unexpectedly:

CICONotCheckedOut: CICONotCheckedOut (10102). Details: id=’10102′ name=’CICONotCheckedOut’ uid=’a2da51ea-792b-e411-9af1-00155d908811′.

Queue: GeneralQueueJobFailed (26000) – ProjectUpdate.FailIfNotCheckedOutMessage. …

For example the following code from the MSDN article on this topic will intermittently get the above error:

// Get the target project and then check it out. The checkOut function
// returns the draft version of the project.
var project = projects.getById(targetGuid);
var draftProject = project.checkOut();

// Set the new property value and then publish the project.
// Specify "true" to also check the project in.

draftProject.set_startDate("2013-12-31 09:00:00.000");
var publishJob = draftProject.publish(true);

// Register the job that you want to run on the server and specify the
// timeout duration and callback function.
projContext.waitForQueueAsync(publishJob, 10, QueueJobSent);

This is despite the fact that we are obviously doing the check-out of the project in line 4.

Worse still:

  1. The update will still work for most fields (like Status Date but NOT for Project Owner), despite the error indicating otherwise!
  2. The error is not consistent, some updates work without an error.

Cause and Solution

Turns out the issue is one due to the asynchronous nature of the client side libraries, specifically it looks like when performing the “waitForQueueAsync”  we are actually requesting four things:

  1. Check out Project
  2. Update project value (start date above)
  3. Publish Project
  4. Check project back in

However it seems that steps 2 and 4 don’t quite run in the correct order!  Changing line 10 as follows to NOT check-in after publishing results in a successful update and no error:

var publishJob = draftProject.publish(false);

Then we need to add a separate checkIn() call AFTER the completion of the publish (IE in the callback function ‘QueueJobSent‘ above) and then call waitForQueueAsync again.

Looks like a bug although perhaps not as it is important to keep in mind that the queued async jobs are not guaranteed to be done in the correct order although clearly it usually happens in the order expected.

 

BTW, Yes expect an update for Bulk Edit supporting more built-in fields soon!

Correcting the alignment of PDP Web Parts

Recently I spoke at a Microsoft Project Server event here in Switzerland on the topic of Extending Project Server and using small pieces of JavaScript with jQuery to make little changes for big effects. One of my demos was to correct the following annoyance that many of us have probably come across but have no out of the box way to fix.

Project Detail Pages column alignment issues

Example

pdp screen 1

 

In yellow I have highlighted the issue that I’m talking about in case it is not obvious in the screenshot. As you see the alignment is actually based on the length of the longest custom field displayed in the web part, so as in the above example where we have used separate webparts to break up the webpage with headings the width of each column is unpredictable.

jQuery to the rescue

This is a great example of using jQuery as it shows how ridiculously simple some things can be to change! So let’s walk through the solution here if you’ve not done this before, as you will see the possible usage of this kind of “fix” is vast.

“Debugging” in Chrome or IE

The first thing you need to do to here is to identify the html element(s) in question, so the easiest way to do that is to use the “Inspect Element” feature available in both IE and Chrome browsers (and probably all others too), you’ll find it on the right click menu

pdp screen 2

When selected the inspect element will open up the developer console of your browser and focus on the specific element under the mouse, in this case the “Description” field text label.

pdp screen 3

Now you can browse the page source and as you see each element is highlighted, neat!

Now we can start using jQuery to select our columns to modify, start by dynamically loading the jQuery library using the following script:

var jq = document.createElement('script');
jq.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);

Now that we have jQuery available you can again look at the source and think about what we need to ‘select’, in this case we can see that our Description label is in a h3 inside of a table (tbody > tr > td) and specifically it has a class of “ms-formlabel”. Cool so in jQuery we can now select all such elements like this:

$("tr td.ms-formlabel")

Best thing is that being JavaScript all elements are selected and can be used in an array, but even better we can directly update all items like this:

$("tr td.ms-formlabel").width("300px");

Neat hey? If you run that command in the console immediately all the columns will update to be 300px wide!

Permanently applying fix to the page

So now we have our script let’s add it to a Content Editor Web Part (CEWP) on the page itself, to do that we need to wrap our line in some html which loads the jQuery library and runs the script when the page is ready, like this:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">

$( document ).ready(function() {
	$("tr td.ms-formlabel").width("300px");
})

</script>

Now edit the PDP web part page, and add a Content Editor web part to it, then simply add the above HTML content to the web part HTML source like so:

First add the Content Editor web part and use the Edit Source ribbon option

pdp screen 4

Then paste in our html script

pdp screen 5

Now each time the page is loaded the script is run and all columns are aligned to 300px looking something like this:

pdp screen 6

Enjoy!

Updating Checked Out Projects with JSOM

Another great thing to come out of Project Conf for me was the connections with people working on some of the same problems that I’ve faced, this is one of those; updating Projects which are checked out is not possible using the same old method that was used with the PSI! (Think about the problem this creates for PDP App Parts!)

Fortunately it is possible thanks to the following undocumented method discovered by Martin Petersen on his blog here:
http://projectserverinsights.blogspot.dk/2014/03/update-project-from-apppart.html

Check it out, and thanks Martin for the solution!

AngularJS and SharePoint App Template

One of the best takeaways for me while working on my Exists App which is built on the MEAN stack was getting to learn AngularJS, better yet at SPConf it was immediately obvious that I’m not the only one who thinks that AngularJS and SharePoint Apps are a perfect fit!

If you don’t know much about AngularJS and want to learn how it relates to SharePoint then I’d highly recommend Jeremy Thake’s excellent session on the topic presented at SPConf where he gives a great introduction to what Angular can do and shows some great examples using SharePoint Apps.

AngularJS Visual Studio Project Template

I’ve been meaning to take this to the next level after toying with creating a basic template app building on the default VS SharePoint hosted App template and adding Angular and some example code in a well defined MVC style template. My intention is to convert this into a VS Template to work along side the default SharePoint App template, but for now I’ve just setup a GitHub repository with a sample (non-templated) project, which looks something like the following:

spngtree

Have a look at the source on GitHub below.

SharePoint / AngularJS App Seed Project

https://github.com/martinlaukkanen/spng-seed

This is a test project designed to be a seed project (or eventually a Visual Studio Template) to implement a SharePoint single-page App built using AngularJS with a heavy emphasis on MVC design patterns.

The project structure is built to be very familiar to any ASP.NET MVC developer, while providing a good starting point for a simple (or complex) SharePoint AngularJS based App.

Initial version notes

  • VS2013 SharePoint Hosted App Project Template
  • NUGET AngularJS-Core package
  • Folder structure as per ASP.NET MVC pattern (/Controllers, /Models, /Views, etc)
  • Sample Model, View and Controller including directive and services to recreate the “‘Hello ‘ + user.get_title()” default template functionality.

Feedback Please!

I’m very keen for any feedback on this so either post below or even on GitHub, in particular my choice of using Directives vs Views or Slices or Includes is somewhat arbitrary. Although it is largely based on my view that this SPA (Single Page App) should not need routes and such as I don’t want to think how that could work within an SPAppWeb.

Finally, I am by no means an Angular expert, in fact I’m brand new to it! So all suggestions on best-practices and relevant design patterns are more than welcome.