Maximizar o uso de listas e bibliotecas modernas

Este artigo discute como obter a quantidade máxima de listas e bibliotecas ao usar a interface do usuário moderna no SharePoint.

Você ainda não pode transformar todas as listas e bibliotecas na experiência moderna porque:

  • Determinados tipos de listas e bibliotecas ainda não foram compilados pela equipe do SharePoint para serem exibidos na interface do usuário moderna, como uma Lista de tarefas ou uma Lista de eventos. Para esses tipos, você pode esperar que a equipe do SharePoint implemente uma versão moderna ou pode mudar para uma opção equivalente. As opções incluem usar o Microsoft Planner em vez de uma lista de Tarefas clássica ou usar o calendário do seu grupo do Microsoft 365 em vez de um calendário de lista clássico de eventos do SharePoint.

  • Determinados tipos de listas e bibliotecas podem ser exibidos na versão moderna, mas estão bloqueados devido a uma configuração ou personalização incompatível; você pode realizar uma ação aqui.

Importante

As ferramentas de modernização e todos os outros componentes PnP são ferramentas de código aberto, sustentadas por uma comunidade ativa que fornece suporte a eles. Não há SLA para suporte de ferramentas de código aberto a partir dos canais oficiais de suporte da Microsoft.

Listar modelos disponíveis na interface do usuário moderna

A seguir, encontram-se os tipos de modelos de lista mais usados que o SharePoint pode renderizar no momento em uma interface do usuário moderna (a partir de outubro de 2018):

  • Lista (100)
  • Biblioteca de Documentos (101)
  • Lista de Links (103)
  • Lista de Comunicados (104)
  • Lista de Contatos (105)
  • Biblioteca de Imagens (109)
  • Biblioteca de Formulários (115)
  • Biblioteca de páginas do site (119)
  • Grade personalizada (120)
  • Lista de links promovidos (170)
  • Biblioteca de páginas de publicação (850)
  • Biblioteca de ativos (851)
  • Lista de rastreamento de problemas (1100)

Nesta seção, você verá como identificar listas que não estão sendo exibidas como listas modernas, a razão disto e como efetuar a correção, se possível. No entanto, antes de começar, é importante entender que, para a maioria dos locatários, grande parte das listas é carregada na versão moderna sem problemas. As listas que não são carregadas na versão moderna permanecem no modo clássico (como a lista de calendário ou de tarefas) ou podem ser desbloqueadas por meio de uma correção, que é o escopo desta série de artigos. As listas que não são carregadas como listas modernas continuam funcionando 100%, são totalmente compatíveis e não o impedem de habilitar a experiência moderna de lista e de biblioteca para o locatário.

Importante

O SharePoint será automaticamente padronizado para Listas e bibliotecas modernas, mas também alternará automaticamente quando necessário. Isso vai garantir que todas as listas que possam usar a versão moderna tenham essa aparência, enquanto as listas que não possam ser alternadas, simplesmente passem para o modo clássico ao serem usadas.

Detectar listas e bibliotecas não disponíveis na interface do usuário moderna

A abordagem recomendada para detectar quais listas e bibliotecas não estão disponíveis na interface do usuário moderna é executar o Verificador de Modernização do SharePoint. Esta ferramenta realiza uma análise profunda de listas e bibliotecas em seu locatário e cria relatórios que oferecem detalhes de quais listas e bibliotecas não serão exibidas na versão moderna e, mais importante, porque isso acontece. Com base na saída do verificador, é possível desbloquear listas e bibliotecas para corrigi-las, o que é abordado na próxima seção.

Desbloquear listas e bibliotecas

Uma lista pode ser bloqueada por diversos motivos, que são todos descritos na saída do verificador. A seguir, estão os motivos comuns e suas abordagens de correção.

Personalizações incompatíveis

