Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to pass data to task pane from new window dialog box in powerpoint add-in. #5231

Open
ankitmahapatra opened this issue Dec 30, 2024 · 12 comments
Assignees
Labels
Area: PowerPoint Issue related to PowerPoint add-ins Needs: author feedback Waiting for author (creator) of Issue to provide more info Possible-Solution Similar-Issue Status: no recent activity Issue or PR is stale (no recent activity)

Comments

@ankitmahapatra
Copy link

ankitmahapatra commented Dec 30, 2024

Issue: Error on Sending Data Back to PowerPoint Add-in task pane in Desktop Version on Mac

Your Environment

  • Platform [PC desktop, Mac, iOS, Office on the web]: Mac
  • Host [Excel, Word, PowerPoint, etc.]: PowerPoint

Expected behavior

performing operations in the pop up dialog should allow data to be sent back to the PowerPoint add-in taskpane correctly using the (Office.context.ui.messageParent) function.

Current behavior

In the PowerPoint Web version, the Office.context.ui.messageParent function sends data back successfully. However, in the PowerPoint Desktop version on Mac, does not occur successfully neither it shows any error in dev console.

Steps to reproduce

1.) Open the PowerPoint add-in on the Mac desktop app.
2.) From the task pane, click a link or button (e.g., "Open Folder") to open a dialog box.
3.) Perform operations within the dialog (e.g., select an item and prepare its details to be sent back).
4.) Close the dialog and attempt to send the selected data back to the task pane.
example snippet which we are doing is below
**`
else if (item.resourcetype === ResourceTypes.STORY) {
const favorite = item.favorite === false ? false : true;
const message = {
type: "CloseDialog",
content: {
hasBeenClicked: "StoryLink",
state: { resourceTitle: item.name, resourceId: item.key, favorite: favorite },
},
};
Office.context.ui.messageParent(JSON.stringify(message));

}`**

Observe the behavior: While the data is sent back successfully in the PowerPoint Web version, the same operation fails in the PowerPoint Desktop version on Mac.

Context

This issue impacts the functionality of our PowerPoint add-in for Mac users. The dialog's inability to send data back to the add-in task pane disrupts the intended workflow. The feature works as expected in the web version, indicating that the issue might be specific to the desktop implementation on Mac.

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.

@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: triage 🔍 New issue, needs PM on rotation to triage ASAP label Dec 30, 2024
Copy link

Here are some similar issues that might help you. Please check if they can solve your problem.


Possible solution (Extracted from existing issue, might be incorrect; please verify carefully)

I see the problem. On Excel desktop for the mac, you can't send a boolean value in the message. I changed true to "true" for my message and it worked. The docs say you can send either a boolean or a string so you might want to leave this open to fix or change the docs. booleans do work everywhere else.

Reference:

@RuizhiSunMS
Copy link
Contributor

Hi @ankitmahapatra, thx for reaching out here.
If you do have an example to repro this, would you please paste the whole code snippet here and make repro steps clearer (for example, what the dialog has, specify the operation in Step 3 and so on)?

@RuizhiSunMS RuizhiSunMS added Needs: author feedback Waiting for author (creator) of Issue to provide more info Area: PowerPoint Issue related to PowerPoint add-ins and removed Needs: triage 🔍 New issue, needs PM on rotation to triage ASAP labels Dec 30, 2024
@ankitmahapatra
Copy link
Author

ankitmahapatra commented Dec 31, 2024

I'm adding here the main code snippet @RuizhiSunMS below (specific part i have commented that This is to handle onclick of any story in the folder naviagtion dialog)

