feat/implement field options edit and change field option type functionality

This commit is contained in:
Mike Abebe 2023-04-09 14:34:32 +03:00
parent e3b7864a91
commit a33fc3dd60
2 changed files with 129 additions and 28 deletions

View File

@ -1,43 +1,21 @@
import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
import AddSvg from '../../_shared/svg/AddSvg';
import { useGridTableHeaderHooks } from './GridTableHeader.hooks';
import { TextTypeSvg } from '../../_shared/svg/TextTypeSvg';
import { NumberTypeSvg } from '../../_shared/svg/NumberTypeSvg';
import { DateTypeSvg } from '../../_shared/svg/DateTypeSvg';
import { SingleSelectTypeSvg } from '../../_shared/svg/SingleSelectTypeSvg';
import { MultiSelectTypeSvg } from '../../_shared/svg/MultiSelectTypeSvg';
import { ChecklistTypeSvg } from '../../_shared/svg/ChecklistTypeSvg';
import { UrlTypeSvg } from '../../_shared/svg/UrlTypeSvg';
import { FieldType } from '@/services/backend/models/flowy-database/field_entities';
import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
import { GridTableHeaderItem } from './GridTableHeaderItem';
import { useTranslation } from 'react-i18next';
export const GridTableHeader = ({ controller }: { controller: DatabaseController }) => {
const { fields, onAddField } = useGridTableHeaderHooks(controller);
const { t } = useTranslation('');
return (
<>
<thead>
<tr>
{fields.map((field) => {
return (
<th key={field.fieldId} className='m-0 border border-l-0 border-shade-6 p-0'>
<div className={'flex cursor-pointer items-center px-4 py-2 hover:bg-main-secondary'}>
<i className={'mr-2 h-5 w-5 text-shade-3'}>
{field.fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>}
{field.fieldType === FieldType.Number && <NumberTypeSvg></NumberTypeSvg>}
{field.fieldType === FieldType.DateTime && <DateTypeSvg></DateTypeSvg>}
{field.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
{field.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
{field.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
{field.fieldType === FieldType.Checkbox && <ChecklistTypeSvg></ChecklistTypeSvg>}
{field.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
</i>
<span>{field.name}</span>
</div>
</th>
);
{fields.map((field, i) => {
return <GridTableHeaderItem field={field} controller={controller} key={i} />;
})}
<th className='m-0 w-40 border border-r-0 border-shade-6 p-0'>

View File

@ -0,0 +1,123 @@
import { CellIdentifier } from '@/appflowy_app/stores/effects/database/cell/cell_bd_svc';
import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
import { TypeOptionController } from '@/appflowy_app/stores/effects/database/field/type_option/type_option_controller';
import { FieldType } from '@/services/backend';
import { useState, useRef } from 'react';
import { Some } from 'ts-results';
import { ChangeFieldTypePopup } from '../../_shared/EditRow/ChangeFieldTypePopup';
import { EditFieldPopup } from '../../_shared/EditRow/EditFieldPopup';
import { ChecklistTypeSvg } from '../../_shared/svg/ChecklistTypeSvg';
import { DateTypeSvg } from '../../_shared/svg/DateTypeSvg';
import { MultiSelectTypeSvg } from '../../_shared/svg/MultiSelectTypeSvg';
import { NumberTypeSvg } from '../../_shared/svg/NumberTypeSvg';
import { SingleSelectTypeSvg } from '../../_shared/svg/SingleSelectTypeSvg';
import { TextTypeSvg } from '../../_shared/svg/TextTypeSvg';
import { UrlTypeSvg } from '../../_shared/svg/UrlTypeSvg';
export const GridTableHeaderItem = ({
controller,
field,
}: {
controller: DatabaseController;
field: {
fieldId: string;
name: string;
fieldType: FieldType;
};
}) => {
const [showFieldEditor, setShowFieldEditor] = useState(false);
const [editFieldTop, setEditFieldTop] = useState(0);
const [editFieldRight, setEditFieldRight] = useState(0);
const [showChangeFieldTypePopup, setShowChangeFieldTypePopup] = useState(false);
const [changeFieldTypeTop, setChangeFieldTypeTop] = useState(0);
const [changeFieldTypeRight, setChangeFieldTypeRight] = useState(0);
const [editingField, setEditingField] = useState<{
fieldId: string;
name: string;
fieldType: FieldType;
} | null>(null);
const ref = useRef<HTMLDivElement>(null);
const changeFieldType = async (newType: FieldType) => {
if (!editingField) return;
const currentField = controller.fieldController.getField(editingField.fieldId);
if (!currentField) return;
const typeOptionController = new TypeOptionController(controller.viewId, Some(currentField));
await typeOptionController.switchToField(newType);
setEditingField({
...editingField,
fieldType: newType,
});
setShowChangeFieldTypePopup(false);
};
return (
<th key={field.fieldId} className='m-0 border border-l-0 border-shade-6 p-0'>
<div
className={'flex w-full cursor-pointer items-center px-4 py-2 hover:bg-main-secondary'}
ref={ref}
onClick={() => {
if (!ref.current) return;
const { top, left } = ref.current.getBoundingClientRect();
setEditFieldRight(left - 10);
setEditFieldTop(top + 35);
setEditingField(field);
setShowFieldEditor(true);
}}
>
<i className={'mr-2 h-5 w-5 text-shade-3'}>
{field.fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>}
{field.fieldType === FieldType.Number && <NumberTypeSvg></NumberTypeSvg>}
{field.fieldType === FieldType.DateTime && <DateTypeSvg></DateTypeSvg>}
{field.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
{field.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
{field.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
{field.fieldType === FieldType.Checkbox && <ChecklistTypeSvg></ChecklistTypeSvg>}
{field.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
</i>
<span>{field.name}</span>
{showFieldEditor && editingField && (
<EditFieldPopup
top={editFieldTop}
right={editFieldRight}
cellIdentifier={
{
fieldId: editingField.fieldId,
fieldType: editingField.fieldType,
viewId: controller.viewId,
} as CellIdentifier
}
viewId={controller.viewId}
onOutsideClick={() => {
setShowFieldEditor(false);
}}
fieldInfo={controller.fieldController.getField(editingField.fieldId)}
changeFieldTypeClick={(buttonTop, buttonRight) => {
setChangeFieldTypeTop(buttonTop);
setChangeFieldTypeRight(buttonRight);
setShowChangeFieldTypePopup(true);
}}
></EditFieldPopup>
)}
{showChangeFieldTypePopup && (
<ChangeFieldTypePopup
top={changeFieldTypeTop}
right={changeFieldTypeRight}
onClick={(newType) => changeFieldType(newType)}
onOutsideClick={() => setShowChangeFieldTypePopup(false)}
></ChangeFieldTypePopup>
)}
</div>
</th>
);
};