<commit_before>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
({
	createComponentForIndex : function(cmp, itemsval, index, afterCreationCallback) {
		var helper = this;

		function createCallback(collector, index) {
			return function(newComponent) {
				collector.components[index] = newComponent;

				//$A.renderingService.requestRerender(newComponent);

				if (--collector.expectedCount === 0) {
					helper.trackItem(collector.cmp, collector.itemval, collector.targetIndex, collector.components);

					var realbody = helper.createFacetFromTrackingInfo(collector.cmp);

					collector.cmp.set("v.realbody", realbody);

					if (afterCreationCallback) {
						afterCreationCallback();
					}

					// DCHASMAN TODO Figure out the best way to deal with the coupling between ArrayValue.commit() and rerendering -> auto Component.destroy()
					//$A.renderingService.removeDirtyValue(collector.cmp.getValue("v.realbody"));
				}
			};
		}

		var itemval = itemsval.getValue(index);

		// Clone the body for this row
		var body = cmp.get("v.body");

		var forceServer = cmp.get("v.forceServer");
		var collector = {
			targetIndex: index,
			itemval : itemval,
			components : [],
			cmp : cmp,
			expectedCount : body.length
		};

		this.createComponents(cmp, itemsval, index, function(cdr, ivp, n) {
			$A.componentService.newComponentAsync(helper, createCallback(collector, n), cdr, ivp, false, false, forceServer);
		});
	},

	createRealBodyServer : function(cmp) {
		var helper = this;

		function createComponentsForIndexFromServer(cmp, itemsval, index) {
			var ret = [];

			$A.setCreationPathIndex(index);
			$A.pushCreationPath("body");

			helper.createComponents(cmp, itemsval, index, function(cdr, ivp, n) {
				ret.push($A.componentService.newComponentDeprecated(cdr, ivp, false, true));
			});

			$A.popCreationPath("body");

			return ret;
		}

		// Although this is becoming an anti-pattern, we actually DO want
		// getValue() here.  With it, we end up sharing model objects (under
		// a PassthroughValue for sub-component ownership).  Without it,
		// ValueFactory makes us a NEW object for child components, and we
		// don't share a data model.
		var itemsval = cmp.getValue("v.items");

		if (itemsval && itemsval.getLength() > 0) {
			$A.pushCreationPath("realbody");

			this.resetItemTracking(cmp);

			var startIndex = this.getStart(cmp);
			var endIndex = this.getEnd(cmp);

			for (var i = startIndex; i < endIndex; i++) {
				var components = createComponentsForIndexFromServer(cmp, itemsval, i);

				this.trackItem(cmp, itemsval.getValue(i), i, components);
			}

			$A.popCreationPath("realbody");
		}

		return this.getUpdatedRealBody(cmp);
	},

	resetItemTracking : function(cmp) {
		cmp._itemInfos = [];
	},

	getItemTracking : function(cmp) {
		if (!cmp._itemInfos) {
			this.resetItemTracking(cmp);
		}

		return cmp._itemInfos;
	},

	trackItem : function(cmp, itemval, index, components) {
		// Track the components associated with this item for future v.items delta calculations
		cmp._itemInfos[index] = {
			index : index,
			itemval : itemval,
			components : components
		};
	},

	getTransformation : function(cmp, itemsval, indexVar, varName, start, end) {
		function PickOperation(itemval, sourceIndex, targetIndex, components, indexVar, varName) {
			this.itemval = itemval;
			this.sourceIndex = sourceIndex;
			this.targetIndex = targetIndex;
			this.components = components;
			this.indexVar = indexVar;
			this.varName = varName;
		}

		var helper = this;

		PickOperation.prototype.run = function(cmp) {
			var moved = this.sourceIndex !== this.targetIndex;

			helper.trackItem(cmp, this.itemval, this.targetIndex, this.components);

			for (var n = 0; n < this.components.length; n++) {
				var component = this.components[n];

				if (moved) {
					// Update the index to match the new position in the facet
					var vp = component.getAttributeValueProvider();
					if (vp) {
						vp.set(indexVar, this.targetIndex);
					}

					$A.renderingService.requestRerender(component);
				}
			}
		}

		PickOperation.prototype.toString = function() {
			return "pick(" + this.sourceIndex + ") to " + this.targetIndex;
		}

		function CreateOperation(index, itemval, cmp) {
			this.index = index;
			this.itemval = itemval;

			if (cmp._pendingCreates) {
				cmp._pendingCreates.push(this);
			} else {
				cmp._pendingCreates = [this];
			}
		}

		CreateOperation.prototype.run = function(cmp) {
			if (this.running) {
				// Create is mid flight just return and wait for the operation to complete
				return;
			}

			this.running = true;

			var that = this;
			// Although this is becoming an anti-pattern, we actually DO want
			// getValue() here.  With it, we end up sharing model objects (under
			// a PassthroughValue for sub-component ownership).  Without it,
			// ValueFactory makes us a NEW object for child components, and we
			// don't share a data model.
			var itemsval = cmp.getValue("v.items");
			helper.createComponentForIndex(cmp, itemsval, this.index, function() {
				// Remove this create op from the set of pending creates
				var i = $A.util.arrayIndexOf(cmp._pendingCreates, that);
				if (i >= 0) {
					cmp._pendingCreates.splice(i, 1);
				}

				this.running = false;
			});
		}

		CreateOperation.prototype.toString = function() {
			return "create(" + this.index + ")";
		}

		var itemInfos = this.getItemTracking(cmp).slice();
		var pendingCreates = cmp._pendingCreates ? cmp._pendingCreates.slice() : undefined;
		var operations = [];

		for (var i = start; i < end; i++) {
			var itemval = itemsval.getValue(i);

			// Find existing itemInfo for this item
			var found = false;
			for (var j = 0; j < itemInfos.length; j++) {
				var info = itemInfos[j];
				if (info && itemval === info.itemval) {
					operations.push(new PickOperation(itemval, j, i, info.components, indexVar, varName));

					// Consume the item
					itemInfos[j] = undefined;
					found = true;
					break;
				}
			}

			// Check to see if we already have a pending create and update its target index
			if (!found && pendingCreates) {
				for (var n = 0; n < pendingCreates.length; n++) {
					var op = pendingCreates[n];
					if (itemval === op.itemval) {
						op.index = i;

						operations.push(op);

						// Consume the item
						pendingCreates.splice(n, 1);
						found = true;
					}
				}
			}

			if (!found) {
				// Add a create to the list operations to be satisfied
				operations.push(new CreateOperation(i, itemval, cmp));
			}
		}

		return operations;
	},

	updateRealBody : function(cmp) {
		var realbody = this.getUpdatedRealBody(cmp);

		cmp.set("v.realbody", realbody);

		// DCHASMAN TODO Rename this horrible misnomer that has nothing to do with rendering and everything to do with updating the contents of the iteration!!!
		cmp.getEvent("rerenderComplete").fire();

		// DCHASMAN TODO Figure out the best way to deal with the coupling between ArrayValue.commit() and rerendering -> auto Component.destroy()
		//$A.renderingService.removeDirtyValue(cmp.getValue("v.realbody"));
	},

	getUpdatedRealBody : function(cmp) {
        // Although this is becoming an anti-pattern, we actually DO want
        // getValue() here.  With it, we end up sharing model objects (under
        // a PassthroughValue for sub-component ownership).  Without it,
        // ValueFactory makes us a NEW object for child components, and we
        // don't share a data model.
        var itemsval = cmp.getValue("v.items");
        var varName = cmp.get("v.var");
		var indexVar = cmp.get("v.indexVar");

		var operations = this.getTransformation(cmp, itemsval, indexVar, varName, this.getStart(cmp), this.getEnd(cmp));

		this.resetItemTracking(cmp);
		for (var n = 0; n < operations.length; n++) {
			operations[n].run(cmp);
		}

		return this.createFacetFromTrackingInfo(cmp);
	},

	createFacetFromTrackingInfo : function(cmp) {
		var realbody = [];
		var trackingInfo = this.getItemTracking(cmp);
		for (var n = 0; n < trackingInfo.length; n++) {
			var info = trackingInfo[n];
			if (info) {
				realbody = realbody.concat(info.components);
			}
		}

		return realbody;
	},

	getStart : function(cmp) {
		var start = cmp.get("v.start");
		return !$A.util.isEmpty(start) ? Math.max(0, this.getNumber(start)) : 0;
	},

	getEnd : function(cmp) {
	    // Although this is becoming an anti-pattern, we actually DO want
        // getValue() here.  With it, we end up sharing model objects (under
        // a PassthroughValue for sub-component ownership).  Without it,
        // ValueFactory makes us a NEW object for child components, and we
        // don't share a data model.
        var itemsval = cmp.getValue("v.items");
		var length = itemsval ? itemsval.getLength() : 0;
		var end = cmp.get("v.end");

		return !$A.util.isEmpty(end) ? Math.min(length, this.getNumber(end)) : length;
	},

	createComponents : function(cmp, itemsval, index, behavior) {
		function createExtraProviders(cmp, itemval, index) {
			var varName = cmp.get("v.var");
			var indexVar = cmp.get("v.indexVar");
			var extraProviders = {};

			extraProviders[varName] = $A.expressionService.create(cmp, itemval);
			if (indexVar) {
				extraProviders[indexVar] = $A.expressionService.create(cmp, index);
			}

			return extraProviders;
		}

		var ivp;
		var body = cmp.get("v.body");
		for (var n = 0; n < body.length; n++) {
			var cdr = body[n];
			if (!ivp) {
				var extraProviders = createExtraProviders(cmp, itemsval.getValue(index), index);
				ivp = $A.expressionService.createPassthroughValue(extraProviders, cdr.valueProvider || cmp.getAttributeValueProvider());
			}

			$A.setCreationPathIndex(n);

			behavior(cdr, ivp, n);
		}
	},

	// temp workaround when strings get passed in until typedef takes care of this for us
	getNumber : function(value) {
		return aura.util.isString(value) ? parseInt(value, 10) : value;
	}
})
<commit_msg>For empty/null lists, we might get a null SimpleValue not an ArrayValue with getLength.  Handle that.<commit_after>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
({
	createComponentForIndex : function(cmp, itemsval, index, afterCreationCallback) {
		var helper = this;

		function createCallback(collector, index) {
			return function(newComponent) {
				collector.components[index] = newComponent;

				//$A.renderingService.requestRerender(newComponent);

				if (--collector.expectedCount === 0) {
					helper.trackItem(collector.cmp, collector.itemval, collector.targetIndex, collector.components);

					var realbody = helper.createFacetFromTrackingInfo(collector.cmp);

					collector.cmp.set("v.realbody", realbody);

					if (afterCreationCallback) {
						afterCreationCallback();
					}

					// DCHASMAN TODO Figure out the best way to deal with the coupling between ArrayValue.commit() and rerendering -> auto Component.destroy()
					//$A.renderingService.removeDirtyValue(collector.cmp.getValue("v.realbody"));
				}
			};
		}

		var itemval = itemsval.getValue(index);

		// Clone the body for this row
		var body = cmp.get("v.body");

		var forceServer = cmp.get("v.forceServer");
		var collector = {
			targetIndex: index,
			itemval : itemval,
			components : [],
			cmp : cmp,
			expectedCount : body.length
		};

		this.createComponents(cmp, itemsval, index, function(cdr, ivp, n) {
			$A.componentService.newComponentAsync(helper, createCallback(collector, n), cdr, ivp, false, false, forceServer);
		});
	},

	createRealBodyServer : function(cmp) {
		var helper = this;

		function createComponentsForIndexFromServer(cmp, itemsval, index) {
			var ret = [];

			$A.setCreationPathIndex(index);
			$A.pushCreationPath("body");

			helper.createComponents(cmp, itemsval, index, function(cdr, ivp, n) {
				ret.push($A.componentService.newComponentDeprecated(cdr, ivp, false, true));
			});

			$A.popCreationPath("body");

			return ret;
		}

		// Although this is becoming an anti-pattern, we actually DO want
		// getValue() here.  With it, we end up sharing model objects (under
		// a PassthroughValue for sub-component ownership).  Without it,
		// ValueFactory makes us a NEW object for child components, and we
		// don't share a data model.
		var itemsval = cmp.getValue("v.items");

		if (itemsval && itemsval.getLength && itemsval.getLength() > 0) {
			$A.pushCreationPath("realbody");

			this.resetItemTracking(cmp);

			var startIndex = this.getStart(cmp);
			var endIndex = this.getEnd(cmp);

			for (var i = startIndex; i < endIndex; i++) {
				var components = createComponentsForIndexFromServer(cmp, itemsval, i);

				this.trackItem(cmp, itemsval.getValue(i), i, components);
			}

			$A.popCreationPath("realbody");
		}

		return this.getUpdatedRealBody(cmp);
	},

	resetItemTracking : function(cmp) {
		cmp._itemInfos = [];
	},

	getItemTracking : function(cmp) {
		if (!cmp._itemInfos) {
			this.resetItemTracking(cmp);
		}

		return cmp._itemInfos;
	},

	trackItem : function(cmp, itemval, index, components) {
		// Track the components associated with this item for future v.items delta calculations
		cmp._itemInfos[index] = {
			index : index,
			itemval : itemval,
			components : components
		};
	},

	getTransformation : function(cmp, itemsval, indexVar, varName, start, end) {
		function PickOperation(itemval, sourceIndex, targetIndex, components, indexVar, varName) {
			this.itemval = itemval;
			this.sourceIndex = sourceIndex;
			this.targetIndex = targetIndex;
			this.components = components;
			this.indexVar = indexVar;
			this.varName = varName;
		}

		var helper = this;

		PickOperation.prototype.run = function(cmp) {
			var moved = this.sourceIndex !== this.targetIndex;

			helper.trackItem(cmp, this.itemval, this.targetIndex, this.components);

			for (var n = 0; n < this.components.length; n++) {
				var component = this.components[n];

				if (moved) {
					// Update the index to match the new position in the facet
					var vp = component.getAttributeValueProvider();
					if (vp) {
						vp.set(indexVar, this.targetIndex);
					}

					$A.renderingService.requestRerender(component);
				}
			}
		}

		PickOperation.prototype.toString = function() {
			return "pick(" + this.sourceIndex + ") to " + this.targetIndex;
		}

		function CreateOperation(index, itemval, cmp) {
			this.index = index;
			this.itemval = itemval;

			if (cmp._pendingCreates) {
				cmp._pendingCreates.push(this);
			} else {
				cmp._pendingCreates = [this];
			}
		}

		CreateOperation.prototype.run = function(cmp) {
			if (this.running) {
				// Create is mid flight just return and wait for the operation to complete
				return;
			}

			this.running = true;

			var that = this;
			// Although this is becoming an anti-pattern, we actually DO want
			// getValue() here.  With it, we end up sharing model objects (under
			// a PassthroughValue for sub-component ownership).  Without it,
			// ValueFactory makes us a NEW object for child components, and we
			// don't share a data model.
			var itemsval = cmp.getValue("v.items");
			helper.createComponentForIndex(cmp, itemsval, this.index, function() {
				// Remove this create op from the set of pending creates
				var i = $A.util.arrayIndexOf(cmp._pendingCreates, that);
				if (i >= 0) {
					cmp._pendingCreates.splice(i, 1);
				}

				this.running = false;
			});
		}

		CreateOperation.prototype.toString = function() {
			return "create(" + this.index + ")";
		}

		var itemInfos = this.getItemTracking(cmp).slice();
		var pendingCreates = cmp._pendingCreates ? cmp._pendingCreates.slice() : undefined;
		var operations = [];

		for (var i = start; i < end; i++) {
			var itemval = itemsval.getValue(i);

			// Find existing itemInfo for this item
			var found = false;
			for (var j = 0; j < itemInfos.length; j++) {
				var info = itemInfos[j];
				if (info && itemval === info.itemval) {
					operations.push(new PickOperation(itemval, j, i, info.components, indexVar, varName));

					// Consume the item
					itemInfos[j] = undefined;
					found = true;
					break;
				}
			}

			// Check to see if we already have a pending create and update its target index
			if (!found && pendingCreates) {
				for (var n = 0; n < pendingCreates.length; n++) {
					var op = pendingCreates[n];
					if (itemval === op.itemval) {
						op.index = i;

						operations.push(op);

						// Consume the item
						pendingCreates.splice(n, 1);
						found = true;
					}
				}
			}

			if (!found) {
				// Add a create to the list operations to be satisfied
				operations.push(new CreateOperation(i, itemval, cmp));
			}
		}

		return operations;
	},

	updateRealBody : function(cmp) {
		var realbody = this.getUpdatedRealBody(cmp);

		cmp.set("v.realbody", realbody);

		// DCHASMAN TODO Rename this horrible misnomer that has nothing to do with rendering and everything to do with updating the contents of the iteration!!!
		cmp.getEvent("rerenderComplete").fire();

		// DCHASMAN TODO Figure out the best way to deal with the coupling between ArrayValue.commit() and rerendering -> auto Component.destroy()
		//$A.renderingService.removeDirtyValue(cmp.getValue("v.realbody"));
	},

	getUpdatedRealBody : function(cmp) {
        // Although this is becoming an anti-pattern, we actually DO want
        // getValue() here.  With it, we end up sharing model objects (under
        // a PassthroughValue for sub-component ownership).  Without it,
        // ValueFactory makes us a NEW object for child components, and we
        // don't share a data model.
        var itemsval = cmp.getValue("v.items");
        var varName = cmp.get("v.var");
		var indexVar = cmp.get("v.indexVar");

		var operations = this.getTransformation(cmp, itemsval, indexVar, varName, this.getStart(cmp), this.getEnd(cmp));

		this.resetItemTracking(cmp);
		for (var n = 0; n < operations.length; n++) {
			operations[n].run(cmp);
		}

		return this.createFacetFromTrackingInfo(cmp);
	},

	createFacetFromTrackingInfo : function(cmp) {
		var realbody = [];
		var trackingInfo = this.getItemTracking(cmp);
		for (var n = 0; n < trackingInfo.length; n++) {
			var info = trackingInfo[n];
			if (info) {
				realbody = realbody.concat(info.components);
			}
		}

		return realbody;
	},

	getStart : function(cmp) {
		var start = cmp.get("v.start");
		return !$A.util.isEmpty(start) ? Math.max(0, this.getNumber(start)) : 0;
	},

	getEnd : function(cmp) {
	    // Although this is becoming an anti-pattern, we actually DO want
        // getValue() here.  With it, we end up sharing model objects (under
        // a PassthroughValue for sub-component ownership).  Without it,
        // ValueFactory makes us a NEW object for child components, and we
        // don't share a data model.
        var itemsval = cmp.getValue("v.items");
		var length = itemsval && itemsval.getLength ? itemsval.getLength() : 0;
		var end = cmp.get("v.end");

		return !$A.util.isEmpty(end) ? Math.min(length, this.getNumber(end)) : length;
	},

	createComponents : function(cmp, itemsval, index, behavior) {
		function createExtraProviders(cmp, itemval, index) {
			var varName = cmp.get("v.var");
			var indexVar = cmp.get("v.indexVar");
			var extraProviders = {};

			extraProviders[varName] = $A.expressionService.create(cmp, itemval);
			if (indexVar) {
				extraProviders[indexVar] = $A.expressionService.create(cmp, index);
			}

			return extraProviders;
		}

		var ivp;
		var body = cmp.get("v.body");
		for (var n = 0; n < body.length; n++) {
			var cdr = body[n];
			if (!ivp) {
				var extraProviders = createExtraProviders(cmp, itemsval.getValue(index), index);
				ivp = $A.expressionService.createPassthroughValue(extraProviders, cdr.valueProvider || cmp.getAttributeValueProvider());
			}

			$A.setCreationPathIndex(n);

			behavior(cdr, ivp, n);
		}
	},

	// temp workaround when strings get passed in until typedef takes care of this for us
	getNumber : function(value) {
		return aura.util.isString(value) ? parseInt(value, 10) : value;
	}
})
<|endoftext|>


