Make page layouts less specific (#15102)
This PR makes some hooks/functions/components more generic. I untied them from dashboards as they will be needed for any page layout type. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
committed by
GitHub
parent
4ae299973b
commit
41c970e163
+7
-7
@@ -1,20 +1,20 @@
|
||||
import { CancelDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/CancelDashboardSingleRecordAction';
|
||||
import { EditDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/EditDashboardSingleRecordAction';
|
||||
import { SaveDashboardSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/components/SaveDashboardSingleRecordAction';
|
||||
import { DashboardSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/types/DashboardSingleRecordActionKeys';
|
||||
import { SingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey';
|
||||
import { inheritActionsFromDefaultConfig } from '@/action-menu/actions/record-actions/utils/inheritActionsFromDefaultConfig';
|
||||
import { ActionScope } from '@/action-menu/actions/types/ActionScope';
|
||||
import { ActionType } from '@/action-menu/actions/types/ActionType';
|
||||
import { ActionViewType } from '@/action-menu/actions/types/ActionViewType';
|
||||
import { PageLayoutSingleRecordActionKeys } from '@/page-layout/actions/PageLayoutSingleRecordActionKeys';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconDeviceFloppy, IconPencil, IconX } from 'twenty-ui/display';
|
||||
|
||||
export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
config: {
|
||||
[DashboardSingleRecordActionKeys.EDIT_DASHBOARD]: {
|
||||
key: DashboardSingleRecordActionKeys.EDIT_DASHBOARD,
|
||||
[PageLayoutSingleRecordActionKeys.EDIT_LAYOUT]: {
|
||||
key: PageLayoutSingleRecordActionKeys.EDIT_LAYOUT,
|
||||
label: msg`Edit Dashboard`,
|
||||
shortLabel: msg`Edit`,
|
||||
isPinned: true,
|
||||
@@ -30,8 +30,8 @@ export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <EditDashboardSingleRecordAction />,
|
||||
},
|
||||
[DashboardSingleRecordActionKeys.SAVE_DASHBOARD]: {
|
||||
key: DashboardSingleRecordActionKeys.SAVE_DASHBOARD,
|
||||
[PageLayoutSingleRecordActionKeys.SAVE_LAYOUT]: {
|
||||
key: PageLayoutSingleRecordActionKeys.SAVE_LAYOUT,
|
||||
label: msg`Save Dashboard`,
|
||||
shortLabel: msg`Save`,
|
||||
isPinned: true,
|
||||
@@ -47,8 +47,8 @@ export const DASHBOARD_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
|
||||
availableOn: [ActionViewType.SHOW_PAGE],
|
||||
component: <SaveDashboardSingleRecordAction />,
|
||||
},
|
||||
[DashboardSingleRecordActionKeys.CANCEL_DASHBOARD_EDITION]: {
|
||||
key: DashboardSingleRecordActionKeys.CANCEL_DASHBOARD_EDITION,
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: {
|
||||
key: PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION,
|
||||
label: msg`Cancel Edition`,
|
||||
shortLabel: msg`Cancel`,
|
||||
isPinned: true,
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
import { Action } from '@/action-menu/actions/components/Action';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useResetDraftPageLayoutToPersistedPageLayout } from '@/dashboards/hooks/useResetDraftPageLayoutToPersistedPageLayout';
|
||||
import { useSetIsDashboardInEditMode } from '@/dashboards/hooks/useSetDashboardInEditMode';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useResetDraftPageLayoutToPersistedPageLayout } from '@/page-layout/hooks/useResetDraftPageLayoutToPersistedPageLayout';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const CancelDashboardSingleRecordAction = () => {
|
||||
@@ -12,15 +12,15 @@ export const CancelDashboardSingleRecordAction = () => {
|
||||
|
||||
const pageLayoutId = selectedRecord?.pageLayoutId;
|
||||
|
||||
const { setIsDashboardInEditMode } =
|
||||
useSetIsDashboardInEditMode(pageLayoutId);
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const { resetDraftPageLayoutToPersistedPageLayout } =
|
||||
useResetDraftPageLayoutToPersistedPageLayout(pageLayoutId);
|
||||
|
||||
const handleClick = () => {
|
||||
resetDraftPageLayoutToPersistedPageLayout();
|
||||
setIsDashboardInEditMode(false);
|
||||
setIsPageLayoutInEditMode(false);
|
||||
};
|
||||
|
||||
return <Action onClick={handleClick} />;
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import { Action } from '@/action-menu/actions/components/Action';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useSetIsDashboardInEditMode } from '@/dashboards/hooks/useSetDashboardInEditMode';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const EditDashboardSingleRecordAction = () => {
|
||||
@@ -11,11 +11,11 @@ export const EditDashboardSingleRecordAction = () => {
|
||||
|
||||
const pageLayoutId = selectedRecord?.pageLayoutId;
|
||||
|
||||
const { setIsDashboardInEditMode } =
|
||||
useSetIsDashboardInEditMode(pageLayoutId);
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const handleClick = () => {
|
||||
setIsDashboardInEditMode(true);
|
||||
setIsPageLayoutInEditMode(true);
|
||||
};
|
||||
|
||||
return <Action onClick={handleClick} />;
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
import { Action } from '@/action-menu/actions/components/Action';
|
||||
import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
|
||||
import { useSetIsDashboardInEditMode } from '@/dashboards/hooks/useSetDashboardInEditMode';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useSavePageLayout } from '@/page-layout/hooks/useSavePageLayout';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const SaveDashboardSingleRecordAction = () => {
|
||||
@@ -14,12 +14,12 @@ export const SaveDashboardSingleRecordAction = () => {
|
||||
|
||||
const { savePageLayout } = useSavePageLayout(pageLayoutId);
|
||||
|
||||
const { setIsDashboardInEditMode } =
|
||||
useSetIsDashboardInEditMode(pageLayoutId);
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const handleClick = async () => {
|
||||
await savePageLayout();
|
||||
setIsDashboardInEditMode(false);
|
||||
setIsPageLayoutInEditMode(false);
|
||||
};
|
||||
|
||||
return <Action onClick={handleClick} />;
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
export enum DashboardSingleRecordActionKeys {
|
||||
EDIT_DASHBOARD = 'edit-dashboard-single-record',
|
||||
SAVE_DASHBOARD = 'save-dashboard-single-record',
|
||||
CANCEL_DASHBOARD_EDITION = 'cancel-dashboard-edition-single-record',
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { DashboardContentRenderer } from '@/dashboards/components/DashboardContentRenderer';
|
||||
import { type Dashboard } from '@/dashboards/components/types/Dashboard';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const DashboardCard = () => {
|
||||
const targetRecord = useTargetRecord();
|
||||
|
||||
const { record: dashboard } = useFindOneRecord<Dashboard>({
|
||||
objectNameSingular: CoreObjectNameSingular.Dashboard,
|
||||
objectRecordId: targetRecord.id,
|
||||
});
|
||||
|
||||
if (!isDefined(dashboard)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <DashboardContentRenderer dashboard={dashboard} />;
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
import { type Dashboard } from '@/dashboards/components/types/Dashboard';
|
||||
import { useSetIsDashboardInEditMode } from '@/dashboards/hooks/useSetDashboardInEditMode';
|
||||
import { PageLayoutRenderer } from '@/page-layout/components/PageLayoutRenderer';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty';
|
||||
|
||||
type DashboardContentRendererProps = {
|
||||
dashboard: Dashboard;
|
||||
};
|
||||
|
||||
export const DashboardContentRenderer = ({
|
||||
dashboard,
|
||||
}: DashboardContentRendererProps) => {
|
||||
const pageLayoutId = dashboard.pageLayoutId;
|
||||
|
||||
const { setIsDashboardInEditMode } =
|
||||
useSetIsDashboardInEditMode(pageLayoutId);
|
||||
|
||||
const onInitialized = (pageLayout: PageLayout) => {
|
||||
if (isPageLayoutEmpty(pageLayout)) {
|
||||
setIsDashboardInEditMode(true);
|
||||
} else {
|
||||
setIsDashboardInEditMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageLayoutRenderer
|
||||
pageLayoutId={pageLayoutId}
|
||||
onInitialized={onInitialized}
|
||||
/>
|
||||
);
|
||||
};
|
||||
+5
-91
@@ -1,41 +1,11 @@
|
||||
import { RecordShowRightDrawerActionMenu } from '@/action-menu/components/RecordShowRightDrawerActionMenu';
|
||||
import { RecordShowRightDrawerOpenRecordButton } from '@/action-menu/components/RecordShowRightDrawerOpenRecordButton';
|
||||
import { DashboardCard } from '@/dashboards/components/DashboardCard';
|
||||
import { InformationBannerDeletedRecord } from '@/information-banner/components/deleted-record/InformationBannerDeletedRecord';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { PageLayoutRecordPageRenderer } from '@/object-record/record-show/components/PageLayoutRecordPageRenderer';
|
||||
import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer';
|
||||
import { RecordShowContainerContextStoreTargetedRecordsEffect } from '@/object-record/record-show/components/RecordShowContainerContextStoreTargetedRecordsEffect';
|
||||
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { type TargetRecordIdentifier } from '@/ui/layout/contexts/TargetRecordIdentifier';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { PageLayoutType } from '~/generated/graphql';
|
||||
|
||||
const StyledShowPageBannerContainer = styled.div`
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
const StyledShowPageRightContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
padding-bottom: ${({ theme, isInRightDrawer }) =>
|
||||
isInRightDrawer ? theme.spacing(16) : 0};
|
||||
`;
|
||||
|
||||
export const PageLayoutDispatcher = ({
|
||||
targetRecordIdentifier,
|
||||
isInRightDrawer = false,
|
||||
@@ -43,71 +13,15 @@ export const PageLayoutDispatcher = ({
|
||||
targetRecordIdentifier: TargetRecordIdentifier;
|
||||
isInRightDrawer?: boolean;
|
||||
}) => {
|
||||
const recordDeletedAt = useRecoilValue<string | null>(
|
||||
recordStoreFamilySelector({
|
||||
recordId: targetRecordIdentifier.id,
|
||||
fieldName: 'deletedAt',
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
targetRecordIdentifier.targetObjectNameSingular ===
|
||||
CoreObjectNameSingular.Dashboard
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
<RecordShowEffect
|
||||
objectNameSingular={targetRecordIdentifier.targetObjectNameSingular}
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>
|
||||
|
||||
<RecordShowContainerContextStoreTargetedRecordsEffect
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>
|
||||
|
||||
{recordDeletedAt && (
|
||||
<StyledShowPageBannerContainer>
|
||||
<InformationBannerDeletedRecord
|
||||
recordId={targetRecordIdentifier.id}
|
||||
objectNameSingular={
|
||||
targetRecordIdentifier.targetObjectNameSingular
|
||||
}
|
||||
/>
|
||||
</StyledShowPageBannerContainer>
|
||||
)}
|
||||
|
||||
<StyledShowPageRightContainer>
|
||||
<LayoutRenderingProvider
|
||||
value={{
|
||||
targetRecordIdentifier: {
|
||||
id: targetRecordIdentifier.id,
|
||||
targetObjectNameSingular:
|
||||
targetRecordIdentifier.targetObjectNameSingular,
|
||||
},
|
||||
layoutType: PageLayoutType.RECORD_PAGE,
|
||||
isInRightDrawer,
|
||||
}}
|
||||
>
|
||||
<StyledContentContainer isInRightDrawer={isInRightDrawer}>
|
||||
<DashboardCard />
|
||||
</StyledContentContainer>
|
||||
</LayoutRenderingProvider>
|
||||
|
||||
{isInRightDrawer && (
|
||||
<RightDrawerFooter
|
||||
actions={[
|
||||
<RecordShowRightDrawerActionMenu />,
|
||||
<RecordShowRightDrawerOpenRecordButton
|
||||
objectNameSingular={
|
||||
targetRecordIdentifier.targetObjectNameSingular
|
||||
}
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</StyledShowPageRightContainer>
|
||||
</>
|
||||
<PageLayoutRecordPageRenderer
|
||||
targetRecordIdentifier={targetRecordIdentifier}
|
||||
isInRightDrawer={isInRightDrawer}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
import { RecordShowRightDrawerActionMenu } from '@/action-menu/components/RecordShowRightDrawerActionMenu';
|
||||
import { RecordShowRightDrawerOpenRecordButton } from '@/action-menu/components/RecordShowRightDrawerOpenRecordButton';
|
||||
import { InformationBannerDeletedRecord } from '@/information-banner/components/deleted-record/InformationBannerDeletedRecord';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { RecordShowContainerContextStoreTargetedRecordsEffect } from '@/object-record/record-show/components/RecordShowContainerContextStoreTargetedRecordsEffect';
|
||||
import { RecordShowEffect } from '@/object-record/record-show/components/RecordShowEffect';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { PageLayoutRenderer } from '@/page-layout/components/PageLayoutRenderer';
|
||||
import { useRecordPageLayoutId } from '@/page-layout/hooks/useRecordPageLayoutId';
|
||||
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { type TargetRecordIdentifier } from '@/ui/layout/contexts/TargetRecordIdentifier';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { PageLayoutType } from '~/generated/graphql';
|
||||
|
||||
const StyledShowPageBannerContainer = styled.div`
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
const StyledShowPageRightContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
padding-bottom: ${({ theme, isInRightDrawer }) =>
|
||||
isInRightDrawer ? theme.spacing(16) : 0};
|
||||
`;
|
||||
|
||||
export const PageLayoutRecordPageRenderer = ({
|
||||
targetRecordIdentifier,
|
||||
isInRightDrawer,
|
||||
}: {
|
||||
targetRecordIdentifier: TargetRecordIdentifier;
|
||||
isInRightDrawer: boolean;
|
||||
}) => {
|
||||
const recordDeletedAt = useRecoilValue<string | null>(
|
||||
recordStoreFamilySelector({
|
||||
recordId: targetRecordIdentifier.id,
|
||||
fieldName: 'deletedAt',
|
||||
}),
|
||||
);
|
||||
|
||||
const { pageLayoutId } = useRecordPageLayoutId({
|
||||
id: targetRecordIdentifier.id,
|
||||
targetObjectNameSingular: targetRecordIdentifier.targetObjectNameSingular,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<RecordShowEffect
|
||||
objectNameSingular={targetRecordIdentifier.targetObjectNameSingular}
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>
|
||||
|
||||
<RecordShowContainerContextStoreTargetedRecordsEffect
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>
|
||||
|
||||
{recordDeletedAt && (
|
||||
<StyledShowPageBannerContainer>
|
||||
<InformationBannerDeletedRecord
|
||||
recordId={targetRecordIdentifier.id}
|
||||
objectNameSingular={targetRecordIdentifier.targetObjectNameSingular}
|
||||
/>
|
||||
</StyledShowPageBannerContainer>
|
||||
)}
|
||||
|
||||
<StyledShowPageRightContainer>
|
||||
<StyledContentContainer isInRightDrawer={isInRightDrawer}>
|
||||
<LayoutRenderingProvider
|
||||
value={{
|
||||
targetRecordIdentifier: {
|
||||
id: targetRecordIdentifier.id,
|
||||
targetObjectNameSingular:
|
||||
targetRecordIdentifier.targetObjectNameSingular,
|
||||
},
|
||||
layoutType:
|
||||
targetRecordIdentifier.targetObjectNameSingular ===
|
||||
CoreObjectNameSingular.Dashboard
|
||||
? PageLayoutType.DASHBOARD
|
||||
: PageLayoutType.RECORD_PAGE,
|
||||
isInRightDrawer,
|
||||
}}
|
||||
>
|
||||
{isDefined(pageLayoutId) && (
|
||||
<PageLayoutRenderer pageLayoutId={pageLayoutId} />
|
||||
)}
|
||||
</LayoutRenderingProvider>
|
||||
</StyledContentContainer>
|
||||
|
||||
{isInRightDrawer && (
|
||||
<RightDrawerFooter
|
||||
actions={[
|
||||
<RecordShowRightDrawerActionMenu />,
|
||||
<RecordShowRightDrawerOpenRecordButton
|
||||
objectNameSingular={
|
||||
targetRecordIdentifier.targetObjectNameSingular
|
||||
}
|
||||
recordId={targetRecordIdentifier.id}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</StyledShowPageRightContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
export enum PageLayoutSingleRecordActionKeys {
|
||||
EDIT_LAYOUT = 'edit-layout-single-record',
|
||||
SAVE_LAYOUT = 'save-layout-single-record',
|
||||
CANCEL_LAYOUT_EDITION = 'cancel-layout-edition-single-record',
|
||||
}
|
||||
@@ -1,49 +1,50 @@
|
||||
import { PageLayoutInitializationQueryEffect } from '@/page-layout/components/PageLayoutInitializationQueryEffect';
|
||||
|
||||
import { PageLayoutRendererContent } from '@/page-layout/components/PageLayoutRendererContent';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { type PageLayout } from '@/page-layout/types/PageLayout';
|
||||
import { getTabListInstanceIdFromPageLayoutId } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutId';
|
||||
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
|
||||
import { isPageLayoutEmpty } from '@/page-layout/utils/isPageLayoutEmpty';
|
||||
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
|
||||
import 'react-grid-layout/css/styles.css';
|
||||
import 'react-resizable/css/styles.css';
|
||||
import { PageLayoutType } from '~/generated/graphql';
|
||||
|
||||
type PageLayoutRendererProps = {
|
||||
pageLayoutId: string;
|
||||
onInitialized?: (pageLayout: PageLayout) => void;
|
||||
};
|
||||
|
||||
export const PageLayoutRenderer = ({
|
||||
pageLayoutId,
|
||||
onInitialized,
|
||||
}: PageLayoutRendererProps) => {
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const onInitialized = (pageLayout: PageLayout) => {
|
||||
if (isPageLayoutEmpty(pageLayout)) {
|
||||
setIsPageLayoutInEditMode(true);
|
||||
} else {
|
||||
setIsPageLayoutInEditMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<LayoutRenderingProvider
|
||||
<PageLayoutComponentInstanceContext.Provider
|
||||
value={{
|
||||
targetRecordIdentifier: undefined,
|
||||
layoutType: PageLayoutType.DASHBOARD,
|
||||
isInRightDrawer: false,
|
||||
instanceId: pageLayoutId,
|
||||
}}
|
||||
>
|
||||
<PageLayoutComponentInstanceContext.Provider
|
||||
<TabListComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: pageLayoutId,
|
||||
instanceId: getTabListInstanceIdFromPageLayoutId(pageLayoutId),
|
||||
}}
|
||||
>
|
||||
<TabListComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: getTabListInstanceIdFromPageLayoutId(pageLayoutId),
|
||||
}}
|
||||
>
|
||||
<PageLayoutInitializationQueryEffect
|
||||
pageLayoutId={pageLayoutId}
|
||||
onInitialized={onInitialized}
|
||||
/>
|
||||
<PageLayoutRendererContent />
|
||||
</TabListComponentInstanceContext.Provider>
|
||||
</PageLayoutComponentInstanceContext.Provider>
|
||||
</LayoutRenderingProvider>
|
||||
<PageLayoutInitializationQueryEffect
|
||||
pageLayoutId={pageLayoutId}
|
||||
onInitialized={onInitialized}
|
||||
/>
|
||||
<PageLayoutRendererContent />
|
||||
</TabListComponentInstanceContext.Provider>
|
||||
</PageLayoutComponentInstanceContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { type TargetRecordIdentifier } from '@/ui/layout/contexts/TargetRecordIdentifier';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useRecordPageLayoutId = ({
|
||||
id,
|
||||
targetObjectNameSingular,
|
||||
}: TargetRecordIdentifier) => {
|
||||
const { record } = useFindOneRecord<ObjectRecord & { pageLayoutId?: string }>(
|
||||
{
|
||||
objectNameSingular: targetObjectNameSingular,
|
||||
objectRecordId: id,
|
||||
},
|
||||
);
|
||||
|
||||
if (!isDefined(record)) {
|
||||
return {
|
||||
pageLayoutId: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (isDefined(record.pageLayoutId)) {
|
||||
return {
|
||||
pageLayoutId: record.pageLayoutId,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: implement a default layout
|
||||
return {
|
||||
pageLayoutId: 'DEFAULT_LAYOUT_ID',
|
||||
};
|
||||
};
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
import { DashboardSingleRecordActionKeys } from '@/action-menu/actions/record-actions/single-record/dashboard-actions/types/DashboardSingleRecordActionKeys';
|
||||
import { forceRegisteredActionsByKeyState } from '@/action-menu/actions/states/forceRegisteredActionsMapComponentState';
|
||||
import { PageLayoutSingleRecordActionKeys } from '@/page-layout/actions/PageLayoutSingleRecordActionKeys';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
export const useSetIsDashboardInEditMode = (pageLayoutIdFromProps: string) => {
|
||||
export const useSetIsPageLayoutInEditMode = (pageLayoutIdFromProps: string) => {
|
||||
const pageLayoutId = useAvailableComponentInstanceIdOrThrow(
|
||||
PageLayoutComponentInstanceContext,
|
||||
pageLayoutIdFromProps,
|
||||
@@ -17,19 +17,19 @@ export const useSetIsDashboardInEditMode = (pageLayoutIdFromProps: string) => {
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const setIsDashboardInEditMode = useRecoilCallback(
|
||||
const setIsPageLayoutInEditMode = useRecoilCallback(
|
||||
({ set }) =>
|
||||
(value: boolean) => {
|
||||
set(isPageLayoutInEditModeState, value);
|
||||
set(forceRegisteredActionsByKeyState, (prev) => ({
|
||||
...prev,
|
||||
[DashboardSingleRecordActionKeys.EDIT_DASHBOARD]: !value,
|
||||
[DashboardSingleRecordActionKeys.SAVE_DASHBOARD]: value,
|
||||
[DashboardSingleRecordActionKeys.CANCEL_DASHBOARD_EDITION]: value,
|
||||
[PageLayoutSingleRecordActionKeys.EDIT_LAYOUT]: !value,
|
||||
[PageLayoutSingleRecordActionKeys.SAVE_LAYOUT]: value,
|
||||
[PageLayoutSingleRecordActionKeys.CANCEL_LAYOUT_EDITION]: value,
|
||||
}));
|
||||
},
|
||||
[isPageLayoutInEditModeState],
|
||||
);
|
||||
|
||||
return { setIsDashboardInEditMode };
|
||||
return { setIsPageLayoutInEditMode };
|
||||
};
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
import { useNavigatePageLayoutCommandMenu } from '@/command-menu/pages/page-layout/hooks/useNavigatePageLayoutCommandMenu';
|
||||
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
|
||||
import { useSetIsDashboardInEditMode } from '@/dashboards/hooks/useSetDashboardInEditMode';
|
||||
import { useSetIsPageLayoutInEditMode } from '@/page-layout/hooks/useSetIsPageLayoutInEditMode';
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { isPageLayoutInEditModeComponentState } from '@/page-layout/states/isPageLayoutInEditModeComponentState';
|
||||
import { WidgetContainer } from '@/page-layout/widgets/components/WidgetContainer';
|
||||
@@ -27,14 +27,14 @@ export const WidgetPlaceholder = () => {
|
||||
isPageLayoutInEditModeComponentState,
|
||||
);
|
||||
|
||||
const { setIsDashboardInEditMode } =
|
||||
useSetIsDashboardInEditMode(pageLayoutId);
|
||||
const { setIsPageLayoutInEditMode } =
|
||||
useSetIsPageLayoutInEditMode(pageLayoutId);
|
||||
|
||||
const { navigatePageLayoutCommandMenu } = useNavigatePageLayoutCommandMenu();
|
||||
|
||||
const handleClick = () => {
|
||||
if (!isPageLayoutInEditMode) {
|
||||
setIsDashboardInEditMode(true);
|
||||
setIsPageLayoutInEditMode(true);
|
||||
}
|
||||
navigatePageLayoutCommandMenu({
|
||||
commandMenuPage: CommandMenuPages.PageLayoutWidgetTypeSelect,
|
||||
|
||||
Reference in New Issue
Block a user