<commit_before>import Ember from 'ember';
import computed from 'ember-new-computed';
import EventListenerMixin from '../mixins/event-listener';
import DefaultAttrs from '../mixins/default-attrs';
import layout from '../templates/components/virtual-each';

let {
  Component,
  String:emberString,
  run:emberRun
} = Ember;

let isWebkit = /WebKit/.test(navigator && navigator.userAgent || '');

export default Component.extend(EventListenerMixin, DefaultAttrs, {
  layout,
  totalHeight: 0,
  content: null,
  classNames: ['virtual-each'],
  attributeBindings: ['style'],
  renderedStart: 0,

  defaultAttrs: {
    scrollTimeout: 30,
    height: 200,
    itemHeight: 20,
    items: []
  },

  eventHandlers: {
    wheel() {
      this._scrolledByWheel = true;
    },

    scroll(e) {
      e.preventDefault();

      const timeout = this.getAttr('scrollTimeout');

      if (timeout && isWebkit && this._scrolledByWheel) {
        this._scrolledByWheel = false;

        if (!this._scrollTimer) {
          this._scrollTimer = setTimeout(() => {
            this._scrollTimer = null;
            this._calculateVisibleItems();
          }, timeout);
        }

        return;
      }

      this._calculateVisibleItems();
    }
  },

  style: computed('height', function() {
    return emberString.fmt('height: %@px', this.getAttr('height'));
  }),

  visibleItems: computed('items', 'renderedStart', 'visibleItemCount', {
    get() {
      let items = this.get('items');
      let renderedStart = this.get('renderedStart');
      let visibleItemCount = this.get('visibleItemCount');

      return items.slice(renderedStart, renderedStart + visibleItemCount).map(function(raw, index) {
        return {
          raw: raw,
          index: renderedStart + index
        }
      });
    }
  }),

  visibleItemCount: computed('height', 'itemHeight', {
    get() {
      let height = this.getAttr('height');
      let itemHeight = this.get('itemHeight');

      return Math.ceil(height / itemHeight) + 1;
    }
  }),

  paddingTop: computed('totalHeight', 'visibleItemCount', 'itemHeight', 'renderedStart', {
    get() {
      let itemHeight = this.get('itemHeight');
      let totalHeight = this.get('totalHeight');
      let padding = this.get('renderedStart') * itemHeight;
      let visibleItemCount = this.get('visibleItemCount');
      let maxPadding = Math.max(0, totalHeight - (visibleItemCount * itemHeight) + itemHeight);

      return Math.min(maxPadding, padding);
    }
  }),

  contentHeight: computed('totalHeight', 'paddingTop', {
    get() {
      return this.get('totalHeight') - this.get('paddingTop');
    }
  }),

  _calculateVisibleItems() {
    emberRun(() => {
      let renderedStart = this.get('renderedStart');
      let scrolledAmount = this.$().scrollTop();
      let visibleStart = Math.floor(scrolledAmount / this.get('itemHeight'));

      if (visibleStart !== renderedStart) {
        this.set('renderedStart', visibleStart);
      }
    });
  },

  didReceiveAttrs() {
    this._super(...arguments);

    let items = this.getAttr('items');

    if (items !== this.get('items')) {
      Ember.run.scheduleOnce('afterRender', () => {
        this.$().scrollTop = 0;
      });
    }

    let itemHeight = this.getAttr('itemHeight');

    this.set('items', items);
    this.set('itemheight', itemHeight);
    this.set('totalHeight', Math.max(items.length * itemHeight, 0));
  }
});
<commit_msg>Update virtual-each.js<commit_after>import Ember from 'ember';
import computed from 'ember-new-computed';
import EventListenerMixin from '../mixins/event-listener';
import DefaultAttrsMixin from '../mixins/default-attrs';
import layout from '../templates/components/virtual-each';

let {
  Component,
  String:emberString,
  run:emberRun
} = Ember;

let isWebkit = /WebKit/.test(navigator && navigator.userAgent || '');

