Skip to content

Commit

Permalink
Use ReactFlow to visualize trigger configuration in its detail page (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
AbbyB97 authored Aug 2, 2024
1 parent b6d62fc commit 01d5b01
Show file tree
Hide file tree
Showing 32 changed files with 1,816 additions and 562 deletions.
8 changes: 6 additions & 2 deletions cypress/component/FlowChart/mock-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export const nodes: CustomNode[] = [
entityLabel: 'demo.3key.test',
icon: 'fa fa-certificate',
isMainNode: true,
certificateNodeStatus: CertificateState.Issued,
certificateNodeValidationStatus: CertificateValidationStatus.Valid,
certificateNodeData: {
certificateNodeStatus: CertificateState.Issued,
certificateNodeValidationStatus: CertificateValidationStatus.Valid,
},
// certificateNodeStatus: CertificateState.Issued,
// certificateNodeValidationStatus: CertificateValidationStatus.Valid,
description: 'This is a description',
otherProperties: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,18 @@
margin-bottom: 10px;
display: flex;
}

.groupConditionBadgeOnly {
max-width: 100%;
white-space: normal;
font-size: 10.25px;
word-wrap: break-word;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
background-color: #6c757d !important;
padding: 5px;
color: white;
border-radius: 10px;
margin-top: 5px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,23 @@ interface ConditionsTableViewerProps {
conditionItems: ConditionItemDto[];
conditionName: string;
conditionUuid: string;
smallerBadges?: boolean;
}

const ConditionsItemsList = ({ conditionItems = [], conditionName, conditionUuid }: ConditionsTableViewerProps) => {
const ConditionsItemsList = ({ conditionItems = [], conditionName, conditionUuid, smallerBadges }: ConditionsTableViewerProps) => {
const searchGroupEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterFieldSource));
const FilterConditionOperatorEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterConditionOperator));
const availableFilters = useSelector(selectors.availableFilters(EntityType.CONDITIONS));
const platformEnums = useSelector(enumSelectors.platformEnums);
const isFetchingConditionDetails = useSelector(rulesSelectors.isFetchingConditionDetails);

const isFetchingAvailableFiltersConditions = useSelector(selectors.isFetchingFilters(EntityType.CONDITIONS));

const isLoading = useMemo(
() => isFetchingAvailableFiltersConditions || isFetchingConditionDetails,
[isFetchingAvailableFiltersConditions, isFetchingConditionDetails],
);

const booleanOptions = useMemo(
() => [
{ label: 'True', value: true },
Expand Down Expand Up @@ -100,9 +108,74 @@ const ConditionsItemsList = ({ conditionItems = [], conditionName, conditionUuid
});
}, [FilterConditionOperatorEnum, availableFilters, booleanOptions, conditionItems, platformEnums, searchGroupEnum]);

if (isFetchingConditionDetails) return <Spinner active={isFetchingConditionDetails} />;
const renderSmallerConditionsBadges = useMemo(() => {
return conditionItems.map((condition, i) => {
const field = availableFilters
.find((a) => a.filterFieldSource === condition.fieldSource)
?.searchFieldData?.find((s) => s.fieldIdentifier === condition.fieldIdentifier);

const label = field ? field.fieldLabel : condition.fieldIdentifier;

let value = '';

value =
field && field.type === FilterFieldType.Boolean
? `'${booleanOptions.find((b) => !!condition.value === b.value)?.label}'`
: Array.isArray(condition.value)
? `${condition.value
.map(
(v) =>
`'${
field?.platformEnum
? platformEnums[field.platformEnum][v]?.label
: v?.name
? v.name
: field && field.attributeContentType === AttributeContentType.Date
? getFormattedDate(v as unknown as string)
: field && field.attributeContentType === AttributeContentType.Datetime
? getFormattedDateTime(v as unknown as string)
: v
}'`,
)
.join(' OR ')}`
: condition.value
? `'${
field?.platformEnum
? platformEnums[field.platformEnum][condition.value as unknown as string]?.label
: field && field.attributeContentType === AttributeContentType.Date
? getFormattedDate(condition.value as unknown as string)
: field && field.attributeContentType === AttributeContentType.Datetime
? getFormattedDateTime(condition.value as unknown as string)
: condition.value
}'`
: '';

