Aric Levin's Digital Transformation Blog https://aric.isite.dev Microsoft Dynamics 365, Power Platform and Azure Wed, 11 May 2022 17:22:23 +0000 en-US hourly 1 https://wordpress.org/?v=5.9.9 Migrate your Microsoft Access database to Power Apps and Dataverse https://aric.isite.dev/powerapps/post/access-migration-dataverse/ Wed, 11 May 2022 17:15:01 +0000 https://aric.isite.dev/?p=680 Today, May 11, 2022, Microsoft released the Access Migration to Power Apps and Dataverse to General Availability. Microsoft Access users will not be able to migrate their data into Power Apps and Dataverse.

The post Migrate your Microsoft Access database to Power Apps and Dataverse appeared first on Aric Levin's Digital Transformation Blog.

]]>
Today, May 11, 2022, Microsoft released the Access Migration to Power Apps and Dataverse to General Availability. Microsoft Access users will not be able to migrate their data into Power Apps and Dataverse.

Customers will not be able to make use of the Dataverse Connector or Migration Tool. The Access migration tool and connector provided within MS Access streamlines the process of migrating tables, relationships, and data with setup taking just a few minutes, and migration handled for you.

With this feature now in General Availability, customers of Microsoft Access are now just a click away from unlocking the following capabilities for the data currently managed in the Access Database:

  • New security and compliance capabilities through Dataverse cloud storage using Azure Active Directory and role-based security while managing it from Access
  • The ability to have real-time sharing and editing of Access data using cloud-based data stores, with front-end apps created in Access, Power Apps Mobile and Microsoft Teams 
  • New front end app scenarios on mobile devices or with Microsoft Teams

To learn more about this new offering, visit this post on the Microsoft Power Apps blog.

https://powerapps.microsoft.com/en-us/blog/access-migration-to-power-apps-and-dataverse-is-released-to-general-availability/

You can also learn about these capabilities in the Microsoft Build sessions available on the blog post link.

To take the next steps and evaluate this for yourself, you can visit https://aka.ms/AccessAndPowerPlatform

The post Migrate your Microsoft Access database to Power Apps and Dataverse appeared first on Aric Levin's Digital Transformation Blog.

]]>
Collaboration enhancements in 2022 Release Plan Wave 1 https://aric.isite.dev/dynamics/post/collaboration-enhancements-2022w1/ Thu, 31 Mar 2022 04:34:00 +0000 https://aric.isite.dev/index.php/2022/03/31/collaboration-enhancements-in-2022-release-plan-wave-1/ Collaboration seems to have been on Microsoft’s roadmap for some time now, and with the updates to the Power Platform in the 2022 Wave 1 Release Plan, there are a few enhancements in this collaboration space for Model Driven apps. In this post, I will go over some of these enhancements and demonstrate how this functionality is used and displayed in your dataverse environment.

The post Collaboration enhancements in 2022 Release Plan Wave 1 appeared first on Aric Levin's Digital Transformation Blog.

]]>
Collaboration seems to have been on Microsoft’s roadmap for some time now, and with the updates to the Power Platform in the 2022 Wave 1 Release Plan, there are a few enhancements in this collaboration space for Model Driven apps. In this post, I will go over some of these enhancements and demonstrate how this functionality is used and displayed in your dataverse environment.

First, let’s go ahead and start by enabling these new features. As with previous functionality that I wrote about, enabling the new collaboration features is done via the Power Platform Admin Center. Navigate to your Power Platform Admin Center, select your environment and Go to Settings and Features. Within Features, you will see a section called Collaboration at the bottom of the page (currently). The Enable preview of the modern link sharing UI, co-presence, online status in model-driven apps is going to be set to Off by default. Change this setting to On in order to enable these features.

You can also set the time of the refresh interval for Co-presence, which is set by default to 60 seconds. Don’t set it to a number that is too small or it might have some performance implications. The screenshot below shows you these settings in the Power Platform Admin Center.

2022 Release Wave 1 - Power Platform Admin Center - Collaboration features

Once we have set this option let’s go ahead and navigate back to our Model Driven app. We will open to browser windows with two different users logged in and accessing the same record. What we will see on the screen is that on the right hand side of the command bar, it will display the initials and presence of the other user or users that are logged into the system accessing that same record. This will allow us to quickly connect and collaborate with these other users. The image(s) below show two users logged on to the same record and being able to see that the other is accessing the record.

2022 Release Wave 1 - Collaboration - Co Presence

2022 Release Wave 1 - Collaboration - Co Presence

When you click on the bubble of the one of the users, you will have a couple of options to start collaboration with them. You will be able to Send the other user an email, Start a Teams chat or open their Contact card and start collaboration from there. See these options in the following screenshot.

2022 Release Wave 1 - Model driven apps - Collaboration Options

The next enhancement that is coming out is how the Owner of the record is presented. With this new release plan, the owner will have the presence bubble next to their name. Hovering over their presence will pop up their presence card contact information and list of recent files, and the ability to expand and see their full ownership information. The screenshot below shows some of that information.

2022 Release Wave 1 - Model driven apps - Owner field profile card

Next, we can see that next to the bubble of the other users accessing the record, we have the Share button. This allows us to share and manage the access to this record with other users.

2022 Release Wave 1 - Model driven apps - Share record

Once we click on the Share button, we will be able to select the users and/or teams that we want to share access to this record with, and provide them with the appropriate Read/Write permissions as required. We can see this in the image below.

2022 Release Wave 1 - Model driven apps - Manage Access/Sharing

There are likely to be additional collaboration changes that will be coming up in the new future to Unified Interface, but for the meantime, I hope you will enjoy the enhancements to this Wave Release.

