feat: centralize browser tab opening with customOpenNewTab utility (#8064)

*  (NodeStatus): Add customOpenNewTab function to handle opening links in a new tab
🔧 (connectionComponent): Use customOpenNewTab function to open links in a new tab
🔧 (linkComponent): Use customOpenNewTab function to open links in a new tab
🔧 (custom-open-new-tab.ts): Create customOpenNewTab function to open links in a new tab
🔧 (new-modal): Use customOpenNewTab function to open LangflowButtonRedirectTarget link in a new tab
🔧 (nodeToolbarComponent): Remove unnecessary dependency openInNewTab from useEffect in NodeToolbarComponent

*  (frontend): Add customOpenNewTab function to handle opening links in a new tab for better customization and control. Remove openInNewTab function to avoid redundancy and simplify code.
This commit is contained in:
Cristhian Zanforlin Lousa 2025-05-15 14:08:46 -03:00 committed by GitHub
commit ebb5254975
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 20 additions and 11 deletions

View file

@ -6,6 +6,7 @@ import { BuildStatus, EventDeliveryType } from "@/constants/enums";
import { useGetConfig } from "@/controllers/API/queries/config/use-get-config";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { track } from "@/customization/utils/analytics";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import { getSpecificClassFromBuildStatus } from "@/CustomNodes/helpers/get-class-from-build-status";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useIconStatus from "@/CustomNodes/hooks/use-icons-status";
@ -26,7 +27,6 @@ import { useHotkeys } from "react-hotkeys-hook";
import IconComponent from "../../../../components/common/genericIconComponent";
import BuildStatusDisplay from "./components/build-status-display";
import { normalizeTimeString } from "./utils/format-run-time";
const POLLING_TIMEOUT = 21000;
const POLLING_INTERVAL = 3000;
@ -100,7 +100,7 @@ export default function NodeStatus({
// Start polling when connection is initiated
const startPolling = () => {
window.open(connectionLink, "_blank");
customOpenNewTab(connectionLink);
stopPolling();
setIsPolling(true);

View file

@ -6,12 +6,13 @@ import {
} from "@/components/ui/popover";
import { Select, SelectTrigger } from "@/components/ui/select-custom";
import { COLOR_OPTIONS } from "@/constants/constants";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useShortcutsStore } from "@/stores/shortcuts";
import { NoteDataType } from "@/types/flow";
import { classNames, cn, openInNewTab } from "@/utils/utils";
import { classNames, cn } from "@/utils/utils";
import { cloneDeep } from "lodash";
import { memo, useCallback, useMemo } from "react";
import IconComponent from "../../../components/common/genericIconComponent";
@ -47,7 +48,7 @@ const NoteToolbarComponent = memo(function NoteToolbarComponent({
const openDocs = useCallback(() => {
if (data.node?.documentation) {
return openInNewTab(data.node?.documentation);
return customOpenNewTab(data.node?.documentation);
}
setNoticeData({
title: `${data.id} docs is not available at the moment.`,

View file

@ -1,6 +1,7 @@
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import ListSelectionComponent from "@/CustomNodes/GenericNode/components/ListSelectionComponent";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useAlertStore from "@/stores/alertStore";
@ -96,7 +97,7 @@ const ConnectionComponent = ({
const handleConnectionButtonClick = () => {
if (selectedItem?.length === 0) return;
window.open(link, "_blank");
customOpenNewTab(link);
startPolling();
};

View file

@ -1,8 +1,8 @@
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import { classNames } from "../../../../../utils/utils";
import IconComponent from "../../../../common/genericIconComponent";
import { Button } from "../../../../ui/button";
import { InputProps, LinkComponentType } from "../../types";
const DEFAULT_ICON = "ExternalLink";
export default function LinkComponent({
@ -15,7 +15,7 @@ export default function LinkComponent({
function handleOpenLink() {
if (value) {
const url = !/^https?:\/\//i.test(value) ? `https://${value}` : value;
window.open(url, "_blank", "noopener,noreferrer");
customOpenNewTab(url);
}
}

View file

@ -0,0 +1,5 @@
import { openInNewTab } from "@/utils/utils";
export const customOpenNewTab = (url: string) => {
openInNewTab(url);
};

View file

@ -8,6 +8,7 @@ import {
} from "@/controllers/API/queries/messages";
import { ENABLE_PUBLISH } from "@/customization/feature-flags";
import { track } from "@/customization/utils/analytics";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import { LangflowButtonRedirectTarget } from "@/customization/utils/urls";
import { useUtilityStore } from "@/stores/utilityStore";
import { swatchColors } from "@/utils/styleUtils";
@ -259,7 +260,7 @@ export default function IOModal({
const LangflowButtonClick = () => {
track("LangflowButtonClick");
window.open(LangflowButtonRedirectTarget(), "_blank");
customOpenNewTab(LangflowButtonRedirectTarget());
};
useEffect(() => {

View file

@ -7,6 +7,7 @@ import ToggleShadComponent from "@/components/core/parameterRenderComponent/comp
import { Button } from "@/components/ui/button";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { usePostRetrieveVertexOrder } from "@/controllers/API/queries/vertex";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import useAddFlow from "@/hooks/flows/use-add-flow";
import { APIClassType } from "@/types/api";
import { useUpdateNodeInternals } from "@xyflow/react";
@ -34,7 +35,7 @@ import {
expandGroupNode,
updateFlowPosition,
} from "../../../../utils/reactflowUtils";
import { cn, getNodeLength, openInNewTab } from "../../../../utils/utils";
import { cn, getNodeLength } from "../../../../utils/utils";
import { ToolbarButton } from "./components/toolbar-button";
import ToolbarModals from "./components/toolbar-modals";
import useShortcuts from "./hooks/use-shortcuts";
@ -249,12 +250,12 @@ const NodeToolbarComponent = memo(
const openDocs = useCallback(() => {
if (data.node?.documentation) {
return openInNewTab(data.node.documentation);
return customOpenNewTab(data.node.documentation);
}
setNoticeData({
title: `${data.id} docs is not available at the moment.`,
});
}, [data.id, data.node?.documentation, openInNewTab]);
}, [data.id, data.node?.documentation]);
useShortcuts({
showOverrideModal,