From 8dcba7550d991274f098bc208ae2ec94832b62a1 Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 16:52:15 +0300 Subject: [PATCH 01/11] chore: Run `Upgrade Teams JS SDK and Code References` from Teams Toolkit --- package.json | 5 +++-- .../hooks/useConfigurationCreate.ts | 14 +++++++++----- .../hooks/useResources.ts | 4 +++- .../hooks/useValidate.ts | 2 +- .../hooks/useConfigurationDelete.ts | 2 +- .../hooks/useConfigurationUpdate.ts | 11 +++++++---- .../hooks/useValidate.ts | 2 +- .../containers/LoginContainer/hooks/useLogin.ts | 1 + .../ZeplinAuthEndContainer.tsx | 3 ++- src/client/hooks/useInitialize.ts | 5 +++-- .../webhookEventService.test.ts | 10 ++++++---- 11 files changed, 37 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index b7228422..56a388ae 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "audit-fix": "HUSKY_SKIP_HOOKS=1 dev-tools npm-audit-fix --production --team-reviewers dx", "prepare": "./scripts/install_husky.sh", "pre-commit": "lint-staged", - "pre-push": "npm run test" + "pre-push": "npm run test", + "clean": "rm -rf dist" }, "repository": { "type": "git", @@ -34,7 +35,7 @@ "dependencies": { "@fluentui/react-northstar": "^0.50.0", "@hapi/joi": "^17.1.1", - "@microsoft/teams-js": "^1.11.0", + "@microsoft/teams-js": "^2.0.0", "@newrelic/pino-enricher": "^1.1.1", "@sentry/browser": "^5.22.3", "@sentry/node": "^5.22.3", diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts index 707854ef..2404ef66 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts @@ -61,13 +61,16 @@ export const useConfigurationCreate = ({ useEffect(() => { if (isInitialized) { - microsoftTeams.getContext(({ + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. + microsoftTeams.app.getContext(({ channelId, channelName, tid: tenantId }) => { - microsoftTeams.settings.getSettings(settings => { - microsoftTeams.settings.registerOnSaveHandler(async saveEvent => { + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + microsoftTeams.pages.config.getConfig(settings => { + microsoftTeams.pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || channelId === undefined || channelName === undefined || @@ -99,7 +102,8 @@ export const useConfigurationCreate = ({ } }); - microsoftTeams.settings.setSettings({ + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + microsoftTeams.pages.config.setConfig({ entityId: configurationId, configName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ @@ -109,7 +113,7 @@ export const useConfigurationCreate = ({ channel: "{channelName}", theme: "{theme}" })}`) - } as microsoftTeams.settings.Settings); + } as microsoftTeams.pages.config.Config); saveEvent.notifySuccess(); } catch (error) { diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts index ecd21adc..9c8527fc 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts @@ -26,7 +26,9 @@ interface UseWorkspacesResultParams { } const getChannelId = (): Promise => new Promise(resolve => { - microsoftTeams.getContext(({ channelId }) => resolve(channelId as string)); + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. + microsoftTeams.app.getContext(({ channelId }) => resolve(channelId as string)); }); export const useResources = ({ diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts index 474aeb0c..5d880413 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts @@ -24,7 +24,7 @@ export const useValidate = (params: UseValidateParams): void => { const valid = isValid(params); useEffect(() => { if (params.enabled) { - microsoftTeams.settings.setValidityState(valid); + microsoftTeams.pages.config.setValidityState(valid); } }, [valid, params.enabled]); }; diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts index e4bf7b17..8a53b45e 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts @@ -14,7 +14,7 @@ export const useConfigurationDelete = ({ configurationId, isInitialized }: UseCo useEffect(() => { if (isInitialized) { - microsoftTeams.settings.registerOnRemoveHandler(async removeEvent => { + microsoftTeams.pages.config.registerOnRemoveHandler(async removeEvent => { try { await deleteConfiguration(configurationId); removeEvent.notifySuccess(); diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts index a04302c3..afa6978d 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts @@ -61,12 +61,14 @@ export const useConfigurationUpdate = ({ useEffect(() => { if (isInitialized) { - microsoftTeams.getContext(({ + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. + microsoftTeams.app.getContext(({ channelId, channelName, tid: tenantId }) => { - microsoftTeams.settings.registerOnSaveHandler(async saveEvent => { + microsoftTeams.pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || channelId === undefined || channelName === undefined || @@ -90,7 +92,8 @@ export const useConfigurationUpdate = ({ } }); - microsoftTeams.settings.setSettings({ + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + microsoftTeams.pages.config.setConfig({ entityId: configurationId, configName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ @@ -100,7 +103,7 @@ export const useConfigurationUpdate = ({ channel: "{channelName}", theme: "{theme}" })}`) - } as microsoftTeams.settings.Settings); + } as microsoftTeams.pages.config.Config); saveEvent.notifySuccess(); } catch (error) { diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts index 4e5e5f63..2ac42439 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts @@ -30,7 +30,7 @@ export const useValidate = (params: UseValidateParams): void => { const valid = isValid(params); useEffect(() => { if (params.enabled) { - microsoftTeams.settings.setValidityState(valid); + microsoftTeams.pages.config.setValidityState(valid); } }, [valid, params.enabled]); }; diff --git a/src/client/containers/LoginContainer/hooks/useLogin.ts b/src/client/containers/LoginContainer/hooks/useLogin.ts index 12bee1e0..43d61a01 100644 --- a/src/client/containers/LoginContainer/hooks/useLogin.ts +++ b/src/client/containers/LoginContainer/hooks/useLogin.ts @@ -26,6 +26,7 @@ export const useLogin = ({ onSuccess }: UseLoginParams): UseLoginResult => { const [loginError, setError] = useState(); const login = useCallback( + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. () => microsoftTeams.authentication.authenticate({ height: 476, successCallback: onSuccess, diff --git a/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx b/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx index cabbb0fe..752b1664 100644 --- a/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx +++ b/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx @@ -12,7 +12,8 @@ export const ZeplinAuthEndContainer: FunctionComponent = () => { } = useRouter(); useEffect(() => { - microsoftTeams.initialize(() => { + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + microsoftTeams.app.initialize(() => { if (error) { microsoftTeams.authentication.notifyFailure(String(error)); return; diff --git a/src/client/hooks/useInitialize.ts b/src/client/hooks/useInitialize.ts index 58c5b228..23fc5612 100644 --- a/src/client/hooks/useInitialize.ts +++ b/src/client/hooks/useInitialize.ts @@ -12,8 +12,9 @@ interface UseInitializeResult { export const useInitialize = ({ onSuccess }: UseInitializeParams = {}): UseInitializeResult => { const [isInitializeLoading, setIsInitializeLoading] = useState(true); useEffect(() => { - microsoftTeams.initialize(() => { - microsoftTeams.appInitialization.notifySuccess(); + // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. + microsoftTeams.app.initialize(() => { + microsoftTeams.app.notifySuccess(); setIsInitializeLoading(false); onSuccess?.(); }); diff --git a/src/server/services/webhookEventService/webhookEventService.test.ts b/src/server/services/webhookEventService/webhookEventService.test.ts index 693a01bd..488f80dd 100644 --- a/src/server/services/webhookEventService/webhookEventService.test.ts +++ b/src/server/services/webhookEventService/webhookEventService.test.ts @@ -52,16 +52,18 @@ interface EventArrivedParams { payload: unknown; } -const getExampleEvent = ({ resourceId = "resource-id", timestamp = 1 } = {}): WebhookEvent => ({ +const getExampleEvent = ({ resourceId = "resource-id", timestamp = 1 } = {}): WebhookEvent => (({ event: "project.color", timestamp, + resource: { id: resourceId } -}) as WebhookEvent; +}) as WebhookEvent); -const getExampleArrivedEventParams = ({ resourceId = "resource-id", timestamp = 1 } = {}): EventArrivedParams => ({ +const getExampleArrivedEventParams = ({ resourceId = "resource-id", timestamp = 1 } = {}): EventArrivedParams => (({ deliveryId: "delivery-id", + payload: { event: "project.color", timestamp, @@ -69,7 +71,7 @@ const getExampleArrivedEventParams = ({ resourceId = "resource-id", timestamp = id: resourceId } } -}) as EventArrivedParams; +}) as EventArrivedParams); const expectedGroupingKey = `webhook-id:others`; const expectedJobId = "delivery-id"; From 901b0efd7c76b25e5606baa3334c42f8607362a8 Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 17:11:14 +0300 Subject: [PATCH 02/11] chore: migrate `hooks/` --- src/client/hooks/useInitialize.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/client/hooks/useInitialize.ts b/src/client/hooks/useInitialize.ts index 23fc5612..eddc2c1d 100644 --- a/src/client/hooks/useInitialize.ts +++ b/src/client/hooks/useInitialize.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { app } from "@microsoft/teams-js"; interface UseInitializeParams { onSuccess?: () => void; @@ -12,9 +12,8 @@ interface UseInitializeResult { export const useInitialize = ({ onSuccess }: UseInitializeParams = {}): UseInitializeResult => { const [isInitializeLoading, setIsInitializeLoading] = useState(true); useEffect(() => { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - microsoftTeams.app.initialize(() => { - microsoftTeams.app.notifySuccess(); + app.initialize().then(() => { + app.notifySuccess(); setIsInitializeLoading(false); onSuccess?.(); }); From 9d52452b8730025eb3c82d42ba8fee3adcd98dc0 Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 17:15:22 +0300 Subject: [PATCH 03/11] chore: migrate `containers/ConfigurationCreateContainer/hooks/` --- .../hooks/useConfigurationCreate.ts | 31 ++++++++++--------- .../hooks/useResources.ts | 13 +++++--- .../hooks/useValidate.ts | 4 +-- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts index 2404ef66..449ee7b0 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts @@ -1,6 +1,6 @@ import { useEffect } from "react"; import { useMutation } from "react-query"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { app, pages } from "@microsoft/teams-js"; import { requester, url } from "../../../lib"; import { Resource, WebhookEventType } from "../../../constants"; @@ -61,16 +61,18 @@ export const useConfigurationCreate = ({ useEffect(() => { if (isInitialized) { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. - microsoftTeams.app.getContext(({ - channelId, - channelName, - tid: tenantId - }) => { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - microsoftTeams.pages.config.getConfig(settings => { - microsoftTeams.pages.config.registerOnSaveHandler(async saveEvent => { + app.getContext().then(({ + channel, + user + }: app.Context) => { + if (!channel || !user || !user.tenant) { + // TODO: Handle undefined + return; + } + const { displayName: channelName, id: channelId } = channel; + const { tenant: { id: tenantId } } = user; + pages.getConfig().then(settings => { + pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || channelId === undefined || channelName === undefined || @@ -102,10 +104,9 @@ export const useConfigurationCreate = ({ } }); - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - microsoftTeams.pages.config.setConfig({ + await pages.config.setConfig({ entityId: configurationId, - configName: resource.name, + suggestedDisplayName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ id: configurationId, resourceName: resource.name, @@ -113,7 +114,7 @@ export const useConfigurationCreate = ({ channel: "{channelName}", theme: "{theme}" })}`) - } as microsoftTeams.pages.config.Config); + }); saveEvent.notifySuccess(); } catch (error) { diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts index 9c8527fc..2609e9a6 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useResources.ts @@ -1,6 +1,6 @@ import { useQuery } from "react-query"; import { INTERNAL_SERVER_ERROR, UNAUTHORIZED } from "http-status-codes"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { app } from "@microsoft/teams-js"; import { requester } from "../../../lib"; import { Project, Styleguide } from "../../../constants"; @@ -25,10 +25,13 @@ interface UseWorkspacesResultParams { onStyleguidesSuccess: (styleguides: Styleguide[]) => void; } -const getChannelId = (): Promise => new Promise(resolve => { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. - microsoftTeams.app.getContext(({ channelId }) => resolve(channelId as string)); +const getChannelId = (): Promise => new Promise((resolve, reject) => { + app.getContext().then(({ channel }) => { + if (channel) { + resolve(channel.id); + } + reject(new Error("Channel is not defined")); + }); }); export const useResources = ({ diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts index 5d880413..80afbe63 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useValidate.ts @@ -1,5 +1,5 @@ import { useEffect } from "react"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { pages } from "@microsoft/teams-js"; import { Resource, resourceBasedEvents, WebhookEventType } from "../../../constants"; @@ -24,7 +24,7 @@ export const useValidate = (params: UseValidateParams): void => { const valid = isValid(params); useEffect(() => { if (params.enabled) { - microsoftTeams.pages.config.setValidityState(valid); + pages.config.setValidityState(valid); } }, [valid, params.enabled]); }; From 5e857a52e31ed26fe93328071a217e43dae2b19d Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 17:27:26 +0300 Subject: [PATCH 04/11] chore: migrate `containers/ConfigurationUpdateContainer/hooks/` --- .../hooks/useConfigurationDelete.ts | 4 +-- .../hooks/useConfigurationUpdate.ts | 26 ++++++++++--------- .../hooks/useValidate.ts | 4 +-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts index 8a53b45e..33585d1b 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationDelete.ts @@ -1,6 +1,6 @@ import { useEffect } from "react"; import { useMutation } from "react-query"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { pages } from "@microsoft/teams-js"; import { requester } from "../../../lib"; @@ -14,7 +14,7 @@ export const useConfigurationDelete = ({ configurationId, isInitialized }: UseCo useEffect(() => { if (isInitialized) { - microsoftTeams.pages.config.registerOnRemoveHandler(async removeEvent => { + pages.config.registerOnRemoveHandler(async removeEvent => { try { await deleteConfiguration(configurationId); removeEvent.notifySuccess(); diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts index afa6978d..7738b2cf 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts @@ -1,6 +1,6 @@ import { useEffect } from "react"; import { useMutation } from "react-query"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { app, pages } from "@microsoft/teams-js"; import { requester, url } from "../../../lib"; import { Resource, WebhookEventType } from "../../../constants"; @@ -61,14 +61,17 @@ export const useConfigurationUpdate = ({ useEffect(() => { if (isInitialized) { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - // TODO: Change the context interface, for more info, please refer to https://aka.ms/teamsfx-context-mapping. - microsoftTeams.app.getContext(({ - channelId, - channelName, - tid: tenantId + app.getContext().then(({ + channel, + user }) => { - microsoftTeams.pages.config.registerOnSaveHandler(async saveEvent => { + if (!channel || !user || !user.tenant) { + // TODO: Handle undefined + return; + } + const { id: channelId, displayName: channelName } = channel; + const { tenant: { id: tenantId } } = user; + pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || channelId === undefined || channelName === undefined || @@ -92,10 +95,9 @@ export const useConfigurationUpdate = ({ } }); - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - microsoftTeams.pages.config.setConfig({ + await pages.config.setConfig({ entityId: configurationId, - configName: resource.name, + suggestedDisplayName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ id: configurationId, resourceName: resource.name, @@ -103,7 +105,7 @@ export const useConfigurationUpdate = ({ channel: "{channelName}", theme: "{theme}" })}`) - } as microsoftTeams.pages.config.Config); + }); saveEvent.notifySuccess(); } catch (error) { diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts index 2ac42439..43de2b3c 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useValidate.ts @@ -1,5 +1,5 @@ import { useEffect } from "react"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { pages } from "@microsoft/teams-js"; import { Resource, resourceBasedEvents, WebhookEventType } from "../../../constants"; interface UseValidateParams { @@ -30,7 +30,7 @@ export const useValidate = (params: UseValidateParams): void => { const valid = isValid(params); useEffect(() => { if (params.enabled) { - microsoftTeams.pages.config.setValidityState(valid); + pages.config.setValidityState(valid); } }, [valid, params.enabled]); }; From c2b411a0cc926714d8298c2d65aac00db69aa09f Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 17:34:20 +0300 Subject: [PATCH 05/11] chore: migrate `containers/ZeplinAuthEndContainer/` --- .../ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx b/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx index 752b1664..f6320a1b 100644 --- a/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx +++ b/src/client/containers/ZeplinAuthEndContainer/ZeplinAuthEndContainer.tsx @@ -1,6 +1,6 @@ import React, { FunctionComponent, useEffect } from "react"; import { useRouter } from "next/router"; -import * as microsoftTeams from "@microsoft/teams-js"; +import { app, authentication } from "@microsoft/teams-js"; import { Loader } from "@fluentui/react-northstar"; export const ZeplinAuthEndContainer: FunctionComponent = () => { @@ -12,14 +12,13 @@ export const ZeplinAuthEndContainer: FunctionComponent = () => { } = useRouter(); useEffect(() => { - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - microsoftTeams.app.initialize(() => { + app.initialize().then(() => { if (error) { - microsoftTeams.authentication.notifyFailure(String(error)); + authentication.notifyFailure(String(error)); return; } - microsoftTeams.authentication.notifySuccess(code as string); + authentication.notifySuccess(code as string); }); }, []); From 6f1a83d57198d1724259071cd51b90466c62b084 Mon Sep 17 00:00:00 2001 From: melsener Date: Fri, 29 Mar 2024 17:54:19 +0300 Subject: [PATCH 06/11] chore: migrate `containers/LoginContainer` --- .../LoginContainer/hooks/useLogin.ts | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/client/containers/LoginContainer/hooks/useLogin.ts b/src/client/containers/LoginContainer/hooks/useLogin.ts index 43d61a01..6cc9a926 100644 --- a/src/client/containers/LoginContainer/hooks/useLogin.ts +++ b/src/client/containers/LoginContainer/hooks/useLogin.ts @@ -1,4 +1,4 @@ -import * as microsoftTeams from "@microsoft/teams-js"; +import { authentication } from "@microsoft/teams-js"; import { useCallback, useState } from "react"; interface UseLoginParams { @@ -26,13 +26,19 @@ export const useLogin = ({ onSuccess }: UseLoginParams): UseLoginResult => { const [loginError, setError] = useState(); const login = useCallback( - // TODO: Convert callback to promise, for more info, please refer to https://aka.ms/teamsfx-callback-to-promise. - () => microsoftTeams.authentication.authenticate({ - height: 476, - successCallback: onSuccess, - failureCallback: value => setError(errorToText(value)), - url: "/api/auth/authorize" - }), + async () => { + try { + // TODO: Check output + const authenticateResult = await authentication.authenticate({ + height: 476, + url: "/api/auth/authorize" + }); + onSuccess(); + return authenticateResult; + } catch (err: unknown) { + setError(errorToText((err as Error)?.message || "Authenticate Error")); + } + }, [] ); From 4f96122aa7f83bb89834345e4f230c5cbe037397 Mon Sep 17 00:00:00 2001 From: melsener Date: Mon, 1 Apr 2024 11:08:12 +0300 Subject: [PATCH 07/11] build: Update SDK and manifest version --- package-lock.json | 20 +++++++++++++------- package.json | 2 +- src/package/manifest.template.json | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 74e81c7e..3ebd5110 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@fluentui/react-northstar": "^0.50.0", "@hapi/joi": "^17.1.1", - "@microsoft/teams-js": "^1.11.0", + "@microsoft/teams-js": "^2.19.0", "@newrelic/pino-enricher": "^1.1.1", "@sentry/browser": "^5.22.3", "@sentry/node": "^5.22.3", @@ -2512,9 +2512,12 @@ } }, "node_modules/@microsoft/teams-js": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-1.11.0.tgz", - "integrity": "sha512-5utMOMWXdNq0cV8hGIZEUpUVChoasoYjBOItgFIKE2a4vavmzlhra+GNXMdpvlYlv6/r7ORtVCQUDFJvPTVj2Q==" + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-2.19.0.tgz", + "integrity": "sha512-QpAK8JO6s9D5qOiW//fwS4bUgzhLr1GDxHCRw+BEs9Uuw5Z9YhwMClhtFlI5P7HlH5SFC4QSsh44HaV31ORXJA==", + "dependencies": { + "debug": "^4.3.3" + } }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.1", @@ -18385,9 +18388,12 @@ } }, "@microsoft/teams-js": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-1.11.0.tgz", - "integrity": "sha512-5utMOMWXdNq0cV8hGIZEUpUVChoasoYjBOItgFIKE2a4vavmzlhra+GNXMdpvlYlv6/r7ORtVCQUDFJvPTVj2Q==" + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-2.19.0.tgz", + "integrity": "sha512-QpAK8JO6s9D5qOiW//fwS4bUgzhLr1GDxHCRw+BEs9Uuw5Z9YhwMClhtFlI5P7HlH5SFC4QSsh44HaV31ORXJA==", + "requires": { + "debug": "^4.3.3" + } }, "@mongodb-js/saslprep": { "version": "1.1.1", diff --git a/package.json b/package.json index 56a388ae..137acf16 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "dependencies": { "@fluentui/react-northstar": "^0.50.0", "@hapi/joi": "^17.1.1", - "@microsoft/teams-js": "^2.0.0", + "@microsoft/teams-js": "^2.19.0", "@newrelic/pino-enricher": "^1.1.1", "@sentry/browser": "^5.22.3", "@sentry/node": "^5.22.3", diff --git a/src/package/manifest.template.json b/src/package/manifest.template.json index 2e85d40a..4d8e72b1 100644 --- a/src/package/manifest.template.json +++ b/src/package/manifest.template.json @@ -1,6 +1,6 @@ { - "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.6/MicrosoftTeams.schema.json", - "manifestVersion": "1.6", + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.12/MicrosoftTeams.schema.json", + "manifestVersion": "1.12", "id": "${NEXT_PRIVATE_APPLICATION_ID}", "version": "${NEXT_PUBLIC_VERSION}", "packageName": "zeplin", From d41866258bfd4af202402e7355f4044e4168475a Mon Sep 17 00:00:00 2001 From: melsener Date: Mon, 1 Apr 2024 12:03:58 +0300 Subject: [PATCH 08/11] fix: Change login flow --- .../LoginContainer/LoginContainer.tsx | 50 ++++++++++++++----- .../containers/LoginContainer/hooks/index.ts | 1 - .../LoginContainer/hooks/useLogin.ts | 46 ----------------- 3 files changed, 38 insertions(+), 59 deletions(-) delete mode 100644 src/client/containers/LoginContainer/hooks/index.ts delete mode 100644 src/client/containers/LoginContainer/hooks/useLogin.ts diff --git a/src/client/containers/LoginContainer/LoginContainer.tsx b/src/client/containers/LoginContainer/LoginContainer.tsx index 3d7e7201..32bf595a 100644 --- a/src/client/containers/LoginContainer/LoginContainer.tsx +++ b/src/client/containers/LoginContainer/LoginContainer.tsx @@ -1,12 +1,22 @@ -import React, { FunctionComponent } from "react"; +import React, { FunctionComponent, useState } from "react"; import { useInitialize } from "../../hooks"; -import { useLogin } from "./hooks"; +import { authentication } from "@microsoft/teams-js"; import { Login } from "./components"; import { Loader } from "@fluentui/react-northstar"; import { useRouter } from "next/router"; import { url, requester, storage } from "../../lib"; +const errorToText = (error?: string): string => { + switch (error) { + case "CancelledByUser": + case "access_denied": + return "You need to authorize Microsoft Teams app to connect your Zeplin projects and styleguides."; + default: + return "Authorization failed due to an API related connectivity issue. Please retry logging in."; + } +}; + export const LoginContainer: FunctionComponent = () => { const { query: { @@ -20,15 +30,30 @@ export const LoginContainer: FunctionComponent = () => { } = useRouter(); const { isInitializeLoading } = useInitialize(); - const [login, { loginError }] = useLogin({ - onSuccess: async (code?: string) => { - try { - const { accessToken, refreshToken } = await requester.createAuthToken(String(code)); - storage.setAccessToken(accessToken); - storage.setRefreshToken(refreshToken); - } catch (err) { - // TODO: log to sentry + const [loginError, setLoginError] = useState(); + + async function authenticate() { + try { + const code = await authentication.authenticate({ + height: 476, + url: "/api/auth/authorize" + }); + return code; + } catch (err) { + setLoginError(errorToText((err as unknown as Error).message)); + } + } + + async function login() { + try { + const code = await authenticate(); + if (!code) { + throw Error("Authentication code is missing"); } + const { accessToken, refreshToken } = await requester.createAuthToken(String(code)); + storage.setAccessToken(accessToken); + storage.setRefreshToken(refreshToken); + replace(id ? url.getConfigurationUpdateUrl({ channel: channel as string, @@ -38,12 +63,13 @@ export const LoginContainer: FunctionComponent = () => { theme: theme as string }) : url.getConfigurationCreateUrl({ - channel: channel as string, theme: theme as string })); + } catch (err) { + // TODO: log to sentry } - }); + } if (isInitializeLoading) { return ; diff --git a/src/client/containers/LoginContainer/hooks/index.ts b/src/client/containers/LoginContainer/hooks/index.ts deleted file mode 100644 index c07ce0b2..00000000 --- a/src/client/containers/LoginContainer/hooks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useLogin"; diff --git a/src/client/containers/LoginContainer/hooks/useLogin.ts b/src/client/containers/LoginContainer/hooks/useLogin.ts deleted file mode 100644 index 6cc9a926..00000000 --- a/src/client/containers/LoginContainer/hooks/useLogin.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { authentication } from "@microsoft/teams-js"; -import { useCallback, useState } from "react"; - -interface UseLoginParams { - onSuccess: (code?: string) => Promise; -} - -type UseLoginResult = [ - () => void, - { - loginError?: string; - } -] - -const errorToText = (error?: string): string => { - switch (error) { - case "CancelledByUser": - case "access_denied": - return "You need to authorize Microsoft Teams app to connect your Zeplin projects and styleguides."; - default: - return "Authorization failed due to an API related connectivity issue. Please retry logging in."; - } -}; - -export const useLogin = ({ onSuccess }: UseLoginParams): UseLoginResult => { - const [loginError, setError] = useState(); - - const login = useCallback( - async () => { - try { - // TODO: Check output - const authenticateResult = await authentication.authenticate({ - height: 476, - url: "/api/auth/authorize" - }); - onSuccess(); - return authenticateResult; - } catch (err: unknown) { - setError(errorToText((err as Error)?.message || "Authenticate Error")); - } - }, - [] - ); - - return [login, { loginError }]; -}; From a8df13cac1b66515740262603a5f833c01ea2149 Mon Sep 17 00:00:00 2001 From: melsener Date: Mon, 1 Apr 2024 14:59:19 +0300 Subject: [PATCH 09/11] fix: Remove early return and todo --- .../hooks/useConfigurationCreate.ts | 8 ++------ .../hooks/useConfigurationUpdate.ts | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts index 449ee7b0..387a76e7 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts @@ -65,12 +65,8 @@ export const useConfigurationCreate = ({ channel, user }: app.Context) => { - if (!channel || !user || !user.tenant) { - // TODO: Handle undefined - return; - } - const { displayName: channelName, id: channelId } = channel; - const { tenant: { id: tenantId } } = user; + const { displayName: channelName, id: channelId } = channel ?? {}; + const { tenant: { id: tenantId } = { id: undefined } } = user ?? {}; pages.getConfig().then(settings => { pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts index 7738b2cf..ea71b74d 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts @@ -65,12 +65,8 @@ export const useConfigurationUpdate = ({ channel, user }) => { - if (!channel || !user || !user.tenant) { - // TODO: Handle undefined - return; - } - const { id: channelId, displayName: channelName } = channel; - const { tenant: { id: tenantId } } = user; + const { id: channelId, displayName: channelName } = channel ?? {}; + const { tenant: { id: tenantId } = { id: undefined } } = user ?? {}; pages.config.registerOnSaveHandler(async saveEvent => { if (tenantId === undefined || channelId === undefined || From 77a94220401b9b0fa8c70659ff956ad6fd65d2ca Mon Sep 17 00:00:00 2001 From: melsener Date: Thu, 20 Jun 2024 15:51:53 +0300 Subject: [PATCH 10/11] fix: fix config parameters --- .../hooks/useConfigurationCreate.ts | 5 +++-- .../hooks/useConfigurationUpdate.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts index 387a76e7..fb81cae5 100644 --- a/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts +++ b/src/client/containers/ConfigurationCreateContainer/hooks/useConfigurationCreate.ts @@ -100,9 +100,10 @@ export const useConfigurationCreate = ({ } }); + // Although there is no 'configName' in the interface, not using it results in empty config name in edit connector menu await pages.config.setConfig({ entityId: configurationId, - suggestedDisplayName: resource.name, + configName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ id: configurationId, resourceName: resource.name, @@ -110,7 +111,7 @@ export const useConfigurationCreate = ({ channel: "{channelName}", theme: "{theme}" })}`) - }); + } as pages.InstanceConfig); saveEvent.notifySuccess(); } catch (error) { diff --git a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts index ea71b74d..95abebf6 100644 --- a/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts +++ b/src/client/containers/ConfigurationUpdateContainer/hooks/useConfigurationUpdate.ts @@ -91,9 +91,10 @@ export const useConfigurationUpdate = ({ } }); + // Although there is no 'configName' in the interface, not using it results in empty config name in edit connector menu await pages.config.setConfig({ entityId: configurationId, - suggestedDisplayName: resource.name, + configName: resource.name, contentUrl: decodeURI(`${window.location.origin}${url.getHomeUrl({ id: configurationId, resourceName: resource.name, @@ -101,7 +102,7 @@ export const useConfigurationUpdate = ({ channel: "{channelName}", theme: "{theme}" })}`) - }); + } as pages.InstanceConfig); saveEvent.notifySuccess(); } catch (error) { From 36aa05c5e86e85bd2132165944f7b6ed7e39d57c Mon Sep 17 00:00:00 2001 From: melsener Date: Mon, 4 Nov 2024 16:13:09 +0300 Subject: [PATCH 11/11] chore: add small differentiator for debug --- .../components/ConfigurationCreate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/containers/ConfigurationCreateContainer/components/ConfigurationCreate.tsx b/src/client/containers/ConfigurationCreateContainer/components/ConfigurationCreate.tsx index d11fa450..839233de 100644 --- a/src/client/containers/ConfigurationCreateContainer/components/ConfigurationCreate.tsx +++ b/src/client/containers/ConfigurationCreateContainer/components/ConfigurationCreate.tsx @@ -135,7 +135,7 @@ export const ConfigurationCreate: FunctionComponent = {errorMessage && ()} - Select the events you want to get a message for: + Select the events you would like to get a message for: