feat: Allow table search to include label and value for tables with select column type (#36061)

This commit is contained in:
Jacques Ikot 2024-09-12 08:28:46 +01:00 committed by GitHub
parent 9706602777
commit 8a9af791e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 307 additions and 26 deletions

View File

@ -1,3 +1,5 @@
import { demoTableDataForSelect } from "../../../../../fixtures/Table/DemoTableData";
import { featureFlagIntercept } from "../../../../../support/Objects/FeatureFlags";
import { import {
entityExplorer, entityExplorer,
propPane, propPane,
@ -8,6 +10,9 @@ import {
draggableWidgets, draggableWidgets,
agHelper, agHelper,
} from "../../../../../support/Objects/ObjectsCore"; } from "../../../../../support/Objects/ObjectsCore";
import EditorNavigation, {
EntityType,
} from "../../../../../support/Pages/EditorNavigation";
describe( describe(
"Verify various Table_Filter combinations", "Verify various Table_Filter combinations",
@ -136,5 +141,46 @@ describe(
table.WaitForTableEmpty("v2"); table.WaitForTableEmpty("v2");
table.RemoveFilterNVerify("2381224", true, true, 0, "v2"); table.RemoveFilterNVerify("2381224", true, true, 0, "v2");
}); });
it("11. Verify table search includes label and value for table with select column type", () => {
// This flag is turned on to allow the label show in the table select cell content
// when this feature is turned on fully, this flag will be removed
featureFlagIntercept({ release_table_cell_label_value_enabled: true });
deployMode.NavigateBacktoEditor();
EditorNavigation.SelectEntityByName("Table1", EntityType.Widget);
propPane.EnterJSContext("Table data", demoTableDataForSelect);
// Edit role column to select type
table.ChangeColumnType("role", "Select", "v2");
table.EditColumn("role", "v2");
agHelper.UpdateCodeInput(
locators._controlOption,
`
{{
[
{"label": "Software Engineer",
"value": 10,},
{"label": "Product Manager",
"value": 20,},
{"label": "UX Designer",
"value": 30,}
]
}}
`,
);
// Search for a label in the table
table.SearchTable("Software Engineer");
table.ReadTableRowColumnData(0, 2, "v2").then((afterSearch) => {
expect(afterSearch).to.eq("Software Engineer");
});
table.RemoveSearchTextNVerify("1", "v2");
// Search for a value in the table
table.SearchTable("20");
table.ReadTableRowColumnData(0, 2, "v2").then((afterSearch) => {
expect(afterSearch).to.eq("Product Manager");
});
table.RemoveSearchTextNVerify("1", "v2");
});
}, },
); );

View File

