<commit_before>//
// Regular Expression for URL validation
//
// Author: Diego Perini
// Updated: 2010/12/05
// License: MIT
//
// Copyright (c) 2010-2013 Diego Perini (http://www.iport.it)
// https://gist.github.com/dperini/729294
var re_weburl = new RegExp(
  "^" +
  // protocol identifier
  "(?:(?:https?|ftp)://)" +
  // user:pass authentication
  "(?:\\S+(?::\\S*)?@)?" +
  "(?:" +
  // IP address exclusion
  // private & local networks
  "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
  "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
  "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
  // IP address dotted notation octets
  // excludes loopback network 0.0.0.0
  // excludes reserved space >= 224.0.0.0
  // excludes network & broacast addresses
  // (first & last IP address of each class)
  "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  "|" +
  // host name
  "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
  // domain name
  "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
  // TLD identifier
  "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
  ")" +
  // port number
  "(?::\\d{2,5})?" +
  // resource path
  "(?:/\\S*)?" +
  "$", "i"
);

window.flagCountries = [
  "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT",
  "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ",
  "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BW", "BY", "BZ", "CA", "CC", "CD",
  "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW",
  "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH",
  "ER", "ES", "ET", "EU", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD",
  "GE", "GG", "GH", "GI", "GL", "GM", "GN", "GQ", "GR", "GS", "GT", "GU", "GW",
  "GY", "HK", "HN", "HR", "HT", "HU", "IC", "ID", "IE", "IL", "IM", "IN", "IQ",
  "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN",
  "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT",
  "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM",
  "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ",
  "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM",
  "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PN", "PR", "PS", "PT", "PW", "PY",
  "QA", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI",
  "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SY", "SZ", "TC", "TD",
  "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW",
  "TZ", "UA", "UG", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU",
  "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW"
];

var dateRelativityApplicator = function($selector) {
  $selector.find("time[datetime]").each(function(index, el) {
    var $el = $(el),
    m = moment($el.attr("datetime"));

    $el.attr("title", $el.attr("datetime"));
    if ($el.data("role") == "timeago") {
      $el.text(m.fromNow());
    } else {
      $el.text(m.calendar());
    }
  });
}

var updateResults = function() {
  var $resultsContainer = $("#results-container");
  var $latestContainer = $("#latest-result-container");

  var source = $("#results-template").html();
  var template = Handlebars.compile(source);

  var latestSource = $("#latest-result-template").html();
  var latestTemplate = Handlebars.compile(latestSource);

  var url = $resultsContainer.data("url");
  var checkURL = $latestContainer.data("url");

  if ($resultsContainer.data("uninitialized")) {
    $resultsContainer.text("Loading…");
  }

  $.getJSON(url, function(data, status, xhr) {
    $.map(data, function(item, index) {
      item.URL = checkURL;

      if ($.inArray(item.Country, flagCountries) > 0) {
        item.Flag = "/images/flags/" + item.Country + ".png"
      } else {
        item.Flag = "/images/flags/_unknown.png"
      }

      if (item.Success) {
        item.Icon = "glyphicon-ok";
        item.TextStatus = "OK"
        item.CSSclass = "default"
        item.PanelCSSclass = "panel-success"
      } else if (item.status < 100) {
        item.Icon = "glyphicon-warning-sign";
        item.TextStatus = "Warning"
        item.CSSclass = "warning"
        item.PanelCSSclass = "panel-warning"
      } else {
        item.Icon = "glyphicon-fire";
        item.TextStatus = "Fail!"
        item.CSSclass = "danger"
        item.PanelCSSclass = "panel-danger"
      }
      return item
    });

    var html = template({"Results": data});
    $resultsContainer.html(html);
    dateRelativityApplicator($resultsContainer);

    var latestHtml = latestTemplate(data[0]);
    $latestContainer.html(latestHtml);
    dateRelativityApplicator($latestContainer);

    setTimeout(updateResults, 30*1000);
  });
}

