Saturday, 30 November 2024

How to Trigger a Microsoft Flow from a Custom Button in Dynamics 365

 When using Microsoft Flow the out-of-the-box button is nested under the ‘Flow’ section and is not easy to find nor is it customizable. Triggering the flow using a ‘Flow Button’ makes the button appear under the ‘Run Flow’ branch which is a nested button that is unintuitive for users.

It is much nicer to have your own customized button to trigger a flow and to do this is surprisingly easy.

image

Creating a Button in Dynamics 365

I created my button using the Ribbon Workbench which calls a command. We’ll go into detail what this command does later on. Here’s my button.

image

Create your Flow

Below is the flow I want to call from the button in Dynamics 365. As you can see there’s a trigger that says ‘When a HTTP request is received’. Once saved the URL will generate for this endpoint and you can define a JSON object that will be received by the Flow. In this example I’m passing through a ‘path’ to the ‘Create File’ method. We’ll keep this blog on the topic of calling Flows from a Dynamics 365 but there’s plenty of information out there on how passing parameters to Flow works. The Flow is simply going to create a File under the path and then send a response with an object.

image


JavaScript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
sendFlowRequest = function () {
    var pathObj = { "path": "/Account/" };

    parent.$.ajax({
        type: "POST",
        url: "https://prod-14.australiasoutheast.logic.azure.com:443/workflows/d5035afc26d740be9c5387da88a06749/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=CJeWFL357zMMIcUKsGu-464rhyfz765BLqOzWhrNm5o",
        contentType: 'application/json',
        data: JSON.stringify(pathObj),
        success: function () {
            alert("success");
        }
    });
}


Above is the code I used to call my Microsoft Flow. The code passes through a ‘pathObj’ which is the object that the request endpoint created in Flow is expecting. The Flow will now create a File under the ‘/Account/’ path.

Response

image

There you have it, using the out of the box way of calling Microsoft Flow’s from the ‘Flow Button’ should not be defaulted to because calling it from your own custom button is surprisingly easy.

Virtual entities revisited: setting up a virtual entity

 In the previous post, I blogged about how useful virtual entities can be when integrating external data with Dataverse, and how we can take that integration even further by adding CRUD support through an embedded canvas app.

But there was a teaser video and no technical details, so, in this post, I’ll talk about setting up the virtual entity and custom provider. In the next post, I’ll talk about the embedded canvas app.

Just to recap, the idea would be to get data from SQL, do surface it in Dataverse as a virtual entity, and, also, to allow at least basic search functionality directly in Dataverse over that entity:

image 

Here is the summary of what needs to be done:

  • Create a virtual entity and define all the fields
  • Create a custom data provider for that virtual entity
  • Configure a virtual entity data source
  • Connect virtual entity to the newly configured data source

Let’s do it.

But, first, let’s set up a SQL database and create a table with some data there.

That database has to be on the server that’s accessible from the plugin. In my case, I just used an Azure SQL database.

And here is the script:

CREATE TABLE ITAExternalContact
(
   Id uniqueidentifier primary key,
   FirstName nvarchar(50), 
   LastName nvarchar(50),
   Email nvarchar(255)
);


INSERT INTO ITAExternalContact
(id, firstname, lastname, email)
values
( newid(), 'Gandalf', 'The Gray', 'gandalfthegray@test.com');

INSERT INTO ITAExternalContact
(id, firstname, lastname, email)
values
( newid(), 'Frodo', 'Baggins', 'frodobaggins@test.com');
INSERT INTO ITAExternalContact
(id, firstname, lastname, email)
values
( newid(), 'John', 'Doe', 'johndoe@test.com');
INSERT INTO ITAExternalContact
(id, firstname, lastname, email)
values
( newid(), 'Santa', 'Claus', 'santaclaus@test.com');

With that done, let’s get back to the Dataverse side.

1. Setting up the virtual entity

This part is very straightforward. It seems we still have to use classic designer for the virtual entities, but, other than that, you just need to create a new entity and mark it as a virtual entity:

image

We are going to use our own custom provider, so I’m not sure it’s important what you put into the “External Name” and “External Collection Name”, but, as you can see above, those fields are mandatory, and I put some values there. Have not used them anywhere else, though.

Leave “Data Source” empty for now.

This entity is going to have 5 fields:

image

Basically, those fields correspond to the SQL columns (they don’t have to – the mapping is done in the custom provider anyway). And the “name” field is there for any entity.

Below is a screenshot for the “First Name”:

image 

