<commit_before>angular.module('spiral')
.directive('spiral', ['$injector', '$window', function($injector, $window) {
	return {
		restrict: 'E',
		controller: ['$element', '$rootScope', '$scope', '$attrs', SpiralController],
		controllerAs: 'ctrl',
		template: function(element, attrs) {
			// Store user's templates defs before angular applies the directive's template
			attrs.$$body = element.children(':not(spiral-header,spiral-sticky):first');
			attrs.$$header = element.children('spiral-header').children();
			attrs.$$sticky = element.children('spiral-sticky').children();

			return '
\

\

\

\

\

\

\

\

\

\

\

';
		},
		compile: function(element, attrs) {
			var bucketSize = attrs.bucketSize = attrs.bucketSize || '25';

			buildTemplate(attrs.$$header, attrs, element.find('.s-header'));
			buildTemplate(attrs.$$sticky, attrs, element.find('.s-sub-header'));

			attrs.$$bodyService = buildTemplate(attrs.$$body, attrs, element.find('.s-bucket .s-content'), bucketSize);

			return spiralLink;

			function spiralLink(scope, element, attrs, ctrl) {
				var $body = element.find('.s-body'),
					$slide = $body.children(),
					throttledScrollHandler = throttle(scrollHandler, 100),
					pendingHides = {count:0},
					resizeFinishTimeout;

				if(attrs.id) {
					scope.$parent[attrs.id]	= ctrl;
				}

				if(attrs.$$bodyService && attrs.$$bodyService.api) {
					attrs.$$bodyService.api(element, ctrl);
				}

				element.on('spiral:re-compute', function(e) {
					reComputeSizes(ctrl.buckets);

					return false;
				});

				$body.on('scroll', throttledScrollHandler);
				angular.element($window).on('resize', resizeHandler);

				function resizeHandler() {
					var bucketsEntity = ctrl.buckets;

					if(resizeFinishTimeout) {
						clearTimeout(resizeFinishTimeout);
					} else {
						for(var i = 0; i < bucketsEntity.length; i++) {
							bucketsEntity[i].visible = true;
						}

						element
							.find('.s-bucket')
							.css('height', '')
								.children()
								.show();
					}

					resizeFinishTimeout = setTimeout(resizeFinish, 300);
				}

				function resizeFinish() {
					resizeFinishTimeout = null;

					reComputeSizesAfterDigest(true);
				}

				function reComputeSizes(bucketsEntity) {
					if(bucketsEntity && bucketsEntity.length) {
						// Reset pending hides, after new sizes we might need to hide a
						// completely different set of buckets.
						cancelPendingHideBuckets();

						scope.$$postDigest(function() {
							// This is a hack to get put to the end of the post digest,
							// ng-show doesn't apply class changes until post digest
							scope.$$postDigest(reComputeSizesAfterDigest);
						});
					}
				}

				function reComputeSizesAfterDigest(force) {
					var $buckets = $slide.children(),
						bucketsEntity = ctrl.buckets,
						bucketsHeight = 0;

					for(var i = 0, val, $el; i < bucketsEntity.length; i++) {
						val = bucketsEntity[i];

						if(!val.pristine || force) {
							val.$el = $el = $buckets.eq(i);

							if(val.visible === false) {
								val.height = $el.children().show().height();

								$el.children().hide();
							} else {
								val.height = $el.height();
							}

							val.pristine = true;
						}

						val.top = bucketsHeight;
						val.bottom = (bucketsHeight += val.height);
					}

					scrollHandler();
				}

				function scrollHandler() {
					var bodyHeight = $body.height(),
						slideHeight = $slide.height(),
						scrollPadding = bodyHeight * 2.5,
						scrollTop = $body.scrollTop(),
						scrollBottom = scrollTop + bodyHeight,
						scrollTopWithPadding = scrollTop - scrollPadding,
						scrollBottomWithPadding = scrollBottom + scrollPadding,
						buckets = ctrl.buckets,
						visibleBucketHeight = 0,
						i = 0, bucket;

					if(resizeFinishTimeout) {
						return;
					}

					if(buckets && buckets.length) {
						for(; i < buckets.length; i++) {
							bucket = buckets[i];

							if(bucket.visible && (bucket.bottom < scrollTopWithPadding || bucket.top > scrollBottomWithPadding)) {
								if(!pendingHides[bucket.$$hashKey]) {
									pendingHides[bucket.$$hashKey] = bucket;

									if(pendingHides.count < 10) {
										clearTimeout(pendingHides.id);
										pendingHides.id = setTimeout(hidePendingBuckets, 500);
									}

									pendingHides.count++;
								}
							} else if(!bucket.visible && bucket.bottom > scrollTopWithPadding && bucket.top < scrollBottomWithPadding) {
								if(pendingHides[bucket.$$hashKey]) {
									delete pendingHides[bucket.$$hashKey];
									pendingHides.count--;
								}

								bucket.visible = true;
								bucket.$el
									.css('height', '')
									.children().css('display', '');
							}
						}
					}

					if(scrollTop === 0) {
						scope.$eval(attrs.fillInTop);
					} else if(scrollBottom === slideHeight) {
						scope.$eval(attrs.fillInBottom);
					}
				}

				function cancelPendingHideBuckets() {
					clearTimeout(pendingHides.id);
					pendingHides = {count:0};
				}

				function hidePendingBuckets() {
					var ids = Object.keys(pendingHides);

					for(var i = 0, bucket; i < ids.length; i++) {
						if(ids[i] === 'id' || ids[i] === 'count') {
							continue;
						}

						bucket = pendingHides[ids[i]];
						bucket.visible = false;
						bucket.$el
							.height(bucket.height)
							.children().hide();
					}

					pendingHides = {count:0};
				}
			}
		}
	};

	function SpiralController($element, $rootScope, $scope, $attrs) {
		var $body = $element.children('.s-body'),
			$slide = $body.children();

		this.buckets = [];

		this.unshift = function(arrayOfData) {
			var bucketSize = $attrs.bucketSize,
				first = this.buckets[0],
				firstHasRoomFor = first && first.remaining || 0,
				unShiftEntities;

			if(firstHasRoomFor > 0) {
				unShiftEntities = arrayOfData.splice(-firstHasRoomFor, firstHasRoomFor);

				first.pristine = false;
				first.remaining -= unShiftEntities.length;
				first.splice.apply(first, [firstHasRoomFor - unShiftEntities.length, unShiftEntities.length].concat(unShiftEntities));
			}

			while(arrayOfData.length) {
				if(arrayOfData.length < bucketSize) {
					unShiftEntities = [];
					unShiftEntities.length = unShiftEntities.remaining = bucketSize - arrayOfData.length;
					unShiftEntities.splice.apply(unShiftEntities, [unShiftEntities.length, 0].concat(arrayOfData));

					arrayOfData.length = 0;

					this.buckets.unshift(unShiftEntities);
				} else {
					this.buckets.unshift(arrayOfData.splice(-bucketSize, bucketSize));
				}
			}

			$element.trigger('spiral:re-compute', true);

			if(!$rootScope.$$phase) {
				$scope.$digest();
			}
		};

		this.push = function(arrayOfData) {
			var bucketSize = $attrs.bucketSize,
				last = this.buckets[this.buckets.length - 1],
				lastHasRoomFor = last && (bucketSize - last.length) || 0;

			if(lastHasRoomFor > 0) {
				last.pristine = false;
				last.push.apply(last, arrayOfData.splice(0, lastHasRoomFor));
			}

			while(arrayOfData.length) {
				this.buckets.push(arrayOfData.splice(0, bucketSize));
			}

			$element.trigger('spiral:re-compute');

			if(!$rootScope.$$phase) {
				$scope.$digest();
			}
		};

		this.reset = function(newArray) {
			this.buckets.length = 0;

			this.push(newArray || []);
		}
	}

	function buildTemplate(def, attrs, $container, bucketSize) {
		var serviceName, service, template;

		if(def && def.length) {
			serviceName = attrs.$normalize(def.prop('tagName').toLowerCase()) + 'Generator';

			if($injector.has(serviceName)) {
				service = $injector.get(serviceName);
				template = service.makeTemplate(def, bucketSize);

				$container.html(template);
			} else {
				$container.append(attrs.$body);
			}
		}

		return service;
	}

	function throttle(fn, delay) {
		var timeoutId;

		return function() {
			if(!timeoutId) {
				timeoutId = setTimeout(function() {
					timeoutId = null;

					fn();
				}, delay);
			}
		};
	}
}]);<commit_msg>Fixing issues when resizing or loading large initial datasets.<commit_after>angular.module('spiral')
.directive('spiral', ['$injector', '$window', function($injector, $window) {
	return {
		restrict: 'E',
		controller: ['$element', '$rootScope', '$scope', '$attrs', SpiralController],
		controllerAs: 'ctrl',
		template: function(element, attrs) {
			// Store user's templates defs before angular applies the directive's template
			attrs.$$body = element.children(':not(spiral-header,spiral-sticky):first');
			attrs.$$header = element.children('spiral-header').children();
			attrs.$$sticky = element.children('spiral-sticky').children();

			return '
\

\

\

\

\

\

\

\

\

\

\

';
		},
		compile: function(element, attrs) {
			var bucketSize = attrs.bucketSize = attrs.bucketSize || '25';

			buildTemplate(attrs.$$header, attrs, element.find('.s-header'));
			buildTemplate(attrs.$$sticky, attrs, element.find('.s-sub-header'));

			attrs.$$bodyService = buildTemplate(attrs.$$body, attrs, element.find('.s-bucket .s-content'), bucketSize);

			return spiralLink;

			function spiralLink(scope, element, attrs, ctrl) {
				var $body = element.find('.s-body'),
					$slide = $body.children(),
					throttledScrollHandler = throttle(scrollHandler, 100),
					pendingHides = {count:0},
					resizeFinishTimeout;

				if(attrs.id) {
					scope.$parent[attrs.id]	= ctrl;
				}

				if(attrs.$$bodyService && attrs.$$bodyService.api) {
					attrs.$$bodyService.api(element, ctrl);
				}

				element.on('spiral:re-compute', function(e) {
					reComputeSizes(ctrl.buckets);

					return false;
				});

				$body.on('scroll', throttledScrollHandler);
				angular.element($window).on('resize', resizeHandler);

				function resizeHandler() {
					var bucketsEntity = ctrl.buckets;

					cancelPendingHideBuckets();

					if(resizeFinishTimeout) {
						clearTimeout(resizeFinishTimeout);
					} else {
						for(var i = 0; i < bucketsEntity.length; i++) {
							bucketsEntity[i].visible = true;
						}

						element
							.find('.s-bucket')
							.css('height', '')
								.children()
								.show();
					}

					resizeFinishTimeout = setTimeout(resizeFinish, 300);
				}

				function resizeFinish() {
					resizeFinishTimeout = null;

					reComputeSizesAfterDigest(true);
				}

				function reComputeSizes(bucketsEntity) {
					if(bucketsEntity && bucketsEntity.length) {
						// Reset pending hides, after new sizes we might need to hide a
						// completely different set of buckets.
						cancelPendingHideBuckets();

						scope.$$postDigest(function() {
							// This is a hack to get put to the end of the post digest,
							// ng-show doesn't apply class changes until post digest
							scope.$$postDigest(reComputeSizesAfterDigest);
						});
					}
				}

				function reComputeSizesAfterDigest(force) {
					var $buckets = $slide.children(),
						bucketsEntity = ctrl.buckets,
						bucketsHeight = 0;

					for(var i = 0, val, $el; i < bucketsEntity.length; i++) {
						val = bucketsEntity[i];

						if(!val.pristine || force) {
							val.$el = $el = (val.$el || $buckets.eq(i));

							if(val.visible === false) {
								val.height = $el.children().show().height();

								$el.children().hide();
							} else {
								val.height = $el.height();
							}

							val.pristine = true;
						}

						val.top = bucketsHeight;
						val.bottom = (bucketsHeight += val.height);
					}

					scrollHandler();
				}

				function scrollHandler() {
					var bodyHeight = $body.height(),
						slideHeight = $slide.height(),
						scrollPadding = bodyHeight * 2.5,
						scrollTop = $body.scrollTop(),
						scrollBottom = scrollTop + bodyHeight,
						scrollTopWithPadding = scrollTop - scrollPadding,
						scrollBottomWithPadding = scrollBottom + scrollPadding,
						buckets = ctrl.buckets,
						visibleBucketHeight = 0,
						i = 0, bucket;

					if(resizeFinishTimeout) {
						return;
					}

					if(buckets && buckets.length) {
						for(; i < buckets.length; i++) {
							bucket = buckets[i];

							if(bucket.visible && (bucket.bottom < scrollTopWithPadding || bucket.top > scrollBottomWithPadding)) {
								if(!pendingHides[bucket.$$hashKey]) {
									pendingHides[bucket.$$hashKey] = bucket;

									if(pendingHides.count < 10) {
										clearTimeout(pendingHides.id);
										pendingHides.id = setTimeout(hidePendingBuckets, 500);
									}

									pendingHides.count++;
								}
							} else if(!bucket.visible && bucket.bottom > scrollTopWithPadding && bucket.top < scrollBottomWithPadding) {
								if(pendingHides[bucket.$$hashKey]) {
									delete pendingHides[bucket.$$hashKey];
								}

								bucket.visible = true;
								bucket.$el
									.css('height', '')
									.children().css('display', '');
							}
						}
					}

					if(scrollTop === 0) {
						scope.$eval(attrs.fillInTop);
					} else if(scrollBottom === slideHeight) {
						scope.$eval(attrs.fillInBottom);
					}
				}

				function cancelPendingHideBuckets() {
					clearTimeout(pendingHides.id);
					pendingHides = {count:0};
				}

				function hidePendingBuckets() {
					var ids = Object.keys(pendingHides);

					for(var i = 0, bucket; i < ids.length; i++) {
						if(ids[i] === 'id' || ids[i] === 'count') {
							continue;
						}

						bucket = pendingHides[ids[i]];
						bucket.visible = false;
						bucket.$el
							.height(bucket.height)
							.children().hide();
					}

					pendingHides = {count:0};
				}
			}
		}
	};

	function SpiralController($element, $rootScope, $scope, $attrs) {
		var $body = $element.children('.s-body'),
			$slide = $body.children();

		this.buckets = [];

		this.unshift = function(arrayOfData) {
			var bucketSize = $attrs.bucketSize,
				first = this.buckets[0],
				firstHasRoomFor = first && first.remaining || 0,
				unShiftEntities;

			if(firstHasRoomFor > 0) {
				unShiftEntities = arrayOfData.splice(-firstHasRoomFor, firstHasRoomFor);

				first.pristine = false;
				first.remaining -= unShiftEntities.length;
				first.splice.apply(first, [firstHasRoomFor - unShiftEntities.length, unShiftEntities.length].concat(unShiftEntities));
			}

			while(arrayOfData.length) {
				if(arrayOfData.length < bucketSize) {
					unShiftEntities = [];
					unShiftEntities.length = unShiftEntities.remaining = bucketSize - arrayOfData.length;
					unShiftEntities.splice.apply(unShiftEntities, [unShiftEntities.length, 0].concat(arrayOfData));

					arrayOfData.length = 0;

					this.buckets.unshift(unShiftEntities);
				} else {
					this.buckets.unshift(arrayOfData.splice(-bucketSize, bucketSize));
				}

				this.buckets[0].visible = true;
			}

			$element.trigger('spiral:re-compute', true);

			if(!$rootScope.$$phase) {
				$scope.$digest();
			}
		};

		this.push = function(arrayOfData) {
			var bucketSize = $attrs.bucketSize,
				last = this.buckets[this.buckets.length - 1],
				lastHasRoomFor = last && (bucketSize - last.length) || 0;

			if(lastHasRoomFor > 0) {
				last.pristine = false;
				last.push.apply(last, arrayOfData.splice(0, lastHasRoomFor));
			}

			while(arrayOfData.length) {
				this.buckets.push(arrayOfData.splice(0, bucketSize));
				this.buckets[this.buckets.length - 1].visible = true;
			}

			$element.trigger('spiral:re-compute');

			if(!$rootScope.$$phase) {
				$scope.$digest();
			}
		};

		this.reset = function(newArray) {
			this.buckets.length = 0;

			this.push(newArray || []);
		}
	}

	function buildTemplate(def, attrs, $container, bucketSize) {
		var serviceName, service, template;

		if(def && def.length) {
			serviceName = attrs.$normalize(def.prop('tagName').toLowerCase()) + 'Generator';

			if($injector.has(serviceName)) {
				service = $injector.get(serviceName);
				template = service.makeTemplate(def, bucketSize);

				$container.html(template);
			} else {
				$container.append(attrs.$body);
			}
		}

		return service;
	}

	function throttle(fn, delay) {
		var timeoutId;

		return function() {
			if(!timeoutId) {
				timeoutId = setTimeout(function() {
					timeoutId = null;

					fn();
				}, delay);
			}
		};
	}
}]);<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint node: true */

