mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat/implement field options edit and change field option type functionality
This commit is contained in:
parent
e3b7864a91
commit
a33fc3dd60
@ -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'>
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user