chore: column rename

This commit is contained in:
ascarbek 2023-03-23 00:04:51 +06:00 committed by Mike Abebe
parent c453d734ab
commit 4545410703
8 changed files with 162 additions and 36 deletions

View File

@ -1,6 +1,6 @@
import { CellIdentifier } from '../../stores/effects/database/cell/cell_bd_svc'; import { CellIdentifier } from '$app/stores/effects/database/cell/cell_bd_svc';
import { CellCache } from '../../stores/effects/database/cell/cell_cache'; import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
import { FieldController } from '../../stores/effects/database/field/field_controller'; import { FieldController } from '$app/stores/effects/database/field/field_controller';
import { useCell } from '../_shared/database-hooks/useCell'; import { useCell } from '../_shared/database-hooks/useCell';
export const BoardTextCell = ({ export const BoardTextCell = ({

View File

@ -9,7 +9,7 @@ export const EditCellText = ({ data, cellController }: { data: string; cellContr
}, [data]); }, [data]);
useEffect(() => { useEffect(() => {
setContentRows(Math.max(1, value.split('\n').length)); setContentRows(Math.max(1, (value || '').split('\n').length));
}, [value]); }, [value]);
const onTextFieldChange = async (v: string) => { const onTextFieldChange = async (v: string) => {
@ -21,13 +21,12 @@ export const EditCellText = ({ data, cellController }: { data: string; cellContr
}; };
return ( return (
<div> <textarea
<textarea className={'h-full w-full resize-none'}
rows={contentRows} rows={contentRows}
value={value} value={value}
onChange={(e) => onTextFieldChange(e.target.value)} onChange={(e) => onTextFieldChange(e.target.value)}
onBlur={() => save()} onBlur={() => save()}
/> />
</div>
); );
}; };

View File

@ -3,56 +3,55 @@ import { useCell } from '$app/components/_shared/database-hooks/useCell';
import { CellCache } from '$app/stores/effects/database/cell/cell_cache'; import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
import { FieldController } from '$app/stores/effects/database/field/field_controller'; import { FieldController } from '$app/stores/effects/database/field/field_controller';
import { DateCellDataPB, FieldType, SelectOptionCellDataPB } from '@/services/backend'; import { DateCellDataPB, FieldType, SelectOptionCellDataPB } from '@/services/backend';
import { TextTypeSvg } from '$app/components/_shared/svg/TextTypeSvg';
import { NumberTypeSvg } from '$app/components/_shared/svg/NumberTypeSvg';
import { DateTypeSvg } from '$app/components/_shared/svg/DateTypeSvg';
import { SingleSelectTypeSvg } from '$app/components/_shared/svg/SingleSelectTypeSvg';
import { MultiSelectTypeSvg } from '$app/components/_shared/svg/MultiSelectTypeSvg';
import { ChecklistTypeSvg } from '$app/components/_shared/svg/ChecklistTypeSvg';
import { UrlTypeSvg } from '$app/components/_shared/svg/UrlTypeSvg';
import { useAppSelector } from '$app/stores/store'; import { useAppSelector } from '$app/stores/store';
import { getBgColor } from '$app/components/_shared/getColor'; import { getBgColor } from '$app/components/_shared/getColor';
import { CheckboxSvg } from '$app/components/_shared/svg/CheckboxSvg';
import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg'; import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg';
import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg'; import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
import { useState } from 'react'; import { useState } from 'react';
import { EditCellText } from '$app/components/board/EditBoardRow/EditCellText'; import { EditCellText } from '$app/components/board/EditBoardRow/EditCellText';
import { EditFieldPopup } from '$app/components/board/EditBoardRow/EditFieldPopup';
import { FieldTypeIcon } from '$app/components/board/EditBoardRow/FieldTypeIcon';
export const EditCellWrapper = ({ export const EditCellWrapper = ({
viewId,
cellIdentifier, cellIdentifier,
cellCache, cellCache,
fieldController, fieldController,
}: { }: {
viewId: string;
cellIdentifier: CellIdentifier; cellIdentifier: CellIdentifier;
cellCache: CellCache; cellCache: CellCache;
fieldController: FieldController; fieldController: FieldController;
}) => { }) => {
const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController); const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController);
const databaseStore = useAppSelector((state) => state.database); const databaseStore = useAppSelector((state) => state.database);
const [showEditField, setShowEditField] = useState(false); const [showFieldEditor, setShowFieldEditor] = useState(false);
const onEditFieldClick = () => { const onEditFieldClick = () => {
setShowEditField(true); setShowFieldEditor(true);
}; };
return ( return (
<div className={'flex w-full items-center'}> <div className={'flex w-full items-center text-xs'}>
<div <div
onClick={() => onEditFieldClick()} onClick={() => onEditFieldClick()}
className={'flex w-[180px] cursor-pointer items-center gap-2 rounded-lg px-4 py-2 hover:bg-shade-6'} className={'relative flex w-[180px] cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 hover:bg-shade-6'}
> >
<div className={'h-5 w-5 flex-shrink-0'}> <div className={'flex h-5 w-5 flex-shrink-0 items-center justify-center'}>
{cellIdentifier.fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>} <FieldTypeIcon fieldType={cellIdentifier.fieldType}></FieldTypeIcon>
{cellIdentifier.fieldType === FieldType.Number && <NumberTypeSvg></NumberTypeSvg>}
{cellIdentifier.fieldType === FieldType.DateTime && <DateTypeSvg></DateTypeSvg>}
{cellIdentifier.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
{cellIdentifier.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
{cellIdentifier.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
{cellIdentifier.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
{cellIdentifier.fieldType === FieldType.Checkbox && <CheckboxSvg></CheckboxSvg>}
</div> </div>
<span className={'overflow-hidden text-ellipsis whitespace-nowrap'}> <span className={'overflow-hidden text-ellipsis whitespace-nowrap'}>
{databaseStore.fields[cellIdentifier.fieldId].title} {databaseStore.fields[cellIdentifier.fieldId].title}
</span> </span>
{showFieldEditor && cellController && (
<EditFieldPopup
fieldName={databaseStore.fields[cellIdentifier.fieldId].title}
fieldType={cellIdentifier.fieldType}
viewId={viewId}
cellController={cellController}
onOutsideClick={() => setShowFieldEditor(false)}
fieldInfo={fieldController.getField(cellIdentifier.fieldId)}
></EditFieldPopup>
)}
</div> </div>
<div className={'flex-1 cursor-pointer rounded-lg px-4 py-2 hover:bg-shade-6'}> <div className={'flex-1 cursor-pointer rounded-lg px-4 py-2 hover:bg-shade-6'}>
{(cellIdentifier.fieldType === FieldType.SingleSelect || {(cellIdentifier.fieldType === FieldType.SingleSelect ||
@ -60,7 +59,7 @@ export const EditCellWrapper = ({
cellIdentifier.fieldType === FieldType.Checklist) && ( cellIdentifier.fieldType === FieldType.Checklist) && (
<div className={'flex items-center gap-2'}> <div className={'flex items-center gap-2'}>
{(data as SelectOptionCellDataPB | undefined)?.select_options?.map((option, index) => ( {(data as SelectOptionCellDataPB | undefined)?.select_options?.map((option, index) => (
<div className={`${getBgColor(option.color)} rounded px-2 py-0.5 text-xs`} key={index}> <div className={`${getBgColor(option.color)} rounded px-2 py-0.5`} key={index}>
{option?.name || ''} {option?.name || ''}
</div> </div>
)) || ''} )) || ''}

View File

@ -0,0 +1,80 @@
import { useEffect, useRef, useState } from 'react';
import useOutsideClick from '$app/components/_shared/useOutsideClick';
import { TrashSvg } from '$app/components/_shared/svg/TrashSvg';
import { CellController } from '$app/stores/effects/database/cell/cell_controller';
import { FieldType } from '@/services/backend';
import { FieldTypeIcon } from '$app/components/board/EditBoardRow/FieldTypeIcon';
import { FieldTypeName } from '$app/components/board/EditBoardRow/FieldTypeName';
import { useTranslation } from 'react-i18next';
import { TypeOptionController } from '$app/stores/effects/database/field/type_option/type_option_controller';
import { Some } from 'ts-results';
import { FieldInfo } from '$app/stores/effects/database/field/field_controller';
export const EditFieldPopup = ({
viewId,
fieldName,
onOutsideClick,
fieldType,
cellController,
fieldInfo,
}: {
viewId: string;
fieldName: string;
onOutsideClick?: () => void;
fieldType: FieldType;
cellController: CellController<any, any>;
fieldInfo: FieldInfo | undefined;
}) => {
const { t } = useTranslation('');
const ref = useRef<HTMLDivElement>(null);
const [name, setName] = useState('');
useOutsideClick(ref, async () => {
await save();
onOutsideClick && onOutsideClick();
});
useEffect(() => {
setName(fieldName);
}, [fieldName]);
const save = async () => {
if (!fieldInfo) return;
const controller = new TypeOptionController(viewId, Some(fieldInfo));
await controller.initialize();
await controller.setFieldName(name);
};
return (
<div ref={ref} className={`absolute left-full top-0 rounded-lg bg-white px-2 py-2 shadow-md`}>
<div className={'flex flex-col gap-4 p-4'}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
onBlur={() => save()}
className={'border-shades-3 flex-1 rounded border bg-main-selector p-1'}
/>
<button
className={
'flex cursor-pointer items-center gap-2 rounded-lg px-2 py-2 text-main-alert hover:bg-main-secondary'
}
>
<i className={'mb-0.5 h-5 w-5'}>
<TrashSvg></TrashSvg>
</i>
<span>{t('grid.field.delete')}</span>
</button>
<button
className={'flex cursor-pointer items-center gap-2 rounded-lg px-2 py-2 text-black hover:bg-main-secondary'}
>
<i className={'h-5 w-5'}>
<FieldTypeIcon fieldType={fieldType}></FieldTypeIcon>
</i>
<span>
<FieldTypeName fieldType={fieldType}></FieldTypeName>
</span>
</button>
</div>
</div>
);
};

View File

@ -4,6 +4,7 @@ import { DatabaseController } from '$app/stores/effects/database/database_contro
import { RowInfo } from '$app/stores/effects/database/row/row_cache'; import { RowInfo } from '$app/stores/effects/database/row/row_cache';
import { EditCellWrapper } from '$app/components/board/EditBoardRow/EditCellWrapper'; import { EditCellWrapper } from '$app/components/board/EditBoardRow/EditCellWrapper';
import AddSvg from '$app/components/_shared/svg/AddSvg'; import AddSvg from '$app/components/_shared/svg/AddSvg';
import { useTranslation } from 'react-i18next';
export const EditRow = ({ export const EditRow = ({
onClose, onClose,
@ -17,6 +18,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('');
return ( return (
<div className={'fixed inset-0 z-20 flex items-center justify-center bg-black/30 backdrop-blur-sm'}> <div className={'fixed inset-0 z-20 flex items-center justify-center bg-black/30 backdrop-blur-sm'}>
@ -26,10 +28,11 @@ export const EditRow = ({
<CloseSvg></CloseSvg> <CloseSvg></CloseSvg>
</button> </button>
</div> </div>
<div className={'flex flex-1 flex-col gap-4'}> <div className={'flex flex-1 flex-col gap-2'}>
{cells.map((cell, cellIndex) => ( {cells.map((cell, cellIndex) => (
<EditCellWrapper <EditCellWrapper
key={cellIndex} key={cellIndex}
viewId={viewId}
cellIdentifier={cell.cellIdentifier} cellIdentifier={cell.cellIdentifier}
cellCache={controller.databaseViewCache.getRowCache().getCellCache()} cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController} fieldController={controller.fieldController}
@ -44,7 +47,7 @@ export const EditRow = ({
<i className={'h-5 w-5'}> <i className={'h-5 w-5'}>
<AddSvg></AddSvg> <AddSvg></AddSvg>
</i> </i>
<span>New Column</span> <span>{t('grid.field.newColumn')}</span>
</button> </button>
</div> </div>
</div> </div>

View File

@ -0,0 +1,24 @@
import { FieldType } from '@/services/backend';
import { TextTypeSvg } from '$app/components/_shared/svg/TextTypeSvg';
import { NumberTypeSvg } from '$app/components/_shared/svg/NumberTypeSvg';
import { DateTypeSvg } from '$app/components/_shared/svg/DateTypeSvg';
import { SingleSelectTypeSvg } from '$app/components/_shared/svg/SingleSelectTypeSvg';
import { MultiSelectTypeSvg } from '$app/components/_shared/svg/MultiSelectTypeSvg';
import { ChecklistTypeSvg } from '$app/components/_shared/svg/ChecklistTypeSvg';
import { UrlTypeSvg } from '$app/components/_shared/svg/UrlTypeSvg';
import { CheckboxSvg } from '$app/components/_shared/svg/CheckboxSvg';
export const FieldTypeIcon = ({ fieldType }: { fieldType: FieldType }) => {
return (
<>
{fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>}
{fieldType === FieldType.Number && <NumberTypeSvg></NumberTypeSvg>}
{fieldType === FieldType.DateTime && <DateTypeSvg></DateTypeSvg>}
{fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
{fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
{fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
{fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
{fieldType === FieldType.Checkbox && <CheckboxSvg></CheckboxSvg>}
</>
);
};

View File

@ -0,0 +1,18 @@
import { FieldType } from '@/services/backend';
import { useTranslation } from 'react-i18next';
export const FieldTypeName = ({ fieldType }: { fieldType: FieldType }) => {
const { t } = useTranslation('');
return (
<>
{fieldType === FieldType.RichText && t('grid.field.textFieldName')}
{fieldType === FieldType.Number && t('grid.field.numberFieldName')}
{fieldType === FieldType.DateTime && t('grid.field.dateFieldName')}
{fieldType === FieldType.SingleSelect && t('grid.field.singleSelectFieldName')}
{fieldType === FieldType.MultiSelect && t('grid.field.multiSelectFieldName')}
{fieldType === FieldType.Checklist && t('grid.field.checklistFieldName')}
{fieldType === FieldType.URL && t('grid.field.urlFieldName')}
{fieldType === FieldType.Checkbox && t('grid.field.checkboxFieldName')}
</>
);
};

View File

@ -41,6 +41,9 @@ module.exports = {
fiol: '#2C144B', fiol: '#2C144B',
}, },
}, },
boxShadow: {
md: '0px 0px 20px rgba(0, 0, 0, 0.1);',
},
}, },
}, },
plugins: [], plugins: [],