Subversion Repositories bacoAlunos

Rev

Rev 1785 | Rev 1791 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/tlds/struts-nested.tld" prefix="nested" %>
<%@ taglib uri="/WEB-INF/tlds/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/tlds/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/tlds/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/tlds/baco.tld" prefix="baco" %>
<%@ taglib uri="/WEB-INF/tlds/jomm.tld" prefix="jomm" %>
<%@ page import="jomm.dao.impl.AbstractDao" %>
<%@ page import="pt.estgp.estgweb.domain.BpmnProcessImpl" %>
<%@ page import="pt.estgp.estgweb.domain.dao.DaoFactory" %>
<%@ page import="pt.estgp.estgweb.web.filters.UserRoleProxy" %>
<%@ taglib tagdir="/WEB-INF/tags" prefix="bacoTags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%

    Long processId = Long.parseLong(request.getParameter("id"));
    AbstractDao.getCurrentSession().beginTransaction();
    BpmnProcessImpl process = (BpmnProcessImpl) DaoFactory.getBpmnProcessDaoImpl().get(processId);


%>

<style>
    div.dirty
    {
        border: 3px dashed orangered !important;
    }
</style>


<link rel="stylesheet" href="<%=request.getContextPath()%>/user/pagecontent/jorgeaux/angulartree/bower_components/angular-ui-tree/dist/angular-ui-tree.min.css">
<script type="text/javascript" src="<%=request.getContextPath()%>/user/pagecontent/jorgeaux/angulartree/bower_components/angular-ui-tree/dist/angular-ui-tree.js"></script>


<div class="container-fluid"
     id="processEditorModule"
     ng-app="processEditorModule"
     ng-controller="processEditorModuleController"
     ng-init="initBuilder()">

<style>
    .has-error .chosen-container
    {
        border: 1px solid #a94442 !important;
    }
</style>

<script>

var exampleBacoJs = {
    "xpto" : 1,
    "@class" : "pt.estgp.estgweb.domain.XptoSchool",
    "zgt" : {
        "zgt1" : 1,
        "zgt2" : 2,
        "@class" : "pt.estgp.estgweb.domain.ZgtDepartment"
    }
}
//does not affect angular JS lib
//you can use-it with angular
//var orderedExample = BacoJS.stringifyOrdered(exampleBacoJs);
//console.log(orderedExample);



//DECLARACAO DA APLICACAO LOCAL EM ANGULAR
var processEditorModule = angular.module('processEditorModule', ['ui.tree']);
GLOBAL_BacoAngularAppDependencies.push('processEditorModule');

/**Fim de directiva reutilizavel**/