The post Collaboration enhancements in 2022 Release Plan Wave 1 appeared first on Aric Levin's Digital Transformation Blog.

]]>
Modern Advanced Find in Unified Interface – 2022 Release Wave 1 https://aric.isite.dev/dynamics/post/modern-advanced-find-2022w1/ Tue, 22 Mar 2022 01:30:00 +0000 https://aric.isite.dev/index.php/2022/03/22/modern-advanced-find-in-unified-interface-2022-release-wave-1/ The Advanced Find features in the Microsoft Dynamics and the Power Platform has gone back since the inception of the product, and not many changes have been done throughout the years. We have seen some of the plans in the last release with table level filtering, but with the upcoming release of the Power Platform 2022 Release Wave 1, the Advanced Find is getting a makeover.

The post Modern Advanced Find in Unified Interface – 2022 Release Wave 1 appeared first on Aric Levin's Digital Transformation Blog.

]]>
The Advanced Find features in the Microsoft Dynamics and the Power Platform has gone back since the inception of the product, and not many changes have been done throughout the years. We have seen some of the plans in the last release with table level filtering, but with the upcoming release of the Power Platform 2022 Release Wave 1, the Advanced Find is getting a makeover.

By default, the legacy Advanced Find functionality will show up after the 2022 Wave 1 is enabled, unless it is configured in the Power Platform Admin Center. To get the modern experience enabled, navigate to the Power Platform Admin Center to the environment that you want this enabled, and click on Settings, and in the Settings page select Product and then select Features. When the Features page will open up, you will see a section called Advanced Find options as shown below

Power Platform 2022 Release Wave 1 Advanced Find - Admin Center Configuration

There are two options that can be enabled for the new Advanced Find. The first is the new modern experience, and the second will allow users to hide System views from their list of views that they usually see in their view selector. Now let’s take a look at this modern experience.

When you click on the Advanced Find button in the navigation bar, it will pop up a panel, where you can select the table that you want to search by.

Power Platform 2022 Release Wave 1 Advanced Find - Select Table

Once you select the table, the page will redirect to the table home page with the default view and the Advanced Filters panel open for filtering. In here you can edit the filter and this will display the results on the page that you are looking for.

Power Platform 2022 Release Wave 1 Advanced Find - Advanced Filters

The view that you now modified (including the column updates and new filter) will show up with an asterisk (*) next to it. When you open up the view selector, you will notice that at the bottom of the list of views, you have two new options: Save as new view (which was previously available on the Command Bar under the Create View command) and Manage and share views as shown in the image below:

Power Platform 2022 Release Wave 1 Advanced Find - View Selector

The Save as new view will simply pop up a window asking for the name and description of this new view, and by clicking Save will create this view to be selected as a Personal view.

The Manage and share view will open a panel with options to determine the Sort order of your views (System before Personal, Personal before System or just in alphabetical order). In addition, each view will have the option to be hidden. This will allow end users to hide System views from their list of views in order to have a short list of Most Commonly used views. There is also the option to set the default view from here.

For personal views (which are followed by a user icon), there are additional options which include Sharing, Assigning, Deactivating or Deleting the views.

Power Platform 2022 Release Wave 1 Advanced Find - Manage and Share Views

If you have Dataverse search enabled in the Power Platform Admin center, you will no longer see the Advanced Find button on the navigation bar on top. Instead you will see the dataverse search bar on top. When you click on the dataverse search bar, it will pop up with default search results, and at the bottom of the search bar you will see the option Search for rows in a table using advanced filters. Clicking on this option will open up the Advanced find panel with the options to select a table as previously shown. The image below shows the Dataverse search window with the link for Advanced filters

Power Platform 2022 Release Wave 1 Advanced Find - Dataverse Search

The one main thing that I can see is still pending is the ability to Export the Fetch Xml, especially for people who are using this for development. I am sure that this functionality will be coming soon, as it is highly requested. If you have multiple environments, you can definitely enable this in your higher environments for your end users, and leave it as old interface in lower environments for development so that you can get the Fetch Xml.

Hope you will enjoy the coming changes.

The post Modern Advanced Find in Unified Interface – 2022 Release Wave 1 appeared first on Aric Levin's Digital Transformation Blog.

]]>
2022 Wave 1 Release Power Apps Read Only Grid https://aric.isite.dev/powerapps/post/powerapps-readonly-grid-2022w1/ Tue, 08 Mar 2022 01:07:00 +0000 https://aric.isite.dev/index.php/2022/03/08/2022-wave-1-release-power-apps-read-only-grid/ In the last Power Platform Release Wave, 2021 Wave 2, Microsoft released some enhancements to the grid control that is displayed in views and subgrids. In the upcoming release, 2022 Wave 1, Microsoft has replaced this grid control with a new read-only that will be part of this release.

The post 2022 Wave 1 Release Power Apps Read Only Grid appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last Power Platform Release Wave, 2021 Wave 2, Microsoft released some enhancements to the grid control that is displayed in views and subgrids. In the upcoming release, 2022 Wave 1, Microsoft has replaced this grid control with a new read-only that will be part of this release.

By default, when the 2022 Wave 1 is enabled, the grid that will show up under the Controls tab for the Entity that you want to enable the grid is the Read only grid (Default). This is the grid that was enabled as part of the previous Wave with a few enhancements. The image below shows you the look and feel of the grid that was available as part of 2021 Wave 2.

Power Apps Read Only Grid - 2021 Wave 2 Release

Once your instance has been upgraded, you will be able to see some changes to your grid control. Theses changes include the labels next to the buttons for Edit columns and Edit filters, the grid title bar design is slightly different, the row selectors have been slightly modified, and at the footer of the screen you will see not only the number of records, but will have the pager visible (regardless of the number of records on the screen). The screenshot below shows the 2022 Wave 1 Read Only Grid as it is out of the box after the upgrade.

Power Apps Read Only Grid - 2022 Wave 1 Release

In order to get some of the additional functionality in the grid, we will need to use the Power Apps Grid instead of the default Read Only Grid. The Power Apps grid contains some additional properties call Jump bar, Reflow behavior and Allow filtering, which we will discuss in a bit, but first, let’s enable the Grid.