All other fields are set up in the same way. Again, when using a custom provider,  “External Name” does not have to be populated.

As with any entity, it might be a good idea to configure some views, so I added those columns to the view below:

image

Last but not least, don’t forget to add that entity to a model-driven application so you could see your entity somewhere:

image

Save, publish all, make sure the application is there and the entity is there.

Just don’t expect it to work yet – we still have not defined the data source. If you try lookin at the entity data at this point, you’ll get an ugly error message. Which is fine, just keep moving on.

2. Setting up the data provider

For this step, there is a good article at the docs site that covers the basics Sample: Generic virtual entity data provider plug-in

We will need a bit more, though, but let me summarize how it works first.

  • There is a plugin that works on RetrieveMultiple and on Retrieve
  • That plugin is working in stage 30
  • We only need to register the plugin – there is no need to register the steps. It’ll happen automatically when registering a data provider
  • For most of the registration steps, we’ll be using plugin registration tool

And here are a couple of observations, btw:

  • Stage 30 will always get “Query” as a QueryExpression. Even if the original query came in as a Fetch. This is different from Stage 20, where that query would still be in Fetch format. This is why we don’t need to convert one format to another in stage 30
  • We’ll need this plugin to support basic search, and, for that, do not forget to go back to the virtual entity configuration and add some fields to the “Quick Find” view. You can do it now or later, but make sure you do it

With that, here is “Execute” method of my plugin:

image

I did put Retrieve and RetrieveMultiple into the same plugin for this example, but, of course, you might want to have two different plugins instead.

Turned out handling that keyword is a bit tricky, but, in the end, the code above worked (sometimes, leading “%” is surrounded by square brackets).

Note: once again, don’t forget to add some columns to the Quick Find view for your entity, or there would be no conditions in the query:

image

And back to the plugin again.

Once there is a keyword (or a guid), the rest is all about loading that data from SQL:

image

  • image

Why am I using TOP 3? Well, for this proof of concept, I have 4 rows in the table, and I wanted to show that I can

  • Control how much data is displayed
  • No matter how much data is there in SQL and how much data is displayed, I can search on all that data and display top 3 matches

There is a sql connection part there, so you’ll need to define your own connection string:

image

Once you’ve built the plugin, open PluginRegistration tool and register the assembly:

image

You don’t need to add any steps.

The, register the data provider. While registering the data provider, you’ll also need to register the data source:

image

Once it’s done, you’ll see those registrations in the Plugin Registration tool:

image

Finally, link your virtual entity to the new data source:

image

Unless I forgot some of the steps, at this point you can save your changes, publish everything, and do a test run.

You should be able to see virtual entities data in the model-driven app:

image

You should be able to do basic search on that data:

image

And you should be able to open each individual record, although, at this point those records will be read-only.

In the next post, I’ll use an embedded canvas app to add “update” functionality.

Comments

*This post is locked for comments

Things to know - pl 200

Power apps notes pl 200

  Change tracking is used to maintain information on what has changed in a table to synchronize with an external system.

Duplicate detection rule: the user can skip and save the record. but if we set an alternate key then we cant save- 

Virtual tables require configuration of a data provider.


send email button press try on cloud flow Link while pressing button using Collect(People, {Id:Id.Text, FirstName:FirstName.Text, LastName:LastName.Text}) If the data source doesn't already exist, a collection is created. if u use collect if current value Id.Text already in people collection is lastname and firstname will not be automatically updated. * Bound action: Bound actions target a single table or a set of rows from a single table. Unbound actions. Unbound actions aren't bound to a table and are called as static operations. Unbound actions are performed on the entire environment, not on specific tables or rows. Set(AgeGroups, ["1-25", "26-54", "55+"]) //set creates global variable and can be use everywhere in app we use set for "updating" global variable and not update function. the above AgeGroup is not a collection. You create GLOBAL variables using Set function, you create CONTEXT variables using UpdateContext function or with Navigate, depending on the situation. The created structure is a Table, which you could also create using the Table function. In order to create a collection, you must call Collect or ClearCollect. To create the site map for the app> add a area>group>sub area @condition(item, value) @GreaterOrEquals(TriggerEmail()?['OverdueDate']: '7') learn later on layers and this https://learn.microsoft.com/en-us/power-platform/alm/segmented-solutions-alm Change tracking is used to maintain information on what has changed in a table to synchronize with an external system. For columns and table only auditing can be enabled.

Friday, 4 October 2024

Power Apps Drag & Drop Kanban code sample

 

Introduction: The Kanban Board App

