import scrollIntoView from "scroll-into-view-if-needed"; import { modText, flashElementsById, isMacOrIOS, flashElement, shiftText, } from "./helpers"; import localStorage from "./localStorage"; import { createMessage, WIDGET_ADDED, BULK_WIDGET_ADDED, WIDGET_REMOVED, BULK_WIDGET_REMOVED, } from "@appsmith/constants/messages"; import { toast } from "design-system"; import { setApiPaneConfigSelectedTabIndex } from "../actions/apiPaneActions"; import { API_EDITOR_TABS } from "../constants/ApiEditorConstants/CommonApiConstants"; import store from "../store"; /** * process the toast for undo/redo * * @param undoRedoToasts */ export const processUndoRedoToasts = ( undoRedoToasts: { isCreated: boolean; isUndo: boolean; widgetName: string | undefined; widgetId: string; }[], ) => { const { isCreated, isUndo } = undoRedoToasts[0]; const isMultipleToasts = undoRedoToasts.length > 1; const widgetName = isMultipleToasts ? `${undoRedoToasts.length}` : undoRedoToasts[0].widgetName; if (isCreated) flashElementsById( undoRedoToasts.map((toast) => toast.widgetId), 100, 1000, ); showUndoRedoToast(widgetName, isMultipleToasts, isCreated, !isUndo); }; /** * shows a toast for undo/redo * * @param widgetName * @param isMultiple * @param isCreated * @param shouldUndo * @returns */ export const showUndoRedoToast = ( widgetName: string | undefined, isMultiple: boolean, isCreated: boolean, shouldUndo: boolean, ) => { if (shouldDisallowToast(shouldUndo)) return; const actionDescription = getActionDescription(isCreated, isMultiple); const widgetText = createMessage(actionDescription, widgetName); const action = shouldUndo ? "undo" : "redo"; const actionKey = shouldUndo ? `${modText()} Z` : isMacOrIOS() ? `${modText()} ${shiftText()} Z` : `${modText()} Y`; toast.show(`${widgetText}. Press ${actionKey} to ${action}`); }; function getActionDescription(isCreated: boolean, isMultiple: boolean) { if (isCreated) return isMultiple ? BULK_WIDGET_ADDED : WIDGET_ADDED; else return isMultiple ? BULK_WIDGET_REMOVED : WIDGET_REMOVED; } /** * search the dom with id of element and scroll the page to its position * * @param id */ export const scrollWidgetIntoView = (id: string) => { const el = document.getElementById(id); if (el) scrollIntoView(el, { scrollMode: "if-needed", block: "center", inline: "center", }); }; /** * checks if toast should be shown to user or not * if the item key is true, then disallowing showing toast * * @param shouldUndo * @returns */ export function shouldDisallowToast(shouldUndo: boolean): boolean { const itemKey = shouldUndo ? "undoToastShown" : "redoToastShown"; const flag = localStorage.getItem(itemKey); if (flag === null || !flag) { localStorage.setItem(itemKey, "true"); return false; } return true; } export function highlightReplayElement(configProperties: Array = []) { const elements = configProperties .map((configProperty: string) => { const replayId = btoa(configProperty); return document.querySelector( `[data-replay-id="${replayId}"]`, ) as HTMLElement; }) .filter((el) => Boolean(el)); if (elements.length === 1) { elements[0].scrollIntoView({ behavior: "smooth" }); } elements.forEach((element) => flashElement(element)); } export function switchTab(replayId: string): boolean { if (!replayId) return false; const element = document.querySelector(`[id$="${replayId}"]`) as HTMLElement; if (!element) return false; if (element.getAttribute("data-state") == "active") return false; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const index = Object.values(API_EDITOR_TABS).indexOf(replayId); store.dispatch(setApiPaneConfigSelectedTabIndex(index)); return true; } export function expandAccordion(replayId: string): boolean { if (!replayId) return false; const element = document.querySelector( `[data-replay-id="section-${replayId}"]`, ); if (!element) return false; const accordion = element.querySelector( ".bp3-icon-chevron-down", ) as HTMLElement; if (!accordion) return false; accordion.click(); return true; }