Uma customização incompatível é o motivo mais comum de não renderização de listas no modo moderno e geralmente se deve a uma das seguintes questões:

  • O uso de JSLink
  • O uso de ação personalizada de um usuário que insere JavaScript

Para corrigir esses bloqueadores, é possível remover a personalização (caso não seja mais relevante para os negócios) ou criar uma solução alternativa. Para saber mais sobre como criar personalizações compatíveis com a experiência moderna de lista e biblioteca, confira o artigo Personalizações de modernização. Como o JSLink no nível da web part impede a página de usar a experiência moderna de lista e biblioteca, é necessário remover essa configuração. Para fazer isso manualmente, coloque a página em modo de edição, acrescentando ?ToolPaneView=2&pagemode=edit à URL da página e atualizando as propriedades da web part. Para fazer isso de forma programática, é possível usar a obtenção de web part por meio da classe LimitedWebPartManager, e depois atualizar as respectivas propriedades conforme mostrado no trecho de código abaixo. É possível combinar esse trecho com o código mais completo, mostrado posteriormente nesta página, para obter uma solução completa.

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

Existência de certos tipos de campos

Determinados tipos de campo (dados externos BCS, geolocalização, OutcomeChoice no modo de edição, imagens, Html e SummaryLinks) ainda não foram compilados para trabalhar em uma interface do usuário moderna. Para corrigir isso, é possível aplicar uma das seguintes abordagens:

  • Remova o campo das exibições. O campo continua existindo, de modo que você tem uma experiência de edição clássica, mas com exibições modernas.
  • Migre os dados do campo para um novo campo que seja compatível com a versão moderna.
  • Remova completamente o campo, se ele não estiver em uso.

Bloqueio da interface do usuário moderna e da biblioteca no nível do site ou da web

A interface do usuário de biblioteca e de lista moderna pode ser bloqueada para um conjunto completo de sites (nível de site) ou para um ou mais sites (nível da web). A correção pode ser feita desativando o respectivo site ou recursos com escopo da Web, conforme mostrado abaixo no trecho de código PnP Windows PowerShell:

$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

Observação

O PnP PowerShell é uma solução de software livre com uma comunidade ativa de suporte. Não há nenhuma SLA para o suporte da ferramenta de software livre por parte da Microsoft.

Bloqueio da interface do usuário moderna e da biblioteca no nível da lista

É possível definir uma lista de modo que ela seja sempre executada na experiência clássica, em nível de lista (ListExperienceOptions definida como ClassicExperience). Para desfazer isso, o trecho de código a seguir pode ser usado:

// 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();

Listas exibidas com BaseTemplate = 0

Cada lista tem um modelo de base, mas às vezes, as listas podem aparecer com um valor de modelo base 0, na saída do verificador. Isso se deve ao fato de que, para essas listas, não há um modo de exibição marcado como padrão ou, às vezes, não há qualquer modo de exibição. A correção para essas listas consiste em navegar até a página de configurações de listas (_layouts/15/listedit.aspx?List=%7B<list id>%7D) e atribuir um modo de exibição à lista.

Páginas personalizadas de exibição de lista contendo mais do que a lista XSLTListViewWebPart

As páginas de edição e exibição da lista clássicas podem ser editadas pelos usuários, portanto é possível adicionar Web Parts adicionais em uma página de visualização da lista. Caso já tenha feito isso, a lista não será mais exibida no modo moderno. Para corrigir isso, a única abordagem possível é descartar as web parts adicionadas nas páginas da lista. Para verificar esses casos manualmente, acesse a lista e acrescente ?ToolPaneView=2&pagemode=edit à URL da lista. Isso exibirá a página no modo de edição e revelará mais web parts, permitindo removê-las. Se desejar fazer a mesma coisa de forma programática, o trecho de código abaixo é um bom ponto de partida. Esse trecho depende da biblioteca principal de sites PnP que pode ser instalada no projeto do Visual Studio por meio do pacote 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;
        }
    }
}

Confira também