瀏覽代碼

chore: column rename

ascarbek 2 年之前
父節點
當前提交
13e9b29eef

+ 3 - 3
frontend/appflowy_tauri/src/appflowy_app/components/board/BoardTextCell.tsx

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

+ 8 - 9
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/EditCellText.tsx

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

+ 21 - 22
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/EditCellWrapper.tsx

@@ -3,56 +3,55 @@ import { useCell } from '$app/components/_shared/database-hooks/useCell';
 import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
 import { FieldController } from '$app/stores/effects/database/field/field_controller';
 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 { getBgColor } from '$app/components/_shared/getColor';
-import { CheckboxSvg } from '$app/components/_shared/svg/CheckboxSvg';
 import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg';
 import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
 import { useState } from 'react';
 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 = ({
+  viewId,
   cellIdentifier,
   cellCache,
   fieldController,
 }: {
+  viewId: string;
   cellIdentifier: CellIdentifier;
   cellCache: CellCache;
   fieldController: FieldController;
 }) => {
   const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController);
   const databaseStore = useAppSelector((state) => state.database);
-  const [showEditField, setShowEditField] = useState(false);
+  const [showFieldEditor, setShowFieldEditor] = useState(false);
   const onEditFieldClick = () => {
-    setShowEditField(true);
+    setShowFieldEditor(true);
   };
 
   return (
-    <div className={'flex w-full items-center'}>
+    <div className={'flex w-full items-center text-xs'}>
       <div
         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'}>
-          {cellIdentifier.fieldType === FieldType.RichText && <TextTypeSvg></TextTypeSvg>}
-          {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 className={'flex h-5 w-5 flex-shrink-0 items-center justify-center'}>
+          <FieldTypeIcon fieldType={cellIdentifier.fieldType}></FieldTypeIcon>
         </div>
         <span className={'overflow-hidden text-ellipsis whitespace-nowrap'}>
           {databaseStore.fields[cellIdentifier.fieldId].title}
         </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 className={'flex-1 cursor-pointer rounded-lg px-4 py-2 hover:bg-shade-6'}>
         {(cellIdentifier.fieldType === FieldType.SingleSelect ||
@@ -60,7 +59,7 @@ export const EditCellWrapper = ({
           cellIdentifier.fieldType === FieldType.Checklist) && (
           <div className={'flex items-center gap-2'}>
             {(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 || ''}
               </div>
             )) || ''}

+ 80 - 0
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/EditFieldPopup.tsx

@@ -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>
+  );
+};

+ 5 - 2
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/EditRow.tsx

@@ -4,6 +4,7 @@ import { DatabaseController } from '$app/stores/effects/database/database_contro
 import { RowInfo } from '$app/stores/effects/database/row/row_cache';
 import { EditCellWrapper } from '$app/components/board/EditBoardRow/EditCellWrapper';
 import AddSvg from '$app/components/_shared/svg/AddSvg';
+import { useTranslation } from 'react-i18next';
 
 export const EditRow = ({
   onClose,
@@ -17,6 +18,7 @@ export const EditRow = ({
   rowInfo: RowInfo;
 }) => {
   const { cells, onNewColumnClick } = useRow(viewId, controller, rowInfo);
+  const { t } = useTranslation('');
 
   return (
     <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>
           </button>
         </div>
-        <div className={'flex flex-1 flex-col gap-4'}>
+        <div className={'flex flex-1 flex-col gap-2'}>
           {cells.map((cell, cellIndex) => (
             <EditCellWrapper
               key={cellIndex}
+              viewId={viewId}
               cellIdentifier={cell.cellIdentifier}
               cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
               fieldController={controller.fieldController}
@@ -44,7 +47,7 @@ export const EditRow = ({
             <i className={'h-5 w-5'}>
               <AddSvg></AddSvg>
             </i>
-            <span>New Column</span>
+            <span>{t('grid.field.newColumn')}</span>
           </button>
         </div>
       </div>

+ 24 - 0
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/FieldTypeIcon.tsx

@@ -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>}
+    </>
+  );
+};

+ 18 - 0
frontend/appflowy_tauri/src/appflowy_app/components/board/EditBoardRow/FieldTypeName.tsx

@@ -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')}
+    </>
+  );
+};

+ 3 - 0
frontend/appflowy_tauri/tailwind.config.cjs

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