Skip to content

Commit

Permalink
Merge branch 'main' into refactoring-useScrollState
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasbordeau committed Aug 22, 2024
2 parents 4cab78d + 579c2eb commit 049a672
Show file tree
Hide file tree
Showing 244 changed files with 3,636 additions and 2,363 deletions.
2 changes: 1 addition & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"start": {
"cache": true,
"dependsOn": ["^build"]
"dependsOn": ["^typecheck","^build"]
},
"lint": {
"executor": "@nx/eslint:lint",
Expand Down
2 changes: 1 addition & 1 deletion packages/twenty-chrome-extension/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7455,7 +7455,7 @@ export type Workspace = {
billingSubscriptions?: Maybe<Array<BillingSubscription>>;
createdAt: Scalars['DateTime'];
currentBillingSubscription?: Maybe<BillingSubscription>;
currentCacheVersion?: Maybe<Scalars['String']>;
metadataVersion?: Maybe<Scalars['String']>;
deletedAt?: Maybe<Scalars['DateTime']>;
displayName?: Maybe<Scalars['String']>;
domainName?: Maybe<Scalars['String']>;
Expand Down
2 changes: 1 addition & 1 deletion packages/twenty-emails/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "twenty-emails",
"version": "0.23.1",
"version": "0.23.2",
"description": "",
"author": "",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/twenty-front/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "twenty-front",
"version": "0.23.1",
"version": "0.23.2",
"private": true,
"type": "module",
"scripts": {
Expand Down
6 changes: 6 additions & 0 deletions packages/twenty-front/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
"outputPath": "{projectRoot}/build"
}
},
"serve": {
"executor": "nx:run-commands",
"options": {
"command": "npx serve -s {projectRoot}/build"
}
},
"start": {
"executor": "@nx/vite:dev-server",
"options": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import { AppPath } from '@/types/AppPath';
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
import { SettingsPath } from '@/types/SettingsPath';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useCleanRecoilState } from '~/hooks/useCleanRecoilState';
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffectNavigateLocation';
import { isDefined } from '~/utils/isDefined';
import { useCleanRecoilState } from '~/hooks/useCleanRecoilState';

// TODO: break down into smaller functions and / or hooks
// - moved usePageChangeEffectNavigateLocation into dedicated hook
Expand Down Expand Up @@ -153,7 +153,10 @@ export const PageChangeEffect = () => {
label: 'Create Task',
type: CommandType.Create,
Icon: IconCheckbox,
onCommandClick: () => openCreateActivity({ targetableObjects: [] }),
onCommandClick: () =>
openCreateActivity({
targetableObjects: [],
}),
},
]);
}, [addToCommandMenu, setToInitialCommandMenu, openCreateActivity]);
Expand Down
5 changes: 4 additions & 1 deletion packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1380,14 +1380,17 @@ export type Workspace = {
billingSubscriptions?: Maybe<Array<BillingSubscription>>;
createdAt: Scalars['DateTime']['output'];
currentBillingSubscription?: Maybe<BillingSubscription>;
currentCacheVersion?: Maybe<Scalars['String']['output']>;
currentMetadataVersion: Scalars['Float']['output'];
databaseSchema: Scalars['String']['output'];
databaseUrl: Scalars['String']['output'];
deletedAt?: Maybe<Scalars['DateTime']['output']>;
displayName?: Maybe<Scalars['String']['output']>;
domainName?: Maybe<Scalars['String']['output']>;
featureFlags?: Maybe<Array<FeatureFlag>>;
id: Scalars['UUID']['output'];
inviteHash?: Maybe<Scalars['String']['output']>;
logo?: Maybe<Scalars['String']['output']>;
metadataVersion: Scalars['Float']['output'];
updatedAt: Scalars['DateTime']['output'];
workspaceMembersCount?: Maybe<Scalars['Float']['output']>;
};
Expand Down
14 changes: 8 additions & 6 deletions packages/twenty-front/src/generated/graphql.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,40 @@ export const useOpenCreateActivityDrawer = ({
assigneeId: customAssignee?.id,
});

const targetableObjectRelationIdName = `${targetableObjects[0].targetObjectNameSingular}Id`;