processEditorModule.controller('processEditorModuleController', function($scope,$interval,$filter)
{
    $scope.callService = function(service,parameters,callback)
    {
        widgetCallWithActionParameters(
                "<%=request.getContextPath()%>/admin/bpmn/bpmnController.do",
                service,
                parameters,
                "#processEditorModule",
                function(jsonAnswer)
                {
                    callback(jsonAnswer);
                    $scope.$apply();
                }
        );
    }
    $scope.callSimpleService = function(service,parameters,callback)
    {
        widgetSimpleCallWithActionParameters(
                "<%=request.getContextPath()%>/admin/bpmn/bpmnController.do",
                service,
                parameters,
                "#processEditorModule",
                function()
                {
                    callback();
                    $scope.$apply();
                }
        );
    }

    /*
    * Variaveis e metodos auxiliares
    * */

    $scope.allFlowComponents = [];
    $scope.autoSavesObjects = [];
    $scope.idTemp = -1;
    $scope.jsps = [];

    $scope.variaveisConstantes = [
        "Formulario",
        "Processo",
        "Tarefa",
        "User Executante",
        "User Iniciador Processo",
        "UserSession"


    ];


    $scope.initBuilder = function()
    {
        $scope.initJsps();
        $scope.inicializarSaves();
        $scope.copiaFlowComponentsDasActorPools();
    }


    $scope.initJsps = function()
    {
        $scope.callService("loadJspsPlugins",{},function(interfaces)
        {
            $scope.jsps = interfaces.jsps;
            $scope.$apply();
            $(".angularChosen").chosen();
        });
    }

    $scope.inicializarSaves = function()
    {
        $interval($scope.autoSaves,2000);
    }

    $scope.copiaFlowComponentsDasActorPools = function()
    {
        for(x in $scope.process.actorPools)
        {
            var pool = $scope.process.actorPools[x];
            for(y in pool.flowComponents)
            {
                var flowComponent = pool.flowComponents[y];
                $scope.allFlowComponents.push(flowComponent);
            }
        }
    }

    $scope.autoSaves = function()
    {
        for(x in $scope.process.actorPools)
        {
            var pool = $scope.process.actorPools[x];
            if(pool.dirty == true)
            {

            }
            for(y in pool.flowComponents)
            {
                var flowComponent = pool.flowComponents[y];
                if(flowComponent.dirty == true)
                {
                    //flowComponent.dirty = false;
                    //todo if para ver se é task pode ser gateway ou event
                    //so estou a meter as tasks nos flow components não estou a meter os gateways nem os eventos
                    var flowComponentCall = flowComponent;
                    $scope.callSimpleService("updateTask",{"object":JSON.stringify(flowComponent)},function()
                    {
                        flowComponentCall.dirty = false;
                        //alert("Apagando dirty");
                        $scope.$apply();
                    });
                }
                for(z in flowComponent.flowConnectors)
                {
                    var flowConnector = flowComponent.flowConnectors[z];
                    if(flowConnector.dirty == true)
                    {
                        var flowConnectorCall = flowConnector;
                        $scope.callSimpleService("updateConnector",{"object":JSON.stringify(flowConnector)},function()
                        {
                            flowConnectorCall.dirty = false;
                            $scope.$apply();
                        });

                    }
                }
            }
        }
        for(x in $scope.process.actorPools)
        {
            var obj = $scope.process.actorPools[x];
            if(obj.dirty == true)
            {

            }
        }
    }




    /** Funções que interagem com directiva reutilizavel **/
    $scope.save = function() {
        $scope.$broadcast('show-errors-check-validity');

        if (!$scope.processoForm.$invalid) {
            alert('User saved');
            //$scope.reset();
        }
        else
        {
            alert("Existem erros no form");
        }
    };
    $scope.reset = function() {
        $scope.$broadcast('show-errors-reset');
        $scope.user = { name: '', email: '' };
    }
    /** Fim de Funções que interagem com directiva reutilizavel **/


    /*
    * Funcoes e variaveis especificas do Processo
    *
    * */

    $scope.process = <%=process.toJson()%>;

    $scope.removeActorPool = function(poolId,$index)
    {
        var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
        if(pool.flowComponents && pool.flowComponents.length > 0)
        {
            alert("Não pode apagar esta pool com atividades no seu interior");
        }
        else
        {
            $scope.callSimpleService("removeActorPool",{"poolId":pool.id},function()
            {
                $scope.process.actorPools.splice($index,1);
            });
        }
    }

    $scope.removeTask = function (poolId,taskId,$index)
    {
        $scope.callSimpleService("removeTask",{"poolId":poolId,"taskId":taskId},function()
        {
            var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
            pool.flowComponents.splice($index,1);
            var taskInAllFlows = $filter('filter')($scope.allFlowComponents, {id: taskId })[0];
            var index = $scope.allFlowComponents.indexOf(taskInAllFlows );
            $scope.allFlowComponents.splice(index,1);
        });
    }

    $scope.removeConnector = function (connectorId,taskId,poolId,$index)
    {
        $scope.callSimpleService("removeConnector",{"taskId":taskId,"connectorId":connectorId},function()
        {
            var pool = $filter('filter')($scope.process.actorPools, {id: poolId })[0];
            var task = $filter('filter')(pool.flowComponents, {id: taskId })[0];
            task.flowConnectors.splice($index,1);
        });
    }

    $scope.setDirty = function(obj)
    {
        obj.dirty = true;
        $scope.autoSavesObjects.push(obj);
    }

    $scope.selected = null;
    $scope.select = function(node)
    {
        if($scope.selected)
        {
            delete $scope.selected.selected;
        }
        $scope.selected = node;
        node.selected = true;
    }



    $scope.newActorPool = function()
    {
        $scope.callService("addActorPool",{"processId":$scope.process.id},function(actorPool)
        {
            if($scope.process.actorPools == null)
                $scope.process.actorPools = [];
            $scope.process.actorPools.push(actorPool);
            $scope.$apply();
            invokeChosenSelects("#bpmnPools");
        });
    }

    $scope.addTaskActor = function(pool)
    {
        $scope.callService("addTaskActor",{"poolId":pool.id},function(taskActor)
        {
            if(pool.flowComponents == null)
                pool.flowComponents = [];
            pool.flowComponents.push(taskActor);
            $scope.allFlowComponents.push(taskActor);
            $scope.$apply();
            //invokeChosenSelects("#bpmnPools");
        });
    }

    $scope.addConnector = function(task)
    {
        $scope.callService("addConnector",{"taskId":task.id},function(connector)
        {
            //connector = orderKeys(connector);
            if(task.flowConnectors == null)
                task.flowConnectors = [];
            task.flowConnectors.push(connector);
            $scope.$apply();
            //invokeChosenSelects("#bpmnPools");
        });
    }

    $scope.orderConnector = function(connector)
    {
        orderKeys(connector);
    }

    $scope.orderKeysRecursive = function(object)
    {
        console.log(BacoJS.stringifyOrdered(object));
    }

    $scope.newRoleForPool = function(item)
    {
        $scope.idTemp--;
        if(item.roles == null)
        {
            item.roles = [];
        }
        item.roles.push(
                {
                    "role" : "",
                    "trans" : ""
                }
        );
        //O chosen está off para que na primeira interação nao actue sobre
        //o option padrão que está sempre presente para preenchimento pelo Angular
        setTimeout(function() { invokeChosenSelects("#bpmnPools"); }, 100);
    }

});
/**
 Directiva showErrors reutilizavel para validação de forms groups
 Basta que um campo no form tenha a classe form-control*

 em cada campo onde quisermos validação é necessario colocar show-errors no container
 e dar um nome unico ao input a validar e também a directiva required

 é necessario dar o nome processoForm neste caso para o save atuar sobre a verificacao de validade da form
 é necessario definir a class .has-error .chosen-container com #a94442 e !important para se sobrebor nos selects do chosen
 */

