## 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
259 lines
7.9 KiB
TypeScript
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;
|