composition errors validation 38/70238/1
authorStanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
Thu, 11 Oct 2018 08:55:50 +0000 (11:55 +0300)
committerStanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
Thu, 11 Oct 2018 08:58:27 +0000 (11:58 +0300)
Issue-ID: SDC-1591
Change-Id: Ie46e1e4bb04c90d1324909d419e3cfe290e881eb
Signed-off-by: Stanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
workflow-designer-ui/src/main/frontend/package.json
workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionActions.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionReducer.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionSelectors.js
workflow-designer-ui/src/main/frontend/src/features/version/composition/custom-properties-provider/provider/camunda/parts/implementation/WorkflowActivity.js
workflow-designer-ui/src/main/frontend/src/features/version/versionController/VersionController.js
workflow-designer-ui/src/main/frontend/src/features/version/versionController/VersionControllerView.jsx
workflow-designer-ui/src/main/frontend/yarn.lock

index 6fdf442..62b06cb 100644 (file)
@@ -27,6 +27,7 @@
                "inherits": "^2.0.3",
                "lodash.assign": "^4.2.0",
                "lodash.isempty": "^4.4.0",
+               "lodash.isequal": "^4.5.0",
                "lodash.map": "^4.6.0",
                "lodash.merge": "^4.6.1",
                "lodash.set": "^4.3.2",
index d898f71..c9fc4b5 100644 (file)
 */
 import { connect } from 'react-redux';
 import { I18n } from 'react-redux-i18n';
-import { updateComposition } from './compositionActions';
+import { updateComposition, updateValidation } from './compositionActions';
 import CompositionView from './CompositionView';
 import { showErrorModalAction } from '../../../shared/modal/modalWrapperActions';
-import { getComposition } from './compositionSelectors';
+import { getComposition, getErrors } from './compositionSelectors';
 import { getWorkflowName } from '../../workflow/workflowSelectors';
 import { activitiesSelector } from 'features/activities/activitiesSelectors';
 import { getInputOutputForComposition } from 'features/version/inputOutput/inputOutputSelectors';
@@ -29,7 +29,8 @@ function mapStateToProps(state) {
         name: getWorkflowName(state),
         versionName: getVersionInfo(state).name,
         activities: activitiesSelector(state),
-        inputOutput: getInputOutputForComposition(state)
+        inputOutput: getInputOutputForComposition(state),
+        errors: getErrors(state)
     };
 }
 
@@ -45,7 +46,9 @@ function mapDispatchToProps(dispatch) {
                     withButtons: true,
                     closeButtonText: I18n.t('buttons.okBtn')
                 })
-            )
+            ),
+        validationUpdate: (element, isValid) =>
+            dispatch(updateValidation({ element, isValid }))
     };
 }
 
index c19ef94..eac3083 100644 (file)
@@ -15,6 +15,7 @@
 */
 import React, { Component } from 'react';
 import fileSaver from 'file-saver';
+import isEqual from 'lodash.isequal';
 import CustomModeler from './custom-modeler';
 import propertiesPanelModule from 'bpmn-js-properties-panel';
 import propertiesProviderModule from './custom-properties-provider/provider/camunda';
@@ -24,7 +25,12 @@ import PropTypes from 'prop-types';
 import CompositionButtons from './components/CompositionButtonsPanel';
 import { setElementInputsOutputs } from './bpmnUtils.js';
 import { I18n } from 'react-redux-i18n';
