chore: edit cell options wip

This commit is contained in:
ascarbek 2023-04-07 21:02:04 +06:00
parent bc9b1a5c33
commit 6bbf6873d6
3 changed files with 227 additions and 3 deletions

View File

@ -1,4 +1,4 @@
import { KeyboardEventHandler, useEffect, useRef, useState } from 'react';
import { KeyboardEventHandler, MouseEventHandler, useEffect, useRef, useState } from 'react';
import { CellIdentifier } from '$app/stores/effects/database/cell/cell_bd_svc';
import { useCell } from '$app/components/_shared/database-hooks/useCell';
import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
@ -21,6 +21,7 @@ export const CellOptionsPopup = ({
cellCache,
fieldController,
onOutsideClick,
openOptionDetail,
}: {
top: number;
left: number;
@ -28,6 +29,7 @@ export const CellOptionsPopup = ({
cellCache: CellCache;
fieldController: FieldController;
onOutsideClick: () => void;
openOptionDetail: (_left: number, _top: number) => void;
}) => {
const ref = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
@ -88,6 +90,19 @@ export const CellOptionsPopup = ({
}
};
const onOptionDetailClick: MouseEventHandler = (e) => {
e.stopPropagation();
let target = e.target as HTMLElement;
while (!(target instanceof HTMLButtonElement)) {
if (target.parentElement === null) return;
target = target.parentElement;
}
const { right: _left, top: _top } = target.getBoundingClientRect();
openOptionDetail(_left, _top);
};
return (
<div
ref={ref}
@ -120,7 +135,7 @@ export const CellOptionsPopup = ({
<div className={'font-mono text-shade-3'}>{value.length}/30</div>
</div>
<div className={'-mx-4 h-[1px] bg-shade-6'}></div>
<div className={'font-semibold text-shade-3'}>{t('grid.selectOption.panelTitle') || ''}</div>
<div className={'font-medium text-shade-3'}>{t('grid.selectOption.panelTitle') || ''}</div>
<div className={'flex flex-col gap-1'}>
{(databaseStore.fields[cellIdentifier.fieldId]?.fieldOptions as ISelectOptionType).selectOptions.map(
(option, index) => (
@ -148,7 +163,7 @@ export const CellOptionsPopup = ({
<CheckmarkSvg></CheckmarkSvg>
</button>
)}
<button className={'h-6 w-6 p-1'}>
<button onClick={onOptionDetailClick} className={'h-6 w-6 p-1'}>
<Details2Svg></Details2Svg>
</button>
</div>

View File

@ -0,0 +1,185 @@
import { CellIdentifier } from '$app/stores/effects/database/cell/cell_bd_svc';
import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
import { FieldController } from '$app/stores/effects/database/field/field_controller';
import { KeyboardEventHandler, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { SelectOptionCellDataPB, SelectOptionColorPB } from '@/services/backend';
import { getBgColor } from '$app/components/_shared/getColor';
import { CloseSvg } from '$app/components/_shared/svg/CloseSvg';
import { SelectOptionCellBackendService } from '$app/stores/effects/database/cell/select_option_bd_svc';
import useOutsideClick from '$app/components/_shared/useOutsideClick';
import { TrashSvg } from '$app/components/_shared/svg/TrashSvg';
import { CheckmarkSvg } from '$app/components/_shared/svg/CheckmarkSvg';
export const EditCellOptionPopup = ({
left,
top,
cellIdentifier,
cellCache,
fieldController,
onOutsideClick,
}: {
left: number;
top: number;
cellIdentifier: CellIdentifier;
cellCache: CellCache;
fieldController: FieldController;
onOutsideClick: () => void;
}) => {
const ref = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const { t } = useTranslation('');
const [adjustedTop, setAdjustedTop] = useState(-100);
const [value, setValue] = useState('');
useOutsideClick(ref, async () => {
onOutsideClick();
});
useEffect(() => {
if (!ref.current) return;
const { height } = ref.current.getBoundingClientRect();
if (top + height > window.innerHeight) {
setAdjustedTop(window.innerHeight - height);
} else {
setAdjustedTop(top);
}
}, [ref, window, top, left]);
const onKeyDown: KeyboardEventHandler = async (e) => {
if (e.key === 'Enter' && value.length > 0) {
await new SelectOptionCellBackendService(cellIdentifier).createOption({ name: value });
setValue('');
}
};
const onKeyDownWrapper: KeyboardEventHandler = (e) => {
if (e.key === 'Escape') {
onOutsideClick();
}
};
const onDeleteOptionClick = () => {
console.log('delete option');
};
return (
<div
ref={ref}
onKeyDown={onKeyDownWrapper}
className={`fixed z-10 rounded-lg bg-white px-2 py-2 text-xs shadow-md transition-opacity duration-300 ${
adjustedTop === -100 ? 'opacity-0' : 'opacity-100'
}`}
style={{ top: `${adjustedTop}px`, left: `${left}px` }}
>
<div className={'flex flex-col gap-2 p-2'}>
<div className={'border-shades-3 flex flex-1 items-center gap-2 rounded border bg-main-selector px-2 '}>
<input
ref={inputRef}
className={'py-2'}
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={onKeyDown}
/>
<div className={'font-mono text-shade-3'}>{value.length}/30</div>
</div>
<button
onClick={() => onDeleteOptionClick()}
className={
'flex cursor-pointer items-center gap-2 rounded-lg px-2 py-2 text-main-alert hover:bg-main-secondary'
}
>
<i className={'h-5 w-5'}>
<TrashSvg></TrashSvg>
</i>
<span>{t('grid.selectOption.deleteTag')}</span>
</button>
<div className={'-mx-4 h-[1px] bg-shade-6'}></div>
<div className={'my-2 font-medium text-shade-3'}>{t('grid.selectOption.colorPanelTitle')}</div>
<div className={'flex flex-col'}>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Purple)}`}></div>
<span>{t('grid.selectOption.purpleColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Pink)}`}></div>
<span>{t('grid.selectOption.pinkColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.LightPink)}`}></div>
<span>{t('grid.selectOption.lightPinkColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Orange)}`}></div>
<span>{t('grid.selectOption.orangeColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Yellow)}`}></div>
<span>{t('grid.selectOption.yellowColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Lime)}`}></div>
<span>{t('grid.selectOption.limeColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Green)}`}></div>
<span>{t('grid.selectOption.greenColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Aqua)}`}></div>
<span>{t('grid.selectOption.aquaColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
<div className={'flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-main-secondary'}>
<div className={'flex items-center gap-2'}>
<div className={`h-4 w-4 rounded-full ${getBgColor(SelectOptionColorPB.Blue)}`}></div>
<span>{t('grid.selectOption.blueColor')}</span>
</div>
<i className={'block h-3 w-3'}>
<CheckmarkSvg></CheckmarkSvg>
</i>
</div>
</div>
</div>
</div>
);
};

View File

@ -15,6 +15,7 @@ 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';
import { EditCellOptionPopup } from '$app/components/_shared/EditRow/EditCellOptionPopup';
export const EditRow = ({
onClose,
@ -48,6 +49,10 @@ export const EditRow = ({
const [datePickerTop, setDatePickerTop] = useState(0);
const [datePickerLeft, setDatePickerLeft] = useState(0);
const [showEditCellOption, setShowEditCellOption] = useState(false);
const [editCellOptionTop, setEditCellOptionTop] = useState(0);
const [editCellOptionLeft, setEditCellOptionLeft] = useState(0);
useEffect(() => {
setUnveil(true);
}, []);
@ -106,6 +111,12 @@ export const EditRow = ({
setShowDatePicker(true);
};
const onOpenOptionDetailClick = (_left: number, _top: number) => {
setShowEditCellOption(true);
setEditCellOptionLeft(_left);
setEditCellOptionTop(_top);
};
const onDragEnd: OnDragEndResponder = (result) => {
if (!result.destination?.index) return;
void controller.moveField({
@ -202,6 +213,7 @@ export const EditRow = ({
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController}
onOutsideClick={() => setShowChangeOptionsPopup(false)}
openOptionDetail={onOpenOptionDetailClick}
></CellOptionsPopup>
)}
{showDatePicker && editingCell && (
@ -214,6 +226,18 @@ export const EditRow = ({
onOutsideClick={() => setShowDatePicker(false)}
></DatePickerPopup>
)}
{showEditCellOption && editingCell && (
<EditCellOptionPopup
top={editCellOptionTop}
left={editCellOptionLeft}
cellIdentifier={editingCell}
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController}
onOutsideClick={() => {
setShowEditCellOption(false);
}}
></EditCellOptionPopup>
)}
</div>
</div>
);