As parity is not yet available between the modern solution designer and the classic designer, we still have to configure PCF controls from within classic interface. In order to do this following the steps below. This will be demonstrated on the Account table, but can be done for any of the entities.

  • Navigate to a solution containing the and click on the Accounts table, and click on Accounts
  • On the command bar click on Switch to Classic
  • Once classic window/tab has opened for the Account entity, click on Controls
  • You should see there the Read Only grid control.
  • Click on the Add Control link under the list of existing controls
  • In the Add Control window, look for Power App Grid, and click on the Add button
  • In the Controls section you will now see both PCF controls, the Read Only grid and the Power Apps grid.
  • Make your Power Apps grid the selected one by selecting the radio buttons under Web, Phone or Tablet

Power Apps Read Only Grid - 2022 Wave 1 Release - Control Settings

Before we go back to the Accounts view, let’s look again at the properties that are available to be modified for the PCF control.

Jump bar: Jump bar is disabled by default and display at the bottom of the grid the selectors to allow to filter the results by any alphabetical letter, but numbers or seeing all the results. This has been available for a long time, but now can be selected whether it should be visible or not.

Power Apps Read Only Grid - 2022 Wave 1 Release - Jumpbar Enabled

Reflow behavior: The reflow behavior determines how we want to control the flow of the grid/view. There are three available options for selection in Reflow:

  • Grid Only – will show the rows in a grid view regardless of the width of the screen
    Power Apps Read Only Grid - 2022 Wave 1 Release - Grid View Only
  • List Only – will show the rows in a grid as a list regardless of the width of the screen
    Power Apps Read Only Grid - 2022 Wave 1 Release - List View Only
  • Reflow – will show the rows in a grid view when space is available, and when the width gets decreased so that it is not properly viewable, it will automatically change to a list view.

Allow filtering: This option sets weather filters are available on the individual columns or not.

Finally, there are also a few settings that are set on the environment scale which are available on your Environment -> Settings -> Features. In the Grids and views section, you will notice that you can set if you want to use the Modern Grid experience, as well as whether the Edit columns button and the Edit filters button are visible on the views.

Power Apps Read Only Grid - 2022 Wave 1 Release - Power Platform Admin Center Settings

The post 2022 Wave 1 Release Power Apps Read Only Grid appeared first on Aric Levin's Digital Transformation Blog.

]]>
Embedded Canvas App Performance Enhancements https://aric.isite.dev/powerapps/post/embedded-canvas-app-performance-enhancements/ Tue, 01 Mar 2022 07:00:00 +0000 https://aric.isite.dev/index.php/2022/03/01/embedded-canvas-app-performance-enhancements/ In the last few months, I have been working on a migration project for a customer from a legacy system to Dataverse, and one of the functionalities included an embedded Canvas app containing multiple screens and quite a bit of functionality. The main issue that was encountered is that within some geographical regions it was taking a longer time than expected to load the app.

The post Embedded Canvas App Performance Enhancements appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last few months, I have been working on a migration project for a customer from a legacy system to Dataverse, and one of the functionalities included an embedded Canvas app containing multiple screens and quite a bit of functionality. The main issue that was encountered is that within some geographical regions it was taking a longer time than expected to load the app.

We opened multiple support tickets with Microsoft to find the root cause of the issue and improved the performance using the Power Apps Review Solution from the PowerCAT team, but it was still not an acceptable load time.

In the last couple of weeks we have gone through the Api calls when the app was loading, and one of the things that we found out was that the app was making 8 calls on load to the primary table hosting the embedded Canvas App, each time retrieving a JSON of 500 records.

Embedded Canvas App Performance - Fiddler Trace

That didn’t make any sense, but we did some further analysis, and the first thing that we found out was the setting of Data row limit, which limits the max number of records to be returned when delegation is not supported, was being called on load multiple times. As we had this setting set up to 2000 it was making 4 calls to return the data on load for each call. We analyzed the data that is to be returned and made some adjustments so that we could accommodate 500 records, and reverted that change.

Embedded Canvas App Performance - Data Row Limit

This change lowered our Api calls on load from 8 to 2.

That was an improvement, but not a full resolution. We are making 2 JSON calls, retrieving 500 records each on the load of the form. This is still taking more time than expected. We were able to get in touch with someone from the product group that provided us some additional insight on this.

The ModelDrivenFormIntegration has two properties, DataSource and On DataRefresh. The DataSource property is set to [@TableName], and the OnDataRefresh is set to Refresh([@TableName]). Each one of these properties is making the Api call that is retrieving the 500 records. Again, doesn’t make sense, but it seems like this is the expected behavior at the time.

Embedded Canvas App Performance - Default ModelDrivenFormIntegration functions

Hopefully sometime in the near future, when Converged Pages can be embedded, this will be resolved.

For now, Microsoft did provide a resolution for this, and there are a few steps.

First, get rid of the code in the DataSource property of ModelDriveFormIntegration. That does not have to be loaded. Once you do that, you might end up seeing a bunch of errors, which you will need to resolve.

Next, on the OnDataRefresh property, add the following Code:

Refresh(TableName); // Note that this is not Refresh([@TableName])

Set(PrimaryId, GUID(First([@ModelDrivenFormIntegration].Data).ItemId)); // Not using the [@ModelDrivenFormIntegration].Item for this.

Next, in order to load data from the Primary record, we can add the following logic

If (!IsBlank(PrimaryId),

Set(PrimaryRecord, Lookup(TableName, PrimaryRecordId = PrimaryId));

)

You should then be able to use the Primary Record to populate and link to data in your embedded canvas app. Let’s look at the sample above as if we were using the Account table. The code on the OnDataRefresh would look something like this:

Embedded Canvas App Performance - Updated On Data Refresh

After adding these modifications, we no longer had the 500 records being loaded on the start of the app. There are still some additional performance issues that we are addressing on preload of Power Automate flows, but those are being addressed as well.

I will update this post with additional findings as we continue our process, but for now, it seems that these latest changes will allow us to go live with the solution. I am still finding some issues were this code is not working in other instances of Dataverse in separate tenants, which I am hoping to address soon.

I hope that this might be of some help in your projects, and looking forward to having converged pages embedded in the form.

Click for a Video demonstration