await createOneActivityTarget({
taskId:
activityObjectNameSingular === CoreObjectNameSingular.Task
? activity.id
: undefined,
noteId:
activityObjectNameSingular === CoreObjectNameSingular.Note
? activity.id
: undefined,
[targetableObjectRelationIdName]: targetableObjects[0].id,
});
if (targetableObjects.length > 0) {
const targetableObjectRelationIdName = `${targetableObjects[0].targetObjectNameSingular}Id`;

await createOneActivityTarget({
taskId:
activityObjectNameSingular === CoreObjectNameSingular.Task
? activity.id
: undefined,
noteId:
activityObjectNameSingular === CoreObjectNameSingular.Note
? activity.id
: undefined,
[targetableObjectRelationIdName]: targetableObjects[0].id,
});

setActivityTargetableEntityArray(targetableObjects);
} else {
await createOneActivityTarget({
taskId:
activityObjectNameSingular === CoreObjectNameSingular.Task
? activity.id
: undefined,
noteId:
activityObjectNameSingular === CoreObjectNameSingular.Note
? activity.id
: undefined,
});

setActivityTargetableEntityArray([]);
}

setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
setViewableRecordId(activity.id);
setViewableRecordNameSingular(activityObjectNameSingular);
setActivityTargetableEntityArray(targetableObjects ?? []);

