<commit_before>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.getCellEditor() != null) editing = true;
    });
    return editing;
  },

  // Resize grid
  resizeGrid: function(grid) {
    grid.resizeCanvas();
    grid.autosizeColumns();
    grid.filterPanel.generateFilters();
    $(window).resize(function() {
      grid.resizeCanvas();
      grid.autosizeColumns();
      grid.filterPanel.generateFilters();
    });
  },

  // Check if filter panel is open (Not in use since Material Design implementation)
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Check if the grid is being filtered
  isFiltering: function() {
    return $(document.activeElement).parent().hasClass('slick-header-column');
  },

  // Check if can add or delete records
  addOrDeleteLocked: function() {
    return this.isEditing() || this.isOpen() || this.isFiltering();
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Refresh create form when continue create new record
  refreshCreateForm: function(grid) {
    var name = grid.name;
    $.get(grid.path + '/wulin_master_new_form' + grid.query, function(data){
      newFormDom = $(data);
      $('#' + name + '_form:visible form').replaceWith(newFormDom.find('form'));
      setTimeout(function(){ Ui.setupForm(grid, false); }, 350);
      Ui.setupComponents(grid);
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').not('[readonly]').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(grid, action, options, callback) {
    $.get(grid.path + '/' + action + grid.query, function(data){
      Ui.createModelModal(grid, data, {
        ready: function(modal, trigger) {
          Ui.setupForm(grid, false);
        }
      });
    });
  },

  setupComponents: function(grid) {
    var name = grid.name;
    // setup select as chosen
    $('#' + name + '_form select[data-required="true"]').chosen();
    $('#' + name + '_form select[data-required="false"]').chosen({allow_single_deselect: true});

    $('#' + name + '_form select').off('change').on('change', function(){
      var flag = $('#' + name + '_form input.target_flag:checkbox[data-target="' + $(this).attr('data-target') + '"]');
      if (flag.size() > 0) flag.attr('checked', 'checked');
    });

    // setup datepicker
    $('#' + name + '_form input[data-date]').datepicker({ dateFormat: 'yy-mm-dd' });
    $('#' + name + '_form input[data-datetime]').datetimepicker({
      onlyTime: false,
      dateFormat: "yy-mm-dd",
      timeFormat: 'HH:mm',
      timeOnly: false,
      stepMinute: 1,
      minuteGrid: 0,
      beforeShow: function() { calendarOpen = true; },
      onClose: function() { calendarOpen = false; }
    });
    $('#' + name + '_form input[data-time]').timepicker({});
  },

  setupForm: function(grid, monitor) {
    var remotePath = [];
    var choicesColumn = [];
    var distinctColumn = [];
    var path;
    var name = grid.name;
    var scope = $('#' + name + '_form');
    var formType = scope.data('action');
    var columns = window[name + "_columns"] || grid.getColumns();
    var currentData = {};

    if (grid.loader)
      currentData = grid.loader.data[grid.getSelectedRows()[0]];

    // special handling for 'choices' and 'choices_column' options
    $.each(columns, function(i, n) {
      if (n['choices'] && typeof(n['choices']) == 'string') {
        if (n['distinct'] && formType != 'create') {
          distinctColumn.push([n.field, n['choices']]);
        } else {
          var formable = n.formable === false ? false : true;

          var editorChoices = n.choices;
          // Use editor's source instead of grid's source
          if (n.editor.source) {
            var match = /^.*(source=.*)$/igm.exec(n.choices);
            var grid_source = match[1];
            editorChoices = n.choices.replace(grid_source, 'source=' + n.editor.source);
          }

          remotePath.push([n.field, editorChoices, formable]);
        }
      } else if (currentData && n['choices_column']) {
        choicesColumn.push([n.field, currentData[n['choices_column']]]);
      }
    });

    // Fetch select options from remote
    if (remotePath.length > 0) {
      $.each(remotePath, function(i, n) {
        var field = n[0];
        var path = n[1];
        var formable = n[2];
        if (!path || !formable) return;

        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        var source = target.attr('data-source');
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();

          $.getJSON(path, function(itemdata){
            $.each(itemdata, function(index, value) {
              if ($.isPlainObject(value)) {
                target.append(
                  "<option value='" + value.id + "'>" +
                  value[source] +
                  "</option>"
                );
              } else {
                target.append("<option value='" + value + "'>" + value + "</option>");
              }
            });
            Ui.setupChosen(target, monitor);
          });

        }
      });
    }

    // Fetch distinct select options from remote
    if (distinctColumn.length > 0) {
      $.each(distinctColumn, function(i, n) {
        var field = n[0];
        var path = n[1];
        if (!path) return;

        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        var source = target.attr('data-source');
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();

          $.getJSON(path, function(itemdata){
            $.each(itemdata, function(index, value) {
              if ($.isPlainObject(value)) {
                target.append("<option value='" + value.id + "'>" + value[source] + "</option>");
              } else {
                target.append("<option value='" + value + "'>" + value + "</option>");
              }
            });
            target.append("<option>Add new Option</option>");
          });

        }
      });
    }

    // Fetch select options from current data
    if (choicesColumn.length > 0) {
        $.each(choicesColumn, function(i, n) {
        var field = n[0];
        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();
            $.each(n[1], function(index, value) {
              target.append("<option value='" + value + "'>" + value + "</option>");
            });
            Ui.setupChosen(target, monitor);
        }
      });
    }

    first_input = $( '#' + name + '_form input:text', scope).first();
    if (first_input.attr('data-date')) {
      first_input.focus();
    }

    // Layout
    $('.ui-dialog-titlebar').hide();
    $('.ui-resizable-handle').hide();
    // $('.chzn-container').width('100%');
    // $('.chzn-drop').width('100%');
    // $('.chzn-search input').width('96%');
  },

  setupChosen: function(dom, monitor) {
    setTimeout(function(){
      var afterSetupChosen = dom.data('afterSetupChosen');
      if (dom.hasClass("chzn-done")) {
        dom.trigger("liszt:updated");
      } else {
        dom.chosen();
      }

      if( afterSetupChosen ) {
        afterSetupChosen();
      }
    }, 100);
  },

  // Close Modal
  closeModal: function(name) {
    var $form = $( '#' + name + '_form' );
    window._focused = {};
    $form.closest('.modal').modal('close');
    $form.closest('.modal').remove();
  },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $( document.activeElement ).parents('.grid_container');
    if (currentGridContainer.size() === 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0];
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

  getModalSize: function(grid, data) {
    var width, height;
    $('body').append(data);
    var modalHeight = $('.create_form .title').outerHeight() +             // Title
                      $('.create_form form').outerHeight() +               // Fields
                      $('.create_form .submit').outerHeight() +            // Button
                      120;                                                 // Padding
    if (grid.options) {
      width = grid.options.form_dialog_width || 600;
      height = grid.options.form_dialog_height || modalHeight;
    } else {
      width = 600;
      height = modalHeight;
    }
    $('.create_form').remove();
    return { width: width, height: height };
  },

  baseModal: function(options = {}) {
    var $modal = $('
')
      .addClass('modal')
      .appendTo($('body'));
    var $modalContent = $('
')
      .addClass('modal-content')
      .appendTo($modal);

    $.extend(options, {
      complete: function() {
        $modal.remove();
      }
    });
    $modal.modal(options);
    $modal.modal('open');

    return $modal;
  },

  headerModal: function(title, options = {}) {
    var $headerModal = this.baseModal(options)
      .addClass('modal-fixed-footer')
      .css({overflow: 'hidden'});
    var $modalHeader = $('
')
      .addClass('modal-header')
      .append($('').text(title))
      .append($('').text('close').addClass('modal-close material-icons right'))
      .prependTo($headerModal);

    return $headerModal;
  },

  createModelModal: function(grid, data, options) {
    $.extend(options, {
      startingTop: '5%',
      endingTop: '5%',
    });

    var modalSize = this.getModalSize(grid, data);
    var $modelModal = this.baseModal(options)
      .width(modalSize.width)
      .height(modalSize.height)
      .css({'max-height': '90%'});

    $modelModal.find('.modal-content').append(data);
  },

  createJsonViewModal: function(jsonData) {
    var $jsonViewModal = this.headerModal('JSON View');
    $jsonViewModal.find('.modal-content')
      .css('margin-top', '24px')
      .JSONView(jsonData)
      .JSONView('collapse');
  },

  formatData: function(grid, arrayData) {
    var data = {}, columns;
    columns = grid.loader.getColumns();
    $.each(columns, function(index, column){
      data[column['id']] = arrayData[index];
    });
    return data;
  }

};
<commit_msg>REFACTOR #14 - Cucumber Happy: Use old fasion optional params<commit_after>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.getCellEditor() != null) editing = true;
    });
    return editing;
  },

  // Resize grid
  resizeGrid: function(grid) {
    grid.resizeCanvas();
    grid.autosizeColumns();
    grid.filterPanel.generateFilters();
    $(window).resize(function() {
      grid.resizeCanvas();
      grid.autosizeColumns();
      grid.filterPanel.generateFilters();
    });
  },

  // Check if filter panel is open (Not in use since Material Design implementation)
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Check if the grid is being filtered
  isFiltering: function() {
    return $(document.activeElement).parent().hasClass('slick-header-column');
  },

  // Check if can add or delete records
  addOrDeleteLocked: function() {
    return this.isEditing() || this.isOpen() || this.isFiltering();
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Refresh create form when continue create new record
  refreshCreateForm: function(grid) {
    var name = grid.name;
    $.get(grid.path + '/wulin_master_new_form' + grid.query, function(data){
      newFormDom = $(data);
      $('#' + name + '_form:visible form').replaceWith(newFormDom.find('form'));
      setTimeout(function(){ Ui.setupForm(grid, false); }, 350);
      Ui.setupComponents(grid);
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').not('[readonly]').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(grid, action, options, callback) {
    $.get(grid.path + '/' + action + grid.query, function(data){
      Ui.createModelModal(grid, data, {
        ready: function(modal, trigger) {
          Ui.setupForm(grid, false);
        }
      });
    });
  },

  setupComponents: function(grid) {
    var name = grid.name;
    // setup select as chosen
    $('#' + name + '_form select[data-required="true"]').chosen();
    $('#' + name + '_form select[data-required="false"]').chosen({allow_single_deselect: true});

    $('#' + name + '_form select').off('change').on('change', function(){
      var flag = $('#' + name + '_form input.target_flag:checkbox[data-target="' + $(this).attr('data-target') + '"]');
      if (flag.size() > 0) flag.attr('checked', 'checked');
    });

    // setup datepicker
    $('#' + name + '_form input[data-date]').datepicker({ dateFormat: 'yy-mm-dd' });
    $('#' + name + '_form input[data-datetime]').datetimepicker({
      onlyTime: false,
      dateFormat: "yy-mm-dd",
      timeFormat: 'HH:mm',
      timeOnly: false,
      stepMinute: 1,
      minuteGrid: 0,
      beforeShow: function() { calendarOpen = true; },
      onClose: function() { calendarOpen = false; }
    });
    $('#' + name + '_form input[data-time]').timepicker({});
  },

  setupForm: function(grid, monitor) {
    var remotePath = [];
    var choicesColumn = [];
    var distinctColumn = [];
    var path;
    var name = grid.name;
    var scope = $('#' + name + '_form');
    var formType = scope.data('action');
    var columns = window[name + "_columns"] || grid.getColumns();
    var currentData = {};

    if (grid.loader)
      currentData = grid.loader.data[grid.getSelectedRows()[0]];

    // special handling for 'choices' and 'choices_column' options
    $.each(columns, function(i, n) {
      if (n['choices'] && typeof(n['choices']) == 'string') {
        if (n['distinct'] && formType != 'create') {
          distinctColumn.push([n.field, n['choices']]);
        } else {
          var formable = n.formable === false ? false : true;

          var editorChoices = n.choices;
          // Use editor's source instead of grid's source
          if (n.editor.source) {
            var match = /^.*(source=.*)$/igm.exec(n.choices);
            var grid_source = match[1];
            editorChoices = n.choices.replace(grid_source, 'source=' + n.editor.source);
          }

          remotePath.push([n.field, editorChoices, formable]);
        }
      } else if (currentData && n['choices_column']) {
        choicesColumn.push([n.field, currentData[n['choices_column']]]);
      }
    });

    // Fetch select options from remote
    if (remotePath.length > 0) {
      $.each(remotePath, function(i, n) {
        var field = n[0];
        var path = n[1];
        var formable = n[2];
        if (!path || !formable) return;

        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        var source = target.attr('data-source');
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();

          $.getJSON(path, function(itemdata){
            $.each(itemdata, function(index, value) {
              if ($.isPlainObject(value)) {
                target.append(
                  "<option value='" + value.id + "'>" +
                  value[source] +
                  "</option>"
                );
              } else {
                target.append("<option value='" + value + "'>" + value + "</option>");
              }
            });
            Ui.setupChosen(target, monitor);
          });

        }
      });
    }

    // Fetch distinct select options from remote
    if (distinctColumn.length > 0) {
      $.each(distinctColumn, function(i, n) {
        var field = n[0];
        var path = n[1];
        if (!path) return;

        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        var source = target.attr('data-source');
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();

          $.getJSON(path, function(itemdata){
            $.each(itemdata, function(index, value) {
              if ($.isPlainObject(value)) {
                target.append("<option value='" + value.id + "'>" + value[source] + "</option>");
              } else {
                target.append("<option value='" + value + "'>" + value + "</option>");
              }
            });
            target.append("<option>Add new Option</option>");
          });

        }
      });
    }

    // Fetch select options from current data
    if (choicesColumn.length > 0) {
        $.each(choicesColumn, function(i, n) {
        var field = n[0];
        var first_input;
        var target = $("select[data-field='" + field + "']", scope);
        if (target.size() == 1) {
          $('option[value!=""]', target).remove();
            $.each(n[1], function(index, value) {
              target.append("<option value='" + value + "'>" + value + "</option>");
            });
            Ui.setupChosen(target, monitor);
        }
      });
    }

    first_input = $( '#' + name + '_form input:text', scope).first();
    if (first_input.attr('data-date')) {
      first_input.focus();
    }

    // Layout
    $('.ui-dialog-titlebar').hide();
    $('.ui-resizable-handle').hide();
    // $('.chzn-container').width('100%');
    // $('.chzn-drop').width('100%');
    // $('.chzn-search input').width('96%');
  },

  setupChosen: function(dom, monitor) {
    setTimeout(function(){
      var afterSetupChosen = dom.data('afterSetupChosen');
      if (dom.hasClass("chzn-done")) {
        dom.trigger("liszt:updated");
      } else {
        dom.chosen();
      }

      if( afterSetupChosen ) {
        afterSetupChosen();
      }
    }, 100);
  },

  // Close Modal
  closeModal: function(name) {
    var $form = $( '#' + name + '_form' );
    window._focused = {};
    $form.closest('.modal').modal('close');
    $form.closest('.modal').remove();
  },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $( document.activeElement ).parents('.grid_container');
    if (currentGridContainer.size() === 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0];
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

  getModalSize: function(grid, data) {
    var width, height;
    $('body').append(data);
    var modalHeight = $('.create_form .title').outerHeight() +             // Title
                      $('.create_form form').outerHeight() +               // Fields
                      $('.create_form .submit').outerHeight() +            // Button
                      120;                                                 // Padding
    if (grid.options) {
      width = grid.options.form_dialog_width || 600;
      height = grid.options.form_dialog_height || modalHeight;
    } else {
      width = 600;
      height = modalHeight;
    }
    $('.create_form').remove();
    return { width: width, height: height };
  },

  baseModal: function(options) {
    var $modal = $('
')
      .addClass('modal')
      .appendTo($('body'));
    var $modalContent = $('
')
      .addClass('modal-content')
      .appendTo($modal);

    $.extend(options, {
      complete: function() {
        $modal.remove();
      }
    });
    $modal.modal(options);
    $modal.modal('open');

    return $modal;
  },

  headerModal: function(title, options) {
    options = options || {};
    var $headerModal = this.baseModal(options)
      .addClass('modal-fixed-footer')
      .css({overflow: 'hidden'});
    var $modalHeader = $('
')
      .addClass('modal-header')
      .append($('').text(title))
      .append($('').text('close').addClass('modal-close material-icons right'))
      .prependTo($headerModal);

    return $headerModal;
  },

  createModelModal: function(grid, data, options) {
    $.extend(options, {
      startingTop: '5%',
      endingTop: '5%',
    });

    var modalSize = this.getModalSize(grid, data);
    var $modelModal = this.baseModal(options)
      .width(modalSize.width)
      .height(modalSize.height)
      .css({'max-height': '90%'});

    $modelModal.find('.modal-content').append(data);
  },

  createJsonViewModal: function(jsonData) {
    var $jsonViewModal = this.headerModal('JSON View');
    $jsonViewModal.find('.modal-content')
      .css('margin-top', '24px')
      .JSONView(jsonData)
      .JSONView('collapse');
  },

  formatData: function(grid, arrayData) {
    var data = {}, columns;
    columns = grid.loader.getColumns();
    $.each(columns, function(index, column){
      data[column['id']] = arrayData[index];
    });
    return data;
  }

};
<|endoftext|>


<commit_before>function applyGrid(){
	var $container = $('.grid')
	$container.imagesLoaded( function(){
		$container.masonry({
			itemSelector: '.grid-item',
			columnWidth: '.grid-sizer',
			percentPosition: true
		});
	});

  $container.infinitescroll({
    navSelector  : 'nav.pagination',    // selector for the paged navigation
    nextSelector : 'nav.pagination a[rel=next]',  // selector for the NEXT link (to page 2)
    itemSelector : '.grid-item',     // selector for all items you'll retrieve
    loading: {
			selector: '.loading-message',
			finishedMsg: 'Isso é tudo, em breve novas oportunidades estarão disponíveis',
			img: 'http://i.imgur.com/6RMhx.gif'
      }
    },
    // trigger Masonry as a callback
    function( newElements ) {
      // hide new items while they are loading
      var $newElems = $( newElements ).css({ opacity: 0 });
      // ensure that images load before adding to masonry layout
      $newElems.imagesLoaded(function(){
        // show elems now they're ready
        $newElems.animate({ opacity: 1 });
        $container.masonry( 'appended', $newElems, true );
      });
    }
  );

}

<commit_msg>Fixed loading message<commit_after>function applyGrid(){
	var $container = $('.grid')
	$container.imagesLoaded( function(){
		$container.masonry({
			itemSelector: '.grid-item',
			columnWidth: '.grid-sizer',
			percentPosition: true
		});
	});

  $container.infinitescroll({
    navSelector  : 'nav.pagination',    // selector for the paged navigation
    nextSelector : 'nav.pagination a[rel=next]',  // selector for the NEXT link (to page 2)
    itemSelector : '.grid-item',     // selector for all items you'll retrieve
    loading: {
			selector: '.loading-message',
			msgText: 'Carregando mais oportunidades...',
			finishedMsg: 'Isso é tudo, em breve novas oportunidades estarão disponíveis',
			img: 'http://i.imgur.com/6RMhx.gif'
      }
    },
    // trigger Masonry as a callback
    function( newElements ) {
      // hide new items while they are loading
      var $newElems = $( newElements ).css({ opacity: 0 });
      // ensure that images load before adding to masonry layout
      $newElems.imagesLoaded(function(){
        // show elems now they're ready
        $newElems.animate({ opacity: 1 });
        $container.masonry( 'appended', $newElems, true );
      });
    }
  );

}

<|endoftext|>


<commit_before>jQuery(document).ready(function($) {

    var width = 960,
        height = 740,
        radius = Math.min(width, height) / 2;

    var x = d3.scale.linear()
        .range([0, 2 * Math.PI]);

    var y = d3.scale.sqrt()
        .range([0, radius]);

    createSunburst("/sunburst");

    var colorGroup0 = ["#FFE1F4", "#FFBFE8", "#FF99D9", "#FF82D0", "#FF6FC9", "#FF4DBC", "#FF2BAF", "#FF009F", "#F7009A", "#EC0094", "#DF008B"];
    var colorGroup1 = ["#E7E9FA", "#CACEF4", "#AAB0EE", "#979FEA", "#8791E7", "#6A76E1", "#4E5BDC", "#2B3CD5", "#2939CD", "#2737C5", "#2534BA"];
    var colorGroup2 = ["#E7F3FA", "#CCE6F2", "#ADD7EB", "#9ACEE7", "#8BC6E2", "#70B9DC", "#54ABD6", "#329BCD", "#3096C7", "#2E8FBE", "#2E8FBE"];
    var colorGroup3 = ["#006060", "#007171", "#007D7D", "#00A4A4", "#00B0B0", "#00D0D0", "#00DFDF", "#00ECEC", "#00F7F7", "#00FFFF", "#2BFFFF", "#4DFFFF"];
    var colorGroup4 = ["#DFDF00", "#ECEC00", "#F7F700", "#FFFF00", "#FFFF2B", "#FFFF4D", "#FFFF6F", "#FFFF82", "#FFFF99", "#FFFFBF", "#FFFFE1"];
    var colorGroup5 = ["#FFF0E1", "#FFDFBF", "#FFCC99", "#FFC082", "#FFB76F", "#FFA64D", "#FF8000", "#F77B00", "#EC7600", "#DF7000"];
    var colorGroup6 = ["#0000F7", "#3131C6", "#0000FF", "#3232CD", "#2B2BFF", "#5555D5", "#4D4DFF", "#7070DC", "#6F6FFF", "#8B8BE2", "#8282FF", "#9A9AE7", "#9999FF", "#ADADEB", "#BFBFFF", "#CCCCF2", "#E1E1FF"];
    var colorGroup7 = ["#E8F9ED", "#CCF2D9", "#ADEBC1", "#9BE6B4", "#55D57E", "#8BE2A8", "#71DB94", "#33CC65", "#30BC5E", "#2DB358", "#2BA653"];
    var colorGroup8 = ["#FFE6E1", "#FFC9BF", "#FFA899", "#FF9582", "#FF846F", "#FF674D", "#FF4A2B", "#FF2600", "#F72500", "#EC2300", "#DF2200"];
    var colorGroup9 = ["#F0EDF3", "#DFD8E7", "#CCBFD9", "#C0B0D0", "#B7A5C9", "#A68FBC", "#957AAF", "#80609F", "#7B5C9A", "#765894", "#70548B"];
    var colorGroup10 = ["#FBE6E6", "#F5C9C9", "#F0A8A8", "#ED9494", "#EB8383", "#E66666", "#E14848", "#DB2424", "#D32323", "#CB2121", "#BF2020"];

    var colorGroups = [colorGroup0, colorGroup1, colorGroup2, colorGroup3, colorGroup4, colorGroup5, colorGroup6, colorGroup7, colorGroup8, colorGroup9, colorGroup10];

    var BASE_COLOR = "#2C2C28";
    var POSITIVE_COLOR = "#007D00";
    var NEGATIVE_COLOR = "#7D1300";

    // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
    // Returns a random integer between min (included) and max (excluded)
    // Using Math.round() will give you a non-uniform distribution!
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
    }

    function randomColorFromGroup(groupNumber) {
        var colorArray = colorGroups[groupNumber];
        var index = getRandomInt(0, colorGroups.length - 1);
        return colorArray[index];
    }

    function setNodeColor(node) {
        var color;
        if (node.depth === 0) {
            color = BASE_COLOR;
        } else {
            switch (node.group) {
                case "Positive":
                    color = POSITIVE_COLOR;
                    break;
                case "Negative":
                    color = NEGATIVE_COLOR;
                    break;
                default:
                    color = randomColorFromGroup(node.group);
            }
        }
        return (node.nodeColor = color);
    }

    $(".chartbutton").on("click", function() {
        event.preventDefault();
        var chartUrl = $(this).attr("href")
        $(".tooltip").remove();
        d3.selectAll("svg").transition()
            .duration(1000)
            .style('opacity', 0.2)
            .remove();
        createSunburst(chartUrl);
    });

    $("#search-button").on('click', function(event) {
        event.preventDefault();

        d3.selectAll("svg").transition()
            .duration(750)
            .style('opacity', 0.2)
            .remove();
        var searchTerm = $("#box").val().replace(/ /g, '+');
        var searchUrl = "/search?utf8=✓&search=" + searchTerm + "&commit=Search";

        console.log("search url:", searchUrl);
        createSunburst(searchUrl);
    });

    function createSunburst(url) {

        var svg = d3.select("#zoomable_sunburst").append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + (height / 2) + ")");

        var partition = d3.layout.partition()
            .value(function(d) {
                return d.size;
            });

        arc = d3.svg.arc()
            .startAngle(function(d) {
                return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
            })
            .endAngle(function(d) {
                return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
            })
            .innerRadius(function(d) {
                return Math.max(0, y(d.y));
            })
            .outerRadius(function(d) {
                return Math.max(0, y(d.y + d.dy));
            });

        var tooltip = d3.select("#zoomable_sunburst")
            .append("div")
            .attr("class", "tooltip")
            .style("position", "absolute")
            .style("z-index", "10")
            .style("opacity", 0);

        function format_number(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        }

        function format_name(d) {
            var name = d.name;
            return '' + name + '
';
        }

        d3.json(url, function(error, root) {

            console.log("data:", root);

            var path = svg.selectAll("path")
                .data(partition.nodes(root))
                .enter().append("path")
                .attr("d", arc)
                .attr("id", function(d, i) {
                    return "path-" + i + "";
                })
                .style("stroke", "#2C2C28")
                .style("fill", setNodeColor)
                .on("click", click)
                .on("mouseover", function(d) {
                    tooltip.html(function() {
                        var name = format_name(d);
                        return name;
                    });
                    return tooltip.transition()
                        .duration(50)
                        .style("opacity", 0.9);
                })
                .on("mousemove", function(d) {
                    return tooltip
                        .style("top", (d3.event.pageY - 10) + "px")
                        .style("left", (d3.event.pageX + 10) + "px");
                })
                .on("mouseout", function(d) {
                    return tooltip.style("opacity", 0);
                });

            buildLegend(root);

            function buildLegend(clickedObject) {

                $(".legend").remove();

                console.log(clickedObject);

                // I want to build the legend with only clickedObject's children whose value is not 0????

                var legendContainer = d3.select("#zoomable_sunburst")
                    .append("svg")
                    .attr("class", "legend")
                    .attr("width", 200)
                    .attr("height", 300);

                var legend = legendContainer.selectAll("rect")
                    .data(clickedObject.children)
                    .enter()
                    .append("rect")
                    .attr("transform", function(d, i) {
                        return "translate(0," + i * 32 + ")";
                    })
                    .attr("width", 200)
                    .attr("margin-bottom", 1)
                    .attr("margin-top", 1)
                    .attr("height", 30)
                    .style("fill", function(d) {
                        return d.nodeColor;
                    })
                    .on("click", click);

                legendContainer.selectAll("text")
                    .data(clickedObject.children)
                    .enter()
                    .append("text")
                    .attr("dy", ".35em")
                    .attr("transform", function(d, i) {
                        return "translate(100," + ((i * 32) + 15) + ")";
                    })
                    .style("text-anchor", "middle")
                    .style("fill", "black")
                    .text(function(d) {
                        return d.name;
                    })
                    .on("click", click);
            }

            function click(d) {

                path.transition()
                    .duration(750)
                    .attrTween("d", arcTween(d));

                d3.select(".legend").transition()
                    .duration(100)
                    .style('opacity', 0.2)
                    .remove();

                buildLegend(d);
            }

        });

        d3.select(self.frameElement).style("height", height + "px");

        // Interpolate the scales!
        function arcTween(d) {
            var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
                yd = d3.interpolate(y.domain(), [d.y, 1]),
                yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
            return function(d, i) {
                return i ? function(t) {
                    return arc(d);
                } : function(t) {
                    x.domain(xd(t));
                    y.domain(yd(t)).range(yr(t));
                    return arc(d);
                };
            };
        }

    }

});
<commit_msg>all buttons aligned<commit_after>jQuery(document).ready(function($) {

    var width = 960,
        height = 740,
        radius = Math.min(width, height) / 2;

    var x = d3.scale.linear()
        .range([0, 2 * Math.PI]);

    var y = d3.scale.sqrt()
        .range([0, radius]);

    createSunburst("/sunburst");

    var colorGroup0 = ["#FFE1F4", "#FFBFE8", "#FF99D9", "#FF82D0", "#FF6FC9", "#FF4DBC", "#FF2BAF", "#FF009F", "#F7009A", "#EC0094", "#DF008B"];
    var colorGroup1 = ["#E7E9FA", "#CACEF4", "#AAB0EE", "#979FEA", "#8791E7", "#6A76E1", "#4E5BDC", "#2B3CD5", "#2939CD", "#2737C5", "#2534BA"];
    var colorGroup2 = ["#E7F3FA", "#CCE6F2", "#ADD7EB", "#9ACEE7", "#8BC6E2", "#70B9DC", "#54ABD6", "#329BCD", "#3096C7", "#2E8FBE", "#2E8FBE"];
    var colorGroup3 = ["#006060", "#007171", "#007D7D", "#00A4A4", "#00B0B0", "#00D0D0", "#00DFDF", "#00ECEC", "#00F7F7", "#00FFFF", "#2BFFFF", "#4DFFFF"];
    var colorGroup4 = ["#DFDF00", "#ECEC00", "#F7F700", "#FFFF00", "#FFFF2B", "#FFFF4D", "#FFFF6F", "#FFFF82", "#FFFF99", "#FFFFBF", "#FFFFE1"];
    var colorGroup5 = ["#FFF0E1", "#FFDFBF", "#FFCC99", "#FFC082", "#FFB76F", "#FFA64D", "#FF8000", "#F77B00", "#EC7600", "#DF7000"];
    var colorGroup6 = ["#0000F7", "#3131C6", "#0000FF", "#3232CD", "#2B2BFF", "#5555D5", "#4D4DFF", "#7070DC", "#6F6FFF", "#8B8BE2", "#8282FF", "#9A9AE7", "#9999FF", "#ADADEB", "#BFBFFF", "#CCCCF2", "#E1E1FF"];
    var colorGroup7 = ["#E8F9ED", "#CCF2D9", "#ADEBC1", "#9BE6B4", "#55D57E", "#8BE2A8", "#71DB94", "#33CC65", "#30BC5E", "#2DB358", "#2BA653"];
    var colorGroup8 = ["#FFE6E1", "#FFC9BF", "#FFA899", "#FF9582", "#FF846F", "#FF674D", "#FF4A2B", "#FF2600", "#F72500", "#EC2300", "#DF2200"];
    var colorGroup9 = ["#F0EDF3", "#DFD8E7", "#CCBFD9", "#C0B0D0", "#B7A5C9", "#A68FBC", "#957AAF", "#80609F", "#7B5C9A", "#765894", "#70548B"];
    var colorGroup10 = ["#FBE6E6", "#F5C9C9", "#F0A8A8", "#ED9494", "#EB8383", "#E66666", "#E14848", "#DB2424", "#D32323", "#CB2121", "#BF2020"];

    var colorGroups = [colorGroup0, colorGroup1, colorGroup2, colorGroup3, colorGroup4, colorGroup5, colorGroup6, colorGroup7, colorGroup8, colorGroup9, colorGroup10];

    var BASE_COLOR = "#2C2C28";
    var POSITIVE_COLOR = "#007D00";
    var NEGATIVE_COLOR = "#7D1300";

    // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
    // Returns a random integer between min (included) and max (excluded)
    // Using Math.round() will give you a non-uniform distribution!
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
    }

    function randomColorFromGroup(groupNumber) {
        var colorArray = colorGroups[groupNumber];
        var index = getRandomInt(0, colorGroups.length - 1);
        return colorArray[index];
    }

    function setNodeColor(node) {
        var color;
        if (node.depth === 0) {
            color = BASE_COLOR;
        } else {
            switch (node.group) {
                case "Positive":
                    color = POSITIVE_COLOR;
                    break;
                case "Negative":
                    color = NEGATIVE_COLOR;
                    break;
                default:
                    color = randomColorFromGroup(node.group);
            }
        }
        return (node.nodeColor = color);
    }

    $(".chartbutton").on("click", function() {
        event.preventDefault();
        var chartUrl = $(this).attr("href")
        $(".tooltip").remove();
        d3.selectAll("svg").transition()
            .duration(1000)
            .style('opacity', 0.2)
            .remove();
        createSunburst(chartUrl);
    });

    $("#search-button").on('click', function(event) {
        event.preventDefault();

        $(".tooltip").remove();
        d3.selectAll("svg").transition()
            .duration(1000)
            .style('opacity', 0.2)
            .remove();
        var searchTerm = $("#box").val().replace(/ /g, '+');
        var searchUrl = "/search?utf8=✓&search=" + searchTerm + "&commit=Search";

        console.log("search url:", searchUrl);
        createSunburst(searchUrl);
    });

    function createSunburst(url) {

        var svg = d3.select("#zoomable_sunburst").append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + (height / 2) + ")");

        var partition = d3.layout.partition()
            .value(function(d) {
                return d.size;
            });

        arc = d3.svg.arc()
            .startAngle(function(d) {
                return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
            })
            .endAngle(function(d) {
                return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
            })
            .innerRadius(function(d) {
                return Math.max(0, y(d.y));
            })
            .outerRadius(function(d) {
                return Math.max(0, y(d.y + d.dy));
            });

        var tooltip = d3.select("#zoomable_sunburst")
            .append("div")
            .attr("class", "tooltip")
            .style("position", "absolute")
            .style("z-index", "10")
            .style("opacity", 0);

        function format_number(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        }

        function format_name(d) {
            var name = d.name;
            return '' + name + '
';
        }

        d3.json(url, function(error, root) {

            console.log("data:", root);

            var path = svg.selectAll("path")
                .data(partition.nodes(root))
                .enter().append("path")
                .attr("d", arc)
                .attr("id", function(d, i) {
                    return "path-" + i + "";
                })
                .style("stroke", "#2C2C28")
                .style("fill", setNodeColor)
                .on("click", click)
                .on("mouseover", function(d) {
                    tooltip.html(function() {
                        var name = format_name(d);
                        return name;
                    });
                    return tooltip.transition()
                        .duration(50)
                        .style("opacity", 0.9);
                })
                .on("mousemove", function(d) {
                    return tooltip
                        .style("top", (d3.event.pageY - 10) + "px")
                        .style("left", (d3.event.pageX + 10) + "px");
                })
                .on("mouseout", function(d) {
                    return tooltip.style("opacity", 0);
                });

            buildLegend(root);

            function buildLegend(clickedObject) {

                $(".legend").remove();

                console.log(clickedObject);

                // I want to build the legend with only clickedObject's children whose value is not 0????

                var legendContainer = d3.select("#zoomable_sunburst")
                    .append("svg")
                    .attr("class", "legend")
                    .attr("width", 200)
                    .attr("height", 300);

                var legend = legendContainer.selectAll("rect")
                    .data(clickedObject.children)
                    .enter()
                    .append("rect")
                    .attr("transform", function(d, i) {
                        return "translate(0," + i * 32 + ")";
                    })
                    .attr("width", 200)
                    .attr("margin-bottom", 1)
                    .attr("margin-top", 1)
                    .attr("height", 30)
                    .style("fill", function(d) {
                        return d.nodeColor;
                    })
                    .on("click", click);

                legendContainer.selectAll("text")
                    .data(clickedObject.children)
                    .enter()
                    .append("text")
                    .attr("dy", ".35em")
                    .attr("transform", function(d, i) {
                        return "translate(100," + ((i * 32) + 15) + ")";
                    })
                    .style("text-anchor", "middle")
                    .style("fill", "black")
                    .text(function(d) {
                        return d.name;
                    })
                    .on("click", click);
            }

            function click(d) {

                path.transition()
                    .duration(750)
                    .attrTween("d", arcTween(d));

                d3.select(".legend").transition()
                    .duration(100)
                    .style('opacity', 0.2)
                    .remove();

                buildLegend(d);
            }

        });

        d3.select(self.frameElement).style("height", height + "px");

        // Interpolate the scales!
        function arcTween(d) {
            var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
                yd = d3.interpolate(y.domain(), [d.y, 1]),
                yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
            return function(d, i) {
                return i ? function(t) {
                    return arc(d);
                } : function(t) {
                    x.domain(xd(t));
                    y.domain(yd(t)).range(yr(t));
                    return arc(d);
                };
            };
        }

    }

});
<|endoftext|>