Special thanks to Srinivasa Dutta and Aaron Richards from Microsoft.

The post Embedded Canvas App Performance Enhancements appeared first on Aric Levin's Digital Transformation Blog.

]]>
Audit Retention enhancements in Power Platform Admin Center https://aric.isite.dev/dynamics/post/audit-retention-ppac/ Mon, 14 Feb 2022 16:43:00 +0000 https://aric.isite.dev/index.php/2022/02/14/audit-retention-enhancements-in-power-platform-admin-center/ A couple of days ago, on February 11th, Microsoft introduced a new set of audit features that will help administrators manage internal and external auditing requirements within Dataverse. Currently auditing is used to track changes that are made on the organization records and user access so that these can be reviewed at a later date.

The main issue that is encountered by many organizations relates to the retention policy of audit logs. Until this new changes, there was no retention policy for auditing, and auditing would be kept forever unless manually deleted by the system administrator.

The post Audit Retention enhancements in Power Platform Admin Center appeared first on Aric Levin's Digital Transformation Blog.

]]>
A couple of days ago, on February 11th, Microsoft introduced a new set of audit features that will help administrators manage internal and external auditing requirements within Dataverse. Currently auditing is used to track changes that are made on the organization records and user access so that these can be reviewed at a later date.

The main issue that is encountered by many organizations relates to the retention policy of audit logs. Until this new changes, there was no retention policy for auditing, and auditing would be kept forever unless manually deleted by the system administrator.

With the new changes, administrators can not select a retention period, so that the audit records will be deleted automatically once that retention period is over. The available options for retentions vary from 30 days to 7 years (30 days, 90 days, 180 days, 1 year, 2 years or seven years). There are also additional options for setting a custom retention period in days or set a forever retention period. The screenshot below shows the default setting prior to making changes to the auditing retention.

Power Platform admin center - retention policy (default)

The following screenshot shows the available options that are available for selection:

Power Platform admin center - retention policy options

When selecting the Custom retention, the screenshot below shows the option to select a custom retention period and enter the number of days that you want to save your audit logs.

Power Platform admin center - custom retention policy

This is a great option when trying to save your log capacity, an issue that I had in the past that required having to go into each environment every 3 months and removing the latest audit log file.

If your tenant is managed by your own Customer Manager Key (CMK/BYOK), this feature does not seem to be available at this time.

The post Audit Retention enhancements in Power Platform Admin Center appeared first on Aric Levin's Digital Transformation Blog.

]]>
Co-Authoring in Canvas Apps https://aric.isite.dev/azure/post/coauthoring-canvas-apps-azure-devops/ Sun, 06 Feb 2022 06:55:00 +0000 https://aric.isite.dev/index.php/2022/02/06/co-authoring-in-canvas-apps/ Late November last year, Microsoft released an experimental feature in Canvas apps to allow co-authoring, so that multiple users can work on the app at the same time. Currently, prior to this feature, if a user is working in Canvas Studio, any other user that will try to login to Canvas Studio will be blocked stating that it is locked by the previous user.

The post Co-Authoring in Canvas Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Late November last year, Microsoft released an experimental feature in Canvas apps to allow co-authoring, so that multiple users can work on the app at the same time. Currently, prior to this feature, if a user is working in Canvas Studio, any other user that will try to login to Canvas Studio will be blocked stating that it is locked by the previous user.

In the post, I will demonstrate how we can enable co-authoring, and show how collaborating works when multiple users are trying to work on the app at the same time.

In order to implement this, there are a couple of prerequisites. We need to connect Power Apps to a Git repository and share the app with the other users that will be co-authoring. In order to connect to a Git repository, we first need to configure it. Currently the supported repositories that can be used are Github and Azure DevOps. In this post, we will be using Azure DevOps to demonstrate how this works.

Configure Azure DevOps:

If you have worked with Azure DevOps before, this should be pretty simple. You will need to create a new repository to use for the Canvas App and generate a Personal Access Token.

Let’s start by configuring Azure DevOps. Navigate to dev.azure.com to your organization, and open the project where you want to create the Repo. If you don’t have a Project yet, you can create a new Project. The url that you should see on your screen should look like:

https://dev.azure.com/ORG_NAME/PROJECT_NAME, where ORG_NAME is the name of your Azure DevOps organization, and PROJECT_NAME is the name of the project you are working on. The screenshot below shows what you should be seeing on the screen:

Canvas Apps Co-Authoring - Azure Dev Ops Configuration (Project View)

Click on Repos to start creating a new Repo. Click on the Plus sign next to the Project Name on the left navigation, and select New Repository. This will open a Panel on the right hand side. Enter the name of the Repo, and click the create button. Make sure that that Add a README checkbox is checked. The screenshot below shows this steps.

Canvas Apps Co-Authoring - Azure Dev Ops Configuration (Create a Repo)

Once the Repo has been created, you can either copy the name of the Repo from the address bar.

For instructions on generating a personal access token, you can read the following post from a couple of years ago:

/Azure/Post/calling-azure-devops-pipeline-flow-canvas

You will not need to use GitBash to convert the token to base64 for this implementation.

Next let’s go back to our Power Apps. If you have not already done so, please make sure to share the app with the other users that will be co-authoring. Make sure it is shared with the other users as co-owners and not just users.

Canvas Apps Co-Authoring - Power Apps - Share Ownership

Now, as the owning user, open the app in edit mode. Click on Setting from the App main screen, or you can go to File menu, and click Settings from there. Within Settings, click on Upcoming Features, select Experimental and look for Show the Git version control setting. Turn this on.

Canvas Apps Co-Authoring - Power Apps - Show Git Version Control Setting

Once this is turned on, within the popup you will see on the left navigation. Click on the link, which will show a window to connect to the Git Version control.

Canvas Apps Co-Authoring - Power Apps - Connect to Git Version Control

Click on the Connect button, and then enter the Git repository URL, Branch and Directory Name

Canvas Apps Co-Authoring - Power Apps - Git Version Control Repo Settings

