From afaf3655d7a0a5776ab701cace36ea3d342ed792 Mon Sep 17 00:00:00 2001 From: Abhijit Bansode Date: Sat, 25 May 2024 02:50:10 +0530 Subject: [PATCH 1/8] initial commit - updated models,redux and api actions,transform functions and broken ui --- src/api.ts | 14 +- src/components/ConditionFormFilter/index.tsx | 2 +- .../GroupActionsViewer/index.tsx | 24 +- .../GroupConditionsViewer/index.tsx | 10 +- src/components/ConditionGroupsList/index.tsx | 18 +- src/components/ConditionsViewer/index.tsx | 330 ++++++------ .../FilterWidgetRuleAction/index.tsx | 166 +++--- .../_pages/action-groups/details/index.tsx | 47 +- .../_pages/action-groups/form/index.tsx | 47 +- .../_pages/action-groups/list/index.tsx | 14 +- .../_pages/condition-groups/details/index.tsx | 50 +- .../_pages/condition-groups/form/index.tsx | 44 +- .../_pages/condition-groups/list/index.tsx | 16 +- .../_pages/discoveries/detail/index.tsx | 34 +- .../_pages/discoveries/form/index.tsx | 152 +++--- .../roles/RolePermissionsEdior/index.tsx | 4 +- src/components/_pages/rules/detail/index.tsx | 198 ++++---- src/components/_pages/rules/form/index.tsx | 36 +- src/components/_pages/rules/list/index.tsx | 4 +- .../_pages/triggers/details/index.tsx | 98 ++-- src/components/_pages/triggers/form/index.tsx | 67 ++- src/components/_pages/triggers/list/index.tsx | 10 +- src/ducks/rules-epics.ts | 270 +++++----- src/ducks/rules.ts | 319 ++++++------ src/ducks/transform/rules.ts | 239 ++++----- src/types/openapi/.openapi-generator/FILES | 42 +- src/types/openapi/apis/RulesManagementApi.ts | 476 ------------------ .../apis/WorkflowActionsManagementApi.ts | 251 +++++++++ .../apis/WorkflowRulesManagementApi.ts | 251 +++++++++ .../apis/WorkflowTriggersManagementApi.ts | 163 ++++++ src/types/openapi/apis/index.ts | 4 +- ...onGroupDetailDto.ts => ActionDetailDto.ts} | 24 +- src/types/openapi/models/ActionDto.ts | 17 +- ...GroupRequestDto.ts => ActionRequestDto.ts} | 23 +- ...leConditionGroupDto.ts => ConditionDto.ts} | 32 +- ...itionRequestDto.ts => ConditionItemDto.ts} | 18 +- ...itionDto.ts => ConditionItemRequestDto.ts} | 24 +- ...upRequestDto.ts => ConditionRequestDto.ts} | 30 +- src/types/openapi/models/ConditionType.ts | 22 + .../models/DiscoveryHistoryDetailDto.ts | 6 +- ...{RuleActionGroupDto.ts => ExecutionDto.ts} | 31 +- src/types/openapi/models/ExecutionItemDto.ts | 43 ++ .../openapi/models/ExecutionItemRequestDto.ts | 43 ++ .../openapi/models/ExecutionRequestDto.ts | 55 ++ src/types/openapi/models/ExecutionType.ts | 22 + .../openapi/models/FilterConditionOperator.ts | 2 +- src/types/openapi/models/FilterFieldSource.ts | 2 +- src/types/openapi/models/PlatformEnum.ts | 5 +- src/types/openapi/models/Resource.ts | 2 +- src/types/openapi/models/RuleActionDto.ts | 55 -- .../openapi/models/RuleActionRequestDto.ts | 49 -- .../models/RuleConditionGroupDetailDto.ts | 55 -- src/types/openapi/models/RuleDetailDto.ts | 38 +- src/types/openapi/models/RuleDto.ts | 25 - src/types/openapi/models/RuleRequestDto.ts | 27 +- .../openapi/models/RuleTriggerRequestDto.ts | 85 ---- ...riggerDetailDto.ts => TriggerDetailDto.ts} | 63 ++- .../{RuleTriggerDto.ts => TriggerDto.ts} | 46 +- src/types/openapi/models/TriggerHistoryDto.ts | 77 +++ .../openapi/models/TriggerHistoryRecordDto.ts | 34 ++ src/types/openapi/models/TriggerRequestDto.ts | 84 ++++ src/types/openapi/models/TriggerType.ts | 23 + .../openapi/models/UpdateActionRequestDto.ts | 31 ++ ...estDto.ts => UpdateConditionRequestDto.ts} | 18 +- ...estDto.ts => UpdateExecutionRequestDto.ts} | 18 +- .../openapi/models/UpdateRuleRequestDto.ts | 26 +- .../models/UpdateRuleTriggerRequestDto.ts | 79 --- .../openapi/models/UpdateTriggerRequestDto.ts | 78 +++ src/types/openapi/models/index.ts | 38 +- src/types/rules.ts | 163 +++--- src/utils/rules.ts | 6 +- 71 files changed, 2603 insertions(+), 2316 deletions(-) delete mode 100644 src/types/openapi/apis/RulesManagementApi.ts create mode 100644 src/types/openapi/apis/WorkflowActionsManagementApi.ts create mode 100644 src/types/openapi/apis/WorkflowRulesManagementApi.ts create mode 100644 src/types/openapi/apis/WorkflowTriggersManagementApi.ts rename src/types/openapi/models/{RuleActionGroupDetailDto.ts => ActionDetailDto.ts} (59%) rename src/types/openapi/models/{RuleActionGroupRequestDto.ts => ActionRequestDto.ts} (54%) rename src/types/openapi/models/{RuleConditionGroupDto.ts => ConditionDto.ts} (57%) rename src/types/openapi/models/{RuleConditionRequestDto.ts => ConditionItemDto.ts} (67%) rename src/types/openapi/models/{RuleConditionDto.ts => ConditionItemRequestDto.ts} (61%) rename src/types/openapi/models/{RuleConditionGroupRequestDto.ts => ConditionRequestDto.ts} (50%) create mode 100644 src/types/openapi/models/ConditionType.ts rename src/types/openapi/models/{RuleActionGroupDto.ts => ExecutionDto.ts} (58%) create mode 100644 src/types/openapi/models/ExecutionItemDto.ts create mode 100644 src/types/openapi/models/ExecutionItemRequestDto.ts create mode 100644 src/types/openapi/models/ExecutionRequestDto.ts create mode 100644 src/types/openapi/models/ExecutionType.ts delete mode 100644 src/types/openapi/models/RuleActionDto.ts delete mode 100644 src/types/openapi/models/RuleActionRequestDto.ts delete mode 100644 src/types/openapi/models/RuleConditionGroupDetailDto.ts delete mode 100644 src/types/openapi/models/RuleTriggerRequestDto.ts rename src/types/openapi/models/{RuleTriggerDetailDto.ts => TriggerDetailDto.ts} (50%) rename src/types/openapi/models/{RuleTriggerDto.ts => TriggerDto.ts} (50%) create mode 100644 src/types/openapi/models/TriggerHistoryDto.ts create mode 100644 src/types/openapi/models/TriggerHistoryRecordDto.ts create mode 100644 src/types/openapi/models/TriggerRequestDto.ts create mode 100644 src/types/openapi/models/TriggerType.ts create mode 100644 src/types/openapi/models/UpdateActionRequestDto.ts rename src/types/openapi/models/{UpdateRuleActionGroupRequestDto.ts => UpdateConditionRequestDto.ts} (53%) rename src/types/openapi/models/{UpdateRuleConditionGroupRequestDto.ts => UpdateExecutionRequestDto.ts} (51%) delete mode 100644 src/types/openapi/models/UpdateRuleTriggerRequestDto.ts create mode 100644 src/types/openapi/models/UpdateTriggerRequestDto.ts diff --git a/src/api.ts b/src/api.ts index fbf348dbc..be0ba2468 100644 --- a/src/api.ts +++ b/src/api.ts @@ -27,13 +27,15 @@ import { RAProfileManagementApi, ResourceManagementApi, RoleManagementApi, - RulesManagementApi, SCEPProfileManagementApi, ScheduledJobsManagementApi, SettingsApi, StatisticsDashboardApi, TokenProfileManagementApi, UserManagementApi, + WorkflowActionsManagementApi, + WorkflowRulesManagementApi, + WorkflowTriggersManagementApi, } from 'types/openapi'; import { TokenInstanceControllerApi } from 'types/openapi/apis/TokenInstanceControllerApi'; import { @@ -51,7 +53,10 @@ export interface ApiClients { auth: AuthenticationManagementApi; users: UserManagementApi; roles: RoleManagementApi; - rules: RulesManagementApi; + // rules: RulesManagementApi; + actions: WorkflowActionsManagementApi; + rules: WorkflowRulesManagementApi; + triggers: WorkflowTriggersManagementApi; auditLogs: AuditLogApi; raProfiles: RAProfileManagementApi; credentials: CredentialManagementApi; @@ -93,7 +98,10 @@ export const backendClient: ApiClients = { auth: new AuthenticationManagementApi(configuration), users: new UserManagementApi(configuration), roles: new RoleManagementApi(configuration), - rules: new RulesManagementApi(configuration), + // rules: new RulesManagementApi(configuration), + actions: new WorkflowActionsManagementApi(configuration), + rules: new WorkflowRulesManagementApi(configuration), + triggers: new WorkflowTriggersManagementApi(configuration), certificates: new CertificateInventoryApi(configuration), auditLogs: new AuditLogApi(configuration), raProfiles: new RAProfileManagementApi(configuration), diff --git a/src/components/ConditionFormFilter/index.tsx b/src/components/ConditionFormFilter/index.tsx index bccbb08d7..0fed2a47f 100644 --- a/src/components/ConditionFormFilter/index.tsx +++ b/src/components/ConditionFormFilter/index.tsx @@ -43,7 +43,7 @@ const ConditionFormFilter = ({ resource, formType, includeIgnoreAction }: Condit } includeIgnoreAction={includeIgnoreAction} onActionsUpdate={(currentActions) => { - actionGroupForm.change('actions', currentActions); + // actionGroupForm.change('actions', currentActions); }} /> diff --git a/src/components/ConditionGroupsList/GroupActionsViewer/index.tsx b/src/components/ConditionGroupsList/GroupActionsViewer/index.tsx index b364847ed..d6c57fbb1 100644 --- a/src/components/ConditionGroupsList/GroupActionsViewer/index.tsx +++ b/src/components/ConditionGroupsList/GroupActionsViewer/index.tsx @@ -5,11 +5,11 @@ import { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { Badge } from 'reactstrap'; import { PlatformEnum } from 'types/openapi'; -import { ActionRuleModel } from 'types/rules'; +import { ExecutionItemModel } from 'types/rules'; import styles from './groupActionsViewer.module.scss'; interface ConditionsTableViewerProps { - groupActions: ActionRuleModel[]; + groupActions: ExecutionItemModel[]; conditionGroupName: string; conditionGroupUuid: string; } @@ -17,7 +17,7 @@ interface ConditionsTableViewerProps { const GroupActionsViewer = ({ groupActions = [], conditionGroupName, conditionGroupUuid }: ConditionsTableViewerProps) => { const searchGroupEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterFieldSource)); const availableFilters = useSelector(selectors.availableFilters(EntityType.ACTIONS)); - const RuleActionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.RuleActionType)); + const executionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ExecutionType)); const renderActionBadges = useMemo(() => { if (!groupActions) return null; @@ -32,23 +32,23 @@ const GroupActionsViewer = ({ groupActions = [], conditionGroupName, conditionGr let value = ''; if (Array.isArray(field?.value)) { - if (Array.isArray(f.actionData)) { - const actionDataValue = f.actionData[0]; + if (Array.isArray(f.data)) { + const actionDataValue = f.data[0]; const coincideValue = field?.value.find((v) => v.uuid === actionDataValue); value = coincideValue?.name || ''; } } else { - if (typeof f.actionData === 'string') { - value = f.actionData; + if (typeof f.data === 'string') { + value = f.data; } - if (typeof f.actionData === 'object') { - value = JSON.stringify(f.actionData); + if (typeof f.data === 'object') { + value = JSON.stringify(f.data); } } return ( - - {getEnumLabel(RuleActionTypeEnum, f.actionType)}  + + {/* {getEnumLabel(executionTypeEnum, f.actionType)}  */} <> {f?.fieldSource && getEnumLabel(searchGroupEnum, f?.fieldSource)} '{label} ' to  @@ -57,7 +57,7 @@ const GroupActionsViewer = ({ groupActions = [], conditionGroupName, conditionGr ); }); - }, [groupActions, availableFilters, RuleActionTypeEnum, searchGroupEnum]); + }, [groupActions, availableFilters, executionTypeEnum, searchGroupEnum]); return (
diff --git a/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx b/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx index e2e20cb5d..42b0a3f4d 100644 --- a/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx +++ b/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx @@ -5,11 +5,11 @@ import { selectors as rulesSelectors } from 'ducks/rules'; import { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { Badge, Spinner } from 'reactstrap'; -import { PlatformEnum, RuleConditionDto } from 'types/openapi'; +import { ConditionItemDto, PlatformEnum } from 'types/openapi'; import styles from './groupConditionsViewer.module.scss'; interface ConditionsTableViewerProps { - groupConditions: RuleConditionDto[]; + groupConditions: ConditionItemDto[]; conditionGroupName: string; conditionGroupUuid: string; } @@ -19,7 +19,7 @@ const GroupConditionsViewer = ({ groupConditions = [], conditionGroupName, condi const FilterConditionOperatorEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterConditionOperator)); const availableFilters = useSelector(selectors.availableFilters(EntityType.CONDITIONS)); const platformEnums = useSelector(enumSelectors.platformEnums); - const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingConditionGroup); + const isFetchingCondition = useSelector(rulesSelectors.isFetchingCondition); const booleanOptions = useMemo( () => [ { label: 'True', value: true }, @@ -54,7 +54,7 @@ const GroupConditionsViewer = ({ groupConditions = [], conditionGroupName, condi return ( ; + if (isFetchingCondition) return ; return (
diff --git a/src/components/ConditionGroupsList/index.tsx b/src/components/ConditionGroupsList/index.tsx index 44ec02112..d3fb85f4c 100644 --- a/src/components/ConditionGroupsList/index.tsx +++ b/src/components/ConditionGroupsList/index.tsx @@ -1,14 +1,12 @@ import { EntityType, selectors } from 'ducks/filters'; import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { ActionGroupModel, ConditionRuleGroupModel } from 'types/rules'; -import GroupActionsViewer from './GroupActionsViewer'; -import GroupConditionsViewer from './GroupConditionsViewer'; +import { ConditionModel, ExecutionModel } from 'types/rules'; import styles from './conditionGroupsList.module.scss'; interface ConditionsTableViewerProps { - ruleConditions?: ConditionRuleGroupModel[]; - actionGroups?: ActionGroupModel[]; + ruleConditions?: ConditionModel[]; + actionGroups?: ExecutionModel[]; } const ConditionsGroupsList = ({ ruleConditions, actionGroups }: ConditionsTableViewerProps) => { @@ -22,24 +20,24 @@ const ConditionsGroupsList = ({ ruleConditions, actionGroups }: ConditionsTableV return ruleConditions.map((conditionGroup, i) => (
- + /> */}
)); } else if (actionGroups?.length) { return actionGroups.map((actionGroup, i) => (
- + /> */}
)); } else return <>; diff --git a/src/components/ConditionsViewer/index.tsx b/src/components/ConditionsViewer/index.tsx index f56afad23..4ce3459c8 100644 --- a/src/components/ConditionsViewer/index.tsx +++ b/src/components/ConditionsViewer/index.tsx @@ -1,14 +1,9 @@ -import { ApiClients } from 'api'; -import ConditionsGroupsList from 'components/ConditionGroupsList'; -import FilterWidget from 'components/FilterWidget'; -import FilterWidgetRuleAction from 'components/FilterWidgetRuleAction'; import { EntityType, actions as filterActions } from 'ducks/filters'; -import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; +import { selectors as rulesSelectors } from 'ducks/rules'; import { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; import { Resource } from 'types/openapi'; -import { conditionGroupToFilter, filterToConditionGroup } from 'utils/rules'; type FormType = 'rules' | 'conditionGroup' | 'actionGroup' | 'trigger'; interface ConditionGroupFormFilterProps { @@ -20,17 +15,17 @@ const ConditionsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) const { id } = useParams(); const editMode = useMemo(() => !!id, [id]); - const conditionGroupsDetails = useSelector(rulesSelectors.conditionGroupDetails); - const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingConditionGroup); - const isUpdatingConditionGroup = useSelector(rulesSelectors.isUpdatingConditionGroup); + // const conditionGroupsDetails = useSelector(rulesSelectors.conditionGroupDetails); + // const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingConditionGroup); + // const isUpdatingConditionGroup = useSelector(rulesSelectors.isUpdatingConditionGroup); - const ruleDetails = useSelector(rulesSelectors.ruleDetails); - const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); - const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); + // const ruleDetails = useSelector(rulesSelectors.ruleDetails); + // const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); + // const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); - const actionGroupDetails = useSelector(rulesSelectors.actionGroupDetails); - const isFetchingActionGroup = useSelector(rulesSelectors.isFetchingActionGroup); - const isUpdatingActionGroup = useSelector(rulesSelectors.isUpdatingActionGroup); + // const actionGroupDetails = useSelector(rulesSelectors.actionGroupDetails); + // const isFetchingActionGroup = useSelector(rulesSelectors.isFetchingActionGroup); + // const isUpdatingActionGroup = useSelector(rulesSelectors.isUpdatingActionGroup); const trigerDetails = useSelector(rulesSelectors.triggerDetails); const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); @@ -45,41 +40,41 @@ const ConditionsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - useEffect(() => { - if (!id) return; - if (formType === 'rules' && id !== ruleDetails?.uuid) { - dispatch(rulesActions.getRule({ ruleUuid: id })); - } - if (formType === 'conditionGroup' && id !== conditionGroupsDetails?.uuid) { - dispatch(rulesActions.getConditionGroup({ conditionGroupUuid: id })); - } - - if (formType === 'actionGroup' && id !== actionGroupDetails?.uuid) { - dispatch(rulesActions.getActionGroup({ actionGroupUuid: id })); - } - - if (formType === 'trigger' && id !== trigerDetails?.uuid) { - dispatch(rulesActions.getTrigger({ triggerUuid: id })); - } - }, [id, dispatch, formType, ruleDetails?.uuid, conditionGroupsDetails?.uuid, actionGroupDetails?.uuid, trigerDetails?.uuid]); - - useEffect(() => { - if (!hasEffectRun && editMode && id) { - let currentConditions = []; - - if (formType === 'rules') { - if (ruleDetails?.uuid !== id) return; - currentConditions = ruleDetails?.conditions || []; - } else { - if (conditionGroupsDetails?.uuid !== id) return; - currentConditions = conditionGroupsDetails?.conditions || []; - } - - const currentFilters = conditionGroupToFilter(currentConditions); - setHasEffectRun(true); - dispatch(filterActions.setCurrentFilters({ currentFilters: currentFilters, entity: EntityType.CONDITIONS })); - } - }, [editMode, ruleDetails, conditionGroupsDetails, hasEffectRun, dispatch, formType, id]); + // useEffect(() => { + // if (!id) return; + // if (formType === 'rules' && id !== ruleDetails?.uuid) { + // dispatch(rulesActions.getRule({ ruleUuid: id })); + // } + // if (formType === 'conditionGroup' && id !== conditionGroupsDetails?.uuid) { + // dispatch(rulesActions.getConditionGroup({ conditionGroupUuid: id })); + // } + + // if (formType === 'actionGroup' && id !== actionGroupDetails?.uuid) { + // dispatch(rulesActions.getActionGroup({ actionGroupUuid: id })); + // } + + // if (formType === 'trigger' && id !== trigerDetails?.uuid) { + // dispatch(rulesActions.getTrigger({ triggerUuid: id })); + // } + // }, [id, dispatch, formType, ruleDetails?.uuid, conditionGroupsDetails?.uuid, actionGroupDetails?.uuid, trigerDetails?.uuid]); + + // useEffect(() => { + // if (!hasEffectRun && editMode && id) { + // let currentConditions = []; + + // if (formType === 'rules') { + // if (ruleDetails?.uuid !== id) return; + // currentConditions = ruleDetails?.conditions || []; + // } else { + // if (conditionGroupsDetails?.uuid !== id) return; + // currentConditions = conditionGroupsDetails?.conditions || []; + // } + + // const currentFilters = conditionGroupToFilter(currentConditions); + // setHasEffectRun(true); + // dispatch(filterActions.setCurrentFilters({ currentFilters: currentFilters, entity: EntityType.CONDITIONS })); + // } + // }, [editMode, ruleDetails, conditionGroupsDetails, hasEffectRun, dispatch, formType, id]); useEffect(() => { return () => { @@ -88,96 +83,97 @@ const ConditionsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const renderAppendContent = useMemo(() => { - if (formType === 'rules' && ruleDetails?.conditionGroups && ruleDetails?.conditionGroups?.length > 0) { - if (isFetchingRuleDetail || isUpdatingRule) return <>; - return ; - } - - if (formType === 'trigger' && trigerDetails?.actionGroups && trigerDetails?.actionGroups?.length > 0) { - if (isFetchingTriggerDetail || isUpdatingTrigger) return <>; - return ; - } else { - return <>; - } - }, [ruleDetails, formType, trigerDetails, isFetchingRuleDetail, isFetchingTriggerDetail, isUpdatingRule, isUpdatingTrigger]); - - const renderFilterWidgetForRules = useMemo(() => { - if (formType !== 'rules' || !id || !ruleDetails) return null; - const disableBadgeRemove = - (ruleDetails.conditions.length === 1 && ruleDetails.conditionGroups.length === 0) || isFetchingRuleDetail || isUpdatingRule; - - const isBusy = isFetchingRuleDetail || isUpdatingRule; - - return ( - - apiClients.resources.listResourceRuleFilterFields({ - resource, - }) - } - disableBadgeRemove={disableBadgeRemove} - onFilterUpdate={(currentFilters) => { - const currentCondition = filterToConditionGroup(currentFilters); - dispatch( - rulesActions.updateRule({ - ruleUuid: id, - rule: { - conditions: currentCondition, - conditionGroupsUuids: ruleDetails.conditionGroups.map((cg) => cg.uuid), - description: ruleDetails.description || '', - }, - }), - ); - }} - /> - ); - }, [resource, dispatch, formType, id, ruleDetails, renderAppendContent, isFetchingRuleDetail, isUpdatingRule]); - - const renderFilterWidgetForConditionGroups = useMemo(() => { - if (formType !== 'conditionGroup' || !id || !conditionGroupsDetails) return null; - const disableBadgeRemove = conditionGroupsDetails.conditions.length === 1 || isFetchingConditionGroup || isUpdatingConditionGroup; - const isBusy = isFetchingConditionGroup || isUpdatingConditionGroup; - return ( -
- - apiClients.resources.listResourceRuleFilterFields({ - resource, - }) - } - disableBadgeRemove={disableBadgeRemove} - onFilterUpdate={(currentFilters) => { - const currentCondition = filterToConditionGroup(currentFilters); - dispatch( - rulesActions.updateConditionGroup({ - conditionGroupUuid: id, - conditionGroup: { - conditions: currentCondition, - }, - }), - ); - }} - /> -
- ); - }, [resource, dispatch, formType, id, conditionGroupsDetails, isFetchingConditionGroup, isUpdatingConditionGroup]); - - const renderFilterWidgetForActionGroup = useMemo(() => { - if (formType !== 'actionGroup' || !id || !actionGroupDetails) return null; - const disableBadgeRemove = actionGroupDetails.actions.length === 1 || isFetchingActionGroup || isUpdatingActionGroup; - - const isBusy = isFetchingActionGroup || isUpdatingActionGroup; - return ( -
- { + // if (formType === 'rules' && ruleDetails?.conditionGroups && ruleDetails?.conditionGroups?.length > 0) { + // if (isFetchingRuleDetail || isUpdatingRule) return <>; + // return ; + // } + + // if (formType === 'trigger' && trigerDetails?.actionGroups && trigerDetails?.actionGroups?.length > 0) { + // if (isFetchingTriggerDetail || isUpdatingTrigger) return <>; + // return ; + // } else { + // return <>; + // } + // }, [ruleDetails, formType, trigerDetails, isFetchingRuleDetail, isFetchingTriggerDetail, isUpdatingRule, isUpdatingTrigger]); + + // const renderFilterWidgetForRules = useMemo(() => { + // if (formType !== 'rules' || !id || !ruleDetails) return null; + // const disableBadgeRemove = + // (ruleDetails.conditions.length === 1 && ruleDetails.conditionGroups.length === 0) || isFetchingRuleDetail || isUpdatingRule; + + // const isBusy = isFetchingRuleDetail || isUpdatingRule; + + // return ( + // + // apiClients.resources.listResourceRuleFilterFields({ + // resource, + // }) + // } + // disableBadgeRemove={disableBadgeRemove} + // onFilterUpdate={(currentFilters) => { + // const currentCondition = filterToConditionGroup(currentFilters); + // dispatch( + // rulesActions.updateRule({ + // ruleUuid: id, + // rule: { + // conditions: currentCondition, + // conditionGroupsUuids: ruleDetails.conditionGroups.map((cg) => cg.uuid), + // description: ruleDetails.description || '', + // }, + // }), + // ); + // }} + // /> + // ); + // }, [resource, dispatch, formType, id, ruleDetails, renderAppendContent, isFetchingRuleDetail, isUpdatingRule]); + + // const renderFilterWidgetForConditionGroups = useMemo(() => { + // if (formType !== 'conditionGroup' || !id || !conditionGroupsDetails) return null; + // const disableBadgeRemove = conditionGroupsDetails.conditions.length === 1 || isFetchingConditionGroup || isUpdatingConditionGroup; + // const isBusy = isFetchingConditionGroup || isUpdatingConditionGroup; + // return ( + //
+ // + // apiClients.resources.listResourceRuleFilterFields({ + // resource, + // }) + // } + // disableBadgeRemove={disableBadgeRemove} + // onFilterUpdate={(currentFilters) => { + // const currentCondition = filterToConditionGroup(currentFilters); + // dispatch( + // rulesActions.updateConditionGroup({ + // conditionGroupUuid: id, + // conditionGroup: { + // conditions: currentCondition, + // }, + // }), + // ); + // }} + // /> + //
+ // ); + // }, [resource, dispatch, formType, id, conditionGroupsDetails, isFetchingConditionGroup, isUpdatingConditionGroup]); + + // const renderFilterWidgetForActionGroup = useMemo(() => { + // if (formType !== 'actionGroup' || !id || !actionGroupDetails) return null; + // const disableBadgeRemove = actionGroupDetails.actions.length === 1 || isFetchingActionGroup || isUpdatingActionGroup; + + // const isBusy = isFetchingActionGroup || isUpdatingActionGroup; + // return ( + //
+ // { + /* -
- ); - }, [resource, dispatch, formType, id, actionGroupDetails, isFetchingActionGroup, isUpdatingActionGroup]); + /> */ + // } + //
+ // ); + // }, [resource, dispatch, formType, id, actionGroupDetails, isFetchingActionGroup, isUpdatingActionGroup]); const renderFilterWidgetForTrigger = useMemo(() => { if (formType !== 'trigger' || !id || !trigerDetails) return null; const isActionOnlyOne = trigerDetails.actions.length === 1; - const isActionGroupEmpty = trigerDetails.actionGroups.length === 0; + // const isActionGroupEmpty = trigerDetails.actionGroups.length === 0; - const disableBadgeRemove = isActionOnlyOne && isActionGroupEmpty; + // const disableBadgeRemove = isActionOnlyOne && isActionGroupEmpty; const isBusy = isFetchingTriggerDetail || isUpdatingTrigger; return (
- { dispatch( rulesActions.updateTrigger({ @@ -242,31 +239,42 @@ const ConditionsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) }), ); }} - /> + /> */}
); - }, [resource, dispatch, formType, id, trigerDetails, renderAppendContent, isFetchingTriggerDetail, isUpdatingTrigger]); + }, [ + resource, + dispatch, + formType, + id, + trigerDetails, + + // renderAppendContent, + + isFetchingTriggerDetail, + isUpdatingTrigger, + ]); const renderWidgetConditionViewer = useMemo(() => { switch (formType) { - case 'conditionGroup': - return renderFilterWidgetForConditionGroups; - case 'rules': - return renderFilterWidgetForRules; + // case 'conditionGroup': + // return renderFilterWidgetForConditionGroups; + // case 'rules': + // return renderFilterWidgetForRules; - case 'actionGroup': - return renderFilterWidgetForActionGroup; + // case 'actionGroup': + // return renderFilterWidgetForActionGroup; - case 'trigger': - return renderFilterWidgetForTrigger; + // case 'trigger': + // return renderFilterWidgetForTrigger; default: return null; } }, [ formType, - renderFilterWidgetForConditionGroups, - renderFilterWidgetForRules, - renderFilterWidgetForActionGroup, + // renderFilterWidgetForConditionGroups, + // renderFilterWidgetForRules, + // renderFilterWidgetForActionGroup, renderFilterWidgetForTrigger, ]); diff --git a/src/components/FilterWidgetRuleAction/index.tsx b/src/components/FilterWidgetRuleAction/index.tsx index 2fe34c129..862edba07 100644 --- a/src/components/FilterWidgetRuleAction/index.tsx +++ b/src/components/FilterWidgetRuleAction/index.tsx @@ -10,8 +10,8 @@ import Select, { MultiValue, SingleValue } from 'react-select'; import { Badge, Button, Col, FormGroup, Input, Label, Row } from 'reactstrap'; import { Observable } from 'rxjs'; import { SearchFieldListModel } from 'types/certificate'; -import { FilterFieldSource, FilterFieldType, PlatformEnum, RuleActionType } from 'types/openapi'; -import { ActionRuleRequestModel } from 'types/rules'; +import { FilterFieldSource, FilterFieldType, PlatformEnum } from 'types/openapi'; +import { ExecutionItemModel, ExecutionItemRequestModel } from 'types/rules'; import styles from './FilterWidgetRuleAction.module.scss'; interface CurrentActionOptions { @@ -23,16 +23,16 @@ interface Props { title: string; entity: EntityType; getAvailableFiltersApi: (apiClients: ApiClients) => Observable>; - onActionsUpdate?: (actionRuleRequests: ActionRuleRequestModel[]) => void; + onActionsUpdate?: (actionRuleRequests: ExecutionItemModel[]) => void; appendInWidgetContent?: React.ReactNode; - actionsList?: ActionRuleRequestModel[]; + ExecutionsList?: ExecutionItemModel[]; includeIgnoreAction?: boolean; disableBadgeRemove?: boolean; busyBadges?: boolean; } export default function FilterWidgetRuleAction({ - actionsList, + ExecutionsList, onActionsUpdate, appendInWidgetContent, title, @@ -45,8 +45,8 @@ export default function FilterWidgetRuleAction({ const dispatch = useDispatch(); const searchGroupEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterFieldSource)); - const RuleActionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.RuleActionType)); - const [actions, setActions] = useState([]); + const executionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ExecutionType)); + const [actions, setActions] = useState([]); const platformEnums = useSelector(enumSelectors.platformEnums); @@ -58,7 +58,7 @@ export default function FilterWidgetRuleAction({ isEditEnabled: false, }); - const [ruleActionType, setRuleActionType] = useState | undefined>(undefined); + // const [ruleActionType, setRuleActionType] = useState | undefined>(undefined); const [fieldSource, setFieldSource] = useState | undefined>(undefined); @@ -71,16 +71,16 @@ export default function FilterWidgetRuleAction({ | undefined >(undefined); - const ruleActionsOptions = useMemo(() => { - if (includeIgnoreAction) { - return [ - { label: getEnumLabel(RuleActionTypeEnum, RuleActionType.Ignore), value: RuleActionType.Ignore }, - { label: getEnumLabel(RuleActionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }, - ]; - } else { - return [{ label: getEnumLabel(RuleActionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }]; - } - }, [includeIgnoreAction, RuleActionTypeEnum]); + // const ruleActionsOptions = useMemo(() => { + // if (includeIgnoreAction) { + // return [ + // { label: getEnumLabel(executionTypeEnum, RuleActionType.Ignore), value: RuleActionType.Ignore }, + // { label: getEnumLabel(executionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }, + // ]; + // } else { + // return [{ label: getEnumLabel(executionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }]; + // } + // }, [includeIgnoreAction, executionTypeEnum]); const booleanOptions = useMemo( () => [ @@ -104,12 +104,16 @@ export default function FilterWidgetRuleAction({ ); const onUpdateClick = useCallback(() => { - if (!ruleActionType?.value) return; - const newAction: ActionRuleRequestModel = { - actionType: ruleActionType?.value, + // if (!ruleActionType?.value) return; + if (!fieldSource?.value) return; + if (!filterField?.value) return; + if (!filterValue) return; + + const newExecution: ExecutionItemRequestModel = { + // actionType: ruleActionType?.value, fieldSource: fieldSource?.value, fieldIdentifier: filterField?.value, - actionData: filterValue + data: filterValue ? typeof filterValue === 'string' ? filterValue : Array.isArray(filterValue) @@ -117,7 +121,7 @@ export default function FilterWidgetRuleAction({ : (filterValue as any).value : undefined, }; - setRuleActionType(undefined); + // setRuleActionType(undefined); setFieldSource(undefined); setFilterField(undefined); setFilterValue(undefined); @@ -125,46 +129,46 @@ export default function FilterWidgetRuleAction({ if (selectedFilter.filterNumber === -1) { let updatedActions = []; - if (newAction.actionType === RuleActionType.Ignore) { - updatedActions = [newAction]; - } else { - updatedActions = [...actions, newAction]; - } + // if (newExecution.actionType === RuleActionType.Ignore) { + // updatedActions = [newExecution]; + // } else { + updatedActions = [...actions, newExecution]; + // } setActions(updatedActions); const updatedActionDataActions = updatedActions.map((a) => { return { - actionType: a.actionType, + // actionType: a.actionType, fieldSource: a.fieldSource, fieldIdentifier: a.fieldIdentifier, - actionData: Array.isArray(a.actionData) - ? a.actionData.map((v) => { + actionData: Array.isArray(a.data) + ? a.data.map((v) => { if (typeof v === 'object' && v.hasOwnProperty('uuid')) { return v.uuid; } return v; }) - : a.actionData, + : a.data, }; }); onActionsUpdate && onActionsUpdate(updatedActionDataActions); setSelectedFilter({ filterNumber: -1, isEditEnabled: false }); } else { - const updatedActions = actions.map((a, i) => (i === selectedFilter.filterNumber ? newAction : a)); + const updatedActions = actions.map((a, i) => (i === selectedFilter.filterNumber ? newExecution : a)); setActions(updatedActions); const updatedActionDataActions = updatedActions.map((a) => { return { - actionType: a.actionType, + // actionType: a.actionType, fieldSource: a.fieldSource, fieldIdentifier: a.fieldIdentifier, - actionData: Array.isArray(a.actionData) - ? a.actionData.map((v) => { + actionData: Array.isArray(a.data) + ? a.data.map((v) => { if (typeof v === 'object' && v.hasOwnProperty('uuid')) { return v.uuid; } return v; }) - : a.actionData, + : a.data, }; }); @@ -172,11 +176,11 @@ export default function FilterWidgetRuleAction({ setSelectedFilter({ filterNumber: -1, isEditEnabled: false }); } }, [ - ruleActionType, + // ruleActionType, fieldSource, filterField, filterValue, - setRuleActionType, + // setRuleActionType, setFieldSource, setFilterField, setFilterValue, @@ -188,7 +192,7 @@ export default function FilterWidgetRuleAction({ useEffect(() => { if (selectedFilter.filterNumber === -1) { - setRuleActionType(undefined); + // setRuleActionType(undefined); setFieldSource(undefined); setFilterField(undefined); setFilterValue(undefined); @@ -243,7 +247,7 @@ export default function FilterWidgetRuleAction({ if (selectedFilter.filterNumber === -1) return objectOptions; - const currentActionData = actions[selectedFilter.filterNumber]?.actionData; + const currentActionData = actions[selectedFilter.filterNumber]?.data; if (currentActionData === undefined) return objectOptions; const filteredOptions = objectOptions.filter((o) => { if (Array.isArray(currentActionData)) { @@ -274,8 +278,8 @@ export default function FilterWidgetRuleAction({ return; } - const selectedActionType = actions[selectedFilter.filterNumber].actionType; - setRuleActionType({ label: getEnumLabel(RuleActionTypeEnum, selectedActionType), value: selectedActionType }); + // const selectedActionType = actions[selectedFilter.filterNumber].actionType; + // setRuleActionType({ label: getEnumLabel(executionTypeEnum, selectedActionType), value: selectedActionType }); const field = actions[selectedFilter.filterNumber].fieldSource; if (!field) { @@ -304,7 +308,7 @@ export default function FilterWidgetRuleAction({ }); } - const currentActionData = actions[selectedFilter.filterNumber].actionData; + const currentActionData = actions[selectedFilter.filterNumber].data; if (currentActionData === undefined) return; if ( @@ -352,22 +356,22 @@ export default function FilterWidgetRuleAction({ setFilterValue(newFilterValue); setSelectedFilter({ filterNumber: selectedFilter.filterNumber, isEditEnabled: true }); } - }, [selectedFilter, actions, currentFields, RuleActionTypeEnum, booleanOptions, currentField, platformEnums, searchGroupEnum]); + }, [selectedFilter, actions, currentFields, executionTypeEnum, booleanOptions, currentField, platformEnums, searchGroupEnum]); useEffect(() => { - // this effect is for updating the actions when the actionsList is passed - if (!actionsList) return; + // this effect is for updating the actions when the ExecutionsList is passed + if (!ExecutionsList) return; - const isActionDataObject = actionsList.some((a) => typeof a.actionData === 'object'); + const isActionDataObject = ExecutionsList.some((a) => typeof a.data === 'object'); if (!isActionDataObject) { - setActions(actionsList); + setActions(ExecutionsList); return; } - const updatedActions = actionsList.map((action) => { - if (!(typeof action.actionData === 'object')) return action; + const updatedActions = ExecutionsList.map((action) => { + if (!(typeof action.data === 'object')) return action; - if (Array.isArray(action.actionData) && action.actionData.every((v) => typeof v === 'string')) { + if (Array.isArray(action.data) && action.data.every((v) => typeof v === 'string')) { const thisCurrentFields = availableFilters.find((f) => f.filterFieldSource === action.fieldSource)?.searchFieldData; if (!thisCurrentFields) return action; @@ -375,7 +379,7 @@ export default function FilterWidgetRuleAction({ if (!thisCurrentField || !Array.isArray(thisCurrentField.value)) return action; - const updatedActionData = action.actionData.map((v) => { + const updatedActionData = action.data.map((v) => { const value = (thisCurrentField.value as Array)?.find((f) => f.uuid === v); return value ? { uuid: value.uuid, name: value.name } : { label: v, value: v }; @@ -389,7 +393,7 @@ export default function FilterWidgetRuleAction({ }); setActions(updatedActions); - }, [actionsList, availableFilters]); + }, [ExecutionsList, availableFilters]); const renderObjectValueSelector = useMemo( () => ( { - setRuleActionType(e); + // setRuleActionType(e); setFilterValue(undefined); setFieldSource(undefined); setFilterField(undefined); }} - value={ruleActionType || null} - isDisabled={isActionTypeIgnore && !selectedFilter.isEditEnabled} + // value={ruleActionType || null} + isDisabled={!selectedFilter.isEditEnabled} /> @@ -472,7 +476,7 @@ export default function FilterWidgetRuleAction({ setFilterField(undefined); setFilterValue(undefined); }} - isDisabled={!ruleActionType?.value || ruleActionType?.value === RuleActionType.Ignore} + // isDisabled={!ruleActionType?.value || ruleActionType?.value === RuleActionType.Ignore} value={fieldSource || null} isClearable={true} /> @@ -490,7 +494,7 @@ export default function FilterWidgetRuleAction({ setFilterValue(undefined); }} value={filterField || null} - isDisabled={!fieldSource || ruleActionType?.value === RuleActionType.Ignore} + isDisabled={!fieldSource} isClearable={true} /> @@ -511,7 +515,7 @@ export default function FilterWidgetRuleAction({ setFilterValue(JSON.parse(JSON.stringify(e.target.value))); }} placeholder="Enter filter value" - disabled={!filterField || ruleActionType?.value === RuleActionType.Ignore} + disabled={!filterField} /> ) : currentField?.type === FilterFieldType.Boolean ? ( { title={submitTitle} inProgressTitle={inProgressTitle} inProgress={submitting} - disabled={ - areDefaultValuesSame(values) || - values.resource === Resource.None || - submitting || - !valid || - isBusy || - !values.conditions.length - } + // disabled={ + // areDefaultValuesSame(values) || + // values.resource === Resource.None || + // submitting || + // !valid || + // isBusy || + // !values.conditions.length + // } /> - - - -
, - ], - })); - }, [selectedTriggers, triggers, eventNameEnum, resourceTypeEnum, triggerTypeEnum]); + // const triggerTableData: TableDataRow[] = useMemo(() => { + // const triggerDataListOrderedAsPerSelectedTriggers = triggers + // .filter((trigger) => selectedTriggers.find((selectedTrigger) => selectedTrigger.value === trigger.uuid)) + // .sort( + // (a, b) => + // selectedTriggers.findIndex((selectedTrigger) => selectedTrigger.value === a.uuid) - + // selectedTriggers.findIndex((selectedTrigger) => selectedTrigger.value === b.uuid), + // ); + + // return triggerDataListOrderedAsPerSelectedTriggers.map((trigger, i) => ({ + // id: trigger.uuid, + // columns: [ + // {trigger.name}, + // getEnumLabel(resourceTypeEnum, trigger.triggerResource || ''), + // getEnumLabel(triggerTypeEnum, trigger.triggerType), + // getEnumLabel(eventNameEnum, trigger.eventName || ''), + // getEnumLabel(resourceTypeEnum, trigger.resource || ''), + // trigger.description || '', + //
+ // + // + + // + //
, + // ], + // })); + // }, [selectedTriggers, triggers, eventNameEnum, resourceTypeEnum, triggerTypeEnum]); return (
() }}> @@ -364,7 +364,7 @@ export default function DiscoveryForm() { )} - + {/*

Note: Triggers will be executed on newly discovered certificate in displayed order

@@ -378,7 +378,7 @@ export default function DiscoveryForm() { onAddClick: onUpdateTriggersConfirmed, }} /> -
+
*/} diff --git a/src/components/_pages/roles/RolePermissionsEdior/index.tsx b/src/components/_pages/roles/RolePermissionsEdior/index.tsx index 8f21d492d..17d9cfc2d 100644 --- a/src/components/_pages/roles/RolePermissionsEdior/index.tsx +++ b/src/components/_pages/roles/RolePermissionsEdior/index.tsx @@ -221,7 +221,7 @@ function RolePermissionsEditor({ } onChange={(e) => allowAction(currentResource, action.name, e.target.checked)} /> -    {action.displayName} +    {action.name} ))}
@@ -246,7 +246,7 @@ function RolePermissionsEditor({ (action) => ({ id: action.name, - content: action.displayName, + content: action.name, sortable: false, align: 'center', width: '5em', diff --git a/src/components/_pages/rules/detail/index.tsx b/src/components/_pages/rules/detail/index.tsx index d1a3ba255..cc10f73ef 100644 --- a/src/components/_pages/rules/detail/index.tsx +++ b/src/components/_pages/rules/detail/index.tsx @@ -7,7 +7,7 @@ import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Link, useParams } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { Button, ButtonGroup, Col, Container, Input, Row } from 'reactstrap'; import { PlatformEnum } from 'types/openapi'; interface SelectChangeValue { @@ -21,7 +21,7 @@ const RuleDetails = () => { const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const conditionGroups = useSelector(rulesSelectors.conditionRuleGroups); + const conditionGroups = useSelector(rulesSelectors.conditions); const [confirmDelete, setConfirmDelete] = useState(false); const [updateDescriptionEditEnable, setUpdateDescription] = useState(false); @@ -42,7 +42,7 @@ const RuleDetails = () => { }, [getFreshDetails]); useEffect(() => { - dispatch(rulesActions.listConditionGroups({ resource: ruleDetails?.resource })); + dispatch(rulesActions.listConditions({ resource: ruleDetails?.resource })); }, [ruleDetails, dispatch]); const isBusy = useMemo(() => isFetchingRuleDetail || isUpdatingRule, [isFetchingRuleDetail, isUpdatingRule]); @@ -50,13 +50,10 @@ const RuleDetails = () => { const conditionGroupsOptions = useMemo(() => { if (conditionGroups === undefined) return []; return conditionGroups - .map((conditionGroup) => { - return { value: conditionGroup.uuid, label: conditionGroup.name }; + .map((conditions) => { + return { value: conditions.uuid, label: conditions.name }; }) - .filter( - (conditionGroup) => - !ruleDetails?.conditionGroups?.map((conditionGroup) => conditionGroup.uuid).includes(conditionGroup.value), - ); + .filter((conditions) => !ruleDetails?.conditions?.map((condition) => condition.uuid).includes(conditions.value)); }, [conditionGroups, ruleDetails]); const onDeleteConfirmed = useCallback(() => { @@ -68,18 +65,18 @@ const RuleDetails = () => { const onUpdateDescriptionConfirmed = useCallback(() => { if (!id || !updateDescriptionEditEnable) return; if (updatedDescription !== ruleDetails?.description) { - dispatch( - rulesActions.updateRule({ - ruleUuid: id, - rule: { - description: updatedDescription, - conditions: ruleDetails?.conditions || [], - conditionGroupsUuids: ruleDetails?.conditionGroups?.length - ? ruleDetails?.conditionGroups.map((conditionGroup) => conditionGroup.uuid) - : [], - }, - }), - ); + // dispatch( + // rulesActions.updateRule({ + // ruleUuid: id, + // rule: { + // description: updatedDescription, + // // conditionsUuids: ruleDetails?.conditions + // conditionUuids: ruleDetails?.conditionGroups?.length + // ? ruleDetails?.conditionGroups.map((conditionGroup) => conditionGroup.uuid) + // : [], + // }, + // }), + // ); } setUpdateDescription(false); }, [dispatch, id, ruleDetails, updatedDescription, updateDescriptionEditEnable]); @@ -90,19 +87,19 @@ const RuleDetails = () => { const newConditionGroupsUuids = newValues.map((conditionGroup) => conditionGroup.value); - const previousAndNewConditionGroupsUuid = ruleDetails?.conditionGroups.map((conditionGroup) => conditionGroup.uuid); + const previousAndNewConditionGroupsUuid = ruleDetails?.conditions.map((conditionGroup) => conditionGroup.uuid); const allConditionGroups = [...(previousAndNewConditionGroupsUuid || []), ...newConditionGroupsUuids]; - dispatch( - rulesActions.updateRule({ - ruleUuid: id, - rule: { - description: ruleDetails?.description || '', - conditions: ruleDetails?.conditions || [], - conditionGroupsUuids: allConditionGroups, - }, - }), - ); + // dispatch( + // rulesActions.updateRule({ + // ruleUuid: id, + // rule: { + // description: ruleDetails?.description || '', + // conditions: ruleDetails?.conditions || [], + // conditionGroupsUuids: allConditionGroups, + // }, + // }), + // ); }, [dispatch, id, ruleDetails], ); @@ -111,21 +108,29 @@ const RuleDetails = () => { (conditionGroupUuid: string) => { if (!id) return; - const updatedConditionGroupsUuid = ruleDetails?.conditionGroups - .filter((conditionGroup) => conditionGroup.uuid !== conditionGroupUuid) - .map((conditionGroup) => conditionGroup.uuid); - dispatch( - rulesActions.updateRule({ - ruleUuid: id, - rule: { - conditions: ruleDetails?.conditions || [], - description: ruleDetails?.description || '', - conditionGroupsUuids: updatedConditionGroupsUuid, - }, - }), - ); + // const updatedConditionGroupsUuid = ruleDetails?.conditionGroups + // .filter((conditionGroup) => conditionGroup.uuid !== conditionGroupUuid) + // .map((conditionGroup) => conditionGroup.uuid); + // dispatch( + // rulesActions.updateRule({ + // ruleUuid: id, + // rule: { + // conditions: ruleDetails?.conditions || [], + // description: ruleDetails?.description || '', + // conditionGroupsUuids: updatedConditionGroupsUuid, + // }, + // }), + // ); }, - [dispatch, id, ruleDetails?.conditionGroups, ruleDetails?.conditions, ruleDetails?.description], + [ + dispatch, + id, + + // ruleDetails?.conditionGroups, + + ruleDetails?.conditions, + ruleDetails?.description, + ], ); const buttons: WidgetButtonProps[] = useMemo( @@ -246,57 +251,56 @@ const RuleDetails = () => { ], ); - const conditionGroupFieldsDataHeader = useMemo( - () => [ - { - id: 'name', - content: 'Name', - }, - { - id: 'description', - content: 'Description', - }, - { - id: 'actions', - content: 'Actions', - }, - ], - [], - ); + // const conditionGroupFieldsDataHeader = useMemo( + // () => [ + // { + // id: 'name', + // content: 'Name', + // }, + // { + // id: 'description', + // content: 'Description', + // }, + // { + // id: 'actions', + // content: 'Actions', + // }, + // ], + // [], + // ); - const conditionGroupFieldsData: TableDataRow[] = useMemo(() => { - const isDeleteDisabled = - (ruleDetails?.conditions.length === 0 && ruleDetails?.conditionGroups.length === 1) || isFetchingRuleDetail || isUpdatingRule; - const conditionGroupData = !ruleDetails?.conditionGroups.length - ? [] - : ruleDetails?.conditionGroups.map((conditionGroup) => { - return { - id: conditionGroup.uuid, - columns: [ - {conditionGroup.name} || '', - conditionGroup.description || '', - , - ], - }; - }); + // const conditionGroupFieldsData: TableDataRow[] = useMemo(() => { + // const isDeleteDisabled = ruleDetails?.conditions.length === 0 || isFetchingRuleDetail || isUpdatingRule; + // const conditionGroupData = !ruleDetails?.conditionGroups.length + // ? [] + // : ruleDetails?.conditionGroups.map((conditionGroup) => { + // return { + // id: conditionGroup.uuid, + // columns: [ + // {conditionGroup.name} || '', + // conditionGroup.description || '', + // , + // ], + // }; + // }); - return conditionGroupData; - }, [ruleDetails, isUpdatingRule, onDeleteConditionGroup, isFetchingRuleDetail]); + // return conditionGroupData; + // }, [ruleDetails, isUpdatingRule, onDeleteConditionGroup, isFetchingRuleDetail]); return ( @@ -306,7 +310,7 @@ const RuleDetails = () => { - + {/* { }} /> - + */} {ruleDetails?.resource && } diff --git a/src/components/_pages/rules/form/index.tsx b/src/components/_pages/rules/form/index.tsx index 9a5f05470..b78b3337b 100644 --- a/src/components/_pages/rules/form/index.tsx +++ b/src/components/_pages/rules/form/index.tsx @@ -15,7 +15,7 @@ import ConditionFormFilter from 'components/ConditionFormFilter'; import ProgressButton from 'components/ProgressButton'; import Select from 'react-select'; import { Resource } from 'types/openapi'; -import { RuleConditiontModel } from 'types/rules'; +import { ConditionItemModel } from 'types/rules'; import { isObjectSame } from 'utils/common-utils'; import { useRuleEvaluatorResourceOptions } from 'utils/rules'; import { composeValidators, validateAlphaNumericWithSpecialChars, validateRequired } from 'utils/validators'; @@ -31,7 +31,7 @@ export interface ConditionGroupFormValues { selectedResource?: SelectChangeValue; resource: Resource; description?: string; - conditions: RuleConditiontModel[]; + conditions: ConditionItemModel[]; conditionGroupsUuids: SelectChangeValue[]; } @@ -41,7 +41,7 @@ const ConditionGroupForm = () => { const navigate = useNavigate(); const title = 'Create Rule'; - const conditionGroups = useSelector(rulesSelectors.conditionRuleGroups); + const conditions = useSelector(rulesSelectors.conditions); const isCreatingRule = useSelector(rulesSelectors.isCreatingRule); const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); const [selectedResourceState, setSelectedResourceState] = useState(); @@ -54,15 +54,15 @@ const ConditionGroupForm = () => { ); const conditionGroupsOptions = useMemo(() => { - if (conditionGroups === undefined) return []; - return conditionGroups.map((conditionGroup) => { + if (conditions === undefined) return []; + return conditions.map((conditionGroup) => { return { value: conditionGroup.uuid, label: conditionGroup.name }; }); - }, [conditionGroups]); + }, [conditions]); useEffect(() => { if (!selectedResourceState) return; - dispatch(rulesActions.listConditionGroups({ resource: selectedResourceState.value as Resource })); + dispatch(rulesActions.listConditions({ resource: selectedResourceState.value as Resource })); }, [dispatch, selectedResourceState]); useEffect(() => { @@ -97,17 +97,17 @@ const ConditionGroupForm = () => { const onSubmit = useCallback( (values: ConditionGroupFormValues) => { if (values.resource === Resource.None) return; - dispatch( - rulesActions.createRule({ - rule: { - conditionGroupsUuids: values.conditionGroupsUuids.map((uuid) => uuid.value), - conditions: values.conditions, - description: values.description, - name: values.name, - resource: values.resource, - }, - }), - ); + // dispatch( + // rulesActions.createRule({ + // rule: { + // conditionGroupsUuids: values.conditionGroupsUuids.map((uuid) => uuid.value), + // conditions: values.conditions, + // description: values.description, + // name: values.name, + // resource: values.resource, + // }, + // }), + // ); }, [dispatch], ); diff --git a/src/components/_pages/rules/list/index.tsx b/src/components/_pages/rules/list/index.tsx index fabb3c509..974a92b89 100644 --- a/src/components/_pages/rules/list/index.tsx +++ b/src/components/_pages/rules/list/index.tsx @@ -24,7 +24,7 @@ const ConditionGroups = () => { const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); const [selectedResource, setSelectedResource] = useState(); const isFetchingList = useSelector(rulesSelectors.isFetchingRulesList); - const isDeleting = useSelector(rulesSelectors.isDeletingConditionGroup); + const isDeleting = useSelector(rulesSelectors.isDeletingRule); const [checkedRows, setCheckedRows] = useState([]); const [confirmDelete, setConfirmDelete] = useState(false); @@ -134,7 +134,7 @@ const ConditionGroups = () => { titleSize="larger" title="Rules" refreshAction={getFreshList} - busy={isBusy} + // busy={isBusy} widgetButtons={buttons} widgetInfoCard={{ title: 'Information', diff --git a/src/components/_pages/triggers/details/index.tsx b/src/components/_pages/triggers/details/index.tsx index 5d0bdd926..816ae335f 100644 --- a/src/components/_pages/triggers/details/index.tsx +++ b/src/components/_pages/triggers/details/index.tsx @@ -22,12 +22,12 @@ const TriggerDetails = () => { const eventNameEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ResourceEvent)); const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const actionGroups = useSelector(rulesSelectors.actionGroups); + const executions = useSelector(rulesSelectors.executions); const rules = useSelector(rulesSelectors.rules); const [confirmDelete, setConfirmDelete] = useState(false); const [updateDescriptionEditEnable, setUpdateDescription] = useState(false); const [updatedDescription, setUpdatedDescription] = useState(''); - const triggerTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.RuleTriggerType)); + const triggerTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.TriggerType)); useEffect(() => { if (!triggerDetails?.description || triggerDetails.uuid !== id) return; @@ -44,20 +44,20 @@ const TriggerDetails = () => { }, [getFreshDetails]); useEffect(() => { - dispatch(rulesActions.listActionGroups({ resource: triggerDetails?.resource })); + dispatch(rulesActions.listExecutions({ resource: triggerDetails?.resource })); dispatch(rulesActions.listRules({ resource: triggerDetails?.resource })); }, [triggerDetails, dispatch]); const isBusy = useMemo(() => isFetchingTriggerDetail || isUpdatingTrigger, [isFetchingTriggerDetail, isUpdatingTrigger]); const actionGroupOptions = useMemo(() => { - if (actionGroups === undefined) return []; - return actionGroups - .map((actionGroup) => { - return { value: actionGroup.uuid, label: actionGroup.name }; + if (executions === undefined) return []; + return executions + .map((execution) => { + return { value: execution.uuid, label: execution.name }; }) - .filter((actionGroup) => !triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid).includes(actionGroup.value)); - }, [actionGroups, triggerDetails]); + .filter((execution) => !triggerDetails?.actions?.map((action) => action.uuid).includes(execution.value)); + }, [executions, triggerDetails]); const rulesOptions = useMemo(() => { if (triggerDetails === undefined) return []; @@ -83,12 +83,18 @@ const TriggerDetails = () => { triggerUuid: id, trigger: { description: updatedDescription, - actions: triggerDetails?.actions || [], - actionGroupsUuids: triggerDetails?.actionGroups?.length - ? triggerDetails?.actionGroups.map((actionGroup) => actionGroup.uuid) - : [], - triggerType: triggerDetails.triggerType, + // actions: triggerDetails?.actions || [], + // actionGroupsUuids: triggerDetails?.actionGroups?.length + // ? triggerDetails?.actionGroups.map((actionGroup) => actionGroup.uuid) + // : [], + // triggerType: triggerDetails.triggerType, + ignoreTrigger: triggerDetails.ignoreTrigger, + resource: triggerDetails.resource, + type: triggerDetails.type, + actionsUuids: triggerDetails?.actions.map((action) => action.uuid) || [], rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], + // event: triggerDetails.event, + // eventResource: triggerDetails.eventResource, }, }), ); @@ -102,16 +108,16 @@ const TriggerDetails = () => { const newActionGroupsUuids = newValues.map((newActionGroup) => newActionGroup.value); - const previousAndNewActionGroupsUuid = triggerDetails?.actionGroups.map((actionGroup) => actionGroup.uuid); + const previousAndNewActionGroupsUuid = triggerDetails?.actions.map((action) => action.uuid); const allActionGroups = [...(previousAndNewActionGroupsUuid || []), ...newActionGroupsUuids]; - dispatch( rulesActions.updateTrigger({ triggerUuid: id, trigger: { - actions: triggerDetails?.actions || [], - actionGroupsUuids: allActionGroups, - triggerType: triggerDetails.triggerType, + actionsUuids: allActionGroups, + ignoreTrigger: triggerDetails.ignoreTrigger, + resource: triggerDetails.resource, + type: triggerDetails.type, rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], description: triggerDetails.description || '', }, @@ -134,10 +140,14 @@ const TriggerDetails = () => { rulesActions.updateTrigger({ triggerUuid: id, trigger: { - actions: triggerDetails?.actions || [], + // actionsUuids: triggerDetails?.actionsUuids || [], rulesUuids: allRules, - actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], - triggerType: triggerDetails.triggerType, + ignoreTrigger: triggerDetails.ignoreTrigger, + resource: triggerDetails.resource, + type: triggerDetails.type, + + // actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], + // triggerType: triggerDetails.triggerType, description: triggerDetails.description || '', }, }), @@ -150,18 +160,22 @@ const TriggerDetails = () => { (actionGroupsUuid: string) => { if (!id || !triggerDetails) return; - const updatedActionGroupsUuid = triggerDetails?.actionGroups + const updatedActionGroupsUuid = triggerDetails?.actions .filter((actionGroup) => actionGroup.uuid !== actionGroupsUuid) .map((actionGroup) => actionGroup.uuid); dispatch( rulesActions.updateTrigger({ triggerUuid: id, trigger: { - actions: triggerDetails?.actions || [], + // actions: triggerDetails?.actions || [], description: triggerDetails?.description || '', - actionGroupsUuids: updatedActionGroupsUuid, - triggerType: triggerDetails.triggerType, + // actionUuids: updatedActionGroupsUuid, + // triggerType: triggerDetails.triggerType, rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], + ignoreTrigger: triggerDetails.ignoreTrigger, + resource: triggerDetails.resource, + type: triggerDetails.type, + actionsUuids: updatedActionGroupsUuid, }, }), ); @@ -179,11 +193,14 @@ const TriggerDetails = () => { rulesActions.updateTrigger({ triggerUuid: id, trigger: { - actions: triggerDetails?.actions || [], + // actions: triggerDetails?.actions || [], rulesUuids: updatedRules, - actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], - triggerType: triggerDetails.triggerType, + // actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], + // triggerType: triggerDetails.triggerType, description: triggerDetails.description || '', + ignoreTrigger: triggerDetails.ignoreTrigger, + resource: triggerDetails.resource, + type: triggerDetails.type, }, }), ); @@ -237,16 +254,16 @@ const TriggerDetails = () => { id: 'triggerResource', columns: [ 'Trigger Resource', - triggerDetails?.triggerResource ? getEnumLabel(resourceTypeEnum, triggerDetails.triggerResource) : '', + triggerDetails?.eventResource ? getEnumLabel(resourceTypeEnum, triggerDetails.eventResource) : '', ], }, { id: 'triggerType', - columns: ['Trigger Type', getEnumLabel(triggerTypeEnum, triggerDetails.triggerType), ''], + columns: ['Trigger Type', getEnumLabel(triggerTypeEnum, triggerDetails.type), ''], }, { id: 'eventName', - columns: ['Event Name', getEnumLabel(eventNameEnum, triggerDetails.eventName || ''), ''], + columns: ['Event Name', getEnumLabel(eventNameEnum, triggerDetails.event || ''), ''], }, { id: 'resource', @@ -344,19 +361,16 @@ const TriggerDetails = () => { ); const actionGroupsFieldsData: TableDataRow[] = useMemo(() => { - const isDeleteDisabled = - (triggerDetails?.actions?.length === 0 && triggerDetails?.actionGroups?.length == 1) || - isUpdatingTrigger || - isFetchingTriggerDetail; + const isDeleteDisabled = triggerDetails?.actions?.length === 0 || isUpdatingTrigger || isFetchingTriggerDetail; - const actionGroupData = !triggerDetails?.actionGroups.length + const actionGroupData = !triggerDetails?.actions.length ? [] - : triggerDetails?.actionGroups.map((actionGroup) => { + : triggerDetails?.actions.map((action) => { return { - id: actionGroup.uuid, + id: action.uuid, columns: [ - {actionGroup.name} || '', - actionGroup.description || '', + {action.name} || '', + action.description || '', + + + ) : ( + + )} + , + ], + }, + ], + [ + actionDetails, + resourceTypeEnum, + onUpdateDescriptionConfirmed, + updateDescriptionEditEnable, + isUpdatingRule, + updatedDescription, + isFetchingRuleDetail, + ], + ); + + // const conditionGroupFieldsDataHeader = useMemo( + // () => [ + // { + // id: 'name', + // content: 'Name', + // }, + // { + // id: 'description', + // content: 'Description', + // }, + // { + // id: 'actions', + // content: 'Actions', + // }, + // ], + // [], + // ); + + // const conditionGroupFieldsData: TableDataRow[] = useMemo(() => { + // const isDeleteDisabled = actionDetails?.conditions.length === 0 || isFetchingRuleDetail || isUpdatingRule; + // const conditionGroupData = !actionDetails?.conditionGroups.length + // ? [] + // : actionDetails?.conditionGroups.map((conditionGroup) => { + // return { + // id: conditionGroup.uuid, + // columns: [ + // {conditionGroup.name} || '', + // conditionGroup.description || '', + // , + // ], + // }; + // }); + + // return conditionGroupData; + // }, [actionDetails, isUpdatingRule, onDeleteConditionGroup, isFetchingRuleDetail]); + + return ( + + + + + + + + {/* + + + + */} + + + {actionDetails?.resource && } + + setConfirmDelete(false)} + buttons={[ + { color: 'danger', onClick: onDeleteConfirmed, body: 'Yes, delete' }, + { color: 'secondary', onClick: () => setConfirmDelete(false), body: 'Cancel' }, + ]} + /> + + ); +}; + +export default RuleDetails; diff --git a/src/components/_pages/actions/detail/rulesDetail.module.scss b/src/components/_pages/actions/detail/rulesDetail.module.scss new file mode 100644 index 000000000..e07c91a7f --- /dev/null +++ b/src/components/_pages/actions/detail/rulesDetail.module.scss @@ -0,0 +1,7 @@ +@import 'src/resources/styles/app'; + +.infoIcon { + color: $czertainly-blue; + font-size: small; + font-size: 14px; +} diff --git a/src/components/_pages/actions/form/index.tsx b/src/components/_pages/actions/form/index.tsx new file mode 100644 index 000000000..8a046e1da --- /dev/null +++ b/src/components/_pages/actions/form/index.tsx @@ -0,0 +1,249 @@ +import Widget from 'components/Widget'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; +// import { EntityType, actions as filterActions } from 'ducks/filters'; +import { EntityType, actions as filterActions } from 'ducks/filters'; +import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; + +import { Field, Form } from 'react-final-form'; + +import { Form as BootstrapForm, Button, ButtonGroup, FormFeedback, FormGroup, Input, Label } from 'reactstrap'; +import { mutators } from 'utils/attributes/attributeEditorMutators'; + +import ProgressButton from 'components/ProgressButton'; +import Select from 'react-select'; +import { Resource } from 'types/openapi'; +import { isObjectSame } from 'utils/common-utils'; +import { useRuleEvaluatorResourceOptions } from 'utils/rules'; +import { composeValidators, validateAlphaNumericWithSpecialChars, validateRequired } from 'utils/validators'; +// import ConditionFormFilter from '../ConditionFormFilter'; + +interface SelectChangeValue { + value: string; + label: string; +} + +export interface actionFormValues { + name: string; + selectedResource?: SelectChangeValue; + resource: Resource; + description?: string; + executionsUuids: SelectChangeValue[]; +} + +const ActionsForm = () => { + // const { id } = useParams(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const title = 'Create Action'; + + const executions = useSelector(rulesSelectors.executions); + const isCreatingRule = useSelector(rulesSelectors.isCreatingRule); + const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); + const [selectedResourceState, setSelectedResourceState] = useState(); + const { resourceOptionsWithRuleEvaluator, isFetchingResourcesList } = useRuleEvaluatorResourceOptions(); + + const isBusy = useMemo( + () => isCreatingRule || isUpdatingRule || isFetchingResourcesList, + [isCreatingRule, isUpdatingRule, isFetchingResourcesList], + ); + + const conditionsOptions = useMemo(() => { + if (executions === undefined) return []; + return executions.map((execution) => { + return { value: execution.uuid, label: execution.name }; + }); + }, [executions]); + + useEffect(() => { + if (!selectedResourceState) return; + dispatch(rulesActions.listExecutions({ resource: selectedResourceState.value as Resource })); + }, [dispatch, selectedResourceState]); + + // useEffect(() => { + // if (!id) return; + // dispatch(rulesActions.getAction({ actionUuid: id })); + // }, [id, dispatch]); + + useEffect(() => { + return () => { + dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); + }; + }, [dispatch]); + + const defaultValues: actionFormValues = useMemo(() => { + return { + name: '', + resource: Resource.None, + selectedResource: undefined, + description: undefined, + executionsUuids: [], + }; + }, []); + + const submitTitle = 'Create'; + const inProgressTitle = 'Creating...'; + + const onCancel = useCallback(() => { + navigate(-1); + }, [navigate]); + + const onSubmit = useCallback( + (values: actionFormValues) => { + if (values.resource === Resource.None) return; + console.log('values', values); + dispatch( + rulesActions.createAction({ + action: { + description: values.description, + name: values.name, + resource: values.resource, + executionsUuids: values.executionsUuids.map((execution) => execution.value), + }, + }), + ); + }, + [dispatch], + ); + + const areDefaultValuesSame = useCallback( + (values: actionFormValues) => { + const areValuesSame = isObjectSame( + values as unknown as Record, + defaultValues as unknown as Record, + ); + return areValuesSame; + }, + [defaultValues], + ); + + return ( + + () }}> + {({ handleSubmit, pristine, submitting, values, valid, form }) => ( + + + {({ input, meta }) => ( + + + + + + {meta.error} + + )} + + + + {({ input, meta }) => ( + + + + + + {meta.error} + + )} + + + + {({ input, meta }) => ( + + + + + + )} + + {/* {values?.resource && } */} + +
+ + + + + +
+
+ )} + +
+ ); +}; + +export default ActionsForm; diff --git a/src/components/_pages/actions/list/actions-list-component/index.tsx b/src/components/_pages/actions/list/actions-list-component/index.tsx new file mode 100644 index 000000000..f49aed135 --- /dev/null +++ b/src/components/_pages/actions/list/actions-list-component/index.tsx @@ -0,0 +1,171 @@ +import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; +import { useDispatch, useSelector } from 'react-redux'; + +import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; +import Dialog from 'components/Dialog'; +import Widget from 'components/Widget'; +import { WidgetButtonProps } from 'components/WidgetButtons'; +import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import Select from 'react-select'; +import { PlatformEnum, Resource } from 'types/openapi'; + +import { useRuleEvaluatorResourceOptions } from 'utils/rules'; +import styles from './ruleList.module.scss'; + +const ActionsList = () => { + const actionsList = useSelector(rulesSelectors.actionsList); + + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); + const [selectedResource, setSelectedResource] = useState(); + const isFetchingList = useSelector(rulesSelectors.isFetchingRulesList); + const isDeleting = useSelector(rulesSelectors.isDeletingRule); + + const [checkedRows, setCheckedRows] = useState([]); + const [confirmDelete, setConfirmDelete] = useState(false); + const { resourceOptionsWithRuleEvaluator, isFetchingResourcesList } = useRuleEvaluatorResourceOptions(); + + const isBusy = useMemo( + () => isFetchingList || isDeleting || isFetchingResourcesList, + [isFetchingList, isDeleting, isFetchingResourcesList], + ); + + const onDeleteConfirmed = useCallback(() => { + dispatch(rulesActions.deleteRule({ ruleUuid: checkedRows[0] })); + setConfirmDelete(false); + setCheckedRows([]); + }, [dispatch, checkedRows]); + + const getFreshList = useCallback(() => { + dispatch(rulesActions.listActions({ resource: selectedResource })); + }, [dispatch, selectedResource]); + + useEffect(() => { + getFreshList(); + }, [getFreshList]); + + const rulesTableHeader: TableHeader[] = useMemo( + () => [ + { + content: 'Name', + align: 'left', + id: 'name', + width: '10%', + sortable: true, + }, + { + content: 'Resource', + align: 'left', + id: 'resource', + width: '10%', + sortable: true, + }, + { + content: 'Description', + align: 'left', + id: 'description', + width: '10%', + }, + ], + [], + ); + + const rulesList: TableDataRow[] = useMemo( + () => + actionsList.map((rule) => { + return { + id: rule.uuid, + columns: [ + {rule.name}, + getEnumLabel(resourceTypeEnum, rule.resource), + rule.description || '', + ], + }; + }), + [actionsList, resourceTypeEnum], + ); + + const buttons: WidgetButtonProps[] = useMemo( + () => [ + { + icon: 'search', + disabled: false, + tooltip: 'Select Resource', + onClick: () => {}, + custom: ( +
+ { - setSelectedResource(event?.value as Resource); - }} - /> -
- ), - }, - { - icon: 'plus', - disabled: false, - tooltip: 'Create', - onClick: () => navigate(`./add`), - }, - { - icon: 'trash', - disabled: checkedRows.length === 0, - tooltip: 'Delete', - onClick: () => setConfirmDelete(true), - }, - ], - [checkedRows, resourceOptionsWithRuleEvaluator, navigate], - ); + if (tabIndex && parseInt(tabIndex) <= 1) { + setActiveTab(parseInt(tabIndex)); + } + }, [tabIndex]); return ( - -
- { - setCheckedRows(checkedRows as string[]); - }} - hasPagination={true} + <> + , + onClick: () => setActiveTab(0), + }, + { + title: 'Conditions', + content: , + onClick: () => setActiveTab(1), + }, + ]} /> -
- - setConfirmDelete(false)} - buttons={[ - { color: 'danger', onClick: onDeleteConfirmed, body: 'Yes, delete' }, - { color: 'secondary', onClick: () => setConfirmDelete(false), body: 'Cancel' }, - ]} - /> +
); }; -export default ConditionGroups; +export default RulesList; diff --git a/src/components/_pages/rules/list/rules-list-component/index.tsx b/src/components/_pages/rules/list/rules-list-component/index.tsx new file mode 100644 index 000000000..9d5de3b9b --- /dev/null +++ b/src/components/_pages/rules/list/rules-list-component/index.tsx @@ -0,0 +1,172 @@ +import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; +import { useDispatch, useSelector } from 'react-redux'; + +import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; +import Dialog from 'components/Dialog'; +import Widget from 'components/Widget'; +import { WidgetButtonProps } from 'components/WidgetButtons'; +import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import Select from 'react-select'; +import { PlatformEnum, Resource } from 'types/openapi'; + +import { useRuleEvaluatorResourceOptions } from 'utils/rules'; +import styles from './ruleList.module.scss'; + +const ConditionGroups = () => { + const rules = useSelector(rulesSelectors.rules); + + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); + const [selectedResource, setSelectedResource] = useState(); + const isFetchingList = useSelector(rulesSelectors.isFetchingRulesList); + const isDeleting = useSelector(rulesSelectors.isDeletingRule); + + const [checkedRows, setCheckedRows] = useState([]); + const [confirmDelete, setConfirmDelete] = useState(false); + const { resourceOptionsWithRuleEvaluator, isFetchingResourcesList } = useRuleEvaluatorResourceOptions(); + + const isBusy = useMemo( + () => isFetchingList || isDeleting || isFetchingResourcesList, + [isFetchingList, isDeleting, isFetchingResourcesList], + ); + + const onDeleteConfirmed = useCallback(() => { + dispatch(rulesActions.deleteRule({ ruleUuid: checkedRows[0] })); + setConfirmDelete(false); + setCheckedRows([]); + }, [dispatch, checkedRows]); + + const getFreshList = useCallback(() => { + dispatch(rulesActions.listRules({ resource: selectedResource })); + }, [dispatch, selectedResource]); + + useEffect(() => { + getFreshList(); + }, [getFreshList]); + + const rulesTableHeader: TableHeader[] = useMemo( + () => [ + { + content: 'Name', + align: 'left', + id: 'name', + width: '10%', + sortable: true, + }, + { + content: 'Resource', + align: 'left', + id: 'resource', + width: '10%', + sortable: true, + }, + { + content: 'Description', + align: 'left', + id: 'description', + width: '10%', + }, + ], + [], + ); + + const rulesList: TableDataRow[] = useMemo( + () => + rules.map((rule) => { + return { + id: rule.uuid, + columns: [ + {rule.name}, + getEnumLabel(resourceTypeEnum, rule.resource), + rule.description || '', + ], + }; + }), + [rules, resourceTypeEnum], + ); + + const buttons: WidgetButtonProps[] = useMemo( + () => [ + { + icon: 'search', + disabled: false, + tooltip: 'Select Resource', + onClick: () => {}, + custom: ( +
+ { - if (event.target) { - const isChecked = (event.target as HTMLInputElement).checked; - if (isChecked) { - form.change('actionsUuids', []); - // form.change('rulesUuids', []); - } - } - }} - /> -
- - )} - - {({ input, meta }) => ( @@ -335,14 +300,14 @@ const TriggerForm = () => { {({ input, meta }) => ( - + { + if (event.target) { + const isChecked = (event.target as HTMLInputElement).checked; + if (isChecked) { + form.change('actionsUuids', []); + } + } + }} + /> + + + )} + + {({ input, meta }) => ( diff --git a/src/ducks/rules-epics.ts b/src/ducks/rules-epics.ts index 53fb33578..7446f4997 100644 --- a/src/ducks/rules-epics.ts +++ b/src/ducks/rules-epics.ts @@ -7,8 +7,11 @@ import { actions as alertActions } from './alerts'; import { actions as appRedirectActions } from './app-redirect'; import * as slice from './rules'; +import { transformActionDtoToModel } from './transform/auth'; import { tranformExecutionRequestModelToDto, + transformActionDetailDtoToModel, + transformActionRequestModelToDto, transformConditionDtoToModel, transformConditionRequestModelToDto, transformExecutionDtoToModel, @@ -18,6 +21,7 @@ import { transformTriggerDetailDtoToModel, transformTriggerDtoToModel, transformTriggerRequestModelToDto, + transformUpdateActionRequestModelToDto, transformUpdateConditionRequestModelToDto, transformUpdateExecutionRequestModelToDto, transformUpdateRuleRequestModelToDto, @@ -31,7 +35,12 @@ const listRules: AppEpic = (action$, state, deps) => { deps.apiClients.rules.listRules({ resource: action.payload.resource }).pipe( switchMap((rules) => of(slice.actions.listRulesSuccess({ rules: rules.map((rule) => transformRuleDtoToModel(rule)) }))), - catchError((err) => of(slice.actions.listRulesFailure({ error: extractError(err, 'Failed to get rules list') }))), + catchError((err) => + of( + slice.actions.listRulesFailure({ error: extractError(err, 'Failed to get rules list') }), + alertActions.error(extractError(err, 'Failed to get rules list')), + ), + ), ), ), ); @@ -49,7 +58,30 @@ const listExecutions: AppEpic = (action$, state, deps) => { }), ), ), - catchError((err) => of(slice.actions.listExecutionsFailure({ error: extractError(err, 'Failed to get Executions list') }))), + catchError((err) => + of( + slice.actions.listExecutionsFailure({ error: extractError(err, 'Failed to get Executions list') }), + alertActions.error(extractError(err, 'Failed to get Executions list')), + ), + ), + ), + ), + ); +}; + +const listActions: AppEpic = (action$, state, deps) => { + return action$.pipe( + filter(slice.actions.listActions.match), + switchMap((action) => + deps.apiClients.actions.listActions({ resource: action.payload.resource }).pipe( + switchMap((actions) => + of( + slice.actions.listActionsSuccess({ + actionsList: actions.map((action) => transformActionDtoToModel(action)), + }), + ), + ), + catchError((err) => of(slice.actions.listActionsFailure({ error: extractError(err, 'Failed to get actions list') }))), ), ), ); @@ -67,7 +99,12 @@ const listConditions: AppEpic = (action$, state, deps) => { }), ), ), - catchError((err) => of(slice.actions.listConditionsFailure({ error: extractError(err, 'Failed to get conditions list') }))), + catchError((err) => + of( + slice.actions.listConditionsFailure({ error: extractError(err, 'Failed to get conditions list') }), + alertActions.error(extractError(err, 'Failed to get conditions list')), + ), + ), ), ), ); @@ -85,7 +122,12 @@ const listTriggers: AppEpic = (action$, state, deps) => { }), ), ), - catchError((err) => of(slice.actions.listTriggersFailure({ error: extractError(err, 'Failed to get triggers list') }))), + catchError((err) => + of( + slice.actions.listTriggersFailure({ error: extractError(err, 'Failed to get triggers list') }), + alertActions.error(extractError(err, 'Failed to get triggers list')), + ), + ), ), ), ); @@ -107,9 +149,34 @@ const createExecution: AppEpic = (action$, state, deps) => { ), ), catchError((err) => - of(slice.actions.createExecutionFailure({ error: extractError(err, 'Failed to create Execution') })), + of( + slice.actions.createExecutionFailure({ error: extractError(err, 'Failed to create Execution') }), + alertActions.error(extractError(err, 'Failed to create Execution')), + ), + ), + ), + ), + ); +}; + +const createAction: AppEpic = (action$, state, deps) => { + return action$.pipe( + filter(slice.actions.createAction.match), + switchMap((action) => + deps.apiClients.actions.createAction({ actionRequestDto: transformActionRequestModelToDto(action.payload.action) }).pipe( + switchMap((action) => + of( + slice.actions.createActionSuccess({ action: transformActionDetailDtoToModel(action) }), + appRedirectActions.redirect({ url: `../actions/detail/${action.uuid}` }), + ), + ), + catchError((err) => + of( + slice.actions.createActionFailure({ error: extractError(err, 'Failed to create action') }), + alertActions.error(extractError(err, 'Failed to create action')), ), ), + ), ), ); }; @@ -132,7 +199,10 @@ const createCondition: AppEpic = (action$, state, deps) => { ), ), catchError((err) => - of(slice.actions.createConditionFailure({ error: extractError(err, 'Failed to create condition') })), + of( + slice.actions.createConditionFailure({ error: extractError(err, 'Failed to create condition') }), + alertActions.error(extractError(err, 'Failed to create condition')), + ), ), ), ), @@ -149,7 +219,12 @@ const createRule: AppEpic = (action$, state, deps) => { appRedirectActions.redirect({ url: `../rules/detail/${rule.uuid}` }), ), ), - catchError((err) => of(slice.actions.createRuleFailure({ error: extractError(err, 'Failed to create rule') }))), + catchError((err) => + of( + slice.actions.createRuleFailure({ error: extractError(err, 'Failed to create rule') }), + alertActions.error(extractError(err, 'Failed to create rule')), + ), + ), ), ), ); @@ -169,7 +244,6 @@ const createTrigger: AppEpic = (action$, state, deps) => { catchError((err) => of( slice.actions.createTriggerFailure({ error: extractError(err, 'Failed to create trigger') }), - alertActions.error(extractError(err, 'Failed to create trigger')), ), ), @@ -186,10 +260,15 @@ const deleteExecution: AppEpic = (action$, state, deps) => { switchMap(() => of( slice.actions.deleteExecutionSuccess({ executionUuid: action.payload.executionUuid }), - appRedirectActions.redirect({ url: `../../executions` }), + appRedirectActions.redirect({ url: `../../actions` }), + ), + ), + catchError((err) => + of( + slice.actions.deleteExecutionFailure({ error: extractError(err, 'Failed to delete Execution') }), + alertActions.error(extractError(err, 'Failed to delete Execution')), ), ), - catchError((err) => of(slice.actions.deleteExecutionFailure({ error: extractError(err, 'Failed to delete Execution') }))), ), ), ); @@ -203,10 +282,15 @@ const deleteCondition: AppEpic = (action$, state, deps) => { switchMap(() => of( slice.actions.deleteConditionSuccess({ conditionUuid: action.payload.conditionUuid }), - appRedirectActions.redirect({ url: `../../conditions` }), + appRedirectActions.redirect({ url: `../../rules` }), + ), + ), + catchError((err) => + of( + slice.actions.deleteConditionFailure({ error: extractError(err, 'Failed to delete condition') }), + alertActions.error(extractError(err, 'Failed to delete condition')), ), ), - catchError((err) => of(slice.actions.deleteConditionFailure({ error: extractError(err, 'Failed to delete condition') }))), ), ), ); @@ -223,7 +307,12 @@ const deleteRule: AppEpic = (action$, state, deps) => { appRedirectActions.redirect({ url: `../rules` }), ), ), - catchError((err) => of(slice.actions.deleteRuleFailure({ error: extractError(err, 'Failed to delete rule') }))), + catchError((err) => + of( + slice.actions.deleteRuleFailure({ error: extractError(err, 'Failed to delete rule') }), + alertActions.error(extractError(err, 'Failed to delete rule')), + ), + ), ), ), ); @@ -240,7 +329,12 @@ const deleteTrigger: AppEpic = (action$, state, deps) => { appRedirectActions.redirect({ url: `../../triggers` }), ), ), - catchError((err) => of(slice.actions.deleteTriggerFailure({ error: extractError(err, 'Failed to delete trigger') }))), + catchError((err) => + of( + slice.actions.deleteTriggerFailure({ error: extractError(err, 'Failed to delete trigger') }), + alertActions.error(extractError(err, 'Failed to delete trigger')), + ), + ), ), ), ); @@ -252,7 +346,29 @@ const getExecution: AppEpic = (action$, state, deps) => { switchMap((action) => deps.apiClients.actions.getExecution({ executionUuid: action.payload.executionUuid }).pipe( switchMap((actionGroup) => of(slice.actions.getExecutionSuccess({ execution: transformExecutionDtoToModel(actionGroup) }))), - catchError((err) => of(slice.actions.getExecutionFailure({ error: extractError(err, 'Failed to get Execution') }))), + catchError((err) => + of( + (slice.actions.getExecutionFailure({ error: extractError(err, 'Failed to get Execution') }), + alertActions.error(extractError(err, 'Failed to get Execution'))), + ), + ), + ), + ), + ); +}; + +const getAction: AppEpic = (action$, state, deps) => { + return action$.pipe( + filter(slice.actions.getAction.match), + switchMap((action) => + deps.apiClients.actions.getAction({ actionUuid: action.payload.actionUuid }).pipe( + switchMap((actionGroup) => of(slice.actions.getActionSuccess({ action: transformActionDetailDtoToModel(actionGroup) }))), + catchError((err) => + of( + slice.actions.getActionFailure({ error: extractError(err, 'Failed to get Action') }), + alertActions.error(extractError(err, 'Failed to get Action')), + ), + ), ), ), ); @@ -270,7 +386,12 @@ const getCondition: AppEpic = (action$, state, deps) => { }), ), ), - catchError((err) => of(slice.actions.getConditionFailure({ error: extractError(err, 'Failed to get Condition') }))), + catchError((err) => + of( + slice.actions.getConditionFailure({ error: extractError(err, 'Failed to get Condition') }), + alertActions.error(extractError(err, 'Failed to get Condition')), + ), + ), ), ), ); @@ -282,7 +403,12 @@ const getRule: AppEpic = (action$, state, deps) => { switchMap((action) => deps.apiClients.rules.getRule({ ruleUuid: action.payload.ruleUuid }).pipe( switchMap((rule) => of(slice.actions.getRuleSuccess({ rule: transformRuleDetailDtoToModel(rule) }))), - catchError((err) => of(slice.actions.getRuleFailure({ error: extractError(err, 'Failed to get rule') }))), + catchError((err) => + of( + slice.actions.getRuleFailure({ error: extractError(err, 'Failed to get rule') }), + alertActions.error(extractError(err, 'Failed to get rule')), + ), + ), ), ), ); @@ -294,7 +420,12 @@ const getTrigger: AppEpic = (action$, state, deps) => { switchMap((action) => deps.apiClients.triggers.getTrigger({ triggerUuid: action.payload.triggerUuid }).pipe( switchMap((trigger) => of(slice.actions.getTriggerSuccess({ trigger: transformTriggerDetailDtoToModel(trigger) }))), - catchError((err) => of(slice.actions.getTriggerFailure({ error: extractError(err, 'Failed to get trigger') }))), + catchError((err) => + of( + slice.actions.getTriggerFailure({ error: extractError(err, 'Failed to get trigger') }), + alertActions.error(extractError(err, 'Failed to get trigger')), + ), + ), ), ), ); @@ -329,6 +460,36 @@ const updateExecution: AppEpic = (action$, state, deps) => { ); }; +const updateAction: AppEpic = (action$, state, deps) => { + return action$.pipe( + filter(slice.actions.updateAction.match), + switchMap((action) => + deps.apiClients.actions + .updateAction({ + actionUuid: action.payload.actionUuid, + updateActionRequestDto: transformUpdateActionRequestModelToDto(action.payload.action), + }) + .pipe( + switchMap((action) => + of( + slice.actions.updateActionSuccess({ + action: transformActionDetailDtoToModel(action), + }), + appRedirectActions.redirect({ url: `../actions/detail/${action.uuid}` }), + ), + ), + catchError((err) => + of( + slice.actions.updateActionFailure({ error: extractError(err, 'Failed to update action group') }), + alertActions.error(extractError(err, 'Failed to update action group')), + slice.actions.getAction({ actionUuid: action.payload.actionUuid }), + ), + ), + ), + ), + ); +}; + const updateCondition: AppEpic = (action$, state, deps) => { return action$.pipe( filter(slice.actions.updateCondition.match), @@ -415,18 +576,22 @@ const epics = [ listExecutions, listConditions, listTriggers, + listActions, createExecution, createCondition, createRule, + createAction, createTrigger, deleteExecution, deleteCondition, deleteRule, deleteTrigger, getExecution, + getAction, getCondition, getRule, getTrigger, + updateAction, updateExecution, updateCondition, updateRule, diff --git a/src/ducks/rules.ts b/src/ducks/rules.ts index bf2fc9503..142711b23 100644 --- a/src/ducks/rules.ts +++ b/src/ducks/rules.ts @@ -1,6 +1,9 @@ import { createSelector, createSlice, PayloadAction } from '@reduxjs/toolkit'; import { Resource } from 'types/openapi'; import { + ActionDetailModel, + ActionModel, + ActionRequestModel, ConditionModel, ConditionRequestModel, ExecutionModel, @@ -11,6 +14,7 @@ import { TriggerDetailModel, TriggerModel, TriggerRequestDto, + UpdateActionRequestModel, UpdateConditionRequestModel, UpdateExecutionRequestModel, UpdateRuleRequestModel, @@ -23,6 +27,9 @@ export type State = { ruleDetails?: RuleDetailModel; executions: ExecutionModel[]; ExecutionDetails?: ExecutionModel; + actionsList: ActionModel[]; + actionDetails?: ActionDetailModel; + conditions: ConditionModel[]; conditionDetails?: ConditionModel; triggers: TriggerModel[]; @@ -33,6 +40,8 @@ export type State = { isFetchingExecutions: boolean; isFetchingConditions: boolean; isFetchingTriggers: boolean; + isCreatingAction: boolean; + isFetchingActionDetail: boolean; isFetchingRuleDetail: boolean; isFetchingExecutionDetails: boolean; isFetchingCondition: boolean; @@ -47,14 +56,18 @@ export type State = { isDeletingTrigger: boolean; isUpdatingCondition: boolean; isUpdatingRule: boolean; + isUpdatingAction: boolean; isUpdatingTrigger: boolean; + isFetchingActions: boolean; }; export const initialState: State = { rules: [], executions: [], conditions: [], + actionsList: [], triggers: [], + isFetchingRulesList: false, isFetchingExecutions: false, isFetchingExecutionDetails: false, @@ -68,6 +81,7 @@ export const initialState: State = { isUpdatingExecution: false, isCreatingExecution: false, + isCreatingAction: false, isDeletingExecution: false, isCreatingCondition: false, isDeletingCondition: false, @@ -76,7 +90,10 @@ export const initialState: State = { isUpdatingCondition: false, isUpdatingRule: false, isUpdatingTrigger: false, + isUpdatingAction: false, isDeletingRule: false, + isFetchingActions: false, + isFetchingActionDetail: false, }; export const slice = createSlice({ @@ -117,6 +134,19 @@ export const slice = createSlice({ state.isFetchingExecutions = false; }, + listActions: (state, action: PayloadAction<{ resource?: Resource }>) => { + state.isFetchingActions = true; + }, + + listActionsSuccess: (state, action: PayloadAction<{ actionsList: ActionModel[] }>) => { + state.actionsList = action.payload.actionsList; + state.isFetchingActions = false; + }, + + listActionsFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { + state.isFetchingActions = false; + }, + listConditions: (state, action: PayloadAction<{ resource?: Resource }>) => { state.isFetchingConditions = true; }, @@ -154,6 +184,19 @@ export const slice = createSlice({ state.isCreatingExecution = false; }, + createAction: (state, action: PayloadAction<{ action: ActionRequestModel }>) => { + state.isCreatingAction = true; + }, + + createActionSuccess: (state, action: PayloadAction<{ action: ActionModel }>) => { + state.actionsList.push(action.payload.action); + state.isCreatingAction = false; + }, + + createActionFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { + state.isCreatingAction = false; + }, + createCondition: (state, action: PayloadAction<{ conditionRequestModel: ConditionRequestModel }>) => { state.isCreatingCondition = true; }, @@ -249,6 +292,19 @@ export const slice = createSlice({ state.isFetchingExecutionDetails = false; }, + getAction: (state, action: PayloadAction<{ actionUuid: string }>) => { + state.isFetchingActionDetail = true; + }, + + getActionSuccess: (state, action: PayloadAction<{ action: ActionDetailModel }>) => { + state.actionDetails = action.payload.action; + state.isFetchingActionDetail = false; + }, + + getActionFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { + state.isFetchingActionDetail = false; + }, + getCondition: (state, action: PayloadAction<{ conditionUuid: string }>) => { state.isFetchingCondition = true; }, @@ -301,6 +357,26 @@ export const slice = createSlice({ state.isUpdatingExecution = false; }, + updateAction: (state, action: PayloadAction<{ actionUuid: string; action: UpdateActionRequestModel }>) => { + state.isUpdatingAction = true; + }, + + updateActionSuccess: (state, action: PayloadAction<{ action: ActionDetailModel }>) => { + state.actionsList = state.actionsList.map((group) => + group.uuid === action.payload.action.uuid ? action.payload.action : group, + ); + + if (state.actionDetails?.uuid === action.payload.action.uuid) { + state.actionDetails = action.payload.action; + } + + state.isUpdatingAction = false; + }, + + updateActionFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { + state.isUpdatingAction = false; + }, + updateCondition: (state, action: PayloadAction<{ conditionUuid: string; condition: UpdateConditionRequestModel }>) => { state.isUpdatingCondition = true; }, @@ -357,11 +433,17 @@ export const slice = createSlice({ const state = createFeatureSelector(slice.name); const rules = createSelector(state, (state) => state.rules); -const conditionDetails = createSelector(state, (state) => state.conditionDetails); const ruleDetails = createSelector(state, (state) => state.ruleDetails); + +const conditions = createSelector(state, (state) => state.conditions); +const conditionDetails = createSelector(state, (state) => state.conditionDetails); + const triggerDetails = createSelector(state, (state) => state.triggerDetails); const triggers = createSelector(state, (state) => state.triggers); +const actionsList = createSelector(state, (state) => state.actionsList); +const actionDetails = createSelector(state, (state) => state.actionDetails); + const executions = createSelector(state, (state) => state.executions); const ExecutionDetails = createSelector(state, (state) => state.ExecutionDetails); @@ -372,7 +454,6 @@ const isCreatingRule = createSelector(state, (state) => state.isCreatingRule); const isUpdatingRule = createSelector(state, (state) => state.isUpdatingRule); const isDeletingRule = createSelector(state, (state) => state.isDeletingRule); const isFetchingRulesList = createSelector(state, (state) => state.isFetchingRulesList); -const conditions = createSelector(state, (state) => state.conditions); const isFetchingConditions = createSelector(state, (state) => state.isFetchingConditions); const isDeletingCondition = createSelector(state, (state) => state.isDeletingCondition); const isFetchingCondition = createSelector(state, (state) => state.isFetchingCondition); @@ -395,6 +476,9 @@ export const selectors = { conditions, conditionDetails, executions, + actionDetails, + actionsList, + ExecutionDetails, ruleDetails, isDeletingRule, diff --git a/src/ducks/transform/rules.ts b/src/ducks/transform/rules.ts index 33aa34e93..3456555f8 100644 --- a/src/ducks/transform/rules.ts +++ b/src/ducks/transform/rules.ts @@ -1,6 +1,10 @@ import { + ActionDetailDto, + ActionDetailModel, ActionDto, ActionModel, + ActionRequestDto, + ActionRequestModel, ConditionDto, ConditionItemDto, ConditionItemModel, @@ -29,6 +33,8 @@ import { TriggerModel, TriggerRequestDto, TriggerRequestModel, + UpdateActionRequestDto, + UpdateActionRequestModel, UpdateConditionRequestDto, UpdateConditionRequestModel, UpdateExecutionRequestDto, @@ -172,3 +178,21 @@ export function transformUpdateRuleRequestModelToDto(updateRuleRequestModel: Upd ...updateRuleRequestModel, }; } + +export function transformActionRequestModelToDto(actionRequestModel: ActionRequestModel): ActionRequestDto { + return { + ...actionRequestModel, + }; +} + +export function transformActionDetailDtoToModel(actionDetailDto: ActionDetailDto): ActionDetailModel { + return { + ...actionDetailDto, + }; +} + +export function transformUpdateActionRequestModelToDto(updateActionRequestModel: UpdateActionRequestModel): UpdateActionRequestDto { + return { + ...updateActionRequestModel, + }; +} diff --git a/src/types/rules.ts b/src/types/rules.ts index cc6bcdcdf..f920e6525 100644 --- a/src/types/rules.ts +++ b/src/types/rules.ts @@ -17,6 +17,7 @@ import type { TriggerDetailDto as TriggerDetailDtoApi, TriggerDto as TriggerDtoApi, TriggerRequestDto as TriggerRequestDtoApi, + UpdateActionRequestDto as UpdateActionRequestDtoApi, UpdateConditionRequestDto as UpdateConditionRequestDtoApi, UpdateExecutionRequestDto as UpdateExecutionRequestDtoApi, UpdateRuleRequestDto as UpdateRuleRequestDtoApi, @@ -107,3 +108,6 @@ export type ActionDetailDto = ActionDetailDtoApi; export type ActionDetailModel = Omit & { executions: Array; }; + +export type UpdateActionRequestDto = UpdateActionRequestDtoApi; +export type UpdateActionRequestModel = UpdateActionRequestDto; From 5d325dddb66e6c3cae1ce6b41e4ab57ffdbd712a Mon Sep 17 00:00:00 2001 From: Abhijit Bansode Date: Sun, 26 May 2024 15:37:47 +0530 Subject: [PATCH 4/8] fixed forms cancels , tabs view, list fixes columns addded , busy spinner for forms , list --- .../_pages/actions/detail/index.tsx | 7 ++-- src/components/_pages/actions/form/index.tsx | 17 ++------ .../list/actions-list-component/index.tsx | 13 +++--- .../list/executions-list-component/index.tsx | 40 ++++++++++++------- .../_pages/conditions/details/index.tsx | 1 + .../_pages/conditions/form/index.tsx | 16 +------- .../_pages/executions/details/index.tsx | 11 ++--- .../_pages/executions/form/index.tsx | 2 +- src/components/_pages/rules/detail/index.tsx | 7 ++-- src/components/_pages/rules/form/index.tsx | 17 ++------ ....module.scss => conditionList.module.scss} | 0 .../list/conditions-list-component/index.tsx | 37 ++++++++++------- .../rules/list/rules-list-component/index.tsx | 18 ++++----- .../_pages/triggers/details/index.tsx | 1 + src/components/_pages/triggers/form/index.tsx | 4 +- src/components/_pages/triggers/list/index.tsx | 14 +++---- src/ducks/rules-epics.ts | 29 ++++++++++++-- src/ducks/rules.ts | 18 +++++++++ 18 files changed, 143 insertions(+), 109 deletions(-) rename src/components/_pages/rules/list/conditions-list-component/{conditionGroupsList.module.scss => conditionList.module.scss} (100%) diff --git a/src/components/_pages/actions/detail/index.tsx b/src/components/_pages/actions/detail/index.tsx index ca8c60300..dee480e99 100644 --- a/src/components/_pages/actions/detail/index.tsx +++ b/src/components/_pages/actions/detail/index.tsx @@ -58,7 +58,7 @@ const RuleDetails = () => { const onDeleteConfirmed = useCallback(() => { if (!id) return; - dispatch(rulesActions.deleteRule({ ruleUuid: id })); + dispatch(rulesActions.deleteAction({ actionUuid: id })); setConfirmDelete(false); }, [dispatch, id]); @@ -157,6 +157,7 @@ const RuleDetails = () => { { id: 'actions', content: 'Actions', + align: 'center', }, ], [], @@ -338,8 +339,8 @@ const RuleDetails = () => { setConfirmDelete(false)} buttons={[ { color: 'danger', onClick: onDeleteConfirmed, body: 'Yes, delete' }, diff --git a/src/components/_pages/actions/form/index.tsx b/src/components/_pages/actions/form/index.tsx index 8a046e1da..99d3ba8c0 100644 --- a/src/components/_pages/actions/form/index.tsx +++ b/src/components/_pages/actions/form/index.tsx @@ -40,16 +40,12 @@ const ActionsForm = () => { const executions = useSelector(rulesSelectors.executions); const isCreatingRule = useSelector(rulesSelectors.isCreatingRule); - const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); const [selectedResourceState, setSelectedResourceState] = useState(); const { resourceOptionsWithRuleEvaluator, isFetchingResourcesList } = useRuleEvaluatorResourceOptions(); - const isBusy = useMemo( - () => isCreatingRule || isUpdatingRule || isFetchingResourcesList, - [isCreatingRule, isUpdatingRule, isFetchingResourcesList], - ); + const isBusy = useMemo(() => isCreatingRule || isFetchingResourcesList, [isCreatingRule, isFetchingResourcesList]); - const conditionsOptions = useMemo(() => { + const executionsOptions = useMemo(() => { if (executions === undefined) return []; return executions.map((execution) => { return { value: execution.uuid, label: execution.name }; @@ -61,11 +57,6 @@ const ActionsForm = () => { dispatch(rulesActions.listExecutions({ resource: selectedResourceState.value as Resource })); }, [dispatch, selectedResourceState]); - // useEffect(() => { - // if (!id) return; - // dispatch(rulesActions.getAction({ actionUuid: id })); - // }, [id, dispatch]); - useEffect(() => { return () => { dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); @@ -86,7 +77,7 @@ const ActionsForm = () => { const inProgressTitle = 'Creating...'; const onCancel = useCallback(() => { - navigate(-1); + navigate('../actions'); }, [navigate]); const onSubmit = useCallback( @@ -208,7 +199,7 @@ const ActionsForm = () => { { const conditions = useSelector(rulesSelectors.conditions); @@ -20,6 +20,7 @@ const ConditionsList = () => { const navigate = useNavigate(); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); + const conditionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ConditionType)); const [selectedResource, setSelectedResource] = useState(); const isFetchingList = useSelector(rulesSelectors.isFetchingConditions); const isDeleting = useSelector(rulesSelectors.isDeletingCondition); @@ -47,7 +48,7 @@ const ConditionsList = () => { getFreshListConditionGroups(); }, [getFreshListConditionGroups]); - const conditionGroupsRowHeaders: TableHeader[] = useMemo( + const conditionDataHeaders: TableHeader[] = useMemo( () => [ { content: 'Name', @@ -56,6 +57,12 @@ const ConditionsList = () => { width: '10%', sortable: true, }, + { + content: 'Type', + align: 'left', + id: 'type', + width: '10%', + }, { content: 'Resource', align: 'left', @@ -73,15 +80,16 @@ const ConditionsList = () => { [], ); - const conditionGroupList: TableDataRow[] = useMemo( + const conditionsData: TableDataRow[] = useMemo( () => - conditions.map((conditionGroup) => { + conditions.map((condition) => { return { - id: conditionGroup.uuid, + id: condition.uuid, columns: [ - {conditionGroup.name}, - getEnumLabel(resourceTypeEnum, conditionGroup.resource), - conditionGroup.description || '', + {condition.name}, + getEnumLabel(conditionTypeEnum, condition.type), + getEnumLabel(resourceTypeEnum, condition.resource), + condition.description || '', ], }; }), @@ -132,20 +140,21 @@ const ConditionsList = () => { titleSize="larger" title="Conditions" refreshAction={getFreshListConditionGroups} - // busy={isBusy} + busy={isBusy} widgetButtons={buttons} widgetInfoCard={{ title: 'Information', - description: 'Condition is named set of conditions for selected resource that can be reused in rules of same resource', + description: 'Condition is named set of conditions items', }} > +
{ setCheckedRows(checkedRows as string[]); }} @@ -155,8 +164,8 @@ const ConditionsList = () => { setConfirmDelete(false)} buttons={[ { color: 'danger', onClick: onDeleteConfirmed, body: 'Yes, delete' }, diff --git a/src/components/_pages/rules/list/rules-list-component/index.tsx b/src/components/_pages/rules/list/rules-list-component/index.tsx index 9d5de3b9b..bcd5ae7c9 100644 --- a/src/components/_pages/rules/list/rules-list-component/index.tsx +++ b/src/components/_pages/rules/list/rules-list-component/index.tsx @@ -14,7 +14,7 @@ import { PlatformEnum, Resource } from 'types/openapi'; import { useRuleEvaluatorResourceOptions } from 'utils/rules'; import styles from './ruleList.module.scss'; -const ConditionGroups = () => { +const RulesList = () => { const rules = useSelector(rulesSelectors.rules); const dispatch = useDispatch(); @@ -48,7 +48,7 @@ const ConditionGroups = () => { getFreshList(); }, [getFreshList]); - const rulesTableHeader: TableHeader[] = useMemo( + const rulesHeader: TableHeader[] = useMemo( () => [ { content: 'Name', @@ -74,7 +74,7 @@ const ConditionGroups = () => { [], ); - const rulesList: TableDataRow[] = useMemo( + const rulesData: TableDataRow[] = useMemo( () => rules.map((rule) => { return { @@ -115,7 +115,7 @@ const ConditionGroups = () => { icon: 'plus', disabled: false, tooltip: 'Create', - onClick: () => navigate(`./add`), + onClick: () => navigate(`../rules/add`), }, { icon: 'trash', @@ -133,11 +133,11 @@ const ConditionGroups = () => { titleSize="larger" title="Rules" refreshAction={getFreshList} - // busy={isBusy} + busy={isBusy} widgetButtons={buttons} widgetInfoCard={{ title: 'Information', - description: 'Rules are combination of conditions and condition groups', + description: 'Rules contain set of conditions', }} >
@@ -146,8 +146,8 @@ const ConditionGroups = () => { hasCheckboxes hasAllCheckBox={false} multiSelect={false} - data={rulesList} - headers={rulesTableHeader} + data={rulesData} + headers={rulesHeader} onCheckedRowsChanged={(checkedRows) => { setCheckedRows(checkedRows as string[]); }} @@ -169,4 +169,4 @@ const ConditionGroups = () => { ); }; -export default ConditionGroups; +export default RulesList; diff --git a/src/components/_pages/triggers/details/index.tsx b/src/components/_pages/triggers/details/index.tsx index 816ae335f..5828da2fc 100644 --- a/src/components/_pages/triggers/details/index.tsx +++ b/src/components/_pages/triggers/details/index.tsx @@ -232,6 +232,7 @@ const TriggerDetails = () => { { id: 'actions', content: 'Actions', + align: 'center', }, ], [], diff --git a/src/components/_pages/triggers/form/index.tsx b/src/components/_pages/triggers/form/index.tsx index ae122e9d7..52c04e7d5 100644 --- a/src/components/_pages/triggers/form/index.tsx +++ b/src/components/_pages/triggers/form/index.tsx @@ -78,8 +78,8 @@ const TriggerForm = () => { const actionsOptions = useMemo(() => { if (actionsList === undefined) return []; - return actionsList.map((conditionGroup) => { - return { value: conditionGroup.uuid, label: conditionGroup.name }; + return actionsList.map((action) => { + return { value: action.uuid, label: action.name }; }); }, [actionsList]); diff --git a/src/components/_pages/triggers/list/index.tsx b/src/components/_pages/triggers/list/index.tsx index 22647c823..03fbe27b9 100644 --- a/src/components/_pages/triggers/list/index.tsx +++ b/src/components/_pages/triggers/list/index.tsx @@ -24,7 +24,7 @@ const TriggerList = () => { const eventNameEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ResourceEvent)); const triggerTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.TriggerType)); const [selectedResource, setSelectedResource] = useState(); - const [selectedTriggerSource, setSelectedTriggerSource] = useState(); + const [selectedEventSource, setSelectedEventSource] = useState(); const isFetchingList = useSelector(rulesSelectors.isFetchingTriggers); const isDeleting = useSelector(rulesSelectors.isDeletingTrigger); @@ -46,8 +46,8 @@ const TriggerList = () => { }, [dispatch, checkedRows]); const getFreshList = useCallback(() => { - dispatch(rulesActions.listTriggers({ resource: selectedResource, eventResource: selectedTriggerSource })); - }, [dispatch, selectedResource, selectedTriggerSource]); + dispatch(rulesActions.listTriggers({ resource: selectedResource, eventResource: selectedEventSource })); + }, [dispatch, selectedResource, selectedEventSource]); useEffect(() => { getFreshList(); @@ -125,7 +125,7 @@ const TriggerList = () => { { icon: 'search', disabled: false, - tooltip: 'Select Trigger Source', + tooltip: 'Select Event Source', onClick: () => {}, custom: (
@@ -134,9 +134,9 @@ const TriggerList = () => { maxMenuHeight={140} menuPlacement="auto" options={resourceOptionsWithEvents} - placeholder="Select Trigger Source" + placeholder="Select Event Source" onChange={(event) => { - setSelectedTriggerSource(event?.value as Resource); + setSelectedEventSource(event?.value as Resource); }} />
@@ -209,7 +209,7 @@ const TriggerList = () => { setConfirmDelete(false)} buttons={[ { color: 'danger', onClick: onDeleteConfirmed, body: 'Yes, delete' }, diff --git a/src/ducks/rules-epics.ts b/src/ducks/rules-epics.ts index 7446f4997..a7da03638 100644 --- a/src/ducks/rules-epics.ts +++ b/src/ducks/rules-epics.ts @@ -260,7 +260,7 @@ const deleteExecution: AppEpic = (action$, state, deps) => { switchMap(() => of( slice.actions.deleteExecutionSuccess({ executionUuid: action.payload.executionUuid }), - appRedirectActions.redirect({ url: `../../actions` }), + appRedirectActions.redirect({ url: `../../actions/1` }), ), ), catchError((err) => @@ -274,6 +274,28 @@ const deleteExecution: AppEpic = (action$, state, deps) => { ); }; +const deleteAction: AppEpic = (action$, state, deps) => { + return action$.pipe( + filter(slice.actions.deleteAction.match), + switchMap((action) => + deps.apiClients.actions.deleteAction({ actionUuid: action.payload.actionUuid }).pipe( + switchMap(() => + of( + slice.actions.deleteActionSuccess({ actionUuid: action.payload.actionUuid }), + appRedirectActions.redirect({ url: `../actions/0` }), + ), + ), + catchError((err) => + of( + slice.actions.deleteActionFailure({ error: extractError(err, 'Failed to delete action') }), + alertActions.error(extractError(err, 'Failed to delete action')), + ), + ), + ), + ), + ); +}; + const deleteCondition: AppEpic = (action$, state, deps) => { return action$.pipe( filter(slice.actions.deleteCondition.match), @@ -282,7 +304,7 @@ const deleteCondition: AppEpic = (action$, state, deps) => { switchMap(() => of( slice.actions.deleteConditionSuccess({ conditionUuid: action.payload.conditionUuid }), - appRedirectActions.redirect({ url: `../../rules` }), + appRedirectActions.redirect({ url: `../../rules/1` }), ), ), catchError((err) => @@ -304,7 +326,7 @@ const deleteRule: AppEpic = (action$, state, deps) => { switchMap(() => of( slice.actions.deleteRuleSuccess({ ruleUuid: action.payload.ruleUuid }), - appRedirectActions.redirect({ url: `../rules` }), + appRedirectActions.redirect({ url: `../rules/0` }), ), ), catchError((err) => @@ -583,6 +605,7 @@ const epics = [ createAction, createTrigger, deleteExecution, + deleteAction, deleteCondition, deleteRule, deleteTrigger, diff --git a/src/ducks/rules.ts b/src/ducks/rules.ts index 142711b23..4326b2a71 100644 --- a/src/ducks/rules.ts +++ b/src/ducks/rules.ts @@ -59,6 +59,7 @@ export type State = { isUpdatingAction: boolean; isUpdatingTrigger: boolean; isFetchingActions: boolean; + isDeletingAction: boolean; }; export const initialState: State = { @@ -94,6 +95,7 @@ export const initialState: State = { isDeletingRule: false, isFetchingActions: false, isFetchingActionDetail: false, + isDeletingAction: false, }; export const slice = createSlice({ @@ -246,6 +248,18 @@ export const slice = createSlice({ deleteExecutionFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { state.isDeletingExecution = false; }, + deleteAction: (state, action: PayloadAction<{ actionUuid: string }>) => { + state.isDeletingAction = true; + }, + + deleteActionSuccess: (state, action: PayloadAction<{ actionUuid: string }>) => { + state.actionsList = state.actionsList.filter((group) => group.uuid !== action.payload.actionUuid); + state.isDeletingAction = false; + }, + + deleteActionFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { + state.isDeletingAction = false; + }, deleteCondition: (state, action: PayloadAction<{ conditionUuid: string }>) => { state.isDeletingCondition = true; @@ -468,6 +482,8 @@ const isFetchingTriggerDetail = createSelector(state, (state) => state.isFetchin const isDeletingTrigger = createSelector(state, (state) => state.isDeletingTrigger); const isFetchingTriggers = createSelector(state, (state) => state.isFetchingTriggers); const isCreatingTrigger = createSelector(state, (state) => state.isCreatingTrigger); +const isFetchingActions = createSelector(state, (state) => state.isFetchingActions); +const isDeletingAction = createSelector(state, (state) => state.isDeletingAction); export const selectors = { rules, @@ -501,6 +517,8 @@ export const selectors = { isDeletingTrigger, isFetchingTriggers, isCreatingTrigger, + isFetchingActions, + isDeletingAction, }; export const actions = slice.actions; From aad8e8cd4788f0c866f72b76707a259070dbe8cc Mon Sep 17 00:00:00 2001 From: Abhijit Bansode Date: Sun, 26 May 2024 23:35:10 +0530 Subject: [PATCH 5/8] trigger detail page , add now row for rules and actions added --- .../index.tsx | 326 ++++++++++++++++++ .../GroupConditionsViewer/index.tsx | 4 +- src/components/ConditionsViewer/index.tsx | 284 --------------- .../FilterWidgetRuleAction/index.tsx | 2 +- .../_pages/actions/detail/index.tsx | 240 +++++++------ src/components/_pages/actions/form/index.tsx | 4 +- .../list/actions-list-component/index.tsx | 2 +- .../list/executions-list-component/index.tsx | 2 +- .../_pages/conditions/details/index.tsx | 16 +- .../_pages/executions/details/index.tsx | 46 ++- src/components/_pages/rules/detail/index.tsx | 221 ++++++------ .../list/conditions-list-component/index.tsx | 2 +- .../rules/list/rules-list-component/index.tsx | 2 +- .../_pages/triggers/details/index.tsx | 108 +++--- src/components/_pages/triggers/list/index.tsx | 15 +- src/ducks/rules.ts | 42 ++- 16 files changed, 685 insertions(+), 631 deletions(-) create mode 100644 src/components/ConditionAndExecutionItemsViewer/index.tsx delete mode 100644 src/components/ConditionsViewer/index.tsx diff --git a/src/components/ConditionAndExecutionItemsViewer/index.tsx b/src/components/ConditionAndExecutionItemsViewer/index.tsx new file mode 100644 index 000000000..98a7c4dbb --- /dev/null +++ b/src/components/ConditionAndExecutionItemsViewer/index.tsx @@ -0,0 +1,326 @@ +import { ApiClients } from 'api'; +import FilterWidget from 'components/FilterWidget'; +import FilterWidgetRuleAction from 'components/FilterWidgetRuleAction'; +import { EntityType, actions as filterActions } from 'ducks/filters'; +import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; +import { useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import { Resource } from 'types/openapi'; +import { conditionGroupToFilter, filterToConditionItems } from 'utils/rules'; +type FormType = 'condtionItems' | 'executionItems'; + +interface ConditionGroupFormFilterProps { + resource: Resource; + formType: FormType; +} + +const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) => { + const { id } = useParams(); + const editMode = useMemo(() => !!id, [id]); + + const conditionDetails = useSelector(rulesSelectors.conditionDetails); + const isFetchingConditionDetails = useSelector(rulesSelectors.isFetchingConditionDetails); + const isUpdatingCondition = useSelector(rulesSelectors.isUpdatingCondition); + + // const ruleDetails = useSelector(rulesSelectors.ruleDetails); + // const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); + // const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); + + const executionDetails = useSelector(rulesSelectors.executionDetails); + const isFetchingExecutionDetails = useSelector(rulesSelectors.isFetchingExecutionDetails); + const isUpdatingExecution = useSelector(rulesSelectors.isUpdatingExecution); + + // const trigerDetails = useSelector(rulesSelectors.triggerDetails); + // const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); + // const isUpdatingTrigger = useSelector(rulesSelectors.isUpdatingTrigger); + + const [hasEffectRun, setHasEffectRun] = useState(false); + + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (!id) return; + // if (formType === 'rules' && id !== ruleDetails?.uuid) { + // dispatch(rulesActions.getRule({ ruleUuid: id })); + // } + if (formType === 'condtionItems' && id !== conditionDetails?.uuid) { + dispatch(rulesActions.getCondition({ conditionUuid: id })); + } + + if (formType === 'executionItems' && id !== executionDetails?.uuid) { + dispatch(rulesActions.getExecution({ executionUuid: id })); + } + + // if (formType === 'actionGroup' && id !== actionGroupDetails?.uuid) { + // dispatch(rulesActions.getActionGroup({ actionGroupUuid: id })); + // } + + // if (formType === 'trigger' && id !== trigerDetails?.uuid) { + // dispatch(rulesActions.getTrigger({ triggerUuid: id })); + // } + }, [ + id, + dispatch, + formType, + conditionDetails?.uuid, + executionDetails?.uuid, + + // ruleDetails?.uuid, + + // actionGroupDetails?.uuid, + // trigerDetails?.uuid + ]); + + useEffect(() => { + if (!hasEffectRun && editMode && id) { + // let currentConditions = []; + + // if (formType === 'rules') { + // if (ruleDetails?.uuid !== id) return; + // currentConditions = ruleDetails?.conditions || []; + // } else { + // if (conditionGroupsDetails?.uuid !== id) return; + // currentConditions = conditionGroupsDetails?.conditions || []; + // } + if (formType == 'condtionItems') { + if (conditionDetails?.uuid !== id) return; + const currentConditions = conditionDetails?.items || []; + + const currentFilters = conditionGroupToFilter(currentConditions); + setHasEffectRun(true); + dispatch(filterActions.setCurrentFilters({ currentFilters: currentFilters, entity: EntityType.CONDITIONS })); + } + + // else { + // if (executionDetails?.uuid !== id) return; + // currentConditions = executionDetails?.items || []; + // } + } + }, [ + editMode, + + // ruleDetails, + + conditionDetails, + + hasEffectRun, + dispatch, + formType, + id, + ]); + + useEffect(() => { + return () => { + dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // const renderAppendContent = useMemo(() => { + // if (formType === 'rules' && ruleDetails?.conditionGroups && ruleDetails?.conditionGroups?.length > 0) { + // if (isFetchingRuleDetail || isUpdatingRule) return <>; + // return ; + // } + + // if (formType === 'trigger' && trigerDetails?.actionGroups && trigerDetails?.actionGroups?.length > 0) { + // if (isFetchingTriggerDetail || isUpdatingTrigger) return <>; + // return ; + // } else { + // return <>; + // } + // }, [ruleDetails, formType, trigerDetails, isFetchingRuleDetail, isFetchingTriggerDetail, isUpdatingRule, isUpdatingTrigger]); + + // const renderFilterWidgetForRules = useMemo(() => { + // if (formType !== 'rules' || !id || !ruleDetails) return null; + // const disableBadgeRemove = + // (ruleDetails.conditions.length === 1 && ruleDetails.conditionGroups.length === 0) || isFetchingRuleDetail || isUpdatingRule; + + // const isBusy = isFetchingRuleDetail || isUpdatingRule; + + // return ( + // + // apiClients.resources.listResourceRuleFilterFields({ + // resource, + // }) + // } + // disableBadgeRemove={disableBadgeRemove} + // onFilterUpdate={(currentFilters) => { + // const currentCondition = filterToConditionItems(currentFilters); + // dispatch( + // rulesActions.updateRule({ + // ruleUuid: id, + // rule: { + // conditions: currentCondition, + // conditionGroupsUuids: ruleDetails.conditionGroups.map((cg) => cg.uuid), + // description: ruleDetails.description || '', + // }, + // }), + // ); + // }} + // /> + // ); + // }, [resource, dispatch, formType, id, ruleDetails, renderAppendContent, isFetchingRuleDetail, isUpdatingRule]); + + const renderFilterWidgetForConditionItems = useMemo(() => { + if (formType !== 'condtionItems' || !id || !conditionDetails) return null; + const disableBadgeRemove = conditionDetails.items.length === 1 || isFetchingConditionDetails || isUpdatingCondition; + const isBusy = isFetchingConditionDetails || isUpdatingCondition; + return ( +
+ + apiClients.resources.listResourceRuleFilterFields({ + resource, + }) + } + disableBadgeRemove={disableBadgeRemove} + onFilterUpdate={(currentFilters) => { + const currentCondition = filterToConditionItems(currentFilters); + dispatch( + rulesActions.updateCondition({ + conditionUuid: id, + condition: { + items: currentCondition, + description: conditionDetails.description || '', + }, + }), + ); + }} + /> +
+ ); + }, [resource, dispatch, formType, id, conditionDetails, isFetchingConditionDetails, isUpdatingCondition]); + + const renderFilterWidgetForExecutionItems = useMemo(() => { + if (formType !== 'executionItems' || !id || !executionDetails) return null; + const disableBadgeRemove = executionDetails.items.length === 1 || isFetchingExecutionDetails || isUpdatingExecution; + + const isBusy = isFetchingExecutionDetails || isUpdatingExecution; + return ( +
+ { + + apiClients.resources.listResourceRuleFilterFields({ + resource, + settable: true, + }) + } + // actionsList={actionGroupDetails.actions} + ExecutionsList={executionDetails.items} + onActionsUpdate={(currentExecutionItems) => { + dispatch( + rulesActions.updateExecution({ + executionUuid: id, + execution: { + items: currentExecutionItems, + description: executionDetails.description, + }, + }), + ); + }} + /> + } +
+ ); + }, [resource, dispatch, formType, id, executionDetails, isFetchingExecutionDetails, isUpdatingExecution]); + + // const renderFilterWidgetForTrigger = useMemo(() => { + // if (formType !== 'trigger' || !id || !trigerDetails) return null; + // const isActionOnlyOne = trigerDetails.actions.length === 1; + // // const isActionGroupEmpty = trigerDetails.actionGroups.length === 0; + + // // const disableBadgeRemove = isActionOnlyOne && isActionGroupEmpty; + // const isBusy = isFetchingTriggerDetail || isUpdatingTrigger; + + // return ( + //
+ // {/* + // apiClients.resources.listResourceRuleFilterFields({ + // resource, + // settable: true, + // }) + // } + // ExecutionsList={trigerDetails.actions} + // onActionsUpdate={(currentActions) => { + // dispatch( + // rulesActions.updateTrigger({ + // triggerUuid: id, + // trigger: { + // actions: currentActions, + // description: trigerDetails.description, + // triggerType: trigerDetails.triggerType, + // rulesUuids: trigerDetails.rules.map((r) => r.uuid), + // actionGroupsUuids: trigerDetails.actionGroups.map((ag) => ag.uuid), + // }, + // }), + // ); + // }} + // /> */} + //
+ // ); + // }, [ + // resource, + // dispatch, + // formType, + // id, + // trigerDetails, + + // // renderAppendContent, + + // isFetchingTriggerDetail, + // isUpdatingTrigger, + // ]); + + const renderWidgetConditionViewer = useMemo(() => { + switch (formType) { + case 'condtionItems': + return renderFilterWidgetForConditionItems; + // case 'rules': + // return renderFilterWidgetForRules; + + case 'executionItems': + return renderFilterWidgetForExecutionItems; + + // case 'trigger': + // return renderFilterWidgetForTrigger; + default: + return null; + } + }, [ + formType, + renderFilterWidgetForConditionItems, + // renderFilterWidgetForRules, + renderFilterWidgetForExecutionItems, + // renderFilterWidgetForTrigger, + ]); + + return
{renderWidgetConditionViewer}
; +}; + +export default ConditionAndExecutionItemsViewer; diff --git a/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx b/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx index 42b0a3f4d..1a44f6bd5 100644 --- a/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx +++ b/src/components/ConditionGroupsList/GroupConditionsViewer/index.tsx @@ -19,7 +19,7 @@ const GroupConditionsViewer = ({ groupConditions = [], conditionGroupName, condi const FilterConditionOperatorEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterConditionOperator)); const availableFilters = useSelector(selectors.availableFilters(EntityType.CONDITIONS)); const platformEnums = useSelector(enumSelectors.platformEnums); - const isFetchingCondition = useSelector(rulesSelectors.isFetchingCondition); + const isFetchingConditionDetails = useSelector(rulesSelectors.isFetchingConditionDetails); const booleanOptions = useMemo( () => [ { label: 'True', value: true }, @@ -69,7 +69,7 @@ const GroupConditionsViewer = ({ groupConditions = [], conditionGroupName, condi }); }; - if (isFetchingCondition) return ; + if (isFetchingConditionDetails) return ; return (
diff --git a/src/components/ConditionsViewer/index.tsx b/src/components/ConditionsViewer/index.tsx deleted file mode 100644 index 4bd650b58..000000000 --- a/src/components/ConditionsViewer/index.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import { EntityType, actions as filterActions } from 'ducks/filters'; -import { selectors as rulesSelectors } from 'ducks/rules'; -import { useEffect, useMemo, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { useParams } from 'react-router-dom'; -import { Resource } from 'types/openapi'; -type FormType = 'rules' | 'conditionGroup' | 'actionGroup' | 'trigger'; - -interface ConditionGroupFormFilterProps { - resource: Resource; - formType: FormType; -} - -const ConditionsViewer = ({ resource, formType }: ConditionGroupFormFilterProps) => { - const { id } = useParams(); - const editMode = useMemo(() => !!id, [id]); - - // const conditionGroupsDetails = useSelector(rulesSelectors.conditionGroupDetails); - // const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingConditionGroup); - // const isUpdatingConditionGroup = useSelector(rulesSelectors.isUpdatingConditionGroup); - - // const ruleDetails = useSelector(rulesSelectors.ruleDetails); - // const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); - // const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); - - // const actionGroupDetails = useSelector(rulesSelectors.actionGroupDetails); - // const isFetchingActionGroup = useSelector(rulesSelectors.isFetchingActionGroup); - // const isUpdatingActionGroup = useSelector(rulesSelectors.isUpdatingActionGroup); - - const trigerDetails = useSelector(rulesSelectors.triggerDetails); - const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); - const isUpdatingTrigger = useSelector(rulesSelectors.isUpdatingTrigger); - - const [hasEffectRun, setHasEffectRun] = useState(false); - - const dispatch = useDispatch(); - - useEffect(() => { - dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - // useEffect(() => { - // if (!id) return; - // if (formType === 'rules' && id !== ruleDetails?.uuid) { - // dispatch(rulesActions.getRule({ ruleUuid: id })); - // } - // if (formType === 'conditionGroup' && id !== conditionGroupsDetails?.uuid) { - // dispatch(rulesActions.getConditionGroup({ conditionGroupUuid: id })); - // } - - // if (formType === 'actionGroup' && id !== actionGroupDetails?.uuid) { - // dispatch(rulesActions.getActionGroup({ actionGroupUuid: id })); - // } - - // if (formType === 'trigger' && id !== trigerDetails?.uuid) { - // dispatch(rulesActions.getTrigger({ triggerUuid: id })); - // } - // }, [id, dispatch, formType, ruleDetails?.uuid, conditionGroupsDetails?.uuid, actionGroupDetails?.uuid, trigerDetails?.uuid]); - - // useEffect(() => { - // if (!hasEffectRun && editMode && id) { - // let currentConditions = []; - - // if (formType === 'rules') { - // if (ruleDetails?.uuid !== id) return; - // currentConditions = ruleDetails?.conditions || []; - // } else { - // if (conditionGroupsDetails?.uuid !== id) return; - // currentConditions = conditionGroupsDetails?.conditions || []; - // } - - // const currentFilters = conditionGroupToFilter(currentConditions); - // setHasEffectRun(true); - // dispatch(filterActions.setCurrentFilters({ currentFilters: currentFilters, entity: EntityType.CONDITIONS })); - // } - // }, [editMode, ruleDetails, conditionGroupsDetails, hasEffectRun, dispatch, formType, id]); - - useEffect(() => { - return () => { - dispatch(filterActions.setCurrentFilters({ currentFilters: [], entity: EntityType.CONDITIONS })); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - // const renderAppendContent = useMemo(() => { - // if (formType === 'rules' && ruleDetails?.conditionGroups && ruleDetails?.conditionGroups?.length > 0) { - // if (isFetchingRuleDetail || isUpdatingRule) return <>; - // return ; - // } - - // if (formType === 'trigger' && trigerDetails?.actionGroups && trigerDetails?.actionGroups?.length > 0) { - // if (isFetchingTriggerDetail || isUpdatingTrigger) return <>; - // return ; - // } else { - // return <>; - // } - // }, [ruleDetails, formType, trigerDetails, isFetchingRuleDetail, isFetchingTriggerDetail, isUpdatingRule, isUpdatingTrigger]); - - // const renderFilterWidgetForRules = useMemo(() => { - // if (formType !== 'rules' || !id || !ruleDetails) return null; - // const disableBadgeRemove = - // (ruleDetails.conditions.length === 1 && ruleDetails.conditionGroups.length === 0) || isFetchingRuleDetail || isUpdatingRule; - - // const isBusy = isFetchingRuleDetail || isUpdatingRule; - - // return ( - // - // apiClients.resources.listResourceRuleFilterFields({ - // resource, - // }) - // } - // disableBadgeRemove={disableBadgeRemove} - // onFilterUpdate={(currentFilters) => { - // const currentCondition = filterToConditionItems(currentFilters); - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // conditions: currentCondition, - // conditionGroupsUuids: ruleDetails.conditionGroups.map((cg) => cg.uuid), - // description: ruleDetails.description || '', - // }, - // }), - // ); - // }} - // /> - // ); - // }, [resource, dispatch, formType, id, ruleDetails, renderAppendContent, isFetchingRuleDetail, isUpdatingRule]); - - // const renderFilterWidgetForConditionGroups = useMemo(() => { - // if (formType !== 'conditionGroup' || !id || !conditionGroupsDetails) return null; - // const disableBadgeRemove = conditionGroupsDetails.conditions.length === 1 || isFetchingConditionGroup || isUpdatingConditionGroup; - // const isBusy = isFetchingConditionGroup || isUpdatingConditionGroup; - // return ( - //
- // - // apiClients.resources.listResourceRuleFilterFields({ - // resource, - // }) - // } - // disableBadgeRemove={disableBadgeRemove} - // onFilterUpdate={(currentFilters) => { - // const currentCondition = filterToConditionItems(currentFilters); - // dispatch( - // rulesActions.updateConditionGroup({ - // conditionGroupUuid: id, - // conditionGroup: { - // conditions: currentCondition, - // }, - // }), - // ); - // }} - // /> - //
- // ); - // }, [resource, dispatch, formType, id, conditionGroupsDetails, isFetchingConditionGroup, isUpdatingConditionGroup]); - - // const renderFilterWidgetForActionGroup = useMemo(() => { - // if (formType !== 'actionGroup' || !id || !actionGroupDetails) return null; - // const disableBadgeRemove = actionGroupDetails.actions.length === 1 || isFetchingActionGroup || isUpdatingActionGroup; - - // const isBusy = isFetchingActionGroup || isUpdatingActionGroup; - // return ( - //
- // { - /* - apiClients.resources.listResourceRuleFilterFields({ - resource, - settable: true, - }) - } - actionsList={actionGroupDetails.actions} - onActionsUpdate={(currentActions) => { - dispatch( - rulesActions.updateActionGroup({ - actionGroupUuid: id, - actionGroup: { - actions: currentActions, - }, - }), - ); - }} - /> */ - // } - //
- // ); - // }, [resource, dispatch, formType, id, actionGroupDetails, isFetchingActionGroup, isUpdatingActionGroup]); - - const renderFilterWidgetForTrigger = useMemo(() => { - if (formType !== 'trigger' || !id || !trigerDetails) return null; - const isActionOnlyOne = trigerDetails.actions.length === 1; - // const isActionGroupEmpty = trigerDetails.actionGroups.length === 0; - - // const disableBadgeRemove = isActionOnlyOne && isActionGroupEmpty; - const isBusy = isFetchingTriggerDetail || isUpdatingTrigger; - - return ( -
- {/* - apiClients.resources.listResourceRuleFilterFields({ - resource, - settable: true, - }) - } - ExecutionsList={trigerDetails.actions} - onActionsUpdate={(currentActions) => { - dispatch( - rulesActions.updateTrigger({ - triggerUuid: id, - trigger: { - actions: currentActions, - description: trigerDetails.description, - triggerType: trigerDetails.triggerType, - rulesUuids: trigerDetails.rules.map((r) => r.uuid), - actionGroupsUuids: trigerDetails.actionGroups.map((ag) => ag.uuid), - }, - }), - ); - }} - /> */} -
- ); - }, [ - resource, - dispatch, - formType, - id, - trigerDetails, - - // renderAppendContent, - - isFetchingTriggerDetail, - isUpdatingTrigger, - ]); - - const renderWidgetConditionViewer = useMemo(() => { - switch (formType) { - // case 'conditionGroup': - // return renderFilterWidgetForConditionGroups; - // case 'rules': - // return renderFilterWidgetForRules; - - // case 'actionGroup': - // return renderFilterWidgetForActionGroup; - - // case 'trigger': - // return renderFilterWidgetForTrigger; - default: - return null; - } - }, [ - formType, - // renderFilterWidgetForConditionGroups, - // renderFilterWidgetForRules, - // renderFilterWidgetForActionGroup, - renderFilterWidgetForTrigger, - ]); - - return
{renderWidgetConditionViewer}
; -}; - -export default ConditionsViewer; diff --git a/src/components/FilterWidgetRuleAction/index.tsx b/src/components/FilterWidgetRuleAction/index.tsx index 9378d66c3..73e3f4aef 100644 --- a/src/components/FilterWidgetRuleAction/index.tsx +++ b/src/components/FilterWidgetRuleAction/index.tsx @@ -429,7 +429,7 @@ export default function FilterWidgetRuleAction({ ); }, - [isFetchingAvailableFilters, executionTypeEnum, onRemoveFilterClick, searchGroupEnum, disableBadgeRemove, busyBadges], + [isFetchingAvailableFilters, onRemoveFilterClick, searchGroupEnum, disableBadgeRemove, busyBadges], ); const isUpdateButtonDisabled = useMemo(() => { diff --git a/src/components/_pages/actions/detail/index.tsx b/src/components/_pages/actions/detail/index.tsx index dee480e99..70d7e6ed6 100644 --- a/src/components/_pages/actions/detail/index.tsx +++ b/src/components/_pages/actions/detail/index.tsx @@ -1,4 +1,3 @@ -import ConditionsViewer from 'components/ConditionsViewer'; import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; import Dialog from 'components/Dialog'; import Widget from 'components/Widget'; @@ -7,7 +6,7 @@ import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; import { actions as rulesActions, selectors as rulesSelectors } from 'ducks/rules'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useParams } from 'react-router-dom'; +import { Link, useParams } from 'react-router-dom'; import { Button, ButtonGroup, Col, Container, Input, Row } from 'reactstrap'; import { PlatformEnum } from 'types/openapi'; interface SelectChangeValue { @@ -18,10 +17,11 @@ const RuleDetails = () => { const { id } = useParams(); const dispatch = useDispatch(); const actionDetails = useSelector(rulesSelectors.actionDetails); - const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); - const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); + const isUpdatingAction = useSelector(rulesSelectors.isUpdatingAction); + const isFetchingActionDetails = useSelector(rulesSelectors.isFetchingActionDetails); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const conditionGroups = useSelector(rulesSelectors.conditions); + const executionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ExecutionType)); + const executions = useSelector(rulesSelectors.executions); const [confirmDelete, setConfirmDelete] = useState(false); const [updateDescriptionEditEnable, setUpdateDescription] = useState(false); @@ -42,19 +42,19 @@ const RuleDetails = () => { }, [getFreshDetails]); useEffect(() => { - dispatch(rulesActions.listConditions({ resource: actionDetails?.resource })); + dispatch(rulesActions.listExecutions({ resource: actionDetails?.resource })); }, [actionDetails, dispatch]); - const isBusy = useMemo(() => isFetchingRuleDetail || isUpdatingRule, [isFetchingRuleDetail, isUpdatingRule]); + const isBusy = useMemo(() => isFetchingActionDetails || isUpdatingAction, [isFetchingActionDetails, isUpdatingAction]); const executionsOptions = useMemo(() => { - if (conditionGroups === undefined) return []; - return conditionGroups + if (executions === undefined) return []; + return executions .map((conditions) => { return { value: conditions.uuid, label: conditions.name }; }) .filter((conditions) => !actionDetails?.executions?.map((condition) => condition.uuid).includes(conditions.value)); - }, [conditionGroups, actionDetails]); + }, [executions, actionDetails]); const onDeleteConfirmed = useCallback(() => { if (!id) return; @@ -65,72 +65,62 @@ const RuleDetails = () => { const onUpdateDescriptionConfirmed = useCallback(() => { if (!id || !updateDescriptionEditEnable) return; if (updatedDescription !== actionDetails?.description) { - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // description: updatedDescription, - // // conditionsUuids: actionDetails?.conditions - // conditionUuids: actionDetails?.conditionGroups?.length - // ? actionDetails?.conditionGroups.map((conditionGroup) => conditionGroup.uuid) - // : [], - // }, - // }), - // ); + dispatch( + rulesActions.updateAction({ + actionUuid: id, + action: { + description: updatedDescription, + executionsUuids: actionDetails?.executions?.length + ? actionDetails?.executions.map((execution) => execution.uuid) + : [], + }, + }), + ); } setUpdateDescription(false); }, [dispatch, id, actionDetails, updatedDescription, updateDescriptionEditEnable]); - const onUpdateConditionGroupsConfirmed = useCallback( + const onUpdateExecutionsConfirmed = useCallback( (newValues: SelectChangeValue[]) => { if (!id) return; - const newConditionGroupsUuids = newValues.map((conditionGroup) => conditionGroup.value); + const newExecutionsUuids = newValues.map((execution) => execution.value); - const previousAndNewConditionGroupsUuid = actionDetails?.executions.map((execution) => execution.uuid); - const allConditionGroups = [...(previousAndNewConditionGroupsUuid || []), ...newConditionGroupsUuids]; + const previousAndNewExecutionsUuid = actionDetails?.executions.map((execution) => execution.uuid); + const allConditionGroups = [...(previousAndNewExecutionsUuid || []), ...newExecutionsUuids]; - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // description: actionDetails?.description || '', - // conditions: actionDetails?.conditions || [], - // conditionGroupsUuids: allConditionGroups, - // }, - // }), - // ); + dispatch( + rulesActions.updateAction({ + actionUuid: id, + action: { + description: actionDetails?.description || '', + executionsUuids: allConditionGroups, + // conditionGroupsUuids: allConditionGroups, + }, + }), + ); }, [dispatch, id, actionDetails], ); - const onDeleteConditionGroup = useCallback( - (conditionGroupUuid: string) => { + const onDeleteExecution = useCallback( + (executionUuid: string) => { if (!id) return; - // const updatedConditionGroupsUuid = actionDetails?.conditionGroups - // .filter((conditionGroup) => conditionGroup.uuid !== conditionGroupUuid) - // .map((conditionGroup) => conditionGroup.uuid); - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // conditions: actionDetails?.conditions || [], - // description: actionDetails?.description || '', - // conditionGroupsUuids: updatedConditionGroupsUuid, - // }, - // }), - // ); + const updatedExecutionsUuid = actionDetails?.executions + .filter((execution) => execution.uuid !== executionUuid) + .map((execution) => execution.uuid); + dispatch( + rulesActions.updateAction({ + actionUuid: id, + action: { + description: actionDetails?.description || '', + executionsUuids: updatedExecutionsUuid?.length ? updatedExecutionsUuid : [], + }, + }), + ); }, - [ - dispatch, - id, - - // actionDetails?.conditionGroups, - - actionDetails?.executions, - actionDetails?.description, - ], + [dispatch, id, actionDetails?.executions, actionDetails?.description], ); const buttons: WidgetButtonProps[] = useMemo( @@ -165,7 +155,7 @@ const RuleDetails = () => { const conditionGroupsDetailData: TableDataRow[] = useMemo( () => - !actionDetails || isFetchingRuleDetail + !actionDetails || isFetchingActionDetails ? [] : [ { @@ -204,7 +194,7 @@ const RuleDetails = () => { title="Update Description" onClick={onUpdateDescriptionConfirmed} disabled={ - isUpdatingRule || + isUpdatingAction || updatedDescription === actionDetails.description || updatedDescription === '' } @@ -215,7 +205,7 @@ const RuleDetails = () => { className="btn btn-link mx-auto danger" size="sm" title="Cancel" - disabled={isUpdatingRule} + disabled={isUpdatingAction} onClick={() => { setUpdateDescription(false); setUpdatedDescription(actionDetails?.description || ''); @@ -246,62 +236,67 @@ const RuleDetails = () => { resourceTypeEnum, onUpdateDescriptionConfirmed, updateDescriptionEditEnable, - isUpdatingRule, + isUpdatingAction, updatedDescription, - isFetchingRuleDetail, + isFetchingActionDetails, ], ); - // const conditionGroupFieldsDataHeader = useMemo( - // () => [ - // { - // id: 'name', - // content: 'Name', - // }, - // { - // id: 'description', - // content: 'Description', - // }, - // { - // id: 'actions', - // content: 'Actions', - // }, - // ], - // [], - // ); + const executionDataHeaders = useMemo( + () => [ + { + id: 'name', + content: 'Name', + }, + { + id: 'type', + content: 'Type', + }, + { + id: 'description', + content: 'Description', + }, + { + id: 'actions', + content: 'Actions', + }, + ], + [], + ); - // const conditionGroupFieldsData: TableDataRow[] = useMemo(() => { - // const isDeleteDisabled = actionDetails?.conditions.length === 0 || isFetchingRuleDetail || isUpdatingRule; - // const conditionGroupData = !actionDetails?.conditionGroups.length - // ? [] - // : actionDetails?.conditionGroups.map((conditionGroup) => { - // return { - // id: conditionGroup.uuid, - // columns: [ - // {conditionGroup.name} || '', - // conditionGroup.description || '', - // , - // ], - // }; - // }); + const executionsData: TableDataRow[] = useMemo(() => { + const isDeleteDisabled = actionDetails?.executions.length === 1 || isFetchingActionDetails || isUpdatingAction; + const conditionGroupData = !actionDetails?.executions.length + ? [] + : actionDetails?.executions.map((conditionGroup) => { + return { + id: conditionGroup.uuid, + columns: [ + {conditionGroup.name} || '', + getEnumLabel(executionTypeEnum, conditionGroup.type) || '', + conditionGroup.description || '', + , + ], + }; + }); - // return conditionGroupData; - // }, [actionDetails, isUpdatingRule, onDeleteConditionGroup, isFetchingRuleDetail]); + return conditionGroupData; + }, [actionDetails, isUpdatingAction, onDeleteExecution, isFetchingActionDetails, executionTypeEnum]); return ( @@ -311,31 +306,30 @@ const RuleDetails = () => { - {/* + - */} + - {actionDetails?.resource && } + {/* {actionDetails?.resource && } */} { const title = 'Create Action'; const executions = useSelector(rulesSelectors.executions); - const isCreatingRule = useSelector(rulesSelectors.isCreatingRule); + const isCreatingAction = useSelector(rulesSelectors.isCreatingAction); const [selectedResourceState, setSelectedResourceState] = useState(); const { resourceOptionsWithRuleEvaluator, isFetchingResourcesList } = useRuleEvaluatorResourceOptions(); - const isBusy = useMemo(() => isCreatingRule || isFetchingResourcesList, [isCreatingRule, isFetchingResourcesList]); + const isBusy = useMemo(() => isCreatingAction || isFetchingResourcesList, [isCreatingAction, isFetchingResourcesList]); const executionsOptions = useMemo(() => { if (executions === undefined) return []; diff --git a/src/components/_pages/actions/list/actions-list-component/index.tsx b/src/components/_pages/actions/list/actions-list-component/index.tsx index 2b10cb368..bd27c5786 100644 --- a/src/components/_pages/actions/list/actions-list-component/index.tsx +++ b/src/components/_pages/actions/list/actions-list-component/index.tsx @@ -80,7 +80,7 @@ const ActionsList = () => { return { id: rule.uuid, columns: [ - {rule.name}, + {rule.name}, getEnumLabel(resourceTypeEnum, rule.resource), rule.description || '', ], diff --git a/src/components/_pages/actions/list/executions-list-component/index.tsx b/src/components/_pages/actions/list/executions-list-component/index.tsx index 363f4f187..f12b1d127 100644 --- a/src/components/_pages/actions/list/executions-list-component/index.tsx +++ b/src/components/_pages/actions/list/executions-list-component/index.tsx @@ -91,7 +91,7 @@ const ExecutionsList = () => { ], }; }), - [executions, resourceTypeEnum], + [executions, resourceTypeEnum, executionTypeEnum], ); const buttons: WidgetButtonProps[] = useMemo( diff --git a/src/components/_pages/conditions/details/index.tsx b/src/components/_pages/conditions/details/index.tsx index 5dbfe10ca..fee75ff97 100644 --- a/src/components/_pages/conditions/details/index.tsx +++ b/src/components/_pages/conditions/details/index.tsx @@ -1,4 +1,4 @@ -import ConditionsViewer from 'components/ConditionsViewer'; +import ConditionAndExecutionItemsViewer from 'components/ConditionAndExecutionItemsViewer'; import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; import Dialog from 'components/Dialog'; import Widget from 'components/Widget'; @@ -15,8 +15,9 @@ const ConditionDetails = () => { const { id } = useParams(); const dispatch = useDispatch(); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); + const conditionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ConditionType)); const conditionDetails = useSelector(rulesSelectors.conditionDetails); - const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingCondition); + const isFetchingConditionGroup = useSelector(rulesSelectors.isFetchingConditionDetails); const isUpdatingGroupDetails = useSelector(rulesSelectors.isUpdatingCondition); const [confirmDelete, setConfirmDelete] = useState(false); @@ -104,6 +105,10 @@ const ConditionDetails = () => { id: 'name', columns: ['Name', conditionDetails.name, ''], }, + { + id: 'type', + columns: ['Type', getEnumLabel(conditionTypeEnum, conditionDetails.type), ''], + }, { id: 'resource', columns: ['Resource', getEnumLabel(resourceTypeEnum, conditionDetails.resource), ''], @@ -171,6 +176,7 @@ const ConditionDetails = () => { ], [ conditionDetails, + conditionTypeEnum, resourceTypeEnum, setUpdateDescription, updateDescriptionEditEnable, @@ -190,7 +196,11 @@ const ConditionDetails = () => { - {conditionDetails?.resource && } + + {conditionDetails?.resource && ( + + )} + { const { id } = useParams(); const dispatch = useDispatch(); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const ExecutionDetails = useSelector(rulesSelectors.ExecutionDetails); + const executionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ExecutionType)); + const executionDetails = useSelector(rulesSelectors.executionDetails); const isFetchingDetails = useSelector(rulesSelectors.isFetchingExecutionDetails); const isUpdatingDetails = useSelector(rulesSelectors.isUpdatingExecution); const [confirmDelete, setConfirmDelete] = useState(false); @@ -25,9 +26,9 @@ const ExecutionDetails = () => { const isBusy = useMemo(() => isFetchingDetails || isUpdatingDetails, [isFetchingDetails, isUpdatingDetails]); useEffect(() => { - if (!ExecutionDetails?.description || ExecutionDetails.uuid !== id) return; - setUpdatedDescription(ExecutionDetails.description); - }, [ExecutionDetails, id]); + if (!executionDetails?.description || executionDetails.uuid !== id) return; + setUpdatedDescription(executionDetails.description); + }, [executionDetails, id]); const getFreshDetails = useCallback(() => { if (!id) return; @@ -46,20 +47,20 @@ const ExecutionDetails = () => { const onUpdateDescriptionConfirmed = useCallback(() => { if (!id || !updateDescriptionEditEnable) return; - if (updatedDescription !== ExecutionDetails?.description) { + if (updatedDescription !== executionDetails?.description) { dispatch( rulesActions.updateExecution({ executionUuid: id, execution: { description: updatedDescription, - // actions: ExecutionDetails?.actions || [], - items: ExecutionDetails?.items || [], + // actions: executionDetails?.actions || [], + items: executionDetails?.items || [], }, }), ); } setUpdateDescription(false); - }, [dispatch, id, ExecutionDetails, updatedDescription, updateDescriptionEditEnable]); + }, [dispatch, id, executionDetails, updatedDescription, updateDescriptionEditEnable]); const buttons: WidgetButtonProps[] = useMemo( () => [ @@ -93,20 +94,24 @@ const ExecutionDetails = () => { const executionDetailsData: TableDataRow[] = useMemo( () => - !ExecutionDetails || isFetchingDetails + !executionDetails || isFetchingDetails ? [] : [ { id: 'uuid', - columns: ['UUID', ExecutionDetails.uuid, ''], + columns: ['UUID', executionDetails.uuid, ''], }, { id: 'name', - columns: ['Name', ExecutionDetails.name, ''], + columns: ['Name', executionDetails.name, ''], + }, + { + id: 'type', + columns: ['Type', getEnumLabel(executionTypeEnum, executionDetails.type), ''], }, { id: 'resource', - columns: ['Resource', getEnumLabel(resourceTypeEnum, ExecutionDetails.resource), ''], + columns: ['Resource', getEnumLabel(resourceTypeEnum, executionDetails.resource), ''], }, { id: 'description', @@ -119,7 +124,7 @@ const ExecutionDetails = () => { placeholder="Enter Description" /> ) : ( - ExecutionDetails.description || '' + executionDetails.description || '' ),
{updateDescriptionEditEnable ? ( @@ -132,7 +137,7 @@ const ExecutionDetails = () => { onClick={onUpdateDescriptionConfirmed} disabled={ isUpdatingDetails || - updatedDescription === ExecutionDetails.description || + updatedDescription === executionDetails.description || updatedDescription === '' } > @@ -144,7 +149,7 @@ const ExecutionDetails = () => { title="Cancel" onClick={() => { setUpdateDescription(false); - setUpdatedDescription(ExecutionDetails?.description || ''); + setUpdatedDescription(executionDetails?.description || ''); }} disabled={isUpdatingDetails} > @@ -170,7 +175,8 @@ const ExecutionDetails = () => { }, ], [ - ExecutionDetails, + executionDetails, + executionTypeEnum, resourceTypeEnum, setUpdateDescription, updateDescriptionEditEnable, @@ -196,7 +202,11 @@ const ExecutionDetails = () => { - {ExecutionDetails?.resource && } + + {executionDetails?.resource && ( + + )} + { const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const conditionGroups = useSelector(rulesSelectors.conditions); + const conditions = useSelector(rulesSelectors.conditions); + const conditionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ConditionType)); const [confirmDelete, setConfirmDelete] = useState(false); const [updateDescriptionEditEnable, setUpdateDescription] = useState(false); @@ -47,14 +47,14 @@ const RuleDetails = () => { const isBusy = useMemo(() => isFetchingRuleDetail || isUpdatingRule, [isFetchingRuleDetail, isUpdatingRule]); - const conditionGroupsOptions = useMemo(() => { - if (conditionGroups === undefined) return []; - return conditionGroups + const conditionsOptions = useMemo(() => { + if (conditions === undefined) return []; + return conditions .map((conditions) => { return { value: conditions.uuid, label: conditions.name }; }) .filter((conditions) => !ruleDetails?.conditions?.map((condition) => condition.uuid).includes(conditions.value)); - }, [conditionGroups, ruleDetails]); + }, [conditions, ruleDetails]); const onDeleteConfirmed = useCallback(() => { if (!id) return; @@ -65,72 +65,59 @@ const RuleDetails = () => { const onUpdateDescriptionConfirmed = useCallback(() => { if (!id || !updateDescriptionEditEnable) return; if (updatedDescription !== ruleDetails?.description) { - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // description: updatedDescription, - // // conditionsUuids: ruleDetails?.conditions - // conditionUuids: ruleDetails?.conditionGroups?.length - // ? ruleDetails?.conditionGroups.map((conditionGroup) => conditionGroup.uuid) - // : [], - // }, - // }), - // ); + dispatch( + rulesActions.updateRule({ + ruleUuid: id, + rule: { + description: updatedDescription, + conditionsUuids: ruleDetails?.conditions?.length ? ruleDetails?.conditions.map((condition) => condition.uuid) : [], + }, + }), + ); } setUpdateDescription(false); }, [dispatch, id, ruleDetails, updatedDescription, updateDescriptionEditEnable]); - const onUpdateConditionGroupsConfirmed = useCallback( + const onUpdateConditionsConfirmed = useCallback( (newValues: SelectChangeValue[]) => { if (!id) return; - const newConditionGroupsUuids = newValues.map((conditionGroup) => conditionGroup.value); + const newConditionsUuids = newValues.map((condition) => condition.value); - const previousAndNewConditionGroupsUuid = ruleDetails?.conditions.map((conditionGroup) => conditionGroup.uuid); - const allConditionGroups = [...(previousAndNewConditionGroupsUuid || []), ...newConditionGroupsUuids]; + const previousAndNewConditionsUuid = ruleDetails?.conditions.map((condition) => condition.uuid); + const allConditions = [...(previousAndNewConditionsUuid || []), ...newConditionsUuids]; - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // description: ruleDetails?.description || '', - // conditions: ruleDetails?.conditions || [], - // conditionGroupsUuids: allConditionGroups, - // }, - // }), - // ); + dispatch( + rulesActions.updateRule({ + ruleUuid: id, + rule: { + description: ruleDetails?.description || '', + conditionsUuids: allConditions, + }, + }), + ); }, [dispatch, id, ruleDetails], ); - const onDeleteConditionGroup = useCallback( - (conditionGroupUuid: string) => { + const onDeleteCondition = useCallback( + (conditionUuid: string) => { if (!id) return; - // const updatedConditionGroupsUuid = ruleDetails?.conditionGroups - // .filter((conditionGroup) => conditionGroup.uuid !== conditionGroupUuid) - // .map((conditionGroup) => conditionGroup.uuid); - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // conditions: ruleDetails?.conditions || [], - // description: ruleDetails?.description || '', - // conditionGroupsUuids: updatedConditionGroupsUuid, - // }, - // }), - // ); + const updatedConditionsUuids = ruleDetails?.conditions + .filter((condition) => condition.uuid !== conditionUuid) + .map((condition) => condition.uuid); + dispatch( + rulesActions.updateRule({ + ruleUuid: id, + rule: { + description: ruleDetails?.description || '', + conditionsUuids: updatedConditionsUuids?.length ? updatedConditionsUuids : [], + }, + }), + ); }, - [ - dispatch, - id, - - // ruleDetails?.conditionGroups, - - ruleDetails?.conditions, - ruleDetails?.description, - ], + [dispatch, id, ruleDetails?.conditions, ruleDetails?.description], ); const buttons: WidgetButtonProps[] = useMemo( @@ -252,56 +239,61 @@ const RuleDetails = () => { ], ); - // const conditionGroupFieldsDataHeader = useMemo( - // () => [ - // { - // id: 'name', - // content: 'Name', - // }, - // { - // id: 'description', - // content: 'Description', - // }, - // { - // id: 'actions', - // content: 'Actions', - // }, - // ], - // [], - // ); + const conditionsTableHeader = useMemo( + () => [ + { + id: 'name', + content: 'Name', + }, + { + id: 'type', + content: 'Type', + }, + { + id: 'description', + content: 'Description', + }, + { + id: 'actions', + content: 'Actions', + }, + ], + [], + ); - // const conditionGroupFieldsData: TableDataRow[] = useMemo(() => { - // const isDeleteDisabled = ruleDetails?.conditions.length === 0 || isFetchingRuleDetail || isUpdatingRule; - // const conditionGroupData = !ruleDetails?.conditionGroups.length - // ? [] - // : ruleDetails?.conditionGroups.map((conditionGroup) => { - // return { - // id: conditionGroup.uuid, - // columns: [ - // {conditionGroup.name} || '', - // conditionGroup.description || '', - // , - // ], - // }; - // }); + const conditionsData: TableDataRow[] = useMemo(() => { + const isDeleteDisabled = ruleDetails?.conditions.length === 1 || isFetchingRuleDetail || isUpdatingRule; + const conditionsData = !ruleDetails?.conditions.length + ? [] + : ruleDetails?.conditions.map((condition) => { + return { + id: condition.uuid, + columns: [ + {condition.name} || '', + getEnumLabel(conditionTypeEnum, condition.type), + condition.description || '', + , + ], + }; + }); - // return conditionGroupData; - // }, [ruleDetails, isUpdatingRule, onDeleteConditionGroup, isFetchingRuleDetail]); + return conditionsData; + }, [ruleDetails, isUpdatingRule, onDeleteCondition, isFetchingRuleDetail, conditionTypeEnum]); return ( @@ -311,32 +303,29 @@ const RuleDetails = () => { - {/* + - */} + - {ruleDetails?.resource && } - { ], }; }), - [conditions, resourceTypeEnum], + [conditions, resourceTypeEnum, conditionTypeEnum], ); const buttons: WidgetButtonProps[] = useMemo( diff --git a/src/components/_pages/rules/list/rules-list-component/index.tsx b/src/components/_pages/rules/list/rules-list-component/index.tsx index bcd5ae7c9..2f1d27023 100644 --- a/src/components/_pages/rules/list/rules-list-component/index.tsx +++ b/src/components/_pages/rules/list/rules-list-component/index.tsx @@ -80,7 +80,7 @@ const RulesList = () => { return { id: rule.uuid, columns: [ - {rule.name}, + {rule.name}, getEnumLabel(resourceTypeEnum, rule.resource), rule.description || '', ], diff --git a/src/components/_pages/triggers/details/index.tsx b/src/components/_pages/triggers/details/index.tsx index 5828da2fc..aafeb8e3d 100644 --- a/src/components/_pages/triggers/details/index.tsx +++ b/src/components/_pages/triggers/details/index.tsx @@ -1,4 +1,3 @@ -import ConditionsViewer from 'components/ConditionsViewer'; import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; import Dialog from 'components/Dialog'; import Widget from 'components/Widget'; @@ -9,7 +8,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Link, useParams } from 'react-router-dom'; import { Button, ButtonGroup, Col, Container, Input, Row } from 'reactstrap'; -import { PlatformEnum } from 'types/openapi'; +import { PlatformEnum, UpdateTriggerRequestDtoEventEnum } from 'types/openapi'; interface SelectChangeValue { value: string; label: string; @@ -22,7 +21,7 @@ const TriggerDetails = () => { const eventNameEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ResourceEvent)); const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); - const executions = useSelector(rulesSelectors.executions); + const actions = useSelector(rulesSelectors.actionsList); const rules = useSelector(rulesSelectors.rules); const [confirmDelete, setConfirmDelete] = useState(false); const [updateDescriptionEditEnable, setUpdateDescription] = useState(false); @@ -48,16 +47,16 @@ const TriggerDetails = () => { dispatch(rulesActions.listRules({ resource: triggerDetails?.resource })); }, [triggerDetails, dispatch]); - const isBusy = useMemo(() => isFetchingTriggerDetail || isUpdatingTrigger, [isFetchingTriggerDetail, isUpdatingTrigger]); + const isBusy = useMemo(() => isUpdatingTrigger || isFetchingTriggerDetail, [isUpdatingTrigger, isFetchingTriggerDetail]); - const actionGroupOptions = useMemo(() => { - if (executions === undefined) return []; - return executions + const actionsOptions = useMemo(() => { + if (actions === undefined) return []; + return actions .map((execution) => { return { value: execution.uuid, label: execution.name }; }) .filter((execution) => !triggerDetails?.actions?.map((action) => action.uuid).includes(execution.value)); - }, [executions, triggerDetails]); + }, [actions, triggerDetails]); const rulesOptions = useMemo(() => { if (triggerDetails === undefined) return []; @@ -83,18 +82,13 @@ const TriggerDetails = () => { triggerUuid: id, trigger: { description: updatedDescription, - // actions: triggerDetails?.actions || [], - // actionGroupsUuids: triggerDetails?.actionGroups?.length - // ? triggerDetails?.actionGroups.map((actionGroup) => actionGroup.uuid) - // : [], - // triggerType: triggerDetails.triggerType, ignoreTrigger: triggerDetails.ignoreTrigger, resource: triggerDetails.resource, type: triggerDetails.type, actionsUuids: triggerDetails?.actions.map((action) => action.uuid) || [], rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], - // event: triggerDetails.event, - // eventResource: triggerDetails.eventResource, + eventResource: triggerDetails.eventResource, + event: (triggerDetails.event as unknown as UpdateTriggerRequestDtoEventEnum) || undefined, }, }), ); @@ -102,24 +96,26 @@ const TriggerDetails = () => { setUpdateDescription(false); }, [dispatch, id, triggerDetails, updatedDescription, updateDescriptionEditEnable]); - const onUpdateActionGroupsConfirmed = useCallback( + const onUpdateActionsConfirmed = useCallback( (newValues: SelectChangeValue[]) => { if (!id || !triggerDetails) return; - const newActionGroupsUuids = newValues.map((newActionGroup) => newActionGroup.value); + const newActionsUuids = newValues.map((newAction) => newAction.value); - const previousAndNewActionGroupsUuid = triggerDetails?.actions.map((action) => action.uuid); - const allActionGroups = [...(previousAndNewActionGroupsUuid || []), ...newActionGroupsUuids]; + const previousAndNewActionsUuid = triggerDetails?.actions.map((action) => action.uuid); + const allActionsUuids = [...(previousAndNewActionsUuid || []), ...newActionsUuids]; dispatch( rulesActions.updateTrigger({ triggerUuid: id, trigger: { - actionsUuids: allActionGroups, + actionsUuids: allActionsUuids, ignoreTrigger: triggerDetails.ignoreTrigger, resource: triggerDetails.resource, type: triggerDetails.type, rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], + eventResource: triggerDetails.eventResource, description: triggerDetails.description || '', + event: (triggerDetails.event as unknown as UpdateTriggerRequestDtoEventEnum) || undefined, }, }), ); @@ -140,15 +136,14 @@ const TriggerDetails = () => { rulesActions.updateTrigger({ triggerUuid: id, trigger: { - // actionsUuids: triggerDetails?.actionsUuids || [], rulesUuids: allRules, ignoreTrigger: triggerDetails.ignoreTrigger, resource: triggerDetails.resource, type: triggerDetails.type, - - // actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], - // triggerType: triggerDetails.triggerType, + actionsUuids: triggerDetails?.actions.map((action) => action.uuid) || [], + eventResource: triggerDetails.eventResource, description: triggerDetails.description || '', + event: (triggerDetails.event as unknown as UpdateTriggerRequestDtoEventEnum) || undefined, }, }), ); @@ -156,26 +151,23 @@ const TriggerDetails = () => { [dispatch, id, triggerDetails], ); - const onDeleteActionGroup = useCallback( - (actionGroupsUuid: string) => { + const onDeleteAction = useCallback( + (actionUuid: string) => { if (!id || !triggerDetails) return; - const updatedActionGroupsUuid = triggerDetails?.actions - .filter((actionGroup) => actionGroup.uuid !== actionGroupsUuid) - .map((actionGroup) => actionGroup.uuid); + const updatedActionsUuid = triggerDetails?.actions.filter((action) => action.uuid !== actionUuid).map((action) => action.uuid); dispatch( rulesActions.updateTrigger({ triggerUuid: id, trigger: { - // actions: triggerDetails?.actions || [], description: triggerDetails?.description || '', - // actionUuids: updatedActionGroupsUuid, - // triggerType: triggerDetails.triggerType, rulesUuids: triggerDetails?.rules.map((rule) => rule.uuid) || [], ignoreTrigger: triggerDetails.ignoreTrigger, resource: triggerDetails.resource, type: triggerDetails.type, - actionsUuids: updatedActionGroupsUuid, + actionsUuids: updatedActionsUuid, + eventResource: triggerDetails.eventResource, + event: (triggerDetails.event as unknown as UpdateTriggerRequestDtoEventEnum) || undefined, }, }), ); @@ -193,14 +185,14 @@ const TriggerDetails = () => { rulesActions.updateTrigger({ triggerUuid: id, trigger: { - // actions: triggerDetails?.actions || [], rulesUuids: updatedRules, - // actionGroupsUuids: triggerDetails?.actionGroups?.map((actionGroup) => actionGroup.uuid) || [], - // triggerType: triggerDetails.triggerType, description: triggerDetails.description || '', ignoreTrigger: triggerDetails.ignoreTrigger, resource: triggerDetails.resource, type: triggerDetails.type, + actionsUuids: triggerDetails?.actions.map((action) => action.uuid) || [], + eventResource: triggerDetails.eventResource, + event: (triggerDetails.event as unknown as UpdateTriggerRequestDtoEventEnum) || undefined, }, }), ); @@ -252,9 +244,13 @@ const TriggerDetails = () => { columns: ['Name', triggerDetails.name, ''], }, { - id: 'triggerResource', + id: 'ignoreTrigger', + columns: ['Ignore Trigger', triggerDetails.ignoreTrigger ? 'Yes' : 'No', ''], + }, + { + id: 'eventResource', columns: [ - 'Trigger Resource', + 'Event Resource', triggerDetails?.eventResource ? getEnumLabel(resourceTypeEnum, triggerDetails.eventResource) : '', ], }, @@ -343,7 +339,7 @@ const TriggerDetails = () => { ], ); - const actionGroupFieldsDataHeader = useMemo( + const actionsDataHeader = useMemo( () => [ { id: 'name', @@ -361,16 +357,16 @@ const TriggerDetails = () => { [], ); - const actionGroupsFieldsData: TableDataRow[] = useMemo(() => { - const isDeleteDisabled = triggerDetails?.actions?.length === 0 || isUpdatingTrigger || isFetchingTriggerDetail; + const actionsData: TableDataRow[] = useMemo(() => { + const isDeleteDisabled = triggerDetails?.actions?.length === 1 || isUpdatingTrigger || isFetchingTriggerDetail; - const actionGroupData = !triggerDetails?.actions.length + const actionsData = !triggerDetails?.actions.length ? [] : triggerDetails?.actions.map((action) => { return { id: action.uuid, columns: [ - {action.name} || '', + {action.name} || '', action.description || '', - // - - // - //
, - // ], - // })); - // }, [selectedTriggers, triggers, eventNameEnum, resourceTypeEnum, triggerTypeEnum]); + const triggerTableData: TableDataRow[] = useMemo(() => { + const triggerDataListOrderedAsPerSelectedTriggers = triggers + .filter((trigger) => selectedTriggers.find((selectedTrigger) => selectedTrigger.value === trigger.uuid)) + .sort( + (a, b) => + selectedTriggers.findIndex((selectedTrigger) => selectedTrigger.value === a.uuid) - + selectedTriggers.findIndex((selectedTrigger) => selectedTrigger.value === b.uuid), + ); + + return triggerDataListOrderedAsPerSelectedTriggers.map((trigger, i) => ({ + id: trigger.uuid, + columns: [ + {trigger.name}, + getEnumLabel(resourceTypeEnum, trigger.eventResource || ''), + getEnumLabel(triggerTypeEnum, trigger.type), + getEnumLabel(eventNameEnum, trigger.event || ''), + getEnumLabel(resourceTypeEnum, trigger.resource || ''), + trigger.description || '', +
+ + + + +
, + ], + })); + }, [selectedTriggers, triggers, eventNameEnum, resourceTypeEnum, triggerTypeEnum]); return (
() }}> @@ -364,7 +364,7 @@ export default function DiscoveryForm() { )} - {/* +

Note: Triggers will be executed on newly discovered certificate in displayed order

@@ -373,12 +373,14 @@ export default function DiscoveryForm() { data={triggerTableData} headers={triggerHeaders} newRowWidgetProps={{ + selectHint: 'Select Triggers', + immidiateAdd: true, newItemsList: triggerOptions, isBusy, onAddClick: onUpdateTriggersConfirmed, }} /> -
*/} +
diff --git a/src/components/_pages/executions/form/index.tsx b/src/components/_pages/executions/form/index.tsx index 8c09d41e0..fe5cc5b0c 100644 --- a/src/components/_pages/executions/form/index.tsx +++ b/src/components/_pages/executions/form/index.tsx @@ -70,7 +70,6 @@ const ExecutionForm = () => { const onSubmit = useCallback( (values: ExecutionFormValues) => { if (values.resource === Resource.None || !values.type) return; - console.log('values', values); dispatch( rulesActions.createExecution({ executionRequestModel: { diff --git a/src/components/_pages/rules/detail/index.tsx b/src/components/_pages/rules/detail/index.tsx index 228b8cea5..29ddb3d83 100644 --- a/src/components/_pages/rules/detail/index.tsx +++ b/src/components/_pages/rules/detail/index.tsx @@ -1,5 +1,7 @@ +import { ApiClients } from 'api'; import CustomTable, { TableDataRow, TableHeader } from 'components/CustomTable'; import Dialog from 'components/Dialog'; +import ConditionsExecutionsList from 'components/ExecutionConditionItemsList'; import Widget from 'components/Widget'; import { WidgetButtonProps } from 'components/WidgetButtons'; import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; @@ -8,7 +10,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Link, useParams } from 'react-router-dom'; import { Button, ButtonGroup, Col, Container, Input, Row } from 'reactstrap'; -import { PlatformEnum } from 'types/openapi'; +import { PlatformEnum, Resource } from 'types/openapi'; interface SelectChangeValue { value: string; label: string; @@ -18,7 +20,7 @@ const RuleDetails = () => { const dispatch = useDispatch(); const ruleDetails = useSelector(rulesSelectors.ruleDetails); const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); - const isFetchingRuleDetail = useSelector(rulesSelectors.isFetchingRuleDetail); + const isFetchingRuleDetails = useSelector(rulesSelectors.isFetchingRuleDetails); const resourceTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.Resource)); const conditions = useSelector(rulesSelectors.conditions); const conditionTypeEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.ConditionType)); @@ -45,7 +47,7 @@ const RuleDetails = () => { dispatch(rulesActions.listConditions({ resource: ruleDetails?.resource })); }, [ruleDetails, dispatch]); - const isBusy = useMemo(() => isFetchingRuleDetail || isUpdatingRule, [isFetchingRuleDetail, isUpdatingRule]); + const isBusy = useMemo(() => isFetchingRuleDetails || isUpdatingRule, [isFetchingRuleDetails, isUpdatingRule]); const conditionsOptions = useMemo(() => { if (conditions === undefined) return []; @@ -152,7 +154,7 @@ const RuleDetails = () => { const ruleDetailsData: TableDataRow[] = useMemo( () => - !ruleDetails || isFetchingRuleDetail + !ruleDetails || isFetchingRuleDetails ? [] : [ { @@ -235,7 +237,7 @@ const RuleDetails = () => { updateDescriptionEditEnable, isUpdatingRule, updatedDescription, - isFetchingRuleDetail, + isFetchingRuleDetails, ], ); @@ -262,7 +264,7 @@ const RuleDetails = () => { ); const conditionsData: TableDataRow[] = useMemo(() => { - const isDeleteDisabled = ruleDetails?.conditions.length === 1 || isFetchingRuleDetail || isUpdatingRule; + const isDeleteDisabled = ruleDetails?.conditions.length === 1 || isFetchingRuleDetails || isUpdatingRule; const conditionsData = !ruleDetails?.conditions.length ? [] : ruleDetails?.conditions.map((condition) => { @@ -293,7 +295,7 @@ const RuleDetails = () => { }); return conditionsData; - }, [ruleDetails, isUpdatingRule, onDeleteCondition, isFetchingRuleDetail, conditionTypeEnum]); + }, [ruleDetails, isUpdatingRule, onDeleteCondition, isFetchingRuleDetails, conditionTypeEnum]); return ( @@ -325,7 +327,21 @@ const RuleDetails = () => { + {/* */} + {ruleDetails?.conditions.length ? ( + + apiClients.resources.listResourceRuleFilterFields({ + resource: ruleDetails?.resource || Resource.None, + }) + } + /> + ) : ( + <> + )} { const onSubmit = useCallback( (values: ruleFormValues) => { if (values.resource === Resource.None) return; - console.log('values', values); dispatch( rulesActions.createRule({ rule: { diff --git a/src/components/_pages/triggers/form/index.tsx b/src/components/_pages/triggers/form/index.tsx index 52c04e7d5..58a877417 100644 --- a/src/components/_pages/triggers/form/index.tsx +++ b/src/components/_pages/triggers/form/index.tsx @@ -139,7 +139,6 @@ const TriggerForm = () => { const onSubmit = useCallback( (values: TriggerFormValues) => { if (values.resource === Resource.None || values.eventResource === Resource.None || !values.triggerType) return; - console.log('values: ', values); dispatch( rulesActions.createTrigger({ trigger: { diff --git a/src/ducks/rules.ts b/src/ducks/rules.ts index e3d5e685d..fa46cc01a 100644 --- a/src/ducks/rules.ts +++ b/src/ducks/rules.ts @@ -42,7 +42,7 @@ export type State = { isFetchingTriggers: boolean; isCreatingAction: boolean; isFetchingActionDetails: boolean; - isFetchingRuleDetail: boolean; + isFetchingRuleDetails: boolean; isFetchingExecutionDetails: boolean; isFetchingConditionDetails: boolean; isFetchingTriggerDetail: boolean; @@ -78,7 +78,7 @@ export const initialState: State = { isFetchingConditions: false, isFetchingTriggers: false, isCreatingRule: false, - isFetchingRuleDetail: false, + isFetchingRuleDetails: false, isUpdatingExecution: false, isCreatingExecution: false, @@ -330,14 +330,14 @@ export const slice = createSlice({ state.isFetchingConditionDetails = false; }, getRule: (state, action: PayloadAction<{ ruleUuid: string }>) => { - state.isFetchingRuleDetail = true; + state.isFetchingRuleDetails = true; }, getRuleSuccess: (state, action: PayloadAction<{ rule: RuleDetailModel }>) => { state.ruleDetails = action.payload.rule; - state.isFetchingRuleDetail = false; + state.isFetchingRuleDetails = false; }, getRuleFailure: (state, action: PayloadAction<{ error: string | undefined }>) => { - state.isFetchingRuleDetail = false; + state.isFetchingRuleDetails = false; }, getTrigger: (state, action: PayloadAction<{ triggerUuid: string }>) => { @@ -471,7 +471,7 @@ const isFetchingRulesList = createSelector(state, (state) => state.isFetchingRul const isFetchingConditions = createSelector(state, (state) => state.isFetchingConditions); const isDeletingCondition = createSelector(state, (state) => state.isDeletingCondition); const isFetchingConditionDetails = createSelector(state, (state) => state.isFetchingConditionDetails); -const isFetchingRuleDetail = createSelector(state, (state) => state.isFetchingRuleDetail); +const isFetchingRuleDetails = createSelector(state, (state) => state.isFetchingRuleDetails); const isCreatingExecution = createSelector(state, (state) => state.isCreatingExecution); const isFetchingExecutions = createSelector(state, (state) => state.isFetchingExecutions); const isDeletingExecution = createSelector(state, (state) => state.isDeletingExecution); @@ -512,7 +512,7 @@ export const selectors = { isUpdatingCondition, isFetchingConditionDetails, isUpdatingRule, - isFetchingRuleDetail, + isFetchingRuleDetails, isCreatingExecution, isFetchingExecutions, isDeletingExecution, From f8c3b7d1efaa4f037d697b81d151fce98fe9dc07 Mon Sep 17 00:00:00 2001 From: Abhijit Bansode Date: Mon, 27 May 2024 14:53:48 +0530 Subject: [PATCH 7/8] add triggers table for discovery detail --- .../_pages/discoveries/detail/index.tsx | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/components/_pages/discoveries/detail/index.tsx b/src/components/_pages/discoveries/detail/index.tsx index 90b133ead..6258db97c 100644 --- a/src/components/_pages/discoveries/detail/index.tsx +++ b/src/components/_pages/discoveries/detail/index.tsx @@ -6,7 +6,7 @@ import Widget from 'components/Widget'; import { WidgetButtonProps } from 'components/WidgetButtons'; import { actions, selectors } from 'ducks/discoveries'; -import { selectors as enumSelectors } from 'ducks/enums'; +import { selectors as enumSelectors, getEnumLabel } from 'ducks/enums'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Link, useParams } from 'react-router-dom'; @@ -147,13 +147,17 @@ export default function DiscoveryDetail() { content: 'Name', }, { - id: 'triggerResource', - content: 'Trigger Resource', + id: 'eventResource', + content: 'Event Resource', }, { id: 'triggerType', content: 'Trigger Type', }, + { + id: 'ignoreTrigger', + content: 'Ignore Trigger', + }, { id: 'eventName', content: 'Event Name', @@ -168,19 +172,20 @@ export default function DiscoveryDetail() { }, ]; - // const triggerTableData: TableDataRow[] = discovery?.triggers.length - // ? discovery.triggers.map((trigger) => ({ - // id: trigger.uuid, - // columns: [ - // {trigger.name}, - // trigger?.triggerResource ? getEnumLabel(resourceTypeEnum, trigger.triggerResource) : '', - // getEnumLabel(triggerTypeEnum, trigger.triggerType), - // getEnumLabel(eventNameEnum, trigger.eventName || ''), - // getEnumLabel(resourceTypeEnum, trigger.resource || ''), - // trigger.description || '', - // ], - // })) - // : []; + const triggerTableData: TableDataRow[] = discovery?.triggers.length + ? discovery.triggers.map((trigger) => ({ + id: trigger.uuid, + columns: [ + {trigger.name}, + trigger?.eventResource ? getEnumLabel(resourceTypeEnum, trigger.eventResource) : '', + getEnumLabel(triggerTypeEnum, trigger.type), + trigger.ignoreTrigger ? 'Yes' : 'No', + getEnumLabel(eventNameEnum, trigger.event || ''), + getEnumLabel(resourceTypeEnum, trigger.resource || ''), + trigger.description || '', + ], + })) + : []; return ( @@ -200,9 +205,9 @@ export default function DiscoveryDetail() { - {/* + - */} + From f2c0f9bd6c1b0c27251c48154c7245a39072be3d Mon Sep 17 00:00:00 2001 From: Abhijit Bansode Date: Mon, 27 May 2024 16:35:21 +0530 Subject: [PATCH 8/8] code clean up --- .../Attributes/AttributeEditor/mock-data.tsx | 6 - .../AttributeViewer/AttributeViewer.cy.tsx | 1 - .../component/_pages/users/form/mock-data.ts | 5 - cypress/support/commands.tsx | 11 -- .../index.tsx | 177 +----------------- .../conditionsItemsList.module.scss | 1 - src/components/FilterWidget/index.tsx | 11 +- .../FilterWidgetRuleAction/index.tsx | 61 +----- .../_pages/actions/detail/index.tsx | 2 - src/components/_pages/actions/form/index.tsx | 7 +- .../_pages/approvals/list/index.tsx | 5 - .../_pages/conditions/form/index.tsx | 5 +- .../_pages/connectors/form/index.tsx | 6 - .../_pages/discoveries/form/index.tsx | 1 - .../_pages/executions/details/index.tsx | 1 - src/components/_pages/rules/form/index.tsx | 8 +- src/components/_pages/triggers/form/index.tsx | 6 +- 17 files changed, 14 insertions(+), 300 deletions(-) diff --git a/cypress/component/Attributes/AttributeEditor/mock-data.tsx b/cypress/component/Attributes/AttributeEditor/mock-data.tsx index 1899570c0..1414f6af9 100644 --- a/cypress/component/Attributes/AttributeEditor/mock-data.tsx +++ b/cypress/component/Attributes/AttributeEditor/mock-data.tsx @@ -111,7 +111,6 @@ export const customAttributeEditorMockData: AttributeEditorProps = { content: [ { data: { - // code: 'PGgxPk9EUE9WRcSOPC9oMT4KPGRpdj5Qb8SNw610YW1lIGtvxL5rbyBjZXJ0aWZpa8OhdG92IHR1IGplLjwvZGl2PgoKPHVsPgogIDxsaT5TdWJqZWN0OiAke25vdGlmaWNhdGlvbkRhdGEuc3ViamVjdERufTwvbGk+CiAgPGxpPlNlcmlhbCBOdW1iZXI6ICR7bm90aWZpY2F0aW9uRGF0YS5zZXJpYWxOdW1iZXJ9PC9saT4KICA8bGk+SXNzdWVyOiAke25vdGlmaWNhdGlvbkRhdGEuaXNzdWVyRG59PC9saT4KPC91bD4=', code: '', language: ProgrammingLanguageEnum.Html, }, @@ -133,11 +132,6 @@ export const customAttributeEditorMockData: AttributeEditorProps = { list: false, multiSelect: false, }, - // content: [ - // { - // data: '1.1', - // }, - // ], }, { uuid: 'test-uuid-7', diff --git a/cypress/component/Attributes/AttributeViewer/AttributeViewer.cy.tsx b/cypress/component/Attributes/AttributeViewer/AttributeViewer.cy.tsx index 48caa7911..523a20b9c 100644 --- a/cypress/component/Attributes/AttributeViewer/AttributeViewer.cy.tsx +++ b/cypress/component/Attributes/AttributeViewer/AttributeViewer.cy.tsx @@ -151,7 +151,6 @@ describe('AttributeViewer with Metadata', () => { it(`should check if source object table is opened in modal`, () => { cy.get('.fa-caret-down').eq(0).click().wait(clickWait); - // cy.get('.fa-arrow-up').eq(1).click().wait(clickWait); cy.get('.fa-info').eq(0).click().wait(clickWait); cy.get('.modal-content').should('be.visible'); diff --git a/cypress/component/_pages/users/form/mock-data.ts b/cypress/component/_pages/users/form/mock-data.ts index 6e91f279c..13bb33e56 100644 --- a/cypress/component/_pages/users/form/mock-data.ts +++ b/cypress/component/_pages/users/form/mock-data.ts @@ -196,9 +196,7 @@ const userFormMockData = { uuid: 'uuid-1234-text-custom-attribute', name: 'Text Me', label: 'Text Me', - // type: 'custom', type: AttributeType.Custom, - // contentType: 'text', contentType: AttributeContentType.Text, content: [ { @@ -211,7 +209,6 @@ const userFormMockData = { name: 'SomeCustom', label: 'SomeCustom', type: AttributeType.Custom, - // contentType: 'integer', contentType: AttributeContentType.Integer, content: [ @@ -225,7 +222,6 @@ const userFormMockData = { name: 'DepartmentAssociation', label: 'Department', type: AttributeType.Custom, - // contentType: 'string', contentType: AttributeContentType.String, content: [ { @@ -299,7 +295,6 @@ const userFormMockData = { name: 'Test Date', label: 'Test Date', type: AttributeType.Custom, - // contentType: 'date', contentType: AttributeContentType.Date, content: [ { diff --git a/cypress/support/commands.tsx b/cypress/support/commands.tsx index 7819c283d..38ac08c30 100644 --- a/cypress/support/commands.tsx +++ b/cypress/support/commands.tsx @@ -29,14 +29,3 @@ Cypress.Commands.add('mount', (component, options = {}, initialRoute = '/') => { return mount(wrapped, mountOptions); }); - -// Cypress.Commands.add("mount", mount); - -// Cypress.Commands.add('mountWithRouter', (component, route) => { -// // Mount the component with the Router context -// cy.mount(component, {}, route); -// }); - -// Cypress.Commands.add('dataCy', (value) => { -// return cy.get(`[data-cy=${value}]`); -// }); diff --git a/src/components/ConditionAndExecutionItemsViewer/index.tsx b/src/components/ConditionAndExecutionItemsViewer/index.tsx index 7bacc33be..b1813db47 100644 --- a/src/components/ConditionAndExecutionItemsViewer/index.tsx +++ b/src/components/ConditionAndExecutionItemsViewer/index.tsx @@ -23,18 +23,10 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup const isFetchingConditionDetails = useSelector(rulesSelectors.isFetchingConditionDetails); const isUpdatingCondition = useSelector(rulesSelectors.isUpdatingCondition); - // const ruleDetails = useSelector(rulesSelectors.ruleDetails); - // const isFetchingRuleDetails = useSelector(rulesSelectors.isFetchingRuleDetails); - // const isUpdatingRule = useSelector(rulesSelectors.isUpdatingRule); - const executionDetails = useSelector(rulesSelectors.executionDetails); const isFetchingExecutionDetails = useSelector(rulesSelectors.isFetchingExecutionDetails); const isUpdatingExecution = useSelector(rulesSelectors.isUpdatingExecution); - // const trigerDetails = useSelector(rulesSelectors.triggerDetails); - // const isFetchingTriggerDetail = useSelector(rulesSelectors.isFetchingTriggerDetail); - // const isUpdatingTrigger = useSelector(rulesSelectors.isUpdatingTrigger); - const [hasEffectRun, setHasEffectRun] = useState(false); const dispatch = useDispatch(); @@ -46,9 +38,7 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup useEffect(() => { if (!id) return; - // if (formType === 'rules' && id !== ruleDetails?.uuid) { - // dispatch(rulesActions.getRule({ ruleUuid: id })); - // } + if (formType === 'condtionItems' && id !== conditionDetails?.uuid) { dispatch(rulesActions.getCondition({ conditionUuid: id })); } @@ -56,38 +46,10 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup if (formType === 'executionItems' && id !== executionDetails?.uuid) { dispatch(rulesActions.getExecution({ executionUuid: id })); } - - // if (formType === 'actionGroup' && id !== actionGroupDetails?.uuid) { - // dispatch(rulesActions.getActionGroup({ actionGroupUuid: id })); - // } - - // if (formType === 'trigger' && id !== trigerDetails?.uuid) { - // dispatch(rulesActions.getTrigger({ triggerUuid: id })); - // } - }, [ - id, - dispatch, - formType, - conditionDetails?.uuid, - executionDetails?.uuid, - - // ruleDetails?.uuid, - - // actionGroupDetails?.uuid, - // trigerDetails?.uuid - ]); + }, [id, dispatch, formType, conditionDetails?.uuid, executionDetails?.uuid]); useEffect(() => { if (!hasEffectRun && editMode && id) { - // let currentConditions = []; - - // if (formType === 'rules') { - // if (ruleDetails?.uuid !== id) return; - // currentConditions = ruleDetails?.conditions || []; - // } else { - // if (conditionGroupsDetails?.uuid !== id) return; - // currentConditions = conditionGroupsDetails?.conditions || []; - // } if (formType == 'condtionItems') { if (conditionDetails?.uuid !== id) return; const currentConditions = conditionDetails?.items || []; @@ -96,24 +58,8 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup setHasEffectRun(true); dispatch(filterActions.setCurrentFilters({ currentFilters: currentFilters, entity: EntityType.CONDITIONS })); } - - // else { - // if (executionDetails?.uuid !== id) return; - // currentConditions = executionDetails?.items || []; - // } } - }, [ - editMode, - - // ruleDetails, - - conditionDetails, - - hasEffectRun, - dispatch, - formType, - id, - ]); + }, [editMode, conditionDetails, hasEffectRun, dispatch, formType, id]); useEffect(() => { return () => { @@ -122,56 +68,6 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - // const renderAppendContent = useMemo(() => { - // if (formType === 'rules' && ruleDetails?.conditionGroups && ruleDetails?.conditionGroups?.length > 0) { - // if (isFetchingRuleDetails || isUpdatingRule) return <>; - // return ; - // } - - // if (formType === 'trigger' && trigerDetails?.actionGroups && trigerDetails?.actionGroups?.length > 0) { - // if (isFetchingTriggerDetail || isUpdatingTrigger) return <>; - // return ; - // } else { - // return <>; - // } - // }, [ruleDetails, formType, trigerDetails, isFetchingRuleDetails, isFetchingTriggerDetail, isUpdatingRule, isUpdatingTrigger]); - - // const renderFilterWidgetForRules = useMemo(() => { - // if (formType !== 'rules' || !id || !ruleDetails) return null; - // const disableBadgeRemove = - // (ruleDetails.conditions.length === 1 && ruleDetails.conditionGroups.length === 0) || isFetchingRuleDetails || isUpdatingRule; - - // const isBusy = isFetchingRuleDetails || isUpdatingRule; - - // return ( - // - // apiClients.resources.listResourceRuleFilterFields({ - // resource, - // }) - // } - // disableBadgeRemove={disableBadgeRemove} - // onFilterUpdate={(currentFilters) => { - // const currentCondition = filterToConditionItems(currentFilters); - // dispatch( - // rulesActions.updateRule({ - // ruleUuid: id, - // rule: { - // conditions: currentCondition, - // conditionGroupsUuids: ruleDetails.conditionGroups.map((cg) => cg.uuid), - // description: ruleDetails.description || '', - // }, - // }), - // ); - // }} - // /> - // ); - // }, [resource, dispatch, formType, id, ruleDetails, renderAppendContent, isFetchingRuleDetails, isUpdatingRule]); - const renderFilterWidgetForConditionItems = useMemo(() => { if (formType !== 'condtionItems' || !id || !conditionDetails) return null; const disableBadgeRemove = conditionDetails.items.length === 1 || isFetchingConditionDetails || isUpdatingCondition; @@ -224,7 +120,6 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup settable: true, }) } - // actionsList={actionGroupDetails.actions} ExecutionsList={executionDetails.items} onActionsUpdate={(currentExecutionItems) => { dispatch( @@ -243,82 +138,18 @@ const ConditionAndExecutionItemsViewer = ({ resource, formType }: ConditionGroup ); }, [resource, dispatch, formType, id, executionDetails, isFetchingExecutionDetails, isUpdatingExecution]); - // const renderFilterWidgetForTrigger = useMemo(() => { - // if (formType !== 'trigger' || !id || !trigerDetails) return null; - // const isActionOnlyOne = trigerDetails.actions.length === 1; - // // const isActionGroupEmpty = trigerDetails.actionGroups.length === 0; - - // // const disableBadgeRemove = isActionOnlyOne && isActionGroupEmpty; - // const isBusy = isFetchingTriggerDetail || isUpdatingTrigger; - - // return ( - //
- // {/* - // apiClients.resources.listResourceRuleFilterFields({ - // resource, - // settable: true, - // }) - // } - // ExecutionsList={trigerDetails.actions} - // onActionsUpdate={(currentActions) => { - // dispatch( - // rulesActions.updateTrigger({ - // triggerUuid: id, - // trigger: { - // actions: currentActions, - // description: trigerDetails.description, - // triggerType: trigerDetails.triggerType, - // rulesUuids: trigerDetails.rules.map((r) => r.uuid), - // actionGroupsUuids: trigerDetails.actionGroups.map((ag) => ag.uuid), - // }, - // }), - // ); - // }} - // /> */} - //
- // ); - // }, [ - // resource, - // dispatch, - // formType, - // id, - // trigerDetails, - - // // renderAppendContent, - - // isFetchingTriggerDetail, - // isUpdatingTrigger, - // ]); - const renderWidgetConditionViewer = useMemo(() => { switch (formType) { case 'condtionItems': return renderFilterWidgetForConditionItems; - // case 'rules': - // return renderFilterWidgetForRules; case 'executionItems': return renderFilterWidgetForExecutionItems; - // case 'trigger': - // return renderFilterWidgetForTrigger; default: return null; } - }, [ - formType, - renderFilterWidgetForConditionItems, - // renderFilterWidgetForRules, - renderFilterWidgetForExecutionItems, - // renderFilterWidgetForTrigger, - ]); + }, [formType, renderFilterWidgetForConditionItems, renderFilterWidgetForExecutionItems]); return
{renderWidgetConditionViewer}
; }; diff --git a/src/components/ExecutionConditionItemsList/ConditionsItemsList/conditionsItemsList.module.scss b/src/components/ExecutionConditionItemsList/ConditionsItemsList/conditionsItemsList.module.scss index 9e3f0d942..307a44267 100644 --- a/src/components/ExecutionConditionItemsList/ConditionsItemsList/conditionsItemsList.module.scss +++ b/src/components/ExecutionConditionItemsList/ConditionsItemsList/conditionsItemsList.module.scss @@ -1,5 +1,4 @@ .groupConditionBadge { - // border: 1px solid rgb(78, 78, 78) !important; font-weight: 500; margin-right: 5px; margin-bottom: 5px; diff --git a/src/components/FilterWidget/index.tsx b/src/components/FilterWidget/index.tsx index 6c758ad64..8ae338e1e 100644 --- a/src/components/FilterWidget/index.tsx +++ b/src/components/FilterWidget/index.tsx @@ -42,20 +42,11 @@ interface Props { entity: EntityType; getAvailableFiltersApi: (apiClients: ApiClients) => Observable>; onFilterUpdate?: (currentFilters: SearchFilterModel[]) => void; - // appendInWidgetContent?: React.ReactNode; disableBadgeRemove?: boolean; busyBadges?: boolean; } -export default function FilterWidget({ - // appendInWidgetContent, - onFilterUpdate, - title, - entity, - getAvailableFiltersApi, - disableBadgeRemove, - busyBadges, -}: Props) { +export default function FilterWidget({ onFilterUpdate, title, entity, getAvailableFiltersApi, disableBadgeRemove, busyBadges }: Props) { const dispatch = useDispatch(); const searchGroupEnum = useSelector(enumSelectors.platformEnum(PlatformEnum.FilterFieldSource)); diff --git a/src/components/FilterWidgetRuleAction/index.tsx b/src/components/FilterWidgetRuleAction/index.tsx index 72cc1b0b4..a6c259783 100644 --- a/src/components/FilterWidgetRuleAction/index.tsx +++ b/src/components/FilterWidgetRuleAction/index.tsx @@ -24,7 +24,6 @@ interface Props { entity: EntityType; getAvailableFiltersApi: (apiClients: ApiClients) => Observable>; onActionsUpdate?: (actionRuleRequests: ExecutionItemModel[]) => void; - // appendInWidgetContent?: React.ReactNode; ExecutionsList?: ExecutionItemModel[]; includeIgnoreAction?: boolean; disableBadgeRemove?: boolean; @@ -34,7 +33,6 @@ interface Props { export default function FilterWidgetRuleAction({ ExecutionsList, onActionsUpdate, - // appendInWidgetContent, title, entity, getAvailableFiltersApi, @@ -58,8 +56,6 @@ export default function FilterWidgetRuleAction({ isEditEnabled: false, }); - // const [ruleActionType, setRuleActionType] = useState | undefined>(undefined); - const [fieldSource, setFieldSource] = useState | undefined>(undefined); const [filterField, setFilterField] = useState | undefined>(undefined); @@ -71,17 +67,6 @@ export default function FilterWidgetRuleAction({ | undefined >(undefined); - // const ruleActionsOptions = useMemo(() => { - // if (includeIgnoreAction) { - // return [ - // { label: getEnumLabel(executionTypeEnum, RuleActionType.Ignore), value: RuleActionType.Ignore }, - // { label: getEnumLabel(executionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }, - // ]; - // } else { - // return [{ label: getEnumLabel(executionTypeEnum, RuleActionType.SetField), value: RuleActionType.SetField }]; - // } - // }, [includeIgnoreAction, executionTypeEnum]); - const booleanOptions = useMemo( () => [ { label: 'True', value: true }, @@ -104,13 +89,11 @@ export default function FilterWidgetRuleAction({ ); const onUpdateClick = useCallback(() => { - // if (!ruleActionType?.value) return; if (!fieldSource?.value) return; if (!filterField?.value) return; if (!filterValue) return; const newExecution: ExecutionItemRequestModel = { - // actionType: ruleActionType?.value, fieldSource: fieldSource?.value, fieldIdentifier: filterField?.value, data: filterValue @@ -121,7 +104,6 @@ export default function FilterWidgetRuleAction({ : (filterValue as any).value : undefined, }; - // setRuleActionType(undefined); setFieldSource(undefined); setFilterField(undefined); setFilterValue(undefined); @@ -129,15 +111,10 @@ export default function FilterWidgetRuleAction({ if (selectedFilter.filterNumber === -1) { let updatedActions = []; - // if (newExecution.actionType === RuleActionType.Ignore) { - // updatedActions = [newExecution]; - // } else { updatedActions = [...actions, newExecution]; - // } setActions(updatedActions); const updatedActionDataActions = updatedActions.map((a) => { return { - // actionType: a.actionType, fieldSource: a.fieldSource, fieldIdentifier: a.fieldIdentifier, data: Array.isArray(a.data) @@ -158,7 +135,6 @@ export default function FilterWidgetRuleAction({ setActions(updatedActions); const updatedActionDataActions = updatedActions.map((a) => { return { - // actionType: a.actionType, fieldSource: a.fieldSource, fieldIdentifier: a.fieldIdentifier, data: Array.isArray(a.data) @@ -176,11 +152,9 @@ export default function FilterWidgetRuleAction({ setSelectedFilter({ filterNumber: -1, isEditEnabled: false }); } }, [ - // ruleActionType, fieldSource, filterField, filterValue, - // setRuleActionType, setFieldSource, setFilterField, setFilterValue, @@ -192,7 +166,6 @@ export default function FilterWidgetRuleAction({ useEffect(() => { if (selectedFilter.filterNumber === -1) { - // setRuleActionType(undefined); setFieldSource(undefined); setFilterField(undefined); setFilterValue(undefined); @@ -278,9 +251,6 @@ export default function FilterWidgetRuleAction({ return; } - // const selectedActionType = actions[selectedFilter.filterNumber].actionType; - // setRuleActionType({ label: getEnumLabel(executionTypeEnum, selectedActionType), value: selectedActionType }); - const field = actions[selectedFilter.filterNumber].fieldSource; if (!field) { setSelectedFilter({ filterNumber: selectedFilter.filterNumber, isEditEnabled: true }); @@ -410,8 +380,6 @@ export default function FilterWidgetRuleAction({ [objectValueOptions, filterValue, currentField], ); - // const isActionTypeIgnore = actions.some((a) => a.actionType === RuleActionType.Ignore); - const renderBadgeContent = useCallback( (itemNumber: number, value: string, label?: string, fieldSource?: string) => { if (isFetchingAvailableFilters || busyBadges) return <>; @@ -432,12 +400,7 @@ export default function FilterWidgetRuleAction({ [isFetchingAvailableFilters, onRemoveFilterClick, searchGroupEnum, disableBadgeRemove, busyBadges], ); - const isUpdateButtonDisabled = useMemo(() => { - { - // if (ruleActionType?.value === RuleActionType.Ignore) return false; - return !filterField || !fieldSource || !filterValue; - } - }, [filterField, fieldSource, filterValue]); + const isUpdateButtonDisabled = useMemo(() => !filterField || !fieldSource || !filterValue, [filterField, fieldSource, filterValue]); return ( <> @@ -445,23 +408,6 @@ export default function FilterWidgetRuleAction({
- {/* - - -