fix: removed -1 and 2d array population error in the selectedRowIndices (#9606)
* fix: removed -1 and 2d array population error in the selectedRowIndices * test: init integration test for bug fix * test: completed the integration tests for bug fixes * test: added unit test for edge case in propertyUtils * refactor: removed unused import * feat: added selectedRowIndices as an option in the autocomplete * fix: fixed table widget test cases
This commit is contained in:
parent
0c74e7273e
commit
3a1c2b0799
208
app/client/cypress/fixtures/tableWithTextWidgetDsl.json
Normal file
208
app/client/cypress/fixtures/tableWithTextWidgetDsl.json
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
{
|
||||
"dsl": {
|
||||
"widgetName": "MainContainer",
|
||||
"backgroundColor": "none",
|
||||
"rightColumn": 744,
|
||||
"snapColumns": 64,
|
||||
"detachFromLayout": true,
|
||||
"widgetId": "0",
|
||||
"topRow": 0,
|
||||
"bottomRow": 1120,
|
||||
"containerStyle": "none",
|
||||
"snapRows": 125,
|
||||
"parentRowSpace": 1,
|
||||
"type": "CANVAS_WIDGET",
|
||||
"canExtend": true,
|
||||
"version": 46,
|
||||
"minHeight": 1100,
|
||||
"parentColumnSpace": 1,
|
||||
"dynamicBindingPathList": [],
|
||||
"leftColumn": 0,
|
||||
"children": [
|
||||
{
|
||||
"widgetName": "Text1",
|
||||
"dynamicPropertyPathList": [],
|
||||
"displayName": "Text",
|
||||
"iconSVG": "/static/media/icon.97c59b52.svg",
|
||||
"topRow": 23,
|
||||
"bottomRow": 41,
|
||||
"parentRowSpace": 10,
|
||||
"type": "TEXT_WIDGET",
|
||||
"hideCard": false,
|
||||
"parentColumnSpace": 26.59375,
|
||||
"dynamicTriggerPathList": [],
|
||||
"leftColumn": 6,
|
||||
"dynamicBindingPathList": [
|
||||
{
|
||||
"key": "text"
|
||||
}
|
||||
],
|
||||
"text": "{{Table1.selectedRowIndices}}",
|
||||
"key": "zzkmsgz6bl",
|
||||
"rightColumn": 30,
|
||||
"backgroundColor": "",
|
||||
"textAlign": "LEFT",
|
||||
"widgetId": "vmo0ewamhx",
|
||||
"isVisible": true,
|
||||
"fontStyle": "BOLD",
|
||||
"textColor": "#231F20",
|
||||
"version": 1,
|
||||
"parentId": "0",
|
||||
"renderMode": "CANVAS",
|
||||
"isLoading": false,
|
||||
"fontSize": "PARAGRAPH"
|
||||
},
|
||||
{
|
||||
"multiRowSelection": false,
|
||||
"widgetName": "Table1",
|
||||
"defaultPageSize": 0,
|
||||
"columnOrder": [
|
||||
"step",
|
||||
"task",
|
||||
"status",
|
||||
"action"
|
||||
],
|
||||
"isVisibleDownload": true,
|
||||
"dynamicPropertyPathList": [],
|
||||
"displayName": "Table",
|
||||
"iconSVG": "/static/media/icon.db8a9cbd.svg",
|
||||
"topRow": 41,
|
||||
"bottomRow": 69,
|
||||
"isSortable": true,
|
||||
"parentRowSpace": 10,
|
||||
"type": "TABLE_WIDGET",
|
||||
"defaultSelectedRow": "0",
|
||||
"hideCard": false,
|
||||
"parentColumnSpace": 25.6875,
|
||||
"dynamicTriggerPathList": [],
|
||||
"dynamicBindingPathList": [
|
||||
{
|
||||
"key": "primaryColumns.step.computedValue"
|
||||
},
|
||||
{
|
||||
"key": "primaryColumns.task.computedValue"
|
||||
},
|
||||
{
|
||||
"key": "primaryColumns.status.computedValue"
|
||||
},
|
||||
{
|
||||
"key": "primaryColumns.action.computedValue"
|
||||
}
|
||||
],
|
||||
"leftColumn": 19,
|
||||
"primaryColumns": {
|
||||
"step": {
|
||||
"index": 0,
|
||||
"width": 150,
|
||||
"id": "step",
|
||||
"horizontalAlignment": "LEFT",
|
||||
"verticalAlignment": "CENTER",
|
||||
"columnType": "text",
|
||||
"textSize": "PARAGRAPH",
|
||||
"enableFilter": true,
|
||||
"enableSort": true,
|
||||
"isVisible": true,
|
||||
"isCellVisible": true,
|
||||
"isDerived": false,
|
||||
"label": "step",
|
||||
"computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}"
|
||||
},
|
||||
"task": {
|
||||
"index": 1,
|
||||
"width": 150,
|
||||
"id": "task",
|
||||
"horizontalAlignment": "LEFT",
|
||||
"verticalAlignment": "CENTER",
|
||||
"columnType": "text",
|
||||
"textSize": "PARAGRAPH",
|
||||
"enableFilter": true,
|
||||
"enableSort": true,
|
||||
"isVisible": true,
|
||||
"isCellVisible": true,
|
||||
"isDerived": false,
|
||||
"label": "task",
|
||||
"computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}"
|
||||
},
|
||||
"status": {
|
||||
"index": 2,
|
||||
"width": 150,
|
||||
"id": "status",
|
||||
"horizontalAlignment": "LEFT",
|
||||
"verticalAlignment": "CENTER",
|
||||
"columnType": "text",
|
||||
"textSize": "PARAGRAPH",
|
||||
"enableFilter": true,
|
||||
"enableSort": true,
|
||||
"isVisible": true,
|
||||
"isCellVisible": true,
|
||||
"isDerived": false,
|
||||
"label": "status",
|
||||
"computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}"
|
||||
},
|
||||
"action": {
|
||||
"index": 3,
|
||||
"width": 150,
|
||||
"id": "action",
|
||||
"horizontalAlignment": "LEFT",
|
||||
"verticalAlignment": "CENTER",
|
||||
"columnType": "button",
|
||||
"textSize": "PARAGRAPH",
|
||||
"enableFilter": true,
|
||||
"enableSort": true,
|
||||
"isVisible": true,
|
||||
"isCellVisible": true,
|
||||
"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.sanitizedTableData.map((currentRow) => ( currentRow.action))}}"
|
||||
}
|
||||
},
|
||||
"delimiter": ",",
|
||||
"key": "fzi9jh5j7j",
|
||||
"derivedColumns": {},
|
||||
"rightColumn": 44,
|
||||
"textSize": "PARAGRAPH",
|
||||
"widgetId": "2tk8bgzwaz",
|
||||
"isVisibleFilters": true,
|
||||
"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": ""
|
||||
}
|
||||
],
|
||||
"isVisible": true,
|
||||
"label": "Data",
|
||||
"searchKey": "",
|
||||
"version": 3,
|
||||
"totalRecordsCount": 0,
|
||||
"parentId": "0",
|
||||
"renderMode": "CANVAS",
|
||||
"isLoading": false,
|
||||
"horizontalAlignment": "LEFT",
|
||||
"isVisibleSearch": true,
|
||||
"isVisiblePagination": true,
|
||||
"verticalAlignment": "CENTER",
|
||||
"columnSizeMap": {
|
||||
"task": 245,
|
||||
"step": 62,
|
||||
"status": 75
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ describe("Test Suite to validate copy/paste table Widget", function() {
|
|||
.last()
|
||||
.click();
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(11);
|
||||
expect($lis).to.have.length(12);
|
||||
expect($lis.eq(0)).to.contain("{{Table1Copy.selectedRow}}");
|
||||
expect($lis.eq(1)).to.contain("{{Table1Copy.selectedRows}}");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
const dsl = require("../../../../fixtures/tableWithTextWidgetDsl.json");
|
||||
const widgetsPage = require("../../../../locators/Widgets.json");
|
||||
|
||||
describe("Table widget edge case scenario testing", function() {
|
||||
before(() => {
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
|
||||
it("Check if the selectedRowIndices does not contain 2d array", function() {
|
||||
cy.openPropertyPane("tablewidget");
|
||||
|
||||
//Enable Multi row select
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
//Change the value of default selected row
|
||||
cy.updateCodeInput(".t--property-control-defaultselectedrow", "1");
|
||||
|
||||
//Disable Multi row select
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should("have.text", "[]");
|
||||
|
||||
//Enable Multi row select
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
||||
"have.text",
|
||||
"[ 1]",
|
||||
);
|
||||
|
||||
//Disable Multi row select
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
//Enable Multi row select
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
||||
"have.text",
|
||||
"[ 1]",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
const dsl = require("../../../../fixtures/tableWithTextWidgetDsl.json");
|
||||
const widgetsPage = require("../../../../locators/Widgets.json");
|
||||
const commonlocators = require("../../../../locators/commonlocators.json");
|
||||
|
||||
describe("Table widget edge case scenario testing", function() {
|
||||
before(() => {
|
||||
cy.addDsl(dsl);
|
||||
});
|
||||
it("Check if the selectedRowIndices does not contain -1", function() {
|
||||
cy.openPropertyPane("tablewidget");
|
||||
|
||||
//Update the property default selected row to blank
|
||||
cy.updateCodeInput(".t--property-control-defaultselectedrow", "");
|
||||
|
||||
//Check if the evaluated value is undefined
|
||||
cy.get(commonlocators.evaluatedCurrentValue)
|
||||
.first()
|
||||
.should("be.visible")
|
||||
.should("have.text", "undefined");
|
||||
|
||||
//Check the value present in the textfield which is selectedRowIndices is blank
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should("have.text", "");
|
||||
|
||||
//Enable the "Enable Multi Row selection"
|
||||
cy.get(widgetsPage.toggleEnableMultirowselection)
|
||||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
//Check the value present in the textfield which is selectedRowIndices is []
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should("have.text", "[]");
|
||||
|
||||
//Select the 1st, 2nd and 3rd row
|
||||
cy.isSelectRow("0");
|
||||
cy.isSelectRow("1");
|
||||
cy.isSelectRow("2");
|
||||
|
||||
//Check the value present in the textfield which is selectedRowIndices is [0,1,2]
|
||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
||||
"have.text",
|
||||
"[ 0, 1, 2]",
|
||||
);
|
||||
});
|
||||
});
|
||||
//
|
||||
|
|
@ -35,18 +35,19 @@ describe("Entity explorer tests related to widgets and validation", function() {
|
|||
.last()
|
||||
.click({ force: true });
|
||||
cy.get(apiwidget.propertyList).then(function($lis) {
|
||||
expect($lis).to.have.length(11);
|
||||
expect($lis).to.have.length(12);
|
||||
expect($lis.eq(0)).to.contain("{{Table1.selectedRow}}");
|
||||
expect($lis.eq(1)).to.contain("{{Table1.selectedRows}}");
|
||||
expect($lis.eq(2)).to.contain("{{Table1.triggeredRow}}");
|
||||
expect($lis.eq(3)).to.contain("{{Table1.selectedRowIndex}}");
|
||||
expect($lis.eq(4)).to.contain("{{Table1.tableData}}");
|
||||
expect($lis.eq(5)).to.contain("{{Table1.pageNo}}");
|
||||
expect($lis.eq(6)).to.contain("{{Table1.pageSize}}");
|
||||
expect($lis.eq(7)).to.contain("{{Table1.isVisible}}");
|
||||
expect($lis.eq(8)).to.contain("{{Table1.searchText}}");
|
||||
expect($lis.eq(9)).to.contain("{{Table1.totalRecordsCount}}");
|
||||
expect($lis.eq(10)).to.contain("{{Table1.sortOrder}}");
|
||||
expect($lis.eq(2)).to.contain("{{Table1.selectedRowIndices}}");
|
||||
expect($lis.eq(3)).to.contain("{{Table1.triggeredRow}}");
|
||||
expect($lis.eq(4)).to.contain("{{Table1.selectedRowIndex}}");
|
||||
expect($lis.eq(5)).to.contain("{{Table1.tableData}}");
|
||||
expect($lis.eq(6)).to.contain("{{Table1.pageNo}}");
|
||||
expect($lis.eq(7)).to.contain("{{Table1.pageSize}}");
|
||||
expect($lis.eq(8)).to.contain("{{Table1.isVisible}}");
|
||||
expect($lis.eq(9)).to.contain("{{Table1.searchText}}");
|
||||
expect($lis.eq(10)).to.contain("{{Table1.totalRecordsCount}}");
|
||||
expect($lis.eq(11)).to.contain("{{Table1.sortOrder}}");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ export const entityDefinitions: Record<string, unknown> = {
|
|||
"!url": "https://docs.appsmith.com/widget-reference/table",
|
||||
selectedRow: generateTypeDef(widget.selectedRow),
|
||||
selectedRows: generateTypeDef(widget.selectedRows),
|
||||
selectedRowIndices: generateTypeDef(widget.selectedRowIndices),
|
||||
triggeredRow: generateTypeDef(widget.triggeredRow),
|
||||
selectedRowIndex: "number",
|
||||
tableData: generateTypeDef(widget.tableData),
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const RULES: Record<AutocompleteDataType, Array<string>> = {
|
|||
"CONTAINER_WIDGET.backgroundColor",
|
||||
],
|
||||
OBJECT: ["ACTION.data"],
|
||||
ARRAY: ["ACTION.data"],
|
||||
ARRAY: ["ACTION.data", "TABLE_WIDGET.selectedRowIndices"],
|
||||
BOOLEAN: [
|
||||
"CHECKBOX_WIDGET.isChecked",
|
||||
"SWITCH_WIDGET.isSwitchedOn",
|
||||
|
|
|
|||
|
|
@ -637,7 +637,11 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
|||
// Use the selectedRowIndex if available as default selected index
|
||||
let selectedRowIndices: number[] = [];
|
||||
// Check if selectedRowIndex is valid
|
||||
if (this.props.selectedRowIndex && this.props.selectedRowIndex > -1) {
|
||||
if (
|
||||
this.props.selectedRowIndex !== undefined &&
|
||||
this.props.selectedRowIndex > -1 &&
|
||||
!Array.isArray(this.props.selectedRowIndex)
|
||||
) {
|
||||
selectedRowIndices = [this.props.selectedRowIndex];
|
||||
}
|
||||
// Else use the defaultSelectedRow if available
|
||||
|
|
@ -649,6 +653,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
|||
? [this.props.defaultSelectedRow]
|
||||
: this.props.defaultSelectedRow;
|
||||
}
|
||||
|
||||
this.props.updateWidgetMetaProperty(
|
||||
"selectedRowIndices",
|
||||
selectedRowIndices,
|
||||
|
|
|
|||
162
app/client/src/widgets/TableWidget/widget/propertyUtils.test.ts
Normal file
162
app/client/src/widgets/TableWidget/widget/propertyUtils.test.ts
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
import { defaultSelectedRowValidation } from "./propertyUtils";
|
||||
import _ from "lodash";
|
||||
|
||||
const tableWProps = {
|
||||
multiRowSelection: false,
|
||||
widgetName: "Table1",
|
||||
defaultPageSize: 0,
|
||||
columnOrder: ["step", "task", "status", "action"],
|
||||
isVisibleDownload: true,
|
||||
dynamicPropertyPathList: [],
|
||||
displayName: "Table",
|
||||
iconSVG: "/static/media/icon.db8a9cbd.svg",
|
||||
topRow: 54,
|
||||
bottomRow: 82,
|
||||
isSortable: true,
|
||||
parentRowSpace: 10,
|
||||
type: "TABLE_WIDGET",
|
||||
defaultSelectedRow: "0",
|
||||
hideCard: false,
|
||||
parentColumnSpace: 25.6875,
|
||||
dynamicTriggerPathList: [],
|
||||
dynamicBindingPathList: [
|
||||
{
|
||||
key: "primaryColumns.step.computedValue",
|
||||
},
|
||||
{
|
||||
key: "primaryColumns.task.computedValue",
|
||||
},
|
||||
{
|
||||
key: "primaryColumns.status.computedValue",
|
||||
},
|
||||
{
|
||||
key: "primaryColumns.action.computedValue",
|
||||
},
|
||||
],
|
||||
leftColumn: 25,
|
||||
primaryColumns: {
|
||||
step: {
|
||||
index: 0,
|
||||
width: 150,
|
||||
id: "step",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "step",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}",
|
||||
},
|
||||
task: {
|
||||
index: 1,
|
||||
width: 150,
|
||||
id: "task",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "task",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}",
|
||||
},
|
||||
status: {
|
||||
index: 2,
|
||||
width: 150,
|
||||
id: "status",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "status",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}",
|
||||
},
|
||||
action: {
|
||||
index: 3,
|
||||
width: 150,
|
||||
id: "action",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "button",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
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.sanitizedTableData.map((currentRow) => ( currentRow.action))}}",
|
||||
},
|
||||
},
|
||||
delimiter: ",",
|
||||
key: "fzi9jh5j7j",
|
||||
derivedColumns: {},
|
||||
rightColumn: 50,
|
||||
textSize: "PARAGRAPH",
|
||||
widgetId: "2tk8bgzwaz",
|
||||
isVisibleFilters: true,
|
||||
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: "",
|
||||
},
|
||||
],
|
||||
isVisible: true,
|
||||
label: "Data",
|
||||
searchKey: "",
|
||||
version: 3,
|
||||
totalRecordsCount: 0,
|
||||
parentId: "0",
|
||||
renderMode: "CANVAS",
|
||||
isLoading: false,
|
||||
horizontalAlignment: "LEFT",
|
||||
isVisibleSearch: true,
|
||||
isVisiblePagination: true,
|
||||
verticalAlignment: "CENTER",
|
||||
columnSizeMap: {
|
||||
task: 245,
|
||||
step: 62,
|
||||
status: 75,
|
||||
},
|
||||
};
|
||||
describe("unit test case for property utils", () => {
|
||||
it("case: check if the defaultSelectedRowValiation returns parsed value as undefined", () => {
|
||||
const value = defaultSelectedRowValidation("", tableWProps as any, _);
|
||||
|
||||
expect(value.isValid).toBeTruthy();
|
||||
expect(value.parsed).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
|
@ -72,6 +72,13 @@ export function defaultSelectedRowValidation(
|
|||
} else {
|
||||
try {
|
||||
const _value: string = value as string;
|
||||
|
||||
if (_value === "") {
|
||||
return {
|
||||
isValid: true,
|
||||
parsed: undefined,
|
||||
};
|
||||
}
|
||||
if (Number.isInteger(parseInt(_value, 10)) && parseInt(_value, 10) > -1)
|
||||
return { isValid: true, parsed: parseInt(_value, 10) };
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user