export const openDialog = (
  dialogUrl: string,
  height: number,
  width: number,
  displayInIframe: boolean,
  urlParameters?: Record<string, string>,
  dataFromTaskpane?: {
    bookmark: string;
    useSvgFlag: boolean;
  },
  onOK?: (data: string) => void,
  onAddWidget?: (widgetDetails: any, data: any) => void,
  onClose?: () => void,
  onOpen?: () => void // New callback for when dialog opens
): void => {
  const language = window.localStorage.getItem("ocean-language");
  const officeLanguage = Office.context.displayLanguage;
  const displayLanguage = language || officeLanguage;
  const parameters = urlParameters || {};
  if (!parameters.language) {
    parameters.language = displayLanguage;
  }

  const searchParameters = new URLSearchParams(parameters);
  Office.context.ui.displayDialogAsync(
    dialogUrl + "?" + searchParameters.toString(),
    {
      height: height,
      width: width,
      displayInIframe: displayInIframe,
      promptBeforeOpen: false,
    },
    (asyncResult: Office.AsyncResult<Office.Dialog>) => {
      const status = asyncResult.status;
      if (status !== Office.AsyncResultStatus.Succeeded) {
        captureExceptionWithoutStore(new Error("Dialog status:" + status));
        const error = asyncResult.error;
        if (error) {
          return;
        }
      }
      const dialog = asyncResult.value;
      if (!dialog) {
        captureExceptionWithoutStore(new Error("No dialog instance available"));
        return;
      }

      // Call the onOpen callback when the dialog is successfully opened
      if (onOpen) {
        onOpen();
      }

      // Add event handlers for the dialog
      //This is to send the details of widget to the dialog when the taskpane receives the DialogReadyMsg
      dialog.addEventHandler(Office.EventType.DialogMessageReceived, (arg: dialogBoxArgs) => {
        arg = arg as dialogBoxArgsWithoutError;
        if (arg.message === DialogReadyMsg && dataFromTaskpane) {
          dialog.messageChild(JSON.stringify(dataFromTaskpane));
        }
      });

      //This is to handle the dialog close event triggered by the X button on top
      dialog.addEventHandler(Office.EventType.DialogEventReceived, (arg: dialogBoxArgs) => {
        arg = arg as dialogBoxArgsWithError;
        if (arg.error === 12006) {
          //This gets triggered when the dialog is closed with the X button on top
          if (onClose) {
            onClose();
          }
        }
      });

      //This is to handle onclick of any story in the folder naviagtion dialog
      //Here we are closing the dialog and sending the resourceId and resourceTitle to the taskpane and redirecting it to the pagelisting screen
      dialog.addEventHandler(Office.EventType.DialogMessageReceived, (args: dialogBoxArgs) => {
        if ("message" in args) {
          const messageType = JSON.parse(args.message).type;
          if (messageType === "CloseDialog") {
            args = args as dialogBoxArgsWithoutError;
            args.message !== DialogReadyMsg &&
              (() => {
                const messageContent = JSON.parse(args.message).content;
                const previousPageState = {
                  resourceTitle: messageContent.state.resourceTitle,
                  resourceId: messageContent.state.resourceId,
                  favorite: messageContent.state.favorite,
                };
                dialog.close();
                const queryParams = new URLSearchParams(previousPageState).toString();
                window.location.href = window.location.href + `story-pages?${queryParams}`;
              })();
          }
        }
      });

      //This is to handle the dialog close event triggered by the OK and Cancel buttons based on the button clicked
      //If OK button is clicked, the bookmark is sent to the taskpane
      //If Cancel button is clicked, the onClose function is called which just closes the dialog
      dialog.addEventHandler(Office.EventType.DialogMessageReceived, (args: dialogBoxArgs) => {
        let bookmark: string = "";
        let hasBeenClicked: string = "";
        let dataUrl: any = "";
        let widgetDetails: any = {};
        if ("message" in args) {
          args = args as dialogBoxArgsWithoutError;
          args.message !== DialogReadyMsg &&
            (() => {
              const messageContent = JSON.parse(args.message).content;
              widgetDetails = messageContent && messageContent.widgetDetails;
              bookmark = messageContent && messageContent.bookmark;
              hasBeenClicked = messageContent && messageContent.hasBeenClicked;
              dataUrl = messageContent && messageContent.dataUrl;
              dialog.close();
            })();
        } else {
          captureExceptionWithoutStore(new Error("Error received from dialog:" + args.error));
          dialog.close();
        }
        if (onOK && hasBeenClicked == DialogButtons.OK) {
          onOK(bookmark);
        } else if (onAddWidget && hasBeenClicked == DialogButtons.AddWidget) {
          onAddWidget(widgetDetails, dataUrl);
        } else if (onClose && hasBeenClicked == DialogButtons.CANCEL) {
          onClose();
        }
      });
    }
  );
};

@ankitmahapatra
Copy link
Author

the event handling set up to process Office.EventType.DialogMessageReceived appears to work flawlessly in the web version of PowerPoint but fails to trigger in the desktop version. Despite ensuring proper initialization and setup, the dialog messages (intended to share resourceId and resourceTitle from the dialog to the task pane) do not reach the DialogMessageReceived event handler

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: attention 👋 Waiting on Microsoft to provide feedback and removed Needs: author feedback Waiting for author (creator) of Issue to provide more info labels Dec 31, 2024
@RuizhiSunMS RuizhiSunMS added Needs: author feedback Waiting for author (creator) of Issue to provide more info and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Dec 31, 2024
@RuizhiSunMS
Copy link
Contributor