"use strict";

var fspath = require("path");
var fs = require("fs");
var os = require("os");
var chokidar = require('chokidar');

var _domainManager,
    _watcherMap = {};

/**
 * @private
 * Un-watch a file or directory.
 * @param {string} path File or directory to unwatch.
 */
function _unwatchPath(path) {
    var watcher = _watcherMap[path];

    if (watcher) {
        try {
            watcher.close();
        } catch (err) {
            console.warn("Failed to unwatch file " + path + ": " + (err && err.message));
        } finally {
            delete _watcherMap[path];
        }
    }
}

/**
 * Un-watch a file or directory. For directories, unwatch all descendants.
 * @param {string} path File or directory to unwatch.
 */
function unwatchPath(path) {
    Object.keys(_watcherMap).forEach(function (keyPath) {
        if (keyPath.indexOf(path) === 0) {
            _unwatchPath(keyPath);
        }
    });
}

/**
 * Watch a file or directory.
 * @param {string} path File or directory to watch.
 * @param {array} ignored List of File or directory to NOT watch.
 */
function watchPath(path, ignored) {
    if (_watcherMap.hasOwnProperty(path)) {
        return;
    }

    try {
        var watcher = chokidar.watch(path, {
            persistent: true,
            ignoreInitial: true,
            ignorePermissionErrors: true,
            followSymlinks: true,
            ignored: ignored
        });

        watcher.on("all", function (event, filename, stats) {
            var type;
            switch (event) {
            case "change":
            case "ready":
                type = "change";
                break;
            case "add":
            case "addDir":
            case "unlink":
            case "unlinkDir":
                type = "rename";
                break;
            case "raw":
            case "error":
                return;
            default:
                console.error("Unknown watching event for file " + path + ": " + event);
                return;
            }

            if (!filename) {
                return;
            }
            // make sure it's normalized
            filename = filename.replace(/\\/g, "/");

            var parent = fspath.dirname(filename) + "/";
            var name = fspath.basename(filename);
            _domainManager.emitEvent("fileWatcher", "change", [parent, type, name, stats]);
        });

        _watcherMap[path] = watcher;

        watcher.on("error", function (err) {
            console.error("Error watching file " + path + ": " + (err && err.message));
            unwatchPath(path);
        });
    } catch (err) {
        console.warn("Failed to watch file " + path + ": " + (err && err.message));
    }
}

/**
 * Un-watch all files and directories.
 */
function unwatchAll() {
    var path;

    for (path in _watcherMap) {
        if (_watcherMap.hasOwnProperty(path)) {
            unwatchPath(path);
        }
    }
}

/**
 * Initialize the "fileWatcher" domain.
 * The fileWatcher domain handles watching and un-watching directories.
 */
