diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_Url_Column_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_Url_Column_spec.ts index f866def606d..e906d531598 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_Url_Column_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/TableV2_Url_Column_spec.ts @@ -20,18 +20,23 @@ describe( table.ReadTableRowColumnData(3, 0, "v2").then(($cellData) => { expect($cellData).to.eq("Profile pic"); }); - table.AssertURLColumnNavigation( - 0, - 0, - "https://randomuser.me/api/portraits/med/women/39.jpg", - "v2", - ); - table.AssertURLColumnNavigation( - 3, - 0, - "https://randomuser.me/api/portraits/med/men/52.jpg", - "v2", - ); + + agHelper + .GetElement(`${table._tableRowColumnData(0, 0, "v2")} a`) + .should( + "have.attr", + "href", + "https://randomuser.me/api/portraits/med/women/39.jpg", + ) + .should("have.attr", "target", "_blank"); + agHelper + .GetElement(`${table._tableRowColumnData(3, 0, "v2")} a`) + .should( + "have.attr", + "href", + "https://randomuser.me/api/portraits/med/men/52.jpg", + ) + .should("have.attr", "target", "_blank"); }); }, ); diff --git a/app/client/src/widgets/TableWidgetV2/component/Constants.ts b/app/client/src/widgets/TableWidgetV2/component/Constants.ts index c4a3d0eceb5..182eb402073 100644 --- a/app/client/src/widgets/TableWidgetV2/component/Constants.ts +++ b/app/client/src/widgets/TableWidgetV2/component/Constants.ts @@ -546,7 +546,7 @@ export enum IMAGE_VERTICAL_ALIGN { } export interface BaseCellComponentProps { - compactMode: string; + compactMode: CompactMode; isHidden: boolean; allowCellWrapping?: boolean; horizontalAlignment?: CellAlignment; diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoToolTipComponent.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoToolTipComponent.tsx index 86b3c41caec..8b9d30e99e6 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoToolTipComponent.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoToolTipComponent.tsx @@ -137,7 +137,7 @@ interface Props { children: React.ReactNode; title: string; tableWidth?: number; - columnType?: string; + columnType?: ColumnTypes; className?: string; compactMode?: string; allowCellWrapping?: boolean; @@ -152,38 +152,6 @@ interface Props { isCellDisabled?: boolean; } -function LinkWrapper(props: Props) { - const content = useToolTip(props.children, props.title); - - return ( - ) => { - e.stopPropagation(); - window.open(props.url, "_blank"); - }} - textColor={props.textColor} - textSize={props.textSize} - verticalAlignment={props.verticalAlignment} - > -
{content}
- - - -
- ); -} - export function AutoToolTipComponent(props: Props) { const content = useToolTip( props.children, @@ -191,12 +159,27 @@ export function AutoToolTipComponent(props: Props) { props.columnType === ColumnTypes.BUTTON, ); - if (props.columnType === ColumnTypes.URL && props.title) { - return ; - } + let contentToRender; + + switch (props.columnType) { + case ColumnTypes.BUTTON: + if (props.title) { + return content; + } - if (props.columnType === ColumnTypes.BUTTON && props.title) { - return content; + break; + case ColumnTypes.URL: + contentToRender = ( + <> +
{content}
+ + + + + ); + break; + default: + contentToRender = content; } return ( @@ -212,12 +195,13 @@ export function AutoToolTipComponent(props: Props) { isCellDisabled={props.isCellDisabled} isCellVisible={props.isCellVisible} isHidden={props.isHidden} + isHyperLink={props.columnType === ColumnTypes.URL} isTextType textColor={props.textColor} textSize={props.textSize} verticalAlignment={props.verticalAlignment} > - {content} + {contentToRender} ); diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoTooltipComponent.test.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoTooltipComponent.test.tsx index 8a9a5721c71..bf46ff76952 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoTooltipComponent.test.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/AutoTooltipComponent.test.tsx @@ -54,7 +54,7 @@ test("does not show tooltip for non-button types", () => { test("handles empty tooltip", () => { const { getByText } = render( - + , ); @@ -86,25 +86,6 @@ test("does not show tooltip for non-truncated text", () => { expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); }); -test("opens a new tab for URL column type when clicked", () => { - const openSpy = jest.spyOn(window, "open").mockImplementation(() => null); - - render( - - Go to Google - , - ); - - fireEvent.click(screen.getByText("Go to Google")); - expect(openSpy).toHaveBeenCalledWith("https://www.google.com", "_blank"); - - openSpy.mockRestore(); -}); - describe("isButtonTextTruncated", () => { function mockElementWidths( offsetWidth: number, diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.test.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.test.tsx new file mode 100644 index 00000000000..ee37e656b95 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.test.tsx @@ -0,0 +1,56 @@ +import React from "react"; +import { render, screen, fireEvent } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import { BasicCell, type PropType } from "./BasicCell"; +import { ColumnTypes } from "widgets/TableWidgetV2/constants"; +import { CompactModeTypes } from "widgets/TableWidget/component/Constants"; + +describe("BasicCell Component", () => { + const defaultProps: PropType = { + value: "Test Value", + onEdit: jest.fn(), + isCellEditable: false, + hasUnsavedChanges: false, + columnType: ColumnTypes.TEXT, + url: "", + compactMode: CompactModeTypes.DEFAULT, + isHidden: false, + isCellVisible: true, + accentColor: "", + tableWidth: 100, + disabledEditIcon: false, + disabledEditIconMessage: "", + }; + + it("renders the value", () => { + render(); + expect(screen.getByText("Test Value")).toBeInTheDocument(); + }); + + it("renders a link when columnType is URL", () => { + render( + , + ); + const link = screen.getByText("Test Value"); + + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute("href", "http://example.com"); + }); + + it("calls onEdit when double-clicked", () => { + render(); + fireEvent.doubleClick(screen.getByText("Test Value")); + expect(defaultProps.onEdit).toHaveBeenCalled(); + }); + + it("forwards ref to the div element", () => { + const ref = React.createRef(); + + render(); + expect(ref.current).toBeInstanceOf(HTMLDivElement); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx index 08d9efe8901..9b2431cf860 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx @@ -1,12 +1,13 @@ import type { Ref } from "react"; -import React, { useCallback } from "react"; +import React, { useCallback, useMemo } from "react"; import { Tooltip } from "@blueprintjs/core"; import styled from "styled-components"; -import type { BaseCellComponentProps } from "../Constants"; +import type { BaseCellComponentProps, CompactMode } from "../Constants"; import { TABLE_SIZES } from "../Constants"; import { TooltipContentWrapper } from "../TableStyledWrappers"; import AutoToolTipComponent from "./AutoToolTipComponent"; import { importSvg } from "@appsmith/ads-old"; +import { ColumnTypes } from "widgets/TableWidgetV2/constants"; const EditIcon = importSvg( async () => import("assets/icons/control/edit-variant1.svg"), @@ -55,7 +56,7 @@ const Content = styled.div` const StyledEditIcon = styled.div<{ accentColor?: string; backgroundColor?: string; - compactMode: string; + compactMode: CompactMode; disabledEditIcon: boolean; }>` position: absolute; @@ -74,12 +75,12 @@ const StyledEditIcon = styled.div<{ } `; -type PropType = BaseCellComponentProps & { +export type PropType = BaseCellComponentProps & { accentColor: string; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any; - columnType: string; + columnType: ColumnTypes; tableWidth: number; isCellEditable?: boolean; isCellEditMode?: boolean; @@ -128,6 +129,18 @@ export const BasicCell = React.forwardRef( }, [onEdit, disabledEditIcon, isCellEditable], ); + const contentToRender = useMemo(() => { + switch (columnType) { + case ColumnTypes.URL: + return ( + + {value} + + ); + default: + return value; + } + }, [columnType, url, value]); return ( - {value} + {contentToRender} {isCellEditable && (