<commit_before>var View = require('./view');
var template = require('./templates/topbar');
var SignInModal = require("./templates/sign_in_modal");
var SignInView = require("./sign_in");
var SessionsView = require("./sessions_view");
var HangoutLink = require("./templates/hangout_link");

module.exports = View.extend({
    id:'top-bar',
    template:template,
    _autocompleteSources:[],
    sessionsView: new SessionsView(),

    events:{
        "click .signin": function() {
            this.$signInModal.modal("toggle");
            return false;
        },
        "click .data-menu-link": function() {
            $('.data-menu').toggle(1000);
        }
    },

    initialize:function (options) {
        _.extend(this, options);
        _.bindAll(this, 'initSearchAutocomplete', 'addAutocompleteSource', 'initHangoutLink');
    },

    initHangoutLink: function() {
        var hangoutId = qed.Display.get("hangoutId");
        if (hangoutId) {
            this.$el.find(".hangout-container").html(HangoutLink({ "hangoutId": hangoutId }));
        }
    },

    afterRender:function () {
        this.initSearchAutocomplete();
        this.initSignIn();

        this.$el.find(".sessions-container").html(this.sessionsView.render().el);
    },

    initSearchAutocomplete:function () {
        var queryEl = this.$el.find("#querySearchTerm");
        var resultsModal = this.$el.find("#searchResults");
        resultsModal.modal({ backdrop:false, show:false });

        var modalBody = resultsModal.find(".modal-body");
        var me = this;

        queryEl.typeahead({
            source:function (query) {
                modalBody.empty();

                _.each(me._autocompleteSources, function (src) {
                    if (src.autocomplete) {
                        var resultBin = function (results) {
                            if (results && results.length) {
                                resultsModal.modal('show');

                                var html = [];
                                html.push("
");
                                if (src.label) html.push("
" + src.label + "
");
                                _.each(_.uniq(results), function (result) {
                                    html.push("
" + result + "
");
                                });
                                html.push("
");
                                modalBody.append(html.join(""));

                                modalBody.find("li").find("a").click(function () {
                                    resultsModal.modal("hide");
                                });
                            }
                        };

                        src.autocomplete(query, resultBin);
                    }
                });
            }
        });
    },

    addAutocompleteSource:function (newSource) {
        this._autocompleteSources.push(newSource);
    },

    initSignIn:function () {
        this.$signInModal = $("body").append(SignInModal()).find(".signin-container");

        var _this = this;
        var addAuthProviders = function(json) {
            _.each(json.providers, function (provider) {
                var sign_in_view = new SignInView({ "provider":provider });
                _this.$signInModal.find(".modal-body").append(sign_in_view.render().el);
                _this.$signInModal.find(".signout-all").click(function() {
                    sign_in_view.signout();
                });
                if (provider.id == "google") {
                    if (provider.active) _this.$el.find(".requires-google-oauth").show();
                    sign_in_view.on("signout", function() {
                        _this.$el.find(".requires-google-oauth").hide();
                    });
                }
            });
        };

        // prepare sign in process in case of 403 (Forbidden)
        var signInProcessStart = _.once(function() {
            $.ajax({
                url: "svc/auth/providers",
                type: "GET",
                dataType: "json",
                success: function(json) {
                    addAuthProviders(json);
                    _this.$signInModal.modal("show");
                    _this.$signInModal.find(".signout-all").click();
                }
            });
        });

        this.$el.ajaxError(function(event, request) {
            if (request.status == 403) signInProcessStart();
        });

        $.ajax({ url:"svc/auth/whoami", method:"GET", context:this, success:addAuthProviders });
    }
});
<commit_msg>initialize hangout link<commit_after>var View = require('./view');
var template = require('./templates/topbar');
var SignInModal = require("./templates/sign_in_modal");
var SignInView = require("./sign_in");
var SessionsView = require("./sessions_view");
var HangoutLink = require("./templates/hangout_link");

module.exports = View.extend({
    id:'top-bar',
    template:template,
    _autocompleteSources:[],
    sessionsView: new SessionsView(),

    events:{
        "click .signin": function() {
            this.$signInModal.modal("toggle");
            return false;
        },
        "click .data-menu-link": function() {
            $('.data-menu').toggle(1000);
        }
    },

    initialize:function (options) {
        _.extend(this, options);
        _.bindAll(this, 'initSearchAutocomplete', 'addAutocompleteSource', 'initHangoutLink');
        _.defer(this.initHangoutLink);
    },

    initHangoutLink: function() {
        var hangoutId = qed.Display.get("hangoutId");
        if (hangoutId) {
            this.$el.find(".hangout-container").html(HangoutLink({ "hangoutId": hangoutId }));
        }
    },

    afterRender:function () {
        this.initSearchAutocomplete();
        this.initSignIn();

        this.$el.find(".sessions-container").html(this.sessionsView.render().el);
    },

    initSearchAutocomplete:function () {
        var queryEl = this.$el.find("#querySearchTerm");
        var resultsModal = this.$el.find("#searchResults");
        resultsModal.modal({ backdrop:false, show:false });

        var modalBody = resultsModal.find(".modal-body");
        var me = this;

        queryEl.typeahead({
            source:function (query) {
                modalBody.empty();

                _.each(me._autocompleteSources, function (src) {
                    if (src.autocomplete) {
                        var resultBin = function (results) {
                            if (results && results.length) {
                                resultsModal.modal('show');

                                var html = [];
                                html.push("
");
                                if (src.label) html.push("
" + src.label + "
");
                                _.each(_.uniq(results), function (result) {
                                    html.push("
" + result + "
");
                                });
                                html.push("
");
                                modalBody.append(html.join(""));

                                modalBody.find("li").find("a").click(function () {
                                    resultsModal.modal("hide");
                                });
                            }
                        };

                        src.autocomplete(query, resultBin);
                    }
                });
            }
        });
    },

    addAutocompleteSource:function (newSource) {
        this._autocompleteSources.push(newSource);
    },

    initSignIn:function () {
        this.$signInModal = $("body").append(SignInModal()).find(".signin-container");

        var _this = this;
        var addAuthProviders = function(json) {
            _.each(json.providers, function (provider) {
                var sign_in_view = new SignInView({ "provider":provider });
                _this.$signInModal.find(".modal-body").append(sign_in_view.render().el);
                _this.$signInModal.find(".signout-all").click(function() {
                    sign_in_view.signout();
                });
                if (provider.id == "google") {
                    if (provider.active) _this.$el.find(".requires-google-oauth").show();
                    sign_in_view.on("signout", function() {
                        _this.$el.find(".requires-google-oauth").hide();
                    });
                }
            });
        };

        // prepare sign in process in case of 403 (Forbidden)
        var signInProcessStart = _.once(function() {
            $.ajax({
                url: "svc/auth/providers",
                type: "GET",
                dataType: "json",
                success: function(json) {
                    addAuthProviders(json);
                    _this.$signInModal.modal("show");
                    _this.$signInModal.find(".signout-all").click();
                }
            });
        });

        this.$el.ajaxError(function(event, request) {
            if (request.status == 403) signInProcessStart();
        });

        $.ajax({ url:"svc/auth/whoami", method:"GET", context:this, success:addAuthProviders });
    }
});
<|endoftext|>


<commit_before>/*************************************************
 * Copyright (c) 2016 Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

export default ['$stateParams', '$scope', '$rootScope',
    'Rest', 'OrganizationList', 'Prompt',
    'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'rbacUiControlService', '$filter', 'Dataset', 'i18n',
    function($stateParams, $scope, $rootScope,
        Rest, OrganizationList, Prompt,
        ProcessErrors, GetBasePath, Wait, $state, rbacUiControlService, $filter, Dataset, i18n) {

        var defaultUrl = GetBasePath('organizations'),
            list = OrganizationList;

        init();

        function init() {
            $scope.canAdd = false;

            rbacUiControlService.canAdd("organizations")
                .then(function(params) {
                    $scope.canAdd = params.canAdd;
                });
            $scope.orgCount = Dataset.data.count;

            // search init
            $scope.list = list;
            $scope[`${list.iterator}_dataset`] = Dataset.data;
            $scope[list.name] = $scope[`${list.iterator}_dataset`].results;

            $scope.orgCards = parseCardData($scope[list.name]);
            $rootScope.flashMessage = null;

            // grab the pagination elements, move, destroy list generator elements
            $('#organization-pagination').appendTo('#OrgCards');
            $('#organizations tag-search').appendTo('.OrgCards-search');
            $('#organizations-list').remove();
        }

        function parseCardData(cards) {
            return cards.map(function(card) {
                var val = {},
                    url = '/#/organizations/' + card.id + '/';
                val.user_capabilities = card.summary_fields.user_capabilities;
                val.name = card.name;
                val.id = card.id;
                val.description = card.description || undefined;
                val.links = [];
                val.links.push({
                    href: url + 'users',
                    name: "USERS",
                    count: card.summary_fields.related_field_counts.users,
                    activeMode: 'users'
                });
                val.links.push({
                    href: url + 'teams',
                    name: "TEAMS",
                    count: card.summary_fields.related_field_counts.teams,
                    activeMode: 'teams'
                });
                val.links.push({
                    href: url + 'inventories',
                    name: "INVENTORIES",
                    count: card.summary_fields.related_field_counts.inventories,
                    activeMode: 'inventories'
                });
                val.links.push({
                    href: url + 'projects',
                    name: "PROJECTS",
                    count: card.summary_fields.related_field_counts.projects,
                    activeMode: 'projects'
                });
                val.links.push({
                    href: url + 'job_templates',
                    name: "JOB TEMPLATES",
                    count: card.summary_fields.related_field_counts.job_templates,
                    activeMode: 'job_templates'
                });
                val.links.push({
                    href: url + 'admins',
                    name: "ADMINS",
                    count: card.summary_fields.related_field_counts.admins,
                    activeMode: 'admins'
                });
                return val;
            });
        }

        $scope.$on("ReloadOrgListView", function() {
            Rest.setUrl($scope.current_url);
            Rest.get()
                .success((data) => $scope.organizations = data.results)
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: 'Error!',
                        msg: 'Call to ' + defaultUrl + ' failed. DELETE returned status: ' + status
                    });
            });
        });

        $scope.$watchCollection('organizations', function(value){
            $scope.orgCards = parseCardData(value);
        });

        if ($scope.removePostRefresh) {
            $scope.removePostRefresh();
        }

        $scope.$watchCollection(`${list.iterator}_dataset`, function(data) {
            $scope[list.name] = data.results;
            $scope.orgCards = parseCardData($scope[list.name]);
        });

        $scope.addOrganization = function() {
            $state.transitionTo('organizations.add');
        };

        $scope.editOrganization = function(id) {
            $state.transitionTo('organizations.edit', {
                organization_id: id
            });
        };

        function isDeletedOrganizationBeingEdited(deleted_organization_id, editing_organization_id) {
            if (editing_organization_id === undefined) {
                return false;
            }
            if (deleted_organization_id === editing_organization_id) {
                return true;
            }
            return false;
        }

        $scope.deleteOrganization = function(id, name) {

            var action = function() {
                $('#prompt-modal').modal('hide');
                Wait('start');
                var url = defaultUrl + id + '/';
                Rest.setUrl(url);
                Rest.destroy()
                    .success(function() {
                        Wait('stop');

                        let reloadListStateParams = null;

                        if($scope.organizations.length === 1 && $state.params.organization_search && !_.isEmpty($state.params.organization_search.page) && $state.params.organization_search.page !== '1') {
                            reloadListStateParams = _.cloneDeep($state.params);
                            reloadListStateParams.organization_search.page = (parseInt(reloadListStateParams.organization_search.page)-1).toString();
                        }

                        if (isDeletedOrganizationBeingEdited(id, parseInt($stateParams.organization_id)) === true) {
                            $state.go('^', reloadListStateParams, { reload: true });
                        } else {
                            $state.go('.', reloadListStateParams, { reload: true });
                        }
                    })
                    .error(function(data, status) {
                        ProcessErrors($scope, data, status, null, {
                            hdr: 'Error!',
                            msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status
                        });
                    });
            };

            Prompt({
                hdr: i18n._('Delete'),
                body: '
' + i18n._('Are you sure you want to delete the organization below?') + '

' + $filter('sanitize')(name) + '
',
                action: action,
                actionText: i18n._('DELETE')
            });
        };
    }
];
<commit_msg>Add translation support to Organization cards<commit_after>/*************************************************
 * Copyright (c) 2016 Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

export default ['$stateParams', '$scope', '$rootScope',
    'Rest', 'OrganizationList', 'Prompt',
    'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'rbacUiControlService', '$filter', 'Dataset', 'i18n',
    function($stateParams, $scope, $rootScope,
        Rest, OrganizationList, Prompt,
        ProcessErrors, GetBasePath, Wait, $state, rbacUiControlService, $filter, Dataset, i18n) {

        var defaultUrl = GetBasePath('organizations'),
            list = OrganizationList;

        init();

        function init() {
            $scope.canAdd = false;

            rbacUiControlService.canAdd("organizations")
                .then(function(params) {
                    $scope.canAdd = params.canAdd;
                });
            $scope.orgCount = Dataset.data.count;

            // search init
            $scope.list = list;
            $scope[`${list.iterator}_dataset`] = Dataset.data;
            $scope[list.name] = $scope[`${list.iterator}_dataset`].results;

            $scope.orgCards = parseCardData($scope[list.name]);
            $rootScope.flashMessage = null;

            // grab the pagination elements, move, destroy list generator elements
            $('#organization-pagination').appendTo('#OrgCards');
            $('#organizations tag-search').appendTo('.OrgCards-search');
            $('#organizations-list').remove();
        }

        function parseCardData(cards) {
            return cards.map(function(card) {
                var val = {},
                    url = '/#/organizations/' + card.id + '/';
                val.user_capabilities = card.summary_fields.user_capabilities;
                val.name = card.name;
                val.id = card.id;
                val.description = card.description || undefined;
                val.links = [];
                val.links.push({
                    href: url + 'users',
                    name: i18n._("USERS"),
                    count: card.summary_fields.related_field_counts.users,
                    activeMode: 'users'
                });
                val.links.push({
                    href: url + 'teams',
                    name: i18n._("TEAMS"),
                    count: card.summary_fields.related_field_counts.teams,
                    activeMode: 'teams'
                });
                val.links.push({
                    href: url + 'inventories',
                    name: i18n._("INVENTORIES"),
                    count: card.summary_fields.related_field_counts.inventories,
                    activeMode: 'inventories'
                });
                val.links.push({
                    href: url + 'projects',
                    name: i18n._("PROJECTS"),
                    count: card.summary_fields.related_field_counts.projects,
                    activeMode: 'projects'
                });
                val.links.push({
                    href: url + 'job_templates',
                    name: i18n._("JOB TEMPLATES"),
                    count: card.summary_fields.related_field_counts.job_templates,
                    activeMode: 'job_templates'
                });
                val.links.push({
                    href: url + 'admins',
                    name: i18n._("ADMINS"),
                    count: card.summary_fields.related_field_counts.admins,
                    activeMode: 'admins'
                });
                return val;
            });
        }

        $scope.$on("ReloadOrgListView", function() {
            Rest.setUrl($scope.current_url);
            Rest.get()
                .success((data) => $scope.organizations = data.results)
                .error(function(data, status) {
                    ProcessErrors($scope, data, status, null, {
                        hdr: 'Error!',
                        msg: 'Call to ' + defaultUrl + ' failed. DELETE returned status: ' + status
                    });
            });
        });

        $scope.$watchCollection('organizations', function(value){
            $scope.orgCards = parseCardData(value);
        });

        if ($scope.removePostRefresh) {
            $scope.removePostRefresh();
        }

        $scope.$watchCollection(`${list.iterator}_dataset`, function(data) {
            $scope[list.name] = data.results;
            $scope.orgCards = parseCardData($scope[list.name]);
        });

        $scope.addOrganization = function() {
            $state.transitionTo('organizations.add');
        };

        $scope.editOrganization = function(id) {
            $state.transitionTo('organizations.edit', {
                organization_id: id
            });
        };

        function isDeletedOrganizationBeingEdited(deleted_organization_id, editing_organization_id) {
            if (editing_organization_id === undefined) {
                return false;
            }
            if (deleted_organization_id === editing_organization_id) {
                return true;
            }
            return false;
        }

        $scope.deleteOrganization = function(id, name) {

            var action = function() {
                $('#prompt-modal').modal('hide');
                Wait('start');
                var url = defaultUrl + id + '/';
                Rest.setUrl(url);
                Rest.destroy()
                    .success(function() {
                        Wait('stop');

                        let reloadListStateParams = null;

                        if($scope.organizations.length === 1 && $state.params.organization_search && !_.isEmpty($state.params.organization_search.page) && $state.params.organization_search.page !== '1') {
                            reloadListStateParams = _.cloneDeep($state.params);
                            reloadListStateParams.organization_search.page = (parseInt(reloadListStateParams.organization_search.page)-1).toString();
                        }

                        if (isDeletedOrganizationBeingEdited(id, parseInt($stateParams.organization_id)) === true) {
                            $state.go('^', reloadListStateParams, { reload: true });
                        } else {
                            $state.go('.', reloadListStateParams, { reload: true });
                        }
                    })
                    .error(function(data, status) {
                        ProcessErrors($scope, data, status, null, {
                            hdr: 'Error!',
                            msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status
                        });
                    });
            };

            Prompt({
                hdr: i18n._('Delete'),
                body: '
' + i18n._('Are you sure you want to delete the organization below?') + '

' + $filter('sanitize')(name) + '
',
                action: action,
                actionText: i18n._('DELETE')
            });
        };
    }
];
<|endoftext|>


<commit_before>'use babel';

import {
  Disposable,
  CompositeDisposable,
} from 'atom';

import DafnyStatusBarElement from './dafny-status-bar-element.js';

export default class DafnyStatusBarView {

  constructor(statusBar) {
    this.statusBar = statusBar;
    this.statusBarElements = new Map();
    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(new Disposable(() => {
      this.removeAll();
    }));
    atom.workspace.onDidChangeActivePaneItem((paneItem) => {
      this.detachAll();
      const statusBarElement = this.statusBarElements.get(paneItem);
      if (statusBarElement) {
        statusBarElement.attach();
      }
    });
  }

  add(textEditor) {
    const statusBarElement = new DafnyStatusBarElement(this.statusBar);
    this.statusBarElements.set(textEditor, statusBarElement);
    statusBarElement.attach();
  }

  remove(textEditor) {
    const statusBarElement = this.statusBarElements.get(textEditor);
    this.statusBarElements.delete(textEditor);
    statusBarElement.destroy();
  }

  update(textEditor, status, result, executionTime) {
    const statusBarElement = this.statusBarElements.get(textEditor);
    statusBarElement.setStatus(status);
    statusBarElement.setTooltip(status, result, executionTime);
  }

  detachAll() {
    this.statusBarElements.forEach((statusBarElement) => {
      statusBarElement.detach();
    });
  }

  removeAll() {
    this.statusBarElements.forEach((statusBarElement, textEditor) => {
      this.remove(textEditor);
    });
  }
}
<commit_msg>Add `atom.workspace.onDidChangeActivePaneItem` to subscriptions<commit_after>'use babel';

import {
  Disposable,
  CompositeDisposable,
} from 'atom';

import DafnyStatusBarElement from './dafny-status-bar-element.js';

export default class DafnyStatusBarView {

  constructor(statusBar) {
    this.statusBar = statusBar;
    this.statusBarElements = new Map();
    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(new Disposable(() => {
      this.removeAll();
    }));
    this.subscriptions.add(atom.workspace.onDidChangeActivePaneItem((paneItem) => {
      this.detachAll();
      const statusBarElement = this.statusBarElements.get(paneItem);
      if (statusBarElement) {
        statusBarElement.attach();
      }
    }));
  }

  add(textEditor) {
    const statusBarElement = new DafnyStatusBarElement(this.statusBar);
    this.statusBarElements.set(textEditor, statusBarElement);
    statusBarElement.attach();
  }

  remove(textEditor) {
    const statusBarElement = this.statusBarElements.get(textEditor);
    this.statusBarElements.delete(textEditor);
    statusBarElement.destroy();
  }

  update(textEditor, status, result, executionTime) {
    const statusBarElement = this.statusBarElements.get(textEditor);
    statusBarElement.setStatus(status);
    statusBarElement.setTooltip(status, result, executionTime);
  }

  detachAll() {
    this.statusBarElements.forEach((statusBarElement) => {
      statusBarElement.detach();
    });
  }

  removeAll() {
    this.statusBarElements.forEach((statusBarElement, textEditor) => {
      this.remove(textEditor);
    });
  }
}
<|endoftext|>


<commit_before>/*jslint es5: true, node: true */
/*global console:true */
/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
var exitHook = require('exit-hook');
var joynr = require('joynr');
var Promise = require('bluebird').Promise;
var provisioning = { ccAddress: {} };

var timeStart;
var SHUTDOWN_MAX_TIME = 2000;

exitHook(function () {
    var timeSpent = Date.now() - timeStart;
    if (timeSpent > SHUTDOWN_MAX_TIME) {
        console.log("Shutdown of libjoynr took longer then expected: " + timeSpent + "ms instead of max " + SHUTDOWN_MAX_TIME + "ms");
        process.exit(-1);
    }
    console.log("Shutdown of libjoynr succeeded within " + timeSpent + "ms");
});

joynr.load(provisioning).then(function(loadedJoynr) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            loadedJoynr.shutdown().then(function() {
                timeStart = Date.now();
                resolve();
            }).catch(reject);
        }, 100);
    });
});

<commit_msg>[JS] Increased timeout for NodeShutdownTest<commit_after>/*jslint es5: true, node: true */
/*global console:true */
/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
var exitHook = require('exit-hook');
var joynr = require('joynr');
var Promise = require('bluebird').Promise;
var provisioning = { ccAddress: {} };

var timeStart;
var SHUTDOWN_MAX_TIME = 5000;

exitHook(function () {
    var timeSpent = Date.now() - timeStart;
    if (timeSpent > SHUTDOWN_MAX_TIME) {
        console.log("Shutdown of libjoynr took longer then expected: " + timeSpent + "ms instead of max " + SHUTDOWN_MAX_TIME + "ms");
        process.exit(-1);
    }
    console.log("Shutdown of libjoynr succeeded within " + timeSpent + "ms");
});

joynr.load(provisioning).then(function(loadedJoynr) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            loadedJoynr.shutdown().then(function() {
                timeStart = Date.now();
                resolve();
            }).catch(reject);
        }, 100);
    });
});