function init(domainManager) {
    if (!domainManager.hasDomain("fileWatcher")) {
        domainManager.registerDomain("fileWatcher", {major: 0, minor: 1});
    }

    domainManager.registerCommand(
        "fileWatcher",
        "watchPath",
        watchPath,
        false,
        "Start watching a file or directory",
        [{
            name: "path",
            type: "string",
            description: "absolute filesystem path of the file or directory to watch"
        }, {
            name: "ignored",
            type: "array",
            description: "list of path to ignore"
        }]
    );
    domainManager.registerCommand(
        "fileWatcher",
        "unwatchPath",
        unwatchPath,
        false,
        "Stop watching a single file or a directory and it's descendants",
        [{
            name: "path",
            type: "string",
            description: "absolute filesystem path of the file or directory to unwatch"
        }]
    );
    domainManager.registerCommand(
        "fileWatcher",
        "unwatchAll",
        unwatchAll,
        false,
        "Stop watching all files and directories"
    );
    domainManager.registerEvent(
        "fileWatcher",
        "change",
        [
            {name: "path", type: "string"},
            {name: "event", type: "string"},
            {name: "filename", type: "string"},
            {name: "stats", type: "object"}
        ]
    );

    _domainManager = domainManager;
}

exports.init = init;
<commit_msg>do not hide true event names from shell file system<commit_after>/*
 * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint node: true */

"use strict";

var fspath = require("path");
var fs = require("fs");
var os = require("os");
var chokidar = require('chokidar');

var _domainManager,
    _watcherMap = {};

/**
 * @private
 * Un-watch a file or directory.
 * @param {string} path File or directory to unwatch.
 */
function _unwatchPath(path) {
    var watcher = _watcherMap[path];

    if (watcher) {
        try {
            watcher.close();
        } catch (err) {
            console.warn("Failed to unwatch file " + path + ": " + (err && err.message));
        } finally {
            delete _watcherMap[path];
        }
    }
}

/**
 * Un-watch a file or directory. For directories, unwatch all descendants.
 * @param {string} path File or directory to unwatch.
 */
function unwatchPath(path) {
    Object.keys(_watcherMap).forEach(function (keyPath) {
        if (keyPath.indexOf(path) === 0) {
            _unwatchPath(keyPath);
        }
    });
}

/**
 * Watch a file or directory.
 * @param {string} path File or directory to watch.
 * @param {array} ignored List of File or directory to NOT watch.
 */
function watchPath(path, ignored) {
    if (_watcherMap.hasOwnProperty(path)) {
        return;
    }

    try {
        var watcher = chokidar.watch(path, {
            persistent: true,
            ignoreInitial: true,
            ignorePermissionErrors: true,
            followSymlinks: true,
            ignored: ignored
        });

        watcher.on("all", function (event, filename, stats) {
            if (event === "raw" || event === "error" || !filename) {
                return;
            }
            // make sure it's normalized
            filename = filename.replace(/\\/g, "/");
            var parent = fspath.dirname(filename) + "/";
            var name = fspath.basename(filename);
            _domainManager.emitEvent("fileWatcher", "change", [parent, event, name, stats]);
        });

        _watcherMap[path] = watcher;

        watcher.on("error", function (err) {
            console.error("Error watching file " + path + ": " + (err && err.message));
            unwatchPath(path);
        });
    } catch (err) {
        console.warn("Failed to watch file " + path + ": " + (err && err.message));
    }
}

/**
 * Un-watch all files and directories.
 */
function unwatchAll() {
    var path;

    for (path in _watcherMap) {
        if (_watcherMap.hasOwnProperty(path)) {
            unwatchPath(path);
        }
    }
}

/**
 * Initialize the "fileWatcher" domain.
 * The fileWatcher domain handles watching and un-watching directories.
 */
function init(domainManager) {
    if (!domainManager.hasDomain("fileWatcher")) {
        domainManager.registerDomain("fileWatcher", {major: 0, minor: 1});
    }

    domainManager.registerCommand(
        "fileWatcher",
        "watchPath",
        watchPath,
        false,
        "Start watching a file or directory",
        [{
            name: "path",
            type: "string",
            description: "absolute filesystem path of the file or directory to watch"
        }, {
            name: "ignored",
            type: "array",
            description: "list of path to ignore"
        }]
    );
    domainManager.registerCommand(
        "fileWatcher",
        "unwatchPath",
        unwatchPath,
        false,
        "Stop watching a single file or a directory and it's descendants",
        [{
            name: "path",
            type: "string",
            description: "absolute filesystem path of the file or directory to unwatch"
        }]
    );
    domainManager.registerCommand(
        "fileWatcher",
        "unwatchAll",
        unwatchAll,
        false,
        "Stop watching all files and directories"
    );
    domainManager.registerEvent(
        "fileWatcher",
        "change",
        [
            {name: "path", type: "string"},
            {name: "event", type: "string"},
            {name: "filename", type: "string"},
            {name: "stats", type: "object"}
        ]
    );

    _domainManager = domainManager;
}

exports.init = init;
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////
// Autodesk.ADN.Viewing.Extension.GenericDockingPanel
// by Philippe Leefsma, May 2015
//
/////////////////////////////////////////////////////////////////////
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");

Autodesk.ADN.Viewing.Extension.GenericDockingPanel = function (viewer, options) {

  Autodesk.Viewing.Extension.call(this, viewer, options);

  var _panel = null;

  /////////////////////////////////////////////////////////////////
  // Extension load callback
  //
  /////////////////////////////////////////////////////////////////
  this.load = function () {

    _panel = new Panel(
      viewer.container,
      guid());

    _panel.setVisible(true);

    console.log('Autodesk.ADN.Viewing.Extension.GenericDockingPanel loaded');

    return true;
  }

  /////////////////////////////////////////////////////////////////
  //  Extension unload callback
  //
  /////////////////////////////////////////////////////////////////
  this.unload = function () {

    _panel.setVisible(false);

    console.log('Autodesk.ADN.Viewing.Extension.GenericDockingPanel unloaded');

    return true;
  }

  /////////////////////////////////////////////////////////////////
  // Generates random guid to use as DOM id
  //
  /////////////////////////////////////////////////////////////////
  function guid() {

    var d = new Date().getTime();

    var guid = 'xxxx-xxxx-xxxx-xxxx'.replace(
      /[xy]/g,
      function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
      });

    return guid;
  }

  /////////////////////////////////////////////////////////////////
  // The demo Panel
  //
  /////////////////////////////////////////////////////////////////
  var Panel = function(
    parentContainer, id) {

    var _thisPanel = this;

    _thisPanel.content = document.createElement('div');

    Autodesk.Viewing.UI.DockingPanel.call(
      this,
      parentContainer,
      id,
      'Temperatures Curve',
      {shadow:true});

    $(_thisPanel.container).addClass('docking-panel');

    /////////////////////////////////////////////////////////////
    // Custom html
    //
    /////////////////////////////////////////////////////////////

    var html = [
    ' <canvas id="canvasChart" height="150" width="305"></canvas>',
    // '',
    ''
    ];
    $(_thisPanel.container).append(html.join('\n'));

    gernerateTempChart();

    /////////////////////////////////////////////////////////////
    // setVisible override (not used in that sample)
    //
    /////////////////////////////////////////////////////////////
    _thisPanel.setVisible = function(show) {

      Autodesk.Viewing.UI.DockingPanel.prototype.
        setVisible.call(this, show);
    }

    /////////////////////////////////////////////////////////////
    // initialize override
    //
    /////////////////////////////////////////////////////////////
    _thisPanel.initialize = function() {

      this.title = this.createTitleBar(
        this.titleLabel ||
        this.container.id);

      this.closer = this.createCloseButton();

      this.container.appendChild(this.title);
      this.title.appendChild(this.closer);
      this.container.appendChild(this.content);

      this.initializeMoveHandlers(this.title);
      this.initializeCloseHandler(this.closer);
    };

    /////////////////////////////////////////////////////////////
    // onTitleDoubleClick override
    //
    /////////////////////////////////////////////////////////////
    var _isMinimized = false;

    _thisPanel.onTitleDoubleClick = function (event) {

      _isMinimized = !_isMinimized;

      if(_isMinimized) {

        $(_thisPanel.container).addClass(
          'docking-panel-minimized');
      }
      else {
        $(_thisPanel.container).removeClass(
          'docking-panel-minimized');
      }
    };
  };

  ////////////////////////////////////
  ///Generate the chart
  ///
  ////////////////////////////////////
  var gernerateTempChart = function(){

    var lineChartData = {
          labels : [],
          datasets : [
            {
              label: "Temperatures",
              fillColor : "rgba(220,220,220,0.2)",
              strokeColor : "rgba(220,220,220,1)",
              pointColor : "rgba(220,220,220,1)",
              pointStrokeColor : "#fff",
              pointHighlightFill : "#fff",
              pointHighlightStroke : "rgba(220,220,220,1)",
              data : []
            }
          ]
        }

    var updateData = function(lineChartData){

      dataloader.getLast10Temperatures(function(tempItems){

        //clear first
        lineChartData.labels.length = 0;
        lineChartData.datasets[0].data.length = 0;

        tempItems.forEach(function(tempItem){
          //add time as label
          var timeStamp = tempItem.timestamp;
          var lbl = new Date(timeStamp).toLocaleTimeString();

          lineChartData.labels.push(lbl);

          //add temperature values
          var temperature = tempItem.value;
          lineChartData.datasets[0].data.push(temperature);

        });

      });

    }

    var highTemperatureMonitor = function(){
      //hard coded
      var alertTemperature = 40;

      //the sensor on roof, dbid = 1735, hardcoded for demo
      var sensorDbId = 1735;

      var alerting = false;

      dataloader.getLastTemperature(function(response){

        var lastTemp = response.temperatureItem.value;

        if(lastTemp > alertTemperature) {
          viewer.setColorMaterial(sensorDbId,0xff0000);
          viewer.fitToView(sensorDbId);

          alerting = true;

        }else if(alerting){

          //dismiss alert

          viewer.restoreColorMaterial(sensorDbId);
          viewer.fitToView();

          alerting = false;

        }

      });

    }

    //generate the chart
    var ctx = document.getElementById("canvasChart").getContext("2d");

    setInterval(function(){

      updateData(lineChartData);

      window.myLine = new Chart(ctx).Line(lineChartData, {
        responsive: true
      });

      //start high temperature monitoring
      highTemperatureMonitor();

    },
    5000  //5 seconds refresh
    );

  }

  /////////////////////////////////////////////////////////////
  // Set up JS inheritance
  //
  /////////////////////////////////////////////////////////////
  Panel.prototype = Object.create(
    Autodesk.Viewing.UI.DockingPanel.prototype);

  Panel.prototype.constructor = Panel;

  /////////////////////////////////////////////////////////////
  // Add needed CSS
  //
  /////////////////////////////////////////////////////////////
  var css = [

    'div.docking-panel {',
      'top: 0px;',
      'left: 0px;',
      'width: 305px;',
      'height: 450px;',
      'resize: both;',
      'overflow: hidden;',
    '}',

    'div.docking-panel-minimized {',
      'height: 34px;',
      'min-height: 34px',
    '}'

  ].join('\n');

  $('').appendTo('head');
};