Developers at a software company use the Kanban board to show their progress on development tasks and bug fixes. When a developer starts a new task, they drag it from Not Started to In Progress. When work on the item is done they drag and drop it into the Completed section.



Install The Power Apps Drag And Drop Managed Solution

Drag and drop functionality is not included in Power Apps out-of-the box. We must download it and install it. Launch a web browser and navigate to the Power Apps drag and drop repository owned by Scott Durow.



Go to the Power Apps drag and drop releases page and download the latest managed solution zip file.



Then open make.powerapps.com. Go to the Solutions menu. Then choose Import Solution. Browse and select the Power Apps Drag and Drop managed solution we just downloaded. Click next the Next button then the import button.



After a few minutes of waiting the Power Apps Drag And Drop component will successfully install and appear in the Solutions menu.



Enable Power Apps Component Framework In Admin Center

The drag and drop functionality we installed was built using the Power Apps component framework (PCF). To use it in a canvas app, we need to enable the PCF in our environment. Go to the Power Platform admin center, open the environments menu and select the environment where drag and drop was installed. Then open the settings page and choose the features.

Toggle on the Power Apps component framework for canvas apps setting. Now we are ready to start building our kanban board app.




Add The Drag And Drop Component To A Canvas App

Open make.powerapps.com and create a new canvas app from blank. Go to the Insert menu and select Get more components from the bottom.



The Power Apps drag and drop component is a code component. Select the code tab and choose it from the list. Then click Import.



The Power Apps drag and drop component will now appear in the the Insert menu under the heading code components.




Populate The Kanbans With Items From A Collection

Place two drag and drop components on the screen and name them pcf_NotStarted and pcf_Completed. Tasks with the status Not Started will appear on the left and tasks with the status Completed will appear on the right. Then insert a new button onto the screen to create a collection of items that will appear in the kanbans.



Use this code in the OnSelect property of the button to generate a collection named colTasksList.

ClearCollect(
    colTasksList,
    Table(
        {
            ID: 1,
            Title: "Task A",
            Description: "Ipsum Lorem Facto",
            Status: "Not Started",
            DisplayOrder: 1,
            Type: "Task",
            TypeIcon: "📘",
            AssignedTo: "Matthew Devaney"
        },
        {
            ID: 2,
            Title: "Task B",
            Description: "Ipsum Lorem Facto",
            Status: "Not Started",
            DisplayOrder: 2,
            Type: "Task",
            TypeIcon: "📘",
            AssignedTo: "Matthew Devaney"
        },
        {
            ID: 3,
            Title: "Task C",
            Description: "Ipsum Lorem Facto",
            Status: "Not Started",
            DisplayOrder: 3,
            Type: "Task",
            TypeIcon: "📘",
            AssignedTo: "Mary Baker"
        },
        {
            ID: 4,
            Title: "Bug A",
            Description: "Ipsum Lorem Facto",
            Status: "Not Started",
            DisplayOrder: 4,
            Type: "Bug",
            TypeIcon: "🐞",
            AssignedTo: "Matthew Devaney"
        },
        {
            ID: 5,
            Title: "Bug B",
            Description: "Ipsum Lorem Facto",
            Status: "Not Started",
            DisplayOrder: 5,
            Type: "Bug",
            TypeIcon: "🐞",
            AssignedTo: "Mary Baker"
        }
    )
)



Click the Not Started drag and drop component and select colTasksList as the datasource.



Then Edit its fields, check every field shown in the menu and click Add. No items will appear in the component just yet. We must do a few more actions first.

Repeat these same steps to select a datasource and add fields for the Completed drag and drop component.




Define The Drop Zone IDs

Each drag and drop component requires a drop zone id. A drop zone id is a unique name which identifies the component. Use the drop zone id Not Started for the component pcf_NotStarted.



Similarly, use the drop zone id Completed for the component named pcf_Completed.



There is another property called other drop zone ids which controls the drag and drop components that may interact with one another. Define the other drop zone id property as Completed for pcf_NotStarted.



Oppositely, write Not Started into the other drop zone id of pcf_Completed.




Setup The IdColumn, ZoneColumn And MasterZone

Once we setup the IdColumn and ZoneColumn properties of the drag and drop component we will finally see some items inside of it. The IdColumn must be set to the unique id of the records in colTasksLists. The ZoneColumn needs to match the record’s field that corresponds to which kanban it’s currently displayed in.



Select the pcf_NotStarted component and use this code in the IdColumn property.

"ID"



Write this code in the ZoneColumn property. Once this code is input we see tasks appear in the component. But we cannot drag and drop them yet.

