feat: updatedRow property should point to the last edited row in table widget (#18225)
* fix: changed the updatedRow logic * fix: removed only modifier from inline spec * fix: addressed review comments * chore: removed the downloads.html file * fix: address review comments
This commit is contained in:
parent
61dfe14f4f
commit
86a4929d64
|
|
@ -2,6 +2,7 @@ const dsl = require("../../../../../fixtures/Table/InlineEditingDSL.json");
|
||||||
const commonlocators = require("../../../../../locators/commonlocators.json");
|
const commonlocators = require("../../../../../locators/commonlocators.json");
|
||||||
const widgetsPage = require("../../../../../locators/Widgets.json");
|
const widgetsPage = require("../../../../../locators/Widgets.json");
|
||||||
import { ObjectsRegistry } from "../../../../../support/Objects/Registry";
|
import { ObjectsRegistry } from "../../../../../support/Objects/Registry";
|
||||||
|
import { PROPERTY_SELECTOR } from "../../../../../locators/WidgetLocators";
|
||||||
const agHelper = ObjectsRegistry.AggregateHelper;
|
const agHelper = ObjectsRegistry.AggregateHelper;
|
||||||
|
|
||||||
describe("Table widget inline editing functionality", () => {
|
describe("Table widget inline editing functionality", () => {
|
||||||
|
|
@ -711,4 +712,104 @@ describe("Table widget inline editing functionality", () => {
|
||||||
"[data-colindex='0'][data-rowindex='0'] .t--inlined-cell-editor",
|
"[data-colindex='0'][data-rowindex='0'] .t--inlined-cell-editor",
|
||||||
).should("not.have.css", "height", "34px");
|
).should("not.have.css", "height", "34px");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("26. should check if updatedRowIndex is getting updated for single row update mode", () => {
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 400, y: 400 });
|
||||||
|
cy.get(".t--widget-textwidget").should("exist");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{Table1.updatedRowIndex}}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.dragAndDropToCanvas("buttonwidget", { x: 300, y: 300 });
|
||||||
|
cy.get(".t--widget-buttonwidget").should("exist");
|
||||||
|
cy.get(PROPERTY_SELECTOR.onClick)
|
||||||
|
.find(".t--js-toggle")
|
||||||
|
.click();
|
||||||
|
cy.updateCodeInput(".t--property-control-label", "Reset");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
PROPERTY_SELECTOR.onClick,
|
||||||
|
`{{resetWidget("Table1",true)}}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// case 1: check if updatedRowIndex has -1 as the default value:
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
|
||||||
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
|
|
||||||
|
cy.makeColumnEditable("step");
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
// case 2: check if updatedRowIndex is 0, when cell at row 0 is updated.
|
||||||
|
cy.editTableCell(0, 0);
|
||||||
|
cy.enterTableCellValue(0, 0, "#12").type("{enter}");
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", 0);
|
||||||
|
|
||||||
|
// case 3: check if updatedRowIndex is -1 when changes are discarded.
|
||||||
|
cy.discardTableRow(4, 0);
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
|
||||||
|
// case 4: check if the updateRowIndex is -1 when widget is reset
|
||||||
|
cy.editTableCell(0, 1);
|
||||||
|
cy.enterTableCellValue(0, 1, "#13").type("{enter}");
|
||||||
|
cy.contains("Reset").click({ force: true });
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
|
||||||
|
// case 5: check if the updatedRowIndex changes to -1 when the table data changes.
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.editTableCell(0, 2);
|
||||||
|
cy.enterTableCellValue(0, 2, "#14").type("{enter}");
|
||||||
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
|
cy.get(widgetsPage.tabedataField).type("{backspace}");
|
||||||
|
cy.wait(300);
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.only("27. should check if updatedRowIndex is getting updated for multi row update mode", () => {
|
||||||
|
cy.dragAndDropToCanvas("textwidget", { x: 400, y: 400 });
|
||||||
|
cy.get(".t--widget-textwidget").should("exist");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
".t--property-control-text",
|
||||||
|
`{{Table1.updatedRowIndex}}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.dragAndDropToCanvas("buttonwidget", { x: 300, y: 300 });
|
||||||
|
cy.get(".t--widget-buttonwidget").should("exist");
|
||||||
|
cy.get(PROPERTY_SELECTOR.onClick)
|
||||||
|
.find(".t--js-toggle")
|
||||||
|
.click();
|
||||||
|
cy.updateCodeInput(".t--property-control-label", "Reset");
|
||||||
|
cy.updateCodeInput(
|
||||||
|
PROPERTY_SELECTOR.onClick,
|
||||||
|
`{{resetWidget("Table1",true)}}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
|
|
||||||
|
cy.makeColumnEditable("step");
|
||||||
|
cy.get(".t--button-tab-CUSTOM").click({ force: true });
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
// case 1: check if updatedRowIndex is 0, when cell at row 0 is updated.
|
||||||
|
cy.editTableCell(0, 0);
|
||||||
|
cy.enterTableCellValue(0, 0, "#12").type("{enter}");
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", 0);
|
||||||
|
|
||||||
|
// case 2: check if the updateRowIndex is -1 when widget is reset
|
||||||
|
cy.editTableCell(0, 1);
|
||||||
|
cy.enterTableCellValue(0, 1, "#13").type("{enter}");
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", 1);
|
||||||
|
cy.contains("Reset").click({ force: true });
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
|
||||||
|
// case 3: check if the updatedRowIndex changes to -1 when the table data changes.
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.editTableCell(0, 2);
|
||||||
|
cy.enterTableCellValue(0, 2, "#14").type("{enter}");
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", 2);
|
||||||
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
|
cy.get(widgetsPage.tabedataField).type("{backspace}");
|
||||||
|
cy.wait(300);
|
||||||
|
cy.get(commonlocators.textWidgetContainer).should("contain.text", -1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,54 @@ export default {
|
||||||
return finalTableData;
|
return finalTableData;
|
||||||
},
|
},
|
||||||
//
|
//
|
||||||
|
getUpdatedRow: (props, moment, _) => {
|
||||||
|
let index = -1;
|
||||||
|
const parsedUpdatedRowIndex = parseInt(props.updatedRowIndex);
|
||||||
|
|
||||||
|
if (!_.isNaN(parsedUpdatedRowIndex)) {
|
||||||
|
index = parsedUpdatedRowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = props.filteredTableData || props.processedTableData || [];
|
||||||
|
const primaryColumns = props.primaryColumns;
|
||||||
|
let updatedRow;
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
const row = rows.find((row) => row.__originalIndex__ === index);
|
||||||
|
updatedRow = { ...row };
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If updatedRowIndex is not a valid index, updatedRow should
|
||||||
|
* have proper row structure with empty string values
|
||||||
|
*/
|
||||||
|
updatedRow = {};
|
||||||
|
if (rows && rows[0]) {
|
||||||
|
Object.keys(rows[0]).forEach((key) => {
|
||||||
|
updatedRow[key] = "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nonDataColumnTypes = [
|
||||||
|
"editActions",
|
||||||
|
"button",
|
||||||
|
"iconButton",
|
||||||
|
"menuButton",
|
||||||
|
];
|
||||||
|
const nonDataColumnAliases = primaryColumns
|
||||||
|
? Object.values(primaryColumns)
|
||||||
|
.filter((column) => nonDataColumnTypes.includes(column.columnType))
|
||||||
|
.map((column) => column.alias)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const keysToBeOmitted = [
|
||||||
|
"__originalIndex__",
|
||||||
|
"__primaryKey__",
|
||||||
|
...nonDataColumnAliases,
|
||||||
|
];
|
||||||
|
return _.omit(updatedRow, keysToBeOmitted);
|
||||||
|
},
|
||||||
|
//
|
||||||
getUpdatedRows: (props, moment, _) => {
|
getUpdatedRows: (props, moment, _) => {
|
||||||
const primaryColumns = props.primaryColumns;
|
const primaryColumns = props.primaryColumns;
|
||||||
const nonDataColumnTypes = [
|
const nonDataColumnTypes = [
|
||||||
|
|
|
||||||
|
|
@ -2069,6 +2069,98 @@ describe("getPageOffset -", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("validate getUpdatedRow", () => {
|
||||||
|
it("should check that valid updated row index returns the valid value", () => {
|
||||||
|
const { getUpdatedRow } = derivedProperty;
|
||||||
|
const input1 = {
|
||||||
|
updatedRowIndex: 1,
|
||||||
|
processedTableData: [
|
||||||
|
{ id: 1234, name: "Jim Doe", extra: "", __originalIndex__: 0 },
|
||||||
|
{ id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 },
|
||||||
|
{ id: 123, name: "John Doe1", extra: "Extra1", __originalIndex__: 1 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const input2 = {
|
||||||
|
updatedRowIndex: 0,
|
||||||
|
processedTableData: [
|
||||||
|
{ id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 },
|
||||||
|
{ id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 },
|
||||||
|
{ id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
expect(getUpdatedRow(input1, moment, _)).toStrictEqual({
|
||||||
|
id: 123,
|
||||||
|
name: "John Doe1",
|
||||||
|
extra: "Extra1",
|
||||||
|
});
|
||||||
|
expect(getUpdatedRow(input2, moment, _)).toStrictEqual({
|
||||||
|
id: 1,
|
||||||
|
name: "Lorem Ipsum",
|
||||||
|
extra: "",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should check that it returns empty values when updateRowIndex is invalid or -1", () => {
|
||||||
|
const { getUpdatedRow } = derivedProperty;
|
||||||
|
const input1 = {
|
||||||
|
updatedRowIndex: -1,
|
||||||
|
processedTableData: [
|
||||||
|
{ id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 },
|
||||||
|
{ id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 },
|
||||||
|
{ id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const input2 = {
|
||||||
|
updatedRowIndex: "dummyIndex",
|
||||||
|
processedTableData: [
|
||||||
|
{ id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 },
|
||||||
|
{ id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 },
|
||||||
|
{ id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const input3 = {
|
||||||
|
updatedRowIndex: undefined,
|
||||||
|
processedTableData: [
|
||||||
|
{ id: 1, name: "Lorem Ipsum", extra: "", __originalIndex__: 0 },
|
||||||
|
{ id: 234, name: "Jane Doe", extra: "Extra2", __originalIndex__: 2 },
|
||||||
|
{ id: 123, name: "John Doe", extra: "Extra1", __originalIndex__: 1 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
expect(getUpdatedRow(input1, moment, _)).toStrictEqual({
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
extra: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getUpdatedRow(input2, moment, _)).toStrictEqual({
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
extra: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getUpdatedRow(input3, moment, _)).toStrictEqual({
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
extra: "",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should check that it removes non data columns", () => {
|
||||||
|
const { getUpdatedRow } = derivedProperty;
|
||||||
|
const input = {
|
||||||
|
updatedRowIndex: 1,
|
||||||
|
processedTableData: sampleProcessedTableData,
|
||||||
|
primaryColumns: samplePrimaryColumns,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(getUpdatedRow(input, moment, _)).toStrictEqual({
|
||||||
|
step: "#2",
|
||||||
|
task: "Create a query fetch_users with the Mock DB",
|
||||||
|
status: "--",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
describe("getEditableCellValidity", () => {
|
describe("getEditableCellValidity", () => {
|
||||||
const { getEditableCellValidity } = derivedProperty;
|
const { getEditableCellValidity } = derivedProperty;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
order: null,
|
order: null,
|
||||||
},
|
},
|
||||||
transientTableData: {},
|
transientTableData: {},
|
||||||
|
updatedRowIndex: -1,
|
||||||
editableCell: defaultEditableCell,
|
editableCell: defaultEditableCell,
|
||||||
columnEditableCellValue: {},
|
columnEditableCellValue: {},
|
||||||
selectColumnFilterText: {},
|
selectColumnFilterText: {},
|
||||||
|
|
@ -142,7 +143,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
filteredTableData: `{{(()=>{ ${derivedProperties.getFilteredTableData}})()}}`,
|
filteredTableData: `{{(()=>{ ${derivedProperties.getFilteredTableData}})()}}`,
|
||||||
updatedRows: `{{(()=>{ ${derivedProperties.getUpdatedRows}})()}}`,
|
updatedRows: `{{(()=>{ ${derivedProperties.getUpdatedRows}})()}}`,
|
||||||
updatedRowIndices: `{{(()=>{ ${derivedProperties.getUpdatedRowIndices}})()}}`,
|
updatedRowIndices: `{{(()=>{ ${derivedProperties.getUpdatedRowIndices}})()}}`,
|
||||||
updatedRow: `{{this.triggeredRow}}`,
|
updatedRow: `{{(()=>{ ${derivedProperties.getUpdatedRow}})()}}`,
|
||||||
pageOffset: `{{(()=>{${derivedProperties.getPageOffset}})()}}`,
|
pageOffset: `{{(()=>{${derivedProperties.getPageOffset}})()}}`,
|
||||||
isEditableCellsValid: `{{(()=>{ ${derivedProperties.getEditableCellValidity}})()}}`,
|
isEditableCellsValid: `{{(()=>{ ${derivedProperties.getEditableCellValidity}})()}}`,
|
||||||
};
|
};
|
||||||
|
|
@ -595,6 +596,9 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
*/
|
*/
|
||||||
if (isTableDataModified) {
|
if (isTableDataModified) {
|
||||||
this.props.updateWidgetMetaProperty("transientTableData", {});
|
this.props.updateWidgetMetaProperty("transientTableData", {});
|
||||||
|
// reset updatedRowIndex whenever transientTableData is flushed.
|
||||||
|
this.props.updateWidgetMetaProperty("updatedRowIndex", -1);
|
||||||
|
|
||||||
this.clearEditableCell(true);
|
this.clearEditableCell(true);
|
||||||
this.props.updateWidgetMetaProperty("selectColumnFilterText", {});
|
this.props.updateWidgetMetaProperty("selectColumnFilterText", {});
|
||||||
}
|
}
|
||||||
|
|
@ -1208,6 +1212,8 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
...transientData,
|
...transientData,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.props.updateWidgetMetaProperty("updatedRowIndex", __originalIndex__);
|
||||||
};
|
};
|
||||||
|
|
||||||
removeRowFromTransientTableData = (index: number) => {
|
removeRowFromTransientTableData = (index: number) => {
|
||||||
|
|
@ -1221,6 +1227,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
newTransientTableData,
|
newTransientTableData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.props.updateWidgetMetaProperty("updatedRowIndex", -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
getRowOriginalIndex = (index: number) => {
|
getRowOriginalIndex = (index: number) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user