Ejercicio: Creación de una ACE de tarjeta de imagen SPFx que muestra el carrusel de imagen
En este ejercicio, creará una extensión de tarjeta adaptable (ACE) SharePoint Framework (SPFx) con la plantilla tarjeta de imagen que muestra las imágenes tomadas por una de las cámaras del rover de Marte seleccionado.
Requisitos previos
El desarrollo de ACE para Viva Connections requiere un inquilino de Microsoft 365, SharePoint Online y Viva Connections configurar en el inquilino. Use los siguientes recursos para preparar el inquilino:
- Viva Connections habilitado en el inquilino de Microsoft 365
- SharePoint Framework: Configurar el inquilino de Microsoft 365
También necesita las herramientas de desarrollo necesarias instaladas en la estación de trabajo:
Importante
En la mayoría de los casos, instalar la última versión de las siguientes herramientas es la mejor opción. Las versiones enumeradas aquí fueron usadas la última vez que se publicó y se probó este módulo.
- Node.js - v16.*
- Gulp CLI: v2.3.*
- Yeoman: v4.3.*
- Generador de Yeoman para SharePoint : v1.17.1
- Visual Studio Code
Creación del proyecto SPFx
Abra un símbolo del sistema y muévase a una carpeta donde quiera crear el proyecto SPFx. A continuación, ejecute el generador de Yeoman de SharePoint mediante el comando siguiente:
yo @microsoft/sharepoint
Use lo siguiente para completar el símbolo del sistema que se muestra:
- ¿Cuál es el nombre de la solución?: AceImageViewer
- ¿Qué tipo de componente del lado cliente se va a crear?: Extensión de tarjeta adaptable
- ¿Qué plantilla desea usar?: Plantilla de tarjeta de imagen
- ¿Cuál es el nombre de la extensión de tarjeta adaptable?: AceImageViewer
Después de aprovisionar las carpetas necesarias para el proyecto, el generador instalará todos los paquetes de dependencias ejecutando npm install automáticamente. Cuando NPM complete la descarga de todas las dependencias, abra el proyecto en Visual Studio Code.
Adición de propiedades públicas al componente ACE
El componente ACE que creará en este ejercicio recuperará y mostrará imágenes tomadas por un rover de Marte mediante uno de los puntos de conexión openAPI de la NASA.
Para llamar a la API, tendremos que establecer tres valores:
- Clave de API
- el rover de Marte para recuperar fotos
- el sol de Marte, un día solar en Marte, para recuperar las imágenes de
Todas ellas serán propiedades públicas y configurables para en el componente ACE.
Nota:
Las API abiertas de la NASA admiten el uso de una clave de API de demostración o la creación de una clave de API gratuita. En este ejercicio se supone que usa la clave de demostración.
La clave de demostración tiene límites de velocidad, como el número máximo de solicitudes por dirección IP en una hora y en un día. Si supera los límites de clave de la API de demostración, puede crear una clave vinculada a su dirección de correo electrónico. Para obtener más información, consulte el sitio open API de la NASA.
Para empezar, agregue las propiedades al componente ACE.
Busque la clase ACE en el archivo ./src/adaptiveCardExtensions/aceImageViewer/AceImageViewerAdaptiveCardExtension.ts y ábrala en VS Code.
Busque la
IAceImageViewerAdaptiveCardExtensionProps
interfaz y actualícela para que contenga las siguientes propiedades:export interface IAceImageViewerAdaptiveCardExtensionProps { title: string; nasa_api_key: string; nasa_rover: string; mars_sol: number; }
A continuación, agregue las propiedades al panel de propiedades:
Busque la clase en el archivo ./src/adaptiveCardExtensions/aceImageViewer/AceImageViewerPropertyPane.ts y ábrala en VS Code.
Busque la
import
instrucción que importa elPropertyPaneTextField
método . Agregue una lista alPropertyPaneDropdown
método a estaimport
instrucción.import { IPropertyPaneConfiguration, PropertyPaneTextField, PropertyPaneDropdown // << add } from '@microsoft/sp-property-pane';
Actualice el método existente
getPropertyPaneConfiguration()
para aceptar un único parámetro que especifique el rover seleccionado:public getPropertyPaneConfiguration(selectedRover: string = 'curiosity'): IPropertyPaneConfiguration { .. }
Agregue los campos siguientes a la matriz de
groupFields
en el objeto devuelto en elgetPropertyPaneConfiguration()
método :PropertyPaneTextField('nasa_api_key', { label: 'NASA API key' }), PropertyPaneDropdown('nasa_rover', { label: 'NASA Mars rover', options: [ { index: 0, key: 'curiosity', text: 'Curiosity' }, { index: 1, key: 'opportunity', text: 'Opportunity' }, { index: 2, key: 'spirit', text: 'Spirit' } ], selectedKey: selectedRover }), PropertyPaneTextField('mars_sol', { label: 'Display photos from Mars day (Sol)' })
Vamos a agregar una pequeña mejora al panel de propiedades: el selector desplegable del rover de Marte debe establecerse de forma predeterminada en el rover seleccionado actualmente. La firma del getPropertyPaneConfiguration()
método acepta un parámetro de entrada que se puede usar para establecerlo:
Volver a la
AceImageViewerAdaptiveCardExtension
clase y busque elgetPropertyPaneConfiguration()
método . Reemplace la instrucción existentereturn
por lo siguiente:return this._deferredPropertyPane?.getPropertyPaneConfiguration(this.properties.nasa_rover);
Por último, agregue establecer algunos valores predeterminados para las propiedades cuando se agregue el componente ACE a la página:
Busque la clase ACE en el archivo ./src/adaptiveCardExtensions/aceImageViewer/AceImageViewerAdaptiveCardExtension.manifest.json y ábrala en VS Code.
Agregue las propiedades siguientes a la lista existente de propiedades en el
preconfiguredEntries.properties
objeto :"nasa_api_key": "DEMO_KEY", "nasa_rover": "curiosity", "nasa_sol": 1000
Incorporación del asistente del servicio de API REST de la NASA
Vamos a agregar un servicio al proyecto para controlar toda la lectura de la OPENAPI REST de la NASA.
Cree un nuevo archivo ./src/adaptiveCardExtensions/aceImageViewer/nasa.service.ts en el proyecto y agréguele el código siguiente:
import { AdaptiveCardExtensionContext } from '@microsoft/sp-adaptive-card-extension-base';
import { HttpClient } from '@microsoft/sp-http';
export interface IMarsRoverCamera {
id: number;
name: string;
rover_id: number;
full_name: string;
}
export interface IMarsRoverVehicle {
id: number;
name: string;
landing_date: Date;
launch_date: Date;
status: string;
}
export interface IMarsRoverPhoto {
id: number;
sol: number;
camera: IMarsRoverCamera;
rover: IMarsRoverVehicle;
img_src: string;
earth_date: Date;
}
export const fetchRoverPhotos = async (
spContext: AdaptiveCardExtensionContext,
apiKey: string,
rover: string,
mars_sol: number): Promise<IMarsRoverPhoto[]> => {
const results: { photos: IMarsRoverPhoto[] } = await (
await spContext.httpClient.get(
`https://api.nasa.gov/mars-photos/api/v1/rovers/${rover}/photos?sol=${mars_sol}&page=1&api_key=${apiKey}`,
HttpClient.configurations.v1
)
).json();
return Promise.resolve(results.photos);
}
Actualización del estado del componente ACE
Con las propiedades públicas y el servicio auxiliar creados, ahora vamos a actualizar el estado del componente que se usa para mostrar los datos en el componente.
Busque la clase ACE en el archivo ./src/adaptiveCardExtensions/aceImageViewer/AceImageViewerAdaptiveCardExtension.ts y ábrala en VS Code.
Agregue la siguiente instrucción
import
después de las instruccionesimport
existentes:import { isEmpty } from '@microsoft/sp-lodash-subset' import { fetchRoverPhotos, IMarsRoverPhoto } from './nasa.service';
Busque la
IAceImageViewerAdaptiveCardExtensionState
interfaz y actualícela para que contenga las siguientes propiedades:export interface IAceImageViewerAdaptiveCardExtensionState { currentIndex: number; roverPhotos: IMarsRoverPhoto[]; }
A continuación, actualice el
onInit()
método de laAceImageViewerAdaptiveCardExtension
clase para inicializar estas dos propiedades en valores vacíos:this.state = { currentIndex: 0, roverPhotos: [] };
onInit()
En , agregue el código siguiente para recuperar imágenes de la API de la NASA si se establecen las propiedades mínimas. Esto debe colocarse inmediatamente antes de la existente.return Promise.resolve();
if (!isEmpty(this.properties.nasa_api_key) && !isEmpty(this.properties.nasa_rover) && !isEmpty(this.properties.mars_sol)){ this.setState({ roverPhotos: await fetchRoverPhotos( this.context, this.properties.nasa_api_key, this.properties.nasa_rover, this.properties.mars_sol) }); }
La última instrucción usa la
await
palabra clave , por lo que debe agregar laasync
palabra clave a laonInit()
declaración del método:public async onInit(): Promise<void> {
Vamos a controlar un escenario más: si el usuario cambia el seleccionado nasa_rover
o mars_sol
en el panel de propiedades, queremos actualizar las imágenes en el estado . Para ello, agregue el código siguiente a la AceImageViewerAdaptiveCardExtension
clase . Se ejecutará cuando cambie una propiedad en el panel de propiedades:
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
if (propertyPath === 'nasa_rover' && newValue !== oldValue) {
(async () => {
this.setState({ roverPhotos: await fetchRoverPhotos(
this.context,
this.properties.nasa_api_key,
newValue,
this.properties.mars_sol)
});
})
}
if (propertyPath === 'mars_sol' && newValue !== oldValue) {
(async () => {
this.setState({ roverPhotos: await fetchRoverPhotos(
this.context,
this.properties.nasa_api_key,
this.properties.nasa_rover,
newValue)
});
})
}
}
Actualización de CardView
Ahora que el componente está configurado para obtener fotos de la API REST y almacenarlas en el estado , puede actualizar la representación para mostrar las fotos. Para empezar, actualice CardView.
Busque y abra el archivo ./src/adaptiveCardExtensions/aceImageViewer/cardView/CardView.ts en VS Code.
Agregue una referencia a la
IActionArguments
interfaz importada desde el@microsoft/sp-adaptive-card-extension-base
paquete:import { BaseImageCardView, IImageCardParameters, IExternalLinkCardAction, IQuickViewCardAction, ICardButton, IActionArguments // << add } from '@microsoft/sp-adaptive-card-extension-base';
A continuación, actualice los botones que se muestran en CardView. CardView puede devolver cero, uno o dos botones. Quiere mostrar dos botones, los botones anterior y siguiente, cuando no esté al principio o al final de la colección de fotos. Para agregarlo, reemplace el contenido del método de descriptor de
cardButtons()
acceso por el código siguiente:const cardButtons: ICardButton[] = []; if (this.state.currentIndex !== 0) { cardButtons.push(<ICardButton>{ title: '<', id: '-1', action: { type: 'Submit', parameters: {} } }); } if (this.state.currentIndex !== (this.state.roverPhotos.length - 1)) { cardButtons.push(<ICardButton>{ title: '>', id: '1', action: { type: 'Submit', parameters: {} } }); } return (cardButtons.length === 0) ? undefined : (cardButtons.length === 1) ? [cardButtons[0]] : [cardButtons[0], cardButtons[1]];
A continuación, reemplace el contenido del método de descriptor de
data()
acceso por el código siguiente. Esto devolverá una imagen predeterminada de Marte con algunas instrucciones si no se especifica el rover o mars sol. De lo contrario, mostrará la imagen actual:if (!this.properties.nasa_rover || !this.properties.mars_sol) { return { primaryText: `Select Mars rover and sol to display photos...`, imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Tharsis_and_Valles_Marineris_-_Mars_Orbiter_Mission_%2830055660701%29.png/240px-Tharsis_and_Valles_Marineris_-_Mars_Orbiter_Mission_%2830055660701%29.png', imageAltText: `Select Mars rover and sol to display photos...`, title: this.properties.title } } else { const rover = `${this.properties.nasa_rover.substring(0, 1).toUpperCase()}${this.properties.nasa_rover.substring(1)}`; const roverImage = this.state.roverPhotos[this.state.currentIndex]; if (roverImage) { return { primaryText: `Photos from the Mars rover ${rover} on sol ${this.properties.mars_sol}`, imageUrl: roverImage.img_src, imageAltText: `Image ${roverImage.id} taken on ${roverImage.earth_date} from ${rover}'s ${roverImage.camera.full_name} camera.`, title: this.properties.title }; } else { return { primaryText: `Please refresh the page to reload the rover photos`, imageUrl: '', imageAltText: '', title: this.properties.title } } }
A continuación, reemplace el contenido del método de descriptor de
onCardSelection()
acceso por el código siguiente. Esto abrirá nuestro QuickView, que actualizará en un momento, cuando se seleccione la tarjeta.return { type: 'QuickView', parameters: { view: QUICK_VIEW_REGISTRY_ID } };
A continuación, implemente el
onAction()
método agregando el código siguiente a laCardView
clase . Esto se ejecutará cada vez que se produzca una acción de envío en la implementación de CardView. Recuerdos en elcardButtons()
método , establezca laid
propiedad de los botones en un número positivo o negativo para navegar por la matriz de imágenes:public onAction(action: IActionArguments): void { if (action.type !== 'Submit') { return; } let currentIndex = this.state.currentIndex; this.setState({ currentIndex: currentIndex + Number(action.id) }); }
Por último, comente o quite la siguiente referencia al
strings
objeto:import * as strings from 'AceImageViewerAdaptiveCardExtensionStrings';
Actualización de QuickView
El último paso antes de probar el componente ACE es actualizar QuickView. En este escenario, quickview mostrará más detalles sobre la foto actual.
Busque y abra el archivo ./src/adaptiveCardExtensions/aceImageViewer/quickView/QuickView.ts en VS Code.
Agregue la siguiente
import
instrucción a las importaciones existentes:import { IMarsRoverPhoto } from '../nasa.service';
Quite la interfaz existente
IQuickViewData
.Reemplace todas las referencias restantes a
IQuickViewData
en laQuickView
clase porIMarsRoverPhoto
.Reemplace el contenido del
data()
método de descriptor de acceso por lo siguiente:return this.state.roverPhotos[this.state.currentIndex];
Por último, comente o quite la siguiente referencia al
strings
objeto:import * as strings from 'AceImageViewerAdaptiveCardExtensionStrings';
Ahora, actualice la plantilla tarjeta adaptable:
Busque y abra el archivo ./src/adaptiveCardExtensions/aceImageViewer/quickView/template/QuickViewTemplate.json en VS Code.
Reemplace el contenido de la plantilla por el código siguiente:
{ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "type": "AdaptiveCard", "body": [ { "type": "Image", "url": "${img_src}" }, { "type": "TextBlock", "text": "${rover.name} rover image #${id}", "horizontalAlignment": "Center" }, { "type": "TextBlock", "text": "Photo Details", "spacing": "Medium", "separator": true, "size": "Large", "weight": "Bolder" }, { "type": "FactSet", "facts": [ { "title": "Rover:", "value": "${rover.name}" }, { "title": "Camera:", "value": "${camera.full_name}" }, { "title": "Date taken:", "value": "${earth_date} (sol ${sol})" } ] } ] }
Prueba de la ACE dinámica
Vamos a probar la ACE para ver nuestro explorador de imágenes.
En la consola, ejecute la siguiente instrucción:
gulp serve --nobrowser
En un explorador, vaya al área de trabajo hospedada de SharePoint en el sitio donde desea probar la ACE. Por ejemplo, si la dirección URL del sitio es https://contoso.sharepoint.com/sites/MSLearningTeam
, la dirección URL del área de trabajo hospedada es https://contoso.sharepoint.com/sites/MSLearningTeam/_layouts/15/workbench.aspx
.
Seleccione el + icono y, a continuación, seleccione AceImageViewer en el cuadro de herramientas:
Observe que la experiencia predeterminada del componente es usar la imagen de Marte. Eso se debe a que no tenemos un sol de Marte establecido:
Al igual que un elemento web SPFx, puede mantener el mouse sobre el componente ACE y seleccionar el icono de lápiz para abrir el panel de propiedades:
Establezca mars sol en 1000 y cierre el panel de propiedades seleccionando la X en la esquina superior derecha y, a continuación, seleccione el vínculo Vista previa en la esquina superior derecha de la navegación superior de la página para poner la página en modo de presentación.
Use los botones proporcionados en CardView para desplazarse por las imágenes. Se muestra una versión recortada de la imagen en cardview de la tarjeta de imagen.
Con el mouse, seleccione en cualquier lugar de la tarjeta, sin seleccionar ninguno de los botones. QuickView mostrará la foto sin recorte con más detalles sobre cuándo se tomó:
En este ejercicio, ha creado una extensión de tarjeta adaptable (ACE) SharePoint Framework (SPFx) con la plantilla tarjeta de imagen que muestra imágenes tomadas por una de las cámaras del rover de Marte seleccionado.