Commit 33561fb9 authored by DMyTryC's avatar DMyTryC Committed by abirembaut

Implementing the interdiction of saving as a fragment when a modal is… (#2572)

* Implementing the interdiction of saving as a fragment when a modal is inside the container

* Disable save as Fragment depending of validation
- Add tests
- Rework Button design
- change error icon color on editor header

* - Do not disable the button "Save as fragment on error
- Put tooltip on the button

* do not put error style on fragment
parent 2687d201
......@@ -30,7 +30,7 @@
}
save(artifact) {
artifact.hasValidationError = componentUtils.hasModalContainingModal(artifact);
artifact.hasValidationError = componentUtils.containsModalInContainer(artifact);
return super.save(artifact);
}
......
......@@ -51,7 +51,7 @@
*/
needSave(artifact) {
if (artifact && artifact.hasValidationError !== undefined) {
artifact.hasValidationError = componentUtils.hasModalContainingModal(artifact);
artifact.hasValidationError = componentUtils.containsModalInContainer(artifact);
}
return angular.toJson(artifact) !== this.lastSavedState;
}
......
......@@ -42,7 +42,7 @@
<open-preview on-open-preview="vm.save(vm.page)" mode="{{vm.mode}}" artifact-id="vm.page.id"
is-disabled="!formName.$valid || vm.isPageDirty(vm.page)"></open-preview>
<div ng-if="vm.page.hasValidationError" uib-tooltip="{{ 'Validation error on the page. Fix is recommended before export' | translate }}" tooltip-placement="bottom" tooltip-popup-delay="300" style="margin-left:10px">
<i class="fa fa-times-circle" style="color:red;"></i>
<i class="fa fa-times-circle error-icon"></i>
<translate>Validation Errors</translate>
</div>
<save-indicator class="EditorHeader-saveIndicator"></save-indicator>
......
......@@ -26,11 +26,11 @@
isEmpty: isEmpty,
isChildOf: isChildOf,
isMovable: isMovable,
hasModalContainingModal: hasModalContainingModal,
getVisibleComponents: getVisibleComponents,
isContainer: isContainer,
getResolutionClasses,
hasModalInSubContainers,
containsModalInContainer,
isModalInContainer,
column: {
width: columnWidth,
className: columnClass,
......@@ -150,9 +150,12 @@
return false;
}
function hasModalContainingModal(container, modalInParents) {
if (modalInParents && container.type === 'modalContainer') {
/**
* Returns true if the container passed contain a Modal in another container.
* (A modal that is not at the root of a Page/Form/layout.)
*/
function containsModalInContainer(container) {
if (isModalInContainer(container)) {
return true;
}
// We normalize container and tabs container into an array of rows
......@@ -161,32 +164,29 @@
container.container && container.container.rows ||
container.$$widget && container.$$widget.rows ||
(container.tabs || [])
.map(getTabRows)
.reduce(flattenReducer, []);
.map(getTabRows)
.reduce(flattenReducer, []);
if (rows.length === 0) {
return false;
}
if (modalInParents === undefined) {
modalInParents = container.type === 'modalContainer';
}
if (container.type === 'modalContainer') {
modalInParents = true;
}
// we reduce rows into an array of widget and iterate over it
// using some to stop when we found the widget
return rows
.reduce(flattenReducer, [])
.some(function(widget) {
return hasModalContainingModal(widget, this);
}, modalInParents);
return containsModalInContainer(widget);
});
}
function hasModalInSubContainers(container) {
return container.type === 'modalContainer' && (container.$$parentContainerRow.container.type === 'fragment' || container.$$parentContainerRow.container.type === 'container');
/**
* Returns true if the container passed is contains in another container than Page, form, or layout.
*/
function isModalInContainer(container) {
return container.type === 'modalContainer' &&
(container.$$parentContainerRow.container.type === 'fragment' ||
container.$$parentContainerRow.container.type === 'container');
}
/**
......
......@@ -106,11 +106,11 @@ angular.module('bonitasoft.designer.editor.whiteboard').controller('ContainerDir
return container && container.propertyValues && container.propertyValues.repeatedCollection && container.propertyValues.repeatedCollection.value;
};
$scope.hasModalContainingModal = function(container) {
return container && (container.type === 'modalContainer' || container.type === 'fragment') && componentUtils.hasModalContainingModal(container);
$scope.containsModalInContainer = function(container) {
return container && componentUtils.containsModalInContainer(container);
};
$scope.hasModalInSubContainers = function(container) {
return container && componentUtils.hasModalInSubContainers(container);
$scope.isModalInContainer = function(container) {
return container && componentUtils.isModalInContainer(container);
};
});
......@@ -15,8 +15,8 @@
</div>
<div ng-repeat="component in row" class="component" ng-class="editor.componentClasses(component)" bo-draggable bo-draggable-data="component" bo-drop-item="dropItem($data, row, rowIndex)">
<i ng-if="hasModalInSubContainers(component)" class="fa fa-times-circle Component-marker error-icon" title="{{ 'A modal container cannot be located in another container. Recommendation: drop all modal containers at the bottom of the whiteboard.' | translate }}"></i>
<div ng-include="component.$$templateUrl" ng-class="{'error':hasModalInSubContainers(component)}"></div>
<i ng-if="isModalInContainer(component)" class="fa fa-times-circle Component-marker error-icon" title="{{ 'A modal container cannot be located in another container. Recommendation: drop all modal containers at the bottom of the whiteboard.' | translate }}"></i>
<div ng-include="component.$$templateUrl" ng-class="{'error':isModalInContainer(component)}"></div>
</div>
<div ng-if="editor.rowSize(row) < 12"
......
......@@ -237,8 +237,7 @@
}
.error {
.modal-element,
.fragment-element{
.modal-element{
border-color: @btn-bonita-primary-bg;
}
}
......
......@@ -133,6 +133,11 @@ describe('pageRepo', function() {
page.rows[0].push(
{
$$id: 'pbModalContainer-1',
$$parentContainerRow: {
container: {
type: 'page',
}
},
type: 'modalContainer',
id: 'pbModalContainer',
container: {
......@@ -150,6 +155,11 @@ describe('pageRepo', function() {
page.rows[0].push(
{
$$id: 'pbModalContainer-2',
$$parentContainerRow: {
container: {
type: 'page',
}
},
type: 'modalContainer',
id: 'pbModalContainer',
container: {
......@@ -167,6 +177,11 @@ describe('pageRepo', function() {
page.rows[0][0].container.rows[0].push(
{
$$id: 'pbModalContainer-3',
$$parentContainerRow: {
container: {
type: 'container',
}
},
type: 'modalContainer',
id: 'pbModalContainer',
container: {
......@@ -184,6 +199,11 @@ describe('pageRepo', function() {
page.rows[0][0].container.rows[0][0].container.rows[0].push(
{
$$id: 'pbModalContainer-4',
$$parentContainerRow: {
container: {
type: 'container',
}
},
type: 'modalContainer',
id: 'pbModalContainer',
container: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment