Don't show summary/fields on workflow record pages (#8804)
Hiding the left column on workflow pages This raises additional questions: how do we edit the title then? Probably need a significant refacto of PageHeader <img width="1094" alt="Screenshot 2024-11-29 at 10 01 08" src="https://github.com/user-attachments/assets/b98d55cb-5097-4e46-bac5-5570d9ca0ad8">
This commit is contained in:
@ -35,7 +35,7 @@ export const RecordShowContainer = ({
|
||||
objectRecordId,
|
||||
});
|
||||
|
||||
const tabs = useRecordShowContainerTabs(
|
||||
const { layout, tabs } = useRecordShowContainerTabs(
|
||||
loading,
|
||||
objectNameSingular as CoreObjectNameSingular,
|
||||
isInRightDrawer,
|
||||
@ -61,6 +61,7 @@ export const RecordShowContainer = ({
|
||||
<ShowPageContainer>
|
||||
<ShowPageSubContainer
|
||||
tabs={tabs}
|
||||
layout={layout}
|
||||
targetableObject={{
|
||||
id: objectRecordId,
|
||||
targetObjectNameSingular: objectMetadataItem?.nameSingular,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { CardType } from '@/object-record/record-show/types/CardType';
|
||||
import { RecordLayoutTab } from '@/ui/layout/tab/types/RecordLayoutTab';
|
||||
import { RecordLayout } from '@/object-record/record-show/types/RecordLayout';
|
||||
import {
|
||||
IconCheckbox,
|
||||
IconList,
|
||||
@ -9,75 +9,77 @@ import {
|
||||
IconTimelineEvent,
|
||||
} from 'twenty-ui';
|
||||
|
||||
export const BASE_RECORD_LAYOUT: Record<string, RecordLayoutTab> = {
|
||||
fields: {
|
||||
title: 'Fields',
|
||||
Icon: IconList,
|
||||
position: 100,
|
||||
cards: [{ type: CardType.FieldCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: true,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
export const BASE_RECORD_LAYOUT: RecordLayout = {
|
||||
tabs: {
|
||||
fields: {
|
||||
title: 'Fields',
|
||||
Icon: IconList,
|
||||
position: 100,
|
||||
cards: [{ type: CardType.FieldCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: true,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
timeline: {
|
||||
title: 'Timeline',
|
||||
Icon: IconTimelineEvent,
|
||||
position: 200,
|
||||
cards: [{ type: CardType.TimelineCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: true,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
timeline: {
|
||||
title: 'Timeline',
|
||||
Icon: IconTimelineEvent,
|
||||
position: 200,
|
||||
cards: [{ type: CardType.TimelineCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: true,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
tasks: {
|
||||
title: 'Tasks',
|
||||
Icon: IconCheckbox,
|
||||
position: 300,
|
||||
cards: [{ type: CardType.TaskCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Task],
|
||||
ifRelationsMissing: ['taskTargets'],
|
||||
tasks: {
|
||||
title: 'Tasks',
|
||||
Icon: IconCheckbox,
|
||||
position: 300,
|
||||
cards: [{ type: CardType.TaskCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Task],
|
||||
ifRelationsMissing: ['taskTargets'],
|
||||
},
|
||||
},
|
||||
},
|
||||
notes: {
|
||||
title: 'Notes',
|
||||
Icon: IconNotes,
|
||||
position: 400,
|
||||
cards: [{ type: CardType.NoteCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Note],
|
||||
ifRelationsMissing: ['noteTargets'],
|
||||
notes: {
|
||||
title: 'Notes',
|
||||
Icon: IconNotes,
|
||||
position: 400,
|
||||
cards: [{ type: CardType.NoteCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Note],
|
||||
ifRelationsMissing: ['noteTargets'],
|
||||
},
|
||||
},
|
||||
},
|
||||
files: {
|
||||
title: 'Files',
|
||||
Icon: IconPaperclip,
|
||||
position: 500,
|
||||
cards: [{ type: CardType.FileCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Attachment],
|
||||
ifRelationsMissing: ['attachments'],
|
||||
files: {
|
||||
title: 'Files',
|
||||
Icon: IconPaperclip,
|
||||
position: 500,
|
||||
cards: [{ type: CardType.FileCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [CoreObjectNameSingular.Attachment],
|
||||
ifRelationsMissing: ['attachments'],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -23,7 +23,7 @@ export const useRecordShowContainerTabs = (
|
||||
targetObjectNameSingular: CoreObjectNameSingular,
|
||||
isInRightDrawer: boolean,
|
||||
objectMetadataItem: ObjectMetadataItem,
|
||||
): SingleTabProps[] => {
|
||||
): { layout: RecordLayout; tabs: SingleTabProps[] } => {
|
||||
const isMobile = useIsMobile();
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
|
||||
@ -34,235 +34,258 @@ export const useRecordShowContainerTabs = (
|
||||
Record<CoreObjectNameSingular, RecordLayout>
|
||||
> = {
|
||||
[CoreObjectNameSingular.Note]: {
|
||||
richText: {
|
||||
title: 'Note',
|
||||
position: 0,
|
||||
Icon: IconNotes,
|
||||
cards: [{ type: CardType.RichTextCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
richText: {
|
||||
title: 'Note',
|
||||
position: 0,
|
||||
Icon: IconNotes,
|
||||
cards: [{ type: CardType.RichTextCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
tasks: null,
|
||||
notes: null,
|
||||
},
|
||||
tasks: null,
|
||||
notes: null,
|
||||
},
|
||||
[CoreObjectNameSingular.Task]: {
|
||||
richText: {
|
||||
title: 'Note',
|
||||
position: 0,
|
||||
Icon: IconNotes,
|
||||
cards: [{ type: CardType.RichTextCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
richText: {
|
||||
title: 'Note',
|
||||
position: 0,
|
||||
Icon: IconNotes,
|
||||
cards: [{ type: CardType.RichTextCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
tasks: null,
|
||||
notes: null,
|
||||
},
|
||||
tasks: null,
|
||||
notes: null,
|
||||
},
|
||||
[CoreObjectNameSingular.Company]: {
|
||||
emails: {
|
||||
title: 'Emails',
|
||||
position: 600,
|
||||
Icon: IconMail,
|
||||
cards: [{ type: CardType.EmailCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
emails: {
|
||||
title: 'Emails',
|
||||
position: 600,
|
||||
Icon: IconMail,
|
||||
cards: [{ type: CardType.EmailCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
calendar: {
|
||||
title: 'Calendar',
|
||||
position: 700,
|
||||
Icon: IconCalendarEvent,
|
||||
cards: [{ type: CardType.CalendarCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
calendar: {
|
||||
title: 'Calendar',
|
||||
position: 700,
|
||||
Icon: IconCalendarEvent,
|
||||
cards: [{ type: CardType.CalendarCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[CoreObjectNameSingular.Person]: {
|
||||
emails: {
|
||||
title: 'Emails',
|
||||
position: 600,
|
||||
Icon: IconMail,
|
||||
cards: [{ type: CardType.EmailCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
emails: {
|
||||
title: 'Emails',
|
||||
position: 600,
|
||||
Icon: IconMail,
|
||||
cards: [{ type: CardType.EmailCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
calendar: {
|
||||
title: 'Calendar',
|
||||
position: 700,
|
||||
Icon: IconCalendarEvent,
|
||||
cards: [{ type: CardType.CalendarCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
calendar: {
|
||||
title: 'Calendar',
|
||||
position: 700,
|
||||
Icon: IconCalendarEvent,
|
||||
cards: [{ type: CardType.CalendarCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: [],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[CoreObjectNameSingular.Workflow]: {
|
||||
workflow: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
hideSummaryAndFields: true,
|
||||
tabs: {
|
||||
workflow: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
timeline: null,
|
||||
fields: null,
|
||||
},
|
||||
timeline: null,
|
||||
},
|
||||
[CoreObjectNameSingular.WorkflowVersion]: {
|
||||
workflowVersion: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowVersionCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
workflowVersion: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowVersionCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
timeline: null,
|
||||
},
|
||||
timeline: null,
|
||||
},
|
||||
[CoreObjectNameSingular.WorkflowRun]: {
|
||||
workflowRunOutput: {
|
||||
title: 'Output',
|
||||
position: 0,
|
||||
Icon: IconPrinter,
|
||||
cards: [{ type: CardType.WorkflowRunOutputCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
tabs: {
|
||||
workflowRunOutput: {
|
||||
title: 'Output',
|
||||
position: 0,
|
||||
Icon: IconPrinter,
|
||||
cards: [{ type: CardType.WorkflowRunOutputCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
workflowRunFlow: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowRunCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
workflowRunFlow: {
|
||||
title: 'Flow',
|
||||
position: 0,
|
||||
Icon: IconSettings,
|
||||
cards: [{ type: CardType.WorkflowRunCard }],
|
||||
hide: {
|
||||
ifMobile: false,
|
||||
ifDesktop: false,
|
||||
ifInRightDrawer: false,
|
||||
ifFeaturesDisabled: ['IS_WORKFLOW_ENABLED'],
|
||||
ifRequiredObjectsInactive: [],
|
||||
ifRelationsMissing: [],
|
||||
},
|
||||
},
|
||||
timeline: null,
|
||||
},
|
||||
timeline: null,
|
||||
},
|
||||
};
|
||||
|
||||
// Merge base layout with object-specific layout
|
||||
const tabDefinitions: RecordLayout = {
|
||||
const recordLayout: RecordLayout = {
|
||||
...BASE_RECORD_LAYOUT,
|
||||
...(OBJECT_SPECIFIC_LAYOUTS[targetObjectNameSingular] || {}),
|
||||
tabs: {
|
||||
...BASE_RECORD_LAYOUT.tabs,
|
||||
...(OBJECT_SPECIFIC_LAYOUTS[targetObjectNameSingular]?.tabs || {}),
|
||||
},
|
||||
};
|
||||
|
||||
return Object.entries(tabDefinitions)
|
||||
.filter(
|
||||
(entry): entry is [string, NonNullable<RecordLayoutTab>] =>
|
||||
entry[1] !== null && entry[1] !== undefined,
|
||||
)
|
||||
.sort(([, a], [, b]) => a.position - b.position)
|
||||
.map(([key, { title, Icon, hide, cards }]) => {
|
||||
// Special handling for fields tab
|
||||
if (key === 'fields') {
|
||||
return {
|
||||
layout: recordLayout,
|
||||
tabs: Object.entries(recordLayout.tabs)
|
||||
.filter(
|
||||
(entry): entry is [string, NonNullable<RecordLayoutTab>] =>
|
||||
entry[1] !== null && entry[1] !== undefined,
|
||||
)
|
||||
.sort(([, a], [, b]) => a.position - b.position)
|
||||
.map(([key, { title, Icon, hide, cards }]) => {
|
||||
// Special handling for fields tab
|
||||
if (key === 'fields') {
|
||||
return {
|
||||
id: key,
|
||||
title,
|
||||
Icon,
|
||||
cards,
|
||||
hide: !(isMobile || isInRightDrawer),
|
||||
};
|
||||
}
|
||||
|
||||
const baseHide =
|
||||
(hide.ifMobile && isMobile) ||
|
||||
(hide.ifDesktop && !isMobile) ||
|
||||
(hide.ifInRightDrawer && isInRightDrawer);
|
||||
|
||||
const featureNotEnabled =
|
||||
hide.ifFeaturesDisabled.length > 0 &&
|
||||
!hide.ifFeaturesDisabled.every((flagKey) => {
|
||||
return !!currentWorkspace?.featureFlags?.find(
|
||||
(flag: FeatureFlag) => flag.key === flagKey && flag.value,
|
||||
);
|
||||
});
|
||||
|
||||
const requiredObjectsInactive =
|
||||
hide.ifRequiredObjectsInactive.length > 0 &&
|
||||
!hide.ifRequiredObjectsInactive.every((obj) =>
|
||||
objectMetadataItems.some(
|
||||
(item) => item.nameSingular === obj && item.isActive,
|
||||
),
|
||||
);
|
||||
|
||||
const relationsDontExist =
|
||||
hide.ifRelationsMissing.length > 0 &&
|
||||
!hide.ifRelationsMissing.every((rel) =>
|
||||
objectMetadataItem.fields.some(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.Relation &&
|
||||
field.name === rel &&
|
||||
field.isActive,
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
id: key,
|
||||
title,
|
||||
Icon,
|
||||
cards,
|
||||
hide: !(isMobile || isInRightDrawer),
|
||||
hide:
|
||||
loading ||
|
||||
baseHide ||
|
||||
featureNotEnabled ||
|
||||
requiredObjectsInactive ||
|
||||
relationsDontExist,
|
||||
};
|
||||
}
|
||||
|
||||
const baseHide =
|
||||
(hide.ifMobile && isMobile) ||
|
||||
(hide.ifDesktop && !isMobile) ||
|
||||
(hide.ifInRightDrawer && isInRightDrawer);
|
||||
|
||||
const featureNotEnabled =
|
||||
hide.ifFeaturesDisabled.length > 0 &&
|
||||
!hide.ifFeaturesDisabled.every((flagKey) => {
|
||||
return !!currentWorkspace?.featureFlags?.find(
|
||||
(flag: FeatureFlag) => flag.key === flagKey && flag.value,
|
||||
);
|
||||
});
|
||||
|
||||
const requiredObjectsInactive =
|
||||
hide.ifRequiredObjectsInactive.length > 0 &&
|
||||
!hide.ifRequiredObjectsInactive.every((obj) =>
|
||||
objectMetadataItems.some(
|
||||
(item) => item.nameSingular === obj && item.isActive,
|
||||
),
|
||||
);
|
||||
|
||||
const relationsDontExist =
|
||||
hide.ifRelationsMissing.length > 0 &&
|
||||
!hide.ifRelationsMissing.every((rel) =>
|
||||
objectMetadataItem.fields.some(
|
||||
(field) =>
|
||||
field.type === FieldMetadataType.Relation &&
|
||||
field.name === rel &&
|
||||
field.isActive,
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
id: key,
|
||||
title,
|
||||
Icon,
|
||||
cards,
|
||||
hide:
|
||||
loading ||
|
||||
baseHide ||
|
||||
featureNotEnabled ||
|
||||
requiredObjectsInactive ||
|
||||
relationsDontExist,
|
||||
};
|
||||
});
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
import { RecordLayoutTab } from '@/ui/layout/tab/types/RecordLayoutTab';
|
||||
|
||||
export type RecordLayout = Record<string, RecordLayoutTab | null>;
|
||||
export type RecordLayout = {
|
||||
hideSummaryAndFields?: boolean;
|
||||
tabs: Record<string, RecordLayoutTab | null>;
|
||||
};
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
import { RecordLayout } from '@/object-record/record-show/types/RecordLayout';
|
||||
|
||||
export type RecordLayoutMap = Record<string, RecordLayout | null>;
|
||||
@ -4,6 +4,7 @@ import { isNewViewableRecordLoadingState } from '@/object-record/record-right-dr
|
||||
import { CardComponents } from '@/object-record/record-show/components/CardComponents';
|
||||
import { FieldsCard } from '@/object-record/record-show/components/FieldsCard';
|
||||
import { SummaryCard } from '@/object-record/record-show/components/SummaryCard';
|
||||
import { RecordLayout } from '@/object-record/record-show/types/RecordLayout';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
|
||||
@ -23,12 +24,12 @@ const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const StyledTabListContainer = styled.div`
|
||||
const StyledTabListContainer = styled.div<{ shouldDisplay: boolean }>`
|
||||
align-items: center;
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
display: ${({ shouldDisplay }) => (shouldDisplay ? 'flex' : 'none')};
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
height: 40px;
|
||||
`;
|
||||
@ -56,6 +57,7 @@ const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
|
||||
export const TAB_LIST_COMPONENT_ID = 'show-page-right-tab-list';
|
||||
|
||||
type ShowPageSubContainerProps = {
|
||||
layout: RecordLayout;
|
||||
tabs: SingleTabProps[];
|
||||
targetableObject: Pick<
|
||||
ActivityTargetableObject,
|
||||
@ -68,6 +70,7 @@ type ShowPageSubContainerProps = {
|
||||
|
||||
export const ShowPageSubContainer = ({
|
||||
tabs,
|
||||
layout,
|
||||
targetableObject,
|
||||
loading,
|
||||
isInRightDrawer = false,
|
||||
@ -120,16 +123,18 @@ export const ShowPageSubContainer = ({
|
||||
recordStoreFamilyState(targetableObject.id),
|
||||
);
|
||||
|
||||
const visibleTabs = tabs.filter((tab) => !tab.hide);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isMobile && !isInRightDrawer && (
|
||||
{!layout.hideSummaryAndFields && !isMobile && !isInRightDrawer && (
|
||||
<ShowPageLeftContainer forceMobile={isMobile}>
|
||||
{summaryCard}
|
||||
{fieldsCard}
|
||||
</ShowPageLeftContainer>
|
||||
)}
|
||||
<StyledShowPageRightContainer isMobile={isMobile}>
|
||||
<StyledTabListContainer>
|
||||
<StyledTabListContainer shouldDisplay={visibleTabs.length > 1}>
|
||||
<TabList
|
||||
behaveAsLinks={!isInRightDrawer}
|
||||
loading={loading || isNewViewableRecordLoading}
|
||||
|
||||
@ -46,7 +46,9 @@ export const TabList = ({
|
||||
className,
|
||||
behaveAsLinks = true,
|
||||
}: TabListProps) => {
|
||||
const initialActiveTabId = tabs.find((tab) => !tab.hide)?.id || '';
|
||||
const visibleTabs = tabs.filter((tab) => !tab.hide);
|
||||
|
||||
const initialActiveTabId = visibleTabs[0]?.id || '';
|
||||
|
||||
const { activeTabIdState, setActiveTabId } = useTabList(tabListInstanceId);
|
||||
|
||||
@ -56,6 +58,10 @@ export const TabList = ({
|
||||
setActiveTabId(initialActiveTabId);
|
||||
}, [initialActiveTabId, setActiveTabId]);
|
||||
|
||||
if (visibleTabs.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TabListScope tabListScopeId={tabListInstanceId}>
|
||||
<TabListFromUrlOptionalEffect
|
||||
@ -64,26 +70,24 @@ export const TabList = ({
|
||||
/>
|
||||
<ScrollWrapper enableYScroll={false} contextProviderName="tabList">
|
||||
<StyledContainer className={className}>
|
||||
{tabs
|
||||
.filter((tab) => !tab.hide)
|
||||
.map((tab) => (
|
||||
<Tab
|
||||
id={tab.id}
|
||||
key={tab.id}
|
||||
title={tab.title}
|
||||
Icon={tab.Icon}
|
||||
logo={tab.logo}
|
||||
active={tab.id === activeTabId}
|
||||
disabled={tab.disabled ?? loading}
|
||||
pill={tab.pill}
|
||||
to={behaveAsLinks ? `#${tab.id}` : undefined}
|
||||
onClick={() => {
|
||||
if (!behaveAsLinks) {
|
||||
setActiveTabId(tab.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{visibleTabs.map((tab) => (
|
||||
<Tab
|
||||
id={tab.id}
|
||||
key={tab.id}
|
||||
title={tab.title}
|
||||
Icon={tab.Icon}
|
||||
logo={tab.logo}
|
||||
active={tab.id === activeTabId}
|
||||
disabled={tab.disabled ?? loading}
|
||||
pill={tab.pill}
|
||||
to={behaveAsLinks ? `#${tab.id}` : undefined}
|
||||
onClick={() => {
|
||||
if (!behaveAsLinks) {
|
||||
setActiveTabId(tab.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</StyledContainer>
|
||||
</ScrollWrapper>
|
||||
</TabListScope>
|
||||
|
||||
Reference in New Issue
Block a user