Optimiser l’utilisation des bibliothèques et des listes modernes

Cet article décrit comment obtenir le nombre maximum de listes et bibliothèques en utilisant l’interface utilisateur moderne de SharePoint.

Vous ne pourrez pas encore appliquer la modernisation à toutes les listes et bibliothèques parce que :

  • Certains types de listes et bibliothèques n’ont pas encore été développées par l’équipe SharePoint pour apparaître dans l’interface utilisateur moderne (par exemple, une liste de tâches ou une liste d’événements). Pour ces types de listes, vous pouvez soit attendre que l’équipe SharePoint développe une version moderne, soit opter pour une option équivalente. Les options incluent l’utilisation de Microsoft Planner au lieu d’une liste de tâches classique, ou l’utilisation du calendrier de votre groupe Microsoft 365 au lieu du calendrier de liste d’événements SharePoint.

  • Cela étant dit, il existe également une catégorie de listes et de bibliothèques qui peuvent être affichées dans une interface moderne, mais qui sont bloquées en raison d’une configuration ou d’une personnalisation incompatible. Vous pouvez prendre des mesures ici.

Importante

Les outils de modernisation et tous les autres composants PnP sont des outils open source bénéficiant d’une prise en charge par une communauté active. Il n’existe aucun contrat de niveau de service pour la prise en charge des outils open source des canaux de support Microsoft officiels.

Liste des modèles disponibles dans l’interface utilisateur moderne

Les types de modèles de listes suivants sont les plus généralement utilisés. SharePoint est actuellement en mesure de les faire apparaître dans l’interface utilisateur moderne (à compter d’octobre 2018) :

  • Liste (100)
  • Bibliothèque de documents (101)
  • Liste de liens (103)
  • Liste d’annonces (104)
  • Liste des contacts (105)
  • Bibliothèque d’images (109)
  • Bibliothèque de formulaires (115)
  • Bibliothèque de pages de site (119)
  • Grille personnalisée (120)
  • Liste de liens mis en avant (170)
  • Bibliothèque de pages de publication (850)
  • Bibliothèque de ressources (851)
  • Liste de suivi des problèmes (1100)

Dans cette section, vous découvrirez comment identifier les listes qui ne s’affichent pas en tant que listes modernes, la raison de ce problème et la solution à appliquer (si possible). Toutefois, il est avant tout important de savoir que, pour la plupart des clients, la majorité des listes sont chargées en version moderne sans aucune restriction. Les listes n’étant pas chargées en tant que listes modernes restent en version classique (par exemple, la liste de tâches ou de calendriers) ou peuvent être débloquées en les corrigeant, ce qui est le sujet de cette série d’articles. Les listes qui ne sont pas chargées en tant que listes modernes peuvent être utilisées sans problème, sont entièrement prises en charge et ne vous empêchent pas d’activer l’expérience de bibliothèque et de liste moderne pour votre client.

Importante

SharePoint utilise automatiquement par défaut les listes et les bibliothèques modernes, mais il repassera automatiquement à la version classique en cas de besoin. Cette opération garantit que toutes les listes pouvant utiliser la version moderne se présentent en tant que listes modernes, tandis que celles qui ne peuvent pas faire de même passent simplement à la version classique lorsque vous les utilisez.

Détecter les listes et bibliothèques indisponibles dans l’interface utilisateur moderne

La méthode recommandée pour détecter les listes et les bibliothèques qui sont indisponibles dans l’interface utilisateur moderne consiste à exécuter le scanneur de modernisation de SharePoint. Cet outil effectue une analyse approfondie de toutes les listes et bibliothèques dans votre client. Il crée également des rapports qui donnent des détails sur les listes et les bibliothèques qui ne s’affichent pas dans l’interface utilisateur moderne, et explique surtout pourquoi cela se produit. En fonction du résultat du scanneur, vous pouvez débloquer les listes et les bibliothèques en les corrigeant, ce que nous verrons dans le chapitre suivant.

Débloquer des listes et bibliothèques

Une liste peut être bloquée pour plusieurs raisons, qui sont toutes détaillées dans le résultat renvoyé par le scanneur. Vous trouverez ci-dessous les causes courantes et les méthodes à suivre pour les corriger.

Personnalisations incompatibles

Une personnalisation incompatible est la raison la plus courante pour les listes qui n’apparaissent pas en version moderne. Elle est généralement liée à l’un des facteurs suivants :

  • Utilisation de JSLink
  • Utilisation d’une action personnalisée par l’utilisateur qui incorpore JavaScript

