OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
687 stars 94 forks source link

Function getSelectedItemsAsync returns error: "Invalid operation (getSelectedItemsAsync) when Office.context.mailbox.item is null." #3680

Closed joaquinluct closed 11 months ago

joaquinluct commented 1 year ago

Provide required information needed to triage your issue

Your Environment

Expected behavior

Get number of selected messages when select multiple messages on UI by calling getSelectedItemsAsync function

Current behavior

We obtain an error: Error: Invalid operation (getSelectedItemsAsync) when Office.context.mailbox.item is null. at B (https://appsforoffice.microsoft.com/lib/1.1/hosted/outlook-web-16.01.js:20:257883) at https://appsforoffice.microsoft.com/lib/1.1/hosted/outlook-web-16.01.js:20:259139 at Z (https://appsforoffice.microsoft.com/lib/1.1/hosted/outlook-web-16.01.js:20:259227) at e.mi (https://appsforoffice.microsoft.com/lib/1.1/hosted/outlook-web-16.01.js:20:327665) at https://localhost:7000/taskpane.js:139414:28 at initializePromise (https://localhost:7000/taskpane.js:445:5) at new Promise (https://localhost:7000/taskpane.js:873:33) at getNumSelectedMails (https://localhost:7000/taskpane.js:139404:10) at https://localhost:7000/taskpane.js:140524:33 at step (https://localhost:7000/taskpane.js:140266:17)

Steps to reproduce

  1. Create Outlook React project add-in via Yeoman with TypeScript option.
  2. Modify manifest.xml with https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/item-multi-select indications.
  3. Replace App.tsx with this code (created for issue propouse):
import React, { useEffect, useState } from "react";
import { hot } from "react-hot-loader/root";

interface Props {
  isMultiSelection: boolean;
  isOfficeInitialized: boolean;
}

function App({ isOfficeInitialized }: Props): JSX.Element {
  if (!isOfficeInitialized) {
    return (
      <>
        <div>waiting</div>
      </>
    );
  }

  async function getNumSelectedMails(): Promise<number> {
    return new Promise((resolve, _reject) => {
      if (typeof Office.context.mailbox.getSelectedItemsAsync !== "function") {
        resolve(NaN);
      }
      Office.context.mailbox.getSelectedItemsAsync((asyncResult) => {
        console.log(asyncResult);
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
          console.log(asyncResult.error.message);
          resolve(NaN);
        }

        resolve(asyncResult.value.length);
      });
    });
  }

  function onItemChanged(eventArgs: any) {
    console.log("[App::onItemChanged]", { args: eventArgs });
  }

  async function onSelectedItemsChanged(eventArgs: any) {
    console.log("[App::onSelectedItemsChanged]", { args: eventArgs });
    const numMails = await getNumSelectedMails()
      .catch((error) => console.log(error))
      .then((num) => num);
    console.log("NUM MAILS", { numMails });
  }

  useEffect(() => {
    if (Office.context.mailbox && typeof Office.context.mailbox.addHandlerAsync === "function") {
      Office.context.mailbox.addHandlerAsync(Office.EventType.ItemChanged, onItemChanged);
      Office.context.mailbox.addHandlerAsync(Office.EventType.SelectedItemsChanged, onSelectedItemsChanged);
    }
    return () => {
      if (Office.context.mailbox && typeof Office.context.mailbox.addHandlerAsync === "function") {
        Office.context.mailbox.removeHandlerAsync(Office.EventType.ItemChanged, onItemChanged);
        Office.context.mailbox.removeHandlerAsync(Office.EventType.SelectedItemsChanged, onSelectedItemsChanged);
      }
    };
  }, []);

  return (
    <>
      <div>Hello world!</div>
    </>
  );
}

export default hot(App);
  1. Select multiple message on Outlook Web UI.

Link to live example(s)

Provide additional details




Context

Useful logs

Thank you for taking the time to report an issue. Our triage team will respond to you in less than 72 hours. Normally, response time is <10 hours Monday through Friday. We do not triage on weekends.