Autodesk.ADN.Viewing.Extension.GenericDockingPanel.prototype =
  Object.create(Autodesk.Viewing.Extension.prototype);

Autodesk.ADN.Viewing.Extension.GenericDockingPanel.prototype.constructor =
  Autodesk.ADN.Viewing.Extension.GenericDockingPanel;

Autodesk.Viewing.theExtensionManager.registerExtension(
  'Autodesk.ADN.Viewing.Extension.GenericDockingPanel',
  Autodesk.ADN.Viewing.Extension.GenericDockingPanel);
<commit_msg>bug fix<commit_after>/////////////////////////////////////////////////////////////////////
// Autodesk.ADN.Viewing.Extension.GenericDockingPanel
// by Philippe Leefsma, May 2015
//
/////////////////////////////////////////////////////////////////////
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");

Autodesk.ADN.Viewing.Extension.GenericDockingPanel = function (viewer, options) {

  Autodesk.Viewing.Extension.call(this, viewer, options);

  var _panel = null;

  /////////////////////////////////////////////////////////////////
  // Extension load callback
  //
  /////////////////////////////////////////////////////////////////
  this.load = function () {

    _panel = new Panel(
      viewer.container,
      guid());

    _panel.setVisible(true);

    console.log('Autodesk.ADN.Viewing.Extension.GenericDockingPanel loaded');

    return true;
  }

  /////////////////////////////////////////////////////////////////
  //  Extension unload callback
  //
  /////////////////////////////////////////////////////////////////
  this.unload = function () {

    _panel.setVisible(false);

    console.log('Autodesk.ADN.Viewing.Extension.GenericDockingPanel unloaded');

    return true;
  }

  /////////////////////////////////////////////////////////////////
  // Generates random guid to use as DOM id
  //
  /////////////////////////////////////////////////////////////////
  function guid() {

    var d = new Date().getTime();

    var guid = 'xxxx-xxxx-xxxx-xxxx'.replace(
      /[xy]/g,
      function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
      });

    return guid;
  }

  /////////////////////////////////////////////////////////////////
  // The demo Panel
  //
  /////////////////////////////////////////////////////////////////
  var Panel = function(
    parentContainer, id) {

    var _thisPanel = this;

    _thisPanel.content = document.createElement('div');

    Autodesk.Viewing.UI.DockingPanel.call(
      this,
      parentContainer,
      id,
      'Temperatures Curve',
      {shadow:true});

    $(_thisPanel.container).addClass('docking-panel');

    /////////////////////////////////////////////////////////////
    // Custom html
    //
    /////////////////////////////////////////////////////////////

    var html = [
    ' <canvas id="canvasChart" height="150" width="305"></canvas>',
    // '',
    ''
    ];
    $(_thisPanel.container).append(html.join('\n'));

    gernerateTempChart();

    /////////////////////////////////////////////////////////////
    // setVisible override (not used in that sample)
    //
    /////////////////////////////////////////////////////////////
    _thisPanel.setVisible = function(show) {

      Autodesk.Viewing.UI.DockingPanel.prototype.
        setVisible.call(this, show);
    }

    /////////////////////////////////////////////////////////////
    // initialize override
    //
    /////////////////////////////////////////////////////////////
    _thisPanel.initialize = function() {

      this.title = this.createTitleBar(
        this.titleLabel ||
        this.container.id);

      this.closer = this.createCloseButton();

      this.container.appendChild(this.title);
      this.title.appendChild(this.closer);
      this.container.appendChild(this.content);

      this.initializeMoveHandlers(this.title);
      this.initializeCloseHandler(this.closer);
    };

    /////////////////////////////////////////////////////////////
    // onTitleDoubleClick override
    //
    /////////////////////////////////////////////////////////////
    var _isMinimized = false;

    _thisPanel.onTitleDoubleClick = function (event) {

      _isMinimized = !_isMinimized;

      if(_isMinimized) {

        $(_thisPanel.container).addClass(
          'docking-panel-minimized');
      }
      else {
        $(_thisPanel.container).removeClass(
          'docking-panel-minimized');
      }
    };
  };

  ////////////////////////////////////
  ///Generate the chart
  ///
  ////////////////////////////////////
  var gernerateTempChart = function(){

    var lineChartData = {
          labels : [],
          datasets : [
            {
              label: "Temperatures",
              fillColor : "rgba(220,220,220,0.2)",
              strokeColor : "rgba(220,220,220,1)",
              pointColor : "rgba(220,220,220,1)",
              pointStrokeColor : "#fff",
              pointHighlightFill : "#fff",
              pointHighlightStroke : "rgba(220,220,220,1)",
              data : []
            }
          ]
        }

    var updateData = function(lineChartData){

      dataloader.getLast10Temperatures(function(tempItems){

        //clear first
        lineChartData.labels.length = 0;
        lineChartData.datasets[0].data.length = 0;

        tempItems.forEach(function(tempItem){
          //add time as label
          var timeStamp = tempItem.timestamp;
          var lbl = new Date(timeStamp).toLocaleTimeString();

          lineChartData.labels.push(lbl);

          //add temperature values
          var temperature = tempItem.value;
          lineChartData.datasets[0].data.push(temperature);

        });

      });

    }

    var highTemperatureMonitor = function(){
      //hard coded
      var alertTemperature = 40;

      //the sensor on roof, dbid = 1735, hardcoded for demo
      var sensorDbId = 1735;

      var alerting = false;

      dataloader.getLastTemperature(function(response){

        var lastTemp = response.temperatureItem.value;

        if(lastTemp > alertTemperature) {
          viewer.setColorMaterial(sensorDbId,0xff0000);
          viewer.fitToView(sensorDbId);

          alerting = true;

        }else if(alerting){

          //dismiss alert

          viewer.restoreColorMaterial(sensorDbId);
          viewer.fitToView();

          alerting = false;

        }

      });

    }

    //generate the chart
    var ctx = document.getElementById("canvasChart").getContext("2d");

    setInterval(function(){

      updateData(lineChartData);

      window.myLine = new Chart(ctx).Line(lineChartData, {
        responsive: true
      });

      //start high temperature monitoring
      highTemperatureMonitor();

    },
    5000  //5 seconds refresh
    );

  }

  /////////////////////////////////////////////////////////////
  // Set up JS inheritance
  //
  /////////////////////////////////////////////////////////////
  Panel.prototype = Object.create(
    Autodesk.Viewing.UI.DockingPanel.prototype);

  Panel.prototype.constructor = Panel;

  /////////////////////////////////////////////////////////////
  // Add needed CSS
  //
  /////////////////////////////////////////////////////////////
  var css = [

    'div.docking-panel {',
      'top: 0px;',
      'left: 0px;',
      'width: 305px;',
      'height: 450px;',
      'resize: both;',
      'overflow: hidden;',
    '}',

    'div.docking-panel-minimized {',
      'height: 34px;',
      'min-height: 34px',
    '}'

  ].join('\n');

  $('').appendTo('head');
};

Autodesk.ADN.Viewing.Extension.GenericDockingPanel.prototype =
  Object.create(Autodesk.Viewing.Extension.prototype);

Autodesk.ADN.Viewing.Extension.GenericDockingPanel.prototype.constructor =
  Autodesk.ADN.Viewing.Extension.GenericDockingPanel;

Autodesk.Viewing.theExtensionManager.registerExtension(
  'Autodesk.ADN.Viewing.Extension.GenericDockingPanel',
  Autodesk.ADN.Viewing.Extension.GenericDockingPanel);
<|endoftext|>


<commit_before>/*!
    Copyright (C) 2014 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: brad@reciprocitylabs.com
    Maintained By: brad@reciprocitylabs.com
*/

