mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: column rename
This commit is contained in:
parent
c453d734ab
commit
4545410703
@ -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 = ({
|
||||||
|
@ -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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
)) || ''}
|
)) || ''}
|
||||||
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
@ -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>}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -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')}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -41,6 +41,9 @@ module.exports = {
|
|||||||
fiol: '#2C144B',
|
fiol: '#2C144B',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
boxShadow: {
|
||||||
|
md: '0px 0px 20px rgba(0, 0, 0, 0.1);',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
|
Loading…
Reference in New Issue
Block a user