Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 74e3dba98f | |||
| d225d132f9 | |||
| 020000b3c5 | |||
| 0a94f93f0c |
+1
@@ -6,6 +6,7 @@ export const FIND_MANY_FRONT_COMPONENTS = gql`
|
||||
id
|
||||
name
|
||||
applicationId
|
||||
isHeadless
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { addWidgetToTab } from '@/page-layout/utils/addWidgetToTab';
|
||||
import { createDefaultFrontComponentWidgetForVerticalList } from '@/page-layout/utils/createDefaultFrontComponentWidgetForVerticalList';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export const useCreateRecordPageFrontComponentWidget = ({
|
||||
pageLayoutId,
|
||||
tabListInstanceId,
|
||||
}: {
|
||||
pageLayoutId: string;
|
||||
tabListInstanceId: string;
|
||||
}) => {
|
||||
const activeTabId = useAtomComponentStateValue(
|
||||
activeTabIdComponentState,
|
||||
tabListInstanceId,
|
||||
);
|
||||
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const pageLayoutDraftState = useAtomComponentStateCallbackState(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const createRecordPageFrontComponentWidget = useCallback(
|
||||
(title: string, frontComponentId: string): PageLayoutWidget | undefined => {
|
||||
if (!isDefined(activeTabId)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const activeTab = pageLayoutDraft.tabs.find(
|
||||
(tab) => tab.id === activeTabId,
|
||||
);
|
||||
const existingWidgets = activeTab?.widgets ?? [];
|
||||
|
||||
const positionIndex = existingWidgets.length;
|
||||
const widgetId = uuidv4();
|
||||
|
||||
const newWidget = createDefaultFrontComponentWidgetForVerticalList({
|
||||
id: widgetId,
|
||||
pageLayoutTabId: activeTabId,
|
||||
title,
|
||||
frontComponentId,
|
||||
positionIndex,
|
||||
});
|
||||
|
||||
store.set(pageLayoutDraftState, (prev) => ({
|
||||
...prev,
|
||||
tabs: addWidgetToTab(prev.tabs, activeTabId, newWidget),
|
||||
}));
|
||||
|
||||
return newWidget;
|
||||
},
|
||||
[activeTabId, pageLayoutDraft.tabs, pageLayoutDraftState, store],
|
||||
);
|
||||
|
||||
return { createRecordPageFrontComponentWidget };
|
||||
};
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import {
|
||||
PageLayoutTabLayoutMode,
|
||||
WidgetConfigurationType,
|
||||
WidgetType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const createDefaultFrontComponentWidgetForVerticalList = ({
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
frontComponentId,
|
||||
positionIndex,
|
||||
}: {
|
||||
id: string;
|
||||
pageLayoutTabId: string;
|
||||
title: string;
|
||||
frontComponentId: string;
|
||||
positionIndex: number;
|
||||
}): PageLayoutWidget => {
|
||||
return {
|
||||
__typename: 'PageLayoutWidget',
|
||||
id,
|
||||
pageLayoutTabId,
|
||||
title,
|
||||
type: WidgetType.FRONT_COMPONENT,
|
||||
configuration: {
|
||||
__typename: 'FrontComponentConfiguration',
|
||||
configurationType: WidgetConfigurationType.FRONT_COMPONENT,
|
||||
frontComponentId,
|
||||
},
|
||||
gridPosition: {
|
||||
__typename: 'GridPosition',
|
||||
row: 0,
|
||||
column: 0,
|
||||
rowSpan: 1,
|
||||
columnSpan: 12,
|
||||
},
|
||||
position: {
|
||||
__typename: 'PageLayoutWidgetVerticalListPosition',
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
index: positionIndex,
|
||||
},
|
||||
objectMetadataId: null,
|
||||
isOverridden: false,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
deletedAt: null,
|
||||
};
|
||||
};
|
||||
+14
-3
@@ -3,13 +3,18 @@ import { Suspense, lazy } from 'react';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { usePageLayoutContentContext } from '@/page-layout/contexts/PageLayoutContentContext';
|
||||
import { useIsPageLayoutInEditMode } from '@/page-layout/hooks/useIsPageLayoutInEditMode';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { PageLayoutWidgetNoDataDisplay } from '@/page-layout/widgets/components/PageLayoutWidgetNoDataDisplay';
|
||||
import { isWidgetConfigurationOfType } from '@/side-panel/pages/page-layout/utils/isWidgetConfigurationOfType';
|
||||
import { PageLayoutTabLayoutMode } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledContainer = styled.div<{ isInEditMode: boolean }>`
|
||||
height: 100%;
|
||||
const StyledContainer = styled.div<{
|
||||
isInEditMode: boolean;
|
||||
isVerticalList: boolean;
|
||||
}>`
|
||||
height: ${({ isVerticalList }) => (isVerticalList ? '300px' : '100%')};
|
||||
overflow: auto;
|
||||
pointer-events: ${({ isInEditMode }) => (isInEditMode ? 'none' : 'auto')};
|
||||
width: 100%;
|
||||
@@ -29,6 +34,9 @@ export const FrontComponentWidgetRenderer = ({
|
||||
widget,
|
||||
}: FrontComponentWidgetRendererProps) => {
|
||||
const isPageLayoutInEditMode = useIsPageLayoutInEditMode();
|
||||
const { layoutMode } = usePageLayoutContentContext();
|
||||
|
||||
const isVerticalList = layoutMode === PageLayoutTabLayoutMode.VERTICAL_LIST;
|
||||
|
||||
const configuration = widget.configuration;
|
||||
|
||||
@@ -42,7 +50,10 @@ export const FrontComponentWidgetRenderer = ({
|
||||
const frontComponentId = configuration.frontComponentId;
|
||||
|
||||
return (
|
||||
<StyledContainer isInEditMode={isPageLayoutInEditMode}>
|
||||
<StyledContainer
|
||||
isInEditMode={isPageLayoutInEditMode}
|
||||
isVerticalList={isVerticalList}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<FrontComponentRenderer frontComponentId={frontComponentId} />
|
||||
</Suspense>
|
||||
|
||||
+41
-5
@@ -5,10 +5,12 @@ import { useCreatePageLayoutGraphWidget } from '@/page-layout/hooks/useCreatePag
|
||||
import { useCreatePageLayoutIframeWidget } from '@/page-layout/hooks/useCreatePageLayoutIframeWidget';
|
||||
import { useCreatePageLayoutRecordTableWidget } from '@/page-layout/hooks/useCreatePageLayoutRecordTableWidget';
|
||||
import { useCreatePageLayoutStandaloneRichTextWidget } from '@/page-layout/hooks/useCreatePageLayoutStandaloneRichTextWidget';
|
||||
import { useCreateRecordPageFrontComponentWidget } from '@/page-layout/hooks/useCreateRecordPageFrontComponentWidget';
|
||||
import { useOpportunityDefaultChartConfig } from '@/page-layout/hooks/useOpportunityDefaultChartConfig';
|
||||
import { useRemovePageLayoutWidgetAndPreservePosition } from '@/page-layout/hooks/useRemovePageLayoutWidgetAndPreservePosition';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { getTabLayoutMode } from '@/page-layout/utils/getTabLayoutMode';
|
||||
import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
@@ -18,6 +20,7 @@ import { usePageLayoutIdFromContextStore } from '@/side-panel/pages/page-layout/
|
||||
import { getFrontComponentWidgetTypeSelectItemId } from '@/side-panel/pages/page-layout/utils/getFrontComponentWidgetTypeSelectItemId';
|
||||
import { isExistingWidgetMissingOrDifferentType } from '@/side-panel/pages/page-layout/utils/isExistingWidgetMissingOrDifferentType';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
@@ -35,6 +38,7 @@ import {
|
||||
import {
|
||||
FeatureFlagKey,
|
||||
type FrontComponent,
|
||||
PageLayoutTabLayoutMode,
|
||||
WidgetType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
@@ -80,6 +84,27 @@ export const SidePanelPageLayoutWidgetTypeSelect = () => {
|
||||
tabListInstanceId,
|
||||
});
|
||||
|
||||
const { createRecordPageFrontComponentWidget } =
|
||||
useCreateRecordPageFrontComponentWidget({
|
||||
pageLayoutId,
|
||||
tabListInstanceId,
|
||||
});
|
||||
|
||||
const activeTabId = useAtomComponentStateValue(
|
||||
activeTabIdComponentState,
|
||||
tabListInstanceId,
|
||||
);
|
||||
|
||||
const activeTab = pageLayoutDraft.tabs.find((tab) => tab.id === activeTabId);
|
||||
|
||||
const activeTabLayoutMode = getTabLayoutMode({
|
||||
tab: activeTab,
|
||||
pageLayoutType: pageLayoutDraft.type,
|
||||
});
|
||||
|
||||
const isVerticalList =
|
||||
activeTabLayoutMode === PageLayoutTabLayoutMode.VERTICAL_LIST;
|
||||
|
||||
const { createPageLayoutRecordTableWidget } =
|
||||
useCreatePageLayoutRecordTableWidget(pageLayoutId);
|
||||
|
||||
@@ -94,7 +119,9 @@ export const SidePanelPageLayoutWidgetTypeSelect = () => {
|
||||
frontComponents: FrontComponent[];
|
||||
}>(FIND_MANY_FRONT_COMPONENTS);
|
||||
|
||||
const frontComponents = frontComponentsData?.frontComponents ?? [];
|
||||
const frontComponents = (frontComponentsData?.frontComponents ?? []).filter(
|
||||
(frontComponent) => !frontComponent.isHeadless,
|
||||
);
|
||||
|
||||
const frontComponentsWithSelectItemId = frontComponents.map(
|
||||
(frontComponent) => ({
|
||||
@@ -212,10 +239,19 @@ export const SidePanelPageLayoutWidgetTypeSelect = () => {
|
||||
removePageLayoutWidgetAndPreservePosition(pageLayoutEditingWidgetId);
|
||||
}
|
||||
|
||||
const newWidget = createPageLayoutFrontComponentWidget(
|
||||
frontComponent.name,
|
||||
frontComponent.id,
|
||||
);
|
||||
const newWidget = isVerticalList
|
||||
? createRecordPageFrontComponentWidget(
|
||||
frontComponent.name,
|
||||
frontComponent.id,
|
||||
)
|
||||
: createPageLayoutFrontComponentWidget(
|
||||
frontComponent.name,
|
||||
frontComponent.id,
|
||||
);
|
||||
|
||||
if (!isDefined(newWidget)) {
|
||||
return;
|
||||
}
|
||||
setPageLayoutEditingWidgetId(newWidget.id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user