Thursday, March 23, 2023

The joys of hiding content from Microsoft Search

 

It was just a question of time, sooner than later we would get a request to hide content in Microsoft Search.


"But why not just use permissions to ensure that only the right group of people can see the content", I hear you say?


Well, in this case the content is visible for everybody, but the business rule is that the content MUST be reviewed at a set interval, and if the content has not been reviewed within this deadline, the end user should not see the content in search anymore.


One option could be to have a workflow that breaks the permissions on the item level once the deadline has been reached, but that option comes with a certain smell of substandard performance and complexity.


The Microsoft Search approach looked less intrusive and gave me some options:

Option A)

I could add a Result Type in the Search and Intelligence Admin center that would "intercept" all items of the specific type (using Content type id or similar property) and only display those items that have been reviewed using the $when clause.


Option B) 

I could change the query for the verticals in order to exclude specific content using a subset of KQL (Manage search verticals


Initially I selected Option A, and use the Search Layout Designer to define the layout, but when the layout was used in the Result Type it had a hard time deciding if the date of the deadline is in the past or the future.

Both blocks below were displayed...but only in the Result Type, in the Search Layout Designer it worked as expected. 😕




Due to this issue, I investigated Option B.

Step one was to get the query right, and using Graph Explorer this was pretty easy:



When I tried to negate the query I found that using the - sign as a shorthand for NOT seems to be a no-go going forward.



Works




Once that query works I just updated the Query for the relevant verticals, in this case only the All vertical.


Add "cacheClear=true" to your URL when testing the update as per Manage search verticals


Can this approach scale?

For now, this solution does solve the current problem, but I doubt very much that it can scale as additional content needs to be excluded. 
It will be interesting to see the solution patterns that will be developed in the coming months as Microsoft Search becomes more top of mind in the MS365 world.










Friday, March 17, 2023

Boost you PnP Modern Search List Layout

 

When working with the PnP Modern Search web parts I am often ask by my customers to tweak the layout of the results.

The Lists Layout seems to be the most popular layout. It looks like this out of the box when searching for documents with some metadata:



We can enhance this layout by making a few simple updates.


Go the Layout section and click on Edit results template



Step one: Upgrade the user info

Find the code block below in the layout template


<span class="template--listItem--author">

{{#with (split (slot item @root.slots.Author) '|')}}{{[1]}}

{{/with}}

</span>


This section shows the name of the Author. Replace it with this section


<mgt-person

ser-id="{{getUserEmail (slot item @root.slots.Author)}}"

      view='threelines'

      show-presence="true"

      person-card="hover"

      avatar-size="large"

      />

</mgt-person>



This is mgt-person, a very powerful component from the Microsoft Graph Toolkit gallery. This component is very configurable, see Person component in MGT for details.

In this case I have chosen the 3 line view (Name + Email + Job title) and that the person-card shall be available. The person card is the card that shows up when the mouse hover above a user's photo. The content of the hover card can also be tweaked, see the link above.



Step two: Update the metadata tags

Find this section:

{{#if (slot item @root.slots.Tags)}}
pnp-icon data-name="Tag" aria-hidden="true" data-theme-variant="{{JSONstringify @root.theme}}"></pnp-icon>
      <div>
      {#each (split (slot item @root.slots.Tags) ",") as |tag| }}
      pan>{{trim tag}}</span>
     {{/each}}
      </div>
{{/if}}


Replace it with this

{{#if (slot item @root.slots.Tags)}}
div>
      {#each (split (slot item @root.slots.Tags) ";") as |tag| }}
            pnp-icon data-name="Tag" aria-hidden="true" data-theme-variant="{{JSONstringify @root.theme}}"></pnp-icon> {{last (split tag "|")}}
            {{/each}}    
/div>
{{/if}}


Finally update the css for template--listItem--result :

 .template--listItem--result {
            flex-basis: 100%!important;
            background-color: antiquewhite;
            box-shadow: 5px 10px #888888;
        }



The final result looks like this.





The layout file can be downloaded from GitHub

Sunday, March 12, 2023

Boost the person fields in your PnP Modern Search Layout

 

This rather generic SharePoint list is created by a self-service site provisioning setup, and it shows who is in change of any Site Collection.






On the front page on each of the Site Collections the customer requests that we insert a web part with some basic site information. In this case the People web part is not sufficient as some of the metadatea can change over time, such as e.g. the Site Owner.

The obvious choice is therefore a PnP Modern Search results web part using a query like 

Path:https://tcwlv.sharepoint.com/sites/SampleTeamSite/Lists/SiteCreationRequestList* basicProvisioningSiteUrlOWSTEXT:{Site.Url}

(basicProvisioningSiteUrlOWSTEXT is the internal name for the SiteUrl column as seen above)

This will give me the data in the list item having the SiteUrl that is the same as the current Site Collection. 


I looked in the People layout and found that the template used to display a person is a pnp-persona template and used it in the custom layout. It looks like this and has not hover card.



This is off cause better than nothing, but even the OOTB List has a hover card, so it needed an upgrade.

I asked the community on the PnP-modern-search discussions and @patrikhellgren provided an incredibly detailed sample using the mgt-person template. (Microsoft Graph Toolkit).

So, by updating the Layout to this I get a tree line Card and the hover card as well 😀

<template id="content">

    {{#> resultTypes item=item}}
        {{!-- The block below will be used as default item template if no result types matched --}}
       
       
        <div class="contactheader">
        Primary Contact
        </div>
       
        <mgt-person
            user-id="{{getUserEmail (slot item @root.slots.Owner)}}"
            view='threelines'
            show-presence="true"
            person-card="hover"
            avatar-size="large"
        />
        </mgt-person>
        <br><br>
    Template: "{{slot item @root.slots.Template}}"

    {{/resultTypes}}
</template>






As an additional bonus I am pretty sure (not verified yet), that the photo comes from AAD and not the User Profile Application, a service that have provided several headaches over the years, especially related to the employee photo ;-)