Speaking at SharePointFest Chicago 2018

I am very lucky enough to have been accepted to speak at SharePointFest Chicago for the third year running now. The subject is Automated Build and deploy of SharePoint Framework webparts.

One of the really fascinating things about working in a modern large development team is the outstanding benefits for automated testing, automated build, and automated deployment. Even for something which might not on the surface seem to be a “big deal” such as SPFx webpart development, has many advantages to be gained by using a professional automated development environment.

Since I submitted and was accepted to speak, VSTS has been renamed to Azure DevOps, so this might be difficult to pull off as a topic – but i think we will be ok 😉

SharePointFest is always  alot of fun with a good crowd of speakers and attendees. I am excited to attend and excited to speak 🙂

 

DEV304 – Using VSTS to automate build and deployment tasks for SharePoint Framework webparts

Working on your own and building SharePoint Framework webparts is one thing, but when you have to work in a team on a larger project, the team approach to development has to be more structured and automated.

Modern team web development practices demand the use of unit tests, load testing and automated build and deploy methodologies. Why should developing for the Sharepoint framework be any different?

In this presentation Mark will highlight the advantages to using VSTS to create and manage and continuous build and deploy process for working with the Sharepoint Framework. Come and see how modern team development techniques can be applied to SPFx.

S106A Fri 2:20 PM – 3:30 pm

The JDRF One Walk – Trying to find a cure for Childhood Type 1 Diabetes

Type 1 Diabetes (T1D) is a serious and stressful disease to manage.  When you have T1D, your pancreas stops producing insulin—a hormone essential to turning food into energy. This means you must constantly monitor your blood-sugar level, administer insulin, and carefully balance these insulin doses with your eating and activity just to stay alive. JDRF is the only global diabetes foundation with a strategic plan to end T1D. One of the main fundraisers for JDRF is in the form of the “Walk for the Cure” held all over the country these walks are often attended by thousands of people, all walking to help raise money to find a cure for T1D.

Just over a year ago we found out that my youngest daughter Paige has Type 1 Diabetes. JDRF has been amazing in helping us initially cope with the disease, but also being there in support of us when we needed it and providing community support for families in our situation.

Last year my company PSC Group sponsored The Odd Socks walk team as part of the work done through the Philanthropic Committee. We raised over $5,000 as a team and we were incredibly proud of what we achieved in our first year.

We are doing the Walk in Schaumburg Illinois again this year September 30th.

Please consider donating your time and or fundraising for the team so that we may find a cure for T1D. You can do both from the link to the team page below.

https://www2.jdrf.org/site/TR?fr_id=7460&pg=team&team_id=264088

You can join the team any time until the day of the walk itself but we need to know before Saturday 22nd if you want one of the new improved TYE-DYE t-shirts for 2018.

 

 

PSC Tech Talk: Using Chrome Profiles for Office365 developers

In this presentation one of our Directors @MarkyRoden gave a short presentation on using Chrome profiles to help manage your life as a developer.

Mark gave the example of having a chrome profile for each of his customers and how he takes advantages of the features the profiles provide.

Using Chrome profiles you can:

  • Store separate bookmarks per profile
    • This means that you can create specific bookmarks just for that customer and/ or that development environment.
  • Different homepages
    • You can create a unique set of pages which always opens for each individual profile. For his salesforce instance Mark has the SalesForce tenant open automatically, for his Azure dev profile, Mark has portal.azure.com open automatically.
  • It remembers you
    • When you log into a website like Office365 for example, you can allow the system to remember who you are and now ask you for authentication every time. These credentials are remembered separately for each profile. Using this Mark can log into him development instance of Office365 by opening the profile and when he opens his PSC instance of Office365 in his Work profile, he is logged into the PSC Office 365 tenant.
  • Chrome extensions
    • Each profile has it’s own set of chrome extensions. So those which are useful for salesforce development, are only available in the salesforce profile.
  • Microsoft Teams
    • Right now you cannot log into two separate client instances within one Teams Client instance. Mark uses his client profiles so that he can access teams for each organization separately within their own tenant, while keeping them all separate from each other.

 

 

 

PSC Tech Talks – Securing AWS Lambdas