<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var util = require('util');
var _ = require('lodash');
var normalizePkValues = require('../../utils/normalize-pk-values');
var Deferred = require('../deferred');

/**
 * addToCollection()
 *
 * Add new child records to the specified collection in each of the target record(s).
 *
 * ```
 * // For users 3 and 4, add pets 99 and 98 to the "pets" collection.
 * // > (if either user record already has one of those pets in its "pets",
 * // > then we just silently skip over it)
 * User.addToCollection([3,4], 'pets', [99,98]).exec(...);
 * ```
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * @param {Array|String|Number} targetRecordIds
 *     The primary key value(s) (i.e. ids) for the parent record(s).
 *     Must be a number or string; e.g. '507f191e810c19729de860ea' or 49
 *     Or an array of numbers or strings; e.g. ['507f191e810c19729de860ea', '14832ace0c179de897'] or [49, 32, 37]
 *
 * @param {String} associationName
 *     The name of the collection association (e.g. "pets")
 *
 * @param {Array} associatedIdsToAdd
 *     The primary key values (i.e. ids) for the child records to add.
 *     Must be an array of numbers or strings; e.g. ['334724948aca33ea0f13', '913303583e0af031358bac931'] or [18, 19]
 *
 * @param {Function?} callback
 *
 * @param {Ref?} metaContainer
 *     For internal use.
 *
 * @returns {Dictionary?} Deferred object if no callback
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 */

