From 02b89b2db17dc1e1181b3af43e02104313355d47 Mon Sep 17 00:00:00 2001 From: Rahul Barwal Date: Mon, 10 Feb 2025 14:50:25 +0530 Subject: [PATCH] chore: Remove HTML column type feature flag and related code (#39108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description It has been a month since we have turned on the flag for table HTML column type and we have not seen any issues. This PR removes all the feature flags related code from the codebase. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Table" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 7a0f810c1f6a271adad082fc5c8b630b427aea34 > Cypress dashboard. > Tags: `@tag.Table` > Spec: >
Fri, 07 Feb 2025 09:20:10 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - The HTML column type now appears as a consistently available option when configuring table widgets. - **Refactor** - The table widget’s architecture has been streamlined for improved modularity and state management, enhancing overall cell rendering. - **Chore** - Legacy conditional toggling for the HTML column type has been removed to simplify configuration and standardize behavior. --- .../TableV2/columnTypes/HTMLCell_spec.ts | 3 - app/client/src/ce/entities/FeatureFlag.ts | 3 - .../src/widgets/TableWidgetV2/constants.ts | 3 - .../widgets/TableWidgetV2/widget/index.tsx | 163 +++++++----------- .../PanelConfig/Data/ColumnType.ts | 58 +------ .../propertyConfig/PanelConfig/Data/index.ts | 3 +- 6 files changed, 69 insertions(+), 164 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/HTMLCell_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/HTMLCell_spec.ts index cac2e52a2b..be2ef5b3d3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/HTMLCell_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/columnTypes/HTMLCell_spec.ts @@ -12,9 +12,6 @@ describe( { tags: ["@tag.Widget", "@tag.Table"] }, function () { before(() => { - featureFlagIntercept({ - release_table_html_column_type_enabled: true, - }); entityExplorer.DragDropWidgetNVerify("tablewidgetv2", 650, 250); propPane.EnterJSContext("Table data", JSON.stringify(htmlTableData)); }); diff --git a/app/client/src/ce/entities/FeatureFlag.ts b/app/client/src/ce/entities/FeatureFlag.ts index 6d8c77d384..ec3785c357 100644 --- a/app/client/src/ce/entities/FeatureFlag.ts +++ b/app/client/src/ce/entities/FeatureFlag.ts @@ -39,8 +39,6 @@ export const FEATURE_FLAG = { release_custom_widget_ai_builder: "release_custom_widget_ai_builder", ab_request_new_integration_enabled: "ab_request_new_integration_enabled", release_evaluation_scope_cache: "release_evaluation_scope_cache", - release_table_html_column_type_enabled: - "release_table_html_column_type_enabled", release_gs_all_sheets_options_enabled: "release_gs_all_sheets_options_enabled", release_git_modularisation_enabled: "release_git_modularisation_enabled", @@ -89,7 +87,6 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = { release_custom_widget_ai_builder: false, ab_request_new_integration_enabled: false, release_evaluation_scope_cache: false, - release_table_html_column_type_enabled: false, release_gs_all_sheets_options_enabled: false, release_git_modularisation_enabled: false, release_git_api_contracts_enabled: false, diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 35d1e7eaee..870040afec 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -243,6 +243,3 @@ export const DEFAULT_COLUMN_NAME = "Table Column"; export const ALLOW_TABLE_WIDGET_SERVER_SIDE_FILTERING = FEATURE_FLAG["release_table_serverside_filtering_enabled"]; - -export const HTML_COLUMN_TYPE_ENABLED = - FEATURE_FLAG["release_table_html_column_type_enabled"]; diff --git a/app/client/src/widgets/TableWidgetV2/widget/index.tsx b/app/client/src/widgets/TableWidgetV2/widget/index.tsx index b81f652b77..9beaac53d9 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/index.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/index.tsx @@ -1,6 +1,6 @@ -import React, { lazy, Suspense } from "react"; import log from "loglevel"; import memoizeOne from "memoize-one"; +import React, { lazy, Suspense } from "react"; import _, { filter, @@ -19,16 +19,61 @@ import _, { xorWith, } from "lodash"; -import type { WidgetProps, WidgetState } from "widgets/BaseWidget"; -import BaseWidget from "widgets/BaseWidget"; +import type { IconName } from "@blueprintjs/icons"; +import { IconNames } from "@blueprintjs/icons"; +import type { BatchPropertyUpdatePayload } from "actions/controlActions"; +import Skeleton from "components/utils/Skeleton"; +import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; +import { Colors } from "constants/Colors"; +import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants"; import { RenderModes, WIDGET_PADDING, WIDGET_TAGS, } from "constants/WidgetConstants"; -import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; -import Skeleton from "components/utils/Skeleton"; +import type { SetterConfig, Stylesheet } from "entities/AppTheming"; +import equal from "fast-deep-equal/es6"; +import { + FlexVerticalAlignment, + ResponsiveBehavior, +} from "layoutSystems/common/utils/constants"; import { noop, retryPromise } from "utils/AppsmithUtils"; +import type { ExtraDef } from "utils/autocomplete/defCreatorUtils"; +import { generateTypeDef } from "utils/autocomplete/defCreatorUtils"; +import type { DynamicPath } from "utils/DynamicBindingUtils"; +import { klonaRegularWithTelemetry } from "utils/helpers"; +import localStorage from "utils/localStorage"; +import type { + AnvilConfig, + AutocompletionDefinitions, + PropertyUpdates, + SnipingModeProperty, +} from "WidgetProvider/constants"; +import type { + WidgetQueryConfig, + WidgetQueryGenerationFormConfig, +} from "WidgetQueryGenerators/types"; +import type { WidgetProps, WidgetState } from "widgets/BaseWidget"; +import BaseWidget from "widgets/BaseWidget"; +import { TimePrecision } from "widgets/DatePickerWidget2/constants"; +import type { MenuItem } from "widgets/MenuButtonWidget/constants"; +import { MenuItemsSource } from "widgets/MenuButtonWidget/constants"; +import { + DefaultAutocompleteDefinitions, + sanitizeKey, +} from "widgets/WidgetUtils"; +import { ButtonCell } from "../component/cellComponents/ButtonCell"; +import { CheckboxCell } from "../component/cellComponents/CheckboxCell"; +import { DateCell } from "../component/cellComponents/DateCell"; +import { EditActionCell } from "../component/cellComponents/EditActionsCell"; +import HTMLCell from "../component/cellComponents/HTMLCell"; +import { IconButtonCell } from "../component/cellComponents/IconButtonCell"; +import { ImageCell } from "../component/cellComponents/ImageCell"; +import { MenuButtonCell } from "../component/cellComponents/MenuButtonCell"; +import PlainTextCell from "../component/cellComponents/PlainTextCell"; +import { SelectCell } from "../component/cellComponents/SelectCell"; +import { SwitchCell } from "../component/cellComponents/SwitchCell"; +import { VideoCell } from "../component/cellComponents/VideoCell"; import type { ColumnProperties, ReactTableColumnProps, @@ -42,6 +87,7 @@ import { SortOrderTypes, StickyType, } from "../component/Constants"; +import { CellWrapper } from "../component/TableStyledWrappers"; import type { EditableCell, OnColumnEventArgs, @@ -58,13 +104,23 @@ import { DEFAULT_MENU_VARIANT, defaultEditableCell, EditableCellActions, - HTML_COLUMN_TYPE_ENABLED, InlineEditingSaveOptions, ORIGINAL_INDEX_KEY, PaginationDirection, TABLE_COLUMN_ORDER_KEY, } from "../constants"; +import IconSVG from "../icon.svg"; +import ThumbnailSVG from "../thumbnail.svg"; import derivedProperties from "./parseDerivedProperties"; +import contentConfig from "./propertyConfig/contentConfig"; +import styleConfig from "./propertyConfig/styleConfig"; +import type { getColumns } from "./reactTableUtils/getColumnsPureFn"; +import { getMemoiseGetColumnsWithLocalStorageFn } from "./reactTableUtils/getColumnsPureFn"; +import type { + tableData, + transformDataWithEditableCell, +} from "./reactTableUtils/transformDataPureFn"; +import { getMemoiseTransformDataWithEditableCell } from "./reactTableUtils/transformDataPureFn"; import { createEditActionColumn, deleteLocalTableColumnOrderByWidgetId, @@ -84,64 +140,6 @@ import { isColumnTypeEditable, updateAndSyncTableLocalColumnOrders, } from "./utilities"; -import contentConfig from "./propertyConfig/contentConfig"; -import styleConfig from "./propertyConfig/styleConfig"; -import type { BatchPropertyUpdatePayload } from "actions/controlActions"; -import type { IconName } from "@blueprintjs/icons"; -import { IconNames } from "@blueprintjs/icons"; -import { Colors } from "constants/Colors"; -import equal from "fast-deep-equal/es6"; -import { - DefaultAutocompleteDefinitions, - sanitizeKey, -} from "widgets/WidgetUtils"; -import PlainTextCell from "../component/cellComponents/PlainTextCell"; -import { ButtonCell } from "../component/cellComponents/ButtonCell"; -import { MenuButtonCell } from "../component/cellComponents/MenuButtonCell"; -import { ImageCell } from "../component/cellComponents/ImageCell"; -import { VideoCell } from "../component/cellComponents/VideoCell"; -import { IconButtonCell } from "../component/cellComponents/IconButtonCell"; -import { EditActionCell } from "../component/cellComponents/EditActionsCell"; -import { CheckboxCell } from "../component/cellComponents/CheckboxCell"; -import { SwitchCell } from "../component/cellComponents/SwitchCell"; -import { SelectCell } from "../component/cellComponents/SelectCell"; -import { CellWrapper } from "../component/TableStyledWrappers"; -import localStorage from "utils/localStorage"; -import type { SetterConfig, Stylesheet } from "entities/AppTheming"; -import { DateCell } from "../component/cellComponents/DateCell"; -import type { MenuItem } from "widgets/MenuButtonWidget/constants"; -import { MenuItemsSource } from "widgets/MenuButtonWidget/constants"; -import { TimePrecision } from "widgets/DatePickerWidget2/constants"; -import type { getColumns } from "./reactTableUtils/getColumnsPureFn"; -import { getMemoiseGetColumnsWithLocalStorageFn } from "./reactTableUtils/getColumnsPureFn"; -import type { - tableData, - transformDataWithEditableCell, -} from "./reactTableUtils/transformDataPureFn"; -import { getMemoiseTransformDataWithEditableCell } from "./reactTableUtils/transformDataPureFn"; -import type { ExtraDef } from "utils/autocomplete/defCreatorUtils"; -import { generateTypeDef } from "utils/autocomplete/defCreatorUtils"; -import type { - AnvilConfig, - AutocompletionDefinitions, - PropertyUpdates, - SnipingModeProperty, -} from "WidgetProvider/constants"; -import type { - WidgetQueryConfig, - WidgetQueryGenerationFormConfig, -} from "WidgetQueryGenerators/types"; -import type { DynamicPath } from "utils/DynamicBindingUtils"; -import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants"; -import { - FlexVerticalAlignment, - ResponsiveBehavior, -} from "layoutSystems/common/utils/constants"; -import IconSVG from "../icon.svg"; -import ThumbnailSVG from "../thumbnail.svg"; -import { klonaRegularWithTelemetry } from "utils/helpers"; -import HTMLCell from "../component/cellComponents/HTMLCell"; -import { objectKeys } from "@appsmith/utils"; const ReactTableComponent = lazy(async () => retryPromise(async () => import("../component")), @@ -914,43 +912,6 @@ class TableWidgetV2 extends BaseWidget { //dont neet to batch this since single action this.hydrateStickyColumns(); } - - /** - * Why we are doing this? - * This is a safety net! Consider this scenario: - * 1. HTML column type is enabled. - * 2. User creates a table with HTML columns. - * 3. HTML column type is disabled. (For any reason) - * - * In this scenario, we don't want incomplete experience for the user. - * Without this safety net, the property pane will not show the HTML as type and the `ColumnType` will be lost(and empty), which is confusing for the user. - * With this safety net, we will update the column type to TEXT. - * @rahulbarwal Remove this once we remove the feature flag - */ - if (!TableWidgetV2.getFeatureFlag(HTML_COLUMN_TYPE_ENABLED)) { - let hasHTMLColumns = false; - const { primaryColumns } = this.props; - - const updatedPrimaryColumns = objectKeys(primaryColumns).reduce( - (acc, widgetId) => { - const column = primaryColumns[widgetId]; - - if (column.columnType === ColumnTypes.HTML) { - acc[widgetId] = { ...column, columnType: ColumnTypes.TEXT }; - hasHTMLColumns = true; - } else { - acc[widgetId] = column; - } - - return acc; - }, - {} as Record, - ); - - if (hasHTMLColumns) { - this.updateWidgetProperty("primaryColumns", updatedPrimaryColumns); - } - } } componentDidUpdate(prevProps: TableWidgetProps) { diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/ColumnType.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/ColumnType.ts index ee66fa0aa1..94ccc6b19f 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/ColumnType.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/ColumnType.ts @@ -1,11 +1,9 @@ import { ColumnTypes, - HTML_COLUMN_TYPE_ENABLED, type TableWidgetProps, } from "widgets/TableWidgetV2/constants"; import { composePropertyUpdateHook } from "widgets/WidgetUtils"; -import Widget from "../../../index"; import { showByColumnType, updateCurrencyDefaultValues, @@ -30,6 +28,10 @@ const ColumnTypeOptions = [ label: "Date", value: ColumnTypes.DATE, }, + { + label: "HTML", + value: ColumnTypes.HTML, + }, { label: "Icon button", value: ColumnTypes.ICON_BUTTON, @@ -68,22 +70,12 @@ const ColumnTypeOptions = [ }, ]; -// TODO: @rahulbarwal Remove this once we have a feature flag for this -// This is a temporary solution to position the HTML column type alphabetically -const columnTypeWithHtml = [ - ...ColumnTypeOptions.slice(0, 4), - { label: "HTML", value: ColumnTypes.HTML }, - ...ColumnTypeOptions.slice(4), -]; - export const columnTypeConfig = { propertyName: "columnType", label: "Column type", helpText: "Type of column to be shown corresponding to the data of the column", controlType: "DROP_DOWN", - // TODO: Remove this once we have a feature flag for this - // Since we want to position the column types alphabetically, right now this is hardcoded options: ColumnTypeOptions, updateHook: composePropertyUpdateHook([ updateNumberColumnTypeTextAlignment, @@ -94,44 +86,6 @@ export const columnTypeConfig = { dependencies: ["primaryColumns", "columnOrder", "childStylesheet"], isBindProperty: false, isTriggerProperty: false, - hidden: (props: TableWidgetProps, propertyPath: string) => { - const isHTMLColumnTypeEnabled = Widget.getFeatureFlag( - HTML_COLUMN_TYPE_ENABLED, - ); - - return ( - isHTMLColumnTypeEnabled || - showByColumnType(props, propertyPath, [ColumnTypes.EDIT_ACTIONS]) - ); - }, -}; - -export const columnTypeWithHtmlConfig = { - propertyName: "columnType", - label: "Column type", - helpText: - "Type of column to be shown corresponding to the data of the column", - controlType: "DROP_DOWN", - // TODO: Remove this once we have a feature flag for this - // Since we want to position the column types alphabetically, right now this is hardcoded - options: columnTypeWithHtml, - updateHook: composePropertyUpdateHook([ - updateNumberColumnTypeTextAlignment, - updateThemeStylesheetsInColumns, - updateMenuItemsSource, - updateCurrencyDefaultValues, - ]), - dependencies: ["primaryColumns", "columnOrder", "childStylesheet"], - isBindProperty: false, - isTriggerProperty: false, - hidden: (props: TableWidgetProps, propertyPath: string) => { - const isHTMLColumnTypeEnabled = Widget.getFeatureFlag( - HTML_COLUMN_TYPE_ENABLED, - ); - - return ( - !isHTMLColumnTypeEnabled || - showByColumnType(props, propertyPath, [ColumnTypes.EDIT_ACTIONS]) - ); - }, + hidden: (props: TableWidgetProps, propertyPath: string) => + showByColumnType(props, propertyPath, [ColumnTypes.EDIT_ACTIONS]), }; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/index.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/index.ts index 6296da47e1..de4a5685fd 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/index.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data/index.ts @@ -9,13 +9,12 @@ import { hideByColumnType, uniqueColumnAliasValidation, } from "../../../propertyUtils"; -import { columnTypeConfig, columnTypeWithHtmlConfig } from "./ColumnType"; +import { columnTypeConfig } from "./ColumnType"; export default { sectionName: "Data", children: [ columnTypeConfig, - columnTypeWithHtmlConfig, { helpText: "The alias that you use in selectedrow", propertyName: "alias",