chore: move fields dnd

This commit is contained in:
ascarbek 2023-03-30 18:44:16 +06:00
parent d1d667c497
commit c7acf9a594
4 changed files with 109 additions and 57 deletions

View File

@ -12,8 +12,10 @@ import { CellOptions } from '$app/components/_shared/EditRow/CellOptions';
import { EditCellNumber } from '$app/components/_shared/EditRow/EditCellNumber';
import { EditCheckboxCell } from '$app/components/_shared/EditRow/EditCheckboxCell';
import { EditCellUrl } from '$app/components/_shared/EditRow/EditCellUrl';
import { Draggable } from 'react-beautiful-dnd';
export const EditCellWrapper = ({
index,
cellIdentifier,
cellCache,
fieldController,
@ -21,6 +23,7 @@ export const EditCellWrapper = ({
onEditOptionsClick,
onEditDateClick,
}: {
index: number;
cellIdentifier: CellIdentifier;
cellCache: CellCache;
fieldController: FieldController;
@ -39,50 +42,61 @@ export const EditCellWrapper = ({
};
return (
<div className={'flex w-full items-center text-xs'}>
<div
ref={el}
onClick={() => onClick()}
className={'relative flex w-[180px] cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 hover:bg-shade-6'}
>
<div className={'flex h-5 w-5 flex-shrink-0 items-center justify-center'}>
<FieldTypeIcon fieldType={cellIdentifier.fieldType}></FieldTypeIcon>
<Draggable draggableId={cellIdentifier.fieldId} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className={'flex w-full items-center text-xs'}
>
<div
ref={el}
onClick={() => onClick()}
className={
'relative flex w-[180px] cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 hover:bg-shade-6'
}
>
<div className={'flex h-5 w-5 flex-shrink-0 items-center justify-center'}>
<FieldTypeIcon fieldType={cellIdentifier.fieldType}></FieldTypeIcon>
</div>
<span className={'overflow-hidden text-ellipsis whitespace-nowrap'}>
{databaseStore.fields[cellIdentifier.fieldId].title}
</span>
</div>
<div className={'flex-1 cursor-pointer rounded-lg hover:bg-shade-6'}>
{(cellIdentifier.fieldType === FieldType.SingleSelect ||
cellIdentifier.fieldType === FieldType.MultiSelect ||
cellIdentifier.fieldType === FieldType.Checklist) &&
cellController && (
<CellOptions
data={data as SelectOptionCellDataPB | undefined}
onEditClick={onEditOptionsClick}
></CellOptions>
)}
{cellIdentifier.fieldType === FieldType.Checkbox && cellController && (
<EditCheckboxCell data={data as boolean | undefined} cellController={cellController}></EditCheckboxCell>
)}
{cellIdentifier.fieldType === FieldType.DateTime && (
<EditCellDate data={data as DateCellDataPB | undefined} onEditClick={onEditDateClick}></EditCellDate>
)}
{cellIdentifier.fieldType === FieldType.Number && cellController && (
<EditCellNumber data={data as string | undefined} cellController={cellController}></EditCellNumber>
)}
{cellIdentifier.fieldType === FieldType.URL && cellController && (
<EditCellUrl data={data as URLCellDataPB | undefined} cellController={cellController}></EditCellUrl>
)}
{cellIdentifier.fieldType === FieldType.RichText && cellController && (
<EditCellText data={data as string | undefined} cellController={cellController}></EditCellText>
)}
</div>
</div>
<span className={'overflow-hidden text-ellipsis whitespace-nowrap'}>
{databaseStore.fields[cellIdentifier.fieldId].title}
</span>
</div>
<div className={'flex-1 cursor-pointer rounded-lg hover:bg-shade-6'}>
{(cellIdentifier.fieldType === FieldType.SingleSelect ||
cellIdentifier.fieldType === FieldType.MultiSelect ||
cellIdentifier.fieldType === FieldType.Checklist) &&
cellController && (
<CellOptions
data={data as SelectOptionCellDataPB | undefined}
onEditClick={onEditOptionsClick}
></CellOptions>
)}
{cellIdentifier.fieldType === FieldType.Checkbox && cellController && (
<EditCheckboxCell data={data as boolean | undefined} cellController={cellController}></EditCheckboxCell>
)}
{cellIdentifier.fieldType === FieldType.DateTime && (
<EditCellDate data={data as DateCellDataPB | undefined} onEditClick={onEditDateClick}></EditCellDate>
)}
{cellIdentifier.fieldType === FieldType.Number && cellController && (
<EditCellNumber data={data as string | undefined} cellController={cellController}></EditCellNumber>
)}
{cellIdentifier.fieldType === FieldType.URL && cellController && (
<EditCellUrl data={data as URLCellDataPB | undefined} cellController={cellController}></EditCellUrl>
)}
{cellIdentifier.fieldType === FieldType.RichText && cellController && (
<EditCellText data={data as string | undefined} cellController={cellController}></EditCellText>
)}
</div>
</div>
)}
</Draggable>
);
};

View File

@ -14,6 +14,7 @@ import { Some } from 'ts-results';
import { FieldType } from '@/services/backend';
import { CellOptionsPopup } from '$app/components/_shared/EditRow/CellOptionsPopup';
import { DatePickerPopup } from '$app/components/_shared/EditRow/DatePickerPopup';
import { DragDropContext, Droppable, OnDragEndResponder } from 'react-beautiful-dnd';
export const EditRow = ({
onClose,
@ -105,6 +106,11 @@ export const EditRow = ({
setShowDatePicker(true);
};
const onDragEnd: OnDragEndResponder = (result) => {
if (!result.destination?.index) return;
void controller.moveField(result.source.droppableId, result.source.index, result.destination.index);
};
return (
<div
className={`fixed inset-0 z-10 flex items-center justify-center bg-black/30 backdrop-blur-sm transition-opacity duration-300 ${
@ -117,19 +123,35 @@ export const EditRow = ({
<CloseSvg></CloseSvg>
</button>
</div>
<div className={`flex flex-1 flex-col gap-2 ${showFieldEditor ? 'overflow-hidden' : 'overflow-auto'}`}>
{cells.map((cell, cellIndex) => (
<EditCellWrapper
key={cellIndex}
cellIdentifier={cell.cellIdentifier}
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController}
onEditFieldClick={(top: number, right: number) => onEditFieldClick(cell.cellIdentifier, top, right)}
onEditOptionsClick={(left: number, top: number) => onEditOptionsClick(cell.cellIdentifier, left, top)}
onEditDateClick={(left: number, top: number) => onEditDateClick(cell.cellIdentifier, left, top)}
></EditCellWrapper>
))}
</div>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId={'field-list'}>
{(provided) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
className={`flex flex-1 flex-col gap-2 ${
showFieldEditor || showChangeOptionsPopup || showDatePicker ? 'overflow-hidden' : 'overflow-auto'
}`}
>
{cells.map((cell, cellIndex) => (
<EditCellWrapper
index={cellIndex}
key={cellIndex}
cellIdentifier={cell.cellIdentifier}
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController}
onEditFieldClick={(top: number, right: number) => onEditFieldClick(cell.cellIdentifier, top, right)}
onEditOptionsClick={(left: number, top: number) =>
onEditOptionsClick(cell.cellIdentifier, left, top)
}
onEditDateClick={(left: number, top: number) => onEditDateClick(cell.cellIdentifier, left, top)}
></EditCellWrapper>
))}
</div>
)}
</Droppable>
</DragDropContext>
<div className={'border-t border-shade-6 pt-2'}>
<button

View File

@ -5,10 +5,12 @@ import {
DatabaseEventGetFields,
DatabaseEventGetGroup,
DatabaseEventGetGroups,
DatabaseEventMoveField,
DatabaseEventMoveGroup,
DatabaseEventMoveGroupRow,
DatabaseEventMoveRow,
DatabaseGroupIdPB,
MoveFieldPayloadPB,
MoveGroupPayloadPB,
MoveGroupRowPayloadPB,
MoveRowPayloadPB,
@ -96,6 +98,16 @@ export class DatabaseBackendService {
return DatabaseEventMoveGroup(payload);
};
moveField = (fieldId: string, fromIndex: number, toIndex: number) => {
const payload = MoveFieldPayloadPB.fromObject({
view_id: this.viewId,
field_id: fieldId,
from_index: fromIndex,
to_index: toIndex,
});
return DatabaseEventMoveField(payload);
};
/// Get all fields in database
getFields = async (fieldIds?: FieldIdPB[]) => {
const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId });

View File

@ -102,6 +102,10 @@ export class DatabaseController {
return this.backendService.moveGroup(fromGroupId, toGroupId);
};
moveField = (fieldId: string, fromIndex: number, toIndex: number) => {
return this.backendService.moveField(fieldId, fromIndex, toIndex);
};
private loadGroup = async () => {
const result = await this.backendService.loadGroups();
if (result.ok) {