"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",
*/
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';
name: getWorkflowName(state),
versionName: getVersionInfo(state).name,
activities: activitiesSelector(state),
- inputOutput: getInputOutputForComposition(state)
+ inputOutput: getInputOutputForComposition(state),
+ errors: getErrors(state)
};
}
withButtons: true,
closeButtonText: I18n.t('buttons.okBtn')
})
- )
+ ),
+ validationUpdate: (element, isValid) =>
+ dispatch(updateValidation({ element, isValid }))
};
}
*/
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';
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,
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() {
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: {
workflow: {
activities: activities,
getActivityInputsOutputs: this.getActivityInputsOutputs,
- workflowInputOutput: inputOutput
+ workflowInputOutput: inputOutput,
+ validationUpdate: validationUpdate
}
});
this.setDiagramToBPMN(composition ? composition : newDiagramXML);
this.modeler.on('element.out', () => this.exportDiagramToStore());
this.bpmnContainer.current.click();
+ this.modeling = this.modeler.get('modeling');
}
getActivityInputsOutputs = selectedValue => {
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(
});
};
setDefaultIdAndName = businessObject => {
- const { name } = this.props;
+ const { name = '' } = this.props;
if (!businessObject.name) {
businessObject.name = name;
}
* 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
+});
* 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',
};
export const PROCESS_DEFAULT_ID = 'Process_1';
+
+export const COMPOSITION_ERROR_COLOR = '#f0c2c2';
+export const COMPOSITION_VALID_COLOR = 'white';
* 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;
}
*/
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;
},
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' }
: {};
},
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 {
workflowId: getWorkflowId(state),
versionsList: getSortedVersions(state),
savedParams: getSavedObjParams(state),
- getIOErrors: getIOErrors(state),
+ hasErrors: getIOErrors(state) || getCompositionHasErrors(state),
isCertifyDisable: getIsCertified(state),
currentWorkflowVersion: state.currentVersion.general
};
workflowId: PropTypes.string,
certifyVersion: PropTypes.func,
changeVersion: PropTypes.func,
- getIOErrors: PropTypes.bool,
- isCertifyDisable: PropTypes.bool
+ isCertifyDisable: PropTypes.bool,
+ hasErrors: PropTypes.bool
};
constructor(props) {
currentWorkflowVersion,
workflowName,
versionsList,
- getIOErrors,
+ hasErrors,
isCertifyDisable
} = this.props;
return (
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}
/>
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"