return (
<div key={i} className="mt-2 me-1">
<span
title={`${getEnumLabel(searchGroupEnum, condition.fieldSource)} ${label} ${getEnumLabel(
FilterConditionOperatorEnum,
condition.operator,
)} ${value}`}
className={styles.groupConditionBadgeOnly}
>
<b>{getEnumLabel(searchGroupEnum, condition.fieldSource)}&nbsp;</b>'{label}'&nbsp;
{getEnumLabel(FilterConditionOperatorEnum, condition.operator)}&nbsp;
{value}
</span>
</div>
);
});
}, [FilterConditionOperatorEnum, availableFilters, booleanOptions, conditionItems, platformEnums, searchGroupEnum]);

if (isLoading) return <Spinner color="gray" active={isFetchingConditionDetails} />;

return (
return smallerBadges ? (
<div>
<h6 className={cx('text-muted', styles.groupConditionTitle)}>{`${conditionName}'s Condition Items`}</h6>
<div className="d-flex flex-wrap">{renderSmallerConditionsBadges}</div>
</div>
) : (
<div className={styles.groupConditionContainerDiv} key={conditionUuid}>
<h6 className={cx('text-muted', styles.groupConditionTitle)}>{`${conditionName}`}</h6>
<div className="ms-3">{renderConditionsBadges}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@
margin-bottom: 10px;
display: flex;
}

.groupSmallerBadge {
max-width: 100%;
white-space: normal;
font-size: 10.25px;
word-wrap: break-word;
flex-grow: 1; // Allow the item to grow to fill available space
flex-shrink: 1; // Allow the item to shrink if necessary
flex-basis: auto; //
background-color: #6c757d !important;
padding: 5px;
color: white;
border-radius: 10px;
// border-radius: 5px;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import cx from 'classnames';
import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums';
import { EntityType, selectors } from 'ducks/filters';
import { selectors as rulesSelectors } from 'ducks/rules';
import { useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { Badge } from 'reactstrap';
import { Badge, Spinner } from 'reactstrap';
import { AttributeContentType, FilterFieldType, PlatformEnum, SearchFieldDataDto } from 'types/openapi';
import { ExecutionItemModel } from 'types/rules';
import { getFormattedDate, getFormattedDateTime } from 'utils/dateUtil';
Expand All @@ -13,13 +14,22 @@ interface ExecutionsItemsListProps {
executionItems: ExecutionItemModel[];
executionName: string;
executionUuid: string;
smallerBadges?: boolean;
}

const ExecutionsItemsList = ({ executionItems = [], executionName, executionUuid }: ExecutionsItemsListProps) => {
const ExecutionsItemsList = ({ executionItems = [], executionName, executionUuid, smallerBadges }: ExecutionsItemsListProps) => {
const searchGroupEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterFieldSource));
const availableFilters = useSelector(selectors.availableFilters(EntityType.ACTIONS));
const platformEnums = useSelector(enumSelectors.platformEnums);

const isFetchingConditionDetails = useSelector(rulesSelectors.isFetchingConditionDetails);
const isFetchingAvailableFiltersConditions = useSelector(selectors.isFetchingFilters(EntityType.ACTIONS));

const isLoading = useMemo(
() => isFetchingAvailableFiltersConditions || isFetchingConditionDetails,
[isFetchingAvailableFiltersConditions, isFetchingConditionDetails],
);

const booleanOptions = useMemo(
() => [
{ label: 'True', value: true },
Expand Down Expand Up @@ -103,7 +113,77 @@ const ExecutionsItemsList = ({ executionItems = [], executionName, executionUuid
});
}, [executionItems, availableFilters, searchGroupEnum, booleanOptions, platformEnums]);

return (
const renderSmallerExecutionsBadges = useMemo(() => {
return executionItems.map((f, i) => {
const field = availableFilters
.find((a) => a.filterFieldSource === f.fieldSource)
?.searchFieldData?.find((s) => s.fieldIdentifier === f.fieldIdentifier);

const label = field ? field.fieldLabel : f.fieldIdentifier;
let value = '';
let coincideValueToShow = '';
if (Array.isArray(field?.value)) {
if (Array.isArray(f.data)) {
const actionDataValues = f.data as string[];
const coincideValues = field?.value.filter((v) => actionDataValues.includes(v.uuid));

if (coincideValues?.length) coincideValueToShow = coincideValues?.map((v) => v.name).join(', ');
}
}

value = coincideValueToShow?.length
? coincideValueToShow
: field && field.type === FilterFieldType.Boolean
? `'${booleanOptions.find((b) => !!f.data === b.value)?.label}'`
: Array.isArray(f.data)
? `${f.data
.map(
(v) =>
`'${
field?.platformEnum
? platformEnums[field.platformEnum][v]?.label
: v?.name
? v.name
: field && field.attributeContentType === AttributeContentType.Date
? getFormattedDate(v as unknown as string)
: field && field.attributeContentType === AttributeContentType.Datetime
? getFormattedDateTime(v as unknown as string)
: v
}'`,
)
.join(', ')}`
: f.data
? `'${
field?.platformEnum
? platformEnums[field.platformEnum][f.data as unknown as string]?.label
: field && field.attributeContentType === AttributeContentType.Date
? getFormattedDate(f.data as unknown as string)
: field && field.attributeContentType === AttributeContentType.Datetime
? getFormattedDateTime(f.data as unknown as string)
: f.data
}'`
: '';

return (
<div key={i} className="mt-2 me-1">
<span className={styles.groupSmallerBadge}>
<b>{f?.fieldSource && getEnumLabel(searchGroupEnum, f?.fieldSource)}&nbsp;</b>'{label}
'&nbsp;to&nbsp;
{value}
</span>
</div>
);
});
}, [executionItems, availableFilters, searchGroupEnum, booleanOptions, platformEnums]);

