From be171e84d7198f6f0439152f5527aa3661a0e7a9 Mon Sep 17 00:00:00 2001
From: Marie <51697796+ijreilly@users.noreply.github.com>
Date: Tue, 8 Oct 2024 16:20:34 +0200
Subject: [PATCH 1/4] Fix create task (#7498)
Fixing issue introduced by [Add Skeleton loading for side
panel](https://github.com/twentyhq/twenty/pull/7394/files#top):
https://github.com/user-attachments/assets/6c8e299c-d663-4aa7-83ed-ca7041cd15e7
---
.../hooks/useOpenCreateActivityDrawer.ts | 2 +-
.../components/RightDrawerRecord.tsx | 18 +++++++++++++++++-
.../components/RecordShowContainer.tsx | 8 ++------
.../record-show/hooks/useRecordShowPage.ts | 6 +++---
4 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts
index c35d278371219..1cc4af08a81e4 100644
--- a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts
+++ b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts
@@ -67,8 +67,8 @@ export const useOpenCreateActivityDrawer = ({
targetableObjects: ActivityTargetableObject[];
customAssignee?: WorkspaceMember;
}) => {
- openRightDrawer(RightDrawerPages.ViewRecord);
setIsNewViewableRecordLoading(true);
+ openRightDrawer(RightDrawerPages.ViewRecord);
setViewableRecordId(null);
setViewableRecordNameSingular(activityObjectNameSingular);
diff --git a/packages/twenty-front/src/modules/object-record/record-right-drawer/components/RightDrawerRecord.tsx b/packages/twenty-front/src/modules/object-record/record-right-drawer/components/RightDrawerRecord.tsx
index 6a76206e6e754..3a747b0913a19 100644
--- a/packages/twenty-front/src/modules/object-record/record-right-drawer/components/RightDrawerRecord.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-right-drawer/components/RightDrawerRecord.tsx
@@ -1,5 +1,6 @@
import { useRecoilValue } from 'recoil';
+import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState';
import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer';
@@ -18,7 +19,19 @@ export const RightDrawerRecord = () => {
const viewableRecordNameSingular = useRecoilValue(
viewableRecordNameSingularState,
);
+ const isNewViewableRecordLoading = useRecoilValue(
+ isNewViewableRecordLoadingState,
+ );
const viewableRecordId = useRecoilValue(viewableRecordIdState);
+
+ if (!viewableRecordNameSingular && !isNewViewableRecordLoading) {
+ throw new Error(`Object name is not defined`);
+ }
+
+ if (!viewableRecordId && !isNewViewableRecordLoading) {
+ throw new Error(`Record id is not defined`);
+ }
+
const { objectNameSingular, objectRecordId } = useRecordShowPage(
viewableRecordNameSingular ?? '',
viewableRecordId ?? '',
@@ -27,12 +40,15 @@ export const RightDrawerRecord = () => {
return (
-
+ {!isNewViewableRecordLoading && (
+
+ )}
diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx
index f9176f4999137..9b1e10601ab49 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx
@@ -21,7 +21,6 @@ import { RecordInlineCell } from '@/object-record/record-inline-cell/components/
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
import { PropertyBoxSkeletonLoader } from '@/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
-import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
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 { recordLoadingFamilyState } from '@/object-record/record-store/states/recordLoadingFamilyState';
@@ -49,6 +48,7 @@ type RecordShowContainerProps = {
objectRecordId: string;
loading: boolean;
isInRightDrawer?: boolean;
+ isNewRightDrawerItemLoading?: boolean;
};
export const RecordShowContainer = ({
@@ -56,6 +56,7 @@ export const RecordShowContainer = ({
objectRecordId,
loading,
isInRightDrawer = false,
+ isNewRightDrawerItemLoading = false,
}: RecordShowContainerProps) => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
@@ -82,9 +83,6 @@ export const RecordShowContainer = ({
recordId: objectRecordId,
}),
);
- const isNewViewableRecordLoading = useRecoilValue(
- isNewViewableRecordLoadingState,
- );
const [uploadImage] = useUploadImageMutation();
const { updateOneRecord } = useUpdateOneRecord({ objectNameSingular });
@@ -166,8 +164,6 @@ export const RecordShowContainer = ({
const isReadOnly = objectMetadataItem.isRemote;
const isMobile = useIsMobile() || isInRightDrawer;
const isPrefetchLoading = useIsPrefetchLoading();
- const isNewRightDrawerItemLoading =
- isInRightDrawer && isNewViewableRecordLoading;
const summaryCard =
!isNewRightDrawerItemLoading && isDefined(recordFromStore) ? (
diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts
index 7bdaf0b4284bf..fb73b8ce9a523 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts
+++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts
@@ -23,10 +23,10 @@ export const useRecordShowPage = (
objectRecordId: paramObjectRecordId,
} = useParams();
- const objectNameSingular = propsObjectNameSingular || paramObjectNameSingular;
- const objectRecordId = propsObjectRecordId || paramObjectRecordId;
+ const objectNameSingular = propsObjectNameSingular ?? paramObjectNameSingular;
+ const objectRecordId = propsObjectRecordId ?? paramObjectRecordId;
- if (!objectNameSingular || !objectRecordId) {
+ if (!isDefined(objectNameSingular) || !isDefined(objectRecordId)) {
throw new Error('Object name or Record id is not defined');
}
From 10e75174f5ae424eaf456777e4f9e18ec23a5d06 Mon Sep 17 00:00:00 2001
From: Vardhaman Bhandari <97441447+Vardhaman619@users.noreply.github.com>
Date: Tue, 8 Oct 2024 20:12:13 +0530
Subject: [PATCH 2/4] Fix: Adjust chevron alignment to the right edge (#7438)
This pull request addresses the alignment issue of the chevron icon,
ensuring that it is positioned correctly on the right edge.
Fixes [#7403](https://github.com/twentyhq/twenty/issues/7403)

---------
Co-authored-by: Charles Bochet
Co-authored-by: ehconitin
---
.../components/SettingsApiKeysFieldItemTableRow.tsx | 3 ++-
.../settings/developers/components/SettingsApiKeysTable.tsx | 2 +-
.../components/SettingsDevelopersWebhookTableRow.tsx | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysFieldItemTableRow.tsx b/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysFieldItemTableRow.tsx
index 4d4dc8d45e6f1..c8051eab0511a 100644
--- a/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysFieldItemTableRow.tsx
+++ b/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysFieldItemTableRow.tsx
@@ -7,7 +7,7 @@ import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
export const StyledApisFieldTableRow = styled(TableRow)`
- grid-template-columns: 312px 132px 68px;
+ grid-template-columns: 312px auto 28px;
`;
const StyledNameTableCell = styled(TableCell)`
@@ -18,6 +18,7 @@ const StyledNameTableCell = styled(TableCell)`
const StyledIconTableCell = styled(TableCell)`
justify-content: center;
padding-right: ${({ theme }) => theme.spacing(1)};
+ padding-left: 0;
`;
const StyledIconChevronRight = styled(IconChevronRight)`
diff --git a/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysTable.tsx b/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysTable.tsx
index ede12c34bf6cb..6d70ada4c862f 100644
--- a/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysTable.tsx
+++ b/packages/twenty-front/src/modules/settings/developers/components/SettingsApiKeysTable.tsx
@@ -18,7 +18,7 @@ const StyledTableBody = styled(TableBody)`
`;
const StyledTableRow = styled(TableRow)`
- grid-template-columns: 312px 132px 68px;
+ grid-template-columns: 312px auto 28px;
`;
export const SettingsApiKeysTable = () => {
diff --git a/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookTableRow.tsx b/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookTableRow.tsx
index 0c093d5ecbd20..d559f89a200a9 100644
--- a/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookTableRow.tsx
+++ b/packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookTableRow.tsx
@@ -1,4 +1,3 @@
-import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconChevronRight } from 'twenty-ui';
@@ -8,12 +7,13 @@ import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
export const StyledApisFieldTableRow = styled(TableRow)`
- grid-template-columns: 444px 68px;
+ grid-template-columns: 1fr 28px;
`;
const StyledIconTableCell = styled(TableCell)`
justify-content: center;
padding-right: ${({ theme }) => theme.spacing(1)};
+ padding-left: 0;
`;
const StyledUrlTableCell = styled(TableCell)`
From 098551b7b882c158bd71e4d65cc4f6375085294e Mon Sep 17 00:00:00 2001
From: Harshit Singh <73997189+harshit078@users.noreply.github.com>
Date: Tue, 8 Oct 2024 20:18:15 +0530
Subject: [PATCH 3/4] fix: Invite by email table overflows in mobile viewport
(#7273)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
##Description
- This PR solves the issue #7253
- Made the invite table mobile friendly for all media width
## Before
https://github.com/user-attachments/assets/458bd47d-38fb-4ddc-a996-c1bb3908d014
## After
https://github.com/user-attachments/assets/7a4f6f9a-7fef-42f1-a226-59a1d73767f4
> [!Note]
> I've added 2 implementations and if either doesn't follow design rules
then it can be changed-
> - Made the trash icon `accent danger`
> - When emails are long, given scroll for ease of convience.
---------
Co-authored-by: Nitin Koche
---
.../settings/SettingsWorkspaceMembers.tsx | 114 ++++++++++++------
1 file changed, 77 insertions(+), 37 deletions(-)
diff --git a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx
index 0079fb8885013..63bbd6717d63a 100644
--- a/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx
+++ b/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx
@@ -7,8 +7,8 @@ import {
IconUsers,
IconReload,
IconMail,
- StyledText,
Avatar,
+ MOBILE_VIEWPORT,
} from 'twenty-ui';
import { isNonEmptyArray } from '@sniptt/guards';
import { useTheme } from '@emotion/react';
@@ -53,6 +53,47 @@ const StyledTable = styled(Table)`
margin-top: ${({ theme }) => theme.spacing(0.5)};
`;
+const StyledTableRow = styled(TableRow)`
+ @media (max-width: ${MOBILE_VIEWPORT}px) {
+ display: grid;
+ grid-template-columns: 3fr;
+ }
+`;
+const StyledTableCell = styled(TableCell)`
+ padding: ${({ theme }) => theme.spacing(1)};
+ @media (max-width: ${MOBILE_VIEWPORT}px) {
+ &:first-child {
+ max-width: 100%;
+ padding-top: 2px;
+ white-space: nowrap;
+ overflow: scroll;
+ scroll-behavior: smooth;
+ }
+ }
+`;
+const StyledIconWrapper = styled.div`
+ left: 2px;
+ margin-right: ${({ theme }) => theme.spacing(2)};
+ position: relative;
+ top: 1px;
+`;
+
+const StyledScrollableTextContainer = styled.div`
+ max-width: 100%;
+ overflow-x: auto;
+ white-space: pre-line;
+`;
+
+const StyledTextContainer = styled.div`
+ color: ${({ theme }) => theme.font.color.secondary};
+ max-width: max-content;
+ overflow-x: auto;
+ position: absolute;
+ @media (min-width: 360px) and (max-width: 420px) {
+ max-width: 150px;
+ margin-top: ${({ theme }) => theme.spacing(1)};
+ }
+`;
const StyledTableHeaderRow = styled(Table)`
margin-bottom: ${({ theme }) => theme.spacing(1.5)};
`;
@@ -165,28 +206,25 @@ export const SettingsWorkspaceMembers = () => {
-
- }
- text={
- workspaceMember.name.firstName +
+
+
+
+
+ {workspaceMember.name.firstName +
' ' +
- workspaceMember.name.lastName
- }
- />
+ workspaceMember.name.lastName}
+
-
+
+ {workspaceMember.userEmail}
+
{currentWorkspaceMember?.id !== workspaceMember.id && (
@@ -225,25 +263,27 @@ export const SettingsWorkspaceMembers = () => {
{workspaceInvitations?.map((workspaceInvitation) => (
-
-
-
- }
- text={workspaceInvitation.email}
- />
-
-
+
+
+
+
+
+
+ {workspaceInvitation.email}
+
+
+
-
-
+
+
{
@@ -266,8 +306,8 @@ export const SettingsWorkspaceMembers = () => {
Icon={IconTrash}
/>
-
-
+
+
))}
From fcd60be110eb0a524f1f2eefe439c3249dd3086d Mon Sep 17 00:00:00 2001
From: Charles Bochet
Date: Tue, 8 Oct 2024 16:52:15 +0200
Subject: [PATCH 4/4] Fix filtered INDEX view not loading (#7501)
## Context
We have recently merged a refactoring of our view module. However, one
case was forgotten which is to test our dynamic filtering logic.
It is currently possible to pass unsaved filters through the URL and
these filters will be applied to the currentView through
`QueryParamsFiltersEffect`. This component was saving filters but also
listening to them through useGetCurrentView hook.
## How
1) I'm removing this infinite loop by directly loading currentViewId
through the right recoil atom.
Bonus: I'm also removing the unmounting logic which seems wrong to me as
unsaved filters are mounted on a specific view, there is no need to
remove them while switching views in my opinion.
---
.../components/RecordDetailRelationSection.tsx | 12 ++++++++++++
.../components/QueryParamsFiltersEffect.tsx | 16 +++++-----------
2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx
index 23fc1f07096f5..edd49b3f84068 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx
@@ -24,12 +24,15 @@ import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRela
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
+import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
+import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { FilterQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
+import { View } from '@/views/types/View';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
@@ -119,12 +122,21 @@ export const RecordDetailRelationSection = ({
scopeId: dropdownId,
});
+ const { records: views } = usePrefetchedData(PrefetchKey.AllViews);
+
+ const indexView = views.find(
+ (view) =>
+ view.key === 'INDEX' &&
+ view.objectMetadataId === relationObjectMetadataItem.id,
+ );
+
const filterQueryParams: FilterQueryParams = {
filter: {
[relationFieldMetadataItem?.name || '']: {
[ViewFilterOperand.Is]: [recordId],
},
},
+ view: indexView?.id,
};
const filterLinkHref = `/objects/${
relationObjectMetadataItem.namePlural
diff --git a/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx b/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx
index 10ecdfa83b87e..f811df0ddf6ba 100644
--- a/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx
+++ b/packages/twenty-front/src/modules/views/components/QueryParamsFiltersEffect.tsx
@@ -1,23 +1,24 @@
import { useEffect } from 'react';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyStateV2';
import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
-import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { useResetUnsavedViewStates } from '@/views/hooks/useResetUnsavedViewStates';
+import { currentViewIdComponentState } from '@/views/states/currentViewIdComponentState';
import { unsavedToUpsertViewFiltersComponentFamilyState } from '@/views/states/unsavedToUpsertViewFiltersComponentFamilyState';
-import { isDefined } from 'twenty-ui';
export const QueryParamsFiltersEffect = () => {
const { hasFiltersQueryParams, getFiltersFromQueryParams, viewIdQueryParam } =
useViewFromQueryParams();
+ const currentViewId = useRecoilComponentValueV2(currentViewIdComponentState);
+
const setUnsavedViewFilter = useSetRecoilComponentFamilyStateV2(
unsavedToUpsertViewFiltersComponentFamilyState,
- { viewId: viewIdQueryParam },
+ { viewId: viewIdQueryParam ?? currentViewId },
);
const { resetUnsavedViewStates } = useResetUnsavedViewStates();
- const { currentViewId } = useGetCurrentView();
useEffect(() => {
if (!hasFiltersQueryParams) {
@@ -29,18 +30,11 @@ export const QueryParamsFiltersEffect = () => {
setUnsavedViewFilter(filtersFromParams);
}
});
-
- return () => {
- if (isDefined(currentViewId)) {
- resetUnsavedViewStates(currentViewId);
- }
- };
}, [
getFiltersFromQueryParams,
hasFiltersQueryParams,
resetUnsavedViewStates,
setUnsavedViewFilter,
- currentViewId,
]);
return <>>;