;(function(can, $, CMS) {

can.Observe("CMS.ModelHelpers.CycleTask", {
  findInCacheById : function() { return null; },
}, {
  init : function() {
    this.attr("owners", new CMS.Models.Person.List(this.owners));
  },
  save : function() {
    var that = this;
    // FIXME: temporary fix for 'Could not get any raw data while
    // converting using .models'
    this._data.owners = $.map(this._data.owners, function(owner){
      return {
        id: owner.id,
        type: owner.type,
      };
    });

    return new CMS.Models.TaskGroupTask({
      task_group: that.task_group,
      title: that.title,
      description: that.description,
      sort_index: Number.MAX_SAFE_INTEGER / 2,
      contact: that.contact,
      context: that.context
    }).save().then(function(task_group_task) {
      return new CMS.Models.CycleTaskGroupObjectTask({
        cycle: that.cycle,
        start_date: that.cycle.reify().start_date,
        end_date: that.cycle.reify().end_date,
        task_group_task: task_group_task,
        cycle_task_group_object: that.cycle_task_group_object,
        sort_index: that.sort_index,
        title: that.title,
        description: that.description,
        status: "Assigned",
        contact: that.contact,
        context: that.context
      }).save();
    });
  },
  computed_errors: can.compute(function() {
    var errors = null;
    if(!this.attr("title")) {
      errors = { title: "Must be defined" };
    }
    return errors;
  })
});

var approval_workflow_errors_compute;
can.Observe("CMS.ModelHelpers.ApprovalWorkflow", {
  defaults : {
    original_object: null
  }
}, {
  save: function() {
    var that = this,
        aws_dfd = this.original_object.get_binding("approval_workflows").refresh_list();

    return aws_dfd.then(function(aws){
      var ret;
      if (aws.length < 1) {
        ret = $.when(
          new CMS.Models.Workflow({
            frequency: "one_time",
            status: "Active",
            title: "Object review for "
                    + that.original_object.constructor.title_singular
                    + ' "' + that.original_object.title + '"',
            object_approval: true,
            notify_on_change: true,
            notify_custom_message: "

"
              + GGRC.current_user.name + " (" + GGRC.current_user.email
              + ") asked you to review newly created "
              + that.original_object.constructor.model_singular + ' "' + that.original_object.title
              + '" before ' + moment(that.end_date).format("MM/DD/YYYY") + ". "
              + "Click here to perform a review.",
            context: that.original_object.context
          }).save()
        ).then(function(wf) {
            return $.when(
              wf,
              new CMS.Models.TaskGroup({
                workflow : wf,
                title: "Object review for "
                        + that.original_object.constructor.title_singular
                        + ' "' + that.original_object.title + '"',
                contact: that.contact,
                context: wf.context
              }).save()
            );
        }).then(function(wf, tg) {
            return $.when(
              wf,
              new CMS.Models.TaskGroupTask({
                task_group: tg,
                start_date: moment().format('MM/DD/YYYY'),
                end_date: that.end_date,
                object_approval: true,
                sort_index: (Number.MAX_SAFE_INTEGER / 2).toString(10),
                contact: that.contact,
                context: wf.context,
                task_type: "text",
                title: "Object review for "
                        + that.original_object.constructor.title_singular
                        + ' "' + that.original_object.title + '"'
              }).save(),
              new CMS.Models.TaskGroupObject({
                task_group: tg,
                object: that.original_object,
                context: wf.context
              }).save()
            );
        });
      } else {
        ret = $.when(
          aws[0].instance.refresh(),
          $.when.apply(
            $,
            can.map(aws[0].instance.task_groups.reify(), function(tg) {
              return tg.refresh();
            })
          ).then(function() {
            return $.when.apply($, can.map(can.makeArray(arguments), function(tg) {
              return tg.attr("contact", that.contact).save().then(function(tg) {
                return $.when.apply($, can.map(tg.task_group_tasks.reify(), function(tgt) {
                  return tgt.refresh().then(function(tgt) {
                    return tgt.attr({
                      'contact': that.contact,
                      'end_date': that.end_date,
                      'start_date': moment().format('MM/DD/YYYY'),
                      'task_type': tgt.task_type || 'text'
                      }).save();
                  });
                }));
              });
            }));
          })
        );
      }

      return ret.then(function(wf) {
        return new CMS.Models.Cycle({
          workflow: wf,
          autogenerate: true,
          context: wf.context
        }).save();
      });
    });
  },
  computed_errors: (approval_workflow_errors_compute = can.compute(function() {
    var errors = null;
    if(!this.attr("contact")) {
      errors = { contact: "Must be defined" };
    }
    if(!this.attr("end_date")) {
      errors = $.extend(errors, { end_date : "Must be defined" });
    }
    return errors;
  })),
  computed_unsuppressed_errors: approval_workflow_errors_compute
});

})(this.can, this.can.$, this.CMS);
<commit_msg>this should fix the link in email<commit_after>/*!
    Copyright (C) 2014 Google Inc., authors, and contributors <see AUTHORS file>
    Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
    Created By: brad@reciprocitylabs.com
    Maintained By: brad@reciprocitylabs.com
*/

;(function(can, $, CMS) {

can.Observe("CMS.ModelHelpers.CycleTask", {
  findInCacheById : function() { return null; },
}, {
  init : function() {
    this.attr("owners", new CMS.Models.Person.List(this.owners));
  },
  save : function() {
    var that = this;
    // FIXME: temporary fix for 'Could not get any raw data while
    // converting using .models'
    this._data.owners = $.map(this._data.owners, function(owner){
      return {
        id: owner.id,
        type: owner.type,
      };
    });

    return new CMS.Models.TaskGroupTask({
      task_group: that.task_group,
      title: that.title,
      description: that.description,
      sort_index: Number.MAX_SAFE_INTEGER / 2,
      contact: that.contact,
      context: that.context
    }).save().then(function(task_group_task) {
      return new CMS.Models.CycleTaskGroupObjectTask({
        cycle: that.cycle,
        start_date: that.cycle.reify().start_date,
        end_date: that.cycle.reify().end_date,
        task_group_task: task_group_task,
        cycle_task_group_object: that.cycle_task_group_object,
        sort_index: that.sort_index,
        title: that.title,
        description: that.description,
        status: "Assigned",
        contact: that.contact,
        context: that.context
      }).save();
    });
  },
  computed_errors: can.compute(function() {
    var errors = null;
    if(!this.attr("title")) {
      errors = { title: "Must be defined" };
    }
    return errors;
  })
});

var approval_workflow_errors_compute;
can.Observe("CMS.ModelHelpers.ApprovalWorkflow", {
  defaults : {
    original_object: null
  }
}, {
  save: function() {
    var that = this,
        aws_dfd = this.original_object.get_binding("approval_workflows").refresh_list();

    return aws_dfd.then(function(aws){
      var ret;
      if (aws.length < 1) {
        ret = $.when(
          new CMS.Models.Workflow({
            frequency: "one_time",
            status: "Active",
            title: "Object review for "
                    + that.original_object.constructor.title_singular
                    + ' "' + that.original_object.title + '"',
            object_approval: true,
            notify_on_change: true,
            notify_custom_message: "

"
              + GGRC.current_user.name + " (" + GGRC.current_user.email
              + ") asked you to review newly created "
              + that.original_object.constructor.model_singular + ' "' + that.original_object.title
              + '" before ' + moment(that.end_date).format("MM/DD/YYYY") + ". "
              + "Click here to perform a review.",
            context: that.original_object.context
          }).save()
        ).then(function(wf) {
            return $.when(
              wf,
              new CMS.Models.TaskGroup({
                workflow : wf,
                title: "Object review for "
                        + that.original_object.constructor.title_singular
                        + ' "' + that.original_object.title + '"',
                contact: that.contact,
                context: wf.context
              }).save()
            );
        }).then(function(wf, tg) {
            return $.when(
              wf,
              new CMS.Models.TaskGroupTask({
                task_group: tg,
                start_date: moment().format('MM/DD/YYYY'),
                end_date: that.end_date,
                object_approval: true,
                sort_index: (Number.MAX_SAFE_INTEGER / 2).toString(10),
                contact: that.contact,
                context: wf.context,
                task_type: "text",
                title: "Object review for "
                        + that.original_object.constructor.title_singular
                        + ' "' + that.original_object.title + '"'
              }).save(),
              new CMS.Models.TaskGroupObject({
                task_group: tg,
                object: that.original_object,
                context: wf.context
              }).save()
            );
        });
      } else {
        ret = $.when(
          aws[0].instance.refresh(),
          $.when.apply(
            $,
            can.map(aws[0].instance.task_groups.reify(), function(tg) {
              return tg.refresh();
            })
          ).then(function() {
            return $.when.apply($, can.map(can.makeArray(arguments), function(tg) {
              return tg.attr("contact", that.contact).save().then(function(tg) {
                return $.when.apply($, can.map(tg.task_group_tasks.reify(), function(tgt) {
                  return tgt.refresh().then(function(tgt) {
                    return tgt.attr({
                      'contact': that.contact,
                      'end_date': that.end_date,
                      'start_date': moment().format('MM/DD/YYYY'),
                      'task_type': tgt.task_type || 'text'
                      }).save();
                  });
                }));
              });
            }));
          })
        );
      }

      return ret.then(function(wf) {
        return new CMS.Models.Cycle({
          workflow: wf,
          autogenerate: true,
          context: wf.context
        }).save();
      });
    });
  },
  computed_errors: (approval_workflow_errors_compute = can.compute(function() {
    var errors = null;
    if(!this.attr("contact")) {
      errors = { contact: "Must be defined" };
    }
    if(!this.attr("end_date")) {
      errors = $.extend(errors, { end_date : "Must be defined" });
    }
    return errors;
  })),
  computed_unsuppressed_errors: approval_workflow_errors_compute
});

})(this.can, this.can.$, this.CMS);
<|endoftext|>


<commit_before>/* eslint-disable import/no-unresolved, import/extensions */
import { View } from 'react-native';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
/* eslint-enable import/no-unresolved, import/extensions */
import RippleFeedback from '../RippleFeedback';

import Title from './Title.react';
import Content from './Content.react';
import Actions from './Actions.react';

const propTypes = {
    onPress: PropTypes.func,
    children: PropTypes.node.isRequired,
    style: PropTypes.object,
};
const defaultProps = {
    onPress: null,
    style: {},
};
const contextTypes = {
    uiTheme: PropTypes.object.isRequired,
};

function getStyles(props, context) {
    const { dialog } = context.uiTheme;

    return {
        container: [
            dialog.container,
            props.style.container,
        ],
    };
}

class Dialog extends PureComponent {
    render() {
        const { onPress, children } = this.props;

        const styles = getStyles(this.props, this.context);

        return (
            <RippleFeedback onPress={onPress} >
                <View style={styles.container} pointerEvents="box-only">
                    {children}
                </View>
            </RippleFeedback>
        );
    }
}

Dialog.propTypes = propTypes;
Dialog.defaultProps = defaultProps;
Dialog.contextTypes = contextTypes;

Dialog.Title = Title;
Dialog.Content = Content;
Dialog.Actions = Actions;

