Расширенные функции просмотра карт

Это продолжение руководства Создание первого расширения адаптивной карточки SharePoint.

Важно!

Эта функция по-прежнему находится в состоянии предварительного просмотра как часть выпуска 1.14 и не должны использоваться в рабочей среде. Мы планируем выпустить их официально как часть предстоящего выпуска 1.15.

В этом руководстве мы реализуем расширенные функции представления карт. Вы проработаете предыдущее руководство и создадите представление карточки, которое будет поддерживаться данными в списке SharePoint.

Создание тестового списка

Проработайте это руководство, создав новый список на сайте SharePoint с примерами данных:

  1. Перейдите к веб-сайту и создайте новый список с именем Список инструкций.

  2. Добавьте столбец типа Однострочный текст с именем Описание.

    Пустой список в SharePoint

  3. Добавьте в список несколько элементов.

    • Заголовок. Шаг 1, Описание. Использование элементов управления доступом (ACE)
    • Заголовок. Шаг 2, Описание. ???
    • Заголовок. Шаг 3, Описание: SPFx 🚀 🌝
  4. Получение идентификатора списка:

    1. Во время просмотра списка выберите значок шестеренки на панели набора, чтобы открыть меню Параметры. Затем выберите элемент меню Параметры списка:

      Экран параметров списка

    2. На странице Параметры списка найдите в URL-адресе ИД списка:

      ID списка в URL-адресе

    3. Сохраните ИД списка, чтобы использовать его на следующем шаге.

Добавление функции расширения адаптивной карточки (ACE)

Начните с ACE HelloWorld из предыдущего руководства, Создание первого расширения адаптивной карточки SharePoint. Для подготовки к шагу 2 внесите следующие изменения.

Измените свойства

Давайте изменим свойства для нашего ACE и зададим идентификатор списка, содержащий данные, которые будут отображаться нашим ACE:

  1. Найдите и откройте следующий файл в проекте: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts.

  2. Измените интерфейс, который используется для определения типа свойства ACE properties:

    export interface IHelloWorldAdaptiveCardExtensionProps {
      title: string;
      description: string;
      iconProperty: string;
      listId: string;
    }
    
  3. Найдите и откройте следующий файл в проекте: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.manifest.json.

  4. Инициализируйте ACE с помощью ИД списка, созданного на предыдущем шаге, задав следующую preConfiguredEntries:

      "preconfiguredEntries": [{
        // ...
        "properties": {
          "title": "HelloWorld",
          "description": "HelloWorld description",
          "iconProperty": "", // Default to sharepointlogo
          "listId": "" // TODO: enter list id
        }
      }]
    

    Важно!

    Убедитесь, что вы вводите ранее полученный идентификатор списка в свойство listId в коде preconfiguredEntries выше.

  5. Найдите и откройте следующий файл: ./src/adaptiveCardExtensions/helloWorld/HelloWorldPropertyPane.ts.

  6. Измените область свойств, добавив следующее поле:

    PropertyPaneTextField('listId', {
      label: 'List ID'
    })
    

Измените состояние ACE

Следующим шагом давайте обновим состояние ACE. При изменениях состояния ACE запускается для повторной отрисовки. Эти изменения добавят в состояние коллекцию элементов списка, а также отображаемый текущий элемент, как указано свойством currentIndex, которое вы добавите.

  1. Найдите и откройте следующий файл в проекте: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts.

  2. Добавьте новый интерфейс для данных списка, добавив в файл следующий код:

    export interface IListItem {
      title: string;
      description: string;
    }
    
  3. Измените интерфейс, используемый для определения состояния ACE, чтобы использовать новый интерфейс IListItem:

    export interface IHelloWorldAdaptiveCardExtensionState {
      currentIndex: number;
      items: IListItem[];
    }
    
  4. Измените инициализацию state путем изменения метода onInit() в ACE:

    public onInit(): Promise<void> {
      this.state = {
        currentIndex: 0,
        items: []
      };
      // ...
    }
    
  5. Временно удалите ссылку на state в ACE и представлениях, для чего измените метод onPropertyPaneFieldChanged():

    // tslint:disable-next-line: no-any
    protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
    }
    
  6. Найдите и откройте следующий файл: ./src/adaptiveCardExtensions/helloWorld/quickView/QuickView.ts.

  7. Измените методы data() и onAction() следующим образом:

    public get data(): IQuickViewData {
      return {
        subTitle: '',
        title: strings.Title
      };
    }
    
    public onAction(action: IActionArguments): void {
    }
    

Теперь, когда состояние обновлено, мы можем обновить ACE для получения данных из списка SharePoint.

Добавьте зависимость

Следующий шаг — добавление поддержки в проект и ACE для получения элементов из списка SharePoint. Для этого используется API SharePoint Framework (SPFx) для вызова конечной точки SharePoint REST.

Сначала добавьте зависимость в пакет SPFx, используемый для отправки HTTP-запросов в конечные точки REST:

  1. Найдите и откройте следующий файл в проекте: ./package.json. Обратите внимание на бета-версию бета-пакетов SPFx, используемых другими пакетами, перечисленными в качестве зависимостей в разделе dependencies файла package.json.

  2. Установите следующий пакет NPM в проект: @microsoft/sp-http:

    npm install @microsoft/sp-http -SE
    

