diff --git a/packages/twenty-front/src/modules/object-record/components/RecordEditableName.tsx b/packages/twenty-front/src/modules/object-record/components/RecordEditableName.tsx new file mode 100644 index 000000000..1877f0794 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/components/RecordEditableName.tsx @@ -0,0 +1,100 @@ +import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; +import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; +import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerInput'; +import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import styled from '@emotion/styled'; +import { useEffect, useState } from 'react'; +import { capitalize } from '~/utils/string/capitalize'; + +const StyledEditableTitleContainer = styled.div` + align-items: flex-start; + display: flex; + flex-direction: row; +`; + +const StyledEditableTitlePrefix = styled.div` + color: ${({ theme }) => theme.font.color.tertiary}; + line-height: 24px; + display: flex; + flex-direction: row; + padding: ${({ theme }) => theme.spacing(0.75)}; + gap: ${({ theme }) => theme.spacing(1)}; +`; + +export const RecordEditableName = ({ + objectNameSingular, + objectRecordId, + objectLabelPlural, +}: { + objectNameSingular: string; + objectRecordId: string; + objectLabelPlural: string; +}) => { + const [isRenaming, setIsRenaming] = useState(false); + const { record, loading } = useFindOneRecord({ + objectNameSingular, + objectRecordId, + recordGqlFields: { + name: true, + }, + }); + + const [recordName, setRecordName] = useState(record?.name); + + const { updateOneRecord } = useUpdateOneRecord({ + objectNameSingular, + recordGqlFields: { + name: true, + }, + }); + + const handleSubmit = (value: string) => { + updateOneRecord({ + idToUpdate: objectRecordId, + updateOneRecordInput: { + name: value, + }, + }); + setIsRenaming(false); + }; + + const handleCancel = () => { + setRecordName(record?.name); + setIsRenaming(false); + }; + + useEffect(() => { + setRecordName(record?.name); + }, [record?.name]); + + if (loading) { + return null; + } + + return ( + + + {capitalize(objectLabelPlural)} + {' / '} + + {isRenaming ? ( + + ) : ( + setIsRenaming(true)} + rightOptions={undefined} + className="navigation-drawer-item" + active + /> + )} + + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts index 786d20299..f2cac6170 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts @@ -204,5 +204,6 @@ export const useRecordShowPagePagination = ( navigateToIndexView, canNavigateToNextRecord, canNavigateToPreviousRecord, + objectMetadataItem, }; }; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerInput.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerInput.tsx index 95b7b52e6..28bdad67b 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerInput.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerInput.tsx @@ -17,7 +17,7 @@ import { useHotkeyScopeOnMount } from '~/hooks/useHotkeyScopeOnMount'; type NavigationDrawerInputProps = { className?: string; - Icon: IconComponent | ((props: TablerIconsProps) => JSX.Element); + Icon?: IconComponent | ((props: TablerIconsProps) => JSX.Element); value: string; onChange: (value: string) => void; onSubmit: (value: string) => void; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx index eb58bb6ec..c04c4fde1 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx @@ -32,7 +32,7 @@ export type NavigationDrawerItemProps = { subItemState?: NavigationDrawerSubItemState; to?: string; onClick?: () => void; - Icon: IconComponent | ((props: TablerIconsProps) => JSX.Element); + Icon?: IconComponent | ((props: TablerIconsProps) => JSX.Element); active?: boolean; danger?: boolean; soon?: boolean; @@ -257,6 +257,7 @@ export const NavigationDrawerItem = ({ const [isNavigationDrawerExpanded, setIsNavigationDrawerExpanded] = useRecoilState(isNavigationDrawerExpandedState); const showBreadcrumb = indentationLevel === 2; + const showStyledSpacer = !!soon || !!count || !!keyboard || !!rightOptions; const handleItemClick = () => { if (isMobile) { @@ -320,7 +321,7 @@ export const NavigationDrawerItem = ({ - + {showStyledSpacer && } {soon && ( @@ -341,8 +342,9 @@ export const NavigationDrawerItem = ({ )} - - {rightOptions && ( + + {rightOptions && ( + { e.stopPropagation(); @@ -358,8 +360,8 @@ export const NavigationDrawerItem = ({ {rightOptions} - )} - + + )} diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormUpdateRecord.tsx b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormUpdateRecord.tsx index 2061a6900..e36d19ebb 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormUpdateRecord.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormUpdateRecord.tsx @@ -1,7 +1,5 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { Select, SelectOption } from '@/ui/input/components/Select'; -import { WorkflowSingleRecordPicker } from '@/workflow/components/WorkflowSingleRecordPicker'; -import { WorkflowStepHeader } from '@/workflow/components/WorkflowStepHeader'; import { WorkflowUpdateRecordAction } from '@/workflow/types/Workflow'; import { useTheme } from '@emotion/react'; import { useEffect, useState } from 'react'; @@ -15,7 +13,9 @@ import { import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition'; import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput'; import { FormMultiSelectFieldInput } from '@/object-record/record-field/form-types/components/FormMultiSelectFieldInput'; +import { WorkflowSingleRecordPicker } from '@/workflow/components/WorkflowSingleRecordPicker'; import { WorkflowStepBody } from '@/workflow/components/WorkflowStepBody'; +import { WorkflowStepHeader } from '@/workflow/components/WorkflowStepHeader'; import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker'; import { JsonValue } from 'type-fest'; import { useDebouncedCallback } from 'use-debounce'; @@ -176,6 +176,7 @@ export const WorkflowEditActionFormUpdateRecord = ({ initialTitle={headerTitle} headerType="Action" /> +