export default Component.extend(EventListenerMixin, DefaultAttrsMixin, {
  layout,
  totalHeight: 0,
  content: null,
  classNames: ['virtual-each'],
  attributeBindings: ['style'],
  renderedStart: 0,

  defaultAttrs: {
    scrollTimeout: 30,
    height: 200,
    itemHeight: 20,
    items: []
  },

  eventHandlers: {
    wheel() {
      this._scrolledByWheel = true;
    },

    scroll(e) {
      e.preventDefault();

      const timeout = this.getAttr('scrollTimeout');

      if (timeout && isWebkit && this._scrolledByWheel) {
        this._scrolledByWheel = false;

        if (!this._scrollTimer) {
          this._scrollTimer = setTimeout(() => {
            this._scrollTimer = null;
            this._calculateVisibleItems();
          }, timeout);
        }

        return;
      }

      this._calculateVisibleItems();
    }
  },

  style: computed('height', function() {
    return emberString.fmt('height: %@px', this.getAttr('height'));
  }),

  visibleItems: computed('items', 'renderedStart', 'visibleItemCount', {
    get() {
      let items = this.get('items');
      let renderedStart = this.get('renderedStart');
      let visibleItemCount = this.get('visibleItemCount');

      return items.slice(renderedStart, renderedStart + visibleItemCount).map(function(raw, index) {
        return {
          raw: raw,
          index: renderedStart + index
        }
      });
    }
  }),

  visibleItemCount: computed('height', 'itemHeight', {
    get() {
      let height = this.getAttr('height');
      let itemHeight = this.get('itemHeight');

      return Math.ceil(height / itemHeight) + 1;
    }
  }),

  paddingTop: computed('totalHeight', 'visibleItemCount', 'itemHeight', 'renderedStart', {
    get() {
      let itemHeight = this.get('itemHeight');
      let totalHeight = this.get('totalHeight');
      let padding = this.get('renderedStart') * itemHeight;
      let visibleItemCount = this.get('visibleItemCount');
      let maxPadding = Math.max(0, totalHeight - (visibleItemCount * itemHeight) + itemHeight);

      return Math.min(maxPadding, padding);
    }
  }),

  contentHeight: computed('totalHeight', 'paddingTop', {
    get() {
      return this.get('totalHeight') - this.get('paddingTop');
    }
  }),

  _calculateVisibleItems() {
    emberRun(() => {
      let renderedStart = this.get('renderedStart');
      let scrolledAmount = this.$().scrollTop();
      let visibleStart = Math.floor(scrolledAmount / this.get('itemHeight'));

      if (visibleStart !== renderedStart) {
        this.set('renderedStart', visibleStart);
      }
    });
  },

  didReceiveAttrs() {
    this._super(...arguments);

    let items = this.getAttr('items');

    if (items !== this.get('items')) {
      Ember.run.scheduleOnce('afterRender', () => {
        this.$().scrollTop = 0;
      });
    }

    let itemHeight = this.getAttr('itemHeight');

    this.set('items', items);
    this.set('itemheight', itemHeight);
    this.set('totalHeight', Math.max(items.length * itemHeight, 0));
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

const {
  Mixin,
  computed,
  defineProperty,
  get
} = Ember;

export default Mixin.create({
  searchCollection: 'model',
  searchQuery: '',

  init() {
    this._super();
    defineProperty(
      this,
      'filteredCollection',
      computed('searchQuery', this.get('searchCollection'), function() {
        let searchWords = this.get('searchQuery').split(' ').map( (x) => {
          x.toLowerCase()
        });
        let collection = get(this, this.get('searchCollection')).filterBy(
          'isNew', false
        );

        if (searchWords === []) {
          return collection;
        }

        return collection.filter((item) => {
          let itemName = item.get(this.get('searchAttribute')).toLowerCase();
          let i;

          for (i = 0; i < searchWords.length; i++) {
            let searchMatch = itemName.includes(searchWords[i]);

            if (searchMatch) {
              return true;
            }
          }
        });
      })
    );
  },

  actions: {
    performSearch(s) {
      this.set('searchQuery', s);
    }
  }
});
<commit_msg>fix linter stuffs<commit_after>import Ember from 'ember';

const {
  Mixin,
  computed,
  defineProperty,
  get
} = Ember;

export default Mixin.create({
  searchCollection: 'model',
  searchQuery: '',

  init() {
    this._super();
    defineProperty(
      this,
      'filteredCollection',
      computed('searchQuery', this.get('searchCollection'), function() {
        let searchWords = this.get('searchQuery').split(' ').map((x) => {
          return x.toLowerCase();
        });
        let collection = get(this, this.get('searchCollection')).filterBy(
          'isNew', false
        );

        if (searchWords === []) {
          return collection;
        }

        return collection.filter((item) => {
          let itemName = item.get(this.get('searchAttribute')).toLowerCase();
          let i;

          for (i = 0; i < searchWords.length; i++) {
            let searchMatch = itemName.includes(searchWords[i]);

            if (searchMatch) {
              return true;
            }
          }
        });
      })
    );
  },

  actions: {
    performSearch(s) {
      this.set('searchQuery', s);
    }
  }
});
<|endoftext|>


<commit_before>
require('../components/validated-form-component');

App.ValidatedPaymentFormComponent = App.ValidatedFormComponent.extend({

  classNameBindings: [ 'isValid:valid:invalid', 'cardType' ],
  cardType: Ember.computed.alias('formModel.creditCardType')

});
<commit_msg>Issue #556 - fix billing address validations + limit zip to 5 chars<commit_after>
require('../components/validated-form-component');

App.ValidatedPaymentFormComponent = App.ValidatedFormComponent.extend({

  classNameBindings: [ 'cardType' ],
  cardType: Ember.computed.alias('formModel.creditCardType'),

  isValid: function() {
    return this.get('formModel.isValid') && this.get('formModel.billingAddress.isValid');
  }.property('formModel.isValid', 'formModel.billingAddress.isValid')

});
<|endoftext|>


<commit_before>var Configuration = {};

Configuration.prefNames = ['url', 'email', 'password'];
Configuration.prefLabels = ['サーバ URL', 'メールアドレス', 'パスワード'];
Configuration.prefDefaults = ['https://s.questetra.net/00000000/', 'SouthPole@questetra.com', 'ssssssss'];
Configuration.keyboards = [Titanium.UI.KEYBOARD_URL, Titanium.UI.KEYBOARD_EMAIL_ADDRESS, Titanium.UI.KEYBOARD_ASCII];
Configuration.passwordMasks = [false, false, true];

/** 設定が入力されているか */
Configuration.filled = function() {
	for(var i=0; i<Configuration.prefNames.length; i++) {
		if(Ti.App.Properties.getString(Configuration.prefNames[i], '') == '') { return false; }
	}
	return true;
}<commit_msg>設定画面のラベルを変更。設定の初期値を変更。<commit_after>var Configuration = {};

Configuration.prefNames = ['url', 'email', 'password'];
Configuration.prefLabels = ['サーバ URL', 'メールアドレス', 'APIパスワード'];
Configuration.prefDefaults = ['https://online-demo-ja.questetra.net/', 'SouthPole@questetra.com', 'ItBKJrysUFCILxheTRUbgPsH4NAJ96s8'];
Configuration.keyboards = [Titanium.UI.KEYBOARD_URL, Titanium.UI.KEYBOARD_EMAIL_ADDRESS, Titanium.UI.KEYBOARD_ASCII];
Configuration.passwordMasks = [false, false, true];

/** 設定が入力されているか */
Configuration.filled = function() {
	for(var i=0; i<Configuration.prefNames.length; i++) {
		if(Ti.App.Properties.getString(Configuration.prefNames[i], '') == '') { return false; }
	}
	return true;
};<|endoftext|>


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

    angular.module('mgApp').directive('spinner', Spinner);

    Spinner.$inject = ['$rootScope', '$timeout'];
    function Spinner($rootScope, $timeout) {
        var $spinnerElement = angular.element('#spinner-parent');
        var showPromise;
        var hidePromise;
        return function (scope, element) {
            $rootScope.$on('events:beginRequest', showSpinner);
            $rootScope.$on('events:endRequest', hideSpinner);

            angular.element(document).on('scroll', onScroll);

            function showSpinner() {
                if (showPromise) {
                    return;
                }

                if (hidePromise) {
                    $timeout.cancel(hidePromise);
                    hidePromise = null;
                }

                showPromise = $timeout(function () {
                    $spinnerElement.show();
                    showPromise = null;
                }, 400);
            }

            function hideSpinner() {
                if (showPromise) {
                    $timeout.cancel(showPromise);
                    showPromise = null;
                }

                hidePromise = $timeout(function () {
                    $spinnerElement.hide();
                    hidePromise = null;
                }, 100);
            }

            function onScroll() {
                var scrollTop = angular.element(this).scrollTop();
                var top = 100 + scrollTop;
                element.css({ 'margin-top': top });
            }
        }
    }
})();<commit_msg>Should fix margin<commit_after>(function () {
    'use strict';

    angular.module('mgApp').directive('spinner', Spinner);

    Spinner.$inject = ['$rootScope', '$timeout'];
    function Spinner($rootScope, $timeout) {
        var $spinnerElement = angular.element('#spinner-parent');
        var showPromise;
        var hidePromise;
        return function (scope, element) {
            $rootScope.$on('events:beginRequest', showSpinner);
            $rootScope.$on('events:endRequest', hideSpinner);

            angular.element(document).on('scroll', onScroll);

            function showSpinner() {
                if (showPromise) {
                    return;
                }

                if (hidePromise) {
                    $timeout.cancel(hidePromise);
                    hidePromise = null;
                }

                showPromise = $timeout(function () {
                    $spinnerElement.show();
                    showPromise = null;
                }, 400);
            }

            function hideSpinner() {
                if (showPromise) {
                    $timeout.cancel(showPromise);
                    showPromise = null;
                }

                hidePromise = $timeout(function () {
                    $spinnerElement.hide();
                    hidePromise = null;
                }, 100);
            }

            function onScroll() {
                var scrollTop = angular.element(this).scrollTop();
                var top = 100 + scrollTop;
                var spinnerElement = element.find('.spinner');
                spinnerElement.css({ 'margin-top': top });
            }
        }
    }
})();<|endoftext|>


<commit_before>/*jshint node: true, strict: false, devel: true, debug: true, undef:true, loopfunc:true */

/*
 ***********  WARNING *************
 * Works only on node <0.12
 * see https://github.com/ranm8/requestify/issues/25
 *
 * nvm (think rvm for node.js) will save your life
 * https://github.com/creationix/nvm
 ***********  WARNING *************
 */

var argv = require('optimist')
  .usage('Usage:\n\t$0 database')
  .demand(1)
  .argv;

var runId = argv._[0];
var DATABASE = 'solar2015-'+runId;

var jQuery = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
Backbone.$ = jQuery;
var btoa = require('btoa');
var mqtt = require('mqtt');
var url = require('url');

// var mongo = require('mongodb');

var Drowsy = require('backbone.drowsy.encorelab').Drowsy;
var Wakeful = require('backbone.drowsy.encorelab/wakeful').Wakeful;

var fs = require('fs');
var config = JSON.parse(fs.readFileSync('../config.json'));

console.log("config.json loaded: ", config);

// Adding BasicAuth to the XHR header in order to authenticate with drowsy database
// this is not really big security but a start
var basicAuthHash = btoa(config.drowsy.username + ':' + config.drowsy.password);
Backbone.$.ajaxSetup({
  beforeSend: function(xhr) {
    return xhr.setRequestHeader('Authorization',
        // 'Basic ' + btoa(username + ':' + password));
        'Basic ' + basicAuthHash);
  }
});

var Skeletor = {};
Skeletor.Model = require('../shared/js/model.js').Skeletor.Model;

// danger! monkeypatch!
String.prototype.toCamelCase = function(){
  return this.replace(/([\-_][a-z]|^[a-z])/g, function($1){return $1.toUpperCase().replace(/[\-_]/,'');});
};

/*******************************/

// changes to these collections will be logged
var COLLECTIONS = [
  'grabbed_poster_items'
];

var LOG_TO_COLLECTION = 'events';

// var mongoClient = new mongo.Db(DATABASE, new mongo.Server('localhost', 27017, {}), {w:0});
// var log;
// // TODO: wait for open
// // TOOD: deal with possible error
// // TODO: maybe just switch to mongojs or some other mongo abstraction lib?
// mongoClient.open(function (err) {
//   mongoClient.collection(LOG_TO_COLLECTION, function (err, collection) {
//     log = collection;
//     console.log("Logging to collection '"+LOG_TO_COLLECTION+"'...");
//   });
// });

setupModel();
console.log("Agent is agenting!");

function setupModel() {
  console.log("Starting to initialize model ...");
  Skeletor.Model.init(config.drowsy.url, DATABASE).done(function () {
    // create collection of grabbed poster item models
    var grabbedPosterItems = new Skeletor.Model.GrabbedPosterItems();
    // and make it wakeful
    grabbedPosterItems.wake(config.wakeful.url);

    // grabbedPosterItems.on('change', function (doc) {
    //   // var changed = doc.changedAttributes();
    //   // changed._id = doc.attributes._id; // need this or Drowsy.Document.parse will crap out
    //   // logEntry('change', doc, changed);
    // });

    // grabbedPosterItems.on('add', function (doc) {
    //   // logEntry('add', doc, doc.toJSON());
    // });

    console.log("Model initialized!");

    var urlObj = url.parse(config.mqtt.protocol+config.mqtt.url+':'+config.mqtt.port);
    console.log("Trying to connect to mqtt server with URL: "+url.format(urlObj));
    // connect to mqtt server
    // var client = mqtt.connect(urlObj);
    // var client = mqtt.connect('mqtt://'+config.mqtt.url);
    // var url = config.mqtt.protocol + config.mqtt.url + ":" + config.mqtt.port;
    var client = mqtt.connect(urlObj, {clientId : 'bot_to_solar2015-'+runId});

    // once connected
    client.on('connect', function () {
      // say hello
      client.publish('IAMPOSTEROUT', 'The mqtt bot for solar2015-'+runId+' just came online :)');
      // start listening for messages from the poster client in channel IAMPOSTEROUT
      client.subscribe('IAMPOSTEROUT', function() {
        // when a message arrives, do something with it
        client.on('message', function (topic, message, packet) {
          console.log("Received '" + message + "' on '" + topic + "'");
          try {
            // parse message to JSON object - might throw error
            var m = JSON.parse(message);
            // check if the message has the right action and is intended for our run
            if (m.action === 'process_grabbed_poster_item' && m.class_name === runId) {
              // create Backbone object and save it
              var gpi = new Skeletor.Model.GrabbedPosterItem(m);
              // set flag to indicate the item was not yet processed into tile
              gpi.set('processed_to_tile', false);
              gpi.save().done(function () {
                console.log('Messages successfully saved to database with id: '+gpi.id);
              });
            } else {
              console.log("Message has wrong action <"+m.action+"> or was for another run <"+runId+">");
            }
          } catch (e) {
            console.warn("Error parsing message body: "+e);
          }
        });
      });
    });

    // client.on('message', function (topic, message) {
    //   // message is Buffer
    //   console.log(message.toString());
    //   client.end();
    // });

  });
}<commit_msg>Waking up model and adding to collection before save to see a wakeful message<commit_after>/*jshint node: true, strict: false, devel: true, debug: true, undef:true, loopfunc:true */

/*
 ***********  WARNING *************
 * Works only on node <0.12
 * see https://github.com/ranm8/requestify/issues/25
 *
 * nvm (think rvm for node.js) will save your life
 * https://github.com/creationix/nvm
 ***********  WARNING *************
 */

var argv = require('optimist')
  .usage('Usage:\n\t$0 database')
  .demand(1)
  .argv;

var runId = argv._[0];
var DATABASE = 'solar2015-'+runId;

var jQuery = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
Backbone.$ = jQuery;
var btoa = require('btoa');
var mqtt = require('mqtt');
var url = require('url');

// var mongo = require('mongodb');

var Drowsy = require('backbone.drowsy.encorelab').Drowsy;
var Wakeful = require('backbone.drowsy.encorelab/wakeful').Wakeful;

var fs = require('fs');
var config = JSON.parse(fs.readFileSync('../config.json'));

console.log("config.json loaded: ", config);

// Adding BasicAuth to the XHR header in order to authenticate with drowsy database
// this is not really big security but a start
var basicAuthHash = btoa(config.drowsy.username + ':' + config.drowsy.password);
Backbone.$.ajaxSetup({
  beforeSend: function(xhr) {
    return xhr.setRequestHeader('Authorization',
        // 'Basic ' + btoa(username + ':' + password));
        'Basic ' + basicAuthHash);
  }
});

var Skeletor = {};
Skeletor.Model = require('../shared/js/model.js').Skeletor.Model;

// danger! monkeypatch!
String.prototype.toCamelCase = function(){
  return this.replace(/([\-_][a-z]|^[a-z])/g, function($1){return $1.toUpperCase().replace(/[\-_]/,'');});
};

/*******************************/

// changes to these collections will be logged
var COLLECTIONS = [
  'grabbed_poster_items'
];

var LOG_TO_COLLECTION = 'events';

// var mongoClient = new mongo.Db(DATABASE, new mongo.Server('localhost', 27017, {}), {w:0});
// var log;
// // TODO: wait for open
// // TOOD: deal with possible error
// // TODO: maybe just switch to mongojs or some other mongo abstraction lib?
// mongoClient.open(function (err) {
//   mongoClient.collection(LOG_TO_COLLECTION, function (err, collection) {
//     log = collection;
//     console.log("Logging to collection '"+LOG_TO_COLLECTION+"'...");
//   });
// });

setupModel();
console.log("Agent is agenting!");

function setupModel() {
  console.log("Starting to initialize model ...");
  Skeletor.Model.init(config.drowsy.url, DATABASE).done(function () {
    // create collection of grabbed poster item models
    var grabbedPosterItems = new Skeletor.Model.GrabbedPosterItems();
    // and make it wakeful
    grabbedPosterItems.wake(config.wakeful.url);

    console.log("Model initialized!");

    var urlObj = url.parse(config.mqtt.protocol+config.mqtt.url+':'+config.mqtt.port);
    console.log("Trying to connect to mqtt server with URL: "+url.format(urlObj));
    // connect to mqtt server
    // var client = mqtt.connect(urlObj);
    // var client = mqtt.connect('mqtt://'+config.mqtt.url);
    // var url = config.mqtt.protocol + config.mqtt.url + ":" + config.mqtt.port;
    var client = mqtt.connect(urlObj, {clientId : 'bot_to_solar2015-'+runId});

    // once connected
    client.on('connect', function () {
      // say hello
      client.publish('IAMPOSTEROUT', 'The mqtt bot for solar2015-'+runId+' just came online :)');
      // start listening for messages from the poster client in channel IAMPOSTEROUT
      client.subscribe('IAMPOSTEROUT', function() {
        // when a message arrives, do something with it
        client.on('message', function (topic, message, packet) {
          console.log("Received '" + message + "' on '" + topic + "'");
          try {
            // parse message to JSON object - might throw error
            var m = JSON.parse(message);
            // check if the message has the right action and is intended for our run
            if (m.action === 'process_grabbed_poster_item' && m.class_name === runId) {
              // create Backbone object and save it
              var gpi = new Skeletor.Model.GrabbedPosterItem(m);
              gpi.wake(config.wakeful.url);
              // set flag to indicate the item was not yet processed into tile
              gpi.set('processed_to_tile', false);
              grabbedPosterItems.add(gpi);
              gpi.save().done(function () {
                console.log('Messages successfully saved to database with id: '+gpi.id);

              });
            } else {
              console.log("Message has wrong action <"+m.action+"> or was for another run <"+runId+">");
            }
          } catch (e) {
            console.warn("Error parsing message body: "+e);
          }
        });
      });
    });

    // client.on('message', function (topic, message) {
    //   // message is Buffer
    //   console.log(message.toString());
    //   client.end();
    // });

  });
}<|endoftext|>


<commit_before>Ti.include('/util.js');
Ti.include('/data.js');
Ti.include('/clubs_data.js');
(function (window) {
  var table, SELECTED, UNSELECTED, selectedClubs, deleteButton;

  SELECTED = {
    backgroundColor: Util.theme.mainColor, color: '#fff', isSelected: true, rightImage: '/images/117-todo.png'
  };
  UNSELECTED = {
    backgroundColor: '#fff', color: '#000', isSelected: false, rightImage: ''
  };
  selectedClubs = Data.getUserClubs();

  window.titleControl = (Ti.UI.createSearchBar({
    barColor: Util.theme.mainColor,
    height: 44,
    width: 'auto'
  }));

  table = Util.createSimpleDataTable(clubsData, {
    'table': { },
    'row': {
    	height: 40,
      process: function (club, object) {
        object.updateLayout(club in selectedClubs ? SELECTED : UNSELECTED);
      }
    }
  });

  table.addEventListener('click', function (e) {
    Ti.API.log(e);
    Ti.API.log(e.rowData.title);
    var title = e.rowData.title;
    if (title in Data.getUserClubs()){
    	e.rowData.updateLayout(UNSELECTED);
    	Ti.API.log("in selected");
    	Data.unsubscribeToClub(e.rowData.title);
    	Ti.API.log(Data.getUserClubs());
    } else {
    	e.rowData.updateLayout(SELECTED);
    	Ti.API.log("not in selected");
    	Data.subscribeToClub(e.rowData.title);
    	Ti.API.log(Data.getUserClubs());
    }
  });

  deleteButton = (window.rightNavButton = Ti.UI.createButton({
     title: 'Delete All'
  }));
  deleteButton.addEventListener('click', function (e) {
    var dialog = Ti.UI.createAlertDialog({
      title: 'Unsubscribe', message: 'Unsubscribe from all clubs?', buttonNames: ['No', 'Yes'], cancel: 0
    });
    dialog.addEventListener('click', function (e) {
      if (e.cancel === e.index || e.cancel === true) {
        return;
      }
      if (e.index === 1) {
        Data.removeAllClubs();
        //Titanium.API.info("Unsubscribed from all clubs.");
        // TODO: update layout for all selected rows
        Util.foreach(table.data[0].rows, function (_, row) {
          Ti.API.info(row);
        	if (row.isSelected) {
        	  row.updateLayout(UNSELECTED);
      	  }
        });
      }
    });
    dialog.show();
  });

  window.add(table);
}).call(Ti.UI.currentWindow, Ti.UI.currentWindow);<commit_msg>Dark Colour for selected items.<commit_after>Ti.include('/util.js');
Ti.include('/data.js');
Ti.include('/clubs_data.js');
(function (window) {
  var table, SELECTED, UNSELECTED, selectedClubs, deleteButton;

  SELECTED = {
    backgroundColor: Util.theme.darkColor, color: '#fff', isSelected: true, rightImage: '/images/117-todo.png'
  };
  UNSELECTED = {
    backgroundColor: '#fff', color: '#000', isSelected: false, rightImage: ''
  };
  selectedClubs = Data.getUserClubs();

  window.titleControl = (Ti.UI.createSearchBar({
    barColor: Util.theme.mainColor,
    height: 44,
    width: 'auto'
  }));

  table = Util.createSimpleDataTable(clubsData, {
    'table': { },
    'row': {
    	height: 40,
      process: function (club, object) {
        object.updateLayout(club in selectedClubs ? SELECTED : UNSELECTED);
      }
    }
  });

  table.addEventListener('click', function (e) {
    Ti.API.log(e);
    Ti.API.log(e.rowData.title);
    var title = e.rowData.title;
    if (title in Data.getUserClubs()){
    	e.rowData.updateLayout(UNSELECTED);
    	Ti.API.log("in selected");
    	Data.unsubscribeToClub(e.rowData.title);
    	Ti.API.log(Data.getUserClubs());
    } else {
    	e.rowData.updateLayout(SELECTED);
    	Ti.API.log("not in selected");
    	Data.subscribeToClub(e.rowData.title);
    	Ti.API.log(Data.getUserClubs());
    }
  });

  deleteButton = (window.rightNavButton = Ti.UI.createButton({
     title: 'Delete All'
  }));
  deleteButton.addEventListener('click', function (e) {
    var dialog = Ti.UI.createAlertDialog({
      title: 'Unsubscribe', message: 'Unsubscribe from all clubs?', buttonNames: ['No', 'Yes'], cancel: 0
    });
    dialog.addEventListener('click', function (e) {
      if (e.cancel === e.index || e.cancel === true) {
        return;
      }
      if (e.index === 1) {
        Data.removeAllClubs();
        //Titanium.API.info("Unsubscribed from all clubs.");
        // TODO: update layout for all selected rows
        Util.foreach(table.data[0].rows, function (_, row) {
          Ti.API.info(row);
        	if (row.isSelected) {
        	  row.updateLayout(UNSELECTED);
      	  }
        });
      }
    });
    dialog.show();
  });

  window.add(table);
}).call(Ti.UI.currentWindow, Ti.UI.currentWindow);<|endoftext|>


<commit_before>var jQuery = jQuery || django.jQuery;
var armstrong = armstrong || {};
armstrong.widgets = armstrong.widgets || {};

armstrong.widgets.generickey = function($, options) {
  var id = options.id,
      container = $("#generic_key_" + id),
      row = container.parents("tr"),
      params = {
        object_id: row.find('.object_id input[type="hidden"]').val(),
        content_type_id: row.find(".content_type input").val()
      };

  var initVisualSearch  = function() {
    $(document).ready(function() {
      var facets = {
        inFlight: false,
        data: [],
        raw: false,
      };
      options.query = options.query || '';
      VS.init({
        container  : container,
        query      : options.query,
        unquotable : [],
        callbacks  : {
          search : function(query) {
            if (query.length <= 0) {
              return;
            }
            var result = query.split(":", 2),
                model = result[0],
                content_type_id = facets.raw[model].id,
                model_id = result[1].slice(2); // ditch the ' "'
            $("#" + id).val(model_id);
            $("#" + id.replace("object_id", "content_type")).val(content_type_id);
          },
          facetMatches : function(callback) {
            if (facets.data.length > 0) {
              callback(facets.data);
            } else if (!facets.inFlight) {
              facets.inFlight = true;
              $.getJSON(options.facetURL, function(data) {
                facets.raw = data;
                for (key in data) {
                  facets.data.push(key);
                }
                callback(facets.data);
                facets.inFlight = false;
              });
            }
          },
          valueMatches : function(facet, searchTerm, callback) {
            var app_label = facets.raw[facet].app_label,
                model = facet;
            // TODO: don't pound the server
            $.getJSON("/admin/" + app_label + "/" + model + "/search/", {q: searchTerm}, function(data) {
              callback(data.results);
            });
          }
        }
      });
    });
  };

  if (params.content_type_id) {
    $.getJSON(options.queryLookupURL, params, function(data) {
      options.query = data.query
      initVisualSearch();
      });
  } else {
    initVisualSearch();
  }
};
<commit_msg>add in code to 'delete' data when you use the clear button<commit_after>var jQuery = jQuery || django.jQuery;
var armstrong = armstrong || {};
armstrong.widgets = armstrong.widgets || {};

armstrong.widgets.generickey = function($, options) {
  var id = options.id,
      container = $("#generic_key_" + id),
      row = container.parents("tr"),
      params = {
        object_id: row.find('.object_id input[type="hidden"]').val(),
        content_type_id: row.find(".content_type input").val()
      };

  var initVisualSearch  = function() {
    $(document).ready(function() {
      var facets = {
        inFlight: false,
        data: [],
        raw: false,
      };
      options.query = options.query || '';
      VS.init({
        container  : container,
        query      : options.query,
        unquotable : [],
        callbacks  : {
          clearSearch: function(callback) {
            row.find('.delete input[type="checkbox"]').attr({"checked": "checked"});
            callback();
          },
          search : function(query) {
            if (query.length <= 0) {
              return;
            }
            var result = query.split(":", 2),
                model = result[0],
                content_type_id = facets.raw[model].id,
                model_id = result[1].slice(2); // ditch the ' "'
            $("#" + id).val(model_id);
            $("#" + id.replace("object_id", "content_type")).val(content_type_id);
          },
          facetMatches : function(callback) {
            if (facets.data.length > 0) {
              callback(facets.data);
            } else if (!facets.inFlight) {
              facets.inFlight = true;
              $.getJSON(options.facetURL, function(data) {
                facets.raw = data;
                for (key in data) {
                  facets.data.push(key);
                }
                callback(facets.data);
                facets.inFlight = false;
              });
            }
          },
          valueMatches : function(facet, searchTerm, callback) {
            var app_label = facets.raw[facet].app_label,
                model = facet;
            // TODO: don't pound the server
            $.getJSON("/admin/" + app_label + "/" + model + "/search/", {q: searchTerm}, function(data) {
              callback(data.results);
            });
          }
        }
      });
    });
  };

  if (params.content_type_id) {
    $.getJSON(options.queryLookupURL, params, function(data) {
      options.query = data.query
      initVisualSearch();
      });
  } else {
    initVisualSearch();
  }
};
<|endoftext|>


<commit_before>
Array.prototype.__in_groups_of = function(n) {
  var length = this.length,
      group_size = Math.ceil(length / n),
      groups = [];
  for(var i=0; i<n; i++) {
    groups.push(this.slice((i*group_size), ((i+1)*group_size)) || []);
  }
  return groups;
}
if(!Array.prototype.in_groups_of) Array.prototype.in_groups_of = Array.prototype.__in_groups_of;

Array.prototype.__group_by = function(fn) {
  var hash = {}, key, array;
  for(var i=0, ii=this.length; i<ii; i++) {
    key = fn(this[i]);
    array = hash[key] || [];
    array.push(this[i]);
    hash[key] = array;
  }
  return hash;
}
if(!Array.prototype.groupBy) Array.prototype.groupBy = Array.prototype.__group_by;

Array.prototype.__includes = function(item) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(this[i] == item) {
      return true;
    }
  }
  return false;
}
if(!Array.prototype.includes) Array.prototype.includes = Array.prototype.__includes;
if(!Array.prototype.include) Array.prototype.include = Array.prototype.__includes;
if(!Array.prototype.contains) Array.prototype.contains = Array.prototype.__includes;
if(!Array.prototype.contain) Array.prototype.contain = Array.prototype.__includes;

Array.prototype.__each = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    fn(this[i]);
  }
}
if(!Array.prototype.each) Array.prototype.each = Array.prototype.__each;

Array.prototype.__collect = function(fn) {
  var array = [];
  for(var i=0, ii=this.length; i<ii; i++) {
    array.push(fn(this[i]));
  }
  return array;
}
if(!Array.prototype.collect) Array.prototype.collect = Array.prototype.__collect;
if(!Array.prototype.map) Array.prototype.map = Array.prototype.__collect;

Array.__each = function(array, fn) {
  for(var i=0, ii=array.length; i<ii; i++) {
    fn(array[i]);
  }
}
if(!Array.each) Array.each = Array.__each;

Array.prototype.__find = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    var e = this[i];
    if(fn(e)) {
      return e;
    }
  }
  return null;
}
if(!Array.prototype.find) Array.prototype.find = Array.prototype.__find;
if(!Array.prototype.detect) Array.prototype.detect = Array.prototype.__find;

Array.prototype.__inject = function(memo, fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    memo = fn(memo, this[i]);
  }
  return memo;
}
if(!Array.prototype.inject) Array.prototype.inject = Array.prototype.__inject;
if(!Array.prototype.reduce) Array.prototype.reduce = Array.prototype.__inject;

Array.prototype.__grep = function(regex) {
  return this.__select(function(e) {
    return e.toString().match(regex);
  });
}
if(!Array.prototype.grep) Array.prototype.grep = Array.prototype.__grep;