module.exports = function addToCollection(targetRecordIds, associationName, associatedIdsToAdd, cb, metaContainer) {

  //   ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ██╗   ██╗███████╗ █████╗  ██████╗ ███████╗
  //  ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ██║   ██║██╔════╝██╔══██╗██╔════╝ ██╔════╝
  //  ██║     ███████║█████╗  ██║     █████╔╝     ██║   ██║███████╗███████║██║  ███╗█████╗
  //  ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██║   ██║╚════██║██╔══██║██║   ██║██╔══╝
  //  ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ╚██████╔╝███████║██║  ██║╚██████╔╝███████╗
  //   ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝     ╚═════╝ ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝
  //

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌┬┐┌─┐┬─┐┌─┐┌─┐┌┬┐  ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐  ┬┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤    │ ├─┤├┬┘│ ┬├┤  │   ├┬┘├┤ │  │ │├┬┘ ││  │ ││└─┐
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘   ┴ ┴ ┴┴└─└─┘└─┘ ┴   ┴└─└─┘└─┘└─┘┴└──┴┘  ┴─┴┘└─┘
  // Normalize (and validate) the specified target record pk values.
  // (if a singular string or number was provided, this converts it into an array.)
  try {
    targetRecordIds = normalizePkValues(targetRecordIds);
  } catch(e) {
    switch (e.code) {
      case 'E_INVALID_PK_VALUES':
        throw new Error('Usage error: The first argument passed to `.addToCollection()` should be the ID (or IDs) of target records whose associated collection will be modified.\nDetails: '+e.message);
      default: throw e;
    }
  }

  // If an empty array of target record ids was provided, then this wouldn't do anything.
  // That doesn't make any sense, so if we see that, we'll fail witih an error.
  if (targetRecordIds.length === 0) {
    throw new Error('Usage error: The first argument passed to `.addToCollection()` should be the ID (or IDs) of target records whose associated collection will be modified.  But instead got an empty array!');
  }

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌─┐┌─┐┌─┐┌─┐┌─┐┬┌─┐┌┬┐┬┌─┐┌┐┌  ┌┐┌┌─┐┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤   ├─┤└─┐└─┐│ ││  │├─┤ │ ││ ││││  │││├─┤│││├┤
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘  ┴ ┴└─┘└─┘└─┘└─┘┴┴ ┴ ┴ ┴└─┘┘└┘  ┘└┘┴ ┴┴ ┴└─┘
  //
  // Validate association name.
  if (!_.isString(associationName)) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association from this model (e.g. "friends"), but instead got: '+util.inspect(associationName,{depth:null}));
  }

  // Look up the association by this name in this model definition.
  var associationDef;// TODO

  // Validate that an association by this name actually exists in this model definition.
  if (!associationDef) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association, but there is no association named `'+associationName+'` defined in this model.');
  }

  // Validate that the association with this name is a collection association.
  if (!associationDef.collection) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association, but the association or attribute named `'+associationName+'` defined in this model is NOT a collection association.');
  }

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌─┐┌─┐┌─┐┌─┐┌─┐┬┌─┐┌┬┐┌─┐┌┬┐  ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐  ┬┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤   ├─┤└─┐└─┐│ ││  │├─┤ │ ├┤  ││  ├┬┘├┤ │  │ │├┬┘ ││  │ ││└─┐
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘  ┴ ┴└─┘└─┘└─┘└─┘┴┴ ┴ ┴ └─┘─┴┘  ┴└─└─┘└─┘└─┘┴└──┴┘  ┴─┴┘└─┘
  // Validate the provided set of associated record ids.
  // (if a singular string or number was provided, this converts it into an array.)
  try {
    associatedIdsToAdd = normalizePkValues(associatedIdsToAdd);
  } catch(e) {
    switch (e.code) {
      case 'E_INVALID_PK_VALUES':
        throw new Error('Usage error: The third argument passed to `.addToCollection()` should be the ID (or IDs) of associated records to add.\nDetails: '+e.message);
      default: throw e;
    }
  }

  //  ┌┐ ┬ ┬┬┬  ┌┬┐   ┬   ┬─┐┌─┐┌┬┐┬ ┬┬─┐┌┐┌  ┌┐┌┌─┐┬ ┬  ┌┬┐┌─┐┌─┐┌─┐┬─┐┬─┐┌─┐┌┬┐
  //  ├┴┐│ │││   ││  ┌┼─  ├┬┘├┤  │ │ │├┬┘│││  │││├┤ │││   ││├┤ ├┤ ├┤ ├┬┘├┬┘├┤  ││
  //  └─┘└─┘┴┴─┘─┴┘  └┘   ┴└─└─┘ ┴ └─┘┴└─┘└┘  ┘└┘└─┘└┴┘  ─┴┘└─┘└  └─┘┴└─┴└─└─┘─┴┘
  //  ┌─    ┬┌─┐  ┬─┐┌─┐┬  ┌─┐┬  ┬┌─┐┌┐┌┌┬┐    ─┐
  //  │───  │├┤   ├┬┘├┤ │  ├┤ └┐┌┘├─┤│││ │   ───│
  //  └─    ┴└    ┴└─└─┘┴─┘└─┘ └┘ ┴ ┴┘└┘ ┴     ─┘
  // If a callback function was not specified, then build a new `Deferred` and bail now.
  if (!_.isFunction(cb)) {
    // TODO: make minor modifications to `Deferred` to allow for slightly easier use- like this:
    return new Deferred(this, addToCollection, {
      method: 'addToCollection',
      targetRecordIds: targetRecordIds,
      associationName: associationName,
      associatedIdsToAdd: associatedIdsToAdd
    });
  }//--•

  // Otherwise, we know that a callback was specified.

  // Now build a call to `update()`.
  // TODO
  return cb();

};
<commit_msg>Remove no-longer-relevant TODO.<commit_after>/**
 * Module dependencies
 */