"Status"



Toggle on the MasterZone property of pcf_NotStarted. There must always be one MasterZone in each group drag and drop components to orchestrate their actions. Now tasks inside the kanban can be re-ordered by dragging and dropping.



We must also set the same values for the IdColumn and ZoneColumn for pcf_Completed.



But the MasterZone property of pcf_Completed should be toggled off.




Test The “Not Started” And “Completed” Kanbans

Put the app in preview mode and give it a try. We can now reorder items inside a drag and drop component and move them to another drag and drop component. Super cool!




Reset The Drag And Drop Component

To return the kanbans to their initial state we can reset the drag and drop component. The component does not have a Reset property like most Power Apps controls. We must do this a different way.



Create a button and write this code in the OnSelect property. The word Reset will be used to identify what action to take. The Now function is added at the end to generate a unique value that will ensure the control is reset.

UpdateContext({locResetKanban: "Reset"&Now()})



Then select the pcf_NotStarted control.



Write the variable name in the InputEvent property of the control. Do the same thing for pcf_Completed.

locResetKanban



Now when the reset button is clicked items will move back into their original positions inside the drag and drop components.




Formatting Items In The Drag And Drop Component

We can control which values from colTasksList appear inside the drag and drop component using the ItemTemplate property and some HTML code. Formatting can also be applied using a combination of HTML and inline-CSS. I highly suggest using the Live Preview extension in VS Code demoed by Scott Durow to perfect your code.

This simple example shows how to display the task name in bold.



Write this code in the ItemTempate property of both the pcf_NotStarted and pcf_Completed components. Note that fields from colTasksList can be included by placing them between a set of squigglybrackets {{ }}.

"<div>
    <h2>{{Title}}</h2>
</div>"



In this next example, the a bolded title showing the task name appears above a description of the task.




Use this code in the ItemTempate property of both the pcf_NotStarted and pcf_Completed components.

"<div>
    <h2>{{Title}}</h2>
    {{Description}}
</div>"



If you want to get really fancy (like me) you can use drop shadows on the item borders to make them look like card elements. I’ve also used CSS flexbox to make the template responsive and emojis (hotkey: [Windows] + [Period]) to make cool looking icons.



Apply this code to ItemTemplate for pcf_NotStarted and pcf_Completed to make them look very stylish indeed. 😀

"<div class=""card"" style=""
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
    margin: 10px;
"">
    <div class=""container"" style=""
        background-color: white;
        padding: 2px 16px;
    "">
        <h3>{{TypeIcon}} &nbsp;{{Title}}</h3>
        <div class=""flex-container"" style=""
            display: flex;
            padding: 0 0 16px
        "">

            <div class=""flex-child"" style=""
                flex: 4;
                margin: 0px;""
            >
            {{AssignedTo}}
            </div>

            <div class=""flex-child"" style=""
                flex: 1;
                text-align: right;
            "">
                <b>8h</b>
            </div>
        </div>
    </div>
</div>"




Style The Kanban Board App

A few more minor improvements are needed to make the app look really awesome.



Update the BackgroundColor property of the pcf_NotStarted control to make it appear light gray.

"rgba(243, 242, 241, 1)"



Do the same for the ItemBackgroundColor property.

"rgba(243, 242, 241, 1)"



Then highlight the pcf_Completed control.



And write the same code for the BackgroundColor and ItemBackgroundColor properties.

"rgba(243, 242, 241, 1)"
"rgba(243, 242, 241, 1)"



Then make the screen a dark gray to contrast with the light gray of the drag and drop component.



Use this code in the fill property of the screen.

RBGA(219, 219, 219, 1)




Make An “In Progress” Kanban

The app should actually have 3 kanbans: Not Started, In Progress and Completed. So let’s go ahead and setup the missing In Progress kanban. Copy the Completed drag and drop component and paste it between Not Started and Completed.



Set the drop zone id to In Progress and the other drop zone ids to Not Started,Completed.



Change the other drop zone ids property to In Progress,Completed for pcf_NotStarted.



And update the other drop zone ids property for pcf_Completed to NotStarted, In Progress.




Test The “Not Started”, “In Progress” And “Completed” Kanbans

That’s all folks. We’re done. Play the app in preview mode and give the drag and drop functionality a try for all 3 kanbans.


How to Trigger a Microsoft Flow from a Custom Button in Dynamics 365

  When using Microsoft Flow the out-of-the-box button is nested under the ‘Flow’ section and is not easy to find nor is it customizable. Tri...