if (isLoading) return <Spinner color="gray" active={isFetchingConditionDetails} />;

return smallerBadges ? (
<div>
<h6 className={cx('text-muted', styles.groupConditionTitle)}>{`${executionName}'s Execution Items`}</h6>
<div className="d-flex flex-wrap">{renderSmallerExecutionsBadges}</div>
</div>
) : (
<div className={styles.groupConditionContainerDiv} key={executionUuid}>
<h6 className={cx('text-muted', styles.groupConditionTitle)}>{`${executionName}`}</h6>
<div className="ms-3">{renderActionBadges}</div>
Expand Down
28 changes: 0 additions & 28 deletions src/components/FilterWidgetRuleAction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -668,34 +668,6 @@ export default function FilterWidgetRuleAction({
.find((a) => a.filterFieldSource === f.fieldSource)
?.searchFieldData?.find((s) => s.fieldIdentifier === f.fieldIdentifier);
const label = field ? field.fieldLabel : f.fieldIdentifier;
// const value =
// field && field.type === FilterFieldType.Boolean
// ? `'${booleanOptions.find((b) => !!f.data === b.value)?.label}'`
// : Array.isArray(f.data)
// ? `${f.data
// .map(
// (v) =>
// `'${
// field?.platformEnum
// ? platformEnums[field.platformEnum][v]?.label
// : v?.name
// ? v.name
// : field && checkIfFieldIsDate(field)
// ? v?.label
// ? getFormattedDateTime(v.label)
// : getFormattedDateTime(v)
// : v
// }'`,
// )
// .join(', ')}`
// : f.data
// ? `'${
// field?.platformEnum
// ? platformEnums[field.platformEnum][f.data as unknown as string]?.label
// : f.data
// }'`
// : '';

const value =
field && field.type === FilterFieldType.Boolean
? `'${booleanOptions.find((b) => !!f.data === b.value)?.label}'`
Expand Down
42 changes: 0 additions & 42 deletions src/components/FlowChart/CustomEdge/FloatingConnectionLine.tsx

This file was deleted.

7 changes: 5 additions & 2 deletions src/components/FlowChart/CustomEdge/edgeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import { CustomNode, nodeHeight, nodeWidth } from '..';
function getNodeIntersection(intersectionNode: CustomNode, targetNode: CustomNode) {
const { positionAbsolute: intersectionNodePosition } = intersectionNode;
const targetPosition = targetNode.positionAbsolute;
const w = nodeWidth / 2;
const h = nodeHeight / 2;
const currentIntersectionNodeWidth = intersectionNode?.data?.group || intersectionNode.hidden !== undefined ? 242.5 : nodeWidth;
const w = currentIntersectionNodeWidth / 2;
const currentIntersectionNodeNodeHeight = intersectionNode?.data?.description ? nodeHeight + 35 : nodeHeight;

const h = currentIntersectionNodeNodeHeight / 2;

if (!intersectionNodePosition || !targetPosition) return { x: 0, y: 0 };

Expand Down
Loading

0 comments on commit 01d5b01

Please sign in to comment.