During this PSC Tech Talk, Roger Tucker gave an in depth technical talk on how to create signatures and the secure HTTP headers necessary to have secure authenticated access to calling and executing Amazon Web Services (AWS) Lambdas.

What are AWS Lambdas?

AWA Lambdas are a serverless service that runs your code in response to events and automatically manages the underlying compute resources.

PSC uses Lambdas for a number of AWS projects which we create and manage for our clients. The advantages of Lambdas are that they self-scale, and the client is only billed for the time the lambads are running. The presentation was not about the right way (there are many) to architect a Lambda based application. That would be for another day.

Samples Lambdas

Roger showed how to create a simple Lambda function in and call it via an unsecured API Gateway endpoint. Using the Postman tool he demonstrated how the response can be triggered from an unsecured API Gateway endpoint in a development environment.

Roger set a different API Gateway endpoint to use IAM (Identify access manager) security. He allowed the TestLambda user to have access to one resource – the secure demo api.

 

His initial attempt to call the enpoint using Postman with no Authorization provided resulted in a “missing authentication token” message.

In the next attempt the AWS signature option was selected in postman.  He provided the appropriate AWS credentials, region and service name in Postman and resubmitted the request.  We saw how Postman allows us to create the AWS Signature and HTTP header for the sake of testing. And now that the test user has access, we can see the proper response from the endpoint.

 

Creating the signature

Roger demonstrated how to create the Signature necessary for the HTTP header. Starting with a Canonical Request, your AWS credentials, endpoint region, and service you can create the signature. The signature is then used to create the HTTP header.

The hashed response to the canonical request “e3boc……”then becomes an input for a string which is needed to generate the signature.

Using the string to sign (containing the credential scope) we then create the Signature and this is what is attached to the api call as an Authorization header.

There are multiple levels of hashing, this is intentionally complicated, so as to make the Lambdas as secure as possible. This signature must make the necessary hash generated on the server to allow the authorization to be allowed.

Roger then closed out the presentation by showing how his Python code creates these separate credentials and how he can then call the secure Lambda directly.

Conclusion

Securing Lambdas is a complex process, this is by design to ensure that an open endpoint cannot be called by a rogue service.

 

Renewed as a Microsoft MVP 2018-2019

I am very honoured and humbled to be renewed as a Microsoft MVP for 2018-2019 in the category of Office Development. The MVP program recognizes content creators, code providers and conference speakers who want to share their knowledge and broaden the outreach of the platforms they work with.

Since I got involved in Office Add-In development over two years ago it has been an truely gratifying, eye-opening experience to see what a transformed company Microsoft is. I have never written a line of .NET code. I am a web developer, and using those web dev. skills I am now a Microsoft developer and MVP. The me of ten years ago would never have believed it possible 🙂

 

Thank you to Microsoft for the recognition and all the perks which come along with the award.
Thank you to every one at PSCGroup who continues to enable me in what I do and love, and long may it continue.
Thank you to all the friends I have met along the way and who’s encouragement is always wecome and appreciated.

 

 

How Windows 10 virtual desktops help me with Office 365 development

In this article I will show how the Windows 10 virtual desktops help keep my brain organized for Office 365 development. It allows me to keep my Chrome Primary work profile for email etc completely separate from my developer tenat Chrome profile. It helps keep me more organized when working on multiple projects as well.

Background

Anyone who has more than one development and primary Office 365 account has come across the age old problem of which environment am I currently working in. Using Chrome profiles as a number of people have blogged about has been a huge help in this. Having a Chrome profile for dev tenant and profile for primary account (work email etc) is a huge help.

But the downside is many instances of chrome floating around and when you click on a link in Outlook it opens in the last Chrome window you were working on – which is frustrating at the best of times when your dev tenant says you dont have access to your primary email (duh) and then you have to hunt down the primary profile window and go back to outlook and start again.

Windows 10 Virtual Desktop

This is where the virtual desktop has really become my best friend for Office365 development. In the latest version of Windows 10 you can easily make a virtual desktop by adding the “Show Task View button” from the context menu when right clicking on the windows task bar.

