多维表格
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.

226 lines
5.9 KiB

feat: infinite scroll (#9403) * feat: infinite scroll wip * feat: implement column create * feat: improve scroll performance and minor bugs * fix: optimize cache clear fix: preserver selected items from cache clear * feat: add keyboard support * fix: get rid of unwanted data * feat: infinite scroll * fix: reload visible data * fix: rowIndex Sync * fix: row height fix * fix: performance issues * fix: small issues * fix: stablize scrolling * fix: scroll fails to load new data * fix: best part is no part remove bunch of manual handling and move to computedProperty * fix: load data as chunks instead of offset * fix: deboucne 500 ms * feat: safe chunk clearing * feat: working infinite table(wip) * fix: handle delete selected range of rows * fix: update types * fix: nuxt warnings * fix: table fixes * feat: undo-redo support for infiniteTable * fix: fix addEmptyRow * fix: groupby fixes * fix: refactor visibleDtaa computed * fix: cache clear * fix: invalid offset error * fix: add empty row elem * fix: rows not loading at end * fix: refactor * fix: more tests passing * fix: perf optimizations * fix: couple tests * fix: row height tests * fix: row height tests * fix: row height tests * fix: sync row comment count * fix: fixes * fix: lot of tests * fix: update the row placeholder columns size calculation * fix: update the totalRows on loadData * fix: tests when count is 0 * fix: hide placeholder if rowHeight is small * fix: not required imo as infinite scroll is implemented * fix: links tests * fix: filter tests * fix: insert after test fix: Row: Create, Update, Delete fix: Row height fix: Create column tests * fix: error, timezone bug fix: shared view data not loading after 100 * fix: ignore shifting. this fixes errors in rows, which has some mandatory required cells * fix: keyboardShortcuts test * fix: project collaboration test * fix: increase local cache fix: records empty on switching to full screen mode fix: links issue on new records * fix: row and col margin for improved data rendering * fix: addEmptyRow to table bottom * fix: update gridShare test fix: shared view grid feat: new count endpoint public * fix: undo-redo test failing * fix: bulkUpdate chore: disabled bulkUpdate tests for now * fix: slow searchBtn * fix: limit max selection * fix: limit selection to 100 * fix: initial chunk load to 100 * fix: couple fixes * fix: couple fixes * fix: row expand * fix: scrollto Top and scrollTo Bottom on Shift Cmd Down/Up * fix: drop support for cmd A * fix: failing tests * fix: error on clicking resize col * fix: premature fetching * fix: deleteSelected not working properly * fix: test build * fix: test build * fix: throttled 500 * fix: scroll related issues fix: added transitions * fix: scroll related issues * fix: decrease col margin * fix: increase local cache and update Buffer * fix: decrease throttle * fix: improve scroll performance * fix: improve scroll performance * fix: improve scroll performance * fix: fixes * feat: beta toggle show * feat: beta toggle show * fix: hold scroll action * fix: sync visible data reloadVisibleDataHook * fix: refactor useBetaFeatureToggle fix: useMultiSelect in table * fix: dynamically reduce margin while loading records * fix: some bugs * fix: data loading in infinitescroll * fix: shared view and search issues * feat: betaToggles menu * fix: scroll showing up in aggregation * fix: text * fix: implement shifting in addEmptyRow * fix: calculate slices on rowHeight modified * fix: keep invalid cells until another row selected * fix: remove row if filter gets failed * fix: update styles * fix: move filter handling to nocodb-sdk * fix: user field filter * fix: sort order * fix:user field sorting * fix: update virtual cols * fix: updated sort handling * fix: updated sort handling * fix: updated sort handling for bulkUpdate and undo-redo * fix: unit tests * fix: deleteSelectedRecords fails * fix: chunkstates errors * fix: sort bugs * fix: scroll position * fix: delete selectedrange of records * fix: improved chunk management * fix: sync toggle states across tabs * fix: sync between tabs * fix: limit issues * fix: update issues * fix: zIndex * fix: minor fixes * fix: cmd arrow issue * fix: bulkdelete index issues * fix: empty rows at top * fix: queue add new record behaviour * fix: resolve rowObj addEmptyRow * fix: typo * fix: clear indexes * fix: reload if width is zero * fix: manual handling * fix: remove console * fix: prefetch when scroll from below * fix: refactor fixes * fix:undo-redo with sort --------- Co-authored-by: mertmit <mertmit99@gmail.com>
3 weeks ago
import { type ColumnType, type SortType, UITypes } from 'nocodb-sdk'
import dayjs from 'dayjs'
export const getSortDirectionOptions = (uidt: UITypes | string, isGroupBy?: boolean) => {
const groupByOptions = isGroupBy
? [
{ text: 'Count (9 → 1)', value: 'count-desc' },
{ text: 'Count (1 → 9)', value: 'count-asc' },
]
: []
switch (uidt) {
case UITypes.Year:
case UITypes.Number:
case UITypes.Decimal:
case UITypes.Rating:
case UITypes.Count:
case UITypes.AutoNumber:
case UITypes.Time:
case UITypes.Currency:
case UITypes.Percent:
case UITypes.Duration:
case UITypes.PhoneNumber:
case UITypes.Date:
case UITypes.DateTime:
case UITypes.CreatedTime:
case UITypes.LastModifiedTime:
return [
{ text: '1 → 9', value: 'asc' },
{ text: '9 → 1', value: 'desc' },
].concat(groupByOptions)
case UITypes.Checkbox:
return [
{ text: '▢ → ✓', value: 'asc' },
{ text: '✓ → ▢', value: 'desc' },
].concat(groupByOptions)
default:
return [
{ text: 'A → Z', value: 'asc' },
{ text: 'Z → A', value: 'desc' },
].concat(groupByOptions)
}
}
feat: infinite scroll (#9403) * feat: infinite scroll wip * feat: implement column create * feat: improve scroll performance and minor bugs * fix: optimize cache clear fix: preserver selected items from cache clear * feat: add keyboard support * fix: get rid of unwanted data * feat: infinite scroll * fix: reload visible data * fix: rowIndex Sync * fix: row height fix * fix: performance issues * fix: small issues * fix: stablize scrolling * fix: scroll fails to load new data * fix: best part is no part remove bunch of manual handling and move to computedProperty * fix: load data as chunks instead of offset * fix: deboucne 500 ms * feat: safe chunk clearing * feat: working infinite table(wip) * fix: handle delete selected range of rows * fix: update types * fix: nuxt warnings * fix: table fixes * feat: undo-redo support for infiniteTable * fix: fix addEmptyRow * fix: groupby fixes * fix: refactor visibleDtaa computed * fix: cache clear * fix: invalid offset error * fix: add empty row elem * fix: rows not loading at end * fix: refactor * fix: more tests passing * fix: perf optimizations * fix: couple tests * fix: row height tests * fix: row height tests * fix: row height tests * fix: sync row comment count * fix: fixes * fix: lot of tests * fix: update the row placeholder columns size calculation * fix: update the totalRows on loadData * fix: tests when count is 0 * fix: hide placeholder if rowHeight is small * fix: not required imo as infinite scroll is implemented * fix: links tests * fix: filter tests * fix: insert after test fix: Row: Create, Update, Delete fix: Row height fix: Create column tests * fix: error, timezone bug fix: shared view data not loading after 100 * fix: ignore shifting. this fixes errors in rows, which has some mandatory required cells * fix: keyboardShortcuts test * fix: project collaboration test * fix: increase local cache fix: records empty on switching to full screen mode fix: links issue on new records * fix: row and col margin for improved data rendering * fix: addEmptyRow to table bottom * fix: update gridShare test fix: shared view grid feat: new count endpoint public * fix: undo-redo test failing * fix: bulkUpdate chore: disabled bulkUpdate tests for now * fix: slow searchBtn * fix: limit max selection * fix: limit selection to 100 * fix: initial chunk load to 100 * fix: couple fixes * fix: couple fixes * fix: row expand * fix: scrollto Top and scrollTo Bottom on Shift Cmd Down/Up * fix: drop support for cmd A * fix: failing tests * fix: error on clicking resize col * fix: premature fetching * fix: deleteSelected not working properly * fix: test build * fix: test build * fix: throttled 500 * fix: scroll related issues fix: added transitions * fix: scroll related issues * fix: decrease col margin * fix: increase local cache and update Buffer * fix: decrease throttle * fix: improve scroll performance * fix: improve scroll performance * fix: improve scroll performance * fix: fixes * feat: beta toggle show * feat: beta toggle show * fix: hold scroll action * fix: sync visible data reloadVisibleDataHook * fix: refactor useBetaFeatureToggle fix: useMultiSelect in table * fix: dynamically reduce margin while loading records * fix: some bugs * fix: data loading in infinitescroll * fix: shared view and search issues * feat: betaToggles menu * fix: scroll showing up in aggregation * fix: text * fix: implement shifting in addEmptyRow * fix: calculate slices on rowHeight modified * fix: keep invalid cells until another row selected * fix: remove row if filter gets failed * fix: update styles * fix: move filter handling to nocodb-sdk * fix: user field filter * fix: sort order * fix:user field sorting * fix: update virtual cols * fix: updated sort handling * fix: updated sort handling * fix: updated sort handling for bulkUpdate and undo-redo * fix: unit tests * fix: deleteSelectedRecords fails * fix: chunkstates errors * fix: sort bugs * fix: scroll position * fix: delete selectedrange of records * fix: improved chunk management * fix: sync toggle states across tabs * fix: sync between tabs * fix: limit issues * fix: update issues * fix: zIndex * fix: minor fixes * fix: cmd arrow issue * fix: bulkdelete index issues * fix: empty rows at top * fix: queue add new record behaviour * fix: resolve rowObj addEmptyRow * fix: typo * fix: clear indexes * fix: reload if width is zero * fix: manual handling * fix: remove console * fix: prefetch when scroll from below * fix: refactor fixes * fix:undo-redo with sort --------- Co-authored-by: mertmit <mertmit99@gmail.com>
3 weeks ago
export const sortByUIType = ({
uidt,
a,
b,
options: { caseSensitive = true, direction },
}: {
uidt: UITypes
a: any
b: any
options: {
caseSensitive?: boolean
direction?: 'asc' | 'desc' | 'count-asc' | 'count-desc'
}
}) => {
let nullsLast = direction !== 'asc'
if ([UITypes.Formula, UITypes.User].includes(uidt)) {
nullsLast = !nullsLast
}
if (a === null || a === undefined) {
return nullsLast ? 1 : -1
}
if (b === null || b === undefined) {
return nullsLast ? -1 : 1
}
if (a === '' && b !== '') return nullsLast ? 1 : -1
if (b === '' && a !== '') return nullsLast ? -1 : 1
let result = 0
switch (uidt) {
case UITypes.Number:
case UITypes.Decimal:
case UITypes.Currency:
case UITypes.Percent:
case UITypes.Rating:
case UITypes.Duration:
case UITypes.ID:
case UITypes.Rollup:
result = Number(a) - Number(b)
break
case UITypes.Links: {
const getLinksValue = (links: any) => {
if (links === null) return null
if (typeof links === 'number') return links
if (links && typeof links === 'object') {
return Object.values(links)[0]
}
return links
}
const valA = getLinksValue(a)
const valB = getLinksValue(b)
if (typeof valA === 'number' && typeof valB === 'number') {
result = valA - valB
} else {
result = String(valA).localeCompare(String(valB))
}
break
}
case UITypes.DateTime:
case UITypes.CreatedTime:
case UITypes.LastModifiedTime:
result = dayjs(a).valueOf() - dayjs(b).valueOf()
break
case UITypes.Time: {
const normalizeTimeValue = (value: any): dayjs.Dayjs => {
// If it's already a dayjs object
if (dayjs.isDayjs(value)) {
return dayjs(`1999-01-01 ${value.format('HH:mm:ss')}`)
}
// If it's a string in HH:mm:ss format (from server)
if (typeof value === 'string' && /^\d{2}:\d{2}:\d{2}$/.test(value)) {
return dayjs(`1999-01-01 ${value}`)
}
// If it's a string in HH:mm format (from local state)
if (typeof value === 'string' && /^\d{2}:\d{2}$/.test(value)) {
return dayjs(`1999-01-01 ${value}:00`)
}
// For any other format, try parsing with dayjs
let parsed = dayjs(value)
// If not valid, try parsing as time only
if (!parsed.isValid()) {
parsed = dayjs(value, 'HH:mm:ss')
}
// If still not valid, try with dummy date
if (!parsed.isValid()) {
parsed = dayjs(`1999-01-01 ${value}`)
}
return parsed
}
const timeA = normalizeTimeValue(a)
const timeB = normalizeTimeValue(b)
result = timeA.valueOf() - timeB.valueOf()
break
}
case UITypes.Year:
result = Number(a) - Number(b)
break
case UITypes.Checkbox:
result = a === b ? 0 : a ? -1 : 1
break
case UITypes.SingleSelect:
case UITypes.MultiSelect:
result = String(a).localeCompare(String(b))
break
case UITypes.Attachment: {
const getAttachmentValue = (att) => {
if (Array.isArray(att) && att.length > 0) {
return att[0].title || att[0].path || ''
}
return ''
}
result = getAttachmentValue(a).localeCompare(getAttachmentValue(b))
break
}
case UITypes.User:
case UITypes.CreatedBy:
case UITypes.LastModifiedBy: {
const getUserValue = (user) => {
if (Array.isArray(user) && user.length > 0) {
return user[0].display_name || user[0].email || ''
}
if (user && typeof user === 'object') {
return user.display_name || user.email || ''
}
return String(user)
}
result = getUserValue(a).localeCompare(getUserValue(b))
break
}
case UITypes.SingleLineText:
case UITypes.LongText:
case UITypes.Email:
case UITypes.URL:
case UITypes.PhoneNumber:
case UITypes.Formula:
if (caseSensitive) {
result = String(a).localeCompare(String(b))
} else {
result = String(a).toLowerCase().localeCompare(String(b).toLowerCase())
}
break
case UITypes.JSON:
result = JSON.stringify(a).localeCompare(JSON.stringify(b))
break
default:
result = String(a).localeCompare(String(b))
}
return direction === 'desc' ? -result : result
}
export const isSortRelevantChange = (
changedFields: string[],
sorts: SortType[],
columnsById: Record<string, ColumnType>,
): boolean => {
const sortColumnTitles = new Set(sorts.map((sort) => columnsById[sort.fk_column_id!]?.title).filter(Boolean))
return changedFields.some((field) => sortColumnTitles.has(field))
}