processEditorModule.directive('showErrors', function($timeout) {
    return {
        restrict: 'A',
        require:  '^form',
        link: function (scope, el, attrs, formCtrl)
        {
            scope.initOk = function(scope, el, attrs, formCtrl) {

                var inputEl   = el[0].querySelector("[name]");
                var inputNgEl = angular.element(inputEl);

                var inputName = inputNgEl.attr('name');

                var blurred = false;
                // only apply the has-error class after the user leaves the text box
                inputNgEl.bind('blur', function() {
                    blurred = true;
                    el.toggleClass('has-error', formCtrl[inputName].$invalid);
                });

                scope.$watch(function() {
                            return formCtrl[inputName].$invalid
                        },
                        function(invalid) {
                            // we only want to toggle the has-error class after the blur
                            // event or if the control becomes valid
                            if (!blurred && invalid) { return }
                            el.toggleClass('has-error', invalid);

                        });


                scope.$on('show-errors-check-validity', function() {
                    el.toggleClass('has-error', formCtrl[inputName].$invalid);
                });

                scope.$on('show-errors-reset', function() {
                    $timeout(function() {
                        el.removeClass('has-error');
                    }, 0, false);
                });
            }
            scope.initClean = function(scope, el, attrs, formCtrl) {


                var inputEl   = el[0].querySelector("[name]");
                var inputNgEl = angular.element(inputEl);

                //scope.$watch("processoForm", function( newValue, oldValue ) {
                if ( inputNgEl.attr('name').indexOf("{")>=0 ) {
                    console.log( "Sujo..." + inputNgEl.attr('name'));
                    $timeout(function() {
                                scope.initClean(scope, el, attrs, formCtrl);
                            }
                            , 100);
                    return;
                }
                else{
                    console.log("LIMPO..." + inputNgEl.attr('name'));
                    scope.initOk(scope, el, attrs, formCtrl);
                }
                //});
            };

            scope.initClean(scope, el, attrs, formCtrl);
        }
    }
});

</script>

<!--TODO TIRAR DAQUI-->
<select ng-model="jsp" class="chosenOff angularChosen" ng-options="o for o in jsps"></select>

<style>
   body{ height: 100vh !important }