<commit_before>'use strict';

(function(angular) {

  var app = angular.module('ov.tableForm', ['ov.i18n', 'ngSanitize']);

  /**
   * Defines a service reload Table
   */
  function TableReloadEventService($rootScope) {
    var sharedService = {};

    // deliver a broadcast service to reload datatable
    sharedService.broadcast = function() {
      $rootScope.$broadcast('reloadDataTable');
    };
    return sharedService;
  }

  /**
   *  Defines a DatePicker controller.
   */
  function DatePickerController() {
    var self = this;

    self.today = function() {
      self.dt = new Date();
    };
    self.today();

    self.clear = function() {
      self.dt = null;
    };

    self.toggleMax = function() {
      self.maxDate = self.maxDate ? null : new Date();
    };
    self.toggleMax();

    self.open = function() {
      self.status.opened = true;
    };

    self.dateOptions = {
      startingDay: 1
    };
    self.status = {
      opened: false
    };
  }

  /**
   * Defines a FormEditController.
   */
  function FormEditController($scope, $filter, entityService, tableReloadEventService) {

    var self = this;
    var type = $scope.editFormContainer.entityType || '';

    // init the form on a row
    this.init = function(row) {
      self.model = row;

      // Call init function if defined to set up dynamically some fields
      if ($scope.editFormContainer.init)
        $scope.editFormContainer.init(row);
      self.fields = $scope.editFormContainer.fields;
      self.originalFields = self.fields;
    };

    // Condition on a row to be edited
    this.conditionEditDetail = $scope.editFormContainer.conditionEditDetail || function() {
      return true;
    };

    this.updateRowBeforeEdit = function(tableRow, lastValueInDb) {
      if ($scope.editFormContainer.updateRowObjectBeforeEdit)
        $scope.editFormContainer.updateRowObjectBeforeEdit(tableRow, lastValueInDb);
      var cacheMustBeDeleted = false;
      for (var attrname in lastValueInDb) {
        if (tableRow[attrname] && typeof tableRow[attrname] !== 'object' &&
                tableRow[attrname] != lastValueInDb[attrname]) {
          cacheMustBeDeleted = true;
          tableRow[attrname] = lastValueInDb[attrname];
        }
      }

      // return if cache need to be deleted (true if any value is change between TableRow and lastValueInDb
      return cacheMustBeDeleted;
    };

    // When submit the form
    this.onSubmit = function() {
      if ($scope.editFormContainer.onSubmit) {
        self.model.saving = true;

        // Call submit function
        $scope.editFormContainer.onSubmit(self.model, function() {

          // on success
          // save value in the fields as initial value
          self.options.updateInitialValue();
          self.model.saving = false;
        }, function() {

          // on error
          // reset the form
          self.options.resetModel();
          $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
          self.model.saving = false;
        });
      } else {

        // if there is no submit function : alert
        $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
      }
    };
    this.options = {};

    // Toggle between show and editable information
    this.editForm = function() {
      entityService.getEntity(type, self.model.id).then(function(response) {
        if (response.data.entity) {
          var lastValue = response.data.entity;
          var cacheMustBeDeleted = self.updateRowBeforeEdit(self.model, lastValue);

          if (cacheMustBeDeleted) {
            $scope.$emit('setAlert', 'warning', $filter('translate')('UI.WARNING_ENTITY_MODIFIED'), 8000);
            entityService.deleteCache(type);
          }
        } else {
          entityService.deleteCache(type);
          $scope.$emit('setAlert', 'danger', $filter('translate')('UI.WARNING_ENTITY_DELETED'), 8000);
          tableReloadEventService.broadcast();
          return;
        }
        $scope.editFormContainer.pendingEdition = true;
        self.form.$show();
      });
    };

    this.cancelForm = function() {
      $scope.editFormContainer.pendingEdition = false;
      self.form.$cancel();
    };
  }

  /**
   * Defines a FormAddController.
   */
  function FormAddController($scope, $filter, tableReloadEventService) {
    var self = this;
    this.model = $scope.addFormContainer.model;
    this.fields = $scope.addFormContainer.fields;

    this.onSubmit = function() {

      // Call submit function
      $scope.addFormContainer.onSubmit(self.model, function() {

        // on success
        // reset the form
        self.options.resetModel();

        // Reload the table
        tableReloadEventService.broadcast();

        // Emit a succeed message
        $scope.$emit('setAlert', 'success', $filter('translate')('UI.SAVE_SUCCESS'), 4000);
      }, function() {
        $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
      });
    };
    this.options = {};
  }

  /**
   * Defines a DataTableController.
   */
  function DataTableController($scope, $modal, entityService) {
    var self = this;

    // All data
    this.rows = $scope.tableContainer.rows || {};

    // Entity to call
    this.entityType = $scope.tableContainer.entityType || '';

    // Filter key list
    this.filterBy = angular.copy($scope.tableContainer.filterBy);

    // Header list
    this.header = $scope.tableContainer.header || [];

    // action object to display in le actions list
    this.actions = $scope.tableContainer.actions || [];

    // Column unsortable
    this.notSortBy = ['action'];

    this.conditionToggleDetail = $scope.editFormContainer.conditionToggleDetail || function() {
      return true;
    };

    // hide selected checkbox
    this.showSelectAll = $scope.tableContainer.showSelectAll || true;

    // is a row selected
    this.isRowSelected = false;

    // Init Datatable
    this.init = {
      count: 10,
      page: 1,
      sortBy: $scope.tableContainer.init ? $scope.tableContainer.init.sortBy : this.header[0]['key'],
      sortOrder: $scope.tableContainer.init ? $scope.tableContainer.init.sortOrder : 'asc'
    };

    this.customTheme = {
      iconUp: 'glyphicon glyphicon-triangle-bottom',
      iconDown: 'glyphicon glyphicon-triangle-top',
      listItemsPerPage: [5, 10, 20, 30],
      itemsPerPage: 10,
      loadOnInit: true,
      cellTheme: $scope.tableContainer.cellTheme
    };

    // Enable selectAll option
    if (this.showSelectAll)
      this.customTheme['templateHeadUrl'] = 'views/elements/head.html';

    // Pagination template
    this.customTheme['templateUrl'] = 'views/elements/pagination.html';

    // callback to load Resource on filter, pagination or sort change
    this.getResource = function(params, paramsObj) {
      var param = {};
      param['count'] = paramsObj.count;
      param['page'] = paramsObj.page;
      param['sort'] = {};
      param['sort'][paramsObj.sortBy] = paramsObj.sortOrder == 'dsc' ? -1 : 1;
      param['filter'] = {};
      self.filterBy.forEach(function(filter) {
        if (filter.value && filter.value != '') {
          if (filter.type == 'date') {
            var date = new Date(filter.value);
            var datePlus = new Date(date);
            datePlus.setDate(date.getDate() + 1);
            param['filter'][filter.key] = {
              $gte: date.getTime(),
              $lt: datePlus.getTime()
            };
          } else if (filter.type == 'select') {
            var values = [filter.value];
            if (filter.filterWithChildren) {
              for (var i = 0; i < filter.options.length; i++) {
                if (filter.options[i].value === filter.value) {
                  values = values.concat(filter.options[i].children.split(','));
                  break;
                }
              }
            }

            param['filter'][filter.key] = {
              $in: values
            };
          } else
            param['filter'][filter.key] = {
              $regex: '.*' + filter.value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '.*'
            };
        }
      });

      // call entities that match params
      return entityService.getEntities(self.entityType, param).then(function(response) {
        self.rows = response.data.rows;
        self.selectAll = false;
        self.isRowSelected = false;
        return {
          rows: self.rows,
          header: self.header,
          pagination: response.data.pagination
        };
      });
    };

    // function to toggle detail
    this.toggleRowDetails = function(row) {
      if (self.conditionToggleDetail(row))
        angular.forEach(self.rows, function(value) {
          value.opened = (value.id === row.id) ? !value.opened : false;
          $scope.editFormContainer.pendingEdition = false;
        });
    };

    // function to call manually to reload dataTable
    this.reloadCallback = function() {
      self.selectAll = false;
    };

    // Broadcast listner to reload dataTable (on add row for exemple)
    $scope.$on('reloadDataTable', function() {
      self.reloadCallback();
    });

    this.commonActionExist = false;

    // call to check all unlocked selection checkbox
    this.checkAll = function() {
      self.commonActionExist = false;
      angular.forEach(self.rows, function(row) {
        row.selected = self.selectAll;
      });
      self.isRowSelected = self.selectAll;
    };

    // call to uncheck the global selection checkbox
    this.uncheckOne = function() {
      self.commonActionExist = false;
      self.selectAll = false;
      self.isRowSelected = false;

      // if one still selected, isRowSelected = true
      angular.forEach(self.rows, function(row) {
        if (row.selected)
          self.isRowSelected = true;
      });
    };

    // Verify if an action is enable for all selected row
    this.verifyCondition = function(action) {
      var enable = true;
      for (var i = 0; i < self.rows.length && enable; i++) {
        var row = self.rows[i];
        if (row.selected) {
          var condition = !action.condition || action.condition(row);
          enable = enable && action.global && condition;
        }
      }
      self.commonActionExist = self.commonActionExist || enable;
      return enable;
    };

    // Execute an action on row after calling a popup verifying and reload table
    this.prepareSingleAction = function(action, row) {
      if (action.warningPopup)
        self.openModal(action.callback, row);
      else {
        action.callback(row, self.reloadCallback);
      }
    };

    // Execute an action on all selected row after calling a popup verifying
    this.executeGlobalAction = function(action) {
      var selected = self.getSelectedId();
      self.openModal(action.global, selected);
    };

    // Get All selected row id
    this.getSelectedId = function() {
      var selected = [];
      for (var i = 0; i < self.rows.length; i++) {
        var row = self.rows[i];
        if (row.selected)
          selected.push(row.id);
      }
      return selected;
    };

    // Open a modal, apply callback on OK promise and reload datatable
    this.openModal = function(action, item) {

      var modalInstance = $modal.open({
        templateUrl: 'tableModal.html',
        controller: 'ModalInstanceTableController'
      });

      modalInstance.result.then(function() {
        action(item, self.reloadCallback);
      }, function() {

        // Do nothing

      });
    };
  }

  /**
   * Defines a modal instance for all modals related to the table form.
   */
  function ModalInstanceTableController($scope, $modalInstance) {
    $scope.ok = function() {
      $modalInstance.close(true);
    };

    $scope.cancel = function() {
      $modalInstance.dismiss('cancel');
    };
  }

  app.controller('DataTableController', DataTableController);
  app.controller('FormEditController', FormEditController);
  app.controller('FormAddController', FormAddController);
  app.controller('ModalInstanceTableController', ModalInstanceTableController);
  app.controller('DatePickerController', DatePickerController);
  app.factory('tableReloadEventService', TableReloadEventService);

  // Controller for table, form in table and form outside table
  DataTableController.$inject = ['$scope', '$modal', 'entityService'];
  FormEditController.$inject = ['$scope', '$filter', 'entityService', 'tableReloadEventService'];
  FormAddController.$inject = ['$scope', '$filter', 'tableReloadEventService'];
  ModalInstanceTableController.$inject = ['$scope', '$modalInstance'];
  DatePickerController.$inject = ['$scope'];

  // Service to reload a displayed table
  TableReloadEventService.$inject = ['$rootScope'];

})(angular);
<commit_msg>#0000018 update table after editing value - meanly to update search<commit_after>'use strict';

(function(angular) {

  var app = angular.module('ov.tableForm', ['ov.i18n', 'ngSanitize']);

  /**
   * Defines a service reload Table
   */
  function TableReloadEventService($rootScope) {
    var sharedService = {};

    // deliver a broadcast service to reload datatable
    sharedService.broadcast = function() {
      $rootScope.$broadcast('reloadDataTable');
    };
    return sharedService;
  }

  /**
   *  Defines a DatePicker controller.
   */
  function DatePickerController() {
    var self = this;

    self.today = function() {
      self.dt = new Date();
    };
    self.today();

    self.clear = function() {
      self.dt = null;
    };

    self.toggleMax = function() {
      self.maxDate = self.maxDate ? null : new Date();
    };
    self.toggleMax();

    self.open = function() {
      self.status.opened = true;
    };

    self.dateOptions = {
      startingDay: 1
    };
    self.status = {
      opened: false
    };
  }

  /**
   * Defines a FormEditController.
   */
  function FormEditController($scope, $filter, entityService, tableReloadEventService) {

    var self = this;
    var type = $scope.editFormContainer.entityType || '';

    // init the form on a row
    this.init = function(row) {
      self.model = row;

      // Call init function if defined to set up dynamically some fields
      if ($scope.editFormContainer.init)
        $scope.editFormContainer.init(row);
      self.fields = $scope.editFormContainer.fields;
      self.originalFields = self.fields;
    };

    // Condition on a row to be edited
    this.conditionEditDetail = $scope.editFormContainer.conditionEditDetail || function() {
      return true;
    };

    this.updateRowBeforeEdit = function(tableRow, lastValueInDb) {
      if ($scope.editFormContainer.updateRowObjectBeforeEdit)
        $scope.editFormContainer.updateRowObjectBeforeEdit(tableRow, lastValueInDb);
      var cacheMustBeDeleted = false;
      for (var attrname in lastValueInDb) {
        if (tableRow[attrname] && typeof tableRow[attrname] !== 'object' &&
                tableRow[attrname] != lastValueInDb[attrname]) {
          cacheMustBeDeleted = true;
          tableRow[attrname] = lastValueInDb[attrname];
        }
      }

      // return if cache need to be deleted (true if any value is change between TableRow and lastValueInDb
      return cacheMustBeDeleted;
    };

    // When submit the form
    this.onSubmit = function() {
      if ($scope.editFormContainer.onSubmit) {
        self.model.saving = true;

        // Call submit function
        $scope.editFormContainer.onSubmit(self.model, function() {

          // on success
          // save value in the fields as initial value
          self.options.updateInitialValue();
          self.model.saving = false;
          tableReloadEventService.broadcast();
        }, function() {

          // on error
          // reset the form
          self.options.resetModel();
          $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
          self.model.saving = false;
        });
      } else {

        // if there is no submit function : alert
        $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
      }
    };
    this.options = {};

    // Toggle between show and editable information
    this.editForm = function() {
      entityService.getEntity(type, self.model.id).then(function(response) {
        if (response.data.entity) {
          var lastValue = response.data.entity;
          var cacheMustBeDeleted = self.updateRowBeforeEdit(self.model, lastValue);

          if (cacheMustBeDeleted) {
            $scope.$emit('setAlert', 'warning', $filter('translate')('UI.WARNING_ENTITY_MODIFIED'), 8000);
            entityService.deleteCache(type);
          }
        } else {
          entityService.deleteCache(type);
          $scope.$emit('setAlert', 'danger', $filter('translate')('UI.WARNING_ENTITY_DELETED'), 8000);
          tableReloadEventService.broadcast();
          return;
        }
        $scope.editFormContainer.pendingEdition = true;
        self.form.$show();
      });
    };

    this.cancelForm = function() {
      $scope.editFormContainer.pendingEdition = false;
      self.form.$cancel();
    };
  }

  /**
   * Defines a FormAddController.
   */
  function FormAddController($scope, $filter, tableReloadEventService) {
    var self = this;
    this.model = $scope.addFormContainer.model;
    this.fields = $scope.addFormContainer.fields;

    this.onSubmit = function() {

      // Call submit function
      $scope.addFormContainer.onSubmit(self.model, function() {

        // on success
        // reset the form
        self.options.resetModel();

        // Reload the table
        tableReloadEventService.broadcast();

        // Emit a succeed message
        $scope.$emit('setAlert', 'success', $filter('translate')('UI.SAVE_SUCCESS'), 4000);
      }, function() {
        $scope.$emit('setAlert', 'danger', $filter('translate')('UI.SAVE_ERROR'), 4000);
      });
    };
    this.options = {};
  }

  /**
   * Defines a DataTableController.
   */
  function DataTableController($scope, $modal, entityService) {
    var self = this;

    // All data
    this.rows = $scope.tableContainer.rows || {};

    // Entity to call
    this.entityType = $scope.tableContainer.entityType || '';

    // Filter key list
    this.filterBy = angular.copy($scope.tableContainer.filterBy);

    // Header list
    this.header = $scope.tableContainer.header || [];

    // action object to display in le actions list
    this.actions = $scope.tableContainer.actions || [];

    // Column unsortable
    this.notSortBy = ['action'];

    this.conditionToggleDetail = $scope.editFormContainer.conditionToggleDetail || function() {
      return true;
    };

    // hide selected checkbox
    this.showSelectAll = $scope.tableContainer.showSelectAll || true;

    // is a row selected
    this.isRowSelected = false;

    // Init Datatable
    this.init = {
      count: 10,
      page: 1,
      sortBy: $scope.tableContainer.init ? $scope.tableContainer.init.sortBy : this.header[0]['key'],
      sortOrder: $scope.tableContainer.init ? $scope.tableContainer.init.sortOrder : 'asc'
    };

    this.customTheme = {
      iconUp: 'glyphicon glyphicon-triangle-bottom',
      iconDown: 'glyphicon glyphicon-triangle-top',
      listItemsPerPage: [5, 10, 20, 30],
      itemsPerPage: 10,
      loadOnInit: true,
      cellTheme: $scope.tableContainer.cellTheme
    };

    // Enable selectAll option
    if (this.showSelectAll)
      this.customTheme['templateHeadUrl'] = 'views/elements/head.html';

    // Pagination template
    this.customTheme['templateUrl'] = 'views/elements/pagination.html';

    // callback to load Resource on filter, pagination or sort change
    this.getResource = function(params, paramsObj) {
      var param = {};
      param['count'] = paramsObj.count;
      param['page'] = paramsObj.page;
      param['sort'] = {};
      param['sort'][paramsObj.sortBy] = paramsObj.sortOrder == 'dsc' ? -1 : 1;
      param['filter'] = {};
      self.filterBy.forEach(function(filter) {
        if (filter.value && filter.value != '') {
          if (filter.type == 'date') {
            var date = new Date(filter.value);
            var datePlus = new Date(date);
            datePlus.setDate(date.getDate() + 1);
            param['filter'][filter.key] = {
              $gte: date.getTime(),
              $lt: datePlus.getTime()
            };
          } else if (filter.type == 'select') {
            var values = [filter.value];
            if (filter.filterWithChildren) {
              for (var i = 0; i < filter.options.length; i++) {
                if (filter.options[i].value === filter.value) {
                  values = values.concat(filter.options[i].children.split(','));
                  break;
                }
              }
            }

            param['filter'][filter.key] = {
              $in: values
            };
          } else
            param['filter'][filter.key] = {
              $regex: '.*' + filter.value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '.*'
            };
        }
      });

      // call entities that match params
      return entityService.getEntities(self.entityType, param).then(function(response) {
        self.rows = response.data.rows;
        self.selectAll = false;
        self.isRowSelected = false;
        return {
          rows: self.rows,
          header: self.header,
          pagination: response.data.pagination
        };
      });
    };

    // function to toggle detail
    this.toggleRowDetails = function(row) {
      if (self.conditionToggleDetail(row))
        angular.forEach(self.rows, function(value) {
          value.opened = (value.id === row.id) ? !value.opened : false;
          $scope.editFormContainer.pendingEdition = false;
        });
    };

    // function to call manually to reload dataTable
    this.reloadCallback = function() {
      self.selectAll = false;
    };

    // Broadcast listner to reload dataTable (on add row for exemple)
    $scope.$on('reloadDataTable', function() {
      self.reloadCallback();
    });

    this.commonActionExist = false;

    // call to check all unlocked selection checkbox
    this.checkAll = function() {
      self.commonActionExist = false;
      angular.forEach(self.rows, function(row) {
        row.selected = self.selectAll;
      });
      self.isRowSelected = self.selectAll;
    };

    // call to uncheck the global selection checkbox
    this.uncheckOne = function() {
      self.commonActionExist = false;
      self.selectAll = false;
      self.isRowSelected = false;

      // if one still selected, isRowSelected = true
      angular.forEach(self.rows, function(row) {
        if (row.selected)
          self.isRowSelected = true;
      });
    };

    // Verify if an action is enable for all selected row
    this.verifyCondition = function(action) {
      var enable = true;
      for (var i = 0; i < self.rows.length && enable; i++) {
        var row = self.rows[i];
        if (row.selected) {
          var condition = !action.condition || action.condition(row);
          enable = enable && action.global && condition;
        }
      }
      self.commonActionExist = self.commonActionExist || enable;
      return enable;
    };

    // Execute an action on row after calling a popup verifying and reload table
    this.prepareSingleAction = function(action, row) {
      if (action.warningPopup)
        self.openModal(action.callback, row);
      else {
        action.callback(row, self.reloadCallback);
      }
    };

    // Execute an action on all selected row after calling a popup verifying
    this.executeGlobalAction = function(action) {
      var selected = self.getSelectedId();
      self.openModal(action.global, selected);
    };

    // Get All selected row id
    this.getSelectedId = function() {
      var selected = [];
      for (var i = 0; i < self.rows.length; i++) {
        var row = self.rows[i];
        if (row.selected)
          selected.push(row.id);
      }
      return selected;
    };

    // Open a modal, apply callback on OK promise and reload datatable
    this.openModal = function(action, item) {

      var modalInstance = $modal.open({
        templateUrl: 'tableModal.html',
        controller: 'ModalInstanceTableController'
      });

      modalInstance.result.then(function() {
        action(item, self.reloadCallback);
      }, function() {

        // Do nothing

      });
    };
  }

  /**
   * Defines a modal instance for all modals related to the table form.
   */
  function ModalInstanceTableController($scope, $modalInstance) {
    $scope.ok = function() {
      $modalInstance.close(true);
    };

    $scope.cancel = function() {
      $modalInstance.dismiss('cancel');
    };
  }

  app.controller('DataTableController', DataTableController);
  app.controller('FormEditController', FormEditController);
  app.controller('FormAddController', FormAddController);
  app.controller('ModalInstanceTableController', ModalInstanceTableController);
  app.controller('DatePickerController', DatePickerController);
  app.factory('tableReloadEventService', TableReloadEventService);

  // Controller for table, form in table and form outside table
  DataTableController.$inject = ['$scope', '$modal', 'entityService'];
  FormEditController.$inject = ['$scope', '$filter', 'entityService', 'tableReloadEventService'];
  FormAddController.$inject = ['$scope', '$filter', 'tableReloadEventService'];
  ModalInstanceTableController.$inject = ['$scope', '$modalInstance'];
  DatePickerController.$inject = ['$scope'];

  // Service to reload a displayed table
  TableReloadEventService.$inject = ['$rootScope'];

})(angular);
<|endoftext|>


<commit_before>/**
 *
 * GeometryCanvasUuid
 *
 */

import React from 'react';
import styled from 'styled-components';

import Button from 'material-ui/Button';

import axios from 'axios';
import { graphQLRoot } from 'utils/constants';

import PropTypes from 'prop-types';
import { download } from 'utils';

import { MdFileDownload } from 'react-icons/lib/md';

const MButton = styled(Button)`
  margin: 12px,
`;

class GeometryCanvasUuid extends React.Component { // eslint-disable-line react/prefer-stateless-function
  componentDidUpdate() {
    if (this.props.uuid !== '') {
      const query = {
        query: `query{systems(uniqueId: "${this.props.uuid}") {
  edges { node { Cifdata } } }}`,
      };
      axios.post(graphQLRoot, query)
      .then((res) => {
        const cifdata = res.data.data.systems.edges[0].node.Cifdata;
        this.cifdata = cifdata;
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.innerHTML = `
function _load_lib(url, callback){
  id =  'load_' + url;
  var s = document.createElement('script');
  s.src = url;
  s.id = id;
  s.async = true;
  s.onreadystatechange = s.onload = callback;
  s.onerror = function(){console.warn("failed to load library " + url);};
  document.getElementsByTagName("head")[0].appendChild(s);

}
// Load Libraries
_load_lib("https://code.jquery.com/jquery-3.2.1.min.js", function(){
  _load_lib("https://hub.chemdoodle.com/cwc/8.0.0/ChemDoodleWeb.js", function(){

  var rotationMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]

  //Code
  let tfcanvas = new ChemDoodle.TransformCanvas3D('${this.props.id}_view');
  let cif = ChemDoodle.readCIF(\`${cifdata}\`, 2, 2, 1);

  tfcanvas.specs.set3DRepresentation('Ball and Stick');
  tfcanvas.specs.backgroundColor = '${this.props.color}';
  tfcanvas.specs.projectionPerspective_3D = true;
  tfcanvas.specs.atoms_displayLabels_3D = true;
  tfcanvas.specs.crystals_unitCellLineWidth = 5;
  tfcanvas.specs.shapes_color = 'black';
  tfcanvas.specs.shapes_lineWidth = 1;
  tfcanvas.specs.fog_mode_3D = 0;
  tfcanvas.specs.shadow_3D = false;
  tfcanvas.specs.atoms_useJMOLColors = true;
  tfcanvas.specs.compass_display = true;
  tfcanvas.loadContent([cif.molecule], [cif.unitCell]);
  });
});`;
        document.getElementById(`${this.props.id}_view`).appendChild(script);
      });
    }
  }

  render() {
    return (

        { /*  this.state.loading ? <LinearProgress color="primary" /> : null */ }
        <p id={`${this.props.id}_script`} />
        <canvas
          id={`${this.props.id}_view`}
          height={this.props.height}
          width={this.props.width}
          style={{
            borderWidth: 1,
            borderColor: '#000000',
            borderStyle: 'solid',
          }}
        />

        <MButton
          raised
          onClick={() => { download(`structure_${this.props.id}.cif`, this.cifdata); }}
          style={{
            margin: 12,
          }}
        >
          <MdFileDownload /> Download CIF
        </MButton>

    );
  }
}

GeometryCanvasUuid.defaultProps = {
  height: 550,
  width: 550,
  color: '#fff',
  uuid: '',

};

GeometryCanvasUuid.propTypes = {
  id: PropTypes.string.isRequired,
  uuid: PropTypes.string,
  height: PropTypes.number,
  width: PropTypes.number,
  color: PropTypes.string,
};

export default GeometryCanvasUuid;
<commit_msg>Broke out a couple of options into arguments<commit_after>/**
 *
 * GeometryCanvasUuid
 *
 */

import React from 'react';
import styled from 'styled-components';

import Button from 'material-ui/Button';

import axios from 'axios';
import { graphQLRoot } from 'utils/constants';

import PropTypes from 'prop-types';
import { download } from 'utils';

import { MdFileDownload } from 'react-icons/lib/md';

const MButton = styled(Button)`
  margin: 12px,
`;

class GeometryCanvasUuid extends React.Component { // eslint-disable-line react/prefer-stateless-function
  componentDidUpdate() {
    if (this.props.uuid !== '') {
      const query = {
        query: `query{systems(uniqueId: "${this.props.uuid}") {
  edges { node { Cifdata } } }}`,
      };
      axios.post(graphQLRoot, query)
      .then((res) => {
        const cifdata = res.data.data.systems.edges[0].node.Cifdata;
        this.cifdata = cifdata;
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.innerHTML = `
function _load_lib(url, callback){
  id =  'load_' + url;
  var s = document.createElement('script');
  s.src = url;
  s.id = id;
  s.async = true;
  s.onreadystatechange = s.onload = callback;
  s.onerror = function(){console.warn("failed to load library " + url);};
  document.getElementsByTagName("head")[0].appendChild(s);

}
// Load Libraries
_load_lib("https://code.jquery.com/jquery-3.2.1.min.js", function(){
  _load_lib("https://hub.chemdoodle.com/cwc/8.0.0/ChemDoodleWeb.js", function(){

  var rotationMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]

  //Code
  let tfcanvas = new ChemDoodle.TransformCanvas3D('${this.props.id}_view');
  let cif = ChemDoodle.readCIF(\`${cifdata}\`, ${this.props.x}, ${this.props.y}, ${this.props.z});

  tfcanvas.specs.set3DRepresentation('Ball and Stick');
  tfcanvas.specs.backgroundColor = '${this.props.color}';
  tfcanvas.specs.projectionPerspective_3D = true;
  tfcanvas.specs.atoms_displayLabels_3D = ${this.props.showLabels};
  tfcanvas.specs.crystals_unitCellLineWidth = 5;
  tfcanvas.specs.shapes_color = 'black';
  tfcanvas.specs.shapes_lineWidth = 1;
  tfcanvas.specs.fog_mode_3D = 0;
  tfcanvas.specs.shadow_3D = false;
  tfcanvas.specs.atoms_useJMOLColors = true;
  tfcanvas.specs.compass_display = ${this.props.showCompass};
  tfcanvas.loadContent([cif.molecule], [cif.unitCell]);
  });
});`;
        document.getElementById(`${this.props.id}_view`).appendChild(script);
      });
    }
  }

  render() {
    return (

        { /*  this.state.loading ? <LinearProgress color="primary" /> : null */ }
        <p id={`${this.props.id}_script`} />
        <canvas
          id={`${this.props.id}_view`}
          height={this.props.height}
          width={this.props.width}
          style={{
            borderWidth: this.props.borderWidth,
            borderColor: '#000000',
            borderStyle: 'solid',
          }}
        />

        {this.props.showDownload === false ? null :
        <MButton
          raised
          onClick={() => { download(`structure_${this.props.id}.cif`, this.cifdata); }}
          style={{
            margin: 12,
          }}
        >
          <MdFileDownload /> Download CIF
        </MButton>
        }

    );
  }
}

GeometryCanvasUuid.defaultProps = {
  height: 550,
  width: 550,
  color: '#fff',
  uuid: '',
  showDownload: true,
  showCompass: true,
  showLabels: true,
  x: 2,
  y: 2,
  z: 1,
  borderWidth: 0.1,
};

GeometryCanvasUuid.propTypes = {
  id: PropTypes.string.isRequired,
  uuid: PropTypes.string,
  height: PropTypes.number,
  width: PropTypes.number,
  color: PropTypes.string,
  showDownload: PropTypes.bool,
  showCompass: PropTypes.bool,
  showLabels: PropTypes.bool,
  x: PropTypes.number,
  y: PropTypes.number,
  z: PropTypes.number,
  borderWidth: PropTypes.number,
};

export default GeometryCanvasUuid;
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name MatchCalendarApp.MatchPost
 * @description
 * # MatchPost
 * Factory in the MatchCalendarApp.
 */
angular.module('MatchCalendarApp')
    //a match post model
    .factory('MatchPostParser', ['$rootScope', 'DateTimeService', '$location', 'GameType', function (MarkdownLinkDataService, DateTimeService, $location, GameType) {

        var ipRegex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?/g;

        return {
            /**
             * @param element the raw post element from the JSON api
             * @returns {MatchPost}
             */
            parse: function (element) {
                var post = {
                    id: element.id,
                    title: element.title,
                    selftext: element.selftext,
                    author: element.author,
                    permalink: 'https://reddit.com' + element.permalink,
                    /*jshint camelcase: false */
                    posted: moment(element.created_utc, 'X'),
                    anchorlink: '#' + $location.path() + '?post=' + element.id
                };

                var parts = post.title.split('-');

                // post isnt formatted correctly, don't display it at all
                if (parts.length < 4) {
                    return null;
                }

                // trim extra whitespaces
                parts = parts.map(function (part) {
                    return part.trim();
                });

                // attempt to parse the date from the post title
                post.opens = moment.utc(parts[0], 'MMM DD HH:mm', 'en');
                post.region = parts[1].toUpperCase();
                post.title = parts[2];

                // assume vanilla if no gamemodes
                if (parts.length === 4) {
                    post.gamemodes = ['Vanilla'];
                } else {
                    // add gamemodes
                    post.gamemodes = parts.slice(4).map(function(mode) { return mode.trim(); });
                }

                // teams parsing
                post.teams = GameType.parseGameType(parts[3]);

                // basic IP checking for parsed links, this will only work for IP addresses
                // TODO check for 'address: X' type string
                // reset regex in case of exact copy of previous post
                ipRegex.exec('');
                var ipcheck = ipRegex.exec(element.selftext);

                if (null !== ipcheck) {
                    post.address = ipcheck[1];

                    // if it's default port, dont show the port number
                    if (typeof ipcheck[2] !== 'undefined' && ipcheck[2] !== '' && ipcheck[2] !== ':25565') {
                        post.address += ipcheck[2];
                    }
                }

                //if it's invalid (no parsable date) read as unparsed date
                if (post.opens !== null && post.opens.isValid()) {
                    var current = DateTimeService.currentTime();
                    var monthsAgo = post.opens.diff(current, 'months');

                    // if it's more than 6 months old, assume it's in the next year
                    if (monthsAgo < -6) {
                        post.opens.add(1, 'years');
                    }
                    // if it's more than 6 months in the future assume it's in the last year
                    else if (monthsAgo > 6) {
                        post.opens.subtract(1, 'years');
                    }
                } else {
                    post.opens = null;
                }

                //fix html encoded entities breaking in post titles
                post.title = he.decode(post.title, {
                    'isAttributeValue': true
                });

                return post;
            }
        };
    }]);
<commit_msg>feat(MatchPostParser): switch back to , for scenario separator<commit_after>'use strict';

/**
 * @ngdoc service
 * @name MatchCalendarApp.MatchPost
 * @description
 * # MatchPost
 * Factory in the MatchCalendarApp.
 */
angular.module('MatchCalendarApp')
    //a match post model
    .factory('MatchPostParser', ['$rootScope', 'DateTimeService', '$location', 'GameType', function (MarkdownLinkDataService, DateTimeService, $location, GameType) {

        var ipRegex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?/g;

        return {
            /**
             * @param element the raw post element from the JSON api
             * @returns {MatchPost}
             */
            parse: function (element) {
                var post = {
                    id: element.id,
                    title: element.title,
                    selftext: element.selftext,
                    author: element.author,
                    permalink: 'https://reddit.com' + element.permalink,
                    /*jshint camelcase: false */
                    posted: moment(element.created_utc, 'X'),
                    anchorlink: '#' + $location.path() + '?post=' + element.id
                };

                var parts = post.title.split('-');

                // post isnt formatted correctly, don't display it at all
                if (parts.length < 4) {
                    return null;
                }

                // trim extra whitespaces
                parts = parts.map(function (part) {
                    return part.trim();
                });

                // attempt to parse the date from the post title
                post.opens = moment.utc(parts[0], 'MMM DD HH:mm', 'en');
                post.region = parts[1].toUpperCase();
                post.title = parts[2];

                // assume vanilla if no gamemodes
                if (parts.length === 4) {
                    post.gamemodes = ['Vanilla'];
                } else {
                    // add gamemodes
                    post.gamemodes = parts[4].split(',').map(function(mode) { return mode.trim(); });
                }

                // teams parsing
                post.teams = GameType.parseGameType(parts[3]);

                // basic IP checking for parsed links, this will only work for IP addresses
                // TODO check for 'address: X' type string
                // reset regex in case of exact copy of previous post
                ipRegex.exec('');
                var ipcheck = ipRegex.exec(element.selftext);

                if (null !== ipcheck) {
                    post.address = ipcheck[1];

                    // if it's default port, dont show the port number
                    if (typeof ipcheck[2] !== 'undefined' && ipcheck[2] !== '' && ipcheck[2] !== ':25565') {
                        post.address += ipcheck[2];
                    }
                }

                //if it's invalid (no parsable date) read as unparsed date
                if (post.opens !== null && post.opens.isValid()) {
                    var current = DateTimeService.currentTime();
                    var monthsAgo = post.opens.diff(current, 'months');

                    // if it's more than 6 months old, assume it's in the next year
                    if (monthsAgo < -6) {
                        post.opens.add(1, 'years');
                    }
                    // if it's more than 6 months in the future assume it's in the last year
                    else if (monthsAgo > 6) {
                        post.opens.subtract(1, 'years');
                    }
                } else {
                    post.opens = null;
                }

                //fix html encoded entities breaking in post titles
                post.title = he.decode(post.title, {
                    'isAttributeValue': true
                });

                return post;
            }
        };
    }]);
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name MatchCalendarApp.MatchPost
 * @description
 * # MatchPost
 * Factory in the MatchCalendarApp.
 */
angular.module('MatchCalendarApp')
    //a match post model
    .factory('MatchPostParser', ['DateTimeService', '$location', 'GameType', function (DateTimeService, $location, GameType) {

        var ipRegex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?/g;
        var sizeRegex = /To(\d*)/;
        var extrasRegex = /(\[.*?])/g;

        return {
            /**
             * @param element the raw post element from the JSON api
             * @returns {MatchPost}
             */
            parse: function (element) {
                var post = {
                    id: element.id,
                    title: element.title,
                    selftext: element.selftext,
                    author: element.author,
                    permalink: 'https://reddit.com' + element.permalink,
                    /*jshint camelcase: false */
                    posted: moment(element.created_utc, 'X'),
                    anchorlink: '#' + $location.path() + '?post=' + element.id,
                    isStartTime: false
                };

                // replace | with a dash and set a flag for start time
                post.title = post.title.replace('|', function() {
                    post.isStartTime = true;
                    return '-';
                });

                var parts = post.title.split('-');

                // post isnt formatted correctly, don't display it at all
                if (parts.length < 3) {
                    console.log('invalid match post formatting for post', post.id);
                    return null;
                }

                // trim extra whitespaces
                parts = parts.map(function (part) {
                    return part.trim();
                });

                // definately not formatted correctly, don't show
                if (parts[0].length < 3) {
                    console.log('invalid match post formatting for post', post.id);
                    return null;
                }

                // parse the region as the last 2 characters
                post.region = parts[0].slice(-2).toUpperCase();
                // attempt to parse the date from the post title
                post.opens = moment.utc(parts[0].slice(0, -2), 'MMM DD HH:mm', 'en');
                post.title = parts[1];

                // assume vanilla if no gamemodes
                if (parts.length === 3) {
                    post.gamemodes = ['Vanilla'];

                    // cut extras out of the team type
                    parts[2] = parts[2].replace(extrasRegex, function(part) {
                        post.title += ' ' + part;
                        return '';
                    }).trim();
                } else {
                    // add gamemodes
                    post.gamemodes = parts[3].split(',').map(function(mode) { return mode.trim(); });

                    if (post.gamemodes.length > 0) {
                        // cut the extras out of the final gamemode
                        post.gamemodes[post.gamemodes.length - 1] = post.gamemodes[post.gamemodes.length - 1].replace(extrasRegex, function(part) {
                            post.title += ' ' + part;
                            return '';
                        }).trim();
                    }
                }

                // teams parsing
                var style = parts[2];

                sizeRegex.exec('');
                var sizeCheck = sizeRegex.exec(style);

                if (null !== sizeCheck) {
                    post.teamSize = sizeCheck[1];
                    style = style.replace(sizeRegex, '').trim();
                }

                var type = GameType.parseGameType(style);

                // not usable style, put original values in
                if (null === type) {
                    post.teams = parts[2];
                } else {
                    post.teams = type.name;
                }

                // basic IP checking for parsed links, this will only work for IP addresses
                // TODO check for 'address: X' type string
                // reset regex in case of exact copy of previous post
                ipRegex.exec('');
                var ipcheck = ipRegex.exec(element.selftext);

                if (null !== ipcheck) {
                    post.address = ipcheck[1];

                    // if it's default port, dont show the port number
                    if (typeof ipcheck[2] !== 'undefined' && ipcheck[2] !== '' && ipcheck[2] !== ':25565') {
                        post.address += ipcheck[2];
                    }
                }

                //if it's invalid (no parsable date) read as unparsed date
                if (post.opens !== null && post.opens.isValid()) {
                    var current = DateTimeService.currentTime();
                    var monthsAgo = post.opens.diff(current, 'months');

                    // if it's more than 6 months old, assume it's in the next year
                    if (monthsAgo < -6) {
                        post.opens.add(1, 'years');
                    }
                    // if it's more than 6 months in the future assume it's in the last year
                    else if (monthsAgo > 6) {
                        post.opens.subtract(1, 'years');
                    }
                } else {
                    post.opens = null;
                }

                //fix html encoded entities breaking in post titles
                post.title = he.decode(post.title, {
                    'isAttributeValue': true
                });

                return post;
            }
        };
    }]);
<commit_msg>feat(MatchPostParser): also log the post title on invalid post formats<commit_after>'use strict';

/**
 * @ngdoc service
 * @name MatchCalendarApp.MatchPost
 * @description
 * # MatchPost
 * Factory in the MatchCalendarApp.
 */
angular.module('MatchCalendarApp')
    //a match post model
    .factory('MatchPostParser', ['DateTimeService', '$location', 'GameType', function (DateTimeService, $location, GameType) {

        var ipRegex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d{1,5})?/g;
        var sizeRegex = /To(\d*)/;
        var extrasRegex = /(\[.*?])/g;

        return {
            /**
             * @param element the raw post element from the JSON api
             * @returns {MatchPost}
             */
            parse: function (element) {
                var post = {
                    id: element.id,
                    title: element.title,
                    selftext: element.selftext,
                    author: element.author,
                    permalink: 'https://reddit.com' + element.permalink,
                    /*jshint camelcase: false */
                    posted: moment(element.created_utc, 'X'),
                    anchorlink: '#' + $location.path() + '?post=' + element.id,
                    isStartTime: false
                };

                // replace | with a dash and set a flag for start time
                post.title = post.title.replace('|', function() {
                    post.isStartTime = true;
                    return '-';
                });

                var parts = post.title.split('-');

                // post isnt formatted correctly, don't display it at all
                if (parts.length < 3) {
                    console.log('invalid match post formatting for post', post.id, post.title);
                    return null;
                }

                // trim extra whitespaces
                parts = parts.map(function (part) {
                    return part.trim();
                });

                // definately not formatted correctly, don't show
                if (parts[0].length < 3) {
                    console.log('invalid match post formatting for post', post.id, post.title);
                    return null;
                }

                // parse the region as the last 2 characters
                post.region = parts[0].slice(-2).toUpperCase();
                // attempt to parse the date from the post title
                post.opens = moment.utc(parts[0].slice(0, -2), 'MMM DD HH:mm', 'en');
                post.title = parts[1];

                // assume vanilla if no gamemodes
                if (parts.length === 3) {
                    post.gamemodes = ['Vanilla'];

                    // cut extras out of the team type
                    parts[2] = parts[2].replace(extrasRegex, function(part) {
                        post.title += ' ' + part;
                        return '';
                    }).trim();
                } else {
                    // add gamemodes
                    post.gamemodes = parts[3].split(',').map(function(mode) { return mode.trim(); });

                    if (post.gamemodes.length > 0) {
                        // cut the extras out of the final gamemode
                        post.gamemodes[post.gamemodes.length - 1] = post.gamemodes[post.gamemodes.length - 1].replace(extrasRegex, function(part) {
                            post.title += ' ' + part;
                            return '';
                        }).trim();
                    }
                }

                // teams parsing
                var style = parts[2];

                sizeRegex.exec('');
                var sizeCheck = sizeRegex.exec(style);

                if (null !== sizeCheck) {
                    post.teamSize = sizeCheck[1];
                    style = style.replace(sizeRegex, '').trim();
                }

                var type = GameType.parseGameType(style);

                // not usable style, put original values in
                if (null === type) {
                    post.teams = parts[2];
                } else {
                    post.teams = type.name;
                }

                // basic IP checking for parsed links, this will only work for IP addresses
                // TODO check for 'address: X' type string
                // reset regex in case of exact copy of previous post
                ipRegex.exec('');
                var ipcheck = ipRegex.exec(element.selftext);

                if (null !== ipcheck) {
                    post.address = ipcheck[1];

                    // if it's default port, dont show the port number
                    if (typeof ipcheck[2] !== 'undefined' && ipcheck[2] !== '' && ipcheck[2] !== ':25565') {
                        post.address += ipcheck[2];
                    }
                }

                //if it's invalid (no parsable date) read as unparsed date
                if (post.opens !== null && post.opens.isValid()) {
                    var current = DateTimeService.currentTime();
                    var monthsAgo = post.opens.diff(current, 'months');

                    // if it's more than 6 months old, assume it's in the next year
                    if (monthsAgo < -6) {
                        post.opens.add(1, 'years');
                    }
                    // if it's more than 6 months in the future assume it's in the last year
                    else if (monthsAgo > 6) {
                        post.opens.subtract(1, 'years');
                    }
                } else {
                    post.opens = null;
                }

                //fix html encoded entities breaking in post titles
                post.title = he.decode(post.title, {
                    'isAttributeValue': true
                });

                return post;
            }
        };
    }]);
<|endoftext|>