var util = require('util');
var _ = require('lodash');
var normalizePkValues = require('../../utils/normalize-pk-values');
var Deferred = require('../deferred');

/**
 * addToCollection()
 *
 * Add new child records to the specified collection in each of the target record(s).
 *
 * ```
 * // For users 3 and 4, add pets 99 and 98 to the "pets" collection.
 * // > (if either user record already has one of those pets in its "pets",
 * // > then we just silently skip over it)
 * User.addToCollection([3,4], 'pets', [99,98]).exec(...);
 * ```
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * @param {Array|String|Number} targetRecordIds
 *     The primary key value(s) (i.e. ids) for the parent record(s).
 *     Must be a number or string; e.g. '507f191e810c19729de860ea' or 49
 *     Or an array of numbers or strings; e.g. ['507f191e810c19729de860ea', '14832ace0c179de897'] or [49, 32, 37]
 *
 * @param {String} associationName
 *     The name of the collection association (e.g. "pets")
 *
 * @param {Array} associatedIdsToAdd
 *     The primary key values (i.e. ids) for the child records to add.
 *     Must be an array of numbers or strings; e.g. ['334724948aca33ea0f13', '913303583e0af031358bac931'] or [18, 19]
 *
 * @param {Function?} callback
 *
 * @param {Ref?} metaContainer
 *     For internal use.
 *
 * @returns {Dictionary?} Deferred object if no callback
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 */

