FieldDisplay & FieldInput (#1708)
* Removed view field duplicate types * wip * wip 2 * wip 3 * Unified state for fields * Renaming * Wip * Post merge * Post post merge * wip * Delete unused file * Boolean and Probability * Finished InlineCell * Renamed EditableCell to TableCell * Finished double texts * Finished MoneyField * Fixed bug inline cell click outside * Fixed hotkey scope * Final fixes * Phone * Fix url and number input validation * Fix * Fix position * wip refactor activity editor * Fixed activity editor --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -58,6 +58,7 @@ export const ActivityAssigneePicker = ({
|
||||
lastName: user.lastName,
|
||||
avatarType: 'rounded',
|
||||
avatarUrl: user.avatarUrl ?? '',
|
||||
originalEntity: user,
|
||||
}),
|
||||
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
||||
});
|
||||
|
||||
@ -8,9 +8,7 @@ import { ActivityComments } from '@/activities/components/ActivityComments';
|
||||
import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown';
|
||||
import { GET_ACTIVITIES } from '@/activities/graphql/queries/getActivities';
|
||||
import { PropertyBox } from '@/ui/editable-field/property-box/components/PropertyBox';
|
||||
import { EditableFieldHotkeyScope } from '@/ui/editable-field/types/EditableFieldHotkeyScope';
|
||||
import { DateEditableField } from '@/ui/editable-field/variants/components/DateEditableField';
|
||||
import { IconCalendar } from '@/ui/icon/index';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import {
|
||||
Activity,
|
||||
@ -22,6 +20,7 @@ import {
|
||||
import { debounce } from '~/utils/debounce';
|
||||
|
||||
import { ActivityAssigneeEditableField } from '../editable-fields/components/ActivityAssigneeEditableField';
|
||||
import { ActivityEditorDateField } from '../editable-fields/components/ActivityEditorDateField';
|
||||
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
|
||||
import { ACTIVITY_UPDATE_FRAGMENT } from '../graphql/fragments/activityUpdateFragment';
|
||||
import { CommentForDrawer } from '../types/CommentForDrawer';
|
||||
@ -185,26 +184,12 @@ export const ActivityEditor = ({
|
||||
<PropertyBox>
|
||||
{activity.type === ActivityType.Task && (
|
||||
<>
|
||||
<DateEditableField
|
||||
value={activity.dueAt}
|
||||
Icon={IconCalendar}
|
||||
label="Due date"
|
||||
onSubmit={(newDate) => {
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
where: {
|
||||
id: activity.id,
|
||||
},
|
||||
data: {
|
||||
dueAt: newDate,
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_ACTIVITIES) ?? ''],
|
||||
});
|
||||
}}
|
||||
hotkeyScope={EditableFieldHotkeyScope.EditableField}
|
||||
/>
|
||||
<ActivityAssigneeEditableField activity={activity} />
|
||||
<RecoilScope>
|
||||
<ActivityEditorDateField activityId={activity.id} />
|
||||
</RecoilScope>
|
||||
<RecoilScope>
|
||||
<ActivityAssigneeEditableField activity={activity} />
|
||||
</RecoilScope>
|
||||
</>
|
||||
)}
|
||||
<ActivityRelationEditableField activity={activity} />
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import { EditableField } from '@/ui/editable-field/components/EditableField';
|
||||
import { FieldRecoilScopeContext } from '@/ui/editable-field/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
||||
import { InlineCell } from '@/ui/editable-field/components/InlineCell';
|
||||
import { EditableFieldHotkeyScope } from '@/ui/editable-field/types/EditableFieldHotkeyScope';
|
||||
import { FieldContext } from '@/ui/field/contexts/FieldContext';
|
||||
import { FieldDefinition } from '@/ui/field/types/FieldDefinition';
|
||||
import { FieldRelationMetadata } from '@/ui/field/types/FieldMetadata';
|
||||
import { IconUserCircle } from '@/ui/icon';
|
||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { UserChip } from '@/users/components/UserChip';
|
||||
import { Company, User } from '~/generated/graphql';
|
||||
|
||||
import { ActivityAssigneeEditableFieldEditMode } from './ActivityAssigneeEditableFieldEditMode';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { Company, User, useUpdateActivityMutation } from '~/generated/graphql';
|
||||
|
||||
type OwnProps = {
|
||||
activity: Pick<Company, 'id' | 'accountOwnerId'> & {
|
||||
@ -16,32 +15,25 @@ type OwnProps = {
|
||||
|
||||
export const ActivityAssigneeEditableField = ({ activity }: OwnProps) => {
|
||||
return (
|
||||
<RecoilScope CustomRecoilScopeContext={FieldRecoilScopeContext}>
|
||||
<RecoilScope>
|
||||
<EditableField
|
||||
customEditHotkeyScope={{
|
||||
scope: RelationPickerHotkeyScope.RelationPicker,
|
||||
}}
|
||||
label="Assignee"
|
||||
IconLabel={IconUserCircle}
|
||||
editModeContent={
|
||||
<ActivityAssigneeEditableFieldEditMode activity={activity} />
|
||||
}
|
||||
displayModeContent={
|
||||
activity.assignee?.displayName ? (
|
||||
<UserChip
|
||||
id={activity.assignee.id}
|
||||
name={activity.assignee?.displayName ?? ''}
|
||||
pictureUrl={activity.assignee?.avatarUrl ?? ''}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
isDisplayModeContentEmpty={!activity.assignee}
|
||||
isDisplayModeFixHeight={true}
|
||||
/>
|
||||
</RecoilScope>
|
||||
</RecoilScope>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
entityId: activity.id,
|
||||
recoilScopeId: 'assignee',
|
||||
fieldDefinition: {
|
||||
key: 'assignee',
|
||||
name: 'Assignee',
|
||||
Icon: IconUserCircle,
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'assignee',
|
||||
relationType: Entity.User,
|
||||
},
|
||||
} satisfies FieldDefinition<FieldRelationMetadata>,
|
||||
useUpdateEntityMutation: useUpdateActivityMutation,
|
||||
hotkeyScope: EditableFieldHotkeyScope.EditableField,
|
||||
}}
|
||||
>
|
||||
<InlineCell />
|
||||
</FieldContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { ActivityAssigneePicker } from '@/activities/components/ActivityAssigneePicker';
|
||||
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
|
||||
import { useInlineCell } from '@/ui/editable-field/hooks/useInlineCell';
|
||||
import { Activity, User } from '~/generated/graphql';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@ -23,7 +23,7 @@ export const ActivityAssigneeEditableFieldEditMode = ({
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: OwnProps) => {
|
||||
const { closeEditableField } = useEditableField();
|
||||
const { closeInlineCell: closeEditableField } = useInlineCell();
|
||||
|
||||
const handleSubmit = () => {
|
||||
closeEditableField();
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
import { InlineCell } from '@/ui/editable-field/components/InlineCell';
|
||||
import { EditableFieldHotkeyScope } from '@/ui/editable-field/types/EditableFieldHotkeyScope';
|
||||
import { FieldContext } from '@/ui/field/contexts/FieldContext';
|
||||
import { FieldDefinition } from '@/ui/field/types/FieldDefinition';
|
||||
import { FieldDateMetadata } from '@/ui/field/types/FieldMetadata';
|
||||
import { IconCalendar } from '@/ui/icon/index';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { useUpdateActivityMutation } from '~/generated/graphql';
|
||||
|
||||
type OwnProps = {
|
||||
activityId: string;
|
||||
};
|
||||
|
||||
export const ActivityEditorDateField = ({ activityId }: OwnProps) => {
|
||||
return (
|
||||
<RecoilScope>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
entityId: activityId,
|
||||
recoilScopeId: 'activityDueAt',
|
||||
fieldDefinition: {
|
||||
key: 'activityDueAt',
|
||||
name: 'Due date',
|
||||
Icon: IconCalendar,
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'dueAt',
|
||||
},
|
||||
} satisfies FieldDefinition<FieldDateMetadata>,
|
||||
useUpdateEntityMutation: useUpdateActivityMutation,
|
||||
hotkeyScope: EditableFieldHotkeyScope.EditableField,
|
||||
}}
|
||||
>
|
||||
<InlineCell />
|
||||
</FieldContext.Provider>
|
||||
</RecoilScope>
|
||||
);
|
||||
};
|
||||
@ -1,5 +1,5 @@
|
||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||
import { EditableField } from '@/ui/editable-field/components/EditableField';
|
||||
import { InlineCellContainer } from '@/ui/editable-field/components/InlineCellContainer';
|
||||
import { FieldRecoilScopeContext } from '@/ui/editable-field/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
||||
import { IconArrowUpRight } from '@/ui/icon';
|
||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||
@ -23,7 +23,7 @@ export const ActivityRelationEditableField = ({ activity }: OwnProps) => {
|
||||
return (
|
||||
<RecoilScope CustomRecoilScopeContext={FieldRecoilScopeContext}>
|
||||
<RecoilScope>
|
||||
<EditableField
|
||||
<InlineCellContainer
|
||||
useEditButton
|
||||
customEditHotkeyScope={{
|
||||
scope: RelationPickerHotkeyScope.RelationPicker,
|
||||
|
||||
@ -5,7 +5,7 @@ import { useHandleCheckableActivityTargetChange } from '@/activities/hooks/useHa
|
||||
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/activities/utils/flatMapAndSortEntityForSelectArrayByName';
|
||||
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
|
||||
import { useFilteredSearchPeopleQuery } from '@/people/hooks/useFilteredSearchPeopleQuery';
|
||||
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
|
||||
import { useInlineCell } from '@/ui/editable-field/hooks/useInlineCell';
|
||||
import { MultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect';
|
||||
import { Activity, ActivityTarget } from '~/generated/graphql';
|
||||
import { assertNotNull } from '~/utils/assert';
|
||||
@ -88,7 +88,7 @@ export const ActivityRelationEditableFieldEditMode = ({
|
||||
const handleCheckItemsChange = useHandleCheckableActivityTargetChange({
|
||||
activity,
|
||||
});
|
||||
const { closeEditableField } = useEditableField();
|
||||
const { closeInlineCell: closeEditableField } = useInlineCell();
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { ActivityEditor } from '@/activities/components/ActivityEditor';
|
||||
import { entityFieldsFamilyState } from '@/ui/field/states/entityFieldsFamilyState';
|
||||
import { useGetActivityQuery } from '~/generated/graphql';
|
||||
|
||||
import '@blocknote/core/style.css';
|
||||
@ -27,12 +29,20 @@ export const RightDrawerActivity = ({
|
||||
showComment = true,
|
||||
autoFillTitle = false,
|
||||
}: OwnProps) => {
|
||||
const [, setEntityFields] = useRecoilState(
|
||||
entityFieldsFamilyState(activityId),
|
||||
);
|
||||
|
||||
const { data } = useGetActivityQuery({
|
||||
variables: {
|
||||
activityId: activityId ?? '',
|
||||
},
|
||||
skip: !activityId,
|
||||
onCompleted: (data) => {
|
||||
setEntityFields(data?.findManyActivities[0] ?? {});
|
||||
},
|
||||
});
|
||||
|
||||
const activity = data?.findManyActivities[0];
|
||||
|
||||
if (!activity) {
|
||||
|
||||
Reference in New Issue
Block a user