</style>
<div class="web-messages"></div>
<form  style="height: 80vh" class="row" name="processoForm">

    <div  style="height: 80vh;overflow-y: auto;" class="col-md-6 form-horizontal">
        <button type="button" ng-click="orderKeysRecursive(process)">Ordena</button>
        <div class="panel panel-primary">
            <div class="panel-heading">
                Identificação do Processo
            </div>
            <div class="panel-body">
                <div class="form-group">
                    <label class="col-md-2 control-label">Classe:</label>
                    <div class="col-md-10">
                        <select  name="process.class" ng-model="process.class" class="chosenOff form-control">
                            <option value="BpmnProcessImpl" ng-selected="{{process.class == 'BpmnProcessImpl'}}">Processo Genérico</option>
                            <option value="BpmnProcessControloAtividadeDocenteImpl" ng-selected="{{process.class == 'BpmnProcessControloAtividadeDocenteImpl'}}">Controlo de Atividade Docente</option>
                        </select>
                    </div>
                </div>
                <div class="form-group" show-errors>
                    <label class="col-md-2 control-label">Nome:</label>
                    <div class="col-md-10"><input name="process.name" required class="form-control" ng-model="process.name"></div>
                </div>
                <div class="form-group" show-errors>
                    <label class="col-md-2 control-label">Description:</label>
                    <div class="col-md-10"><textarea name="process.description" required rows="5" class="form-control" ng-model="process.description"></textarea></div>
                </div>

                <div id="controloAtividadeDocente" ng-if="process.class == 'BpmnProcessControloAtividadeDocenteImpl'">
                    <div class="well well-sm">
                        Controlo de Atividade Docente
                        <a class="pull-right btn btn-success btn-xs" data-nodrag ng-click="newAtividadePontuada()" style="margin-right: 8px;">
                            <span class="glyphicon glyphicon-plus"></span></a>
                    </div>
                    <table class="table">
                        <thead>
                        <tr>
                            <th>Chave ID</th>
                            <th style="width: 50%">Papel Validador</th>
                            <th>Pontos</th>
                            <th>Tipo de Atividade</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr ng-repeat="a in process.esquemaPontos.atividades">
                            <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].tipoAtividadeChave" required type="text" class="form-control" ng-model="a.tipoAtividadeChave"></td>
                            <td show-errors>
                                <select name="process.esquemaPontos.atividades[{{$index}}].papelValidador" required class="chosenOff form-control" ng-model="a.papelValidador" class="form-control">
                                    <%
                                        for(String role: UserRoleProxy.getUserRoles())
                                        {
                                            request.setAttribute("role",role);
                                    %>
                                    <option value="${role}" ng-selected="{{a.papelValidador == '${role}'}}"><bean:message key="user.role.${role}"/></option>
                                    <%
                                        }
                                    %>
                                </select>
                            </td>
                            <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].pontos" required type="text" class="form-control" ng-model="a.pontos"></td>
                            <td show-errors><input name="process.esquemaPontos.atividades[{{$index}}].tipoAtividadeNome" required type="text" class="form-control" ng-model="a.tipoAtividadeNome"></td>
                        </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

        <div class="panel panel-info panel-block" id="bpmnPools">
            <div class="panel-heading clearfix">
                <span class="glyphicon glyphicon-users"></span>
                Pools de Atores
                <button class="btn btn-xs btn-success pull-right" type="button" ng-click="newActorPool()"><span class="glyphicon glyphicon-plus"></span></button>
            </div>

            <div ng-repeat="a in process.actorPools" class="panel-body gutter-0">
                <div class="panel panel-default">
                    <div class="panel-heading clearfix">
                        <a class="pull-right btn btn-default btn-xs bpmnTask" data-nodrag ng-click="addTaskActor(a)" style="margin-right: 8px;">
                            <span class="glyphicon glyphicon-user"></span><span class="bpmn-icon-task"></span></a>
                        <a class="pull-right btn btn-default btn-xs bpmnGateway" data-nodrag ng-click="newFlowComponent('bpmnGateway')" style="margin-right: 8px;">
                            <span class="bpmn-icon-gateway-none"></span></a>
                        <a class="pull-right btn btn-default btn-xs bpmnEndEvent" data-nodrag ng-click="newFlowComponent('bpmnEndEvent')" style="margin-right: 8px;">
                            <span class="bpmn-icon-end-event-none"></span></a>
                    </div>
                    <div class="panel-body">
                        <div class="col-md-1">
                            <span class="glyphicon glyphicon-user"></span>
                        </div>
                        <div class="col-md-5">
                            <input placeholder="Coloque aqui o nome do ator" class="form-control" ng-model="a.name">
                        </div>
                        <div class="col-md-1">
                            <button class="btn btn-xs btn-success pull-right" type="button" ng-click="newRoleForPool(a)"><span class="glyphicon glyphicon-plus"></span>Papel</button>
                        </div>
                        <div class="col-md-4">
                            <label ng-if="a.roles.length == 0">Não obrigatórios</label>
                            <div ng-repeat="r in a.roles" class="gutter-0">
                                <div class="col-md-2">
                                    <a class="btn btn-danger btn-xs" data-nodrag ng-click="a.roles.splice($index, 1)"><span
                                            class="glyphicon glyphicon-remove"></span></a>
                                </div>
                                <div class="col-md-10">

                                    <select class="chosenOff" ng-model="r.role" class="form-control">
                                        <%
                                            for(String role: UserRoleProxy.getUserRoles())
                                            {
                                                request.setAttribute("role",role);
                                        %>
                                        <option value="${role}" ng-selected="{{r.role == '${role}'}}"><bean:message key="user.role.${role}"/></option>
                                        <%
                                            }
                                        %>
                                    </select>
                                </div>

                            </div>
                        </div>
                        <div class="col-md-1">
                            <bacoTags:confirm  msg="Tem a certeza que deseja remover a pool {{a.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeActorPool({{a.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>

                        </div>
                    </div>
                    <div class="panel-body">
                        <div ui-tree="treeOptions" id="page-content-root">
                            <div class="form-group">
                                <label class="control-label"> Pesquisar:</label>
                                <div class="col-md-4">
                                    <input class="form-control" ng-model="a.searchText">
                                </div>
                            </div>

                            <ol ui-tree-nodes ng-model="a.flowComponents">
                                <li   ng-repeat="node in a.flowComponents | filter:a.searchText" ui-tree-node ng-include="'flowComponent_renderer.html'" ng-init="pool=a"></li>
                            </ol>
                        </div>
                    </div>
                </div>

            </div>

        </div>





    </div>

    <div class="col-md-6" style="height: 80vh;overflow-y: auto;">

        <%--Podemos usar aqui startsWith para FlowComponent e ja apanha todas --%>
        <div ng-if="selected['@class'].startsWith('pt.estgp.estgweb.domain.BpmnFlowComponentTask')" class="panel panel-info panel-block bpmnActorTask" ng-class="{dirty: selected.dirty==true}" >
            <div class="panel-heading clearfix">
                <span class="glyphicon glyphicon-users"></span>
                Tarefa de Utilizador <input ng-keyup="setDirty(selected)" data-nodrag class="form-control" ng-model="selected.title">
            </div>


            <div class="panel-body">

            </div>
        </div>

        <div ng-if="selected['@class'].startsWith('pt.estgp.estgweb.domain.BpmnFlowConnector')" class="panel panel-info panel-block bpmnConnector" ng-class="{dirty: selected.dirty==true}">
            <div class="panel-heading clearfix">
                <span class="bpmn-icon-connection control-label"></span>
                Connector -
                <input ng-keyup="setDirty(selected)" data-nodrag class="form-control" ng-model="selected.nameConnection">
            </div>


            <div class="panel-body">

            </div>
        </div>
        <h2>Debug</h2>
        <pre class="code">{{ process | json }}</pre>
        <h2>All Flow Components</h2>
        <pre class="code">{{ allFlowComponents | json }}</pre>