@ -37,10 +37,10 @@ describe(
}); });
}); });
it("3. should check that options given in the property pane is appearing on the table", () => { it("3. should check that JSON options given in the property pane is appearing on the table", () => {
cy.get(".t--property-control-options").should("exist"); cy.get(_.locators._controlOption).should("exist");
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
` `
[ [
{ {
@ -80,9 +80,52 @@ describe(
cy.get(".menu-item-active.has-focus").should("contain", "#1"); cy.get(".menu-item-active.has-focus").should("contain", "#1");
}); });
it("4. should check that placeholder property is working", () => { it("4. should check that javascript options given in the property pane is appearing on the table", () => {
cy.get(_.locators._controlOption).should("exist");
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
`
{{[
{
"label": "#1",
"value": "#1"
},
{
"label": "#2",
"value": "#2"
},
{
"label": "#3",
"value": "#3"
}
]}}
`,
);
cy.editTableSelectCell(0, 0);
[
{
label: "#1",
value: "#1",
},
{
label: "#2",
value: "#2",
},
{
label: "#3",
value: "#3",
},
].forEach((item) => {
cy.get(".menu-item-text").contains(item.value).should("exist");
});
cy.get(".menu-item-active.has-focus").should("contain", "#1");
});
it("5. should check that placeholder property is working", () => {
cy.updateCodeInput(
_.locators._controlOption,
` `
[ [
{ {
@ -116,9 +159,9 @@ describe(
).should("contain", "choose an item"); ).should("contain", "choose an item");
}); });
it("5. should check that filterable property is working", () => { it("6. should check that filterable property is working", () => {
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
` `
{{[ {{[
{ {
@ -161,7 +204,7 @@ describe(
cy.get(".t--canvas-artboard").click({ force: true }); cy.get(".t--canvas-artboard").click({ force: true });
}); });
it("6. should check that on option select is working", () => { it("7. should check that on option select is working", () => {
_.agHelper.CheckForPageSaveError(); _.agHelper.CheckForPageSaveError();
featureFlagIntercept({ release_table_cell_label_value_enabled: true }); featureFlagIntercept({ release_table_cell_label_value_enabled: true });
cy.openPropertyPane("tablewidgetv2"); cy.openPropertyPane("tablewidgetv2");
@ -174,7 +217,7 @@ describe(
`, `,
); );
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
` `
[ [
{ {
@ -204,9 +247,9 @@ describe(
cy.discardTableRow(4, 0); cy.discardTableRow(4, 0);
}); });
it("7. should check that currentRow is accessible in the select options", () => { it("8. should check that currentRow is accessible in the select options", () => {
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
` `
{{[ {{[
{ {
@ -229,7 +272,7 @@ describe(
cy.get(".menu-item-text").contains("#1").should("not.exist"); cy.get(".menu-item-text").contains("#1").should("not.exist");
}); });
it("8. should check that 'same select option in new row' property is working", () => { it("9. should check that 'same select option in new row' property is working", () => {
_.propPane.NavigateBackToPropertyPane(); _.propPane.NavigateBackToPropertyPane();
const checkSameOptionsInNewRowWhileEditing = () => { const checkSameOptionsInNewRowWhileEditing = () => {
@ -246,7 +289,7 @@ describe(
cy.get(".t--property-control-newrowoptions").should("not.exist"); cy.get(".t--property-control-newrowoptions").should("not.exist");
cy.updateCodeInput( cy.updateCodeInput(
".t--property-control-options", _.locators._controlOption,
` `
{{[{ {{[{
"label": "male", "label": "male",
@ -295,7 +338,7 @@ describe(
checkSameOptionsWhileAddingNewRow(); checkSameOptionsWhileAddingNewRow();
}); });
it("9. should check that 'new row select options' is working", () => { it("10. should check that 'new row select options' is working", () => {
const checkNewRowOptions = () => { const checkNewRowOptions = () => {
// New row select options should be visible when "Same options in new row" is turned off // New row select options should be visible when "Same options in new row" is turned off
_.propPane.TogglePropertyState("Same options in new row", "Off"); _.propPane.TogglePropertyState("Same options in new row", "Off");
@ -360,7 +403,7 @@ describe(
checkNoOptionState(); checkNoOptionState();
}); });
it("10. should check that server side filering is working", () => { it("11. should check that server side filering is working", () => {
_.dataSources.CreateDataSource("Postgres"); _.dataSources.CreateDataSource("Postgres");
_.dataSources.CreateQueryAfterDSSaved( _.dataSources.CreateQueryAfterDSSaved(
"SELECT * FROM public.astronauts {{this.params.filterText ? `WHERE name LIKE '%${this.params.filterText}%'` : ''}} LIMIT 10;", "SELECT * FROM public.astronauts {{this.params.filterText ? `WHERE name LIKE '%${this.params.filterText}%'` : ''}} LIMIT 10;",

View File

@ -0,0 +1,46 @@
export const demoTableDataForSelect = `
{{
[
{
role: 10,
id: 1,
name: "Alice Johnson",
email: "alice.johnson@example.com",
age: 28,
gender: 2
},
{
role: 20,
id: 2,
name: "Bob Smith",
email: "bob.smith@example.com",
age: 34,
gender: 1
},
{
role: 30,
id: 3,
name: "Charlie Brown",
email: "charlie.brown@example.com",
age: 25,
gender: 3
},
{
role: 20,
id: 4,
name: "Diana Prince",
email: "diana.prince@example.com",
age: 30,
gender: 2
},
{
role: 10,
id: 5,
name: "Evan Williams",
email: "evan.williams@example.com",
age: 27,
gender: 1
}
]
}}
`;

View File

@ -342,13 +342,47 @@ export default {
const newRow = { ...row }; const newRow = { ...row };
selectColumnKeysWithSortByLabel.forEach((key) => { selectColumnKeysWithSortByLabel.forEach((key) => {
const value = row[key]; const value = row[key];
const selectOptions = const isSelectOptionsAnArray = _.isArray(
primaryColumns[key].selectOptions[row.__originalIndex__]; primaryColumns[key].selectOptions,
const option = selectOptions.find((option) => option.value === value); );
let selectOptions;
/*
* If selectOptions is an array, check if it contains nested arrays.
* This is to handle situations where selectOptons is a javascript object and computes as a nested array.
*/
if (isSelectOptionsAnArray) {
if (_.some(primaryColumns[key].selectOptions, _.isArray)) {
/* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */
selectOptions =
primaryColumns[key].selectOptions[row.__originalIndex__];
const option = selectOptions.find((option) => {
return option.value === value;
});
if (option) { if (option) {
newRow[key] = option.label; newRow[key] = option.label;
} }
} else {
/* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */
selectOptions = primaryColumns[key].selectOptions;
const option = selectOptions.find(
(option) => option.value === value,
);
if (option) {
newRow[key] = option.label;
}
}
} else {
/* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */
selectOptions = JSON.parse(primaryColumns[key].selectOptions);
const option = selectOptions.find(
(option) => option.value === value,
);
if (option) {
newRow[key] = option.label;
}
}
}); });
return newRow; return newRow;
@ -450,19 +484,56 @@ export default {
} }
}); });
/*
* When sorting is done, transform the data back to its original state
* where table data shows value instead of label
*/
if (selectColumnKeysWithSortByLabel.length) { if (selectColumnKeysWithSortByLabel.length) {
const transformedLabelToValueData = sortedTableData.map((row) => { const transformedLabelToValueData = sortedTableData.map((row) => {
const newRow = { ...row }; const newRow = { ...row };
selectColumnKeysWithSortByLabel.forEach((key) => { selectColumnKeysWithSortByLabel.forEach((key) => {
const label = row[key]; const label = row[key];
const selectOptions = const isSelectOptionsAnArray = _.isArray(
primaryColumns[key].selectOptions,
);
let selectOptions;
/*
* If selectOptions is an array, check if it contains nested arrays.
* This is to handle situations where selectOptons is a javascript object and computes as a nested array.
*/
if (isSelectOptionsAnArray) {
if (_.some(primaryColumns[key].selectOptions, _.isArray)) {
/* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */
selectOptions =
primaryColumns[key].selectOptions[row.__originalIndex__]; primaryColumns[key].selectOptions[row.__originalIndex__];
const option = selectOptions.find((option) => {
return option.label === label;
});
if (option) {
newRow[key] = option.value;
}
} else {
/* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */
selectOptions = primaryColumns[key].selectOptions;
const option = selectOptions.find( const option = selectOptions.find(
(option) => option.label === label, (option) => option.label === label,
); );
if (option) { if (option) {
newRow[key] = option.value; newRow[key] = option.value;
} }
}
} else {
/* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */
selectOptions = JSON.parse(primaryColumns[key].selectOptions);
const option = selectOptions.find(
(option) => option.label === label,
);
if (option) {
newRow[key] = option.value;
}
}
}); });
return newRow; return newRow;
@ -587,8 +658,83 @@ export default {
const columnWithDisplayText = Object.values(props.primaryColumns).filter( const columnWithDisplayText = Object.values(props.primaryColumns).filter(
(column) => column.columnType === "url" && column.displayText, (column) => column.columnType === "url" && column.displayText,
); );
/*
* For select columns with label and values, we need to include the label value
* in the search
*/
let labelValueForSelectCell = "";
/*
* Initialize an array to store keys for columns that have the 'select' column type
* and contain selectOptions.
*/
const selectColumnKeys = [];
/*
* Iterate over the primary columns to identify which columns are of type 'select'
* and have selectOptions. These keys are pushed into the selectColumnKeys array.
*/
Object.entries(props.primaryColumns).forEach(([id, column]) => {
const isColumnSelectColumnType =
column?.columnType === "select" && column?.selectOptions?.length;
if (isColumnSelectColumnType) {
selectColumnKeys.push(id);
}
});
/*
* If there are any select columns, iterate over them to find the label value
* associated with the selected value in each row.
*/
if (selectColumnKeys.length) {
selectColumnKeys.forEach((key) => {
const value = row[key];
const isSelectOptionsAnArray = _.isArray(
primaryColumns[key].selectOptions,
);
let selectOptions;
/*
* If selectOptions is an array, check if it contains nested arrays.
* This is to handle situations where selectOptons is a javascript object and computes as a nested array.
*/
if (isSelectOptionsAnArray) {
if (_.some(primaryColumns[key].selectOptions, _.isArray)) {
/* Handle the case where selectOptions contains nested arrays - selectOptions is javascript */
selectOptions =
primaryColumns[key].selectOptions[row.__originalIndex__];
const option = selectOptions.find((option) => {
return option.value === value;
});
if (option) {
labelValueForSelectCell = option.label;
}
} else {
/* Handle the case where selectOptions is a flat array - selectOptions is plain JSON */
selectOptions = primaryColumns[key].selectOptions;
const option = selectOptions.find(
(option) => option.value === value,
);
if (option) {
labelValueForSelectCell = option.label;
}
}
} else {
/* If selectOptions is not an array, parse it as JSON - not evaluated yet, so returns as string */
selectOptions = JSON.parse(primaryColumns[key].selectOptions);
const option = selectOptions.find(
(option) => option.value === value,
);
if (option) {
labelValueForSelectCell = option.label;
}
}
});
}
const displayedRow = { const displayedRow = {
...row, ...row,
labelValueForSelectCell,
...columnWithDisplayText.reduce((acc, column) => { ...columnWithDisplayText.reduce((acc, column) => {
let displayText; let displayText;
if (_.isArray(column.displayText)) { if (_.isArray(column.displayText)) {