chore(twenty-front): migrate command-menu, workflow, page-layout and UI modules from Emotion to Linaria (PR 4-6/10) (#18342)
## Summary
Continues the Emotion → Linaria migration (PR 4-6 from the [migration
plan](docs/emotion-to-linaria-migration-plan.md)). Migrates **311
files** across four module groups:
| Module | Files |
|---|---|
| command-menu | 53 |
| workflow | 84 |
| page-layout | 84 |
| UI (partial - first ~80 files) | ~80 |
| twenty-ui (TEXT_INPUT_STYLE) | 1 |
| misc (hooks, keyboard-shortcut-menu, file-upload) | ~9 |
### Migration patterns applied
- `import styled from '@emotion/styled'` → `import { styled } from
'@linaria/react'`
- `import { useTheme } from '@emotion/react'` → `import { useContext }
from 'react'` + `import { ThemeContext } from 'twenty-ui/theme'`
- `${({ theme }) => theme.X.Y.Z}` → `${themeCssVariables.X.Y.Z}` (static
CSS variables)
- `theme.spacing(N)` → `themeCssVariables.spacing[N]`
- `styled(motion.div)` → `motion.create(StyledBase)` (11 components)
- `styled(Component)<TypeParams>` → wrapper div approach for non-HTML
elements
- Multi-declaration interpolations split into one CSS property per
interpolation
- Interpolation return types fixed (`&&` → ternary `? : ''`)
- `TEXT_INPUT_STYLE` converted from function to static string constant
(backward compatible)
- Emotion `<Global>` replaced with `useEffect` style injection
- Complex runtime-dependent styles use CSS custom properties via
`style={}` prop
### After this PR
- **Remaining files**: ~400 (object-record: ~160, settings: ~200, UI:
~44)
- **No breaking changes**: CSS variables resolve identically to the
previous Emotion theme values
This commit is contained in:
+14
-12
@@ -1,6 +1,5 @@
|
||||
import { LightCopyIconButton } from '@/object-record/record-field/ui/components/LightCopyIconButton';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
IconLoader,
|
||||
@@ -9,6 +8,9 @@ import {
|
||||
} from 'twenty-ui/display';
|
||||
import { CodeEditor, CoreEditorHeader } from 'twenty-ui/input';
|
||||
import { AnimatedCircleLoading } from 'twenty-ui/utilities';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -28,26 +30,26 @@ type OutputAccent = 'default' | 'success' | 'error';
|
||||
|
||||
const StyledInfoContainer = styled.div`
|
||||
display: flex;
|
||||
font-size: ${({ theme }) => theme.font.size.md};
|
||||
font-size: ${themeCssVariables.font.size.md};
|
||||
`;
|
||||
|
||||
const StyledOutput = styled.div<{ accent?: OutputAccent }>`
|
||||
align-items: center;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
color: ${({ theme, accent }) =>
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
color: ${({ accent }) =>
|
||||
accent === 'success'
|
||||
? theme.color.turquoise
|
||||
? themeCssVariables.color.turquoise
|
||||
: accent === 'error'
|
||||
? theme.color.red
|
||||
: theme.font.color.secondary};
|
||||
? themeCssVariables.color.red
|
||||
: themeCssVariables.font.color.secondary};
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const StyledStatusInfo = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
`;
|
||||
|
||||
export type ExecutionStatus = {
|
||||
@@ -77,7 +79,7 @@ export const WorkflowStepExecutionResult = ({
|
||||
loadingMessage = t`Processing...`,
|
||||
idleMessage = t`Output`,
|
||||
}: WorkflowStepExecutionResultProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const SuccessLeftNode = (
|
||||
<StyledOutput accent="success">
|
||||
|
||||
+5
-4
@@ -32,8 +32,7 @@ import { getConnectionOptionsForSourceHandle } from '@/workflow/workflow-diagram
|
||||
import { WORKFLOW_DIAGRAM_NODE_DEFAULT_SOURCE_HANDLE_ID } from '@/workflow/workflow-diagram/workflow-nodes/constants/WorkflowDiagramNodeDefaultSourceHandleId';
|
||||
import { WORKFLOW_DIAGRAM_NODE_DEFAULT_TARGET_HANDLE_ID } from '@/workflow/workflow-diagram/workflow-nodes/constants/WorkflowDiagramNodeDefaultTargetHandleId';
|
||||
import { workflowInsertStepIdsComponentState } from '@/workflow/workflow-steps/states/workflowInsertStepIdsComponentState';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import {
|
||||
Background,
|
||||
ReactFlow,
|
||||
@@ -64,6 +63,8 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Tag, type TagColor } from 'twenty-ui/components';
|
||||
import { useStore } from 'jotai';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledResetReactflowStyles = styled.div`
|
||||
height: 100%;
|
||||
@@ -92,7 +93,7 @@ const StyledStatusTagContainer = styled.div`
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
padding: ${({ theme }) => theme.spacing(4)};
|
||||
padding: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
const defaultFitViewOptions = {
|
||||
@@ -166,7 +167,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
}) => void;
|
||||
}) => {
|
||||
const store = useStore();
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const reactflow = useReactFlow();
|
||||
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramConnector = () => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<svg
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { WorkflowDiagramConnector } from '@/workflow/workflow-diagram/components
|
||||
import { VERTICAL_DISTANCE_BETWEEN_TWO_NODES } from '@/workflow/workflow-diagram/constants/VerticalDistanceBetweenTwoNodes';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
|
||||
+7
-6
@@ -4,23 +4,24 @@ import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStart
|
||||
import { useWorkflowDiagramScreenToFlowPosition } from '@/workflow/workflow-diagram/hooks/useWorkflowDiagramScreenToFlowPosition';
|
||||
import { workflowDiagramRightClickMenuPositionState } from '@/workflow/workflow-diagram/states/workflowDiagramRightClickMenuPositionState';
|
||||
import { useTidyUp } from '@/workflow/workflow-version/hooks/useTidyUp';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRef } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus, IconReorder } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { WorkflowDiagramRightClickCommandMenuClickOutsideEffect } from './WorkflowDiagramRightClickCommandMenuClickOutsideEffect';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div<{ x: number; y: number }>`
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
border-radius: ${({ theme }) => theme.spacing(2)};
|
||||
background: ${themeCssVariables.background.primary};
|
||||
box-shadow: ${themeCssVariables.boxShadow.strong};
|
||||
border-radius: ${themeCssVariables.spacing[2]};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(0.5)};
|
||||
gap: ${themeCssVariables.spacing[0.5]};
|
||||
left: ${({ x }) => `${x}px`};
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
position: absolute;
|
||||
top: ${({ y }) => `${y}px`};
|
||||
width: 200px;
|
||||
|
||||
+7
-6
@@ -6,22 +6,23 @@ import { WorkflowRunVisualizer } from '@/workflow/workflow-diagram/components/Wo
|
||||
import { WorkflowRunVisualizerEffect } from '@/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect';
|
||||
import { WorkflowRunVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowRunVisualizerComponentInstanceContext';
|
||||
import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Suspense, useId } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Suspense, useContext, useId } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledLoadingSkeletonContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
height: 100%;
|
||||
padding: ${({ theme }) => theme.spacing(4)};
|
||||
padding: ${themeCssVariables.spacing[4]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const LoadingSkeleton = () => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledLoadingSkeletonContainer>
|
||||
|
||||
+7
-6
@@ -4,22 +4,23 @@ import { getWorkflowVisualizerComponentInstanceId } from '@/workflow/utils/getWo
|
||||
import { WorkflowVersionVisualizer } from '@/workflow/workflow-diagram/components/WorkflowVersionVisualizer';
|
||||
import { WorkflowVersionVisualizerEffect } from '@/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect';
|
||||
import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Suspense } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Suspense, useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledLoadingSkeletonContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
height: 100%;
|
||||
padding: ${({ theme }) => theme.spacing(4)};
|
||||
padding: ${themeCssVariables.spacing[4]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const LoadingSkeleton = () => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledLoadingSkeletonContainer>
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { type Theme } from '@emotion/react';
|
||||
import type { ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowDiagramColors = {
|
||||
background: string;
|
||||
@@ -18,7 +18,7 @@ export const getWorkflowDiagramColors = ({
|
||||
theme,
|
||||
runStatus,
|
||||
}: {
|
||||
theme: Theme;
|
||||
theme: ThemeType;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
}): WorkflowDiagramNodeColors => {
|
||||
switch (runStatus) {
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/workflow-edges/hooks/useEdgeState';
|
||||
import { type WorkflowDiagramEdgeComponentProps } from '@/workflow/workflow-diagram/workflow-edges/types/WorkflowDiagramEdgeComponentProps';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { BaseEdge } from '@xyflow/react';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowDiagramBaseEdgeProps = Pick<
|
||||
WorkflowDiagramEdgeComponentProps,
|
||||
@@ -24,7 +25,7 @@ export const WorkflowDiagramBaseEdge = ({
|
||||
markerEnd,
|
||||
path,
|
||||
}: WorkflowDiagramBaseEdgeProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { isEdgeSelected, isEdgeHovered } = useEdgeState();
|
||||
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getEdgePath } from '@/workflow/workflow-diagram/workflow-edges/utils/getEdgePath';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { BaseEdge, type EdgeProps } from '@xyflow/react';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowDiagramBlankEdgeProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
@@ -15,7 +16,7 @@ export const WorkflowDiagramBlankEdge = ({
|
||||
targetX,
|
||||
targetPosition,
|
||||
}: WorkflowDiagramBlankEdgeProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { segments } = getEdgePath({
|
||||
sourceX,
|
||||
|
||||
+3
-2
@@ -2,8 +2,9 @@ import {
|
||||
type ConnectionLineComponentProps,
|
||||
getBezierPath,
|
||||
} from '@xyflow/react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { EDGE_BRANCH_ARROW_MARKER } from '@/workflow/workflow-diagram/workflow-edges/constants/EdgeBranchArrowMarker';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowDiagramConnectionProps = ConnectionLineComponentProps;
|
||||
|
||||
@@ -13,7 +14,7 @@ export const WorkflowDiagramConnection = ({
|
||||
toX,
|
||||
toY,
|
||||
}: WorkflowDiagramConnectionProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const [path] = getBezierPath({
|
||||
sourceX: fromX,
|
||||
|
||||
+3
-2
@@ -1,8 +1,9 @@
|
||||
import { useContext } from 'react';
|
||||
import { EDGE_BRANCH_ARROW_MARKER } from '@/workflow/workflow-diagram/workflow-edges/constants/EdgeBranchArrowMarker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramCustomMarkers = () => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<svg style={{ position: 'absolute', top: 0, left: 0 }}>
|
||||
|
||||
+3
-2
@@ -2,10 +2,11 @@ import { WorkflowDiagramEdgeLabel } from '@/workflow/workflow-diagram/workflow-e
|
||||
import { WorkflowDiagramEdgeLabelContainer } from '@/workflow/workflow-diagram/workflow-edges/components/WorkflowDiagramEdgeLabelContainer';
|
||||
import { type WorkflowDiagramEdgeComponentProps } from '@/workflow/workflow-diagram/workflow-edges/types/WorkflowDiagramEdgeComponentProps';
|
||||
import { getEdgePath } from '@/workflow/workflow-diagram/workflow-edges/utils/getEdgePath';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { i18n } from '@lingui/core';
|
||||
import { BaseEdge, EdgeLabelRenderer } from '@xyflow/react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowDiagramDefaultEdgeReadonlyProps =
|
||||
WorkflowDiagramEdgeComponentProps;
|
||||
@@ -21,7 +22,7 @@ export const WorkflowDiagramDefaultEdgeReadonly = ({
|
||||
markerEnd,
|
||||
data,
|
||||
}: WorkflowDiagramDefaultEdgeReadonlyProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const {
|
||||
segments,
|
||||
|
||||
+29
-17
@@ -1,19 +1,18 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { IconButtonGroup, type IconButtonGroupProps } from 'twenty-ui/input';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { css } from '@emotion/react';
|
||||
import { css } from '@linaria/core';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useMemo, type CSSProperties } from 'react';
|
||||
import { IconButtonGroup, type IconButtonGroupProps } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledIconButtonGroup = styled(IconButtonGroup)<{ selected?: boolean }>`
|
||||
const iconButtonGroupStyle = css`
|
||||
background-color: var(--edge-btn-bg, transparent);
|
||||
border: var(--edge-btn-border, none);
|
||||
pointer-events: all;
|
||||
`;
|
||||
|
||||
${({ selected, theme }) => {
|
||||
if (!selected) return '';
|
||||
const colors = getWorkflowDiagramColors({ theme });
|
||||
return css`
|
||||
background-color: ${colors.selected.background};
|
||||
border: 1px solid ${colors.selected.borderColor};
|
||||
`;
|
||||
}}
|
||||
const StyledWrapper = styled.div`
|
||||
display: contents;
|
||||
`;
|
||||
|
||||
type WorkflowDiagramEdgeButtonGroupProps = IconButtonGroupProps & {
|
||||
@@ -24,11 +23,24 @@ export const WorkflowDiagramEdgeButtonGroup = ({
|
||||
selected = false,
|
||||
iconButtons,
|
||||
}: WorkflowDiagramEdgeButtonGroupProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const dynamicStyles = useMemo(() => {
|
||||
if (!selected) return {};
|
||||
const colors = getWorkflowDiagramColors({ theme });
|
||||
return {
|
||||
'--edge-btn-bg': colors.selected.background,
|
||||
// eslint-disable-next-line lingui/no-unlocalized-strings
|
||||
'--edge-btn-border': `1px solid ${colors.selected.borderColor}`,
|
||||
} as CSSProperties;
|
||||
}, [selected, theme]);
|
||||
|
||||
return (
|
||||
<StyledIconButtonGroup
|
||||
className="nodrag nopan"
|
||||
iconButtons={iconButtons}
|
||||
selected={selected}
|
||||
/>
|
||||
<StyledWrapper style={dynamicStyles}>
|
||||
<IconButtonGroup
|
||||
className={`nodrag nopan ${iconButtonGroupStyle}`}
|
||||
iconButtons={iconButtons}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
+10
-9
@@ -1,23 +1,24 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Label } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.strong};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
background: ${themeCssVariables.background.secondary};
|
||||
border: 1px solid ${themeCssVariables.border.color.strong};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
justify-content: center;
|
||||
padding-block: ${({ theme }) => theme.spacing(0.5)};
|
||||
padding-inline: ${({ theme }) => theme.spacing(1)};
|
||||
padding-block: ${themeCssVariables.spacing[0.5]};
|
||||
padding-inline: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledNumber = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
`;
|
||||
|
||||
type WorkflowDiagramEdgeLabelProps = {
|
||||
|
||||
+10
-20
@@ -1,5 +1,4 @@
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Position } from '@xyflow/react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -13,28 +12,19 @@ const StyledWorkflowDiagramEdgeLabelContainer = styled.div<{
|
||||
position: absolute;
|
||||
width: fit-content;
|
||||
|
||||
${({ position, sourceX, sourceY, centerX, centerY }) => {
|
||||
transform: ${({ position, sourceX, sourceY, centerX, centerY }) => {
|
||||
if (isDefined(centerX) && isDefined(centerY)) {
|
||||
return css`
|
||||
transform: translate(-50%, -50%) translate(${centerX}px, ${centerY}px);
|
||||
`;
|
||||
return `translate(-50%, -50%) translate(${centerX}px, ${centerY}px)`;
|
||||
}
|
||||
|
||||
switch (position) {
|
||||
case Position.Right: {
|
||||
return css`
|
||||
transform: translate(0%, -50%)
|
||||
translate(${Math.floor(sourceX)}px, ${sourceY}px) translateX(10px);
|
||||
`;
|
||||
}
|
||||
case Position.Bottom: {
|
||||
return css`
|
||||
transform: translate(-50%, 0%)
|
||||
translate(${sourceX}px, ${Math.floor(sourceY)}px) translateY(10px);
|
||||
`;
|
||||
}
|
||||
case Position.Right:
|
||||
return `translate(0%, -50%) translate(${Math.floor(sourceX)}px, ${sourceY}px) translateX(10px)`;
|
||||
case Position.Bottom:
|
||||
return `translate(-50%, 0%) translate(${sourceX}px, ${Math.floor(sourceY)}px) translateY(10px)`;
|
||||
default:
|
||||
return 'none';
|
||||
}
|
||||
}}
|
||||
}};
|
||||
`;
|
||||
|
||||
export { StyledWorkflowDiagramEdgeLabelContainer as WorkflowDiagramEdgeLabelContainer };
|
||||
|
||||
+5
-6
@@ -1,12 +1,11 @@
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledContainer = styled.div<{ labelX: number; labelY: number }>`
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
pointer-events: all;
|
||||
${({ labelX, labelY }) => css`
|
||||
transform: translate(-50%, -50%) translate(${labelX}px, ${labelY}px);
|
||||
`}
|
||||
transform: ${({ labelX, labelY }) =>
|
||||
`translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`};
|
||||
position: absolute;
|
||||
`;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledContainer = styled.div<{ shouldDisplay: boolean }>`
|
||||
opacity: ${({ shouldDisplay }) => (shouldDisplay ? 1 : 0)};
|
||||
|
||||
+4
-1
@@ -17,9 +17,11 @@ import { useLingui } from '@lingui/react/macro';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramEmptyTriggerEditable = ({ id }: { id: string }) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { openWorkflowTriggerTypeInCommandMenu } = useWorkflowCommandMenu();
|
||||
|
||||
@@ -60,6 +62,7 @@ export const WorkflowDiagramEmptyTriggerEditable = ({ id }: { id: string }) => {
|
||||
return (
|
||||
<WorkflowNodeContainer
|
||||
data-click-outside-id={WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID}
|
||||
theme={theme}
|
||||
onClick={handleClick}
|
||||
selected={selected}
|
||||
>
|
||||
@@ -72,7 +75,7 @@ export const WorkflowDiagramEmptyTriggerEditable = ({ id }: { id: string }) => {
|
||||
</WorkflowNodeLabel>
|
||||
</WorkflowNodeLabelWithCounterPart>
|
||||
|
||||
<WorkflowNodeTitle selected={selected}>
|
||||
<WorkflowNodeTitle theme={theme} selected={selected}>
|
||||
{t`Add a Trigger`}
|
||||
</WorkflowNodeTitle>
|
||||
</WorkflowNodeRightPart>
|
||||
|
||||
+4
-1
@@ -19,10 +19,12 @@ import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramEmptyTriggerReadonly = ({ id }: { id: string }) => {
|
||||
const { getIcon } = useIcons();
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const workflowVisualizerWorkflowId = useAtomComponentStateValue(
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
@@ -73,6 +75,7 @@ export const WorkflowDiagramEmptyTriggerReadonly = ({ id }: { id: string }) => {
|
||||
return (
|
||||
<WorkflowNodeContainer
|
||||
data-click-outside-id={WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID}
|
||||
theme={theme}
|
||||
onClick={handleClick}
|
||||
selected={selected}
|
||||
>
|
||||
@@ -85,7 +88,7 @@ export const WorkflowDiagramEmptyTriggerReadonly = ({ id }: { id: string }) => {
|
||||
</WorkflowNodeLabel>
|
||||
</WorkflowNodeLabelWithCounterPart>
|
||||
|
||||
<WorkflowNodeTitle selected={selected}>
|
||||
<WorkflowNodeTitle theme={theme} selected={selected}>
|
||||
{t`Add a Trigger`}
|
||||
</WorkflowNodeTitle>
|
||||
</WorkflowNodeRightPart>
|
||||
|
||||
+88
-79
@@ -2,47 +2,23 @@ import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { NODE_HANDLE_HEIGHT_PX } from '@/workflow/workflow-diagram/constants/NodeHandleHeightPx';
|
||||
import { NODE_HANDLE_WIDTH_PX } from '@/workflow/workflow-diagram/constants/NodeHandleWidthPx';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Handle, Position, type HandleProps } from '@xyflow/react';
|
||||
import { useContext, useMemo, type CSSProperties } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const HANDLE_SCALE_ON_HOVER = 1.5;
|
||||
|
||||
const StyledHandle = styled(Handle, {
|
||||
shouldForwardProp: (prop) =>
|
||||
prop !== 'disableHoverEffect' &&
|
||||
prop !== 'selected' &&
|
||||
prop !== 'hovered' &&
|
||||
prop !== 'runStatus',
|
||||
})<{
|
||||
type: HandleProps['type'];
|
||||
disableHoverEffect?: boolean;
|
||||
selected: boolean;
|
||||
hovered?: boolean;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
}>`
|
||||
const StyledHandle = styled(Handle)`
|
||||
&.react-flow__handle {
|
||||
opacity: ${({ type }) => (type === 'target' ? 0 : 1)};
|
||||
height: ${NODE_HANDLE_HEIGHT_PX}px;
|
||||
width: ${NODE_HANDLE_WIDTH_PX}px;
|
||||
|
||||
${({ theme, selected, hovered, disableHoverEffect, runStatus }) => {
|
||||
if (!selected) {
|
||||
return css`
|
||||
background: ${theme.background.primary};
|
||||
border-color: ${hovered && disableHoverEffect !== true
|
||||
? theme.font.color.light
|
||||
: theme.border.color.strong};
|
||||
`;
|
||||
}
|
||||
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
|
||||
return css`
|
||||
background: ${colors.selected.background};
|
||||
border-color: ${colors.selected.borderColor};
|
||||
`;
|
||||
}}
|
||||
opacity: var(--handle-opacity, 1);
|
||||
background: var(--handle-bg);
|
||||
border-color: var(--handle-border-color);
|
||||
transform: var(--handle-transform);
|
||||
transform-origin: var(--handle-transform-origin);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
@@ -50,8 +26,8 @@ const StyledHandle = styled(Handle, {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: calc(100% + ${({ theme }) => theme.spacing(4)});
|
||||
height: calc(100% + ${({ theme }) => theme.spacing(4)});
|
||||
width: calc(100% + ${themeCssVariables.spacing[4]});
|
||||
height: calc(100% + ${themeCssVariables.spacing[4]});
|
||||
}
|
||||
|
||||
transition:
|
||||
@@ -60,55 +36,88 @@ const StyledHandle = styled(Handle, {
|
||||
border-color 0.1s;
|
||||
z-index: 1;
|
||||
|
||||
${({ position }) => {
|
||||
if (position === Position.Right) {
|
||||
return css`
|
||||
transform: translate(50%, -50%);
|
||||
transform-origin: top right;
|
||||
`;
|
||||
}
|
||||
|
||||
return css`
|
||||
transform: translate(-50%, 50%);
|
||||
transform-origin: bottom left;
|
||||
`;
|
||||
}}
|
||||
|
||||
&.connectionindicator {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
${({ disableHoverEffect, theme }) => {
|
||||
if (disableHoverEffect === true) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const colors = getWorkflowDiagramColors({ theme });
|
||||
|
||||
return css`
|
||||
background: ${colors.selected.background} !important;
|
||||
border-color: ${colors.selected.borderColor} !important;
|
||||
`;
|
||||
}}
|
||||
|
||||
${({ disableHoverEffect, position }) => {
|
||||
if (disableHoverEffect === true) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (position === Position.Right) {
|
||||
return css`
|
||||
transform: scale(${HANDLE_SCALE_ON_HOVER}) translate(50%, -50%);
|
||||
`;
|
||||
}
|
||||
|
||||
return css`
|
||||
transform: scale(${HANDLE_SCALE_ON_HOVER}) translate(-50%, 50%);
|
||||
`;
|
||||
}}
|
||||
background: var(--handle-hover-bg, var(--handle-bg)) !important;
|
||||
border-color: var(
|
||||
--handle-hover-border-color,
|
||||
var(--handle-border-color)
|
||||
) !important;
|
||||
transform: var(--handle-hover-transform, var(--handle-transform));
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledHandle as WorkflowDiagramHandleSource };
|
||||
type WorkflowDiagramHandleSourceProps = {
|
||||
id: string;
|
||||
type: HandleProps['type'];
|
||||
position: Position;
|
||||
selected: boolean;
|
||||
hovered?: boolean;
|
||||
disableHoverEffect?: boolean;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
};
|
||||
|
||||
export const WorkflowDiagramHandleSource = ({
|
||||
id,
|
||||
type,
|
||||
position,
|
||||
selected,
|
||||
hovered,
|
||||
disableHoverEffect,
|
||||
runStatus,
|
||||
}: WorkflowDiagramHandleSourceProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const dynamicStyles = useMemo(() => {
|
||||
const isRight = position === Position.Right;
|
||||
const transform = isRight ? 'translate(50%, -50%)' : 'translate(-50%, 50%)';
|
||||
// eslint-disable-next-line lingui/no-unlocalized-strings
|
||||
const transformOrigin = isRight ? 'top right' : 'bottom left';
|
||||
|
||||
let bg: string;
|
||||
let borderColor: string;
|
||||
|
||||
if (selected) {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
bg = colors.selected.background;
|
||||
borderColor = colors.selected.borderColor;
|
||||
} else {
|
||||
bg = theme.background.primary;
|
||||
borderColor =
|
||||
hovered && disableHoverEffect !== true
|
||||
? theme.font.color.light
|
||||
: theme.border.color.strong;
|
||||
}
|
||||
|
||||
const styles: Record<string, string> = {
|
||||
'--handle-opacity': type === 'target' ? '0' : '1',
|
||||
'--handle-bg': bg,
|
||||
'--handle-border-color': borderColor,
|
||||
'--handle-transform': transform,
|
||||
'--handle-transform-origin': transformOrigin,
|
||||
};
|
||||
|
||||
if (disableHoverEffect !== true) {
|
||||
const hoverColors = getWorkflowDiagramColors({ theme });
|
||||
styles['--handle-hover-bg'] = hoverColors.selected.background;
|
||||
styles['--handle-hover-border-color'] = hoverColors.selected.borderColor;
|
||||
styles['--handle-hover-transform'] =
|
||||
`scale(${HANDLE_SCALE_ON_HOVER}) ${transform}`;
|
||||
}
|
||||
|
||||
return styles as CSSProperties;
|
||||
}, [position, selected, hovered, disableHoverEffect, runStatus, type, theme]);
|
||||
|
||||
return (
|
||||
<StyledHandle
|
||||
id={id}
|
||||
type={type}
|
||||
position={position}
|
||||
style={dynamicStyles}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
import { WORKFLOW_DIAGRAM_NODE_DEFAULT_TARGET_HANDLE_ID } from '@/workflow/workflow-diagram/workflow-nodes/constants/WorkflowDiagramNodeDefaultTargetHandleId';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Handle, Position } from '@xyflow/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowDiagramHandleTargetProps = {
|
||||
isConnectable?: boolean;
|
||||
@@ -10,7 +11,7 @@ const StyledHandle = styled(Handle)`
|
||||
&.react-flow__handle {
|
||||
opacity: 0;
|
||||
z-index: 1;
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
|
||||
+6
-2
@@ -19,11 +19,12 @@ import { WORKFLOW_DIAGRAM_NODE_DEFAULT_SOURCE_HANDLE_ID } from '@/workflow/workf
|
||||
import { useConnectionState } from '@/workflow/workflow-diagram/workflow-nodes/hooks/useConnectionState';
|
||||
import { isNodeTitleHighlighted } from '@/workflow/workflow-diagram/workflow-nodes/utils/isNodeTitleHighlighted';
|
||||
import { workflowInsertStepIdsComponentState } from '@/workflow/workflow-steps/states/workflowInsertStepIdsComponentState';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Position } from '@xyflow/react';
|
||||
import { useState } from 'react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledAddStepButtonContainer = styled.div<{
|
||||
shouldDisplay: boolean;
|
||||
@@ -51,6 +52,7 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
onClick?: () => void;
|
||||
}) => {
|
||||
const { i18n } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
@@ -95,6 +97,7 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
<>
|
||||
<WorkflowNodeContainer
|
||||
data-click-outside-id={WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID}
|
||||
theme={theme}
|
||||
onClick={onClick}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
@@ -115,6 +118,7 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
</WorkflowNodeLabelWithCounterPart>
|
||||
|
||||
<WorkflowNodeTitle
|
||||
theme={theme}
|
||||
highlight={nodeTitleHighlighted}
|
||||
selected={selected}
|
||||
>
|
||||
|
||||
+3
-2
@@ -1,15 +1,16 @@
|
||||
import { type WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { getWorkflowNodeIconKey } from '@/workflow/workflow-diagram/utils/getWorkflowNodeIconKey';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramStepNodeIcon = ({
|
||||
data,
|
||||
}: {
|
||||
data: WorkflowDiagramStepNodeData;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { getIcon } = useIcons();
|
||||
const Icon = getIcon(getWorkflowNodeIconKey(data));
|
||||
|
||||
|
||||
+4
@@ -25,6 +25,7 @@ import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomStat
|
||||
import { useContext } from 'react';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const WorkflowDiagramStepNodeReadonly = ({
|
||||
id,
|
||||
@@ -34,6 +35,7 @@ export const WorkflowDiagramStepNodeReadonly = ({
|
||||
data: WorkflowDiagramStepNodeData;
|
||||
}) => {
|
||||
const { getIcon } = useIcons();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const workflowVisualizerWorkflowId = useAtomComponentStateValue(
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
@@ -88,6 +90,7 @@ export const WorkflowDiagramStepNodeReadonly = ({
|
||||
<>
|
||||
<WorkflowNodeContainer
|
||||
data-click-outside-id={WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID}
|
||||
theme={theme}
|
||||
onClick={handleClick}
|
||||
selected={selected}
|
||||
>
|
||||
@@ -104,6 +107,7 @@ export const WorkflowDiagramStepNodeReadonly = ({
|
||||
</WorkflowNodeLabelWithCounterPart>
|
||||
|
||||
<WorkflowNodeTitle
|
||||
theme={theme}
|
||||
highlight={nodeTitleHighlighted}
|
||||
selected={selected}
|
||||
>
|
||||
|
||||
+32
-29
@@ -1,20 +1,22 @@
|
||||
import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import type { ThemeType } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledNodeContainer = styled.div<{
|
||||
theme: ThemeType;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
isConnectable?: boolean;
|
||||
selected: boolean;
|
||||
}>`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
max-width: 240px;
|
||||
min-width: 44px;
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: border-box;
|
||||
@@ -22,34 +24,35 @@ const StyledNodeContainer = styled.div<{
|
||||
position: relative;
|
||||
transition: border-color 0.1s;
|
||||
|
||||
${({ theme, runStatus, selected, isConnectable }) => {
|
||||
background: ${({ theme, runStatus, selected }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
return selected ? colors.selected.background : colors.unselected.background;
|
||||
}};
|
||||
|
||||
const background = selected
|
||||
? colors.selected.background
|
||||
: colors.unselected.background;
|
||||
border-color: ${({ theme, runStatus, selected }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
return selected
|
||||
? colors.selected.borderColor
|
||||
: colors.unselected.borderColor;
|
||||
}};
|
||||
|
||||
return css`
|
||||
background: ${background};
|
||||
border-color: ${selected
|
||||
&:hover {
|
||||
background: ${({ theme, runStatus, selected }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
const bg = selected
|
||||
? colors.selected.background
|
||||
: colors.unselected.background;
|
||||
return `linear-gradient(0deg, ${themeCssVariables.background.transparent.lighter} 0%, ${themeCssVariables.background.transparent.lighter} 100%), ${bg}`;
|
||||
}};
|
||||
|
||||
border-color: ${({ theme, runStatus, selected, isConnectable }) => {
|
||||
if (isConnectable === true) return themeCssVariables.color.blue;
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
return selected
|
||||
? colors.selected.borderColor
|
||||
: colors.unselected.borderColor};
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
${theme.background.transparent.lighter} 0%,
|
||||
${theme.background.transparent.lighter} 100%
|
||||
),
|
||||
${background};
|
||||
|
||||
${isConnectable &&
|
||||
css`
|
||||
border-color: ${theme.color.blue} !important;
|
||||
`};
|
||||
}
|
||||
`;
|
||||
}}
|
||||
: colors.unselected.borderColor;
|
||||
}};
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledNodeContainer as WorkflowNodeContainer };
|
||||
|
||||
+3
-2
@@ -1,8 +1,9 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledNodeIconContainer = styled.div`
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.background.transparent.light};
|
||||
background: ${themeCssVariables.background.transparent.light};
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
+29
-12
@@ -1,23 +1,40 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Label } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledNodeLabel = styled(Label)<{
|
||||
type WorkflowNodeLabelProps = {
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
selected: boolean;
|
||||
}>`
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const StyledNodeLabelWrapper = styled.div<{ labelColor: string }>`
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 0;
|
||||
|
||||
${({ theme, runStatus, selected }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
|
||||
return css`
|
||||
color: ${selected ? colors.selected.color : colors.unselected.color};
|
||||
`;
|
||||
}}
|
||||
> div {
|
||||
color: ${({ labelColor }) => labelColor};
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledNodeLabel as WorkflowNodeLabel };
|
||||
export const WorkflowNodeLabel = ({
|
||||
runStatus,
|
||||
selected,
|
||||
children,
|
||||
className,
|
||||
}: WorkflowNodeLabelProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
const labelColor = selected ? colors.selected.color : colors.unselected.color;
|
||||
|
||||
return (
|
||||
<StyledNodeLabelWrapper labelColor={labelColor} className={className}>
|
||||
<Label>{children}</Label>
|
||||
</StyledNodeLabelWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledNodeLabelWithCounterPart = styled.div`
|
||||
align-items: center;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledNodeRightPart = styled.div`
|
||||
align-items: flex-start;
|
||||
|
||||
+14
-23
@@ -1,38 +1,29 @@
|
||||
import type { WorkflowRunStepStatus } from '@/workflow/types/Workflow';
|
||||
import { getWorkflowDiagramColors } from '@/workflow/workflow-diagram/utils/getWorkflowDiagramColors';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { styled } from '@linaria/react';
|
||||
import type { ThemeType } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
const StyledNodeTitle = styled.div<{
|
||||
theme: ThemeType;
|
||||
highlight?: boolean;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
selected: boolean;
|
||||
}>`
|
||||
box-sizing: border-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
align-self: stretch;
|
||||
display: -webkit-box;
|
||||
font-size: ${({ theme }) => theme.font.size.md};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
${({ theme, highlight, runStatus, selected }) => {
|
||||
box-sizing: border-box;
|
||||
color: ${({ theme, highlight, runStatus, selected }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
if (highlight === true) return colors.selected.titleColor;
|
||||
return selected ? colors.selected.titleColor : colors.unselected.titleColor;
|
||||
}};
|
||||
display: -webkit-box;
|
||||
font-size: ${themeCssVariables.font.size.md};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
overflow: hidden;
|
||||
|
||||
if (true === highlight) {
|
||||
return css`
|
||||
color: ${colors.selected.titleColor};
|
||||
`;
|
||||
}
|
||||
|
||||
return css`
|
||||
color: ${selected
|
||||
? colors.selected.titleColor
|
||||
: colors.unselected.titleColor};
|
||||
`;
|
||||
}}
|
||||
text-overflow: ellipsis;
|
||||
`;
|
||||
|
||||
export { StyledNodeTitle as WorkflowNodeTitle };
|
||||
|
||||
+23
-18
@@ -23,8 +23,7 @@ import { WorkflowNodeRightPart } from '@/workflow/workflow-diagram/workflow-node
|
||||
import { WorkflowNodeTitle } from '@/workflow/workflow-diagram/workflow-nodes/components/WorkflowNodeTitle';
|
||||
import { WORKFLOW_DIAGRAM_NODE_DEFAULT_SOURCE_HANDLE_ID } from '@/workflow/workflow-diagram/workflow-nodes/constants/WorkflowDiagramNodeDefaultSourceHandleId';
|
||||
import { getNodeIterationCount } from '@/workflow/workflow-diagram/workflow-nodes/utils/getNodeIterationCount';
|
||||
import { css, useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Position } from '@xyflow/react';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { useContext } from 'react';
|
||||
@@ -32,15 +31,17 @@ import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { StepStatus } from 'twenty-shared/workflow';
|
||||
import { IconCheck, IconX, useIcons } from 'twenty-ui/display';
|
||||
import { Loader } from 'twenty-ui/feedback';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext, type ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
const StyledNodeLabelWithCounterPart = styled(WorkflowNodeLabelWithCounterPart)`
|
||||
column-gap: ${({ theme }) => theme.spacing(2)};
|
||||
column-gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledStatusIconsContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
justify-content: flex-end;
|
||||
box-sizing: border-box;
|
||||
`;
|
||||
@@ -49,7 +50,7 @@ const StyledColorIcon = styled.div<{
|
||||
color: string;
|
||||
}>`
|
||||
align-items: center;
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
height: 14px;
|
||||
@@ -59,22 +60,18 @@ const StyledColorIcon = styled.div<{
|
||||
`;
|
||||
|
||||
const StyledIterationCounter = styled.div<{
|
||||
theme: ThemeType;
|
||||
runStatus?: WorkflowRunStepStatus;
|
||||
}>`
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
|
||||
${({ theme, runStatus }) => {
|
||||
const colors = getWorkflowDiagramColors({ theme, runStatus });
|
||||
return css`
|
||||
color: ${colors.unselected.color};
|
||||
`;
|
||||
}}
|
||||
color: ${({ theme, runStatus }) =>
|
||||
getWorkflowDiagramColors({ theme, runStatus }).unselected.color};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
`;
|
||||
|
||||
const StyledRightPartContainer = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const WorkflowRunDiagramStepNode = ({
|
||||
@@ -85,7 +82,7 @@ export const WorkflowRunDiagramStepNode = ({
|
||||
data: WorkflowRunDiagramStepNodeData;
|
||||
}) => {
|
||||
const { getIcon } = useIcons();
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const workflowVisualizerWorkflowId = useAtomComponentStateValue(
|
||||
workflowVisualizerWorkflowIdComponentState,
|
||||
@@ -140,6 +137,7 @@ export const WorkflowRunDiagramStepNode = ({
|
||||
<>
|
||||
<WorkflowNodeContainer
|
||||
data-click-outside-id={WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID}
|
||||
theme={theme}
|
||||
runStatus={data.runStatus}
|
||||
onClick={handleClick}
|
||||
selected={selected}
|
||||
@@ -157,7 +155,10 @@ export const WorkflowRunDiagramStepNode = ({
|
||||
|
||||
<StyledRightPartContainer>
|
||||
{iterationCount > 0 && (
|
||||
<StyledIterationCounter runStatus={data.runStatus}>
|
||||
<StyledIterationCounter
|
||||
theme={theme}
|
||||
runStatus={data.runStatus}
|
||||
>
|
||||
{iterationCount}
|
||||
</StyledIterationCounter>
|
||||
)}
|
||||
@@ -189,7 +190,11 @@ export const WorkflowRunDiagramStepNode = ({
|
||||
</StyledRightPartContainer>
|
||||
</StyledNodeLabelWithCounterPart>
|
||||
|
||||
<WorkflowNodeTitle runStatus={data.runStatus} selected={selected}>
|
||||
<WorkflowNodeTitle
|
||||
theme={theme}
|
||||
runStatus={data.runStatus}
|
||||
selected={selected}
|
||||
>
|
||||
{data.name}
|
||||
</WorkflowNodeTitle>
|
||||
</WorkflowNodeRightPart>
|
||||
|
||||
+4
-3
@@ -1,4 +1,5 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledStepListContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -6,8 +7,8 @@ const StyledStepListContainer = styled.div`
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
padding-block: ${({ theme }) => theme.spacing(1)};
|
||||
padding-inline: ${({ theme }) => theme.spacing(2)};
|
||||
padding-block: ${themeCssVariables.spacing[1]};
|
||||
padding-inline: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export { StyledStepListContainer as RightDrawerStepListContainer };
|
||||
|
||||
+9
-8
@@ -1,13 +1,14 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledSelectStepTitle = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
padding-left: ${({ theme }) => theme.spacing(1)};
|
||||
padding-right: ${({ theme }) => theme.spacing(1)};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
padding-top: ${themeCssVariables.spacing[2]};
|
||||
padding-bottom: ${themeCssVariables.spacing[1]};
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
padding-right: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export { StyledSelectStepTitle as RightDrawerWorkflowSelectStepTitle };
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledWorkflowRunStepJsonContainer = styled(WorkflowStepBody)`
|
||||
grid-template-rows: max-content;
|
||||
|
||||
+6
-5
@@ -1,18 +1,19 @@
|
||||
import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
|
||||
import { AppErrorDisplay } from '@/error-handler/components/internal/AppErrorDisplay';
|
||||
import { type AppErrorDisplayProps } from '@/error-handler/types/AppErrorDisplayProps';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledWorkflowStepBody = styled.div`
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
background: ${themeCssVariables.background.primary};
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
padding-block: ${({ theme }) => theme.spacing(4)};
|
||||
padding-inline: ${({ theme }) => theme.spacing(3)};
|
||||
row-gap: ${({ theme }) => theme.spacing(4)};
|
||||
padding-block: ${themeCssVariables.spacing[4]};
|
||||
padding-inline: ${themeCssVariables.spacing[3]};
|
||||
row-gap: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
export const WorkflowStepBody = ({
|
||||
|
||||
+3
-2
@@ -1,13 +1,14 @@
|
||||
import { useAddRootStepFilter } from '@/workflow/workflow-steps/filters/hooks/useAddRootStepFilter';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import { IconFilter } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
margin-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowStepFilterAddRootStepFilterButton = () => {
|
||||
|
||||
+3
-2
@@ -5,9 +5,10 @@ import { WorkflowStepFilterOperandSelect } from '@/workflow/workflow-steps/filte
|
||||
import { WorkflowStepFilterOptionsDropdown } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterOptionsDropdown';
|
||||
import { WorkflowStepFilterValueInput } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterValueInput';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { type StepFilter, type StepFilterGroup } from 'twenty-shared/types';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowStepFilterColumnProps = {
|
||||
stepFilterGroup: StepFilterGroup;
|
||||
@@ -22,7 +23,7 @@ const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const WorkflowStepFilterColumn = ({
|
||||
|
||||
+2
-4
@@ -9,7 +9,6 @@ import { useAvailableVariablesInWorkflowStep } from '@/workflow/workflow-variabl
|
||||
import { useSearchVariable } from '@/workflow/workflow-variables/hooks/useSearchVariable';
|
||||
import { type StepOutputSchemaV2 } from '@/workflow/workflow-variables/types/StepOutputSchemaV2';
|
||||
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext, useState } from 'react';
|
||||
import { type StepFilter } from 'twenty-shared/types';
|
||||
@@ -32,7 +31,6 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
}: WorkflowStepFilterFieldSelectProps) => {
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
@@ -153,8 +151,8 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
}
|
||||
dropdownPlacement="bottom-end"
|
||||
dropdownOffset={{
|
||||
x: parseInt(theme.spacing(0.5), 10),
|
||||
y: parseInt(theme.spacing(1), 10),
|
||||
x: 2,
|
||||
y: 4,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
+10
-7
@@ -2,21 +2,24 @@ import { WorkflowStepFilterAddFilterRuleSelect } from '@/workflow/workflow-steps
|
||||
import { WorkflowStepFilterColumn } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterColumn';
|
||||
import { useChildStepFiltersAndChildStepFilterGroups } from '@/workflow/workflow-steps/filters/hooks/useChildStepFiltersAndChildStepFilterGroups';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
|
||||
align-items: start;
|
||||
background-color: ${({ theme, isGrayBackground }) =>
|
||||
isGrayBackground ? theme.background.transparent.lighter : 'transparent'};
|
||||
border: ${({ theme }) => `1px solid ${theme.border.color.medium}`};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
background-color: ${({ isGrayBackground }) =>
|
||||
isGrayBackground
|
||||
? themeCssVariables.background.transparent.lighter
|
||||
: 'transparent'};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(6)};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[6]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
type WorkflowStepFilterGroupChildrenProps = {
|
||||
|
||||
+3
-2
@@ -3,9 +3,10 @@ import { WorkflowStepFilterGroupChildren } from '@/workflow/workflow-steps/filte
|
||||
import { WorkflowStepFilterGroupOptionsDropdown } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterGroupOptionsDropdown';
|
||||
import { WorkflowStepFilterLogicalOperatorCell } from '@/workflow/workflow-steps/filters/components/WorkflowStepFilterLogicalOperatorCell';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { type StepFilterGroup } from 'twenty-shared/types';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowStepFilterGroupColumnProps = {
|
||||
parentStepFilterGroup: StepFilterGroup;
|
||||
@@ -17,7 +18,7 @@ const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const WorkflowStepFilterGroupColumn = ({
|
||||
|
||||
+8
-7
@@ -4,29 +4,30 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/filters/hooks/useUpsertStepFilterSettings';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { StepLogicalOperator, type StepFilterGroup } from 'twenty-shared/types';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledText = styled.div`
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
display: flex;
|
||||
height: ${({ theme }) => theme.spacing(8)};
|
||||
height: ${themeCssVariables.spacing[8]};
|
||||
`;
|
||||
|
||||
const StyledNumber = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
margin-right: ${({ theme }) => theme.spacing(1)};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
margin-right: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: start;
|
||||
display: flex;
|
||||
min-width: ${({ theme }) => theme.spacing(20)};
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
min-width: ${themeCssVariables.spacing[20]};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
`;
|
||||
|
||||
type WorkflowStepFilterLogicalOperatorCellProps = {
|
||||
|
||||
+3
-2
@@ -1,5 +1,4 @@
|
||||
import { type SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/permission-flags/types/SettingsRolePermissionsSettingPermission';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { IconTrash } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
import {
|
||||
@@ -9,6 +8,8 @@ import {
|
||||
StyledRowLeftContent,
|
||||
StyledText,
|
||||
} from './WorkflowAiAgentPermissionsStyles';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowAiAgentPermissionsFlagRowProps = {
|
||||
permission: SettingsRolePermissionsSettingPermission;
|
||||
@@ -27,7 +28,7 @@ export const WorkflowAiAgentPermissionsFlagRow = ({
|
||||
onAdd,
|
||||
onDelete,
|
||||
}: WorkflowAiAgentPermissionsFlagRowProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const isClickable = !readonly && !isEnabled && Boolean(onAdd);
|
||||
const isDisabled = isEnabled && !showDeleteButton;
|
||||
|
||||
|
||||
+3
-2
@@ -1,4 +1,3 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import {
|
||||
StyledIconChevronRight,
|
||||
@@ -7,6 +6,8 @@ import {
|
||||
StyledRowLeftContent,
|
||||
StyledText,
|
||||
} from './WorkflowAiAgentPermissionsStyles';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowAiAgentPermissionsObjectRowProps = {
|
||||
objectMetadata: {
|
||||
@@ -23,7 +24,7 @@ export const WorkflowAiAgentPermissionsObjectRow = ({
|
||||
onClick,
|
||||
readonly,
|
||||
}: WorkflowAiAgentPermissionsObjectRowProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { getIcon } = useIcons();
|
||||
const IconComponent = getIcon(objectMetadata.icon);
|
||||
|
||||
|
||||
+18
-16
@@ -1,12 +1,14 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { IconChevronRight, Label } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export const StyledText = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
`;
|
||||
|
||||
export const StyledLabel = styled(Label)`
|
||||
margin: ${({ theme }) => theme.spacing(3, 3, 0)};
|
||||
margin: ${themeCssVariables.spacing[3]} ${themeCssVariables.spacing[3]}
|
||||
${themeCssVariables.spacing[0]};
|
||||
`;
|
||||
|
||||
export const StyledRow = styled.div<{ isDisabled?: boolean }>`
|
||||
@@ -14,16 +16,16 @@ export const StyledRow = styled.div<{ isDisabled?: boolean }>`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
box-sizing: border-box;
|
||||
border-radius: ${({ theme }) => theme.spacing(1)};
|
||||
border-radius: ${themeCssVariables.spacing[1]};
|
||||
cursor: ${({ isDisabled }) => (isDisabled ? 'not-allowed' : 'pointer')};
|
||||
opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
|
||||
pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'auto')};
|
||||
|
||||
:hover {
|
||||
background-color: ${({ theme, isDisabled }) =>
|
||||
isDisabled ? 'inherit' : theme.background.transparent.light};
|
||||
background-color: ${({ isDisabled }) =>
|
||||
isDisabled ? 'inherit' : themeCssVariables.background.transparent.light};
|
||||
}
|
||||
|
||||
:hover [data-delete-button] {
|
||||
@@ -33,32 +35,32 @@ export const StyledRow = styled.div<{ isDisabled?: boolean }>`
|
||||
|
||||
export const StyledDeleteButton = styled.div`
|
||||
opacity: 0;
|
||||
transition: opacity ${({ theme }) => theme.animation.duration.fast}ms;
|
||||
transition: opacity ${themeCssVariables.animation.duration.fast}ms;
|
||||
`;
|
||||
|
||||
export const StyledRowLeftContent = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const StyledList = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(0.5)};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[0.5]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const StyledIconContainer = styled.div`
|
||||
background-color: ${({ theme }) => theme.background.tertiary};
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
border-radius: ${({ theme }) => theme.spacing(1)};
|
||||
background-color: ${themeCssVariables.background.tertiary};
|
||||
padding: ${themeCssVariables.spacing[1]};
|
||||
border-radius: ${themeCssVariables.spacing[1]};
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
`;
|
||||
|
||||
export const StyledIconChevronRight = styled(IconChevronRight)`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
`;
|
||||
|
||||
+8
-7
@@ -8,7 +8,7 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
|
||||
import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState';
|
||||
import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState';
|
||||
import { workflowAiAgentPermissionsSelectedObjectIdState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsSelectedObjectIdState';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -25,10 +25,11 @@ import { WorkflowAiAgentPermissionsCrudList } from './WorkflowAiAgentPermissions
|
||||
import { WorkflowAiAgentPermissionsFlagList } from './WorkflowAiAgentPermissionsFlagList';
|
||||
import { WorkflowAiAgentPermissionsObjectsList } from './WorkflowAiAgentPermissionsObjectsList';
|
||||
import { getFilteredPermissions } from './workflowAiAgentPermissions.utils';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
const StyledSearchInput = styled(TextInput)`
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border-block: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-block: 1px solid ${themeCssVariables.border.color.medium};
|
||||
input {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
@@ -39,7 +40,7 @@ const StyledSearchInput = styled(TextInput)`
|
||||
`;
|
||||
|
||||
const StyledBackButtonText = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
`;
|
||||
|
||||
const StyledBackButton = styled.button`
|
||||
@@ -47,15 +48,15 @@ const StyledBackButton = styled.button`
|
||||
align-items: center;
|
||||
background: none;
|
||||
border: none;
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding: ${themeCssVariables.spacing[3]};
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
+4
-3
@@ -16,7 +16,7 @@ import { WORKFLOW_AI_AGENT_TABS } from '@/workflow/workflow-steps/workflow-actio
|
||||
import { useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/hooks/useResetWorkflowAiAgentPermissionsStateOnCommandMenuClose';
|
||||
import { workflowAiAgentActionAgentState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentActionAgentState';
|
||||
import { workflowAiAgentPermissionsIsAddingPermissionState } from '@/workflow/workflow-steps/workflow-actions/ai-agent-action/states/workflowAiAgentPermissionsIsAddingPermissionState';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { RightDrawerSkeletonLoader } from '~/loading/components/RightDrawerSkeletonLoader';
|
||||
import { WorkflowAiAgentPromptTab } from './WorkflowAiAgentPromptTab';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export type WorkflowAiAgentTabId =
|
||||
(typeof WORKFLOW_AI_AGENT_TABS)[keyof typeof WORKFLOW_AI_AGENT_TABS];
|
||||
@@ -50,8 +51,8 @@ type WorkflowEditActionAiAgentProps = {
|
||||
};
|
||||
|
||||
const StyledTabList = styled(TabList)`
|
||||
background-color: ${({ theme }) => theme.background.secondary};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledPermissionsStepBody = styled(WorkflowStepBody)`
|
||||
|
||||
+35
-33
@@ -3,13 +3,15 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/c
|
||||
|
||||
import { type OutputSchemaField } from '@/ai/constants/OutputFieldTypeOptions';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconPlus, IconTrash } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { v4 } from 'uuid';
|
||||
import { WorkflowOutputFieldTypeSelector } from './WorkflowOutputFieldTypeSelector';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowOutputSchemaBuilderProps = {
|
||||
fields: OutputSchemaField[];
|
||||
@@ -25,80 +27,80 @@ const StyledOutputSchemaContainer = styled.div`
|
||||
const StyledFieldsContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledOutputSchemaFieldContainer = styled.div`
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
border: 1px solid ${themeCssVariables.border.color.light};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledSettingsContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
padding: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledSettingsHeader = styled.div`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||
display: grid;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding-right: ${themeCssVariables.spacing[2]};
|
||||
padding-left: ${themeCssVariables.spacing[3]};
|
||||
grid-template-columns: 1fr 24px;
|
||||
padding-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
padding-bottom: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledTitleContainer = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding-top: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding-top: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledCloseButtonContainer = styled.div`
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledAddFieldButton = styled.button`
|
||||
align-items: center;
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
border: 1px solid ${themeCssVariables.border.color.light};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-family: inherit;
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
justify-content: center;
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
margin-top: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
width: 100%;
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
|
||||
&:hover {
|
||||
background-color: ${({ theme }) => theme.background.transparent.light};
|
||||
background-color: ${themeCssVariables.background.transparent.light};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledMessageContentContainer = styled.div`
|
||||
flex-direction: column;
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
padding: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
padding: ${themeCssVariables.spacing[4]};
|
||||
line-height: normal;
|
||||
`;
|
||||
|
||||
const StyledMessageDescription = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
font-weight: ${({ theme }) => theme.font.weight.regular};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
font-weight: ${themeCssVariables.font.weight.regular};
|
||||
`;
|
||||
|
||||
export const WorkflowOutputSchemaBuilder = ({
|
||||
@@ -106,7 +108,7 @@ export const WorkflowOutputSchemaBuilder = ({
|
||||
onChange,
|
||||
readonly,
|
||||
}: WorkflowOutputSchemaBuilderProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const addField = () => {
|
||||
const newField: OutputSchemaField = {
|
||||
|
||||
+4
-3
@@ -1,10 +1,11 @@
|
||||
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { type Monaco } from '@monaco-editor/react';
|
||||
import { type editor } from 'monaco-editor';
|
||||
import { IconMaximize } from 'twenty-ui/display';
|
||||
import { CodeEditor, LightIconButton } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const CODE_EDITOR_MIN_HEIGHT = 343;
|
||||
|
||||
@@ -19,8 +20,8 @@ const StyledCodeEditorContainer = styled.div`
|
||||
|
||||
const StyledFullScreenButtonContainer = styled.div`
|
||||
position: absolute;
|
||||
top: ${({ theme }) => theme.spacing(2)};
|
||||
right: ${({ theme }) => theme.spacing(2)};
|
||||
top: ${themeCssVariables.spacing[2]};
|
||||
right: ${themeCssVariables.spacing[2]};
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
|
||||
+4
-3
@@ -28,7 +28,7 @@ import { logicFunctionTestDataFamilyState } from '@/workflow/workflow-steps/work
|
||||
import { WorkflowLogicFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowLogicFunctionTabId';
|
||||
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
@@ -48,6 +48,7 @@ import { CodeEditor } from 'twenty-ui/input';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { getFunctionInputFromInputSchema } from 'twenty-shared/workflow';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const CODE_EDITOR_MIN_HEIGHT = 343;
|
||||
|
||||
@@ -61,8 +62,8 @@ const StyledCodeEditorContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledTabList = styled(TabList)`
|
||||
background-color: ${({ theme }) => theme.background.secondary};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledFullScreenCodeEditorContainer = styled.div`
|
||||
|
||||
+3
-2
@@ -3,13 +3,14 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/c
|
||||
import { type VariablePickerComponent } from '@/object-record/record-field/ui/form-types/types/VariablePickerComponent';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { type FunctionInput } from 'twenty-shared/workflow';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isObject } from '@sniptt/guards';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div<{ fullWidth?: boolean }>`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
flex-wrap: wrap;
|
||||
|
||||
> * {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { useGetLogicFunctionSourceCode } from '@/logic-functions/hooks/useGetLog
|
||||
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
|
||||
import { WorkflowEditActionCodeFields } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCodeFields';
|
||||
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { type Monaco } from '@monaco-editor/react';
|
||||
import { type editor } from 'monaco-editor';
|
||||
import { AutoTypings } from 'monaco-editor-auto-typings';
|
||||
|
||||
+1
-4
@@ -12,7 +12,6 @@ import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowS
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { canObjectBeManagedByWorkflow } from 'twenty-shared/workflow';
|
||||
@@ -66,8 +65,6 @@ export const WorkflowEditActionCreateRecord = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionCreateRecordProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
@@ -218,7 +215,7 @@ export const WorkflowEditActionCreateRecord = ({
|
||||
saveAction(newFormData);
|
||||
}}
|
||||
withSearchInput
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
|
||||
|
||||
+1
-4
@@ -9,7 +9,6 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
|
||||
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { canObjectBeManagedByWorkflow } from 'twenty-shared/workflow';
|
||||
import { HorizontalSeparator, useIcons } from 'twenty-ui/display';
|
||||
@@ -38,8 +37,6 @@ export const WorkflowEditActionDeleteRecord = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionDeleteRecordProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
@@ -136,7 +133,7 @@ export const WorkflowEditActionDeleteRecord = ({
|
||||
saveAction(newFormData);
|
||||
}}
|
||||
withSearchInput
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
|
||||
|
||||
+1
-3
@@ -24,7 +24,6 @@ import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowS
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
import { useEmailForm } from '@/workflow/workflow-steps/workflow-actions/hooks/useEmailForm';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -56,7 +55,6 @@ export const WorkflowEditActionEmailBase = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionEmailBaseProps) => {
|
||||
const theme = useTheme();
|
||||
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
|
||||
const { triggerApisOAuth } = useTriggerApisOAuth();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
@@ -242,7 +240,7 @@ export const WorkflowEditActionEmailBase = ({
|
||||
handleConnectedAccountChange(connectedAccountId);
|
||||
}}
|
||||
disabled={actionOptions.readonly}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
{isDefined(missingScopes) && (
|
||||
|
||||
+1
-4
@@ -12,7 +12,6 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { type UpdateRecordFormData } from '@/workflow/workflow-steps/workflow-actions/types/update-record-form-data.type';
|
||||
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -39,8 +38,6 @@ export const WorkflowEditActionUpdateRecord = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionUpdateRecordProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
@@ -169,7 +166,7 @@ export const WorkflowEditActionUpdateRecord = ({
|
||||
saveAction(newFormData);
|
||||
}}
|
||||
withSearchInput
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
|
||||
|
||||
+1
-4
@@ -13,7 +13,6 @@ import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowS
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -76,8 +75,6 @@ export const WorkflowEditActionUpsertRecord = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionUpsertRecordProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
@@ -235,7 +232,7 @@ export const WorkflowEditActionUpsertRecord = ({
|
||||
saveAction(newFormData);
|
||||
}}
|
||||
withSearchInput
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
|
||||
|
||||
+5
-4
@@ -11,26 +11,27 @@ import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/sta
|
||||
import { rootLevelStepFilterGroupComponentSelector } from '@/workflow/workflow-steps/filters/states/rootLevelStepFilterGroupComponentSelector';
|
||||
import { type FilterSettings } from '@/workflow/workflow-steps/filters/types/FilterSettings';
|
||||
import { isStepFilterGroupChildAStepFilterGroup } from '@/workflow/workflow-steps/filters/utils/isStepFilterGroupChildAStepFilterGroup';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: start;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledChildContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(6)};
|
||||
gap: ${themeCssVariables.spacing[6]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledFilterBodyContainer = styled(WorkflowStepBody)`
|
||||
gap: ${({ theme }) => theme.spacing(0)};
|
||||
gap: ${themeCssVariables.spacing[0]};
|
||||
`;
|
||||
|
||||
type WorkflowEditActionFilterBodyProps = {
|
||||
|
||||
+7
-8
@@ -1,5 +1,4 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { i18n } from '@lingui/core';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
@@ -33,13 +32,14 @@ import { WorkflowFindRecordsFilters } from '@/workflow/workflow-steps/workflow-a
|
||||
import { WorkflowFindRecordsFiltersEffect } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsFiltersEffect';
|
||||
import { WorkflowFindRecordsSorts } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowFindRecordsSorts';
|
||||
import { WorkflowObjectDropdownContent } from '@/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowObjectDropdownContent';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledLabel = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
display: block;
|
||||
font-size: ${({ theme }) => theme.font.size.xs};
|
||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
font-size: ${themeCssVariables.font.size.xs};
|
||||
font-weight: ${themeCssVariables.font.weight.semiBold};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledRecordTypeSelectContainer = styled.div<{ fullWidth?: boolean }>`
|
||||
@@ -81,7 +81,6 @@ export const WorkflowEditActionFindRecords = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionFindRecordsProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const maxRecordsFormatted = QUERY_MAX_RECORDS.toLocaleString();
|
||||
|
||||
@@ -202,7 +201,7 @@ export const WorkflowEditActionFindRecords = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
/>
|
||||
</StyledRecordTypeSelectContainer>
|
||||
|
||||
|
||||
+5
-4
@@ -2,27 +2,28 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
|
||||
import { filterSortableFieldMetadataItems } from '@/object-metadata/utils/filterSortableFieldMetadataItems';
|
||||
import { type RecordSort } from '@/object-record/record-sort/types/RecordSort';
|
||||
import { Select } from '@/ui/input/components/Select';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconArrowsSort, IconTrash, useIcons } from 'twenty-ui/display';
|
||||
import { Button, type SelectOption } from 'twenty-ui/input';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { ViewSortDirection } from '~/generated-metadata/graphql';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledSortItemContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledAddButtonContainer = styled.div`
|
||||
margin-top: ${({ theme }) => theme.spacing(1)};
|
||||
margin-top: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
type WorkflowFindRecordsSortsProps = {
|
||||
|
||||
+34
-34
@@ -14,12 +14,11 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { WorkflowEditActionFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/components/WorkflowEditActionFormFieldSettings';
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { css, useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { type OnDragEndResponder } from '@hello-pangea/dnd';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
@@ -33,6 +32,8 @@ import {
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { v4 } from 'uuid';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export type WorkflowEditActionFormBuilderProps = {
|
||||
triggerType: WorkflowTriggerType | undefined;
|
||||
@@ -51,13 +52,13 @@ type FormData = WorkflowFormActionField[];
|
||||
|
||||
const StyledWorkflowStepBody = styled(WorkflowStepBody)`
|
||||
display: block;
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
padding-right: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledFormFieldContainer = styled.div`
|
||||
align-items: flex-end;
|
||||
column-gap: ${({ theme }) => theme.spacing(1)};
|
||||
column-gap: ${themeCssVariables.spacing[1]};
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'grip input delete'
|
||||
@@ -68,19 +69,19 @@ const StyledFormFieldContainer = styled.div`
|
||||
|
||||
const StyledDraggingIndicator = styled.div`
|
||||
position: absolute;
|
||||
inset: ${({ theme }) => theme.spacing(-2)};
|
||||
top: ${({ theme }) => theme.spacing(-1)};
|
||||
background-color: ${({ theme }) => theme.background.transparent.light};
|
||||
inset: -8px;
|
||||
top: -4px;
|
||||
background-color: ${themeCssVariables.background.transparent.light};
|
||||
`;
|
||||
|
||||
const StyledLightGripIconButton = styled(LightIconButton)`
|
||||
grid-area: grip;
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledLightTrashIconButton = styled(LightIconButton)`
|
||||
grid-area: delete;
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledFormFieldInputContainer = styled(FormFieldInputContainer)`
|
||||
@@ -99,20 +100,19 @@ const StyledFieldContainer = styled.div<{
|
||||
border: none;
|
||||
display: flex;
|
||||
font-family: inherit;
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
padding-right: ${themeCssVariables.spacing[2]};
|
||||
width: 100%;
|
||||
|
||||
cursor: ${({ readonly }) => (readonly ? 'default' : 'pointer')};
|
||||
|
||||
${({ readonly, theme }) =>
|
||||
!readonly &&
|
||||
css`
|
||||
&:hover,
|
||||
&[data-open='true'] {
|
||||
background-color: ${theme.background.transparent.lighter};
|
||||
}
|
||||
`}
|
||||
&:hover,
|
||||
&[data-open='true'] {
|
||||
background-color: ${({ readonly }) =>
|
||||
readonly
|
||||
? 'transparent'
|
||||
: themeCssVariables.background.transparent.lighter};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledPlaceholder = styled(FormFieldPlaceholder)`
|
||||
@@ -120,30 +120,30 @@ const StyledPlaceholder = styled(FormFieldPlaceholder)`
|
||||
`;
|
||||
|
||||
const StyledAddFieldButtonContainer = styled.div`
|
||||
padding-left: ${({ theme }) => theme.spacing(7)};
|
||||
padding-right: ${({ theme }) => theme.spacing(7)};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${themeCssVariables.spacing[7]};
|
||||
padding-right: ${themeCssVariables.spacing[7]};
|
||||
padding-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledAddFieldButtonContentContainer = styled.div`
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
display: flex;
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
gap: ${({ theme }) => theme.spacing(0.5)};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[0.5]};
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledCalloutContainer = styled.div`
|
||||
padding-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${({ theme }) => theme.spacing(7)};
|
||||
padding-right: ${({ theme }) => theme.spacing(7)};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-bottom: ${themeCssVariables.spacing[2]};
|
||||
padding-left: ${themeCssVariables.spacing[7]};
|
||||
padding-right: ${themeCssVariables.spacing[7]};
|
||||
padding-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledNotClosableCalloutContainer = styled(StyledCalloutContainer)`
|
||||
padding-bottom: ${({ theme }) => theme.spacing(4)};
|
||||
padding-bottom: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
export const WorkflowEditActionFormBuilder = ({
|
||||
@@ -151,7 +151,7 @@ export const WorkflowEditActionFormBuilder = ({
|
||||
action,
|
||||
actionOptions,
|
||||
}: WorkflowEditActionFormBuilderProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { t } = useLingui();
|
||||
|
||||
const [formData, setFormData] = useState<FormData>(action.settings.input);
|
||||
@@ -278,7 +278,7 @@ export const WorkflowEditActionFormBuilder = ({
|
||||
isInsideScrollableContainer
|
||||
disableDraggingBackground
|
||||
draggableComponentStyles={{
|
||||
marginBottom: theme.spacing(4),
|
||||
marginBottom: themeCssVariables.spacing[4],
|
||||
}}
|
||||
itemComponent={({ isDragging }) => {
|
||||
const showButtons =
|
||||
|
||||
+21
-19
@@ -6,11 +6,13 @@ import { FORM_SELECT_FIELD_TYPE_OPTIONS } from '@/workflow/workflow-steps/workfl
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { type WorkflowFormFieldType } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormFieldType';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { IconSettingsAutomation, IconX } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowEditActionFormFieldSettingsProps = {
|
||||
field: WorkflowFormActionField;
|
||||
@@ -19,42 +21,42 @@ type WorkflowEditActionFormFieldSettingsProps = {
|
||||
};
|
||||
|
||||
const StyledFormFieldSettingsContainer = styled.div`
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
border: 1px solid ${themeCssVariables.border.color.light};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
margin-top: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
margin-top: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledSettingsContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
padding: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledSettingsHeader = styled.div`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||
display: grid;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-left: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding-right: ${themeCssVariables.spacing[2]};
|
||||
padding-left: ${themeCssVariables.spacing[3]};
|
||||
grid-template-columns: 1fr 24px;
|
||||
padding-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
padding-bottom: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledTitleContainer = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding-top: ${({ theme }) => theme.spacing(3)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding-top: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledCloseButtonContainer = styled.div`
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowEditActionFormFieldSettings = ({
|
||||
@@ -62,7 +64,7 @@ export const WorkflowEditActionFormFieldSettings = ({
|
||||
onChange,
|
||||
onClose,
|
||||
}: WorkflowEditActionFormFieldSettingsProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledFormFieldSettingsContainer>
|
||||
|
||||
+3
-2
@@ -4,9 +4,10 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowFormFieldSettingsNumberProps = {
|
||||
field: WorkflowFormActionField;
|
||||
@@ -16,7 +17,7 @@ type WorkflowFormFieldSettingsNumberProps = {
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowFormFieldSettingsNumber = ({
|
||||
|
||||
+4
-6
@@ -6,12 +6,12 @@ import { Select } from '@/ui/input/components/Select';
|
||||
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { type SelectOption } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowFormFieldSettingsRecordPickerProps = {
|
||||
field: WorkflowFormActionField;
|
||||
@@ -21,15 +21,13 @@ type WorkflowFormFieldSettingsRecordPickerProps = {
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowFormFieldSettingsRecordPicker = ({
|
||||
field,
|
||||
onChange,
|
||||
}: WorkflowFormFieldSettingsRecordPickerProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
@@ -67,7 +65,7 @@ export const WorkflowFormFieldSettingsRecordPicker = ({
|
||||
});
|
||||
}}
|
||||
withSearchInput
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
</FormFieldInputContainer>
|
||||
|
||||
+4
-3
@@ -7,9 +7,10 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowFormFieldSettingsSelectProps = {
|
||||
field: WorkflowFormActionField;
|
||||
@@ -19,13 +20,13 @@ type WorkflowFormFieldSettingsSelectProps = {
|
||||
const StyledFormFieldSettingsSelect = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledRowContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowFormFieldSettingsSelect = ({
|
||||
|
||||
+3
-2
@@ -4,9 +4,10 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { type WorkflowFormActionField } from '@/workflow/workflow-steps/workflow-actions/form-action/types/WorkflowFormActionField';
|
||||
import { getDefaultFormFieldSettings } from '@/workflow/workflow-steps/workflow-actions/form-action/utils/getDefaultFormFieldSettings';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowFormFieldSettingsTextProps = {
|
||||
field: WorkflowFormActionField;
|
||||
@@ -16,7 +17,7 @@ type WorkflowFormFieldSettingsTextProps = {
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
export const WorkflowFormFieldSettingsText = ({
|
||||
|
||||
+3
-2
@@ -1,9 +1,10 @@
|
||||
import { type WorkflowActionType } from '@/workflow/types/Workflow';
|
||||
import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
export const useActionIconColorOrThrow = (actionType: WorkflowActionType) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return getActionIconColorOrThrow({ theme, actionType });
|
||||
};
|
||||
|
||||
+7
-6
@@ -13,7 +13,7 @@ import {
|
||||
import { getBodyTypeFromHeaders } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/getBodyTypeFromHeaders';
|
||||
import { parseHttpJsonBodyWithoutVariablesOrThrow } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/parseHttpJsonBodyWithoutVariablesOrThrow';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { isString } from '@sniptt/guards';
|
||||
import { useState } from 'react';
|
||||
import { isDefined, parseJson } from 'twenty-shared/utils';
|
||||
@@ -24,20 +24,21 @@ import {
|
||||
import { IconFileText, IconKey } from 'twenty-ui/display';
|
||||
import { type JsonValue } from 'type-fest';
|
||||
import { KeyValuePairInput } from './KeyValuePairInput';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledSelectDropdown = styled(Select)`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
margin-bottom: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
const StyledNoBodyMessage = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-size: ${({ theme }) => theme.font.size.md};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
font-size: ${themeCssVariables.font.size.md};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
text-align: left;
|
||||
`;
|
||||
|
||||
|
||||
+3
-2
@@ -7,12 +7,13 @@ import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAto
|
||||
import { useSetAtomFamilyState } from '@/ui/utilities/state/jotai/hooks/useSetAtomFamilyState';
|
||||
import { httpRequestTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/http-request-action/states/httpRequestTestDataFamilyState';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledVariableInputsContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
type HttpRequestTestVariableInputProps = {
|
||||
|
||||
+7
-11
@@ -4,32 +4,28 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { AUTO_SET_HEADER_KEYS } from '@/workflow/workflow-steps/workflow-actions/http-request-action/constants/AutoSetHeaderKeys';
|
||||
import { isAutoSetHeaderKey } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/isReadOnlyHeaderKey';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { css } from '@emotion/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useState } from 'react';
|
||||
import { IconTrash } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { v4 } from 'uuid';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledKeyValueContainer = styled.div<{ readonly: boolean | undefined }>`
|
||||
display: grid;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
|
||||
${({ readonly, theme }) =>
|
||||
grid-template-columns: ${({ readonly }) =>
|
||||
readonly
|
||||
? css`
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
`
|
||||
: css`
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr)) ${theme.spacing(8)};
|
||||
`};
|
||||
? 'repeat(2, minmax(0, 1fr))'
|
||||
: `repeat(2, minmax(0, 1fr)) ${themeCssVariables.spacing[8]}`};
|
||||
`;
|
||||
export type KeyValuePair = {
|
||||
id: string;
|
||||
|
||||
+9
-8
@@ -13,10 +13,9 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { getBodyTypeFromHeaders } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/getBodyTypeFromHeaders';
|
||||
import { isMethodWithBody } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/isMethodWithBody';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useEffect } from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { IconPlayerPlay, IconSettings } from 'twenty-ui/display';
|
||||
import {
|
||||
HTTP_METHODS,
|
||||
@@ -31,6 +30,8 @@ import { BodyInput } from './BodyInput';
|
||||
import { HttpRequestExecutionResult } from './HttpRequestExecutionResult';
|
||||
import { HttpRequestTestVariableInput } from './HttpRequestTestVariableInput';
|
||||
import { KeyValuePairInput } from './KeyValuePairInput';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowEditActionHttpRequestProps = {
|
||||
action: WorkflowHttpRequestAction;
|
||||
@@ -41,15 +42,15 @@ type WorkflowEditActionHttpRequestProps = {
|
||||
};
|
||||
|
||||
const StyledTabList = styled(TabList)`
|
||||
background-color: ${({ theme }) => theme.background.secondary};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledTestTabContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
height: 100%;
|
||||
min-height: 400px;
|
||||
`;
|
||||
@@ -57,7 +58,7 @@ const StyledTestTabContent = styled.div`
|
||||
const StyledConfigurationTabContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
`;
|
||||
@@ -89,7 +90,7 @@ export const WorkflowEditActionHttpRequest = ({
|
||||
actionOptions,
|
||||
}: WorkflowEditActionHttpRequestProps) => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const activeTabId = useAtomComponentStateValue(
|
||||
activeTabIdComponentState,
|
||||
WORKFLOW_HTTP_REQUEST_TAB_LIST_COMPONENT_ID,
|
||||
|
||||
+2
-4
@@ -117,8 +117,7 @@ export const Configured: Story = {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const urlLabel = await canvas.findByText('URL');
|
||||
const urlInputContainer = urlLabel.closest('div')?.nextElementSibling;
|
||||
const urlEditor = urlInputContainer?.querySelector('.ProseMirror');
|
||||
const urlEditor = urlLabel.parentElement?.querySelector('.ProseMirror');
|
||||
expect(urlEditor).toBeVisible();
|
||||
expect(urlEditor).toHaveTextContent('https://api.example.com/data');
|
||||
|
||||
@@ -138,8 +137,7 @@ export const ReadOnly: Story = {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const urlLabel = await canvas.findByText('URL');
|
||||
const urlInputContainer = urlLabel.closest('div')?.nextElementSibling;
|
||||
const urlEditor = urlInputContainer?.querySelector('.ProseMirror');
|
||||
const urlEditor = urlLabel.parentElement?.querySelector('.ProseMirror');
|
||||
expect(urlEditor).toBeVisible();
|
||||
expect(urlEditor).toHaveTextContent('https://api.example.com/data');
|
||||
expect(urlEditor).toHaveAttribute('contenteditable', 'false');
|
||||
|
||||
+4
-3
@@ -22,23 +22,24 @@ import { getBranchesToDelete } from '@/workflow/workflow-steps/workflow-actions/
|
||||
import { getBranchLabel } from '@/workflow/workflow-steps/workflow-actions/if-else-action/utils/getBranchLabel';
|
||||
import { useStepsOutputSchema } from '@/workflow/workflow-variables/hooks/useStepsOutputSchema';
|
||||
import { useTidyUpWorkflowVersion } from '@/workflow/workflow-version/hooks/useTidyUpWorkflowVersion';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { Fragment } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type StepIfElseBranch } from 'twenty-shared/workflow';
|
||||
import { HorizontalSeparator, IconPlus } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: start;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
const StyledBodyContainer = styled(WorkflowStepBody)`
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
type WorkflowEditActionIfElseBodyProps = {
|
||||
|
||||
+4
-3
@@ -6,23 +6,24 @@ import { useChildStepFiltersAndChildStepFilterGroups } from '@/workflow/workflow
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/filters/states/context/WorkflowStepFilterContext';
|
||||
import { type FilterSettings } from '@/workflow/workflow-steps/filters/types/FilterSettings';
|
||||
import { isStepFilterGroupChildAStepFilterGroup } from '@/workflow/workflow-steps/filters/utils/isStepFilterGroupChildAStepFilterGroup';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { i18n, type MessageDescriptor } from '@lingui/core';
|
||||
import { type StepFilter, type StepFilterGroup } from 'twenty-shared/types';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { type StepIfElseBranch } from 'twenty-shared/workflow';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledBranchContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledFiltersContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
|
||||
+6
-5
@@ -6,23 +6,24 @@ import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThro
|
||||
import { getStepDefinitionOrThrow } from '@/workflow/utils/getStepDefinitionOrThrow';
|
||||
import { getIsDescendantOfIterator } from '@/workflow/workflow-steps/utils/getIsDescendantOfIterator';
|
||||
import { getWorkflowRunAllStepInfoHistory } from '@/workflow/workflow-steps/utils/getWorkflowRunAllStepInfoHistory';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { plural } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft, IconChevronRight } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-block: ${({ theme }) => theme.spacing(2)};
|
||||
padding-inline: ${({ theme }) => theme.spacing(3)};
|
||||
padding-block: ${themeCssVariables.spacing[2]};
|
||||
padding-inline: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledCounter = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
`;
|
||||
|
||||
export const WorkflowIteratorSubStepSwitcher = ({
|
||||
|
||||
+3
-2
@@ -7,18 +7,19 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { WorkflowEditActionCodeFields } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionCodeFields';
|
||||
import { setNestedValue } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/setNestedValue';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isObject } from '@sniptt/guards';
|
||||
import { useMemo } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Callout } from 'twenty-ui/display';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
type WorkflowEditActionLogicFunctionProps = {
|
||||
|
||||
+10
-11
@@ -1,9 +1,8 @@
|
||||
import { type WorkflowActionType } from '@/workflow/types/Workflow';
|
||||
import { type Theme } from '@emotion/react';
|
||||
import { COLOR_LIGHT, GRAY_SCALE_LIGHT } from 'twenty-ui/theme';
|
||||
import { COLOR_LIGHT, GRAY_SCALE_LIGHT, type ThemeType } from 'twenty-ui/theme';
|
||||
import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
|
||||
|
||||
const mockTheme: Theme = {
|
||||
const mockTheme: ThemeType = {
|
||||
color: {
|
||||
orange: COLOR_LIGHT.orange,
|
||||
pink: COLOR_LIGHT.pink,
|
||||
@@ -14,7 +13,7 @@ const mockTheme: Theme = {
|
||||
tertiary: GRAY_SCALE_LIGHT.gray9,
|
||||
},
|
||||
},
|
||||
} as Theme;
|
||||
} as ThemeType;
|
||||
|
||||
describe('getActionIconColorOrThrow', () => {
|
||||
describe('action types that return red color', () => {
|
||||
@@ -91,7 +90,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
|
||||
describe('theme object handling', () => {
|
||||
it('should use the provided theme colors correctly', () => {
|
||||
const customTheme: Theme = {
|
||||
const customTheme: ThemeType = {
|
||||
color: {
|
||||
red: COLOR_LIGHT.red,
|
||||
orange: COLOR_LIGHT.orange,
|
||||
@@ -102,7 +101,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
tertiary: GRAY_SCALE_LIGHT.gray11,
|
||||
},
|
||||
},
|
||||
} as Theme;
|
||||
} as ThemeType;
|
||||
|
||||
expect(
|
||||
getActionIconColorOrThrow({
|
||||
@@ -229,7 +228,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
});
|
||||
|
||||
it('should use the provided theme colors correctly', () => {
|
||||
const customTheme: Theme = {
|
||||
const customTheme: ThemeType = {
|
||||
color: {
|
||||
red: COLOR_LIGHT.red,
|
||||
orange: COLOR_LIGHT.orange,
|
||||
@@ -240,7 +239,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
tertiary: GRAY_SCALE_LIGHT.gray11,
|
||||
},
|
||||
},
|
||||
} as Theme;
|
||||
} as ThemeType;
|
||||
|
||||
expect(
|
||||
getActionIconColorOrThrow({ theme: customTheme, actionType: 'CODE' }),
|
||||
@@ -266,7 +265,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
});
|
||||
|
||||
it('should return undefined when red color is missing for SEND_EMAIL action', () => {
|
||||
const themeWithoutBlue: Theme = {
|
||||
const themeWithoutBlue: ThemeType = {
|
||||
color: {
|
||||
orange: COLOR_LIGHT.orange,
|
||||
pink: COLOR_LIGHT.pink,
|
||||
@@ -276,7 +275,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
tertiary: GRAY_SCALE_LIGHT.gray9,
|
||||
},
|
||||
},
|
||||
} as Theme;
|
||||
} as ThemeType;
|
||||
|
||||
expect(
|
||||
getActionIconColorOrThrow({
|
||||
@@ -289,7 +288,7 @@ describe('getActionIconColorOrThrow', () => {
|
||||
it('should handle null theme gracefully', () => {
|
||||
expect(() => {
|
||||
getActionIconColorOrThrow({
|
||||
theme: null as unknown as Theme,
|
||||
theme: null as unknown as ThemeType,
|
||||
actionType: 'CODE',
|
||||
});
|
||||
}).toThrow();
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
import { type WorkflowActionType } from '@/workflow/types/Workflow';
|
||||
import { type Theme } from '@emotion/react';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
import { type ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
export const getActionIconColorOrThrow = ({
|
||||
theme,
|
||||
actionType,
|
||||
}: {
|
||||
theme: Theme;
|
||||
theme: ThemeType;
|
||||
actionType: WorkflowActionType;
|
||||
}) => {
|
||||
switch (actionType) {
|
||||
|
||||
+20
-19
@@ -6,11 +6,12 @@ import { convertScheduleToCronExpression } from '@/workflow/workflow-trigger/uti
|
||||
import { normalizeCronExpression } from '@/workflow/workflow-trigger/utils/cron-to-human/utils/normalizeCronExpression';
|
||||
import { getTriggerScheduleDescription } from '@/workflow/workflow-trigger/utils/getTriggerScheduleDescription';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { CronExpressionParser } from 'cron-parser';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
import { formatDateTimeString } from '~/utils/string/formatDateTimeString';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const getNextExecutions = (
|
||||
cronExpression: string,
|
||||
@@ -44,39 +45,39 @@ const getNextExecutions = (
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(3)};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
margin-top: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledSection = styled.div`
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.sm};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
padding: ${({ theme }) => theme.spacing(3)} ${({ theme }) => theme.spacing(4)};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
padding: ${themeCssVariables.spacing[3]} ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
const StyledScheduleDescription = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
`;
|
||||
|
||||
const StyledScheduleTitle = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledExecutionItem = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
margin-top: ${({ theme }) => theme.spacing(0.5)};
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
margin-top: ${themeCssVariables.spacing[0.5]};
|
||||
`;
|
||||
|
||||
type CronExpressionHelperProps = {
|
||||
|
||||
+7
-8
@@ -15,21 +15,21 @@ import { type WorkflowDatabaseEventTrigger } from '@/workflow/types/Workflow';
|
||||
import { splitWorkflowTriggerEventName } from '@/workflow/utils/splitWorkflowTriggerEventName';
|
||||
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
|
||||
import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/WorkflowStepFooter';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { IconChevronLeft, IconSettings, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledLabel = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
display: block;
|
||||
font-size: ${({ theme }) => theme.font.size.xs};
|
||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
font-size: ${themeCssVariables.font.size.xs};
|
||||
font-weight: ${themeCssVariables.font.weight.semiBold};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledRecordTypeSelectContainer = styled.div<{ fullWidth?: boolean }>`
|
||||
@@ -63,7 +63,6 @@ export const WorkflowEditTriggerDatabaseEventForm = ({
|
||||
trigger,
|
||||
triggerOptions,
|
||||
}: WorkflowEditTriggerDatabaseEventFormProps) => {
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const { t } = useLingui();
|
||||
const [searchInputValue, setSearchInputValue] = useState('');
|
||||
@@ -250,7 +249,7 @@ export const WorkflowEditTriggerDatabaseEventForm = ({
|
||||
))}
|
||||
</>
|
||||
}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
/>
|
||||
</StyledRecordTypeSelectContainer>
|
||||
{isDefined(selectedObjectMetadataItem) && isFieldFilteringSupported && (
|
||||
|
||||
+12
-14
@@ -9,13 +9,13 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { MANUAL_TRIGGER_AVAILABILITY_TYPE_OPTIONS } from '@/workflow/workflow-trigger/constants/ManualTriggerAvailabilityTypeOptions';
|
||||
import { MANUAL_TRIGGER_IS_PINNED_OPTIONS } from '@/workflow/workflow-trigger/constants/ManualTriggerIsPinnedOptions';
|
||||
import { getManualTriggerDefaultSettings } from '@/workflow/workflow-trigger/utils/getManualTriggerDefaultSettings';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { type SelectOption } from 'twenty-ui/input';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowEditTriggerManualProps = {
|
||||
trigger: WorkflowManualTrigger;
|
||||
@@ -31,15 +31,15 @@ type WorkflowEditTriggerManualProps = {
|
||||
};
|
||||
|
||||
const StyledLabel = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-size: ${({ theme }) => theme.font.size.xs};
|
||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
font-size: ${themeCssVariables.font.size.xs};
|
||||
font-weight: ${themeCssVariables.font.weight.semiBold};
|
||||
margin-bottom: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledDescription = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
margin-top: 1px;
|
||||
`;
|
||||
|
||||
@@ -52,8 +52,6 @@ export const WorkflowEditTriggerManual = ({
|
||||
trigger,
|
||||
triggerOptions,
|
||||
}: WorkflowEditTriggerManualProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
@@ -107,7 +105,7 @@ export const WorkflowEditTriggerManual = ({
|
||||
}),
|
||||
});
|
||||
}}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
|
||||
@@ -139,7 +137,7 @@ export const WorkflowEditTriggerManual = ({
|
||||
},
|
||||
});
|
||||
}}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
) : null}
|
||||
@@ -147,7 +145,7 @@ export const WorkflowEditTriggerManual = ({
|
||||
<IconPicker
|
||||
dropdownId="workflow-edit-manual-trigger-icon"
|
||||
selectedIconKey={trigger.settings.icon}
|
||||
dropdownOffset={{ y: -parseInt(theme.spacing(3), 10) }}
|
||||
dropdownOffset={{ y: -12 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
maxIconsVisible={9 * 8} // 9 columns * 8 lines
|
||||
disabled={triggerOptions.readonly}
|
||||
@@ -209,7 +207,7 @@ export const WorkflowEditTriggerManual = ({
|
||||
},
|
||||
});
|
||||
}}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
</WorkflowStepBody>
|
||||
|
||||
+4
-4
@@ -12,10 +12,9 @@ import { WorkflowStepFooter } from '@/workflow/workflow-steps/components/Workflo
|
||||
import { WEBHOOK_TRIGGER_AUTHENTICATION_OPTIONS } from '@/workflow/workflow-trigger/constants/WebhookTriggerAuthenticationOptions';
|
||||
import { WEBHOOK_TRIGGER_HTTP_METHOD_OPTIONS } from '@/workflow/workflow-trigger/constants/WebhookTriggerHttpMethodOptions';
|
||||
import { getWebhookTriggerDefaultSettings } from '@/workflow/workflow-trigger/utils/getWebhookTriggerDefaultSettings';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useState } from 'react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { getOutputSchemaFromValue } from 'twenty-shared/logic-function';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
@@ -25,6 +24,7 @@ import { IconCopy } from 'twenty-ui/display';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
type WorkflowEditTriggerWebhookFormProps = {
|
||||
trigger: WorkflowWebhookTrigger;
|
||||
@@ -50,7 +50,7 @@ export const WorkflowEditTriggerWebhookForm = ({
|
||||
trigger,
|
||||
triggerOptions,
|
||||
}: WorkflowEditTriggerWebhookFormProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const [errorMessages, setErrorMessages] = useState<FormErrorMessages>({});
|
||||
const [errorMessagesVisible, setErrorMessagesVisible] = useState(false);
|
||||
@@ -110,7 +110,7 @@ export const WorkflowEditTriggerWebhookForm = ({
|
||||
{ computeOutputSchema: false },
|
||||
);
|
||||
}}
|
||||
dropdownOffset={{ y: parseInt(theme.spacing(1), 10) }}
|
||||
dropdownOffset={{ y: 4 }}
|
||||
dropdownWidth={GenericDropdownContentWidth.ExtraLarge}
|
||||
/>
|
||||
{trigger.settings.httpMethod === 'POST' && (
|
||||
|
||||
+7
-8
@@ -1,14 +1,13 @@
|
||||
import { type Theme } from '@emotion/react';
|
||||
import { COLOR_LIGHT } from 'twenty-ui/theme';
|
||||
import { COLOR_LIGHT, type ThemeType } from 'twenty-ui/theme';
|
||||
import { getTriggerIconColor } from '@/workflow/workflow-trigger/utils/getTriggerIconColor';
|
||||
|
||||
describe('getTriggerIconColor', () => {
|
||||
const mockTheme: Theme = {
|
||||
const mockTheme: ThemeType = {
|
||||
color: {
|
||||
blue: COLOR_LIGHT.blue,
|
||||
purple: COLOR_LIGHT.purple,
|
||||
},
|
||||
} as unknown as Theme;
|
||||
} as unknown as ThemeType;
|
||||
|
||||
it('returns the blue color for database event from theme', () => {
|
||||
const result = getTriggerIconColor({
|
||||
@@ -29,12 +28,12 @@ describe('getTriggerIconColor', () => {
|
||||
});
|
||||
|
||||
it('works with different theme configurations', () => {
|
||||
const differentTheme: Theme = {
|
||||
const differentTheme: ThemeType = {
|
||||
color: {
|
||||
blue: COLOR_LIGHT.blue,
|
||||
purple: COLOR_LIGHT.purple,
|
||||
},
|
||||
} as unknown as Theme;
|
||||
} as unknown as ThemeType;
|
||||
|
||||
const result = getTriggerIconColor({
|
||||
theme: differentTheme,
|
||||
@@ -45,12 +44,12 @@ describe('getTriggerIconColor', () => {
|
||||
});
|
||||
|
||||
it('maintains reference to theme.color.blue', () => {
|
||||
const customTheme: Theme = {
|
||||
const customTheme: ThemeType = {
|
||||
color: {
|
||||
blue: COLOR_LIGHT.blue,
|
||||
purple: COLOR_LIGHT.purple,
|
||||
},
|
||||
} as unknown as Theme;
|
||||
} as unknown as ThemeType;
|
||||
|
||||
const result = getTriggerIconColor({
|
||||
theme: customTheme,
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { type Theme } from '@emotion/react';
|
||||
import { type WorkflowTriggerType } from '@/workflow/types/Workflow';
|
||||
import { type ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
export const getTriggerIconColor = ({
|
||||
theme,
|
||||
triggerType,
|
||||
}: {
|
||||
theme: Theme;
|
||||
theme: ThemeType;
|
||||
triggerType: WorkflowTriggerType;
|
||||
}) => {
|
||||
switch (triggerType) {
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
import { BaseChip } from '@/object-record/record-field/ui/form-types/components/BaseChip';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { NodeViewWrapper, type NodeViewProps } from '@tiptap/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledWrapper = styled.span`
|
||||
display: inline-block;
|
||||
padding-inline: ${({ theme }) => theme.spacing(0.5)};
|
||||
padding-inline: ${themeCssVariables.spacing[0.5]};
|
||||
`;
|
||||
|
||||
type WorkflowTextEditorTextChipProps = NodeViewProps;
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
import { VariableChip } from '@/object-record/record-field/ui/form-types/components/VariableChip';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { NodeViewWrapper, type NodeViewProps } from '@tiptap/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledWrapper = styled.span`
|
||||
display: inline-block;
|
||||
padding-inline: ${({ theme }) => theme.spacing(0.5)};
|
||||
padding-inline: ${themeCssVariables.spacing[0.5]};
|
||||
`;
|
||||
|
||||
type WorkflowTextEditorVariableChipProps = NodeViewProps;
|
||||
|
||||
+38
-27
@@ -1,39 +1,50 @@
|
||||
import { type VariablePickerComponent } from '@/object-record/record-field/ui/form-types/types/VariablePickerComponent';
|
||||
import { WorkflowVariablesDropdown } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdown';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
export const StyledSearchVariablesDropdownContainer = styled.div<{
|
||||
const StyledSearchVariablesDropdownContainer = styled.div<{
|
||||
multiline?: boolean;
|
||||
readonly?: boolean;
|
||||
isReadonly?: boolean;
|
||||
}>`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
${({ theme, readonly }) =>
|
||||
!readonly &&
|
||||
css`
|
||||
:hover {
|
||||
background-color: ${theme.background.transparent.light};
|
||||
}
|
||||
`}
|
||||
|
||||
${({ theme, multiline }) =>
|
||||
background-color: ${({ multiline }) =>
|
||||
multiline
|
||||
? css`
|
||||
border-radius: ${theme.border.radius.sm};
|
||||
padding: ${theme.spacing(0.5)} ${theme.spacing(0)};
|
||||
position: absolute;
|
||||
right: ${theme.spacing(0)};
|
||||
top: ${theme.spacing(0)};
|
||||
`
|
||||
: css`
|
||||
background-color: ${theme.background.transparent.lighter};
|
||||
border-top-right-radius: ${theme.border.radius.sm};
|
||||
border-bottom-right-radius: ${theme.border.radius.sm};
|
||||
border: 1px solid ${theme.border.color.medium};
|
||||
`}
|
||||
? 'transparent'
|
||||
: themeCssVariables.background.transparent.lighter};
|
||||
|
||||
border-radius: ${({ multiline }) =>
|
||||
multiline
|
||||
? themeCssVariables.border.radius.sm
|
||||
: `0 ${themeCssVariables.border.radius.sm} ${themeCssVariables.border.radius.sm} 0`};
|
||||
|
||||
border: ${({ multiline }) =>
|
||||
multiline ? 'none' : `1px solid ${themeCssVariables.border.color.medium}`};
|
||||
|
||||
padding: ${({ multiline }) =>
|
||||
multiline
|
||||
? `${themeCssVariables.spacing[0.5]} ${themeCssVariables.spacing[0]}`
|
||||
: '0'};
|
||||
|
||||
position: ${({ multiline }) => (multiline ? 'absolute' : 'static')};
|
||||
right: ${({ multiline }) =>
|
||||
multiline ? themeCssVariables.spacing[0] : 'auto'};
|
||||
top: ${({ multiline }) =>
|
||||
multiline ? themeCssVariables.spacing[0] : 'auto'};
|
||||
|
||||
&:hover {
|
||||
background-color: ${({ isReadonly, multiline }) => {
|
||||
if (isReadonly === true) {
|
||||
return multiline
|
||||
? 'transparent'
|
||||
: themeCssVariables.background.transparent.lighter;
|
||||
}
|
||||
return themeCssVariables.background.transparent.light;
|
||||
}};
|
||||
}
|
||||
`;
|
||||
|
||||
export const WorkflowVariablePicker: VariablePickerComponent = ({
|
||||
@@ -47,7 +58,7 @@ export const WorkflowVariablePicker: VariablePickerComponent = ({
|
||||
return (
|
||||
<StyledSearchVariablesDropdownContainer
|
||||
multiline={multiline}
|
||||
readonly={disabled}
|
||||
isReadonly={disabled}
|
||||
>
|
||||
<WorkflowVariablesDropdown
|
||||
instanceId={instanceId}
|
||||
|
||||
+10
-9
@@ -10,22 +10,23 @@ import { SEARCH_VARIABLES_DROPDOWN_ID } from '@/workflow/workflow-variables/cons
|
||||
|
||||
import { useAvailableVariablesInWorkflowStep } from '@/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep';
|
||||
import { type StepOutputSchemaV2 } from '@/workflow/workflow-variables/types/StepOutputSchemaV2';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconVariablePlus } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
const StyledDropdownVariableButtonContainer = styled(
|
||||
StyledDropdownButtonContainer,
|
||||
)<{ transparentBackground?: boolean; disabled?: boolean }>`
|
||||
background-color: ${({ theme, transparentBackground }) =>
|
||||
background-color: ${({ transparentBackground }) =>
|
||||
transparentBackground
|
||||
? 'transparent'
|
||||
: theme.background.transparent.lighter};
|
||||
: themeCssVariables.background.transparent.lighter};
|
||||
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
:hover {
|
||||
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
|
||||
}
|
||||
@@ -50,7 +51,7 @@ export const WorkflowVariablesDropdown = ({
|
||||
multiline?: boolean;
|
||||
clickableComponent?: React.ReactNode;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${instanceId}`;
|
||||
const isDropdownOpen = useAtomComponentStateValue(
|
||||
@@ -138,7 +139,7 @@ export const WorkflowVariablesDropdown = ({
|
||||
}
|
||||
dropdownPlacement="bottom-end"
|
||||
dropdownOffset={{
|
||||
x: parseInt(theme.spacing(0.5), 10),
|
||||
x: 2,
|
||||
y: parseInt(theme.spacing(multiline ? 11 : 1), 10),
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user