Clicking on the Task icon brings up the option to create a new virtual desktop and also a view of some of things you have worked on recently.

Opening a new virtual desktop everything is blank and you can open Chrome and go to your dev chrome profile happily.

Switching between desktops

You can go through the process of Task View and clicking on the desktop you want

OR

You can use CTRL-WINDOWSKEY-Left/Right to navigate back and forth between the desktops. They don’t cycle but if you only have two then Left or Right isn’t that hard 🙂

Clicking a link in outlook

If I am working in desktop 2 (O365Dev) and I go back to Desktop 1(primary O365), clicking a link in the primary O365 Outlook opens the link in the primary desktop chrome profile. Always.

YAY 🙂

Mentally this also helps me keep my Director day job (primary O365) and dev environment (xomino365) separate and makes life easier.

It’s not for everyone but really helps me 🙂

Extra Bonus shortcut

I discovered by accident (as you do) that you can create a new Virtual desktop using the CTRL key and a three-finger down swipe on the laptop.

 

 

Office Add-Ins: Working with Tables in Word. Part 4: Getting a table in a Content Control

In this article we will see how to use a ContentControl to quickly and accurately access a table in a Word document.

Introduction

In previous articles we have seen how to get a Table using a search or cycling through allTables in the document. While these are two perfectly valid methods they come with some potential issues and considerations for architecting the Word document itself. In this article we will see how to control access to the right table at the right time without the concerns or issues from the previous article.

Content Controls

Rich Text Content controls are the only content controls supported in Office.js (as of version 1.3). The documentation for the Content control API documentation shows us that we can get a content control via a “tag” which is assigned to the Content Control in Developer Mode within the word document.

Create a Content Control on your word document and give it a Tag (Birds in this case)

In normal mode we can then insert a table

Using the following code we can access the content control, get the first (only) table inside there and manipulate it by adding a new row.

async function runContent() {
    await Word.run(async (context) => {

        // Create a proxy object for the content controls collection that contains a specific tag.
        var contentBirds = context.document.contentControls.getByTag('Birds');
        // Queue a command to load the tag property for all of content controls. 
        context.load(contentBirds, 'tag');
        await context.sync()

        // Queue a commmand to load the results.
        const tableCollection = contentBirds.items[0].tables;
        context.load(tableCollection);
        await context.sync()
        var theTable = tableCollection.items[0];
        context.load(theTable, '');
        await context.sync();
        let numRows = theTable.rowCount.toString()
        theTable.addRows("End", 1, [[numRows, "Phoenix"]])
        
    });
}

The inserted row can be seen, and in a similar manner to the previous article we can log the amount of time taken to execute the function. In this case it is slightly slower (100ms) than searching (80ms) (there is more context loading) but it is consistent and does not come with any of the disadvantages of having to search for a specific term in a table.

Note

The obvious downside to this method is if a user of the word document takes the table out of the content control (either on purpose or by mistake). Checks should be put int he code to determine that if the table cannot be found then call the elgant error handling.

Conclusion

This is the most reliable manner for accessing a table quickly and accurately within a Word document, but does come with a small amount of additional overhead and the extra construct of having to have a Content Control within the Word document.

Office Add-Ins: Working with Tables in Word. Part 3: Two methods for getting existing tables

In this article I will demonstrate a method for getting to a Table using the prescribed methods in the API context.body.

Background

In previous articles we jhave seen how to create a table from scratch using the API or using OOXML. In this article we will look at how to reference an existing table and get a handle on it. We are going to look at two methods, one direct and one indirect, both have advantages and disadvantages.

Getting a table via the API directly

Within the the API model you can access all tables through the context.document.body.tables

The Methods (at leave in v1.3) are rather limiting and you cannot get a Table directly by name or id.

        const tableCollection = context.document.body.tables;

and from there you can reference each table individually through the index.

            theTable = tableCollection.items[i]

What this does not however facilitate is getting the table you want, directly. Let’s say I want to get the Insects table from the image below – how do I get that?

Well if you KNOW it is the nth table in the document then you are fine – but the chances are you don’t or at best can’t be sure.

Testing each table

