多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.0 KiB

Nc feat/type conversions rebased (#8680) * feat: created inferTypes.ts * chore: switch to sdk types * feat: convert string to given type * feat: convert string to rating * fix: handle the case with multiple . * feat: numeric decimal type conversion in postgres * feat: add cast for non text fields * refactor: move type casts to separate file * feat: add casts for date, date-time and time * doc: added function docs * feat: added cast for year and rating * feat: added cast for duration * fix: cast for multi-select * fix: cast for multi-select * fix: cast for year * feat: date conversion on best effort basis * fix: single line text to select * fix: any field to select * lint: simplified expressions * fix: user conversion * fix: user conversion * fix: date time conversion * test: added test cases for type casts * fix: SLT to User field * fix: SLT to Long text, single select and multiselect * chore: handle True/False & TRUE/FALSE in checkbox * lint: fixed eslint issues * chore: remove system fields as destination type when converting a field * feat: show warning when changing column type * fix: toned down edit modal * test: click on update button during warning popup * test: update selector * test: fix type change flag * fix: handle date format * chore: auto focus update button * fix: parameterize columnName and other values * chore: removed number of digits limit for hour * test: fix add-edit modal label * fix: fixed missing column reference * fix: handle missing date format * fix: handle missing date format * test: fix save routine mux * test: fix barCode & QRCode save * refactor: combined uiType filters * fix: sanitise column name * refactor: switch to some instead of find * feat: created inferTypes.ts * chore: switch to sdk types * feat: convert string to given type * feat: numeric decimal type conversion in postgres * feat: add cast for non text fields * refactor: move type casts to separate file * feat: add casts for date, date-time and time * doc: added function docs * feat: added cast for year and rating * feat: added cast for duration * fix: cast for multi-select * fix: cast for multi-select * fix: cast for year * feat: date conversion on best effort basis * fix: single line text to select * fix: user conversion * fix: date time conversion * fix: SLT to User field * fix: SLT to Long text, single select and multiselect * chore: handle True/False & TRUE/FALSE in checkbox * lint: fixed eslint issues * feat: show warning when changing column type * fix: toned down edit modal * test: click on update button during warning popup * fix: handle date format * chore: auto focus update button * fix: parameterize columnName and other values * chore: removed number of digits limit for hour * fix: handle missing date format * fix: handle missing date format * test: fix save routine mux * fix: revert removing verify * fix: sanitise column name * fix: pass context * tests: remove duplicate statement * fix: add context bypass for list method * fix: disable type conversion for Formula, BarCode, QrCode * fix: render confirm modal sing useDialog to avoid accidental closing * refactor: construct context using column while getting colOptions data --------- Co-authored-by: rohittp <tprohit9@gmail.com> Co-authored-by: Pranav C <pranavxc@gmail.com>
3 months ago
import { UITypes } from 'nocodb-sdk'
import { getCheckboxValue } from './parsers/parserHelpers'
/*
* @param {string} str - string with numbers
* @returns {number} - number extracted from string
*
* @example abc123 -> 123
* @example 12.3abc -> 12.3
* @example 12.3.2 -> 12.32
*/
function extractNumbers(str: string): number {
const parts = str.replace(/[^\d.]/g, '').split('.')
if (parts.length > 1) parts[0] += '.'
return parseFloat(parts.join(''))
}
/*
* @param {string} value - string value of duration
* @returns {number} - duration in seconds
*
* @example 1:30:00 -> 5400
* @example 1:30 -> 5400
* @example 90 -> 90
*/
function toDuration(value: string) {
if (value.includes(':')) {
const [hours, minutes, seconds] = value.split(':').map((v) => parseInt(v) || 0)
return hours * 3600 + minutes * 60 + seconds
}
return Math.floor(extractNumbers(value))
}
/*
* @param {string} value - string value to convert
* @param {string} type - type of the field to convert to
* @returns {number|string|boolean|array} - converted value
*
* @example convert('12.3', 'Number') -> 12
* @example convert('1a23', 'SingleLineText') -> '1a23'
* @example convert('1', 'Checkbox') -> true
*/
export function convert(value: string, type: string, limit = 100): unknown {
switch (type) {
case UITypes.SingleLineText:
case UITypes.SingleSelect:
case UITypes.LongText:
case UITypes.Email:
case UITypes.URL:
return value
case UITypes.Number:
return Math.floor(extractNumbers(value))
case UITypes.Decimal:
case UITypes.Currency:
return extractNumbers(value)
case UITypes.Percent:
case UITypes.Rating:
return Math.min(limit, Math.max(0, extractNumbers(value)))
case UITypes.Checkbox:
return getCheckboxValue(value)
case UITypes.Date:
case UITypes.DateTime:
case UITypes.Time:
return new Date(value)
case UITypes.Duration:
return toDuration(value)
case UITypes.MultiSelect:
return value.split(',').map((v) => v.trim())
}
}