module.exports = function addToCollection(targetRecordIds, associationName, associatedIdsToAdd, cb, metaContainer) {

  //   ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗    ██╗   ██╗███████╗ █████╗  ██████╗ ███████╗
  //  ██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝    ██║   ██║██╔════╝██╔══██╗██╔════╝ ██╔════╝
  //  ██║     ███████║█████╗  ██║     █████╔╝     ██║   ██║███████╗███████║██║  ███╗█████╗
  //  ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗     ██║   ██║╚════██║██╔══██║██║   ██║██╔══╝
  //  ╚██████╗██║  ██║███████╗╚██████╗██║  ██╗    ╚██████╔╝███████║██║  ██║╚██████╔╝███████╗
  //   ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝     ╚═════╝ ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝
  //

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌┬┐┌─┐┬─┐┌─┐┌─┐┌┬┐  ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐  ┬┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤    │ ├─┤├┬┘│ ┬├┤  │   ├┬┘├┤ │  │ │├┬┘ ││  │ ││└─┐
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘   ┴ ┴ ┴┴└─└─┘└─┘ ┴   ┴└─└─┘└─┘└─┘┴└──┴┘  ┴─┴┘└─┘
  // Normalize (and validate) the specified target record pk values.
  // (if a singular string or number was provided, this converts it into an array.)
  try {
    targetRecordIds = normalizePkValues(targetRecordIds);
  } catch(e) {
    switch (e.code) {
      case 'E_INVALID_PK_VALUES':
        throw new Error('Usage error: The first argument passed to `.addToCollection()` should be the ID (or IDs) of target records whose associated collection will be modified.\nDetails: '+e.message);
      default: throw e;
    }
  }

  // If an empty array of target record ids was provided, then this wouldn't do anything.
  // That doesn't make any sense, so if we see that, we'll fail witih an error.
  if (targetRecordIds.length === 0) {
    throw new Error('Usage error: The first argument passed to `.addToCollection()` should be the ID (or IDs) of target records whose associated collection will be modified.  But instead got an empty array!');
  }

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌─┐┌─┐┌─┐┌─┐┌─┐┬┌─┐┌┬┐┬┌─┐┌┐┌  ┌┐┌┌─┐┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤   ├─┤└─┐└─┐│ ││  │├─┤ │ ││ ││││  │││├─┤│││├┤
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘  ┴ ┴└─┘└─┘└─┘└─┘┴┴ ┴ ┴ ┴└─┘┘└┘  ┘└┘┴ ┴┴ ┴└─┘
  //
  // Validate association name.
  if (!_.isString(associationName)) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association from this model (e.g. "friends"), but instead got: '+util.inspect(associationName,{depth:null}));
  }

  // Look up the association by this name in this model definition.
  var associationDef;// TODO

  // Validate that an association by this name actually exists in this model definition.
  if (!associationDef) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association, but there is no association named `'+associationName+'` defined in this model.');
  }

  // Validate that the association with this name is a collection association.
  if (!associationDef.collection) {
    throw new Error('Usage error: The second argument to `addToCollection()` should be the name of a collection association, but the association or attribute named `'+associationName+'` defined in this model is NOT a collection association.');
  }

  //  ┬  ┬┌─┐┬  ┬┌┬┐┌─┐┌┬┐┌─┐  ┌─┐┌─┐┌─┐┌─┐┌─┐┬┌─┐┌┬┐┌─┐┌┬┐  ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐  ┬┌┬┐┌─┐
  //  └┐┌┘├─┤│  │ ││├─┤ │ ├┤   ├─┤└─┐└─┐│ ││  │├─┤ │ ├┤  ││  ├┬┘├┤ │  │ │├┬┘ ││  │ ││└─┐
  //   └┘ ┴ ┴┴─┘┴─┴┘┴ ┴ ┴ └─┘  ┴ ┴└─┘└─┘└─┘└─┘┴┴ ┴ ┴ └─┘─┴┘  ┴└─└─┘└─┘└─┘┴└──┴┘  ┴─┴┘└─┘
  // Validate the provided set of associated record ids.
  // (if a singular string or number was provided, this converts it into an array.)
  try {
    associatedIdsToAdd = normalizePkValues(associatedIdsToAdd);
  } catch(e) {
    switch (e.code) {
      case 'E_INVALID_PK_VALUES':
        throw new Error('Usage error: The third argument passed to `.addToCollection()` should be the ID (or IDs) of associated records to add.\nDetails: '+e.message);
      default: throw e;
    }
  }

  //  ┌┐ ┬ ┬┬┬  ┌┬┐   ┬   ┬─┐┌─┐┌┬┐┬ ┬┬─┐┌┐┌  ┌┐┌┌─┐┬ ┬  ┌┬┐┌─┐┌─┐┌─┐┬─┐┬─┐┌─┐┌┬┐
  //  ├┴┐│ │││   ││  ┌┼─  ├┬┘├┤  │ │ │├┬┘│││  │││├┤ │││   ││├┤ ├┤ ├┤ ├┬┘├┬┘├┤  ││
  //  └─┘└─┘┴┴─┘─┴┘  └┘   ┴└─└─┘ ┴ └─┘┴└─┘└┘  ┘└┘└─┘└┴┘  ─┴┘└─┘└  └─┘┴└─┴└─└─┘─┴┘
  //  ┌─    ┬┌─┐  ┬─┐┌─┐┬  ┌─┐┬  ┬┌─┐┌┐┌┌┬┐    ─┐
  //  │───  │├┤   ├┬┘├┤ │  ├┤ └┐┌┘├─┤│││ │   ───│
  //  └─    ┴└    ┴└─└─┘┴─┘└─┘ └┘ ┴ ┴┘└┘ ┴     ─┘
  // If a callback function was not specified, then build a new `Deferred` and bail now.
  if (!_.isFunction(cb)) {
    return new Deferred(this, addToCollection, {
      method: 'addToCollection',
      targetRecordIds: targetRecordIds,
      associationName: associationName,
      associatedIdsToAdd: associatedIdsToAdd
    });
  }//--•

  // Otherwise, we know that a callback was specified.

  // Now build a call to `update()`.
  // TODO
  return cb();

};
<|endoftext|>