joaquinlefebvre commented 1 year ago

My apologies for the issue.

I have already managed to understand the problem.

When I have the panel open for a message, the multi-message option does not work. The panel must be closed to allow the user to click on the multiple messages option. Using this option, the number of messages is now correctly displayed through the "getSelectedItemsAsync" function. It's a bit confusing, since if I have the 'pinnable' option active, as a user, I expect it to be indifferent to clicking on a message or several. Well, then, understood. Thank you so much.

I think so this issue can be closed. For me it is not the best expected interface, but I have already changed the code to close the panel when the user goes from selecting one message to selecting several

exextoc commented 1 year ago

Can you please help us understand a bit, what is meant by panel open? If possible, please share a small video as there is no such rule that the add-in has to be closed to multiselect the items.

joaquinlefebvre commented 1 year ago

https://github.com/OfficeDev/office-js/assets/94112683/9711869e-b48d-4623-9894-099ffe215b7b

joaquinlefebvre commented 1 year ago

Sorry about my english. 'panel open' mind 'Add-in taskpane openned'.

When I show my add-in taskpane via single message, and select another messages, the function getSelectedItemsAsync fails. But when I show my add-in taskpane via multple messages selected this function works properly. That's mind than I can't switch from my one message UI to my multiple messages UI without close the add-in.

exextoc commented 1 year ago

We are not able to repro this at our end, can you please share the manifest/hosted add-in that will help us to understand the exact issue.

exextoc commented 1 year ago

When multiple emails are selected, it is expected that Office.context.mailbox.item will be null and there is no single item selected. With multiple item selection getSelectedItemsAsync should work.

joaquinlefebvre commented 1 year ago

