lespoupeesrusses/promethee

View on GitHub
app/views/promethee/_edit.html.erb

Summary

Maintainability
Test Coverage
<%
@disable_page_attributes = false
@disable_page_attributes ||= disable_page_attributes

promethee_data = Promethee::Data::Master.new master_data
preview_url ||= promethee_preview_path
back_url ||= nil
logo = File.read "#{__dir__}/../../assets/images/icon-promethee.svg"
%>

<script type="text/javascript">
  angular
  .module('uid', [])
  .factory('uidService', function () {
    // Option 3 : https://stackoverflow.com/a/27747377
    return {
      generate: function () {
        var arr = new Uint8Array(10 / 2),
        hexArr = [],
        i;

        (window.crypto || window.msCrypto).getRandomValues(arr);
        for (i = 0; i < arr.length; i += 1) {
          hexArr[i] = ('0' + arr[i].toString(16)).substr(-2);
        }

        return hexArr.join('');
      }
    };
  });
</script>

<script type="text/javascript">
var promethee = angular
  .module('Promethee', ['summernote', 'ngAnimate', 'ngFileUpload', 'ui.sortable', 'colorpicker.module', 'uid'], ['$rootScopeProvider', function($rootScopeProvider) {
    $rootScopeProvider.digestTtl(30);
  }])
  .value('definitions', [])
  .value('presets', []);
</script>

<% promethee_util_partials.each do |partial| %>
  <%= render partial %>
<% end %>

<% promethee_preset_partials.each do |partial| %>
    <%= render partial %>
<% end %>

