The Power Of A Great User Story

For anyone that personally knows me, they will know that I am absolutely obsessed with getting User Stories right!

On the face of it, it may seem impossible to deliver part of a business process from one single sentence, but user stories are one of the best tools you can use, right from your initial engagement through to post go-live support as long as each part adds value.

What is a User Story?

User stories can help us to define a requirement for a business user or process that needs to be included within a project or product to ensure success. Generally speaking, user stories follow the following format:

As a [persona], I want to [achieve], so that I can [action].

That is all, one seemingly simple statement. Some may feel that writing user stories are a waste of time in an agile project, particularly as an agile project is supposed to deliver technical outputs quickly, however, user stories can actually speed up the turnaround time of the solution, providing that we pay particular and collaborative attention to it’s construction.

The Construction

Let’s take a look at what we want to achieve from each part of the User Story and how we can add value. As I am a Power Platform and Dynamics 365 Customer Engagement consulting manager, I’ll be using an example from Dynamics 365 Customer Service.

As a [persona],…

It would be easy to write “As a user…” here and be done, but this doesn’t tell us anything except that this isn’t an automated process.

Particularly in the Power Platform and Dynamics 365 space, the functionality and security model can span multiple applications, so perhaps we can describe the user and the way that they’re accessing the product or feature.

As a Customer Service Representative accessing the standard Customer Service Hub application,

From the above, we can understand that:

  • The user definitely needs a Dynamics 365 Customer Service license if existing licenses do not allow access.
  • The user is likely to use the standard Security Role provided due to the persona’s role.
  • The user is not expecting a tailored sitemap experience, as they will access the application through existing means.
  • The experience is triggered by end user behaviour rather than automated processes, until we discover more about the rest of the story.

I want to [achieve],…

We now want to ensure that we describe the Customer Service Representative’s objective in this part of the user story, so that we can start to understand our scope and design our solution.

As a Customer Service Representative accessing the standard Customer Service Hub application, I want to see all of my priority ‘1 – Blocker’ Cases in a separate list sorted by oldest to newest creation date,…

To add to our previous understanding, we now know:

  • The user has a focus on Cases that need the highest amount of attention, and these should be categorised by priority. Right now we don’t know the full list of priorities, but we can add that as a known unknown in our design.
  • The user needs a new view for just the Cases categorised by this priority, and the out-of-the-box priorities are High, Medium, Low. It seems like we need to carry out Column and List configuration in Dataverse here.
  • The List that we configure needs to include the Created On date, and needs a sorting on this Column too.

So that I can [action].

The primary purpose of this part of the user story is to justify the action through behaviour. Some consider this part of the user story optional, however I like to ensure it’s included in every user story as it can significantly change the estimate required to deliver.

This part of the user story doesn’t just have design benefits, but it can also help us prioritise the user story against other user stories in the backlog when we are working in iterations or sprints.

As a Customer Service Representative accessing the standard Customer Service Hub application, I want to see all of my priority ‘1 – Blocker’ Cases in a separate list sorted by oldest to newest creation date, so that I can ensure that we do our best to meet our 1 day ‘solution or workaround’ Service Level Agreement (SLA) for blocked customers.

We now know why this design is so important, and we can deduce the following:

  • The organisation makes promises within their agreements with customers to ensure that business processes aren’t blocked for more than one day, and this needs to be a core emphasise within the design.
  • We can ask if we can further improve the design by introducing system triggered Service Level Agreement functionality.
  • Most importantly, another business initialism has been cleared up, by clarifying why the customer keeps writing SLA all over their documents!

Isn’t This Too Much Detail?

Not at all. It’s unlikely that we will every get to this level of detail within one round of workshops, however, through refinement during iterations or sprints, this can tell us almost exactly how we need to build a feature. It will also help us more accurately estimate our delivery and provide a higher chance of passing tests after deployment.

One phrase I frequently hear is ‘we don’t need to worry, it’s just out of the box functionality’, but from one sentence regarding standard functionality, we have been able to arrive at 10 conclusions with definitive design that definitely carry an associated effort.