<commit_before>// Sample file for ensuring the regions get added.
// Output Fizz on multiples of 3, Output Buzz on multiples of 5
// Output FizzBuzz on multiples of 3 and 5

let output = "";

let i = 1;
while (i <= 100) {
  let string = `${i} `;
  if ((i % 3) === 0) { string += 'Fizz'; }
  if ((i % 5) === 0) { string += 'Buzz'; }
  output += `${string}\n`;
  i++;
}
<commit_msg>Remove file from decaffeinate<commit_after><|endoftext|>


<commit_before>import contains from '../common/contains';
import {def_table} from '../support/constants';
import getElementsByTagName from '../common/getElementsByTagName';
import getValue from '../system/getValue';
import insertHtmlBeforeEnd from '../common/insertHtmlBeforeEnd';
import partial from '../common/partial';
import querySelectorArray from '../common/querySelectorArray';

function totalKey(isAllies) {
  if (isAllies) {return 'alliestotal';}
  return 'enemiestotal';
}

function contactSlots(numberOfContacts, contactsTotal) {
  if (contactsTotal && contactsTotal >= numberOfContacts) {
    return '/' + contactsTotal;
  }
  return '';
}

function countContacts(isAllies, el) {
  var target = el.parentNode;
  var numberOfContacts = getElementsByTagName(def_table,
    target.nextSibling.nextSibling).length - 1;
  insertHtmlBeforeEnd(target,
    ' ' + numberOfContacts.toString() +
    contactSlots(numberOfContacts, getValue(totalKey(isAllies))) +
    '');
}

export default function profileParseAllyEnemy() {
  // Allies/Enemies count/total function
  var headings = querySelectorArray('#profileLeftColumn strong');
  headings.filter(contains('Allies')).forEach(partial(countContacts, true));
  headings.filter(contains('Enemies')).forEach(partial(countContacts, false));
}
<commit_msg>fix improper use of nextSibling<commit_after>import contains from '../common/contains';
import {def_table} from '../support/constants';
import getElementsByTagName from '../common/getElementsByTagName';
import getValue from '../system/getValue';
import insertHtmlBeforeEnd from '../common/insertHtmlBeforeEnd';
import partial from '../common/partial';
import querySelectorArray from '../common/querySelectorArray';

function totalKey(isAllies) {
  if (isAllies) {return 'alliestotal';}
  return 'enemiestotal';
}

function contactSlots(numberOfContacts, contactsTotal) {
  if (contactsTotal && contactsTotal >= numberOfContacts) {
    return '/' + contactsTotal;
  }
  return '';
}

function countContacts(isAllies, el) {
  var target = el.parentNode;
  var numberOfContacts = getElementsByTagName(def_table,
    target.nextElementSibling).length - 1;
  insertHtmlBeforeEnd(target,
    ' ' + numberOfContacts.toString() +
    contactSlots(numberOfContacts, getValue(totalKey(isAllies))) +
    '');
}

export default function profileParseAllyEnemy() {
  // Allies/Enemies count/total function
  var headings = querySelectorArray('#profileLeftColumn strong');
  headings.filter(contains('Allies')).forEach(partial(countContacts, true));
  headings.filter(contains('Enemies')).forEach(partial(countContacts, false));
}
<|endoftext|>


<commit_before>/*jslint indent: 2, nomen: true, maxlen: 100, white: true  plusplus: true */
/*global $, _, d3*/
/*global document*/
/*global modalDialogHelper, uiComponentsHelper*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
function ArangoAdapterControls(list, adapter) {
  "use strict";

  if (list === undefined) {
    throw "A list element has to be given.";
  }
  if (adapter === undefined) {
    throw "The ArangoAdapter has to be given.";
  }
  this.addControlChangeCollections = function(callback) {
    var prefix = "control_adapter_collections",
      idprefix = prefix + "_";

    adapter.getCollections(function(nodeCols, edgeCols) {
      adapter.getGraphs(function(graphs) {
        uiComponentsHelper.createButton(list, "Collections", prefix, function() {
          modalDialogHelper.createModalDialog("Switch Collections",
            idprefix, [{
              type: "decission",
              id: "collections",
              group: "loadtype",
              text: "Select existing collections",
              isDefault: (adapter.getGraphName() === undefined),
              interior: [
                {
                  type: "list",
                  id: "node_collection",
                  text: "Vertex collection",
                  objects: nodeCols,
                  selected: adapter.getNodeCollection()
                },{
                  type: "list",
                  id: "edge_collection",
                  text: "Edge collection",
                  objects: edgeCols,
                  selected: adapter.getEdgeCollection()
                }
              ]
            },{
              type: "decission",
              id: "graphs",
              group: "loadtype",
              text: "Select existing graph",
              isDefault: (adapter.getGraphName() !== undefined),
              interior: [
                {
                  type: "list",
                  id: "graph",
                  objects: graphs,
                  selected: adapter.getGraphName()
                }
              ]
            },{
              type: "checkbox",
              text: "Start with random vertex",
              id: "random",
              selected: true
            },{
              type: "checkbox",
              id: "undirected",
              selected: (adapter.getDirection() === "any")
            }], function () {
              var nodes = $("#" + idprefix + "node_collection")
                .children("option")
                .filter(":selected")
                .text(),
                edges = $("#" + idprefix + "edge_collection")
                  .children("option")
                  .filter(":selected")
                  .text(),
                graph = $("#" + idprefix + "graph")
                  .children("option")
                  .filter(":selected")
                  .text(),
                undirected = !!$("#" + idprefix + "undirected").attr("checked"),
                random = !!$("#" + idprefix + "random").attr("checked"),
                selected = $("input[type='radio'][name='loadtype']:checked").attr("id");
              if (selected === idprefix + "collections") {
                adapter.changeToCollections(nodes, edges, undirected);
              } else {
                adapter.changeToGraph(graph, undirected);
              }
              if (random) {
                adapter.loadRandomNode(callback);
                return;
              }
              if (_.isFunction(callback)) {
                callback();
              }
            }
          );
        });
      });
    });
  };

  this.addControlChangePriority = function() {
    var prefix = "control_adapter_priority",
      idprefix = prefix + "_",
      prioList = adapter.getPrioList(),
      label = "Group vertices";

      uiComponentsHelper.createButton(list, label, prefix, function() {
        modalDialogHelper.createModalChangeDialog(label,
          idprefix, [{
            type: "extendable",
            id: "attribute",
            objects: adapter.getPrioList()
          }], function () {
            var list = $("input[id^=" + idprefix + "attribute_]"),
              prios = [];
            list.each(function(i, t) {
              var val = $(t).attr("value");
              if (val !== "") {
                prios.push(val);
              }
            });
            adapter.changeTo({
              prioList: prios
            });
          }
        );
      });
    /*
    adapter.getCollections(function(nodeCols, edgeCols) {
      uiComponentsHelper.createButton(list, "Collections", prefix, function() {
        modalDialogHelper.createModalDialog("Switch Collections",
          idprefix, [{
            type: "list",
            id: "nodecollection",
            objects: nodeCols
          },{
            type: "list",
            id: "edgecollection",
            objects: edgeCols
          },{
            type: "checkbox",
            id: "undirected"
          }], function () {
            var  = $("#" + idprefix + "nodecollection").attr("value"),
              edges = $("#" + idprefix + "edgecollection").attr("value"),
              undirected = !!$("#" + idprefix + "undirected").attr("checked");
            adapter.changeTo(nodes, edges, undirected);

          }
        );
      });
    });
    */
  };

  this.addAll = function() {
    this.addControlChangeCollections();
    this.addControlChangePriority();
  };
}
<commit_msg>Fixed a bug where random start node and direction of graph was not accepted properly<commit_after>/*jslint indent: 2, nomen: true, maxlen: 100, white: true  plusplus: true */
/*global $, _, d3*/
/*global document*/
/*global modalDialogHelper, uiComponentsHelper*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
function ArangoAdapterControls(list, adapter) {
  "use strict";

  if (list === undefined) {
    throw "A list element has to be given.";
  }
  if (adapter === undefined) {
    throw "The ArangoAdapter has to be given.";
  }
  this.addControlChangeCollections = function(callback) {
    var prefix = "control_adapter_collections",
      idprefix = prefix + "_";

    adapter.getCollections(function(nodeCols, edgeCols) {
      adapter.getGraphs(function(graphs) {
        uiComponentsHelper.createButton(list, "Collections", prefix, function() {
          modalDialogHelper.createModalDialog("Switch Collections",
            idprefix, [{
              type: "decission",
              id: "collections",
              group: "loadtype",
              text: "Select existing collections",
              isDefault: (adapter.getGraphName() === undefined),
              interior: [
                {
                  type: "list",
                  id: "node_collection",
                  text: "Vertex collection",
                  objects: nodeCols,
                  selected: adapter.getNodeCollection()
                },{
                  type: "list",
                  id: "edge_collection",
                  text: "Edge collection",
                  objects: edgeCols,
                  selected: adapter.getEdgeCollection()
                }
              ]
            },{
              type: "decission",
              id: "graphs",
              group: "loadtype",
              text: "Select existing graph",
              isDefault: (adapter.getGraphName() !== undefined),
              interior: [
                {
                  type: "list",
                  id: "graph",
                  objects: graphs,
                  selected: adapter.getGraphName()
                }
              ]
            },{
              type: "checkbox",
              text: "Start with random vertex",
              id: "random",
              selected: true
            },{
              type: "checkbox",
              id: "undirected",
              selected: (adapter.getDirection() === "any")
            }], function () {
              var nodes = $("#" + idprefix + "node_collection")
                .children("option")
                .filter(":selected")
                .text(),
                edges = $("#" + idprefix + "edge_collection")
                  .children("option")
                  .filter(":selected")
                  .text(),
                graph = $("#" + idprefix + "graph")
                  .children("option")
                  .filter(":selected")
                  .text(),
                undirected = !!$("#" + idprefix + "undirected").prop("checked"),
                random = !!$("#" + idprefix + "random").prop("checked"),
                selected = $("input[type='radio'][name='loadtype']:checked").prop("id");
              if (selected === idprefix + "collections") {
                adapter.changeToCollections(nodes, edges, undirected);
              } else {
                adapter.changeToGraph(graph, undirected);
              }
              if (random) {
                adapter.loadRandomNode(callback);
                return;
              }
              if (_.isFunction(callback)) {
                callback();
              }
            }
          );
        });
      });
    });
  };

  this.addControlChangePriority = function() {
    var prefix = "control_adapter_priority",
      idprefix = prefix + "_",
      prioList = adapter.getPrioList(),
      label = "Group vertices";

      uiComponentsHelper.createButton(list, label, prefix, function() {
        modalDialogHelper.createModalChangeDialog(label,
          idprefix, [{
            type: "extendable",
            id: "attribute",
            objects: adapter.getPrioList()
          }], function () {
            var list = $("input[id^=" + idprefix + "attribute_]"),
              prios = [];
            list.each(function(i, t) {
              var val = $(t).attr("value");
              if (val !== "") {
                prios.push(val);
              }
            });
            adapter.changeTo({
              prioList: prios
            });
          }
        );
      });
    /*
    adapter.getCollections(function(nodeCols, edgeCols) {
      uiComponentsHelper.createButton(list, "Collections", prefix, function() {
        modalDialogHelper.createModalDialog("Switch Collections",
          idprefix, [{
            type: "list",
            id: "nodecollection",
            objects: nodeCols
          },{
            type: "list",
            id: "edgecollection",
            objects: edgeCols
          },{
            type: "checkbox",
            id: "undirected"
          }], function () {
            var  = $("#" + idprefix + "nodecollection").attr("value"),
              edges = $("#" + idprefix + "edgecollection").attr("value"),
              undirected = !!$("#" + idprefix + "undirected").attr("checked");
            adapter.changeTo(nodes, edges, undirected);

          }
        );
      });
    });
    */
  };

  this.addAll = function() {
    this.addControlChangeCollections();
    this.addControlChangePriority();
  };
}
<|endoftext|>


