lespoupeesrusses/promethee

View on GitHub
app/views/promethee/edit/_move.html.erb

Summary

Maintainability
Test Coverage
<script type="text/javascript">
promethee
  .directive('addable', function() {
    return {
      restrict:'A',
      link: function(scope, element, attrs) {
        element.draggable({
          revert: true,
          revertDuration: 0,
          scroll: true,
          refreshPositions: true,
          cursor: 'move',
          cursorAt: { top: 50, left: 50 },
          helper: 'clone',
          appendTo: '.promethee-edit__move',
          start: function(event, ui) {
            var type = $(element[0]).data('type');
            $('.promethee-edit__move').addClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
          },
          stop: function(event, ui) {
            var type = $(element[0]).data('type');
            $('.promethee-edit__move').removeClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
          }
        });
      }
    }
  })
  .directive('draggable', function() {
    return {
      restrict:'A',
      link: function(scope, element, attrs) {
        element.draggable({
          revert: true,
          revertDuration: 0,
          scroll: true,
          refreshPositions: true,
          cursor: 'move',
          start: function() {
            var type = $(element[0]).data('type');
            $('.promethee-edit__move').addClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
          },
          stop: function() {
            var type = $(element[0]).data('type');
            $('.promethee-edit__move').removeClass('promethee-edit__move--dragging promethee-edit__move--dragging--' + type);
          }
        });
      }
    }
  })
  .directive('droppable', ['$compile', 'presets', function($compile, presets) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.droppable({
          tolerance: 'pointer',
          drop: function(event, ui) {
            var draggedFromLibrary = false;
            var draggedFromList = angular.element(ui.draggable).parent().scope().components;
            var droppedToList = angular.element(this).scope().components;
            var droppedToIndex = parseInt(this.getAttribute('data-index'));
            var draggedFromPresets = ui.draggable.attr('data-preset');

            if(draggedFromPresets) {
              var preset = presets.find(function(preset) {
                return preset.name === draggedFromPresets;
              });

              var provideIdentifiers = function(components) {
                var component;
                for(var i = 0; i < components.length; i++) {
                  component = components[i];
                  component.id = scope.generateIdentifier();
                  if(Array.isArray(component.children)) provideIdentifiers(component.children);
                }

                return components;
              };

              var components = provideIdentifiers(angular.copy(preset.components));
              droppedToList.splice.apply(droppedToList, [droppedToIndex, 0].concat(components));

              scope.$apply();

              return;
            }

            if (draggedFromList === undefined) {
              draggedFromLibrary = true;
            }
            if (draggedFromLibrary) {
              var definition = angular.element(ui.draggable).scope().definition;
              var component = angular.copy(definition.data);
              component.id = scope.generateIdentifier();
            } else {
              var draggedFromIndex = parseInt(ui.draggable[0].getAttribute('data-list-index'));
              draggedFromList.splice(draggedFromIndex, 1);

              var component = angular.element(ui.draggable).scope().component;
              if (draggedFromList == droppedToList) {
                // The object we dragged was removed from the list
                if (draggedFromIndex < droppedToIndex) {
                  // It was before the dropped index, so removing it changed the index
                  droppedToIndex -= 1;
                }
              }
            }
            droppedToList.splice(droppedToIndex, 0, component);

            scope.promethee.inspected = component;

            scope.$apply();
          }
        });
      }
    }
  }]);

</script>

<div class="promethee-edit__move" ng-show="promethee.mode == 'move'">
  <div class="promethee-edit__library">
    <div class="promethee-edit__library-header">Library</div>
    <div class="promethee-edit__library-content">
      <div  ng-repeat="definition in promethee.definitions | filter:{library:true} | orderBy:'position'" class="promethee-edit__library__item-container">
        <div  addable
              class="promethee-edit__library__item"
              data-type="{{definition.data.type}}">
          <div class="promethee-edit__library__item__icon" ng-bind-html="definition.icon | htmlSafe"></div>
          <div class="promethee-edit__library__item__name">{{definition.name}}</div>
        </div>
      </div>
    </div>
    <div class="promethee-edit__library-header">Presets</div>
    <div class="promethee-edit__library-content">
      <div ng-repeat="preset in promethee.presets | orderBy:'position'" class="promethee-edit__library__item-container">
        <div addable class="promethee-edit__library__item" data-type="text" data-preset="{{preset.name}}">
          <div class="promethee-edit__library__item__icon" ng-bind-html="preset.icon | htmlSafe"></div>
          <div class="promethee-edit__library__item__name">{{preset.name}}</div>
        </div>
      </div>
    </div>
  </div>

  <div class="promethee-edit__move__page">
    <ng-include src="'promethee/move/component'"></ng-include>
  </div>

  <div class="promethee-edit__inspect" ng-show="promethee.inspected.type">
    <div class="promethee-edit__inspect-header">
      {{promethee.inspected.type}}
    </div>
    <div class="promethee-edit__inspect-content">
      <div ng-repeat="definition in promethee.definitions | orderBy:'position'">
        <ng-include src="'promethee/components/' + definition.data.type + '/edit/inspect'"
                    ng-if="promethee.inspected.type == definition.data.type"
                    class="promethee-edit__inspect-content--{{ definition.data.type }}"></ng-include>
      </div>
    </div>
  </div>
</div>

<script type="text/ng-template" id="promethee/move/component">
  <div class="promethee-edit__move__component">
    <ng-include src="'promethee/components/' + component.type + '/edit/move'"></ng-include>
  </div>
</script>

<script type="text/ng-template" id="promethee/move/components">
  <div ng-init="parent_id = component.id; parent_type = component.type; components = component.children">
    <div
      droppable
      class="<%= promethee_bem_classes 'promethee-edit__move__droppable', '--{{parent_type}}' %>"
      data-id="{{parent_id}}"
      data-type="{{parent_type}}"
      data-index="0"
      >
    </div>
    <div
      draggable
      ng-repeat="component in components"
      class="<%= promethee_bem_classes 'promethee-edit__move__draggable', '--{{component.type}}' %>"
      data-id="{{component.id}}"
      data-type="{{component.type}}"
      data-list-id="{{parent_id}}"
      data-list-type="{{parent_type}}"
      data-list-index="{{$index}}"
      >
      <ng-include src="'promethee/move/component'"></ng-include>
      <div
        droppable
        class="<%= promethee_bem_classes 'promethee-edit__move__droppable', '--{{parent_type}}' %>"
        data-id="{{parent_id}}"
        data-type="{{parent_type}}"
        data-index="{{$index+1}}"
        >
      </div>
    </div>
  </div>
</script>