Array.prototype.__remove = function(removeMe) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(this[i]==removeMe) {
      this.splice(i, 1);
      ii--;
      i--;
    }
  }
}
if(!Array.prototype.remove) Array.prototype.remove = Array.prototype.__remove;

Array.prototype.__removeWith = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(fn(this[i])) {
      this.splice(i, 1);
      ii--;
      i--;
    }
  }
}
if(!Array.prototype.removeWith) Array.prototype.removeWith = Array.prototype.__removeWith;
if(!Array.prototype.removeIf) Array.prototype.removeIf = Array.prototype.__removeWith;

Array.prototype.__select = function(fn) {
  var selected = [];
  for(var i=0, ii=this.length; i<ii; i++) {
    if(fn(this[i])) {
      selected.push(this[i]);
    }
  }
  return selected;
}
if(!Array.prototype.select) Array.prototype.select = Array.prototype.__select;
if(!Array.prototype.findAll) Array.prototype.findAll = Array.prototype.__select;

Array.prototype.__dup = function() {
  return this.slice(0);
}
if(!Array.prototype.dup) Array.prototype.dup = Array.prototype.__dup;

Array.prototype.__first = function() {
  return this[0];
}
if(!Array.prototype.first) Array.prototype.first = Array.prototype.__first;

Array.prototype.__last = function() {
  return this[this.length - 1];
}
if(!Array.prototype.last) Array.prototype.last = Array.prototype.__last;
<commit_msg>add eachWithObject to Array<commit_after>
Array.prototype.__in_groups_of = function(n) {
  var length = this.length,
      group_size = Math.ceil(length / n),
      groups = [];
  for(var i=0; i<n; i++) {
    groups.push(this.slice((i*group_size), ((i+1)*group_size)) || []);
  }
  return groups;
}
if(!Array.prototype.in_groups_of) Array.prototype.in_groups_of = Array.prototype.__in_groups_of;

Array.prototype.__group_by = function(fn) {
  var hash = {}, key, array;
  for(var i=0, ii=this.length; i<ii; i++) {
    key = fn(this[i]);
    array = hash[key] || [];
    array.push(this[i]);
    hash[key] = array;
  }
  return hash;
}
if(!Array.prototype.groupBy) Array.prototype.groupBy = Array.prototype.__group_by;

Array.prototype.__includes = function(item) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(this[i] == item) {
      return true;
    }
  }
  return false;
}
if(!Array.prototype.includes) Array.prototype.includes = Array.prototype.__includes;
if(!Array.prototype.include) Array.prototype.include = Array.prototype.__includes;
if(!Array.prototype.contains) Array.prototype.contains = Array.prototype.__includes;
if(!Array.prototype.contain) Array.prototype.contain = Array.prototype.__includes;

Array.prototype.__each = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    fn(this[i]);
  }
}
if(!Array.prototype.each) Array.prototype.each = Array.prototype.__each;

Array.prototype.__collect = function(fn) {
  var array = [];
  for(var i=0, ii=this.length; i<ii; i++) {
    array.push(fn(this[i]));
  }
  return array;
}
if(!Array.prototype.collect) Array.prototype.collect = Array.prototype.__collect;
if(!Array.prototype.map) Array.prototype.map = Array.prototype.__collect;

Array.__each = function(array, fn) {
  for(var i=0, ii=array.length; i<ii; i++) {
    fn(array[i]);
  }
}
if(!Array.each) Array.each = Array.__each;

Array.prototype.__find = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    var e = this[i];
    if(fn(e)) {
      return e;
    }
  }
  return null;
}
if(!Array.prototype.find) Array.prototype.find = Array.prototype.__find;
if(!Array.prototype.detect) Array.prototype.detect = Array.prototype.__find;

Array.prototype.__inject = function(memo, fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    memo = fn(memo, this[i]);
  }
  return memo;
}
if(!Array.prototype.inject) Array.prototype.inject = Array.prototype.__inject;
if(!Array.prototype.reduce) Array.prototype.reduce = Array.prototype.__inject;

Array.prototype.__eachWithObject = function(memo, fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    fn(memo, this[i]);
  }
  return memo;
}
if(!Array.prototype.eachWithObject) Array.prototype.eachWithObject = Array.prototype.__eachWithObject;

Array.prototype.__grep = function(regex) {
  return this.__select(function(e) {
    return e.toString().match(regex);
  });
}
if(!Array.prototype.grep) Array.prototype.grep = Array.prototype.__grep;

Array.prototype.__remove = function(removeMe) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(this[i]==removeMe) {
      this.splice(i, 1);
      ii--;
      i--;
    }
  }
}
if(!Array.prototype.remove) Array.prototype.remove = Array.prototype.__remove;

Array.prototype.__removeWith = function(fn) {
  for(var i=0, ii=this.length; i<ii; i++) {
    if(fn(this[i])) {
      this.splice(i, 1);
      ii--;
      i--;
    }
  }
}
if(!Array.prototype.removeWith) Array.prototype.removeWith = Array.prototype.__removeWith;
if(!Array.prototype.removeIf) Array.prototype.removeIf = Array.prototype.__removeWith;

Array.prototype.__select = function(fn) {
  var selected = [];
  for(var i=0, ii=this.length; i<ii; i++) {
    if(fn(this[i])) {
      selected.push(this[i]);
    }
  }
  return selected;
}
if(!Array.prototype.select) Array.prototype.select = Array.prototype.__select;
if(!Array.prototype.findAll) Array.prototype.findAll = Array.prototype.__select;

Array.prototype.__dup = function() {
  return this.slice(0);
}
if(!Array.prototype.dup) Array.prototype.dup = Array.prototype.__dup;

Array.prototype.__first = function() {
  return this[0];
}
if(!Array.prototype.first) Array.prototype.first = Array.prototype.__first;

Array.prototype.__last = function() {
  return this[this.length - 1];
}
if(!Array.prototype.last) Array.prototype.last = Array.prototype.__last;
<|endoftext|>


<commit_before>/**
 * Created by Ilya V. Schurov on 19/02/2017.
 */

$(function() {
    $(".process_autograded_status")
        .each(function process_element(i, element) {
            var submission_id = element.data("submission-id");

            $.getJSON($SCRIPT_ROOT +
                "/json/autograded_status/" + submission_id,
                function(submission) {
                    if (submission.status === 'autograded') {
                        element.empty().append(
                            $("<a>").attr("href", $SCRIPT_ROOT
                            + "/get/feedback/" + submission_id)
                                .html("Результаты проверки")
                            );

                    } else if (submission.status === 'processing') {
                        element.text(
                            "Идёт автоматическая проверка. " +
                            "Пожалуйста, подождите."
                        );
                        setTimeout(process_element(i, element), 1000);
                    } else if (submission.status === 'failed') {
                        element.text("ОШИБКА: " + submission.log);
                    } else if (submission.status === 'late') {
                        element.text("Проверка не производится: работа " +
                            "сдана после дедлайна. Пожалуйста,  " +
                            "обратитесь к преподавателю, если считаете, " +
                            "что работа " +
                            "всё равно должна быть проверена.");
                    } else if (submission.status === 'sent-to-grading') {
                        element.text("Работа ожидает автоматической " +
                            "проверки, но все роботы-проверяльщики " +
                            "заняты. Пожалуйста, подождите.");
                        setTimeout(process_element(i, element), 1000);
                    } else if (submission.status == 'timeout') {
                        element.text("ОШИБКА: выполнение " +
                            "занимает слишком  " +
                            "много времени, скорее всего где-то есть " +
                            "бесконечный цикл.");
                    }
                }
            );
        });
});<commit_msg>fixes<commit_after>/**
 * Created by Ilya V. Schurov on 19/02/2017.
 */

