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 { EditCellNumber } from '$app/components/_shared/EditRow/EditCellNumber';
import { EditCheckboxCell } from '$app/components/_shared/EditRow/EditCheckboxCell'; import { EditCheckboxCell } from '$app/components/_shared/EditRow/EditCheckboxCell';
import { EditCellUrl } from '$app/components/_shared/EditRow/EditCellUrl'; import { EditCellUrl } from '$app/components/_shared/EditRow/EditCellUrl';
import { Draggable } from 'react-beautiful-dnd';
export const EditCellWrapper = ({ export const EditCellWrapper = ({
index,
cellIdentifier, cellIdentifier,
cellCache, cellCache,
fieldController, fieldController,
@ -21,6 +23,7 @@ export const EditCellWrapper = ({
onEditOptionsClick, onEditOptionsClick,
onEditDateClick, onEditDateClick,
}: { }: {
index: number;
cellIdentifier: CellIdentifier; cellIdentifier: CellIdentifier;
cellCache: CellCache; cellCache: CellCache;
fieldController: FieldController; fieldController: FieldController;
@ -39,50 +42,61 @@ export const EditCellWrapper = ({
}; };
return ( return (
<div className={'flex w-full items-center text-xs'}> <Draggable draggableId={cellIdentifier.fieldId} index={index}>
<div {(provided) => (
ref={el} <div
onClick={() => onClick()} ref={provided.innerRef}
className={'relative flex w-[180px] cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 hover:bg-shade-6'} {...provided.draggableProps}
> {...provided.dragHandleProps}
<div className={'flex h-5 w-5 flex-shrink-0 items-center justify-center'}> className={'flex w-full items-center text-xs'}
<FieldTypeIcon fieldType={cellIdentifier.fieldType}></FieldTypeIcon> >
<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> </div>
<span className={'overflow-hidden text-ellipsis whitespace-nowrap'}> )}
{databaseStore.fields[cellIdentifier.fieldId].title} </Draggable>
</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>
); );
}; };

View File

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

View File

@ -5,10 +5,12 @@ import {
DatabaseEventGetFields, DatabaseEventGetFields,
DatabaseEventGetGroup, DatabaseEventGetGroup,
DatabaseEventGetGroups, DatabaseEventGetGroups,
DatabaseEventMoveField,
DatabaseEventMoveGroup, DatabaseEventMoveGroup,
DatabaseEventMoveGroupRow, DatabaseEventMoveGroupRow,
DatabaseEventMoveRow, DatabaseEventMoveRow,
DatabaseGroupIdPB, DatabaseGroupIdPB,
MoveFieldPayloadPB,
MoveGroupPayloadPB, MoveGroupPayloadPB,
MoveGroupRowPayloadPB, MoveGroupRowPayloadPB,
MoveRowPayloadPB, MoveRowPayloadPB,
@ -96,6 +98,16 @@ export class DatabaseBackendService {
return DatabaseEventMoveGroup(payload); 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 /// Get all fields in database
getFields = async (fieldIds?: FieldIdPB[]) => { getFields = async (fieldIds?: FieldIdPB[]) => {
const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId }); const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId });

View File

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