Pour résoudre ces problèmes de blocage, vous pouvez supprimer la personnalisation (si elle n’est plus pertinente au niveau professionnel) ou créer une solution de remplacement. Pour plus d’informations sur la création de personnalisations compatibles avec l’expérience de bibliothèque et de liste moderne, reportez-vous à l’article Modernisation des personnalisations. Étant donné que JSLink au niveau du composant WebPart n’empêche pas la page d’utiliser l’expérience de bibliothèque et de liste moderne, vous devez supprimer cette configuration. Vous pouvez le faire manuellement en mettant la page en mode Édition en ajoutant ?ToolPaneView=2&pagemode=edit à l’URL de la page, puis en mettant à jour les propriétés du composant WebPart. Pour le faire par programmation, vous pouvez obtenir le composant WebPart par le biais de la classe LimitedWebPartManager, puis mettre à jour les propriétés respectives tel qu’illustré dans l’extrait de code ci-dessous : Vous pouvez associer cet extrait de code au code plus complet illustré ultérieurement sur cette page pour obtenir une solution complète.

webPart.Properties["JSLink"] = "";
webPart.SaveWebPartChanges();
cc.ExecuteQuery();

Présence de certains types de champs

Certains types de champs (données externes BCS, géolocalisation, OutcomeChoice en mode d’édition, image, code HTML et liens de synthèse) n’ont pas (encore) été conçus pour être utilisés dans une interface utilisateur moderne. Pour résoudre ce problème, vous pouvez appliquer les méthodes suivantes :

  • Supprimer l’affichage du champ. Le champ reste présent, vous disposez alors d’une expérience d’édition classique, mais au moins les affichages sont modernes.
  • Migrer les données du champ dans un nouveau champ qui est compatible avec l’interface utilisateur moderne.
  • Supprimer complètement le champ s’il n’est pas utilisé.

Blocage de l’interface utilisateur moderne et de bibliothèque au niveau du site ou du web

L’interface utilisateur de bibliothèque et de liste moderne peut être bloquée pour une collection de sites entière (niveau du site) ou pour un ou plusieurs sites (niveau du web). Vous pouvez remédier à ce problème en désactivant le site approprié ou les fonctionnalités web comprises, comme illustré dans l’extrait de code PowerShell PnP ci-dessous :

$minimumVersion = New-Object System.Version("2.24.1803.0")
if (-not (Get-InstalledModule -Name SharePointPnPPowerShellOnline -MinimumVersion $minimumVersion -ErrorAction Ignore))
{
    Install-Module SharePointPnPPowerShellOnline -MinimumVersion $minimumVersion -Scope CurrentUser
}
Import-Module SharePointPnPPowerShellOnline -DisableNameChecking -MinimumVersion $minimumVersion

Connect-PnPOnline -Url "<your site url>"

# Disable the modern list site level blocking feature
Disable-PnPFeature -Identity "E3540C7D-6BEA-403C-A224-1A12EAFEE4C4" -Scope Site
# Disable the modern list web level blocking feature
Disable-PnPFeature -Identity "52E14B6F-B1BB-4969-B89B-C4FAA56745EF" -Scope Web

Remarque

PnP PowerShell est une solution open source pour laquelle un support est assuré par la communauté active. Il n’existe pas de contrat SLA Microsoft pour le support technique relatif à cet outil open source.

Blocage de l’interface utilisateur moderne et de bibliothèque au niveau de la liste

Une liste peut être définie de façon à toujours exécuter l’expérience classique au niveau de la liste (ListExperienceOptions défini sur ClassicExperience). Pour annuler cette opération, l’extrait de code suivant peut être utilisé :

// Load the list you want to update
var list = context.Web.Lists.GetByTitle(title);
context.Load(list);
context.ExecuteQuery();

// Possible options are Auto (= defaults to modern), NewExperience (= "modern") and ClassicExperience
list.ListExperienceOptions = ListExperience.Auto;

// Persist the changes
list.Update();
context.ExecuteQuery();

Listes s’affichant avec BaseTemplate = 0

Chaque liste a un modèle de base, mais il peut arriver que vous rencontriez des listes avec une valeur de modèle de base de 0 dans le résultat de scanneur. Cela est dû au fait que, pour ces listes, aucun affichage n’est signalé par défaut ou aucun affichage n’existe. Pour corriger ces listes, accédez à la page des paramètres des listes (_layouts/15/listedit.aspx?List=%7B<list id>%7D) et attribuez un affichage à la liste.

Pages d’affichage de listes personnalisées contenant d’autres éléments que la liste XSLTListViewWebPart

Les pages d’affichage et de modification de listes classiques peuvent être modifiées par les utilisateurs. Vous pouvez par exemple ajouter des composants WebPart supplémentaires à une page d’affichage de liste. Ce faisant, la liste n’apparaît plus en version moderne. Pour résoudre ce problème, la seule méthode à suivre consiste à supprimer les composants WebPart ajoutés aux pages de listes. Vous pouvez vérifier manuellement ces cas en accédant à la liste et en ajoutant ?ToolPaneView=2&pagemode=edit à l’URL de la liste. La page passera en mode Édition en affichant les composants WebPart supplémentaires et vous permettra de les supprimer. Si vous souhaitez réaliser la même opération par programmation, l’extrait de code ci-dessous est un bon début. Cet extrait de code dépend de la bibliothèque PnP Sites Core que vous pouvez installer sur votre projet Visual Studio à l’aide du package NuGet SharePointPnPCoreOnline.

