PromucFlow_constructor/app/client/src/widgets/TableWidgetV2/index.ts
Keyur Paralkar 3ee46ffd14
fix: add select options field to new row (#22003)
## Description

This PR introduces new two new properties: `Same options in new row` and
`New row options` for the select column type.
We show these two fields when the allow add new row is turned on in
table
- SameOptionsInNewRow -- Boolean field ; When turned on the option for
the first row is used in the new row. Default is true
     - Label : Use same options in new row
- Tooltip : Toggle to display same choices for new row and editing
existing row in column.
- NewRowOptions -- Array field; when the above boolean is turned off we
show this option to let people add options specifically for new row.
Supports static and dynamic data, but doesn't support currentRow
    - Label: New row options
- Tooltip : Options exclusively displayed in the column for new row
addition.

Fixes #20230


## Type of change

- Bug fix (non-breaking change which fixes an issue)


## How Has This Been Tested?

- Cypress:
- When allowAddNewRow is turned on, same new option should be true and
new row option should be invisible.
- When turned on same option, options of the first row should appear
while editing as well as adding new row.
    - When turned off, New row option should be visible
- Fill new row options, the new row options should appear while adding
new row in select field.
    -  New row options should not have access to the currentRow
- Both the options should only be visible only when allowNewRow is true.
    -  Should support static and dynamic values in new row options

- Manual
- For the new DnD Tables. Check if the above functionality is working as
expected.
- For Existing tables, Check if the above functionality is working as
expected. This needed to be tested from migration standpoint

### Test Plan
> https://github.com/appsmithorg/TestSmith/issues/2367

### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)


## Checklist:
### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


### QA activity:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
2023-04-06 23:58:24 +05:30

259 lines
7.9 KiB
TypeScript

import { Colors } from "constants/Colors";
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
import { cloneDeep, set } from "lodash";
import {
combineDynamicBindings,
getDynamicBindings,
} from "utils/DynamicBindingUtils";
import { getDefaultResponsiveBehavior } from "utils/layoutPropertiesUtils";
import type { WidgetProps } from "widgets/BaseWidget";
import { BlueprintOperationTypes } from "widgets/constants";
import { StickyType } from "./component/Constants";
import { InlineEditingSaveOptions } from "./constants";
import IconSVG from "./icon.svg";
import Widget from "./widget";
import { escapeString } from "./widget/utilities";
export const CONFIG = {
type: Widget.getWidgetType(),
name: "Table",
iconSVG: IconSVG,
needsMeta: true,
needsHeightForContent: true,
defaults: {
responsiveBehavior: getDefaultResponsiveBehavior(Widget.getWidgetType()),
minWidth: FILL_WIDGET_MIN_WIDTH,
rows: 28,
canFreezeColumn: true,
columnUpdatedAt: Date.now(),
columns: 34,
animateLoading: true,
defaultSelectedRowIndex: 0,
defaultSelectedRowIndices: [0],
label: "Data",
widgetName: "Table",
searchKey: "",
textSize: "0.875rem",
horizontalAlignment: "LEFT",
verticalAlignment: "CENTER",
totalRecordsCount: 0,
defaultPageSize: 0,
dynamicPropertyPathList: [],
borderColor: Colors.GREY_5,
borderWidth: "1",
dynamicBindingPathList: [
{
key: "primaryColumns.step.computedValue",
},
{
key: "primaryColumns.task.computedValue",
},
{
key: "primaryColumns.status.computedValue",
},
{
key: "primaryColumns.action.computedValue",
},
{
key: "primaryColumns.action.buttonColor",
},
{
key: "primaryColumns.action.borderRadius",
},
{
key: "primaryColumns.action.boxShadow",
},
],
primaryColumns: {
step: {
index: 0,
width: 150,
id: "step",
originalId: "step",
alias: "step",
allowSameOptionsInNewRow: true,
horizontalAlignment: "LEFT",
verticalAlignment: "CENTER",
columnType: "text",
textSize: "0.875rem",
enableFilter: true,
enableSort: true,
isVisible: true,
isCellVisible: true,
isCellEditable: false,
isDerived: false,
label: "step",
computedValue: `{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow["step"]))}}`,
validation: {},
sticky: StickyType.NONE,
},
task: {
index: 1,
width: 150,
id: "task",
originalId: "task",
alias: "task",
allowSameOptionsInNewRow: true,
horizontalAlignment: "LEFT",
verticalAlignment: "CENTER",
columnType: "text",
textSize: "0.875rem",
enableFilter: true,
enableSort: true,
isVisible: true,
isCellVisible: true,
isCellEditable: false,
isDerived: false,
label: "task",
computedValue: `{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow["task"]))}}`,
validation: {},
sticky: StickyType.NONE,
},
status: {
index: 2,
width: 150,
id: "status",
originalId: "status",
alias: "status",
allowSameOptionsInNewRow: true,
horizontalAlignment: "LEFT",
verticalAlignment: "CENTER",
columnType: "text",
textSize: "0.875rem",
enableFilter: true,
enableSort: true,
isVisible: true,
isCellVisible: true,
isCellEditable: false,
isDerived: false,
label: "status",
computedValue: `{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow["status"]))}}`,
validation: {},
sticky: StickyType.NONE,
},
action: {
index: 3,
width: 150,
id: "action",
originalId: "action",
alias: "action",
allowSameOptionsInNewRow: true,
horizontalAlignment: "LEFT",
verticalAlignment: "CENTER",
columnType: "button",
textSize: "0.875rem",
enableFilter: true,
enableSort: true,
isVisible: true,
isCellVisible: true,
isCellEditable: false,
isDisabled: false,
isDerived: false,
label: "action",
onClick:
"{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}",
computedValue: `{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow["action"]))}}`,
validation: {},
sticky: StickyType.NONE,
},
},
tableData: [
{
step: "#1",
task: "Drop a table",
status: "✅",
action: "",
},
{
step: "#2",
task: "Create a query fetch_users with the Mock DB",
status: "--",
action: "",
},
{
step: "#3",
task: "Bind the query using => fetch_users.data",
status: "--",
action: "",
},
],
columnWidthMap: {
task: 245,
step: 70,
status: 85,
},
columnOrder: ["step", "task", "status", "action"],
blueprint: {
operations: [
{
type: BlueprintOperationTypes.MODIFY_PROPS,
fn: (widget: WidgetProps & { children?: WidgetProps[] }) => {
const primaryColumns = cloneDeep(widget.primaryColumns);
const columnIds = Object.keys(primaryColumns);
columnIds.forEach((columnId) => {
set(
primaryColumns,
`${columnId}.computedValue`,
`{{${
widget.widgetName
}.processedTableData.map((currentRow, currentIndex) => ( currentRow["${escapeString(
primaryColumns[columnId].alias,
)}"]))}}`,
);
set(primaryColumns, `${columnId}.labelColor`, Colors.WHITE);
Object.keys(
widget.childStylesheet[primaryColumns[columnId].columnType] ||
[],
).map((propertyKey) => {
const { jsSnippets, stringSegments } = getDynamicBindings(
widget.childStylesheet[primaryColumns[columnId].columnType][
propertyKey
],
);
const js = combineDynamicBindings(jsSnippets, stringSegments);
set(
primaryColumns,
`${columnId}.${propertyKey}`,
`{{${widget.widgetName}.processedTableData.map((currentRow, currentIndex) => ( ${js}))}}`,
);
});
});
const updatePropertyMap = [
{
widgetId: widget.widgetId,
propertyName: "primaryColumns",
propertyValue: primaryColumns,
},
];
return updatePropertyMap;
},
},
],
},
enableClientSideSearch: true,
isVisibleSearch: true,
isVisibleFilters: true,
isVisibleDownload: true,
isVisiblePagination: true,
isSortable: true,
delimiter: ",",
version: 1,
inlineEditingSaveOption: InlineEditingSaveOptions.ROW_LEVEL,
},
properties: {
derived: Widget.getDerivedPropertiesMap(),
default: Widget.getDefaultPropertiesMap(),
meta: Widget.getMetaPropertiesMap(),
contentConfig: Widget.getPropertyPaneContentConfig(),
styleConfig: Widget.getPropertyPaneStyleConfig(),
stylesheetConfig: Widget.getStylesheetConfig(),
loadingProperties: Widget.getLoadingProperties(),
},
};
export default Widget;