Make positions possibly negatives (#5690)
Closes https://github.com/twentyhq/twenty/issues/5427
This commit is contained in:
@ -9,6 +9,7 @@ import { useRecordBoardStates } from '@/object-record/record-board/hooks/interna
|
|||||||
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
|
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
|
||||||
import { RecordBoardColumn } from '@/object-record/record-board/record-board-column/components/RecordBoardColumn';
|
import { RecordBoardColumn } from '@/object-record/record-board/record-board-column/components/RecordBoardColumn';
|
||||||
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { getDraggedRecordPosition } from '@/object-record/record-board/utils/get-dragged-record-position.util';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
@ -107,7 +108,6 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
|||||||
.getLoadable(recordStoreFamilyState(recordBeforeId))
|
.getLoadable(recordStoreFamilyState(recordBeforeId))
|
||||||
.getValue()
|
.getValue()
|
||||||
: null;
|
: null;
|
||||||
const recordBeforePosition: number | undefined = recordBefore?.position;
|
|
||||||
|
|
||||||
const recordAfterId =
|
const recordAfterId =
|
||||||
otherRecordsInDestinationColumn[destinationIndexInColumn];
|
otherRecordsInDestinationColumn[destinationIndexInColumn];
|
||||||
@ -116,12 +116,11 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
|||||||
.getLoadable(recordStoreFamilyState(recordAfterId))
|
.getLoadable(recordStoreFamilyState(recordAfterId))
|
||||||
.getValue()
|
.getValue()
|
||||||
: null;
|
: null;
|
||||||
const recordAfterPosition: number | undefined = recordAfter?.position;
|
|
||||||
|
|
||||||
const beforeBoundary = recordBeforePosition ?? 0;
|
const draggedRecordPosition = getDraggedRecordPosition(
|
||||||
const afterBoundary = recordAfterPosition ?? beforeBoundary + 1;
|
recordBefore?.position,
|
||||||
|
recordAfter?.position,
|
||||||
const draggedRecordPosition = (beforeBoundary + afterBoundary) / 2;
|
);
|
||||||
|
|
||||||
updateOneRecord({
|
updateOneRecord({
|
||||||
idToUpdate: draggedRecordId,
|
idToUpdate: draggedRecordId,
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { getDraggedRecordPosition } from '../get-dragged-record-position.util';
|
||||||
|
|
||||||
|
describe('getDraggedRecordPosition', () => {
|
||||||
|
it('when both records defined and positive, should return the average of the two positions', () => {
|
||||||
|
expect(getDraggedRecordPosition(1, 3)).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when both records defined and negative, should return the average of the two positions', () => {
|
||||||
|
expect(getDraggedRecordPosition(-3, -1)).toBe(-2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when both records defined and one negative, should return the average of the two positions', () => {
|
||||||
|
expect(getDraggedRecordPosition(-1, 3)).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when only record after, should return the position - 1', () => {
|
||||||
|
expect(getDraggedRecordPosition(undefined, 3)).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when only record before, should return the position + 1', () => {
|
||||||
|
expect(getDraggedRecordPosition(1, undefined)).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when both records undefined, should return 1', () => {
|
||||||
|
expect(getDraggedRecordPosition(undefined, undefined)).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
|
export const getDraggedRecordPosition = (
|
||||||
|
recordBeforePosition?: number,
|
||||||
|
recordAfterPosition?: number,
|
||||||
|
): number => {
|
||||||
|
if (isDefined(recordAfterPosition) && isDefined(recordBeforePosition)) {
|
||||||
|
return (recordBeforePosition + recordAfterPosition) / 2;
|
||||||
|
} else if (isDefined(recordAfterPosition)) {
|
||||||
|
return recordAfterPosition - 1;
|
||||||
|
} else if (isDefined(recordBeforePosition)) {
|
||||||
|
return recordBeforePosition + 1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -48,11 +48,11 @@ describe('RecordPositionFactory', () => {
|
|||||||
|
|
||||||
expect(result).toEqual(value);
|
expect(result).toEqual(value);
|
||||||
});
|
});
|
||||||
it('should return the existing position / 2 when value is first', async () => {
|
it('should return the existing position -1 when value is first', async () => {
|
||||||
const value = 'first';
|
const value = 'first';
|
||||||
const result = await factory.create(value, objectMetadata, workspaceId);
|
const result = await factory.create(value, objectMetadata, workspaceId);
|
||||||
|
|
||||||
expect(result).toEqual(0.5);
|
expect(result).toEqual(0);
|
||||||
});
|
});
|
||||||
it('should return the existing position + 1 when value is last', async () => {
|
it('should return the existing position + 1 when value is last', async () => {
|
||||||
const value = 'last';
|
const value = 'last';
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { isDefined } from 'class-validator';
|
||||||
|
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
import {
|
import {
|
||||||
RecordPositionQueryFactory,
|
RecordPositionQueryFactory,
|
||||||
@ -32,6 +34,8 @@ export class RecordPositionFactory {
|
|||||||
dataSourceSchema,
|
dataSourceSchema,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If the value was 'first', the first record will be the one with the lowest position
|
||||||
|
// If the value was 'last', the first record will be the one with the highest position
|
||||||
const records = await this.workspaceDataSourceService.executeRawQuery(
|
const records = await this.workspaceDataSourceService.executeRawQuery(
|
||||||
query,
|
query,
|
||||||
[],
|
[],
|
||||||
@ -39,10 +43,16 @@ export class RecordPositionFactory {
|
|||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
if (
|
||||||
(value === 'first'
|
!isDefined(records) ||
|
||||||
? records[0]?.position / 2
|
records.length === 0 ||
|
||||||
: records[0]?.position + 1) || 1
|
!isDefined(records[0]?.position)
|
||||||
);
|
) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value === 'first'
|
||||||
|
? records[0].position - 1
|
||||||
|
: records[0].position + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ const isValidStringPosition = (value: string): boolean =>
|
|||||||
typeof value === 'string' && (value === 'first' || value === 'last');
|
typeof value === 'string' && (value === 'first' || value === 'last');
|
||||||
|
|
||||||
const isValidNumberPosition = (value: number): boolean =>
|
const isValidNumberPosition = (value: number): boolean =>
|
||||||
typeof value === 'number' && value >= 0;
|
typeof value === 'number';
|
||||||
|
|
||||||
const checkPosition = (value: any): PositionType => {
|
const checkPosition = (value: any): PositionType => {
|
||||||
if (isValidNumberPosition(value) || isValidStringPosition(value)) {
|
if (isValidNumberPosition(value) || isValidStringPosition(value)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user