$(function() {
  dateRelativityApplicator($("body"));

  var $checkForm = $("#check-form");
  if ($checkForm.length) {

    $checkForm.isHappy({
      fields: {
        "#url": {
          required: true,
          message: "You must enter a valid http or https URL. Private IP ranges are not allowed.",
          test: function (val) {
            return re_weburl.test(val);
          }
        },
      },
      unHappy: function() {
        $checkForm.find(".form-group").addClass("has-error").removeClass("has-success")
      },
      happy: function() {
        $checkForm.find(".form-group").addClass("has-success").removeClass("has-error")
      }
    });
  }

  $("#delete-check-form").on("submit", function(event){
    $button = $(this).find("button");
    if ($button.data("state") == "unarmed") {
      event.preventDefault()
      $button.data("state", "armed")
      $button.find("[data-role=label]").text("Are you sure?");
      setTimeout(function() {
        $button.data("state", "unarmed")
        $button.find("[data-role=label]").text("Destroy");
        $button.blur()
      }, 5000)
    }
  });

  var $resultsContainer = $("#results-container");
  if ($resultsContainer.length) {
    updateResults()
  }

  $("[data-role=modal]").on("click", function(event){
    event.preventDefault();
    $this = $(this);

    $img = $("").attr("src", $this.attr("href"));
    $body = $("

").html($img);
    $content = $("

").html($body);
    $dialog = $("

").html($content);
    $modal = $("

").html($dialog);

    $modal.modal("show");
  });
});
<commit_msg>Don’t explode if there’s no data <commit_after>//
// Regular Expression for URL validation
//
// Author: Diego Perini
// Updated: 2010/12/05
// License: MIT
//
// Copyright (c) 2010-2013 Diego Perini (http://www.iport.it)
// https://gist.github.com/dperini/729294
var re_weburl = new RegExp(
  "^" +
  // protocol identifier
  "(?:(?:https?|ftp)://)" +
  // user:pass authentication
  "(?:\\S+(?::\\S*)?@)?" +
  "(?:" +
  // IP address exclusion
  // private & local networks
  "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
  "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
  "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
  // IP address dotted notation octets
  // excludes loopback network 0.0.0.0
  // excludes reserved space >= 224.0.0.0
  // excludes network & broacast addresses
  // (first & last IP address of each class)
  "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  "|" +
  // host name
  "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
  // domain name
  "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
  // TLD identifier
  "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
  ")" +
  // port number
  "(?::\\d{2,5})?" +
  // resource path
  "(?:/\\S*)?" +
  "$", "i"
);

window.flagCountries = [
  "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT",
  "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ",
  "BL", "BM", "BN", "BO", "BR", "BS", "BT", "BW", "BY", "BZ", "CA", "CC", "CD",
  "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW",
  "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH",
  "ER", "ES", "ET", "EU", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD",
  "GE", "GG", "GH", "GI", "GL", "GM", "GN", "GQ", "GR", "GS", "GT", "GU", "GW",
  "GY", "HK", "HN", "HR", "HT", "HU", "IC", "ID", "IE", "IL", "IM", "IN", "IQ",
  "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN",
  "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT",
  "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM",
  "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ",
  "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM",
  "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PN", "PR", "PS", "PT", "PW", "PY",
  "QA", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI",
  "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SY", "SZ", "TC", "TD",
  "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW",
  "TZ", "UA", "UG", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU",
  "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW"
];

var dateRelativityApplicator = function($selector) {
  $selector.find("time[datetime]").each(function(index, el) {
    var $el = $(el),
    m = moment($el.attr("datetime"));

    $el.attr("title", $el.attr("datetime"));
    if ($el.data("role") == "timeago") {
      $el.text(m.fromNow());
    } else {
      $el.text(m.calendar());
    }
  });
}

var updateResults = function() {
  var $resultsContainer = $("#results-container");
  var $latestContainer = $("#latest-result-container");

  var source = $("#results-template").html();
  var template = Handlebars.compile(source);

  var latestSource = $("#latest-result-template").html();
  var latestTemplate = Handlebars.compile(latestSource);

  var url = $resultsContainer.data("url");
  var checkURL = $latestContainer.data("url");

  if ($resultsContainer.data("uninitialized")) {
    $resultsContainer.text("Loading…");
  }

  $.getJSON(url, function(data, status, xhr) {
    if (!data) {
      setTimeout(updateResults, 20*1000);
    } else {
      $.map(data, function(item, index) {
        item.URL = checkURL;

        if ($.inArray(item.Country, flagCountries) > 0) {
          item.Flag = "/images/flags/" + item.Country + ".png"
        } else {
          item.Flag = "/images/flags/_unknown.png"
        }

        if (item.Success) {
          item.Icon = "glyphicon-ok";
          item.TextStatus = "OK"
          item.CSSclass = "default"
          item.PanelCSSclass = "panel-success"
        } else if (item.status < 100) {
          item.Icon = "glyphicon-warning-sign";
          item.TextStatus = "Warning"
          item.CSSclass = "warning"
          item.PanelCSSclass = "panel-warning"
        } else {
          item.Icon = "glyphicon-fire";
          item.TextStatus = "Fail!"
          item.CSSclass = "danger"
          item.PanelCSSclass = "panel-danger"
        }
        return item
      });

      var html = template({"Results": data});
      $resultsContainer.html(html);
      dateRelativityApplicator($resultsContainer);

      var latestHtml = latestTemplate(data[0]);
      $latestContainer.html(latestHtml);
      dateRelativityApplicator($latestContainer);

      setTimeout(updateResults, 30*1000);
    }
  });
}

$(function() {
  dateRelativityApplicator($("body"));

  var $checkForm = $("#check-form");
  if ($checkForm.length) {

    $checkForm.isHappy({
      fields: {
        "#url": {
          required: true,
          message: "You must enter a valid http or https URL. Private IP ranges are not allowed.",
          test: function (val) {
            return re_weburl.test(val);
          }
        },
      },
      unHappy: function() {
        $checkForm.find(".form-group").addClass("has-error").removeClass("has-success")
      },
      happy: function() {
        $checkForm.find(".form-group").addClass("has-success").removeClass("has-error")
      }
    });
  }

  $("#delete-check-form").on("submit", function(event){
    $button = $(this).find("button");
    if ($button.data("state") == "unarmed") {
      event.preventDefault()
      $button.data("state", "armed")
      $button.find("[data-role=label]").text("Are you sure?");
      setTimeout(function() {
        $button.data("state", "unarmed")
        $button.find("[data-role=label]").text("Destroy");
        $button.blur()
      }, 5000)
    }
  });

  var $resultsContainer = $("#results-container");
  if ($resultsContainer.length) {
    updateResults()
  }

  $("[data-role=modal]").on("click", function(event){
    event.preventDefault();
    $this = $(this);

    $img = $("").attr("src", $this.attr("href"));
    $body = $("

").html($img);
    $content = $("

").html($body);
    $dialog = $("

").html($content);
    $modal = $("

").html($dialog);

    $modal.modal("show");
  });
});
<|endoftext|>


<commit_before>angular.module('coinmachine', ['ui.router', 'kendo.directives', 'lbServices', 'ngMaterial'])
    .config(['$stateProvider', 'SocketProvider', function ($stateProvider) {
        'use strict';
    }])
    .factory('Context', ['$rootScope', function($rootScope) {
        return {
            emit: function(eventName, value) {
                $rootScope.$emit(eventName, value);
            },
            subscribe: function(eventName, callback) {
                return $rootScope.$on(eventName, callback);
            },
            unsubscribe: function(currentScope) {
                currentScope.currentScope.vm.cleanUpFuncsId.forEach(function(id) {
                    $rootScope.$$listeners[id] = [];
                });
            }
        };
    }])
    .factory('Socket', ['$log', 'Context', function($log, Context) {
        var socket = undefined;

        return {
            connect: function() {
                socket = io.connect('http://localhost:3000');

                socket.on('error', function(err){
                    $log.error(err)
                });

                socket.on('connect', function() {
                    $log.info('User connected to socket.io server');

                    // define socket.io channels beetween utrack and utrack-gateway
                    $log.info('Subscribed to bittrex-event');
                    socket.on('bittrex-event', function(event) {
                        // propagate the message throw event bus
                        Context.emit('bittrex-event', event);

                        //$log.info('event from bittrex-event topic is: ' + event);
                    });
                });

                socket.on("disconnect",function(event) {
                    $log.info('User disconnected to socket.io server with event: ' + event);
                });

                return socket;
            },
            disconnect: function(event) {
                $log.info('User disconnected to socket.io with event: ' + event);
            }
        };
    }])
    .directive('expandKGrid', ['$window', '$timeout', function ($window, $timeout) {
        // Define the directive, but restrict its usage to
        var directive = {
            link: link,           // The function attaching the behavior
            restrict: 'A',        // Restrict directive to be used only as attribute
            require: 'kendoGrid'  // Ensure the directive is set on a <kendo-grid> element
        };

        function link(scope, element, attrs) {
            function resize() {
                var newHeight = element.innerHeight(),
                    otherElements = element.children().not(".k-grid-content"),
                    otherElementsHeight = 0;

                // calculate columns and pagination toobar market grid height
                otherElements.each(function(){
                    otherElementsHeight += $(this).outerHeight();
                });

                var height = $(window).height() - $('#market-filter').height() - $('#market-footer').height() - otherElementsHeight - 56;

                // market grid container height calculation:
                //  -- market filter height
                //  -- footer height
                //  -- market grid header and footer
                //  -- window margin and padding height
                element.children(".k-grid-content").height(height);
            }

            // Attach an eventHandler to the resize event of the window to resize the data area of the grid accordingly
            $($window).resize(function () {
                resize();
            });

            $timeout(function() {
                resize();
            }, 500);
        }

        return directive;
    }])
    .controller('mainController', ['$scope', '$log', 'Bittrex', 'Socket', 'Context', function ($scope, $log, Bittrex, Socket, Context) {
        'use strict';

        // configure any kendo widgets before rendered
        $scope.$on("kendoRendered", function(e) {
            // set list time intervals to readonly
            //$scope.comboboxMarketInterval.readonly(true);
        });

        // initialize markers collection
        $scope.markets = [];

        // initialize filter date
        $scope.startTimestamp = new Date();
        $scope.quantity = 1;

        // configure kendo-ui table
        $scope.optionsGrid = {
            toolbar: ["excel", "pdf"],
            excel: {
                fileName: "Markets Export.xlsx",
                allPages: true
            },
            pdf: {
                fileName: "Markets Export.pdf",
                allPages: true
            },
            dataSource: {
                data: $scope.markets,
                schema: {
                    model: {
                        fields: {
                            MarketName: { type: "string" },
                            High: { type: "number" },
                            Low: { type: "number" },
                            Volume: { type: "number" },
                            Last: { type: "number" },
                            BaseVolume: { type: "number" },
                            TimeStamp: { type: "date" },
                            Bid: { type: "number" },
                            Ask: { type: "number" },
                            OpenBuyOrders: { type: "number" },
                            OpenSellOrders: { type: "number" },
                            PrevDay: { type: "number" },
                            Created: { type: "date" }
                        }
                    }
                },
                pageSize: 50
            },
            scrollable: true,
            sortable: true,
            filterable: true,
            resizable: true,
            columnMenu: true,

            pageable: {
                input: true,
                numeric: false
            },
            columns: [
                { field: "MarketName", title: "Market Name"},
                { field: "High", title: "High"},
                { field: "Low", title: "Low"},
                { field: "Volume", title: "Volume"},
                { field: "Last", title: "Last"},
                { field: "BaseVolume", title: "Base Volume"},
                { field: "TimeStamp", title: "TimeStamp", template: '#= kendo.toString(kendo.parseDate(TimeStamp), "dd/MM/yyyy HH:mm:ss")#'},
                { field: "Bid", title: "Bid"},
                { field: "Ask", title: "Ask"},
                { field: "OpenBuyOrders", title: "Open Buy Orders"},
                { field: "OpenSellOrders", title: "Open Sell Orders"},
                { field: "PrevDay", title: "Previous Day"},
                { field: "Created", title: "Created", template: '#= kendo.toString(kendo.parseDate(Created), "dd/MM/yyyy HH:mm:ss")#'}
            ]
        };

        // configure kendo-ui header table tooltips
        $scope.toolTipOptions = {
            filter: ".k-header",
            position: "top",
            content: function(e) {
                if ($scope.marketGrid.columns[e.target.context.cellIndex] !== undefined)
                    var content = $scope.marketGrid.columns[e.target.context.cellIndex].title;

                return content;
            }
        };

        // load market candles
        $scope.onGraphClick = function (event) {
            Bittrex.getCandles({market: 'BTC-LTC', tickInterval: 'fiveMin', startTimestamp: $scope.startTimestamp})
                .$promise
                .then(function(candles, responseHeaders) {
                        if (candles.result.length > 0)
                            $scope.candles = JSON.parse(angular.toJson(candles.result));
                        else
                            $scope.candles = [];

                        // create data table on loaded data
                        var dataTable = anychart.data.table();

                        // refresh anyChart datasource
                        $log.info($scope.candles.length + ' candles recovered');
                    },
                    function(httpResponse) {
                        var error = httpResponse.data.error;
                        $log.error('Error querying candles - ' + error.status + ": " + error.message);
                    });
        };

        // load market summary
        $scope.onMarketClick = function (event) {
            Bittrex.getMarketSummaries()
                .$promise
                .then(function(markets, responseHeaders) {
                    if (markets.length > 0)
                        $scope.markets = JSON.parse(angular.toJson(markets));
                    else
                        $scope.markets = [];

                    // refresh grid datasource
                    $scope.marketGrid.dataSource.data($scope.markets);

                    $log.info($scope.markets.length + ' markets recovered');
                },
                function(httpResponse) {
                    var error = httpResponse.data.error;
                    $log.error('Error querying markets - ' + error.status + ": " + error.message);
                });
        };

        // connect socket.io client to socket server
        Socket.connect();

        // subscribe socket.io client to bittrex-event topic
        var cleanUpFuncBittrexEventConfirm = Context.subscribe('bittrex-event', function(event, markets) {
            // refresh grid datasource markets
            $scope.marketGrid.dataSource.data(markets);
        });

        // unsubscribe socket.io client to bittrex-event topic
        $scope.$on('$destroy', function() {
            cleanUpFuncBittrexEventConfirm();
        });
    }]);
<commit_msg>last update<commit_after>angular.module('coinmachine', ['ui.router', 'kendo.directives', 'lbServices', 'ngMaterial'])
    .config(['$stateProvider', 'SocketProvider', function ($stateProvider) {
        'use strict';
    }])
    .factory('Context', ['$rootScope', function($rootScope) {
        return {
            emit: function(eventName, value) {
                $rootScope.$emit(eventName, value);
            },
            subscribe: function(eventName, callback) {
                return $rootScope.$on(eventName, callback);
            },
            unsubscribe: function(currentScope) {
                currentScope.currentScope.vm.cleanUpFuncsId.forEach(function(id) {
                    $rootScope.$$listeners[id] = [];
                });
            }
        };
    }])
    .factory('Socket', ['$log', 'Context', function($log, Context) {
        var socket = undefined;

        return {
            connect: function() {
                socket = io.connect('http://localhost:3000');

                socket.on('error', function(err){
                    $log.error(err)
                });

                socket.on('connect', function() {
                    $log.info('User connected to socket.io server');

                    // define socket.io channels beetween utrack and utrack-gateway
                    $log.info('Subscribed to bittrex-event');
                    socket.on('bittrex-event', function(event) {
                        // propagate the message throw event bus
                        Context.emit('bittrex-event', event);

                        //$log.info('event from bittrex-event topic is: ' + event);
                    });
                });

                socket.on("disconnect",function(event) {
                    $log.info('User disconnected to socket.io server with event: ' + event);
                });

                return socket;
            },
            disconnect: function(event) {
                $log.info('User disconnected to socket.io with event: ' + event);
            }
        };
    }])
    .directive('expandKGrid', ['$window', '$timeout', function ($window, $timeout) {
        // Define the directive, but restrict its usage to
        var directive = {
            link: link,           // The function attaching the behavior
            restrict: 'A',        // Restrict directive to be used only as attribute
            require: 'kendoGrid'  // Ensure the directive is set on a <kendo-grid> element
        };

        function link(scope, element, attrs) {
            function resize() {
                var newHeight = element.innerHeight(),
                    otherElements = element.children().not(".k-grid-content"),
                    otherElementsHeight = 0;

                // calculate columns and pagination toobar market grid height
                otherElements.each(function(){
                    otherElementsHeight += $(this).outerHeight();
                });

                var height = $(window).height() - $('#market-filter').height() - $('#market-footer').height() - otherElementsHeight - 56;

                // market grid container height calculation:
                //  -- market filter height
                //  -- footer height
                //  -- market grid header and footer
                //  -- window margin and padding height
                element.children(".k-grid-content").height(height);
            }

            // Attach an eventHandler to the resize event of the window to resize the data area of the grid accordingly
            $($window).resize(function () {
                resize();
            });

            $timeout(function() {
                resize();
            }, 500);
        }

        return directive;
    }])
    .controller('mainController', ['$scope', '$log', 'Bittrex', 'Socket', 'Context', function ($scope, $log, Bittrex, Socket, Context) {
        'use strict';

        // configure any kendo widgets before rendered
        $scope.$on("kendoRendered", function(e) {
            // set list time intervals to readonly
            //$scope.comboboxMarketInterval.readonly(true);
        });

        // initialize markers collection
        $scope.markets = [];

        // initialize filter values
        $scope.startTimestamp = new Date();
        $scope.quantity = 1;

        // configure kendo-ui table
        $scope.optionsGrid = {
            toolbar: ["excel", "pdf"],
            excel: {
                fileName: "Markets Export.xlsx",
                allPages: true
            },
            pdf: {
                fileName: "Markets Export.pdf",
                allPages: true
            },
            dataSource: {
                data: $scope.markets,
                schema: {
                    model: {
                        fields: {
                            MarketName: { type: "string" },
                            High: { type: "number" },
                            Low: { type: "number" },
                            Volume: { type: "number" },
                            Last: { type: "number" },
                            BaseVolume: { type: "number" },
                            TimeStamp: { type: "date" },
                            Bid: { type: "number" },
                            Ask: { type: "number" },
                            OpenBuyOrders: { type: "number" },
                            OpenSellOrders: { type: "number" },
                            PrevDay: { type: "number" },
                            Created: { type: "date" }
                        }
                    }
                },
                pageSize: 50
            },
            scrollable: true,
            sortable: true,
            filterable: true,
            resizable: true,
            columnMenu: true,

            pageable: {
                input: true,
                numeric: false
            },
            columns: [
                { field: "MarketName", title: "Market Name"},
                { field: "High", title: "High"},
                { field: "Low", title: "Low"},
                { field: "Volume", title: "Volume"},
                { field: "Last", title: "Last"},
                { field: "BaseVolume", title: "Base Volume"},
                { field: "TimeStamp", title: "TimeStamp", template: '#= kendo.toString(kendo.parseDate(TimeStamp), "dd/MM/yyyy HH:mm:ss")#'},
                { field: "Bid", title: "Bid"},
                { field: "Ask", title: "Ask"},
                { field: "OpenBuyOrders", title: "Open Buy Orders"},
                { field: "OpenSellOrders", title: "Open Sell Orders"},
                { field: "PrevDay", title: "Previous Day"},
                { field: "Created", title: "Created", template: '#= kendo.toString(kendo.parseDate(Created), "dd/MM/yyyy HH:mm:ss")#'}
            ]
        };

        // configure kendo-ui header table tooltips
        $scope.toolTipOptions = {
            filter: ".k-header",
            position: "top",
            content: function(e) {
                if ($scope.marketGrid.columns[e.target.context.cellIndex] !== undefined)
                    var content = $scope.marketGrid.columns[e.target.context.cellIndex].title;

                return content;
            }
        };

        // load market candles
        $scope.onGraphClick = function (event) {
            Bittrex.getCandles({market: 'BTC-LTC', tickInterval: 'fiveMin', startTimestamp: $scope.startTimestamp})
                .$promise
                .then(function(candles, responseHeaders) {
                        if (candles.result.length > 0)
                            $scope.candles = JSON.parse(angular.toJson(candles.result));
                        else
                            $scope.candles = [];

                        // create data table on loaded data
                        var dataTable = anychart.data.table();

                        // refresh anyChart datasource
                        $log.info($scope.candles.length + ' candles recovered');
                    },
                    function(httpResponse) {
                        var error = httpResponse.data.error;
                        $log.error('Error querying candles - ' + error.status + ": " + error.message);
                    });
        };

        // load market summary
        $scope.onMarketClick = function (event) {
            Bittrex.getMarketSummaries()
                .$promise
                .then(function(markets, responseHeaders) {
                    if (markets.length > 0)
                        $scope.markets = JSON.parse(angular.toJson(markets));
                    else
                        $scope.markets = [];

                    // refresh grid datasource
                    $scope.marketGrid.dataSource.data($scope.markets);

                    $log.info($scope.markets.length + ' markets recovered');
                },
                function(httpResponse) {
                    var error = httpResponse.data.error;
                    $log.error('Error querying markets - ' + error.status + ": " + error.message);
                });
        };

        // connect socket.io client to socket server
        Socket.connect();

        // subscribe socket.io client to bittrex-event topic
        var cleanUpFuncBittrexEventConfirm = Context.subscribe('bittrex-event', function(event, markets) {
            // refresh grid datasource markets
            $scope.marketGrid.dataSource.data(markets);
        });

        // unsubscribe socket.io client to bittrex-event topic
        $scope.$on('$destroy', function() {
            cleanUpFuncBittrexEventConfirm();
        });
    }]);
<|endoftext|>


<commit_before>import he from "he";
import {getPlayerColor, setFocusScreen, cellFocused, findNextCell} from "./game";
import sort from "immutable-sort";

export function drawLeaderboard(state) {
  const tbody = document.getElementById("leaderboard-body");

  const sortedPlayers = sort(state.players, (a, b) => b.total_mass - a.total_mass);
  // Initial case
  if(tbody.rows.length === 0) {
    createTable(sortedPlayers, null, true);
    return;
  }

  const oldBounding = [... tbody.rows].reduce((result, row) => {
    result[row.id] = row.getBoundingClientRect();
    return result;
  }, {});

  createTable(sortedPlayers, oldBounding, false);
}

function createTable(players, oldBounding, firstTime) {
  const new_tbody = document.createElement("tbody");
  new_tbody.setAttribute("id", "leaderboard-body");

  for(const playerIndex in players) {
    const player = players[playerIndex];
    const color = getPlayerColor(players, player);

    const row = new_tbody.insertRow();
    row.id = `player-${player.id}`;
    row.onclick = function() {
      focusOnPlayer(player);
    };

    if(!player.isActive) {
      row.className = "inactive-player";
    }

    row.insertCell(0).innerHTML = `<div class="color-box" style="background-color: ${color};"></div>`;
    row.insertCell(1).innerHTML = (parseInt(playerIndex) + 1).toString();
    row.insertCell(2).innerHTML = he.encode(player.name);
    row.insertCell(3).innerHTML = he.encode(player.total_mass.toString());

    if(!firstTime) {
      addTransition(oldBounding, row, playerIndex);
    }
  }

  const old = document.getElementById("leaderboard-body");
  const leaderboard = document.getElementById("leaderboard");
  leaderboard.replaceChild(new_tbody, old);
  cleanEventListeners(old);
}

function addTransition(oldBounding, row, playerIndex) {
  const header = document.getElementById("leaderboard-header").getBoundingClientRect();

  const deltaY = oldBounding[row.id].top - (playerIndex * (header.bottom - header.top) + header.bottom);

  requestAnimationFrame(() => {
    row.style.transform = `translate(0, ${deltaY}px)`;
    row.style.transition = "transform 0s";
    requestAnimationFrame(() => {
      row.style.transform = "";
      row.style.transition = "transform 0.5s";
    });
  });
}

function cleanEventListeners(old) {
  for(const row of old.rows) {
    row.onclick = null;
  }
}

function focusOnPlayer(player) {
  findNextCell(player.cells, player.id);
  if(cellFocused) {
    setFocusScreen(cellFocused.position);
  }
}
<commit_msg>JS New players are displayed on the leaderboard<commit_after>import he from "he";
import {getPlayerColor, setFocusScreen, cellFocused, findNextCell} from "./game";
import sort from "immutable-sort";

export function drawLeaderboard(state) {
  const tbody = document.getElementById("leaderboard-body");

  const sortedPlayers = sort(state.players, (a, b) => b.total_mass - a.total_mass);
  // Initial case
  if(tbody.rows.length !== sortedPlayers.length) {
    createTable(sortedPlayers, null, true);
    return;
  }

  const oldBounding = [... tbody.rows].reduce((result, row) => {
    result[row.id] = row.getBoundingClientRect();
    return result;
  }, {});

  createTable(sortedPlayers, oldBounding, false);
}

function createTable(players, oldBounding, firstTime) {
  const new_tbody = document.createElement("tbody");
  new_tbody.setAttribute("id", "leaderboard-body");

  for(const playerIndex in players) {
    const player = players[playerIndex];
    const color = getPlayerColor(players, player);

    const row = new_tbody.insertRow();
    row.id = `player-${player.id}`;
    row.onclick = function() {
      focusOnPlayer(player);
    };

    if(!player.isActive) {
      row.className = "inactive-player";
    }

    row.insertCell(0).innerHTML = `<div class="color-box" style="background-color: ${color};"></div>`;
    row.insertCell(1).innerHTML = (parseInt(playerIndex) + 1).toString();
    row.insertCell(2).innerHTML = he.encode(player.name);
    row.insertCell(3).innerHTML = he.encode(player.total_mass.toString());

    if(!firstTime) {
      addTransition(oldBounding, row, playerIndex);
    }
  }

  const old = document.getElementById("leaderboard-body");
  const leaderboard = document.getElementById("leaderboard");
  leaderboard.replaceChild(new_tbody, old);
  cleanEventListeners(old);
}

function addTransition(oldBounding, row, playerIndex) {
  const header = document.getElementById("leaderboard-header").getBoundingClientRect();

  const deltaY = oldBounding[row.id].top - (playerIndex * (header.bottom - header.top) + header.bottom);

  requestAnimationFrame(() => {
    row.style.transform = `translate(0, ${deltaY}px)`;
    row.style.transition = "transform 0s";
    requestAnimationFrame(() => {
      row.style.transform = "";
      row.style.transition = "transform 0.5s";
    });
  });
}

function cleanEventListeners(old) {
  for(const row of old.rows) {
    row.onclick = null;
  }
}

function focusOnPlayer(player) {
  findNextCell(player.cells, player.id);
  if(cellFocused) {
    setFocusScreen(cellFocused.position);
  }
}
<|endoftext|>


<commit_before>define([
	'config/types',
	'utils/isEqual',
	'utils/defineProperty',
	'shared/registerDependant',
	'shared/unregisterDependant'
], function (
	types,
	isEqual,
	defineProperty,
	registerDependant,
	unregisterDependant
) {

	'use strict';

	var Reference, thisPattern;

	thisPattern = /this/;

	Reference = function ( root, keypath, evaluator, argNum, priority ) {
		var value;

		this.evaluator = evaluator;
		this.keypath = keypath;
		this.root = root;
		this.argNum = argNum;
		this.type = types.REFERENCE;
		this.priority = priority;

		value = root.get( keypath );

		if ( typeof value === 'function' ) {
			value = value._wrapped || wrapFunction( value, root, evaluator );
		}

		this.value = evaluator.values[ argNum ] = value;

		registerDependant( this );
	};

	Reference.prototype = {
		update: function () {
			var value = this.root.get( this.keypath );

			if ( typeof value === 'function' && !value._nowrap ) {
				value = value[ '_' + this.root._guid ] || wrapFunction( value, this.root, this.evaluator );
			}

			if ( !isEqual( value, this.value ) ) {
				this.evaluator.values[ this.argNum ] = value;
				this.evaluator.bubble();

				this.value = value;
			}
		},

		teardown: function () {
			unregisterDependant( this );
		}
	};

	return Reference;

	function wrapFunction ( fn, ractive, evaluator ) {
		var prop;

		// if the function doesn't refer to `this`, we don't need
		// to set the context
		if ( !thisPattern.test( fn.toString() ) ) {
			defineProperty( fn, '_nowrap', { // no point doing this every time
				value: true
			});
			return fn;
		}

		// otherwise, we do
		defineProperty( fn, '_' + ractive._guid, {
			value: function () {
				var originalGet, result, softDependencies;

				originalGet = ractive.get;
				ractive.get = function ( keypath ) {
					if ( !softDependencies ) {
						softDependencies = [];
					}

					if ( !softDependencies[ keypath ] ) {
						softDependencies[ softDependencies.length ] = keypath;
						softDependencies[ keypath ] = true;
					}

					return originalGet.call( ractive, keypath );
				};

				result = fn.apply( ractive, arguments );

				if ( softDependencies ) {
					evaluator.updateSoftDependencies( softDependencies );
				}

				// reset
				ractive.get = originalGet;

				return result;
			},
			writable: true
		});

		for ( prop in fn ) {
			if ( fn.hasOwnProperty( prop ) ) {
				fn[ '_' + ractive._guid ][ prop ] = fn[ prop ];
			}
		}

		return fn[ '_' + ractive._guid ];
	}

});<commit_msg>fix mistake with function wrapping<commit_after>define([
	'config/types',
	'utils/isEqual',
	'utils/defineProperty',
	'shared/registerDependant',
	'shared/unregisterDependant'
], function (
	types,
	isEqual,
	defineProperty,
	registerDependant,
	unregisterDependant
) {

	'use strict';

	var Reference, thisPattern;

	thisPattern = /this/;

	Reference = function ( root, keypath, evaluator, argNum, priority ) {
		var value;

		this.evaluator = evaluator;
		this.keypath = keypath;
		this.root = root;
		this.argNum = argNum;
		this.type = types.REFERENCE;
		this.priority = priority;

		value = root.get( keypath );

		if ( typeof value === 'function' ) {
			value = value[ '_' + root._guid ] || wrapFunction( value, root, evaluator );
		}

		this.value = evaluator.values[ argNum ] = value;

		registerDependant( this );
	};

	Reference.prototype = {
		update: function () {
			var value = this.root.get( this.keypath );

			if ( typeof value === 'function' && !value._nowrap ) {
				value = value[ '_' + this.root._guid ] || wrapFunction( value, this.root, this.evaluator );
			}

			if ( !isEqual( value, this.value ) ) {
				this.evaluator.values[ this.argNum ] = value;
				this.evaluator.bubble();

				this.value = value;
			}
		},

		teardown: function () {
			unregisterDependant( this );
		}
	};

	return Reference;

	function wrapFunction ( fn, ractive, evaluator ) {
		var prop;

		// if the function doesn't refer to `this`, we don't need
		// to set the context
		if ( !thisPattern.test( fn.toString() ) ) {
			defineProperty( fn, '_nowrap', { // no point doing this every time
				value: true
			});
			return fn;
		}

		// otherwise, we do
		defineProperty( fn, '_' + ractive._guid, {
			value: function () {
				var originalGet, result, softDependencies;

				originalGet = ractive.get;
				// TODO we should capture dependencies more intelligently than this,
				// creating a new function a bunch of times
				ractive.get = function ( keypath ) {
					if ( !softDependencies ) {
						softDependencies = [];
					}

					if ( !softDependencies[ keypath ] ) {
						softDependencies[ softDependencies.length ] = keypath;
						softDependencies[ keypath ] = true;
					}

					return originalGet.call( ractive, keypath );
				};

				result = fn.apply( ractive, arguments );

				if ( softDependencies ) {
					evaluator.updateSoftDependencies( softDependencies );
				}

				// reset
				ractive.get = originalGet;

				return result;
			},
			writable: true
		});

		for ( prop in fn ) {
			if ( fn.hasOwnProperty( prop ) ) {
				fn[ '_' + ractive._guid ][ prop ] = fn[ prop ];
			}
		}

		return fn[ '_' + ractive._guid ];
	}

});<|endoftext|>


<commit_before>import './Draft.css';
import './Editor.css';
import classNames from 'classnames';
import { convertFromHTML } from 'draft-convert';
import createHashtagPlugin from 'draft-js-hashtag-plugin';
import createLinkifyPlugin from 'draft-js-linkify-plugin';
import { defineMessages } from '../../shared/i18n';
import draftJSExtendPlugins, {
  alignmentPlugin,
  blockDndPlugin,
  blockRenderers,
  decorator,
  dividerPlugin,
  focusPlugin,
} from './plugins';
import Editor from 'draft-js-plugins-editor';
import { convertFromRaw, convertToRaw, EditorState, RichUtils } from 'draft-js';
import Emojis, { emojiPlugin } from './ui/autocomplete/Emojis';
import { handleKeyCommand, keyBindingFn } from './input/keyboard';
import HiddenSnackbarShim from '../components/HiddenSnackbarShim';
import Mentions, { mentionPlugin } from './ui/autocomplete/Mentions';
import React, { Component } from 'react';
import styles from './Editor.module.css';
import Toolbars, { inlineToolbarPlugin, linkPlugin, sideToolbarPlugin } from './ui/toolbars';
import unfurl from './media/unfurl';
import uploadFiles from './media/attachment';

const messages = defineMessages({
  errorMedia: { msg: 'Error uploading image.' },
  errorUnfurl: { msg: 'Error unfurling link.' },
});

const { AlignmentTool } = alignmentPlugin;

const MAX_DEPTH = 5;

const plugins = [
  alignmentPlugin,
  blockDndPlugin,
  createHashtagPlugin(),
  createLinkifyPlugin(),
  dividerPlugin,
  emojiPlugin,
  focusPlugin,
  inlineToolbarPlugin,
  linkPlugin,
  mentionPlugin,
  sideToolbarPlugin,
];

class HelloWorldEditor extends Component {
  constructor(props) {
    super(props);

    const content = this.props.content;

    let state;
    if (content?.content) {
      state = convertFromRaw(typeof content.content === 'string' ? JSON.parse(content.content) : content.content);
    } else if (content?.view) {
      // XXX(mime): this is the dumbest shit i have ever seen. ARGH. the custom block renderer won't fire unless
      // there's a whitespace character before the <img /> tag to attach to. ARRRRRRRRRRGH.
      // See related hack in image.js for the blockRendererFn.
      const view = content.view.replace(/<img /g, ' <img ');

      state = draftJSExtendPlugins(convertFromHTML)(view);
    }

    this.state = {
      editorState: state ? EditorState.createWithContent(state) : EditorState.createEmpty(),
      errorMessage: null,
      hasText: !!state,
      hasUnsavedChanges: false,
      showEditor: false,
    };
  }

  componentDidMount() {
    // TODO(mime): for some reason editorKey isn't working - having problems with SSR.
    this.setState({ showEditor: true });

    if (!this.props.readOnly) {
      window.addEventListener('beforeunload', this.handleOnBeforeUnload);
    }
  }

  componentWillUnmount() {
    if (!this.props.readOnly) {
      window.removeEventListener('beforeunload', this.handleOnBeforeUnload);
    }
  }

  get editorState() {
    return this.state.editorState;
  }

  handleOnBeforeUnload = evt => {
    if (this.state.hasUnsavedChanges) {
      evt.returnValue = 'You have unfinished changes!';
    }
  };

  setUnsavedChanges(hasUnsavedChanges) {
    this.setState({ hasUnsavedChanges });
  }

  onChange = editorState => {
    const hasText = !!editorState
      .getCurrentContent()
      .getPlainText()
      .trim();

    this.setState({
      editorState,
      hasText,
      hasUnsavedChanges: !this.props.dontWarnOnUnsaved,
    });

    this.props.onChange && this.props.onChange();
  };

  handleDroppedFiles = async (selection, files) => {
    const { editorState, fileInfos, isError } = await uploadFiles(this.state.editorState, files);
    if (isError) {
      this.setState({ errorMessage: messages.errorMedia }, () => {
        this.setState({ errorMessage: null });
      });
      return;
    }

    this.setState({ editorState });

    this.props.onMediaAdd && this.props.onMediaAdd(fileInfos);
  };

  handleKeyCommand = cmd => {
    const editorState = handleKeyCommand(cmd, this.state.editorState);

    if (!editorState) {
      return 'unhandled';
    }

    if (typeof editorState === 'object') {
      this.setState({ editorState });
    }

    return 'handled';
  };

  handleOnTab = evt => {
    this.setState({ editorState: RichUtils.onTab(evt, this.state.editorState, MAX_DEPTH) });
  };

  handlePastedText = async (text, html, editorState) => {
    if (text.match(/^https?:\/\//)) {
      const editorStateAndInfo = await unfurl(text, editorState);

      if (!editorStateAndInfo.wasMediaFound) {
        return;
      }

      if (editorStateAndInfo.isError) {
        this.setState({ errorMessage: messages.errorUnfurl }, () => {
          this.setState({ errorMessage: null });
        });
        return;
      }

      this.setState({ editorState: editorStateAndInfo.editorState });

      if (editorStateAndInfo.thumb) {
        this.props.onMediaAdd && this.props.onMediaAdd({ fileInfos: [{ thumb: editorStateAndInfo.thumb }] });
      }
    }
  };

  export() {
    return convertToRaw(this.state.editorState.getCurrentContent());
  }

  clear() {
    this.setState({
      editorState: EditorState.createEmpty(),
      hasText: false,
      hasUnsavedChanges: false,
    });
  }

  render() {
    return (
      <>
        {this.state.showEditor ? (
          <div
            className={classNames('e-content', {
              [styles.showPlaceholder]: this.props.showPlaceholder && !this.state.hasText,
              [styles.commentType]: this.props.type === 'comment',
            })}
          >
            <Editor
              blockRendererFn={blockRenderers}
              decorators={[decorator]}
              editorKey="editor"
              editorState={this.state.editorState}
              handleDroppedFiles={this.handleDroppedFiles}
              handleKeyCommand={this.handleKeyCommand}
              handlePastedText={this.handlePastedText}
              keyBindingFn={keyBindingFn}
              onChange={this.onChange}
              onTab={this.handleOnTab}
              plugins={plugins}
              readOnly={this.props.readOnly}
            />
            <Toolbars AlignmentTool={AlignmentTool} dividerPlugin={dividerPlugin} />
            <Emojis />
            <Mentions />
          </div>
        ) : null}
        <HiddenSnackbarShim message={this.state.errorMessage} variant="error" />
      </>
    );
  }
}

export default HelloWorldEditor;
<commit_msg>unfurl: take 3, argh, wrong data structure<commit_after>import './Draft.css';
import './Editor.css';
import classNames from 'classnames';
import { convertFromHTML } from 'draft-convert';
import createHashtagPlugin from 'draft-js-hashtag-plugin';
import createLinkifyPlugin from 'draft-js-linkify-plugin';
import { defineMessages } from '../../shared/i18n';
import draftJSExtendPlugins, {
  alignmentPlugin,
  blockDndPlugin,
  blockRenderers,
  decorator,
  dividerPlugin,
  focusPlugin,
} from './plugins';
import Editor from 'draft-js-plugins-editor';
import { convertFromRaw, convertToRaw, EditorState, RichUtils } from 'draft-js';
import Emojis, { emojiPlugin } from './ui/autocomplete/Emojis';
import { handleKeyCommand, keyBindingFn } from './input/keyboard';
import HiddenSnackbarShim from '../components/HiddenSnackbarShim';
import Mentions, { mentionPlugin } from './ui/autocomplete/Mentions';
import React, { Component } from 'react';
import styles from './Editor.module.css';
import Toolbars, { inlineToolbarPlugin, linkPlugin, sideToolbarPlugin } from './ui/toolbars';
import unfurl from './media/unfurl';
import uploadFiles from './media/attachment';

const messages = defineMessages({
  errorMedia: { msg: 'Error uploading image.' },
  errorUnfurl: { msg: 'Error unfurling link.' },
});

const { AlignmentTool } = alignmentPlugin;

const MAX_DEPTH = 5;

const plugins = [
  alignmentPlugin,
  blockDndPlugin,
  createHashtagPlugin(),
  createLinkifyPlugin(),
  dividerPlugin,
  emojiPlugin,
  focusPlugin,
  inlineToolbarPlugin,
  linkPlugin,
  mentionPlugin,
  sideToolbarPlugin,
];

class HelloWorldEditor extends Component {
  constructor(props) {
    super(props);

    const content = this.props.content;

    let state;
    if (content?.content) {
      state = convertFromRaw(typeof content.content === 'string' ? JSON.parse(content.content) : content.content);
    } else if (content?.view) {
      // XXX(mime): this is the dumbest shit i have ever seen. ARGH. the custom block renderer won't fire unless
      // there's a whitespace character before the <img /> tag to attach to. ARRRRRRRRRRGH.
      // See related hack in image.js for the blockRendererFn.
      const view = content.view.replace(/<img /g, ' <img ');

      state = draftJSExtendPlugins(convertFromHTML)(view);
    }

    this.state = {
      editorState: state ? EditorState.createWithContent(state) : EditorState.createEmpty(),
      errorMessage: null,
      hasText: !!state,
      hasUnsavedChanges: false,
      showEditor: false,
    };
  }

  componentDidMount() {
    // TODO(mime): for some reason editorKey isn't working - having problems with SSR.
    this.setState({ showEditor: true });

    if (!this.props.readOnly) {
      window.addEventListener('beforeunload', this.handleOnBeforeUnload);
    }
  }

  componentWillUnmount() {
    if (!this.props.readOnly) {
      window.removeEventListener('beforeunload', this.handleOnBeforeUnload);
    }
  }

  get editorState() {
    return this.state.editorState;
  }

  handleOnBeforeUnload = evt => {
    if (this.state.hasUnsavedChanges) {
      evt.returnValue = 'You have unfinished changes!';
    }
  };

  setUnsavedChanges(hasUnsavedChanges) {
    this.setState({ hasUnsavedChanges });
  }

  onChange = editorState => {
    const hasText = !!editorState
      .getCurrentContent()
      .getPlainText()
      .trim();

    this.setState({
      editorState,
      hasText,
      hasUnsavedChanges: !this.props.dontWarnOnUnsaved,
    });

    this.props.onChange && this.props.onChange();
  };

  handleDroppedFiles = async (selection, files) => {
    const { editorState, fileInfos, isError } = await uploadFiles(this.state.editorState, files);
    if (isError) {
      this.setState({ errorMessage: messages.errorMedia }, () => {
        this.setState({ errorMessage: null });
      });
      return;
    }

    this.setState({ editorState });

    this.props.onMediaAdd && this.props.onMediaAdd(fileInfos);
  };

  handleKeyCommand = cmd => {
    const editorState = handleKeyCommand(cmd, this.state.editorState);

    if (!editorState) {
      return 'unhandled';
    }

    if (typeof editorState === 'object') {
      this.setState({ editorState });
    }

    return 'handled';
  };

  handleOnTab = evt => {
    this.setState({ editorState: RichUtils.onTab(evt, this.state.editorState, MAX_DEPTH) });
  };

  handlePastedText = async (text, html, editorState) => {
    if (text.match(/^https?:\/\//)) {
      const editorStateAndInfo = await unfurl(text, editorState);

      if (!editorStateAndInfo.wasMediaFound) {
        return;
      }

      if (editorStateAndInfo.isError) {
        this.setState({ errorMessage: messages.errorUnfurl }, () => {
          this.setState({ errorMessage: null });
        });
        return;
      }

      this.setState({ editorState: editorStateAndInfo.editorState });

      if (editorStateAndInfo.thumb) {
        this.props.onMediaAdd && this.props.onMediaAdd([{ thumb: editorStateAndInfo.thumb }]);
      }
    }
  };

  export() {
    return convertToRaw(this.state.editorState.getCurrentContent());
  }

  clear() {
    this.setState({
      editorState: EditorState.createEmpty(),
      hasText: false,
      hasUnsavedChanges: false,
    });
  }

  render() {
    return (
      <>
        {this.state.showEditor ? (
          <div
            className={classNames('e-content', {
              [styles.showPlaceholder]: this.props.showPlaceholder && !this.state.hasText,
              [styles.commentType]: this.props.type === 'comment',
            })}
          >
            <Editor
              blockRendererFn={blockRenderers}
              decorators={[decorator]}
              editorKey="editor"
              editorState={this.state.editorState}
              handleDroppedFiles={this.handleDroppedFiles}
              handleKeyCommand={this.handleKeyCommand}
              handlePastedText={this.handlePastedText}
              keyBindingFn={keyBindingFn}
              onChange={this.onChange}
              onTab={this.handleOnTab}
              plugins={plugins}
              readOnly={this.props.readOnly}
            />
            <Toolbars AlignmentTool={AlignmentTool} dividerPlugin={dividerPlugin} />
            <Emojis />
            <Mentions />
          </div>
        ) : null}
        <HiddenSnackbarShim message={this.state.errorMessage} variant="error" />
      </>
    );
  }
}

export default HelloWorldEditor;
<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular
        .module('webApp')
        .controller('InputsCtrl', InputsCtrl);

    InputsCtrl.$inject = ['FragmentFactory', 'PolicyFactory', 'TemplateFactory', '$filter', '$modal'];

    function InputsCtrl(FragmentFactory, PolicyFactory, TemplateFactory, $filter, $modal) {
        /*jshint validthis: true*/
       var vm = this;

       vm.getInputs = getInputs;
       vm.deleteInput = deleteInput;
       vm.getInputTypes = getInputTypes;
       vm.createInput = createInput;
       vm.editInput = editInput;
       vm.createInputModal = createInputModal;
       vm.editInputModal = editInputModal;
       vm.duplicateInput = duplicateInput;
       vm.deleteInputConfirm = deleteInputConfirm;
       vm.getPolicyNames = getPolicyNames;
       vm.setInputsId = setInputsId;
       vm.inputTypes = [];
       vm.inputId = 1;

       init();

        /////////////////////////////////

        function init() {
            getInputs();
        };

        function getInputs() {
            var inputList = FragmentFactory.GetFragments("input");

            inputList.then(function (result) {
                vm.inputsData = vm.setInputsId(result);
                vm.getInputTypes(result);
            });
        };

        function deleteInput(fragmentType, fragmentName, index) {
            console.log('--> Deleting input');
            console.log('> Getting Policies affected');
            var policiesToDelete = PolicyFactory.GetPolicyByFragmentName(fragmentType, fragmentName);

            policiesToDelete.then(function (result) {
                console.log(result);

                var policies = vm.getPolicyNames(result);
                var inputToDelete =
                {
                    'type':fragmentType,
                    'name': fragmentName,
                    'policies': policies,
                    'index': index
                };
                vm.deleteInputConfirm('lg', inputToDelete);
            },
            function (error) {
              console.log('#ERROR#');
              console.log(error);
            });
        };

        function duplicateInput(inputName) {
            var inputSelected = $filter('filter')(angular.copy(vm.inputsData), {name:inputName}, true)[0];

            var newName = autoIncrementName(inputSelected.name);
            inputSelected.name = newName;

            var newName = SetDuplicatetedInput('sm', inputSelected);
       };

        function createInput() {
           var inputFragmentTemplate = TemplateFactory.GetNewFragmentTemplate('input');

           inputFragmentTemplate.then(function (result) {
                console.log('*********Controller');
                console.log(result);

                var createInputData = {
                    'action': 'create',
                    'inputDataTemplate': result,
                    'texts': {
                        'title': '_INPUT_WINDOW_NEW_TITLE_',
                        'button': '_INPUT_WINDOW_NEW_BUTTON_',
                        'button_icon': 'icon-circle-plus'
                    }
                };

               vm.createInputModal(createInputData);
           });
        };

        function editInput(inputType, inputName, index) {
           var inputSelected = $filter('filter')(angular.copy(vm.inputsData), {name:inputName}, true)[0];
           var id = inputSelected.id;

           delete inputSelected["id"];

           var inputFragmentTemplate = TemplateFactory.GetNewFragmentTemplate('input');

           inputFragmentTemplate.then(function (result) {
                console.log('--> Editing input');
                console.log('> Getting Fragment Template');
                console.log(result);
                console.log('> Getting Policies affected');
                var policiesAffected = PolicyFactory.GetPolicyByFragmentName(inputType, inputName);
                var inputDataTemplate = result;

                policiesAffected.then(function (result) {
                    console.log(result);

                    var policies = vm.getPolicyNames(result);
                    var editInputData = {
                        'index': index,
                        'id': id,
                        'action': 'edit',
                        'inputSelected': inputSelected,
                        'inputDataTemplate': inputDataTemplate,
                        'policies': policies,
                        'texts': {
                            'title': '_INPUT_WINDOW_MODIFY_TITLE_',
                            'button': '_INPUT_WINDOW_MODIFY_BUTTON_',
                            'button_icon': 'icon-circle-check'
                        }
                    };

                    vm.editInputModal(editInputData);
                },
                function (error) {
                  console.log('#ERROR#');
                  console.log(error);
                });
           });
        };

        function setInputsId(inputsData) {
            for (var i=0; i < inputsData.length; i++) {
                inputsData[i].id = vm.inputId;
                vm.inputId++;
            }
            return inputsData;
        };

        function getPolicyNames(policiesData) {
            var policies = [];

            for (var i=0; i<policiesData.length; i++){
                policies.push(policiesData[i].name);
            }

            return policies;
        };

        function getInputTypes(inputs) {
            for (var i=0; i<inputs.length; i++) {
                var newType = false;
                var type    = inputs[i].element.type;

                if (i === 0) {
                    vm.inputTypes.push({'type': type, 'count': 1});
                }
                else {
                    for (var j=0; j<vm.inputTypes.length; j++) {
                        if (vm.inputTypes[j].type === type) {
                            vm.inputTypes[j].count++;
                            newType = false;
                            break;
                        }
                        else if (vm.inputTypes[j].type !== type){
                            newType = true;
                        }
                    }
                    if (newType) {
                        vm.inputTypes.push({'type': type, 'count':1});
                    }
                }
            }
        };

        function createInputModal(newInputTemplateData) {
            var modalInstance = $modal.open({
               animation: true,
               templateUrl: 'templates/inputs/input-details.tpl.html',
               controller: 'NewFragmentModalCtrl as vm',
               size: 'lg',
               resolve: {
                   item: function () {
                       return newInputTemplateData;
                   }
               }
            });

            modalInstance.result.
               then(function (newInputData) {
                   console.log('*************** Controller back');
                   console.log(newInputData);

                   var newFragment = FragmentFactory.CreateFragment(newInputData.data);

                   newFragment
                       .then(function (result) {
                           console.log('*********Fragment created');
                           console.log(result);

                           var newId = vm.inputsData[vm.inputsData.length-1].id + 1;
                           result.id = newId;

                           vm.inputsData.push(result);
                           console.log(vm.inputsData);
                       },
                       function (error) {
                           console.log(error);
                           console.log('Modal dismissed at: ' + new Date())
                       });

               }, function () {
                   console.log('Modal dismissed at: ' + new Date())
               });
            };

        function editInputModal(editInputData) {
           var modalInstance = $modal.open({
               animation: true,
               templateUrl: 'templates/inputs/input-details.tpl.html',
               controller: 'NewFragmentModalCtrl as vm',
               size: 'lg',
               resolve: {
                   item: function () {
                       return editInputData;
                   }
               }
           });

           modalInstance.result.
               then(function (updatedInputData) {
                   console.log('*************** Controller back');
                   console.log(updatedInputData);

                   var updatedFragment = FragmentFactory.UpdateFragment(updatedInputData.data);

                   updatedFragment
                       .then(function (result) {
                           console.log('*********Fragment updated');
                           console.log(result);

                           result.id = updatedInputData.id;

                           vm.inputsData[updatedInputData.index] = result;
                           console.log(vm.inputsData);
                       },
                       function (error) {
                           console.log(error);
                           console.log('Modal dismissed at: ' + new Date())
                       });

               }, function () {
                   console.log('Modal dismissed at: ' + new Date())
               });
        };

        function deleteInputConfirm(size, input) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: 'templates/components/st_delete_modal.tpl.html',
                controller: 'DeleteFragmentModalCtrl',
                size: size,
                resolve: {
                    item: function () {
                        return input;
                    }
                }
            });

            modalInstance.result
                .then(function (selectedItem) {
                    console.log(selectedItem);
                    var fragmentDeleted = FragmentFactory.DeleteFragment(selectedItem.type, selectedItem.name);

                    fragmentDeleted
                        .then(function (result) {
                            console.log('*********Fragment deleted');
                            vm.inputsData.splice(selectedItem.index, 1);

                        });
                },
                function () {
                    console.log('Modal dismissed at: ' + new Date())
                });
        };

        function SetDuplicatetedInput(size, inputName) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: 'templates/components/st_duplicate_modal.tpl.html',
                controller: 'DuplicateFragmentModalCtrl as vm',
                size: 'lg',
                resolve: {
                    item: function () {
                        return inputName;
                    }
                }
            });

            modalInstance.result
                .then(function (selectedItem) {
                    delete selectedItem["id"];
                    console.log(selectedItem);

                    var newFragment = FragmentFactory.CreateFragment(selectedItem);

                    newFragment
                        .then(function (result) {
                            console.log('*********Fragment created');
                            console.log(result);

                            var newId = vm.inputsData[vm.inputsData.length-1].id + 1;
                            selectedItem.id = newId;

                            vm.inputsData.push(selectedItem);
                        },
                        function (error) {
                            console.log(error);
                            console.log('Modal dismissed at: ' + new Date())
                        });

                },
                function () {
                    console.log('Modal dismissed at: ' + new Date())
                });
        };
    };

    /*NEW & EDIT FRAGMENT MODAL CONTROLLER*/
    angular
        .module('webApp')
        .controller('NewFragmentModalCtrl', NewFragmentModalCtrl);

    NewFragmentModalCtrl.$inject = ['$modalInstance', 'item', 'FragmentFactory'];

    function NewFragmentModalCtrl($modalInstance, item, FragmentFactory) {
        /*jshint validthis: true*/
        var vm = this;

        vm.setProperties = setProperties;
        vm.ok = ok;
        vm.cancel = cancel;
        vm.initFragmentObject = initFragmentObject;
        vm.setFragmentData = setFragmentData;
        vm.createTypeModels = createTypeModels;
        vm.dataSource = {};
        vm.dataSource.element = {};
        vm.templateInputsData = [];
        vm.properties = [];
        vm.error = false;

        init();

        /////////////////////////////////

        function init() {
            console.log('--> NewFragmentModalCtrl');
            console.log('> Data received');
            console.log(item);

            setTexts(item.texts);

            vm.action = item.action;

            if (vm.action === 'edit') {
                vm.templateInputsData = item.inputDataTemplate;
                vm.dataSource = item.inputSelected;
                vm.createTypeModels(vm.templateInputsData);
                vm.selectedIndex = vm.index;
                vm.policiesAffected = item.policies;
            }
            else {
                vm.templateInputsData = item.inputDataTemplate;
                vm.initFragmentObject(vm.templateInputsData);
                vm.createTypeModels(vm.templateInputsData);
                vm.selectedIndex = 0;
            }
        };

        function setTexts(texts) {
            vm.modalTexts = {};
            vm.modalTexts.title = texts.title;
            vm.modalTexts.button = texts.button;
            vm.modalTexts.icon = texts.button_icon;
        }

        function initFragmentObject(fragmentData) {
            /*Init fragment*/
            vm.dataSource.fragmentType = 'input';
            vm.dataSource.name = '';

            /*Init fragment.element*/
            vm.dataSource.element.type = fragmentData[0].name;
            vm.dataSource.element.name = 'in-' + vm.dataSource.element.type;

            /*Init fragment.element.configuration*/
            vm.dataSource.element.configuration = {};

            vm.setFragmentData(0);
        };

        function createTypeModels(fragmentData) {
            /*Create one properties model for each input type*/
            for (var i=0; i<fragmentData.length; i++){
                vm.properties[fragmentData[i].name] = {};

                for (var j=0; j<fragmentData[i].properties.length; j++) {
                    if (fragmentData[i].properties[j].propertyId !== 'name' && fragmentData[i].properties[j].propertyId !== 'type'){
                        vm.properties[fragmentData[i].name][fragmentData[i].properties[j].propertyId] = '';
                    }
                }

                /*Init properties*/
                if(i === 0 && vm.action !== 'edit') {
                    vm.dataSource.element.configuration = vm.properties[fragmentData[i].name];
                }

                else if(vm.action === 'edit' && fragmentData[i].name === vm.dataSource.element.type) {
                    vm.properties[fragmentData[i].name] = vm.dataSource.element.configuration;
                    vm.dataSource.element.configuration = vm.properties[fragmentData[i].name];
                    vm.index = i;
                }
            }
        };

        function setFragmentData(index) {
            /*Set fragment*/
            vm.dataSource.description = vm.templateInputsData[index].description.long;
            vm.dataSource.shortDescription = vm.templateInputsData[index].description.short;
            vm.dataSource.icon = vm.templateInputsData[index].icon.url;
            vm.dataSource.element.name = 'in-' + vm.dataSource.element.type;
        };

        function setProperties(index, inputName) {
            vm.selectedIndex = index;
            vm.dataSource.element.configuration = vm.properties[inputName];
            vm.setFragmentData(index);
        };

        function ok() {
            if (vm.form.$valid){
                checkInputName(vm.dataSource.fragmentType, vm.dataSource.name);
            }
        };

        function checkInputName(inputType, inputName) {
            var newFragment = FragmentFactory.GetFragmentByName(inputType, inputName);

            newFragment
            .then(function (result) {
                vm.error = true;
            },
            function (error) {
                var callBackData = {
                    'index': item.index,
                    'id': item.id,
                    'data': vm.dataSource,
                };
               $modalInstance.close(callBackData);
            });
        };

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

    /*DELETE INPUT MODALS CONTROLLER */
    angular
        .module('webApp')
        .controller('DeleteFragmentModalCtrl', DeleteFragmentModalCtrl);

    DeleteFragmentModalCtrl.$inject = ['$scope', '$modalInstance', 'item'];

    function DeleteFragmentModalCtrl($scope, $modalInstance, item) {
        console.log('*********Modal');
        console.log(item);

        $scope.inputs = item;

        $scope.ok = function () {
            $modalInstance.close($scope.inputs);
        };

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

    /*DUPLICATE INPUT MODAL CONTROLLER */
    angular
        .module('webApp')
        .controller('DuplicateFragmentModalCtrl', DuplicateFragmentModalCtrl);

    DuplicateFragmentModalCtrl.$inject = ['$modalInstance', 'item', 'FragmentFactory'];

    function DuplicateFragmentModalCtrl($modalInstance, item, FragmentFactory) {
        /*jshint validthis: true*/
        var vm = this;

        vm.ok = ok;
        vm.cancel = cancel;
        vm.error = false;

        init();

        ///////////////////////////////////////

        function init () {
            console.log('*********Modal');
            console.log(item);
            vm.inputData = item;
        };

        function ok() {
            if (vm.form.$valid){
                checkInputName(vm.inputData.fragmentType, vm.inputData.name);
            }
        };

        function checkInputName(inputType, inputName) {
            var newFragment = FragmentFactory.GetFragmentByName(inputType, inputName);

            newFragment
            .then(function (result) {
                vm.error = true;
            },
            function (error) {
                $modalInstance.close(vm.inputData);
            });
        };

        function cancel() {
            $modalInstance.dismiss('cancel');
        };
    };
})();
<commit_msg>feature/inputs-v1: form validation in new/edit modal<commit_after>(function() {
    'use strict';

    angular
        .module('webApp')
        .controller('InputsCtrl', InputsCtrl);

    InputsCtrl.$inject = ['FragmentFactory', 'PolicyFactory', 'TemplateFactory', '$filter', '$modal'];

    function InputsCtrl(FragmentFactory, PolicyFactory, TemplateFactory, $filter, $modal) {
        /*jshint validthis: true*/
       var vm = this;

       vm.getInputs = getInputs;
       vm.deleteInput = deleteInput;
       vm.getInputTypes = getInputTypes;
       vm.createInput = createInput;
       vm.editInput = editInput;
       vm.createInputModal = createInputModal;
       vm.editInputModal = editInputModal;
       vm.duplicateInput = duplicateInput;
       vm.deleteInputConfirm = deleteInputConfirm;
       vm.getPolicyNames = getPolicyNames;
       vm.setInputsId = setInputsId;
       vm.inputTypes = [];
       vm.inputId = 1;

       init();

        /////////////////////////////////

        function init() {
            getInputs();
        };

        function getInputs() {
            var inputList = FragmentFactory.GetFragments("input");

            inputList.then(function (result) {
                vm.inputsData = vm.setInputsId(result);
                vm.getInputTypes(result);
            });
        };

        function deleteInput(fragmentType, fragmentName, index) {
            console.log('--> Deleting input');
            console.log('> Getting Policies affected');
            var policiesToDelete = PolicyFactory.GetPolicyByFragmentName(fragmentType, fragmentName);

            policiesToDelete.then(function (result) {
                console.log(result);

                var policies = vm.getPolicyNames(result);
                var inputToDelete =
                {
                    'type':fragmentType,
                    'name': fragmentName,
                    'policies': policies,
                    'index': index
                };
                vm.deleteInputConfirm('lg', inputToDelete);
            },
            function (error) {
              console.log('#ERROR#');
              console.log(error);
            });
        };

        function duplicateInput(inputName) {
            var inputSelected = $filter('filter')(angular.copy(vm.inputsData), {name:inputName}, true)[0];

            var newName = autoIncrementName(inputSelected.name);
            inputSelected.name = newName;

            var newName = SetDuplicatetedInput('sm', inputSelected);
       };

        function createInput() {
           var inputFragmentTemplate = TemplateFactory.GetNewFragmentTemplate('input');

           inputFragmentTemplate.then(function (result) {
                console.log('*********Controller');
                console.log(result);

                var createInputData = {
                    'action': 'create',
                    'inputDataTemplate': result,
                    'texts': {
                        'title': '_INPUT_WINDOW_NEW_TITLE_',
                        'button': '_INPUT_WINDOW_NEW_BUTTON_',
                        'button_icon': 'icon-circle-plus'
                    }
                };

               vm.createInputModal(createInputData);
           });
        };

        function editInput(inputType, inputName, index) {
           var inputSelected = $filter('filter')(angular.copy(vm.inputsData), {name:inputName}, true)[0];
           var id = inputSelected.id;

           delete inputSelected["id"];

           var inputFragmentTemplate = TemplateFactory.GetNewFragmentTemplate('input');

           inputFragmentTemplate.then(function (result) {
                console.log('--> Editing input');
                console.log('> Getting Fragment Template');
                console.log(result);
                console.log('> Getting Policies affected');
                var policiesAffected = PolicyFactory.GetPolicyByFragmentName(inputType, inputName);
                var inputDataTemplate = result;

                policiesAffected.then(function (result) {
                    console.log(result);

                    var policies = vm.getPolicyNames(result);
                    var editInputData = {
                        'index': index,
                        'id': id,
                        'action': 'edit',
                        'inputSelected': inputSelected,
                        'inputDataTemplate': inputDataTemplate,
                        'policies': policies,
                        'texts': {
                            'title': '_INPUT_WINDOW_MODIFY_TITLE_',
                            'button': '_INPUT_WINDOW_MODIFY_BUTTON_',
                            'button_icon': 'icon-circle-check'
                        }
                    };

                    vm.editInputModal(editInputData);
                },
                function (error) {
                  console.log('#ERROR#');
                  console.log(error);
                });
           });
        };

        function setInputsId(inputsData) {
            for (var i=0; i < inputsData.length; i++) {
                inputsData[i].id = vm.inputId;
                vm.inputId++;
            }
            return inputsData;
        };

        function getPolicyNames(policiesData) {
            var policies = [];

            for (var i=0; i<policiesData.length; i++){
                policies.push(policiesData[i].name);
            }

            return policies;
        };

        function getInputTypes(inputs) {
            for (var i=0; i<inputs.length; i++) {
                var newType = false;
                var type    = inputs[i].element.type;

                if (i === 0) {
                    vm.inputTypes.push({'type': type, 'count': 1});
                }
                else {
                    for (var j=0; j<vm.inputTypes.length; j++) {
                        if (vm.inputTypes[j].type === type) {
                            vm.inputTypes[j].count++;
                            newType = false;
                            break;
                        }
                        else if (vm.inputTypes[j].type !== type){
                            newType = true;
                        }
                    }
                    if (newType) {
                        vm.inputTypes.push({'type': type, 'count':1});
                    }
                }
            }
        };

        function createInputModal(newInputTemplateData) {
            var modalInstance = $modal.open({
               animation: true,
               templateUrl: 'templates/inputs/input-details.tpl.html',
               controller: 'NewFragmentModalCtrl as vm',
               size: 'lg',
               resolve: {
                   item: function () {
                       return newInputTemplateData;
                   }
               }
            });

            modalInstance.result.
               then(function (newInputData) {
                   console.log('*************** Controller back');
                   console.log(newInputData);

                   var newFragment = FragmentFactory.CreateFragment(newInputData.data);

                   newFragment
                       .then(function (result) {
                           console.log('*********Fragment created');
                           console.log(result);

                           var newId = vm.inputsData[vm.inputsData.length-1].id + 1;
                           result.id = newId;

                           vm.inputsData.push(result);
                           console.log(vm.inputsData);
                       },
                       function (error) {
                           console.log(error);
                           console.log('Modal dismissed at: ' + new Date())
                       });

               }, function () {
                   console.log('Modal dismissed at: ' + new Date())
               });
            };

        function editInputModal(editInputData) {
           var modalInstance = $modal.open({
               animation: true,
               templateUrl: 'templates/inputs/input-details.tpl.html',
               controller: 'NewFragmentModalCtrl as vm',
               size: 'lg',
               resolve: {
                   item: function () {
                       return editInputData;
                   }
               }
           });

           modalInstance.result.
               then(function (updatedInputData) {
                   console.log('*************** Controller back');
                   console.log(updatedInputData);

                   var updatedFragment = FragmentFactory.UpdateFragment(updatedInputData.data);

                   updatedFragment
                       .then(function (result) {
                           console.log('*********Fragment updated');
                           console.log(result);

                           result.id = updatedInputData.id;

                           vm.inputsData[updatedInputData.index] = result;
                           console.log(vm.inputsData);
                       },
                       function (error) {
                           console.log(error);
                           console.log('Modal dismissed at: ' + new Date())
                       });

               }, function () {
                   console.log('Modal dismissed at: ' + new Date())
               });
        };

        function deleteInputConfirm(size, input) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: 'templates/components/st_delete_modal.tpl.html',
                controller: 'DeleteFragmentModalCtrl',
                size: size,
                resolve: {
                    item: function () {
                        return input;
                    }
                }
            });

            modalInstance.result
                .then(function (selectedItem) {
                    console.log(selectedItem);
                    var fragmentDeleted = FragmentFactory.DeleteFragment(selectedItem.type, selectedItem.name);

                    fragmentDeleted
                        .then(function (result) {
                            console.log('*********Fragment deleted');
                            vm.inputsData.splice(selectedItem.index, 1);

                        });
                },
                function () {
                    console.log('Modal dismissed at: ' + new Date())
                });
        };

        function SetDuplicatetedInput(size, inputName) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: 'templates/components/st_duplicate_modal.tpl.html',
                controller: 'DuplicateFragmentModalCtrl as vm',
                size: 'lg',
                resolve: {
                    item: function () {
                        return inputName;
                    }
                }
            });

            modalInstance.result
                .then(function (selectedItem) {
                    delete selectedItem["id"];
                    console.log(selectedItem);

                    var newFragment = FragmentFactory.CreateFragment(selectedItem);

                    newFragment
                        .then(function (result) {
                            console.log('*********Fragment created');
                            console.log(result);

                            var newId = vm.inputsData[vm.inputsData.length-1].id + 1;
                            selectedItem.id = newId;

                            vm.inputsData.push(selectedItem);
                        },
                        function (error) {
                            console.log(error);
                            console.log('Modal dismissed at: ' + new Date())
                        });

                },
                function () {
                    console.log('Modal dismissed at: ' + new Date())
                });
        };
    };

    /*NEW & EDIT FRAGMENT MODAL CONTROLLER*/
    angular
        .module('webApp')
        .controller('NewFragmentModalCtrl', NewFragmentModalCtrl);

    NewFragmentModalCtrl.$inject = ['$modalInstance', 'item', 'FragmentFactory'];

    function NewFragmentModalCtrl($modalInstance, item, FragmentFactory) {
        /*jshint validthis: true*/
        var vm = this;

        vm.setProperties = setProperties;
        vm.ok = ok;
        vm.cancel = cancel;
        vm.initFragmentObject = initFragmentObject;
        vm.setFragmentData = setFragmentData;
        vm.createTypeModels = createTypeModels;
        vm.dataSource = {};
        vm.dataSource.element = {};
        vm.templateInputsData = [];
        vm.properties = [];
        vm.error = false;

        init();

        /////////////////////////////////

        function init() {
            console.log('--> NewFragmentModalCtrl');
            console.log('> Data received');
            console.log(item);

            setTexts(item.texts);

            vm.action = item.action;

            if (vm.action === 'edit') {
                vm.templateInputsData = item.inputDataTemplate;
                vm.dataSource = item.inputSelected;
                vm.createTypeModels(vm.templateInputsData);
                vm.selectedIndex = vm.index;
                vm.policiesAffected = item.policies;
            }
            else {
                vm.templateInputsData = item.inputDataTemplate;
                vm.initFragmentObject(vm.templateInputsData);
                vm.createTypeModels(vm.templateInputsData);
                vm.selectedIndex = 0;
            }
        };

        function setTexts(texts) {
            vm.modalTexts = {};
            vm.modalTexts.title = texts.title;
            vm.modalTexts.button = texts.button;
            vm.modalTexts.icon = texts.button_icon;
        }

        function initFragmentObject(fragmentData) {
            /*Init fragment*/
            vm.dataSource.fragmentType = 'input';
            vm.dataSource.name = '';

            /*Init fragment.element*/
            vm.dataSource.element.type = fragmentData[0].name;
            vm.dataSource.element.name = 'in-' + vm.dataSource.element.type;

            /*Init fragment.element.configuration*/
            vm.dataSource.element.configuration = {};

            vm.setFragmentData(0);
        };

        function createTypeModels(fragmentData) {
            /*Create one properties model for each input type*/
            for (var i=0; i<fragmentData.length; i++){
                vm.properties[fragmentData[i].name] = {};

                for (var j=0; j<fragmentData[i].properties.length; j++) {
                    if (fragmentData[i].properties[j].propertyId !== 'name' && fragmentData[i].properties[j].propertyId !== 'type'){
                        vm.properties[fragmentData[i].name][fragmentData[i].properties[j].propertyId] = '';
                    }
                }

                /*Init properties*/
                if(i === 0 && vm.action !== 'edit') {
                    vm.dataSource.element.configuration = vm.properties[fragmentData[i].name];
                }

                else if(vm.action === 'edit' && fragmentData[i].name === vm.dataSource.element.type) {
                    vm.properties[fragmentData[i].name] = vm.dataSource.element.configuration;
                    vm.dataSource.element.configuration = vm.properties[fragmentData[i].name];
                    vm.index = i;
                }
            }
        };

        function setFragmentData(index) {
            /*Set fragment*/
            vm.dataSource.description = vm.templateInputsData[index].description.long;
            vm.dataSource.shortDescription = vm.templateInputsData[index].description.short;
            vm.dataSource.icon = vm.templateInputsData[index].icon.url;
            vm.dataSource.element.name = 'in-' + vm.dataSource.element.type;
        };

        function setProperties(index, inputName) {
            vm.selectedIndex = index;
            vm.dataSource.element.configuration = vm.properties[inputName];
            vm.setFragmentData(index);
        };

        function ok() {
            if (vm.form.$valid){
                checkInputName(vm.dataSource.fragmentType, vm.dataSource.name);
            }
        };

        function checkInputName(inputType, inputName) {
            var newFragment = FragmentFactory.GetFragmentByName(inputType, inputName);

            newFragment
            .then(function (result) {
                vm.error = true;
            },
            function (error) {
                var callBackData = {
                    'index': item.index,
                    'id': item.id,
                    'data': vm.dataSource,
                };
               $modalInstance.close(callBackData);
            });
        };

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

    /*DELETE INPUT MODALS CONTROLLER */
    angular
        .module('webApp')
        .controller('DeleteFragmentModalCtrl', DeleteFragmentModalCtrl);

    DeleteFragmentModalCtrl.$inject = ['$scope', '$modalInstance', 'item'];

    function DeleteFragmentModalCtrl($scope, $modalInstance, item) {
        console.log('*********Modal');
        console.log(item);

        $scope.inputs = item;

        $scope.ok = function () {
            $modalInstance.close($scope.inputs);
        };

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

    /*DUPLICATE INPUT MODAL CONTROLLER */
    angular
        .module('webApp')
        .controller('DuplicateFragmentModalCtrl', DuplicateFragmentModalCtrl);

    DuplicateFragmentModalCtrl.$inject = ['$modalInstance', 'item', 'FragmentFactory'];

    function DuplicateFragmentModalCtrl($modalInstance, item, FragmentFactory) {
        /*jshint validthis: true*/
        var vm = this;

        vm.ok = ok;
        vm.cancel = cancel;
        vm.error = false;

        init();

        ///////////////////////////////////////

        function init () {
            console.log('*********Modal');
            console.log(item);
            vm.inputData = item;
        };

        function ok() {
            if (vm.form.$valid){
                checkInputName(vm.inputData.fragmentType, vm.inputData.name);
            }
        };

        function checkInputName(inputType, inputName) {
            var newFragment = FragmentFactory.GetFragmentByName(inputType, inputName);

            newFragment
            .then(function (result) {
                vm.error = true;
            },
            function (error) {
                $modalInstance.close(vm.inputData);
            });
        };

        function cancel() {
            $modalInstance.dismiss('cancel');
        };
    };
})();
<|endoftext|>