From 5ab28342110bede88d4fb71a40f87c859fbcaf22 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Thu, 19 Sep 2024 03:27:22 +0100 Subject: [PATCH 01/21] adjust moment inputFormat for Unix ms + allow validate unix ms in transformDatePureFn --- .../component/cellComponents/DateCell.tsx | 12 ++++++++++-- .../widget/reactTableUtils/transformDataPureFn.tsx | 6 ++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx index 16f1bf8811d..bb9edb7a035 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -9,7 +9,10 @@ import DateComponent from "widgets/DatePickerWidget2/component"; import { TimePrecision } from "widgets/DatePickerWidget2/constants"; import type { RenderDefaultPropsType } from "./PlainTextCell"; import styled from "styled-components"; -import { EditableCellActions } from "widgets/TableWidgetV2/constants"; +import { + DateInputFormat, + EditableCellActions, +} from "widgets/TableWidgetV2/constants"; import { ISO_DATE_FORMAT } from "constants/WidgetValidation"; import moment from "moment"; import { BasicCell } from "./BasicCell"; @@ -218,6 +221,7 @@ export const DateCell = (props: DateComponentProps) => { }, [value, props.outputFormat]); const onDateSelected = (date: string) => { + let momentAdjustedInputFormat = inputFormat; if (isNewRow) { updateNewRowValues(alias, date, date); return; @@ -232,7 +236,11 @@ export const DateCell = (props: DateComponentProps) => { setShowRequiredError(false); setHasFocus(false); - const formattedDate = date ? moment(date).format(inputFormat) : ""; + if (inputFormat === DateInputFormat.MILLISECONDS) + momentAdjustedInputFormat = "x"; + const formattedDate = date + ? moment(date).format(momentAdjustedInputFormat) + : ""; onDateSave(rowIndex, alias, formattedDate, onDateSelectedString); }; diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx index f05308f0d47..da59e47b71e 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx @@ -38,14 +38,16 @@ export const transformDataPureFn = ( const type = _.isArray(column.metaProperties.inputFormat) ? column.metaProperties.inputFormat[rowIndex] : column.metaProperties.inputFormat; - if ( type !== DateInputFormat.EPOCH && type !== DateInputFormat.MILLISECONDS ) { inputFormat = type; moment(value as MomentInput, inputFormat); - } else if (!isNumber(value)) { + } else if ( + !isNumber(value) && + type !== DateInputFormat.MILLISECONDS + ) { isValidDate = false; } } catch (e) { From 1a4ebe9f7085bffc000277ce35f4c22b999822ae Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Thu, 19 Sep 2024 03:28:42 +0100 Subject: [PATCH 02/21] add enum for MomentDateInputFormat --- .../TableWidgetV2/component/cellComponents/DateCell.tsx | 3 ++- app/client/src/widgets/TableWidgetV2/constants.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx index bb9edb7a035..793f978ef0e 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -12,6 +12,7 @@ import styled from "styled-components"; import { DateInputFormat, EditableCellActions, + MomentDateInputFormat, } from "widgets/TableWidgetV2/constants"; import { ISO_DATE_FORMAT } from "constants/WidgetValidation"; import moment from "moment"; @@ -237,7 +238,7 @@ export const DateCell = (props: DateComponentProps) => { setHasFocus(false); if (inputFormat === DateInputFormat.MILLISECONDS) - momentAdjustedInputFormat = "x"; + momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; const formattedDate = date ? moment(date).format(momentAdjustedInputFormat) : ""; diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 0e066c83f9a..5ce342031f6 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -219,6 +219,10 @@ export enum DateInputFormat { MILLISECONDS = "Milliseconds", } +export enum MomentDateInputFormat { + MILLISECONDS = "x", +} + export const defaultEditableCell: EditableCell = { column: "", index: -1, From 6b6b7a89016902699709c7524551d6926f0089f0 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Thu, 19 Sep 2024 04:30:30 +0100 Subject: [PATCH 03/21] add base test --- .../TableV2/Date_column_editing_2_spec.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index 50728d23c91..bf55bd64cac 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -92,5 +92,67 @@ describe( expect($textData).to.include("YYYY-MM-DDTHH:mm:ss.SSSZ"), ); }); + + it("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { + EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); + // propPane.NavigateBackToPropertyPane(); + propPane.UpdatePropertyFieldValue( + "Table data", + ` + {{ + [ + { + unix: 1726713837918, + role: 1, + id: 1, + name: "Alice Johnson", + email: "alice.johnson@example.com", + age: 28, + gender: 2, + }, + { + unix: 1726713837918, + role: 2, + id: 2, + name: "Bob Smith", + email: "bob.smith@example.com", + age: 34, + gender: 1 + }, + { + unix: 1726713837918, + role: 3, + id: 3, + name: "Charlie Brown", + email: "charlie.brown@example.com", + age: 25, + gender: 3 + }, + { + unix: 1726713837918, + role: 2, + id: 4, + name: "Diana Prince", + email: "diana.prince@example.com", + age: 30, + gender: 2 + }, + { + unix: 1726713837918, + role: 1, + id: 5, + name: "Evan Williams", + email: "evan.williams@example.com", + age: 27, + gender: 1 + } + ] + }} + `, + ); + table.EditColumn("unix", "v2"); + // table.ChangeColumnType("unix", "Date", "v2"); + // propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); + }); }, ); From 94ef32dd08a507f7173e34df16c856b83b93081b Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Thu, 19 Sep 2024 10:30:38 +0100 Subject: [PATCH 04/21] improve test --- .../ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index bf55bd64cac..f4171f0422f 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -150,9 +150,9 @@ describe( }} `, ); + table.ChangeColumnType("unix", "Date", "v2"); table.EditColumn("unix", "v2"); - // table.ChangeColumnType("unix", "Date", "v2"); - // propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); + propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); }); }, ); From da89194ff11a8aee5abb1f6785aec386ecf0f57e Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 20 Sep 2024 09:39:23 +0100 Subject: [PATCH 05/21] improve Date_column_editing_2_spec --- .../Widgets/TableV2/Date_column_editing_2_spec.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index f4171f0422f..8b89f990b94 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -93,7 +93,7 @@ describe( ); }); - it("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { + it.only("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); // propPane.NavigateBackToPropertyPane(); propPane.UpdatePropertyFieldValue( @@ -152,7 +152,12 @@ describe( ); table.ChangeColumnType("unix", "Date", "v2"); table.EditColumn("unix", "v2"); + + propPane.ToggleJSMode("Date format", true); propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); + + propPane.ToggleJSMode("Display format", true); + propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD HH:mm"); }); }, ); From 2621b9aaeb5d4adaf56860b0b0badbda22409c48 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 20 Sep 2024 11:27:47 +0100 Subject: [PATCH 06/21] complete test --- .../TableV2/Date_column_editing_2_spec.ts | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index 8b89f990b94..18030d65613 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -93,9 +93,29 @@ describe( ); }); - it.only("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { + it("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { + // Get string format for tomorrow date - Sat Sep 21 2024 format + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + const formattedTomorrowDateVerbose = tomorrow + .toLocaleDateString("en-US", { + weekday: "short", + year: "numeric", + month: "short", + day: "2-digit", + }) + .replace(/,/g, ""); + + // Get strig format for tomorrow date - 2024-09-21 + const formattedTomorrowDateYYYYMMDD = tomorrow + .toISOString() + .split("T")[0]; + EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); - // propPane.NavigateBackToPropertyPane(); + + propPane.NavigateBackToPropertyPane(); + + // Update table data propPane.UpdatePropertyFieldValue( "Table data", ` @@ -150,14 +170,36 @@ describe( }} `, ); + + // Change column to date table.ChangeColumnType("unix", "Date", "v2"); + + // Edit column table.EditColumn("unix", "v2"); + // Update date format property propPane.ToggleJSMode("Date format", true); propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); + // Update display format property propPane.ToggleJSMode("Display format", true); - propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD HH:mm"); + propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD"); + + // Toggle editable + propPane.TogglePropertyState("Editable", "On"); + + // Click unix cell edit + table.ClickOnEditIcon(0, 2); + + // Click on specific date within + agHelper.GetNClick( + `${table._dateInputPopover} [aria-label='${formattedTomorrowDateVerbose}']`, + ); + + // Check that date is set in column + table + .ReadTableRowColumnData(0, 2, "v2") + .then((val) => expect(val).to.equal(formattedTomorrowDateYYYYMMDD)); }); }, ); From 877f4ce63c583f583d7ef90a750fa465e8f8b070 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 09:07:22 +0100 Subject: [PATCH 07/21] extract helper and fixtures in test case --- .../TableV2/Date_column_editing_2_spec.ts | 78 ++----------------- .../ClientSide/Widgets/TableV2/fixtures.ts | 51 ++++++++++++ .../ClientSide/Widgets/TableV2/helpers.ts | 33 ++++++++ 3 files changed, 90 insertions(+), 72 deletions(-) create mode 100644 app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts create mode 100644 app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index 18030d65613..ac936a7a6e3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -10,6 +10,8 @@ import { datePickerlocators } from "../../../../../locators/WidgetLocators"; import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; +import { getFormattedTomorrowDates } from "./helpers"; +import { unixTableV2Data } from "./fixtures"; describe( "Table widget date column inline editing functionality", @@ -94,82 +96,14 @@ describe( }); it("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { - // Get string format for tomorrow date - Sat Sep 21 2024 format - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - const formattedTomorrowDateVerbose = tomorrow - .toLocaleDateString("en-US", { - weekday: "short", - year: "numeric", - month: "short", - day: "2-digit", - }) - .replace(/,/g, ""); - - // Get strig format for tomorrow date - 2024-09-21 - const formattedTomorrowDateYYYYMMDD = tomorrow - .toISOString() - .split("T")[0]; + const { verboseFormat, isoFormat } = getFormattedTomorrowDates(); EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); propPane.NavigateBackToPropertyPane(); // Update table data - propPane.UpdatePropertyFieldValue( - "Table data", - ` - {{ - [ - { - unix: 1726713837918, - role: 1, - id: 1, - name: "Alice Johnson", - email: "alice.johnson@example.com", - age: 28, - gender: 2, - }, - { - unix: 1726713837918, - role: 2, - id: 2, - name: "Bob Smith", - email: "bob.smith@example.com", - age: 34, - gender: 1 - }, - { - unix: 1726713837918, - role: 3, - id: 3, - name: "Charlie Brown", - email: "charlie.brown@example.com", - age: 25, - gender: 3 - }, - { - unix: 1726713837918, - role: 2, - id: 4, - name: "Diana Prince", - email: "diana.prince@example.com", - age: 30, - gender: 2 - }, - { - unix: 1726713837918, - role: 1, - id: 5, - name: "Evan Williams", - email: "evan.williams@example.com", - age: 27, - gender: 1 - } - ] - }} - `, - ); + propPane.UpdatePropertyFieldValue("Table data", unixTableV2Data); // Change column to date table.ChangeColumnType("unix", "Date", "v2"); @@ -193,13 +127,13 @@ describe( // Click on specific date within agHelper.GetNClick( - `${table._dateInputPopover} [aria-label='${formattedTomorrowDateVerbose}']`, + `${table._dateInputPopover} [aria-label='${verboseFormat}']`, ); // Check that date is set in column table .ReadTableRowColumnData(0, 2, "v2") - .then((val) => expect(val).to.equal(formattedTomorrowDateYYYYMMDD)); + .then((val) => expect(val).to.equal(isoFormat)); }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts new file mode 100644 index 00000000000..89e5335dcbd --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts @@ -0,0 +1,51 @@ +export const unixTableV2Data = ` +{{ + [ + { + unix: 1726713837918, + role: 1, + id: 1, + name: "Alice Johnson", + email: "alice.johnson@example.com", + age: 28, + gender: 2, + }, + { + unix: 1726713837918, + role: 2, + id: 2, + name: "Bob Smith", + email: "bob.smith@example.com", + age: 34, + gender: 1 + }, + { + unix: 1726713837918, + role: 3, + id: 3, + name: "Charlie Brown", + email: "charlie.brown@example.com", + age: 25, + gender: 3 + }, + { + unix: 1726713837918, + role: 2, + id: 4, + name: "Diana Prince", + email: "diana.prince@example.com", + age: 30, + gender: 2 + }, + { + unix: 1726713837918, + role: 1, + id: 5, + name: "Evan Williams", + email: "evan.williams@example.com", + age: 27, + gender: 1 + } + ] + }} +`; diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts new file mode 100644 index 00000000000..713c897c601 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts @@ -0,0 +1,33 @@ +/** + * Helper function to get formatted date strings for tomorrow's date. + * + * @returns {Object} An object containing: + * - verbose format (e.g., "Sat Sep 21 2024") + * - ISO date format (e.g., "2024-09-21") + */ +export function getFormattedTomorrowDates() { + // Create a new Date object for today + const tomorrow = new Date(); + + // Set the date to tomorrow by adding 1 to today's date + tomorrow.setDate(tomorrow.getDate() + 1); + + // Format tomorrow's date in verbose form (e.g., "Sat Sep 21 2024") + const verboseFormat = tomorrow + .toLocaleDateString("en-US", { + weekday: "short", + year: "numeric", + month: "short", + day: "2-digit", + }) + .replace(/,/g, ""); // Remove commas from the formatted string + + // Format tomorrow's date in ISO form (e.g., "2024-09-21") + const isoFormat = tomorrow.toISOString().split("T")[0]; // Extract the date part only + + // Return both formatted date strings as an object + return { + verboseFormat, + isoFormat, + }; +} From 68facfb7b87d0ddab1cc500cae8bdbd6677941ae Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 09:56:08 +0100 Subject: [PATCH 08/21] improve transformDataPureFn - remove redundant !isNumber(value) check for EPOCK and MILLISECONDS format --- .../TableWidgetV2/component/cellComponents/DateCell.tsx | 9 ++++++++- app/client/src/widgets/TableWidgetV2/constants.ts | 4 +++- .../widget/reactTableUtils/transformDataPureFn.tsx | 8 ++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx index 052d9600b70..884116599d5 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -223,6 +223,7 @@ export const DateCell = (props: DateComponentProps) => { const onDateSelected = (date: string) => { let momentAdjustedInputFormat = inputFormat; + if (isNewRow) { updateNewRowValues(alias, date, date); @@ -240,11 +241,17 @@ export const DateCell = (props: DateComponentProps) => { setShowRequiredError(false); setHasFocus(false); - if (inputFormat === DateInputFormat.MILLISECONDS) + // If the input format is milliseconds or epoch, convert the date to the required format + if (inputFormat === DateInputFormat.MILLISECONDS) { momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; + } else if (inputFormat === DateInputFormat.EPOCH) { + momentAdjustedInputFormat = MomentDateInputFormat.SECONDS; + } + const formattedDate = date ? moment(date).format(momentAdjustedInputFormat) : ""; + onDateSave(rowIndex, alias, formattedDate, onDateSelectedString); }; diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 5ce342031f6..9297a486bdf 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -14,6 +14,7 @@ import type { Alignment } from "@blueprintjs/core"; import type { IconName } from "@blueprintjs/icons"; import type { ButtonVariant } from "components/constants"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; +import { objectKeys } from "@appsmith/utils"; export interface EditableCell { column: string; @@ -198,7 +199,7 @@ export interface OnColumnEventArgs { additionalData?: Record; } -export const ICON_NAMES = Object.keys(IconNames).map( +export const ICON_NAMES = objectKeys(IconNames).map( (name: string) => IconNames[name as keyof typeof IconNames], ); @@ -221,6 +222,7 @@ export enum DateInputFormat { export enum MomentDateInputFormat { MILLISECONDS = "x", + SECONDS = "X", } export const defaultEditableCell: EditableCell = { diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx index b343d4bb3a1..55dbaec39c7 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx @@ -1,7 +1,7 @@ import log from "loglevel"; import type { MomentInput } from "moment"; import moment from "moment"; -import _, { isNumber, isNil, isArray } from "lodash"; +import _, { isNil, isArray } from "lodash"; import type { EditableCell } from "../../constants"; import { ColumnTypes, DateInputFormat } from "../../constants"; import type { ReactTableColumnProps } from "../../component/Constants"; @@ -38,17 +38,13 @@ export const transformDataPureFn = ( const type = _.isArray(column.metaProperties.inputFormat) ? column.metaProperties.inputFormat[rowIndex] : column.metaProperties.inputFormat; + if ( type !== DateInputFormat.EPOCH && type !== DateInputFormat.MILLISECONDS ) { inputFormat = type; moment(value as MomentInput, inputFormat); - } else if ( - !isNumber(value) && - type !== DateInputFormat.MILLISECONDS - ) { - isValidDate = false; } } catch (e) { isValidDate = false; From 33da955f5cc8b67e41ff8477512dc81a234c2df6 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 09:57:00 +0100 Subject: [PATCH 09/21] improve transformDataPureFn - remove redundant !isNumber(value) check for EPOCK and MILLISECONDS format --- app/client/src/widgets/TableWidgetV2/constants.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 9297a486bdf..8fb0e8605aa 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -14,7 +14,6 @@ import type { Alignment } from "@blueprintjs/core"; import type { IconName } from "@blueprintjs/icons"; import type { ButtonVariant } from "components/constants"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import { objectKeys } from "@appsmith/utils"; export interface EditableCell { column: string; @@ -199,7 +198,7 @@ export interface OnColumnEventArgs { additionalData?: Record; } -export const ICON_NAMES = objectKeys(IconNames).map( +export const ICON_NAMES = Object.keys(IconNames).map( (name: string) => IconNames[name as keyof typeof IconNames], ); From d6ec6aeaff9f55ccc9df2d0fc0b41e21c063c904 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 10:20:04 +0100 Subject: [PATCH 10/21] add base test for transformDataPureFn --- .../TransformDataPureFn.test.ts | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts new file mode 100644 index 00000000000..2468ff8ef95 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts @@ -0,0 +1,129 @@ +import { ColumnTypes, DateInputFormat } from "widgets/TableWidgetV2/constants"; +import { transformDataPureFn } from "./transformDataPureFn"; +import type { ReactTableColumnProps } from "widgets/TableWidgetV2/component/Constants"; + +// Mock columns data +const columns = [ + { + alias: "epoch", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: DateInputFormat.EPOCH, + format: "YYYY-MM-DD", + }, + }, + { + alias: "milliseconds", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: DateInputFormat.MILLISECONDS, + format: "YYYY-MM-DD", + }, + }, + { + alias: "iso_8601", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "YYYY-MM-DDTHH:mm:ss.SSSZ", + format: "YYYY-MM-DD", + }, + }, + { + alias: "yyyy_mm_dd", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "YYYY-MM-DD", + format: "YYYY-MM-DD", + }, + }, + { + alias: "lll", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "LLL", + format: "YYYY-MM-DD", + }, + }, +]; + +// Mock table data +const tableData = [ + { + epoch: "1727132400", + milliseconds: "1727132400000", + iso_8601: "2024-09-24T00:00:00.000+01:00", + yyyy_mm_dd: "2024-09-24", + lll: "September 25, 2024 12:00 AM", + }, + { + epoch: 1726980974, + milliseconds: 1726980974328, + iso_8601: "2024-09-23T09:01:53.350627", + yyyy_mm_dd: "2024-09-23", + lll: "Sep 23, 2024 09:01", + }, +]; + +// Expected transformed data +const expectedData = [ + { + epoch: "2024-09-24", // Converted from epoch to date + milliseconds: "2024-09-24", // Converted from milliseconds to date + iso_8601: "2024-09-24", // ISO 8601 to date + yyyy_mm_dd: "2024-09-24", // No transformation needed + lll: "2024-09-25", // LLL format to date + }, + { + epoch: "2024-09-22", // Converted from epoch to date + milliseconds: "2024-09-22", // Converted from milliseconds to date + iso_8601: "2024-09-23", // ISO 8601 to date + yyyy_mm_dd: "2024-09-23", // No transformation needed + lll: "2024-09-23", // LLL format to date + }, +]; + +describe("transformDataPureFn", () => { + it("should transform table data based on column meta properties", () => { + const result = transformDataPureFn( + tableData, + columns as ReactTableColumnProps[], + ); + + expect(result).toEqual(expectedData); + }); + + it("should handle invalid date values", () => { + const invalidTableData = [ + { + epoch: "invalid_epoch", + milliseconds: "invalid_milliseconds", + iso_8601: "invalid_iso_8601", + yyyy_mm_dd: "invalid_date", + lll: "invalid_lll", + }, + ]; + + const expectedInvalidData = [ + { + epoch: "Invalid date", + milliseconds: "Invalid date", + iso_8601: "8601-01-01", + yyyy_mm_dd: "Invalid date", + lll: "Invalid date", + }, + ]; + + const result = transformDataPureFn( + invalidTableData, + columns as ReactTableColumnProps[], + ); + + expect(result).toEqual(expectedInvalidData); + }); + + it("should return an empty array when tableData is not an array", () => { + const result = transformDataPureFn([], columns as ReactTableColumnProps[]); + + expect(result).toEqual([]); + }); +}); From 2ec53d13d959fda8fe013ea0d315155404ed5387 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 10:45:11 +0100 Subject: [PATCH 11/21] complete transformDataPureFn unit test --- .../TransformDataPureFn.test.ts | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts index 2468ff8ef95..5610b141ff5 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts @@ -82,6 +82,70 @@ const expectedData = [ }, ]; +// Mock columns for non-date data +const columnsNonDate = [ + { + id: "role", + alias: "role", + metaProperties: { + type: ColumnTypes.NUMBER, + format: "", + inputFormat: "", + decimals: 0, + }, + }, + { + id: "id", + alias: "id", + metaProperties: { + type: ColumnTypes.NUMBER, + format: "", + inputFormat: "", + decimals: 0, + }, + }, + { + id: "name", + alias: "name", + metaProperties: { + type: ColumnTypes.TEXT, + format: "", + inputFormat: "", + decimals: 0, + }, + }, +]; + +// Mock table data for non-date transformation +const tableDataNonDate = [ + { + role: 1, + id: 1, + name: "Alice Johnson", + __originalIndex__: 0, + }, + { + role: 2, + id: 2, + name: "Bob Smith", + __originalIndex__: 1, + }, +]; + +// Expected transformed data for non-date columns +const expectedDataNonDate = [ + { + role: 1, + id: 1, + name: "Alice Johnson", + }, + { + role: 2, + id: 2, + name: "Bob Smith", + }, +]; + describe("transformDataPureFn", () => { it("should transform table data based on column meta properties", () => { const result = transformDataPureFn( @@ -121,9 +185,18 @@ describe("transformDataPureFn", () => { expect(result).toEqual(expectedInvalidData); }); - it("should return an empty array when tableData is not an array", () => { + it("should return an empty array when tableData is empty", () => { const result = transformDataPureFn([], columns as ReactTableColumnProps[]); expect(result).toEqual([]); }); + + it("should not transform non-date data", () => { + const result = transformDataPureFn( + tableDataNonDate, + columnsNonDate as ReactTableColumnProps[], + ); + + expect(result).toEqual(expectedDataNonDate); + }); }); From 4b5f3734fa69f3c8c9b38b669f61e4ff12f417cd Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 10:46:39 +0100 Subject: [PATCH 12/21] extract test fixtures --- .../TransformDataPureFn.test.ts | 155 +----------------- .../widget/reactTableUtils/fixtures.ts | 145 ++++++++++++++++ 2 files changed, 154 insertions(+), 146 deletions(-) create mode 100644 app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts index 5610b141ff5..3dbf751e9aa 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts @@ -1,150 +1,13 @@ -import { ColumnTypes, DateInputFormat } from "widgets/TableWidgetV2/constants"; -import { transformDataPureFn } from "./transformDataPureFn"; import type { ReactTableColumnProps } from "widgets/TableWidgetV2/component/Constants"; - -// Mock columns data -const columns = [ - { - alias: "epoch", - metaProperties: { - type: ColumnTypes.DATE, - inputFormat: DateInputFormat.EPOCH, - format: "YYYY-MM-DD", - }, - }, - { - alias: "milliseconds", - metaProperties: { - type: ColumnTypes.DATE, - inputFormat: DateInputFormat.MILLISECONDS, - format: "YYYY-MM-DD", - }, - }, - { - alias: "iso_8601", - metaProperties: { - type: ColumnTypes.DATE, - inputFormat: "YYYY-MM-DDTHH:mm:ss.SSSZ", - format: "YYYY-MM-DD", - }, - }, - { - alias: "yyyy_mm_dd", - metaProperties: { - type: ColumnTypes.DATE, - inputFormat: "YYYY-MM-DD", - format: "YYYY-MM-DD", - }, - }, - { - alias: "lll", - metaProperties: { - type: ColumnTypes.DATE, - inputFormat: "LLL", - format: "YYYY-MM-DD", - }, - }, -]; - -// Mock table data -const tableData = [ - { - epoch: "1727132400", - milliseconds: "1727132400000", - iso_8601: "2024-09-24T00:00:00.000+01:00", - yyyy_mm_dd: "2024-09-24", - lll: "September 25, 2024 12:00 AM", - }, - { - epoch: 1726980974, - milliseconds: 1726980974328, - iso_8601: "2024-09-23T09:01:53.350627", - yyyy_mm_dd: "2024-09-23", - lll: "Sep 23, 2024 09:01", - }, -]; - -// Expected transformed data -const expectedData = [ - { - epoch: "2024-09-24", // Converted from epoch to date - milliseconds: "2024-09-24", // Converted from milliseconds to date - iso_8601: "2024-09-24", // ISO 8601 to date - yyyy_mm_dd: "2024-09-24", // No transformation needed - lll: "2024-09-25", // LLL format to date - }, - { - epoch: "2024-09-22", // Converted from epoch to date - milliseconds: "2024-09-22", // Converted from milliseconds to date - iso_8601: "2024-09-23", // ISO 8601 to date - yyyy_mm_dd: "2024-09-23", // No transformation needed - lll: "2024-09-23", // LLL format to date - }, -]; - -// Mock columns for non-date data -const columnsNonDate = [ - { - id: "role", - alias: "role", - metaProperties: { - type: ColumnTypes.NUMBER, - format: "", - inputFormat: "", - decimals: 0, - }, - }, - { - id: "id", - alias: "id", - metaProperties: { - type: ColumnTypes.NUMBER, - format: "", - inputFormat: "", - decimals: 0, - }, - }, - { - id: "name", - alias: "name", - metaProperties: { - type: ColumnTypes.TEXT, - format: "", - inputFormat: "", - decimals: 0, - }, - }, -]; - -// Mock table data for non-date transformation -const tableDataNonDate = [ - { - role: 1, - id: 1, - name: "Alice Johnson", - __originalIndex__: 0, - }, - { - role: 2, - id: 2, - name: "Bob Smith", - __originalIndex__: 1, - }, -]; - -// Expected transformed data for non-date columns -const expectedDataNonDate = [ - { - role: 1, - id: 1, - name: "Alice Johnson", - }, - { - role: 2, - id: 2, - name: "Bob Smith", - }, -]; +import { + columns, + columnsNonDate, + expectedData, + expectedDataNonDate, + tableData, + tableDataNonDate, +} from "./fixtures"; +import { transformDataPureFn } from "./transformDataPureFn"; describe("transformDataPureFn", () => { it("should transform table data based on column meta properties", () => { diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts new file mode 100644 index 00000000000..cccaaf15d3f --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts @@ -0,0 +1,145 @@ +import { ColumnTypes, DateInputFormat } from "widgets/TableWidgetV2/constants"; + +// Mock columns data +export const columns = [ + { + alias: "epoch", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: DateInputFormat.EPOCH, + format: "YYYY-MM-DD", + }, + }, + { + alias: "milliseconds", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: DateInputFormat.MILLISECONDS, + format: "YYYY-MM-DD", + }, + }, + { + alias: "iso_8601", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "YYYY-MM-DDTHH:mm:ss.SSSZ", + format: "YYYY-MM-DD", + }, + }, + { + alias: "yyyy_mm_dd", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "YYYY-MM-DD", + format: "YYYY-MM-DD", + }, + }, + { + alias: "lll", + metaProperties: { + type: ColumnTypes.DATE, + inputFormat: "LLL", + format: "YYYY-MM-DD", + }, + }, +]; + +// Mock table data +export const tableData = [ + { + epoch: "1727132400", + milliseconds: "1727132400000", + iso_8601: "2024-09-24T00:00:00.000+01:00", + yyyy_mm_dd: "2024-09-24", + lll: "September 25, 2024 12:00 AM", + }, + { + epoch: 1726980974, + milliseconds: 1726980974328, + iso_8601: "2024-09-23T09:01:53.350627", + yyyy_mm_dd: "2024-09-23", + lll: "Sep 23, 2024 09:01", + }, +]; + +// Expected transformed data +export const expectedData = [ + { + epoch: "2024-09-24", // Converted from epoch to date + milliseconds: "2024-09-24", // Converted from milliseconds to date + iso_8601: "2024-09-24", // ISO 8601 to date + yyyy_mm_dd: "2024-09-24", // No transformation needed + lll: "2024-09-25", // LLL format to date + }, + { + epoch: "2024-09-22", // Converted from epoch to date + milliseconds: "2024-09-22", // Converted from milliseconds to date + iso_8601: "2024-09-23", // ISO 8601 to date + yyyy_mm_dd: "2024-09-23", // No transformation needed + lll: "2024-09-23", // LLL format to date + }, +]; + +// Mock columns for non-date data +export const columnsNonDate = [ + { + id: "role", + alias: "role", + metaProperties: { + type: ColumnTypes.NUMBER, + format: "", + inputFormat: "", + decimals: 0, + }, + }, + { + id: "id", + alias: "id", + metaProperties: { + type: ColumnTypes.NUMBER, + format: "", + inputFormat: "", + decimals: 0, + }, + }, + { + id: "name", + alias: "name", + metaProperties: { + type: ColumnTypes.TEXT, + format: "", + inputFormat: "", + decimals: 0, + }, + }, +]; + +// Mock table data for non-date transformation +export const tableDataNonDate = [ + { + role: 1, + id: 1, + name: "Alice Johnson", + __originalIndex__: 0, + }, + { + role: 2, + id: 2, + name: "Bob Smith", + __originalIndex__: 1, + }, +]; + +// Expected transformed data for non-date columns +export const expectedDataNonDate = [ + { + role: 1, + id: 1, + name: "Alice Johnson", + }, + { + role: 2, + id: 2, + name: "Bob Smith", + }, +]; From aca19a8440b7d3fa063b350556ea439f3f7ffd58 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 23 Sep 2024 10:47:02 +0100 Subject: [PATCH 13/21] remove TODO comment --- .../TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx index 55dbaec39c7..1454694ce8b 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/transformDataPureFn.tsx @@ -10,7 +10,6 @@ import shallowEqual from "shallowequal"; export type tableData = Array>; -//TODO: (Vamsi) need to unit test this function export const transformDataPureFn = ( tableData: Array>, columns: ReactTableColumnProps[], From 36c32d629b6616b55988a12739a604a187b35072 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Tue, 24 Sep 2024 08:15:54 +0100 Subject: [PATCH 14/21] add formattedDate to isNewRow --- .../component/cellComponents/DateCell.tsx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx index 884116599d5..ac30a4e5eb5 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -224,8 +224,19 @@ export const DateCell = (props: DateComponentProps) => { const onDateSelected = (date: string) => { let momentAdjustedInputFormat = inputFormat; + // If the input format is milliseconds or epoch, convert the date to the required format + if (inputFormat === DateInputFormat.MILLISECONDS) { + momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; + } else if (inputFormat === DateInputFormat.EPOCH) { + momentAdjustedInputFormat = MomentDateInputFormat.SECONDS; + } + + const formattedDate = date + ? moment(date).format(momentAdjustedInputFormat) + : ""; + if (isNewRow) { - updateNewRowValues(alias, date, date); + updateNewRowValues(alias, date, formattedDate); return; } @@ -241,17 +252,6 @@ export const DateCell = (props: DateComponentProps) => { setShowRequiredError(false); setHasFocus(false); - // If the input format is milliseconds or epoch, convert the date to the required format - if (inputFormat === DateInputFormat.MILLISECONDS) { - momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; - } else if (inputFormat === DateInputFormat.EPOCH) { - momentAdjustedInputFormat = MomentDateInputFormat.SECONDS; - } - - const formattedDate = date - ? moment(date).format(momentAdjustedInputFormat) - : ""; - onDateSave(rowIndex, alias, formattedDate, onDateSelectedString); }; From d8701f22ca5ea33376af0d1267c36dfcf9e236c4 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Wed, 25 Sep 2024 00:31:16 +0100 Subject: [PATCH 15/21] fix: extract momentAdjustedInputFormat into a function in DateCell --- .../component/cellComponents/DateCell.tsx | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx index ac30a4e5eb5..8e34d928d86 100644 --- a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -200,6 +200,19 @@ export const DateCell = (props: DateComponentProps) => { const [isValid, setIsValid] = useState(true); const [showRequiredError, setShowRequiredError] = useState(false); const contentRef = useRef(null); + + const convertInputFormatToMomentFormat = (inputFormat: string) => { + let momentAdjustedInputFormat = inputFormat; + + if (inputFormat === DateInputFormat.MILLISECONDS) { + momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; + } else if (inputFormat === DateInputFormat.EPOCH) { + momentAdjustedInputFormat = MomentDateInputFormat.SECONDS; + } + + return momentAdjustedInputFormat; + }; + const isCellCompletelyValid = useMemo( () => isEditableCellValid && isValid, [isEditableCellValid, isValid], @@ -222,14 +235,8 @@ export const DateCell = (props: DateComponentProps) => { }, [value, props.outputFormat]); const onDateSelected = (date: string) => { - let momentAdjustedInputFormat = inputFormat; - - // If the input format is milliseconds or epoch, convert the date to the required format - if (inputFormat === DateInputFormat.MILLISECONDS) { - momentAdjustedInputFormat = MomentDateInputFormat.MILLISECONDS; - } else if (inputFormat === DateInputFormat.EPOCH) { - momentAdjustedInputFormat = MomentDateInputFormat.SECONDS; - } + const momentAdjustedInputFormat = + convertInputFormatToMomentFormat(inputFormat); const formattedDate = date ? moment(date).format(momentAdjustedInputFormat) From 17fa7e9d13b549f3e3012e8c22b23a84e25cdb7a Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Wed, 25 Sep 2024 07:28:48 +0100 Subject: [PATCH 16/21] extend test to cover all table column date types --- .../TableV2/Date_column_editing_2_spec.ts | 43 ----- .../Date_column_types_validation_spec.ts | 167 ++++++++++++++++++ .../ClientSide/Widgets/TableV2/fixtures.ts | 114 +++++++----- 3 files changed, 233 insertions(+), 91 deletions(-) create mode 100644 app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts index ac936a7a6e3..50728d23c91 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_editing_2_spec.ts @@ -10,8 +10,6 @@ import { datePickerlocators } from "../../../../../locators/WidgetLocators"; import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; -import { getFormattedTomorrowDates } from "./helpers"; -import { unixTableV2Data } from "./fixtures"; describe( "Table widget date column inline editing functionality", @@ -94,46 +92,5 @@ describe( expect($textData).to.include("YYYY-MM-DDTHH:mm:ss.SSSZ"), ); }); - - it("4. should allow input format of Unix Timestamp(ms) and not throw Invalid Value error when inline editing", () => { - const { verboseFormat, isoFormat } = getFormattedTomorrowDates(); - - EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); - - propPane.NavigateBackToPropertyPane(); - - // Update table data - propPane.UpdatePropertyFieldValue("Table data", unixTableV2Data); - - // Change column to date - table.ChangeColumnType("unix", "Date", "v2"); - - // Edit column - table.EditColumn("unix", "v2"); - - // Update date format property - propPane.ToggleJSMode("Date format", true); - propPane.UpdatePropertyFieldValue("Date format", "Milliseconds"); - - // Update display format property - propPane.ToggleJSMode("Display format", true); - propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD"); - - // Toggle editable - propPane.TogglePropertyState("Editable", "On"); - - // Click unix cell edit - table.ClickOnEditIcon(0, 2); - - // Click on specific date within - agHelper.GetNClick( - `${table._dateInputPopover} [aria-label='${verboseFormat}']`, - ); - - // Check that date is set in column - table - .ReadTableRowColumnData(0, 2, "v2") - .then((val) => expect(val).to.equal(isoFormat)); - }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts new file mode 100644 index 00000000000..07ea4cac15c --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts @@ -0,0 +1,167 @@ +import { + agHelper, + entityExplorer, + propPane, + table, +} from "../../../../../support/Objects/ObjectsCore"; + +import EditorNavigation, { + EntityType, +} from "../../../../../support/Pages/EditorNavigation"; +import { tableV2DateTestData } from "./fixtures"; +import { getFormattedTomorrowDates } from "./helpers"; + +describe( + "Table widget date column type validation", + { tags: ["@tag.Widget", "@tag.Table"] }, + () => { + before(() => { + entityExplorer.DragNDropWidget("tablewidgetv2", 350, 500); + EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); + propPane.ToggleJSMode("Table data", true); + propPane.UpdatePropertyFieldValue("Table data", tableV2DateTestData); + }); + + afterEach(() => { + propPane.NavigateBackToPropertyPane(false); + }); + + const setEditableDateFormats = (format: string) => { + // Update date format property + propPane.ToggleJSMode("Date format", true); + propPane.UpdatePropertyFieldValue("Date format", format); + + // Update display format property + propPane.ToggleJSMode("Display format", true); + propPane.UpdatePropertyFieldValue("Display format", "YYYY-MM-DD"); + + // Toggle editable + propPane.TogglePropertyState("Editable", "On"); + }; + + const clickAndValidateDateCell = (row: number, column: number) => { + // Click unix cell edit + table.ClickOnEditIcon(row, column); + + // Click on specific date within + agHelper.GetNClick( + `${table._dateInputPopover} [aria-label='${getFormattedTomorrowDates().verboseFormat}']`, + ); + + // Check that date is set in column + table + .ReadTableRowColumnData(row, column, "v2") + .then((val) => + expect(val).to.equal(getFormattedTomorrowDates().isoFormat), + ); + }; + + it("1. should allow inline editing of Unix Timestamp in seconds (unix/s)", () => { + table.ChangeColumnType("unix/s", "Date"); + setEditableDateFormats("Epoch"); + clickAndValidateDateCell(0, 0); + }); + + it("2. should allow inline editing of Unix Timestamp in milliseconds (unix/ms)", () => { + table.ChangeColumnType("unix/ms", "Date"); + setEditableDateFormats("Milliseconds"); + clickAndValidateDateCell(0, 1); + }); + + it("3. should allow inline editing of date in YYYY-MM-DD format", () => { + table.ChangeColumnType("yyyy-mm-dd", "Date"); + setEditableDateFormats("YYYY-MM-DD"); + clickAndValidateDateCell(0, 2); + }); + + it("4. should allow inline editing of date in YYYY-MM-DD HH:mm format", () => { + table.ChangeColumnType("yyyy-mm-dd hh:mm", "Date"); + setEditableDateFormats("YYYY-MM-DD HH:mm"); + clickAndValidateDateCell(0, 3); + }); + + it("5. should allow inline editing of date in ISO 8601 format (YYYY-MM-DDTHH:mm:ss)", () => { + table.ChangeColumnType("yyyy-mm-ddTHH:mm:ss", "Date"); + setEditableDateFormats("YYYY-MM-DDTHH:mm:ss"); + clickAndValidateDateCell(0, 4); + }); + + it("6. should allow inline editing of date in YYYY-MM-DD HH:mm:ss format", () => { + table.ChangeColumnType("yyyy-mm-dd hh:mm:ss", "Date"); + setEditableDateFormats("YYYY-MM-DD HH:mm:ss"); + clickAndValidateDateCell(0, 5); + }); + + it("7. should allow inline editing of date in 'do MMM yyyy' format", () => { + table.ChangeColumnType("do MMM yyyy", "Date"); + setEditableDateFormats("Do MMM YYYY"); + clickAndValidateDateCell(0, 6); + }); + + it("8. should allow inline editing of date in DD/MM/YYYY format", () => { + table.ChangeColumnType("dd/mm/yyyy", "Date"); + setEditableDateFormats("DD/MM/YYYY"); + clickAndValidateDateCell(0, 7); + }); + + it("9. should allow inline editing of date in DD/MM/YYYY HH:mm format", () => { + table.ChangeColumnType("dd/mm/yyyy hh:mm", "Date"); + setEditableDateFormats("DD/MM/YYYY HH:mm"); + clickAndValidateDateCell(0, 8); + }); + + it("10. should allow inline editing of date in LLL (Month Day, Year Time) format", () => { + table.ChangeColumnType("lll", "Date"); + setEditableDateFormats("LLL"); + clickAndValidateDateCell(0, 9); + }); + + it("11. should allow inline editing of date in LL (Month Day, Year) format", () => { + table.ChangeColumnType("ll", "Date"); + setEditableDateFormats("LL"); + clickAndValidateDateCell(0, 10); + }); + + it("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { + table.ChangeColumnType("d mmmm, yyyy", "Date"); + setEditableDateFormats("D MMMM, YYYY"); + clickAndValidateDateCell(0, 11); + }); + + it("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { + table.ChangeColumnType("h:mm A d mmmm, yyyy", "Date"); + setEditableDateFormats("h:mm A D MMMM, YYYY"); + clickAndValidateDateCell(0, 12); + }); + + it("14. should allow inline editing of date in MM-DD-YYYY format", () => { + table.ChangeColumnType("mm-dd-yyyy", "Date"); + setEditableDateFormats("MM-DD-YYYY"); + clickAndValidateDateCell(0, 13); + }); + + it("15. should allow inline editing of date in DD-MM-YYYY format", () => { + table.ChangeColumnType("dd-mm-yyyy", "Date"); + setEditableDateFormats("DD-MM-YYYY"); + clickAndValidateDateCell(0, 14); + }); + + it("16. should allow inline editing of date in MM/DD/YYYY format", () => { + table.ChangeColumnType("mm/dd/yyyy", "Date"); + setEditableDateFormats("MM/DD/YYYY"); + clickAndValidateDateCell(0, 15); + }); + + it("17. should allow inline editing of date in DD/MM/YY format", () => { + table.ChangeColumnType("dd/mm/yy", "Date"); + setEditableDateFormats("DD/MM/YY"); + clickAndValidateDateCell(0, 16); + }); + + it("18. should allow inline editing of date in MM/DD/YY format", () => { + table.ChangeColumnType("mm/dd/yy", "Date"); + setEditableDateFormats("MM/DD/YY"); + clickAndValidateDateCell(0, 17); + }); + }, +); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts index 89e5335dcbd..8f1ef7b2bcd 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts @@ -1,51 +1,69 @@ -export const unixTableV2Data = ` +export const tableV2DateTestData = ` {{ [ - { - unix: 1726713837918, - role: 1, - id: 1, - name: "Alice Johnson", - email: "alice.johnson@example.com", - age: 28, - gender: 2, - }, - { - unix: 1726713837918, - role: 2, - id: 2, - name: "Bob Smith", - email: "bob.smith@example.com", - age: 34, - gender: 1 - }, - { - unix: 1726713837918, - role: 3, - id: 3, - name: "Charlie Brown", - email: "charlie.brown@example.com", - age: 25, - gender: 3 - }, - { - unix: 1726713837918, - role: 2, - id: 4, - name: "Diana Prince", - email: "diana.prince@example.com", - age: 30, - gender: 2 - }, - { - unix: 1726713837918, - role: 1, - id: 5, - name: "Evan Williams", - email: "evan.williams@example.com", - age: 27, - gender: 1 - } - ] - }} + { + "unix/s": 1727212200, + "unix/ms": 1727212200000, + "yyyy-mm-dd": "2024-09-25", + "yyyy-mm-dd hh:mm": "2024-09-25 14:30", + iso8601: "2024-09-25T14:30:00.000Z", + "yyyy-mm-ddTHH:mm:ss": "2024-09-25T14:30:00", + "yyyy-mm-dd hh:mm:ss": "2024-09-25 02:30:00", + "do MMM yyyy": "25th Sep 2024", + "dd/mm/yyyy": "25/09/2024", + "dd/mm/yyyy hh:mm": "25/09/2024 14:30", + lll: "September 25, 2024 2:30 PM", + ll: "September 25, 2024", + "d mmmm, yyyy": "25 September, 2024", + "h:mm A d mmmm, yyyy": "2:30 PM 25 September, 2024", + "mm-dd-yyyy": "09-25-2024", + "dd-mm-yyyy": "25-09-2024", + "mm/dd/yyyy": "09/25/2024", + "dd/mm/yy": "25/09/24", + "mm/dd/yy": "09/25/24", + }, + { + "unix/s": 1695676200, + "unix/ms": 1695676200000, + "yyyy-mm-dd": "2023-09-25", + "yyyy-mm-dd hh:mm": "2023-09-25 10:15", + iso8601: "2023-09-25T10:15:00.000Z", + "yyyy-mm-ddTHH:mm:ss": "2023-09-25T10:15:00", + "yyyy-mm-dd hh:mm:ss": "2023-09-25 10:15:00", + "do MMM yyyy": "25th Sep 2023", + "dd/mm/yyyy": "25/09/2023", + "dd/mm/yyyy hh:mm": "25/09/2023 10:15", + lll: "September 25, 2023 10:15 AM", + ll: "September 25, 2023", + "d mmmm, yyyy": "25 September, 2023", + "h:mm A d mmmm, yyyy": "10:15 AM 25 September, 2023", + "mm-dd-yyyy": "09-25-2023", + "dd-mm-yyyy": "25-09-2023", + "mm/dd/yyyy": "09/25/2023", + "dd/mm/yy": "25/09/23", + "mm/dd/yy": "09/25/23", + }, + { + "unix/s": 1664140200, + "unix/ms": 1664140200000, + "yyyy-mm-dd": "2022-09-25", + "yyyy-mm-dd hh:mm": "2022-09-25 08:45", + iso8601: "2022-09-25T08:45:00.000Z", + "yyyy-mm-ddTHH:mm:ss": "2022-09-25T08:45:00", + "yyyy-mm-dd hh:mm:ss": "2022-09-25 08:45:00", + "do MMM yyyy": "25th Sep 2022", + "dd/mm/yyyy": "25/09/2022", + "dd/mm/yyyy hh:mm": "25/09/2022 08:45", + lll: "September 25, 2022 8:45 AM", + ll: "September 25, 2022", + "d mmmm, yyyy": "25 September, 2022", + "h:mm A d mmmm, yyyy": "8:45 AM 25 September, 2022", + "mm-dd-yyyy": "09-25-2022", + "dd-mm-yyyy": "25-09-2022", + "mm/dd/yyyy": "09/25/2022", + "dd/mm/yy": "25/09/22", + "mm/dd/yy": "09/25/22", + }, + ] +}} `; From 2abc737be8f41b371b05206fe82c3da0798e3a67 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 27 Sep 2024 12:50:26 +0100 Subject: [PATCH 17/21] fix test case and move fixtures --- .../Date_column_types_validation_spec.ts | 85 ++++++++----------- .../ClientSide/Widgets/TableV2/fixtures.ts | 69 --------------- .../cypress/fixtures/tableDateColumnTypes.ts | 26 ++++++ 3 files changed, 60 insertions(+), 120 deletions(-) delete mode 100644 app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts create mode 100644 app/client/cypress/fixtures/tableDateColumnTypes.ts diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts index 07ea4cac15c..361a02637bf 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts @@ -1,3 +1,4 @@ +import { tableDateColumnTypes } from "../../../../../fixtures/tableDateColumnTypes"; import { agHelper, entityExplorer, @@ -8,7 +9,6 @@ import { import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; -import { tableV2DateTestData } from "./fixtures"; import { getFormattedTomorrowDates } from "./helpers"; describe( @@ -19,10 +19,11 @@ describe( entityExplorer.DragNDropWidget("tablewidgetv2", 350, 500); EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); propPane.ToggleJSMode("Table data", true); - propPane.UpdatePropertyFieldValue("Table data", tableV2DateTestData); + propPane.UpdatePropertyFieldValue("Table data", tableDateColumnTypes); + table.EditColumn("unixs", "v2"); }); - afterEach(() => { + beforeEach(() => { propPane.NavigateBackToPropertyPane(false); }); @@ -57,111 +58,93 @@ describe( }; it("1. should allow inline editing of Unix Timestamp in seconds (unix/s)", () => { - table.ChangeColumnType("unix/s", "Date"); + table.ChangeColumnType("unixs", "Date"); setEditableDateFormats("Epoch"); clickAndValidateDateCell(0, 0); }); it("2. should allow inline editing of Unix Timestamp in milliseconds (unix/ms)", () => { - table.ChangeColumnType("unix/ms", "Date"); + table.ChangeColumnType("unixms", "Date"); setEditableDateFormats("Milliseconds"); clickAndValidateDateCell(0, 1); }); it("3. should allow inline editing of date in YYYY-MM-DD format", () => { - table.ChangeColumnType("yyyy-mm-dd", "Date"); + table.EditColumn("yyyymmdd", "v2"); setEditableDateFormats("YYYY-MM-DD"); clickAndValidateDateCell(0, 2); }); it("4. should allow inline editing of date in YYYY-MM-DD HH:mm format", () => { - table.ChangeColumnType("yyyy-mm-dd hh:mm", "Date"); + table.EditColumn("yyyymmddhhmm", "v2"); setEditableDateFormats("YYYY-MM-DD HH:mm"); clickAndValidateDateCell(0, 3); }); it("5. should allow inline editing of date in ISO 8601 format (YYYY-MM-DDTHH:mm:ss)", () => { - table.ChangeColumnType("yyyy-mm-ddTHH:mm:ss", "Date"); + table.EditColumn("iso8601", "v2"); setEditableDateFormats("YYYY-MM-DDTHH:mm:ss"); clickAndValidateDateCell(0, 4); }); - it("6. should allow inline editing of date in YYYY-MM-DD HH:mm:ss format", () => { - table.ChangeColumnType("yyyy-mm-dd hh:mm:ss", "Date"); - setEditableDateFormats("YYYY-MM-DD HH:mm:ss"); + it("6. should allow inline editing of date in YYYY-MM-DD HH:mm format", () => { + table.EditColumn("yyyymmddTHHmmss", "v2"); + setEditableDateFormats("YYYY-MM-DD HH:mm"); clickAndValidateDateCell(0, 5); }); it("7. should allow inline editing of date in 'do MMM yyyy' format", () => { - table.ChangeColumnType("do MMM yyyy", "Date"); - setEditableDateFormats("Do MMM YYYY"); + table.ChangeColumnType("yyyymmddhhmmss", "Date"); + setEditableDateFormats("YYYY-MM-DDTHH:mm:ss"); clickAndValidateDateCell(0, 6); }); it("8. should allow inline editing of date in DD/MM/YYYY format", () => { - table.ChangeColumnType("dd/mm/yyyy", "Date"); - setEditableDateFormats("DD/MM/YYYY"); + table.ChangeColumnType("doMMMyyyy", "Date"); + setEditableDateFormats("Do MMM YYYY"); clickAndValidateDateCell(0, 7); }); it("9. should allow inline editing of date in DD/MM/YYYY HH:mm format", () => { - table.ChangeColumnType("dd/mm/yyyy hh:mm", "Date"); - setEditableDateFormats("DD/MM/YYYY HH:mm"); + table.EditColumn("ddmmyyyy", "v2"); + setEditableDateFormats("DD/MM/YYYY"); clickAndValidateDateCell(0, 8); }); it("10. should allow inline editing of date in LLL (Month Day, Year Time) format", () => { - table.ChangeColumnType("lll", "Date"); - setEditableDateFormats("LLL"); + table.EditColumn("ddmmyyyyhhmm", "v2"); + setEditableDateFormats("DD/MM/YYYY HH:mm"); clickAndValidateDateCell(0, 9); }); it("11. should allow inline editing of date in LL (Month Day, Year) format", () => { - table.ChangeColumnType("ll", "Date"); - setEditableDateFormats("LL"); + table.EditColumn("lll", "v2"); + setEditableDateFormats("LLL"); clickAndValidateDateCell(0, 10); }); - it("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { - table.ChangeColumnType("d mmmm, yyyy", "Date"); - setEditableDateFormats("D MMMM, YYYY"); + it.only("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { + table.EditColumn("ll", "v2"); + setEditableDateFormats("LL"); clickAndValidateDateCell(0, 11); }); - it("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { - table.ChangeColumnType("h:mm A d mmmm, yyyy", "Date"); - setEditableDateFormats("h:mm A D MMMM, YYYY"); + it.only("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { + table.EditColumn("dmmmmyyyy", "v2"); + setEditableDateFormats("D MMMM, YYYY"); clickAndValidateDateCell(0, 12); }); - it("14. should allow inline editing of date in MM-DD-YYYY format", () => { - table.ChangeColumnType("mm-dd-yyyy", "Date"); - setEditableDateFormats("MM-DD-YYYY"); + it.only("14. should allow inline editing of date in MM-DD-YYYY format", () => { + table.EditColumn("hmmAdmmmmyyyy", "v2"); + setEditableDateFormats("H:mm A D MMMM, YYYY"); clickAndValidateDateCell(0, 13); }); - it("15. should allow inline editing of date in DD-MM-YYYY format", () => { - table.ChangeColumnType("dd-mm-yyyy", "Date"); - setEditableDateFormats("DD-MM-YYYY"); + it.only("15. should allow inline editing of date in DD-MM-YYYY format", () => { + table.EditColumn("mm1dd1yyyy", "v2"); + setEditableDateFormats("MM-DD-YYYY"); clickAndValidateDateCell(0, 14); }); - - it("16. should allow inline editing of date in MM/DD/YYYY format", () => { - table.ChangeColumnType("mm/dd/yyyy", "Date"); - setEditableDateFormats("MM/DD/YYYY"); - clickAndValidateDateCell(0, 15); - }); - - it("17. should allow inline editing of date in DD/MM/YY format", () => { - table.ChangeColumnType("dd/mm/yy", "Date"); - setEditableDateFormats("DD/MM/YY"); - clickAndValidateDateCell(0, 16); - }); - - it("18. should allow inline editing of date in MM/DD/YY format", () => { - table.ChangeColumnType("mm/dd/yy", "Date"); - setEditableDateFormats("MM/DD/YY"); - clickAndValidateDateCell(0, 17); - }); }, ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts deleted file mode 100644 index 8f1ef7b2bcd..00000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/fixtures.ts +++ /dev/null @@ -1,69 +0,0 @@ -export const tableV2DateTestData = ` -{{ - [ - { - "unix/s": 1727212200, - "unix/ms": 1727212200000, - "yyyy-mm-dd": "2024-09-25", - "yyyy-mm-dd hh:mm": "2024-09-25 14:30", - iso8601: "2024-09-25T14:30:00.000Z", - "yyyy-mm-ddTHH:mm:ss": "2024-09-25T14:30:00", - "yyyy-mm-dd hh:mm:ss": "2024-09-25 02:30:00", - "do MMM yyyy": "25th Sep 2024", - "dd/mm/yyyy": "25/09/2024", - "dd/mm/yyyy hh:mm": "25/09/2024 14:30", - lll: "September 25, 2024 2:30 PM", - ll: "September 25, 2024", - "d mmmm, yyyy": "25 September, 2024", - "h:mm A d mmmm, yyyy": "2:30 PM 25 September, 2024", - "mm-dd-yyyy": "09-25-2024", - "dd-mm-yyyy": "25-09-2024", - "mm/dd/yyyy": "09/25/2024", - "dd/mm/yy": "25/09/24", - "mm/dd/yy": "09/25/24", - }, - { - "unix/s": 1695676200, - "unix/ms": 1695676200000, - "yyyy-mm-dd": "2023-09-25", - "yyyy-mm-dd hh:mm": "2023-09-25 10:15", - iso8601: "2023-09-25T10:15:00.000Z", - "yyyy-mm-ddTHH:mm:ss": "2023-09-25T10:15:00", - "yyyy-mm-dd hh:mm:ss": "2023-09-25 10:15:00", - "do MMM yyyy": "25th Sep 2023", - "dd/mm/yyyy": "25/09/2023", - "dd/mm/yyyy hh:mm": "25/09/2023 10:15", - lll: "September 25, 2023 10:15 AM", - ll: "September 25, 2023", - "d mmmm, yyyy": "25 September, 2023", - "h:mm A d mmmm, yyyy": "10:15 AM 25 September, 2023", - "mm-dd-yyyy": "09-25-2023", - "dd-mm-yyyy": "25-09-2023", - "mm/dd/yyyy": "09/25/2023", - "dd/mm/yy": "25/09/23", - "mm/dd/yy": "09/25/23", - }, - { - "unix/s": 1664140200, - "unix/ms": 1664140200000, - "yyyy-mm-dd": "2022-09-25", - "yyyy-mm-dd hh:mm": "2022-09-25 08:45", - iso8601: "2022-09-25T08:45:00.000Z", - "yyyy-mm-ddTHH:mm:ss": "2022-09-25T08:45:00", - "yyyy-mm-dd hh:mm:ss": "2022-09-25 08:45:00", - "do MMM yyyy": "25th Sep 2022", - "dd/mm/yyyy": "25/09/2022", - "dd/mm/yyyy hh:mm": "25/09/2022 08:45", - lll: "September 25, 2022 8:45 AM", - ll: "September 25, 2022", - "d mmmm, yyyy": "25 September, 2022", - "h:mm A d mmmm, yyyy": "8:45 AM 25 September, 2022", - "mm-dd-yyyy": "09-25-2022", - "dd-mm-yyyy": "25-09-2022", - "mm/dd/yyyy": "09/25/2022", - "dd/mm/yy": "25/09/22", - "mm/dd/yy": "09/25/22", - }, - ] -}} -`; diff --git a/app/client/cypress/fixtures/tableDateColumnTypes.ts b/app/client/cypress/fixtures/tableDateColumnTypes.ts new file mode 100644 index 00000000000..614b36b5e11 --- /dev/null +++ b/app/client/cypress/fixtures/tableDateColumnTypes.ts @@ -0,0 +1,26 @@ +export const tableDateColumnTypes = ` +{{ + [ + { + "unixs": 1727212200, + "unixms": 1727212200000, + "yyyymmdd": "2024-09-25", + "yyyymmddhhmm": "2024-09-25 14:30", + iso8601: "2024-09-25T14:30:00.000Z", + "yyyymmddTHHmmss": "2024-09-25T14:30:00", + "yyyymmddhhmmss": "2024-09-25 02:30:00", + "doMMMyyyy": "25th Sep 2024", + "ddmmyyyy": "25/09/2024", + "ddmmyyyyhhmm": "25/09/2024 14:30", + lll: "September 25, 2024 2:30 PM", + ll: "September 25, 2024", + "dmmmmyyyy": "25 September, 2024", + "hmmAdmmmmyyyy": "2:30 PM 25 September, 2024", + "mm1dd1yyyy": "09-25-2024", + "dd1mm1yyyy": "25-09-2024", + "ddimmiyy": "25/09/24", + "mmddyy": "09/25/24", + }, + ] +}} +`; From 17e8f41c99219fd0ab57cc503d45047414baa625 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 27 Sep 2024 12:50:51 +0100 Subject: [PATCH 18/21] remove .only from test --- .../Widgets/TableV2/Date_column_types_validation_spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts index 361a02637bf..ef71d4112cc 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts @@ -123,25 +123,25 @@ describe( clickAndValidateDateCell(0, 10); }); - it.only("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { + it("12. should allow inline editing of date in 'D MMMM, YYYY' format", () => { table.EditColumn("ll", "v2"); setEditableDateFormats("LL"); clickAndValidateDateCell(0, 11); }); - it.only("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { + it("13. should allow inline editing of date in 'h:mm A D MMMM, YYYY' format", () => { table.EditColumn("dmmmmyyyy", "v2"); setEditableDateFormats("D MMMM, YYYY"); clickAndValidateDateCell(0, 12); }); - it.only("14. should allow inline editing of date in MM-DD-YYYY format", () => { + it("14. should allow inline editing of date in MM-DD-YYYY format", () => { table.EditColumn("hmmAdmmmmyyyy", "v2"); setEditableDateFormats("H:mm A D MMMM, YYYY"); clickAndValidateDateCell(0, 13); }); - it.only("15. should allow inline editing of date in DD-MM-YYYY format", () => { + it("15. should allow inline editing of date in DD-MM-YYYY format", () => { table.EditColumn("mm1dd1yyyy", "v2"); setEditableDateFormats("MM-DD-YYYY"); clickAndValidateDateCell(0, 14); From dfe7b6594ea8f6482aca1647e04b02e36cfb1169 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 27 Sep 2024 13:58:37 +0100 Subject: [PATCH 19/21] check unit test --- .../widget/reactTableUtils/TransformDataPureFn.test.ts | 2 +- .../widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts index 3dbf751e9aa..97a994ce670 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts @@ -26,7 +26,7 @@ describe("transformDataPureFn", () => { milliseconds: "invalid_milliseconds", iso_8601: "invalid_iso_8601", yyyy_mm_dd: "invalid_date", - lll: "invalid_lll", + lll: "invalid_date", }, ]; diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts index cccaaf15d3f..75355f2f4b9 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/fixtures.ts @@ -47,8 +47,8 @@ export const columns = [ // Mock table data export const tableData = [ { - epoch: "1727132400", - milliseconds: "1727132400000", + epoch: 1727132400, + milliseconds: 1727132400000, iso_8601: "2024-09-24T00:00:00.000+01:00", yyyy_mm_dd: "2024-09-24", lll: "September 25, 2024 12:00 AM", From b13f966cac83b049b3050858135c3361c7d4716d Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Fri, 27 Sep 2024 14:45:23 +0100 Subject: [PATCH 20/21] add helper in Table.ts --- .../Date_column_types_validation_spec.ts | 5 ++- .../ClientSide/Widgets/TableV2/helpers.ts | 33 ------------------ app/client/cypress/support/Pages/Table.ts | 34 +++++++++++++++++++ 3 files changed, 36 insertions(+), 36 deletions(-) delete mode 100644 app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts index ef71d4112cc..0ce8bc321a3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/Date_column_types_validation_spec.ts @@ -9,7 +9,6 @@ import { import EditorNavigation, { EntityType, } from "../../../../../support/Pages/EditorNavigation"; -import { getFormattedTomorrowDates } from "./helpers"; describe( "Table widget date column type validation", @@ -46,14 +45,14 @@ describe( // Click on specific date within agHelper.GetNClick( - `${table._dateInputPopover} [aria-label='${getFormattedTomorrowDates().verboseFormat}']`, + `${table._dateInputPopover} [aria-label='${table.getFormattedTomorrowDates().verboseFormat}']`, ); // Check that date is set in column table .ReadTableRowColumnData(row, column, "v2") .then((val) => - expect(val).to.equal(getFormattedTomorrowDates().isoFormat), + expect(val).to.equal(table.getFormattedTomorrowDates().isoFormat), ); }; diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts deleted file mode 100644 index 713c897c601..00000000000 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TableV2/helpers.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Helper function to get formatted date strings for tomorrow's date. - * - * @returns {Object} An object containing: - * - verbose format (e.g., "Sat Sep 21 2024") - * - ISO date format (e.g., "2024-09-21") - */ -export function getFormattedTomorrowDates() { - // Create a new Date object for today - const tomorrow = new Date(); - - // Set the date to tomorrow by adding 1 to today's date - tomorrow.setDate(tomorrow.getDate() + 1); - - // Format tomorrow's date in verbose form (e.g., "Sat Sep 21 2024") - const verboseFormat = tomorrow - .toLocaleDateString("en-US", { - weekday: "short", - year: "numeric", - month: "short", - day: "2-digit", - }) - .replace(/,/g, ""); // Remove commas from the formatted string - - // Format tomorrow's date in ISO form (e.g., "2024-09-21") - const isoFormat = tomorrow.toISOString().split("T")[0]; // Extract the date part only - - // Return both formatted date strings as an object - return { - verboseFormat, - isoFormat, - }; -} diff --git a/app/client/cypress/support/Pages/Table.ts b/app/client/cypress/support/Pages/Table.ts index 2f90efb052c..5ca57eeb5b4 100644 --- a/app/client/cypress/support/Pages/Table.ts +++ b/app/client/cypress/support/Pages/Table.ts @@ -848,4 +848,38 @@ export class Table { this.agHelper.GetHoverNClick(selector, 1, true); verify && cy.get(selector).eq(1).should("be.disabled"); } + + /** + * Helper function to get formatted date strings for tomorrow's date. + * + * @returns {Object} An object containing: + * - verbose format (e.g., "Sat Sep 21 2024") + * - ISO date format (e.g., "2024-09-21") + */ + public getFormattedTomorrowDates() { + // Create a new Date object for today + const tomorrow = new Date(); + + // Set the date to tomorrow by adding 1 to today's date + tomorrow.setDate(tomorrow.getDate() + 1); + + // Format tomorrow's date in verbose form (e.g., "Sat Sep 21 2024") + const verboseFormat = tomorrow + .toLocaleDateString("en-US", { + weekday: "short", + year: "numeric", + month: "short", + day: "2-digit", + }) + .replace(/,/g, ""); // Remove commas from the formatted string + + // Format tomorrow's date in ISO form (e.g., "2024-09-21") + const isoFormat = tomorrow.toISOString().split("T")[0]; // Extract the date part only + + // Return both formatted date strings as an object + return { + verboseFormat, + isoFormat, + }; + } } From 325f896087ac551f6ec0bb90e0a929df9eff3ed8 Mon Sep 17 00:00:00 2001 From: Rahul Barwal Date: Fri, 27 Sep 2024 20:03:05 +0530 Subject: [PATCH 21/21] Run unit test with separate data. --- .../reactTableUtils/TransformDataPureFn.test.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts index 97a994ce670..b3b033b9b9f 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/reactTableUtils/TransformDataPureFn.test.ts @@ -11,12 +11,18 @@ import { transformDataPureFn } from "./transformDataPureFn"; describe("transformDataPureFn", () => { it("should transform table data based on column meta properties", () => { - const result = transformDataPureFn( - tableData, + let result = transformDataPureFn( + [tableData[0]], columns as ReactTableColumnProps[], ); - expect(result).toEqual(expectedData); + expect(result[0]).toEqual(expectedData[0]); + + result = transformDataPureFn( + [tableData[1]], + columns as ReactTableColumnProps[], + ); + expect(result[0]).toEqual(expectedData[1]); }); it("should handle invalid date values", () => {