<!--

        -->

    </div>
</form>




<style>
    table.tableHeading
    {
        border: 0;
        width: 100%;
    }
    table.tableHeading td
    {
        padding: 5px;

    }
    table.tableHeading td.headingTitle
    {
        width: 50%;
    }

</style>


<script type="text/ng-template" id="flowComponent_renderer.html">
    <!-- Coloquei aqui o predicado no NGClass que quando existe uma property nodrop = true o angular coloca nodrop na class o que faz o elemento ficar a vermelho e nao permite drop-->
    <div ng-click="select(node)" class="panel panel-default panel-block tree-node tree-node-content nodrop"  ng-class="{selected: node.selected == true, bpmnActorTask: node['@class'] == 'pt.estgp.estgweb.domain.BpmnFlowComponentTaskActorImpl',dirty: node.dirty==true,nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved}">
        <!--<div class="panel-heading clearfix" ng-class="node.type">
            <div class="row gutter-0">
                <div class="col-md-12">






                </div>
            </div>
        </div>-->
        <div class="panel-body">
            <table class="tableHeading">
                <tr>
                    <td><i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i></td>
                    <td>
                        <span ng-if="node['@class'] == 'pt.estgp.estgweb.domain.BpmnFlowComponentTaskActorImpl'">
                            <span class="glyphicon glyphicon-user"></span><span class="bpmn-icon-task"></span>
                        </span>
                        <span ng-if="node.type == 'bpmnGateway'" class="bpmn-icon-gateway-none"></span>
                        <span ng-if="node.type == 'bpmnEndEvent'" class="bpmn-icon-end-event-none"></span>
                        <label ng-if="node['@class'] == 'pt.estgp.estgweb.domain.BpmnFlowComponentTaskActorImpl'" class="control-label">Tarefa Actor</label>
                        <label ng-if="node.type == 'bpmnGateway'" class="control-label">Gateway</label>
                        <label ng-if="node.type == 'bpmnEndEvent'" class="control-label">EventoFim</label>
                    </td>
                    <td class="headingTitle">
                        <input ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.title">
                    </td>
                    <td>
                        <bacoTags:confirm  msg="Tem a certeza que deseja remover a atividade {{node.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeTask({{pool.id}},{{node.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>
                    </td>
                </tr>
            </table>
            <%--
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-user"></span> Actor Pool
                </div>
                <div class="col-md-10">
                    <select ng-change="setDirty(node)" class="chosenOff form-control" ng-model="node.actorPool" class="form-control">
                        <option ng-repeat="a in process.actorPools" value="{{a.id}}" ng-selected="{{a.id == node.actorPool}}">{{a.name}}</option>
                    </select>
                </div>
            </div>
            --%>
        </div>
        <div class="panel-footer clearfix">
            <a class="btn btn-success btn-xs" ng-if="node.flowConnectors && node.flowConnectors.length > 0" data-nodrag ng-click="toggle(this)">
                <span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed,'glyphicon-chevron-down': !collapsed}"></span>
            </a>

            <a class="pull-right btn btn-default btn-xs" data-nodrag ng-click="addConnector(node)" style="margin-right: 8px;"><span
                    class="bpmn-icon-connection"></span></a>

        </div>
    </div>

    <ol ui-tree-nodes="" data-nodrop-enabled="true" ng-model="node.flowConnectors" ng-class="{hidden: collapsed}" ng-init="task=node">
        <li ng-repeat="node in node.flowConnectors" ui-tree-node ng-include="'connector_renderer.html'">
        </li>
    </ol>