$(function() {
    $(".process_autograded_status")
        .each(function process_element(i, element) {
            element = $(element);
            var submission_id = element.data("submission-id");

            $.getJSON($SCRIPT_ROOT +
                "/json/autograded_status/" + submission_id,
                function(submission) {
                    if (submission.status === 'autograded') {
                        element.empty().append(
                            $("<a>").attr("href", $SCRIPT_ROOT
                            + "/get/feedback/" + submission_id)
                                .html("Результаты проверки")
                            );

                    } else if (submission.status === 'processing') {
                        element.text(
                            "Идёт автоматическая проверка. " +
                            "Пожалуйста, подождите."
                        );
                        setTimeout(process_element(i, element), 1000);
                    } else if (submission.status === 'failed') {
                        element.text("ОШИБКА: " + submission.log);
                    } else if (submission.status === 'late') {
                        element.text("Проверка не производится: работа " +
                            "сдана после дедлайна. Пожалуйста,  " +
                            "обратитесь к преподавателю, если считаете, " +
                            "что работа " +
                            "всё равно должна быть проверена.");
                    } else if (submission.status === 'sent-to-grading') {
                        element.text("Работа ожидает автоматической " +
                            "проверки, но все роботы-проверяльщики " +
                            "заняты. Пожалуйста, подождите.");
                        setTimeout(process_element(i, element), 1000);
                    } else if (submission.status == 'timeout') {
                        element.text("ОШИБКА: выполнение " +
                            "занимает слишком  " +
                            "много времени, скорее всего где-то есть " +
                            "бесконечный цикл.");
                    }
                }
            );
        });
});<|endoftext|>


<commit_before>import atLibModels from '~models';
import atLibComponents from '~components';

import Strings from '~features/output/jobs.strings';
import Controller from '~features/output/index.controller';
import PageService from '~features/output/page.service';
import ScrollService from '~features/output/scroll.service';

const Template = require('~features/output/index.view.html');

const MODULE_NAME = 'at.features.output';
const PAGE_CACHE = true;
const PAGE_LIMIT = 3;
const PAGE_SIZE = 100;
const WS_PREFIX = 'ws';

function resolveResource (Job, ProjectUpdate, AdHocCommand, SystemJob, WorkflowJob, $stateParams) {
    const { id, type } = $stateParams;

    let Resource;
    let related = 'events';

    switch (type) {
        case 'project':
            Resource = ProjectUpdate;
            break;
        case 'playbook':
            Resource = Job;
            related = 'job_events';
            break;
        case 'command':
            Resource = AdHocCommand;
            break;
        case 'system':
            Resource = SystemJob;
            break;
        case 'workflow':
            Resource = WorkflowJob;
            break;
        default:
            // Redirect
            return null;
    }

    return new Resource('get', id)
        .then(model => model.extend(related, {
            pageCache: PAGE_CACHE,
            pageLimit: PAGE_LIMIT,
            params: {
                page_size: PAGE_SIZE,
                order_by: 'start_line'
            }
        }))
        .then(model => {
            return {
                id,
                type,
                model,
                related,
                ws: {
                    namespace: `${WS_PREFIX}-${getWebSocketResource(type).key}-${id}`
                },
                page: {
                    cache: PAGE_CACHE,
                    size: PAGE_SIZE,
                    pageLimit: PAGE_LIMIT
                }
            };
        });
}

function resolveWebSocketConnection (SocketService, $stateParams) {
    const { type, id } = $stateParams;
    const resource = getWebSocketResource(type);

    let name;
    let events;

    const state = {
        data: {
            socket: {
                groups: {
                    [resource.name]: ['status_changed', 'summary'],
                    [resource.key]: []
                }
            }
        }
    };

    SocketService.addStateResolve(state, id);
}

function resolveBreadcrumb (strings) {
    return {
        label: strings.get('state.TITLE')
    };
}

function getWebSocketResource (type) {
    let name;
    let key;

    switch (type) {
        case 'system':
            name = 'system_jobs';
            key = 'system_job_events';
            break;
        case 'project':
            name = 'project_updates';
            key = 'project_update_events';
            break;
        case 'command':
            name = 'ad_hoc_commands';
            key = 'ad_hoc_command_events';
            break;
        case 'inventory':
            name = 'inventory_updates';
            key = 'inventory_update_events';
            break;
        case 'playbook':
            name = 'jobs';
            key = 'job_events';
            break;
    }

    return { name, key };
}

function JobsRun ($stateRegistry) {
    const state = {
        name: 'jobz',
        url: '/jobz/:type/:id',
        route: '/jobz/:type/:id',
        data: {
            activityStream: true,
            activityStreamTarget: 'jobs'
        },
        views: {
            '@': {
                templateUrl: Template,
                controller: Controller,
                controllerAs: 'vm'
            }
        },
        resolve: {
            resource: [
                'JobModel',
                'ProjectUpdateModel',
                'AdHocCommandModel',
                'SystemJobModel',
                'WorkflowJobModel',
                '$stateParams',
                resolveResource
            ],
            ncyBreadcrumb: [
                'JobStrings',
                resolveBreadcrumb
            ],
            webSocketConnection: [
                'SocketService',
                '$stateParams',
                resolveWebSocketConnection
            ]
        },
    };

    $stateRegistry.register(state);
}

JobsRun.$inject = ['$stateRegistry'];

angular
    .module(MODULE_NAME, [
        atLibModels,
        atLibComponents
    ])
    .service('JobStrings', Strings)
    .service('JobPageService', PageService)
    .service('JobScrollService', ScrollService)
    .run(JobsRun);

export default MODULE_NAME;
<commit_msg>Remove stream service from job index includes<commit_after>import atLibModels from '~models';
import atLibComponents from '~components';

import Strings from '~features/output/jobs.strings';
import Controller from '~features/output/index.controller';
import PageService from '~features/output/page.service';
import RenderService from '~features/output/render.service';
import ScrollService from '~features/output/scroll.service';

const Template = require('~features/output/index.view.html');

const MODULE_NAME = 'at.features.output';
const PAGE_CACHE = true;
const PAGE_LIMIT = 3;
const PAGE_SIZE = 100;
const WS_PREFIX = 'ws';

function resolveResource (Job, ProjectUpdate, AdHocCommand, SystemJob, WorkflowJob, $stateParams) {
    const { id, type } = $stateParams;

    let Resource;
    let related = 'events';

    switch (type) {
        case 'project':
            Resource = ProjectUpdate;
            break;
        case 'playbook':
            Resource = Job;
            related = 'job_events';
            break;
        case 'command':
            Resource = AdHocCommand;
            break;
        case 'system':
            Resource = SystemJob;
            break;
        case 'workflow':
            Resource = WorkflowJob;
            break;
        default:
            // Redirect
            return null;
    }

    return new Resource('get', id)
        .then(model => model.extend(related, {
            pageCache: PAGE_CACHE,
            pageLimit: PAGE_LIMIT,
            params: {
                page_size: PAGE_SIZE,
                order_by: 'start_line'
            }
        }))
        .then(model => {
            return {
                id,
                type,
                model,
                related,
                ws: {
                    namespace: `${WS_PREFIX}-${getWebSocketResource(type).key}-${id}`
                },
                page: {
                    cache: PAGE_CACHE,
                    size: PAGE_SIZE,
                    pageLimit: PAGE_LIMIT
                }
            };
        });
}

function resolveWebSocketConnection (SocketService, $stateParams) {
    const { type, id } = $stateParams;
    const resource = getWebSocketResource(type);

    let name;
    let events;

    const state = {
        data: {
            socket: {
                groups: {
                    [resource.name]: ['status_changed', 'summary'],
                    [resource.key]: []
                }
            }
        }
    };

    SocketService.addStateResolve(state, id);
}

function resolveBreadcrumb (strings) {
    return {
        label: strings.get('state.TITLE')
    };
}

function getWebSocketResource (type) {
    let name;
    let key;

    switch (type) {
        case 'system':
            name = 'system_jobs';
            key = 'system_job_events';
            break;
        case 'project':
            name = 'project_updates';
            key = 'project_update_events';
            break;
        case 'command':
            name = 'ad_hoc_commands';
            key = 'ad_hoc_command_events';
            break;
        case 'inventory':
            name = 'inventory_updates';
            key = 'inventory_update_events';
            break;
        case 'playbook':
            name = 'jobs';
            key = 'job_events';
            break;
    }

    return { name, key };
}

function JobsRun ($stateRegistry) {
    const state = {
        name: 'jobz',
        url: '/jobz/:type/:id',
        route: '/jobz/:type/:id',
        data: {
            activityStream: true,
            activityStreamTarget: 'jobs'
        },
        views: {
            '@': {
                templateUrl: Template,
                controller: Controller,
                controllerAs: 'vm'
            }
        },
        resolve: {
            resource: [
                'JobModel',
                'ProjectUpdateModel',
                'AdHocCommandModel',
                'SystemJobModel',
                'WorkflowJobModel',
                '$stateParams',
                resolveResource
            ],
            ncyBreadcrumb: [
                'JobStrings',
                resolveBreadcrumb
            ],
            webSocketConnection: [
                'SocketService',
                '$stateParams',
                resolveWebSocketConnection
            ]
        },
    };

    $stateRegistry.register(state);
}

JobsRun.$inject = ['$stateRegistry'];

angular
    .module(MODULE_NAME, [
        atLibModels,
        atLibComponents
    ])
    .service('JobStrings', Strings)
    .service('JobPageService', PageService)
    .service('JobScrollService', ScrollService)
    .run(JobsRun);

export default MODULE_NAME;
<|endoftext|>