This is our manifest.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp
  xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
  xmlns:mailappor="http://schemas.microsoft.com/office/mailappversionoverrides"
  xsi:type="MailApp">
  <Id>7e166523-11bc-472e-8ab1-194936833226</Id>
  <Version>2.0.0.1</Version>
  <ProviderName>Lefebvre</ProviderName>
  <DefaultLocale>es-ES</DefaultLocale>
  <DisplayName DefaultValue="Lex-ON (DEV)"/>
  <Description DefaultValue="Una herramienta de Lefebvre para tener tus expedientes combinados con tu correo"/>
  <IconUrl DefaultValue="https://localhost:3000/assets/icon-64.png"/>
  <HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/icon-128.png"/>
  <SupportUrl DefaultValue="https://centrodeayuda.lefebvre.es/"/>
  <AppDomains>
    <AppDomain>https://lefebvre.es</AppDomain>
  </AppDomains>
  <Hosts>
    <Host Name="Mailbox"/>
  </Hosts>
  <Requirements>
    <Sets>
      <Set Name="Mailbox" MinVersion="1.1"/>
    </Sets>
  </Requirements>
  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation DefaultValue="https://localhost:3000/taskpane.html"/>
        <RequestedHeight>450</RequestedHeight>
      </DesktopSettings>
    </Form>
    <Form xsi:type="ItemEdit">
      <DesktopSettings>
        <SourceLocation DefaultValue="https://localhost:3000/compose.html"/>
      </DesktopSettings>
    </Form>
  </FormSettings>
  <Permissions>ReadWriteMailbox</Permissions>
  <Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs" ItemType="Message" FormType="Read"/>
    <Rule xsi:type="ItemIs" ItemType="Message" FormType="Edit"/>
  </Rule>
  <DisableEntityHighlighting>false</DisableEntityHighlighting>
  <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
    <Requirements>
      <bt:Sets DefaultMinVersion="1.1">
        <bt:Set Name="Mailbox"/>
      </bt:Sets>
    </Requirements>
    <Hosts>
      <Host xsi:type="MailHost">
        <DesktopFormFactor>
          <FunctionFile resid="Commands.Url"/>
          <ExtensionPoint xsi:type="MessageReadCommandSurface">
            <OfficeTab id="TabDefault">
              <Group id="msgReadGroup">
                <Label resid="GroupLabel"/>
                <Control xsi:type="Button" id="msgReadOpenPaneButton">
                  <Label resid="TaskpaneButton.Label"/>
                  <Supertip>
                    <Title resid="TaskpaneButton.Label"/>
                    <Description resid="TaskpaneButton.Tooltip"/>
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="Icon.16x16"/>
                    <bt:Image size="32" resid="Icon.32x32"/>
                    <bt:Image size="80" resid="Icon.80x80"/>
                  </Icon>
                  <Action xsi:type="ShowTaskpane">
                    <SourceLocation resid="Taskpane.Url"/>
                  </Action>
                </Control>
                <!-- <Control xsi:type="Button" id="ActionButton">
                  <Label resid="ActionButton.Label"/>
                  <Supertip>
                    <Title resid="ActionButton.Label"/>
                    <Description resid="ActionButton.Tooltip"/>
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="Icon.16x16"/>
                    <bt:Image size="32" resid="Icon.32x32"/>
                    <bt:Image size="80" resid="Icon.80x80"/>
                  </Icon>
                  <Action xsi:type="ExecuteFunction">
                    <FunctionName>action</FunctionName>
                  </Action>
                </Control> -->
              </Group>
            </OfficeTab>
          </ExtensionPoint>
          <ExtensionPoint xsi:type="MessageComposeCommandSurface">
            <OfficeTab id="TabCompose">
              <Group id="msgComposeGroup">
                <Label resid="GroupLabel"/>
                <Control xsi:type="Button" id="msgComposeOpenPaneButton">
                  <Label resid="TaskpaneComposeButton.Label"/>
                  <Supertip>
                    <Title resid="TaskpaneComposeButton.Label"/>
                    <Description resid="TaskpaneComposeButton.Tooltip"/>
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="Icon.16x16"/>
                    <bt:Image size="32" resid="Icon.32x32"/>
                    <bt:Image size="80" resid="Icon.80x80"/>
                  </Icon>
                  <Action xsi:type="ShowTaskpane">
                    <SourceLocation resid="Compose.Url"/>
                  </Action>
                </Control>
              </Group>
            </OfficeTab>
          </ExtensionPoint>
          <!-- <ExtensionPoint xsi:type="LaunchEvent">
            <LaunchEvents>
              <LaunchEvent Type="OnMessageSend" FunctionName="onMessageSendHandler" SendMode="PromptUser" />
            </LaunchEvents>
            <SourceLocation resid="MessageSend.Url"/>
          </ExtensionPoint> -->
        </DesktopFormFactor>
      </Host>
    </Hosts>
    <Resources>
      <bt:Images>
        <bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
        <bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
        <bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
      </bt:Images>
      <bt:Urls>
        <bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
        <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
        <bt:Url id="Compose.Url" DefaultValue="https://localhost:3000/compose.html"/>
      </bt:Urls>
      <bt:ShortStrings>
        <bt:String id="GroupLabel" DefaultValue="Lefebvre Lex-ON Add-in"/>
        <bt:String id="TaskpaneButton.Label" DefaultValue="Lex-ON"/>
        <bt:String id="TaskpaneComposeButton.Label" DefaultValue="Lex-ON"/>
        <bt:String id="ActionButton.Label" DefaultValue="Lex-ON"/>
        <bt:String id="Classify.Label" DefaultValue="Clasificación en Lex-ON"/>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Clasifica y guarda tus adjuntos en Lex-ON"/>
        <bt:String id="TaskpaneComposeButton.Tooltip" DefaultValue="Te ayuda a componer un mensaje con datos de Lex-ON"/>
        <bt:String id="ActionButton.Tooltip" DefaultValue="Perform an action when clicked."/>
        <bt:String id="Classify.Tooltip" DefaultValue="Clasificación masiva de correos en Lex-ON"/>
      </bt:LongStrings>
    </Resources>
    <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1" xsi:type="VersionOverridesV1_1">
      <Requirements>
        <bt:Sets DefaultMinVersion="1.1">
          <bt:Set Name="Mailbox"/>
        </bt:Sets>
      </Requirements>
      <Hosts>
        <Host xsi:type="MailHost">
          <Runtimes>
            <!-- HTML file including reference to or inline JavaScript event handlers.
                This is used by Outlook on the web and on the new Mac UI. -->
            <Runtime resid="MessageSend.Url">
              <!-- JavaScript file containing event handlers. This is used by Outlook on Windows. -->
              <Override type="javascript" resid="OfficeDesktop.Url"/>
            </Runtime>
          </Runtimes>
          <DesktopFormFactor>
            <FunctionFile resid="Commands.Url"/>
            <ExtensionPoint xsi:type="MessageReadCommandSurface">
              <OfficeTab id="TabDefault">
                <Group id="msgReadGroup">
                  <Label resid="GroupLabel"/>
                  <Control xsi:type="Button" id="msgReadOpenPaneButton">
                    <Label resid="TaskpaneButton.Label"/>
                    <Supertip>
                      <Title resid="TaskpaneButton.Label"/>
                      <Description resid="TaskpaneButton.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Icon.16x16"/>
                      <bt:Image size="32" resid="Icon.32x32"/>
                      <bt:Image size="80" resid="Icon.80x80"/>
                    </Icon>
                    <Action xsi:type="ShowTaskpane">
                      <SourceLocation resid="Taskpane.Url"/>
                      <SupportsPinning>true</SupportsPinning>
                      <SupportsMultiSelect>true</SupportsMultiSelect>
                      <!-- <SupportsNoItemContext>true</SupportsNoItemContext> -->
                    </Action>
                  </Control>
                  <!-- <Control xsi:type="Button" id="ActionButton">
                    <Label resid="ActionButton.Label"/>
                    <Supertip>
                      <Title resid="ActionButton.Label"/>
                      <Description resid="ActionButton.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Icon.16x16"/>
                      <bt:Image size="32" resid="Icon.32x32"/>
                      <bt:Image size="80" resid="Icon.80x80"/>
                    </Icon>
                    <Action xsi:type="ExecuteFunction">
                      <FunctionName>action</FunctionName>
                    </Action>
                  </Control> -->
                </Group>
              </OfficeTab>
            </ExtensionPoint>
            <ExtensionPoint xsi:type="MessageComposeCommandSurface">
              <OfficeTab id="TabCompose">
                <Group id="msgComposeGroup">
                  <Label resid="GroupLabel"/>
                  <Control xsi:type="Button" id="msgComposeOpenPaneButton">
                    <Label resid="TaskpaneComposeButton.Label"/>
                    <Supertip>
                      <Title resid="TaskpaneComposeButton.Label"/>
                      <Description resid="TaskpaneComposeButton.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Icon.16x16"/>
                      <bt:Image size="32" resid="Icon.32x32"/>
                      <bt:Image size="80" resid="Icon.80x80"/>
                    </Icon>
                    <Action xsi:type="ShowTaskpane">
                      <SourceLocation resid="Compose.Url"/>
                      <SupportsPinning>true</SupportsPinning>
                    </Action>
                  </Control>
                </Group>
              </OfficeTab>
            </ExtensionPoint>
            <ExtensionPoint xsi:type="LaunchEvent">
              <LaunchEvents>
                <LaunchEvent Type="OnMessageSend" FunctionName="onMessageSend" SendMode="PromptUser" />
              </LaunchEvents>
              <!-- Identifies the runtime to be used (also referenced by the Runtime element). -->
              <SourceLocation resid="MessageSend.Url"/>
            </ExtensionPoint>
          </DesktopFormFactor>
        </Host>
      </Hosts>
      <Resources>
        <bt:Images>
          <bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
          <bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
          <bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
        </bt:Images>
        <bt:Urls>
          <bt:Url id="MessageSend.Url" DefaultValue="https://localhost:3000/commands.html"/>
          <bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
          <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
          <bt:Url id="Compose.Url" DefaultValue="https://localhost:3000/compose.html"/>
          <bt:Url id="OfficeDesktop.Url" DefaultValue="https://localhost:3000/officeDesktop.js"/>
        </bt:Urls>
        <bt:ShortStrings>
          <bt:String id="GroupLabel" DefaultValue="Lefebvre Lex-ON Add-in"/>
          <bt:String id="TaskpaneButton.Label" DefaultValue="Lex-ON"/>
          <bt:String id="TaskpaneComposeButton.Label" DefaultValue="Lex-ON"/>
          <bt:String id="ActionButton.Label" DefaultValue="Lex-ON"/>
          <bt:String id="Classify.Label" DefaultValue="Clasificación en Lex-ON"/>
        </bt:ShortStrings>
        <bt:LongStrings>
          <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Clasifica y guarda tus adjuntos en Lex-ON"/>
          <bt:String id="TaskpaneComposeButton.Tooltip" DefaultValue="Te ayuda a componer un mensaje con datos de Lex-ON"/>
          <bt:String id="ActionButton.Tooltip" DefaultValue="Perform an action when clicked."/>
          <bt:String id="Classify.Tooltip" DefaultValue="Clasificación masiva de correos en Lex-ON"/>
        </bt:LongStrings>
      </Resources>
      <WebApplicationInfo>
        <!-- <Id>983326de-6d2d-4cfb-b03a-ea174ac0e196</Id>
        <Resource>api://localhost:3000/983326de-6d2d-4cfb-b03a-ea174ac0e196</Resource> -->
        <Id>4287a4a8-cf7c-4c0c-b5e9-1f5646e90217</Id>
        <Resource>api://localhost:3000/4287a4a8-cf7c-4c0c-b5e9-1f5646e90217</Resource>
        <Scopes>
          <Scope>User.Read</Scope>
          <Scope>profile</Scope>
          <Scope>Mail.Read</Scope>
          <Scope>Mail.ReadBasic</Scope>
        </Scopes>
      </WebApplicationInfo>
    </VersionOverrides>
  </VersionOverrides>
