GridTableHeaderItem.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { CellIdentifier } from '@/appflowy_app/stores/effects/database/cell/cell_bd_svc';
  2. import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
  3. import { TypeOptionController } from '@/appflowy_app/stores/effects/database/field/type_option/type_option_controller';
  4. import { FieldType } from '@/services/backend';
  5. import { useState, useRef } from 'react';
  6. import { Some } from 'ts-results';
  7. import { ChangeFieldTypePopup } from '../../_shared/EditRow/ChangeFieldTypePopup';
  8. import { EditFieldPopup } from '../../_shared/EditRow/EditFieldPopup';
  9. import { ChecklistTypeSvg } from '../../_shared/svg/ChecklistTypeSvg';
  10. import { DateTypeSvg } from '../../_shared/svg/DateTypeSvg';
  11. import { MultiSelectTypeSvg } from '../../_shared/svg/MultiSelectTypeSvg';
  12. import { NumberTypeSvg } from '../../_shared/svg/NumberTypeSvg';
  13. import { SingleSelectTypeSvg } from '../../_shared/svg/SingleSelectTypeSvg';
  14. import { TextTypeSvg } from '../../_shared/svg/TextTypeSvg';
  15. import { UrlTypeSvg } from '../../_shared/svg/UrlTypeSvg';
  16. export const GridTableHeaderItem = ({
  17. controller,
  18. field,
  19. }: {
  20. controller: DatabaseController;
  21. field: {
  22. fieldId: string;
  23. name: string;
  24. fieldType: FieldType;
  25. };
  26. }) => {
  27. const [showFieldEditor, setShowFieldEditor] = useState(false);
  28. const [editFieldTop, setEditFieldTop] = useState(0);
  29. const [editFieldRight, setEditFieldRight] = useState(0);
  30. const [showChangeFieldTypePopup, setShowChangeFieldTypePopup] = useState(false);
  31. const [changeFieldTypeTop, setChangeFieldTypeTop] = useState(0);
  32. const [changeFieldTypeRight, setChangeFieldTypeRight] = useState(0);
  33. const [editingField, setEditingField] = useState<{
  34. fieldId: string;
  35. name: string;
  36. fieldType: FieldType;
  37. } | null>(null);
  38. const ref = useRef<HTMLDivElement>(null);
  39. const changeFieldType = async (newType: FieldType) => {
  40. if (!editingField) return;
  41. const currentField = controller.fieldController.getField(editingField.fieldId);
  42. if (!currentField) return;
  43. const typeOptionController = new TypeOptionController(controller.viewId, Some(currentField));
  44. await typeOptionController.switchToField(newType);
  45. setEditingField({
  46. ...editingField,
  47. fieldType: newType,
  48. });
  49. setShowChangeFieldTypePopup(false);
  50. };
  51. return (
  52. <th key={field.fieldId} className='m-0 border border-l-0 border-shade-6 p-0'>
  53. <div
  54. className={'flex w-full cursor-pointer items-center px-4 py-2 hover:bg-main-secondary'}
  55. ref={ref}
  56. onClick={() => {
  57. if (!ref.current) return;
  58. const { top, left } = ref.current.getBoundingClientRect();
  59. setEditFieldRight(left - 10);
  60. setEditFieldTop(top + 35);
  61. setEditingField(field);
  62. setShowFieldEditor(true);
  63. }}
  64. >
  65. <i className={'mr-2 h-5 w-5 text-shade-3'}>
  66. {field.fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>}
  67. {field.fieldType === FieldType.Number && <NumberTypeSvg></NumberTypeSvg>}
  68. {field.fieldType === FieldType.DateTime && <DateTypeSvg></DateTypeSvg>}
  69. {field.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
  70. {field.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
  71. {field.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
  72. {field.fieldType === FieldType.Checkbox && <ChecklistTypeSvg></ChecklistTypeSvg>}
  73. {field.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
  74. </i>
  75. <span>{field.name}</span>
  76. {showFieldEditor && editingField && (
  77. <EditFieldPopup
  78. top={editFieldTop}
  79. left={editFieldRight}
  80. cellIdentifier={
  81. {
  82. fieldId: editingField.fieldId,
  83. fieldType: editingField.fieldType,
  84. viewId: controller.viewId,
  85. } as CellIdentifier
  86. }
  87. viewId={controller.viewId}
  88. onOutsideClick={() => {
  89. setShowFieldEditor(false);
  90. }}
  91. fieldInfo={controller.fieldController.getField(editingField.fieldId)}
  92. changeFieldTypeClick={(buttonTop, buttonRight) => {
  93. setChangeFieldTypeTop(buttonTop);
  94. setChangeFieldTypeRight(buttonRight);
  95. setShowChangeFieldTypePopup(true);
  96. }}
  97. ></EditFieldPopup>
  98. )}
  99. {showChangeFieldTypePopup && (
  100. <ChangeFieldTypePopup
  101. top={changeFieldTypeTop}
  102. left={changeFieldTypeRight}
  103. onClick={(newType) => changeFieldType(newType)}
  104. onOutsideClick={() => setShowChangeFieldTypePopup(false)}
  105. ></ChangeFieldTypePopup>
  106. )}
  107. </div>
  108. </th>
  109. );
  110. };