Next you will get a repo authentication window requesting your username and password. Enter your user account email in the username field, and the Personal Access Token that you created and copied as the password. If you get a message that the directory was not found, just let the system create the directory for you.

Once you have finished configuring this, you will that there is an additional button added to the Canvas apps command bar, shown in the image below. This is the Commit changes and check for updates button.

Canvas Apps Co-Authoring - Power Apps - Toolbar Changes

Now that we have enabled the Git version control in our app, we can try and test out Co-authoring. You will probably have to log out and log back into the app for this to work.

The video below will show you the app open in two separate windows. We will make a change to the app in one of the windows, and click on the Commit changes and check for updates button. Once done, we will click on the same button on the other window (logged in as a different user), and you will see how the changes are updated in that window as well.
NOTE: If the video does not full show in your browser, right click the video and select Open in new tab.

This is one of the long awaited features, and although still experimental, and I am sure will improve over time, this is a great start for co-authoring. I know that it is something that I will be using shortly.

The post Co-Authoring in Canvas Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II https://aric.isite.dev/development/post/multiselect-lookup-pcf-overview-update-nn/ Sun, 09 Jan 2022 16:00:00 +0000 https://aric.isite.dev/index.php/2022/01/09/using-microsoft-multiselect-lookup-in-your-model-driven-apps-part-ii/ In the last blog post, I demonstrated how to use the Microsoft Multiselect Lookup control (similar to the Activity Party control), which was released as part of an update to Field Services to add new values to a backend many to many relationship. In this post, I am going to extend this further to show how to add and remove items from the multiselect control, and have them get updated in the relationship.

The post Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last blog post, I demonstrated how to use the Microsoft Multiselect Lookup control (similar to the Activity Party control), which was released as part of an update to Field Services to add new values to a backend many to many relationship. In this post, I am going to extend this further to show how to add and remove items from the multiselect control, and have them get updated in the relationship.

The post will go through adding existing values to a Multiselect control, and then removing the values and seeing how these values are adding and removed from the control.

Let’s go ahead and start with showing the way this works. The image below shows the control with the existing values, as well as the corresponding values of the JSON string and the text box containing the text values only of the control to be displayed in the view.

Microsoft Multiselect Lookup - N:N Update 1

You will notice that the form has three values of three separate contacts that were previously added on the create of the account record. I will now go ahead and remove two of the values from the form, and you will see that both the Contacts (JSON) string gets updated and the Contact Values text gets updated.

Microsoft Multiselect Lookup - N:N Update - Removal

Finally, let’s go ahead and add one of the contacts back. You will now see that the Contact Values and the Contacts (JSON) string got updated.

Microsoft Multiselect Lookup - N:N Update - Addition

At the end of the post, you will be able to see a video of this in action, including everything that was added in the previous post (of creating a new record). Now let’s jump into the lookup how this was built. This is slightly more complex that the create logic from the previous post as there are various conditions that have to be met.

First let’s take a look at the JSON configuration that will be added to the Plugin step. Note that the plugin step is now different, because it runs on a single attribute. If you have multiple attributes that you need to run this against, then each one will have a separate plugin step. The sample JSON below shows you how to configure this:

[{“_attributeName”:”crde5_contacts”,”_textAttributeName”:”crde5_contactvalues”,”_relationshipType”:”native”,”_relationshipName”:”crde5_accounts_contacts”,”_details”:

{

“_primaryEntityName”:”crde5_accounts_contacts”,

“_relatedAttributeName”:”accountid”,

“_linkToEntityName”:”contact”,

“_linkFromAttributeName”:”contactid”,

“_linkToAttributeName”:”contactid”,

“_linkToPrimaryAttributeName”:”fullname”

}

}]

The first section is the same as for the create, with the exception of the details. I used the same serialization class for both plugins (create and update). The details contain additional parameters which allow me to add a relationship to the related entity to pull values from. This is required to get the existing values that are already in the N:N relationship that is created for this object. You can omit the linked entity part, but I added in order to be able to retrieve the name value from the related entity to the relationship entity.

Next, let’s look at the changes to the serialization class. The LookupAttribute class now contains an additional Data Member called LookupAttributeDetails which is added as a variable and to the class constructor. An additional class of type Lookup attribute details is also created. You can see the code changes below:

[DataContract]
public class LookupAttribute
{
	[DataMember] 
	public string _attributeName { get; set; }
	[DataMember]
	public string _textAttributeName { get; set; }
	[DataMember] 
	public string _relationshipType { get; set; }
	[DataMember] 
	public string _relationshipName { get; set; }
	[DataMember] 
	public LookupAttributeDetails _details { get; set; }

	public LookupAttribute(string attributeName, string textAttributeName, string relationshipType, string relationshipName, LookupAttributeDetails details)
	{
		_attributeName = attributeName;
		_textAttributeName = textAttributeName;
		_relationshipType = relationshipType;
		_relationshipName = relationshipName;
		_details = details;
	}
}

[DataContract]
public class LookupAttributeDetails
{
	[DataMember] 
	public string _primaryEntityName { get; set; }
	[DataMember]
	public string _relatedAttributeName { get; set; }
	[DataMember] 
	public string _linkToEntityName { get; set; }
	[DataMember] 
	public string _linkFromAttributeName { get; set; }
	[DataMember] 
	public string _linkToAttributeName { get; set; }
	[DataMember] 
	public string _linkToPrimaryAttributeName { get; set; }

	public LookupAttributeDetails(string primaryEntityName, string relatedAttributeName, string linkToEntityName, string linkFromAttributeName, string linkToAttributeName, string linkToPrimaryAttributeName)
	{
		_primaryEntityName = primaryEntityName;
		_relatedAttributeName = relatedAttributeName;
		_linkToEntityName = linkToEntityName;
		_linkFromAttributeName = linkFromAttributeName;
		_linkToAttributeName = linkToAttributeName;
		_linkToPrimaryAttributeName = linkToPrimaryAttributeName;
	}
}

Next, let’s look at our Plugin class. Same as the previous Create Plugin we are retrieving the Unsecure and Secure configuration from the Plugin step to be used to populate the lookupAttributes list.

