mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: move fields dnd
This commit is contained in:
parent
d1d667c497
commit
c7acf9a594
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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 });
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user