<script type="text/javascript">
promethee.controller('PrometheeController', ['$scope', 'summernoteConfig', 'presets', '$filter', function($scope, summernoteConfig, presets, $filter) {

  $scope.generateIdentifier = function() {
    // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
    function s4() {
      return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
  }

  $scope.data = <%= promethee_data.to_json.html_safe %>;

  // Data (TODO use standard method createComponentFromDefinition)
  if (typeof $scope.data !== 'object' || $scope.data === null || $scope.data.type !== 'page') {
    $scope.data = {
      id: $scope.generateIdentifier(),
      type: 'page',
      attributes: {
        title: {
          searchable: true,
          translatable: true,
          type: 'string',
          value: 'New page'
        },
        description: {
          searchable: true,
          translatable: true,
          type: 'text',
          value: ''
        },
        thumbnail: {
          searchable: false,
          translatable: false,
          type: 'blob',
          value: {
            id: undefined,
            name: ''
          }
        },
        stylesheets: {
          searchable: false,
          translatable: false,
          type: 'string',
          value: ''
        },
        javascripts: {
          searchable: false,
          translatable: false,
          type: 'string',
          value: ''
        }
      },
      children: []
    };
  }

  $scope.promethee = {
    data: $scope.data,
    definitions: [],
    presets: presets,
    inspected: $scope.data,
    mode: 'move',
    preview: 'desktop',
    fullscreen: true
  };

  $scope.findDefinitionByType = function(type) {
    return $filter('filter')($scope.promethee.definitions, {'data':{'type':type}})[0];
  }

  $scope.addComponentByType = function(type, target, index = -1) {
    var definition = $scope.findDefinitionByType(type);

    $scope.addComponent(definition, target, index);
  }

  $scope.addComponent = function(definition, target, index = -1) {
    var component = $scope.createComponentFromDefinition(definition);
    if (index === -1) {
      target.push(component);
    } else {
      target.splice(index, 0, component);
    }
  }

  $scope.createComponentFromDefinition = function(definition) {
    var component = angular.copy(definition.data);
    component.id = $scope.generateIdentifier();
    return component;
  }

  $scope.inspect = function(component, event) {
    if(event.target.closest('.promethee-edit__component') === event.currentTarget) {
      $scope.promethee.inspected = component;
    }
  }

  $scope.enablePreview = function() {
    if (this.promethee.mode === 'preview') return;
    this.promethee.mode = 'preview';
    this.sendPreviewData('preview');
  }

  $scope.sendPreviewData = function(target) {
    var form = document.createElement('form');
    document.body.appendChild(form);
    form.method = 'POST';
    form.action = "<%= preview_url %>";
    form.target = target;

    var input = document.createElement('input');
    input.type = 'text';
    input.value = JSON.stringify($scope.promethee.data);
    input.name = 'data';
    form.appendChild(input);

    <% if defined?(preview_layout) %>
    var layoutInput = document.createElement('input');
    layoutInput.type = 'text';
    layoutInput.value = "<%= preview_layout %>";
    layoutInput.name = 'preview_layout';
    form.appendChild(layoutInput);
    <% end %>

    form.submit();
    document.body.removeChild(form);
  }

  $scope.remove = function(component, components) {
    var index = components.indexOf(component);
    components.splice(index, 1);
    this.promethee.inspected = null;
  }

  $scope.submit = function() {
    window.warnBeforeUnload.unlock();
    $('#promethee').closest('form').submit();
  };

  $scope.$watch('promethee.data', function(new_val, old_val) {
    if (old_val != new_val) {
      window.warnBeforeUnload.lock();
    }
  }, true);

  $scope.summernoteConfig = summernoteConfig;
}]);
</script>

<div class="promethee-loader">
  <div class="promethee-loader__inner"><%= image_tag 'loader.gif' %></div>
</div>

<div  id="promethee"
      ng-app="Promethee"
      ng-controller="PrometheeController as prometheeController"
      ng-init="component = promethee.data"
      class="ng-cloak">

  <% promethee_template_partials.each do |partial| %>
    <%= render partial %>
  <% end %>

  <div class="promethee-edit" ng-show="promethee.fullscreen">
    <input type="hidden" name="page[data]" id="page_data" value="{{promethee.data}}"  />
    <div class="upload__modal" ng-show="upload.running">

    </div>
    <nav class="navbar navbar-default promethee-edit__navbar px-0 py-0" ng-class="{'navbar-fixed-top': promethee.fullscreen }">
      <div class="container-fluid">
        <div class="navbar-header promethee-edit__icon">
          <div class="navbar-brand"><%= logo.html_safe %></div>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav navbar-right ml-auto">
            <li class="nav-item" ng-click="promethee.mode = 'move'" ng-class="{active: promethee.mode == 'move'}">
              <a class="nav-link" href="#" title="Edit"><%= icon('fa', 'pencil') %></a>
            </li>
            <li class="nav-item" ng-class="{active: promethee.mode == 'preview'}">
              <a class="nav-link" href="#" title="Preview" ng-click="enablePreview()" data-toggle="dropdown"><%= icon('fa', 'eye') %></a>
              <ul class="dropdown-menu" ng-show="promethee.mode == 'preview'">
                <li ng-click="promethee.preview = 'desktop'"
                    class="nav-item"
                    ng-class="{active: promethee.preview == 'desktop'}">
                    <a class="promethee-previewmode promethee-previewmode__desktop nav-link" href="#" title="Desktop"><i class="fa fa-desktop"></i></a>
                  </li>
                <li ng-click="promethee.preview = 'tablet'"
                    class="nav-item"
                    ng-class="{active: promethee.preview == 'tablet'}">
                    <a class="promethee-previewmode promethee-previewmode__tablet nav-link" href="#" title="Tablet"><i class="fa fa-tablet"></i></a>
                  </li>
                <li ng-click="promethee.preview = 'mobile'"
                    class="nav-item"
                    ng-class="{active: promethee.preview == 'mobile'}">
                    <a class="promethee-previewmode promethee-previewmode__mobile nav-link" href="#" title="Mobile"><i class="fa fa-mobile"></i></a>
                  </li>
              </ul>
            </li>
            <li class="nav-item" ng-click="submit()">
              <a class="nav-link" href="#" title="Save"><%= icon('fa', 'save') %></a>
            </li>
            <% if back_url.present? %>
              <li class="nav-item">
                <a class="nav-link" href="<%= back_url %>" title="Close"><%= icon('fa', 'close') %></a>
              </li>
            <% else %>
              <li class="nav-item" ng-click="promethee.fullscreen = false">
                <a class="nav-link" href="#" title="Close"><%= icon('fa', 'close') %></a>
              </li>
            <% end %>
          </ul>
        </div>
      </div>
    </nav>

    <% promethee_component_partials.each do |partial| %>
      <%= render partial %>
    <% end %>

    <%= render 'promethee/edit/move' %>
    <%= render 'promethee/edit/preview' %>
  </div>
</div>