openRightDrawer(RightDrawerPages.ViewRecord);
setIsUpsertingActivityInDB(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { useMemo, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { useRecoilState, useSetRecoilState } from 'recoil';

import { currentUserState } from '@/auth/states/currentUserState';
Expand Down Expand Up @@ -49,8 +49,8 @@ export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
},
}),
headers: {
...(currentWorkspace?.currentCacheVersion && {
'X-Schema-Version': currentWorkspace.currentCacheVersion,
...(currentWorkspace?.metadataVersion && {
'X-Schema-Version': `${currentWorkspace.metadataVersion}`,
}),
},
defaultOptions: {
Expand Down Expand Up @@ -95,7 +95,7 @@ export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
setCurrentWorkspace,
setWorkspaces,
isDebugMode,
currentWorkspace?.currentCacheVersion,
currentWorkspace?.metadataVersion,
setPreviousUrl,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type CurrentWorkspace = Pick<
| 'activationStatus'
| 'currentBillingSubscription'
| 'workspaceMembersCount'
| 'currentCacheVersion'
| 'metadataVersion'
>;

export const currentWorkspaceState = createState<CurrentWorkspace | null>({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import styled from '@emotion/styled';
import { useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';

import { useClearField } from '@/object-record/record-field/hooks/useClearField';
import { useSelectField } from '@/object-record/record-field/meta-types/hooks/useSelectField';
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
import { SINGLE_ENTITY_SELECT_BASE_LIST } from '@/object-record/relation-picker/constants/SingleEntitySelectBaseList';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { SelectOption } from '@/spreadsheet-import/types';
import { SelectInput } from '@/ui/input/components/SelectInput';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { useSelectableListStates } from '@/ui/layout/selectable-list/hooks/internal/useSelectableListStates';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemSelectTag } from '@/ui/navigation/menu-item/components/MenuItemSelectTag';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { isDefined } from '~/utils/isDefined';

const StyledRelationPickerContainer = styled.div`
left: -1px;
position: absolute;
top: -1px;
`;
import { useState } from 'react';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-ui';

type SelectFieldInputProps = {
onSubmit?: FieldInputEvent;
Expand All @@ -36,55 +22,30 @@ export const SelectFieldInput = ({
}: SelectFieldInputProps) => {
const { persistField, fieldDefinition, fieldValue, hotkeyScope } =
useSelectField();
const { selectedItemIdState } = useSelectableListStates({
selectableListScopeId: SINGLE_ENTITY_SELECT_BASE_LIST,
});
const [selectWrapperRef, setSelectWrapperRef] =
useState<HTMLDivElement | null>(null);

const [filteredOptions, setFilteredOptions] = useState<SelectOption[]>([]);

const { handleResetSelectedPosition } = useSelectableList(
SINGLE_ENTITY_SELECT_BASE_LIST,
);
const clearField = useClearField();

const selectedItemId = useRecoilValue(selectedItemIdState);
const [searchFilter, setSearchFilter] = useState('');
const containerRef = useRef<HTMLDivElement>(null);

const selectedOption = fieldDefinition.metadata.options.find(
(option) => option.value === fieldValue,
);

const optionsToSelect =
fieldDefinition.metadata.options.filter((option) => {
return (
option.value !== fieldValue &&
option.label.toLowerCase().includes(searchFilter.toLowerCase())
);
}) || [];

const optionsInDropDown = selectedOption
? [selectedOption, ...optionsToSelect]
: optionsToSelect;

// handlers
const handleClearField = () => {
clearField();
onCancel?.();
};

useListenClickOutside({
refs: [containerRef],
callback: (event) => {
event.stopImmediatePropagation();
const handleSubmit = (option: SelectOption) => {
onSubmit?.(() => persistField(option?.value));

const weAreNotInAnHTMLInput = !(
event.target instanceof HTMLInputElement &&
event.target.tagName === 'INPUT'
);
if (weAreNotInAnHTMLInput && isDefined(onCancel)) {
onCancel();
handleResetSelectedPosition();
}
},
});
handleResetSelectedPosition();
};

useScopedHotkeys(
Key.Escape,
Expand All @@ -96,81 +57,40 @@ export const SelectFieldInput = ({
[onCancel, handleResetSelectedPosition],
);

useScopedHotkeys(
Key.Enter,
() => {
const selectedOption = optionsInDropDown.find((option) =>
option.label.toLowerCase().includes(searchFilter.toLowerCase()),
);

if (isDefined(selectedOption)) {
onSubmit?.(() => persistField(selectedOption.value));
}
handleResetSelectedPosition();
},
hotkeyScope,
);

const optionIds = [
`No ${fieldDefinition.label}`,
...optionsInDropDown.map((option) => option.value),
...filteredOptions.map((option) => option.value),
];

return (
<SelectableList
selectableListId={SINGLE_ENTITY_SELECT_BASE_LIST}
selectableItemIdArray={optionIds}
hotkeyScope={hotkeyScope}
onEnter={(itemId) => {
const option = optionsInDropDown.find(
(option) => option.value === itemId,
);
if (isDefined(option)) {
onSubmit?.(() => persistField(option.value));
handleResetSelectedPosition();
}
}}
>
<StyledRelationPickerContainer ref={containerRef}>
<DropdownMenu data-select-disable>
<DropdownMenuSearchInput
value={searchFilter}
onChange={(event) => setSearchFilter(event.currentTarget.value)}
autoFocus
/>
<DropdownMenuSeparator />

<DropdownMenuItemsContainer hasMaxHeight>
{fieldDefinition.metadata.isNullable ?? (
<MenuItemSelectTag
key={`No ${fieldDefinition.label}`}
selected={false}
text={`No ${fieldDefinition.label}`}
color="transparent"
variant="outline"
onClick={handleClearField}
isKeySelected={selectedItemId === `No ${fieldDefinition.label}`}
/>
)}

{optionsInDropDown.map((option) => {
return (
<MenuItemSelectTag
key={option.value}
selected={option.value === fieldValue}
text={option.label}
color={option.color}
onClick={() => {
onSubmit?.(() => persistField(option.value));
handleResetSelectedPosition();
}}
isKeySelected={selectedItemId === option.value}
/>
);
})}
</DropdownMenuItemsContainer>
</DropdownMenu>
</StyledRelationPickerContainer>
</SelectableList>
<div ref={setSelectWrapperRef}>
<SelectableList
selectableListId={SINGLE_ENTITY_SELECT_BASE_LIST}
selectableItemIdArray={optionIds}
hotkeyScope={hotkeyScope}
onEnter={(itemId) => {
const option = filteredOptions.find(
(option) => option.value === itemId,
);
if (isDefined(option)) {
onSubmit?.(() => persistField(option.value));
handleResetSelectedPosition();
}
}}
>
<SelectInput
parentRef={selectWrapperRef}
onOptionSelected={handleSubmit}
options={fieldDefinition.metadata.options}
onCancel={onCancel}
defaultOption={selectedOption}
onFilterChange={setFilteredOptions}
onClear={
fieldDefinition.metadata.isNullable ? handleClearField : undefined
}
clearLabel={fieldDefinition.label}
/>
</SelectableList>
</div>
);
};
Loading

0 comments on commit 049a672

Please sign in to comment.