From 12ea1b86ea8e75154a248a9dc5a314da9d956fa4 Mon Sep 17 00:00:00 2001 From: Souma Ghosh <103924539+souma-ghosh@users.noreply.github.com> Date: Mon, 16 Jan 2023 14:53:56 +0530 Subject: [PATCH] feat: Date column type editing for table widget (#19181) - Integrates Date picker component inside table's date column - Enables edit mode for date type column in table widget - Adds all the required Property controls for date picker - Builds the user flow for date column editing in table widget --- .../fixtures/Table/DateCellEditingDSL.json | 813 ++++++++++++++++++ .../TableV2/Date_column_editing_spec.js | 366 ++++++++ .../Widgets/TableV2/Inline_editing_spec.js | 6 +- .../Widgets/TableV2/Text_wrapping_spec.js | 8 +- .../inline_editing_validations_spec.js | 2 +- .../DatePickerWidget2/component/index.tsx | 23 + .../TableWidgetV2/component/Constants.ts | 13 + .../component/cellComponents/DateCell.tsx | 357 ++++++++ .../widgets/TableWidgetV2/widget/index.tsx | 84 ++ .../widget/propertyConfig/PanelConfig/Data.ts | 8 +- .../PanelConfig/DateProperties.ts | 57 ++ .../propertyConfig/PanelConfig/Events.ts | 18 +- .../propertyConfig/PanelConfig/General.ts | 2 - .../propertyConfig/PanelConfig/Validation.ts | 9 +- .../PanelConfig/Validations/Common.ts | 18 + .../PanelConfig/Validations/Date.ts | 36 + .../PanelConfig/Validations/Number.ts | 17 +- .../propertyConfig/PanelConfig/index.ts | 2 + .../widget/propertyUtils.test.ts | 35 + .../TableWidgetV2/widget/propertyUtils.ts | 16 + .../widgets/TableWidgetV2/widget/utilities.ts | 19 +- 21 files changed, 1880 insertions(+), 29 deletions(-) create mode 100644 app/client/cypress/fixtures/Table/DateCellEditingDSL.json create mode 100644 app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Date_column_editing_spec.js create mode 100644 app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx create mode 100644 app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/DateProperties.ts create mode 100644 app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Date.ts diff --git a/app/client/cypress/fixtures/Table/DateCellEditingDSL.json b/app/client/cypress/fixtures/Table/DateCellEditingDSL.json new file mode 100644 index 0000000000..135cb40e40 --- /dev/null +++ b/app/client/cypress/fixtures/Table/DateCellEditingDSL.json @@ -0,0 +1,813 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 4896, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1030, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 71, + "minHeight": 1292, + "dynamicTriggerPathList": [], + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "borderColor": "#E0DEDE", + "isVisibleDownload": true, + "iconSVG": "/static/media/icon.db8a9cbd2acd22a31ea91cc37ea2a46c.svg", + "topRow": 0, + "isSortable": true, + "type": "TABLE_WIDGET_V2", + "inlineEditingSaveOption": "ROW_LEVEL", + "animateLoading": true, + "dynamicBindingPathList": [ + { + "key": "primaryColumns.status.computedValue" + }, + { + "key": "accentColor" + }, + { + "key": "boxShadow" + }, + { + "key": "tableData" + }, + { + "key": "primaryColumns.revenue.computedValue" + }, + { + "key": "primaryColumns.imdb_id.computedValue" + }, + { + "key": "primaryColumns.release_date.computedValue" + }, + { + "key": "primaryColumns.genres.computedValue" + }, + { + "key": "primaryColumns.vote_average.computedValue" + }, + { + "key": "primaryColumns.tagline.computedValue" + }, + { + "key": "primaryColumns._id.computedValue" + }, + { + "key": "primaryColumns.title.computedValue" + }, + { + "key": "primaryColumns.vote_count.computedValue" + }, + { + "key": "primaryColumns.poster_path.computedValue" + }, + { + "key": "primaryColumns.homepage.computedValue" + }, + { + "key": "borderRadius" + }, + { + "key": "primaryColumns.customColumn1.buttonColor" + }, + { + "key": "primaryColumns.customColumn1.borderRadius" + }, + { + "key": "primaryColumns.customColumn1.boxShadow" + }, + { + "key": "primaryColumns.EditActions1.saveButtonColor" + }, + { + "key": "primaryColumns.EditActions1.saveBorderRadius" + }, + { + "key": "primaryColumns.EditActions1.discardBorderRadius" + }, + { + "key": "primaryColumns.EditActions1.isSaveDisabled" + }, + { + "key": "primaryColumns.EditActions1.isDiscardDisabled" + } + ], + "leftColumn": 0, + "delimiter": ",", + "defaultSelectedRowIndex": 0, + "showInlineEditingOptionDropdown": true, + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isVisibleFilters": true, + "isVisible": true, + "fontStyle": "", + "enableClientSideSearch": true, + "version": 1, + "textColor": "#18181b", + "totalRecordsCount": 0, + "isLoading": false, + "childStylesheet": { + "button": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "menuButton": { + "menuColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "iconButton": { + "buttonColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "boxShadow": "none" + }, + "editActions": { + "saveButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "saveBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "discardButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "discardBorderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + }, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "defaultSelectedRowIndices": [ + 0 + ], + "widgetName": "Table1", + "defaultPageSize": 0, + "columnOrder": [ + "status", + "revenue", + "imdb_id", + "release_date", + "genres", + "vote_average", + "tagline", + "_id", + "title", + "vote_count", + "poster_path", + "homepage", + "customColumn1", + "EditActions1" + ], + "dynamicPropertyPathList": [ + { + "key": "primaryColumns.EditActions1.isSaveDisabled" + }, + { + "key": "primaryColumns.EditActions1.isDiscardDisabled" + } + ], + "compactMode": "DEFAULT", + "displayName": "Table", + "bottomRow": 65, + "columnWidthMap": { + "task": 245, + "step": 62, + "status": 105, + "release_date": 226, + "genres": 193 + }, + "parentRowSpace": 10, + "hideCard": false, + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [ + { + "key": "primaryColumns.release_date.onSubmit" + }, + { + "key": "primaryColumns.release_date.onDateSelected" + } + ], + "borderWidth": "1", + "primaryColumns": { + "status": { + "index": 2, + "width": 150, + "id": "status", + "originalId": "status", + "alias": "status", + "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": {}, + "labelColor": "#FFFFFF", + "fontStyle": "", + "cellBackground": "transparent", + "textColor": "#18181b" + }, + "revenue": { + "allowCellWrapping": false, + "index": 0, + "width": 150, + "originalId": "revenue", + "id": "revenue", + "alias": "revenue", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "number", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "revenue", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"revenue\"]))}}", + "validation": { + "isColumnEditableCellRequired": true + }, + "cellBackground": "transparent" + }, + "imdb_id": { + "allowCellWrapping": false, + "index": 1, + "width": 150, + "originalId": "imdb_id", + "id": "imdb_id", + "alias": "imdb_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "imdb_id", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"imdb_id\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "release_date": { + "allowCellWrapping": false, + "index": 2, + "width": 150, + "originalId": "release_date", + "id": "release_date", + "alias": "release_date", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "date", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "release_date", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"release_date\"]))}}", + "validation": { + "minDate": "1905-12-05T00:00:00.000+05:21", + "maxDate": "2058-12-31T00:00:00.000+05:30", + "isColumnEditableCellRequired": false + }, + "cellBackground": "transparent", + "onSubmit": "", + "onDateSelected": "{{showAlert('onDateSelected')}}", + "firstDayOfWeek": "0", + "timePrecision": "second", + "shortcuts": true, + "outputFormat": "YYYY-MM-DDTHH:mm:ss", + "inputFormat": "YYYY-MM-DD" + }, + "genres": { + "allowCellWrapping": false, + "index": 3, + "width": 150, + "originalId": "genres", + "id": "genres", + "alias": "genres", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "genres", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"genres\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "vote_average": { + "allowCellWrapping": false, + "index": 4, + "width": 150, + "originalId": "vote_average", + "id": "vote_average", + "alias": "vote_average", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "number", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "vote_average", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"vote_average\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "tagline": { + "allowCellWrapping": false, + "index": 5, + "width": 150, + "originalId": "tagline", + "id": "tagline", + "alias": "tagline", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "tagline", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"tagline\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "_id": { + "allowCellWrapping": false, + "index": 6, + "width": 150, + "originalId": "_id", + "id": "_id", + "alias": "_id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "_id", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"_id\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "title": { + "allowCellWrapping": false, + "index": 7, + "width": 150, + "originalId": "title", + "id": "title", + "alias": "title", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "title", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"title\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "vote_count": { + "allowCellWrapping": false, + "index": 8, + "width": 150, + "originalId": "vote_count", + "id": "vote_count", + "alias": "vote_count", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "number", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "vote_count", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"vote_count\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "poster_path": { + "allowCellWrapping": false, + "index": 9, + "width": 150, + "originalId": "poster_path", + "id": "poster_path", + "alias": "poster_path", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "poster_path", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"poster_path\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "homepage": { + "allowCellWrapping": false, + "index": 10, + "width": 150, + "originalId": "homepage", + "id": "homepage", + "alias": "homepage", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": false, + "label": "homepage", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( currentRow[\"homepage\"]))}}", + "validation": {}, + "cellBackground": "transparent" + }, + "customColumn1": { + "allowCellWrapping": false, + "index": 10, + "width": 150, + "originalId": "customColumn1", + "id": "customColumn1", + "alias": "customColumn1", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "iconButton", + "textColor": "#18181b", + "textSize": "0.875rem", + "fontStyle": "", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "customColumn1", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "cellBackground": "transparent", + "labelColor": "#FFFFFF", + "buttonColor": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.colors.primaryColor))}}", + "borderRadius": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.borderRadius.appBorderRadius))}}", + "boxShadow": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( 'none'))}}", + "customAlias": "" + }, + "EditActions1": { + "allowCellWrapping": false, + "index": 10, + "width": 150, + "originalId": "EditActions1", + "id": "EditActions1", + "alias": "EditActions1", + "columnType": "editActions", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellEditable": false, + "isEditable": false, + "isCellVisible": true, + "isDerived": true, + "label": "Save / Discard", + "isSaveVisible": true, + "isDiscardVisible": true, + "computedValue": "", + "validation": {}, + "buttonStyle": "rgb(3, 179, 101)", + "saveIconAlign": "left", + "discardIconAlign": "left", + "saveActionLabel": "Save", + "discardActionLabel": "Discard", + "saveButtonColor": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.colors.primaryColor))}}", + "discardButtonColor": "#F22B2B", + "saveBorderRadius": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.borderRadius.appBorderRadius))}}", + "discardBorderRadius": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( appsmith.theme.borderRadius.appBorderRadius))}}", + "discardButtonVariant": "TERTIARY", + "isSaveDisabled": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( !Table1.updatedRowIndices.includes(currentIndex)))}}", + "isDiscardDisabled": "{{Table1.processedTableData.map((currentRow, currentIndex) => ( !Table1.updatedRowIndices.includes(currentIndex)))}}" + } + }, + "key": "ds95nyw2jg", + "isDeprecated": false, + "rightColumn": 64, + "textSize": "0.875rem", + "widgetId": "h0hd2shht7", + "tableData": [ + { + "revenue": 42600000, + "imdb_id": "tt3228774", + "release_date": "2021-05-26" + }, + { + "revenue": 435954000, + "imdb_id": "tt5034838", + "release_date": "2021-03-24" + }, + { + "revenue": 13126737, + "imdb_id": "tt32286774", + "release_date": "2021-05-05" + } + ], + "label": "Data", + "searchKey": "", + "parentId": "0", + "renderMode": "CANVAS", + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "cellBackground": "transparent", + "verticalAlignment": "CENTER" + }, + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b523e6f70ba6f40a10fc2c7c5b5.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 67, + "bottomRow": 95, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "leftColumn": 3, + "dynamicBindingPathList": [ + { + "key": "truncateButtonColor" + }, + { + "key": "fontFamily" + }, + { + "key": "borderRadius" + }, + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{JSON.stringify(Table1.updatedRow)}}", + "key": "tgzs4gzszh", + "isDeprecated": false, + "rightColumn": 19, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "7z3nhdsqcz", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "originalTopRow": 67, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "maxDynamicHeight": 9000, + "originalBottomRow": 95, + "fontSize": "1rem", + "minDynamicHeight": 4 + }, + { + "widgetName": "Text2", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b523e6f70ba6f40a10fc2c7c5b5.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 67, + "bottomRow": 71, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "leftColumn": 20, + "dynamicBindingPathList": [ + { + "key": "truncateButtonColor" + }, + { + "key": "fontFamily" + }, + { + "key": "borderRadius" + }, + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{JSON.stringify(Table1.updatedRows)}}", + "key": "wxnjnt7ml3", + "isDeprecated": false, + "rightColumn": 36, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "buu1i75k2o", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "originalTopRow": 67, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "maxDynamicHeight": 9000, + "originalBottomRow": 71, + "fontSize": "1rem", + "minDynamicHeight": 4 + }, + { + "widgetName": "Text3", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b523e6f70ba6f40a10fc2c7c5b5.svg", + "searchTags": [ + "typography", + "paragraph", + "label" + ], + "topRow": 67, + "bottomRow": 71, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "overflow": "NONE", + "fontFamily": "{{appsmith.theme.fontFamily.appFont}}", + "parentColumnSpace": 20.0625, + "dynamicTriggerPathList": [], + "leftColumn": 37, + "dynamicBindingPathList": [ + { + "key": "truncateButtonColor" + }, + { + "key": "fontFamily" + }, + { + "key": "borderRadius" + }, + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "{{appsmith.theme.colors.primaryColor}}", + "text": "{{JSON.stringify(Table1.updatedRowIndices)}}", + "key": "wxnjnt7ml3", + "isDeprecated": false, + "rightColumn": 53, + "textAlign": "LEFT", + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "pw6uyso07g", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "maxDynamicHeight": 9000, + "fontSize": "1rem", + "minDynamicHeight": 4 + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Date_column_editing_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Date_column_editing_spec.js new file mode 100644 index 0000000000..a194107086 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Date_column_editing_spec.js @@ -0,0 +1,366 @@ +const dsl = require("../../../../../fixtures/Table/DateCellEditingDSL.json"); +const commonlocators = require("../../../../../locators/commonlocators.json"); +const widgetsPage = require("../../../../../locators/Widgets.json"); +import { ObjectsRegistry } from "../../../../../support/Objects/Registry"; +import { PROPERTY_SELECTOR } from "../../../../../locators/WidgetLocators"; +const agHelper = ObjectsRegistry.AggregateHelper; + +describe("Table widget date column inline editing functionality", () => { + before(() => { + cy.addDsl(dsl); + }); + + it("1. should check that edit check box is enabled for date type column in the columns list", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.get( + `[data-rbd-draggable-id="release_date"] .t--card-checkbox input`, + ).should("not.be.disabled"); + }); + + it("2. should check that date cell edit mode can be turned on", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-general .t--property-control-editable", + ).should("exist"); + cy.get( + ".t--property-pane-section-general .t--property-control-editable input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Head} [data-header="release_date"] svg`, + ).should("exist"); + }); + + it("3. should check that user can edit date in table cell", () => { + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick(); + cy.get(".bp3-dateinput-popover").should("exist"); + cy.get(".t--inlined-cell-editor").should("exist"); + cy.get(".bp3-dateinput-popover [aria-label='Mon May 17 2021']").click(); + cy.get(".bp3-dateinput-popover").should("not.exist"); + cy.get(".t--inlined-cell-editor").should("not.exist"); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).should("contain", "2021-05-17T00:00:00"); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(".bp3-dateinput-popover").should("exist"); + cy.get(".t--inlined-cell-editor").should("exist"); + cy.get(`${commonlocators.textWidget}`) + .first() + .click(); + cy.get(".bp3-dateinput-popover").should("not.exist"); + cy.get(".t--inlined-cell-editor").should("not.exist"); + cy.get( + `[type='CANVAS_WIDGET'] .t--widget-textwidget ${commonlocators.textWidget} span`, + ).should( + "contain", + `{"revenue":42600000,"imdb_id":"tt3228774","release_date":"2021-05-17"}`, + ); + cy.get( + `[type='CANVAS_WIDGET'] .t--widget-textwidget+.t--widget-textwidget ${commonlocators.textWidget} span`, + ).should( + "contain", + `[{"index":0,"updatedFields":{"release_date":"2021-05-17"},"allFields":{"revenue":42600000,"imdb_id":"tt3228774","release_date":"2021-05-17"}}]`, + ); + cy.get( + `[type='CANVAS_WIDGET'] .t--widget-textwidget+.t--widget-textwidget+.t--widget-textwidget ${commonlocators.textWidget} span`, + ).should("contain", "[0]"); + }); + + it("4. should check that changing property pane display format for date column changes date display format", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-displayformat .bp3-popover-target") + .last() + .click(); + cy.get(".t--dropdown-option") + .children() + .contains("Do MMM YYYY") + .click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).should("contain", "17th May 2021"); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-displayformat .bp3-popover-target") + .last() + .click(); + cy.get(".t--dropdown-option") + .children() + .contains("DD/MM/YYYY") + .click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).should("contain", "17/05/2021"); + }); + + it("5. should check that changing property pane first day of week changes the date picker starting day", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-firstdayofweek .t--code-editor-wrapper") + .last() + .click() + .type("{backspace}1"); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get( + ".bp3-datepicker .DayPicker .DayPicker-Months .DayPicker-WeekdaysRow div:first-child abbr", + ).should("contain", "Mo"); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-firstdayofweek .t--code-editor-wrapper") + .last() + .click() + .type("{backspace}5"); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get( + ".bp3-datepicker .DayPicker .DayPicker-Months .DayPicker-WeekdaysRow div:first-child abbr", + ).should("contain", "Fr"); + }); + + it.skip("6. should check that changing property pane time precision changes the date picker time precision", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-timeprecision .bp3-popover-target") + .last() + .click(); + cy.get(".t--dropdown-option") + .children() + .contains("Minute") + .click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-hour").should("exist"); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-minute").should("exist"); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-second").should( + "not.exist", + ); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-timeprecision .bp3-popover-target") + .last() + .click(); + cy.get(".t--dropdown-option") + .children() + .contains("None") + .click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(".bp3-timepicker-input-row").should("not.exist"); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get(".t--property-control-timeprecision .bp3-popover-target") + .last() + .click(); + cy.get(".t--dropdown-option") + .children() + .contains("Second") + .click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-hour").should("exist"); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-minute").should("exist"); + cy.get(".bp3-timepicker-input-row .bp3-timepicker-second").should("exist"); + }); + + it("7. should check visible property control functionality", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-general .t--property-control-visible", + ).should("exist"); + cy.get( + ".t--property-pane-section-general .t--property-control-visible input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Head} [data-header="release_date"] .hidden-header`, + ).should("exist"); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-general .t--property-control-visible input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Head} [data-header="release_date"] .draggable-header`, + ).should("exist"); + }); + + it("8. should check Show Shortcuts property control functionality", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-datesettings .t--property-control-showshortcuts", + ).should("exist"); + cy.get( + ".t--property-pane-section-datesettings .t--property-control-showshortcuts input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(`.bp3-dateinput-popover .bp3-daterangepicker-shortcuts`).should( + "not.exist", + ); + + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-datesettings .t--property-control-showshortcuts", + ).should("exist"); + cy.get( + ".t--property-pane-section-datesettings .t--property-control-showshortcuts input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3)`, + ).dblclick({ + force: true, + }); + cy.get(`.bp3-dateinput-popover .bp3-daterangepicker-shortcuts`).should( + "exist", + ); + }); + + it("9. should check min date and max date property control functionality", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-validation .t--property-control-mindate", + ).should("exist"); + cy.get( + ".t--property-pane-section-validation .t--property-control-maxdate", + ).should("exist"); + + cy.get( + ".t--property-pane-section-validation .t--property-control-mindate div:last-child .bp3-popover-wrapper", + ) + .click() + .clear() + .type("2022-05-05T00:00:10.1010+05:30{enter}"); + cy.get( + ".t--property-pane-section-validation .t--property-control-maxdate div:last-child .bp3-popover-wrapper", + ) + .click() + .clear() + .type("2022-05-30T00:00:10.1010+05:30{enter}"); + + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) .td:nth-child(3)`, + ).realHover(); + cy.get(`.t--editable-cell-icon`) + .first() + .click({ + force: true, + }); + cy.get( + ".bp3-transition-container .bp3-popover .bp3-popover-content", + ).should("contain", "Date out of range"); + cy.get( + ".t--property-pane-section-validation .t--property-control-mindate div:last-child .bp3-popover-wrapper", + ) + .click() + .clear() + .type("{enter}"); + cy.get( + ".t--property-pane-section-validation .t--property-control-maxdate div:last-child .bp3-popover-wrapper", + ) + .click() + .clear() + .type("{enter}"); + }); + + it("10. should check property pane Required toggle functionality", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.editColumn("release_date"); + cy.get( + ".t--property-pane-section-validation .t--property-control-required", + ).should("exist"); + cy.get( + ".t--property-pane-section-validation .t--property-control-required input[type=checkbox]+span", + ).click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) .td:nth-child(3)`, + ).realHover(); + cy.get(`.t--editable-cell-icon`) + .first() + .click({ + force: true, + }); + cy.get(".bp3-dateinput-popover [aria-label='Wed May 26 2021']").click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) .td:nth-child(3)`, + ).realHover(); + cy.get(`.t--editable-cell-icon`) + .first() + .click({ + force: true, + }); + cy.get(".bp3-dateinput-popover [aria-label='Wed May 26 2021']").click(); + cy.get( + ".bp3-transition-container .bp3-popover .bp3-popover-content", + ).should("exist"); + cy.get( + ".bp3-transition-container .bp3-popover .bp3-popover-content", + ).should("contain", "This field is required"); + cy.get(".bp3-dateinput-popover [aria-label='Wed May 26 2021']").click(); + cy.get( + ".bp3-transition-container .bp3-popover .bp3-popover-content", + ).should("not.exist"); + }); + + it("11. should check date cells behave as expected when adding a new row to table", () => { + cy.openPropertyPane("tablewidgetv2"); + cy.get(".t--property-pane-back-btn").click(); + cy.get( + ".t--property-pane-section-addingarow .t--property-control-allowaddingarow input[type=checkbox]+span", + ).click(); + cy.get(".t--add-new-row").click(); + cy.get(".bp3-datepicker").should("not.exist"); + cy.get(".t--inlined-cell-editor") + .should("have.css", "border") + .and("eq", "1px solid rgb(255, 255, 255)"); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3) input`, + ).should("have.value", ""); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3) input`, + ).click(); + cy.get(".bp3-datepicker").should("exist"); + cy.get(".t--inlined-cell-editor") + .should("have.css", "border") + .and("not.eq", "none") + .and("not.eq", "1px solid rgb(255, 255, 255)"); + cy.get( + ".bp3-datepicker .DayPicker .DayPicker-Body .DayPicker-Week:nth-child(2) .DayPicker-Day:first-child", + ).click(); + cy.get( + `${commonlocators.TableV2Row} .tr:nth-child(1) div:nth-child(3) input`, + ).should("not.have.value", ""); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Inline_editing_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Inline_editing_spec.js index e1493cc660..e2d00eaeff 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Inline_editing_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Inline_editing_spec.js @@ -141,7 +141,7 @@ describe("Table widget inline editing functionality", () => { }, { columnType: "Date", - expected: "be.disabled", + expected: "not.be.disabled", }, { columnType: "Image", @@ -198,7 +198,7 @@ describe("Table widget inline editing functionality", () => { }, { columnType: "Date", - expected: "not.exist", + expected: "exist", }, { columnType: "Image", @@ -765,7 +765,7 @@ describe("Table widget inline editing functionality", () => { cy.get(commonlocators.textWidgetContainer).should("contain.text", -1); }); - it.only("27. should check if updatedRowIndex is getting updated for multi row update mode", () => { + it("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( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Text_wrapping_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Text_wrapping_spec.js index 57c7553585..cdbcd1b622 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Text_wrapping_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/Text_wrapping_spec.js @@ -74,7 +74,7 @@ describe("Table Widget text wrapping functionality", function() { }); }); - it("4. should check that cell wrapping option is only available for plain text, number, date and URL", () => { + it("4. should check that cell wrapping option is only available for plain text, number and URL", () => { cy.openPropertyPane("tablewidgetv2"); cy.editColumn("email"); [ @@ -92,7 +92,7 @@ describe("Table Widget text wrapping functionality", function() { }, { columnType: "Date", - expected: "exist", + expected: "not.exist", }, { columnType: "Image", @@ -127,11 +127,11 @@ describe("Table Widget text wrapping functionality", function() { }); }); - it("5. should check that plain text, number, date and URL column is getting wrapped when cell wrapping is enabled", () => { + it("5. should check that plain text, number and URL column is getting wrapped when cell wrapping is enabled", () => { cy.openPropertyPane("tablewidgetv2"); cy.editColumn("id"); - ["URL", "Number", "Date", "Plain Text"].forEach((data, i) => { + ["URL", "Number", "Plain Text"].forEach((data, i) => { cy.get(commonlocators.changeColType) .last() .click(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/inline_editing_validations_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/inline_editing_validations_spec.js index d8a2ca7882..b7c2b6c4b3 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/inline_editing_validations_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/TableV2/inline_editing_validations_spec.js @@ -57,7 +57,7 @@ describe("Table widget inline editing validation functionality", () => { .contains("Date") .click(); cy.wait("@updateLayout"); - cy.get(".t--property-pane-section-collapse-validation").should("not.exist"); + cy.get(".t--property-pane-section-collapse-validation").should("exist"); cy.get(commonlocators.changeColType) .last() .click(); diff --git a/app/client/src/widgets/DatePickerWidget2/component/index.tsx b/app/client/src/widgets/DatePickerWidget2/component/index.tsx index 292881d345..c18ad0433f 100644 --- a/app/client/src/widgets/DatePickerWidget2/component/index.tsx +++ b/app/client/src/widgets/DatePickerWidget2/component/index.tsx @@ -167,6 +167,15 @@ class DatePickerComponent extends React.Component< return _date.isValid() ? _date.toDate() : undefined; }; + getConditionalPopoverProps = (props: DatePickerComponentProps) => { + if (typeof props.isPopoverOpen === "boolean") { + return { + isOpen: props.isPopoverOpen, + }; + } + return {}; + }; + render() { const { compactMode, @@ -357,6 +366,14 @@ class DatePickerComponent extends React.Component< usePortal: !this.props.withoutPortal, canEscapeKeyClose: true, portalClassName: `${DATEPICKER_POPUP_CLASSNAME}-${this.props.widgetId}`, + onClose: this.props.onPopoverClosed, + /* + Conditional popover props are the popover props that should not be sent to + DateInput in any way if they are not applicable. + Here isOpen prop if sent in any way will interfere with the normal functionality + of Date Picker widget's popover but is required for Table Widget's date cell popover + */ + ...this.getConditionalPopoverProps(this.props), }} shortcuts={this.props.shortcuts} showActionsBar @@ -404,6 +421,9 @@ class DatePickerComponent extends React.Component< isValid = false; } } + if (!isValid && this.props?.onDateOutOfRange) { + this.props.onDateOutOfRange(); + } return isValid; }; @@ -474,6 +494,9 @@ interface DatePickerComponentProps extends ComponentProps { labelTooltip?: string; onFocus?: () => void; onBlur?: () => void; + onPopoverClosed?: (e: unknown) => void; + isPopoverOpen?: boolean; + onDateOutOfRange?: () => void; } interface DatePickerComponentState { diff --git a/app/client/src/widgets/TableWidgetV2/component/Constants.ts b/app/client/src/widgets/TableWidgetV2/component/Constants.ts index 1d4f1e3603..a645382ff2 100644 --- a/app/client/src/widgets/TableWidgetV2/component/Constants.ts +++ b/app/client/src/widgets/TableWidgetV2/component/Constants.ts @@ -15,6 +15,7 @@ import { MenuItemsSource, } from "widgets/MenuButtonWidget/constants"; import { ColumnTypes } from "../constants"; +import { TimePrecision } from "widgets/DatePickerWidget2/constants"; export type TableSizes = { COLUMN_HEADER_HEIGHT: number; @@ -182,6 +183,13 @@ export interface ImageCellProperties { imageSize?: ImageSize; } +export interface DateCellProperties { + inputFormat: string; + outputFormat: string; + shortcuts: boolean; + timePrecision?: TimePrecision; +} + export interface BaseCellProperties { horizontalAlignment?: CellAlignment; verticalAlignment?: VerticalAlignment; @@ -206,6 +214,7 @@ export interface CellLayoutProperties MenuButtonCellProperties, SelectCellProperties, ImageCellProperties, + DateCellProperties, BaseCellProperties {} export interface TableColumnMetaProps { @@ -264,6 +273,8 @@ export interface ColumnStyleProperties { export interface DateColumnProperties { outputFormat?: string; inputFormat?: string; + shortcuts?: boolean; + timePrecision?: TimePrecision; } export interface ColumnEditabilityProperties { @@ -276,6 +287,8 @@ export interface ColumnEditabilityProperties { isEditableCellRequired?: boolean; min?: number; max?: number; + minDate?: string; + maxDate?: string; }; } diff --git a/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx new file mode 100644 index 0000000000..cd8570b33a --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/component/cellComponents/DateCell.tsx @@ -0,0 +1,357 @@ +import React, { useMemo, useRef, useState } from "react"; +import { + ALIGN_ITEMS, + VerticalAlignment, + EDITABLE_CELL_PADDING_OFFSET, + TABLE_SIZES, +} from "../Constants"; +import DateComponent from "widgets/DatePickerWidget2/component"; +import { TimePrecision } from "widgets/DatePickerWidget2/constants"; +import { RenderDefaultPropsType } from "./PlainTextCell"; +import styled from "styled-components"; +import { EditableCellActions } from "widgets/TableWidgetV2/constants"; +import { ISO_DATE_FORMAT } from "constants/WidgetValidation"; +import moment from "moment"; +import { BasicCell } from "./BasicCell"; +import { Colors } from "constants/Colors"; +import ErrorTooltip from "components/editorComponents/ErrorTooltip"; +import { + createMessage, + INPUT_WIDGET_DEFAULT_VALIDATION_ERROR, +} from "@appsmith/constants/messages"; + +type DateComponentProps = RenderDefaultPropsType & + editPropertyType & { + accentColor?: string; + borderRadius?: string; + boxShadow?: string; + closeOnSelection: boolean; + maxDate: string; + minDate: string; + onDateChange?: string; + shortcuts: boolean; + timePrecision: TimePrecision; + inputFormat: string; + outputFormat: string; + onDateSave: ( + rowIndex: number, + alias: string, + value: string, + onSubmit?: string, + ) => void; + onDateSelectedString: string; + firstDayOfWeek?: number; + isRequired: boolean; + updateNewRowValues: ( + alias: string, + value: unknown, + parsedValue: unknown, + ) => void; + }; + +const COMPONENT_DEFAULT_VALUES = { + maxDate: "2121-12-31T18:29:00.000Z", + minDate: "1920-12-31T18:30:00.000Z", + timePrecision: TimePrecision.MINUTE, +}; + +type editPropertyType = { + alias: string; + onDateSelectedString: string; + rowIndex: number; +}; + +const DEFAULT_BORDER_RADIUS = "0"; + +const Container = styled.div<{ + isCellEditMode?: boolean; + verticalAlignment?: VerticalAlignment; + cellBackground?: string; +}>` + height: 100%; + width: 100%; + display: flex; + align-items: ${(props) => + props.verticalAlignment && ALIGN_ITEMS[props.verticalAlignment]}; +`; + +const FOCUS_CLASS = "has-focus"; + +const Wrapper = styled.div<{ + accentColor: string; + compactMode: string; + allowCellWrapping?: boolean; + verticalAlignment?: VerticalAlignment; + textSize?: string; + isEditableCellValid: boolean; + paddedInput: boolean; +}>` + padding: 1px; + border: 1px solid + ${(props) => (!props.isEditableCellValid ? Colors.DANGER_SOLID : "#fff")}; + background: #fff; + position: absolute; + width: ${(props) => + props.paddedInput + ? `calc(100% - ${EDITABLE_CELL_PADDING_OFFSET}px)` + : "100%"}; + left: 50%; + transform: translate(-50%, 0); + overflow: hidden; + border-radius: 3px; + display: flex; + height: ${(props) => { + if (props.allowCellWrapping) { + return props.paddedInput + ? `calc(100% - ${EDITABLE_CELL_PADDING_OFFSET}px)` + : "100%"; + } else { + return props.paddedInput + ? `${TABLE_SIZES[props.compactMode].ROW_HEIGHT - + EDITABLE_CELL_PADDING_OFFSET}px` + : `${TABLE_SIZES[props.compactMode].ROW_HEIGHT}px`; + } + }}; + ${(props) => { + switch (props.verticalAlignment) { + case "TOP": + return `top: 0;`; + case "BOTTOM": + return `bottom: 0;`; + case "CENTER": + return ` + top: calc(50% - (${TABLE_SIZES[props.compactMode].ROW_HEIGHT}/2)px); + `; + } + }} + + &&&&& { + .bp3-input, + .bp3-input:focus { + border: none; + /* + * using !important since underlying + * component styles has !important + */ + box-shadow: none !important; + padding: 0px 5px 0px 6px; + font-size: ${(props) => props.textSize}; + background: transparent; + color: inherit; + } + } + + &.${FOCUS_CLASS} { + ${(props) => + props.isEditableCellValid && `border: 1px solid ${props.accentColor}`} + } +`; + +export const DateCell = (props: DateComponentProps) => { + const { + accentColor, + alias, + allowCellWrapping, + borderRadius, + cellBackground, + columnType, + compactMode, + disabledEditIcon, + disabledEditIconMessage, + firstDayOfWeek, + fontStyle, + hasUnsavedChanges, + horizontalAlignment, + inputFormat, + isCellDisabled, + isCellEditable, + isCellEditMode, + isCellVisible, + isHidden, + isNewRow, + isRequired, + maxDate, + minDate, + onDateSave, + onDateSelectedString, + outputFormat, + rowIndex, + shortcuts, + tableWidth, + textColor, + textSize, + timePrecision, + toggleCellEditMode, + updateNewRowValues, + validationErrorMessage, + value, + verticalAlignment, + widgetId, + } = props; + + const [hasFocus, setHasFocus] = useState(false); + const [isValid, setIsValid] = useState(true); + const [showRequiredError, setShowRequiredError] = useState(false); + const contentRef = useRef(null); + + const valueInISOFormat = useMemo(() => { + if (typeof value !== "string") return ""; + + if (moment(value, ISO_DATE_FORMAT, true).isValid()) { + return value; + } + + const valueInSelectedFormat = moment(value, props.outputFormat, true); + + if (valueInSelectedFormat.isValid()) { + return valueInSelectedFormat.format(ISO_DATE_FORMAT); + } + + return value; + }, [value, props.outputFormat]); + + const onDateSelected = (date: string) => { + if (isNewRow) { + updateNewRowValues(alias, date, date); + return; + } + + if (isRequired && !date) { + setIsValid(false); + setShowRequiredError(true); + return; + } + setIsValid(true); + setShowRequiredError(false); + setHasFocus(false); + + const formattedDate = date ? moment(date).format(inputFormat) : ""; + onDateSave(rowIndex, alias, formattedDate, onDateSelectedString); + }; + + const onDateCellEdit = () => { + setHasFocus(true); + if (isRequired && !value) { + setIsValid(false); + setShowRequiredError(true); + } + toggleCellEditMode(true, rowIndex, alias, value); + }; + + const onPopoverClosed = () => { + setHasFocus(false); + setIsValid(true); + toggleCellEditMode( + false, + rowIndex, + alias, + value, + "", + EditableCellActions.DISCARD, + ); + }; + + const onDateOutOfRange = () => { + setIsValid(false); + setShowRequiredError(false); + }; + + const onDateInputFocus = () => { + if (isNewRow) { + setHasFocus(true); + } + }; + + let editor; + + if (isCellEditMode) { + editor = ( + + + + + + ); + } + + return ( + + + {editor} + + ); +}; diff --git a/app/client/src/widgets/TableWidgetV2/widget/index.tsx b/app/client/src/widgets/TableWidgetV2/widget/index.tsx index fa6f4bec6d..6d14780bc7 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/index.tsx +++ b/app/client/src/widgets/TableWidgetV2/widget/index.tsx @@ -87,7 +87,9 @@ import { SwitchCell } from "../component/cellComponents/SwitchCell"; import { SelectCell } from "../component/cellComponents/SelectCell"; import { CellWrapper } from "../component/TableStyledWrappers"; import { Stylesheet } from "entities/AppTheming"; +import { DateCell } from "../component/cellComponents/DateCell"; import { MenuItem, MenuItemsSource } from "widgets/MenuButtonWidget/constants"; +import { TimePrecision } from "widgets/DatePickerWidget2/constants"; const ReactTableComponent = lazy(() => retryPromise(() => import("../component")), @@ -1840,6 +1842,59 @@ class TableWidgetV2 extends BaseWidget { /> ); + case ColumnTypes.DATE: + return ( + + ); + default: let validationErrorMessage; @@ -1989,6 +2044,35 @@ class TableWidgetV2 extends BaseWidget { } }; + onDateSave = ( + rowIndex: number, + alias: string, + value: string, + onSubmit?: string, + ) => { + if (this.isColumnCellValid(alias)) { + this.updateTransientTableData({ + [ORIGINAL_INDEX_KEY]: this.getRowOriginalIndex(rowIndex), + [alias]: value, + }); + + if (onSubmit && this.props.editableCell?.column) { + this.onColumnEvent({ + rowIndex: rowIndex, + action: onSubmit, + triggerPropertyName: "onSubmit", + eventType: EventType.ON_SUBMIT, + row: { + ...this.props.filteredTableData[rowIndex], + [this.props.editableCell.column]: value, + }, + }); + } + + this.clearEditableCell(); + } + }; + clearEditableCell = (skipTimeout?: boolean) => { const clear = () => { this.props.updateWidgetMetaProperty("editableCell", defaultEditableCell); diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data.ts index 4a3a912eae..d9de02a5dc 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Data.ts @@ -174,7 +174,7 @@ export default { }, { propertyName: "inputFormat", - label: "Original Date Format", + label: "Date Format", helpText: "Date format of incoming data to the column", controlType: "DROP_DOWN", options: [ @@ -265,7 +265,7 @@ export default { hidden: (props: TableWidgetProps, propertyPath: string) => { const baseProperty = getBasePropertyPath(propertyPath); const columnType = get(props, `${baseProperty}.columnType`, ""); - return columnType !== "date"; + return columnType !== ColumnTypes.DATE; }, dependencies: ["primaryColumns", "columnOrder"], isBindProperty: true, @@ -303,7 +303,7 @@ export default { }, { propertyName: "outputFormat", - label: "Display Date Format", + label: "Display Format", helpText: "Date format to be shown to users", controlType: "DROP_DOWN", customJSControl: "TABLE_COMPUTE_VALUE", @@ -394,7 +394,7 @@ export default { hidden: (props: TableWidgetProps, propertyPath: string) => { const baseProperty = getBasePropertyPath(propertyPath); const columnType = get(props, `${baseProperty}.columnType`, ""); - return columnType !== "date"; + return columnType !== ColumnTypes.DATE; }, dependencies: ["primaryColumns", "columnType"], isBindProperty: true, diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/DateProperties.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/DateProperties.ts new file mode 100644 index 0000000000..c61120f8bf --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/DateProperties.ts @@ -0,0 +1,57 @@ +import { ValidationTypes } from "constants/WidgetValidation"; +import { ColumnTypes, TableWidgetProps } from "widgets/TableWidgetV2/constants"; +import { get } from "lodash"; +import { + allowedFirstDayOfWeekRange, + showByColumnType, +} from "../../propertyUtils"; +import { AutocompleteDataType } from "utils/autocomplete/CodemirrorTernService"; + +export default { + sectionName: "Date Settings", + hidden: (props: TableWidgetProps, propertyPath: string) => { + if (showByColumnType(props, propertyPath, [ColumnTypes.IMAGE], true)) { + return false; + } else { + const columnType = get(props, `${propertyPath}.columnType`, ""); + const isEditable = get(props, `${propertyPath}.isEditable`, ""); + return columnType !== ColumnTypes.DATE || !isEditable; + } + }, + children: [ + { + propertyName: "firstDayOfWeek", + label: "First Day Of Week", + helpText: "Defines the first day of the week for calendar", + controlType: "INPUT_TEXT", + defaultValue: "0", + inputType: "NUMBER", + isBindProperty: true, + isTriggerProperty: false, + dependencies: ["primaryColumns", "columnType"], + validation: { + type: ValidationTypes.FUNCTION, + params: { + fnString: allowedFirstDayOfWeekRange.toString(), + expected: { + type: + "0 : sunday\n1 : monday\n2 : tuesday\n3 : wednesday\n4 : thursday\n5 : friday\n6 : saturday", + example: "0", + autocompleteDataType: AutocompleteDataType.STRING, + }, + }, + }, + }, + { + propertyName: "shortcuts", + label: "Show Shortcuts", + helpText: "Choose to show shortcut menu", + controlType: "SWITCH", + isJSConvertible: false, + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.BOOLEAN }, + dependencies: ["primaryColumns", "columnType"], + }, + ], +}; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Events.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Events.ts index 727dec087a..8c71269e1a 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Events.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Events.ts @@ -4,6 +4,7 @@ import { getBasePropertyPath, showByColumnType, hideByColumnType, + getColumnPath, } from "../../propertyUtils"; export default { @@ -20,7 +21,8 @@ export default { columnType === ColumnTypes.NUMBER || columnType === ColumnTypes.CHECKBOX || columnType === ColumnTypes.SWITCH || - columnType === ColumnTypes.SELECT + columnType === ColumnTypes.SELECT || + columnType === ColumnTypes.DATE ) || !isEditable ); } @@ -133,5 +135,19 @@ export default { filterText: "", }), }, + { + propertyName: "onDateSelected", + label: "onDateSelected", + helpText: "Triggers an action when a date is selected in the calendar", + controlType: "ACTION_SELECTOR", + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: true, + dependencies: ["primaryColumns"], + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + return hideByColumnType(props, path, [ColumnTypes.DATE], true); + }, + }, ], }; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/General.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/General.ts index a7738c298d..2287748c72 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/General.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/General.ts @@ -99,7 +99,6 @@ export default { ColumnTypes.TEXT, ColumnTypes.NUMBER, ColumnTypes.URL, - ColumnTypes.DATE, ]); }, }, @@ -234,7 +233,6 @@ export const GeneralStyle = { }, }, }, - { propertyName: "imageSize", dependencies: ["primaryColumns", "columnType"], diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validation.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validation.ts index 792cb882a8..eaffc65e8f 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validation.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validation.ts @@ -3,6 +3,7 @@ import { get } from "lodash"; import { hideByColumnType } from "../../propertyUtils"; import commonValidations from "./Validations/Common"; import numberTypeValidations from "./Validations/Number"; +import dateTypeValidations from "./Validations/Date"; export default { sectionName: "Validation", @@ -14,10 +15,14 @@ export default { hideByColumnType( props, propertyPath, - [ColumnTypes.TEXT, ColumnTypes.NUMBER], + [ColumnTypes.TEXT, ColumnTypes.NUMBER, ColumnTypes.DATE], true, ) ); }, - children: [...numberTypeValidations, ...commonValidations], + children: [ + ...numberTypeValidations, + ...dateTypeValidations, + ...commonValidations, + ], }; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Common.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Common.ts index b21c7db3f1..6eb567b3bd 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Common.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Common.ts @@ -1,4 +1,9 @@ import { ValidationTypes } from "constants/WidgetValidation"; +import { TableWidgetProps, ColumnTypes } from "widgets/TableWidgetV2/constants"; +import { + showByColumnType, + getColumnPath, +} from "widgets/TableWidgetV2/widget/propertyUtils"; export default [ { @@ -11,6 +16,11 @@ export default [ isBindProperty: true, isTriggerProperty: false, validation: { type: ValidationTypes.REGEX }, + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + + return showByColumnType(props, path, [ColumnTypes.DATE], true); + }, }, { propertyName: "validation.isColumnEditableCellValid", @@ -27,6 +37,10 @@ export default [ default: true, }, }, + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + return showByColumnType(props, path, [ColumnTypes.DATE], true); + }, }, { propertyName: "validation.errorMessage", @@ -38,6 +52,10 @@ export default [ isBindProperty: true, isTriggerProperty: false, validation: { type: ValidationTypes.TEXT }, + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + return showByColumnType(props, path, [ColumnTypes.DATE], true); + }, }, { propertyName: "validation.isColumnEditableCellRequired", diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Date.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Date.ts new file mode 100644 index 0000000000..5567f72843 --- /dev/null +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Date.ts @@ -0,0 +1,36 @@ +import { ColumnTypes, TableWidgetProps } from "widgets/TableWidgetV2/constants"; +import { + getColumnPath, + hideByColumnType, +} from "widgets/TableWidgetV2/widget/propertyUtils"; + +export default [ + { + propertyName: "validation.minDate", + helpText: "Sets the minimum allowed date", + label: "Min Date", + controlType: "DATE_PICKER", + placeholderText: "1", + isBindProperty: true, + isTriggerProperty: false, + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + return hideByColumnType(props, path, [ColumnTypes.DATE], true); + }, + dependencies: ["primaryColumns"], + }, + { + propertyName: "validation.maxDate", + helpText: "Sets the maximum allowed value", + label: "Max Date", + controlType: "DATE_PICKER", + placeholderText: "100", + isBindProperty: true, + isTriggerProperty: false, + hidden: (props: TableWidgetProps, propertyPath: string) => { + const path = getColumnPath(propertyPath); + return hideByColumnType(props, path, [ColumnTypes.DATE], true); + }, + dependencies: ["primaryColumns"], + }, +]; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Number.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Number.ts index ff47800856..bbd7fa4652 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Number.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/Validations/Number.ts @@ -1,6 +1,9 @@ import { ValidationTypes } from "constants/WidgetValidation"; import { ColumnTypes, TableWidgetProps } from "widgets/TableWidgetV2/constants"; -import { hideByColumnType } from "widgets/TableWidgetV2/widget/propertyUtils"; +import { + hideByColumnType, + getColumnPath, +} from "widgets/TableWidgetV2/widget/propertyUtils"; export default [ { @@ -16,11 +19,7 @@ export default [ params: { default: -Infinity }, }, hidden: (props: TableWidgetProps, propertyPath: string) => { - const path = propertyPath - .split(".") - .slice(0, 2) - .join("."); - + const path = getColumnPath(propertyPath); return hideByColumnType(props, path, [ColumnTypes.NUMBER], true); }, dependencies: ["primaryColumns"], @@ -38,11 +37,7 @@ export default [ params: { default: Infinity }, }, hidden: (props: TableWidgetProps, propertyPath: string) => { - const path = propertyPath - .split(".") - .slice(0, 2) - .join("."); - + const path = getColumnPath(propertyPath); return hideByColumnType(props, path, [ColumnTypes.NUMBER], true); }, dependencies: ["primaryColumns"], diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/index.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/index.ts index 579bd15d32..eb4424e072 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/index.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/PanelConfig/index.ts @@ -15,6 +15,7 @@ import Color from "./Color"; import BorderAndShadow from "./BorderAndShadow"; import Validations from "./Validation"; import Select from "./Select"; +import DateProperties from "./DateProperties"; import { updateCustomColumnAliasOnLabelChange } from "../../propertyUtils"; export default { @@ -31,6 +32,7 @@ export default { DiscardButtonproperties, Select, Events, + DateProperties, ], styleChildren: [ GeneralStyle, diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts index 11a01a914a..66e2f7cbf8 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.test.ts @@ -8,6 +8,7 @@ import { uniqueColumnAliasValidation, updateCustomColumnAliasOnLabelChange, selectColumnOptionsValidation, + allowedFirstDayOfWeekRange, } from "./propertyUtils"; import _ from "lodash"; import { ColumnTypes, TableWidgetProps } from "../constants"; @@ -950,3 +951,37 @@ describe("updateCustomColumnAliasOnLabelChange", () => { ]); }); }); + +describe("allowedFirstDayOfWeekRange", () => { + it("should return valid object value is within 0 to 6", () => { + expect(allowedFirstDayOfWeekRange(4)).toEqual({ + isValid: true, + parsed: 4, + messages: [], + }); + }); + + it("should return valid object value is within 0 to 6", () => { + expect(allowedFirstDayOfWeekRange(0)).toEqual({ + isValid: true, + parsed: 0, + messages: [], + }); + }); + + it("should return invalid object when value is not within 0 to 6", () => { + expect(allowedFirstDayOfWeekRange(8)).toEqual({ + isValid: false, + parsed: 0, + messages: ["Number should be between 0-6."], + }); + }); + + it("should return invalid object when value is not within 0 to 6", () => { + expect(allowedFirstDayOfWeekRange(-2)).toEqual({ + isValid: false, + parsed: 0, + messages: ["Number should be between 0-6."], + }); + }); +}); diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts index 46c7985684..37a575155b 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyUtils.ts @@ -643,6 +643,16 @@ export const updateCustomColumnAliasOnLabelChange = ( } }; +export const allowedFirstDayOfWeekRange = (value: number) => { + const allowedValues = [0, 1, 2, 3, 4, 5, 6]; + const isValid = allowedValues.includes(Number(value)); + return { + isValid: isValid, + parsed: isValid ? Number(value) : 0, + messages: isValid ? [] : ["Number should be between 0-6."], + }; +}; + export const hideByMenuItemsSource = ( props: TableWidgetProps, propertyPath: string, @@ -895,3 +905,9 @@ export function selectColumnOptionsValidation( messages: [_message], }; } + +export const getColumnPath = (propPath: string) => + propPath + .split(".") + .slice(0, 2) + .join("."); diff --git a/app/client/src/widgets/TableWidgetV2/widget/utilities.ts b/app/client/src/widgets/TableWidgetV2/widget/utilities.ts index c6cac6e1eb..b3ccd55af6 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/utilities.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/utilities.ts @@ -468,14 +468,30 @@ export const getCellProperties = ( rowIndex, true, ), - resetFilterTextOnClose: getBooleanPropertyValue( + resetFilterTextOnClose: getPropertyValue( columnProperties.resetFilterTextOnClose, rowIndex, ), + inputFormat: getPropertyValue( + columnProperties.inputFormat, + rowIndex, + true, + ), + outputFormat: getPropertyValue( + columnProperties.outputFormat, + rowIndex, + true, + ), + shortcuts: getBooleanPropertyValue(columnProperties.shortcuts, rowIndex), selectOptions: getArrayPropertyValue( columnProperties.selectOptions, rowIndex, ), + timePrecision: getPropertyValue( + columnProperties.timePrecision, + rowIndex, + true, + ), } as CellLayoutProperties; } return {} as CellLayoutProperties; @@ -487,6 +503,7 @@ const EdtiableColumnTypes: string[] = [ ColumnTypes.SELECT, ColumnTypes.CHECKBOX, ColumnTypes.SWITCH, + ColumnTypes.DATE, ]; export function isColumnTypeEditable(columnType: string) {