Получение данных списка

Далее добавьте поддержку для вызова API SharePoint REST и добавления извлеченных элементов в состояние ACE. Когда состояние обновляется, то оно запускает ACE для повторной отрисовки.

  1. Найдите и откройте следующий файл в проекте: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts.

  2. Запросите данные списка с помощью API SPFx SPHttpClient. Добавьте в класс, реализующий ACE, следующий код:

    import { SPHttpClient } from '@microsoft/sp-http';
    
    ..
    
    private _fetchData(): Promise<void> {
      if (this.properties.listId) {
        return this.context.spHttpClient.get(
          `${this.context.pageContext.web.absoluteUrl}` +
            `/_api/web/lists/GetById(id='${this.properties.listId}')/items`,
          SPHttpClient.configurations.v1
        )
          .then((response) => response.json())
          .then((jsonResponse) => jsonResponse.value.map(
            (item) => { return { title: item.Title, description: item.Description }; })
            )
          .then((items) => this.setState({ items }));
      }
    
      return Promise.resolve();
    }
    
  3. Обновите ACE для запроса данных списка во время инициализации путем обновления метода onInit().

    Замените последнюю строку return Promise.resolve(); на return this._fetchData(); следующим образом:

    public onInit(): Promise<void> {
      // ...
      return this._fetchData();
    }
    
  4. Измените ACE так, чтобы он запрашивал данные списка при обновлении области свойств. Добавьте в класс, реализующий ACE, следующий метод: Этот код запрашивает данные только при смене ИД списка в области свойств:

    protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
      if (propertyPath === 'listId' && newValue !== oldValue) {
        if (newValue) {
          this._fetchData();
        } else {
          this.setState({ items: [] });
        }
      }
    }
    

Обновления карточек

С обновленным ACE для получения элементов из списка SharePoint давайте обновим карточку, чтобы отобразить эти данные.

  1. Найдите и откройте следующий файл: ./src/adaptiveCardExtensions/helloWorld/cardView/CardView.ts.

  2. Обновите метод получения data(), чтобы он выводил на экран данные из списка:

    public get data(): IPrimaryTextCardParameters {
      const { title, description } = this.state.items[this.state.currentIndex];
      return {
        description,
        primaryText: title
      };
    }
    

Теперь можно протестировать ACE. Создайте и запустите ACE в hosted workbench (размещенная рабочая область):

gulp serve

Когда загрузится локальный веб-сервер, перейдите в hosted workbench: https://{tenant}.sharepoint.com/_layouts/15/workbench.aspx

Примечание.

Удалите из workbench все старые экземпляры ACE. Экземпляры ACE из предыдущего руководства будут показывать сообщение об ошибке, поскольку свойства ACE были изменены.

Откройте инструментарий и выберите ACE:

Выбор ACE в инструментарии

Условные представления карточек

По умолчанию представления автоматически реагируют на размер карточки. Однако ACE могут при желании предоставлять различные представления для любого размера карты.

Измените HelloWorld ACE, чтобы он выводил на экран общее количество элементов списка в карточке среднего размера, а элементы списка — в карточке большого размера для максимально эффективного использования доступного пространства.

Представление карты среднего размера

Давайте создадим представление карточки среднего размера для нашего ACE:

  1. Создайте новый файл в папке./src/adaptiveCardExtensions/helloWorld/cardView/MediumCardView.ts.

  2. Добавьте следующий код, чтобы создать представление карточки среднего размера:

    import {
      BaseBasicCardView,
      IActionArguments,
      IBasicCardParameters,
      ICardButton
    } from '@microsoft/sp-adaptive-card-extension-base';
    import {
      IListItem, QUICK_VIEW_REGISTRY_ID,
      IHelloWorldAdaptiveCardExtensionProps,
      IHelloWorldAdaptiveCardExtensionState
    } from '../HelloWorldAdaptiveCardExtension';
    
    // Extend from BaseBasicCardView
    export class MediumCardView extends BaseBasicCardView<IHelloWorldAdaptiveCardExtensionProps, IHelloWorldAdaptiveCardExtensionState> {
      // Use the Card button to open the Quick View
      public get cardButtons(): [ICardButton] {
        return [
          {
            title: 'View All',
            action: {
              type: 'QuickView',
              parameters: {
                view: QUICK_VIEW_REGISTRY_ID
              }
            }
          }
        ];
      }
    
      // Display the total number of steps
      public get data(): IBasicCardParameters {
        return {
          primaryText: `${this.state.items.length} Steps`
        };
      }
    }
    
  3. Найдите и откройте следующий файл в проекте: ./src/adaptiveCardExtensions/helloWorld/HelloWorldAdaptiveCardExtension.ts.

  4. Теперь зарегистрируйте новое представление, внеся следующие изменения в ACE:

    import { MediumCardView } from './cardView/MediumCardView';
    
    ..
    
    const MEDIUM_VIEW_REGISTRY_ID: string = 'HelloWorld_MEDIUM_VIEW';
    
    ..
    
    public onInit(): Promise<void> {
      // ...
      this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView());
      this.cardNavigator.register(MEDIUM_VIEW_REGISTRY_ID, () => new MediumCardView());
      // ...
    }
    
  5. Изменим метод renderCard(), чтобы он возвращал представление карточки среднего размера или большой в зависимости от размера карточки:

    protected renderCard(): string | undefined {
      return this.cardSize === 'Medium' ? MEDIUM_VIEW_REGISTRY_ID : CARD_VIEW_REGISTRY_ID;
    }
    