using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.WebParts;
using OfficeDevPnP.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;

namespace MultipleWebPartFixer
{
    class Program
    {
        static void Main(string[] args)
        {
            string siteUrl = "https://contoso.sharepoint.com/sites/demo";
            string userName = "joe@contoso.onmicrosoft.com";
            AuthenticationManager am = new AuthenticationManager();
            using (var cc = am.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, GetSecureString("Password")))
            {
                // Grab the list
                var list = cc.Web.Lists.GetByTitle("listtofix");
                list.EnsureProperties(l => l.RootFolder, l => l.Id);

                bool isNoScriptSite = cc.Web.IsNoScriptSite();

                if (isNoScriptSite)
                {
                    throw new Exception("You don't have the needed permissions to apply this fix!");
                }

                // get the current (allitems) form
                var files = list.RootFolder.FindFiles("allitems.aspx");
                var allItemsForm = files.FirstOrDefault();
                if (allItemsForm != null)
                {
                    // Load web part manager and web parts
                    var limitedWPManager = allItemsForm.GetLimitedWebPartManager(PersonalizationScope.Shared);
                    cc.Load(limitedWPManager);

                    // Load the web parts on the page
                    IEnumerable<WebPartDefinition> webParts = cc.LoadQuery(limitedWPManager.WebParts.IncludeWithDefaultProperties(wp => wp.Id, wp => wp.ZoneId, wp => wp.WebPart.ExportMode, wp => wp.WebPart.Title, wp => wp.WebPart.ZoneIndex, wp => wp.WebPart.IsClosed, wp => wp.WebPart.Hidden, wp => wp.WebPart.Properties));
                    cc.ExecuteQueryRetry();

                    List<WebPartDefinition> webPartsToDelete = new List<WebPartDefinition>();
                    if (webParts.Count() > 1)
                    {
                        // List all except the XsltListView web part(s)
                        foreach (var webPart in webParts)
                        {
                            if (GetTypeFromProperties(webPart.WebPart.Properties) != "XsltListView")
                            {
                                webPartsToDelete.Add(webPart);
                            }
                        }

                        if (webPartsToDelete.Count == webParts.Count() - 1)
                        {
                            foreach(var webPart in webPartsToDelete)
                            {
                                webPart.DeleteWebPart();
                            }
                            cc.ExecuteQueryRetry();
                            Console.WriteLine("List fixed!");
                        }
                        else
                        {
                            // Special case...investigation needed. Go to list and append ?ToolPaneView=2&pagemode=edit to the list url to check the page
                            Console.WriteLine("Go to list and append ?ToolPaneView=2&pagemode=edit to the list url to check this page");
                        }
                    }
                }
            }

            Console.WriteLine("Press enter to continue...");
            Console.ReadLine();
        }

        public static string GetTypeFromProperties(PropertyValues properties)
        {
            // Check for XSLTListView web part
            string[] xsltWebPart = new string[] { "ListUrl", "ListId", "Xsl", "JSLink", "ShowTimelineIfAvailable" };
            if (CheckWebPartProperties(xsltWebPart, properties))
            {
                return "XsltListView";
            }

            return "";
        }
        private static bool CheckWebPartProperties(string[] propertiesToCheck, PropertyValues properties)
        {
            bool isWebPart = true;
            foreach (var wpProp in propertiesToCheck)
            {
                if (!properties.FieldValues.ContainsKey(wpProp))
                {
                    isWebPart = false;
                    break;
                }
            }

            return isWebPart;
        }

        private static SecureString GetSecureString(string label)
        {
            SecureString sStrPwd = new SecureString();
            try
            {
                Console.Write(String.Format("{0}: ", label));

                for (ConsoleKeyInfo keyInfo = Console.ReadKey(true); keyInfo.Key != ConsoleKey.Enter; keyInfo = Console.ReadKey(true))
                {
                    if (keyInfo.Key == ConsoleKey.Backspace)
                    {
                        if (sStrPwd.Length > 0)
                        {
                            sStrPwd.RemoveAt(sStrPwd.Length - 1);
                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                            Console.Write(" ");
                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                        }
                    }
                    else if (keyInfo.Key != ConsoleKey.Enter)
                    {
                        Console.Write("*");
                        sStrPwd.AppendChar(keyInfo.KeyChar);
                    }

                }
                Console.WriteLine("");
            }
            catch (Exception e)
            {
                sStrPwd = null;
                Console.WriteLine(e.Message);
            }

            return sStrPwd;
        }
    }
}

Voir aussi