Side Panel Sub Page Framework® (#18579)
Replace hard-coded implementations for sub pages in the side panel with a proper framework
This commit is contained in:
committed by
GitHub
parent
5bfa4c5c39
commit
2a6fcfcfb3
@@ -5,6 +5,9 @@ import {
|
||||
OverflowingTextWithTooltip,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { SidePanelAskAIInfo } from '@/side-panel/components/SidePanelAskAIInfo';
|
||||
import { SidePanelFolderInfo } from '@/side-panel/components/SidePanelFolderInfo';
|
||||
import { SidePanelLinkInfo } from '@/side-panel/components/SidePanelLinkInfo';
|
||||
@@ -14,9 +17,6 @@ import { SidePanelPageInfoLayout } from '@/side-panel/components/SidePanelPageIn
|
||||
import { SidePanelPageLayoutInfo } from '@/side-panel/components/SidePanelPageLayoutInfo';
|
||||
import { SidePanelRecordInfo } from '@/side-panel/components/SidePanelRecordInfo';
|
||||
import { SidePanelWorkflowStepInfo } from '@/side-panel/components/SidePanelWorkflowStepInfo';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { SidePanelPages } from 'twenty-shared/types';
|
||||
|
||||
@@ -98,11 +98,9 @@ export const SidePanelPageInfo = ({ pageChip }: SidePanelPageInfoProps) => {
|
||||
? [
|
||||
SidePanelPages.PageLayoutWidgetTypeSelect,
|
||||
SidePanelPages.PageLayoutGraphTypeSelect,
|
||||
SidePanelPages.PageLayoutGraphFilter,
|
||||
SidePanelPages.PageLayoutIframeSettings,
|
||||
SidePanelPages.PageLayoutTabSettings,
|
||||
SidePanelPages.PageLayoutFieldsSettings,
|
||||
SidePanelPages.PageLayoutFieldsLayout,
|
||||
].includes(pageChip.page?.page)
|
||||
: false;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { CommandMenuContextProvider } from '@/command-menu-item/contexts/CommandMenuContextProvider';
|
||||
import { SidePanelContainer } from '@/side-panel/components/SidePanelContainer';
|
||||
import { SidePanelSubPageRouter } from '@/side-panel/components/SidePanelSubPageRouter';
|
||||
import { SidePanelTopBar } from '@/side-panel/components/SidePanelTopBar';
|
||||
import { SIDE_PANEL_PAGES_CONFIG } from '@/side-panel/constants/SidePanelPagesConfig';
|
||||
import { SidePanelPageComponentInstanceContext } from '@/side-panel/states/contexts/SidePanelPageComponentInstanceContext';
|
||||
@@ -56,7 +57,9 @@ export const SidePanelRouter = () => {
|
||||
displayType="listItem"
|
||||
containerType="command-menu-list"
|
||||
>
|
||||
{sidePanelPageComponent}
|
||||
<SidePanelSubPageRouter>
|
||||
{sidePanelPageComponent}
|
||||
</SidePanelSubPageRouter>
|
||||
</CommandMenuContextProvider>
|
||||
</StyledSidePanelContent>
|
||||
</SidePanelPageComponentInstanceContext.Provider>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { SIDE_PANEL_SUB_PAGES_CONFIG } from '@/side-panel/constants/SidePanelSubPagesConfig';
|
||||
import { useSidePanelSubPageHistory } from '@/side-panel/hooks/useSidePanelSubPageHistory';
|
||||
import { SidePanelSubPageNavigationHeader } from '@/side-panel/pages/common/components/SidePanelSubPageNavigationHeader';
|
||||
import { styled } from '@linaria/react';
|
||||
import React, { type ReactNode } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
const StyledSubPageContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
type SidePanelSubPageRouterProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const SidePanelSubPageRouter = ({
|
||||
children,
|
||||
}: SidePanelSubPageRouterProps) => {
|
||||
const { currentSidePanelSubPage, goBackFromSidePanelSubPage } =
|
||||
useSidePanelSubPageHistory();
|
||||
|
||||
if (!isDefined(currentSidePanelSubPage)) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
const subPageComponent = SIDE_PANEL_SUB_PAGES_CONFIG.get(
|
||||
currentSidePanelSubPage.subPage,
|
||||
);
|
||||
|
||||
if (!isDefined(subPageComponent)) {
|
||||
throw new Error(
|
||||
`Missing side panel sub-page config for "${currentSidePanelSubPage.subPage}". ` +
|
||||
'Please add it to SIDE_PANEL_SUB_PAGES_CONFIG.',
|
||||
);
|
||||
}
|
||||
|
||||
const keyedSubPageComponent = React.isValidElement(subPageComponent)
|
||||
? React.cloneElement(subPageComponent, {
|
||||
key: currentSidePanelSubPage.id,
|
||||
})
|
||||
: subPageComponent;
|
||||
|
||||
return (
|
||||
<StyledSubPageContainer>
|
||||
<SidePanelSubPageNavigationHeader
|
||||
title={currentSidePanelSubPage.title}
|
||||
onBackClick={goBackFromSidePanelSubPage}
|
||||
/>
|
||||
{keyedSubPageComponent}
|
||||
</StyledSubPageContainer>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { SidePanelSubPageNavigationHeader } from '@/side-panel/pages/common/components/SidePanelSubPageNavigationHeader';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledSubViewContainer = styled.div`
|
||||
@@ -50,8 +49,6 @@ const StyledScrollableListWrapper = styled.div`
|
||||
`;
|
||||
|
||||
type SidePanelSubViewWithSearchProps = {
|
||||
backBarTitle: string;
|
||||
onBack: () => void;
|
||||
searchPlaceholder: string;
|
||||
searchValue: string;
|
||||
onSearchChange: (value: string) => void;
|
||||
@@ -60,8 +57,6 @@ type SidePanelSubViewWithSearchProps = {
|
||||
};
|
||||
|
||||
export const SidePanelSubViewWithSearch = ({
|
||||
backBarTitle,
|
||||
onBack,
|
||||
searchPlaceholder,
|
||||
searchValue,
|
||||
onSearchChange,
|
||||
@@ -69,10 +64,6 @@ export const SidePanelSubViewWithSearch = ({
|
||||
children,
|
||||
}: SidePanelSubViewWithSearchProps) => (
|
||||
<StyledSubViewContainer>
|
||||
<SidePanelSubPageNavigationHeader
|
||||
title={backBarTitle}
|
||||
onBackClick={onBack}
|
||||
/>
|
||||
<StyledSearchContainer>
|
||||
<StyledSearchInput
|
||||
placeholder={searchPlaceholder}
|
||||
|
||||
+7
-15
@@ -1,9 +1,10 @@
|
||||
import { type PageLayoutTab } from '@/page-layout/types/PageLayoutTab';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { GRAPH_TYPE_INFORMATION } from '@/side-panel/pages/page-layout/constants/GraphTypeInformation';
|
||||
import { getCurrentGraphTypeFromConfig } from '@/side-panel/pages/page-layout/utils/getCurrentGraphTypeFromConfig';
|
||||
import { isWidgetConfigurationOfTypeGraph } from '@/side-panel/pages/page-layout/utils/isWidgetConfigurationOfTypeGraph';
|
||||
import { type PageLayoutTab } from '@/page-layout/types/PageLayoutTab';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useContext } from 'react';
|
||||
import { SidePanelPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -14,7 +15,6 @@ import {
|
||||
type IconComponent,
|
||||
} from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
|
||||
type PageLayoutHeaderInfo = {
|
||||
headerIcon: IconComponent | undefined;
|
||||
@@ -105,8 +105,7 @@ export const usePageLayoutHeaderInfo = ({
|
||||
};
|
||||
}
|
||||
|
||||
case SidePanelPages.PageLayoutGraphTypeSelect:
|
||||
case SidePanelPages.PageLayoutGraphFilter: {
|
||||
case SidePanelPages.PageLayoutGraphTypeSelect: {
|
||||
if (!isDefined(pageLayoutEditingWidgetId)) {
|
||||
return null;
|
||||
}
|
||||
@@ -127,12 +126,6 @@ export const usePageLayoutHeaderInfo = ({
|
||||
widgetInEditMode.configuration,
|
||||
);
|
||||
const graphTypeInfo = GRAPH_TYPE_INFORMATION[currentGraphType];
|
||||
const graphTypeLabel = t(graphTypeInfo.label);
|
||||
|
||||
const headerType =
|
||||
sidePanelPage === SidePanelPages.PageLayoutGraphFilter
|
||||
? graphTypeLabel
|
||||
: t`Chart`;
|
||||
|
||||
const title = isDefined(editedTitle)
|
||||
? editedTitle
|
||||
@@ -143,16 +136,15 @@ export const usePageLayoutHeaderInfo = ({
|
||||
return {
|
||||
headerIcon: graphTypeInfo.icon,
|
||||
headerIconColor: iconColor,
|
||||
headerType,
|
||||
headerType: t`Chart`,
|
||||
title,
|
||||
isReadonly: sidePanelPage === SidePanelPages.PageLayoutGraphFilter,
|
||||
isReadonly: false,
|
||||
tab: undefined,
|
||||
widgetInEditMode,
|
||||
};
|
||||
}
|
||||
|
||||
case SidePanelPages.PageLayoutFieldsSettings:
|
||||
case SidePanelPages.PageLayoutFieldsLayout: {
|
||||
case SidePanelPages.PageLayoutFieldsSettings: {
|
||||
if (!isDefined(pageLayoutEditingWidgetId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user