Ejercicio: Creación de una ACE de SPFx con funcionalidades de ubicación geográfica
En este ejercicio, creará una extensión de tarjeta adaptable (ACE) de SharePoint Framework (SPFx) con la plantilla tarjeta de texto principal que usa las funcionalidades de ubicación geográfica en Conexiones Viva.
El escenario que implementará es una versión simplificada de un servicio de traslado de campus que una gran universidad o empresa tiene para ayudar a los empleados y visitantes a llegar entre edificios. El ACE es para el buceador de un transbordador. El conductor usará la ACE para reservar un viaje e indicar que está en camino de recoger a un pasajero o entregar a un pasajero a su destino.
Requisitos previos
El desarrollo de ACE para conexiones Viva requiere un inquilino de Microsoft 365, SharePoint Online y Conexiones Viva configurados en el inquilino. Use los siguientes recursos para preparar el inquilino:
- Conexiones Viva habilitadas en el inquilino de Microsoft 365
- SharePoint Framework: configuración del 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 de una lista de SharePoint para almacenar los datos
El primer paso consiste en crear una nueva lista de SharePoint para almacenar los datos de cada conductor de lanzadera del campus.
En un explorador, vaya al sitio de SharePoint donde desea probar el proyecto que creará en este ejercicio.
Seleccione New (Nuevo ) y, a continuación, List (Lista ) en las opciones disponibles:
En el cuadro de diálogo Crear una lista , seleccione Lista en blanco.
Establezca el nombre de la lista en Campus Shuttle y seleccione Crear.
Cuando el explorador se actualice para mostrar la nueva lista, agregue algunas columnas a la lista. Seleccione Agregar columna, Texto y, a continuación, haga clic en el botón Siguiente . En el panel Crear una columna , escriba los valores siguientes y seleccione Guardar:
- Nombre: OriginLocation
- Tipo: línea única de texto
Repita este proceso con los siguientes valores para agregar algunas columnas más a la lista:
- Columna:
- Nombre: DestinationName
- Tipo: línea única de texto
- Columna:
- Nombre: DestinationLocation
- Tipo: línea única de texto
- Columna:
- Nombre: Estado
- Tipo: Elección
-
Opciones:
- Contratado
- en route
- disponible
Con la lista para almacenar los datos de nuestra ACE, ahora podemos crear el proyecto.
Creación y preparación del proyecto de 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?: AceCampusShuttle
- ¿Qué tipo de componente del lado cliente se va a crear?: Extensión de tarjeta adaptable
- ¿Qué plantilla desea usar?: Plantilla de texto principal
- ¿Cuál es el nombre de la extensión de tarjeta adaptable?: Campus Shuttle
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 datos de ejemplo
La ACE que creará dará al controlador de transporte la opción de seleccionar un destino de una lista de ubicaciones conocidas o seleccionar un punto en un mapa.
Cree un archivo ./src/adaptiveCardExtensions/campusShuttle/assets/campus_locations.json en el proyecto y agregue una matriz para objetos de ubicación. Cada ubicación debe tener una propiedad name, latitude y longitud . O bien, puede pegar el siguiente JSON en el archivo que contiene algunas ubicaciones de la Universidad de Florida en Gainesville, Florida, Estados Unidos.
[
{ "title": "UF: Reitz Student Union", "latitude": 29.6463258, "longitude": -82.3499756 },
{ "title": "UF: The Hub", "latitude": 29.648018, "longitude": -82.345664 },
{ "title": "UF: Department of Computer and Information Science and Engineering", "latitude": 29.6476101, "longitude": -82.3466208 },
{ "title": "UF: Materials Science and Engineering", "latitude": 29.6476101, "longitude": -82.3466208 },
{ "title": "UF: Turlington Hall", "latitude": 29.6476101, "longitude": -82.3466208 },
{ "title": "UF: McCarty Hall A", "latitude": 29.6476101, "longitude": -82.3466208 },
{ "title": "UF: Peabody Hall", "latitude": 29.6502915, "longitude": -82.3433807 },
{ "title": "UF: Norman Hall", "latitude": 29.6486165, "longitude": -82.3398393 },
{ "title": "UF: Warrington College of Business", "latitude": 29.65093, "longitude": -82.3402091 },
{ "title": "UF: Mechanical and Aerospace Engineering Building A", "latitude": 29.6436917, "longitude": -82.3478054 },
{ "title": "UF: New Physics Building (NPB)", "latitude": 29.6439734, "longitude": -82.3506927 },
{ "title": "UF: Murphree Hall", "latitude": 29.6508923, "longitude": -82.3480633 }
]
Adición del asistente del servicio de API REST de SharePoint
A continuación, vamos a agregar un servicio REST de SharePoint al proyecto para controlar toda la lectura y escritura en la lista de SharePoint que creó para almacenar los datos del controlador de transporte.
Cree un nuevo archivo ./src/adaptiveCardExtensions/campusShuttle/sp.service.ts en el proyecto y agréguele el código siguiente:
import { AdaptiveCardExtensionContext } from '@microsoft/sp-adaptive-card-extension-base';
import { SPHttpClient } from '@microsoft/sp-http'
export const STATUS_HIRED = 'hired';
export const STATUS_ENROUTE = 'en route';
export const STATUS_AVAILABLE = 'available';
export interface ILocation {
latitude: number;
longitude: number;
}
export interface IListItem {
['@odata.type']?: string;
Id?: string;
Title: string;
Status: string;
OriginLocation?: string | ILocation;
DestinationName?: string;
DestinationLocation?: string | ILocation;
}
export const fetchListItem = async (spContext: AdaptiveCardExtensionContext, listId: string): Promise<IListItem> => {
if (!listId) { return Promise.reject('No listId specified.'); }
const listApiUrl = `${spContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById(id='${listId}')`;
const user = spContext.pageContext.user.loginName;
const response: { value: IListItem[] } = await (await spContext.spHttpClient.get(
`${listApiUrl}/items/?$select=Id,Title,Status,OriginLocation,DestinationName,DestinationLocation&$filter=Title eq '${user}'&$top=1`,
SPHttpClient.configurations.v1
)).json();
if (response.value.length === 0) { return Promise.resolve(undefined); }
const convertedTrip = response.value[0];
if (convertedTrip) {
const origin = convertedTrip.OriginLocation as string;
convertedTrip.OriginLocation = <ILocation>{
latitude: Number(origin.split(',')[0]),
longitude: Number(origin.split(',')[1])
};
}
if (convertedTrip) {
const destination = convertedTrip.DestinationLocation as string;
convertedTrip.DestinationLocation = <ILocation>{
latitude: Number(destination.split(',')[0]),
longitude: Number(destination.split(',')[1])
};
}
return Promise.resolve(convertedTrip);
}
const getItemEntityType = async (spContext: AdaptiveCardExtensionContext, listApiUrl: string): Promise<string> => {
const response: { ListItemEntityTypeFullName: string } = await (await spContext.spHttpClient.get(
`${listApiUrl}?$select=ListItemEntityTypeFullName`,
SPHttpClient.configurations.v1
)).json();
return response.ListItemEntityTypeFullName;
}
const createListItem = async (
spContext: AdaptiveCardExtensionContext,
listApiUrl: string,
listItem: IListItem): Promise<void> => {
listItem['@odata.type'] = await getItemEntityType(spContext, listApiUrl);
await spContext.spHttpClient.post(
`${listApiUrl}/items`,
SPHttpClient.configurations.v1,
{
headers: {
'ACCEPT': 'application/json; odata.metadata=none',
'CONTENT-TYPE': 'application/json'
},
body: JSON.stringify(listItem)
}
);
return Promise.resolve();
}
export const upsertListItem = async (spContext: AdaptiveCardExtensionContext, listId: string, listItem: IListItem): Promise<void> => {
if (!listId) { return Promise.reject('No listId specified.'); }
const listApiUrl = `${spContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById(id='${listId}')`;
const originLocationObj = (listItem.OriginLocation as ILocation);
listItem.OriginLocation = `${originLocationObj.latitude},${originLocationObj.longitude}`;
const destinationLocationObj = (listItem.DestinationLocation as ILocation);
listItem.DestinationLocation = `${destinationLocationObj.latitude},${destinationLocationObj.longitude}`;
if (!listItem['@odata.type']) { return createListItem(spContext, listApiUrl, listItem); }
await spContext.spHttpClient.post(
`${listApiUrl}/items(${listItem.Id})`,
SPHttpClient.configurations.v1,
{
headers: { 'IF-MATCH': '*', 'X-HTTP-METHOD': 'MERGE' },
body: JSON.stringify(<IListItem>{
Title: listItem.Title,
Status: listItem.Status,
OriginLocation: listItem.OriginLocation,
DestinationName: listItem.DestinationName,
DestinationLocation: listItem.DestinationLocation
})
}
);
return Promise.resolve();
}
export const deleteListItem = async (spContext: AdaptiveCardExtensionContext, listId: string, listItemId: number): Promise<void> => {
if (!listId) { return Promise.reject('No listId specified.'); }
if (!listItemId) { return Promise.reject('No listItemId specified.'); }
const listApiUrl = `${spContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById(id='${listId}')`;
await spContext.spHttpClient.post(
`${listApiUrl}/items(${listItemId})`,
SPHttpClient.configurations.v1,
{
headers: { 'IF-MATCH': '*', 'X-HTTP-METHOD': 'DELETE' }
}
);
}
Este servicio exporta los siguientes elementos que usará en todo el proyecto:
- Tres constantes () para las opciones de estado:
STATUS_AVAILABLE
STATUS_ENROUTE
STATUS_HIRED
-
fetchListItem()
: este método recupera el registro del controlador que ha iniciado sesión actualmente (si está presente). -
upsertListItem()
: este método crea o actualiza un registro de controlador existente. -
deleteListItem()
: este método elimina un registro de controlador cuando están más tiempo en un viaje.
Inicializar el proyecto
Ahora que el proyecto tiene algunas dependencias principales agregadas, ahora vamos a implementar la inicialización de algunas características principales cuando la ACE se cargue por primera vez en la página. Esto implica configurar el estado de la ACE y permitir que el usuario establezca el identificador de la lista que contiene los detalles del viaje del controlador.
Actualice la ACE para permitir que el usuario establezca el identificador de lista de SharePoint.
Busque la clase ACE en el archivo ./src/adaptiveCardExtensions/campusShuttle/CampusShuttleAdaptiveCardExtension.ts y ábrala en VS Code.
Busque la ICampusShuttleAdaptiveCardExtensionProps
interfaz y agregue la listId
propiedad para almacenar el identificador de la lista de SharePoint que contiene los registros de estado del controlador:
export interface ICampusShuttleAdaptiveCardExtensionProps {
title: string;
listId: string;
}
Busque y abra el archivo ./src/adaptiveCardExtensions/campusShuttle/CampusShuttlePropertyPane.ts. Agregue una nueva PropertyPaneTextField
a la groupFields
matriz para agregar una opción para que el usuario establezca el identificador de la lista que contiene los registros de estado del controlador:
groupFields: [
PropertyPaneTextField('title', {
label: strings.TitleFieldLabel
}),
PropertyPaneTextField('listId', {
label: 'List ID (GUID)'
})
]
Por último, vuelva al archivo CampusShuttleAdaptiveCardExtension.ts y agregue el siguiente método a la CampusShuttleAdaptiveCardExtension
clase . El tiempo de ejecución de SPFx genera este evento cuando cambia el valor de una propiedad en el panel de propiedades. Queremos que nuestra ACE use un cambio en el identificador de la lista para intentar inicializar el estado de la ACE si se encuentra un registro de controlador:
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
if (propertyPath === 'listId' && newValue !== oldValue) {
if (newValue) {
(async () => {
const trip = await fetchListItem(this.context, this.properties.listId);
if (trip) { this.setState({ currentTrip: trip }); }
})();
}
}
}
Actualización del estado de ACE y la vista de tarjeta inicial
Agregue la siguiente import
instrucción después de las instrucciones existentes import
en el archivo:
import {
IListItem,
fetchListItem,
STATUS_AVAILABLE
} from './sp.service';
Busque la interfaz ICampusShuttleAdaptiveCardExtensionState
de estado y agregue la propiedad currentTrip
como se muestra en el código siguiente:
export interface ICampusShuttleAdaptiveCardExtensionState {
currentTrip: IListItem;
}
Inicialice la propiedad state en el método existente onInit()
. Reemplace el existente this.state = { };
por el código siguiente para establecer el estado como un recorrido de marcador de posición para el controlador actual:
this.state = {
currentTrip: {
Title: this.context.pageContext.user.loginName,
Status: STATUS_AVAILABLE
}
};
A continuación, agregue el código siguiente al onInit()
método , inmediatamente antes de la return Promise.resolve();
instrucción para recuperar el registro de viaje del controlador actual de la lista de SharePoint. Si se encuentra un viaje coincidente, actualiza el estado de la ACE a este viaje, sobrescribiendo el viaje predeterminado vacío que creó al inicializar el estado.
if (this.properties.listId) {
const trip = await fetchListItem(this.context, this.properties.listId);
if (trip) { this.setState({ currentTrip: trip }); }
}
Este código usa la await
palabra clave pero la firma del onInit()
método, mientras devuelve un Promise
, no tiene la palabra clave necesaria async
. Actualice la declaración del onInit()
método para incluir esta palabra clave:
public async onInit(): Promise<void> { .. }
Quite el control QuickView existente y actualice el CardView inicial.
El último paso antes de probar nuestra ACE es quitar la vista rápida actual. Más adelante, agregaremos varias vistas rápidas nuevas a la ACE.
Para empezar, quite las siguientes líneas del archivo CampusShuttleAdaptiveCardExtension.ts :
Quite la siguiente
import
instrucción:import { QuickView } from './quickView/QuickView';
Quite la
export
declaración del identificador de QuickView:export const QUICK_VIEW_REGISTRY_ID: string = 'CampusShuttle_QUICK_VIEW';
En el método de
onInit()
laCampusShuttleAdaptiveCardExtension
clase , quite la siguiente instrucción que registra QuickView:this.quickViewNavigator.register(QUICK_VIEW_REGISTRY_ID, () => new QuickView());
Elimine los siguientes archivos del proyecto:
- ./src/adaptiveCardExtensions/campusShuttle/quickView/template/QuickViewTemplate.json
- ./src/adaptiveCardExtensions/campusShuttle/quickView/QuickView.ts
A continuación, busque y abra CardView: ./src/adaptiveCardExtensions/campusShuttle/cardView/CardView.ts y realice los siguientes cambios en él:
Busque la instrucción existente
import
que hace referencia a valores del@microsoft/sp-adaptive-card-extension-base
paquete y quite las siguientes referencias:- IExternalLinkCardAction
- IQuickViewCardAction
Busque la instrucción existente
import
que hace referencia a valores delCampusShuttleAdaptiveCardExtension
módulo y quite la referencia a laQUICK_VIEW_REGISTRY_ID
constante.Agregue la siguiente instrucción
import
después de las instruccionesimport
existentes:import { STATUS_AVAILABLE } from '../sp.service';
Reemplace el contenido del miembro del
cardButtons()
descriptor de acceso por la instrucción siguienteswitch
. Actualizará esta instrucción switch a lo largo de este ejercicio a medida que agregue nueva funcionalidad a la ACE:
public get cardButtons(): [ICardButton] | [ICardButton, ICardButton] | undefined {
switch (this.state.currentTrip.Status) {
default:
return undefined;
break;
}
}
- Actualice el miembro del
data()
descriptor de acceso para devolver las propiedades que se usarán para la tarjeta actual:
public get data(): IPrimaryTextCardParameters {
return {
primaryText: strings.PrimaryText,
description: (this.state.currentTrip.Status === STATUS_AVAILABLE)
? `available for hire`
: `TODO`,
title: this.properties.title
};
}
- Quite el miembro de descriptor de acceso existente
onCardSelection()
porque cardview ya no tiene botones.
Prueba de la ACE
Ahora está listo para probar el estado inicial de nuestra ACE.
En la consola, ejecute la siguiente instrucción:
gulp serve --nobrowser
En un explorador, vaya al área de trabajo hospedada de SharePoint en el mismo sitio donde creó la lista para almacenar registros de controladores. Por ejemplo, si la dirección URL de lista es https://contoso.sharepoint.com/sites/MSLearningTeam/Lists/Campus%20Shuttle/AllItems.aspx
, 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 Campus Shuttle en el cuadro de herramientas:
Mantenga el mouse sobre el componente ACE y seleccione el icono de lápiz para abrir el panel de propiedades:
Escriba el identificador de la lista de SharePoint en el cuadro de texto Id . de lista y cierre el panel de propiedades seleccionando el icono X en la esquina superior derecha.
Sugerencia
Puede obtener el identificador de una lista en la dirección URL de la página de configuración de la lista.
En primer lugar, vaya a la lista y, a continuación, seleccione el icono de engranaje en la barra de conjuntos de aplicaciones y, a continuación, seleccione el vínculo Configuración de lista.
La cadena de consulta de la página de configuración de lista contiene una propiedad List , como List=%7B93f11b8b-6201-4199-b263-3ca78408a73b%7D
. Se trata de una cadena codificada en dirección URL que contiene GUID rodeado por {}
. Quite el %7B
prefijo y %7D
el sufijo para obtener el identificador de la lista. Por ejemplo, este identificador de lista es 93f11b8b-6201-4199-b263-3ca78408a73b
.
No observará ningún cambio en la representación de la ACE porque todavía no hay ningún registro en la lista.
En este momento, el proyecto mínimo está funcionando. Puede empezar a agregar interactividad a la ACE con QuickViews.
Agregar capacidad para crear viajes con QuickViews
Ahora implementará la funcionalidad para permitir que el usuario actual agregue un nuevo viaje mediante la ACE. Cuando crean un viaje, tienen tres cosas que deben establecer:
- ubicación de origen/inicio para el viaje
- ubicación de destino para el viaje
- si el conductor del transbordador está en ruta para recoger a un pasajero de la ubicación de origen, o si ha recogido al pasajero y en el camino hacia el destino
Para implementar esto, creará varias vistas rápidas y usará la funcionalidad de ubicación geográfica de las ACE en Conexiones Viva.
Creación de StartTrip QuickView
Empiece por crear un nuevo archivo StartTripCard.json en la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template y agregue el siguiente JSON. Esto establece el contenido de QuickView mediante una tarjeta adaptable.
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Start a trip",
"size": "Large",
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": "Select trip status:",
"size": "medium",
"weight": "Bolder"
},
{
"id": "tripType",
"type": "Input.ChoiceSet",
"value": "$trip.Status",
"choices": [
{
"title": "en route to pickup",
"value": "en route"
},
{
"title": "starting trip",
"value": "hired"
}
]
},
{
"type": "TextBlock",
"text": "Set trip details:",
"size": "medium",
"weight": "Bolder"
}
],
"actions": [
{
"id": "originLocation",
"type": "Action.Submit",
"title": "(1) Select trip origin from map"
},
{
"id": "destinationLocation",
"type": "Action.Submit",
"title": "(2) Select / set trip destination"
},
{
"id": "save",
"type": "Action.Submit",
"title": "Save trip",
"style": "positive"
}
]
}
A continuación, cree el archivo StartTrip.ts en la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView . Este archivo contendrá la clase que implementa QuickView.
Agregue el siguiente código al archivo:
import {
ISPFxAdaptiveCard,
BaseAdaptiveCardView,
IActionArguments
} from '@microsoft/sp-adaptive-card-extension-base';
import * as strings from 'CampusShuttleAdaptiveCardExtensionStrings';
import {
ICampusShuttleAdaptiveCardExtensionProps,
ICampusShuttleAdaptiveCardExtensionState
} from '../CampusShuttleAdaptiveCardExtension';
import { IListItem, upsertListItem } from '../sp.service';
export interface IStartTripData {
title: string;
trip: IListItem;
}
export class StartTrip extends BaseAdaptiveCardView<
ICampusShuttleAdaptiveCardExtensionProps,
ICampusShuttleAdaptiveCardExtensionState,
IStartTripData
> {
public get data(): IStartTripData {
return {
title: strings.Title,
trip: this.state.currentTrip
};
}
public get template(): ISPFxAdaptiveCard {
return require('./template/StartTripCard.json');
}
public onAction(action: IActionArguments): void {
if (action.type === 'Submit') {
if (action.data.tripType) {
const trip = this.state.currentTrip;
trip.Status = action.data.tripType;
this.setState({ currentTrip: trip });
}
if (action.id === 'originLocation') {
// TODO QuickView originLocation
} else if (action.id === 'destinationLocation') {
// TODO QuickView destinationLocation
} else if (action.id === 'save') {
(async () => {
await upsertListItem(this.context, this.properties.listId, this.state.currentTrip);
// TODO QuickView save
})();
}
}
}
}
La StartTrip
clase de este archivo contiene tres miembros:
-
data()
: este miembro de descriptor de acceso devuelve un objeto al motor de representación de tarjeta adaptable que se usará para enlazar propiedades a la tarjeta adaptable que se usa para implementar QuickView. -
template()
: este miembro de descriptor de acceso devuelve un objeto JSON que contiene la definición de tarjeta adaptable. -
onAction()
: se llama a este método cuando se producen ciertas acciones en la tarjeta adaptable. En este punto, el código simplemente guarda el valor del tipo de viaje (en la ruta | contratada) y contiene los marcadores de posición para más tarjetas de QuickView que agregará al proyecto.
Para simplificar la referencia a las vistas rápidas que contendrá el proyecto, agregue un nuevo archivo index.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
export * from './StartTrip';
Registro y referencia a StartTrip QuickView
Para usar este nuevo QuickView, debe registrarlo con el navegador QuickView de ACE. Abra el archivo ./src/adaptiveCardExtensions/campusShuttle/CampusShuttleAdaptiveCardExtension.ts .
Agregue la siguiente import
instrucción después de las instrucciones de importación existentes para importar la nueva vista rápida que creó:
import {
StartTrip
} from './quickView';
Busque la constante inmediatamente antes de la declaración de clase CampusShuttleAdaptiveCardExtension
y agregue la siguiente declaración:
export const QUICK_VIEW_START_TRIP_REGISTRY_ID: string = 'CampusShuttle_StartTrip_QUICK_VIEW';
A continuación, en CampusShuttleAdaptiveCardExtension
el método de onInit()
clase , busque la línea siguiente:
this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView());
Agregue la línea siguiente para registrar starttrip QuickView con el navegador QuickView.
this.quickViewNavigator.register(QUICK_VIEW_START_TRIP_REGISTRY_ID, () => new StartTrip());
Adición de StartTrip QuickView a CardView
El último paso es agregar QuickView a nuestro CardView para usarlo. Busque y abra el archivo siguiente en VS Code: ./src/adaptiveCardExtensions/campusShuttle/cardView/CardView.ts
Busque la import
instrucción que importa la propiedad y la interfaz de estado del archivo que contiene la declaración de clase ACE. Agregue la constante que agregó que contiene el identificador de StartTrip QuickView:
import {
ICampusShuttleAdaptiveCardExtensionProps,
ICampusShuttleAdaptiveCardExtensionState,
QUICK_VIEW_START_TRIP_REGISTRY_ID // << add this
} from '../CampusShuttleAdaptiveCardExtension';
A continuación, en la cardButtons()
instrucción del descriptor de switch
acceso, agregue case
la instrucción antes de la existente default
para mostrar un botón para reservar un viaje cuando el estado del controlador actual esté disponible:
switch (this.state.currentTrip.Status) {
case STATUS_AVAILABLE:
return [{
title: 'Book a Trip',
action: {
type: 'QuickView',
parameters: { view: QUICK_VIEW_START_TRIP_REGISTRY_ID }
}
}];
break;
default:
return undefined;
break;
}
Pruebe la ACE para comprobar que QuickView funciona. Si anteriormente detuvo el servidor web local, reinícielo ejecutando lo siguiente en la consola:
gulp serve --nobrowser
Vaya al área de trabajo hospedada de SharePoint para ver campus shuttle ACE:
Observe el botón Reservar un viaje en CardView. Pruébelo seleccionando el vínculo Vista previa en la sección superior derecha de la navegación superior. Esta página cambiará del modo de edición al modo de visualización, donde puede seleccionar el botón:
Ahora vamos a implementar la funcionalidad de StartTrip QuickView.
Adición de funcionalidad a StartTrip QuickView
Ahora agregará tres Vistas rápidas que usará StartTrip QuickView. Uno controla la configuración de la ubicación de origen del viaje, otro controla la selección o configuración del destino del viaje y el último actúa como aviso de confirmación al guardar el viaje.
Agregue un nuevo archivo SetOriginCard.json a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template con el código siguiente:
{ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.5", "body": [ { "type": "TextBlock", "weight": "Bolder", "size": "large", "text": "${title}" }, { "type": "TextBlock", "text": "${description}", "wrap": true } ], "actions": [ { "id": "originLocation", "type": "VivaAction.GetLocation", "title": "Select location on the map", "parameters": { "chooseLocationOnMap": true } } ] }
Observe que la acción única de esta tarjeta adaptable se establece en el tipo VivaAction.GetLocation. Esto pedirá al usuario que seleccione una ubicación de su dispositivo y devuelva las coordenadas.
Implemente SetOrigin QuickView agregando un nuevo archivo SetOrigin.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
import { ISPFxAdaptiveCard, BaseAdaptiveCardView, IGetLocationActionArguments } from '@microsoft/sp-adaptive-card-extension-base'; import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState } from '../CampusShuttleAdaptiveCardExtension'; import { ILocation, IListItem } from '../sp.service'; export interface ISetOriginData { title: string; description: string; trip: IListItem; } export class SetOrigin extends BaseAdaptiveCardView< ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, ISetOriginData > { public get data(): ISetOriginData { return { title: 'Set trip starting location', description: 'Select the trip origin location by selecting it on the map.', trip: this.state.currentTrip }; } public get template(): ISPFxAdaptiveCard { return require('./template/SetOriginCard.json'); } public onAction(action: IGetLocationActionArguments): void { if (action.type === 'VivaAction.GetLocation'){ const currentTrip = this.state.currentTrip; currentTrip.OriginLocation = <ILocation> { latitude: action.location.latitude, longitude: action.location.longitude }; this.setState({ currentTrip: currentTrip }); this.quickViewNavigator.pop(); } } }
Observe cómo este código, dentro del
onAction()
controlador de eventos, obtiene la ubicación seleccionada cuando la tarjeta adaptable envía VivaAction.GetLocation . Establece la ubicación seleccionada en el viaje y actualiza el objeto de viaje en el estado de la ACE. La última llamada athis.quickViewNavigator.pop()
quita esta vista rápida de la pila de QuickView, lo que desencadena una nueva representación de la siguiente vista rápida en la pila.
Ahora implemente una vista rápida similar para establecer la ubicación de destino:
Agregue un nuevo archivo SetDestinationCard.json a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template con el código siguiente:
{ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.5", "body": [ { "type": "TextBlock", "weight": "Bolder", "text": "${title}" }, { "type": "TextBlock", "text": "${description}" }, { "type": "TextBlock", "text": "Select a known location..." }, { "id": "knownDestinationSelection", "type": "Input.ChoiceSet", "choices": [ { "$data": "${campus_locations}", "title": "${title}", "value": "${latitude},${longitude}" } ] }, { "type": "TextBlock", "text": "... or select a specific location on the map:" } ], "actions": [ { "id": "destinationLocation", "type": "VivaAction.GetLocation", "title": "Select trip destination from map", "parameters": { "chooseLocationOnMap": true } }, { "id": "save", "type": "Action.Submit", "title": "Save destination location", "style": "positive" } ] }
Esta tarjeta adaptable es similar a la que se usa en la ubicación de origen de la manera en que permite al usuario seleccionar una ubicación en el mapa o seleccionar una lista de ubicaciones predefinidas. Estas ubicaciones predefinidas se encuentran en el archivo ./src/adaptiveCardExtensions/campusShuttle/assets/campus_locations.json .
La tarjeta adaptable también contiene otro botón de acción de envío. A diferencia de QuickView de origen establecido, este botón se usará para cerrar la vista rápida de destino establecida, ya que el usuario tiene dos opciones para seleccionar un destino de viaje.
Implemente SetDestination QuickView agregando un nuevo archivo SetDestination.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
import { ISPFxAdaptiveCard, BaseAdaptiveCardView, IActionArguments, IGetLocationActionArguments } from '@microsoft/sp-adaptive-card-extension-base'; import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState } from '../CampusShuttleAdaptiveCardExtension'; import { ILocation, IListItem } from '../sp.service'; import { sortBy } from '@microsoft/sp-lodash-subset'; interface ICampusLocations { title: string; latitude: number; longitude: number; } export interface ISetDestinationData { title: string; description: string; campus_locations: ICampusLocations[]; trip: IListItem; } const LOCATIONS = require('../assets/campus_locations.json'); export class SetDestination extends BaseAdaptiveCardView< ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, ISetDestinationData > { public get data(): ISetDestinationData { return { title: 'Set trip destination location', description: 'Pick from a list of known locations, or set the destination by selecting it on the map.', campus_locations: sortBy(LOCATIONS, (l) => l.title), trip: this.state.currentTrip }; } public get template(): ISPFxAdaptiveCard { return require('./template/SetDestinationCard.json'); } public onAction(action: IActionArguments | IGetLocationActionArguments): void { const currentTrip = this.state.currentTrip; // if picked a location on the map... if (action.type === 'VivaAction.GetLocation') { currentTrip.DestinationLocation = <ILocation>{ latitude: action.location.latitude, longitude: action.location.longitude }; this.setState({ currentTrip: currentTrip }); } else if (action.type === 'Submit' && action.id === 'save') { // else, check if picked location from dropdown and save it if (action.data.knownDestinationSelection) { currentTrip.DestinationLocation = <ILocation>{ latitude: Number(action.data.knownDestinationSelection.split(',')[0]), longitude: Number(action.data.knownDestinationSelection.split(',')[1]) }; const selectedLocation = LOCATIONS.filter((knownLocation: any) => ( knownLocation.latitude === (currentTrip.DestinationLocation as ILocation).latitude && knownLocation.longitude === (currentTrip.DestinationLocation as ILocation).longitude ))[0]; currentTrip.DestinationName = selectedLocation.title; } this.setState({ currentTrip: currentTrip }); this.quickViewNavigator.pop(); } } }
El último paso es agregar una vista rápida de confirmación de guardado al proyecto:
Agregue un nuevo archivo SaveTripCard.json a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template con el código siguiente:
{ "schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.5", "body": [{ "type": "TextBlock", "text": "${title}" }], "actions": [{ "type": "Action.Submit", "id": "close", "title": "Close" }] }
Implemente SaveTrip QuickView agregando un nuevo archivo SaveTrip.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
import { BaseAdaptiveCardView, IActionArguments, ISPFxAdaptiveCard } from '@microsoft/sp-adaptive-card-extension-base'; import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState } from '../CampusShuttleAdaptiveCardExtension'; export interface ISaveTripData { title: string; } export class SaveTrip extends BaseAdaptiveCardView< ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, ISaveTripData > { public get data(): ISaveTripData { return { title: 'Trip saved successfully.' }; } public get template(): ISPFxAdaptiveCard { return require('./template/SaveTripCard.json'); } public onAction(action: IActionArguments): void { if (action.id === 'close') { this.quickViewNavigator.close(); } } }
Para usar estas tres vistas rápidas nuevas, debe registrarlas:
Abra el archivo ./src/adaptiveCardExtensions/campusShuttle/quickView/index.ts y exporte las nuevas vistas rápidas:
export * from './StartTrip'; export * from './SetOrigin'; // << add export * from './SetDestination'; // << add export * from './SaveTrip'; // << add
Abra el archivo ./src/adaptiveCardExtensions/campusShuttle/CampusShuttleAdaptiveCardExtension.ts .
Actualice la instrucción existente
import
que agregó para importar starttrip QuickView para hacer referencia a las tres vistas rápidas nuevas:import { StartTrip, SetOrigin, SetDestination, SaveTrip } from './quickView';
Busque las constantes que declaran los identificadores de CardView y QuickView y agregue los siguientes identificadores para las nuevas vistas rápidas:
export const QUICK_VIEW_SET_ORIGIN_REGISTRY_ID: string = 'CampusShuttle_SetOrigin_QUICK_VIEW'; export const QUICK_VIEW_SET_DESTINATION_REGISTRY_ID: string = 'CampusShuttle_SetDestination_QUICK_VIEW'; export const QUICK_VIEW_SAVE_TRIP_REGISTRY_ID: string = 'CampusShuttle_SaveTrip_QUICK_VIEW';
En el
onInit()
método de laCampusShuttleAdaptiveCardExtension
clase , agregue el código siguiente después de la llamada existente a lathis.quickViewNavigator.register()
instrucción que registró starttrip QuickView:this.quickViewNavigator.register(QUICK_VIEW_SET_ORIGIN_REGISTRY_ID, () => new SetOrigin()); this.quickViewNavigator.register(QUICK_VIEW_SET_DESTINATION_REGISTRY_ID, () => new SetDestination()); this.quickViewNavigator.register(QUICK_VIEW_SAVE_TRIP_REGISTRY_ID, () => new SaveTrip());
El último paso es conectar las vistas rápidas a la vista rápida de StartTrip existente.
Busque y abra el archivo ./src/adaptiveCardExtensions/campusShuttle/quickView/StartTrip.ts .
Busque la instrucción existente
import
que hace referencia a las interfaces de estado y propiedad en elCampusShuttleCopilotAdaptiveCardExtension
módulo. Actualícelo para importar las tres constantes de las tres nuevas vistas rápidas:import { ICampusShuttleCopilotAdaptiveCardExtensionProps, ICampusShuttleCopilotAdaptiveCardExtensionState, QUICK_VIEW_SET_ORIGIN_REGISTRY_ID, QUICK_VIEW_SET_DESTINATION_REGISTRY_ID, QUICK_VIEW_SAVE_TRIP_REGISTRY_ID } from '../CampusShuttleAdaptiveCardExtension';
Implemente SetOrigin QuickView reemplazando el comentario
// TODO QuickView originLocation
en elonAction()
método por lo siguiente:this.quickViewNavigator.push(QUICK_VIEW_SET_ORIGIN_REGISTRY_ID);
Implemente setDestination QuickView reemplazando el comentario
// TODO QuickView destinationLocation
en elonAction()
método por lo siguiente:this.quickViewNavigator.push(QUICK_VIEW_SET_DESTINATION_REGISTRY_ID);
Implemente saveTrip QuickView reemplazando el comentario
// TODO QuickView save
en elonAction()
método por lo siguiente:this.quickViewNavigator.push(QUICK_VIEW_SAVE_TRIP_REGISTRY_ID);
Observe que cada una de estas llamadas inserta una vista rápida en el navegador. Esto desencadena una nueva representación de QuickView mediante el nuevo elemento de la pila. Recuerde que anteriormente, estábamos sacando vistas rápidas de la pila.
El último paso es actualizar la pantalla CardView cuando se ha reservado un viaje.
Busque y abra el archivo ./src/adaptiveCardExtensions/campusShuttle/cardView/CardView.ts .
Reemplace la instrucción existente
import
,import { STATUS_AVAILABLE } from '../sp.service';
, por el código siguiente:import { ILocation, STATUS_AVAILABLE, STATUS_ENROUTE, STATUS_HIRED } from '../sp.service';
Actualice la
switch
instrucción delcardButtons()
método al código siguiente.switch (this.state.currentTrip.Status) { case STATUS_AVAILABLE: return [{ title: 'Book a Trip', action: { type: 'QuickView', parameters: { view: QUICK_VIEW_START_TRIP_REGISTRY_ID } } }]; break; case STATUS_ENROUTE: return [ { title: 'View pickup location', action: { type: 'VivaAction.ShowLocation', parameters: { locationCoordinates: { latitude: (this.state.currentTrip.OriginLocation as ILocation).latitude, longitude: (this.state.currentTrip.OriginLocation as ILocation).longitude } } } } ]; break; case STATUS_HIRED: return [ { title: 'View dropoff location', action: { type: 'VivaAction.ShowLocation', parameters: { locationCoordinates: { latitude: (this.state.currentTrip.DestinationLocation as ILocation).latitude, longitude: (this.state.currentTrip.DestinationLocation as ILocation).longitude } } } } ]; break; default: return undefined; break; }
Estos cambios mostrarán condicionalmente diferentes botones y texto en función del estado del controlador de transporte actual. Observe que ahora estamos usando la acción
VivaAction.ShowLocation
de CardView para mostrar las ubicaciones de origen y destino especificadas.Por último, actualice la
return
instrucción deldata()
método al código siguiente.return { primaryText: strings.PrimaryText, description: (this.state.currentTrip.Status === STATUS_AVAILABLE) ? `available for hire` : (this.state.currentTrip.Status === STATUS_ENROUTE) ? `Booked - ${STATUS_ENROUTE} to pickup...` : (this.state.currentTrip.DestinationName) ? `Hired - driving passenger to ${this.state.currentTrip.DestinationName}...` : `Hired - driving passenger to destination...`, title: this.properties.title };
Tenga en cuenta que esto cambiará el mensaje condicional en función del estado del viaje del conductor del transbordador.
Experiencia de creación de un viaje de prueba
En este punto, puede probar la experiencia de creación de viajes completa en el explorador.
Si anteriormente detuvo el servidor web local, reinícielo ejecutando lo siguiente en la consola:
gulp serve --nobrowser
Vaya al área de trabajo hospedada de SharePoint para ver campus shuttle ACE.
Las ACE solo mostrarán un botón en CardView cuando el tamaño de la tarjeta esté establecido en Medio. Mientras la página está en modo de edición, abra el panel de propiedades y cambie el tamaño de la tarjeta a Grande para que ambos botones aparezcan en CardView.
A continuación, seleccione el botón Vista previa en la parte superior derecha de la barra de herramientas.
Para empezar, seleccione el botón Reservar un viaje en el CardView inicial. Muestra la vista rápida Iniciar un viaje que probó anteriormente.
Seleccione el botón (1) Seleccionar origen del viaje desde el mapa para cargar SetOrigin QuickView. Ahora, seleccione seleccionar la ubicación en el botón de mapa . Si no ha concedido a su explorador acceso a su ubicación, se le pedirá que lo haga. Debe aprobar esta solicitud para que la acción VivaAction.GetLocation funcione:
Después de conceder al explorador acceso a su ubicación, aparecerá un cuadro de diálogo con un mapa. Center the map on the location for the pickup location for the trip, select the pickup and select the Share Location button.
Seleccione el botón (2) Seleccionar o establecer destino de viaje para cargar la vista rápida SetDestination. Esta vez, seleccione una de las ubicaciones conocidas en el cuadro desplegable y seleccione el botón Guardar ubicación de destino .
Por último, seleccione el estado del viaje para en la ruta de recogida y seleccione el botón Guardar viaje .
Con el viaje guardado, observe que CardView ahora muestra diferentes botones y texto en función del contexto actual.
Por último, vaya a la lista que contiene los datos del viaje para ver cómo se almacenan los datos para nuestro viaje de prueba:
El Campus Shuttle ACE está en buena forma para la creación de viajes. Los dos últimos pasos consisten en implementar los escenarios en los que el conductor está en ruta para recoger a un pasajero y conducir al pasajero a su destino.
Agregar funcionalidad cuando se dirige a la recogida de pasajeros
Ahora vamos a implementar el escenario cuando el conductor está en ruta para recoger a un pasajero.
Agregue un nuevo archivo UpdateTripCard.json a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template con el código siguiente:
{ "schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.5", "body": [ { "type": "TextBlock", "weight": "Bolder", "text": "${title}" } ], "actions": [ { "id": "cancel", "type": "Action.Submit", "title": "Cancel Current Trip" }, { "id": "pickup", "type": "Action.Submit", "title": "Pickup Passenger", "style": "positive" } ] }
Implemente UpdateTrip QuickView agregando un nuevo archivo UpdateTrip.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
import { IActionArguments, ISPFxAdaptiveCard, BaseAdaptiveCardView } from '@microsoft/sp-adaptive-card-extension-base'; import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState } from '../CampusShuttleAdaptiveCardExtension'; import { STATUS_HIRED, upsertListItem } from '../sp.service'; export interface IUpdateTripData { title: string; } export class UpdateTrip extends BaseAdaptiveCardView< ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, IUpdateTripData > { public get data(): IUpdateTripData { return { title: 'Update the existing trip' }; } public get template(): ISPFxAdaptiveCard { return require('./template/UpdateTripCard.json'); } public onAction(action: IActionArguments): void { if (action.type !== 'Submit') { return; } switch (action.id) { case 'cancel': // TODO QuickView cancelTrip break case 'pickup': // update current item status const trip = this.state.currentTrip; trip.Status = STATUS_HIRED; // save to list (async () => { await upsertListItem(this.context, this.properties.listId, trip); })(); // update ACE this.setState({ currentTrip: trip }); this.quickViewNavigator.close(); break default: return; } } }
Nuestro proyecto necesita un paso de confirmación si el conductor quiere eliminar un viaje, ya sea cancelándolo o entregando un pasajero. Para implementar esto, usaremos una vista rápida de confirmación única que controlará dinámicamente ambos casos.
Agregue un nuevo archivo ConfirmationCard.json a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView/template con el código siguiente:
{ "schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.5", "body": [ { "type": "TextBlock", "text": "${title}", "size": "Large" }, { "type": "TextBlock", "text": "${description}" } ], "actions": [ { "id": "confirm", "type": "Action.Submit", "title": "${title}", "style": "positive" } ] }
Implemente la vista rápida de confirmación agregando un nuevo archivo ConfirmationQuickView.ts a la carpeta ./src/adaptiveCardExtensions/campusShuttle/quickView con el código siguiente:
import { IActionArguments, ISPFxAdaptiveCard, BaseAdaptiveCardView } from '@microsoft/sp-adaptive-card-extension-base'; import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState } from '../CampusShuttleAdaptiveCardExtension'; import { deleteListItem, STATUS_AVAILABLE } from '../sp.service'; export interface IConfirmationQuickViewData { title: string; description: string; } export class ConfirmationQuickView extends BaseAdaptiveCardView< ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, IConfirmationQuickViewData > { constructor(private confirmType: 'cancel' | 'complete') { super(); } public get data(): IConfirmationQuickViewData { return { title: `${this.confirmType.substring(0,1).toUpperCase()}${this.confirmType.substring(1,this.confirmType.length)} Trip`, description: `Are you sure you want to ${this.confirmType} the trip?` }; } public get template(): ISPFxAdaptiveCard { return require('./template/ConfirmationCard.json'); } public onAction(action: IActionArguments): void { if (action.type === 'Submit' && action.id === 'confirm') { (async () => { // delete list item await deleteListItem(this.context, this.properties.listId, Number(this.state.currentTrip.Id)); })(); // update state to initial value this.setState({ currentTrip: { Title: this.context.pageContext.user.loginName, Status: STATUS_AVAILABLE } }); // close this.quickViewNavigator.close(); } } }
Para usar estas tres vistas rápidas nuevas, debe registrarlas:
Abra el archivo ./src/adaptiveCardExtensions/campusShuttle/quickView/index.ts y exporte las nuevas vistas rápidas:
// .. existing export statements export * from './UpdateTrip'; export * from './ConfirmationQuickView';
Abra el archivo ./src/adaptiveCardExtensions/campusShuttle/CampusShuttleAdaptiveCardExtension.ts .
Actualice el existente
import
para importar las vistas rápidas para hacer referencia a las nuevas vistas rápidas:import { StartTrip, SetOrigin, SetDestination, SaveTrip, UpdateTrip, // << add ConfirmationQuickView // << add } from './quickView';
Busque las constantes que declaran los identificadores de CardView y QuickView y agregue los siguientes identificadores para las nuevas vistas rápidas:
export const QUICK_VIEW_CANCEL_TRIP_REGISTRY_ID: string = 'CampusShuttleCopilot_CancelTrip_QUICK_VIEW'; export const QUICK_VIEW_COMPLETE_TRIP_REGISTRY_ID: string = 'CampusShuttleCopilot_CompleteTrip_QUICK_VIEW'; export const QUICK_VIEW_UPDATE_TRIP_REGISTRY_ID: string = 'CampusShuttleCopilot_UpdateTrip_QUICK_VIEW';
Observe cómo las dos primeras constantes no hacen referencia al QuickView de confirmación? Esto se debe a que vamos a crear dos implementaciones del mismo QuickView.
En el
onInit()
método de laCampusShuttleAdaptiveCardExtension
clase , agregue el código siguiente después de la llamada existente a lathis.quickViewNavigator.register()
instrucción que registró starttrip QuickView:this.quickViewNavigator.register(QUICK_VIEW_CANCEL_TRIP_REGISTRY_ID, () => new ConfirmationQuickView('cancel')); this.quickViewNavigator.register(QUICK_VIEW_COMPLETE_TRIP_REGISTRY_ID, () => new ConfirmationQuickView('complete')); this.quickViewNavigator.register(QUICK_VIEW_UPDATE_TRIP_REGISTRY_ID, () => new UpdateTrip());
El último paso es conectar las vistas rápidas a las vistas rápidas y cardview existentes.
Busque y abra el archivo ./src/adaptiveCardExtensions/campusShuttle/cardView/CardView.ts .
Busque la instrucción existente
import
que hace referencia a las interfaces de estado y propiedad en elCampusShuttleCopilotAdaptiveCardExtension
módulo. Actualícela para importar las tres constantes de la actualización y complete las nuevas vistas rápidas:import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, QUICK_VIEW_START_TRIP_REGISTRY_ID, QUICK_VIEW_UPDATE_TRIP_REGISTRY_ID, // << add QUICK_VIEW_COMPLETE_TRIP_REGISTRY_ID // << add } from '../CampusShuttleAdaptiveCardExtension';
En el
cardButton()
método de descriptor de acceso, actualice la instrucción switch para agregar más botones:Agregue el botón siguiente a la
case STATUS_ENROUTE
return
instrucción :{ title: 'Update Trip', action: { type: 'QuickView', parameters: { view: QUICK_VIEW_UPDATE_TRIP_REGISTRY_ID } } }
Agregue el botón siguiente a la
case STATUS_HIRED
return
instrucción :{ title: 'Complete Trip', action: { type: 'QuickView', parameters: { view: QUICK_VIEW_COMPLETE_TRIP_REGISTRY_ID } } }
Busque y abra el archivo ./src/adaptiveCardExtensions/campusShuttle/quickView/UpdateTrip.ts .
Busque la instrucción existente
import
que hace referencia a las interfaces de estado y propiedad en elCampusShuttleCopilotAdaptiveCardExtension
módulo. Actualícela para importar las tres constantes de la actualización y complete las nuevas vistas rápidas:import { ICampusShuttleAdaptiveCardExtensionProps, ICampusShuttleAdaptiveCardExtensionState, QUICK_VIEW_CANCEL_TRIP_REGISTRY_ID // << add } from '../CampusShuttleAdaptiveCardExtension';
Implemente SetOrigin QuickView reemplazando el comentario
// TODO QuickView cancelTrip
en elonAction()
método por lo siguiente:this.quickViewNavigator.push(QUICK_VIEW_CANCEL_TRIP_REGISTRY_ID);
Experiencia de administración de viajes de prueba
En este punto, puede probar la experiencia de administración de viajes en el explorador.
Si anteriormente detuvo el servidor web local, reinícielo ejecutando lo siguiente en la consola:
gulp serve --nobrowser
Vaya al área de trabajo hospedada de SharePoint para ver la ACE de campus shuttle y seleccione el botón Vista previa en la parte superior derecha de la barra de herramientas.
Observe que CardView ahora contiene un botón Actualizar viaje .
Seleccione el botón Actualizar viaje y observe que hay dos opciones para cancelar o recoger a un pasajero.
Al seleccionar el botón Cancelar viaje actual , se restablecerá el estado de ACE y se eliminará el registro del controlador de la lista de SharePoint. Al seleccionar el botón Recoger pasajeros , se actualizará el viaje, tanto en el estado ACE como en el elemento de lista de SharePoint, para cambiar el estado del viaje de en ruta a contratado.
Seleccione el botón Pickup Passenger (Pasajeros de recogida ). Observe que el contexto de CardView y los botones cambian para indicar el cambio al estado del viaje:
Por último, seleccione el botón Completar viaje para ver la vista rápida de confirmación y, a continuación, seleccione el botón Completar viaje para confirmar. Esto completará el viaje.
En este ejercicio, ha creado una ACE de SPFx con la opción Tarjeta de texto principal que usa las funcionalidades de ubicación geográfica en Conexiones Viva.