</script>


<script type="text/ng-template" id="connector_renderer.html">
    <!-- Coloquei aqui o predicado no NGClass que quando existe uma property nodrop = true o angular coloca nodrop na class o que faz o elemento ficar a vermelho e nao permite drop-->

    <button type="button" ng-click="orderConnector(node)">Ordena</button>
    <div ng-click="select(node)" class="panel panel-info panel-block tree-node tree-node-content bpmnConnector" data-nodrag ng-class="{dirty: node.dirty==true, selected: node.selected == true,nodrop: node.nodrop, nodrag: node.nodrag, moved: node.moved}">
        <div class="panel-heading clearfix" ng-class="node.type">
            <div class="row gutter-0">
                <table class="tableHeading">
                    <tr>
                        <!--<td><i class="glyphicon glyphicon-resize-vertical" ui-tree-handle></i></td>-->
                        <td>
                            <span class="bpmn-icon-connection control-label"></span> Conector
                        </td>
                        <td class="headingTitle">
                            <input ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.nameConnection">
                        </td>
                        <td>
                            <bacoTags:confirm  msg="Tem a certeza que deseja remover o connector {{node.name}}" targetFunction="angular.element($('#processEditorModule')).scope().removeConnector({{node.id}},{{task.id}},{{pool.id}},{{$index}});angular.element($('#processEditorModule')).scope().$apply();" btnClass="btn btn-danger btn-xs pull-right" icon="glyphicon glyphicon-remove"/>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
        <div class="panel-body">
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-arrow-right"></span> Ligação
                </div>
                <div class="col-md-10">
                    <select ng-change="setDirty(node)" data-nodrag class="form-control" ng-model="node.flowComponentId"
                            ng-options="f.id as f.title for f in allFlowComponents">
                    </select>
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-tag"></span> Chave
                </div>
                <div class="col-md-10">
                    <input type="text" ng-keyup="setDirty(node)" data-nodrag class="form-control" ng-model="node.keyValue">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-2">
                    <span class="glyphicon glyphicon-envelope"></span> Enviar Emails
                </div>
                <div class="col-md-2">
                    <select class="form-control chosenOff" ng-change="setDirty(node)" ng-model="node.sendEmail" ng-options="o.v as o.n for o in [{ n: 'Sim', v: true }, { n: 'Não', v: false }]">
                    </select>
                </div>
            </div>
            <div class="form-group" ng-show="node.sendEmail==true">
                <div class="col-md-2">
                    Mensagem
                </div>
                <div class="col-md-10">
                    <textarea ng-keyup="setDirty(node)" rows="3" class="form-control" ng-model="node.msgEmail"></textarea>
                </div>
            </div>
        </div>
    </div>



