|
@@ -12,11 +12,16 @@ import { ChangeFieldTypePopup } from '$app/components/_shared/EditRow/ChangeFiel
|
|
import { TypeOptionController } from '$app/stores/effects/database/field/type_option/type_option_controller';
|
|
import { TypeOptionController } from '$app/stores/effects/database/field/type_option/type_option_controller';
|
|
import { Some } from 'ts-results';
|
|
import { Some } from 'ts-results';
|
|
import { FieldType, SelectOptionPB } from '@/services/backend';
|
|
import { FieldType, SelectOptionPB } from '@/services/backend';
|
|
-import { CellOptionsPopup } from '$app/components/_shared/EditRow/CellOptionsPopup';
|
|
|
|
-import { DatePickerPopup } from '$app/components/_shared/EditRow/DatePickerPopup';
|
|
|
|
|
|
+import { CellOptionsPopup } from '$app/components/_shared/EditRow/Options/CellOptionsPopup';
|
|
|
|
+import { DatePickerPopup } from '$app/components/_shared/EditRow/Date/DatePickerPopup';
|
|
import { DragDropContext, Droppable, OnDragEndResponder } from 'react-beautiful-dnd';
|
|
import { DragDropContext, Droppable, OnDragEndResponder } from 'react-beautiful-dnd';
|
|
-import { EditCellOptionPopup } from '$app/components/_shared/EditRow/EditCellOptionPopup';
|
|
|
|
-import { NumberFormatPopup } from '$app/components/_shared/EditRow/NumberFormatPopup';
|
|
|
|
|
|
+import { EditCellOptionPopup } from '$app/components/_shared/EditRow/Options/EditCellOptionPopup';
|
|
|
|
+import { NumberFormatPopup } from '$app/components/_shared/EditRow/Date/NumberFormatPopup';
|
|
|
|
+import { CheckListPopup } from '$app/components/_shared/EditRow/CheckList/CheckListPopup';
|
|
|
|
+import { EditCheckListPopup } from '$app/components/_shared/EditRow/CheckList/EditCheckListPopup';
|
|
|
|
+import { PropertiesPanel } from '$app/components/_shared/EditRow/PropertiesPanel';
|
|
|
|
+import { ImageSvg } from '$app/components/_shared/svg/ImageSvg';
|
|
|
|
+import { PromptWindow } from '$app/components/_shared/PromptWindow';
|
|
|
|
|
|
export const EditRow = ({
|
|
export const EditRow = ({
|
|
onClose,
|
|
onClose,
|
|
@@ -30,7 +35,7 @@ export const EditRow = ({
|
|
rowInfo: RowInfo;
|
|
rowInfo: RowInfo;
|
|
}) => {
|
|
}) => {
|
|
const { cells, onNewColumnClick } = useRow(viewId, controller, rowInfo);
|
|
const { cells, onNewColumnClick } = useRow(viewId, controller, rowInfo);
|
|
- const { t } = useTranslation('');
|
|
|
|
|
|
+ const { t } = useTranslation();
|
|
const [unveil, setUnveil] = useState(false);
|
|
const [unveil, setUnveil] = useState(false);
|
|
|
|
|
|
const [editingCell, setEditingCell] = useState<CellIdentifier | null>(null);
|
|
const [editingCell, setEditingCell] = useState<CellIdentifier | null>(null);
|
|
@@ -56,10 +61,21 @@ export const EditRow = ({
|
|
|
|
|
|
const [editingSelectOption, setEditingSelectOption] = useState<SelectOptionPB | undefined>();
|
|
const [editingSelectOption, setEditingSelectOption] = useState<SelectOptionPB | undefined>();
|
|
|
|
|
|
|
|
+ const [showEditCheckList, setShowEditCheckList] = useState(false);
|
|
|
|
+ const [editCheckListTop, setEditCheckListTop] = useState(0);
|
|
|
|
+ const [editCheckListLeft, setEditCheckListLeft] = useState(0);
|
|
|
|
+
|
|
const [showNumberFormatPopup, setShowNumberFormatPopup] = useState(false);
|
|
const [showNumberFormatPopup, setShowNumberFormatPopup] = useState(false);
|
|
const [numberFormatTop, setNumberFormatTop] = useState(0);
|
|
const [numberFormatTop, setNumberFormatTop] = useState(0);
|
|
const [numberFormatLeft, setNumberFormatLeft] = useState(0);
|
|
const [numberFormatLeft, setNumberFormatLeft] = useState(0);
|
|
|
|
|
|
|
|
+ const [showCheckListPopup, setShowCheckListPopup] = useState(false);
|
|
|
|
+ const [checkListPopupTop, setCheckListPopupTop] = useState(0);
|
|
|
|
+ const [checkListPopupLeft, setCheckListPopupLeft] = useState(0);
|
|
|
|
+
|
|
|
|
+ const [deletingPropertyId, setDeletingPropertyId] = useState<string | null>(null);
|
|
|
|
+ const [showDeletePropertyPrompt, setShowDeletePropertyPrompt] = useState(false);
|
|
|
|
+
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
setUnveil(true);
|
|
setUnveil(true);
|
|
}, []);
|
|
}, []);
|
|
@@ -125,12 +141,26 @@ export const EditRow = ({
|
|
setEditCellOptionTop(_top);
|
|
setEditCellOptionTop(_top);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const onOpenCheckListDetailClick = (_left: number, _top: number, _select_option: SelectOptionPB) => {
|
|
|
|
+ setEditingSelectOption(_select_option);
|
|
|
|
+ setShowEditCheckList(true);
|
|
|
|
+ setEditCheckListLeft(_left + 10);
|
|
|
|
+ setEditCheckListTop(_top);
|
|
|
|
+ };
|
|
|
|
+
|
|
const onNumberFormat = (_left: number, _top: number) => {
|
|
const onNumberFormat = (_left: number, _top: number) => {
|
|
setShowNumberFormatPopup(true);
|
|
setShowNumberFormatPopup(true);
|
|
setNumberFormatLeft(_left + 10);
|
|
setNumberFormatLeft(_left + 10);
|
|
setNumberFormatTop(_top);
|
|
setNumberFormatTop(_top);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const onEditCheckListClick = (cellIdentifier: CellIdentifier, left: number, top: number) => {
|
|
|
|
+ setEditingCell(cellIdentifier);
|
|
|
|
+ setShowCheckListPopup(true);
|
|
|
|
+ setCheckListPopupLeft(left);
|
|
|
|
+ setCheckListPopupTop(top + 40);
|
|
|
|
+ };
|
|
|
|
+
|
|
const onDragEnd: OnDragEndResponder = (result) => {
|
|
const onDragEnd: OnDragEndResponder = (result) => {
|
|
if (!result.destination?.index) return;
|
|
if (!result.destination?.index) return;
|
|
void controller.moveField({
|
|
void controller.moveField({
|
|
@@ -140,129 +170,193 @@ export const EditRow = ({
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const onDeletePropertyClick = (fieldId: string) => {
|
|
|
|
+ setDeletingPropertyId(fieldId);
|
|
|
|
+ setShowDeletePropertyPrompt(true);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const onDelete = async () => {
|
|
|
|
+ if (!deletingPropertyId) return;
|
|
|
|
+ const fieldInfo = controller.fieldController.getField(deletingPropertyId);
|
|
|
|
+ if (!fieldInfo) return;
|
|
|
|
+ const typeController = new TypeOptionController(viewId, Some(fieldInfo));
|
|
|
|
+ await typeController.initialize();
|
|
|
|
+ await typeController.deleteField();
|
|
|
|
+ setShowDeletePropertyPrompt(false);
|
|
|
|
+ };
|
|
|
|
+
|
|
return (
|
|
return (
|
|
- <div
|
|
|
|
- className={`fixed inset-0 z-10 flex items-center justify-center bg-black/30 backdrop-blur-sm transition-opacity duration-300 ${
|
|
|
|
- unveil ? 'opacity-100' : 'opacity-0'
|
|
|
|
- }`}
|
|
|
|
- onClick={() => onCloseClick()}
|
|
|
|
- >
|
|
|
|
|
|
+ <>
|
|
<div
|
|
<div
|
|
- onClick={(e) => {
|
|
|
|
- e.stopPropagation();
|
|
|
|
- }}
|
|
|
|
- className={`relative flex h-[90%] w-[70%] flex-col gap-8 rounded-xl bg-white px-8 pb-4 pt-12`}
|
|
|
|
|
|
+ className={`fixed inset-0 z-10 flex items-center justify-center bg-black/30 backdrop-blur-sm transition-opacity duration-300 ${
|
|
|
|
+ unveil ? 'opacity-100' : 'opacity-0'
|
|
|
|
+ }`}
|
|
|
|
+ onClick={() => onCloseClick()}
|
|
>
|
|
>
|
|
- <div onClick={() => onCloseClick()} className={'absolute top-4 right-4'}>
|
|
|
|
- <button className={'block h-8 w-8 rounded-lg text-shade-2 hover:bg-main-secondary'}>
|
|
|
|
- <CloseSvg></CloseSvg>
|
|
|
|
- </button>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div
|
|
|
|
+ onClick={(e) => {
|
|
|
|
+ e.stopPropagation();
|
|
|
|
+ }}
|
|
|
|
+ className={`relative flex h-[90%] w-[70%] flex-col gap-8 rounded-xl bg-white `}
|
|
|
|
+ >
|
|
|
|
+ <div onClick={() => onCloseClick()} className={'absolute top-1 right-1'}>
|
|
|
|
+ <button className={'block h-8 w-8 rounded-lg text-shade-2 hover:bg-main-secondary'}>
|
|
|
|
+ <CloseSvg></CloseSvg>
|
|
|
|
+ </button>
|
|
|
|
+ </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={onEditFieldClick}
|
|
|
|
- onEditOptionsClick={onEditOptionsClick}
|
|
|
|
- onEditDateClick={onEditDateClick}
|
|
|
|
- ></EditCellWrapper>
|
|
|
|
- ))}
|
|
|
|
|
|
+ <div className={'flex h-full'}>
|
|
|
|
+ <div className={'flex h-full flex-1 flex-col border-r border-shade-6 pb-4 pt-6'}>
|
|
|
|
+ <div className={'pl-12 pb-4'}>
|
|
|
|
+ <button className={'flex items-center gap-2 p-4'}>
|
|
|
|
+ <i className={'h-5 w-5'}>
|
|
|
|
+ <ImageSvg></ImageSvg>
|
|
|
|
+ </i>
|
|
|
|
+ <span className={'text-xs'}>Add Cover</span>
|
|
|
|
+ </button>
|
|
</div>
|
|
</div>
|
|
- )}
|
|
|
|
- </Droppable>
|
|
|
|
- </DragDropContext>
|
|
|
|
-
|
|
|
|
- <div className={'border-t border-shade-6 pt-2'}>
|
|
|
|
- <button
|
|
|
|
- onClick={() => onNewColumnClick()}
|
|
|
|
- className={'flex w-full items-center gap-2 rounded-lg px-4 py-2 hover:bg-shade-6'}
|
|
|
|
- >
|
|
|
|
- <i className={'h-5 w-5'}>
|
|
|
|
- <AddSvg></AddSvg>
|
|
|
|
- </i>
|
|
|
|
- <span>{t('grid.field.newColumn')}</span>
|
|
|
|
- </button>
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
- {showFieldEditor && editingCell && (
|
|
|
|
- <EditFieldPopup
|
|
|
|
- top={editFieldTop}
|
|
|
|
- left={editFieldLeft}
|
|
|
|
- cellIdentifier={editingCell}
|
|
|
|
- viewId={viewId}
|
|
|
|
- onOutsideClick={onOutsideEditFieldClick}
|
|
|
|
- fieldInfo={controller.fieldController.getField(editingCell.fieldId)}
|
|
|
|
- fieldController={controller.fieldController}
|
|
|
|
- changeFieldTypeClick={onChangeFieldTypeClick}
|
|
|
|
- onNumberFormat={onNumberFormat}
|
|
|
|
- ></EditFieldPopup>
|
|
|
|
- )}
|
|
|
|
- {showChangeFieldTypePopup && (
|
|
|
|
- <ChangeFieldTypePopup
|
|
|
|
- top={changeFieldTypeTop}
|
|
|
|
- left={changeFieldTypeLeft}
|
|
|
|
- onClick={(newType) => changeFieldType(newType)}
|
|
|
|
- onOutsideClick={() => setShowChangeFieldTypePopup(false)}
|
|
|
|
- ></ChangeFieldTypePopup>
|
|
|
|
- )}
|
|
|
|
- {showChangeOptionsPopup && editingCell && (
|
|
|
|
- <CellOptionsPopup
|
|
|
|
- top={changeOptionsTop}
|
|
|
|
- left={changeOptionsLeft}
|
|
|
|
- cellIdentifier={editingCell}
|
|
|
|
- cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
|
|
|
- fieldController={controller.fieldController}
|
|
|
|
- onOutsideClick={() => setShowChangeOptionsPopup(false)}
|
|
|
|
- openOptionDetail={onOpenOptionDetailClick}
|
|
|
|
- ></CellOptionsPopup>
|
|
|
|
- )}
|
|
|
|
- {showDatePicker && editingCell && (
|
|
|
|
- <DatePickerPopup
|
|
|
|
- top={datePickerTop}
|
|
|
|
- left={datePickerLeft}
|
|
|
|
- cellIdentifier={editingCell}
|
|
|
|
- cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
|
|
|
- fieldController={controller.fieldController}
|
|
|
|
- onOutsideClick={() => setShowDatePicker(false)}
|
|
|
|
- ></DatePickerPopup>
|
|
|
|
- )}
|
|
|
|
- {showEditCellOption && editingCell && editingSelectOption && (
|
|
|
|
- <EditCellOptionPopup
|
|
|
|
- top={editCellOptionTop}
|
|
|
|
- left={editCellOptionLeft}
|
|
|
|
- cellIdentifier={editingCell}
|
|
|
|
- editingSelectOption={editingSelectOption}
|
|
|
|
- onOutsideClick={() => {
|
|
|
|
- setShowEditCellOption(false);
|
|
|
|
- }}
|
|
|
|
- ></EditCellOptionPopup>
|
|
|
|
- )}
|
|
|
|
- {showNumberFormatPopup && editingCell && (
|
|
|
|
- <NumberFormatPopup
|
|
|
|
- top={numberFormatTop}
|
|
|
|
- left={numberFormatLeft}
|
|
|
|
- cellIdentifier={editingCell}
|
|
|
|
- fieldController={controller.fieldController}
|
|
|
|
- onOutsideClick={() => {
|
|
|
|
- setShowNumberFormatPopup(false);
|
|
|
|
- }}
|
|
|
|
- ></NumberFormatPopup>
|
|
|
|
- )}
|
|
|
|
|
|
+ <DragDropContext onDragEnd={onDragEnd}>
|
|
|
|
+ <Droppable droppableId={'field-list'}>
|
|
|
|
+ {(provided) => (
|
|
|
|
+ <div
|
|
|
|
+ {...provided.droppableProps}
|
|
|
|
+ ref={provided.innerRef}
|
|
|
|
+ className={`flex flex-1 flex-col gap-8 px-8 ${
|
|
|
|
+ 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={onEditFieldClick}
|
|
|
|
+ onEditOptionsClick={onEditOptionsClick}
|
|
|
|
+ onEditDateClick={onEditDateClick}
|
|
|
|
+ onEditCheckListClick={onEditCheckListClick}
|
|
|
|
+ ></EditCellWrapper>
|
|
|
|
+ ))}
|
|
|
|
+ </div>
|
|
|
|
+ )}
|
|
|
|
+ </Droppable>
|
|
|
|
+ </DragDropContext>
|
|
|
|
+
|
|
|
|
+ <div className={'border-t border-shade-6 px-8 pt-2'}>
|
|
|
|
+ <button
|
|
|
|
+ onClick={() => onNewColumnClick()}
|
|
|
|
+ className={'flex w-full items-center gap-2 rounded-lg px-4 py-2 hover:bg-shade-6'}
|
|
|
|
+ >
|
|
|
|
+ <i className={'h-5 w-5'}>
|
|
|
|
+ <AddSvg></AddSvg>
|
|
|
|
+ </i>
|
|
|
|
+ <span>{t('grid.field.newProperty')}</span>
|
|
|
|
+ </button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <PropertiesPanel
|
|
|
|
+ viewId={viewId}
|
|
|
|
+ controller={controller}
|
|
|
|
+ rowInfo={rowInfo}
|
|
|
|
+ onDeletePropertyClick={onDeletePropertyClick}
|
|
|
|
+ ></PropertiesPanel>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ {showFieldEditor && editingCell && (
|
|
|
|
+ <EditFieldPopup
|
|
|
|
+ top={editFieldTop}
|
|
|
|
+ left={editFieldLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ viewId={viewId}
|
|
|
|
+ onOutsideClick={onOutsideEditFieldClick}
|
|
|
|
+ fieldInfo={controller.fieldController.getField(editingCell.fieldId)}
|
|
|
|
+ fieldController={controller.fieldController}
|
|
|
|
+ changeFieldTypeClick={onChangeFieldTypeClick}
|
|
|
|
+ onNumberFormat={onNumberFormat}
|
|
|
|
+ ></EditFieldPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showChangeFieldTypePopup && (
|
|
|
|
+ <ChangeFieldTypePopup
|
|
|
|
+ top={changeFieldTypeTop}
|
|
|
|
+ left={changeFieldTypeLeft}
|
|
|
|
+ onClick={(newType) => changeFieldType(newType)}
|
|
|
|
+ onOutsideClick={() => setShowChangeFieldTypePopup(false)}
|
|
|
|
+ ></ChangeFieldTypePopup>
|
|
|
|
+ )}
|
|
|
|
+ {showChangeOptionsPopup && editingCell && (
|
|
|
|
+ <CellOptionsPopup
|
|
|
|
+ top={changeOptionsTop}
|
|
|
|
+ left={changeOptionsLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
|
|
|
+ fieldController={controller.fieldController}
|
|
|
|
+ onOutsideClick={() => setShowChangeOptionsPopup(false)}
|
|
|
|
+ openOptionDetail={onOpenOptionDetailClick}
|
|
|
|
+ ></CellOptionsPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showDatePicker && editingCell && (
|
|
|
|
+ <DatePickerPopup
|
|
|
|
+ top={datePickerTop}
|
|
|
|
+ left={datePickerLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
|
|
|
+ fieldController={controller.fieldController}
|
|
|
|
+ onOutsideClick={() => setShowDatePicker(false)}
|
|
|
|
+ ></DatePickerPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showEditCellOption && editingCell && editingSelectOption && (
|
|
|
|
+ <EditCellOptionPopup
|
|
|
|
+ top={editCellOptionTop}
|
|
|
|
+ left={editCellOptionLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ editingSelectOption={editingSelectOption}
|
|
|
|
+ onOutsideClick={() => {
|
|
|
|
+ setShowEditCellOption(false);
|
|
|
|
+ }}
|
|
|
|
+ ></EditCellOptionPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showNumberFormatPopup && editingCell && (
|
|
|
|
+ <NumberFormatPopup
|
|
|
|
+ top={numberFormatTop}
|
|
|
|
+ left={numberFormatLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ fieldController={controller.fieldController}
|
|
|
|
+ onOutsideClick={() => {
|
|
|
|
+ setShowNumberFormatPopup(false);
|
|
|
|
+ }}
|
|
|
|
+ ></NumberFormatPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showCheckListPopup && editingCell && (
|
|
|
|
+ <CheckListPopup
|
|
|
|
+ top={checkListPopupTop}
|
|
|
|
+ left={checkListPopupLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
|
|
|
+ fieldController={controller.fieldController}
|
|
|
|
+ onOutsideClick={() => setShowCheckListPopup(false)}
|
|
|
|
+ openCheckListDetail={onOpenCheckListDetailClick}
|
|
|
|
+ ></CheckListPopup>
|
|
|
|
+ )}
|
|
|
|
+ {showEditCheckList && editingCell && editingSelectOption && (
|
|
|
|
+ <EditCheckListPopup
|
|
|
|
+ top={editCheckListTop}
|
|
|
|
+ left={editCheckListLeft}
|
|
|
|
+ cellIdentifier={editingCell}
|
|
|
|
+ editingSelectOption={editingSelectOption}
|
|
|
|
+ onOutsideClick={() => setShowEditCheckList(false)}
|
|
|
|
+ ></EditCheckListPopup>
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
+ {showDeletePropertyPrompt && (
|
|
|
|
+ <PromptWindow
|
|
|
|
+ msg={'Are you sure you want to delete this property?'}
|
|
|
|
+ onYes={() => onDelete()}
|
|
|
|
+ onCancel={() => setShowDeletePropertyPrompt(false)}
|
|
|
|
+ ></PromptWindow>
|
|
|
|
+ )}
|
|
|
|
+ </>
|
|
);
|
|
);
|
|
};
|
|
};
|