Various fixes (#11108)
Fixes many bug regarding TableCell and InlineCells
This commit is contained in:
@ -17,6 +17,7 @@ import { FieldContext } from '@/object-record/record-field/contexts/FieldContext
|
|||||||
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
||||||
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
|
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
|
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
|
||||||
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
||||||
|
|
||||||
@ -102,7 +103,6 @@ export const CalendarEventDetails = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId: calendarEvent.id,
|
recordId: calendarEvent.id,
|
||||||
hotkeyScope: 'calendar-event-details',
|
hotkeyScope: 'calendar-event-details',
|
||||||
recoilScopeId: `${calendarEvent.id}-${fieldName}`,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: formatFieldMetadataItemAsFieldDefinition({
|
fieldDefinition: formatFieldMetadataItemAsFieldDefinition({
|
||||||
field: fieldsByName[fieldName],
|
field: fieldsByName[fieldName],
|
||||||
@ -116,7 +116,7 @@ export const CalendarEventDetails = ({
|
|||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
value={{
|
value={{
|
||||||
instanceId: `${calendarEvent.id}-${fieldName}`,
|
instanceId: getRecordFieldInputId(calendarEvent.id, fieldName),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordInlineCell readonly />
|
<RecordInlineCell readonly />
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useMemo, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import {
|
import {
|
||||||
IconCalendar,
|
IconCalendar,
|
||||||
@ -94,11 +94,6 @@ export const AttachmentRow = ({
|
|||||||
const [attachmentFileName, setAttachmentFileName] =
|
const [attachmentFileName, setAttachmentFileName] =
|
||||||
useState(originalFileName);
|
useState(originalFileName);
|
||||||
|
|
||||||
const fieldContext = useMemo(
|
|
||||||
() => ({ recoilScopeId: attachment?.id ?? '' }),
|
|
||||||
[attachment?.id],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { destroyOneRecord: destroyOneAttachment } = useDestroyOneRecord({
|
const { destroyOneRecord: destroyOneAttachment } = useDestroyOneRecord({
|
||||||
objectNameSingular: CoreObjectNameSingular.Attachment,
|
objectNameSingular: CoreObjectNameSingular.Attachment,
|
||||||
});
|
});
|
||||||
@ -161,7 +156,13 @@ export const AttachmentRow = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FieldContext.Provider value={fieldContext as GenericFieldContextType}>
|
<FieldContext.Provider
|
||||||
|
value={
|
||||||
|
{
|
||||||
|
recordId: attachment.id,
|
||||||
|
} as GenericFieldContextType
|
||||||
|
}
|
||||||
|
>
|
||||||
<ActivityRow disabled>
|
<ActivityRow disabled>
|
||||||
<StyledLeftContent>
|
<StyledLeftContent>
|
||||||
<AttachmentIcon attachmentType={attachment.type} />
|
<AttachmentIcon attachmentType={attachment.type} />
|
||||||
|
|||||||
@ -1,23 +1,21 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Key } from 'ts-key-enum';
|
|
||||||
import { IconArrowUpRight, IconPencil } from 'twenty-ui';
|
import { IconArrowUpRight, IconPencil } from 'twenty-ui';
|
||||||
|
|
||||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||||
import { useOpenActivityTargetInlineCellEditMode } from '@/activities/inline-cell/hooks/useOpenActivityTargetInlineCellEditMode';
|
import { useOpenActivityTargetInlineCellEditMode } from '@/activities/inline-cell/hooks/useOpenActivityTargetInlineCellEditMode';
|
||||||
import { useUpdateActivityTargetFromInlineCell } from '@/activities/inline-cell/hooks/useUpdateActivityTargetFromInlineCell';
|
import { useUpdateActivityTargetFromInlineCell } from '@/activities/inline-cell/hooks/useUpdateActivityTargetFromInlineCell';
|
||||||
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
|
import { useFieldContext } from '@/object-record/hooks/useFieldContext';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { FieldFocusContextProvider } from '@/object-record/record-field/contexts/FieldFocusContextProvider';
|
import { FieldFocusContextProvider } from '@/object-record/record-field/contexts/FieldFocusContextProvider';
|
||||||
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
||||||
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { RecordInlineCellContainer } from '@/object-record/record-inline-cell/components/RecordInlineCellContainer';
|
import { RecordInlineCellContainer } from '@/object-record/record-inline-cell/components/RecordInlineCellContainer';
|
||||||
import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
||||||
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
||||||
import { MultipleRecordPicker } from '@/object-record/record-picker/multiple-record-picker/components/MultipleRecordPicker';
|
import { MultipleRecordPicker } from '@/object-record/record-picker/multiple-record-picker/components/MultipleRecordPicker';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { MultipleRecordPickerHotkeyScope } from '@/object-record/record-picker/multiple-record-picker/types/MultipleRecordPickerHotkeyScope';
|
||||||
|
|
||||||
type ActivityTargetsInlineCellProps = {
|
type ActivityTargetsInlineCellProps = {
|
||||||
activityRecordId: string;
|
activityRecordId: string;
|
||||||
@ -26,6 +24,7 @@ type ActivityTargetsInlineCellProps = {
|
|||||||
activityObjectNameSingular:
|
activityObjectNameSingular:
|
||||||
| CoreObjectNameSingular.Note
|
| CoreObjectNameSingular.Note
|
||||||
| CoreObjectNameSingular.Task;
|
| CoreObjectNameSingular.Task;
|
||||||
|
componentInstanceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ActivityTargetsInlineCell = ({
|
export const ActivityTargetsInlineCell = ({
|
||||||
@ -33,26 +32,17 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
showLabel = true,
|
showLabel = true,
|
||||||
maxWidth,
|
maxWidth,
|
||||||
activityObjectNameSingular,
|
activityObjectNameSingular,
|
||||||
|
componentInstanceId,
|
||||||
}: ActivityTargetsInlineCellProps) => {
|
}: ActivityTargetsInlineCellProps) => {
|
||||||
const { activityTargetObjectRecords } =
|
const { activityTargetObjectRecords } =
|
||||||
useActivityTargetObjectRecords(activityRecordId);
|
useActivityTargetObjectRecords(activityRecordId);
|
||||||
|
|
||||||
const multipleRecordPickerInstanceId = `multiple-record-picker-target-${activityRecordId}`;
|
const { closeInlineCell } = useInlineCell(componentInstanceId);
|
||||||
|
|
||||||
const { closeInlineCell } = useInlineCell();
|
|
||||||
|
|
||||||
const { fieldDefinition } = useContext(FieldContext);
|
const { fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
const isFieldReadOnly = useIsFieldValueReadOnly();
|
const isFieldReadOnly = useIsFieldValueReadOnly();
|
||||||
|
|
||||||
useScopedHotkeys(
|
|
||||||
Key.Escape,
|
|
||||||
() => {
|
|
||||||
closeInlineCell();
|
|
||||||
},
|
|
||||||
ActivityEditorHotkeyScope.ActivityTargets,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { FieldContextProvider: ActivityTargetsContextProvider } =
|
const { FieldContextProvider: ActivityTargetsContextProvider } =
|
||||||
useFieldContext({
|
useFieldContext({
|
||||||
objectNameSingular: activityObjectNameSingular,
|
objectNameSingular: activityObjectNameSingular,
|
||||||
@ -72,7 +62,11 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldInputScope recordFieldInputScopeId={activityRecordId}>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
|
value={{
|
||||||
|
instanceId: componentInstanceId,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<FieldFocusContextProvider>
|
<FieldFocusContextProvider>
|
||||||
{ActivityTargetsContextProvider && (
|
{ActivityTargetsContextProvider && (
|
||||||
<ActivityTargetsContextProvider>
|
<ActivityTargetsContextProvider>
|
||||||
@ -80,20 +74,20 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
value={{
|
value={{
|
||||||
buttonIcon: IconPencil,
|
buttonIcon: IconPencil,
|
||||||
customEditHotkeyScope:
|
customEditHotkeyScope:
|
||||||
ActivityEditorHotkeyScope.ActivityTargets,
|
MultipleRecordPickerHotkeyScope.MultipleRecordPicker,
|
||||||
IconLabel: showLabel ? IconArrowUpRight : undefined,
|
IconLabel: showLabel ? IconArrowUpRight : undefined,
|
||||||
showLabel: showLabel,
|
showLabel: showLabel,
|
||||||
readonly: isFieldReadOnly,
|
readonly: isFieldReadOnly,
|
||||||
labelWidth: fieldDefinition?.labelWidth,
|
labelWidth: fieldDefinition?.labelWidth,
|
||||||
editModeContent: (
|
editModeContent: (
|
||||||
<MultipleRecordPicker
|
<MultipleRecordPicker
|
||||||
componentInstanceId={multipleRecordPickerInstanceId}
|
componentInstanceId={componentInstanceId}
|
||||||
onClickOutside={() => {
|
onClickOutside={() => {
|
||||||
closeInlineCell();
|
closeInlineCell();
|
||||||
}}
|
}}
|
||||||
onChange={(morphItem) => {
|
onChange={(morphItem) => {
|
||||||
updateActivityTargetFromInlineCell({
|
updateActivityTargetFromInlineCell({
|
||||||
recordPickerInstanceId: multipleRecordPickerInstanceId,
|
recordPickerInstanceId: componentInstanceId,
|
||||||
morphItem,
|
morphItem,
|
||||||
activityTargetWithTargetRecords:
|
activityTargetWithTargetRecords:
|
||||||
activityTargetObjectRecords,
|
activityTargetObjectRecords,
|
||||||
@ -113,7 +107,7 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
),
|
),
|
||||||
onOpenEditMode: () => {
|
onOpenEditMode: () => {
|
||||||
openActivityTargetInlineCellEditMode({
|
openActivityTargetInlineCellEditMode({
|
||||||
recordPickerInstanceId: multipleRecordPickerInstanceId,
|
recordPickerInstanceId: componentInstanceId,
|
||||||
activityTargetObjectRecords,
|
activityTargetObjectRecords,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -124,6 +118,6 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
</ActivityTargetsContextProvider>
|
</ActivityTargetsContextProvider>
|
||||||
)}
|
)}
|
||||||
</FieldFocusContextProvider>
|
</FieldFocusContextProvider>
|
||||||
</RecordFieldInputScope>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -96,6 +96,7 @@ export const NoteCard = ({
|
|||||||
{NoteTargetsContextProvider && (
|
{NoteTargetsContextProvider && (
|
||||||
<NoteTargetsContextProvider>
|
<NoteTargetsContextProvider>
|
||||||
<ActivityTargetsInlineCell
|
<ActivityTargetsInlineCell
|
||||||
|
componentInstanceId={`note-card-${note.id}-targets`}
|
||||||
activityRecordId={note.id}
|
activityRecordId={note.id}
|
||||||
activityObjectNameSingular={CoreObjectNameSingular.Note}
|
activityObjectNameSingular={CoreObjectNameSingular.Note}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -135,6 +135,7 @@ export const TaskRow = ({ task }: { task: Task }) => {
|
|||||||
activityRecordId={task.id}
|
activityRecordId={task.id}
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
maxWidth={200}
|
maxWidth={200}
|
||||||
|
componentInstanceId={`task-row-targets-${task.id}`}
|
||||||
/>
|
/>
|
||||||
</TaskTargetsContextProvider>
|
</TaskTargetsContextProvider>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
export enum ActivityEditorHotkeyScope {
|
export enum ActivityEditorHotkeyScope {
|
||||||
ActivityTitle = 'activity-title',
|
ActivityTitle = 'activity-title',
|
||||||
ActivityBody = 'activity-body',
|
ActivityBody = 'activity-body',
|
||||||
ActivityTargets = 'activity-targets',
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,8 @@ import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/reco
|
|||||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||||
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
import { RecordSortsComponentInstanceContext } from '@/object-record/record-sort/states/context/RecordSortsComponentInstanceContext';
|
||||||
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
|
||||||
|
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||||
|
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||||
@ -29,7 +31,7 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { useIsMobile } from 'twenty-ui';
|
import { useIsMobile } from 'twenty-ui';
|
||||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
@ -65,9 +67,23 @@ export const CommandMenuContainer = ({
|
|||||||
|
|
||||||
useCommandMenuHotKeys();
|
useCommandMenuHotKeys();
|
||||||
|
|
||||||
|
const handleClickOutside = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() => {
|
||||||
|
const hotkeyScope = snapshot
|
||||||
|
.getLoadable(currentHotkeyScopeState)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (hotkeyScope.scope === AppHotkeyScope.CommandMenuOpen) {
|
||||||
|
closeCommandMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[closeCommandMenu],
|
||||||
|
);
|
||||||
|
|
||||||
useListenClickOutside({
|
useListenClickOutside({
|
||||||
refs: [commandMenuRef],
|
refs: [commandMenuRef],
|
||||||
callback: closeCommandMenu,
|
callback: handleClickOutside,
|
||||||
listenerId: 'COMMAND_MENU_LISTENER_ID',
|
listenerId: 'COMMAND_MENU_LISTENER_ID',
|
||||||
excludeClassNames: ['page-header-command-menu-button'],
|
excludeClassNames: ['page-header-command-menu-button'],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -77,7 +77,12 @@ export const RecordChip = ({
|
|||||||
avatarType={recordChipData.avatarType}
|
avatarType={recordChipData.avatarType}
|
||||||
avatarUrl={recordChipData.avatarUrl ?? ''}
|
avatarUrl={recordChipData.avatarUrl ?? ''}
|
||||||
className={className}
|
className={className}
|
||||||
variant={variant}
|
variant={
|
||||||
|
variant ??
|
||||||
|
(!forceDisableClick
|
||||||
|
? AvatarChipVariant.Regular
|
||||||
|
: AvatarChipVariant.Transparent)
|
||||||
|
}
|
||||||
to={to ?? getLinkToShowPage(objectNameSingular, record)}
|
to={to ?? getLinkToShowPage(objectNameSingular, record)}
|
||||||
onClick={(clickEvent) => {
|
onClick={(clickEvent) => {
|
||||||
// TODO refactor wrapper event listener to avoid colliding events
|
// TODO refactor wrapper event listener to avoid colliding events
|
||||||
|
|||||||
@ -59,7 +59,6 @@ export const useFieldContext = ({
|
|||||||
key={objectRecordId + fieldMetadataItem.id}
|
key={objectRecordId + fieldMetadataItem.id}
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
recoilScopeId: objectRecordId + fieldMetadataItem.id,
|
|
||||||
isLabelIdentifier,
|
isLabelIdentifier,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'
|
|||||||
import { getFieldButtonIcon } from '@/object-record/record-field/utils/getFieldButtonIcon';
|
import { getFieldButtonIcon } from '@/object-record/record-field/utils/getFieldButtonIcon';
|
||||||
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
||||||
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
export const RecordBoardCardBody = ({
|
export const RecordBoardCardBody = ({
|
||||||
@ -43,7 +44,6 @@ export const RecordBoardCardBody = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId,
|
recordId,
|
||||||
maxWidth: 156,
|
maxWidth: 156,
|
||||||
recoilScopeId: `board-card-${recordId}-${fieldDefinition.fieldMetadataId}`,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
disableTooltip: false,
|
disableTooltip: false,
|
||||||
@ -64,7 +64,11 @@ export const RecordBoardCardBody = ({
|
|||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
value={{
|
value={{
|
||||||
instanceId: `board-card-${recordId}-${fieldDefinition.fieldMetadataId}`,
|
instanceId: getRecordFieldInputId(
|
||||||
|
recordId,
|
||||||
|
fieldDefinition.metadata.fieldName,
|
||||||
|
'record-board-card',
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordInlineCell />
|
<RecordInlineCell />
|
||||||
|
|||||||
@ -10,11 +10,8 @@ import { PhonesFieldInput } from '@/object-record/record-field/meta-types/input/
|
|||||||
import { RawJsonFieldInput } from '@/object-record/record-field/meta-types/input/components/RawJsonFieldInput';
|
import { RawJsonFieldInput } from '@/object-record/record-field/meta-types/input/components/RawJsonFieldInput';
|
||||||
import { RelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/components/RelationFromManyFieldInput';
|
import { RelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/components/RelationFromManyFieldInput';
|
||||||
import { SelectFieldInput } from '@/object-record/record-field/meta-types/input/components/SelectFieldInput';
|
import { SelectFieldInput } from '@/object-record/record-field/meta-types/input/components/SelectFieldInput';
|
||||||
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
|
|
||||||
import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones';
|
import { isFieldPhones } from '@/object-record/record-field/types/guards/isFieldPhones';
|
||||||
import { isFieldRelationFromManyObjects } from '@/object-record/record-field/types/guards/isFieldRelationFromManyObjects';
|
import { isFieldRelationFromManyObjects } from '@/object-record/record-field/types/guards/isFieldRelationFromManyObjects';
|
||||||
import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject';
|
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
|
||||||
|
|
||||||
import { ArrayFieldInput } from '@/object-record/record-field/meta-types/input/components/ArrayFieldInput';
|
import { ArrayFieldInput } from '@/object-record/record-field/meta-types/input/components/ArrayFieldInput';
|
||||||
import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress';
|
import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress';
|
||||||
@ -30,6 +27,7 @@ import { isFieldMultiSelect } from '@/object-record/record-field/types/guards/is
|
|||||||
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
|
||||||
import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating';
|
import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating';
|
||||||
import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson';
|
import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson';
|
||||||
|
import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject';
|
||||||
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
||||||
import { FieldContext } from '../contexts/FieldContext';
|
import { FieldContext } from '../contexts/FieldContext';
|
||||||
import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput';
|
import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput';
|
||||||
@ -58,7 +56,6 @@ type FieldInputProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const FieldInput = ({
|
export const FieldInput = ({
|
||||||
recordFieldInputdId,
|
|
||||||
onCancel,
|
onCancel,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onEnter,
|
onEnter,
|
||||||
@ -71,9 +68,7 @@ export const FieldInput = ({
|
|||||||
const { fieldDefinition } = useContext(FieldContext);
|
const { fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldInputScope
|
<>
|
||||||
recordFieldInputScopeId={getScopeIdFromComponentId(recordFieldInputdId)}
|
|
||||||
>
|
|
||||||
{isFieldRelationToOneObject(fieldDefinition) ? (
|
{isFieldRelationToOneObject(fieldDefinition) ? (
|
||||||
<RelationToOneFieldInput onSubmit={onSubmit} onCancel={onCancel} />
|
<RelationToOneFieldInput onSubmit={onSubmit} onCancel={onCancel} />
|
||||||
) : isFieldRelationFromManyObjects(fieldDefinition) ? (
|
) : isFieldRelationFromManyObjects(fieldDefinition) ? (
|
||||||
@ -173,6 +168,6 @@ export const FieldInput = ({
|
|||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
)}
|
)}
|
||||||
</RecordFieldInputScope>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -23,7 +23,6 @@ export type GenericFieldContextType = {
|
|||||||
fieldDefinition: FieldDefinition<FieldMetadata>;
|
fieldDefinition: FieldDefinition<FieldMetadata>;
|
||||||
useUpdateRecord?: RecordUpdateHook;
|
useUpdateRecord?: RecordUpdateHook;
|
||||||
recordId: string;
|
recordId: string;
|
||||||
recoilScopeId?: string;
|
|
||||||
hotkeyScope: string;
|
hotkeyScope: string;
|
||||||
isLabelIdentifier: boolean;
|
isLabelIdentifier: boolean;
|
||||||
labelIdentifierLink?: string;
|
labelIdentifierLink?: string;
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
import { RecordFieldInputScopeInternalContext } from '@/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext';
|
|
||||||
import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector';
|
|
||||||
import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
|
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
|
||||||
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
|
|
||||||
import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector';
|
|
||||||
|
|
||||||
export const useRecordFieldInputStates = <FieldValue>(
|
|
||||||
recordFieldInputId?: string,
|
|
||||||
) => {
|
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
|
||||||
RecordFieldInputScopeInternalContext,
|
|
||||||
getScopeIdOrUndefinedFromComponentId(recordFieldInputId),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
getDraftValueSelector: extractComponentSelector<
|
|
||||||
FieldInputDraftValue<FieldValue> | undefined
|
|
||||||
>(recordFieldInputDraftValueComponentSelector, scopeId),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -9,7 +9,6 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'
|
|||||||
import { computeDraftValueFromFieldValue } from '@/object-record/record-field/utils/computeDraftValueFromFieldValue';
|
import { computeDraftValueFromFieldValue } from '@/object-record/record-field/utils/computeDraftValueFromFieldValue';
|
||||||
import { computeDraftValueFromString } from '@/object-record/record-field/utils/computeDraftValueFromString';
|
import { computeDraftValueFromString } from '@/object-record/record-field/utils/computeDraftValueFromString';
|
||||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
|
||||||
import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector';
|
import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector';
|
||||||
|
|
||||||
export const useInitDraftValueV2 = <FieldValue>() => {
|
export const useInitDraftValueV2 = <FieldValue>() => {
|
||||||
@ -19,19 +18,19 @@ export const useInitDraftValueV2 = <FieldValue>() => {
|
|||||||
value,
|
value,
|
||||||
recordId,
|
recordId,
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
|
fieldComponentInstanceId,
|
||||||
}: {
|
}: {
|
||||||
value?: string;
|
value?: string;
|
||||||
recordId: string;
|
recordId: string;
|
||||||
fieldDefinition: FieldDefinition<FieldMetadata>;
|
fieldDefinition: FieldDefinition<FieldMetadata>;
|
||||||
|
fieldComponentInstanceId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const recordFieldInputScopeId = `${getRecordFieldInputId(
|
|
||||||
recordId,
|
|
||||||
fieldDefinition?.metadata?.fieldName,
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
const getDraftValueSelector = extractComponentSelector<
|
const getDraftValueSelector = extractComponentSelector<
|
||||||
FieldInputDraftValue<FieldValue> | undefined
|
FieldInputDraftValue<FieldValue> | undefined
|
||||||
>(recordFieldInputDraftValueComponentSelector, recordFieldInputScopeId);
|
>(
|
||||||
|
recordFieldInputDraftValueComponentSelector,
|
||||||
|
fieldComponentInstanceId,
|
||||||
|
);
|
||||||
|
|
||||||
const recordFieldValue = snapshot
|
const recordFieldValue = snapshot
|
||||||
.getLoadable(
|
.getLoadable(
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useRecordFieldInputStates } from '@/object-record/record-field/hooks/internal/useRecordFieldInputStates';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector';
|
||||||
import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
|
import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
|
||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
|
import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector';
|
||||||
|
|
||||||
export const useRecordFieldInput = <FieldValue>(
|
export const useRecordFieldInput = <FieldValue>() => {
|
||||||
recordFieldInputId?: string,
|
const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
) => {
|
RecordFieldComponentInstanceContext,
|
||||||
const { scopeId, getDraftValueSelector } =
|
);
|
||||||
useRecordFieldInputStates<FieldValue>(recordFieldInputId);
|
|
||||||
|
const getDraftValueSelector = extractComponentSelector<
|
||||||
|
FieldInputDraftValue<FieldValue> | undefined
|
||||||
|
>(
|
||||||
|
recordFieldInputDraftValueComponentSelector,
|
||||||
|
recordFieldComponentInstanceId,
|
||||||
|
);
|
||||||
|
|
||||||
const setDraftValue = useSetRecoilState(getDraftValueSelector());
|
const setDraftValue = useSetRecoilState(getDraftValueSelector());
|
||||||
|
|
||||||
@ -26,7 +35,6 @@ export const useRecordFieldInput = <FieldValue>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scopeId,
|
|
||||||
setDraftValue,
|
setDraftValue,
|
||||||
getDraftValueSelector,
|
getDraftValueSelector,
|
||||||
isDraftValueEmpty,
|
isDraftValueEmpty,
|
||||||
|
|||||||
@ -19,7 +19,6 @@ export const FieldContextProvider = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId: recordId ?? '1',
|
recordId: recordId ?? '1',
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
recoilScopeId: '1',
|
|
||||||
hotkeyScope: 'hotkey-scope',
|
hotkeyScope: 'hotkey-scope',
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
useUpdateRecord: () => [() => undefined, {}],
|
useUpdateRecord: () => [() => undefined, {}],
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export const useAddressField = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldAddressValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldAddressValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@ export const useCurrencyField = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldCurrencyValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldCurrencyValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,7 @@ export const useDateField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { setDraftValue } = useRecordFieldInput<FieldDateValue>(
|
const { setDraftValue } = useRecordFieldInput<FieldDateValue>();
|
||||||
`${recordId}-${fieldName}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
|
|||||||
@ -29,9 +29,7 @@ export const useDateTimeField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { setDraftValue } = useRecordFieldInput<FieldDateTimeValue>(
|
const { setDraftValue } = useRecordFieldInput<FieldDateTimeValue>();
|
||||||
`${recordId}-${fieldName}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export const useEmailsField = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldEmailsValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldEmailsValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export const useFullNameField = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldFullNameValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldFullNameValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ export const useJsonField = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldJsonValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldJsonValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export const useLinksField = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldLinksValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldLinksValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export const useMultiSelectField = () => {
|
|||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldMultiSelectValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldMultiSelectValue>();
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export const useNumberField = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldNumberValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldNumberValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export const usePhonesField = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldPhonesValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldPhonesValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -28,9 +28,8 @@ export const useRelationField = <T extends ObjectRecord | ObjectRecord[]>() => {
|
|||||||
recordStoreFamilySelector({ recordId, fieldName }),
|
recordStoreFamilySelector({ recordId, fieldName }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { getDraftValueSelector } = useRecordFieldInput<FieldRelationValue<T>>(
|
const { getDraftValueSelector } =
|
||||||
`${recordId}-${fieldName}`,
|
useRecordFieldInput<FieldRelationValue<T>>();
|
||||||
);
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
const initialSearchValue = draftValue;
|
const initialSearchValue = draftValue;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export const useRichTextField = () => {
|
|||||||
const fieldRichTextValue = isFieldRichTextValue(fieldValue) ? fieldValue : '';
|
const fieldRichTextValue = isFieldRichTextValue(fieldValue) ? fieldValue : '';
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldRichTextValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldRichTextValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export const useRichTextV2Field = () => {
|
|||||||
: ({ blocknote: null, markdown: null } as FieldRichTextV2Value);
|
: ({ blocknote: null, markdown: null } as FieldRichTextV2Value);
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldRichTextValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldRichTextValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export const useSelectField = () => {
|
|||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldSelectValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldSelectValue>();
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export const useTextField = () => {
|
|||||||
const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : '';
|
const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : '';
|
||||||
|
|
||||||
const { setDraftValue, getDraftValueSelector } =
|
const { setDraftValue, getDraftValueSelector } =
|
||||||
useRecordFieldInput<FieldTextValue>(`${recordId}-${fieldName}`);
|
useRecordFieldInput<FieldTextValue>();
|
||||||
|
|
||||||
const draftValue = useRecoilValue(getDraftValueSelector());
|
const draftValue = useRecoilValue(getDraftValueSelector());
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope
|
|||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
|
|
||||||
const AddressValueSetterEffect = ({
|
const AddressValueSetterEffect = ({
|
||||||
value,
|
value,
|
||||||
@ -49,32 +51,42 @@ const AddressInputWithContext = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FieldContextProvider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
fieldDefinition={{
|
value={{
|
||||||
fieldMetadataId: 'text',
|
instanceId: getRecordFieldInputId(
|
||||||
label: 'Address',
|
recordId ?? '',
|
||||||
type: FieldMetadataType.ADDRESS,
|
'Address',
|
||||||
iconName: 'IconTag',
|
'record-table-cell',
|
||||||
metadata: {
|
),
|
||||||
fieldName: 'Address',
|
|
||||||
placeHolder: 'Enter text',
|
|
||||||
objectMetadataNameSingular: 'person',
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
recordId={recordId}
|
|
||||||
>
|
>
|
||||||
<AddressValueSetterEffect value={value} />
|
<FieldContextProvider
|
||||||
<AddressInput
|
fieldDefinition={{
|
||||||
onEnter={onEnter}
|
fieldMetadataId: 'text',
|
||||||
onEscape={onEscape}
|
label: 'Address',
|
||||||
onClickOutside={onClickOutside}
|
type: FieldMetadataType.ADDRESS,
|
||||||
value={value}
|
iconName: 'IconTag',
|
||||||
hotkeyScope="hotkey-scope"
|
metadata: {
|
||||||
onTab={onTab}
|
fieldName: 'Address',
|
||||||
onShiftTab={onShiftTab}
|
placeHolder: 'Enter text',
|
||||||
/>
|
objectMetadataNameSingular: 'person',
|
||||||
</FieldContextProvider>
|
},
|
||||||
<div data-testid="data-field-input-click-outside-div" />
|
}}
|
||||||
|
recordId={recordId}
|
||||||
|
>
|
||||||
|
<AddressValueSetterEffect value={value} />
|
||||||
|
<AddressInput
|
||||||
|
onEnter={onEnter}
|
||||||
|
onEscape={onEscape}
|
||||||
|
onClickOutside={onClickOutside}
|
||||||
|
value={value}
|
||||||
|
hotkeyScope="hotkey-scope"
|
||||||
|
onTab={onTab}
|
||||||
|
onShiftTab={onShiftTab}
|
||||||
|
/>
|
||||||
|
</FieldContextProvider>
|
||||||
|
<div data-testid="data-field-input-click-outside-div" />
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
|
|||||||
import { FieldMetadataType } from '~/generated/graphql';
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import {
|
import {
|
||||||
BooleanFieldInput,
|
BooleanFieldInput,
|
||||||
BooleanFieldInputProps,
|
BooleanFieldInputProps,
|
||||||
@ -39,23 +41,36 @@ const BooleanFieldInputWithContext = ({
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
}: BooleanFieldInputWithContextProps) => {
|
}: BooleanFieldInputWithContextProps) => {
|
||||||
return (
|
return (
|
||||||
<FieldContextProvider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
fieldDefinition={{
|
value={{
|
||||||
defaultValue: false,
|
instanceId: getRecordFieldInputId(
|
||||||
fieldMetadataId: 'boolean',
|
recordId ?? '',
|
||||||
label: 'Boolean',
|
'Boolean',
|
||||||
iconName: 'Icon123',
|
'record-table-cell',
|
||||||
type: FieldMetadataType.BOOLEAN,
|
),
|
||||||
metadata: {
|
|
||||||
fieldName: 'Boolean',
|
|
||||||
objectMetadataNameSingular: 'person',
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
recordId={recordId}
|
|
||||||
>
|
>
|
||||||
<BooleanFieldValueSetterEffect value={value} recordId={recordId ?? ''} />
|
<FieldContextProvider
|
||||||
<BooleanFieldInput onSubmit={onSubmit} testId="boolean-field-input" />
|
fieldDefinition={{
|
||||||
</FieldContextProvider>
|
defaultValue: false,
|
||||||
|
fieldMetadataId: 'boolean',
|
||||||
|
label: 'Boolean',
|
||||||
|
iconName: 'Icon123',
|
||||||
|
type: FieldMetadataType.BOOLEAN,
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'Boolean',
|
||||||
|
objectMetadataNameSingular: 'person',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
recordId={recordId}
|
||||||
|
>
|
||||||
|
<BooleanFieldValueSetterEffect
|
||||||
|
value={value}
|
||||||
|
recordId={recordId ?? ''}
|
||||||
|
/>
|
||||||
|
<BooleanFieldInput onSubmit={onSubmit} testId="boolean-field-input" />
|
||||||
|
</FieldContextProvider>
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope
|
|||||||
import { FieldMetadataType } from '~/generated/graphql';
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
||||||
import { useDateTimeField } from '../../../hooks/useDateTimeField';
|
import { useDateTimeField } from '../../../hooks/useDateTimeField';
|
||||||
import {
|
import {
|
||||||
@ -66,7 +68,15 @@ const DateFieldInputWithContext = ({
|
|||||||
}, [setHotkeyScope]);
|
}, [setHotkeyScope]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
|
value={{
|
||||||
|
instanceId: getRecordFieldInputId(
|
||||||
|
recordId ?? '',
|
||||||
|
'Date',
|
||||||
|
'record-table-cell',
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
<FieldContextProvider
|
<FieldContextProvider
|
||||||
fieldDefinition={{
|
fieldDefinition={{
|
||||||
fieldMetadataId: 'date',
|
fieldMetadataId: 'date',
|
||||||
@ -90,7 +100,7 @@ const DateFieldInputWithContext = ({
|
|||||||
/>
|
/>
|
||||||
</FieldContextProvider>
|
</FieldContextProvider>
|
||||||
<div data-testid="data-field-input-click-outside-div"></div>
|
<div data-testid="data-field-input-click-outside-div"></div>
|
||||||
</div>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { FieldMetadataType } from '~/generated/graphql';
|
|||||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||||
|
|
||||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
||||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||||
import { useNumberField } from '../../../hooks/useNumberField';
|
import { useNumberField } from '../../../hooks/useNumberField';
|
||||||
@ -43,7 +45,15 @@ const NumberFieldInputWithContext = ({
|
|||||||
}, [setHotKeyScope]);
|
}, [setHotKeyScope]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
|
value={{
|
||||||
|
instanceId: getRecordFieldInputId(
|
||||||
|
recordId ?? '',
|
||||||
|
'Number',
|
||||||
|
'record-table-cell',
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
<FieldContextProvider
|
<FieldContextProvider
|
||||||
fieldDefinition={{
|
fieldDefinition={{
|
||||||
fieldMetadataId: 'number',
|
fieldMetadataId: 'number',
|
||||||
@ -69,7 +79,7 @@ const NumberFieldInputWithContext = ({
|
|||||||
/>
|
/>
|
||||||
</FieldContextProvider>
|
</FieldContextProvider>
|
||||||
<div data-testid="data-field-input-click-outside-div" />
|
<div data-testid="data-field-input-click-outside-div" />
|
||||||
</div>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { isDefined } from 'twenty-shared';
|
|||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { FieldRatingValue } from '../../../../types/FieldMetadata';
|
import { FieldRatingValue } from '../../../../types/FieldMetadata';
|
||||||
import { useRatingField } from '../../../hooks/useRatingField';
|
import { useRatingField } from '../../../hooks/useRatingField';
|
||||||
import { RatingFieldInput, RatingFieldInputProps } from '../RatingFieldInput';
|
import { RatingFieldInput, RatingFieldInputProps } from '../RatingFieldInput';
|
||||||
@ -42,22 +44,32 @@ const RatingFieldInputWithContext = ({
|
|||||||
}, [setHotKeyScope]);
|
}, [setHotKeyScope]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FieldContextProvider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
fieldDefinition={{
|
value={{
|
||||||
fieldMetadataId: 'rating',
|
instanceId: getRecordFieldInputId(
|
||||||
label: 'Rating',
|
recordId ?? '',
|
||||||
type: FieldMetadataType.RATING,
|
'Rating',
|
||||||
iconName: 'Icon123',
|
'record-table-cell',
|
||||||
metadata: {
|
),
|
||||||
fieldName: 'Rating',
|
|
||||||
objectMetadataNameSingular: 'person',
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
recordId={recordId}
|
|
||||||
>
|
>
|
||||||
<RatingFieldValueSetterEffect value={value} />
|
<FieldContextProvider
|
||||||
<RatingFieldInput onSubmit={onSubmit} />
|
fieldDefinition={{
|
||||||
</FieldContextProvider>
|
fieldMetadataId: 'rating',
|
||||||
|
label: 'Rating',
|
||||||
|
type: FieldMetadataType.RATING,
|
||||||
|
iconName: 'Icon123',
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'Rating',
|
||||||
|
objectMetadataNameSingular: 'person',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
recordId={recordId}
|
||||||
|
>
|
||||||
|
<RatingFieldValueSetterEffect value={value} />
|
||||||
|
<RatingFieldInput onSubmit={onSubmit} />
|
||||||
|
</FieldContextProvider>
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
|
||||||
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import { FieldMetadataType } from '~/generated/graphql';
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
|
||||||
|
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
|
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||||
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
|
||||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||||
|
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||||
import { FieldContextProvider } from '../../../components/FieldContextProvider';
|
import { FieldContextProvider } from '../../../components/FieldContextProvider';
|
||||||
import { useTextField } from '../../../hooks/useTextField';
|
import { useTextField } from '../../../hooks/useTextField';
|
||||||
import { TextFieldInput, TextFieldInputProps } from '../TextFieldInput';
|
import { TextFieldInput, TextFieldInputProps } from '../TextFieldInput';
|
||||||
@ -43,7 +44,11 @@ const TextFieldInputWithContext = ({
|
|||||||
}, [setHotKeyScope]);
|
}, [setHotKeyScope]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
|
value={{
|
||||||
|
instanceId: 'record-field-component-instance-id',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<FieldContextProvider
|
<FieldContextProvider
|
||||||
fieldDefinition={{
|
fieldDefinition={{
|
||||||
fieldMetadataId: 'text',
|
fieldMetadataId: 'text',
|
||||||
@ -69,7 +74,7 @@ const TextFieldInputWithContext = ({
|
|||||||
/>
|
/>
|
||||||
</FieldContextProvider>
|
</FieldContextProvider>
|
||||||
<div data-testid="data-field-input-click-outside-div" />
|
<div data-testid="data-field-input-click-outside-div" />
|
||||||
</div>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
|
|
||||||
import { RecordFieldInputScopeInternalContext } from '@/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext';
|
|
||||||
|
|
||||||
type RecordFieldInputScopeProps = {
|
|
||||||
children: ReactNode;
|
|
||||||
recordFieldInputScopeId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RecordFieldInputScope = ({
|
|
||||||
children,
|
|
||||||
recordFieldInputScopeId,
|
|
||||||
}: RecordFieldInputScopeProps) => {
|
|
||||||
return (
|
|
||||||
<RecordFieldInputScopeInternalContext.Provider
|
|
||||||
value={{ scopeId: recordFieldInputScopeId }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</RecordFieldInputScopeInternalContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
|
||||||
import { RecoilComponentStateKey } from '@/ui/utilities/state/component-state/types/RecoilComponentStateKey';
|
|
||||||
|
|
||||||
type RecordFieldInputScopeInternalContextProps = RecoilComponentStateKey;
|
|
||||||
|
|
||||||
export const RecordFieldInputScopeInternalContext =
|
|
||||||
createScopeInternalContext<RecordFieldInputScopeInternalContextProps>();
|
|
||||||
@ -12,15 +12,19 @@ import { useIsFieldInputOnly } from '@/object-record/record-field/hooks/useIsFie
|
|||||||
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
||||||
import { useOpenFieldInputEditMode } from '@/object-record/record-field/hooks/useOpenFieldInputEditMode';
|
import { useOpenFieldInputEditMode } from '@/object-record/record-field/hooks/useOpenFieldInputEditMode';
|
||||||
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
|
||||||
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
|
||||||
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
|
||||||
|
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
||||||
import { MultipleRecordPickerHotkeyScope } from '@/object-record/record-picker/multiple-record-picker/types/MultipleRecordPickerHotkeyScope';
|
import { MultipleRecordPickerHotkeyScope } from '@/object-record/record-picker/multiple-record-picker/types/MultipleRecordPickerHotkeyScope';
|
||||||
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
import { SingleRecordPickerHotkeyScope } from '@/object-record/record-picker/single-record-picker/types/SingleRecordPickerHotkeyScope';
|
||||||
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
||||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
||||||
import { RecordInlineCellContainer } from './RecordInlineCellContainer';
|
import { RecordInlineCellContainer } from './RecordInlineCellContainer';
|
||||||
import {
|
import {
|
||||||
@ -42,6 +46,10 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
|||||||
onCloseEditMode,
|
onCloseEditMode,
|
||||||
} = useContext(FieldContext);
|
} = useContext(FieldContext);
|
||||||
|
|
||||||
|
const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
|
RecordFieldComponentInstanceContext,
|
||||||
|
);
|
||||||
|
|
||||||
const buttonIcon = useGetButtonIcon();
|
const buttonIcon = useGetButtonIcon();
|
||||||
|
|
||||||
const isFieldInputOnly = useIsFieldInputOnly();
|
const isFieldInputOnly = useIsFieldInputOnly();
|
||||||
@ -78,15 +86,22 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
|||||||
closeInlineCell();
|
closeInlineCell();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClickOutside: FieldInputClickOutsideEvent = (
|
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||||
persistField,
|
({ snapshot }) =>
|
||||||
event,
|
(persistField, event) => {
|
||||||
) => {
|
const hotkeyScope = snapshot
|
||||||
event.stopImmediatePropagation();
|
.getLoadable(currentHotkeyScopeState)
|
||||||
|
.getValue();
|
||||||
|
if (hotkeyScope.scope !== InlineCellHotkeyScope.InlineCell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
persistField();
|
persistField();
|
||||||
closeInlineCell();
|
closeInlineCell();
|
||||||
};
|
},
|
||||||
|
[closeInlineCell],
|
||||||
|
);
|
||||||
|
|
||||||
const { getIcon } = useIcons();
|
const { getIcon } = useIcons();
|
||||||
const { openFieldInput, closeFieldInput } = useOpenFieldInputEditMode();
|
const { openFieldInput, closeFieldInput } = useOpenFieldInputEditMode();
|
||||||
@ -132,10 +147,7 @@ export const RecordInlineCell = ({ loading }: RecordInlineCellProps) => {
|
|||||||
isCentered,
|
isCentered,
|
||||||
editModeContent: (
|
editModeContent: (
|
||||||
<FieldInput
|
<FieldInput
|
||||||
recordFieldInputdId={getRecordFieldInputId(
|
recordFieldInputdId={recordFieldComponentInstanceId}
|
||||||
recordId,
|
|
||||||
fieldDefinition?.metadata?.fieldName,
|
|
||||||
)}
|
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/states/recordFieldInputIsFieldInErrorComponentState';
|
import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/states/recordFieldInputIsFieldInErrorComponentState';
|
||||||
import { recordFieldInputLayoutDirectionComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionComponentState';
|
import { recordFieldInputLayoutDirectionComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionComponentState';
|
||||||
import { recordFieldInputLayoutDirectionLoadingComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionLoadingComponentState';
|
import { recordFieldInputLayoutDirectionLoadingComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionLoadingComponentState';
|
||||||
import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
import { RecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
||||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
|
||||||
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -37,21 +37,19 @@ export const RecordInlineCellEditMode = ({
|
|||||||
children,
|
children,
|
||||||
}: RecordInlineCellEditModeProps) => {
|
}: RecordInlineCellEditModeProps) => {
|
||||||
const { isCentered } = useContext(RecordInlineCellContext);
|
const { isCentered } = useContext(RecordInlineCellContext);
|
||||||
const { recordId, fieldDefinition } = useContext(FieldContext);
|
|
||||||
|
|
||||||
const instanceId = getRecordFieldInputId(
|
const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
recordId,
|
RecordFieldComponentInstanceContext,
|
||||||
fieldDefinition?.metadata?.fieldName,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirection = useSetRecoilComponentStateV2(
|
const setFieldInputLayoutDirection = useSetRecoilComponentStateV2(
|
||||||
recordFieldInputLayoutDirectionComponentState,
|
recordFieldInputLayoutDirectionComponentState,
|
||||||
instanceId,
|
recordFieldComponentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2(
|
const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2(
|
||||||
recordFieldInputLayoutDirectionLoadingComponentState,
|
recordFieldInputLayoutDirectionLoadingComponentState,
|
||||||
instanceId,
|
recordFieldComponentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirectionMiddleware = {
|
const setFieldInputLayoutDirectionMiddleware = {
|
||||||
|
|||||||
@ -6,22 +6,28 @@ import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousH
|
|||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2';
|
import { useInitDraftValueV2 } from '@/object-record/record-field/hooks/useInitDraftValueV2';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
|
||||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { isInlineCellInEditModeScopedState } from '../states/isInlineCellInEditModeScopedState';
|
import { isInlineCellInEditModeScopedState } from '../states/isInlineCellInEditModeScopedState';
|
||||||
import { InlineCellHotkeyScope } from '../types/InlineCellHotkeyScope';
|
import { InlineCellHotkeyScope } from '../types/InlineCellHotkeyScope';
|
||||||
|
|
||||||
export const useInlineCell = () => {
|
export const useInlineCell = (
|
||||||
const {
|
recordFieldComponentInstanceIdFromProps?: string,
|
||||||
recoilScopeId = '',
|
) => {
|
||||||
recordId,
|
const { recordId, fieldDefinition } = useContext(FieldContext);
|
||||||
fieldDefinition,
|
|
||||||
} = useContext(FieldContext);
|
const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
|
RecordFieldComponentInstanceContext,
|
||||||
|
recordFieldComponentInstanceIdFromProps,
|
||||||
|
);
|
||||||
|
|
||||||
const [isInlineCellInEditMode, setIsInlineCellInEditMode] = useRecoilState(
|
const [isInlineCellInEditMode, setIsInlineCellInEditMode] = useRecoilState(
|
||||||
isInlineCellInEditModeScopedState(recoilScopeId),
|
isInlineCellInEditModeScopedState(recordFieldComponentInstanceId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { onOpenEditMode, onCloseEditMode } = useRecordInlineCellContext();
|
const { onOpenEditMode, onCloseEditMode } = useRecordInlineCellContext();
|
||||||
@ -50,7 +56,15 @@ export const useInlineCell = () => {
|
|||||||
const openInlineCell = (customEditHotkeyScopeForField?: string) => {
|
const openInlineCell = (customEditHotkeyScopeForField?: string) => {
|
||||||
onOpenEditMode?.();
|
onOpenEditMode?.();
|
||||||
setIsInlineCellInEditMode(true);
|
setIsInlineCellInEditMode(true);
|
||||||
initFieldInputDraftValue({ recordId, fieldDefinition });
|
initFieldInputDraftValue({
|
||||||
|
recordId,
|
||||||
|
fieldDefinition,
|
||||||
|
fieldComponentInstanceId: getRecordFieldInputId(
|
||||||
|
recordId,
|
||||||
|
fieldDefinition.metadata.fieldName,
|
||||||
|
'inline-cell',
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
if (isDefined(customEditHotkeyScopeForField)) {
|
if (isDefined(customEditHotkeyScopeForField)) {
|
||||||
setHotkeyScopeAndMemorizePreviousScope(customEditHotkeyScopeForField);
|
setHotkeyScopeAndMemorizePreviousScope(customEditHotkeyScopeForField);
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { useRecordShowContainerActions } from '@/object-record/record-show/hooks
|
|||||||
import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData';
|
import { useRecordShowContainerData } from '@/object-record/record-show/hooks/useRecordShowContainerData';
|
||||||
import { RecordDetailDuplicatesSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection';
|
import { RecordDetailDuplicatesSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailDuplicatesSection';
|
||||||
import { RecordDetailRelationSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSection';
|
import { RecordDetailRelationSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSection';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported';
|
import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported';
|
||||||
import { FieldMetadataType } from '~/generated/graphql';
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -97,7 +98,6 @@ export const FieldsCard = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
recoilScopeId: objectRecordId + fieldMetadataItem.id,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
@ -110,22 +110,21 @@ export const FieldsCard = ({
|
|||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<ActivityTargetsInlineCell
|
||||||
value={{
|
componentInstanceId={getRecordFieldInputId(
|
||||||
instanceId: objectRecordId + fieldMetadataItem.id,
|
objectRecordId,
|
||||||
}}
|
fieldMetadataItem.name,
|
||||||
>
|
'fields-card',
|
||||||
<ActivityTargetsInlineCell
|
)}
|
||||||
activityObjectNameSingular={
|
activityObjectNameSingular={
|
||||||
objectNameSingular as
|
objectNameSingular as
|
||||||
| CoreObjectNameSingular.Note
|
| CoreObjectNameSingular.Note
|
||||||
| CoreObjectNameSingular.Task
|
| CoreObjectNameSingular.Task
|
||||||
}
|
}
|
||||||
activityRecordId={objectRecordId}
|
activityRecordId={objectRecordId}
|
||||||
showLabel={true}
|
showLabel={true}
|
||||||
maxWidth={200}
|
maxWidth={200}
|
||||||
/>
|
/>
|
||||||
</RecordFieldComponentInstanceContext.Provider>
|
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
@ -135,7 +134,6 @@ export const FieldsCard = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
recoilScopeId: objectRecordId + fieldMetadataItem.id,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
@ -150,7 +148,11 @@ export const FieldsCard = ({
|
|||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
value={{
|
value={{
|
||||||
instanceId: `${objectRecordId}-${fieldMetadataItem.id}`,
|
instanceId: getRecordFieldInputId(
|
||||||
|
objectRecordId,
|
||||||
|
fieldMetadataItem.name,
|
||||||
|
'fields-card',
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordInlineCell loading={recordLoading} />
|
<RecordInlineCell loading={recordLoading} />
|
||||||
@ -169,7 +171,6 @@ export const FieldsCard = ({
|
|||||||
key={objectRecordId + fieldMetadataItem.id}
|
key={objectRecordId + fieldMetadataItem.id}
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
recoilScopeId: objectRecordId + fieldMetadataItem.id,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
|
|||||||
@ -68,8 +68,6 @@ export const ObjectRecordShowPageBreadcrumb = ({
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
recoilScopeId:
|
|
||||||
objectRecordId + labelIdentifierFieldMetadataItem?.id,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
type:
|
type:
|
||||||
|
|||||||
@ -70,8 +70,6 @@ export const SummaryCard = ({
|
|||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
recoilScopeId:
|
|
||||||
objectRecordId + labelIdentifierFieldMetadataItem?.id,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
type:
|
type:
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import { RecordDetailRecordsListItem } from '@/object-record/record-show/record-
|
|||||||
import { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect';
|
import { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { getForeignKeyNameFromRelationFieldName } from '@/object-record/utils/getForeignKeyNameFromRelationFieldName';
|
import { getForeignKeyNameFromRelationFieldName } from '@/object-record/utils/getForeignKeyNameFromRelationFieldName';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported';
|
import { isFieldCellSupported } from '@/object-record/utils/isFieldCellSupported';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
@ -268,7 +269,6 @@ export const RecordDetailRelationRecordsListItem = ({
|
|||||||
value={{
|
value={{
|
||||||
recordId: relationRecord.id,
|
recordId: relationRecord.id,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
recoilScopeId: `${relationRecord.id}-${fieldMetadataItem.id}`,
|
|
||||||
isLabelIdentifier: false,
|
isLabelIdentifier: false,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
@ -283,7 +283,11 @@ export const RecordDetailRelationRecordsListItem = ({
|
|||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
value={{
|
value={{
|
||||||
instanceId: `${relationRecord.id}-${fieldMetadataItem.id}`,
|
instanceId: getRecordFieldInputId(
|
||||||
|
relationRecord.id,
|
||||||
|
fieldMetadataItem.name,
|
||||||
|
'record-detail',
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordInlineCell />
|
<RecordInlineCell />
|
||||||
|
|||||||
@ -13,7 +13,10 @@ export const useUpsertRecordsInStore = () => {
|
|||||||
.getValue();
|
.getValue();
|
||||||
|
|
||||||
if (JSON.stringify(currentRecord) !== JSON.stringify(record)) {
|
if (JSON.stringify(currentRecord) !== JSON.stringify(record)) {
|
||||||
set(recordStoreFamilyState(record.id), record);
|
set(recordStoreFamilyState(record.id), {
|
||||||
|
...currentRecord,
|
||||||
|
...record,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -62,7 +62,10 @@ export const useSetRecordTableData = ({
|
|||||||
.getValue();
|
.getValue();
|
||||||
|
|
||||||
if (JSON.stringify(currentRecord) !== JSON.stringify(record)) {
|
if (JSON.stringify(currentRecord) !== JSON.stringify(record)) {
|
||||||
set(recordStoreFamilyState(record.id), record);
|
set(recordStoreFamilyState(record.id), {
|
||||||
|
...currentRecord,
|
||||||
|
...record,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/states/recordFieldInputIsFieldInErrorComponentState';
|
import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/states/recordFieldInputIsFieldInErrorComponentState';
|
||||||
import { recordFieldInputLayoutDirectionComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionComponentState';
|
import { recordFieldInputLayoutDirectionComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionComponentState';
|
||||||
import { recordFieldInputLayoutDirectionLoadingComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionLoadingComponentState';
|
import { recordFieldInputLayoutDirectionLoadingComponentState } from '@/object-record/record-field/states/recordFieldInputLayoutDirectionLoadingComponentState';
|
||||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
|
||||||
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer';
|
||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -14,7 +14,7 @@ import {
|
|||||||
offset,
|
offset,
|
||||||
useFloating,
|
useFloating,
|
||||||
} from '@floating-ui/react';
|
} from '@floating-ui/react';
|
||||||
import { ReactElement, useContext } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
const StyledEditableCellEditModeContainer = styled.div<RecordTableCellEditModeProps>`
|
const StyledEditableCellEditModeContainer = styled.div<RecordTableCellEditModeProps>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -35,25 +35,21 @@ export type RecordTableCellEditModeProps = {
|
|||||||
export const RecordTableCellEditMode = ({
|
export const RecordTableCellEditMode = ({
|
||||||
children,
|
children,
|
||||||
}: RecordTableCellEditModeProps) => {
|
}: RecordTableCellEditModeProps) => {
|
||||||
const { recordId, fieldDefinition } = useContext(FieldContext);
|
|
||||||
|
|
||||||
const isFieldInError = useRecoilComponentValueV2(
|
const isFieldInError = useRecoilComponentValueV2(
|
||||||
recordFieldInputIsFieldInErrorComponentState,
|
recordFieldInputIsFieldInErrorComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const instanceId = getRecordFieldInputId(
|
const recordFieldComponentInstanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
recordId,
|
RecordFieldComponentInstanceContext,
|
||||||
fieldDefinition?.metadata?.fieldName,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirection = useSetRecoilComponentStateV2(
|
const setFieldInputLayoutDirection = useSetRecoilComponentStateV2(
|
||||||
recordFieldInputLayoutDirectionComponentState,
|
recordFieldInputLayoutDirectionComponentState,
|
||||||
instanceId,
|
recordFieldComponentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2(
|
const setFieldInputLayoutDirectionLoading = useSetRecoilComponentStateV2(
|
||||||
recordFieldInputLayoutDirectionLoadingComponentState,
|
recordFieldInputLayoutDirectionLoadingComponentState,
|
||||||
instanceId,
|
recordFieldComponentInstanceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const setFieldInputLayoutDirectionMiddleware = {
|
const setFieldInputLayoutDirectionMiddleware = {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { useRecordTableRowContextOrThrow } from '@/object-record/record-table/co
|
|||||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
import { SelectFieldHotkeyScope } from '@/object-record/select/types/SelectFieldHotkeyScope';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
import { RelationDefinitionType } from '~/generated-metadata/graphql';
|
||||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||||
|
|
||||||
@ -72,7 +73,6 @@ export const RecordTableCellFieldContextWrapper = ({
|
|||||||
return (
|
return (
|
||||||
<FieldContext.Provider
|
<FieldContext.Provider
|
||||||
value={{
|
value={{
|
||||||
recoilScopeId: recordId + columnDefinition.label,
|
|
||||||
recordId,
|
recordId,
|
||||||
fieldDefinition: columnDefinition,
|
fieldDefinition: columnDefinition,
|
||||||
useUpdateRecord: () => [updateRecord, {}],
|
useUpdateRecord: () => [updateRecord, {}],
|
||||||
@ -89,7 +89,13 @@ export const RecordTableCellFieldContextWrapper = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordFieldComponentInstanceContext.Provider
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
value={{ instanceId: recordId + columnDefinition.label }}
|
value={{
|
||||||
|
instanceId: getRecordFieldInputId(
|
||||||
|
recordId,
|
||||||
|
columnDefinition.metadata.fieldName,
|
||||||
|
'record-table-cell',
|
||||||
|
),
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</RecordFieldComponentInstanceContext.Provider>
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
|
|||||||
@ -3,9 +3,13 @@ import { useContext } from 'react';
|
|||||||
import { FieldInput } from '@/object-record/record-field/components/FieldInput';
|
import { FieldInput } from '@/object-record/record-field/components/FieldInput';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
import { useIsFieldValueReadOnly } from '@/object-record/record-field/hooks/useIsFieldValueReadOnly';
|
||||||
|
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
||||||
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
||||||
import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
||||||
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
|
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
export const RecordTableCellFieldInput = () => {
|
export const RecordTableCellFieldInput = () => {
|
||||||
const { recordId, fieldDefinition } = useContext(FieldContext);
|
const { recordId, fieldDefinition } = useContext(FieldContext);
|
||||||
@ -31,16 +35,22 @@ export const RecordTableCellFieldInput = () => {
|
|||||||
onCloseTableCell();
|
onCloseTableCell();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClickOutside = (
|
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||||
persistField: () => void,
|
({ snapshot }) =>
|
||||||
event: MouseEvent | TouchEvent,
|
(persistField, event) => {
|
||||||
) => {
|
const hotkeyScope = snapshot
|
||||||
event.stopImmediatePropagation();
|
.getLoadable(currentHotkeyScopeState)
|
||||||
|
.getValue();
|
||||||
|
if (hotkeyScope.scope !== TableHotkeyScope.CellEditMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
persistField();
|
persistField();
|
||||||
|
onCloseTableCell();
|
||||||
onCloseTableCell();
|
},
|
||||||
};
|
[onCloseTableCell],
|
||||||
|
);
|
||||||
|
|
||||||
const handleEscape: FieldInputEvent = (persistField) => {
|
const handleEscape: FieldInputEvent = (persistField) => {
|
||||||
persistField();
|
persistField();
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { recordIndexOpenRecordInState } from '@/object-record/record-index/state
|
|||||||
import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState';
|
import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState';
|
||||||
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
|
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
|
||||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||||
|
import { getRecordFieldInputId } from '@/object-record/utils/getRecordFieldInputId';
|
||||||
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
|
||||||
import { useClickOustideListenerStates } from '@/ui/utilities/pointer-event/hooks/useClickOustideListenerStates';
|
import { useClickOustideListenerStates } from '@/ui/utilities/pointer-event/hooks/useClickOustideListenerStates';
|
||||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||||
@ -158,6 +159,11 @@ export const useOpenRecordTableCellV2 = (tableScopeId: string) => {
|
|||||||
value: initialValue,
|
value: initialValue,
|
||||||
recordId,
|
recordId,
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
|
fieldComponentInstanceId: getRecordFieldInputId(
|
||||||
|
recordId,
|
||||||
|
fieldDefinition.metadata.fieldName,
|
||||||
|
'record-table-cell',
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
toggleClickOutsideListener(false);
|
toggleClickOutsideListener(false);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEv
|
|||||||
import { useInlineCell } from '../../record-inline-cell/hooks/useInlineCell';
|
import { useInlineCell } from '../../record-inline-cell/hooks/useInlineCell';
|
||||||
|
|
||||||
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { RecordTitleCellContainer } from '@/object-record/record-title-cell/components/RecordTitleCellContainer';
|
import { RecordTitleCellContainer } from '@/object-record/record-title-cell/components/RecordTitleCellContainer';
|
||||||
import {
|
import {
|
||||||
RecordTitleCellContext,
|
RecordTitleCellContext,
|
||||||
@ -30,7 +31,13 @@ export const RecordTitleCell = ({
|
|||||||
|
|
||||||
const isFieldInputOnly = useIsFieldInputOnly();
|
const isFieldInputOnly = useIsFieldInputOnly();
|
||||||
|
|
||||||
const { closeInlineCell } = useInlineCell();
|
const { closeInlineCell } = useInlineCell(
|
||||||
|
getRecordFieldInputId(
|
||||||
|
recordId,
|
||||||
|
fieldDefinition?.metadata?.fieldName,
|
||||||
|
'title',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const handleEnter: FieldInputEvent = (persistField) => {
|
const handleEnter: FieldInputEvent = (persistField) => {
|
||||||
persistField();
|
persistField();
|
||||||
@ -64,10 +71,6 @@ export const RecordTitleCell = ({
|
|||||||
const recordTitleCellContextValue: RecordTitleCellContextProps = {
|
const recordTitleCellContextValue: RecordTitleCellContextProps = {
|
||||||
editModeContent: (
|
editModeContent: (
|
||||||
<RecordTitleCellFieldInput
|
<RecordTitleCellFieldInput
|
||||||
recordFieldInputId={getRecordFieldInputId(
|
|
||||||
recordId,
|
|
||||||
fieldDefinition?.metadata?.fieldName,
|
|
||||||
)}
|
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
onTab={handleTab}
|
onTab={handleTab}
|
||||||
@ -82,10 +85,20 @@ export const RecordTitleCell = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FieldFocusContextProvider>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
<RecordTitleCellContext.Provider value={recordTitleCellContextValue}>
|
value={{
|
||||||
<RecordTitleCellContainer />
|
instanceId: getRecordFieldInputId(
|
||||||
</RecordTitleCellContext.Provider>
|
recordId,
|
||||||
</FieldFocusContextProvider>
|
fieldDefinition?.metadata?.fieldName,
|
||||||
|
'title',
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FieldFocusContextProvider>
|
||||||
|
<RecordTitleCellContext.Provider value={recordTitleCellContextValue}>
|
||||||
|
<RecordTitleCellContainer />
|
||||||
|
</RecordTitleCellContext.Provider>
|
||||||
|
</FieldFocusContextProvider>
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
|
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
|
||||||
|
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
|
||||||
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
|
||||||
@ -11,7 +8,6 @@ import { RecordTitleCellTextFieldInput } from '@/object-record/record-title-cell
|
|||||||
import { RecordTitleFullNameFieldInput } from '@/object-record/record-title-cell/components/RecordTitleFullNameFieldInput';
|
import { RecordTitleFullNameFieldInput } from '@/object-record/record-title-cell/components/RecordTitleFullNameFieldInput';
|
||||||
|
|
||||||
type RecordTitleCellFieldInputProps = {
|
type RecordTitleCellFieldInputProps = {
|
||||||
recordFieldInputId: string;
|
|
||||||
onClickOutside?: (
|
onClickOutside?: (
|
||||||
persist: () => void,
|
persist: () => void,
|
||||||
event: MouseEvent | TouchEvent,
|
event: MouseEvent | TouchEvent,
|
||||||
@ -25,7 +21,6 @@ type RecordTitleCellFieldInputProps = {
|
|||||||
|
|
||||||
export const RecordTitleCellFieldInput = ({
|
export const RecordTitleCellFieldInput = ({
|
||||||
sizeVariant,
|
sizeVariant,
|
||||||
recordFieldInputId,
|
|
||||||
onEnter,
|
onEnter,
|
||||||
onEscape,
|
onEscape,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
@ -39,9 +34,7 @@ export const RecordTitleCellFieldInput = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldInputScope
|
<>
|
||||||
recordFieldInputScopeId={getScopeIdFromComponentId(recordFieldInputId)}
|
|
||||||
>
|
|
||||||
{isFieldText(fieldDefinition) ? (
|
{isFieldText(fieldDefinition) ? (
|
||||||
<RecordTitleCellTextFieldInput
|
<RecordTitleCellTextFieldInput
|
||||||
onEnter={onEnter}
|
onEnter={onEnter}
|
||||||
@ -61,6 +54,6 @@ export const RecordTitleCellFieldInput = ({
|
|||||||
sizeVariant={sizeVariant}
|
sizeVariant={sizeVariant}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</RecordFieldInputScope>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const getRecordFieldInputId = (
|
export const getRecordFieldInputId = (
|
||||||
recordId: string,
|
recordId: string,
|
||||||
fieldName?: string,
|
fieldName?: string,
|
||||||
|
prefix?: string,
|
||||||
): string => {
|
): string => {
|
||||||
|
if (isDefined(prefix)) {
|
||||||
|
return `${prefix}-${recordId}-${fieldName}`;
|
||||||
|
}
|
||||||
|
|
||||||
return `${recordId}-${fieldName}`;
|
return `${recordId}-${fieldName}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { FieldDisplay } from '@/object-record/record-field/components/FieldDispl
|
|||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { BooleanFieldInput } from '@/object-record/record-field/meta-types/input/components/BooleanFieldInput';
|
import { BooleanFieldInput } from '@/object-record/record-field/meta-types/input/components/BooleanFieldInput';
|
||||||
import { RatingFieldInput } from '@/object-record/record-field/meta-types/input/components/RatingFieldInput';
|
import { RatingFieldInput } from '@/object-record/record-field/meta-types/input/components/RatingFieldInput';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import { SettingsDataModelSetFieldValueEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetFieldValueEffect';
|
import { SettingsDataModelSetFieldValueEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetFieldValueEffect';
|
||||||
import { SettingsDataModelSetPreviewRecordEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetRecordEffect';
|
import { SettingsDataModelSetPreviewRecordEffect } from '@/settings/data-model/fields/preview/components/SettingsDataModelSetRecordEffect';
|
||||||
import { useFieldPreviewValue } from '@/settings/data-model/fields/preview/hooks/useFieldPreviewValue';
|
import { useFieldPreviewValue } from '@/settings/data-model/fields/preview/hooks/useFieldPreviewValue';
|
||||||
@ -98,59 +99,65 @@ export const SettingsDataModelFieldPreview = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{previewRecord ? (
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
<SettingsDataModelSetPreviewRecordEffect
|
value={{
|
||||||
fieldName={fieldName}
|
instanceId: 'record-field-component-instance-id',
|
||||||
record={previewRecord}
|
}}
|
||||||
/>
|
>
|
||||||
) : (
|
{previewRecord ? (
|
||||||
<SettingsDataModelSetFieldValueEffect
|
<SettingsDataModelSetPreviewRecordEffect
|
||||||
recordId={recordId}
|
fieldName={fieldName}
|
||||||
fieldName={fieldName}
|
record={previewRecord}
|
||||||
value={fieldPreviewValue}
|
/>
|
||||||
/>
|
) : (
|
||||||
)}
|
<SettingsDataModelSetFieldValueEffect
|
||||||
<StyledFieldPreview shrink={shrink}>
|
recordId={recordId}
|
||||||
{!!withFieldLabel && (
|
fieldName={fieldName}
|
||||||
<StyledFieldLabel>
|
value={fieldPreviewValue}
|
||||||
<FieldIcon
|
/>
|
||||||
size={theme.icon.size.md}
|
|
||||||
stroke={theme.icon.stroke.sm}
|
|
||||||
/>
|
|
||||||
{fieldMetadataItem.label}:
|
|
||||||
</StyledFieldLabel>
|
|
||||||
)}
|
)}
|
||||||
<FieldContext.Provider
|
<StyledFieldPreview shrink={shrink}>
|
||||||
value={{
|
{!!withFieldLabel && (
|
||||||
recordId,
|
<StyledFieldLabel>
|
||||||
isLabelIdentifier,
|
<FieldIcon
|
||||||
fieldDefinition: {
|
size={theme.icon.size.md}
|
||||||
type: fieldMetadataItem.type,
|
stroke={theme.icon.stroke.sm}
|
||||||
iconName: 'FieldIcon',
|
/>
|
||||||
fieldMetadataId: fieldMetadataItem.id || '',
|
{fieldMetadataItem.label}:
|
||||||
label: fieldMetadataItem.label,
|
</StyledFieldLabel>
|
||||||
metadata: {
|
|
||||||
fieldName,
|
|
||||||
objectMetadataNameSingular: objectMetadataItem.nameSingular,
|
|
||||||
relationObjectMetadataNameSingular:
|
|
||||||
relationObjectMetadataItem?.nameSingular,
|
|
||||||
options: fieldMetadataItem.options ?? [],
|
|
||||||
settings: fieldMetadataItem.settings,
|
|
||||||
},
|
|
||||||
defaultValue: fieldMetadataItem.defaultValue,
|
|
||||||
},
|
|
||||||
hotkeyScope: 'field-preview',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{fieldMetadataItem.type === FieldMetadataType.BOOLEAN ? (
|
|
||||||
<BooleanFieldInput readonly />
|
|
||||||
) : fieldMetadataItem.type === FieldMetadataType.RATING ? (
|
|
||||||
<RatingFieldInput readonly />
|
|
||||||
) : (
|
|
||||||
<FieldDisplay />
|
|
||||||
)}
|
)}
|
||||||
</FieldContext.Provider>
|
<FieldContext.Provider
|
||||||
</StyledFieldPreview>
|
value={{
|
||||||
|
recordId,
|
||||||
|
isLabelIdentifier,
|
||||||
|
fieldDefinition: {
|
||||||
|
type: fieldMetadataItem.type,
|
||||||
|
iconName: 'FieldIcon',
|
||||||
|
fieldMetadataId: fieldMetadataItem.id || '',
|
||||||
|
label: fieldMetadataItem.label,
|
||||||
|
metadata: {
|
||||||
|
fieldName,
|
||||||
|
objectMetadataNameSingular: objectMetadataItem.nameSingular,
|
||||||
|
relationObjectMetadataNameSingular:
|
||||||
|
relationObjectMetadataItem?.nameSingular,
|
||||||
|
options: fieldMetadataItem.options ?? [],
|
||||||
|
settings: fieldMetadataItem.settings,
|
||||||
|
},
|
||||||
|
defaultValue: fieldMetadataItem.defaultValue,
|
||||||
|
},
|
||||||
|
hotkeyScope: 'field-preview',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{fieldMetadataItem.type === FieldMetadataType.BOOLEAN ? (
|
||||||
|
<BooleanFieldInput readonly />
|
||||||
|
) : fieldMetadataItem.type === FieldMetadataType.RATING ? (
|
||||||
|
<RatingFieldInput readonly />
|
||||||
|
) : (
|
||||||
|
<FieldDisplay />
|
||||||
|
)}
|
||||||
|
</FieldContext.Provider>
|
||||||
|
</StyledFieldPreview>
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,8 +8,6 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
|||||||
|
|
||||||
import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope';
|
import { CurrencyPickerHotkeyScope } from '../types/CurrencyPickerHotkeyScope';
|
||||||
|
|
||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
|
||||||
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
|
||||||
import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect';
|
import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect';
|
||||||
|
|
||||||
const StyledDropdownButtonContainer = styled.div`
|
const StyledDropdownButtonContainer = styled.div`
|
||||||
@ -69,10 +67,6 @@ export const CurrencyPickerDropdownButton = ({
|
|||||||
closeDropdown();
|
closeDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
const { toggleClickOutsideListener } = useClickOutsideListener(
|
|
||||||
TableHotkeyScope.CellEditMode,
|
|
||||||
);
|
|
||||||
|
|
||||||
const currency = currencies.find(({ value }) => value === valueCode);
|
const currency = currencies.find(({ value }) => value === valueCode);
|
||||||
|
|
||||||
const currencyCode = currency?.value ?? CurrencyCode.USD;
|
const currencyCode = currency?.value ?? CurrencyCode.USD;
|
||||||
@ -98,8 +92,6 @@ export const CurrencyPickerDropdownButton = ({
|
|||||||
}
|
}
|
||||||
dropdownPlacement="bottom-start"
|
dropdownPlacement="bottom-start"
|
||||||
dropdownOffset={{ x: 0, y: 4 }}
|
dropdownOffset={{ x: 0, y: 4 }}
|
||||||
onOpen={() => toggleClickOutsideListener(false)}
|
|
||||||
onClose={() => toggleClickOutsideListener(true)}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||||
|
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/states/contexts/RecordFieldComponentInstanceContext';
|
||||||
import {
|
import {
|
||||||
RecordFieldValueSelectorContextProvider,
|
RecordFieldValueSelectorContextProvider,
|
||||||
useSetRecordValue,
|
useSetRecordValue,
|
||||||
@ -124,26 +125,32 @@ export const getFieldDecorator =
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordFieldValueSelectorContextProvider>
|
<RecordFieldComponentInstanceContext.Provider
|
||||||
<FieldContext.Provider
|
value={{
|
||||||
value={{
|
instanceId: 'record-field-component-instance-id',
|
||||||
recordId: record.id,
|
}}
|
||||||
isLabelIdentifier,
|
>
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
<RecordFieldValueSelectorContextProvider>
|
||||||
field: fieldMetadataItem,
|
<FieldContext.Provider
|
||||||
position: 0,
|
value={{
|
||||||
objectMetadataItem,
|
recordId: record.id,
|
||||||
}),
|
isLabelIdentifier,
|
||||||
hotkeyScope: 'hotkey-scope',
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
}}
|
field: fieldMetadataItem,
|
||||||
>
|
position: 0,
|
||||||
<RecordMockSetterEffect
|
objectMetadataItem,
|
||||||
companies={companies}
|
}),
|
||||||
people={people}
|
hotkeyScope: 'hotkey-scope',
|
||||||
tasks={tasks}
|
}}
|
||||||
/>
|
>
|
||||||
<Story />
|
<RecordMockSetterEffect
|
||||||
</FieldContext.Provider>
|
companies={companies}
|
||||||
</RecordFieldValueSelectorContextProvider>
|
people={people}
|
||||||
|
tasks={tasks}
|
||||||
|
/>
|
||||||
|
<Story />
|
||||||
|
</FieldContext.Provider>
|
||||||
|
</RecordFieldValueSelectorContextProvider>
|
||||||
|
</RecordFieldComponentInstanceContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -46,7 +46,6 @@ export const useMockFieldContext = ({
|
|||||||
key={objectRecordId + fieldMetadataItem.id}
|
key={objectRecordId + fieldMetadataItem.id}
|
||||||
value={{
|
value={{
|
||||||
recordId: objectRecordId,
|
recordId: objectRecordId,
|
||||||
recoilScopeId: objectRecordId + fieldMetadataItem.id,
|
|
||||||
isLabelIdentifier,
|
isLabelIdentifier,
|
||||||
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
fieldDefinition: formatFieldMetadataItemAsColumnDefinition({
|
||||||
field: fieldMetadataItem,
|
field: fieldMetadataItem,
|
||||||
|
|||||||
@ -361,7 +361,7 @@ const StyledButton = styled('button', {
|
|||||||
const StyledButtonWrapper = styled.div<
|
const StyledButtonWrapper = styled.div<
|
||||||
Pick<
|
Pick<
|
||||||
ButtonProps,
|
ButtonProps,
|
||||||
'isLoading' | 'variant' | 'accent' | 'inverted' | 'disabled'
|
'isLoading' | 'variant' | 'accent' | 'inverted' | 'disabled' | 'fullWidth'
|
||||||
>
|
>
|
||||||
>`
|
>`
|
||||||
${({ theme, variant, accent, inverted, disabled }) => css`
|
${({ theme, variant, accent, inverted, disabled }) => css`
|
||||||
@ -409,7 +409,9 @@ const StyledButtonWrapper = styled.div<
|
|||||||
|
|
||||||
max-width: ${({ isLoading, theme }) =>
|
max-width: ${({ isLoading, theme }) =>
|
||||||
isLoading ? `calc(100% - ${theme.spacing(8)})` : 'none'};
|
isLoading ? `calc(100% - ${theme.spacing(8)})` : 'none'};
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Button = ({
|
export const Button = ({
|
||||||
@ -445,6 +447,7 @@ export const Button = ({
|
|||||||
accent={accent}
|
accent={accent}
|
||||||
inverted={inverted}
|
inverted={inverted}
|
||||||
disabled={soon || disabled}
|
disabled={soon || disabled}
|
||||||
|
fullWidth={fullWidth}
|
||||||
>
|
>
|
||||||
{(isLoading || Icon) && (
|
{(isLoading || Icon) && (
|
||||||
<ButtonIcon Icon={Icon} isLoading={!!isLoading} />
|
<ButtonIcon Icon={Icon} isLoading={!!isLoading} />
|
||||||
|
|||||||
Reference in New Issue
Block a user