diff --git a/apps/meteor/app/ui-message/client/ActionManager.js b/apps/meteor/app/ui-message/client/ActionManager.js index ebe9d1aed093..220b786c6540 100644 --- a/apps/meteor/app/ui-message/client/ActionManager.js +++ b/apps/meteor/app/ui-message/client/ActionManager.js @@ -75,9 +75,7 @@ export const handlePayloadUserInteraction = (type, { /* appId,*/ triggerId, ...d return UIKitInteractionTypes.ERRORS; } - if ( - [UIKitInteractionTypes.BANNER_UPDATE, UIKitInteractionTypes.MODAL_UPDATE, UIKitInteractionTypes.CONTEXTUAL_BAR_UPDATE].includes(type) - ) { + if ([UIKitInteractionTypes.BANNER_UPDATE, UIKitInteractionTypes.CONTEXTUAL_BAR_UPDATE].includes(type)) { events.emit(viewId, { type, triggerId, @@ -88,14 +86,19 @@ export const handlePayloadUserInteraction = (type, { /* appId,*/ triggerId, ...d return type; } - if ([UIKitInteractionTypes.MODAL_OPEN].includes(type)) { + if (type === UIKitInteractionTypes.MODAL_OPEN) { const instance = imperativeModal.open({ component: UiKitModal, props: { - triggerId, - viewId, - appId, - ...data, + view: { + viewId: data.view.id, + appId: data.view.appId, + blocks: data.view.blocks, + title: data.view.title, + close: data.view.close, + showIcon: data.view.showIcon, + submit: data.view.submit, + }, }, }); @@ -106,7 +109,23 @@ export const handlePayloadUserInteraction = (type, { /* appId,*/ triggerId, ...d }, }); - return UIKitInteractionTypes.MODAL_OPEN; + return type; + } + + if (type === UIKitInteractionTypes.MODAL_UPDATE) { + events.emit(viewId, { + type, + triggerId, + viewId: data.view.id, + appId: data.view.appId, + blocks: data.view.blocks, + title: data.view.title, + close: data.view.close, + showIcon: data.view.showIcon, + submit: data.view.submit, + }); + + return type; } if ([UIKitInteractionTypes.CONTEXTUAL_BAR_OPEN].includes(type)) { diff --git a/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx b/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx index c5a265203c8a..d2c3493f4695 100644 --- a/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx +++ b/apps/meteor/client/UIKit/hooks/useUIKitHandleAction.tsx @@ -4,7 +4,7 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useUiKitActionManager } from '../../hooks/useUiKitActionManager'; -const useUIKitHandleAction = (state: S): ((event: UIKitActionEvent) => Promise) => { +const useUIKitHandleAction = (state: S): ((event: UIKitActionEvent) => Promise) => { const actionManager = useUiKitActionManager(); return useMutableCallback(async ({ blockId, value, appId, actionId }) => { if (!appId) { diff --git a/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx b/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx index 561852a06527..2573d2868607 100644 --- a/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx +++ b/apps/meteor/client/UIKit/hooks/useUIKitHandleClose.tsx @@ -8,10 +8,7 @@ import { useUiKitActionManager } from '../../hooks/useUiKitActionManager'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const emptyFn = (_error: any, _result: UIKitInteractionType | void): void => undefined; -const useUIKitHandleClose = ( - state: S, - fn = emptyFn, -): (() => Promise) => { +const useUIKitHandleClose = (state: S, fn = emptyFn): (() => Promise) => { const actionManager = useUiKitActionManager(); const dispatchToastMessage = useToastMessageDispatch(); return useMutableCallback(() => diff --git a/apps/meteor/client/UIKit/hooks/useUIKitStateManager.tsx b/apps/meteor/client/UIKit/hooks/useUIKitStateManager.tsx index 738b337e3c91..7c582800f40d 100644 --- a/apps/meteor/client/UIKit/hooks/useUIKitStateManager.tsx +++ b/apps/meteor/client/UIKit/hooks/useUIKitStateManager.tsx @@ -5,7 +5,9 @@ import { useEffect, useState } from 'react'; import { useUiKitActionManager } from '../../hooks/useUiKitActionManager'; -const useUIKitStateManager = (initialState: S): S => { +export function useUIKitStateManager(initialState: UiKit.ModalView): any; +export function useUIKitStateManager(initialState: S): S; +export function useUIKitStateManager(initialState: S): S { const actionManager = useUiKitActionManager(); const [state, setState] = useSafely(useState(initialState)); @@ -31,6 +33,4 @@ const useUIKitStateManager = (initialSta }, [actionManager, setState, viewId]); return state; -}; - -export { useUIKitStateManager }; +} diff --git a/apps/meteor/client/lib/banners.ts b/apps/meteor/client/lib/banners.ts index df38e7f16dcd..91185450a21a 100644 --- a/apps/meteor/client/lib/banners.ts +++ b/apps/meteor/client/lib/banners.ts @@ -15,7 +15,7 @@ export type LegacyBannerPayload = { onClose?: () => Promise | void; }; -type BannerPayload = LegacyBannerPayload | UiKit.BannerPayload; +type BannerPayload = LegacyBannerPayload | UiKit.BannerView; export const isLegacyPayload = (payload: BannerPayload): payload is LegacyBannerPayload => !('blocks' in payload); @@ -35,7 +35,7 @@ export const open = (payload: BannerPayload): void => { if (isLegacyPayload(_payload)) { return _payload.id === (payload as LegacyBannerPayload).id; } - return _payload.viewId === (payload as UiKit.BannerPayload).viewId; + return _payload.viewId === (payload as UiKit.BannerView).viewId; }); if (index === -1) { diff --git a/apps/meteor/client/views/banners/BannerRegion.tsx b/apps/meteor/client/views/banners/BannerRegion.tsx index f457d2b38e8f..91a1737f1ca8 100644 --- a/apps/meteor/client/views/banners/BannerRegion.tsx +++ b/apps/meteor/client/views/banners/BannerRegion.tsx @@ -24,7 +24,7 @@ const BannerRegion = (): ReactElement | null => { return ; } - return ; + return ; }; export default BannerRegion; diff --git a/apps/meteor/client/views/banners/UiKitBanner.tsx b/apps/meteor/client/views/banners/UiKitBanner.tsx index 8e306c98e633..4c54ac0abb8a 100644 --- a/apps/meteor/client/views/banners/UiKitBanner.tsx +++ b/apps/meteor/client/views/banners/UiKitBanner.tsx @@ -16,11 +16,11 @@ import * as banners from '../../lib/banners'; bannerParser.mrkdwn = ({ text }): ReactElement => ; type UiKitBannerProps = { - payload: UiKit.BannerPayload; + view: UiKit.BannerView; }; -const UiKitBanner = ({ payload }: UiKitBannerProps) => { - const state = useUIKitStateManager(payload); +const UiKitBanner = ({ view }: UiKitBannerProps) => { + const state = useUIKitStateManager(view); const icon = useMemo(() => { if (state.icon) { diff --git a/apps/meteor/client/views/banners/hooks/useCloudAnnouncementBanners.ts b/apps/meteor/client/views/banners/hooks/useCloudAnnouncementBanners.ts index 0fc675284b61..9828766a47ef 100644 --- a/apps/meteor/client/views/banners/hooks/useCloudAnnouncementBanners.ts +++ b/apps/meteor/client/views/banners/hooks/useCloudAnnouncementBanners.ts @@ -6,7 +6,7 @@ import * as banners from '../../../lib/banners'; const isBannerCarryingAnnouncement = ( announcement: Serialized, -): announcement is Serialized => announcement.surface === 'banner'; +): announcement is Serialized => announcement.surface === 'banner'; export const useCloudAnnouncementBanners = () => { const queryResult = useCloudAnnouncementsQuery({ diff --git a/apps/meteor/client/views/banners/hooks/useRemoteBanners.ts b/apps/meteor/client/views/banners/hooks/useRemoteBanners.ts index ddd2b5ab651a..ebed89e06037 100644 --- a/apps/meteor/client/views/banners/hooks/useRemoteBanners.ts +++ b/apps/meteor/client/views/banners/hooks/useRemoteBanners.ts @@ -22,7 +22,7 @@ export const useRemoteBanners = () => { const { signal } = controller; - const mapBanner = (banner: Serialized): UiKit.BannerPayload => ({ + const mapBanner = (banner: Serialized): UiKit.BannerView => ({ ...banner.view, viewId: banner.view.viewId || banner._id, }); diff --git a/apps/meteor/client/views/modal/hooks/useCloudAnnouncementModals.tsx b/apps/meteor/client/views/modal/hooks/useCloudAnnouncementModals.tsx index 1177c14e08a0..cb0247b95d0c 100644 --- a/apps/meteor/client/views/modal/hooks/useCloudAnnouncementModals.tsx +++ b/apps/meteor/client/views/modal/hooks/useCloudAnnouncementModals.tsx @@ -1,5 +1,4 @@ -import type { IUIKitSurface } from '@rocket.chat/apps-engine/definition/uikit'; -import type { Cloud, Serialized } from '@rocket.chat/core-typings'; +import type { Cloud, Serialized, UiKit } from '@rocket.chat/core-typings'; import { useSetModal } from '@rocket.chat/ui-contexts'; import React, { useEffect } from 'react'; @@ -8,7 +7,7 @@ import UiKitModal from '../uikit/UiKitModal'; const isModalCarryingAnnouncement = ( announcement: Serialized, -): announcement is Serialized & { surface: 'modal'; view: IUIKitSurface } => announcement.surface === 'modal'; +): announcement is Serialized => announcement.surface === 'modal'; export const useCloudAnnouncementModals = () => { const queryResult = useCloudAnnouncementsQuery({ @@ -23,16 +22,7 @@ export const useCloudAnnouncementModals = () => { } for (const announcement of queryResult.data) { - setModal( - , - ); + setModal(); } }, [queryResult.data, queryResult.isSuccess, setModal]); }; diff --git a/apps/meteor/client/views/modal/uikit/UiKitModal.tsx b/apps/meteor/client/views/modal/uikit/UiKitModal.tsx index 5baad8543769..5319f85bb1a5 100644 --- a/apps/meteor/client/views/modal/uikit/UiKitModal.tsx +++ b/apps/meteor/client/views/modal/uikit/UiKitModal.tsx @@ -1,9 +1,8 @@ -import type { IUIKitSurface } from '@rocket.chat/apps-engine/definition/uikit'; import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer'; +import type { UiKit } from '@rocket.chat/core-typings'; import { useDebouncedCallback, useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { UiKitContext } from '@rocket.chat/fuselage-ui-kit'; import { MarkupInteractionContext } from '@rocket.chat/gazzodown'; -import type { LayoutBlock } from '@rocket.chat/ui-kit'; import type { ContextType, ReactEventHandler } from 'react'; import React from 'react'; @@ -14,21 +13,16 @@ import ModalBlock from './ModalBlock'; import { useValues } from './hooks/useValues'; type UiKitModalProps = { - viewId: string; - type: 'errors' | string; - appId: string; - mid: string; - errors: Record; - view: IUIKitSurface; + view: UiKit.ModalView; }; -const UiKitModal = (props: UiKitModalProps) => { +const UiKitModal = ({ view }: UiKitModalProps) => { const actionManager = useUiKitActionManager(); - const state = useUIKitStateManager(props as any); + const state = useUIKitStateManager(view); - const { appId, viewId, mid: _mid, errors, view } = state; + const { appId, errors, viewId, blocks } = state; - const [values, updateValues] = useValues(view.blocks as LayoutBlock[]); + const [values, updateValues] = useValues(blocks); const groupStateByBlockId = (values: { value: unknown; blockId: string }[]) => Object.entries(values).reduce((obj, [key, { blockId, value }]) => { @@ -63,7 +57,7 @@ const UiKitModal = (props: UiKitModalProps) => { // TODO: this structure is atrociously wrong; we should revisit this const context: ContextType = { // @ts-expect-error Property 'mid' does not exist on type 'ActionParams'. - action: ({ actionId, appId, value, blockId, mid = _mid, dispatchActionConfig }) => { + action: ({ actionId, appId, value, blockId, mid, dispatchActionConfig }) => { if (Array.isArray(dispatchActionConfig) && dispatchActionConfig.includes('on_character_entered')) { debouncedBlockAction(actionId, appId, value, blockId, mid); } else { @@ -101,7 +95,7 @@ const UiKitModal = (props: UiKitModalProps) => { appId, payload: { view: { - ...view, + ...state, id: viewId, state: groupStateByBlockId(values), }, @@ -115,7 +109,7 @@ const UiKitModal = (props: UiKitModalProps) => { viewId, appId, view: { - ...view, + ...state, id: viewId, state: groupStateByBlockId(values), }, @@ -127,7 +121,7 @@ const UiKitModal = (props: UiKitModalProps) => { viewId, appId, view: { - ...view, + ...state, id: viewId, state: groupStateByBlockId(values), }, @@ -142,7 +136,7 @@ const UiKitModal = (props: UiKitModalProps) => { detectEmoji, }} > - + ); diff --git a/apps/meteor/server/services/nps/getAndCreateNpsSurvey.ts b/apps/meteor/server/services/nps/getAndCreateNpsSurvey.ts index dce5f7eac4ad..8e4c06941c81 100644 --- a/apps/meteor/server/services/nps/getAndCreateNpsSurvey.ts +++ b/apps/meteor/server/services/nps/getAndCreateNpsSurvey.ts @@ -10,7 +10,7 @@ type NpsSurveyData = { id: string; platform: BannerPlatform[]; roles: string[]; - survey: UiKit.BannerPayload; + survey: UiKit.BannerView; createdAt: Date; startAt: Date; expireAt: Date;