using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(_unsecureConfigData)))
{
	DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(List<LookupAttribute>));
	lookupAttributes = (List<LookupAttribute>)deserializer.ReadObject(stream);
}

We then retrieve the data from the actual PCF control, which contains the JSON string of all the contacts that were previously added. This is still similar to the Create Plugin.

string controlData = target.GetAttributeValue<string>(attribute._attributeName);
using (MemoryStream dataStream = new MemoryStream(Encoding.Unicode.GetBytes(controlData)))
{
	DataContractJsonSerializer dataDeserializer = new DataContractJsonSerializer(typeof(List<LookupObject>));
	List<LookupObject> lookupObjects = (List<LookupObject>)dataDeserializer.ReadObject(dataStream);
}

The first difference is that now we want to retrieve the related entity values. We do this by creating a query expression that pulls the data elements based on what we set in the unsecured configuration of the plugin step. This is required so that we can have two list of values (current and previous), and add or remove values to the related entity based on changes in the PCF control. The code below shows the dynamic creation of the query expression, and retrieval of the related values and adding them to the collection of existing objects.

QueryExpression query = new QueryExpression(attribute._relationshipName);
query.ColumnSet.AddColumns(attribute._details._linkFromAttributeName, attribute._details._relatedAttributeName);
query.Criteria.AddCondition(attribute._details._relatedAttributeName, ConditionOperator.Equal, target.Id);
LinkEntity linkEntity = query.AddLink(attribute._details._linkToEntityName, attribute._details._linkFromAttributeName, attribute._details._linkToAttributeName);
linkEntity.EntityAlias = attribute._details._linkToEntityName;
linkEntity.Columns.AddColumn(attribute._details._linkToPrimaryAttributeName);

EntityCollection data = service.RetrieveMultiple(query);
if (data.Entities.Count > 0)
{
	List<LookupObject> existingObjects = new List<LookupObject>();
	foreach (Entity related in data.Entities)
	{
		existingObjects.Add(new LookupObject(
			related.GetAttributeValue<Guid>(attribute._details._linkToAttributeName).ToString(), 
			related.GetAttributeValue<AliasedValue>(attribute._details._linkToEntityName + "." + attribute._details._linkToPrimaryAttributeName).Value.ToString(), 
			attribute._details._linkToEntityName));
	}
}

Now that we have the two pieces of data, and both are of type Lookup Object, we want to make a comparison so that we can determine if to add or remove items them from the related relationship records. The code below created two lists of type Lookup Objects called Items to Add and Items to Remove, and populates them with data when there are elements to add or remove.

List<LookupObject> itemsToAdd = new List<LookupObject>(); 
List<LookupObject> itemsToRemove = new List<LookupObject>(); 

EntityReferenceCollection relatedReferencesToAdd = new EntityReferenceCollection();
foreach (LookupObject item in lookupObjects)
{
	var itemExists = existingObjects.Exists(x => x._id == item._id);
	tracingService.Trace("Item {0} does {1} exist in Related Table", item._id, itemExists.ToString());
	if (!itemExists)
	{
		itemsToAdd.Add(item);
		relatedReferencesToAdd.Add(new EntityReference(item._etn, new Guid(item._id)));
	}
}

EntityReferenceCollection relatedReferencesToRemove = new EntityReferenceCollection();
foreach (LookupObject item in existingObjects)
{
	var itemExists = lookupObjects.Exists(x => x._id == item._id);
	tracingService.Trace("Item {0} does {1} exist in Form Table", item._id, itemExists.ToString());
	if (!itemExists)
	{
		itemsToRemove.Add(item);
		relatedReferencesToRemove.Add(new EntityReference(item._etn, new Guid(item._id)));
	}
}

After adding the items to these collections, we create an Associate Request to add all of the related Items to Add, and create a Disassociate Request to remove all of the related Items that are no longer in the PCF control.

if (itemsToAdd.Count > 0)
{
	AssociateRequest addRequest = new AssociateRequest();
	addRequest.Target = target.ToEntityReference();
	addRequest.Relationship = new Relationship(attribute._relationshipName);
	addRequest.RelatedEntities = relatedReferencesToAdd;
	AssociateResponse addResponse = (AssociateResponse)service.Execute(addRequest);
}

if (itemsToRemove.Count > 0)
{
	DisassociateRequest removeRequest = new DisassociateRequest();
	removeRequest.Target = target.ToEntityReference();
	removeRequest.Relationship = new Relationship(attribute._relationshipName);
	removeRequest.RelatedEntities = relatedReferencesToRemove;
	DisassociateResponse removeResponse = (DisassociateResponse)service.Execute(removeRequest);
}

Finally, same as what we did for the Create Plugin, we are going to update the text value containing the list of Contact names to be displayed on the view.

You can find the code in the following my github repository below

https://github.com/ariclevin/PowerPlatform/tree/master/PCF/MultiSelectLookup

The post Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
Using Microsoft Multiselect Lookup in your Model Driven Apps https://aric.isite.dev/development/post/multiselect-lookup-pcf-overview/ Mon, 03 Jan 2022 04:41:00 +0000 https://aric.isite.dev/index.php/2022/01/03/using-microsoft-multiselect-lookup-in-your-model-driven-apps/ Earlier last year (September timeframe), Microsoft released a Multiselect Lookup control (similar to the Activity Party control) as part of an update to Field Services. The control does not seem to be available across the entire spectrum yet, but if you have a Field Services License or an Enterprise license, you should be able to use this control across your Dataverse environment.

The post Using Microsoft Multiselect Lookup in your Model Driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Earlier last year (September timeframe), Microsoft released a Multiselect Lookup control (similar to the Activity Party control) as part of an update to Field Services. The control does not seem to be available across the entire spectrum yet, but if you have a Field Services License or an Enterprise license, you should be able to use this control across your Dataverse environment.

In this post, I will walk through adding the control to the form, saving the record and seeing how we can use some basic plugin logic and configuration to write that data in related entities.

The control is not linked to any of the related entities that you are adding, but only stores a JSON string value to the attribute.

Let’s first go ahead and find the control. If you navigate to you Default solution, and filter by custom controls and do a search for Lookup, you will find the following controls:

Multiselect Lookup - Custom Control in Maker Portal

Next we are going to need to create an attribute (column) in the Maker Portal to host the control. Since the data in the control that is being used is in JSON format, you need to consider the size of the column that you are creating. The format that is being stored in the control contains the Id, the name and the Entity Type Name.

The image below contains two fields that are being used for this control. The first will host the PCF control, while the second will host just the text values of the control in order to be displayed in a view for the users.

Multiselect Lookup - Custom Attributes for configuration

For the purpose of the demo the Contacts column is set to a length of 1000, and the Contacts Value is set to a length of 200.

Now let’s go ahead and add the control to the form. The control is not available in the maker portal, so we will have to use the Classic/Legacy portal to add the control to the form. In the image below we see that the control has been added to the form. We will now go to the properties of the control, and select the Controls tab.

In the controls tab, we will click on the link to Add Control, and then select the control that is called MultiselectLookupControl. We then set the Web, Phone and Tablet options to use the new control instead of the Text Box (default) control.

There are two properties that need to be set in order to use the control. Those are the entity name, which is called entityName_Display_Key and the default view id, called defaultViewId_Display_Key, which can be retrieved from the Home Page views of the Contact table or from the Maker Portal when editing a view. These are displayed as part of the Urls.

Multiselect Lookup - Custom Control Form Configuration

Now that we have added the control, we can test how the control works on the form. Note that we have not implemented any logic for what we want to do once the user adds values to the control.

The images below shows you how the control will look on the form once multiple values have been added, and the data that has been saved.

Multiselect Lookup - Custom Control Form Presentation

Multiselect Lookup - Custom Control View Presentation

Now that we have seen the controls on the form, let’s start and building some of the logic that is associated with it. As this control that we are going to be using will be for a native many to many (N:N) relationship, we will need to provide some configuration data that will be stored in the plugin. Since you can have multiple controls on the form itself, the configuration will allow the plugin to loop through all the controls and process them accordingly.

The configuration information will store the column name of the control, the type of relationship (in this case only native, but in future posts I will show how to do the same for a manual relationship), and the relationship name. I also have the text attribute name if we want to use a separate attribute for storing the names only of the selected records (this is for display in views).

The configuration contains a JSON array with the following key/value pairs: Attribute Name, Text Attribute Name, Relationship Type and Relationship Name as shown below:

[{“_attributeName”:”crde5_contacts”,”_textAttributeName”:”crde5_contactvalues”,”_relationshipType”:”native”,”_relationshipName”:”crde5_accounts_contacts”}]

We will store that in the Unsecure Configuration or Secure Configuration of the Plugin Step. The image below shows you how this looks within the Plugin step, but this will have to wait till the plugin is complete. The highlighted items shows the required configuration.

Multiselect Lookup - Plugin Step Unsecured Configuration

Next, let’s go ahead and build the plugin. We add two files to the plugin.

The first files contains two classes which are used for the serialization/deserialization of the JSON string from the PCF control and the JSON string for the Unsecured configuration. The LookupObject class contains the id, name and entity name that are saved by the PCF control, as shown in the code below.

    [DataContract]
    public class LookupObject
    {
        [DataMember] 
        public string _id { get; set; }
        [DataMember] 
        public string _name { get; set; }
        [DataMember]
        public string _etn { get; set; }

        public LookupObject(string id, string name, string etn)
        {
            _id = id;
            _name = name;
            _etn = etn;
        }
    }

The second class, LookupAttribute, contains the information about each attribute that is configured for use by the plugin. We use the attribute name, text attribute name, relationship type and relationship name.

The attribute name is the name of the attribute of the PCF control field. The text attribute name is the attribute of the text only concatenation of the values from the pcf control in a separate text attribute. The relationship type will contain the value of native or manual based on the type of relationship, and the relationship name contains the name of the relationship that will be used for the Associate Requests. The code below shows the Lookup Attribute class that will be used for serialization.

    [DataContract]
    public class LookupAttribute
    {
        [DataMember] 
        public string _attributeName { get; set; }
        [DataMember]
        public string _textAttributeName { get; set; }
        [DataMember] 
        public string _relationshipType { get; set; }
        [DataMember] 
        public string _relationshipName { get; set; }

        public LookupAttribute(string attributeName, string textAttributeName, string relationshipType, string relationshipName)
        {
            _attributeName = attributeName;
            _textAttributeName = textAttributeName;
            _relationshipType = relationshipType;
            _relationshipName = relationshipName;

        }

    }

Next, let’s look at the plugin code. The plugin contains a single class (so far) that is used for the retrieval of the secure and unsecure configuration strings and for the execution of the plugin code.

In this case we will be using the unsecure configuration. The code below shows the code to get the secure and unsecure configuration and store them in variables.

        string _unsecureConfigData = string.Empty;
        string _secureConfigData = string.Empty;

        public MultiSelectLookupPostCreate(string unsecureConfig, string secureConfig)
        {
            if (!string.IsNullOrEmpty(secureConfig))
                _secureConfigData = secureConfig;

            if (!string.IsNullOrEmpty(unsecureConfig))
                _unsecureConfigData = unsecureConfig;            
        }

Next we will look at the code of the Execute function. The entire code will be shared in my github repo, so I will only be going through the relevant code.

First we will create a List of type LookupAttribute which will contain all of the different attributes that this code will need to run for. If there are multiple PCF controls, the same code can be run for all of them. The code below shows how to ready the configuration data from the JSON unsecured configuration string that was initialized previously.

List lookupAttributes;
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(_unsecureConfigData)))
{
   DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(List));
   lookupAttributes = (List)deserializer.ReadObject(stream);
}

Next, we will loop through each of the controls, and within each of the controls we will get the JSON data of that control, serialize it.