What you can do is cycle through all the tables in the collection and test the first cell. I have specifically created these tables in such a manner that the first cell in the table is testable. Cycling through all the tables allows me to do a simple test of the first cell and if it is Insects then I know I am in the right table.

In this example we get all tables and then once we have the Insects table I insert a row:

async function runAllTables() {
    await Word.run(async (context) => {

        const tableCollection = context.document.body.tables;
        // Queue a commmand to load the results.
        context.load(tableCollection);
        await context.sync()
        //cycle through the tbale collection and test the first cell of each table looking for insects
        for (var i = 0; i < tableCollection.items.length; i++) {
            var theTable = null;
            theTable = tableCollection.items[i];
            var cell1 = theTable.values[0][0];
            if (cell1 == "Insects") {
                //once found, load the table in memory and add a row
                context.load(theTable, '');
                await context.sync();
                let numRows = theTable.rowCount.toString()
                theTable.addRows("End", 1, [[numRows, "Lightning Bug"]])
            }
        }
    });
}

As the number of tables in the document increase this gets slower and slower (understandably). There is also a limitation on the fact that you might not be able to identify the Table with a value in the first cell as easily (depends on requirements). As you can see from this example in the console.log I added the length of time to complete the addRow and it is 77ms on three tables. If I copy and past the first two tables and make a lot more of them you can see the speed gets slower (124ms) which might not seem like a lot, but in a large document with lots of large tables it can become significant to the end user.

Searching for a word in the document, and then getting the table parent

If you are able to identify a string in your table, you can search for that string and then get the parentTable. That method for finding your table is much more efficient and faster than getting all tables in a collection as per the previous method.

In this example we search for Insects, get the parentTable and then simply insert a row with a new value

async function runSearch() {
    await Word.run(async (context) => {
        const body = context.document.body 
        const insectRangeCollection = body.search("Insects");
        // Queue a commmand to load the results.
        context.load(insectRangeCollection);
        await context.sync()
        //get the parent table from the search result range
        const table1 = insectRangeCollection.getFirst().parentTable
        context.load(table1, '');
        await context.sync()
        let numRows2 = table1.rowCount.toString()
        table1.addRows("End", 1, [[numRows2, "Butterfly"]])
    });
}

As with the previous example – if I copy and paste the first two tables and make a lot more of them, you will see that this search and add row process remains approx the same speed as before.

 

Conclusion

While neither of these methods are ideal, if you know what is possible before you start to create your solution you can work in your options. Not having an obvious getTableById method is somewhat limiting.

NW Chicago JavaScript Meetup: Overview of E2E Testing with Cypress – June 21

On June 21st PSCGroup will be hosting the NorthWest Chicago JavaScript Meetup in our offices from 6-8:30pm

We are very happy to announce a second speaker – Steve Schwarz !

In addition to the Firebase presentation this should make for a really interesting event 🙂

For more information check out the Meetup site

https://www.meetup.com/Northwest-Chicago-JavaScript/events/250983909/

Office Add-Ins: Working with Tables in Word. Part 2: Creation from OOXML

In this long overdue article I will discuss how to create a custom table, get the OOXML from it, clean it and then be able to insert the table anywhere into a Word document.

Background

In the previous article we looked at how to create a table from  scratch using range.insert table which is nice but limiting in that the formatting of the created table leaves a lot to be desired. It would be much easier to create the table we want first, get the OOXML and then be able to re-insert it pre-formmated so to speak.

Getting the OOXML of a table

One of the examples posted in the Add-in API documention uses the range.getOOXML to show how to extract the OOXML from a highlighted range in a word document. Using the Add-in Script Lab we can easily simulate this in a word document. I took the basic API call example and inserted the code from the API documentation.

 

  1. I created a custom table with hashed borders (formatting) and highlighted it
  2. Click the run code button to execute the sample code
  3. The OOXML was generated in the console below

Inserting OOXML

Using this process in reverse you can then copy the OOXML and using the range.insertOOXML method you can click anywhere in a word document and click a button to insert the preformatted table.

 

Conclusion

While we can format tables manually with code – as we get more complicated with out tables this may not be an option. Inserting as OOXML will guarantee the formatting we want and then allow us to manipulate as a table as we will see next