Como crear un command set SPFx con un panel react en una librería de documentos - Blog de David Alonso. Microsoft SharePoint, Office 365, Azure y otras tecnologías Microsoft

Blog de David Alonso. Microsoft SharePoint, Office 365, Azure y otras tecnologías Microsoft

Microsoft SharePoint, Azure, Office 365

sábado, 22 de febrero de 2020

Como crear un command set SPFx con un panel react en una librería de documentos

Como crear una extensión SPFX en SharePoint Online


extension-sharepoint-framework

¿Qué es una Extensión SPFX?

Una extensión de SharePoint, permite ampliar la funcionalidad propia de SharePoint Online en las páginas Modernas. Con las extensiones se permite crear:
  • Personalizadores de aplicaciones. Permite agregar scripts a la página, así como tener acceso a marcadores de posición de elementos HTML conocidos y ampliarlos con representaciones personalizadas.
  • Personalizadores de campo. Puede usarse para proporcionar vistas modificadas de los datos para los campos de una lista.
  • Conjuntos de comandos. Extiende las superficies de comando de SharePoint para agregar nuevas acciones y proporciona código del lado cliente que puede utilizar para implementar comportamientos.

Para ver más información sobre las extensiones SPFX haz clic aquí

Tutorial para tu primera Extensión SPFX


A continuación vamos a mostrar los pasos para generar un command set en SharePoint con SPFx que al hacer clic, abra un panel react. En el ejemplo mostraremos dentro del panel algún metadato del documento.
Lo primero que hay que hacer es abrir la ventana de comandos cmd y crear el command set con el comand yeoman: 



yo @microsoft/sharepoint


A continuación, hay que ir rellenando los pasos del asistente yeoman para la creación del command set: 
  • Indicar un nombre para el  command-extension  y presionar Entrar.
  • Seleccionar Solo SharePoint Online (más reciente) y presione Entrar.
  • Elegir Usar la carpeta actual y presione Entrar. Es por ello por lo que en el primer paso se debería de crear una carpeta y situarse en ella antes de lanzar el asistente yeoman. 
  • Seleccionar Y para permitir que la solución se implemente en todos los sitios inmediatamente. En este caso, el command set podrá ser visible en todos los sitios del tenant. Si se desea que el command set solo esté visible en los sitios que lo agreguemos bajo demanda, indicar N.
  • Seleccionar N en la pregunta si la solución contiene permisos exclusivos.
  • Seleccionar Extensión como tipo de componente del lado cliente que se va a crear.
  • Seleccionar ListView Command Set como tipo de extensión que se va a crear.

A continuación, comenzará el proceso de creación del command set. Este proceso tarda unos minutos, hay que tener paciencia.


Nuestro Command Set aparecerá en la barra de menú de la biblioteca de documentos cuando seleccionemos un documento y el objetivo es abrir un panel lateral con información del documento.
Lo primero que vamos a hacer es crear un componente react para mostrar el panel.
Dentro de la carpeta
src\extensions\nombredelcmmandset, creamos otra carpeta llamada components, y dentro de ella creamos un nuevo archivo PanelDocumento.tsx. En ese fichero agregamos los siguientes componentes.


import * as React from 'react'
import { Label } from 'office-ui-fabric-react/lib/Label';
import { TextField, DefaultButton, PrimaryButton, DialogFooter, autobind, Panel, Spinner, SpinnerType,Dialog } from "office-ui-fabric-react"
import { getId } from 'office-ui-fabric-react/lib/Utilities';
import { MessageBar, MessageBarType } from 'office-ui-fabric-react/lib/MessageBar';
import { Promise } from 'es6-promise';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { PageContext } from '@microsoft/sp-page-context';
import { ContextualMenu } from 'office-ui-fabric-react/lib/ContextualMenu';
import { hiddenContentStyle, mergeStyles } from 'office-ui-fabric-react/lib/Styling';
import { HttpClient, SPHttpClient, HttpClientConfiguration, HttpClientResponse, ODataVersion, IHttpClientConfiguration, IHttpClientOptions, ISPHttpClientOptions } from '@microsoft/sp-http';

const screenReaderOnly = mergeStyles(hiddenContentStyle);

En el mismo .tsx creamos el state del componente.


