8726 workflow add a test button in workflow code step (#9016)
- add test button to workflow code step - add test tab to workflow code step https://github.com/user-attachments/assets/e180a827-7321-49a2-8026-88490c557da2  
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
import { getHighlightedDates } from '@/ui/input/components/internal/date/utils/getHighlightedDates';
|
||||
|
||||
jest.useFakeTimers().setSystemTime(new Date('2024-10-01T00:00:00.000Z'));
|
||||
|
||||
describe('getHighlightedDates', () => {
|
||||
it('should should return empty if range is undefined', () => {
|
||||
const dateRange = undefined;
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Fragment } from 'react';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: ${({ theme }) => theme.spacing(2)} ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
type RightDrawerFooterProps = {
|
||||
actions: React.ReactNode[];
|
||||
};
|
||||
|
||||
export const RightDrawerFooter = ({ actions }: RightDrawerFooterProps) => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
{actions.map((action, index) => (
|
||||
<Fragment key={index}>{action}</Fragment>
|
||||
))}
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
@ -13,6 +13,7 @@ import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
|
||||
|
||||
const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
|
||||
display: flex;
|
||||
@ -34,19 +35,6 @@ const StyledTabListContainer = styled.div<{ shouldDisplay: boolean }>`
|
||||
height: 40px;
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@ -57,7 +45,7 @@ const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>`
|
||||
export const TAB_LIST_COMPONENT_ID = 'show-page-right-tab-list';
|
||||
|
||||
type ShowPageSubContainerProps = {
|
||||
layout: RecordLayout;
|
||||
layout?: RecordLayout;
|
||||
tabs: SingleTabProps[];
|
||||
targetableObject: Pick<
|
||||
ActivityTargetableObject,
|
||||
@ -76,10 +64,9 @@ export const ShowPageSubContainer = ({
|
||||
isInRightDrawer = false,
|
||||
isNewRightDrawerItemLoading = false,
|
||||
}: ShowPageSubContainerProps) => {
|
||||
const { activeTabIdState } = useTabList(
|
||||
const { activeTabId } = useTabList(
|
||||
`${TAB_LIST_COMPONENT_ID}-${isInRightDrawer}`,
|
||||
);
|
||||
const activeTabId = useRecoilValue(activeTabIdState);
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
@ -125,9 +112,12 @@ export const ShowPageSubContainer = ({
|
||||
|
||||
const visibleTabs = tabs.filter((tab) => !tab.hide);
|
||||
|
||||
const displaySummaryAndFields =
|
||||
layout && !layout.hideSummaryAndFields && !isMobile && !isInRightDrawer;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!layout.hideSummaryAndFields && !isMobile && !isInRightDrawer && (
|
||||
{displaySummaryAndFields && (
|
||||
<ShowPageLeftContainer forceMobile={isMobile}>
|
||||
{summaryCard}
|
||||
{fieldsCard}
|
||||
@ -147,9 +137,7 @@ export const ShowPageSubContainer = ({
|
||||
{renderActiveTabContent()}
|
||||
</StyledContentContainer>
|
||||
{isInRightDrawer && recordFromStore && !recordFromStore.deletedAt && (
|
||||
<StyledButtonContainer>
|
||||
<RecordShowRightDrawerActionMenu />
|
||||
</StyledButtonContainer>
|
||||
<RightDrawerFooter actions={[<RecordShowRightDrawerActionMenu />]} />
|
||||
)}
|
||||
</StyledShowPageRightContainer>
|
||||
</>
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
import styled from '@emotion/styled';
|
||||
import * as React from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconComponent } from 'twenty-ui';
|
||||
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { TabListScope } from '@/ui/layout/tab/scopes/TabListScope';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
|
||||
import { TabListFromUrlOptionalEffect } from '@/ui/layout/tab/components/TabListFromUrlOptionalEffect';
|
||||
import { LayoutCard } from '@/ui/layout/tab/types/LayoutCard';
|
||||
import { Tab } from './Tab';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export type SingleTabProps = {
|
||||
title: string;
|
||||
@ -30,13 +29,17 @@ type TabListProps = {
|
||||
behaveAsLinks?: boolean;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
const StyledTabsContainer = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
height: 40px;
|
||||
user-select: none;
|
||||
margin-bottom: -1px;
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
border-bottom: ${({ theme }) => `1px solid ${theme.border.color.light}`};
|
||||
`;
|
||||
|
||||
export const TabList = ({
|
||||
@ -50,11 +53,9 @@ export const TabList = ({
|
||||
|
||||
const initialActiveTabId = visibleTabs[0]?.id || '';
|
||||
|
||||
const { activeTabIdState, setActiveTabId } = useTabList(tabListInstanceId);
|
||||
const { activeTabId, setActiveTabId } = useTabList(tabListInstanceId);
|
||||
|
||||
const activeTabId = useRecoilValue(activeTabIdState);
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
setActiveTabId(initialActiveTabId);
|
||||
}, [initialActiveTabId, setActiveTabId]);
|
||||
|
||||
@ -63,13 +64,13 @@ export const TabList = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<TabListScope tabListScopeId={tabListInstanceId}>
|
||||
<TabListFromUrlOptionalEffect
|
||||
componentInstanceId={tabListInstanceId}
|
||||
tabListIds={tabs.map((tab) => tab.id)}
|
||||
/>
|
||||
<ScrollWrapper enableYScroll={false} contextProviderName="tabList">
|
||||
<StyledContainer className={className}>
|
||||
<StyledContainer className={className}>
|
||||
<TabListScope tabListScopeId={tabListInstanceId}>
|
||||
<TabListFromUrlOptionalEffect
|
||||
componentInstanceId={tabListInstanceId}
|
||||
tabListIds={tabs.map((tab) => tab.id)}
|
||||
/>
|
||||
<StyledTabsContainer>
|
||||
{visibleTabs.map((tab) => (
|
||||
<Tab
|
||||
id={tab.id}
|
||||
@ -88,8 +89,8 @@ export const TabList = ({
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</StyledContainer>
|
||||
</ScrollWrapper>
|
||||
</TabListScope>
|
||||
</StyledTabsContainer>
|
||||
</TabListScope>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
type TabListFromUrlOptionalEffectProps = {
|
||||
componentInstanceId: string;
|
||||
@ -13,11 +12,9 @@ export const TabListFromUrlOptionalEffect = ({
|
||||
tabListIds,
|
||||
}: TabListFromUrlOptionalEffectProps) => {
|
||||
const location = useLocation();
|
||||
const { activeTabIdState } = useTabList(componentInstanceId);
|
||||
const { setActiveTabId } = useTabList(componentInstanceId);
|
||||
const { activeTabId, setActiveTabId } = useTabList(componentInstanceId);
|
||||
|
||||
const hash = location.hash.replace('#', '');
|
||||
const activeTabId = useRecoilValue(activeTabIdState);
|
||||
|
||||
useEffect(() => {
|
||||
if (hash === activeTabId) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import { useTabList } from '../useTabList';
|
||||
|
||||
@ -8,9 +8,7 @@ describe('useTabList', () => {
|
||||
it('Should update the activeTabId state', async () => {
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const { activeTabIdState, setActiveTabId } =
|
||||
useTabList('TEST_TAB_LIST_ID');
|
||||
const activeTabId = useRecoilValue(activeTabIdState);
|
||||
const { activeTabId, setActiveTabId } = useTabList('TEST_TAB_LIST_ID');
|
||||
|
||||
return {
|
||||
activeTabId,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useTabListStates } from '@/ui/layout/tab/hooks/internal/useTabListStates';
|
||||
|
||||
@ -7,10 +7,10 @@ export const useTabList = (tabListId?: string) => {
|
||||
tabListScopeId: tabListId,
|
||||
});
|
||||
|
||||
const setActiveTabId = useSetRecoilState(activeTabIdState);
|
||||
const [activeTabId, setActiveTabId] = useRecoilState(activeTabIdState);
|
||||
|
||||
return {
|
||||
activeTabIdState,
|
||||
activeTabId,
|
||||
setActiveTabId,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user