foreach (LookupAttribute attribute in lookupAttributes)
{
   string controlData = target.GetAttributeValue<string>(attribute._attributeName);
   using (MemoryStream dataStream = new MemoryStream(Encoding.Unicode.GetBytes(controlData)))
   {
      DataContractJsonSerializer dataDeserializer = new DataContractJsonSerializer(typeof(List));
      List lookupObjects = (List)dataDeserializer.ReadObject(dataStream);
...
   }
}

We will loop through each of the selected values in the PCF and add them to the entity reference collection so that it can be associated. The code below shows the loop.

List<string> lookupObjectNames = new List<string>();
EntityReferenceCollection relatedReferences = new EntityReferenceCollection();

foreach (LookupObject lookupObject in lookupObjects)
{
   Guid lookupObjectId = new Guid(lookupObject._id);
   relatedReferences.Add(new EntityReference(lookupObject._etn, lookupObjectId));
                                        
   lookupObjectNames.Add(lookupObject._name);
}

Finally, now that we have the collection, we will execute the Associate Request to add all of the values to the native relationship:

AssociateRequest request = new AssociateRequest();
request.Target = target.ToEntityReference();
request.Relationship = new Relationship(attribute._relationshipName);
request.RelatedEntities = relatedReferences;
AssociateResponse response = (AssociateResponse)service.Execute(request);

We can then if necessary, update the created record with the text attribute of the name values of the PCF control, shown below.

Entity update = new Entity(target.LogicalName);
update.Id = target.Id;
update.Attributes[attribute._textAttributeName] = String.Join(",", lookupObjectNames);
service.Update(update);

This is basically it. In the next blog articles, I will demonstrate how to update existing controls as well as how to create and update 1:n relationship records. A video will be coming shortly to demonstrate this functionality.

You can find the code in the following my github repository below

https://github.com/ariclevin/PowerPlatform/tree/master/PCF/MultiSelectLookup

The post Using Microsoft Multiselect Lookup in your Model Driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Power Platform 2021 Release Wave 2 Unified Interface Updates – In-App Notifications https://aric.isite.dev/dynamics/post/2021-wave2-uci-in-app-notifications/ Sun, 17 Oct 2021 06:55:00 +0000 https://aric.isite.dev/index.php/2021/10/17/power-platform-2021-release-wave-2-unified-interface-updates-in-app-notifications/ n preparation for our upcoming NYC BizApps event on October 27, 2021, and the Power Platform 2021 Wave 2 release (weekend of October 23/24), I am writing a series of blog posts related to some of the most sought after updates. In this post we will review the new Notifications table and In-App Notifications.

The post Power Platform 2021 Release Wave 2 Unified Interface Updates – In-App Notifications appeared first on Aric Levin's Digital Transformation Blog.

]]>
In preparation for our upcoming NYC BizApps event on October 27, 2021, and the Power Platform 2021 Wave 2 release (weekend of October 23/24), I am writing a series of blog posts related to some of the most sought after updates. In this post we will review the new Notifications table and In-App Notifications.

Although the In-App Notifications are documented as part of the Power Platform 2021 Release Wave 1, and was make available for Public preview in July, it is not yet available as part of GA, so I will be reviewing this new feature here.

So, what is In-app notifications. In-app notifications provide us the ability to alert users on certain processes that have been completed or required their attention, and these are displayed in their Model-driven app as part of the new notifications icon (or notification center).

This notifications feature is not available by default in every environment, and require a System Administrator or App Maker to make this feature available within the app. In order to enable this, we need to call the following statement (which can be done from the console of our browser window while running our model driven app.

fetch(window.origin + "/api/data/v9.1/SaveSettingValue()",{

 method: "POST",

   headers: {'Content-Type': 'application/json'},

   body: JSON.stringify({AppUniqueName: "ENTER_APP_UNIQUE_NAME", SettingName:"AllowNotificationsEarlyAccess", Value: "true"})

   });

An example of the Unique App Name would be: crde4_MyApp. Once this feature is enabled we will be able to use the Notifications table to display notifications to end users.

Now that we configured our environment, let’s go ahead and create a notification. There are a few required parameters (or recommended) that we need to add in order to display the notification, such as the title, owner and body. The owner of the notification is the user that this notification will be displayed for. There are additional options such as Icon Type, Toast Type Expiration and Data which is a JSON string that is used for extensibility and parsing richer data into the notification. The screenshot below shows you the properties

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Notification Table Properties

You can read the Microsoft blog on Notification, by clicking on the link below:
https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/send-in-app-notifications#notification-table

Most of the sample in the above link are visible via JavaScript. Let’s demonstrate how this would look using Power Automate flow.

In our example we will create a flow that displays a notification when a new account is created. This is a simple flow, without any additional parameters, or configuration of the JSON string.

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Basic Flow

Let’s go ahead and create the record. As this logic does not require to create a lot of data, I will just enter some minimal data. The only parameters that the flow is actually using is the name of the account and the creator. The image below shows the record that we created.

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Create New Account to trigger flow

Once we create the new record, we will receive a notification in the Notification Center or as a toast that the account has been created as shown in the image below.

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Basic Notification in Notification Center

Now, sometimes the toast notifications are not immediate, and we might have saved the record and closed it, so we would like to have a link back to the record. So let’s go ahead and first modify the flow and see how this works in action. We will add the Data element to create our custom JSON string, so that the user can access the record that was created. The image below shows the changes to the Add New row of the flow to enable a click-through, so that you can open the record that was created.

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Flow with JSON Data/Action

Once the flow executes, the notification will be displayed to the end user, with a link to navigate to the correct record. Note that sometimes notifications don’t appear immediately and there is a slight delay, but as mentioned previously, this is still in preview.

Power Platform 2021 Release Wave 2 Unified Interface - Notifications - Notification with Action in Notification Center

Additional posts related to the Dynamics 365 and Power Platform 2021 Release Wave 2 will be posted by following the link below:

Power Platform 2021 Wave 2 Release Posts

The post Power Platform 2021 Release Wave 2 Unified Interface Updates – In-App Notifications appeared first on Aric Levin's Digital Transformation Blog.

]]>