From 5618f75511be3aa17d25fca56b397b6f907b59fd Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Mon, 6 Feb 2023 21:40:40 -0500 Subject: [PATCH 01/10] edge cases --- packages/iris-grid/src/GotoRow.scss | 2 +- packages/iris-grid/src/GotoRow.tsx | 18 ++++++- packages/iris-grid/src/IrisGrid.tsx | 63 +++++++++++++++++++++---- packages/iris-grid/src/IrisGridUtils.ts | 14 ++++++ 4 files changed, 86 insertions(+), 11 deletions(-) diff --git a/packages/iris-grid/src/GotoRow.scss b/packages/iris-grid/src/GotoRow.scss index 485aceaffb..0cfac268d3 100644 --- a/packages/iris-grid/src/GotoRow.scss +++ b/packages/iris-grid/src/GotoRow.scss @@ -25,7 +25,7 @@ } .goto-row-text { - width: 10ch; + min-width: 10ch; } .goto-row-close { diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index 2454aa0448..a6f097eedd 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -91,6 +91,12 @@ function GotoRow({ e.stopPropagation(); e.preventDefault(); onGotoValueSubmit(); + } else if ( + e.key === 'Backspace' && + (gotoValue === `${Number.POSITIVE_INFINITY}` || + gotoValue === `${Number.NEGATIVE_INFINITY}`) + ) { + onGotoValueInputChanged(''); } }; @@ -126,13 +132,20 @@ function GotoRow({
onGotoValueInputChanged(e.target.value)} + onChange={e => { + if (/^-?[0-9]*\.?[0-9]*e?[0-9]*$/.test(e.target.value)) { + onGotoValueInputChanged(e.target.value); + } else if (e.target.value.toLowerCase() === '-i') { + onGotoValueInputChanged(`${Number.NEGATIVE_INFINITY}`); + } else if (e.target.value.toLowerCase() === 'i') { + onGotoValueInputChanged(`${Number.POSITIVE_INFINITY}`); + } + }} value={gotoValue} />
@@ -202,6 +215,7 @@ function GotoRow({ }} value={gotoValue} > + diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index 0504ea1912..39e5858667 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -2453,6 +2453,29 @@ export class IrisGrid extends Component { this.focusRowInGrid(row); return; } + + let cursorRow; + let cursorColumn; + if (this.grid) { + ({ cursorRow, cursorColumn } = this.grid.state); + } + if (cursorRow != null && cursorColumn != null) { + // if a row is selected + const { model } = this.props; + const { name, type } = model.columns[cursorColumn]; + + const cellValue = model.valueForCell(cursorColumn, cursorRow); + const text = IrisGridUtils.convertValueToText(cellValue, type); + this.setState({ + isGotoShown: !isGotoShown, + gotoRow: `${cursorRow}`, + gotoValue: `${text}`, + gotoValueSelectedColumnName: name, + gotoRowError: '', + gotoValueError: '', + }); + return; + } this.setState({ isGotoShown: !isGotoShown, gotoRow: '', @@ -3219,18 +3242,19 @@ export class IrisGrid extends Component { if (inputString === '') { return; } + const selectedColumn = IrisGridUtils.getColumnByName( + model.columns, + selectedColumnName + ); - const columnIndex = model.getColumnIndexByName(selectedColumnName); - if (columnIndex === undefined) { + if (selectedColumn === undefined) { return; } - const selectedColumn = model.columns[columnIndex]; - let searchFromRow; if (this.grid) { - ({ selectionEndRow: searchFromRow } = this.grid.state); + ({ cursorRow: searchFromRow } = this.grid.state); } if (searchFromRow == null) { @@ -3243,11 +3267,13 @@ export class IrisGrid extends Component { gotoValueSelectedFilter === FilterType.eqIgnoreCase; try { + const { formatter } = model; const columnDataType = TableUtils.getNormalizedType(selectedColumn.type); let rowIndex; switch (columnDataType) { + case TableUtils.dataType.CHAR: case TableUtils.dataType.STRING: { rowIndex = await model.seekRow( isBackwards === true ? searchFromRow - 1 : searchFromRow + 1, @@ -3261,7 +3287,6 @@ export class IrisGrid extends Component { break; } case TableUtils.dataType.DATETIME: { - const { formatter } = model; const [startDate] = DateUtils.parseDateRange( inputString, formatter.timeZone @@ -3298,7 +3323,7 @@ export class IrisGrid extends Component { searchFromRow, selectedColumn, dh.ValueType.STRING, - inputString, + TableUtils.makeNumberValue(inputString), undefined, undefined, isBackwards ?? false @@ -3311,7 +3336,11 @@ export class IrisGrid extends Component { searchFromRow, selectedColumn, dh.ValueType.STRING, - inputString, + TableUtils.makeValue( + selectedColumn.type, + inputString, + formatter.timeZone + ), undefined, undefined, isBackwards ?? false @@ -3322,6 +3351,7 @@ export class IrisGrid extends Component { this.grid?.setFocusRow(rowIndex); this.setState({ gotoValueError: '' }); } catch (e: unknown) { + console.error(e); this.setState({ gotoValueError: 'invalid input' }); } } @@ -3635,6 +3665,23 @@ export class IrisGrid extends Component { } handleGotoValueSelectedColumnNameChanged(columnName: ColumnName): void { + const { model } = this.props; + let cursorRow; + if (this.grid) { + ({ cursorRow } = this.grid.state); + } + if (cursorRow != null) { + const index = model.getColumnIndexByName(columnName); + const column = IrisGridUtils.getColumnByName(model.columns, columnName); + assertNotNull(index); + const value = model.valueForCell(index, cursorRow); + const text = IrisGridUtils.convertValueToText(value, column?.type); + this.setState({ + gotoValueSelectedColumnName: columnName, + gotoValue: `${text}`, + gotoValueError: '', + }); + } this.setState({ gotoValueSelectedColumnName: columnName, gotoValueError: '', diff --git a/packages/iris-grid/src/IrisGridUtils.ts b/packages/iris-grid/src/IrisGridUtils.ts index a270751725..7ebd91c2c6 100644 --- a/packages/iris-grid/src/IrisGridUtils.ts +++ b/packages/iris-grid/src/IrisGridUtils.ts @@ -1671,6 +1671,20 @@ class IrisGridUtils { return { groups: [...groupMap.values()], maxDepth, groupMap, parentMap }; } + + static convertValueToText(value: unknown, columnName?: string): unknown { + if ( + columnName != null && + TableUtils.isCharType(columnName) && + value != null + ) { + return String.fromCharCode(parseInt(value as string, 10)); + } + if (value == null) { + return ''; + } + return value; + } } export default IrisGridUtils; From 89d68e77eddc1a1aea53529eef7242a02efa62ef Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Mon, 6 Feb 2023 23:32:50 -0500 Subject: [PATCH 02/10] removed log statement --- packages/iris-grid/src/IrisGrid.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index 39e5858667..77ded27dd7 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -3351,7 +3351,6 @@ export class IrisGrid extends Component { this.grid?.setFocusRow(rowIndex); this.setState({ gotoValueError: '' }); } catch (e: unknown) { - console.error(e); this.setState({ gotoValueError: 'invalid input' }); } } From 5abe84a15435d6cb9805f2c010f2509e44737a99 Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Tue, 7 Feb 2023 17:04:37 -0500 Subject: [PATCH 03/10] fixed char and infinity --- packages/iris-grid/src/GotoRow.tsx | 7 ++++--- packages/iris-grid/src/IrisGrid.tsx | 12 ++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index a6f097eedd..b5c52d2373 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -138,11 +138,12 @@ function GotoRow({ onKeyDown={handleGotoValueKeyDown} placeholder="value" onChange={e => { - if (/^-?[0-9]*\.?[0-9]*e?[0-9]*$/.test(e.target.value)) { + const value = e.target.value.toLowerCase(); + if (/^-?[0-9]*\.?[0-9]*$/.test(e.target.value)) { onGotoValueInputChanged(e.target.value); - } else if (e.target.value.toLowerCase() === '-i') { + } else if (value === '-i' || value === '-infinity') { onGotoValueInputChanged(`${Number.NEGATIVE_INFINITY}`); - } else if (e.target.value.toLowerCase() === 'i') { + } else if (value === 'i' || value === 'infinity') { onGotoValueInputChanged(`${Number.POSITIVE_INFINITY}`); } }} diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index 77ded27dd7..e147c8d6be 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -69,6 +69,7 @@ import dh, { Sort, Table, TableViewportSubscription, + ValueTypeUnion, } from '@deephaven/jsapi-shim'; import { DateUtils, @@ -3308,7 +3309,13 @@ export class IrisGrid extends Component { !TableUtils.isBigDecimalType(selectedColumn.type) && !TableUtils.isBigIntegerType(selectedColumn.type) ) { - const inputValue = parseInt(inputString, 10); + let inputValue = parseInt(inputString, 10); + if (inputString === '-Infinity') { + inputValue = Number.NEGATIVE_INFINITY; + } else if (inputString === 'Infinity') { + inputValue = Number.POSITIVE_INFINITY; + } + rowIndex = await model.seekRow( searchFromRow, selectedColumn, @@ -3323,7 +3330,7 @@ export class IrisGrid extends Component { searchFromRow, selectedColumn, dh.ValueType.STRING, - TableUtils.makeNumberValue(inputString), + inputString, undefined, undefined, isBackwards ?? false @@ -3351,6 +3358,7 @@ export class IrisGrid extends Component { this.grid?.setFocusRow(rowIndex); this.setState({ gotoValueError: '' }); } catch (e: unknown) { + console.log(e); this.setState({ gotoValueError: 'invalid input' }); } } From 306e131b141678a74817a08e2271e14c48f9c42a Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Tue, 7 Feb 2023 17:11:09 -0500 Subject: [PATCH 04/10] removed extraneous imports and logs --- packages/iris-grid/src/IrisGrid.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index e147c8d6be..ebbdc09668 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -69,7 +69,6 @@ import dh, { Sort, Table, TableViewportSubscription, - ValueTypeUnion, } from '@deephaven/jsapi-shim'; import { DateUtils, @@ -3358,7 +3357,6 @@ export class IrisGrid extends Component { this.grid?.setFocusRow(rowIndex); this.setState({ gotoValueError: '' }); } catch (e: unknown) { - console.log(e); this.setState({ gotoValueError: 'invalid input' }); } } From 0997c14cac8f4890acf6b21aaad91f7ac561d5e3 Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Fri, 10 Feb 2023 15:13:12 -0500 Subject: [PATCH 05/10] added tests --- packages/iris-grid/src/IrisGrid.tsx | 10 ++++------ packages/iris-grid/src/IrisGridUtils.test.ts | 15 +++++++++++++++ packages/iris-grid/src/IrisGridUtils.ts | 16 +++++++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index ebbdc09668..540d4018b3 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -2469,7 +2469,7 @@ export class IrisGrid extends Component { this.setState({ isGotoShown: !isGotoShown, gotoRow: `${cursorRow}`, - gotoValue: `${text}`, + gotoValue: text, gotoValueSelectedColumnName: name, gotoRowError: '', gotoValueError: '', @@ -3671,10 +3671,8 @@ export class IrisGrid extends Component { handleGotoValueSelectedColumnNameChanged(columnName: ColumnName): void { const { model } = this.props; - let cursorRow; - if (this.grid) { - ({ cursorRow } = this.grid.state); - } + const cursorRow = this.grid?.state.cursorRow; + if (cursorRow != null) { const index = model.getColumnIndexByName(columnName); const column = IrisGridUtils.getColumnByName(model.columns, columnName); @@ -3683,7 +3681,7 @@ export class IrisGrid extends Component { const text = IrisGridUtils.convertValueToText(value, column?.type); this.setState({ gotoValueSelectedColumnName: columnName, - gotoValue: `${text}`, + gotoValue: text, gotoValueError: '', }); } diff --git a/packages/iris-grid/src/IrisGridUtils.test.ts b/packages/iris-grid/src/IrisGridUtils.test.ts index a5b7b0ea89..e7962e576e 100644 --- a/packages/iris-grid/src/IrisGridUtils.test.ts +++ b/packages/iris-grid/src/IrisGridUtils.test.ts @@ -572,3 +572,18 @@ describe('combineFiltersFromList', () => { ); }); }); + +describe('convert value to text', () => { + it('converts null to empty string', () => { + expect(IrisGridUtils.convertValueToText(null, 'string')).toEqual(''); + }); + it('converts ascii to char on char column', () => { + expect(IrisGridUtils.convertValueToText('65', 'char')).toEqual('A'); + }); + it('converts null to empty char on char column', () => { + expect(IrisGridUtils.convertValueToText(null, 'char')).toEqual(''); + }); + it('converts number to string on number column', () => { + expect(IrisGridUtils.convertValueToText(123, 'number')).toEqual('123'); + }); +}); diff --git a/packages/iris-grid/src/IrisGridUtils.ts b/packages/iris-grid/src/IrisGridUtils.ts index 7ebd91c2c6..6a52621504 100644 --- a/packages/iris-grid/src/IrisGridUtils.ts +++ b/packages/iris-grid/src/IrisGridUtils.ts @@ -1672,18 +1672,24 @@ class IrisGridUtils { return { groups: [...groupMap.values()], maxDepth, groupMap, parentMap }; } - static convertValueToText(value: unknown, columnName?: string): unknown { + /** + * @param value The value of the cell in a column + * @param columnType The type of the column + * @returns The value of the cell converted to text + */ + static convertValueToText(value: unknown, columnType?: string): string { if ( - columnName != null && - TableUtils.isCharType(columnName) && - value != null + columnType != null && + TableUtils.isCharType(columnType) && + value != null && + !Number.isNaN(parseInt(value as string, 10)) ) { return String.fromCharCode(parseInt(value as string, 10)); } if (value == null) { return ''; } - return value; + return `${value}`; } } From 7eda219fc0999052b89584f07297fcdb161bee0c Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Fri, 10 Feb 2023 15:32:53 -0500 Subject: [PATCH 06/10] added support for delete --- packages/iris-grid/src/GotoRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index b5c52d2373..a26ed331e3 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -92,7 +92,7 @@ function GotoRow({ e.preventDefault(); onGotoValueSubmit(); } else if ( - e.key === 'Backspace' && + (e.key === 'Backspace' || e.key === 'Delete') && (gotoValue === `${Number.POSITIVE_INFINITY}` || gotoValue === `${Number.NEGATIVE_INFINITY}`) ) { From 1557a3597e807467fc5dccb84007f23d5ee3da09 Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Thu, 23 Feb 2023 11:16:48 -0500 Subject: [PATCH 07/10] a --- packages/iris-grid/src/GotoRow.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index a26ed331e3..a5023f49c6 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -102,8 +102,7 @@ function GotoRow({ const index = model.getColumnIndexByName(gotoValueSelectedColumnName); - assertNotNull(index); - const selectedColumn = columns[index]; + const selectedColumn = columns[index ?? 0]; const columnType = selectedColumn?.type; From b6c63ef890c4a52c99d678658816550211ed1dbf Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Thu, 23 Feb 2023 11:17:06 -0500 Subject: [PATCH 08/10] b --- packages/iris-grid/src/GotoRow.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index a5023f49c6..a195f4a3a0 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -15,7 +15,6 @@ import { } from '@deephaven/filters'; import { Button, DateTimeInput } from '@deephaven/components'; import { TableUtils } from '@deephaven/jsapi-utils'; -import { assertNotNull } from '@deephaven/utils'; import classNames from 'classnames'; import './GotoRow.scss'; import IrisGridModel from './IrisGridModel'; From 44bc342694a934632c9dd02e4fcac66634a39338 Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Wed, 1 Mar 2023 12:39:47 -0500 Subject: [PATCH 09/10] fixed date time column --- packages/iris-grid/src/GotoRow.tsx | 15 ++++++- packages/iris-grid/src/IrisGrid.tsx | 43 +++++++++---------- packages/iris-grid/src/IrisGridUtils.test.ts | 44 +++++++++++++++++--- packages/iris-grid/src/IrisGridUtils.ts | 16 +++++-- 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/packages/iris-grid/src/GotoRow.tsx b/packages/iris-grid/src/GotoRow.tsx index a195f4a3a0..9ea5e63b4b 100644 --- a/packages/iris-grid/src/GotoRow.tsx +++ b/packages/iris-grid/src/GotoRow.tsx @@ -85,7 +85,8 @@ function GotoRow({ const res = 'Row number'; const { rowCount } = model; - const handleGotoValueKeyDown = (e: KeyboardEvent) => { + + const handleGotoValueNumberKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { e.stopPropagation(); e.preventDefault(); @@ -99,6 +100,14 @@ function GotoRow({ } }; + const handleGotoValueKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Enter') { + e.stopPropagation(); + e.preventDefault(); + onGotoValueSubmit(); + } + }; + const index = model.getColumnIndexByName(gotoValueSelectedColumnName); const selectedColumn = columns[index ?? 0]; @@ -133,10 +142,11 @@ function GotoRow({ className={classNames('form-control', { 'is-invalid': gotoValueError !== '', })} - onKeyDown={handleGotoValueKeyDown} + onKeyDown={handleGotoValueNumberKeyDown} placeholder="value" onChange={e => { const value = e.target.value.toLowerCase(); + // regex tests for if (/^-?[0-9]*\.?[0-9]*$/.test(e.target.value)) { onGotoValueInputChanged(e.target.value); } else if (value === '-i' || value === '-infinity') { @@ -160,6 +170,7 @@ function GotoRow({ 'is-invalid': gotoValueError !== '', } )} + defaultValue={gotoValue} onChange={onGotoValueInputChanged} /> diff --git a/packages/iris-grid/src/IrisGrid.tsx b/packages/iris-grid/src/IrisGrid.tsx index 540d4018b3..569334bf19 100644 --- a/packages/iris-grid/src/IrisGrid.tsx +++ b/packages/iris-grid/src/IrisGrid.tsx @@ -2454,32 +2454,31 @@ export class IrisGrid extends Component { return; } - let cursorRow; - let cursorColumn; - if (this.grid) { - ({ cursorRow, cursorColumn } = this.grid.state); - } - if (cursorRow != null && cursorColumn != null) { - // if a row is selected - const { model } = this.props; - const { name, type } = model.columns[cursorColumn]; + const cursorRow = this.grid?.state.cursorRow; + const cursorColumn = this.grid?.state.cursorColumn; - const cellValue = model.valueForCell(cursorColumn, cursorRow); - const text = IrisGridUtils.convertValueToText(cellValue, type); + if (cursorRow == null || cursorColumn == null) { + // if a cell is not selected / grid is not rendered this.setState({ isGotoShown: !isGotoShown, - gotoRow: `${cursorRow}`, - gotoValue: text, - gotoValueSelectedColumnName: name, + gotoRow: '', + gotoValue: '', gotoRowError: '', gotoValueError: '', }); return; } + // if a row is selected + const { model } = this.props; + const { name, type } = model.columns[cursorColumn]; + + const cellValue = model.valueForCell(cursorColumn, cursorRow); + const text = IrisGridUtils.convertValueToText(cellValue, type); this.setState({ isGotoShown: !isGotoShown, - gotoRow: '', - gotoValue: '', + gotoRow: `${cursorRow}`, + gotoValue: text, + gotoValueSelectedColumnName: name, gotoRowError: '', gotoValueError: '', }); @@ -3251,11 +3250,7 @@ export class IrisGrid extends Component { return; } - let searchFromRow; - - if (this.grid) { - ({ cursorRow: searchFromRow } = this.grid.state); - } + let searchFromRow = this.grid?.state.cursorRow; if (searchFromRow == null) { searchFromRow = 0; @@ -3676,9 +3671,11 @@ export class IrisGrid extends Component { if (cursorRow != null) { const index = model.getColumnIndexByName(columnName); const column = IrisGridUtils.getColumnByName(model.columns, columnName); - assertNotNull(index); + if (index == null || column == null) { + return; + } const value = model.valueForCell(index, cursorRow); - const text = IrisGridUtils.convertValueToText(value, column?.type); + const text = IrisGridUtils.convertValueToText(value, column.type); this.setState({ gotoValueSelectedColumnName: columnName, gotoValue: text, diff --git a/packages/iris-grid/src/IrisGridUtils.test.ts b/packages/iris-grid/src/IrisGridUtils.test.ts index e7962e576e..08c232ea10 100644 --- a/packages/iris-grid/src/IrisGridUtils.test.ts +++ b/packages/iris-grid/src/IrisGridUtils.test.ts @@ -1,6 +1,7 @@ import { GridUtils, GridRange, MoveOperation } from '@deephaven/grid'; import dh, { Column, Table, Sort } from '@deephaven/jsapi-shim'; import { TypeValue as FilterTypeValue } from '@deephaven/filters'; +import { DateUtils } from '@deephaven/jsapi-utils'; import type { AdvancedFilter } from './CommonTypes'; import { FilterData } from './IrisGrid'; import IrisGridTestUtils from './IrisGridTestUtils'; @@ -573,17 +574,50 @@ describe('combineFiltersFromList', () => { }); }); -describe('convert value to text', () => { +describe('convert string to text', () => { it('converts null to empty string', () => { expect(IrisGridUtils.convertValueToText(null, 'string')).toEqual(''); }); - it('converts ascii to char on char column', () => { - expect(IrisGridUtils.convertValueToText('65', 'char')).toEqual('A'); + it('converts empty string', () => { + expect(IrisGridUtils.convertValueToText('', 'string')).toEqual(''); }); - it('converts null to empty char on char column', () => { + it('converts string to stri', () => { + expect(IrisGridUtils.convertValueToText('test', 'string')).toEqual('test'); + }); + it('converts length 1 string to stri', () => { + expect(IrisGridUtils.convertValueToText('t', 'string')).toEqual('t'); + }); + it('converts number to strin', () => { + expect(IrisGridUtils.convertValueToText(65, 'string')).toEqual('65'); + }); +}); + +describe('convert char to text', () => { + it('converts number to ascii', () => { + expect(IrisGridUtils.convertValueToText(65, 'char')).toEqual('A'); + }); + it('converts null to empty char', () => { expect(IrisGridUtils.convertValueToText(null, 'char')).toEqual(''); }); +}); + +describe('convert other column types to text', () => { it('converts number to string on number column', () => { - expect(IrisGridUtils.convertValueToText(123, 'number')).toEqual('123'); + expect(IrisGridUtils.convertValueToText(65, 'number')).toEqual('65'); + }); + it('converts null to empty string on number column', () => { + expect(IrisGridUtils.convertValueToText(null, 'number')).toEqual(''); + }); + it('converts null to empty string on number column', () => { + expect( + IrisGridUtils.convertValueToText( + dh.i18n.DateTimeFormat.parse( + DateUtils.FULL_DATE_FORMAT, + '2022-02-03 02:14:59.000000000', + dh.i18n.TimeZone.getTimeZone('NY') + ), + 'datetime' + ) + ).toEqual(1643872499000); }); }); diff --git a/packages/iris-grid/src/IrisGridUtils.ts b/packages/iris-grid/src/IrisGridUtils.ts index 6a52621504..16e6c47ef7 100644 --- a/packages/iris-grid/src/IrisGridUtils.ts +++ b/packages/iris-grid/src/IrisGridUtils.ts @@ -126,6 +126,10 @@ function isValidIndex(x: number, array: unknown[]): boolean { return x >= 0 && x < array.length; } +function isDateWrapper(value: unknown): value is DateWrapper { + return (value as DateWrapper).asDate != null; +} + class IrisGridUtils { /** * Exports the state from Grid component to a JSON stringifiable object @@ -1677,14 +1681,20 @@ class IrisGridUtils { * @param columnType The type of the column * @returns The value of the cell converted to text */ - static convertValueToText(value: unknown, columnType?: string): string { + static convertValueToText(value: unknown, columnType: string): string { if ( columnType != null && TableUtils.isCharType(columnType) && value != null && - !Number.isNaN(parseInt(value as string, 10)) + typeof value === 'number' ) { - return String.fromCharCode(parseInt(value as string, 10)); + return String.fromCharCode(value); + } + if (TableUtils.isDateType(columnType) && isDateWrapper(value)) { + const date = new Date(value.asDate()); + const dateText = date.toISOString(); + const formattedText = dateText.replace(/[A-Z]/g, ' '); + return formattedText; } if (value == null) { return ''; From d9c3bff5ec2c8799131b1f6bcb82061f8acec18a Mon Sep 17 00:00:00 2001 From: Tony Zhou Date: Wed, 1 Mar 2023 16:40:04 -0500 Subject: [PATCH 10/10] added datetime tests --- packages/iris-grid/src/IrisGridUtils.test.ts | 6 +++--- packages/iris-grid/src/IrisGridUtils.ts | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/iris-grid/src/IrisGridUtils.test.ts b/packages/iris-grid/src/IrisGridUtils.test.ts index 08c232ea10..d121846d3c 100644 --- a/packages/iris-grid/src/IrisGridUtils.test.ts +++ b/packages/iris-grid/src/IrisGridUtils.test.ts @@ -608,7 +608,7 @@ describe('convert other column types to text', () => { it('converts null to empty string on number column', () => { expect(IrisGridUtils.convertValueToText(null, 'number')).toEqual(''); }); - it('converts null to empty string on number column', () => { + it('converts time correctly on datetime column', () => { expect( IrisGridUtils.convertValueToText( dh.i18n.DateTimeFormat.parse( @@ -616,8 +616,8 @@ describe('convert other column types to text', () => { '2022-02-03 02:14:59.000000000', dh.i18n.TimeZone.getTimeZone('NY') ), - 'datetime' + 'io.deephaven.time.DateTime' ) - ).toEqual(1643872499000); + ).toEqual('2022-02-03 02:14:59.000'); }); }); diff --git a/packages/iris-grid/src/IrisGridUtils.ts b/packages/iris-grid/src/IrisGridUtils.ts index 16e6c47ef7..82e9fed0d4 100644 --- a/packages/iris-grid/src/IrisGridUtils.ts +++ b/packages/iris-grid/src/IrisGridUtils.ts @@ -1692,8 +1692,10 @@ class IrisGridUtils { } if (TableUtils.isDateType(columnType) && isDateWrapper(value)) { const date = new Date(value.asDate()); - const dateText = date.toISOString(); - const formattedText = dateText.replace(/[A-Z]/g, ' '); + const offset = date.getTimezoneOffset(); + const offsetDate = new Date(date.getTime() - offset * 60 * 1000); + const dateText = offsetDate.toISOString(); + const formattedText = dateText.replace('T', ' ').substring(0, 23); return formattedText; } if (value == null) {