Проверьте изменения, обновляя рабочую область:

Новый ACE, отрисовка различных размеров ACE

Измените размер карточки на большой и обновите окно браузера:

ACE, отрисовка карточки большого размера

Взаимодействие карточек большого размера

Представления карточки ACE поддерживают взаимодействие с пользователем. Кнопки могут вызывать REST API или использоваться для взаимодействия с картой другими способами. В этом разделе вы измените представление "Большая карточка", чтобы оно итеративно проходило по элементам в списке SharePoint.

  1. Найдите и откройте следующий файл: ./src/adaptiveCardExtensions/helloWorld/cardView/CardView.ts.

  2. В верхней части файла добавьте IActionArguments в качестве одной из ссылок для импорта из пакета @microsoft/sp-adaptive-card-extension-base:

    import { IActionArguments } from '@microsoft/sp-adaptive-card-extension-base';
    
  3. Кнопки в представлении "Карточка" могут быть динамическими в зависимости от текущего состояния ACE. Добавьте следующий код в файл CardView.ts ACE:

    public get cardButtons(): [ICardButton] | [ICardButton, ICardButton] {
      const buttons: ICardButton[] = [];
    
      // Hide the Previous button if at Step 1
      if (this.state.currentIndex > 0) {
        buttons.push({
          title: 'Previous',
          action: {
            type: 'Submit',
            parameters: {
              id: 'previous',
              op: -1 // Decrement the index
            }
          }
        });
      }
    
      // Hide the Next button if at the end
      if (this.state.currentIndex < this.state.items.length - 1) {
        buttons.push({
          title: 'Next',
          action: {
            type: 'Submit',
            parameters: {
              id: 'next',
              op: 1 // Increment the index
            }
          }
        });
      }
    
      return buttons as [ICardButton] | [ICardButton, ICardButton];
    }
    
  4. Затем сделайте так, чтобы state обновлялся при нажатии кнопки, для чего реализуйте следующий метод:

    public onAction(action: IActionArguments): void {
      if (action.type === 'Submit') {
        const { id, op } = action.data;
        switch (id) {
          case 'previous':
          case 'next':
          this.setState({ currentIndex: this.state.currentIndex + op });
          break;
        }
      }
    }
    

Проверьте изменения, перезагрузив workbench в браузере.

Первый экземпляр карточки будет показывать первый элемент списка с кнопкой Далее :

Первое представление карточки с кнопкой

Выберите кнопку Далее. Карточка отобразит следующий элемент в списке и добавит кнопку Назад :

Карточка с элементом списка SharePoint, который не является ни первым, ни последним элементом в списке

Нажимайте кнопку Далее, пока не дойдете до последнего элемента в списке. Карточка отобразит элемент в списке и только кнопку Назад :

Карточка с последним элементом списка и одной кнопкой

Представление карты кэширования и состояние ACE

Начиная с SPFx версии 1.14, ACE получат уровень кэширования на стороне клиента, который можно настроить для хранения следующего.

  1. Последняя отрисованная карта.
  2. Состояние ACE.

Отрисовка из кэшированного представления карточки

Если хранится последняя отрисовка карточки, панель мониторинга отрисовывает эту кэшированную карту до инициализации ACE, что улучшает воспринимаемую производительность.

Параметры этого кэша можно настроить, переопределив следующий метод:

protected getCacheSettings(): Partial<ICacheSettings> {
  return {
    isEnabled: true, // can be set to false to disable caching
    expiryTimeInSeconds: 86400, // controls how long until the cached card and state are stale
    cachedCardView: () => new CardView() // function that returns the custom Card view that will be used to generate the cached card
  };
}

Восстановление из кэшированного состояния ACE

Подмножество кэшируемого состояния ACE можно настроить, переопределив следующий метод:

protected getCachedState(state: TState): Partial<TState>;

Объект, возвращенный этим методом, будет сериализован и кэширован. По умолчанию состояния не кэшируются. В следующем вызове onInit десериализованное значение будет передано в onInit как часть ICachedLoadParameters

public onInit(cachedLoadParameters?: ICachedLoadParameters): Promise<void>;

Затем это значение можно использовать для восстановления состояния только что инициализированного ACE.

Заключение

Проработав это руководство, вы освоите следующие темы:

  • Изменение properties ACE по умолчанию
  • Изменение интерфейсов ACE properties/state
  • Создание и регистрация представлений карт
  • Отрисовка элементов представления карточки в зависимости от условий
  • Дополнительные операции с представлением карт
  • Представление карты кэширования и состояние ACE