Tu primer webpart con Sharepoint Framework

En el post anterior hemos creado nuestro developer tenant y lo hemos configurado, a continuación hemos configurado nuestra máquina de desarrollo para empezar a programar nuestra primera webpart con el Sharepoint Framework.

Hoy, vamos a hacer un webpart fácil, un webpart que tenga una propiedad sencilla y se pueda ver el valor de esa propiedad dinámicamente.

En primer lugar lo que tenemos que saber que lo que estamos construyendo aquí es puro web part del lado del cliente, los webparts del lado del cliente ya son soportados en SharePoint y Office 365, pero de una manera diferente, se puede añadir un editor de código, y pegar el código JavaScript y HTML, no tendrán ningún problema, pero el problema con este enfoque es el mantenimiento, el código reside en una página, en la sección de código de un elemento Web, no hay manera de controlar el codigo fuente con TFS o Git.

En este punto, podemos usar CMD para algunos de los comandos que necesitamos para ejecutar, pero quiero introducir una herramienta que algunos de ustedes pueden no conocer, CMDER, un gran reemplazo con una mejor apariencia y características avanzadas. Puede descargarlo aquí.

Paso 1

Vamos a crear nuestro directorio donde almacenaremos nuestra solución.

mkdir OurFirstSPFApp  
cd OurFirstSPFApp  

Paso 2

Crear el proyecto Web Part, para ello vamos a utilizar el generador Yeoman que construimos en el paso anterior

yo @microsoft/sharepoint  

Se le pedirá una serie de preguntas:

Aceptar el nombre por defecto como su nombre de la solución y pulse Enter.
Seleccione Usar la carpeta actual para colocar los archivos.

El siguiente conjunto de instrucciones le pedirá información específica acerca de su web part:

Aceptar el nombre por defecto como nombre de elemento Web y pulse Enter.
Acepte la descripción predeterminada como su descripción de elementos Web y pulse Enter.
Aceptar el valor predeterminado No Javascript Framework web como el Framework que desea utilizar y pulse Enter.

Yeoman instalará todas las dependencias necesarias y la estructura del proyecto, como se muestra aquí:

Paso 3

Se puede utilizar cualquier editor de código que te gusta, a mi me gusta VS Code, y eso es lo que veras en las capturas de pantalla.

Para abrir la parte web en VS Code sólo tiene que escribir:

code .  

Etapa 4

Ahora necesitamos una vista previa de nuestra web part, para eso tenemos que depender de gulp, gulp es un administrador de tareas que se encarga de construir procesos tales como:

Combinar y minificar JavaScript y CSS.
Ejecutar herramientas para llamar a las funciones de empaquetamiento y minificación antes de cada compilación.
Compilar archivos SASS en CSS.
Compilar los archivos de Typescript a JavaScript.

En un futuro post vamos a personalizar el proceso de construcción con gulp.

Por ahora, vamos a utilizar el siguiente comando:

gulp serve  

Esto creará un servidor NodeJS local
Una vez que corremos gulp serve un navegador se abrirá con nuestro workbench de trabajo local, este es el lugar donde vamos a editar nuestra página y agregar el elemento Web para la prueba.

Paso 5

Vamos a compilar nuestro proyecto

Visual Studio Code proporciona soporte incorporado para el gulp y otros administradores de tareas. Puede presionar Ctrl + Shift + B si está en Windows o Cmd + Shift + B si se encuentra en Mac para compilar, depurar y tener vista previa del web part.

Una vez que hagas esto, usted será capaz de ver en la ventana de resultados como el proyecto se está construyendo

Ahora puede agregar el elemento Web a su página,

Y verlo en acción,

Paso 5

Vamos a aprender acerca de la estructura del proyecto

El SRC es donde toda la magia sucede, esto es la carpeta que realmente importa, y en la que se codifica.

TypeScript es el idioma principal para construir webparts de SharePoint del lado del cliente. TypeScript es un superconjunto escrito de JavaScript que se compila en pleno JavaScript. Las herramientas de desarrollo del lado del cliente de SharePoint se construyen utilizando clases de TypeScript, módulos e interfaces para ayudar a los desarrolladores a crear piezas solidas para los Web parts del lado del cliente.

Paso 6

Vamos a dar un paseo a través del código y los archivos más importantes

OurFirstSpAppWebPart.ts La clase de elemento Web

OurFirstSpAppWebPart.ts define el punto de entrada principal para su Web Part en la que la clase OurFirstSpAppWebPart extiende la clase BaseClientSideWebPart. Cualquier Web Part del lado del cliente se debe extender esta clase.

public constructor(context: IWebPartContext) {  
    super(context);
}

