<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SharePoint on LinkeD365 Blog</title><link>https://linked365.blog/tags/sharepoint/</link><description>Recent content in SharePoint on LinkeD365 Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 07 Jun 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://linked365.blog/tags/sharepoint/index.xml" rel="self" type="application/rss+xml"/><item><title>Approvals - Showing History in SharePoint</title><link>https://linked365.blog/2020/06/07/approvals-showing-history-in-sharepoint/</link><pubDate>Sun, 07 Jun 2020 00:00:00 +0000</pubDate><guid>https://linked365.blog/2020/06/07/approvals-showing-history-in-sharepoint/</guid><description>&lt;img src="https://linked365.blog/images/2020/06-Annotation-2020-06-04-091056.png" alt="Featured image of post Approvals - Showing History in SharePoint" />&lt;p>Last week, I took part in the Microsoft 365 Virtual Marathon. This was a branch out for me, as it wasn&amp;rsquo;t specifically Dynamics 365 or Power Platform related, though everything is one now right?&lt;/p>
&lt;p>My talk was around Approvals, displaying 3 types of approvals, from a Send with Options to Adaptive cards, topics I have covered in my &lt;a class="link" href="https://linked365.blog/2020/04/02/quick-approvals-send-with-options/" target="_blank" rel="noopener"
>blog&lt;/a> &lt;a class="link" href="https://linked365.blog/2019/07/04/adaptive-cards-improved-approvals-part-1/" target="_blank" rel="noopener"
>before&lt;/a>.&lt;/p>
&lt;p>During the sessions, one of the questions was around tracking approvals. Even in the Approvals app, it is very difficult to track who has approved and when including the comments. If you want to see this in combination to the thing you were approving, it means swapping between apps and ensuring you know what record you are looking at.&lt;/p>
&lt;p>I took this as a challenge, and decided to use the Power Apps in SharePoint form to display Approvals.&lt;/p>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Display of Approvals in SharePoint or and Power Platform application is not intuitive. I use a Power App to display approvals against items on a SharePoint document library.&lt;/p>
&lt;h2 id="form-in-action">Form in Action&lt;/h2>
&lt;p>Before I run through the detail, check out the form in action below. As you show more details and display the associated Power Apps form, a list of the approvals is shown. If you drill into the approvals, more details about who it was sent to and how they responded are available.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-approvals1.gif"
loading="lazy"
alt="GIF showing Approvals in SharePoint"
>&lt;/p>
&lt;h2 id="simple-approval">Simple Approval&lt;/h2>
&lt;p>To get some approvals, I created a flow which is triggered when a file is added to the SharePoint folder. Obviously, this could be a lot more complex than this, but this simple one is to get some data in my approvals to show in SharePoint.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-50.png"
loading="lazy"
>&lt;/p>
&lt;p>The critical part of this is the item link. You need a method of linking your approvals with the item it corresponds to, and MS does not provide you with a key field. You could create an approval, update a bespoke field on the document meta with the approval id, but I did not want to create unnecessary fields. I ensure that the item link will take me to the document in SharePoint.&lt;/p>
&lt;h2 id="sharepoint-form">SharePoint form&lt;/h2>
&lt;p>First of all, using Power Apps in SharePoint is not the same as a standard Power App. It frightened me when you start the Power App that it dumps you into the Default Instance. Also, these applications are not solution aware. I don&amp;rsquo;t think you can share the forms either. It is certainly not what I am used to. Not sure why this is the case. Let me know if you know any different.&lt;/p>
&lt;p>In the document library, select Power Apps, customise forms.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-48.png"
loading="lazy"
>&lt;/p>
&lt;p>The form I created has a SharePointIntegration property in it, which is the context that is passed in. The form is linked to that record, in my case a document.&lt;/p>
&lt;p>There are a couple of triggers on the integration which are used to force the display of the first screen when this is triggered. If you don&amp;rsquo;t apply this logic, the screen that was displayed last will return to the user, meaning the user tends to be left in the second, approval details screen.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-63.png"
loading="lazy"
>&lt;/p>
&lt;p>I have added a couple of fields to the top half of the form, which represents some of the core fields you need. Below that, I have added a gallery.&lt;/p>
&lt;p>Also, to use later, onvisible takes the document that is passed in or the first in the list and sticks it in a local variable&lt;/p>
&lt;p>&lt;img src="https://i2.wp.com/linked365.blog/wp-content/uploads/2020/06/image-51.png?fit=1024%2C174&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>The Gallery Items is a filtered list of the Approvals entity within your CDS environment.&lt;/p>
&lt;p>Here, you can see that I am filtering the Approvals entity by the item link, using the base SharePoint URL and the full path to the file. This isn&amp;rsquo;t the full path, just the bit after your site collection.&lt;/p>
&lt;p>&lt;img src="https://i2.wp.com/linked365.blog/wp-content/uploads/2020/06/image-52.png?fit=1024%2C575&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>In the gallery Item are 3 fields. The first field is a visual indicator of the current status of approval. It is a combination of the Status reason as well as the result.&lt;/p>
&lt;p>&lt;img src="https://i0.wp.com/linked365.blog/wp-content/uploads/2020/06/image-53.png?fit=1024%2C425&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>This label is also coloured to show Approved as green, Pending as black &amp;amp; Rejected as Red.&lt;/p>
&lt;p>&lt;img src="https://i1.wp.com/linked365.blog/wp-content/uploads/2020/06/image-54.png?fit=1024%2C90&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>The next fields is just a display of who created the approval and when.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-55.png"
loading="lazy"
>&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-56.png"
loading="lazy"
>&lt;/p>
&lt;p>I added a second screen to my app, so you can see the detail of the approval, navigated to by selection of the approval.&lt;/p>
&lt;h3 id="approval-detail">Approval Detail&lt;/h3>
&lt;p>This form is pretty simple looking, with just a gallery. On visible of the form, two collections are populated, which are filtered lists of Approval Requests and Approval Responses. Working with local collections is a lot easier, particularly if you need to reference them multiple times.&lt;/p>
&lt;p>&lt;img src="https://i0.wp.com/linked365.blog/wp-content/uploads/2020/06/image-59.png?fit=1024%2C84&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>The gallery is connected to the requestList, filtered by the previous step.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-60.png"
loading="lazy"
>&lt;/p>
&lt;p>The name of the approver is taken from the owner of the request. I added a timestamp as well.&lt;/p>
&lt;p>&lt;img src="https://i1.wp.com/linked365.blog/wp-content/uploads/2020/06/image-58.png?fit=1024%2C188&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>The third field combines several, depending on whether there are any responses to the particular request by the user. Also, the status, even for those that have been classified as rejected, is Active. There does not seem to be any direct link between the request and its response. I am assuming that each request can only have 1 response by 1 person, so filter the already filtered responses by the user who is the approver. Colour coding on the value again gives a more visual representation.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">If&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">IsEmpty&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Filter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">responsesList&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Owning&lt;/span> &lt;span class="n">User&lt;/span>&lt;span class="sc">&amp;#39;.&amp;#39;&lt;/span>&lt;span class="n">Full&lt;/span> &lt;span class="n">Name&lt;/span>&lt;span class="err">&amp;#39;&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">ThisItem&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Owning&lt;/span> &lt;span class="n">User&lt;/span>&lt;span class="sc">&amp;#39;.&amp;#39;&lt;/span>&lt;span class="n">Full&lt;/span> &lt;span class="n">Name&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">If&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Status&lt;/span> &lt;span class="n">Reason&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">&amp;#34;Active&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;Pending&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Status&lt;/span> &lt;span class="n">Reason&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Text&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">First&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Filter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">responsesList&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Owning&lt;/span> &lt;span class="n">User&lt;/span>&lt;span class="sc">&amp;#39;.&amp;#39;&lt;/span>&lt;span class="n">Full&lt;/span> &lt;span class="n">Name&lt;/span>&lt;span class="err">&amp;#39;&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">ThisItem&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Owning&lt;/span> &lt;span class="n">User&lt;/span>&lt;span class="sc">&amp;#39;.&amp;#39;&lt;/span>&lt;span class="n">Full&lt;/span> &lt;span class="n">Name&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">).&lt;/span>&lt;span class="n">Response&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>There are a couple of other fields on the grid, firstly the Comments entered if there are any. This comes from the response. I trigger the visibility of this field depending on whether it has a value.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-61.png"
loading="lazy"
>&lt;/p>
&lt;p>Finally, who re-assigned the request. Here I use a lookup, which allows a traversal to the the users name.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/06-image-62.png"
loading="lazy"
>&lt;/p></description></item><item><title>Quick Approvals - Send with Options</title><link>https://linked365.blog/2020/04/02/quick-approvals-send-with-options/</link><pubDate>Thu, 02 Apr 2020 00:00:00 +0000</pubDate><guid>https://linked365.blog/2020/04/02/quick-approvals-send-with-options/</guid><description>&lt;img src="https://linked365.blog/images/2020/04-04-image-38.png" alt="Featured image of post Quick Approvals - Send with Options" />&lt;p>As I digitally transform the club I am involved with, &lt;a class="link" href="http://stardiving.org" target="_blank" rel="noopener"
>stardiving.org&lt;/a> I come across ways in Power Automate that are pretty useful. I have previously talked about &lt;a class="link" href="https://linked365.blog/adaptive-cards-improved-approvals-part-1/" target="_blank" rel="noopener"
>Adaptive Cards&lt;/a> for approvals and this works great, but only for internal use. Same with Approvals, they are perfect for what I wanted to achieve, but limited to internal users.&lt;/p>
&lt;p>Send Email with options is a great way of getting approval or an answer to a specific question for any user, external or internal. I use this action, along with a Form &amp;amp; some parallel branching to move our little club another step towards total digitisation&lt;/p>
&lt;h2 id="the-scenario">The Scenario&lt;/h2>
&lt;p>My club, for a new member, requires entry of their personal details, medical information and contact details, and the way we store this and allow for access necessitates that we use online, secure storage. With my background, it is clear we should use SharePoint lists to store this data (yes, I know SharePoint is not a data repository, but it works great when you do not have a lot of data and limited monetary resources).&lt;/p>
&lt;p>Forms is also a great tool to publish these questions out to our members or their parent or guardian. It gives a great look and feel, is pretty easy to set up and, again, is free in the licensing Microsoft generously gives the club due to its charitable status. The problem with Forms is that you can not collate signatures. You can&amp;rsquo;t do this via Forms Pro either, there are several really good business reasons for this, especially as Adobe or Docusign make a whole business out of this.&lt;/p>
&lt;p>For my scenario, we had to get agreement to various parts of the entry, particularly around the consent to store their data and use it run the club. This would be easy in a paper form, just ask for a signature, but to bring this electronically, I needed to create a way of ensuring that they have agreed and capture that agreement.&lt;/p>
&lt;p>Power Automate has a great approvals engine, but you can not send an approval outside of your organisation (you can if the user is a guest, but I don&amp;rsquo;t want to add all our parents as guests). So this is out.&lt;/p>
&lt;p>&lt;a class="link" href="https://linked365.blog/adaptive-cards-improved-approvals-part-1/" target="_blank" rel="noopener"
>Adaptive Cards&lt;/a> are also great, but this is restricted to internal users as well, and you are reliant on the receiver of the card having the appropriately supported viewer, which is only Microsoft applications currently.&lt;/p>
&lt;p>Power Automate also has a &amp;ldquo;Send email with Options&amp;rdquo; which allows a much simpler approval process, but you can send it to anyone. Perfect for my scenario, free and any email address!&lt;/p>
&lt;h2 id="the-solution">The solution&lt;/h2>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-38.png"
loading="lazy"
>&lt;/p>
&lt;ul>
&lt;li>Forms data entry&lt;/li>
&lt;li>Copy information to SharePoint list&lt;/li>
&lt;li>Ask for approval via email
&lt;ul>
&lt;li>Approve email given&lt;/li>
&lt;li>Have a record that they acknowledged.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>If approval is not given, notify an administrator&lt;/li>
&lt;/ul>
&lt;h2 id="form">Form&lt;/h2>
&lt;p>&lt;a class="link" href="https://meganvwalker.com/" target="_blank" rel="noopener"
>Megan Walker&lt;/a> is the Forms queen, not going to try and compete with the knowledge she has imparted since Forms came out.&lt;/p>
&lt;p>My form is pretty simple, asks a host of questions on behalf of the diver and the parent. There are a couple of sections, branched depending on whether the user is entering this form as a member or their parent/guardian.&lt;/p>
&lt;p>I ask in the form for them to confirm a couple of key points, by asking for the name of the diver to confirm their agreement. This is obviously not foolproof, but gives enough confirmation, backed up with the email approval that comes as part of the Flow.&lt;/p>
&lt;h2 id="create-sharepoint-item">Create SharePoint Item&lt;/h2>
&lt;p>My trigger is &amp;ldquo;When a New response is submitted&amp;rdquo;. As I have no CDS, this is the only one available to me. I then get the response details, which helps later when you want to copy the details across to SharePoint list.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-29.png"
loading="lazy"
>&lt;/p>
&lt;p>Next step is to create the SharePoint list&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-30.png"
loading="lazy"
>&lt;/p>
&lt;p>Because we will have different user groups, there are separate questions in the survey which populate the same data fields in the list. This is done with a simple if ( equals (field,&amp;rsquo;&amp;rsquo;), value1, value2) function. The random field names are those linking to the questions, which look prettier when you insert them.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">equals&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">body&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Get_response_details&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">)?[&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">r11eaea5575824aa8b515f76fd43d1332&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>&lt;span class="err">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="n">body&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Get_response_details&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">)?[&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">r6d52d6567ea1425aaf91c6d678c125e8&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>&lt;span class="n">body&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">Get_response_details&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">)?[&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="n">r11eaea5575824aa8b515f76fd43d1332&lt;/span>&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="emailing-for-approval">Emailing for approval&lt;/h2>
&lt;p>After the list item is created, I put in a parallel branch. The left branch sends out the email for approval, the right branch waits for a week. If the week is reached, send an email to our administrator to chase the person, as the user who entered the information has not done the confirmation.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-31.png"
loading="lazy"
>&lt;/p>
&lt;p>On the left parallel branch, I create the email with options&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-32.png"
loading="lazy"
>&lt;/p>
&lt;p>This formatted email converts into the email below, shown in GMail. You can see the formatting that was applied, and the 2 buttons I defined in the action.&lt;/p>
&lt;p>&lt;img src="https://i1.wp.com/linked365.blog/wp-content/uploads/2020/03/image-33.png?fit=1024%2C424&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>Clicking on the Approve or Deny button shows the user this screen, thanking them for their response&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-34.png"
loading="lazy"
>&lt;/p>
&lt;h2 id="waiting-for-approval">Waiting for Approval&lt;/h2>
&lt;p>Back in the Flow, we wait for a response.&lt;/p>
&lt;p>&lt;img src="https://i1.wp.com/linked365.blog/wp-content/uploads/2020/03/image-35.png?fit=1024%2C267&amp;amp;ssl=1"
loading="lazy"
>&lt;/p>
&lt;p>If it is not Approve, then send an email to our administrator, to check what part they don&amp;rsquo;t agree with.&lt;/p>
&lt;p>If it is Approve, update the item to confirm that the member is registered successfully&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-36.png"
loading="lazy"
>&lt;/p>
&lt;p>Either way, cancel the flow. As the other parallel branch is waiting for a week and then responding to our administrator, cut this short by cancelling the flow.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/04-04-image-37.png"
loading="lazy"
>&lt;/p></description></item><item><title>Incident App (Part 2)</title><link>https://linked365.blog/2020/03/18/incident-app-part-2/</link><pubDate>Wed, 18 Mar 2020 00:00:00 +0000</pubDate><guid>https://linked365.blog/2020/03/18/incident-app-part-2/</guid><description>&lt;img src="https://linked365.blog/images/2020/02-image-15.png" alt="Featured image of post Incident App (Part 2)" />&lt;p>In the first part of this series, &lt;a class="link" href="https://linked365.blog/2020/02/23/incident-app-part-1/" target="_blank" rel="noopener"
>here&lt;/a> I established an application I wrote to improve incident management at the club I am proud to chair.&lt;/p>
&lt;h2 id="requirements">Requirements&lt;/h2>
&lt;ul>
&lt;li>Centralised, secure list of incidents - (&lt;a class="link" href="https://linked365.blog/2020/02/23/incident-app-part-1/" target="_blank" rel="noopener"
>Part 1&lt;/a>)&lt;/li>
&lt;li>Ability to add divers to list for trials or competitions (&lt;a class="link" href="https://linked365.blog/2020/02/23/incident-app-part-1/" target="_blank" rel="noopener"
>Part 1&lt;/a>)&lt;/li>
&lt;li>Data entry must be easy and not time-consuming (&lt;a class="link" href="https://linked365.blog/2020/02/23/incident-app-part-1/" target="_blank" rel="noopener"
>Part 1&lt;/a>)&lt;/li>
&lt;li>Weekly notification of all incidents to the welfare officer&lt;/li>
&lt;li>Email to parent or guardian of the diver when an incident is raised&lt;/li>
&lt;li>Escalation to welfare officer and others in the organisation for serious incidents&lt;/li>
&lt;li>Not cost anything&lt;/li>
&lt;/ul>
&lt;p>In this part I will walk you through the flows I used to notify parents and the welfare officer. There is also a requirement to escalate, notify immediately for serious incidents.&lt;/p>
&lt;h2 id="weekly-notification">Weekly Notification&lt;/h2>
&lt;p>To allow our welfare officer to monitor all incidents and any patterns, it was requested that they receive a weekly overview of all incidents raised that week.&lt;/p>
&lt;p>To do this, I created a flow using the recurrence trigger.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-10.png?w=619"
loading="lazy"
>&lt;/p>
&lt;p>Using these options, the flow will trigger at 3 am every Sunday morning.&lt;/p>
&lt;p>I then establish a variable for the email body and go off and retrieve all the items that have been created since last week. The filter query is used here to filter on all incidents that were created after 7 days ago, a simple addDays function used to get to the date 7 days ago&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-12.png?w=553"
loading="lazy"
>&lt;/p>
&lt;p>Next, just check to see if there are any incidents this week by checking the length of the returned list.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-13.png?w=552"
loading="lazy"
>&lt;/p>
&lt;p>If this is greater than 0, then incidents have been created, go on to create an email, if not, just do nothing.&lt;/p>
&lt;p>The next part is where I had to be a little bit clever, as the standard thing you would do did not give me enough flexibility. You could pass this list into a Create HTML function, but this put the data in a column format, where I wanted to display as a list going down the page, more of a normal email format.&lt;/p>
&lt;p>Instead, I built up an email, formatting the content as I went. Starting with an apply to each, taking the Get Items from SharePoint command. The first action I used repeatedly in the creation of the email, which is stripping the html content from html aware fields in the columns of the SharePoint. Leaving these in resulted in a lot of mangled emails.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-14.png?w=576"
loading="lazy"
>&lt;/p>
&lt;p>I then append to the Email Body string I created earlier a formatted HTML content.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-15.png?w=545"
loading="lazy"
>&lt;/p>
&lt;p>The incident date is a simple formatDateTime function useage&lt;/p>
&lt;p>formatDateTime(items(&amp;lsquo;Apply_to_each&amp;rsquo;)?[&amp;lsquo;IncidentDate&amp;rsquo;],&amp;lsquo;dd/MM/yyyy&amp;rsquo;)&lt;/p>
&lt;p>The next step is because Contacted field is a multi-choice option set. Again, I loop through the contents of the Contacted? field and append to the email body variable.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-16.png?w=571"
loading="lazy"
>&lt;/p>
&lt;p>The final parts of the loop finish of the content for each incident&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-17.png?w=554"
loading="lazy"
>&lt;/p>
&lt;p>Finally, send out the email. Subject details how many incidents in the week with a count from the SharePoint items returned.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-18.png?w=566"
loading="lazy"
>&lt;/p>
&lt;h2 id="email-the-parent--guardian">Email the Parent / Guardian&lt;/h2>
&lt;p>The next requirement was to notify the diver&amp;rsquo;s parent or guardian. For years, we had relied on slips of paper, which again is a GPDR nightmare. Using email was a sure fire way to ensure we have done our duty. This only applied for minor incidents, parents will certainly be involved a lot quicker for anything serious.&lt;/p>
&lt;p>Firstly, trigger when a new item is created in the SharePoint list&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-19.png?w=549"
loading="lazy"
>&lt;/p>
&lt;p>Next, get the diver that is indicated in the list, diver id being the linking record between the incident list &amp;amp; members&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-20.png?w=559"
loading="lazy"
>&lt;/p>
&lt;p>As this SharePoint get items call may return more than one item, we have to place in a Apply to Each&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-21.png?w=317"
loading="lazy"
>&lt;/p>
&lt;p>Check to see if the diver has an email address (if new divers come on board, this might not be the case until we have their full details).&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-22.png?w=768"
loading="lazy"
>&lt;/p>
&lt;p>If no email, stop the action, otherwise send an email to the email to notify the parent.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-23.png?w=547"
loading="lazy"
>&lt;/p>
&lt;h2 id="escalate-an-incident">Escalate an Incident&lt;/h2>
&lt;p>Most incidents, thankfully, require little follow up or after care. But, there are occasions that require our parent association to be notified along with insurance companies. We also have an internal follow up process for such incidents by our welfare officer.&lt;/p>
&lt;p>Rather than create a new flow, after the flow above, I continue. Does the Contacted multiple select option set contain Ambulance or Police, both mean an immediate escalation. This is done by looping through the options selected and updating a variable if one of them matches either of the 2 conditions.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-26.png?w=778"
loading="lazy"
>&lt;/p>
&lt;p>Further, there is a severe boolean on the form, so if that is triggered, also update the variable to true.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-27.png?w=666"
loading="lazy"
>&lt;/p>
&lt;p>Finally, if Severe has been set, send an email&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/03-image-28.png?w=696"
loading="lazy"
>&lt;/p></description></item><item><title>Incident App (Part 1)</title><link>https://linked365.blog/2020/02/23/incident-app-part-1/</link><pubDate>Sun, 23 Feb 2020 00:00:00 +0000</pubDate><guid>https://linked365.blog/2020/02/23/incident-app-part-1/</guid><description>&lt;img src="https://linked365.blog/images/2020/02-image-15.png" alt="Featured image of post Incident App (Part 1)" />&lt;p>Most of you won&amp;rsquo;t know this, but to keep me busy (as if work, blogging, presenting &amp;amp; community isn&amp;rsquo;t enough) I am the chair of my local platform diving club, Star Diving. Give them a look at &lt;a class="link" href="http://stardiving.org/" target="_blank" rel="noopener"
>http://stardiving.org/&lt;/a> if you or your son or daughter want to learn a great sport that pushes you to control your body &amp;amp; keep fit.&lt;/p>
&lt;p>My youngest son is part of the Skills squad (very proud parent) and he loves it. To support him and mainly because I was the last to step back, I became the chair of the club last April.&lt;/p>
&lt;p>Star is a registered charity, whose purpose is to promote diving across Surrey and beyond and have 200 members or all ages. As a registered charity, Microsoft generously gives Star 25 licenses for using Office 365, we host our email and use teams and other things.&lt;/p>
&lt;h2 id="the-requirement">The requirement&lt;/h2>
&lt;p>Diving is a dangerous sport to the untrained and accidents happen. Logging accidents and informing parents, in this day and age of GPDR has become a concern. Gone are the days that we can keep an accident book at the pool side and have a chat with a parent. Our duty of care needs to ensure any incidents are logged centrally to ensure repeat incidents.&lt;/p>
&lt;p>On discussing with our coaches and welfare officer a list of requirements where created. Wasn&amp;rsquo;t a formal list, just from conversations etc, but like any good BA, I created a list&lt;/p>
&lt;ul>
&lt;li>Centralised, secure list of incidents&lt;/li>
&lt;li>Ability to add divers to list for trials or competitions&lt;/li>
&lt;li>Data entry must be easy and not time-consuming&lt;/li>
&lt;li>Weekly notification of all incidents to the welfare officer&lt;/li>
&lt;li>Email to parent or guardian of the diver when an incident is raised&lt;/li>
&lt;li>Escalation to welfare officer and others in the organisation for serious incidents&lt;/li>
&lt;li>Not cost anything&lt;/li>
&lt;/ul>
&lt;p>Of all these requirements, the last one drove me in a direction which is not my normal. I am so used to firing up a CDS environment, creating an entity structure and starting the process from data.&lt;/p>
&lt;p>I decided to delve into the unknown (I know the principles, like any Solution Architect, but doing is different) and create a SharePoint list or two to store the data and build a Power App on top to handle data entry. Power Automate will be used to link the app together and provide the notifications.&lt;/p>
&lt;h2 id="introducing-pike">Introducing Pike&lt;/h2>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-15.png?w=430"
loading="lazy"
>&lt;/p>
&lt;p>Pike&amp;rsquo;s front screen has a series of buttons that I will hopefully expand on as I add functionality. I have used the default black and yellow scheme, as Star&amp;rsquo;s colours are the same.&lt;/p>
&lt;h2 id="data-entry">Data Entry&lt;/h2>
&lt;p>If you click on Create New Incident, you are taken to the first data entry screen.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-16.png?w=432"
loading="lazy"
>&lt;/p>
&lt;p>This is my first learning point. I knew what the * next to the fields means, but my users didn&amp;rsquo;t. Don&amp;rsquo;t assume that just because you know how something works that others will.&lt;/p>
&lt;p>This is a simple form based on the SharePoint list. The fields are formatted for the screen, and I didn&amp;rsquo;t want a lot of scrolling, so split the data entry over 2 screens. The first screen uses a second list for all our divers and displays a drop-down of them.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-17.png?w=419"
loading="lazy"
>&lt;/p>
&lt;p>Further, if the diver is not on the list, for trials or competitions, you can add them using the + next to the diver&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-18.png?w=406"
loading="lazy"
>&lt;/p>
&lt;p>The Reporter field is a Person or Group field in SharePoint, which allows linking to a user on our environment. Location is a choice field, with diving specific terms.&lt;/p>
&lt;p>Once all the fields that require data are filled in, a big Next button appears at the bottom&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-19.png?w=426"
loading="lazy"
>&lt;/p>
&lt;p>This is done by a simple formula on the Visible property of the button, namely, only display if the form is valid&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-20.png?w=558"
loading="lazy"
>&lt;/p>
&lt;p>Selecting the button passed to a second New form, to finish entering the data.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-21.png?w=392"
loading="lazy"
>&lt;/p>
&lt;p>The Contacted? field is a multi-choice field and it kicks off a flow for serious incidents (if a hospital visit or ambulance is called, it is serious by default)&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-22.png?w=404"
loading="lazy"
>&lt;/p>
&lt;p>Again, the visibility of the submit button is controlled by the validity of the form.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-23.png?w=431"
loading="lazy"
>&lt;/p>
&lt;p>The submit form doesn&amp;rsquo;t conduct a straight submit but combines the data on the two forms. Additionally, notify the user if there is a positive or negative outcome to the submission&lt;/p>
&lt;p>Patch(
Incidents,
Defaults(Incidents),
&amp;lsquo;frmIncidentNew-First&amp;rsquo;.Updates,
&amp;lsquo;frmIncidentNew-Second&amp;rsquo;.Updates, {&amp;lsquo;Welfare History&amp;rsquo;: &amp;ldquo;Created by &amp;quot; &amp;amp; User().FullName}
);
If(
IsEmpty(Errors(Incidents)),
Notify(
&amp;ldquo;Your incident has been recorded&amp;rdquo;,
NotificationType.Success
);
Navigate(
Home,
ScreenTransition.CoverRight
),
Notify(
&amp;ldquo;There was a problem submitting your incident. Please contact &lt;a class="link" href="mailto:incidents@stardiving.org" >incidents@stardiving.org&lt;/a> manually&amp;rdquo;,
NotificationType.Error
)
)&lt;/p>
&lt;p>This returns the user to the home screen, where they can view incidents they logged by clicking My Logged Incidents.&lt;/p>
&lt;h2 id="viewing-incidents">Viewing Incidents&lt;/h2>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-25.png?w=437"
loading="lazy"
>&lt;/p>
&lt;p>As you can see, I got bored in testing &amp;amp; documented a lot of gruesome accidents, which thankfully doesn&amp;rsquo;t happen.&lt;/p>
&lt;p>Clicking on the arrow shows the detail.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-27.png?w=415"
loading="lazy"
>&lt;/p>
&lt;p>For a normal coach, a reporter, this is the end of the functionality. But for our welfare officer and administrator, there are a couple of additional features.&lt;/p>
&lt;h2 id="securing-special-features">Securing Special features&lt;/h2>
&lt;p>On startup of the application, I run a Flow.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-28.png?w=918"
loading="lazy"
>&lt;/p>
&lt;p>This flow is checking to see if the logged in user is the owner of the team that owns the Incidents list.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-29.png?w=638"
loading="lazy"
>&lt;/p>
&lt;p>Firstly, initialise some variables, then call the SharePoint API to check the current users rights in the given SharePoint site.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-30.png?w=631"
loading="lazy"
>&lt;/p>
&lt;p>The variable in the Uri is passed in from the Power App, which is the users email address.&lt;/p>
&lt;p>If this call returns a value, it means that the user is in the owner team, and this result is passed back to the Power App.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-31.png?w=573"
loading="lazy"
>&lt;/p>
&lt;p>The isAdmin boolean is set after the call as shown previously.&lt;/p>
&lt;p>This global variable is used on the List of Incidents screen to hide or show an icon at the top&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-32.png?w=425"
loading="lazy"
>&lt;/p>
&lt;p>The visibility of this is controlled by the isAdmin value.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-33.png?w=372"
loading="lazy"
>&lt;/p>
&lt;p>This button toggles whether the user sees all the incidents or just their own. This allows an admin to view all incidents.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-34.png?w=443"
loading="lazy"
>&lt;/p>
&lt;p>On the incident detail screen, there is a edit button as well, which allows an admin or welfare officer to add some commentary to the incident, such as when the parent is contacted or details about any investigations.&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-35.png?w=427"
loading="lazy"
>&lt;/p>
&lt;h2 id="the-sharepoint-list">The SharePoint List&lt;/h2>
&lt;p>In SharePoint, you can see the recorded incident in the SharePoint list&lt;/p>
&lt;p>&lt;img src="https://linked365.blog/images/2020/02-image-36.png?w=1024"
loading="lazy"
>&lt;/p>
&lt;p>This is a simple use of the list, and is secure. Next article, I will walk-through the other flows that are being triggered to notify the parents and welfare officers to complete the requirements.&lt;/p>
&lt;h2 id="conclusions">Conclusions&lt;/h2>
&lt;p>It is a simple app, but it really hits the mark for being cheap (free), secure, easy &amp;amp; portable. SharePoint may not be the database of choice for everyone, but you can not knock it for being cheap. Power Apps just adds that extra polish to the data storage mechanism that takes it from a plain list to an intuitive application.&lt;/p>
&lt;p>If there are any clubs out there that want to work with me on implementing this app at your organisation, particularly charities, give me a shout. I would be happy to help &amp;amp; share the application and spend time installing with you.&lt;/p></description></item></channel></rss>