Im sorry but @ankitmahapatra what you shared still lacks some details. Would you please share some more including:

  1. is this code snippet a part of your addin (or it can repro with ScriptLab)?
  2. please add how you call the openDialog and parameter examples, guessing them would make unnecessary cost.
  3. dialog url
  4. a record of how it works unexpectedly is not necessary but helpful

@ankitmahapatra
Copy link
Author

ankitmahapatra commented Dec 31, 2024

sure.

This code snippet is a part of our addin.
we have a button called Open Folder in our PPT add in and on clicking of the button calls the handleMyFiles function from where the call to openDialog goes.. Also what we are listing inside that dialog box is a component whose path we are sending as newLocation. The initial part of code is setting of path of the component into newLocation.

const searchParams = new URLSearchParams(window.location.search);
 let newLocation = `${window.location.origin}${window.location.pathname}?${searchParams.toString()}`;
 newLocation += "#/dialogs/FolderDialog";
 
 
 // Function to handle the "My Files" button click event
 const handleMyFiles = async () => {
   if (!dialogOpen) {
     // open a new dialog where all the contents will be listed.
     openDialog(
       newLocation,
       50,
       50,
       false,
       undefined, // Set parameters to `undefined` if no values to pass
       undefined, // Set dataFromTaskpane to `undefined` if you have no data
       undefined, // onOK handler
       undefined, // onAddWidget handler
       () => setDialogOpen(false), // onClose handler
       () => setDialogOpen(true) // onOpen handler
     );
   }
 };

I'll record and attach a video of how it is working in ppt desktop version and web version within some time.
Below i have attached the full file where my open button is there (on clicking of which opens the new dialog)

export const HomePage = () => {
//The code to store the state of which tab the user was on before He/She went to PageListing page is implemented in the HomePage component.
//Write now we are using the cache to store the state of the tab.
//Once the fix for replaceState and pushState is available we can use the browser history to store the state of the tab in URL parameters and move away from this.
const cacheService = CacheService.getAppCacheService();
const initialTab = cacheService.getCache().get("homeTab") || "Explore";
// State to manage the selected tab value
const [selectedValue, setSelectedValue] = React.useState<TabValue>(
  initialTab === i18n.t("Homepage.exploreLabel.text")
    ? i18n.t("Homepage.exploreTab.text")
    : i18n.t("Homepage.favoriteTab.text")
);

// State to manage whether the dialog is open or not
const [dialogOpen, setDialogOpen] = useState(false);

// Function to handle tab selection
const onTabSelect = (_event: SelectTabEvent, data: SelectTabData) => {
  setSelectedValue(data.value);
  // Update the cache with the selected tab value
  CacheService.getAppCacheService()
    .getCache()
    .add(
      "homeTab",
      data.value === i18n.t("Homepage.exploreTab.text")
        ? i18n.t("Homepage.exploreLabel.text")
        : i18n.t("Homepage.favoritesLabel.text")
    );
};

const searchParams = new URLSearchParams(window.location.search);
let newLocation = `${window.location.origin}${window.location.pathname}?${searchParams.toString()}`;
newLocation += "#/dialogs/FolderDialog";
// Function to handle the "My Files" button click event
const handleMyFiles = async () => {
  if (!dialogOpen) {
    // open a new dialog where all the contents will be listed.
    openDialog(
      newLocation,
      50,
      50,
      false,
      undefined, // Set parameters to `undefined` if no values to pass
      undefined, // Set dataFromTaskpane to `undefined` if you have no data
      undefined, // onOK handler
      undefined, // onAddWidget handler
      () => setDialogOpen(false), // onClose handler
      () => setDialogOpen(true) // onOpen handler
    );
  }
};

// Define tabs for the HomePage
const HomeScreenTabs = [
  {
    iconName: "FolderSearch",
    value: "Homepage.exploreTab.text",
    text: i18n.t("Homepage.exploreLabel.text"),
    styling: { padding: "6px", marginRight: "4px", width: "30%" },
  },
  {
    iconName: "FavoriteStar",
    value: "Homepage.favoriteTab.text",
    text: i18n.t("Homepage.favoritesLabel.text"),
    styling: { padding: "6px", marginLeft: "4px", width: "30%" },
  },
];

const classNames = getHomePageStyles();
return (
  <>
    <div>
      {/* Render the tab list */}
      <TabList
        className={classNames.tabList}
        selectedValue={selectedValue}
        onTabSelect={onTabSelect}
        size="medium"
        reserveSelectedTabSpace={false}
      >
        {HomeScreenTabs.map((tabItem) => {
          return (
            <Tab
              style={tabItem.styling}
              className={classNames.tabItem}
              key={tabItem.value}
              icon={<Icon iconName={tabItem.iconName} className={classNames.iconStyle} />}
              value={i18n.t(tabItem.value)}
            >
              {tabItem.text}
            </Tab>
          );
        })}
      </TabList>
      {/* Render the content based on the selected tab */}
      {selectedValue === i18n.t("Homepage.exploreTab.text") && <ExploreTab />}
      {selectedValue === i18n.t("Homepage.favoriteTab.text") && <FavoritesTab />}
    </div>
    {supports(featureFlag.folderNavigation) && (
      <div className={classNames.folder}>
        <hr className={classNames.divider} />
        <div className={classNames.folderDiv}>
          {supports(featureFlag.folderNavigation) && (
            <TooltipHost content={i18n.t("FolderDialog.OpenFolder.text")}>
              <DefaultButton
                text={i18n.t("FolderDialog.OpenFolder.text")}
                className={classNames.folderButton}
                onClick={handleMyFiles}
                disabled={dialogOpen} // Disable the button if dialog is open
              />
            </TooltipHost>
          )}
        </div>
      </div>
    )}
  </>
);
};

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: attention 👋 Waiting on Microsoft to provide feedback and removed Needs: author feedback Waiting for author (creator) of Issue to provide more info labels Dec 31, 2024
@ankitmahapatra
Copy link
Author