-import { PROCESS_DEFAULT_ID } from './compositionConstants';
+import {
+    PROCESS_DEFAULT_ID,
+    COMPOSITION_ERROR_COLOR,
+    COMPOSITION_VALID_COLOR
+} from './compositionConstants';
+
 class CompositionView extends Component {
     static propTypes = {
         compositionUpdate: PropTypes.func,
@@ -33,7 +39,9 @@ class CompositionView extends Component {
         name: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
         versionName: PropTypes.string,
         inputOutput: PropTypes.object,
-        activities: PropTypes.array
+        activities: PropTypes.array,
+        validationUpdate: PropTypes.func,
+        errors: PropTypes.array
     };
 
     constructor() {
@@ -46,9 +54,25 @@ class CompositionView extends Component {
             diagram: false
         };
     }
-
+    componentDidUpdate(prevProps) {
+        const { errors } = this.props;
+        if (!isEqual(prevProps.errors, errors)) {
+            errors.map(item => {
+                this.modeling.setColor([item.element], {
+                    fill: item.isValid
+                        ? COMPOSITION_VALID_COLOR
+                        : COMPOSITION_ERROR_COLOR
+                });
+            });
+        }
+    }
     componentDidMount() {
-        const { composition, activities, inputOutput } = this.props;
+        const {
+            composition,
+            activities,
+            inputOutput,
+            validationUpdate
+        } = this.props;
 
         this.modeler = new CustomModeler({
             propertiesPanel: {
@@ -64,7 +88,8 @@ class CompositionView extends Component {
             workflow: {
                 activities: activities,
                 getActivityInputsOutputs: this.getActivityInputsOutputs,
-                workflowInputOutput: inputOutput
+                workflowInputOutput: inputOutput,
+                validationUpdate: validationUpdate
             }
         });
 
@@ -72,6 +97,7 @@ class CompositionView extends Component {
         this.setDiagramToBPMN(composition ? composition : newDiagramXML);
         this.modeler.on('element.out', () => this.exportDiagramToStore());
         this.bpmnContainer.current.click();
+        this.modeling = this.modeler.get('modeling');
     }
 
     getActivityInputsOutputs = selectedValue => {
@@ -96,9 +122,9 @@ class CompositionView extends Component {
                     I18n.t('workflow.composition.importErrorMsg')
                 );
             }
-            let canvas = modeler.get('canvas');
+            const canvas = modeler.get('canvas');
             canvas.zoom('fit-viewport');
-            let { businessObject } = canvas._rootElement;
+            const { businessObject } = canvas._rootElement;
 
             this.setDefaultIdAndName(businessObject);
             setElementInputsOutputs(
@@ -109,7 +135,7 @@ class CompositionView extends Component {
         });
     };
     setDefaultIdAndName = businessObject => {
-        const { name } = this.props;
+        const { name = '' } = this.props;
         if (!businessObject.name) {
             businessObject.name = name;
         }
index 3f1755d..b11c956 100644 (file)
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-import { SET_COMPOSITION } from './compositionConstants';
+import { SET_COMPOSITION, UPDATE_ERRORS } from './compositionConstants';
 
 export const updateComposition = payload => ({
     type: SET_COMPOSITION,
     payload
 });
+
+export const updateValidation = payload => ({
+    type: UPDATE_ERRORS,
+    payload
+});
index 7f3537f..79c7e8e 100644 (file)
@@ -14,6 +14,7 @@
 * limitations under the License.
 */
 export const SET_COMPOSITION = 'composition/SET_COMPOSITION';
+export const UPDATE_ERRORS = 'composition/UPDATE_ERRORS';
 
 export const bpmnElementsTypes = {
     EXTENSION_ElEMENTS: 'bpmn:ExtensionElements',
@@ -23,3 +24,6 @@ export const bpmnElementsTypes = {
 };
 
 export const PROCESS_DEFAULT_ID = 'Process_1';
+
+export const COMPOSITION_ERROR_COLOR = '#f0c2c2';
+export const COMPOSITION_VALID_COLOR = 'white';
index 9c70736..9ad0f67 100644 (file)
 * limitations under the License.
 */
 import { SET_COMPOSITION } from './compositionConstants';
+import { UPDATE_ERRORS } from './compositionConstants';
 
-export default (state = {}, action) => {
+export default (state = { diagram: false, errors: [] }, action) => {
     switch (action.type) {
         case SET_COMPOSITION:
             return {
+                ...state,
                 diagram: action.payload
             };
+        case UPDATE_ERRORS: {
+            const filteredErrors = state.errors.filter(
+                el => el.id !== action.payload.id
+            );
+            return {
+                ...state,
+                errors: [...filteredErrors, action.payload]
+            };
+        }
         default:
             return state;
     }
index 7e28ca6..e6b51f1 100644 (file)
 */
 export const getComposition = state =>
     state && state.currentVersion && state.currentVersion.composition.diagram;
+
+export const getCompositionHasErrors = state =>
+    state &&
+    state.currentVersion &&
+    state.currentVersion.composition &&
+    state.currentVersion.composition.errors &&
+    Boolean(
+        state.currentVersion.composition.errors.find(item => !item.isValid)
+    );
+
+export const getErrors = state =>
+    state &&
+    state.currentVersion &&
+    state.currentVersion.composition &&
+    state.currentVersion.composition.errors;
index 50d53b5..6616f6a 100644 (file)
@@ -69,7 +69,11 @@ const workflowActivity = (element, config, bpmnFactory, options, translate) => {
         },
 
         validate: function(element, values) {
-            return isWorkflowActivity(element) && !values.workflowActivity
+            const hasErrors =
+                isWorkflowActivity(element) && !values.workflowActivity;
+            config.validationUpdate(element, !hasErrors);
+
+            return hasErrors
                 ? { workflowActivity: 'Must provide a value' }
                 : {};
         },
index 3a4b71d..5c33433 100644 (file)
@@ -32,6 +32,7 @@ import {
 import { workflowVersionFetchRequestedAction } from '../versionConstants';
 import { getIsCertified } from 'features/version/general/generalSelectors';
 import { getIOErrors } from 'features/version/inputOutput/inputOutputSelectors';
+import { getCompositionHasErrors } from 'features/version/composition/compositionSelectors';
 
 function mapStateToProps(state) {
     return {
@@ -39,7 +40,7 @@ function mapStateToProps(state) {
         workflowId: getWorkflowId(state),
         versionsList: getSortedVersions(state),
         savedParams: getSavedObjParams(state),
-        getIOErrors: getIOErrors(state),
+        hasErrors: getIOErrors(state) || getCompositionHasErrors(state),
         isCertifyDisable: getIsCertified(state),
         currentWorkflowVersion: state.currentVersion.general
     };
index 3f47b44..88157e9 100644 (file)
@@ -36,8 +36,8 @@ export default class VersionControllerView extends Component {
         workflowId: PropTypes.string,
         certifyVersion: PropTypes.func,
         changeVersion: PropTypes.func,
-        getIOErrors: PropTypes.bool,
-        isCertifyDisable: PropTypes.bool
+        isCertifyDisable: PropTypes.bool,
+        hasErrors: PropTypes.bool
     };
 
     constructor(props) {
@@ -95,7 +95,7 @@ export default class VersionControllerView extends Component {
             currentWorkflowVersion,
             workflowName,
             versionsList,
-            getIOErrors,
+            hasErrors,
             isCertifyDisable
         } = this.props;
         return (
@@ -109,9 +109,9 @@ export default class VersionControllerView extends Component {
                         onVersionSelectChange={this.versionChangeCallback}
                     />
                     <ActionButtons
-                        saveDisabled={isCertifyDisable || getIOErrors}
+                        saveDisabled={isCertifyDisable || hasErrors}
                         onSaveClick={this.sendSaveParamsToServer}
-                        certifyDisabled={isCertifyDisable || getIOErrors}
+                        certifyDisabled={isCertifyDisable || hasErrors}
                         onCertifyClick={this.certifyVersion}
                         onUndoClick={this.undoClickCallback}
                     />
index c984790..4235c3d 100644 (file)
@@ -7032,6 +7032,10 @@ lodash.isempty@^4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
 
+lodash.isequal@^4.5.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+
 lodash.isplainobject@^4.0.6:
   version "4.0.6"
   resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"