</script>



<!--Estilos CSS do Exemplo do Overview Nem olhei para eles copy paste e pronto-->
<style>

    .panel-block .panel-heading, .panel-block .panel-footer
    {
        padding:5px;
    }

    /* remove */
    .gutter-0.row {
        margin-right: -0px !important;
        margin-left: -0px !important;
    }
    .gutter-0 > [class*="col-"]{
        padding-right: 0px !important;
        padding-left: 0px !important;
    }

    /* customize */
    .gutter-6.row {
        margin-right: -3px !important;
        margin-left: -3px !important;
    }
    .gutter-6 > [class*="col-"] {
        padding-right: 3px !important;
        padding-left: 3px !important;
    }




    .panel-info.bpmnActorTask > .panel-heading, .bpmnActorTask{ background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnTask { background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnStartEvent { background-color: #EEF1CA !important; border-color: #A5CF84 !important }
    .bpmnMiddleEvent { background-color: #A7BBCF !important ;border-color: #4F87B0 !important}
    .bpmnEndEvent { background-color: #FDE6E2 !important; border-color: #8C121D; !important }
    .bpmnGateway { background-color: #ffcf53 !important; border-color: #ffa42a !important}
    .bpmnFase { background-color: #ECECF4 !important; border-color: #276E9F !important}
    .panel-info.bpmnConnector > .panel-heading , .bpmnConnector { background-color: white !important; ;border-color: #b7bdbb !important }



    .panel-info.bpmnActorTask.selected > .panel-heading,.bpmnActorTask.selected { background-color: #e7daac !important;border-color: #c69763 !important }
    .bpmnTask { background-color: #fff2c3 !important;border-color: #c69763 !important }
    .bpmnStartEvent { background-color: #EEF1CA !important; border-color: #A5CF84 !important }
    .bpmnMiddleEvent { background-color: #A7BBCF !important ;border-color: #4F87B0 !important}
    .bpmnEndEvent { background-color: #FDE6E2 !important; border-color: #8C121D; !important }
    .bpmnGateway { background-color: #ffcf53 !important; border-color: #ffa42a !important}
    .bpmnFase { background-color: #ECECF4 !important; border-color: #276E9F !important}
    .panel-info.bpmnConnector.selected > .panel-heading , .bpmnConnector.selected { background-color: #dadada !important; ;border-color: #b7bdbb !important }

    .btn {
        margin-right: 8px;
    }


    .angular-ui-tree-handle {
        background: #f8faff;
        border: 1px solid #dae2ea;
        color: #7c9eb2;
        padding: 0;
    }

    .angular-ui-tree-handle:hover {
        color: #438eb9;
        background: #f4f6f7;
        border-color: #dce2e8;
    }

    .angular-ui-tree-placeholder {
        background: #f0f9ff;
        border: 2px dashed #bed2db;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

    tr.angular-ui-tree-empty {
        height:100px
    }

    .group-title {
        background-color: #687074 !important;
        color: #FFF !important;
    }


    /* --- Tree --- */
    .tree-node {
        border: 1px solid #dae2ea;
        background: #f8faff;
        color: #7c9eb2;
    }

    .nodrop {
        background-color: #f2dede;
    }


    .nodrag {
        background-color: #f2eec1;
    }

    .tree-node-content {
        margin: 10px;
    }
    .tree-handle {
        /*padding: 10px;*/
        background: #428bca;
        color: #FFF;
        margin-right: 15px;
    }

    .angular-ui-tree-handle:hover {
    }

    .angular-ui-tree-placeholder {
        background: #f0f9ff;
        border: 2px dashed #bed2db;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

    /*Estilo adicionado por mim para os movidos*/
    .moved
    {
        border: 2px solid blue !important;
    }
</style>
</div>

<%
    AbstractDao.getCurrentSession().getTransaction().commit();
%>