<commit_before>module.exports = function(r) {
    const dbExec = require('./run');
    const db = require('./db')(r);
    const model = require('./model')(r);

    return {
        getAllForProject,
        get,
        create,
        update,
        createTask,
        getTask,
        updateTask,
        experimentExistsInProject,
        experimentTaskExistsInExperiment,
        experimentNoteExistsInExperiment,
        deleteTask,
        taskIsUsingProcess,
        getExperimentNote,
        createExperimentNote,
        updateExperimentNote,
        deleteExperimentNote
    };

    function* getAllForProject(projectID) {
        let rql = r.table('project2experiment').getAll(projectID, {index: 'project_id'})
            .eqJoin('experiment_id', r.table('experiments')).zip()
            .merge((experiment) => {
                return {
                    tasks: r.table('experiment2experimenttask')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
                        .filter({parent_id: ''})
                        .orderBy('index')
                        .coerceTo('array'),
                    notes: r.table('experiment2experimentnote')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_note_id', r.table('experimentnotes')).zip()
                        .orderBy('name')
                        .coerceTo('array')
                }
            });
        let experiments = yield dbExec(rql);
        return {val: experiments};
    }

    // Get assumes that validating the experiment for the project has already occured.
    function* get(experimentID) {
        let rql = r.table('experiments').get(experimentID)
            .merge((experiment) => {
                return {
                    tasks: r.table('experiment2experimenttask')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
                        .filter({parent_id: ''})
                        .orderBy('index')
                        .coerceTo('array')
                }
            });
        let experiment = yield dbExec(rql);
        experiment.tasks.forEach((task) => task.tasks = []);
        return {val: experiment};
    }

    function* create(experiment, owner) {
        let e = new model.Experiment(experiment.name, owner);
        e.description = experiment.description;
        let newExperiment = yield db.insert('experiments', e);
        let proj2experiment = new model.Project2Experiment(experiment.project_id, newExperiment.id);
        yield db.insert('project2experiment', proj2experiment);
        let etask = new model.ExperimentTask('', owner);
        yield createTask(newExperiment.id, etask, owner);
        return yield get(newExperiment.id);
    }

    function* update(experimentID, updateArgs) {
        yield db.update('experiments', experimentID, updateArgs);
        return yield get(experimentID);
    }

    function* createTask(experimentID, task, owner) {
        let etask = new model.ExperimentTask(task.name, owner);
        etask.description = task.description;
        etask.parent_id = task.parent_id;
        etask.index = task.index;
        yield updateIndexOfAllAffected(experimentID, task.parent_id, task.index);
        let createdTask = yield db.insert('experimenttasks', etask);
        let e2etask = new model.Experiment2ExperimentTask(experimentID, createdTask.id);
        yield db.insert('experiment2experimenttask', e2etask);
        return yield getTask(createdTask.id);
    }

    function* updateIndexOfAllAffected(experimentID, parentID, index) {
        let rql = r.table('experiment2experimenttask')
            .getAll(experimentID, {index: 'experiment_id'})
            .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
            .filter({parent_id: parentID})
            .filter(r.row('index').ge(index));

        let matchingTasks = yield dbExec(rql);
        let itemsToChange = matchingTasks.map((t) => { return {id: t.id, index: t.index + 1}; });
        let updateRql = r.table('experimenttasks').insert(itemsToChange, {conflict: 'update'});
        yield dbExec(updateRql);
    }

    function* getTask(taskID) {
        let rql = r.table('experimenttasks').get(taskID)
            .merge((task) => {
                return {
                    processes: r.table('experimenttask2process').getAll(task('id'), {index: 'experiment_task_id'})
                        .eqJoin('process_id', r.table('processes')).zip().coerceTo('array'),
                    tasks: r.table('experimenttasks').getAll(task('id'), {index: 'parent_id'}).coerceTo('array')
                }
            });
        let t = yield dbExec(rql);

        // merge processes into tasks and then remove the entry
        t.tasks.concat(t.processes);
        delete t.processes;

        return {val: t};
    }

    function* updateTask(taskID, updateArgs) {
        if (updateArgs.swap) {
            let task = yield r.table('experimenttasks').get(taskID);
            let swapTask = yield r.table('experimenttasks').get(updateArgs.swap.task_id);
            if (swapTask.parent_id !== task.parent_id) {
                return {error: 'Tasks have different parents'};
            }
            let swapItems = [
                {
                    id: taskID,
                    index: swapTask.index
                },
                {
                    id: updateArgs.swap.task_id,
                    index: task.index
                }
            ];
            let updateRql = r.table('experimenttasks').insert(swapItems, {conflict: 'update'});
            yield dbExec(updateRql);
        }
        yield db.update('experimenttasks', taskID, updateArgs);
        return yield getTask(taskID);
    }

    function* experimentExistsInProject(projectID, experimentID) {
        let rql = r.table('project2experiment').getAll([projectID, experimentID], {index: 'project_experiment'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* experimentTaskExistsInExperiment(experimentID, experimentTaskID) {
        let rql = r.table('experiment2experimenttask')
            .getAll([experimentID, experimentTaskID], {index: 'experiment_experiment_task'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* experimentNoteExistsInExperiment(experimentID, experimentNoteID) {
        let rql = r.table('experiment2experimentnote')
            .getAll([experimentID, experimentNoteID], {index: 'experiment_experiment_note'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* deleteTask(experimentID, taskID) {
        yield r.table('experiment2experimenttask').getAll([experimentID, taskID]).delete();
        let old = yield r.table('experimenttasks').get(taskID).delete({returnChanges: true});
        let oldParentID = old.changes[0].old_val.parent_id;
        let oldIndex = old.changes[0].old_val.index;
        yield updateTasksAboveDeleted(experimentID, oldParentID, oldIndex);
        return {val: old.changes[0].old_val};
    }

    function* updateTasksAboveDeleted(experimentID, parentID, index) {
        let rql = r.table('experiment2experimenttask')
            .getAll(experimentID, {index: 'experiment_id'})
            .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
            .filter({parent_id: parentID})
            .filter(r.row('index').ge(index));

        let matchingTasks = yield dbExec(rql);
        let itemsToChange = matchingTasks.map((t) => { return {id: t.id, index: t.index - 1}; });
        let updateRql = r.table('experimenttasks').insert(itemsToChange, {conflict: 'update'});
        yield dbExec(updateRql);
    }

    function* taskIsUsingProcess(taskID) {
        let rql = r.table('experimenttasks').get(taskID);
        let task = yield dbExec(rql);
        return task.process_id !== '';
    }

    function* getExperimentNote(noteID) {
        let rql = r.table('experimentnotes').get(noteID);
        let note = yield dbExec(rql);
        return {val: note};
    }

    function* createExperimentNote(experimentID, user, noteArgs) {
        let note = new model.ExperimentNote(noteArgs.name, noteArgs.note, user);
        let created = yield db.insert('experimentnotes', note);
        let e2en = new model.Experiment2ExperimentNote(experimentID, created.id);
        yield db.insert('experiment2experimentnote', e2en);
        return {val: created};
    }

    function* updateExperimentNote(noteID, noteArgs) {
        yield r.table('experimentnotes').get(noteID).update(noteArgs);
        return yield getExperimentNote(noteID);
    }

    function* deleteExperimentNote(experimentID, noteID) {
        yield r.table('experiment2experimentnote')
            .getAll([experimentID, noteID], {index: 'experiment_experiment_note'}).delete();
        let old = yield r.table('experimentnotes').get(noteID).delete({returnChanges: true});
        return {val: old.changes[0].old_val};
    }
};
<commit_msg>Add notes when getting a single experiment.<commit_after>module.exports = function(r) {
    const dbExec = require('./run');
    const db = require('./db')(r);
    const model = require('./model')(r);

    return {
        getAllForProject,
        get,
        create,
        update,
        createTask,
        getTask,
        updateTask,
        experimentExistsInProject,
        experimentTaskExistsInExperiment,
        experimentNoteExistsInExperiment,
        deleteTask,
        taskIsUsingProcess,
        getExperimentNote,
        createExperimentNote,
        updateExperimentNote,
        deleteExperimentNote
    };

    function* getAllForProject(projectID) {
        let rql = r.table('project2experiment').getAll(projectID, {index: 'project_id'})
            .eqJoin('experiment_id', r.table('experiments')).zip()
            .merge((experiment) => {
                return {
                    tasks: r.table('experiment2experimenttask')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
                        .filter({parent_id: ''})
                        .orderBy('index')
                        .coerceTo('array'),
                    notes: r.table('experiment2experimentnote')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_note_id', r.table('experimentnotes')).zip()
                        .orderBy('name')
                        .coerceTo('array')
                }
            });
        let experiments = yield dbExec(rql);
        return {val: experiments};
    }

    // Get assumes that validating the experiment for the project has already occured.
    function* get(experimentID) {
        let rql = r.table('experiments').get(experimentID)
            .merge((experiment) => {
                return {
                    tasks: r.table('experiment2experimenttask')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
                        .filter({parent_id: ''})
                        .orderBy('index')
                        .coerceTo('array'),
                    notes: r.table('experiment2experimentnote')
                        .getAll(experiment('id'), {index: 'experiment_id'})
                        .eqJoin('experiment_note_id', r.table('experimentnotes')).zip()
                        .orderBy('name')
                        .coerceTo('array')
                }
            });
        let experiment = yield dbExec(rql);
        experiment.tasks.forEach((task) => task.tasks = []);
        return {val: experiment};
    }

    function* create(experiment, owner) {
        let e = new model.Experiment(experiment.name, owner);
        e.description = experiment.description;
        let newExperiment = yield db.insert('experiments', e);
        let proj2experiment = new model.Project2Experiment(experiment.project_id, newExperiment.id);
        yield db.insert('project2experiment', proj2experiment);
        let etask = new model.ExperimentTask('', owner);
        yield createTask(newExperiment.id, etask, owner);
        return yield get(newExperiment.id);
    }

    function* update(experimentID, updateArgs) {
        yield db.update('experiments', experimentID, updateArgs);
        return yield get(experimentID);
    }

    function* createTask(experimentID, task, owner) {
        let etask = new model.ExperimentTask(task.name, owner);
        etask.description = task.description;
        etask.parent_id = task.parent_id;
        etask.index = task.index;
        yield updateIndexOfAllAffected(experimentID, task.parent_id, task.index);
        let createdTask = yield db.insert('experimenttasks', etask);
        let e2etask = new model.Experiment2ExperimentTask(experimentID, createdTask.id);
        yield db.insert('experiment2experimenttask', e2etask);
        return yield getTask(createdTask.id);
    }

    function* updateIndexOfAllAffected(experimentID, parentID, index) {
        let rql = r.table('experiment2experimenttask')
            .getAll(experimentID, {index: 'experiment_id'})
            .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
            .filter({parent_id: parentID})
            .filter(r.row('index').ge(index));

        let matchingTasks = yield dbExec(rql);
        let itemsToChange = matchingTasks.map((t) => { return {id: t.id, index: t.index + 1}; });
        let updateRql = r.table('experimenttasks').insert(itemsToChange, {conflict: 'update'});
        yield dbExec(updateRql);
    }

    function* getTask(taskID) {
        let rql = r.table('experimenttasks').get(taskID)
            .merge((task) => {
                return {
                    processes: r.table('experimenttask2process').getAll(task('id'), {index: 'experiment_task_id'})
                        .eqJoin('process_id', r.table('processes')).zip().coerceTo('array'),
                    tasks: r.table('experimenttasks').getAll(task('id'), {index: 'parent_id'}).coerceTo('array')
                }
            });
        let t = yield dbExec(rql);

        // merge processes into tasks and then remove the entry
        t.tasks.concat(t.processes);
        delete t.processes;

        return {val: t};
    }

    function* updateTask(taskID, updateArgs) {
        if (updateArgs.swap) {
            let task = yield r.table('experimenttasks').get(taskID);
            let swapTask = yield r.table('experimenttasks').get(updateArgs.swap.task_id);
            if (swapTask.parent_id !== task.parent_id) {
                return {error: 'Tasks have different parents'};
            }
            let swapItems = [
                {
                    id: taskID,
                    index: swapTask.index
                },
                {
                    id: updateArgs.swap.task_id,
                    index: task.index
                }
            ];
            let updateRql = r.table('experimenttasks').insert(swapItems, {conflict: 'update'});
            yield dbExec(updateRql);
        }
        yield db.update('experimenttasks', taskID, updateArgs);
        return yield getTask(taskID);
    }

    function* experimentExistsInProject(projectID, experimentID) {
        let rql = r.table('project2experiment').getAll([projectID, experimentID], {index: 'project_experiment'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* experimentTaskExistsInExperiment(experimentID, experimentTaskID) {
        let rql = r.table('experiment2experimenttask')
            .getAll([experimentID, experimentTaskID], {index: 'experiment_experiment_task'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* experimentNoteExistsInExperiment(experimentID, experimentNoteID) {
        let rql = r.table('experiment2experimentnote')
            .getAll([experimentID, experimentNoteID], {index: 'experiment_experiment_note'});
        let matches = yield dbExec(rql);
        return matches.length !== 0;
    }

    function* deleteTask(experimentID, taskID) {
        yield r.table('experiment2experimenttask').getAll([experimentID, taskID]).delete();
        let old = yield r.table('experimenttasks').get(taskID).delete({returnChanges: true});
        let oldParentID = old.changes[0].old_val.parent_id;
        let oldIndex = old.changes[0].old_val.index;
        yield updateTasksAboveDeleted(experimentID, oldParentID, oldIndex);
        return {val: old.changes[0].old_val};
    }

    function* updateTasksAboveDeleted(experimentID, parentID, index) {
        let rql = r.table('experiment2experimenttask')
            .getAll(experimentID, {index: 'experiment_id'})
            .eqJoin('experiment_task_id', r.table('experimenttasks')).zip()
            .filter({parent_id: parentID})
            .filter(r.row('index').ge(index));

        let matchingTasks = yield dbExec(rql);
        let itemsToChange = matchingTasks.map((t) => { return {id: t.id, index: t.index - 1}; });
        let updateRql = r.table('experimenttasks').insert(itemsToChange, {conflict: 'update'});
        yield dbExec(updateRql);
    }

    function* taskIsUsingProcess(taskID) {
        let rql = r.table('experimenttasks').get(taskID);
        let task = yield dbExec(rql);
        return task.process_id !== '';
    }

    function* getExperimentNote(noteID) {
        let rql = r.table('experimentnotes').get(noteID);
        let note = yield dbExec(rql);
        return {val: note};
    }

    function* createExperimentNote(experimentID, user, noteArgs) {
        let note = new model.ExperimentNote(noteArgs.name, noteArgs.note, user);
        let created = yield db.insert('experimentnotes', note);
        let e2en = new model.Experiment2ExperimentNote(experimentID, created.id);
        yield db.insert('experiment2experimentnote', e2en);
        return {val: created};
    }

    function* updateExperimentNote(noteID, noteArgs) {
        yield r.table('experimentnotes').get(noteID).update(noteArgs);
        return yield getExperimentNote(noteID);
    }

    function* deleteExperimentNote(experimentID, noteID) {
        yield r.table('experiment2experimentnote')
            .getAll([experimentID, noteID], {index: 'experiment_experiment_note'}).delete();
        let old = yield r.table('experimentnotes').get(noteID).delete({returnChanges: true});
        return {val: old.changes[0].old_val};
    }
};
<|endoftext|>


<commit_before>$(function () {

    $('.MVCGridContainer').each(function () {

        var mvcGridName = $("#" + this.id).find("input[name='MVCGridName']").val();

        loadMVCGridData(mvcGridName);
    });

});

function mvcGridSort(mvcGridName, sortColumn, sortDirection) {
    var id = 'MVCGrid_' + mvcGridName + '_SortColumn';
    var idd = 'MVCGrid_' + mvcGridName + '_SortDirection';

    $('#' + id).val(sortColumn);
    $('#' + idd).val(sortDirection);

    loadMVCGridData(mvcGridName);
}

function mvcGridGotoPage(mvcGridName, pageNumber) {

    var pageIndex = pageNumber - 1;

    var id = 'MVCGrid_' + mvcGridName + '_PageIndex';

    $('#' + id).val(pageIndex);

    loadMVCGridData(mvcGridName);
}

function updateQueryString(mvcGridName) {
    var pageIndex = $('#' + 'MVCGrid_' + mvcGridName + '_PageIndex').val();
    var sortCol = $('#' + 'MVCGrid_' + mvcGridName + '_SortColumn').val();
    var sortDir = $('#' + 'MVCGrid_' + mvcGridName + '_SortDirection').val();

    var pageNum = 1;

    if (pageIndex != '') {
        pageNum = pageIndex + 1;
    }

    var qs = "?page=" + pageNum;

    if (sortCol != '') {
        qs += '&sort=' + sortCol;
    }

    if (sortDir != '') {
        qs += '&sortdir=' + sortDir;
    }

    if (history.pushState) {
        var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + qs;
        window.history.pushState({ path: newurl }, '', newurl);
    }
}

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

function loadMVCGridData(mvcGridName) {

    //var pageParam = getParameterByName("page");
    //alert(pageParam);

    var containerHtmlId = 'MVCGridContainer_' + mvcGridName;
    var tableHolderHtmlId = 'MVCGridTableHolder_' + mvcGridName;

    var pageIndex = $('#' + 'MVCGrid_' + mvcGridName + '_PageIndex').val();
    var sortCol = $('#' + 'MVCGrid_' + mvcGridName + '_SortColumn').val();
    var sortDir = $('#' + 'MVCGrid_' + mvcGridName + '_SortDirection').val();

    $.ajax({
        type: "GET",
        url: "/MVCGridHandler.axd",
        data: { 'Name': mvcGridName, 'PageIndex': pageIndex, 'SortColumn': sortCol, 'SortDirection': sortDir },
        cache: false,
        success: function (result) {
            //do somthing here
            //alert(result);

            $('#' + tableHolderHtmlId).html(result);
            updateQueryString(mvcGridName);
        }
    });
}<commit_msg>fixed bug in js<commit_after>$(function () {

    $('.MVCGridContainer').each(function () {

        var mvcGridName = $("#" + this.id).find("input[name='MVCGridName']").val();

        loadMVCGridData(mvcGridName);
    });

});

function mvcGridSort(mvcGridName, sortColumn, sortDirection) {
    var id = 'MVCGrid_' + mvcGridName + '_SortColumn';
    var idd = 'MVCGrid_' + mvcGridName + '_SortDirection';

    $('#' + id).val(sortColumn);
    $('#' + idd).val(sortDirection);

    loadMVCGridData(mvcGridName);
}

function mvcGridGotoPage(mvcGridName, pageNumber) {

    var pageIndex = pageNumber - 1;

    var id = 'MVCGrid_' + mvcGridName + '_PageIndex';

    $('#' + id).val(pageIndex);

    loadMVCGridData(mvcGridName);
}

function updateQueryString(mvcGridName) {
    var pageIndex = $('#' + 'MVCGrid_' + mvcGridName + '_PageIndex').val();
    var sortCol = $('#' + 'MVCGrid_' + mvcGridName + '_SortColumn').val();
    var sortDir = $('#' + 'MVCGrid_' + mvcGridName + '_SortDirection').val();

    var pageNum = 1;

    if (pageIndex != '') {
        pageNum = Number(pageIndex) + 1;
    }

    var qs = "?page=" + pageNum;

    if (sortCol != '') {
        qs += '&sort=' + sortCol;
    }

    if (sortDir != '') {
        qs += '&sortdir=' + sortDir;
    }

    if (history.pushState) {
        var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + qs;
        window.history.pushState({ path: newurl }, '', newurl);
    }
}

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

function loadMVCGridData(mvcGridName) {

    //var pageParam = getParameterByName("page");
    //alert(pageParam);

    var containerHtmlId = 'MVCGridContainer_' + mvcGridName;
    var tableHolderHtmlId = 'MVCGridTableHolder_' + mvcGridName;

    var pageIndex = $('#' + 'MVCGrid_' + mvcGridName + '_PageIndex').val();
    var sortCol = $('#' + 'MVCGrid_' + mvcGridName + '_SortColumn').val();
    var sortDir = $('#' + 'MVCGrid_' + mvcGridName + '_SortDirection').val();

    $.ajax({
        type: "GET",
        url: "/MVCGridHandler.axd",
        data: { 'Name': mvcGridName, 'PageIndex': pageIndex, 'SortColumn': sortCol, 'SortDirection': sortDir },
        cache: false,
        success: function (result) {
            //do somthing here
            //alert(result);

            $('#' + tableHolderHtmlId).html(result);
            updateQueryString(mvcGridName);
        }
    });
}<|endoftext|>


<commit_before>import { registerPlugin } from "@finos/perspective-viewer/dist/esm/utils.js";
import L from "leaflet"
import { feature } from "topojson-client"
import "../../../assets/stylesheets/comp-perspective-viewer-map.css"

// default geoJSON column name
const geomColumn = "geometry"
// default HTML id
const idMap = "map"

function createMapNode(element, div) {
  if (document.getElementById(idMap)) {
    document.getElementById(idMap).remove()
  }
  // Attach the container div to the DOM
  const mapElement = document.createElement("div");
  mapElement.id = idMap
  div.innerHTML = ""
  div.appendChild(document.createElement("slot"))
  element.appendChild(mapElement);

  // Initialize Leaflet
  const map = L.map(idMap);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  // Add Topojson handlers
  L.TopoJSON = L.GeoJSON.extend({
    addData: function (jsonData) {
      if (jsonData.type === 'Topology') {
        for (let key in jsonData.objects) {
          L.GeoJSON.prototype.addData.call(this, feature(jsonData, jsonData.objects[key]));
        }
      } else {
        L.GeoJSON.prototype.addData.call(this, jsonData);
      }
    },
  });
  L.topoJSON = function (data, options) {
    return new L.TopoJSON(data, options);
  };

  return map;
}

function createLegend({ grades = [], getColor = d => d, fmt = d => d.toLocaleString() }) {
  const legend = L.control({ position: 'bottomleft' });

  legend.onAdd = function () {
      const div = L.DomUtil.create('div', 'perspective-map-legend')

      // loop through our density intervals and generate a label with a colored square for each interval
      for (var i = 0; i < grades.length; i++) {
          div.innerHTML +=
              ' ' +
              fmt(grades[i]) + (grades[i + 1] ? '–' + fmt(grades[i + 1]) + '
' : '+');
      }

      return div;
  };

  return legend;
}

function createTooltip() {
  const info = L.control();

  info.onAdd = function () {
      this._div = L.DomUtil.create('div', 'perspective-map-tooltip');
      this.update();
      return this._div;
  };

  // method that we will use to update the control based on feature properties passed
  info.update = function (props = {}) {
      this._div.innerHTML = Object.entries(props).map(([key, value]) => `<div><b>${key}</b>: ${value}</div>`).join("");
  };

  return info;
}

export class MapPlugin {
  // static name = "Map"

  static async create(div, view) {
    try {
      const columns = JSON.parse(this.getAttribute("columns"))

      // Enforces to have a geometry column
      if (!columns.includes(geomColumn)) {
        columns.push(geomColumn)
        this.setAttribute("columns", JSON.stringify(columns))
      }

      const map = createMapNode(this, div);

      // fetch the current displayed data
      const data = await view.to_json() || []
      if (data.some(({ [geomColumn]: geometry }) => !!geometry)) {

        // find first numeric field
        const [numericField] = (Object.entries(data[0]) || []).find(([, value]) => Number.isFinite(value))
        const mappedData = data.map(d => d[numericField])
        const isInteger = mappedData.every(x => Number.isInteger(x))

        // get range array
        const [min, max] = [Math.min(...mappedData), Math.max(...mappedData)]
        // max. categories
        const maxCategories = 5
        // substract one to maxCategories in order to keep the max. value INSIDE the range
        const step = (max - min) / (maxCategories - 1)
        const grades = Array.from({ length: maxCategories - 1 }, (_, i) => isInteger ? Math.floor(min + (i * step)) : min + (i * step))
        grades.push(max)

        const getColor = (value) => {
          // if don't substract 1, you'll never get the first index
          const ix = grades.findIndex(x => value <= x)
          // categories begins as of 1
          return ix >= 0 ? `var(--perspective-map-category-${ix + 1})` : ''
        }

        const style = ({ properties = {} }) => ({
          fillColor: getColor(properties[numericField]),
          fillOpacity: 1,
          color: getColor(properties[numericField]),
          opacity: 1,
        })

        // creates features ONLY if they're plane strings
        const features =
          data
            .map(({ [geomColumn]: geometry = "{}", ...properties }) => {
              // parse all the geoms as topojson, even they're not
              const { features: [ feature ] } = L.topoJSON(JSON.parse(geometry)).toGeoJSON()
              return { ...feature, properties };
            })
            .filter(Boolean) || [];

        if (features.length) {
          createLegend({ grades, getColor }).addTo(map)

          const tooltip = createTooltip({ grades, getColor })
          tooltip.addTo(map)

          const onEachFeature = (feature, layer) => {
            layer.on({
              mouseover: () => tooltip.update(feature.properties),
              mouseout: () => tooltip.update()
            });
          };

          const geojson = L.geoJSON(features, { style, onEachFeature }).addTo(map);
          map.fitBounds(geojson.getBounds());
        } else {
          // if there's nothing to display, you must set the default view
          // TODO: parametrize
          map.setView([40.3, -3.7], 13)
        }

      }
    } catch (e) {
      if (e.message !== "View is not initialized") {
        throw e;
      }
    }
  }

  static update() {}

  static resize() {}

  static delete() {}

  static save() {}

  static restore() {}
}

registerPlugin("map", MapPlugin);
<commit_msg>set the name of the plugin with defineProperty<commit_after>import { registerPlugin } from "@finos/perspective-viewer/dist/esm/utils.js";
import L from "leaflet"
import { feature } from "topojson-client"
import "../../../assets/stylesheets/comp-perspective-viewer-map.css"

// default geoJSON column name
const geomColumn = "geometry"
// default HTML id
const idMap = "map"

function createMapNode(element, div) {
  if (document.getElementById(idMap)) {
    document.getElementById(idMap).remove()
  }
  // Attach the container div to the DOM
  const mapElement = document.createElement("div");
  mapElement.id = idMap
  div.innerHTML = ""
  div.appendChild(document.createElement("slot"))
  element.appendChild(mapElement);

  // Initialize Leaflet
  const map = L.map(idMap);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  // Add Topojson handlers
  L.TopoJSON = L.GeoJSON.extend({
    addData: function (jsonData) {
      if (jsonData.type === 'Topology') {
        for (let key in jsonData.objects) {
          L.GeoJSON.prototype.addData.call(this, feature(jsonData, jsonData.objects[key]));
        }
      } else {
        L.GeoJSON.prototype.addData.call(this, jsonData);
      }
    },
  });
  L.topoJSON = function (data, options) {
    return new L.TopoJSON(data, options);
  };

  return map;
}

function createLegend({ grades = [], getColor = d => d, fmt = d => d.toLocaleString() }) {
  const legend = L.control({ position: 'bottomleft' });

  legend.onAdd = function () {
      const div = L.DomUtil.create('div', 'perspective-map-legend')

      // loop through our density intervals and generate a label with a colored square for each interval
      for (var i = 0; i < grades.length; i++) {
          div.innerHTML +=
              ' ' +
              fmt(grades[i]) + (grades[i + 1] ? '–' + fmt(grades[i + 1]) + '
' : '+');
      }

      return div;
  };

  return legend;
}

function createTooltip() {
  const info = L.control();

  info.onAdd = function () {
      this._div = L.DomUtil.create('div', 'perspective-map-tooltip');
      this.update();
      return this._div;
  };

  // method that we will use to update the control based on feature properties passed
  info.update = function (props = {}) {
      this._div.innerHTML = Object.entries(props).map(([key, value]) => `<div><b>${key}</b>: ${value}</div>`).join("");
  };

  return info;
}

export class MapPlugin {
  // static name = "Map"

  static async create(div, view) {
    try {
      const columns = JSON.parse(this.getAttribute("columns"))

      // Enforces to have a geometry column
      if (!columns.includes(geomColumn)) {
        columns.push(geomColumn)
        this.setAttribute("columns", JSON.stringify(columns))
      }

      const map = createMapNode(this, div);

      // fetch the current displayed data
      const data = await view.to_json() || []
      if (data.some(({ [geomColumn]: geometry }) => !!geometry)) {

        // find first numeric field
        const [numericField] = (Object.entries(data[0]) || []).find(([, value]) => Number.isFinite(value))
        const mappedData = data.map(d => d[numericField])
        const isInteger = mappedData.every(x => Number.isInteger(x))

        // get range array
        const [min, max] = [Math.min(...mappedData), Math.max(...mappedData)]
        // max. categories
        const maxCategories = 5
        // substract one to maxCategories in order to keep the max. value INSIDE the range
        const step = (max - min) / (maxCategories - 1)
        const grades = Array.from({ length: maxCategories - 1 }, (_, i) => isInteger ? Math.floor(min + (i * step)) : min + (i * step))
        grades.push(max)

        const getColor = (value) => {
          // if don't substract 1, you'll never get the first index
          const ix = grades.findIndex(x => value <= x)
          // categories begins as of 1
          return ix >= 0 ? `var(--perspective-map-category-${ix + 1})` : ''
        }

        const style = ({ properties = {} }) => ({
          fillColor: getColor(properties[numericField]),
          fillOpacity: 1,
          color: getColor(properties[numericField]),
          opacity: 1,
        })

        // creates features ONLY if they're plane strings
        const features =
          data
            .map(({ [geomColumn]: geometry = "{}", ...properties }) => {
              // parse all the geoms as topojson, even they're not
              const { features: [ feature ] } = L.topoJSON(JSON.parse(geometry)).toGeoJSON()
              return { ...feature, properties };
            })
            .filter(Boolean) || [];

        if (features.length) {
          createLegend({ grades, getColor }).addTo(map)

          const tooltip = createTooltip({ grades, getColor })
          tooltip.addTo(map)

          const onEachFeature = (feature, layer) => {
            layer.on({
              mouseover: () => tooltip.update(feature.properties),
              mouseout: () => tooltip.update()
            });
          };

          const geojson = L.geoJSON(features, { style, onEachFeature }).addTo(map);
          map.fitBounds(geojson.getBounds());
        } else {
          // if there's nothing to display, you must set the default view
          // TODO: parametrize
          map.setView([40.3, -3.7], 13)
        }

      }
    } catch (e) {
      if (e.message !== "View is not initialized") {
        throw e;
      }
    }
  }

  static update() {}

  static resize() {}

  static delete() {}

  static save() {}

  static restore() {}
}

Object.defineProperty(MapPlugin, 'name', {
  writable: true,
  value: 'Map'
});

registerPlugin("map", MapPlugin);
<|endoftext|>


<commit_before>import Vue from 'vue'
import App from './App.vue'
import Storage from 'vue-ls'
import router from './router'
import store from './store/'

import { VueAxios } from "@/utils/request"

import Antd from 'ant-design-vue'
import Viser from 'viser-vue'
import 'ant-design-vue/dist/antd.less';  // or 'ant-design-vue/dist/antd.less'

import '@/permission' // permission control
import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/
import VueApexCharts from 'vue-apexcharts'

import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
// import "@jeecg/antd-online-214"
// import '@jeecg/antd-online-214/dist/OnlineForm.css'
if (process.env.NODE_ENV !== 'production') {
  require('@jeecg/antd-online-214')
  require('@jeecg/antd-online-214/dist/OnlineForm.css')
}

import {
  ACCESS_TOKEN,
  DEFAULT_COLOR,
  DEFAULT_THEME,
  DEFAULT_LAYOUT_MODE,
  DEFAULT_COLOR_WEAK,
  SIDEBAR_TYPE,
  DEFAULT_FIXED_HEADER,
  DEFAULT_FIXED_HEADER_HIDDEN,
  DEFAULT_FIXED_SIDEMENU,
  DEFAULT_CONTENT_WIDTH_TYPE,
  DEFAULT_MULTI_PAGE
} from "@/store/mutation-types"
import config from '@/defaultSettings'

import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index'

Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
Vue.use(Antd)
Vue.use(VueAxios, router)
Vue.use(Viser)
Vue.use(hasPermission)
Vue.use(JDictSelectTag)
Vue.use(Print)
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
Vue.use(preview)
Vue.use(vueBus);
Vue.use(JeecgComponents);

new Vue({
  router,
  store,
  mounted () {
    store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
    store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
    store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
    store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
    store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
    store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
    store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
    store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
    store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
    store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
    store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
  },
  render: h => h(App)
}).$mount('#app')
<commit_msg>build后online表单无法添加/编辑问题处理<commit_after>import Vue from 'vue'
import App from './App.vue'
import Storage from 'vue-ls'
import router from './router'
import store from './store/'

import { VueAxios } from "@/utils/request"

import Antd from 'ant-design-vue'
import Viser from 'viser-vue'
import 'ant-design-vue/dist/antd.less';  // or 'ant-design-vue/dist/antd.less'

import '@/permission' // permission control
import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/
import VueApexCharts from 'vue-apexcharts'

import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'

require('@jeecg/antd-online-214')
require('@jeecg/antd-online-214/dist/OnlineForm.css')

import {
  ACCESS_TOKEN,
  DEFAULT_COLOR,
  DEFAULT_THEME,
  DEFAULT_LAYOUT_MODE,
  DEFAULT_COLOR_WEAK,
  SIDEBAR_TYPE,
  DEFAULT_FIXED_HEADER,
  DEFAULT_FIXED_HEADER_HIDDEN,
  DEFAULT_FIXED_SIDEMENU,
  DEFAULT_CONTENT_WIDTH_TYPE,
  DEFAULT_MULTI_PAGE
} from "@/store/mutation-types"
import config from '@/defaultSettings'

import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index'

Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
Vue.use(Antd)
Vue.use(VueAxios, router)
Vue.use(Viser)
Vue.use(hasPermission)
Vue.use(JDictSelectTag)
Vue.use(Print)
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
Vue.use(preview)
Vue.use(vueBus);
Vue.use(JeecgComponents);

new Vue({
  router,
  store,
  mounted () {
    store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
    store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
    store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
    store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
    store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
    store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
    store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
    store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
    store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
    store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
    store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
  },
  render: h => h(App)
}).$mount('#app')
<|endoftext|>