export default Dialog;
<commit_msg>Fix dialog subview clicks (#220)<commit_after>/* eslint-disable import/no-unresolved, import/extensions */
import { View } from 'react-native';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
/* eslint-enable import/no-unresolved, import/extensions */
import RippleFeedback from '../RippleFeedback';

import Title from './Title.react';
import Content from './Content.react';
import Actions from './Actions.react';

const propTypes = {
    onPress: PropTypes.func,
    children: PropTypes.node.isRequired,
    style: PropTypes.object,
};
const defaultProps = {
    onPress: null,
    style: {},
};
const contextTypes = {
    uiTheme: PropTypes.object.isRequired,
};

function getStyles(props, context) {
    const { dialog } = context.uiTheme;

    return {
        container: [
            dialog.container,
            props.style.container,
        ],
    };
}

class Dialog extends PureComponent {
    render() {
        const { onPress, children } = this.props;

        const styles = getStyles(this.props, this.context);

        return (
            <RippleFeedback onPress={onPress}>
                <View style={styles.container}>
                    {children}
                </View>
            </RippleFeedback>
        );
    }
}

Dialog.propTypes = propTypes;
Dialog.defaultProps = defaultProps;
Dialog.contextTypes = contextTypes;

Dialog.Title = Title;
Dialog.Content = Content;
Dialog.Actions = Actions;

export default Dialog;
<|endoftext|>


<commit_before>
const widgetize = require('widgetize');
const template = require('./TradePrices.html');
const pkg = require('./package.json');
const d3 = require('d3');

const MARGIN_TOP = 50;
const MARGIN_BOTTOM = 50;
const MARGIN_LEFT = 80;
const MARGIN_RIGHT = 20;

/**
 * Trade Prices Widget
 */
class TradePrices extends widgetize.base(HTMLElement)
{
	init()
	{
		this._width = 0;

		this._height = 0;

		this._data = [];

		this._graph = null;

		this._xAxis = null;

		this._yAxis = null;

		this._xAxisLabel = null;

		this._yAxisLabel = null;

		this._toolTip = null;

		this._xScale = null;

		this._yScale = null;

		this._toolTopLabel = null;
	}

	get width()
	{
		return this._width;
	}

	set width(value)
	{
		if (value !== this._width)
		{
			this._width = value;
			this.invalidate();
		}
	}

	get height()
	{
		return this._height;
	}

	set height(value)
	{
		if (value !== this._height)
		{
			this._height = value;
			this.invalidate();
		}
	}

	get data()
	{
		return this._data;
	}

	set data(value)
	{
		if (value !== this._data && Array.isArray(value) )
		{
			this._data = value;
			this.invalidate();
		}
	}

	attach(dom)
	{
		this._graph = d3.select(dom).append('svg')
			.attr('width', this._width)
			.attr('height', this.height);

		this._xAxis = this._graph.append('svg:g')
			.attr('class', 'x axis');

		this._xAxisLabel = this._xAxis.append('text')
			.attr('y', 40)
			.attr('class', 'axis-label')
			.text('Trade Time');

		this._yAxis = this._graph.append('svg:g')
			.attr('class', 'y axis')
			.attr('transform', 'translate(' + MARGIN_LEFT + ',0)');

		this._yAxisLabel = this._graph.append('text')
			.attr('transform', 'rotate(-90)')
			.attr('y', 0)
			.attr('dy', '1em')
			.attr('class', 'axis-label')
			.text('Trade Price');

		this._voronoiGroup = this._graph.append('svg:g')
			.attr('class', 'voronoi');
	}

	update()
	{
		let data = this._data.concat();

		data.forEach((item) => {
			item.time = new Date(item.time);
		});

		this._xScale = d3.time.scale()
			.range([MARGIN_LEFT, this._width - MARGIN_RIGHT])
			.domain([
				d3.min(data, xAxisValue),
				d3.max(data, xAxisValue)
			]);

		this._xAxis.attr('transform', 'translate(0,' + (this._height - MARGIN_BOTTOM) + ')')
             .call(xAxisFactory(this._xScale));

		this._xAxisLabel.attr('x', (this._width - MARGIN_RIGHT)/2)

		this._yScale = d3.scale.linear()
			.range([this._height - MARGIN_TOP, MARGIN_BOTTOM])
			.domain([
				d3.min(data, yAxisValue),
				d3.max(data, yAxisValue)
			]);

        this._yAxis.call(yAxisFactory(this._yScale));

		this._yAxisLabel.attr('x', 0 - (this._height / 2));

		let voronoi = d3.geom.voronoi()
			.x((d) => { return this._xScale(d.time); })
			.y((d) => { return this._yScale(d.price); })
			.clipExtent([[MARGIN_LEFT, MARGIN_TOP], [this._width - MARGIN_RIGHT, this._height - MARGIN_BOTTOM]]);

		let dataGroup = d3.nest()
			.key(item => item.exchange)
			.entries(data)
			.sort(sortGroup);

		let line = lineFactory(this._xScale, this._yScale);

		let lines = this._graph.selectAll('path.line').data(dataGroup, exchange => exchange.key);

		lines.enter().append('svg:path')
				.attr('class', exchange => {
					return 'line line-' + exchange.key;
				})
				.attr('id', exchange => {
					return 'line_' + exchange.key;
				});

		lines.transition()
			.attr('d', exchange => line(exchange.values));

		lines.exit().remove();

		let colSpace = this._width / dataGroup.length;

		let legends = this._graph.selectAll('text.legend').data(dataGroup, exchange => exchange.key);

		legends.enter().append('text')
				.attr('y', 30)
				.attr('class', exchange => {
					return 'legend legend-' + exchange.key;
				})
				.text(exchange => exchange.key);

		legends.transition()
			.attr('x', (exchange, index) => {
				return (colSpace/2) + index*colSpace;
			});

		legends.exit().remove();

		let voronoiPaths = this._voronoiGroup.selectAll('path').data(voronoi(this._data));

		voronoiPaths.enter().append('svg:path')
				.on('mouseover', () => {
					this._toolTip.style('display', null);
				})
				.on('mouseout', onMouseOut.bind(this));

		voronoiPaths.attr('d', cord => {
			return 'M' + cord.join('L') + 'Z';
		});

		voronoiPaths.exit().remove();

		this._toolTip = this._graph.append('svg:g')
			.attr('class', 'toolTip')
			.attr('width', 50)
			.attr('height', 50)
			.style('display', 'none');

		this._toolTip.append('svg:circle')
				.style('fill', 'none')
				.style('stroke', 'blue')
				.attr('x', 50)
				.attr('y', 50)
				.attr('r', 4);

		this._toolTopLabel = this._toolTip.append('svg:text')
			.attr('y', -10);
	}

}

module.exports = widgetize(pkg.name, TradePrices, template);

/* PRIVAYE */

function xAxisValue(item)
{
	return item.time;
}

function yAxisValue(item)
{
	return item.price;
}

function xAxisFactory(xScale)
{
	return d3.svg.axis()
		.scale(xScale)
		.tickFormat(d3.time.format('%H:%M'))
		.orient('bottom');
}

function yAxisFactory(yScale)
{
	return d3.svg.axis()
		.scale(yScale)
		.orient('left');
}

function lineFactory(xScale, yScale)
{
	return d3.svg.line()
		.x(item => xScale(xAxisValue(item)))
		.y(item => yScale(yAxisValue(item)));
}

function onMouseOut(cord)
{
	let trade = cord.point;

	this._toolTip.style('display', 'none');

	this._toolTip
		.attr('transform', 'translate(' + this._xScale(xAxisValue(trade)) + ',' + this._yScale(yAxisValue(trade)) + ')');

	this._toolTopLabel
		.text(trade.price);
}

function sortGroup(item1, item2)
{
	if (item1.key > item2.key)
	{
		return 1;
	}
	else if (item1.key < item2.key)
	{
		return -1;
	}
	else
	{
		return 0;
	}
}<commit_msg>More efficient mouse handling<commit_after>
const widgetize = require('widgetize');
const template = require('./TradePrices.html');
const pkg = require('./package.json');
const d3 = require('d3');

const MARGIN_TOP = 50;
const MARGIN_BOTTOM = 50;
const MARGIN_LEFT = 80;
const MARGIN_RIGHT = 20;

/**
 * Trade Prices Widget
 */
class TradePrices extends widgetize.base(HTMLElement)
{
	init()
	{
		this._width = 0;

		this._height = 0;

		this._data = [];

		this._graph = null;

		this._xAxis = null;

		this._yAxis = null;

		this._xAxisLabel = null;

		this._yAxisLabel = null;

		this._toolTip = null;

		this._xScale = null;

		this._yScale = null;

		this._toolTopLabel = null;
	}

	get width()
	{
		return this._width;
	}

	set width(value)
	{
		if (value !== this._width)
		{
			this._width = value;
			this.invalidate();
		}
	}

	get height()
	{
		return this._height;
	}

	set height(value)
	{
		if (value !== this._height)
		{
			this._height = value;
			this.invalidate();
		}
	}

	get data()
	{
		return this._data;
	}

	set data(value)
	{
		if (value !== this._data && Array.isArray(value) )
		{
			this._data = value;
			this.invalidate();
		}
	}

	attach(dom)
	{
		this._graph = d3.select(dom).append('svg')
			.attr('width', this._width)
			.attr('height', this.height);

		this._xAxis = this._graph.append('svg:g')
			.attr('class', 'x axis');

		this._xAxisLabel = this._xAxis.append('text')
			.attr('y', 40)
			.attr('class', 'axis-label')
			.text('Trade Time');

		this._yAxis = this._graph.append('svg:g')
			.attr('class', 'y axis')
			.attr('transform', 'translate(' + MARGIN_LEFT + ',0)');

		this._yAxisLabel = this._graph.append('text')
			.attr('transform', 'rotate(-90)')
			.attr('y', 0)
			.attr('dy', '1em')
			.attr('class', 'axis-label')
			.text('Trade Price');

		this._voronoiGroup = this._graph.append('svg:g')
			.attr('class', 'voronoi')
				.on('mouseover', () => {
					this._toolTip.style('display', null);
				})
				.on('mouseout', () => {
					this._toolTip.style('display', 'none');
				})
				.on('mousemove', onMouseMove.bind(this));;
	}

	update()
	{
		let data = this._data.concat();

		data.forEach((item) => {
			item.time = new Date(item.time);
		});

		this._xScale = d3.time.scale()
			.range([MARGIN_LEFT, this._width - MARGIN_RIGHT])
			.domain([
				d3.min(data, xAxisValue),
				d3.max(data, xAxisValue)
			]);

		this._xAxis.attr('transform', 'translate(0,' + (this._height - MARGIN_BOTTOM) + ')')
             .call(xAxisFactory(this._xScale));

		this._xAxisLabel.attr('x', (this._width - MARGIN_RIGHT)/2)

		this._yScale = d3.scale.linear()
			.range([this._height - MARGIN_TOP, MARGIN_BOTTOM])
			.domain([
				d3.min(data, yAxisValue),
				d3.max(data, yAxisValue)
			]);

        this._yAxis.call(yAxisFactory(this._yScale));

		this._yAxisLabel.attr('x', 0 - (this._height / 2));

		let voronoi = d3.geom.voronoi()
			.x((d) => { return this._xScale(d.time); })
			.y((d) => { return this._yScale(d.price); })
			.clipExtent([[MARGIN_LEFT, MARGIN_TOP], [this._width - MARGIN_RIGHT, this._height - MARGIN_BOTTOM]]);

		let dataGroup = d3.nest()
			.key(item => item.exchange)
			.entries(data)
			.sort(sortGroup);

		let line = lineFactory(this._xScale, this._yScale);

		let lines = this._graph.selectAll('path.line').data(dataGroup, exchange => exchange.key);

		lines.enter().append('svg:path')
				.attr('class', exchange => {
					return 'line line-' + exchange.key;
				})
				.attr('id', exchange => {
					return 'line_' + exchange.key;
				});

		lines.transition()
			.attr('d', exchange => line(exchange.values));

		lines.exit().remove();

		let colSpace = this._width / dataGroup.length;

		let legends = this._graph.selectAll('text.legend').data(dataGroup, exchange => exchange.key);

		legends.enter().append('text')
				.attr('y', 30)
				.attr('class', exchange => {
					return 'legend legend-' + exchange.key;
				})
				.text(exchange => exchange.key);

		legends.transition()
			.attr('x', (exchange, index) => {
				return (colSpace/2) + index*colSpace;
			});

		legends.exit().remove();

		let voronoiPaths = this._voronoiGroup.selectAll('path').data(voronoi(this._data));

		voronoiPaths.enter().append('svg:path');

		voronoiPaths.attr('d', cord => {
			return 'M' + cord.join('L') + 'Z';
		});

		voronoiPaths.exit().remove();

		this._toolTip = this._graph.append('svg:g')
			.attr('class', 'toolTip')
			.attr('width', 50)
			.attr('height', 50)
			.style('display', 'none');

		this._toolTip.append('svg:circle')
				.style('fill', 'none')
				.style('stroke', 'blue')
				.attr('x', 50)
				.attr('y', 50)
				.attr('r', 4);

		this._toolTopLabel = this._toolTip.append('svg:text')
			.attr('y', -10);
	}

}

module.exports = widgetize(pkg.name, TradePrices, template);

/* PRIVAYE */

function xAxisValue(item)
{
	return item.time;
}

function yAxisValue(item)
{
	return item.price;
}

function xAxisFactory(xScale)
{
	return d3.svg.axis()
		.scale(xScale)
		.tickFormat(d3.time.format('%H:%M'))
		.orient('bottom');
}

function yAxisFactory(yScale)
{
	return d3.svg.axis()
		.scale(yScale)
		.orient('left');
}

function lineFactory(xScale, yScale)
{
	return d3.svg.line()
		.x(item => xScale(xAxisValue(item)))
		.y(item => yScale(yAxisValue(item)));
}

function onMouseMove()
{
	let element = d3.event.target;

	let trade = d3.select(element).datum().point;

	this._toolTip
		.attr('transform', 'translate(' + this._xScale(xAxisValue(trade)) + ',' + this._yScale(yAxisValue(trade)) + ')');

	this._toolTopLabel
		.text(trade.price);
}

function sortGroup(item1, item2)
{
	if (item1.key > item2.key)
	{
		return 1;
	}
	else if (item1.key < item2.key)
	{
		return -1;
	}
	else
	{
		return 0;
	}
}<|endoftext|>


<commit_before>/*global Clipboard*/
import Ember from 'ember';

export default Ember.Component.extend({
  actionLabel: 'Copy',
  classNames: ['click-to-copy'],
  Clipboard: Clipboard,
  errorMessage: 'Press ⌘+C to copy',
  isTooltipped: false,
  message: null,
  successMessage: 'Copied!',
  tagName: 'span',
  text: null,

  dataClipboardText: Ember.computed.alias('text'),

  attributeBindings: ['dataClipboardText:data-clipboard-text',
                      'message:data-message'],

  classNameBindings: ['isTooltipped:tooltipped'],

  setupClipboard: Ember.on('didInsertElement', function(){
    this.clipboard = new this.Clipboard('#' + this.elementId);
    this.clipboard.on('success', Ember.run.bind(this, 'success'));
    this.clipboard.on('error', Ember.run.bind(this, 'error'));
  }),

  success: function(){
    this.set('message', this.successMessage);
    this.showMessage();
  },

  error: function(){
    this.set('message', this.errorMessage);
    this.showMessage();
  },

  showMessage: function() {
    this.set('isTooltipped', true);

    Ember.run.later(() => {
      if (!this.isDestroying && !this.isDestroyed) {
        this.set('isTooltipped', false);
      }
    });
  }
});
<commit_msg>Added wait of 3s to the clipboard tooltip removal.<commit_after>/*global Clipboard*/
import Ember from 'ember';

export default Ember.Component.extend({
  actionLabel: 'Copy',
  classNames: ['click-to-copy'],
  Clipboard: Clipboard,
  errorMessage: 'Press ⌘+C to copy',
  isTooltipped: false,
  message: null,
  successMessage: 'Copied!',
  tagName: 'span',
  text: null,

  dataClipboardText: Ember.computed.alias('text'),

  attributeBindings: ['dataClipboardText:data-clipboard-text',
                      'message:data-message'],

  classNameBindings: ['isTooltipped:tooltipped'],

  setupClipboard: Ember.on('didInsertElement', function(){
    this.clipboard = new this.Clipboard('#' + this.elementId);
    this.clipboard.on('success', Ember.run.bind(this, 'success'));
    this.clipboard.on('error', Ember.run.bind(this, 'error'));
  }),

  success: function(){
    this.set('message', this.successMessage);
    this.showMessage();
  },

  error: function(){
    this.set('message', this.errorMessage);
    this.showMessage();
  },

  showMessage: function() {
    this.set('isTooltipped', true);

    Ember.run.later(() => {
      if (!this.isDestroying && !this.isDestroyed) {
        this.set('isTooltipped', false);
      }
    }, 3000);
  }
});
<|endoftext|>


<commit_before>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var React = require('react');
var _ = require('lodash');
var cx = require('react/lib/cx');

var ModalOverlay = require('../ModalOverlay');

var PatientCard = React.createClass({
  propTypes: {
    href: React.PropTypes.string,
    onClick: React.PropTypes.func,
    onRemovePatient: React.PropTypes.func,
    patient: React.PropTypes.object
  },

  getInitialState: function() {
    return {
      showModalOverlay: false
    };
  },

  render: function() {
    var patient = this.props.patient;
    var self = this;
    var classes = cx({
      'patientcard': true
    });

    var remove = (function(patient) {

        if (_.isEmpty(patient.permissions) === false && (!patient.permissions.admin && !patient.permissions.root)) {

          var title = 'Remove yourself from ' + patient.profile.fullName + "'s care team.";

          return (
            /* jshint ignore:start */

            /* jshint ignore:end */
          );
        }
    })(patient);

    var permissions = (function(patient) {
      var classes = {
        'Navbar-icon': true,
        'patientcard-permissions-icon': true
      };

      if(_.isEmpty(patient.permissions) === false && (patient.permissions.root || patient.permissions.admin || patient.permissions.upload)) {
        classes['icon-permissions-upload'] = true;
      } else {
        return null;
      }

      classes = cx(classes);

      return (
        /* jshint ignore:start */

        /* jshint ignore:end */
      );
    })(patient);

    /* jshint ignore:start */
    return (

          {patient.profile.fullName}

          {remove}
          {permissions}

        {this.renderModalOverlay()}

    );
    /* jshint ignore:end */
  },

  renderRemoveDialog: function(patient) {
    return (
      /* jshint ignore:start */

{"Are you sure you want to leave this person's Care Team? You will no longer be able to view their data."}

          <button className="PatientInfo-button PatientInfo-button--secondary" type="button" onClick={this.overlayClickHandler}>Cancel</button>
          <button className="PatientInfo-button PatientInfo-button--primary" type="submit" onClick={this.handleRemovePatient(patient)}>{"I'm sure, remove me."}</button>

      /* jshint ignore:end */
    );
  },

  handleRemovePatient: function(patient) {
    var self = this;

    return function() {
      self.props.onRemovePatient(patient.userid, function(err) {
          self.setState({
            showModalOverlay: false,
          });
        }
      );
    };
  },

  handleRemove: function(patient) {
    var self = this;

    return function() {
      self.setState({
        showModalOverlay: true,
        dialog: self.renderRemoveDialog(patient)
      });
    };
  },

  overlayClickHandler: function() {
    this.setState({
      showModalOverlay: false
    });
  },

  renderModalOverlay: function() {

    return (
      /* jshint ignore:start */
      <ModalOverlay
        show={this.state.showModalOverlay}
        dialog={this.state.dialog}
        overlayClickHandler={this.overlayClickHandler}/>
      /* jshint ignore:end */
    );

  }
});

module.exports = PatientCard;
<commit_msg>fix case<commit_after>/** @jsx React.DOM */
/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var React = require('react');
var _ = require('lodash');
var cx = require('react/lib/cx');

var ModalOverlay = require('../modaloverlay');

var PatientCard = React.createClass({
  propTypes: {
    href: React.PropTypes.string,
    onClick: React.PropTypes.func,
    onRemovePatient: React.PropTypes.func,
    patient: React.PropTypes.object
  },

  getInitialState: function() {
    return {
      showModalOverlay: false
    };
  },

  render: function() {
    var patient = this.props.patient;
    var self = this;
    var classes = cx({
      'patientcard': true
    });

    var remove = (function(patient) {

        if (_.isEmpty(patient.permissions) === false && (!patient.permissions.admin && !patient.permissions.root)) {

          var title = 'Remove yourself from ' + patient.profile.fullName + "'s care team.";

          return (
            /* jshint ignore:start */

            /* jshint ignore:end */
          );
        }
    })(patient);

    var permissions = (function(patient) {
      var classes = {
        'Navbar-icon': true,
        'patientcard-permissions-icon': true
      };

      if(_.isEmpty(patient.permissions) === false && (patient.permissions.root || patient.permissions.admin || patient.permissions.upload)) {
        classes['icon-permissions-upload'] = true;
      } else {
        return null;
      }

      classes = cx(classes);

      return (
        /* jshint ignore:start */

        /* jshint ignore:end */
      );
    })(patient);

    /* jshint ignore:start */
    return (

          {patient.profile.fullName}

          {remove}
          {permissions}

        {this.renderModalOverlay()}

    );
    /* jshint ignore:end */
  },

  renderRemoveDialog: function(patient) {
    return (
      /* jshint ignore:start */

{"Are you sure you want to leave this person's Care Team? You will no longer be able to view their data."}

          <button className="PatientInfo-button PatientInfo-button--secondary" type="button" onClick={this.overlayClickHandler}>Cancel</button>
          <button className="PatientInfo-button PatientInfo-button--primary" type="submit" onClick={this.handleRemovePatient(patient)}>{"I'm sure, remove me."}</button>

      /* jshint ignore:end */
    );
  },

  handleRemovePatient: function(patient) {
    var self = this;

    return function() {
      self.props.onRemovePatient(patient.userid, function(err) {
          self.setState({
            showModalOverlay: false,
          });
        }
      );
    };
  },

  handleRemove: function(patient) {
    var self = this;

    return function() {
      self.setState({
        showModalOverlay: true,
        dialog: self.renderRemoveDialog(patient)
      });
    };
  },

  overlayClickHandler: function() {
    this.setState({
      showModalOverlay: false
    });
  },

  renderModalOverlay: function() {

    return (
      /* jshint ignore:start */
      <ModalOverlay
        show={this.state.showModalOverlay}
        dialog={this.state.dialog}
        overlayClickHandler={this.overlayClickHandler}/>
      /* jshint ignore:end */
    );

  }
});

module.exports = PatientCard;
<|endoftext|>


<commit_before>import $ from 'blingblingjs'

export default class SelectionLabel extends HTMLElement {

  constructor() {
    super()
    this.$shadow = this.attachShadow({mode: 'open'})
  }

  connectedCallback() {
    $('a', this.$shadow).on('click mouseenter', this.dispatchQuery.bind(this))
  }

  disconnectedCallback() {
    $('a', this.$shadow).off('click', this.dispatchQuery)
  }

  dispatchQuery(e) {
    this.$shadow.host.dispatchEvent(new CustomEvent('query', {
      bubbles: true,
      detail:   {
        text:       e.target.textContent,
        activator:  e.type,
      }
    }))
  }

  set text(content) {
    this._text = content
  }

  set position({boundingRect, node_label_id}) {
    this.$shadow.innerHTML  = this.render(boundingRect, node_label_id)
  }

  set update({x,y}) {
    const label = this.$shadow.children[1]
    label.style.top  = y + window.scrollY + 'px'
    label.style.left = x - 1 + 'px'
  }

  render({ x, y, width, height, top, left }, node_label_id) {
    this.$shadow.host.setAttribute('data-label-id', node_label_id)

    return `
      ${this.styles({top,left})}

        ${this._text}

    `
  }

  styles({top,left}) {
    return `

    `
  }
}

customElements.define('pb-label', SelectionLabel)<commit_msg>fixes jitter after update runs<commit_after>import $ from 'blingblingjs'

export default class SelectionLabel extends HTMLElement {

  constructor() {
    super()
    this.$shadow = this.attachShadow({mode: 'open'})
  }

  connectedCallback() {
    $('a', this.$shadow).on('click mouseenter', this.dispatchQuery.bind(this))
  }

  disconnectedCallback() {
    $('a', this.$shadow).off('click', this.dispatchQuery)
  }

  dispatchQuery(e) {
    this.$shadow.host.dispatchEvent(new CustomEvent('query', {
      bubbles: true,
      detail:   {
        text:       e.target.textContent,
        activator:  e.type,
      }
    }))
  }

  set text(content) {
    this._text = content
  }

  set position({boundingRect, node_label_id}) {
    this.$shadow.innerHTML  = this.render(boundingRect, node_label_id)
  }

  set update({x,y}) {
    const label = this.$shadow.children[1]
    label.style.top  = y + window.scrollY + 'px'
    label.style.left = x - 1 + 'px'
  }

  render({ x, y, width, height, top, left }, node_label_id) {
    this.$shadow.host.setAttribute('data-label-id', node_label_id)

    return `
      ${this.styles({top,left})}

        ${this._text}

    `
  }

  styles({top,left}) {
    return `

    `
  }
}

customElements.define('pb-label', SelectionLabel)<|endoftext|>


<commit_before>// @flow
import React, { Component, PropTypes } from 'react';
import { observer } from 'mobx-react';
import Dialog from 'react-toolbox/lib/dialog/Dialog';
import Input from 'react-toolbox/lib/input/Input';
import Dropdown from 'react-toolbox/lib/dropdown/Dropdown';
import MobxReactForm from 'mobx-react-form';
import { defineMessages, intlShape } from 'react-intl';
import styles from './WalletCreateForm.scss';

const messages = defineMessages({
  walletName: {
    id: 'wallet.create.form.name.label',
    defaultMessage: '!!!Wallet Name',
    description: 'Label for the "Wallet Name" text input in the wallet create form.'
  },
  currency: {
    id: 'wallet.create.form.currency.label',
    defaultMessage: '!!!Currency',
    description: 'Label for the "Currency" dropdown in the wallet create form.'
  },
});

const currencies = [
  { value: 'ada', label: 'ADA' },
];

@observer
export default class WalletCreateForm extends Component {

  static propTypes = {
    validator: PropTypes.instanceOf(MobxReactForm),
  };

  static contextTypes = {
    intl: intlShape.isRequired,
  };

  state: {
    isSubmitting: boolean
  };

  state = {
    isSubmitting: false
  };

  actions = [
    {
      label: 'Create personal wallet',
      onClick: () => {
        this.props.validator.submit({
          onSuccess: (form) => {
            this.setState({ isSubmitting: true });
            form.onSuccess(form);
          },
          onError: (form) => {
            this.setState({ isSubmitting: false });
            form.onError(form);
          }
        });
      }
    }
  ];

  render() {
    const { intl } = this.context;
    const { validator } = this.props;
    const walletName = validator.$('walletName');
    const currency = validator.$('currency');
    return (

        <Dialog
          className={this.state.isSubmitting ? styles.isSubmitting : null}
          title="Create Wallet"
          actions={this.actions}
          active
        >

          <Input
            type="text"
            label={intl.formatMessage(messages.walletName)}
            hint="e.g: Shopping Wallet"
            value={walletName.value}
            error={walletName.error}
            onChange={walletName.onChange}
            onFocus={walletName.onFocus}
            onBlur={walletName.onBlur}
          />

          <Dropdown
            label={intl.formatMessage(messages.currency)}
            value={currency.value}
            onChange={currency.onChange}
            onFocus={currency.onFocus}
            onBlur={currency.onBlur}
            error={currency.error}
            source={currencies}
          />

        </Dialog>

    );
  }

}
<commit_msg>submit wallet create form on ENTER key in name field<commit_after>// @flow
import React, { Component, PropTypes } from 'react';
import { observer } from 'mobx-react';
import Dialog from 'react-toolbox/lib/dialog/Dialog';
import Input from 'react-toolbox/lib/input/Input';
import Dropdown from 'react-toolbox/lib/dropdown/Dropdown';
import MobxReactForm from 'mobx-react-form';
import { defineMessages, intlShape } from 'react-intl';
import styles from './WalletCreateForm.scss';

const messages = defineMessages({
  walletName: {
    id: 'wallet.create.form.name.label',
    defaultMessage: '!!!Wallet Name',
    description: 'Label for the "Wallet Name" text input in the wallet create form.'
  },
  currency: {
    id: 'wallet.create.form.currency.label',
    defaultMessage: '!!!Currency',
    description: 'Label for the "Currency" dropdown in the wallet create form.'
  },
});

const currencies = [
  { value: 'ada', label: 'ADA' },
];

@observer
export default class WalletCreateForm extends Component {

  static propTypes = {
    validator: PropTypes.instanceOf(MobxReactForm),
  };

  static contextTypes = {
    intl: intlShape.isRequired,
  };

  state: {
    isSubmitting: boolean
  };

  state = {
    isSubmitting: false
  };

  actions = [
    {
      label: 'Create personal wallet',
      onClick: this.submit
    }
  ];

  submit() {
    this.props.validator.submit({
      onSuccess: (form) => {
        this.setState({ isSubmitting: true });
        form.onSuccess(form);
      },
      onError: (form) => {
        this.setState({ isSubmitting: false });
        form.onError(form);
      }
    });
  }

  checkForEnterKey(event: KeyboardEvent) {
    if (event.key === 'Enter') {
      this.submit();
    }
  }

  render() {
    const { intl } = this.context;
    const { validator } = this.props;
    const walletName = validator.$('walletName');
    const currency = validator.$('currency');
    return (

        <Dialog
          className={this.state.isSubmitting ? styles.isSubmitting : null}
          title="Create Wallet"
          actions={this.actions}
          active
        >

          <Input
            type="text"
            label={intl.formatMessage(messages.walletName)}
            hint="e.g: Shopping Wallet"
            value={walletName.value}
            error={walletName.error}
            onChange={walletName.onChange}
            onFocus={walletName.onFocus}
            onBlur={walletName.onBlur}
            onKeyPress={this.checkForEnterKey.bind(this)}
          />

          <Dropdown
            label={intl.formatMessage(messages.currency)}
            value={currency.value}
            onChange={currency.onChange}
            onFocus={currency.onFocus}
            onBlur={currency.onBlur}
            error={currency.error}
            source={currencies}
          />

        </Dialog>

    );
  }

}
<|endoftext|>