</OfficeApp>
joaquinlefebvre commented 1 year ago

Otherwise, you can reproduce this issue with this steps:

  1. Create Outlook React project add-in via Yeoman with TypeScript option.
  2. Modify manifest.xml with https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/item-multi-select indications.
  3. Replace App.tsx with this code (created for issue propouse): (code at the issue description)

I make a zip with the React project:

TestConecta.zip

joaquinlefebvre commented 1 year ago

When multiple emails are selected, it is expected that Office.context.mailbox.item will be null and there is no single item selected. With multiple item selection getSelectedItemsAsync should work.

So, when a user has a single item selected and the add-in taskpane is open, and he wants to select multiple message, he needs to close this add-in taskpane and open it with the multiple-selection add-in icon? If this is the operative, then ok. We change the code to close the add-in taskpane on single item selected when the user select more than one.

exextoc commented 1 year ago

In the video, the reading pane seems to be off. Can you check if you still face the issue, when you enable the reading pane.

joaquinlefebvre commented 1 year ago

No, reading pane is on. I made sure it was open to do correct development, just as the documentation says, and yes, I still have the problem.

Were you unable to reproduce the problem by following these steps?

Steps to reproduce Create Outlook React project add-in via Yeoman with TypeScript option. Modify manifest.xml with https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/item-multi-select indications. Replace App.tsx with this code (created for issue propouse):

DivyaPatidar commented 1 year ago

Thanks for reporting this issue regarding getSelectedItemsAsync API. It has been put on our backlog. We unfortunately have no timelines to share at this point. Internal tracking id: Office: 3947473

exextoc commented 11 months ago

This issue has been fixed and fix will be rolled out 100% by end of week.

joaquinlefebvre commented 11 months ago

I can’t thank you enough!!

exextoc commented 11 months ago

Closing the issue as it's been fixed.

joaquinlefebvre commented 11 months ago

Closing the issue as it's been fixed.

Thanks. It works as expected.