<commit_before>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2015 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

var juju = {components: {}}; // eslint-disable-line no-unused-vars

chai.config.includeStack = true;
chai.config.truncateThreshold = 0;

describe('BooleanConfig', function() {

  beforeAll(function(done) {
    // By loading this file it adds the component to the juju components.
    YUI().use('boolean-config', function() { done(); });
  });

  it('renders a checked input based on config prop', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        label="Test"
        option={option} />
    );
    var expected = (

Test

          <input
            disabled={false}
            type="checkbox"
            id={option.key}
            onClick={output.props.children[1].props.children[0].props.onClick}
            onChange={output.props.children[1].props.children[0].props.onChange}
            checked={true}
            className="boolean-config--input" />

    );
    assert.deepEqual(output, expected);
  });

  it('renders an unchecked input based on config prop', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={false}
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

          <input
            disabled={false}
            type="checkbox"
            id={option.key}
            onClick={output.props.children[1].props.children[0].props.onClick}
            onChange={output.props.children[1].props.children[0].props.onChange}
            checked={false}
            className="boolean-config--input" />

);
  });

  it('supports string boolean config props (true)', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="True"
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

          <input
            disabled={false}
            type="checkbox"
            id={option.key}
            onClick={output.props.children[1].props.children[0].props.onClick}
            onChange={output.props.children[1].props.children[0].props.onChange}
            checked={true}
            className="boolean-config--input" />

);
  });

  it('supports string boolean config props (false)', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="False"
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

          <input
            disabled={false}
            type="checkbox"
            id={option.key}
            onClick={output.props.children[1].props.children[0].props.onClick}
            onChange={output.props.children[1].props.children[0].props.onChange}
            checked={false}
            className="boolean-config--input" />

);
  });

  it('can call an onChange method if supplied', function() {
    var onChange = sinon.stub();
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="False"
        label="Test"
        onChange={onChange}
        option={option} />
    );
    output.props.children[1].props.children[0].props.onChange({
      target: {
        checked: true
      }
    });
    assert.equal(onChange.callCount, 1);
  });

  it('can update when new config is provided', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var shallowRenderer = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        label="Test"
        option={option} />, true);
    var instance = shallowRenderer.getMountedInstance();
    assert.isTrue(instance.state.value);
    shallowRenderer.render(
      <juju.components.BooleanConfig
        config={false}
        label="Test"
        option={option} />);
    assert.isFalse(instance.state.value);
  });

  it('can be disabled', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        disabled={true}
        label="Test"
        option={option} />
    );
    var expected = (
      <input
        disabled={true}
        type="checkbox"
        id={option.key}
        onClick={output.props.children[1].props.children[0].props.onClick}
        onChange={output.props.children[1].props.children[0].props.onChange}
        checked={true}
        className="boolean-config--input" />);
    assert.deepEqual(output.props.children[1].props.children[0], expected);
  });
});
<commit_msg>Test fixes.<commit_after>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2015 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

var juju = {components: {}}; // eslint-disable-line no-unused-vars

chai.config.includeStack = true;
chai.config.truncateThreshold = 0;

describe('BooleanConfig', function() {

  beforeAll(function(done) {
    // By loading this file it adds the component to the juju components.
    YUI().use('boolean-config', function() { done(); });
  });

  it('renders a checked input based on config prop', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        label="Test"
        option={option} />
    );
    var expected = (

Test

            <input
              disabled={false}
              type="checkbox"
              id={option.key}
              onClick={output.props.children[0].props.children[1].props.children[0].props.onClick}
              onChange={output.props.children[0].props.children[1].props.children[0].props.onChange}
              checked={true}
              className="boolean-config--input" />

    );
    assert.deepEqual(output, expected);
  });

  it('renders an unchecked input based on config prop', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={false}
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

            <input
              disabled={false}
              type="checkbox"
              id={option.key}
              onClick={output.props.children[0].props.children[1].props.children[0].props.onClick}
              onChange={output.props.children[0].props.children[1].props.children[0].props.onChange}
              checked={false}
              className="boolean-config--input" />

);
  });

  it('supports string boolean config props (true)', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="True"
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

            <input
              disabled={false}
              type="checkbox"
              id={option.key}
              onClick={output.props.children[0].props.children[1].props.children[0].props.onClick}
              onChange={output.props.children[0].props.children[1].props.children[0].props.onChange}
              checked={true}
              className="boolean-config--input" />

);
  });

  it('supports string boolean config props (false)', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="False"
        label="Test"
        option={option} />
    );
    assert.deepEqual(output,

Test

            <input
              disabled={false}
              type="checkbox"
              id={option.key}
              onClick={output.props.children[0].props.children[1].props.children[0].props.onClick}
              onChange={output.props.children[0].props.children[1].props.children[0].props.onChange}
              checked={false}
              className="boolean-config--input" />

);
  });

  it('can call an onChange method if supplied', function() {
    var onChange = sinon.stub();
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config="False"
        label="Test"
        onChange={onChange}
        option={option} />
    );
    output.props.children[0].props.children[1].props.children[0].props.onChange({
      target: {
        checked: true
      }
    });
    assert.equal(onChange.callCount, 1);
  });

  it('can update when new config is provided', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var shallowRenderer = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        label="Test"
        option={option} />, true);
    var instance = shallowRenderer.getMountedInstance();
    assert.isTrue(instance.state.value);
    shallowRenderer.render(
      <juju.components.BooleanConfig
        config={false}
        label="Test"
        option={option} />);
    assert.isFalse(instance.state.value);
  });

  it('can be disabled', function() {
    var option = {
      key: 'testcheck',
      description: 'it is a test config option',
    };
    var output = jsTestUtils.shallowRender(
      <juju.components.BooleanConfig
        config={true}
        disabled={true}
        label="Test"
        option={option} />
    );
    var expected = (
      <input
        disabled={true}
        type="checkbox"
        id={option.key}
        onClick={output.props.children[0].props.children[1].props.children[0].props.onClick}
        onChange={output.props.children[0].props.children[1].props.children[0].props.onChange}
        checked={true}
        className="boolean-config--input" />);
    assert.deepEqual(output.props.children[0].props.children[1].props.children[0], expected);
  });
});
<|endoftext|>