This is the successfull scenario where the ppt web-version works perfectly.

Clicking.a.link.working.in.web.ppt.version.mp4

1.) In the video, the dialog box is already open.
2.) When a link from the list is clicked, it triggers the handleLinkClick function, which is shown in the debugger.
3.) Within handleLinkClick, the message is passed to the task pane using Office.context.ui.messageParent(...).
4.) After continuing the debugger, the focus shifts to another window (the PowerPoint task pane).
5.) In the task pane, the event handler captures the message sent from the dialog box.
The statements execute successfully, and the data passed via the URL works as expected.

This is the unsuccessfull scenario where the ppt web-version works perfectly.

Clicking.a.link.now.working.in.ppt.desktop.version.mac.mp4

1.) In the video, the dialog box is already open.
2.) When a link in the dialog box list is clicked, the handleLinkClick function is triggered, and the message function is called.
3.) This behavior matches what was observed in the PowerPoint web version up to this point.
4.) After this, the debugger shifts to another file (some Microsoft system files).
5.) From there, it moves to the callCallback() function but does not return to the task pane.
In the web version, the process successfully returned to the task pane after this step, but this does not happen here.
The dev console shows no error messages, but the call stack vanishes without throwing any errors.

@ankitmahapatra
Copy link
Author

@RuizhiSunMS please let me know if you need further info or if i missed anything

@RuizhiSunMS
Copy link
Contributor

if this case is inside the addin and can't repro simply with scriptlab, please share the project (as a zip for example) so that we can sideload to investigate. This part is owned by our partner team. They require local repro steps strictly.

@RuizhiSunMS RuizhiSunMS added Needs: author feedback Waiting for author (creator) of Issue to provide more info and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Dec 31, 2024
@ankitmahapatra
Copy link
Author

I'm discussing this with one of our senior dev.. We will soon give the whole project as well as also the steps to set it up so that we can reach to the solution asap.

Thanks

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: attention 👋 Waiting on Microsoft to provide feedback and removed Needs: author feedback Waiting for author (creator) of Issue to provide more info labels Jan 1, 2025
@guoms1 guoms1 self-assigned this Jan 3, 2025
@guoms1
Copy link

guoms1 commented Jan 3, 2025

Dear @ankitmahapatra

Thank you for the update. I'll be on standby for the project details and setup steps. Please let me know if there's anything further required.

Best regards,
guoms1

@guoms1 guoms1 added Needs: author feedback Waiting for author (creator) of Issue to provide more info and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Jan 3, 2025
@microsoft-github-policy-service microsoft-github-policy-service bot added the Status: no recent activity Issue or PR is stale (no recent activity) label Jan 7, 2025
Copy link
Contributor

This issue has been automatically marked as stale because it is marked as needing author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. Thank you for your interest in Office Add-ins!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: PowerPoint Issue related to PowerPoint add-ins Needs: author feedback Waiting for author (creator) of Issue to provide more info Possible-Solution Similar-Issue Status: no recent activity Issue or PR is stale (no recent activity)
Projects
None yet
Development

No branches or pull requests

3 participants