I am sure others reading this will find additional conclusions too, and this is the great thing about user stories – multiple perspectives can help to narrow down exactly what the client is asking for, and ultimately lead to a higher quality delivery.

How To Enable ModelDrivenFormIntegration for Existing Canvas Apps

Earlier this week I found myself trying to embed an existing Canvas app into a Model-Driven app to better present information relating to the record using the flexible UI controls, but as an infrequent user of such a feature, I struggled to understand how I could reference the current Model-Driven app record’s data within the Canvas app!

All over the web I could find resources pointing towards a special type of control called ModelDrivenFormIntegration and how it works, but I simply couldn’t see it within my solution. This is where it should be:

A screenshot of a Canvas app, highlighting the ModelDrivenFormIntegration control that appears after embedding within a Model-Driven app.

The new Power Platform interface has improved so many of the existing controls and added fantastic new features, but unfortunately at the time of writing, embedding a Canvas app via the new user interface needs a little more work, and it doesn’t quite complete the job in all circumstances. There are two reasons for this:

  1. You have to associate the control with a field on the Form, and when adding the Canvas app via the new User Interface, it doesn’t configure the field control automatically leading to errors when loading.
  2. The functionality available via the ‘Customize’ button is not available in the new User Interface, which is partly the reason for this blog post!

As some of you will be aware, sometimes it’s just better to head over to the classic user interface to complete your configuration, and although I’m finding myself using this user interface less these days. In this post I attempt to bridge the gap and I’ll explain how to get things working.

What is ModelDrivenFormIntegration?

As Microsoft have explained in detail here, this control allows us to bring contextual data from the Model-Driven app that the Canvas app is utilised in.

There are a significant number of benefits to doing this, primarily because it provides you with the ability to dynamically change your Canvas app content based upon the record you’re currently viewing in the Model-Driven app.

Enable ModelDrivenFormIntegration

Step 1: From https://make.powerapps.com, navigate to the correct environment and choose the relevant Table’s Form within your solution file. Use the ‘Switch to Classic‘ button from the navigation bar straight away.

A screenshot of a Dataverse Table's Form, highlighting the 'Switch To Classic' button.

Step 2: Navigate to the required field you’ve configured for your Canvas app control and double click. You’ll notice a pop up window which provides the ability to navigate to the Canvas app control configuration. Click on ‘Controls‘ and press the ‘Customize‘ button.

A screenshot of the classic user interface that was inherited from Dynamics CRM, showing the Properties of a Mandatory field on the Controls tab, highlighting the 'Customize' button.

Step 3: Your Canvas app will now open, and you’ll notice that ModelDrivenFormIntegration is now available as the first control on the list for the first time! We’re not done yet though, we need to tell the control which Table we are using within the Model-Driven app by editing the ‘DataSource‘ Property.

A screenshot of a Canvas app, highlighting the ModelDrivenFormIntegration control's Property called 'DataSource'.

And finally the ‘OnDataRefresh‘ Property.

A screenshot of a Canvas app, highlighting the ModelDrivenFormIntegration control's Property called 'OnDataRefresh'.

We can use the plural label/friendly name of the Table here, instead of having to look up the logical name, which is a great touch in a lot of Power FX’s abilities.

Conclusion

And we’re done!

The configuration for this isn’t difficult, but finding out why the issue exists can often be challenging, especially if you’re an infrequent user of this functionality.

Remember to ‘Save‘ and ‘Publish‘ your Canvas app changes when you’re ready, but you don’t need to publish your Model-Driven app as this was simply a route into enabling the functionality with no configuration changes.

There are a few pointers to be aware of when generally configuring embedding Canvas Apps:

  1. Microsoft advise that associating your embedded Canvas app control is tied to a mandatory field, so that you can guarantee the operation of the Canvas app.
  2. Remember to share your Canvas app or make other users Co-Owners as appropriate before releasing the functionality to end users.
  3. The classic user interface is due to be deprecated in an upcoming release nearer the end of the year. I suspect this feature will still work for a short period of time, but we will have to watch and wait until such a time, and I’ll update this post if/when this happens.

Power Apps ModelDrivenFormIntegration Control

Embedded Canvas App Guidelines & Troubleshooting