feat: Allow table search to include label and value for tables with select column type (#36061)
This commit is contained in:
parent
9706602777
commit
8a9af791e4
|
|
@ -1,3 +1,5 @@
|
|||
import { demoTableDataForSelect } from "../../../../../fixtures/Table/DemoTableData";
|
||||
import { featureFlagIntercept } from "../../../../../support/Objects/FeatureFlags";
|
||||
import {
|
||||
entityExplorer,
|
||||
propPane,
|
||||
|
|
@ -8,6 +10,9 @@ import {
|
|||
draggableWidgets,
|
||||
agHelper,
|
||||
} from "../../../../../support/Objects/ObjectsCore";
|
||||
import EditorNavigation, {
|
||||
EntityType,
|
||||
} from "../../../../../support/Pages/EditorNavigation";
|
||||
|
||||
describe(
|
||||
"Verify various Table_Filter combinations",
|
||||
|
|
@ -136,5 +141,46 @@ describe(
|
|||
table.WaitForTableEmpty("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");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ describe(
|
|||
});
|
||||
});
|
||||
|
||||
it("3. should check that options given in the property pane is appearing on the table", () => {
|
||||
cy.get(".t--property-control-options").should("exist");
|
||||
it("3. should check that JSON options given in the property pane is appearing on the table", () => {
|
||||
cy.get(_.locators._controlOption).should("exist");
|
||||
cy.updateCodeInput(
|
||||
".t--property-control-options",
|
||||
_.locators._controlOption,
|
||||
`
|
||||
[
|
||||
{
|
||||
|
|
@ -80,9 +80,52 @@ describe(
|
|||
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(
|
||||
".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");
|
||||
});
|
||||
|
||||
it("5. should check that filterable property is working", () => {
|
||||
it("6. should check that filterable property is working", () => {
|
||||
cy.updateCodeInput(
|
||||
".t--property-control-options",
|
||||
_.locators._controlOption,
|
||||
`
|
||||
{{[
|
||||
{
|
||||
|
|
@ -161,7 +204,7 @@ describe(
|
|||
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();
|
||||
featureFlagIntercept({ release_table_cell_label_value_enabled: true });
|
||||
cy.openPropertyPane("tablewidgetv2");
|
||||
|
|
@ -174,7 +217,7 @@ describe(
|
|||
`,
|
||||
);
|
||||
cy.updateCodeInput(
|
||||
".t--property-control-options",
|
||||
_.locators._controlOption,
|
||||
`
|
||||
[
|
||||
{
|
||||
|
|
@ -204,9 +247,9 @@ describe(
|
|||
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(
|
||||
".t--property-control-options",
|
||||
_.locators._controlOption,
|
||||
`
|
||||
{{[
|
||||
{
|
||||
|
|
@ -229,7 +272,7 @@ describe(
|
|||
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();
|
||||
|
||||
const checkSameOptionsInNewRowWhileEditing = () => {
|
||||
|
|
@ -246,7 +289,7 @@ describe(
|
|||
cy.get(".t--property-control-newrowoptions").should("not.exist");
|
||||
|
||||
cy.updateCodeInput(
|
||||
".t--property-control-options",
|
||||
_.locators._controlOption,
|
||||
`
|
||||
{{[{
|
||||
"label": "male",
|
||||
|
|
@ -295,7 +338,7 @@ describe(
|
|||
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 = () => {
|
||||
// New row select options should be visible when "Same options in new row" is turned off
|
||||
_.propPane.TogglePropertyState("Same options in new row", "Off");
|
||||
|
|
@ -360,7 +403,7 @@ describe(
|
|||
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.CreateQueryAfterDSSaved(
|
||||
"SELECT * FROM public.astronauts {{this.params.filterText ? `WHERE name LIKE '%${this.params.filterText}%'` : ''}} LIMIT 10;",
|
||||
|
|
|
|||
46
app/client/cypress/fixtures/Table/DemoTableData.ts
Normal file
46
app/client/cypress/fixtures/Table/DemoTableData.ts
Normal 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
|
||||
}
|
||||
]
|
||||
}}
|
||||
`;
|
||||
|
|
@ -342,12 +342,46 @@ export default {
|
|||
const newRow = { ...row };
|
||||
selectColumnKeysWithSortByLabel.forEach((key) => {
|
||||
const value = row[key];
|
||||
const selectOptions =
|
||||
primaryColumns[key].selectOptions[row.__originalIndex__];
|
||||
const option = selectOptions.find((option) => option.value === value);
|
||||
const isSelectOptionsAnArray = _.isArray(
|
||||
primaryColumns[key].selectOptions,
|
||||
);
|
||||
|
||||
if (option) {
|
||||
newRow[key] = option.label;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -450,18 +484,55 @@ 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) {
|
||||
const transformedLabelToValueData = sortedTableData.map((row) => {
|
||||
const newRow = { ...row };
|
||||
selectColumnKeysWithSortByLabel.forEach((key) => {
|
||||
const label = row[key];
|
||||
const selectOptions =
|
||||
primaryColumns[key].selectOptions[row.__originalIndex__];
|
||||
const option = selectOptions.find(
|
||||
(option) => option.label === label,
|
||||
const isSelectOptionsAnArray = _.isArray(
|
||||
primaryColumns[key].selectOptions,
|
||||
);
|
||||
if (option) {
|
||||
newRow[key] = option.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.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(
|
||||
(option) => option.label === label,
|
||||
);
|
||||
if (option) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -587,8 +658,83 @@ export default {
|
|||
const columnWithDisplayText = Object.values(props.primaryColumns).filter(
|
||||
(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 = {
|
||||
...row,
|
||||
labelValueForSelectCell,
|
||||
...columnWithDisplayText.reduce((acc, column) => {
|
||||
let displayText;
|
||||
if (_.isArray(column.displayText)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user