7499 refactor right drawer to have contextual actions (#7954)
Closes #7499 - Modifies context store states to be component states - Introduces the concept of `mainContextStore` which will dictate the available actions inside the command K - Adds contextual actions inside the right drawer - Creates a new type of modal variant
This commit is contained in:
@ -7,7 +7,7 @@ import { useDebouncedCallback } from 'use-debounce';
|
||||
import { Button, ButtonAccent } from '@/ui/input/button/components/Button';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { Modal, ModalVariants } from '@/ui/layout/modal/components/Modal';
|
||||
import {
|
||||
Section,
|
||||
SectionAlignment,
|
||||
@ -26,6 +26,7 @@ export type ConfirmationModalProps = {
|
||||
confirmationValue?: string;
|
||||
confirmButtonAccent?: ButtonAccent;
|
||||
AdditionalButtons?: React.ReactNode;
|
||||
modalVariant?: ModalVariants;
|
||||
};
|
||||
|
||||
const StyledConfirmationModal = styled(Modal)`
|
||||
@ -71,6 +72,7 @@ export const ConfirmationModal = ({
|
||||
confirmationPlaceholder,
|
||||
confirmButtonAccent = 'danger',
|
||||
AdditionalButtons,
|
||||
modalVariant = 'primary',
|
||||
}: ConfirmationModalProps) => {
|
||||
const [inputConfirmationValue, setInputConfirmationValue] =
|
||||
useState<string>('');
|
||||
@ -113,6 +115,7 @@ export const ConfirmationModal = ({
|
||||
onEnter={handleEnter}
|
||||
isClosable={true}
|
||||
padding="large"
|
||||
modalVariant={modalVariant}
|
||||
>
|
||||
<StyledCenteredTitle>
|
||||
<H1Title title={title} fontColor={H1TitleFontColor.Primary} />
|
||||
|
||||
@ -94,7 +94,9 @@ const StyledBackDrop = styled(motion.div)<{
|
||||
background: ${({ theme, modalVariant }) =>
|
||||
modalVariant === 'primary'
|
||||
? theme.background.overlayPrimary
|
||||
: theme.background.overlaySecondary};
|
||||
: modalVariant === 'secondary'
|
||||
? theme.background.overlaySecondary
|
||||
: theme.background.overlayTertiary};
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
@ -132,7 +134,7 @@ const ModalFooter = ({ children, className }: ModalFooterProps) => (
|
||||
|
||||
export type ModalSize = 'small' | 'medium' | 'large';
|
||||
export type ModalPadding = 'none' | 'small' | 'medium' | 'large';
|
||||
export type ModalVariants = 'primary' | 'secondary';
|
||||
export type ModalVariants = 'primary' | 'secondary' | 'tertiary';
|
||||
|
||||
export type ModalProps = React.PropsWithChildren & {
|
||||
size?: ModalSize;
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
import { ReactNode } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { MOBILE_VIEWPORT } from 'twenty-ui';
|
||||
|
||||
import { RightDrawer } from '@/ui/layout/right-drawer/components/RightDrawer';
|
||||
|
||||
import { PagePanel } from './PagePanel';
|
||||
|
||||
type RightDrawerContainerProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const StyledMainContainer = styled.div`
|
||||
background: ${({ theme }) => theme.background.noisy};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
min-height: 0;
|
||||
padding-bottom: ${({ theme }) => theme.spacing(3)};
|
||||
padding-right: ${({ theme }) => theme.spacing(3)};
|
||||
padding-left: 0;
|
||||
width: 100%;
|
||||
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
padding-left: ${({ theme }) => theme.spacing(3)};
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
type LeftContainerProps = {
|
||||
isRightDrawerOpen?: boolean;
|
||||
};
|
||||
|
||||
const StyledLeftContainer = styled.div<LeftContainerProps>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const RightDrawerContainer = ({
|
||||
children,
|
||||
}: RightDrawerContainerProps) => (
|
||||
<StyledMainContainer>
|
||||
<StyledLeftContainer>
|
||||
<PagePanel>{children}</PagePanel>
|
||||
</StyledLeftContainer>
|
||||
<RightDrawer />
|
||||
</StyledMainContainer>
|
||||
);
|
||||
@ -1,3 +1,4 @@
|
||||
import { RecordShowActionMenu } from '@/action-menu/components/RecordShowActionMenu';
|
||||
import { Calendar } from '@/activities/calendar/components/Calendar';
|
||||
import { EmailThreads } from '@/activities/emails/components/EmailThreads';
|
||||
import { Attachments } from '@/activities/files/components/Attachments';
|
||||
@ -6,13 +7,11 @@ import { ObjectTasks } from '@/activities/tasks/components/ObjectTasks';
|
||||
import { TimelineActivities } from '@/activities/timeline-activities/components/TimelineActivities';
|
||||
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
|
||||
import { FieldsCard } from '@/object-record/record-show/components/FieldsCard';
|
||||
import { SummaryCard } from '@/object-record/record-show/components/SummaryCard';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
import { ShowPageActivityContainer } from '@/ui/layout/show-page/components/ShowPageActivityContainer';
|
||||
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
|
||||
import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
|
||||
@ -25,9 +24,7 @@ import { WorkflowVersionVisualizerEffect } from '@/workflow/components/WorkflowV
|
||||
import { WorkflowVisualizer } from '@/workflow/components/WorkflowVisualizer';
|
||||
import { WorkflowVisualizerEffect } from '@/workflow/components/WorkflowVisualizerEffect';
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { IconTrash } from 'twenty-ui';
|
||||
|
||||
const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
|
||||
display: flex;
|
||||
@ -198,18 +195,6 @@ export const ShowPageSubContainer = ({
|
||||
}
|
||||
};
|
||||
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
|
||||
const { deleteOneRecord } = useDeleteOneRecord({
|
||||
objectNameSingular: targetableObject.targetObjectNameSingular,
|
||||
});
|
||||
|
||||
const handleDelete = async () => {
|
||||
setIsDeleting(true);
|
||||
await deleteOneRecord(targetableObject.id);
|
||||
setIsDeleting(false);
|
||||
};
|
||||
|
||||
const [recordFromStore] = useRecoilState<ObjectRecord | null>(
|
||||
recordStoreFamilyState(targetableObject.id),
|
||||
);
|
||||
@ -236,12 +221,7 @@ export const ShowPageSubContainer = ({
|
||||
</StyledContentContainer>
|
||||
{isInRightDrawer && recordFromStore && !recordFromStore.deletedAt && (
|
||||
<StyledButtonContainer>
|
||||
<Button
|
||||
Icon={IconTrash}
|
||||
onClick={handleDelete}
|
||||
disabled={isDeleting}
|
||||
title={isDeleting ? 'Deleting...' : 'Delete'}
|
||||
></Button>
|
||||
<RecordShowActionMenu actionMenuId={'right-drawer-action-menu'} />
|
||||
</StyledButtonContainer>
|
||||
)}
|
||||
</StyledShowPageRightContainer>
|
||||
|
||||
Reference in New Issue
Block a user