export interface IPanelState
{    
    saving: boolean;  
    delayResults?: boolean;
    hideDialog: boolean;
    sending: boolean 

y sus propiedades, donde nos llegaran los datos del documento que vamos a mostrar en el panel.


export interface IPanelProps {     
    onClose: () => void;     
    isOpen: boolean;     
    currentTitle: string;
    listId: string
    spPageContext : PageContext;
    propHttpClient : HttpClient

En el render, pintaremos un Panel y las Label necesarias para mostrar los datos así como un botón Cancelar para cerrar el Panel.


public render(): React.ReactElement<IContabilizarPanelProps> {  
        let { isOpen, currentTitle } = this.props
                return (  
                  <div>          
                    <Panel isOpen={isOpen} headerText={this.props.titulodoc}>
                       
                        <Label><b>Nombre Documento:</b> {this.props.currentTitle}</Label>  
                        <Label><b>ID Lista Firma:</b> {this.props. listId }</Label>
                        <DialogFooter>
                            <DefaultButton text="Cancelar" onClick={this._onCancel} disabled={this.state.sending}/>
                        </DialogFooter>            
                    </Panel>            
                    </div>       
                );
    }


Además, añadimos el método onCancel y otros métodos necesarios:


private _onCancel() {               
        this.props.onClose();  
      
   

private _showDialog = (): void => {
      this.setState({ hideDialog: false });
    };
 
    private _closeDialog = (): void => {
      this.setState({ hideDialog: true });
    };

Volvemos al commandset, para ello en la carpeta src\extensions\nombrecommandset, localizar el archivo CommandSet.tsEste archivo ejecuta la acción del clic del commandset y lo que queremos es que nos abra un Panel lateral con los datos del documento sobre el que hemos hecho clic.
Para ello, dentro de la clase que se define vamos a incluir un control HTMLdivElement:


  private panelPlaceHolder: HTMLDivElement = null;

En la función onInit vamos a meter este div HTML dentro del body de la página. Se puede incluir esta línea justo debajo del Log.info que nos genera automáticamente la extensión quedando el onInit de la siguiente forma:


this @override
  public onInit(): Promise<void> {
    Log.info(LOG_SOURCE, 'Initialized SpoContabilizarCommandSet');
    this.panelPlaceHolder = document.body.appendChild(document.createElement("div"));
    return Promise.resolve();
  }

Cuando se crea un commandSet, por defecto nos da 2 botones, pero aquí nos vamos a quedar con uno. Para ello en el método onExecute, dejamos solo el case ‘COMMAND_1’ y además, en elfichero CommandSet.manifest.json , dentro de “ítems”, dejamos solamente la definición del COMMAND_1 :


"items": {
    "COMMAND_1": {
      "title": { "default": "Command Prueba" },
      "iconImageUrl": "",
      "type": "command"
    }  
  }

Se puede modificar el title que será el texto que muestre la acción del menú y el icono. Para subir un icono se puede o bien indicar la ruta de un icono que tengamos en el directorio de la extensión spfx, o indicar el icono en base64.
Volvemos al método onExecute del CommandSet. Vamos a obtener el valor id y el valor del nombre del documento seleccionado, y llamaremos a una función showPanel que será la que muestre el componente react del panel


  @override
  public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
    switch (event.itemId) {
      case 'COMMAND_1':
        let selectedItem = event.selectedRows[0];
        const docUrl = selectedItem.getValueByName("FileRef");
        const listItemId = selectedItem.getValueByName('ID') as number;       
        this._showPanel(listItemId, docUrl);    
        break;
  
      default:
        throw new Error('Unknown command');
    }
  }

La función showPanel y funciones auxiliares:



private _showPanel(itemId: number, currentTitle: string) 
      
    this._renderPanelComponent({       
      isOpen: true     
      currentTitle     
      itemId     
      listId: this.context.pageContext.list.id.toString(),       
      onClose: this._dismissPanel     
    });  
 

  @autobind   private _dismissPanel() {    
    this._renderPanelComponent({ isOpen: false });   
 
  private _renderPanelComponent(props: any) {    
       const element: React.ReactElement<IPanelProps> = React.createElement(
         CustomPanel, assign({       
            onClose: null,       
            currentTitle: null,
            itemId: null,
            isOpen: false,
            listId: null,
            propHttpClient: this.context.httpClient,
            spPageContext: this.context.pageContext         
            },
            ReactDom.render(element, this.panelPlaceHolder);   
      }


Con este código,  ya se dispone de un CommandSet con un panel.
Para probarlo, se puede indicar la url de una librería en  el archivo serve.json en la propiedad "pageUrl" 


"pageUrl": "https://myurl.sharepoint.com/sites/mySite/SitePages/myPage.aspx",


Se abrirá la biblioteca de documentos y cuando haces clic en el documento, se mostrará en la barra de herramientas una nueva opción con el commandset. Al hacer clic sobre esa opción se abrirá el panel.


En futuro post explicaré como desplegar un command set para varias colecciones de sitios. 

No hay comentarios:

Publicar un comentario