BaseClientSideWebPart implementa la funcionalidad mínima que se requiere para construir una web part. Esta clase también ofrece un montón de parámetros para validar y acceder a las propiedades de sólo lectura, como displayMode, propiedades de elementos web, el contexto, el instanceId del webpart, el DOMElement y mucho más.

Nótese que también estamos definiendo nuestra clase de Web Part para aceptar un tipo de propiedad IOurFirstSpfAppWebPartProps

Las propiedades se definen en una interfaz en un IOurFirstSpfAppWebPartProps.ts

export interface IOurFirstSpfAppWebPartProps {  
  description: string;
}

Esta definición de la propiedad se utiliza para definir los tipos de propiedades personalizados para su web part, lo que vamos a ver en el panel de propiedades.

Parte de Web render ()

El elemento DOM donde la web part se mostrara es en el método render. Este método se utiliza para representar la web part dentro de ese elemento DOM. En nuestra web part OurFirstSpfAppWebPart, se pasa en el DIV para el elemento DOM. Los parámetros del método incluyen el modo de visualización (ya sea de lectura o de edición) y las propiedades de la web part configurados si los hubiere:

import {  
  BaseClientSideWebPart,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField
} from '@microsoft/sp-client-preview';

import styles from './OurFirstSpfWebPart.module.scss';  
import * as strings from 'ourFirstSpfWebPartStrings';  
import { IOurFirstSpfWebPartWebPartProps } from './IOurFirstSpfWebPartWebPartProps';

export default class OurFirstSpfWebPartWebPart extends BaseClientSideWebPart<IOurFirstSpfWebPartWebPartProps> {

  public constructor(context: IWebPartContext) {
    super(context);
  }

public render(): void {  
  this.domElement.innerHTML = `
    <div class="${styles.helloWorld}">
      <div class="${styles.container}">
        <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
          <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
            <span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
            <p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
            <p class="ms-font-l ms-fontColor-white">${this.properties.description}</p>
            <a href="https://github.com/SharePoint/sp-dev-docs/wiki" class="ms-Button ${styles.button}">
              <span class="ms-Button-label">Learn more</span>
            </a>
          </div>
        </div>
    </div>
  </div>`;
}

Analicemos este código, el más importante, como se puede ver que importamos los estilos de un css, pero lo que es más sorprendente de TypeScript es que podemos reemplazar estilos dinámicamente usando variables, como por ejemplo:

${styles.helloWorld}

También aquí se puede ver que podemos utilizar

${this.properties.description}

para utilizar las propiedades del panel de propiedades, pero ¿qué pasa si queremos hacer algo más interesante, lo que yo quiero que se fijen es algo llamado el panel de propiedades reactiva, podemos explicar sobre esto más adelante , pero básicamente lo que se ingrese o seleccione en sus propiedades se refleja inmediatamente en su web part en tiempo real, como llamados servicios web, actualización de valores,etc.

Para el ejemplo, he agregado 2 propiedades en el archivo: IOurFirstSpfWebPartWebPartProps.ts

export interface IOurFirstSpfWebPartWebPartProps {  
  description: string;
  n1: string;
  n2: string;
}

Luego he añadido estas propiedades en el manifest.json

{
  "$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",

  "id": "1ac1bfca-4ac6-4bb8-906e-6715ab383a2b",
  "componentType": "WebPart",
  "version": "0.0.1",
  "manifestVersion": 2,

  "preconfiguredEntries": [{
    "groupId": "1ac1bfca-4ac6-4bb8-906e-6715ab383a2b",
    "group": { "default": "Under Development" },
    "title": { "default": "OurFirstSpfWebPart" },
    "description": { "default": "OurFirstSPFWebPart description" },
    "officeFabricIconFontName": "Page",
    "properties": {
      "description": "OurFirstSpfWebPart",
       "n1": "1",
       "n2": "2"
    }
  }]
}

Y, finalmente, en mi método render he utilizado estos para sumar 2 números.

  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.ourFirstSpfWebPart}">
        <div class="${styles.container}">
          <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
            <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
              <span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
              <p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
              <p class="ms-font-l ms-fontColor-white">${parseInt(this.properties.n1)+parseInt(this.properties.n2)}</p>
              <a href="https://github.com/SharePoint/sp-dev-docs/wiki" class="ms-Button ${styles.button}">
                <span class="ms-Button-label">Learn more</span>
              </a>
            </div>
          </div>
        </div>
      </div>`;
  }

Como puedes ver la sintaxis es muy parecida a Angular donde de alguna manera se enlaza lo que se esta digitando en el panel de propiedades, con lo que queremos que haga nuestro web part.

El resultado final